import React, { useEffect, useRef, useState } from "react" import styles from "./style.module.css" import { Icon, Text } from "../../atoms" import { getGlobalStyle } from "../../../helpers" type Layout = "list" | "columns" interface LayoutSwitcherProps { setLayout: (layout: Layout) => void layout: Layout } export const LayoutSwitcher: React.FC = ({ setLayout, layout = "list" }: { setLayout: (layout: Layout) => void layout: Layout }) => { const toolbarRef = useRef(null) const buttonsRef = useRef>([]) const [sliderStyle, setSliderStyle] = useState<{ left: number, width: number }>({ left: 0, width: 0 }) // set refs length = number of buttons (2) const buttonCount = 2 useEffect(() => { // create array slots if empty if (buttonsRef.current.length !== buttonCount) { buttonsRef.current = Array(buttonCount).fill(null) } const compute = () => { const toolbar = toolbarRef.current if (!toolbar) return // find active button index const index = layout === "list" ? 0 : 1 const btn = buttonsRef.current[index] if (!btn) return const toolbarRect = toolbar.getBoundingClientRect() const btnRect = btn.getBoundingClientRect() // calculate left relative to toolbar const left = Math.round(btnRect.left - toolbarRect.left + toolbar.scrollLeft) const width = Math.round(btnRect.width) setSliderStyle({ left, width }) } compute() // responsive: ResizeObserver preferred let ro: ResizeObserver | null = null if (typeof ResizeObserver !== "undefined") { ro = new ResizeObserver(() => compute()) ro.observe(document.documentElement) // also observe toolbar for layout changes if (toolbarRef.current) ro.observe(toolbarRef.current) } else { window.addEventListener("resize", compute) } // cleanup return () => { if (ro) ro.disconnect() else window.removeEventListener("resize", compute) } }, [layout]) return ( <>
) }