{"version":3,"sources":["../src/tabs/tabs-list.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactElement, MouseEvent } from \"react\";\nimport { forwardRef, useEffect, useRef } from \"react\";\nimport { clsx } from \"@postenbring/hedwig-css/typed-classname\";\nimport { useResize, useHydrated, useMergeRefs } from \"../utils/utils\";\nimport { useTabsContext } from \"./context\";\n\nexport interface TabsListProps extends HTMLAttributes<HTMLDivElement> {\n  children: ReactElement<TabsTabProps> | ReactElement<TabsTabProps>[];\n\n  /**\n   * Direction of the tabs. Can either be vertical or horizontal.\n   * Horizontal breaks on window width with fallback back to vertical\n   *\n   * @default \"horizontal\"\n   */\n  direction?: \"vertical\" | \"horizontal\";\n}\n\nexport const TabsList = forwardRef<HTMLDivElement, TabsListProps>(\n  ({ children, direction = \"horizontal\", className, ...rest }, ref) => {\n    const { activeTabId } = useTabsContext();\n    const tabsListRef = useRef<HTMLDivElement>(null);\n    const mergedRef = useMergeRefs([tabsListRef, ref]);\n    const { width: tabsWidth } = useResize(tabsListRef);\n\n    const isClientSide = useHydrated();\n    const { innerWidth } = isClientSide ? window : { innerWidth: 1000 };\n    const wideEnough = innerWidth >= tabsWidth;\n\n    const previousTabId = useRef(activeTabId);\n\n    // Marker animation\n    useEffect(() => {\n      const tabList = tabsListRef.current;\n      const activeTab = tabList?.querySelector(`[data-tabid=\"${activeTabId}\"]`);\n      if (!activeTab || !tabList) return;\n\n      const { offsetHeight: containerHeight, offsetWidth: containerWidth } = tabList;\n      const { offsetHeight, offsetWidth, offsetTop, offsetLeft } = activeTab as HTMLElement;\n\n      // Calculate the height and width of the marker relative to the container\n      const height = offsetHeight / containerHeight;\n      const width = offsetWidth / containerWidth;\n\n      // NOTE: Doing a DOM manipulation here to set the CSS variables for the marker\n      // Not really the react idomatic way, but as long as it works we are able to skip some intermidiate `useState`\n      tabsListRef.current.style.setProperty(\"--_hds-tabs-marker-height\", String(height));\n      tabsListRef.current.style.setProperty(\"--_hds-tabs-marker-width\", String(width));\n      tabsListRef.current.style.setProperty(\"--_hds-tabs-marker-top\", `${offsetTop}px`);\n      tabsListRef.current.style.setProperty(\"--_hds-tabs-marker-left\", `${offsetLeft}px`);\n\n      // Start with border fallback, then switch to the animated marker when the user changes tabs\n      // This way the marker is placed immediately to the default tab, then animates smoothly to the next when selected\n      if (previousTabId.current !== activeTabId) {\n        tabsListRef.current.style.setProperty(\n          \"--_hds-tabs-marker-animated-color\",\n          \"var(--_hds-tabs-marker-color)\",\n        );\n        tabsListRef.current.style.setProperty(\n          \"--_hds-tabs-marker-border-fallback-color\",\n          \"transparent\",\n        );\n      }\n      previousTabId.current = activeTabId;\n    }, [activeTabId, innerWidth]);\n\n    return (\n      <div\n        className={clsx(\n          \"hds-tabs__list\",\n          direction === \"horizontal\"\n            ? {\n                \"hds-tabs__list--horizontal\": wideEnough,\n                \"hds-tabs__list--vertical\": !wideEnough,\n              }\n            : {\n                \"hds-tabs__list--vertical\": true,\n              },\n          className as undefined,\n        )}\n        ref={mergedRef}\n        role=\"tablist\"\n        {...rest}\n      >\n        {children}\n      </div>\n    );\n  },\n);\nTabsList.displayName = \"Tabs.List\";\n\nexport interface TabsTabProps extends HTMLAttributes<HTMLButtonElement> {\n  children: ReactElement<HTMLElement> | string;\n\n  /**\n   * Identifier for the tab\n   */\n  tabId: string;\n}\n\nexport const TabsTab = forwardRef<HTMLButtonElement, TabsTabProps>(\n  ({ children, tabId, className, onClick, ...rest }, ref) => {\n    const context = useTabsContext();\n\n    const toggleTab = (e: MouseEvent<HTMLButtonElement>) => {\n      e.preventDefault();\n      context.toggleActiveTabId(tabId);\n      onClick?.(e);\n    };\n    return (\n      <button\n        className={clsx(\n          \"hds-tabs__tab\",\n          { \"hds-tabs__tab--active\": context.activeTabId === tabId },\n          className as undefined,\n        )}\n        data-tabid={tabId}\n        onClick={toggleTab}\n        ref={ref}\n        type=\"button\"\n        role=\"tab\"\n        {...rest}\n      >\n        {children}\n      </button>\n    );\n  },\n);\nTabsTab.displayName = \"Tabs.Tab\";\n"],"mappings":";;;;;;;;;;;;;;;AACA,SAAS,YAAY,WAAW,cAAc;AAC9C,SAAS,YAAY;AAiEf;AAjDC,IAAM,WAAW;AAAA,EACtB,CAAC,IAA4D,QAAQ;AAApE,iBAAE,YAAU,YAAY,cAAc,UAnBzC,IAmBG,IAAoD,iBAApD,IAAoD,CAAlD,YAAU,aAA0B;AACrC,UAAM,EAAE,YAAY,IAAI,eAAe;AACvC,UAAM,cAAc,OAAuB,IAAI;AAC/C,UAAM,YAAY,aAAa,CAAC,aAAa,GAAG,CAAC;AACjD,UAAM,EAAE,OAAO,UAAU,IAAI,UAAU,WAAW;AAElD,UAAM,eAAe,YAAY;AACjC,UAAM,EAAE,WAAW,IAAI,eAAe,SAAS,EAAE,YAAY,IAAK;AAClE,UAAM,aAAa,cAAc;AAEjC,UAAM,gBAAgB,OAAO,WAAW;AAGxC,cAAU,MAAM;AACd,YAAM,UAAU,YAAY;AAC5B,YAAM,YAAY,mCAAS,cAAc,gBAAgB,WAAW;AACpE,UAAI,CAAC,aAAa,CAAC,QAAS;AAE5B,YAAM,EAAE,cAAc,iBAAiB,aAAa,eAAe,IAAI;AACvE,YAAM,EAAE,cAAc,aAAa,WAAW,WAAW,IAAI;AAG7D,YAAM,SAAS,eAAe;AAC9B,YAAM,QAAQ,cAAc;AAI5B,kBAAY,QAAQ,MAAM,YAAY,6BAA6B,OAAO,MAAM,CAAC;AACjF,kBAAY,QAAQ,MAAM,YAAY,4BAA4B,OAAO,KAAK,CAAC;AAC/E,kBAAY,QAAQ,MAAM,YAAY,0BAA0B,GAAG,SAAS,IAAI;AAChF,kBAAY,QAAQ,MAAM,YAAY,2BAA2B,GAAG,UAAU,IAAI;AAIlF,UAAI,cAAc,YAAY,aAAa;AACzC,oBAAY,QAAQ,MAAM;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AACA,oBAAY,QAAQ,MAAM;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,oBAAc,UAAU;AAAA,IAC1B,GAAG,CAAC,aAAa,UAAU,CAAC;AAE5B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,cAAc,eACV;AAAA,YACE,8BAA8B;AAAA,YAC9B,4BAA4B,CAAC;AAAA,UAC/B,IACA;AAAA,YACE,4BAA4B;AAAA,UAC9B;AAAA,UACJ;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL,MAAK;AAAA,SACD,OAfL;AAAA,QAiBE;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,SAAS,cAAc;AAWhB,IAAM,UAAU;AAAA,EACrB,CAAC,IAAkD,QAAQ;AAA1D,iBAAE,YAAU,OAAO,WAAW,QArGjC,IAqGG,IAA0C,iBAA1C,IAA0C,CAAxC,YAAU,SAAO,aAAW;AAC7B,UAAM,UAAU,eAAe;AAE/B,UAAM,YAAY,CAAC,MAAqC;AACtD,QAAE,eAAe;AACjB,cAAQ,kBAAkB,KAAK;AAC/B,yCAAU;AAAA,IACZ;AACA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,EAAE,yBAAyB,QAAQ,gBAAgB,MAAM;AAAA,UACzD;AAAA,QACF;AAAA,QACA,cAAY;AAAA,QACZ,SAAS;AAAA,QACT;AAAA,QACA,MAAK;AAAA,QACL,MAAK;AAAA,SACD,OAXL;AAAA,QAaE;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,QAAQ,cAAc;","names":[]}