@transkripid/flowbite-react
Version:
Official React components built for Flowbite and Tailwind CSS - Transkrip.id fork
1 lines • 9.06 kB
Source Map (JSON)
{"version":3,"file":"Tabs.mjs","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["'use client';\n\nimport type { ComponentProps, ForwardedRef, KeyboardEvent, PropsWithChildren, ReactElement } from 'react';\nimport { Children, forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport { twMerge } from 'tailwind-merge';\nimport { mergeDeep } from '../../helpers/merge-deep';\nimport { getTheme } from '../../theme-store';\nimport type { DeepPartial } from '../../types';\nimport type { FlowbiteBoolean } from '../Flowbite';\nimport type { TabItemProps } from './TabItem';\nimport { TabItem } from './TabItem';\n\nexport interface FlowbiteTabsTheme {\n base: string;\n tablist: {\n base: string;\n styles: TabStyles;\n tabitem: {\n base: string;\n styles: TabStyleItem<TabStyles>;\n icon: string;\n };\n };\n tabitemcontainer: {\n base: string;\n styles: TabStyles;\n };\n tabpanel: string;\n}\n\nexport interface TabStyles {\n default: string;\n fullWidth: string;\n pills: string;\n underline: string;\n}\n\nexport interface TabStyleItemProps {\n base: string;\n active: FlowbiteBoolean;\n}\n\nexport type TabStyleItem<Type> = {\n [K in keyof Type]: TabStyleItemProps;\n};\n\nexport type TabItemStatus = 'active' | 'notActive';\n\ninterface TabEventProps {\n target: number;\n}\n\ninterface TabKeyboardEventProps extends TabEventProps {\n event: KeyboardEvent<HTMLButtonElement>;\n}\n\nexport interface TabsProps extends Omit<ComponentProps<'div'>, 'ref' | 'style'> {\n onActiveTabChange?: (activeTab: number) => void;\n style?: keyof TabStyles;\n theme?: DeepPartial<FlowbiteTabsTheme>;\n}\n\nexport interface TabsRef {\n setActiveTab: (activeTab: number) => void;\n}\n\nconst TabsComponent = forwardRef<TabsRef, TabsProps>(\n (\n { children, className, onActiveTabChange, style = 'default', theme: customTheme = {}, ...props },\n ref: ForwardedRef<TabsRef>,\n ) => {\n const theme = mergeDeep(getTheme().tabs, customTheme);\n\n const id = useId();\n const tabs = useMemo(\n () =>\n Children.map(\n Children.toArray(children) as ReactElement<PropsWithChildren<TabItemProps>>[],\n ({ props }) => props,\n ),\n [children],\n );\n const tabRefs = useRef<HTMLButtonElement[]>([]);\n const [activeTab, setActiveTab] = useState(\n Math.max(\n 0,\n tabs.findIndex((tab) => tab.active),\n ),\n );\n const [focusedTab, setFocusedTab] = useState(-1);\n\n const setActiveTabWithCallback = (activeTab: number) => {\n setActiveTab(activeTab);\n if (onActiveTabChange) onActiveTabChange(activeTab);\n };\n\n const handleClick = ({ target }: TabEventProps): void => {\n setActiveTabWithCallback(target);\n setFocusedTab(target);\n };\n\n const handleKeyboard = ({ event, target }: TabKeyboardEventProps): void => {\n if (event.key === 'ArrowLeft') {\n setFocusedTab(Math.max(0, focusedTab - 1));\n }\n\n if (event.key === 'ArrowRight') {\n setFocusedTab(Math.min(tabs.length - 1, focusedTab + 1));\n }\n\n if (event.key === 'Enter') {\n setActiveTabWithCallback(target);\n setFocusedTab(target);\n }\n };\n\n const tabItemStyle = theme.tablist.tabitem.styles[style];\n const tabItemContainerStyle = theme.tabitemcontainer.styles[style];\n\n useEffect(() => {\n tabRefs.current[focusedTab]?.focus();\n }, [focusedTab]);\n\n useImperativeHandle(ref, () => ({\n setActiveTab: setActiveTabWithCallback,\n }));\n\n return (\n <div className={twMerge(theme.base, className)}>\n <div\n aria-label=\"Tabs\"\n role=\"tablist\"\n className={twMerge(theme.tablist.base, theme.tablist.styles[style], className)}\n {...props}\n >\n {tabs.map((tab, index) => (\n <button\n key={index}\n type=\"button\"\n aria-controls={`${id}-tabpanel-${index}`}\n aria-selected={index === activeTab}\n className={twMerge(\n theme.tablist.tabitem.base,\n tabItemStyle.base,\n index === activeTab && tabItemStyle.active.on,\n index !== activeTab && !tab.disabled && tabItemStyle.active.off,\n )}\n disabled={tab.disabled}\n id={`${id}-tab-${index}`}\n onClick={() => handleClick({ target: index })}\n onKeyDown={(event) => handleKeyboard({ event, target: index })}\n ref={(element) => (tabRefs.current[index] = element as HTMLButtonElement)}\n role=\"tab\"\n tabIndex={index === focusedTab ? 0 : -1}\n style={{ zIndex: index === focusedTab ? 2 : 1 }}\n >\n {tab.icon && <tab.icon className={theme.tablist.tabitem.icon} />}\n {tab.title}\n </button>\n ))}\n </div>\n <div className={twMerge(theme.tabitemcontainer.base, tabItemContainerStyle)}>\n {tabs.map((tab, index) => (\n <div\n key={index}\n aria-labelledby={`${id}-tab-${index}`}\n className={theme.tabpanel}\n hidden={index !== activeTab}\n id={`${id}-tabpanel-${index}`}\n role=\"tabpanel\"\n tabIndex={0}\n >\n {tab.children}\n </div>\n ))}\n </div>\n </div>\n );\n },\n);\n\nTabsComponent.displayName = 'Tabs';\n\nexport const Tabs = Object.assign(TabsComponent, {\n Item: TabItem,\n});\n"],"names":["TabsComponent","forwardRef","children","className","onActiveTabChange","style","theme","customTheme","props","ref","mergeDeep","getTheme","tabs","id","useId","useMemo","Children","map","toArray","tabRefs","useRef","activeTab","setActiveTab","useState","Math","max","findIndex","tab","active","focusedTab","setFocusedTab","setActiveTabWithCallback","handleClick","target","handleKeyboard","event","key","min","length","tabItemStyle","tablist","tabitem","styles","tabItemContainerStyle","tabitemcontainer","useEffect","current","focus","useImperativeHandle","twMerge","base","jsx","index","jsxs","on","disabled","off","element","zIndex","icon","tab_0","title","tabpanel","displayName","Tabs","Object","assign","Item","TabItem"],"mappings":"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"}