@smwb/ui-react 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI_LESS_OVERRIDES.md +84 -21
- package/AI_THEMING.md +72 -28
- package/README.md +654 -0
- package/dist/assets/styles/less/components/appBar/appBar.entry.css +1 -1
- package/dist/assets/styles/less/components/button/button.entry.css +1 -1
- package/dist/assets/styles/less/components/checkbox/checkbox.entry.css +1 -1
- package/dist/assets/styles/less/components/chip/chip.entry.css +1 -1
- package/dist/assets/styles/less/components/commandPalette/commandPalette.entry.css +1 -0
- package/dist/assets/styles/less/components/composer/composer.entry.css +1 -0
- package/dist/assets/styles/less/components/dagView/dagView.entry.css +1 -0
- package/dist/assets/styles/less/components/diffStat/diffStat.entry.css +1 -0
- package/dist/assets/styles/less/components/kbd/kbd.entry.css +1 -0
- package/dist/assets/styles/less/components/list/list.entry.css +1 -1
- package/dist/assets/styles/less/components/qrCode/qrCode.entry.css +1 -0
- package/dist/assets/styles/less/components/radioButton/radioButton.entry.css +1 -1
- package/dist/assets/styles/less/components/selectField/selectField.entry.css +1 -1
- package/dist/assets/styles/less/components/sidebar/sidebar.entry.css +1 -1
- package/dist/assets/styles/less/components/statusDot/statusDot.entry.css +1 -0
- package/dist/assets/styles/less/components/swimlanes/swimlanes.entry.css +1 -0
- package/dist/assets/styles/less/components/tabGroups/tabGroups.entry.css +1 -0
- package/dist/assets/styles/less/components/tabs/tab/tab.entry.css +1 -1
- package/dist/assets/styles/less/components/tabs/tabPanel/tabPanel.entry.css +1 -0
- package/dist/assets/styles/less/components/tabs/tabs.entry.css +1 -1
- package/dist/assets/styles/less/components/textField/textField.entry.css +1 -1
- package/dist/assets/styles/less/components/toggle/toggle.entry.css +1 -1
- package/dist/assets/styles/less/components/treeView/treeView.entry.css +1 -1
- package/dist/assets/styles/less/tokens.entry.css +1 -1
- package/dist/components/dataDisplay/chat/chat.d.ts +43 -1
- package/dist/components/dataDisplay/chat/chat.js +179 -150
- package/dist/components/dataDisplay/chat/chat.js.map +1 -1
- package/dist/components/dataDisplay/chat/chatComposer.d.ts +17 -0
- package/dist/components/dataDisplay/chat/chatComposer.js +31 -29
- package/dist/components/dataDisplay/chat/chatComposer.js.map +1 -1
- package/dist/components/dataDisplay/chat/index.d.ts +1 -1
- package/dist/components/dataDisplay/chat/utils.d.ts +14 -0
- package/dist/components/dataDisplay/chat/utils.js.map +1 -1
- package/dist/components/dataDisplay/dagView/dagLayout.d.ts +74 -0
- package/dist/components/dataDisplay/dagView/dagLayout.js +289 -0
- package/dist/components/dataDisplay/dagView/dagLayout.js.map +1 -0
- package/dist/components/dataDisplay/dagView/dagView.d.ts +157 -0
- package/dist/components/dataDisplay/dagView/dagView.js +543 -0
- package/dist/components/dataDisplay/dagView/dagView.js.map +1 -0
- package/dist/components/dataDisplay/dagView/index.d.ts +4 -0
- package/dist/components/dataDisplay/dagView/panZoom.d.ts +75 -0
- package/dist/components/dataDisplay/dagView/panZoom.js +171 -0
- package/dist/components/dataDisplay/dagView/panZoom.js.map +1 -0
- package/dist/components/dataDisplay/diffStat/diffStat.d.ts +54 -0
- package/dist/components/dataDisplay/diffStat/diffStat.js +63 -0
- package/dist/components/dataDisplay/diffStat/diffStat.js.map +1 -0
- package/dist/components/dataDisplay/diffStat/index.d.ts +2 -0
- package/dist/components/dataDisplay/kbd/index.d.ts +4 -0
- package/dist/components/dataDisplay/kbd/kbd.d.ts +40 -0
- package/dist/components/dataDisplay/kbd/kbd.js +27 -0
- package/dist/components/dataDisplay/kbd/kbd.js.map +1 -0
- package/dist/components/dataDisplay/kbd/kbdKeys.d.ts +18 -0
- package/dist/components/dataDisplay/kbd/kbdKeys.js +72 -0
- package/dist/components/dataDisplay/kbd/kbdKeys.js.map +1 -0
- package/dist/components/dataDisplay/list/listItem.d.ts +34 -0
- package/dist/components/dataDisplay/list/listItem.js +47 -24
- package/dist/components/dataDisplay/list/listItem.js.map +1 -1
- package/dist/components/dataDisplay/qrCode/index.d.ts +2 -0
- package/dist/components/dataDisplay/qrCode/qrCode.d.ts +28 -0
- package/dist/components/dataDisplay/qrCode/qrCode.js +78 -0
- package/dist/components/dataDisplay/qrCode/qrCode.js.map +1 -0
- package/dist/components/dataDisplay/qrCode/qrCodePath.d.ts +7 -0
- package/dist/components/dataDisplay/qrCode/qrCodePath.js +20 -0
- package/dist/components/dataDisplay/qrCode/qrCodePath.js.map +1 -0
- package/dist/components/dataDisplay/statusDot/index.d.ts +2 -0
- package/dist/components/dataDisplay/statusDot/statusDot.d.ts +35 -0
- package/dist/components/dataDisplay/statusDot/statusDot.js +30 -0
- package/dist/components/dataDisplay/statusDot/statusDot.js.map +1 -0
- package/dist/components/dataDisplay/swimlanes/index.d.ts +2 -0
- package/dist/components/dataDisplay/swimlanes/swimlanes.d.ts +53 -0
- package/dist/components/dataDisplay/swimlanes/swimlanes.js +357 -0
- package/dist/components/dataDisplay/swimlanes/swimlanes.js.map +1 -0
- package/dist/components/dataDisplay/treeView/treeView.d.ts +17 -1
- package/dist/components/dataDisplay/treeView/treeView.js +113 -92
- package/dist/components/dataDisplay/treeView/treeView.js.map +1 -1
- package/dist/components/feedBack/modal/modal.js +84 -63
- package/dist/components/feedBack/modal/modal.js.map +1 -1
- package/dist/components/inputs/button/button.d.ts +13 -1
- package/dist/components/inputs/button/button.js +57 -51
- package/dist/components/inputs/button/button.js.map +1 -1
- package/dist/components/inputs/composer/composer.d.ts +149 -0
- package/dist/components/inputs/composer/composer.js +219 -0
- package/dist/components/inputs/composer/composer.js.map +1 -0
- package/dist/components/inputs/composer/composerFiles.d.ts +26 -0
- package/dist/components/inputs/composer/composerFiles.js +19 -0
- package/dist/components/inputs/composer/composerFiles.js.map +1 -0
- package/dist/components/inputs/composer/composerKeys.d.ts +29 -0
- package/dist/components/inputs/composer/composerKeys.js +7 -0
- package/dist/components/inputs/composer/composerKeys.js.map +1 -0
- package/dist/components/inputs/composer/index.d.ts +3 -0
- package/dist/components/layout/sheet/sheet.d.ts +12 -0
- package/dist/components/layout/sheet/sheet.js +152 -137
- package/dist/components/layout/sheet/sheet.js.map +1 -1
- package/dist/components/layout/tabGroups/index.d.ts +4 -0
- package/dist/components/layout/tabGroups/tabGroups.d.ts +94 -0
- package/dist/components/layout/tabGroups/tabGroups.js +783 -0
- package/dist/components/layout/tabGroups/tabGroups.js.map +1 -0
- package/dist/components/layout/tabGroups/tabGroupsFocus.d.ts +55 -0
- package/dist/components/layout/tabGroups/tabGroupsFocus.js +199 -0
- package/dist/components/layout/tabGroups/tabGroupsFocus.js.map +1 -0
- package/dist/components/layout/tabGroups/tabGroupsLayout.d.ts +250 -0
- package/dist/components/layout/tabGroups/tabGroupsLayout.js +497 -0
- package/dist/components/layout/tabGroups/tabGroupsLayout.js.map +1 -0
- package/dist/components/navigation/appBar/appBar.d.ts +22 -0
- package/dist/components/navigation/appBar/appBar.js +31 -26
- package/dist/components/navigation/appBar/appBar.js.map +1 -1
- package/dist/components/navigation/commandPalette/commandPalette.d.ts +111 -0
- package/dist/components/navigation/commandPalette/commandPalette.js +337 -0
- package/dist/components/navigation/commandPalette/commandPalette.js.map +1 -0
- package/dist/components/navigation/commandPalette/commandPaletteFilter.d.ts +11 -0
- package/dist/components/navigation/commandPalette/commandPaletteFilter.js +16 -0
- package/dist/components/navigation/commandPalette/commandPaletteFilter.js.map +1 -0
- package/dist/components/navigation/commandPalette/commandPaletteNavigation.d.ts +13 -0
- package/dist/components/navigation/commandPalette/commandPaletteNavigation.js +38 -0
- package/dist/components/navigation/commandPalette/commandPaletteNavigation.js.map +1 -0
- package/dist/components/navigation/commandPalette/commandPaletteTypes.d.ts +39 -0
- package/dist/components/navigation/commandPalette/index.d.ts +4 -0
- package/dist/components/navigation/sidebar/sidebar.d.ts +10 -0
- package/dist/components/navigation/sidebar/sidebar.js +61 -59
- package/dist/components/navigation/sidebar/sidebar.js.map +1 -1
- package/dist/components/navigation/tabs/index.d.ts +3 -1
- package/dist/components/navigation/tabs/tab/tab.d.ts +88 -1
- package/dist/components/navigation/tabs/tab/tab.js +121 -42
- package/dist/components/navigation/tabs/tab/tab.js.map +1 -1
- package/dist/components/navigation/tabs/tabPanel/tabPanel.d.ts +19 -0
- package/dist/components/navigation/tabs/tabPanel/tabPanel.js +27 -0
- package/dist/components/navigation/tabs/tabPanel/tabPanel.js.map +1 -0
- package/dist/components/navigation/tabs/tabs.d.ts +75 -5
- package/dist/components/navigation/tabs/tabs.js +369 -145
- package/dist/components/navigation/tabs/tabs.js.map +1 -1
- package/dist/components/navigation/tabs/tabs.utils.d.ts +20 -0
- package/dist/components/navigation/tabs/tabs.utils.js +11 -0
- package/dist/components/navigation/tabs/tabs.utils.js.map +1 -0
- package/dist/components/navigation/tabs/tabsContext.d.ts +11 -0
- package/dist/components/navigation/tabs/tabsContext.js +6 -0
- package/dist/components/navigation/tabs/tabsContext.js.map +1 -0
- package/dist/headless/components/dataDisplay/chat/chat.js +179 -150
- package/dist/headless/components/dataDisplay/chat/chat.js.map +1 -1
- package/dist/headless/components/dataDisplay/chat/chatComposer.js +31 -29
- package/dist/headless/components/dataDisplay/chat/chatComposer.js.map +1 -1
- package/dist/headless/components/dataDisplay/chat/utils.js.map +1 -1
- package/dist/headless/components/dataDisplay/dagView/dagLayout.js +289 -0
- package/dist/headless/components/dataDisplay/dagView/dagLayout.js.map +1 -0
- package/dist/headless/components/dataDisplay/dagView/dagView.js +541 -0
- package/dist/headless/components/dataDisplay/dagView/dagView.js.map +1 -0
- package/dist/headless/components/dataDisplay/dagView/panZoom.js +171 -0
- package/dist/headless/components/dataDisplay/dagView/panZoom.js.map +1 -0
- package/dist/headless/components/dataDisplay/diffStat/diffStat.js +61 -0
- package/dist/headless/components/dataDisplay/diffStat/diffStat.js.map +1 -0
- package/dist/headless/components/dataDisplay/kbd/kbd.js +25 -0
- package/dist/headless/components/dataDisplay/kbd/kbd.js.map +1 -0
- package/dist/headless/components/dataDisplay/kbd/kbdKeys.js +72 -0
- package/dist/headless/components/dataDisplay/kbd/kbdKeys.js.map +1 -0
- package/dist/headless/components/dataDisplay/list/listItem.js +47 -24
- package/dist/headless/components/dataDisplay/list/listItem.js.map +1 -1
- package/dist/headless/components/dataDisplay/qrCode/qrCode.js +76 -0
- package/dist/headless/components/dataDisplay/qrCode/qrCode.js.map +1 -0
- package/dist/headless/components/dataDisplay/qrCode/qrCodePath.js +20 -0
- package/dist/headless/components/dataDisplay/qrCode/qrCodePath.js.map +1 -0
- package/dist/headless/components/dataDisplay/statusDot/statusDot.js +28 -0
- package/dist/headless/components/dataDisplay/statusDot/statusDot.js.map +1 -0
- package/dist/headless/components/dataDisplay/swimlanes/swimlanes.js +355 -0
- package/dist/headless/components/dataDisplay/swimlanes/swimlanes.js.map +1 -0
- package/dist/headless/components/dataDisplay/treeView/treeView.js +113 -92
- package/dist/headless/components/dataDisplay/treeView/treeView.js.map +1 -1
- package/dist/headless/components/feedBack/modal/modal.js +85 -64
- package/dist/headless/components/feedBack/modal/modal.js.map +1 -1
- package/dist/headless/components/inputs/button/button.js +56 -50
- package/dist/headless/components/inputs/button/button.js.map +1 -1
- package/dist/headless/components/inputs/composer/composer.js +217 -0
- package/dist/headless/components/inputs/composer/composer.js.map +1 -0
- package/dist/headless/components/inputs/composer/composerFiles.js +19 -0
- package/dist/headless/components/inputs/composer/composerFiles.js.map +1 -0
- package/dist/headless/components/inputs/composer/composerKeys.js +7 -0
- package/dist/headless/components/inputs/composer/composerKeys.js.map +1 -0
- package/dist/headless/components/layout/sheet/sheet.js +160 -145
- package/dist/headless/components/layout/sheet/sheet.js.map +1 -1
- package/dist/headless/components/layout/tabGroups/tabGroups.js +781 -0
- package/dist/headless/components/layout/tabGroups/tabGroups.js.map +1 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsFocus.js +199 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsFocus.js.map +1 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsLayout.js +497 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsLayout.js.map +1 -0
- package/dist/headless/components/navigation/appBar/appBar.js +35 -30
- package/dist/headless/components/navigation/appBar/appBar.js.map +1 -1
- package/dist/headless/components/navigation/commandPalette/commandPalette.js +335 -0
- package/dist/headless/components/navigation/commandPalette/commandPalette.js.map +1 -0
- package/dist/headless/components/navigation/commandPalette/commandPaletteFilter.js +16 -0
- package/dist/headless/components/navigation/commandPalette/commandPaletteFilter.js.map +1 -0
- package/dist/headless/components/navigation/commandPalette/commandPaletteNavigation.js +38 -0
- package/dist/headless/components/navigation/commandPalette/commandPaletteNavigation.js.map +1 -0
- package/dist/headless/components/navigation/sidebar/sidebar.js +56 -54
- package/dist/headless/components/navigation/sidebar/sidebar.js.map +1 -1
- package/dist/headless/components/navigation/tabs/tab/tab.js +121 -42
- package/dist/headless/components/navigation/tabs/tab/tab.js.map +1 -1
- package/dist/headless/components/navigation/tabs/tabPanel/tabPanel.js +25 -0
- package/dist/headless/components/navigation/tabs/tabPanel/tabPanel.js.map +1 -0
- package/dist/headless/components/navigation/tabs/tabs.js +369 -145
- package/dist/headless/components/navigation/tabs/tabs.js.map +1 -1
- package/dist/headless/components/navigation/tabs/tabs.utils.js +11 -0
- package/dist/headless/components/navigation/tabs/tabs.utils.js.map +1 -0
- package/dist/headless/components/navigation/tabs/tabsContext.js +6 -0
- package/dist/headless/components/navigation/tabs/tabsContext.js.map +1 -0
- package/dist/headless/hooks/useFocusTrap.js +24 -21
- package/dist/headless/hooks/useFocusTrap.js.map +1 -1
- package/dist/headless/hooks/useKeyboardShortcut.js +19 -0
- package/dist/headless/hooks/useKeyboardShortcut.js.map +1 -0
- package/dist/headless/index.js +360 -316
- package/dist/headless/index.js.map +1 -1
- package/dist/headless/utils/keyboardShortcut.js +49 -0
- package/dist/headless/utils/keyboardShortcut.js.map +1 -0
- package/dist/headless/utils/linkAttrs.js +13 -0
- package/dist/headless/utils/linkAttrs.js.map +1 -0
- package/dist/headless/utils/restoreFocus.js +10 -0
- package/dist/headless/utils/restoreFocus.js.map +1 -0
- package/dist/hooks/useFocusTrap.d.ts +6 -1
- package/dist/hooks/useFocusTrap.js +24 -21
- package/dist/hooks/useFocusTrap.js.map +1 -1
- package/dist/hooks/useKeyboardShortcut.d.ts +30 -0
- package/dist/hooks/useKeyboardShortcut.js +19 -0
- package/dist/hooks/useKeyboardShortcut.js.map +1 -0
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +24 -3
- package/dist/index.js +360 -316
- package/dist/index.js.map +1 -1
- package/dist/utils/keyboardShortcut.d.ts +12 -0
- package/dist/utils/keyboardShortcut.js +49 -0
- package/dist/utils/keyboardShortcut.js.map +1 -0
- package/dist/utils/linkAttrs.d.ts +13 -0
- package/dist/utils/linkAttrs.js +13 -0
- package/dist/utils/linkAttrs.js.map +1 -0
- package/dist/utils/restoreFocus.d.ts +8 -0
- package/dist/utils/restoreFocus.js +10 -0
- package/dist/utils/restoreFocus.js.map +1 -0
- package/package.json +5 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.js","sources":["../../../../src/components/navigation/tabs/tabs.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"clsx\";\nimport { debounce } from \"../../../utils/debounce\";\nimport { Tab, TabProps } from \"./tab/tab\";\nimport { useEventCallback } from \"../../../hooks/useEventCallback\";\nimport { animate } from \"../../../utils/animate\";\nimport Icon from \"../../base/icon/icon\";\n\nexport interface TabsProps {\n /**\n * Index of the selected tab. Tabs count in the order they render: a tab left out,\n * such as `{show && <Tab />}` while `show` is false, takes no index.\n */\n value: number;\n /** Called with the index of the clicked tab, counted as for `value`. */\n onChange: (e: React.MouseEvent<HTMLButtonElement>, index: number) => void;\n /** Draw the indicator as wide as the selected tab's label rather than the whole tab. */\n indicatorContent?: boolean;\n /**\n * Let the tab row scroll sideways instead of clipping it. The edge beyond which\n * more tabs are hidden fades out.\n */\n scrollable?: boolean;\n /** With `scrollable`: buttons at both ends that scroll the row while it overflows. */\n scrollButtons?: boolean;\n /** Compact tabs: labels as written (no capitals, no letter spacing) and less padding. */\n dense?: boolean;\n /** Accessible label of the button that scrolls back. */\n scrollBackAriaLabel?: string;\n /** Accessible label of the button that scrolls forward. */\n scrollForwardAriaLabel?: string;\n className?: string;\n children?: React.ReactNode;\n /** Accessible label for the tab list. */\n \"aria-label\"?: string;\n}\n\ninterface IndicatorStyle {\n root: {\n left: number;\n width: number;\n };\n content?: {\n width: number;\n };\n}\n\nconst defaultIndicatorStyle = {\n root: {},\n content: {},\n} as IndicatorStyle;\n\n/** A scroll button moves the row by this share of its visible width. */\nconst SCROLL_PAGE = 0.8;\n\ninterface Overflow {\n start: boolean;\n end: boolean;\n}\n\nexport const Tabs = React.forwardRef<HTMLDivElement, TabsProps>(function Tabs(props, ref) {\n const {\n className,\n children,\n onChange,\n value,\n indicatorContent = false,\n scrollable = false,\n scrollButtons = false,\n dense = false,\n scrollBackAriaLabel = \"Scroll tabs back\",\n scrollForwardAriaLabel = \"Scroll tabs forward\",\n \"aria-label\": ariaLabel,\n ...rest\n } = props;\n const [mounted, setMounted] = React.useState(false);\n const [indicatorStyle, setIndicatorStyle] = React.useState<IndicatorStyle>(defaultIndicatorStyle);\n // Whether tabs are hidden past the start / the end of a scrollable row. Only\n // measured in the browser, so the server markup shows neither.\n const [overflow, setOverflow] = React.useState<Overflow>({ start: false, end: false });\n\n const tabsRef = React.useRef<HTMLDivElement>(null);\n const tabListRef = React.useRef<HTMLDivElement>(null);\n\n // Видимость следующего таба в пикселях\n const viewNextTabInPixels = 40;\n\n const getTabsMeta = () => {\n const tabsNode = tabsRef.current;\n\n let tabsMeta;\n\n if (tabsNode) {\n const rect = tabsNode.getBoundingClientRect();\n\n tabsMeta = {\n clientWidth: tabsNode.clientWidth,\n scrollLeft: tabsNode.scrollLeft,\n scrollTop: tabsNode.scrollTop,\n scrollWidth: tabsNode.scrollWidth,\n top: rect.top,\n bottom: rect.bottom,\n left: rect.left,\n right: rect.right,\n };\n }\n\n let tabMeta: DOMRect | null = null;\n let tabContentMeta: DOMRect | null = null;\n\n if (!tabListRef.current) {\n console.error(\"tabListRef.current is undefined\");\n }\n if (tabsNode && tabListRef.current) {\n const children = tabListRef.current.children;\n\n if (children.length > 0) {\n const tab = children[value];\n\n tabMeta = tab ? tab.getBoundingClientRect() : null;\n\n if (indicatorContent) {\n // The label box of that same tab, found in the DOM like the tab itself.\n const content = tab ? tab.querySelector(\".smwb-tab__content\") : null;\n tabContentMeta = content ? content.getBoundingClientRect() : null;\n }\n }\n }\n return { tabsMeta, tabMeta, tabContentMeta };\n };\n\n const updateIndicatorState = useEventCallback(() => {\n const { tabsMeta, tabMeta, tabContentMeta } = getTabsMeta();\n let startValue = 0;\n\n if (tabMeta && tabsMeta) {\n startValue = 1 * (tabMeta.left - tabsMeta.left + tabsMeta.scrollLeft);\n }\n\n const newIndicatorStyle: IndicatorStyle = {\n root: {\n left: startValue,\n width: tabMeta ? tabMeta.width : 0,\n },\n };\n\n if (indicatorContent && tabContentMeta) {\n newIndicatorStyle.content = {\n width: tabContentMeta.width,\n };\n }\n\n if (isNaN(indicatorStyle.root.left) || isNaN(indicatorStyle.root.width)) {\n setIndicatorStyle(newIndicatorStyle);\n } else {\n const dStart = Math.abs(indicatorStyle.root.left - newIndicatorStyle.root.left);\n const dSize = Math.abs(indicatorStyle.root.width - newIndicatorStyle.root.width);\n\n if (dStart >= 1 || dSize >= 1) {\n setIndicatorStyle(newIndicatorStyle);\n }\n }\n });\n\n const scroll = (scrollValue: number, { animation = true } = {}) => {\n if (!tabsRef.current) {\n return;\n }\n if (animation) {\n animate(tabsRef.current, \"scrollLeft\", scrollValue, {\n duration: 300,\n });\n } else {\n tabsRef.current.scrollLeft = scrollValue;\n }\n };\n\n const updateOverflow = useEventCallback(() => {\n const node = tabsRef.current;\n const max = node ? node.scrollWidth - node.clientWidth : 0;\n const next: Overflow =\n node && scrollable\n ? { start: node.scrollLeft > 1, end: node.scrollLeft < max - 1 }\n : { start: false, end: false };\n setOverflow((prev) => (prev.start === next.start && prev.end === next.end ? prev : next));\n });\n\n const scrollByPage = (direction: -1 | 1) => {\n const node = tabsRef.current;\n if (node) {\n scroll(node.scrollLeft + direction * node.clientWidth * SCROLL_PAGE);\n }\n };\n\n const scrollSelectedIntoView = useEventCallback((animation: boolean) => {\n const { tabsMeta, tabMeta } = getTabsMeta();\n\n if (!tabMeta || !tabsMeta) {\n return;\n }\n\n if (tabMeta.left < tabsMeta.left) {\n // Левая сторона таба не видна.\n const nextScrollStart = tabsMeta.scrollLeft + (tabMeta.left - tabsMeta.left);\n scroll(nextScrollStart - viewNextTabInPixels, { animation });\n } else if (tabMeta.right > tabsMeta.right) {\n // Правая сторона таба не видна.\n const nextScrollStart = tabsMeta.scrollLeft + (tabMeta.right - tabsMeta.right);\n scroll(nextScrollStart + viewNextTabInPixels, { animation });\n }\n });\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n React.useEffect(() => {\n updateIndicatorState();\n });\n\n React.useEffect(() => {\n const onResize = debounce(() => {\n if (tabsRef.current) {\n updateIndicatorState();\n updateOverflow();\n }\n }, 166);\n if (!tabsRef.current || !tabsRef.current.ownerDocument.defaultView) {\n console.error(`tabsRef.current.ownerDocument.defaultView is undefined`);\n return;\n }\n const window: Window & typeof globalThis = tabsRef.current.ownerDocument.defaultView;\n\n window.addEventListener(\"resize\", onResize);\n const scroller = tabsRef.current;\n scroller.addEventListener(\"scroll\", updateOverflow, { passive: true });\n\n let resizeObserver: ResizeObserver;\n\n // The row and each tab: a label can grow with its data while the row keeps\n // its width.\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(onResize);\n resizeObserver.observe(scroller);\n\n Array.from(tabListRef.current?.children ?? []).forEach((child) => {\n resizeObserver.observe(child);\n });\n }\n updateOverflow();\n\n return () => {\n onResize.cancel();\n\n window.removeEventListener(\"resize\", onResize);\n scroller.removeEventListener(\"scroll\", updateOverflow);\n\n if (resizeObserver) {\n resizeObserver.disconnect();\n }\n };\n }, [updateIndicatorState, updateOverflow]);\n\n React.useEffect(() => {\n // Не анимировать при первом рендере\n scrollSelectedIntoView(defaultIndicatorStyle !== indicatorStyle);\n }, [scrollSelectedIntoView, indicatorStyle]);\n\n // Only elements are tabs: a child left out, such as `{show && <Tab />}`, takes no\n // index, so `value` counts the tabs that render, as the indicator does in the DOM.\n const tabs = React.Children.toArray(children)\n .filter((child): child is React.ReactElement<TabProps> => React.isValidElement(child))\n .map((child, index) =>\n React.cloneElement(child, {\n isActive: value === index,\n // The tab's own onClick runs first, then the tab list picks the tab.\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n child.props.onClick?.(event);\n onChange(event, index);\n },\n } as TabProps)\n );\n\n const showScrollButtons = scrollable && scrollButtons && (overflow.start || overflow.end);\n\n return (\n <div\n className={cn(\n \"smwb-tabs\",\n {\n \"smwb-tabs--dense\": dense,\n \"smwb-tabs--overflow-start\": overflow.start,\n \"smwb-tabs--overflow-end\": overflow.end,\n },\n className\n )}\n role={\"tabpanel\"}\n ref={ref}\n {...rest}\n >\n {showScrollButtons && (\n <button\n type=\"button\"\n className=\"smwb-tabs__scroll-button smwb-tabs__scroll-button--start\"\n aria-label={scrollBackAriaLabel}\n disabled={!overflow.start}\n onClick={() => scrollByPage(-1)}\n >\n <Icon name=\"chevron_left\" size={20} />\n </button>\n )}\n <div\n className={cn(\"smwb-tabs__scroller\", {\n \"smwb-tabs__scroller--scrollable\": scrollable,\n })}\n ref={tabsRef}\n >\n <div className=\"smwb-tabs__scroll-area\" ref={tabListRef} role=\"tablist\" aria-label={ariaLabel}>\n {tabs}\n </div>\n {mounted && (\n <span className=\"smwb-tabs__indicator\" style={indicatorStyle.root}>\n <span className=\"smwb-tabs__indicator-content\" style={indicatorStyle.content} />\n </span>\n )}\n </div>\n {showScrollButtons && (\n <button\n type=\"button\"\n className=\"smwb-tabs__scroll-button smwb-tabs__scroll-button--end\"\n aria-label={scrollForwardAriaLabel}\n disabled={!overflow.end}\n onClick={() => scrollByPage(1)}\n >\n <Icon name=\"chevron_right\" size={20} />\n </button>\n )}\n </div>\n );\n});\n\nexport { Tab };\nexport type { TabProps };\n"],"names":["defaultIndicatorStyle","SCROLL_PAGE","Tabs","React","props","ref","className","children","onChange","value","indicatorContent","scrollable","scrollButtons","dense","scrollBackAriaLabel","scrollForwardAriaLabel","ariaLabel","rest","mounted","setMounted","indicatorStyle","setIndicatorStyle","overflow","setOverflow","tabsRef","tabListRef","viewNextTabInPixels","getTabsMeta","tabsNode","tabsMeta","rect","tabMeta","tabContentMeta","tab","content","updateIndicatorState","useEventCallback","startValue","newIndicatorStyle","dStart","dSize","scroll","scrollValue","animation","animate","updateOverflow","node","max","next","prev","scrollByPage","direction","scrollSelectedIntoView","nextScrollStart","onResize","debounce","window","scroller","resizeObserver","_b","_a","child","tabs","index","event","showScrollButtons","jsxs","cn","jsx","Icon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tabs.js","sources":["../../../../src/components/navigation/tabs/tabs.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"clsx\";\nimport { debounce } from \"../../../utils/debounce\";\nimport { Tab, TabProps, type TabActionsApi, type TabCloseReason } from \"./tab/tab\";\nimport { TabPanel, type TabPanelProps } from \"./tabPanel/tabPanel\";\nimport { useEventCallback } from \"../../../hooks/useEventCallback\";\nimport { animate } from \"../../../utils/animate\";\nimport Icon from \"../../base/icon/icon\";\nimport { useRovingTabIndex } from \"../../../hooks/useRovingTabIndex\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { matchesKeyboardShortcut } from \"../../../utils/keyboardShortcut\";\nimport { Menu, MenuItem } from \"../menu\";\nimport { getHiddenIndexes } from \"./tabs.utils\";\nimport { TabsContext, type TabsContextValue } from \"./tabsContext\";\n\n/**\n * Tabs follow the WAI-ARIA tabs pattern with manual activation. The selected tab is the row's one\n * tab stop (`tabIndex` 0, the others -1). The arrow keys along the row's `orientation` move focus to\n * the next or the previous tab (wrapping at the ends), Home and End to the first and the last one;\n * disabled tabs are skipped. Enter or Space then selects the focused tab, as a click does:\n * `onChange` is called for it, with the key's click. Moving focus changes nothing by itself, so a\n * row of link tabs does not navigate as the arrows pass them. Tab leaves the row for what follows\n * it, the selected `TabPanel` first when `panels` are given.\n *\n * A `Tab` can be `closable` and take `actions`; they sit beside the tab and out of the Tab order.\n * Delete on the focused tab, its close button or its `actions` (through `close`) ask `onClose` to\n * close it, and when it goes, focus moves to the tab that takes its place instead of falling to the\n * page. A middle click on a closable tab closes it too.\n *\n * With `onReorder` the row's tabs drag onto one another to reorder: `onReorder(from, to)` reports\n * the drop and the owner moves the tabs. With `overflowMenu` a scrollable row that overflows gains\n * a trigger beside it listing the clipped tabs. The chords Mod+W (close the focused closable tab)\n * and Mod+Shift+[ / Mod+Shift+] (switch to the previous / next tab) are handled on the row, as\n * best-effort: a browser of its own tabs reserves them.\n */\nexport interface TabsProps {\n /**\n * Index of the selected tab. Tabs count in the order they render: a tab left out,\n * such as `{show && <Tab />}` while `show` is false, takes no index.\n */\n value: number;\n /**\n * Called with the index of the clicked tab, counted as for `value`. A tab chosen from the keyboard\n * (Enter or Space on the focused tab) calls it with that click too. A modified or non-primary\n * click (Ctrl, Meta, Shift or Alt held, or a button other than the main one) on a link tab\n * (`Tab` with `href`) is the browser's, as \"open in a new tab\": it does not call `onChange`.\n */\n onChange: (e: React.MouseEvent<HTMLButtonElement>, index: number) => void;\n /**\n * Which way the tabs run. It sets `aria-orientation` on the tab list and picks the arrow keys that\n * move between tabs: Left and Right when horizontal, Up and Down when vertical. The styles draw\n * a horizontal row; a vertical list is yours to lay out.\n */\n orientation?: \"horizontal\" | \"vertical\";\n /**\n * The content of the tabs: `TabPanel`s, rendered after the tab row. With them each tab gets\n * `aria-controls` its panel and each panel `aria-labelledby` its tab. Without them the tabs link\n * to nothing, as before. Give a panel to every tab: a tab whose panel is left out still names it.\n * A `TabPanel` placed anywhere else is not linked to the tabs and is always shown.\n */\n panels?: React.ReactNode;\n /**\n * Base of the ids that link tabs and panels: tab `n` is `{id}-tab-{n}`, its panel `{id}-panel-{n}`.\n * It is also the id of the root element. A generated one by default.\n */\n id?: string;\n /** Draw the indicator as wide as the selected tab's label rather than the whole tab. */\n indicatorContent?: boolean;\n /**\n * Let the tab row scroll sideways instead of clipping it. The edge beyond which\n * more tabs are hidden fades out.\n */\n scrollable?: boolean;\n /**\n * With `scrollable`: buttons at both ends that scroll the row while it overflows. They are for\n * the pointer and stay out of the Tab order: the arrow keys reach every tab and scroll it into\n * view.\n */\n scrollButtons?: boolean;\n /**\n * Present ⇒ the row is reorderable by dragging a tab onto another (pointer-only; there is no\n * keyboard reorder). `Tabs` does not move the tabs itself: it reports the drag with\n * `onReorder(from, to)` — indexes counted as for `value` — and the owner reorders its state.\n * The tabs keep their focus through a reorder, and a reorder keeps the selection on the same tab:\n * when the dragged tab is the selected one, its new index is reported through `onChange` too, so\n * a controlled owner moves its value along with its array. That report carries the drop event in\n * place of the click a keyboard or menu choice makes, so the index argument is the authoritative\n * one: on a drop `event.currentTarget` is the scroll area, not the moved tab.\n */\n onReorder?: (from: number, to: number) => void;\n /**\n * With `scrollable`: when the row overflows, a trigger button is rendered beside the scroller\n * (in the scroll buttons' spot) that opens a menu of the tabs the viewport clips — any clipped\n * part beyond a 1px tolerance counts. Each entry shows the tab's icon and label, the selected one\n * is marked `aria-current=\"true\"`, and choosing one calls `onChange` for it and scrolls it into\n * view. The trigger appears only after the browser has measured an overflow, so the server markup\n * shows none.\n */\n overflowMenu?: boolean;\n /** Accessible label of the overflow-menu trigger. English by default; set it to localise. */\n overflowMenuAriaLabel?: string;\n /** Compact tabs: labels as written (no capitals, no letter spacing) and less padding. */\n dense?: boolean;\n /** Accessible label of the button that scrolls back. */\n scrollBackAriaLabel?: string;\n /** Accessible label of the button that scrolls forward. */\n scrollForwardAriaLabel?: string;\n className?: string;\n children?: React.ReactNode;\n /** Accessible label for the tab list. */\n \"aria-label\"?: string;\n}\n\ninterface IndicatorStyle {\n root: {\n left: number;\n width: number;\n };\n content?: {\n width: number;\n };\n}\n\nconst defaultIndicatorStyle = {\n root: {},\n content: {},\n} as IndicatorStyle;\n\n/** A scroll button moves the row by this share of its visible width. */\nconst SCROLL_PAGE = 0.8;\n\n/** A click that asks the browser for something else than \"go here\": a new tab, a new window, a download. */\nconst isModifiedClick = (event: React.MouseEvent): boolean =>\n event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey;\n\n/** Whether `panels` holds anything to draw: fragments count by what is inside them. */\nconst hasContent = (node: React.ReactNode): boolean =>\n React.Children.toArray(node).some((child) =>\n React.isValidElement<{ children?: React.ReactNode }>(child) && child.type === React.Fragment\n ? hasContent(child.props.children)\n : true\n );\n\nconst isTabDisabled = (tab: React.ReactElement<TabProps> | undefined): boolean =>\n Boolean(tab?.props.disabled) || tab?.props[\"aria-disabled\"] === true || tab?.props[\"aria-disabled\"] === \"true\";\n\ninterface Overflow {\n start: boolean;\n end: boolean;\n}\n\nexport const Tabs = React.forwardRef<HTMLDivElement, TabsProps>(function Tabs(props, ref) {\n const {\n className,\n children,\n onChange,\n value,\n indicatorContent = false,\n scrollable = false,\n scrollButtons = false,\n onReorder,\n overflowMenu = false,\n overflowMenuAriaLabel = \"More tabs\",\n dense = false,\n orientation = \"horizontal\",\n panels,\n id: idProp,\n scrollBackAriaLabel = \"Scroll tabs back\",\n scrollForwardAriaLabel = \"Scroll tabs forward\",\n \"aria-label\": ariaLabel,\n ...rest\n } = props;\n const [mounted, setMounted] = React.useState(false);\n const [indicatorStyle, setIndicatorStyle] = React.useState<IndicatorStyle>(defaultIndicatorStyle);\n // Whether tabs are hidden past the start / the end of a scrollable row. Only\n // measured in the browser, so the server markup shows neither.\n const [overflow, setOverflow] = React.useState<Overflow>({ start: false, end: false });\n // The indexes of the tabs the scroller's viewport clips: what the overflow menu lists. Empty on\n // the server and until the first measurement, like the overflow state above.\n const [hiddenIndexes, setHiddenIndexes] = React.useState<number[]>([]);\n // The overflow-menu trigger and the menu it opens, composed here when `overflowMenu` is on.\n const [overflowOpen, setOverflowOpen] = React.useState(false);\n const [overflowTrigger, setOverflowTrigger] = React.useState<HTMLButtonElement | null>(null);\n\n const generatedId = React.useId();\n const baseId = idProp ?? generatedId;\n // The tab that has focus while focus is in the tab list: it is the row's tab stop then, so\n // Tab from there leaves the row instead of landing on the selected tab again.\n const [focusedIndex, setFocusedIndex] = React.useState<number | null>(null);\n\n const tabsRef = React.useRef<HTMLDivElement>(null);\n const tabListRef = React.useRef<HTMLDivElement>(null);\n // The tab the user asked to close while it, or something beside it, had focus: its item, which\n // goes with it, and its place. If it goes while focus is lost with it, focus moves on to a neighbour.\n const closingRef = React.useRef<{ item: Element; index: number } | null>(null);\n // Drag-to-reorder: the index the drag started at and the two items it marks, the source and the\n // current drop target. Cleared on drop and dragend; a drag that never started marks nothing.\n const dragSourceRef = React.useRef<number | null>(null);\n const draggingItemRef = React.useRef<HTMLElement | null>(null);\n const dropTargetItemRef = React.useRef<HTMLElement | null>(null);\n\n // Видимость следующего таба в пикселях\n const viewNextTabInPixels = 40;\n\n const getTabsMeta = () => {\n const tabsNode = tabsRef.current;\n\n let tabsMeta;\n\n if (tabsNode) {\n const rect = tabsNode.getBoundingClientRect();\n\n tabsMeta = {\n clientWidth: tabsNode.clientWidth,\n scrollLeft: tabsNode.scrollLeft,\n scrollTop: tabsNode.scrollTop,\n scrollWidth: tabsNode.scrollWidth,\n top: rect.top,\n bottom: rect.bottom,\n left: rect.left,\n right: rect.right,\n };\n }\n\n let tabMeta: DOMRect | null = null;\n let tabContentMeta: DOMRect | null = null;\n\n if (!tabListRef.current) {\n console.error(\"tabListRef.current is undefined\");\n }\n if (tabsNode && tabListRef.current) {\n const children = tabListRef.current.children;\n\n if (children.length > 0) {\n const tab = children[value];\n\n tabMeta = tab ? tab.getBoundingClientRect() : null;\n\n if (indicatorContent) {\n // The label box of that same tab, found in the DOM like the tab itself.\n const content = tab ? tab.querySelector(\".smwb-tab__content\") : null;\n tabContentMeta = content ? content.getBoundingClientRect() : null;\n }\n }\n }\n return { tabsMeta, tabMeta, tabContentMeta };\n };\n\n const updateIndicatorState = useEventCallback(() => {\n const { tabsMeta, tabMeta, tabContentMeta } = getTabsMeta();\n let startValue = 0;\n\n if (tabMeta && tabsMeta) {\n startValue = 1 * (tabMeta.left - tabsMeta.left + tabsMeta.scrollLeft);\n }\n\n const newIndicatorStyle: IndicatorStyle = {\n root: {\n left: startValue,\n width: tabMeta ? tabMeta.width : 0,\n },\n };\n\n if (indicatorContent && tabContentMeta) {\n newIndicatorStyle.content = {\n width: tabContentMeta.width,\n };\n }\n\n if (isNaN(indicatorStyle.root.left) || isNaN(indicatorStyle.root.width)) {\n setIndicatorStyle(newIndicatorStyle);\n } else {\n const dStart = Math.abs(indicatorStyle.root.left - newIndicatorStyle.root.left);\n const dSize = Math.abs(indicatorStyle.root.width - newIndicatorStyle.root.width);\n\n if (dStart >= 1 || dSize >= 1) {\n setIndicatorStyle(newIndicatorStyle);\n }\n }\n });\n\n const scroll = (scrollValue: number, { animation = true } = {}) => {\n if (!tabsRef.current) {\n return;\n }\n if (animation) {\n animate(tabsRef.current, \"scrollLeft\", scrollValue, {\n duration: 300,\n });\n } else {\n tabsRef.current.scrollLeft = scrollValue;\n }\n };\n\n const updateOverflow = useEventCallback(() => {\n const node = tabsRef.current;\n const max = node ? node.scrollWidth - node.clientWidth : 0;\n const next: Overflow =\n node && scrollable\n ? { start: node.scrollLeft > 1, end: node.scrollLeft < max - 1 }\n : { start: false, end: false };\n setOverflow((prev) => (prev.start === next.start && prev.end === next.end ? prev : next));\n // Which tabs the viewport clips, measured the same way: the scroller is `position: relative`,\n // so a child's `offsetLeft` is its place in the row's content. Only the menu needs the list,\n // so nothing is measured without it. Kept by identity when unchanged, like `overflow` above,\n // because this runs after every render.\n const hidden =\n node && scrollable && overflowMenu\n ? getHiddenIndexes(\n Array.from(tabListRef.current?.children ?? []).map((child) => {\n const item = child as HTMLElement;\n return { offsetLeft: item.offsetLeft, offsetWidth: item.offsetWidth };\n }),\n node.scrollLeft,\n node.clientWidth\n )\n : [];\n setHiddenIndexes((prev) =>\n prev.length === hidden.length && prev.every((index, at) => index === hidden[at]) ? prev : hidden\n );\n });\n\n const scrollByPage = (direction: -1 | 1) => {\n const node = tabsRef.current;\n if (node) {\n scroll(node.scrollLeft + direction * node.clientWidth * SCROLL_PAGE);\n }\n };\n\n // Scroll the tab at `index` into the viewport, leaving a strip of the next one in view so the\n // row reads as scrollable. The one the overflow menu jumps to is named by index, not by `value`.\n const scrollIndexIntoView = useEventCallback((index: number, animation: boolean = true) => {\n const node = tabsRef.current;\n const tab = node && tabListRef.current ? (tabListRef.current.children[index] as HTMLElement | undefined) : null;\n if (!node || !tab) {\n return;\n }\n const tabsRect = node.getBoundingClientRect();\n const tabRect = tab.getBoundingClientRect();\n if (tabRect.left < tabsRect.left) {\n scroll(node.scrollLeft + (tabRect.left - tabsRect.left) - viewNextTabInPixels, { animation });\n } else if (tabRect.right > tabsRect.right) {\n scroll(node.scrollLeft + (tabRect.right - tabsRect.right) + viewNextTabInPixels, { animation });\n }\n });\n\n const scrollSelectedIntoView = useEventCallback((animation: boolean) => {\n const { tabsMeta, tabMeta } = getTabsMeta();\n\n if (!tabMeta || !tabsMeta) {\n return;\n }\n\n if (tabMeta.left < tabsMeta.left) {\n // Левая сторона таба не видна.\n const nextScrollStart = tabsMeta.scrollLeft + (tabMeta.left - tabsMeta.left);\n scroll(nextScrollStart - viewNextTabInPixels, { animation });\n } else if (tabMeta.right > tabsMeta.right) {\n // Правая сторона таба не видна.\n const nextScrollStart = tabsMeta.scrollLeft + (tabMeta.right - tabsMeta.right);\n scroll(nextScrollStart + viewNextTabInPixels, { animation });\n }\n });\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n React.useEffect(() => {\n updateIndicatorState();\n // Measured again after every render: tabs added, closed or reordered change what is clipped,\n // and the scroll and resize listeners below only answer their own events. Both setters keep\n // the previous array when nothing moved, so this cannot settle into a loop.\n updateOverflow();\n });\n\n React.useEffect(() => {\n const onResize = debounce(() => {\n if (tabsRef.current) {\n updateIndicatorState();\n updateOverflow();\n }\n }, 166);\n if (!tabsRef.current || !tabsRef.current.ownerDocument.defaultView) {\n console.error(`tabsRef.current.ownerDocument.defaultView is undefined`);\n return;\n }\n const window: Window & typeof globalThis = tabsRef.current.ownerDocument.defaultView;\n\n window.addEventListener(\"resize\", onResize);\n const scroller = tabsRef.current;\n scroller.addEventListener(\"scroll\", updateOverflow, { passive: true });\n\n let resizeObserver: ResizeObserver;\n\n // The row and each tab: a label can grow with its data while the row keeps\n // its width.\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(onResize);\n resizeObserver.observe(scroller);\n\n Array.from(tabListRef.current?.children ?? []).forEach((child) => {\n resizeObserver.observe(child);\n });\n }\n updateOverflow();\n\n return () => {\n onResize.cancel();\n\n window.removeEventListener(\"resize\", onResize);\n scroller.removeEventListener(\"scroll\", updateOverflow);\n\n if (resizeObserver) {\n resizeObserver.disconnect();\n }\n };\n }, [updateIndicatorState, updateOverflow]);\n\n React.useEffect(() => {\n // Не анимировать при первом рендере\n scrollSelectedIntoView(defaultIndicatorStyle !== indicatorStyle);\n }, [scrollSelectedIntoView, indicatorStyle]);\n\n // Only elements are tabs: a child left out, such as `{show && <Tab />}`, takes no\n // index, so `value` counts the tabs that render, as the indicator does in the DOM.\n const tabElements = React.Children.toArray(children).filter((child): child is React.ReactElement<TabProps> =>\n React.isValidElement(child)\n );\n const hasPanels = hasContent(panels);\n // A tab's own id is the one its panel is labelled by.\n const tabIds = tabElements.map((child, index) => child.props.id ?? `${baseId}-tab-${index}`);\n const tabIdsKey = tabIds.join(\"\\n\");\n const panelId = (index: number) => `${baseId}-panel-${index}`;\n // The selected tab is the stop; a value that points at no tab leaves the first one, and a\n // disabled one, which cannot take focus, leaves the first tab that can.\n const selectedStop = value >= 0 && value < tabElements.length ? value : 0;\n const firstEnabled = tabElements.findIndex((tab) => !isTabDisabled(tab));\n const fallbackStop = isTabDisabled(tabElements[selectedStop]) && firstEnabled >= 0 ? firstEnabled : selectedStop;\n const stopIndex = focusedIndex ?? fallbackStop;\n const tabs = tabElements.map((child, index) =>\n React.cloneElement(child, {\n isActive: value === index,\n tabStop: stopIndex === index,\n // The caller's own id and aria-controls win over the linked ones.\n id: tabIds[index],\n \"aria-controls\": child.props[\"aria-controls\"] ?? (hasPanels ? panelId(index) : undefined),\n // The tab's own onClose runs after the row notes which tab is closing.\n onClose: (event: React.SyntheticEvent<HTMLElement>, reason: TabCloseReason) => {\n requestClose(index, event, reason);\n },\n // Only a row that can be reordered makes its items draggable, and a disabled tab never. `Tab`\n // puts it on the item: the wrapper when the tab has a close button or actions, the tab itself\n // when it has neither, so the drag surface is the same element as in Solid.\n draggable: onReorder !== undefined && !isTabDisabled(child) ? true : undefined,\n // The tab's own onClick runs first, then the tab list picks the tab.\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n child.props.onClick?.(event);\n // A link tab opens elsewhere on a modified click: the browser's, not a selection here.\n if (child.props.href !== undefined && isModifiedClick(event)) {\n return;\n }\n onChange(event, index);\n },\n } as TabProps)\n );\n\n // The tabs in the DOM, by what they are: their indexes are the ones `value` counts.\n const getTabNodes = (): HTMLElement[] =>\n Array.from(tabListRef.current?.querySelectorAll<HTMLElement>('[role=\"tab\"]') ?? []);\n // A tab with a close button or actions sits in an item with them: focus on any of it is focus on the tab.\n const itemOf = (tab: HTMLElement): HTMLElement => tab.closest<HTMLElement>(\".smwb-tab-item\") ?? tab;\n const indexOfFocus = (target: Node | null): number =>\n target ? getTabNodes().findIndex((node) => itemOf(node).contains(target)) : -1;\n const isNodeDisabled = (node: HTMLElement | undefined): boolean =>\n !node || node.getAttribute(\"aria-disabled\") === \"true\" || (node as HTMLButtonElement).disabled === true;\n\n const noteClosing = (index: number, reason: TabCloseReason) => {\n const item = getTabNodes()[index];\n const active = item?.ownerDocument.activeElement;\n // Focus in the item is focus on the tab. A close from the tab's own `actions` is the user's\n // wherever focus is: it is in the menu then, which is drawn outside the row.\n const focused = reason === \"actions\" || Boolean(active && item && itemOf(item).contains(active));\n closingRef.current = item && focused ? { item: itemOf(item), index } : null;\n };\n\n // Ask the tab at `index` to close, as its close button, its Delete key or a middle press on it\n // would: the row notes which tab is going so focus can move on once it does, then the owner is\n // asked through that tab's own `onClose`. The Mod+W chord takes this same path.\n const requestClose = (index: number, event: React.SyntheticEvent<HTMLElement>, reason: TabCloseReason): void => {\n noteClosing(index, reason);\n tabElements[index]?.props.onClose?.(event, reason);\n };\n\n // Drag-to-reorder (with `onReorder`): the source and the drop target are tab items, tracked on\n // the row. Tabs only reports `onReorder(from, to)` and the moved tab's new index when that tab is\n // the selected one — the owner moves the tabs in its own state; focus is the row's only care.\n // The item is the drag surface, so any element inside it answers for it: a drag from a tab's close\n // button starts on that item and a drop on it lands there, as in Solid's `dragItemOf`.\n const dragItemOf = (target: EventTarget | null): HTMLElement | null =>\n target instanceof Element ? itemOf(target as HTMLElement) : null;\n\n const clearDragMarks = (): void => {\n draggingItemRef.current?.classList.remove(\"smwb-tab-item--dragging\");\n dropTargetItemRef.current?.classList.remove(\"smwb-tab-item--drop-target\");\n draggingItemRef.current = null;\n dropTargetItemRef.current = null;\n };\n\n const onItemDragStart = (event: React.DragEvent<HTMLDivElement>): void => {\n if (!onReorder) {\n return;\n }\n const item = dragItemOf(event.target);\n if (!item) {\n return;\n }\n const index = indexOfFocus(item);\n if (index < 0 || isNodeDisabled(getTabNodes()[index])) {\n return;\n }\n dragSourceRef.current = index;\n draggingItemRef.current = item;\n item.classList.add(\"smwb-tab-item--dragging\");\n // Firefox wants the drag given something to carry, or it never starts.\n if (event.dataTransfer) {\n event.dataTransfer.setData(\"text/plain\", String(index));\n event.dataTransfer.effectAllowed = \"move\";\n }\n };\n\n const onItemDragOver = (event: React.DragEvent<HTMLDivElement>): void => {\n if (!onReorder || dragSourceRef.current === null) {\n return;\n }\n const item = dragItemOf(event.target);\n if (!item) {\n return;\n }\n // Without this the browser allows no drop here.\n event.preventDefault();\n if (item === dropTargetItemRef.current) {\n return;\n }\n dropTargetItemRef.current?.classList.remove(\"smwb-tab-item--drop-target\");\n dropTargetItemRef.current = item;\n item.classList.add(\"smwb-tab-item--drop-target\");\n };\n\n const onItemDrop = (event: React.DragEvent<HTMLDivElement>): void => {\n const from = dragSourceRef.current;\n dragSourceRef.current = null;\n if (from === null) {\n return;\n }\n const to = indexOfFocus(dragItemOf(event.target));\n clearDragMarks();\n event.preventDefault();\n if (to >= 0 && to !== from) {\n onReorder?.(from, to);\n // The owner splices the tab it was told to move into `to`, so when that tab is the selected\n // one its index moves with it and the value would be left pointing at a neighbour: the row\n // reports the new index, as a keyboard choice does, and the owner's selection follows the\n // tab. Dragging any other tab leaves the selection where it is. A drag carries no click, so\n // only the index is carried over, as through the overflow menu.\n if (from === value) {\n onChange(event as unknown as React.MouseEvent<HTMLButtonElement>, to);\n }\n }\n };\n\n const onItemDragEnd = (): void => {\n dragSourceRef.current = null;\n clearDragMarks();\n };\n\n const onRovingKeyDown = useRovingTabIndex({\n count: tabElements.length,\n activeIndex: stopIndex,\n orientation,\n onMove: (next) => getTabNodes()[next]?.focus(),\n isDisabled: (index) => isNodeDisabled(getTabNodes()[index]),\n });\n\n // Select the enabled tab `delta` places from the focused one, wrapping at the ends and skipping\n // disabled tabs: as Enter or Space would, through a click synthesized on the tab, so `onChange`\n // is called for it on the same contract as a pointer choice.\n const switchByChord = (target: EventTarget | null, delta: -1 | 1): void => {\n const nodes = getTabNodes();\n const from = indexOfFocus(target as Node | null);\n if (from < 0 || nodes.length === 0) {\n return;\n }\n for (let step = 1; step <= nodes.length; step += 1) {\n const node = nodes[(from + delta * step + nodes.length) % nodes.length];\n if (node && !isNodeDisabled(node)) {\n node.focus();\n node.click();\n return;\n }\n }\n };\n\n const onTabListKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n // The tabs' chords, ahead of the \"chords belong to the browser\" guard below. They are\n // best-effort: a browser of its own tabs reserves Mod+W and Mod+Shift+[/], and they bite only\n // in an embedded webview. Focus has to be on a tab for any of them.\n if ((event.ctrlKey || event.metaKey) && !event.altKey && !event.defaultPrevented) {\n const focused = indexOfFocus(event.target as Node | null);\n if (focused < 0) {\n return;\n }\n if (matchesKeyboardShortcut(event, [\"Mod\", \"W\"])) {\n const tab = tabElements[focused];\n if (tab?.props.closable && !isTabDisabled(tab)) {\n event.preventDefault();\n requestClose(focused, event, \"key\");\n }\n return;\n }\n if (matchesKeyboardShortcut(event, [\"Mod\", \"Shift\", \"[\"])) {\n event.preventDefault();\n switchByChord(event.target, -1);\n return;\n }\n if (matchesKeyboardShortcut(event, [\"Mod\", \"Shift\", \"]\"])) {\n event.preventDefault();\n switchByChord(event.target, 1);\n return;\n }\n }\n // Chords belong to the browser; a handler that took the key first keeps it.\n if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) {\n return;\n }\n if (!(event.target as Element).closest('[role=\"tab\"]')) {\n return;\n }\n onRovingKeyDown(event);\n };\n\n // Focus can leave the row without a blur: the focused tab is removed, and the browser moves\n // focus to the body. The row keeps the focused tab as its stop only while focus is in it, on\n // the tab that has it now (tabs before it may have come or gone).\n useSafeLayoutEffect(() => {\n const doc = tabListRef.current?.ownerDocument;\n const closing = closingRef.current;\n if (doc && closing && !closing.item.isConnected) {\n closingRef.current = null;\n // A tab the user closed took the focus with it: the tab that takes its place gets it (the\n // previous one if it was last), the nearest that is not disabled. Focus that went anywhere\n // else meanwhile stays there.\n if (!doc.activeElement || doc.activeElement === doc.body) {\n const nodes = getTabNodes();\n const from = Math.min(closing.index, nodes.length - 1);\n const candidates = [...nodes.keys()].filter((index) => !isNodeDisabled(nodes[index]));\n const target = candidates.find((index) => index >= from) ?? candidates[candidates.length - 1];\n if (target !== undefined) {\n nodes[target]?.focus();\n setFocusedIndex(target);\n return;\n }\n }\n }\n if (focusedIndex === null) {\n return;\n }\n const index = indexOfFocus(doc?.activeElement ?? null);\n const next = index >= 0 ? index : null;\n if (next !== focusedIndex) {\n setFocusedIndex(next);\n }\n });\n\n const onTabListFocus = (event: React.FocusEvent<HTMLDivElement>) => {\n const index = indexOfFocus(event.target);\n if (index >= 0) {\n setFocusedIndex(index);\n }\n if (closingRef.current && !closingRef.current.item.contains(event.target)) {\n closingRef.current = null;\n }\n };\n\n const onTabListBlur = (event: React.FocusEvent<HTMLDivElement>) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n setFocusedIndex(null);\n closingRef.current = null;\n }\n };\n\n const contextValue = React.useMemo<TabsContextValue>(\n () => ({ value, tabId: (index: number) => tabIds[index] ?? `${baseId}-tab-${index}`, panelId }),\n // tabIds is rebuilt each render and panelId only reads baseId: tabIdsKey stands for them.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [value, baseId, tabIdsKey]\n );\n\n const showScrollButtons = scrollable && scrollButtons && (overflow.start || overflow.end);\n // The overflow menu's trigger appears only once the browser has measured a clipped tab, so the\n // server markup — and the first client render — shows none.\n const showOverflowTrigger = scrollable && overflowMenu && hiddenIndexes.length > 0;\n\n // Choosing an entry selects that tab and brings it into view; the menu closes either way.\n const chooseOverflowItem = (event: React.MouseEvent<HTMLLIElement>, index: number): void => {\n setOverflowOpen(false);\n // The row's contract names a click on the tab; a menu item is an `li`, so only its index is\n // carried over.\n onChange(event as unknown as React.MouseEvent<HTMLButtonElement>, index);\n scrollIndexIntoView(index);\n };\n\n return (\n <TabsContext.Provider value={contextValue}>\n <div\n id={idProp}\n className={cn(\n \"smwb-tabs\",\n {\n \"smwb-tabs--dense\": dense,\n \"smwb-tabs--overflow-start\": overflow.start,\n \"smwb-tabs--overflow-end\": overflow.end,\n },\n className\n )}\n ref={ref}\n {...rest}\n >\n {showScrollButtons && (\n <button\n type=\"button\"\n className=\"smwb-tabs__scroll-button smwb-tabs__scroll-button--start\"\n aria-label={scrollBackAriaLabel}\n disabled={!overflow.start}\n tabIndex={-1}\n onClick={() => scrollByPage(-1)}\n >\n <Icon name=\"chevron_left\" size={20} />\n </button>\n )}\n <div\n className={cn(\"smwb-tabs__scroller\", {\n \"smwb-tabs__scroller--scrollable\": scrollable,\n })}\n ref={tabsRef}\n >\n <div\n className=\"smwb-tabs__scroll-area\"\n ref={tabListRef}\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-orientation={orientation}\n onKeyDown={onTabListKeyDown}\n onFocus={onTabListFocus}\n onBlur={onTabListBlur}\n onDragStart={onItemDragStart}\n onDragOver={onItemDragOver}\n onDrop={onItemDrop}\n onDragEnd={onItemDragEnd}\n >\n {tabs}\n </div>\n {mounted && (\n <span className=\"smwb-tabs__indicator\" style={indicatorStyle.root}>\n <span className=\"smwb-tabs__indicator-content\" style={indicatorStyle.content} />\n </span>\n )}\n </div>\n {showScrollButtons && (\n <button\n type=\"button\"\n className=\"smwb-tabs__scroll-button smwb-tabs__scroll-button--end\"\n aria-label={scrollForwardAriaLabel}\n disabled={!overflow.end}\n tabIndex={-1}\n onClick={() => scrollByPage(1)}\n >\n <Icon name=\"chevron_right\" size={20} />\n </button>\n )}\n {showOverflowTrigger && (\n <>\n <button\n type=\"button\"\n className=\"smwb-tabs__overflow-trigger\"\n aria-haspopup=\"menu\"\n aria-expanded={overflowOpen}\n aria-label={overflowMenuAriaLabel}\n // For the pointer, like the scroll buttons: the arrow keys reach every tab.\n tabIndex={-1}\n ref={setOverflowTrigger}\n onClick={() => setOverflowOpen((open) => !open)}\n >\n <Icon name=\"more_horiz\" size={20} />\n </button>\n <Menu\n anchorElement={overflowTrigger}\n isOpen={overflowOpen}\n onClose={() => setOverflowOpen(false)}\n placement=\"bottom-end\"\n >\n {hiddenIndexes.map((index) => {\n const tab = tabElements[index];\n return (\n <MenuItem\n key={index}\n disabled={isTabDisabled(tab)}\n aria-current={index === value ? \"true\" : undefined}\n onClick={(event) => chooseOverflowItem(event, index)}\n >\n {tab?.props.icon && (\n <span className=\"smwb-tab__icon\" aria-hidden=\"true\">\n {tab.props.icon}\n </span>\n )}\n {tab?.props.label && <span className=\"smwb-tab__text-label\">{tab.props.label}</span>}\n </MenuItem>\n );\n })}\n </Menu>\n </>\n )}\n </div>\n {panels}\n </TabsContext.Provider>\n );\n});\n\nexport { Tab, TabPanel };\nexport type { TabProps, TabPanelProps, TabActionsApi, TabCloseReason };\n"],"names":["defaultIndicatorStyle","SCROLL_PAGE","isModifiedClick","event","hasContent","node","React","child","isTabDisabled","tab","Tabs","props","ref","className","children","onChange","value","indicatorContent","scrollable","scrollButtons","onReorder","overflowMenu","overflowMenuAriaLabel","dense","orientation","panels","idProp","scrollBackAriaLabel","scrollForwardAriaLabel","ariaLabel","rest","mounted","setMounted","indicatorStyle","setIndicatorStyle","overflow","setOverflow","hiddenIndexes","setHiddenIndexes","overflowOpen","setOverflowOpen","overflowTrigger","setOverflowTrigger","generatedId","baseId","focusedIndex","setFocusedIndex","tabsRef","tabListRef","closingRef","dragSourceRef","draggingItemRef","dropTargetItemRef","viewNextTabInPixels","getTabsMeta","tabsNode","tabsMeta","rect","tabMeta","tabContentMeta","content","updateIndicatorState","useEventCallback","startValue","newIndicatorStyle","dStart","dSize","scroll","scrollValue","animation","animate","updateOverflow","max","next","prev","hidden","getHiddenIndexes","_b","_a","item","index","at","scrollByPage","direction","scrollIndexIntoView","tabsRect","tabRect","scrollSelectedIntoView","nextScrollStart","onResize","debounce","window","scroller","resizeObserver","tabElements","hasPanels","tabIds","tabIdsKey","panelId","selectedStop","firstEnabled","fallbackStop","stopIndex","tabs","reason","requestClose","getTabNodes","itemOf","indexOfFocus","target","isNodeDisabled","noteClosing","active","focused","_c","dragItemOf","clearDragMarks","onItemDragStart","onItemDragOver","onItemDrop","from","to","onItemDragEnd","onRovingKeyDown","useRovingTabIndex","switchByChord","delta","nodes","step","onTabListKeyDown","matchesKeyboardShortcut","useSafeLayoutEffect","doc","closing","candidates","_d","onTabListFocus","onTabListBlur","contextValue","showScrollButtons","showOverflowTrigger","chooseOverflowItem","jsxs","TabsContext","cn","jsx","Icon","Fragment","open","Menu","MenuItem"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure geometry helpers for the tab row's overflow measurement. The hidden-tab math lives
|
|
3
|
+
* here, without a DOM, so it is testable in jsdom, which has no layout: tests feed mocked
|
|
4
|
+
* measurements straight in.
|
|
5
|
+
*/
|
|
6
|
+
/** What `getHiddenIndexes` needs to know of one tab's place in the row. */
|
|
7
|
+
export interface TabMeasureEntry {
|
|
8
|
+
/** The tab's left edge in the row's content: where it sits when nothing is scrolled. */
|
|
9
|
+
offsetLeft: number;
|
|
10
|
+
/** The tab's width. */
|
|
11
|
+
offsetWidth: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The indexes of the tabs that the scroller's viewport clips — *any* clipped part counts,
|
|
15
|
+
* so a tab that is only half visible is listed too. `entries` are the tabs in row order,
|
|
16
|
+
* each in content coordinates; the viewport is `[scrollLeft, scrollLeft + clientWidth]`.
|
|
17
|
+
* A pixel of tolerance keeps a tab flush with the edge from flickering while the row
|
|
18
|
+
* scrolls in fractional steps.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getHiddenIndexes(entries: TabMeasureEntry[], scrollLeft: number, clientWidth: number): number[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function r(o, e, n) {
|
|
2
|
+
const s = e, c = e + n, f = [];
|
|
3
|
+
return o.forEach((t, d) => {
|
|
4
|
+
const i = t.offsetLeft < s - 1, p = t.offsetLeft + t.offsetWidth > c + 1;
|
|
5
|
+
(i || p) && f.push(d);
|
|
6
|
+
}), f;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
r as getHiddenIndexes
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=tabs.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.utils.js","sources":["../../../../src/components/navigation/tabs/tabs.utils.ts"],"sourcesContent":["/**\n * Pure geometry helpers for the tab row's overflow measurement. The hidden-tab math lives\n * here, without a DOM, so it is testable in jsdom, which has no layout: tests feed mocked\n * measurements straight in.\n */\n\n/** What `getHiddenIndexes` needs to know of one tab's place in the row. */\nexport interface TabMeasureEntry {\n /** The tab's left edge in the row's content: where it sits when nothing is scrolled. */\n offsetLeft: number;\n /** The tab's width. */\n offsetWidth: number;\n}\n\n/**\n * The indexes of the tabs that the scroller's viewport clips — *any* clipped part counts,\n * so a tab that is only half visible is listed too. `entries` are the tabs in row order,\n * each in content coordinates; the viewport is `[scrollLeft, scrollLeft + clientWidth]`.\n * A pixel of tolerance keeps a tab flush with the edge from flickering while the row\n * scrolls in fractional steps.\n */\nexport function getHiddenIndexes(entries: TabMeasureEntry[], scrollLeft: number, clientWidth: number): number[] {\n const EPSILON = 1;\n const start = scrollLeft;\n const end = scrollLeft + clientWidth;\n const hidden: number[] = [];\n entries.forEach((entry, index) => {\n const clippedBefore = entry.offsetLeft < start - EPSILON;\n const clippedAfter = entry.offsetLeft + entry.offsetWidth > end + EPSILON;\n if (clippedBefore || clippedAfter) {\n hidden.push(index);\n }\n });\n return hidden;\n}\n"],"names":["getHiddenIndexes","entries","scrollLeft","clientWidth","start","end","hidden","entry","index","clippedBefore","clippedAfter"],"mappings":"AAqBO,SAASA,EAAiBC,GAA4BC,GAAoBC,GAA+B;AAE9G,QAAMC,IAAQF,GACRG,IAAMH,IAAaC,GACnBG,IAAmB,CAAA;AACzB,SAAAL,EAAQ,QAAQ,CAACM,GAAOC,MAAU;AAChC,UAAMC,IAAgBF,EAAM,aAAaH,IAAQ,GAC3CM,IAAeH,EAAM,aAAaA,EAAM,cAAcF,IAAM;AAClE,KAAII,KAAiBC,MACnBJ,EAAO,KAAKE,CAAK;AAAA,EAErB,CAAC,GACMF;AACT;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/** What a TabPanel reads from the Tabs that renders it. */
|
|
3
|
+
export interface TabsContextValue {
|
|
4
|
+
/** Index of the selected tab. */
|
|
5
|
+
value: number;
|
|
6
|
+
/** The id of the tab at `index`: the one the panel at that index is labelled by. */
|
|
7
|
+
tabId: (index: number) => string;
|
|
8
|
+
/** The id of the panel at `index`: the one the tab at that index controls. */
|
|
9
|
+
panelId: (index: number) => string;
|
|
10
|
+
}
|
|
11
|
+
export declare const TabsContext: React.Context<TabsContextValue | null>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabsContext.js","sources":["../../../../src/components/navigation/tabs/tabsContext.ts"],"sourcesContent":["import React from \"react\";\n\n/** What a TabPanel reads from the Tabs that renders it. */\nexport interface TabsContextValue {\n /** Index of the selected tab. */\n value: number;\n /** The id of the tab at `index`: the one the panel at that index is labelled by. */\n tabId: (index: number) => string;\n /** The id of the panel at `index`: the one the tab at that index controls. */\n panelId: (index: number) => string;\n}\n\nexport const TabsContext = React.createContext<TabsContextValue | null>(null);\n"],"names":["TabsContext","React"],"mappings":";AAYO,MAAMA,IAAcC,EAAM,cAAuC,IAAI;"}
|
|
@@ -1,174 +1,203 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useMemo as
|
|
3
|
-
import
|
|
4
|
-
import { FloatingButton as
|
|
5
|
-
import { Icon as
|
|
6
|
-
import { useControllableState as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
import { jsx as e, jsxs as D, Fragment as Ht } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo as Vt, useId as jt } from "react";
|
|
3
|
+
import K from "clsx";
|
|
4
|
+
import { FloatingButton as kt } from "../../inputs/floatingButton/floatingButton.js";
|
|
5
|
+
import { Icon as Dt } from "../../base/icon/icon.js";
|
|
6
|
+
import { useControllableState as M } from "../../../hooks/useControllableState.js";
|
|
7
|
+
import { Composer as Kt } from "../../inputs/composer/composer.js";
|
|
8
|
+
import { ChatComposer as Mt } from "./chatComposer.js";
|
|
9
|
+
import { ChatHeader as Rt } from "./chatHeader.js";
|
|
10
|
+
import { ChatMessages as St } from "./chatMessages.js";
|
|
11
|
+
import { ChatShell as ot } from "./chatShell.js";
|
|
12
|
+
import At from "./useChatFileUpload.js";
|
|
13
|
+
import { CHAT_EXPAND_LAYOUTS as Tt } from "./types.js";
|
|
14
|
+
import { resolveAllowedLayouts as Xt, pickInitialLayout as R, shouldShowChatCloseButton as Yt } from "./utils.js";
|
|
15
|
+
function la({
|
|
16
|
+
className: S,
|
|
17
|
+
messages: o,
|
|
18
|
+
showAvatars: A = !1,
|
|
19
|
+
showAttachments: T = !1,
|
|
20
|
+
headerTitle: X,
|
|
21
|
+
headerSubtitle: Y,
|
|
22
|
+
headerActions: $,
|
|
23
|
+
footer: c,
|
|
24
|
+
children: q,
|
|
25
|
+
anchor: w = "bottom-right",
|
|
26
|
+
themeMode: G = "inherit",
|
|
27
|
+
allowedLayouts: h,
|
|
28
|
+
layout: J,
|
|
29
|
+
defaultLayout: x,
|
|
30
|
+
onLayoutChange: Q,
|
|
31
|
+
open: W,
|
|
32
|
+
defaultOpen: Z = !1,
|
|
33
|
+
onOpenChange: L,
|
|
34
|
+
floatingTrigger: C = !1,
|
|
35
|
+
triggerIcon: m,
|
|
36
|
+
triggerLabel: v,
|
|
37
|
+
onLoadMore: g,
|
|
38
|
+
hasMore: U,
|
|
39
|
+
onSendMessage: n,
|
|
40
|
+
busy: r,
|
|
41
|
+
onStop: p,
|
|
42
|
+
composerProps: t,
|
|
43
|
+
legacyComposer: P = !1,
|
|
44
|
+
composerPlaceholder: O = "message",
|
|
45
|
+
composerDisabled: y,
|
|
46
|
+
composerShiftEnterNewline: tt = !0,
|
|
47
|
+
composerCtrlEnterNewline: at = !0,
|
|
48
|
+
fileUpload: et = !1,
|
|
49
|
+
onUploadFiles: u,
|
|
50
|
+
fileUploadAccept: B,
|
|
51
|
+
fileUploadMaxFiles: lt,
|
|
52
|
+
attachAriaLabel: d,
|
|
53
|
+
loading: nt,
|
|
54
|
+
loadingMore: it,
|
|
55
|
+
loadingSkeletonCount: ht,
|
|
56
|
+
renderMessage: ut,
|
|
57
|
+
embedded: l = !1,
|
|
58
|
+
overlayContext: b = !1,
|
|
59
|
+
showStatus: dt = !1,
|
|
60
|
+
statusIcons: ft,
|
|
61
|
+
renderStatus: st,
|
|
62
|
+
showCloseButton: ct
|
|
58
63
|
}) {
|
|
59
|
-
var
|
|
60
|
-
const
|
|
61
|
-
() =>
|
|
62
|
-
[
|
|
63
|
-
), [
|
|
64
|
-
value:
|
|
65
|
-
defaultValue:
|
|
66
|
-
onChange:
|
|
67
|
-
}), [
|
|
68
|
-
value:
|
|
69
|
-
defaultValue:
|
|
70
|
-
onChange:
|
|
71
|
-
}),
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
},
|
|
76
|
-
|
|
64
|
+
var H, V, j, k;
|
|
65
|
+
const N = Vt(
|
|
66
|
+
() => Xt(h != null ? h : Tt),
|
|
67
|
+
[h]
|
|
68
|
+
), [I, _] = M({
|
|
69
|
+
value: W,
|
|
70
|
+
defaultValue: Z,
|
|
71
|
+
onChange: L
|
|
72
|
+
}), [f, E] = M({
|
|
73
|
+
value: J,
|
|
74
|
+
defaultValue: R(N, x),
|
|
75
|
+
onChange: Q
|
|
76
|
+
}), s = l ? "fullHeight" : C ? I ? f : "closed" : f, Ct = () => {
|
|
77
|
+
_(!0), f === "closed" && E(R(N, x));
|
|
78
|
+
}, mt = () => {
|
|
79
|
+
_(!1);
|
|
80
|
+
}, vt = (i) => {
|
|
81
|
+
_(!0), E(i);
|
|
77
82
|
}, {
|
|
78
|
-
enabled:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
enabled: a,
|
|
84
|
+
maxFiles: z,
|
|
85
|
+
getRootProps: yt,
|
|
86
|
+
getInputProps: bt,
|
|
87
|
+
isDragActive: Nt
|
|
88
|
+
} = At({
|
|
89
|
+
enabled: et,
|
|
90
|
+
accept: B,
|
|
91
|
+
maxFiles: lt,
|
|
92
|
+
onUploadFiles: u,
|
|
93
|
+
disabled: y
|
|
94
|
+
}), F = jt(), _t = !!n || a, wt = P || a && !n, xt = a ? /* @__PURE__ */ e("input", { ...bt({ id: F }), "data-testid": "chat-file-input" }) : null, Ot = /* @__PURE__ */ D(Ht, { children: [
|
|
95
|
+
xt,
|
|
96
|
+
/* @__PURE__ */ e(
|
|
97
|
+
Mt,
|
|
92
98
|
{
|
|
93
|
-
onSendMessage:
|
|
94
|
-
placeholder:
|
|
95
|
-
disabled:
|
|
96
|
-
shiftEnterNewline:
|
|
97
|
-
ctrlEnterNewline:
|
|
98
|
-
fileUpload:
|
|
99
|
-
attachInputId:
|
|
100
|
-
attachAriaLabel:
|
|
99
|
+
onSendMessage: n,
|
|
100
|
+
placeholder: O,
|
|
101
|
+
disabled: y,
|
|
102
|
+
shiftEnterNewline: tt,
|
|
103
|
+
ctrlEnterNewline: at,
|
|
104
|
+
fileUpload: a,
|
|
105
|
+
attachInputId: a ? F : void 0,
|
|
106
|
+
attachAriaLabel: d
|
|
101
107
|
}
|
|
102
108
|
)
|
|
103
|
-
] })
|
|
104
|
-
|
|
109
|
+
] }), Bt = /* @__PURE__ */ e(
|
|
110
|
+
Kt,
|
|
105
111
|
{
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
...t,
|
|
113
|
+
className: K("smwb-chat__composer", t == null ? void 0 : t.className),
|
|
114
|
+
sendKey: (H = t == null ? void 0 : t.sendKey) != null ? H : "enter",
|
|
115
|
+
"aria-label": (V = t == null ? void 0 : t["aria-label"]) != null ? V : t != null && t["aria-labelledby"] ? void 0 : "Message",
|
|
116
|
+
sendLabel: (j = t == null ? void 0 : t.sendLabel) != null ? j : "Send message",
|
|
117
|
+
attachLabel: d != null ? d : t == null ? void 0 : t.attachLabel,
|
|
118
|
+
placeholder: O,
|
|
119
|
+
disabled: y,
|
|
120
|
+
busy: r,
|
|
121
|
+
onStop: p,
|
|
122
|
+
onSend: n ? (i) => void n(i) : void 0,
|
|
123
|
+
...a ? {
|
|
124
|
+
onAttach: (i) => void (u == null ? void 0 : u(i)),
|
|
125
|
+
accept: B,
|
|
126
|
+
maxFiles: z,
|
|
127
|
+
multiple: z > 1,
|
|
128
|
+
// The shell is the drop target: a drop here has to reach it, not be handled twice.
|
|
129
|
+
dropTarget: !1
|
|
130
|
+
} : {}
|
|
118
131
|
}
|
|
119
|
-
),
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
132
|
+
), It = (k = c != null ? c : q) != null ? k : _t ? wt ? Ot : Bt : void 0, Et = /* @__PURE__ */ e(
|
|
133
|
+
St,
|
|
134
|
+
{
|
|
135
|
+
messages: o,
|
|
136
|
+
showAvatars: A,
|
|
137
|
+
showAttachments: T,
|
|
138
|
+
showStatus: dt,
|
|
139
|
+
statusIcons: ft,
|
|
140
|
+
renderStatus: st,
|
|
141
|
+
onLoadMore: g,
|
|
142
|
+
hasMore: U,
|
|
143
|
+
loading: nt,
|
|
144
|
+
loadingMore: it,
|
|
145
|
+
loadingSkeletonCount: ht,
|
|
146
|
+
renderMessage: ut
|
|
147
|
+
}
|
|
148
|
+
), zt = a ? yt() : void 0, Ft = Yt({
|
|
149
|
+
floatingTrigger: C,
|
|
150
|
+
embedded: l,
|
|
151
|
+
overlayContext: b,
|
|
152
|
+
effectiveLayout: s,
|
|
153
|
+
showCloseButton: ct
|
|
125
154
|
});
|
|
126
|
-
return /* @__PURE__ */
|
|
155
|
+
return /* @__PURE__ */ D(
|
|
127
156
|
"div",
|
|
128
157
|
{
|
|
129
|
-
className:
|
|
158
|
+
className: K(
|
|
130
159
|
"smwb-chat",
|
|
131
|
-
!
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
160
|
+
!l && `smwb-chat_${w}`,
|
|
161
|
+
l && "smwb-chat_embedded",
|
|
162
|
+
b && "smwb-chat_overlay-context",
|
|
163
|
+
S
|
|
135
164
|
),
|
|
136
165
|
"data-testid": "chat",
|
|
137
166
|
children: [
|
|
138
|
-
|
|
139
|
-
|
|
167
|
+
C && !l && !I ? /* @__PURE__ */ e(
|
|
168
|
+
kt,
|
|
140
169
|
{
|
|
141
170
|
className: "smwb-chat__trigger",
|
|
142
|
-
"aria-label":
|
|
171
|
+
"aria-label": v != null ? v : "Open chat",
|
|
143
172
|
"data-testid": "chat-trigger",
|
|
144
|
-
onClick:
|
|
145
|
-
children:
|
|
173
|
+
onClick: Ct,
|
|
174
|
+
children: m != null ? m : /* @__PURE__ */ e(Dt, { name: "chat", size: 24 })
|
|
146
175
|
}
|
|
147
176
|
) : null,
|
|
148
|
-
/* @__PURE__ */
|
|
149
|
-
|
|
177
|
+
/* @__PURE__ */ e(
|
|
178
|
+
ot,
|
|
150
179
|
{
|
|
151
|
-
layout:
|
|
152
|
-
anchor:
|
|
153
|
-
themeMode:
|
|
154
|
-
embedded:
|
|
155
|
-
overlayContext:
|
|
156
|
-
fileDropzoneRootProps:
|
|
157
|
-
fileDropzoneActive:
|
|
158
|
-
header: /* @__PURE__ */
|
|
159
|
-
|
|
180
|
+
layout: s,
|
|
181
|
+
anchor: w,
|
|
182
|
+
themeMode: G,
|
|
183
|
+
embedded: l,
|
|
184
|
+
overlayContext: b,
|
|
185
|
+
fileDropzoneRootProps: zt,
|
|
186
|
+
fileDropzoneActive: a && Nt,
|
|
187
|
+
header: /* @__PURE__ */ e(
|
|
188
|
+
Rt,
|
|
160
189
|
{
|
|
161
|
-
title:
|
|
162
|
-
subtitle:
|
|
163
|
-
actions:
|
|
164
|
-
layout:
|
|
165
|
-
allowedLayouts:
|
|
166
|
-
onLayoutChange:
|
|
167
|
-
onClose:
|
|
190
|
+
title: X,
|
|
191
|
+
subtitle: Y,
|
|
192
|
+
actions: $,
|
|
193
|
+
layout: s === "closed" ? f : s,
|
|
194
|
+
allowedLayouts: N,
|
|
195
|
+
onLayoutChange: vt,
|
|
196
|
+
onClose: Ft ? mt : void 0
|
|
168
197
|
}
|
|
169
198
|
),
|
|
170
|
-
footer:
|
|
171
|
-
children:
|
|
199
|
+
footer: It,
|
|
200
|
+
children: Et
|
|
172
201
|
}
|
|
173
202
|
)
|
|
174
203
|
]
|
|
@@ -176,7 +205,7 @@ function qt({
|
|
|
176
205
|
);
|
|
177
206
|
}
|
|
178
207
|
export {
|
|
179
|
-
|
|
180
|
-
|
|
208
|
+
la as Chat,
|
|
209
|
+
la as default
|
|
181
210
|
};
|
|
182
211
|
//# sourceMappingURL=chat.js.map
|