@smwb/ui-solid 0.13.0 → 0.14.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/README.md +564 -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/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 +42 -0
- package/dist/components/dataDisplay/chat/chat.js +116 -57
- 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 +21 -19
- 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/dagView.js +238 -223
- package/dist/components/dataDisplay/dagView/dagView.js.map +1 -1
- package/dist/components/dataDisplay/diffStat/diffStat.d.ts +55 -0
- package/dist/components/dataDisplay/diffStat/diffStat.js +70 -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 +41 -0
- package/dist/components/dataDisplay/kbd/kbd.js +47 -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 +70 -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 +57 -20
- 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 +30 -0
- package/dist/components/dataDisplay/qrCode/qrCode.js +88 -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 +31 -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 +75 -0
- package/dist/components/dataDisplay/swimlanes/swimlanes.js +361 -0
- package/dist/components/dataDisplay/swimlanes/swimlanes.js.map +1 -0
- package/dist/components/dataDisplay/treeView/treeView.d.ts +20 -0
- package/dist/components/dataDisplay/treeView/treeView.js +161 -95
- package/dist/components/dataDisplay/treeView/treeView.js.map +1 -1
- package/dist/components/feedBack/modal/modal.d.ts +9 -0
- package/dist/components/feedBack/modal/modal.js +68 -54
- package/dist/components/feedBack/modal/modal.js.map +1 -1
- package/dist/components/inputs/button/button.d.ts +12 -0
- package/dist/components/inputs/button/button.js +44 -37
- package/dist/components/inputs/button/button.js.map +1 -1
- package/dist/components/inputs/composer/composer.d.ts +148 -0
- package/dist/components/inputs/composer/composer.js +276 -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 +18 -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 +100 -86
- 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 +102 -0
- package/dist/components/layout/tabGroups/tabGroups.js +895 -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 +192 -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 +480 -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 +60 -22
- package/dist/components/navigation/appBar/appBar.js.map +1 -1
- package/dist/components/navigation/commandPalette/commandPalette.d.ts +126 -0
- package/dist/components/navigation/commandPalette/commandPalette.js +457 -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 +15 -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 +6 -0
- package/dist/components/navigation/sidebar/sidebar.d.ts +10 -0
- package/dist/components/navigation/sidebar/sidebar.js +12 -10
- 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 +89 -2
- package/dist/components/navigation/tabs/tab/tab.js +164 -44
- package/dist/components/navigation/tabs/tab/tab.js.map +1 -1
- package/dist/components/navigation/tabs/tabPanel/tabPanel.d.ts +20 -0
- package/dist/components/navigation/tabs/tabPanel/tabPanel.js +34 -0
- package/dist/components/navigation/tabs/tabPanel/tabPanel.js.map +1 -0
- package/dist/components/navigation/tabs/tabs.d.ts +73 -3
- package/dist/components/navigation/tabs/tabs.js +387 -160
- 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 +31 -1
- package/dist/components/navigation/tabs/tabsContext.js.map +1 -1
- package/dist/headless/components/dataDisplay/chat/chat.js +116 -57
- package/dist/headless/components/dataDisplay/chat/chat.js.map +1 -1
- package/dist/headless/components/dataDisplay/chat/chatComposer.js +21 -19
- 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/dagView.js +238 -223
- package/dist/headless/components/dataDisplay/dagView/dagView.js.map +1 -1
- package/dist/headless/components/dataDisplay/diffStat/diffStat.js +68 -0
- package/dist/headless/components/dataDisplay/diffStat/diffStat.js.map +1 -0
- package/dist/headless/components/dataDisplay/kbd/kbd.js +45 -0
- package/dist/headless/components/dataDisplay/kbd/kbd.js.map +1 -0
- package/dist/headless/components/dataDisplay/kbd/kbdKeys.js +70 -0
- package/dist/headless/components/dataDisplay/kbd/kbdKeys.js.map +1 -0
- package/dist/headless/components/dataDisplay/list/listItem.js +57 -20
- package/dist/headless/components/dataDisplay/list/listItem.js.map +1 -1
- package/dist/headless/components/dataDisplay/qrCode/qrCode.js +86 -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 +29 -0
- package/dist/headless/components/dataDisplay/statusDot/statusDot.js.map +1 -0
- package/dist/headless/components/dataDisplay/swimlanes/swimlanes.js +359 -0
- package/dist/headless/components/dataDisplay/swimlanes/swimlanes.js.map +1 -0
- package/dist/headless/components/dataDisplay/treeView/treeView.js +161 -95
- package/dist/headless/components/dataDisplay/treeView/treeView.js.map +1 -1
- package/dist/headless/components/feedBack/modal/modal.js +68 -54
- package/dist/headless/components/feedBack/modal/modal.js.map +1 -1
- package/dist/headless/components/inputs/button/button.js +42 -35
- package/dist/headless/components/inputs/button/button.js.map +1 -1
- package/dist/headless/components/inputs/composer/composer.js +274 -0
- package/dist/headless/components/inputs/composer/composer.js.map +1 -0
- package/dist/headless/components/inputs/composer/composerFiles.js +18 -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 +100 -86
- package/dist/headless/components/layout/sheet/sheet.js.map +1 -1
- package/dist/headless/components/layout/tabGroups/tabGroups.js +893 -0
- package/dist/headless/components/layout/tabGroups/tabGroups.js.map +1 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsFocus.js +192 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsFocus.js.map +1 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsLayout.js +480 -0
- package/dist/headless/components/layout/tabGroups/tabGroupsLayout.js.map +1 -0
- package/dist/headless/components/navigation/appBar/appBar.js +64 -26
- package/dist/headless/components/navigation/appBar/appBar.js.map +1 -1
- package/dist/headless/components/navigation/commandPalette/commandPalette.js +455 -0
- package/dist/headless/components/navigation/commandPalette/commandPalette.js.map +1 -0
- package/dist/headless/components/navigation/commandPalette/commandPaletteFilter.js +15 -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 +28 -26
- package/dist/headless/components/navigation/sidebar/sidebar.js.map +1 -1
- package/dist/headless/components/navigation/tabs/tab/tab.js +164 -44
- package/dist/headless/components/navigation/tabs/tab/tab.js.map +1 -1
- package/dist/headless/components/navigation/tabs/tabPanel/tabPanel.js +32 -0
- package/dist/headless/components/navigation/tabs/tabPanel/tabPanel.js.map +1 -0
- package/dist/headless/components/navigation/tabs/tabs.js +387 -160
- 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.map +1 -1
- package/dist/headless/index.js +405 -367
- package/dist/headless/index.js.map +1 -1
- package/dist/headless/primitives/createFocusTrap.js +17 -17
- package/dist/headless/primitives/createFocusTrap.js.map +1 -1
- package/dist/headless/primitives/createKeyboardShortcut.js +16 -0
- package/dist/headless/primitives/createKeyboardShortcut.js.map +1 -0
- package/dist/headless/primitives/restoreFocus.js +10 -0
- package/dist/headless/primitives/restoreFocus.js.map +1 -0
- package/dist/headless/source/components/dataDisplay/chat/chat.jsx +38 -4
- package/dist/headless/source/components/dataDisplay/chat/chat.jsx.map +1 -1
- package/dist/headless/source/components/dataDisplay/chat/chatComposer.jsx +1 -0
- package/dist/headless/source/components/dataDisplay/chat/chatComposer.jsx.map +1 -1
- package/dist/headless/source/components/dataDisplay/chat/index.js.map +1 -1
- package/dist/headless/source/components/dataDisplay/chat/utils.js.map +2 -2
- package/dist/headless/source/components/dataDisplay/dagView/dagView.jsx +30 -21
- package/dist/headless/source/components/dataDisplay/dagView/dagView.jsx.map +1 -1
- package/dist/headless/source/components/dataDisplay/diffStat/diffStat.jsx +76 -0
- package/dist/headless/source/components/dataDisplay/diffStat/diffStat.jsx.map +1 -0
- package/dist/headless/source/components/dataDisplay/diffStat/index.js +19 -0
- package/dist/headless/source/components/dataDisplay/diffStat/index.js.map +7 -0
- package/dist/headless/source/components/dataDisplay/kbd/index.js +9 -0
- package/dist/headless/source/components/dataDisplay/kbd/index.js.map +7 -0
- package/dist/headless/source/components/dataDisplay/kbd/kbd.jsx +48 -0
- package/dist/headless/source/components/dataDisplay/kbd/kbd.jsx.map +1 -0
- package/dist/headless/source/components/dataDisplay/kbd/kbdKeys.js +79 -0
- package/dist/headless/source/components/dataDisplay/kbd/kbdKeys.js.map +7 -0
- package/dist/headless/source/components/dataDisplay/list/listItem.jsx +37 -7
- package/dist/headless/source/components/dataDisplay/list/listItem.jsx.map +1 -1
- package/dist/headless/source/components/dataDisplay/qrCode/index.js +6 -0
- package/dist/headless/source/components/dataDisplay/qrCode/index.js.map +7 -0
- package/dist/headless/source/components/dataDisplay/qrCode/qrCode.jsx +94 -0
- package/dist/headless/source/components/dataDisplay/qrCode/qrCode.jsx.map +1 -0
- package/dist/headless/source/components/dataDisplay/qrCode/qrCodePath.js +24 -0
- package/dist/headless/source/components/dataDisplay/qrCode/qrCodePath.js.map +7 -0
- package/dist/headless/source/components/dataDisplay/statusDot/index.js +6 -0
- package/dist/headless/source/components/dataDisplay/statusDot/index.js.map +7 -0
- package/dist/headless/source/components/dataDisplay/statusDot/statusDot.jsx +28 -0
- package/dist/headless/source/components/dataDisplay/statusDot/statusDot.jsx.map +1 -0
- package/dist/headless/source/components/dataDisplay/swimlanes/index.js +15 -0
- package/dist/headless/source/components/dataDisplay/swimlanes/index.js.map +7 -0
- package/dist/headless/source/components/dataDisplay/swimlanes/swimlanes.jsx +450 -0
- package/dist/headless/source/components/dataDisplay/swimlanes/swimlanes.jsx.map +1 -0
- package/dist/headless/source/components/dataDisplay/treeView/treeView.jsx +118 -37
- package/dist/headless/source/components/dataDisplay/treeView/treeView.jsx.map +1 -1
- package/dist/headless/source/components/feedBack/modal/modal.jsx +34 -4
- package/dist/headless/source/components/feedBack/modal/modal.jsx.map +1 -1
- package/dist/headless/source/components/inputs/button/button.jsx +6 -2
- package/dist/headless/source/components/inputs/button/button.jsx.map +1 -1
- package/dist/headless/source/components/inputs/composer/composer.jsx +319 -0
- package/dist/headless/source/components/inputs/composer/composer.jsx.map +1 -0
- package/dist/headless/source/components/inputs/composer/composerFiles.js +27 -0
- package/dist/headless/source/components/inputs/composer/composerFiles.js.map +7 -0
- package/dist/headless/source/components/inputs/composer/composerKeys.js +11 -0
- package/dist/headless/source/components/inputs/composer/composerKeys.js.map +7 -0
- package/dist/headless/source/components/inputs/composer/index.js +5 -0
- package/dist/headless/source/components/inputs/composer/index.js.map +7 -0
- package/dist/headless/source/components/layout/sheet/sheet.jsx +33 -11
- package/dist/headless/source/components/layout/sheet/sheet.jsx.map +1 -1
- package/dist/headless/source/components/layout/tabGroups/index.js +8 -0
- package/dist/headless/source/components/layout/tabGroups/index.js.map +7 -0
- package/dist/headless/source/components/layout/tabGroups/tabGroups.jsx +1117 -0
- package/dist/headless/source/components/layout/tabGroups/tabGroups.jsx.map +1 -0
- package/dist/headless/source/components/layout/tabGroups/tabGroupsFocus.js +222 -0
- package/dist/headless/source/components/layout/tabGroups/tabGroupsFocus.js.map +7 -0
- package/dist/headless/source/components/layout/tabGroups/tabGroupsLayout.js +629 -0
- package/dist/headless/source/components/layout/tabGroups/tabGroupsLayout.js.map +7 -0
- package/dist/headless/source/components/navigation/appBar/appBar.jsx +27 -3
- package/dist/headless/source/components/navigation/appBar/appBar.jsx.map +1 -1
- package/dist/headless/source/components/navigation/commandPalette/commandPalette.jsx +506 -0
- package/dist/headless/source/components/navigation/commandPalette/commandPalette.jsx.map +1 -0
- package/dist/headless/source/components/navigation/commandPalette/commandPaletteFilter.js +16 -0
- package/dist/headless/source/components/navigation/commandPalette/commandPaletteFilter.js.map +7 -0
- package/dist/headless/source/components/navigation/commandPalette/commandPaletteNavigation.js +54 -0
- package/dist/headless/source/components/navigation/commandPalette/commandPaletteNavigation.js.map +7 -0
- package/dist/headless/source/components/navigation/commandPalette/commandPaletteTypes.js +1 -0
- package/dist/headless/source/components/navigation/commandPalette/commandPaletteTypes.js.map +7 -0
- package/dist/headless/source/components/navigation/commandPalette/index.js +11 -0
- package/dist/headless/source/components/navigation/commandPalette/index.js.map +7 -0
- package/dist/headless/source/components/navigation/sidebar/sidebar.jsx +5 -2
- package/dist/headless/source/components/navigation/sidebar/sidebar.jsx.map +1 -1
- package/dist/headless/source/components/navigation/tabs/index.js +2 -0
- package/dist/headless/source/components/navigation/tabs/index.js.map +2 -2
- package/dist/headless/source/components/navigation/tabs/tab/tab.jsx +135 -8
- package/dist/headless/source/components/navigation/tabs/tab/tab.jsx.map +1 -1
- package/dist/headless/source/components/navigation/tabs/tabPanel/tabPanel.jsx +28 -0
- package/dist/headless/source/components/navigation/tabs/tabPanel/tabPanel.jsx.map +1 -0
- package/dist/headless/source/components/navigation/tabs/tabs.jsx +361 -13
- package/dist/headless/source/components/navigation/tabs/tabs.jsx.map +1 -1
- package/dist/headless/source/components/navigation/tabs/tabs.utils.js +18 -0
- package/dist/headless/source/components/navigation/tabs/tabs.utils.js.map +7 -0
- package/dist/headless/source/components/navigation/tabs/tabsContext.js.map +2 -2
- package/dist/headless/source/index.js +41 -1
- package/dist/headless/source/index.js.map +2 -2
- package/dist/headless/source/primitives/createFocusTrap.js +8 -3
- package/dist/headless/source/primitives/createFocusTrap.js.map +2 -2
- package/dist/headless/source/primitives/createKeyboardShortcut.js +23 -0
- package/dist/headless/source/primitives/createKeyboardShortcut.js.map +7 -0
- package/dist/headless/source/primitives/restoreFocus.js +14 -0
- package/dist/headless/source/primitives/restoreFocus.js.map +7 -0
- package/dist/headless/source/utils/keyboardShortcut.js +74 -0
- package/dist/headless/source/utils/keyboardShortcut.js.map +7 -0
- package/dist/headless/source/utils/linkAttrs.js +16 -0
- package/dist/headless/source/utils/linkAttrs.js.map +7 -0
- package/dist/headless/utils/keyboardShortcut.js +48 -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/index.d.ts +24 -3
- package/dist/index.js +405 -367
- package/dist/index.js.map +1 -1
- package/dist/primitives/createFocusTrap.d.ts +5 -0
- package/dist/primitives/createFocusTrap.js +17 -17
- package/dist/primitives/createFocusTrap.js.map +1 -1
- package/dist/primitives/createKeyboardShortcut.d.ts +23 -0
- package/dist/primitives/createKeyboardShortcut.js +16 -0
- package/dist/primitives/createKeyboardShortcut.js.map +1 -0
- package/dist/primitives/restoreFocus.d.ts +8 -0
- package/dist/primitives/restoreFocus.js +10 -0
- package/dist/primitives/restoreFocus.js.map +1 -0
- package/dist/source/components/dataDisplay/chat/chat.jsx +38 -4
- package/dist/source/components/dataDisplay/chat/chat.jsx.map +1 -1
- package/dist/source/components/dataDisplay/chat/chatComposer.jsx +1 -0
- package/dist/source/components/dataDisplay/chat/chatComposer.jsx.map +1 -1
- package/dist/source/components/dataDisplay/chat/index.js.map +1 -1
- package/dist/source/components/dataDisplay/chat/utils.js.map +2 -2
- package/dist/source/components/dataDisplay/dagView/dagView.jsx +30 -21
- package/dist/source/components/dataDisplay/dagView/dagView.jsx.map +1 -1
- package/dist/source/components/dataDisplay/diffStat/diffStat.jsx +78 -0
- package/dist/source/components/dataDisplay/diffStat/diffStat.jsx.map +1 -0
- package/dist/source/components/dataDisplay/diffStat/index.js +19 -0
- package/dist/source/components/dataDisplay/diffStat/index.js.map +7 -0
- package/dist/source/components/dataDisplay/kbd/index.js +9 -0
- package/dist/source/components/dataDisplay/kbd/index.js.map +7 -0
- package/dist/source/components/dataDisplay/kbd/kbd.jsx +50 -0
- package/dist/source/components/dataDisplay/kbd/kbd.jsx.map +1 -0
- package/dist/source/components/dataDisplay/kbd/kbdKeys.js +79 -0
- package/dist/source/components/dataDisplay/kbd/kbdKeys.js.map +7 -0
- package/dist/source/components/dataDisplay/list/listItem.jsx +37 -7
- package/dist/source/components/dataDisplay/list/listItem.jsx.map +1 -1
- package/dist/source/components/dataDisplay/qrCode/index.js +6 -0
- package/dist/source/components/dataDisplay/qrCode/index.js.map +7 -0
- package/dist/source/components/dataDisplay/qrCode/qrCode.jsx +96 -0
- package/dist/source/components/dataDisplay/qrCode/qrCode.jsx.map +1 -0
- package/dist/source/components/dataDisplay/qrCode/qrCodePath.js +24 -0
- package/dist/source/components/dataDisplay/qrCode/qrCodePath.js.map +7 -0
- package/dist/source/components/dataDisplay/statusDot/index.js +6 -0
- package/dist/source/components/dataDisplay/statusDot/index.js.map +7 -0
- package/dist/source/components/dataDisplay/statusDot/statusDot.jsx +30 -0
- package/dist/source/components/dataDisplay/statusDot/statusDot.jsx.map +1 -0
- package/dist/source/components/dataDisplay/swimlanes/index.js +15 -0
- package/dist/source/components/dataDisplay/swimlanes/index.js.map +7 -0
- package/dist/source/components/dataDisplay/swimlanes/swimlanes.jsx +452 -0
- package/dist/source/components/dataDisplay/swimlanes/swimlanes.jsx.map +1 -0
- package/dist/source/components/dataDisplay/treeView/treeView.jsx +118 -37
- package/dist/source/components/dataDisplay/treeView/treeView.jsx.map +1 -1
- package/dist/source/components/feedBack/modal/modal.jsx +34 -4
- package/dist/source/components/feedBack/modal/modal.jsx.map +1 -1
- package/dist/source/components/inputs/button/button.jsx +6 -2
- package/dist/source/components/inputs/button/button.jsx.map +1 -1
- package/dist/source/components/inputs/composer/composer.jsx +321 -0
- package/dist/source/components/inputs/composer/composer.jsx.map +1 -0
- package/dist/source/components/inputs/composer/composerFiles.js +27 -0
- package/dist/source/components/inputs/composer/composerFiles.js.map +7 -0
- package/dist/source/components/inputs/composer/composerKeys.js +11 -0
- package/dist/source/components/inputs/composer/composerKeys.js.map +7 -0
- package/dist/source/components/inputs/composer/index.js +5 -0
- package/dist/source/components/inputs/composer/index.js.map +7 -0
- package/dist/source/components/layout/sheet/sheet.jsx +33 -11
- package/dist/source/components/layout/sheet/sheet.jsx.map +1 -1
- package/dist/source/components/layout/tabGroups/index.js +8 -0
- package/dist/source/components/layout/tabGroups/index.js.map +7 -0
- package/dist/source/components/layout/tabGroups/tabGroups.jsx +1119 -0
- package/dist/source/components/layout/tabGroups/tabGroups.jsx.map +1 -0
- package/dist/source/components/layout/tabGroups/tabGroupsFocus.js +222 -0
- package/dist/source/components/layout/tabGroups/tabGroupsFocus.js.map +7 -0
- package/dist/source/components/layout/tabGroups/tabGroupsLayout.js +629 -0
- package/dist/source/components/layout/tabGroups/tabGroupsLayout.js.map +7 -0
- package/dist/source/components/navigation/appBar/appBar.jsx +27 -3
- package/dist/source/components/navigation/appBar/appBar.jsx.map +1 -1
- package/dist/source/components/navigation/commandPalette/commandPalette.jsx +508 -0
- package/dist/source/components/navigation/commandPalette/commandPalette.jsx.map +1 -0
- package/dist/source/components/navigation/commandPalette/commandPaletteFilter.js +16 -0
- package/dist/source/components/navigation/commandPalette/commandPaletteFilter.js.map +7 -0
- package/dist/source/components/navigation/commandPalette/commandPaletteNavigation.js +54 -0
- package/dist/source/components/navigation/commandPalette/commandPaletteNavigation.js.map +7 -0
- package/dist/source/components/navigation/commandPalette/commandPaletteTypes.js +1 -0
- package/dist/source/components/navigation/commandPalette/commandPaletteTypes.js.map +7 -0
- package/dist/source/components/navigation/commandPalette/index.js +11 -0
- package/dist/source/components/navigation/commandPalette/index.js.map +7 -0
- package/dist/source/components/navigation/sidebar/sidebar.jsx +5 -2
- package/dist/source/components/navigation/sidebar/sidebar.jsx.map +1 -1
- package/dist/source/components/navigation/tabs/index.js +2 -0
- package/dist/source/components/navigation/tabs/index.js.map +2 -2
- package/dist/source/components/navigation/tabs/tab/tab.jsx +135 -8
- package/dist/source/components/navigation/tabs/tab/tab.jsx.map +1 -1
- package/dist/source/components/navigation/tabs/tabPanel/tabPanel.jsx +30 -0
- package/dist/source/components/navigation/tabs/tabPanel/tabPanel.jsx.map +1 -0
- package/dist/source/components/navigation/tabs/tabs.jsx +361 -13
- package/dist/source/components/navigation/tabs/tabs.jsx.map +1 -1
- package/dist/source/components/navigation/tabs/tabs.utils.js +18 -0
- package/dist/source/components/navigation/tabs/tabs.utils.js.map +7 -0
- package/dist/source/components/navigation/tabs/tabsContext.js.map +2 -2
- package/dist/source/index.js +41 -1
- package/dist/source/index.js.map +2 -2
- package/dist/source/primitives/createFocusTrap.js +8 -3
- package/dist/source/primitives/createFocusTrap.js.map +2 -2
- package/dist/source/primitives/createKeyboardShortcut.js +23 -0
- package/dist/source/primitives/createKeyboardShortcut.js.map +7 -0
- package/dist/source/primitives/restoreFocus.js +14 -0
- package/dist/source/primitives/restoreFocus.js.map +7 -0
- package/dist/source/utils/keyboardShortcut.js +74 -0
- package/dist/source/utils/keyboardShortcut.js.map +7 -0
- package/dist/source/utils/linkAttrs.js +16 -0
- package/dist/source/utils/linkAttrs.js.map +7 -0
- package/dist/utils/keyboardShortcut.d.ts +12 -0
- package/dist/utils/keyboardShortcut.js +48 -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/package.json +66 -3
|
@@ -1,73 +1,145 @@
|
|
|
1
1
|
import "@smwb/ui-styles/less/tokens.entry.less";
|
|
2
2
|
import "@smwb/ui-styles/less/components/treeView/treeView.entry.less";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
For,
|
|
5
|
+
Show,
|
|
6
|
+
createContext,
|
|
7
|
+
createMemo,
|
|
8
|
+
createSignal,
|
|
9
|
+
createUniqueId,
|
|
10
|
+
mergeProps,
|
|
11
|
+
splitProps,
|
|
12
|
+
useContext
|
|
13
|
+
} from "solid-js";
|
|
4
14
|
import cn from "clsx";
|
|
5
15
|
import { Icon } from "../../base/icon";
|
|
6
16
|
import { createControllableState } from "../../../primitives/createControllableState";
|
|
7
17
|
import { mergeRefs } from "../../../primitives/mergeRefs";
|
|
18
|
+
import { isOwnClick } from "../../../utils/ownClick";
|
|
8
19
|
const TreeContext = createContext();
|
|
20
|
+
function sameItem(a, b) {
|
|
21
|
+
if (a === b) return true;
|
|
22
|
+
if (a.id !== b.id || a.label !== b.label || a.hasChildren !== b.hasChildren) return false;
|
|
23
|
+
const left = a.children;
|
|
24
|
+
const right = b.children;
|
|
25
|
+
if (left === right) return true;
|
|
26
|
+
if (!left || !right || left.length !== right.length) return false;
|
|
27
|
+
return left.every((child, idx) => {
|
|
28
|
+
const other = right[idx];
|
|
29
|
+
return !!other && child.id === other.id && child.label === other.label && child.hasChildren === other.hasChildren;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function TreeNodes(props) {
|
|
33
|
+
const entries = createMemo(
|
|
34
|
+
() => props.items.map((item, idx) => {
|
|
35
|
+
const path = props.path === "" ? `${idx}` : `${props.path}.${idx}`;
|
|
36
|
+
return { id: item.id ?? path, item, path };
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
const byId = createMemo(() => new Map(entries().map((entry) => [entry.id, entry])));
|
|
40
|
+
const ids = createMemo(() => entries().map((entry) => entry.id));
|
|
41
|
+
return <For each={ids()}>
|
|
42
|
+
{(id) => {
|
|
43
|
+
let last = byId().get(id);
|
|
44
|
+
const entry = () => last = byId().get(id) ?? last;
|
|
45
|
+
return props.wrap ? <div class="smwb-tree__wrapper" role="presentation">
|
|
46
|
+
<TreeNode entry={entry} />
|
|
47
|
+
</div> : <TreeNode entry={entry} />;
|
|
48
|
+
}}
|
|
49
|
+
</For>;
|
|
50
|
+
}
|
|
9
51
|
function TreeNode(props) {
|
|
10
52
|
const ctx = useContext(TreeContext);
|
|
11
|
-
const nodeId = ()
|
|
12
|
-
const
|
|
13
|
-
const
|
|
53
|
+
const nodeId = props.entry().id;
|
|
54
|
+
const item = () => props.entry().item;
|
|
55
|
+
const labelId = `${createUniqueId()}-label`;
|
|
56
|
+
const slotItem = createMemo(() => item(), void 0, { equals: sameItem });
|
|
57
|
+
const labelSlot = createMemo(
|
|
58
|
+
() => ctx.renderLabel ? ctx.renderLabel(slotItem(), nodeId) : slotItem().label
|
|
59
|
+
);
|
|
60
|
+
const resolvedChildren = () => item().children ?? ctx.loadedChildren()[nodeId];
|
|
61
|
+
const isLazy = () => ctx.hasLoader && (!!item().hasChildren || !!ctx.loadedChildren()[nodeId]);
|
|
14
62
|
const hasChildNodes = () => !!resolvedChildren() && (resolvedChildren()?.length ?? 0) > 0 || isLazy();
|
|
15
|
-
const isOpen = () => ctx.expandedIds().includes(nodeId
|
|
16
|
-
const isSelected = () => ctx.selectedIds().includes(nodeId
|
|
17
|
-
const isLoading = () => ctx.loadingIds().includes(nodeId
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (ctx.
|
|
63
|
+
const isOpen = () => ctx.expandedIds().includes(nodeId);
|
|
64
|
+
const isSelected = () => ctx.selectedIds().includes(nodeId);
|
|
65
|
+
const isLoading = () => ctx.loadingIds().includes(nodeId);
|
|
66
|
+
const toggleNode = () => {
|
|
67
|
+
if (!isOpen()) ctx.ensureLoaded(item(), nodeId);
|
|
68
|
+
ctx.toggleExpanded(nodeId);
|
|
69
|
+
};
|
|
70
|
+
const activateRow = () => {
|
|
71
|
+
if (ctx.toggleOnRowClick && hasChildNodes()) toggleNode();
|
|
72
|
+
if (ctx.selectable) ctx.toggleSelected(nodeId);
|
|
24
73
|
};
|
|
25
74
|
const onKeyDown = (event) => {
|
|
75
|
+
if (event.target !== event.currentTarget) return;
|
|
26
76
|
if (event.key === "Enter" || event.key === " ") {
|
|
27
77
|
event.preventDefault();
|
|
28
|
-
|
|
78
|
+
activateRow();
|
|
29
79
|
} else if (event.key === "ArrowRight" && hasChildNodes()) {
|
|
30
|
-
ctx.ensureLoaded(
|
|
31
|
-
ctx.setOpen(nodeId
|
|
80
|
+
ctx.ensureLoaded(item(), nodeId);
|
|
81
|
+
ctx.setOpen(nodeId, true);
|
|
32
82
|
} else if (event.key === "ArrowLeft" && hasChildNodes()) {
|
|
33
|
-
ctx.setOpen(nodeId
|
|
83
|
+
ctx.setOpen(nodeId, false);
|
|
34
84
|
}
|
|
35
85
|
};
|
|
86
|
+
const onContentClick = (event) => {
|
|
87
|
+
if (isOwnClick(event)) activateRow();
|
|
88
|
+
};
|
|
36
89
|
return <div
|
|
37
90
|
class={cn("smwb-tree__node", { "smwb-tree__node_selected": isSelected() })}
|
|
38
91
|
role="treeitem"
|
|
92
|
+
aria-labelledby={labelId}
|
|
39
93
|
aria-expanded={hasChildNodes() ? isOpen() : void 0}
|
|
40
94
|
aria-selected={ctx.selectable || ctx.checkboxes ? isSelected() : void 0}
|
|
41
95
|
>
|
|
42
|
-
<
|
|
96
|
+
<div class="smwb-tree__node__row">
|
|
97
|
+
{
|
|
98
|
+
/*
|
|
99
|
+
A pointer shortcut: the keyboard expands with ArrowRight/ArrowLeft on the row, so the chevron is
|
|
100
|
+
decorative, unnamed and no Tab stop. If it ever becomes a real <button>, `aria-hidden` must go with
|
|
101
|
+
it (a focusable element inside `aria-hidden` is an ARIA violation) and it then needs a name plus
|
|
102
|
+
`aria-expanded`.
|
|
103
|
+
*/
|
|
104
|
+
}
|
|
105
|
+
<span class="smwb-tree__node__toggle" aria-hidden="true" onClick={() => hasChildNodes() && toggleNode()}>
|
|
106
|
+
<Show when={hasChildNodes()}>
|
|
107
|
+
<Icon name={isOpen() ? "expand_more" : "chevron_right"} size={20} />
|
|
108
|
+
</Show>
|
|
109
|
+
</span>
|
|
43
110
|
<Show when={ctx.checkboxes}>
|
|
44
111
|
<input
|
|
45
112
|
type="checkbox"
|
|
46
113
|
class="smwb-tree__node__checkbox"
|
|
47
114
|
checked={isSelected()}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
aria-label={props.item.label}
|
|
115
|
+
onChange={() => ctx.toggleSelected(nodeId)}
|
|
116
|
+
aria-label={item().label}
|
|
51
117
|
/>
|
|
52
118
|
</Show>
|
|
53
|
-
<span class="smwb-
|
|
54
|
-
<
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
119
|
+
<span class="smwb-tree__node__content" onClick={onContentClick} onKeyDown={onKeyDown} tabindex={0} role="button">
|
|
120
|
+
<span class="smwb-tree__node__label" id={labelId}>
|
|
121
|
+
<Show when={hasChildNodes()} fallback={<Icon name={ctx.listIcon} size={20} />}>
|
|
122
|
+
<Icon name={isOpen() ? ctx.nodeIcon.opened ?? "folder_open" : ctx.nodeIcon.closed ?? "folder"} fill={1} size={20} />
|
|
123
|
+
</Show>
|
|
124
|
+
{labelSlot()}
|
|
125
|
+
</span>
|
|
58
126
|
</span>
|
|
59
|
-
|
|
127
|
+
<Show when={ctx.renderActions}>
|
|
128
|
+
{(renderActions) => {
|
|
129
|
+
const actionsSlot = createMemo(() => renderActions()(slotItem(), nodeId));
|
|
130
|
+
return <span class="smwb-tree__node__actions">{actionsSlot()}</span>;
|
|
131
|
+
}}
|
|
132
|
+
</Show>
|
|
133
|
+
</div>
|
|
60
134
|
<Show when={hasChildNodes() && isOpen()}>
|
|
61
135
|
<div role="group">
|
|
62
136
|
<Show
|
|
63
137
|
when={!(isLoading() && !resolvedChildren())}
|
|
64
138
|
fallback={<div class="smwb-tree__node__loading" role="status">
|
|
65
|
-
|
|
139
|
+
{ctx.loadingText}
|
|
66
140
|
</div>}
|
|
67
141
|
>
|
|
68
|
-
<
|
|
69
|
-
{(child, idx) => <TreeNode item={child} path={`${props.path}.${idx()}`} />}
|
|
70
|
-
</For>
|
|
142
|
+
<TreeNodes items={resolvedChildren() ?? []} path={props.entry().path} />
|
|
71
143
|
</Show>
|
|
72
144
|
</div>
|
|
73
145
|
</Show>
|
|
@@ -82,7 +154,8 @@ function TreeView(props) {
|
|
|
82
154
|
defaultExpanded: [],
|
|
83
155
|
defaultSelected: [],
|
|
84
156
|
selectable: false,
|
|
85
|
-
checkboxes: false
|
|
157
|
+
checkboxes: false,
|
|
158
|
+
loadingText: "Loading\u2026"
|
|
86
159
|
},
|
|
87
160
|
props
|
|
88
161
|
);
|
|
@@ -99,7 +172,10 @@ function TreeView(props) {
|
|
|
99
172
|
"onSelectedChange",
|
|
100
173
|
"selectable",
|
|
101
174
|
"checkboxes",
|
|
175
|
+
"toggleOnRowClick",
|
|
102
176
|
"renderLabel",
|
|
177
|
+
"renderActions",
|
|
178
|
+
"loadingText",
|
|
103
179
|
"loadChildren",
|
|
104
180
|
"ref",
|
|
105
181
|
"data-testid"
|
|
@@ -152,6 +228,12 @@ function TreeView(props) {
|
|
|
152
228
|
get checkboxes() {
|
|
153
229
|
return local.checkboxes;
|
|
154
230
|
},
|
|
231
|
+
get toggleOnRowClick() {
|
|
232
|
+
return local.toggleOnRowClick ?? !local.selectable;
|
|
233
|
+
},
|
|
234
|
+
get loadingText() {
|
|
235
|
+
return local.loadingText;
|
|
236
|
+
},
|
|
155
237
|
get nodeIcon() {
|
|
156
238
|
return local.nodeIcon;
|
|
157
239
|
},
|
|
@@ -161,6 +243,9 @@ function TreeView(props) {
|
|
|
161
243
|
get renderLabel() {
|
|
162
244
|
return local.renderLabel;
|
|
163
245
|
},
|
|
246
|
+
get renderActions() {
|
|
247
|
+
return local.renderActions;
|
|
248
|
+
},
|
|
164
249
|
get hasLoader() {
|
|
165
250
|
return !!local.loadChildren;
|
|
166
251
|
}
|
|
@@ -173,11 +258,7 @@ function TreeView(props) {
|
|
|
173
258
|
role="tree"
|
|
174
259
|
class={cn("smwb-tree", local.class)}
|
|
175
260
|
>
|
|
176
|
-
<
|
|
177
|
-
{(node, idx) => <div class="smwb-tree__wrapper" role="presentation">
|
|
178
|
-
<TreeNode item={node} path={`${idx()}`} />
|
|
179
|
-
</div>}
|
|
180
|
-
</For>
|
|
261
|
+
<TreeNodes items={local.data} path="" wrap />
|
|
181
262
|
</div>
|
|
182
263
|
</TreeContext.Provider>;
|
|
183
264
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/dataDisplay/treeView/treeView.tsx"],"sourcesContent":["import \"@smwb/ui-styles/less/tokens.entry.less\";\nimport \"@smwb/ui-styles/less/components/treeView/treeView.entry.less\";\nimport { type Accessor, type JSX, For, Show, createContext, createSignal, mergeProps, splitProps, useContext } from \"solid-js\";\nimport cn from \"clsx\";\nimport { Icon } from \"../../base/icon\";\nimport { createControllableState } from \"../../../primitives/createControllableState\";\nimport { mergeRefs, type Ref } from \"../../../primitives/mergeRefs\";\n\nexport interface ITreeNodeItem {\n /** Stable identifier. Falls back to the positional path when omitted. */\n id?: string;\n label: string;\n children?: ITreeNodeItem[];\n /** Hint that the node is expandable even before its children are loaded. */\n hasChildren?: boolean;\n}\n\nexport interface TreeViewProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n nodeIcon?: { opened?: string; closed?: string };\n listIcon?: string;\n data: ITreeNodeItem[];\n expanded?: string[];\n defaultExpanded?: string[];\n onExpandedChange?: (expanded: string[]) => void;\n selected?: string[];\n defaultSelected?: string[];\n /** Reports the full selection plus, for user toggles, the node that just changed. */\n onSelectedChange?: (selected: string[], changed?: { id: string; selected: boolean }) => void;\n selectable?: boolean;\n checkboxes?: boolean;\n renderLabel?: (item: ITreeNodeItem, nodeId: string) => JSX.Element;\n loadChildren?: (item: ITreeNodeItem, nodeId: string) => Promise<ITreeNodeItem[]>;\n /** Test id of the root `<div>`; `tree-view` unless given. */\n \"data-testid\"?: string | undefined;\n ref?: Ref<HTMLDivElement>;\n}\n\ninterface TreeContextValue {\n expandedIds: Accessor<string[]>;\n selectedIds: Accessor<string[]>;\n loadedChildren: Accessor<Record<string, ITreeNodeItem[]>>;\n loadingIds: Accessor<string[]>;\n toggleExpanded: (id: string) => void;\n setOpen: (id: string, open: boolean) => void;\n toggleSelected: (id: string) => void;\n ensureLoaded: (item: ITreeNodeItem, nodeId: string) => void;\n selectable: boolean;\n checkboxes: boolean;\n nodeIcon: { opened?: string; closed?: string };\n listIcon: string;\n renderLabel: ((item: ITreeNodeItem, nodeId: string) => JSX.Element) | undefined;\n hasLoader: boolean;\n}\n\nconst TreeContext = createContext<TreeContextValue>();\n\nfunction TreeNode(props: { item: ITreeNodeItem; path: string }): JSX.Element {\n const ctx = useContext(TreeContext)!;\n const nodeId = (): string => props.item.id ?? props.path;\n const resolvedChildren = (): ITreeNodeItem[] | undefined => props.item.children ?? ctx.loadedChildren()[nodeId()];\n const isLazy = (): boolean => ctx.hasLoader && (!!props.item.hasChildren || !!ctx.loadedChildren()[nodeId()]);\n const hasChildNodes = (): boolean => (!!resolvedChildren() && (resolvedChildren()?.length ?? 0) > 0) || isLazy();\n const isOpen = (): boolean => ctx.expandedIds().includes(nodeId());\n const isSelected = (): boolean => ctx.selectedIds().includes(nodeId());\n const isLoading = (): boolean => ctx.loadingIds().includes(nodeId());\n\n const onLabelClick = (): void => {\n if (hasChildNodes()) {\n if (!isOpen()) ctx.ensureLoaded(props.item, nodeId());\n ctx.toggleExpanded(nodeId());\n }\n if (ctx.selectable) ctx.toggleSelected(nodeId());\n };\n\n const onKeyDown: JSX.EventHandler<HTMLSpanElement, KeyboardEvent> = (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onLabelClick();\n } else if (event.key === \"ArrowRight\" && hasChildNodes()) {\n ctx.ensureLoaded(props.item, nodeId());\n ctx.setOpen(nodeId(), true);\n } else if (event.key === \"ArrowLeft\" && hasChildNodes()) {\n ctx.setOpen(nodeId(), false);\n }\n };\n\n return (\n <div\n class={cn(\"smwb-tree__node\", { \"smwb-tree__node_selected\": isSelected() })}\n role=\"treeitem\"\n aria-expanded={hasChildNodes() ? isOpen() : undefined}\n aria-selected={ctx.selectable || ctx.checkboxes ? isSelected() : undefined}\n >\n <span class=\"smwb-tree__node__content\" onClick={onLabelClick} onKeyDown={onKeyDown} tabindex={0} role=\"button\">\n <Show when={ctx.checkboxes}>\n <input\n type=\"checkbox\"\n class=\"smwb-tree__node__checkbox\"\n checked={isSelected()}\n onClick={(e) => e.stopPropagation()}\n onChange={() => ctx.toggleSelected(nodeId())}\n aria-label={props.item.label}\n />\n </Show>\n <span class=\"smwb-tree__node__label\">\n <Show when={hasChildNodes()} fallback={<Icon name={ctx.listIcon} size={20} />}>\n <Icon name={isOpen() ? ctx.nodeIcon.opened ?? \"folder_open\" : ctx.nodeIcon.closed ?? \"folder\"} fill={1} size={20} />\n </Show>\n {ctx.renderLabel ? ctx.renderLabel(props.item, nodeId()) : props.item.label}\n </span>\n </span>\n <Show when={hasChildNodes() && isOpen()}>\n <div role=\"group\">\n <Show\n when={!(isLoading() && !resolvedChildren())}\n fallback={\n <div class=\"smwb-tree__node__loading\" role=\"status\">\n Загрузка…\n </div>\n }\n >\n <For each={resolvedChildren() ?? []}>\n {(child, idx) => <TreeNode item={child} path={`${props.path}.${idx()}`} />}\n </For>\n </Show>\n </div>\n </Show>\n </div>\n );\n}\n\nexport function TreeView(props: TreeViewProps): JSX.Element {\n const merged = mergeProps(\n {\n listIcon: \"draft\",\n nodeIcon: { closed: \"folder\", opened: \"folder_open\" } as { opened?: string; closed?: string },\n data: [] as ITreeNodeItem[],\n defaultExpanded: [] as string[],\n defaultSelected: [] as string[],\n selectable: false,\n checkboxes: false,\n },\n props\n );\n const [local, rest] = splitProps(merged, [\n \"class\",\n \"listIcon\",\n \"nodeIcon\",\n \"data\",\n \"expanded\",\n \"defaultExpanded\",\n \"onExpandedChange\",\n \"selected\",\n \"defaultSelected\",\n \"onSelectedChange\",\n \"selectable\",\n \"checkboxes\",\n \"renderLabel\",\n \"loadChildren\",\n \"ref\",\n \"data-testid\",\n ]);\n\n const [loadedChildren, setLoadedChildren] = createSignal<Record<string, ITreeNodeItem[]>>({});\n const [loadingIds, setLoadingIds] = createSignal<string[]>([]);\n const [expandedIds, setExpandedIds] = createControllableState<string[]>({\n value: () => local.expanded,\n defaultValue: local.defaultExpanded,\n onChange: (next) => local.onExpandedChange?.(next),\n });\n let lastToggled: { id: string; selected: boolean } | undefined;\n const [selectedIds, setSelectedIds] = createControllableState<string[]>({\n value: () => local.selected,\n defaultValue: local.defaultSelected,\n onChange: (next) => {\n // createControllableState calls onChange synchronously from the setter,\n // so lastToggled still refers to the toggle that caused this change.\n const changed = lastToggled;\n lastToggled = undefined;\n local.onSelectedChange?.(next, changed);\n },\n });\n\n const toggleExpanded = (id: string): void =>\n setExpandedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n\n const setOpen = (id: string, open: boolean): void =>\n setExpandedIds((prev) => {\n const has = prev.includes(id);\n if (open && !has) return [...prev, id];\n if (!open && has) return prev.filter((x) => x !== id);\n return prev;\n });\n\n const toggleSelected = (id: string): void => {\n lastToggled = { id, selected: !selectedIds().includes(id) };\n setSelectedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const ensureLoaded = (item: ITreeNodeItem, nodeId: string): void => {\n if (!local.loadChildren || loadedChildren()[nodeId] || (item.children && item.children.length > 0)) return;\n setLoadingIds((prev) => (prev.includes(nodeId) ? prev : [...prev, nodeId]));\n void local\n .loadChildren(item, nodeId)\n .then((children) => setLoadedChildren((prev) => ({ ...prev, [nodeId]: children })))\n .finally(() => setLoadingIds((prev) => prev.filter((x) => x !== nodeId)));\n };\n\n const contextValue: TreeContextValue = {\n expandedIds,\n selectedIds,\n loadedChildren,\n loadingIds,\n toggleExpanded,\n setOpen,\n toggleSelected,\n ensureLoaded,\n get selectable() {\n return local.selectable;\n },\n get checkboxes() {\n return local.checkboxes;\n },\n get nodeIcon() {\n return local.nodeIcon;\n },\n get listIcon() {\n return local.listIcon;\n },\n get renderLabel() {\n return local.renderLabel;\n },\n get hasLoader() {\n return !!local.loadChildren;\n },\n };\n\n return (\n <TreeContext.Provider value={contextValue}>\n <div\n {...rest}\n data-testid={local[\"data-testid\"] ?? \"tree-view\"}\n ref={mergeRefs(local.ref)}\n role=\"tree\"\n class={cn(\"smwb-tree\", local.class)}\n >\n <For each={local.data}>\n {(node, idx) => (\n <div class=\"smwb-tree__wrapper\" role=\"presentation\">\n <TreeNode item={node} path={`${idx()}`} />\n </div>\n )}\n </For>\n </div>\n </TreeContext.Provider>\n );\n}\n\nexport default TreeView;\n"],"mappings":"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","names":[],"file":"treeView.jsx"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/dataDisplay/treeView/treeView.tsx"],"sourcesContent":["import \"@smwb/ui-styles/less/tokens.entry.less\";\nimport \"@smwb/ui-styles/less/components/treeView/treeView.entry.less\";\nimport {\n type Accessor,\n type JSX,\n For,\n Show,\n createContext,\n createMemo,\n createSignal,\n createUniqueId,\n mergeProps,\n splitProps,\n useContext,\n} from \"solid-js\";\nimport cn from \"clsx\";\nimport { Icon } from \"../../base/icon\";\nimport { createControllableState } from \"../../../primitives/createControllableState\";\nimport { mergeRefs, type Ref } from \"../../../primitives/mergeRefs\";\nimport { isOwnClick } from \"../../../utils/ownClick\";\n\nexport interface ITreeNodeItem {\n /** Stable identifier. Falls back to the positional path when omitted. */\n id?: string;\n label: string;\n children?: ITreeNodeItem[];\n /** Hint that the node is expandable even before its children are loaded. */\n hasChildren?: boolean;\n}\n\nexport interface TreeViewProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n nodeIcon?: { opened?: string; closed?: string };\n listIcon?: string;\n data: ITreeNodeItem[];\n expanded?: string[];\n defaultExpanded?: string[];\n onExpandedChange?: (expanded: string[]) => void;\n selected?: string[];\n defaultSelected?: string[];\n /** Reports the full selection plus, for user toggles, the node that just changed. */\n onSelectedChange?: (selected: string[], changed?: { id: string; selected: boolean }) => void;\n /**\n * Enables row selection: a click, Enter or Space on a row toggles its selection. The chevron and the\n * Left/Right keys never change it.\n */\n selectable?: boolean;\n /** Renders a checkbox per node bound to selection. */\n checkboxes?: boolean;\n /**\n * Whether a click, Enter or Space on a row also expands or collapses its children. The chevron and the\n * Right/Left keys always do. Defaults to `true` while the tree is not `selectable` (a row has nothing else to\n * do) and to `false` otherwise, so that selecting a row leaves it open or closed.\n */\n toggleOnRowClick?: boolean;\n /** Custom node renderer. */\n renderLabel?: (item: ITreeNodeItem, nodeId: string) => JSX.Element;\n /**\n * Per-node actions (buttons, a menu trigger), drawn at the end of the row. They sit beside the row's\n * button, not inside it, so they take their own clicks, Enter and Space, focus and accessible names.\n */\n renderActions?: (item: ITreeNodeItem, nodeId: string) => JSX.Element;\n /** Text shown while `loadChildren` is pending; \"Loading…\" unless given. */\n loadingText?: string;\n /** Lazily resolves children the first time a node is expanded. */\n loadChildren?: (item: ITreeNodeItem, nodeId: string) => Promise<ITreeNodeItem[]>;\n /** Test id of the root `<div>`; `tree-view` unless given. */\n \"data-testid\"?: string | undefined;\n ref?: Ref<HTMLDivElement>;\n}\n\ninterface TreeContextValue {\n expandedIds: Accessor<string[]>;\n selectedIds: Accessor<string[]>;\n loadedChildren: Accessor<Record<string, ITreeNodeItem[]>>;\n loadingIds: Accessor<string[]>;\n toggleExpanded: (id: string) => void;\n setOpen: (id: string, open: boolean) => void;\n toggleSelected: (id: string) => void;\n ensureLoaded: (item: ITreeNodeItem, nodeId: string) => void;\n selectable: boolean;\n checkboxes: boolean;\n toggleOnRowClick: boolean;\n loadingText: string;\n nodeIcon: { opened?: string; closed?: string };\n listIcon: string;\n renderLabel: ((item: ITreeNodeItem, nodeId: string) => JSX.Element) | undefined;\n renderActions: ((item: ITreeNodeItem, nodeId: string) => JSX.Element) | undefined;\n hasLoader: boolean;\n}\n\nconst TreeContext = createContext<TreeContextValue>();\n\ninterface TreeEntry {\n id: string;\n item: ITreeNodeItem;\n path: string;\n}\n\n/**\n * Whether two items are the same as far as a row's own markup goes. A caller that refetches hands the tree\n * brand-new objects for the same nodes, and comparing those by identity would rebuild the `renderLabel` /\n * `renderActions` output on every refetch: Solid replaces a dynamic child, so the elements the caller drew\n * (and the focus in them, an open menu anchored to one, a caret) would be thrown away while the row around\n * them survives. Children are compared one level deep — a row draws that it has them, not their subtrees.\n */\nfunction sameItem(a: ITreeNodeItem, b: ITreeNodeItem): boolean {\n if (a === b) return true;\n if (a.id !== b.id || a.label !== b.label || a.hasChildren !== b.hasChildren) return false;\n const left = a.children;\n const right = b.children;\n if (left === right) return true;\n if (!left || !right || left.length !== right.length) return false;\n return left.every((child, idx) => {\n const other = right[idx];\n return !!other && child.id === other.id && child.label === other.label && child.hasChildren === other.hasChildren;\n });\n}\n\n/**\n * The rows of one level, keyed by node id. `For` keys by reference, so it would rebuild every row (and drop\n * the focus in it) whenever the caller hands in new objects for the same nodes. It is given the ids instead:\n * equal strings are the same row, and a row reads its item from the current data.\n */\nfunction TreeNodes(props: { items: ITreeNodeItem[]; path: string; wrap?: boolean }): JSX.Element {\n const entries = createMemo<TreeEntry[]>(() =>\n props.items.map((item, idx) => {\n const path = props.path === \"\" ? `${idx}` : `${props.path}.${idx}`;\n return { id: item.id ?? path, item, path };\n })\n );\n const byId = createMemo(() => new Map(entries().map((entry) => [entry.id, entry])));\n const ids = createMemo(() => entries().map((entry) => entry.id));\n\n return (\n <For each={ids()}>\n {(id) => {\n // A removed row is disposed after the lookup recomputes, so keep the last entry for that pass.\n let last = byId().get(id)!;\n const entry = (): TreeEntry => (last = byId().get(id) ?? last);\n return props.wrap ? (\n <div class=\"smwb-tree__wrapper\" role=\"presentation\">\n <TreeNode entry={entry} />\n </div>\n ) : (\n <TreeNode entry={entry} />\n );\n }}\n </For>\n );\n}\n\nfunction TreeNode(props: { entry: Accessor<TreeEntry> }): JSX.Element {\n const ctx = useContext(TreeContext)!;\n // The id is the row's identity and never changes while the row lives.\n const nodeId = props.entry().id;\n const item = (): ITreeNodeItem => props.entry().item;\n // Names the treeitem: its own content would drag the actions and the checkbox into the node's name.\n const labelId = `${createUniqueId()}-label`;\n // What the caller's renderers see. Held by value, not by identity, so a refetch that hands in new\n // objects for the same nodes does not rebuild the slots below (see sameItem).\n const slotItem = createMemo(() => item(), undefined, { equals: sameItem });\n const labelSlot = createMemo<JSX.Element>(() =>\n ctx.renderLabel ? ctx.renderLabel(slotItem(), nodeId) : slotItem().label\n );\n const resolvedChildren = (): ITreeNodeItem[] | undefined => item().children ?? ctx.loadedChildren()[nodeId];\n const isLazy = (): boolean => ctx.hasLoader && (!!item().hasChildren || !!ctx.loadedChildren()[nodeId]);\n const hasChildNodes = (): boolean => (!!resolvedChildren() && (resolvedChildren()?.length ?? 0) > 0) || isLazy();\n const isOpen = (): boolean => ctx.expandedIds().includes(nodeId);\n const isSelected = (): boolean => ctx.selectedIds().includes(nodeId);\n const isLoading = (): boolean => ctx.loadingIds().includes(nodeId);\n\n const toggleNode = (): void => {\n if (!isOpen()) ctx.ensureLoaded(item(), nodeId);\n ctx.toggleExpanded(nodeId);\n };\n\n const activateRow = (): void => {\n if (ctx.toggleOnRowClick && hasChildNodes()) toggleNode();\n if (ctx.selectable) ctx.toggleSelected(nodeId);\n };\n\n const onKeyDown: JSX.EventHandler<HTMLSpanElement, KeyboardEvent> = (event) => {\n // Keys from controls a custom label draws are theirs.\n if (event.target !== event.currentTarget) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n activateRow();\n } else if (event.key === \"ArrowRight\" && hasChildNodes()) {\n ctx.ensureLoaded(item(), nodeId);\n ctx.setOpen(nodeId, true);\n } else if (event.key === \"ArrowLeft\" && hasChildNodes()) {\n ctx.setOpen(nodeId, false);\n }\n };\n\n const onContentClick: JSX.EventHandler<HTMLSpanElement, MouseEvent> = (event) => {\n if (isOwnClick(event)) activateRow();\n };\n\n return (\n <div\n class={cn(\"smwb-tree__node\", { \"smwb-tree__node_selected\": isSelected() })}\n role=\"treeitem\"\n aria-labelledby={labelId}\n aria-expanded={hasChildNodes() ? isOpen() : undefined}\n aria-selected={ctx.selectable || ctx.checkboxes ? isSelected() : undefined}\n >\n <div class=\"smwb-tree__node__row\">\n {/*\n A pointer shortcut: the keyboard expands with ArrowRight/ArrowLeft on the row, so the chevron is\n decorative, unnamed and no Tab stop. If it ever becomes a real <button>, `aria-hidden` must go with\n it (a focusable element inside `aria-hidden` is an ARIA violation) and it then needs a name plus\n `aria-expanded`.\n */}\n <span class=\"smwb-tree__node__toggle\" aria-hidden=\"true\" onClick={() => hasChildNodes() && toggleNode()}>\n <Show when={hasChildNodes()}>\n <Icon name={isOpen() ? \"expand_more\" : \"chevron_right\"} size={20} />\n </Show>\n </span>\n <Show when={ctx.checkboxes}>\n <input\n type=\"checkbox\"\n class=\"smwb-tree__node__checkbox\"\n checked={isSelected()}\n onChange={() => ctx.toggleSelected(nodeId)}\n aria-label={item().label}\n />\n </Show>\n <span class=\"smwb-tree__node__content\" onClick={onContentClick} onKeyDown={onKeyDown} tabindex={0} role=\"button\">\n <span class=\"smwb-tree__node__label\" id={labelId}>\n <Show when={hasChildNodes()} fallback={<Icon name={ctx.listIcon} size={20} />}>\n <Icon name={isOpen() ? ctx.nodeIcon.opened ?? \"folder_open\" : ctx.nodeIcon.closed ?? \"folder\"} fill={1} size={20} />\n </Show>\n {labelSlot()}\n </span>\n </span>\n <Show when={ctx.renderActions}>\n {(renderActions) => {\n // Created inside the branch that draws it, so SSR and hydration agree on which keys exist.\n const actionsSlot = createMemo<JSX.Element>(() => renderActions()(slotItem(), nodeId));\n return <span class=\"smwb-tree__node__actions\">{actionsSlot()}</span>;\n }}\n </Show>\n </div>\n <Show when={hasChildNodes() && isOpen()}>\n <div role=\"group\">\n <Show\n when={!(isLoading() && !resolvedChildren())}\n fallback={\n <div class=\"smwb-tree__node__loading\" role=\"status\">\n {ctx.loadingText}\n </div>\n }\n >\n <TreeNodes items={resolvedChildren() ?? []} path={props.entry().path} />\n </Show>\n </div>\n </Show>\n </div>\n );\n}\n\nexport function TreeView(props: TreeViewProps): JSX.Element {\n const merged = mergeProps(\n {\n listIcon: \"draft\",\n nodeIcon: { closed: \"folder\", opened: \"folder_open\" } as { opened?: string; closed?: string },\n data: [] as ITreeNodeItem[],\n defaultExpanded: [] as string[],\n defaultSelected: [] as string[],\n selectable: false,\n checkboxes: false,\n loadingText: \"Loading…\",\n },\n props\n );\n const [local, rest] = splitProps(merged, [\n \"class\",\n \"listIcon\",\n \"nodeIcon\",\n \"data\",\n \"expanded\",\n \"defaultExpanded\",\n \"onExpandedChange\",\n \"selected\",\n \"defaultSelected\",\n \"onSelectedChange\",\n \"selectable\",\n \"checkboxes\",\n \"toggleOnRowClick\",\n \"renderLabel\",\n \"renderActions\",\n \"loadingText\",\n \"loadChildren\",\n \"ref\",\n \"data-testid\",\n ]);\n\n const [loadedChildren, setLoadedChildren] = createSignal<Record<string, ITreeNodeItem[]>>({});\n const [loadingIds, setLoadingIds] = createSignal<string[]>([]);\n const [expandedIds, setExpandedIds] = createControllableState<string[]>({\n value: () => local.expanded,\n defaultValue: local.defaultExpanded,\n onChange: (next) => local.onExpandedChange?.(next),\n });\n let lastToggled: { id: string; selected: boolean } | undefined;\n const [selectedIds, setSelectedIds] = createControllableState<string[]>({\n value: () => local.selected,\n defaultValue: local.defaultSelected,\n onChange: (next) => {\n // createControllableState calls onChange synchronously from the setter,\n // so lastToggled still refers to the toggle that caused this change.\n const changed = lastToggled;\n lastToggled = undefined;\n local.onSelectedChange?.(next, changed);\n },\n });\n\n const toggleExpanded = (id: string): void =>\n setExpandedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n\n const setOpen = (id: string, open: boolean): void =>\n setExpandedIds((prev) => {\n const has = prev.includes(id);\n if (open && !has) return [...prev, id];\n if (!open && has) return prev.filter((x) => x !== id);\n return prev;\n });\n\n const toggleSelected = (id: string): void => {\n lastToggled = { id, selected: !selectedIds().includes(id) };\n setSelectedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const ensureLoaded = (item: ITreeNodeItem, nodeId: string): void => {\n if (!local.loadChildren || loadedChildren()[nodeId] || (item.children && item.children.length > 0)) return;\n setLoadingIds((prev) => (prev.includes(nodeId) ? prev : [...prev, nodeId]));\n void local\n .loadChildren(item, nodeId)\n .then((children) => setLoadedChildren((prev) => ({ ...prev, [nodeId]: children })))\n .finally(() => setLoadingIds((prev) => prev.filter((x) => x !== nodeId)));\n };\n\n const contextValue: TreeContextValue = {\n expandedIds,\n selectedIds,\n loadedChildren,\n loadingIds,\n toggleExpanded,\n setOpen,\n toggleSelected,\n ensureLoaded,\n get selectable() {\n return local.selectable;\n },\n get checkboxes() {\n return local.checkboxes;\n },\n get toggleOnRowClick() {\n return local.toggleOnRowClick ?? !local.selectable;\n },\n get loadingText() {\n return local.loadingText;\n },\n get nodeIcon() {\n return local.nodeIcon;\n },\n get listIcon() {\n return local.listIcon;\n },\n get renderLabel() {\n return local.renderLabel;\n },\n get renderActions() {\n return local.renderActions;\n },\n get hasLoader() {\n return !!local.loadChildren;\n },\n };\n\n return (\n <TreeContext.Provider value={contextValue}>\n <div\n {...rest}\n data-testid={local[\"data-testid\"] ?? \"tree-view\"}\n ref={mergeRefs(local.ref)}\n role=\"tree\"\n class={cn(\"smwb-tree\", local.class)}\n >\n <TreeNodes items={local.data} path=\"\" wrap />\n </div>\n </TreeContext.Provider>\n );\n}\n\nexport default TreeView;\n"],"mappings":"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","names":[],"file":"treeView.jsx"}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import "@smwb/ui-styles/less/tokens.entry.less";
|
|
2
2
|
import "@smwb/ui-styles/less/components/modal/modal.entry.less";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Show,
|
|
5
|
+
createEffect,
|
|
6
|
+
createSignal,
|
|
7
|
+
mergeProps,
|
|
8
|
+
on,
|
|
9
|
+
onCleanup,
|
|
10
|
+
splitProps
|
|
11
|
+
} from "solid-js";
|
|
4
12
|
import { Dynamic, Portal, isServer } from "solid-js/web";
|
|
5
13
|
import cn from "clsx";
|
|
6
14
|
import { createCssTransition } from "../../../primitives/createCssTransition";
|
|
7
15
|
import { createFocusTrap } from "../../../primitives/createFocusTrap";
|
|
8
16
|
import { isTopOverlayLayer } from "../../../primitives/overlayLayer";
|
|
17
|
+
import { restoreFocus } from "../../../primitives/restoreFocus";
|
|
9
18
|
import { mergeRefs } from "../../../primitives/mergeRefs";
|
|
10
19
|
const OVERLAY_CLASSNAMES = {
|
|
11
20
|
appear: "smwb-modal__overlay-appear",
|
|
@@ -17,6 +26,11 @@ const OVERLAY_CLASSNAMES = {
|
|
|
17
26
|
exit: "smwb-modal__overlay-exit",
|
|
18
27
|
exitActive: "smwb-modal__overlay-exit-active"
|
|
19
28
|
};
|
|
29
|
+
function isTopModal(overlay) {
|
|
30
|
+
if (!overlay || typeof document === "undefined") return true;
|
|
31
|
+
const open = document.querySelectorAll(".smwb-modal__overlay:not(.smwb-modal__overlay-exit)");
|
|
32
|
+
return open[open.length - 1] === overlay;
|
|
33
|
+
}
|
|
20
34
|
function ModalBase(props) {
|
|
21
35
|
const merged = mergeProps(
|
|
22
36
|
{
|
|
@@ -46,15 +60,30 @@ function ModalBase(props) {
|
|
|
46
60
|
"closeOnEsc",
|
|
47
61
|
"ref"
|
|
48
62
|
]);
|
|
49
|
-
|
|
63
|
+
const [contentEl, setContentEl] = createSignal();
|
|
50
64
|
let overlayEl;
|
|
65
|
+
createEffect(
|
|
66
|
+
on(
|
|
67
|
+
() => local.open,
|
|
68
|
+
(open) => {
|
|
69
|
+
if (!open) return;
|
|
70
|
+
const opener = contentEl()?.contains(document.activeElement) ? null : document.activeElement;
|
|
71
|
+
onCleanup(() => restoreFocus(opener, contentEl()));
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
);
|
|
51
75
|
const transition = createCssTransition({
|
|
52
76
|
in: () => local.open,
|
|
53
77
|
timeout: { appear: 225, enter: 225, exit: 150 },
|
|
54
78
|
classNames: OVERLAY_CLASSNAMES,
|
|
55
79
|
appear: !local.disableAppearAnimation
|
|
56
80
|
});
|
|
57
|
-
createFocusTrap({
|
|
81
|
+
createFocusTrap({
|
|
82
|
+
active: () => local.open && transition.mounted(),
|
|
83
|
+
container: contentEl,
|
|
84
|
+
restoreFocus: false,
|
|
85
|
+
isTopmost: () => isTopModal(overlayEl)
|
|
86
|
+
});
|
|
58
87
|
createEffect(() => {
|
|
59
88
|
if (!local.open || !local.closeOnEsc || !local.onClose) return;
|
|
60
89
|
const onKeyDown = (event) => {
|
|
@@ -77,9 +106,10 @@ function ModalBase(props) {
|
|
|
77
106
|
<Dynamic
|
|
78
107
|
component={local.asForm ? "form" : "div"}
|
|
79
108
|
{...rest}
|
|
80
|
-
ref={mergeRefs(local.ref, (el) =>
|
|
109
|
+
ref={mergeRefs(local.ref, (el) => setContentEl(el))}
|
|
81
110
|
class={cn("smwb-modal", `smwb-${local.size}`, `smwb-${local.animation}`, local.class)}
|
|
82
111
|
onClick={(event) => event.stopPropagation()}
|
|
112
|
+
tabindex={-1}
|
|
83
113
|
role={local.role}
|
|
84
114
|
aria-modal="true"
|
|
85
115
|
>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/feedBack/modal/modal.tsx"],"sourcesContent":["import \"@smwb/ui-styles/less/tokens.entry.less\";\nimport \"@smwb/ui-styles/less/components/modal/modal.entry.less\";\nimport { type JSX, type ParentProps, Show, createEffect, mergeProps, onCleanup, splitProps } from \"solid-js\";\nimport { Dynamic, Portal, isServer } from \"solid-js/web\";\nimport cn from \"clsx\";\nimport { createCssTransition } from \"../../../primitives/createCssTransition\";\nimport { createFocusTrap } from \"../../../primitives/createFocusTrap\";\nimport { isTopOverlayLayer } from \"../../../primitives/overlayLayer\";\nimport { mergeRefs, type Ref } from \"../../../primitives/mergeRefs\";\n\nexport interface ModalProps {\n size?: \"small\" | \"medium\" | \"large\" | \"fullscreen\";\n closeOnOutsideClick?: boolean;\n onClose?: () => void;\n open: boolean;\n animation?: \"fade\" | \"scale\" | \"drop\";\n class?: string;\n backdrop?: \"blured\" | \"dark\" | \"transparent\" | \"darkBlured\";\n asForm?: boolean;\n disableAppearAnimation?: boolean;\n /** ARIA role of the dialog. */\n role?: \"dialog\" | \"alertdialog\";\n /** Close the modal when Escape is pressed. */\n closeOnEsc?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n ref?: Ref<HTMLDivElement>;\n}\n\nconst OVERLAY_CLASSNAMES = {\n appear: \"smwb-modal__overlay-appear\",\n appearActive: \"smwb-modal__overlay-appear-active\",\n appearDone: \"smwb-modal__overlay-appear-done\",\n enter: \"smwb-modal__overlay-enter\",\n enterActive: \"smwb-modal__overlay-enter-active\",\n enterDone: \"smwb-modal__overlay-enter-done\",\n exit: \"smwb-modal__overlay-exit\",\n exitActive: \"smwb-modal__overlay-exit-active\",\n};\n\nfunction ModalBase(props: ParentProps<ModalProps>): JSX.Element {\n const merged = mergeProps(\n {\n animation: \"fade\" as const,\n backdrop: \"dark\" as const,\n size: \"large\" as const,\n closeOnOutsideClick: true,\n asForm: false,\n disableAppearAnimation: false,\n role: \"dialog\" as const,\n closeOnEsc: true,\n },\n props\n );\n const [local, rest] = splitProps(merged, [\n \"children\",\n \"onClose\",\n \"open\",\n \"class\",\n \"animation\",\n \"backdrop\",\n \"size\",\n \"closeOnOutsideClick\",\n \"asForm\",\n \"disableAppearAnimation\",\n \"role\",\n \"closeOnEsc\",\n \"ref\",\n ]);\n\n let contentEl: HTMLDivElement | undefined;\n let overlayEl: HTMLDivElement | undefined;\n\n const transition = createCssTransition({\n in: () => local.open,\n timeout: { appear: 225, enter: 225, exit: 150 },\n classNames: OVERLAY_CLASSNAMES,\n appear: !local.disableAppearAnimation,\n });\n\n createFocusTrap({ active: () => local.open && transition.mounted(), container: () => contentEl });\n\n createEffect(() => {\n if (!local.open || !local.closeOnEsc || !local.onClose) return;\n const onKeyDown = (event: KeyboardEvent): void => {\n // Only the topmost overlay layer reacts to Escape, and not to one handled inside\n // it, e.g. by a menu closing on it.\n if (event.key === \"Escape\" && !event.defaultPrevented && isTopOverlayLayer(overlayEl)) local.onClose?.();\n };\n document.addEventListener(\"keydown\", onKeyDown);\n onCleanup(() => document.removeEventListener(\"keydown\", onKeyDown));\n });\n\n // Always attached and checks the props itself. Solid binds event handlers\n // once, and the portal builds the overlay in a tracked scope, so choosing the\n // handler by these props there would rebuild the dialog, content included,\n // whenever one of them changes.\n const onOverlayClick = (): void => {\n if (local.closeOnOutsideClick) local.onClose?.();\n };\n\n return (\n <Show when={transition.mounted()}>\n <Portal mount={(isServer ? undefined : document.body) as Node}>\n <div\n ref={(el) => (overlayEl = el)}\n data-smwb-overlay-layer\n class={cn(\"smwb-modal__overlay\", `smwb-${local.backdrop}`, `smwb-${local.size}`, transition.classes())}\n onClick={onOverlayClick}\n >\n <Dynamic\n component={local.asForm ? \"form\" : \"div\"}\n {...rest}\n ref={mergeRefs(local.ref, (el) => (contentEl = el as HTMLDivElement))}\n class={cn(\"smwb-modal\", `smwb-${local.size}`, `smwb-${local.animation}`, local.class)}\n onClick={(event: MouseEvent) => event.stopPropagation()}\n role={local.role}\n aria-modal=\"true\"\n >\n {local.children}\n </Dynamic>\n </div>\n </Portal>\n </Show>\n );\n}\n\nexport interface ModalSlotProps {\n class?: string;\n}\n\nexport function Header(props: ParentProps<ModalSlotProps>): JSX.Element {\n return <div class={cn(\"smwb-modal__header\", props.class)}>{props.children}</div>;\n}\n\nexport function Content(props: ParentProps<ModalSlotProps>): JSX.Element {\n return <div class={cn(\"smwb-modal__content\", props.class)}>{props.children}</div>;\n}\n\nexport function Footer(props: ParentProps<ModalSlotProps>): JSX.Element {\n return <div class={cn(\"smwb-modal__footer\", props.class)}>{props.children}</div>;\n}\n\nexport const Modal = Object.assign(ModalBase, { Footer, Header, Content });\n\nexport default Modal;\n"],"mappings":"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","names":[],"file":"modal.jsx"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/feedBack/modal/modal.tsx"],"sourcesContent":["import \"@smwb/ui-styles/less/tokens.entry.less\";\nimport \"@smwb/ui-styles/less/components/modal/modal.entry.less\";\nimport {\n type JSX,\n type ParentProps,\n Show,\n createEffect,\n createSignal,\n mergeProps,\n on,\n onCleanup,\n splitProps,\n} from \"solid-js\";\nimport { Dynamic, Portal, isServer } from \"solid-js/web\";\nimport cn from \"clsx\";\nimport { createCssTransition } from \"../../../primitives/createCssTransition\";\nimport { createFocusTrap } from \"../../../primitives/createFocusTrap\";\nimport { isTopOverlayLayer } from \"../../../primitives/overlayLayer\";\nimport { restoreFocus } from \"../../../primitives/restoreFocus\";\nimport { mergeRefs, type Ref } from \"../../../primitives/mergeRefs\";\n\nexport interface ModalProps {\n size?: \"small\" | \"medium\" | \"large\" | \"fullscreen\";\n closeOnOutsideClick?: boolean;\n onClose?: () => void;\n open: boolean;\n animation?: \"fade\" | \"scale\" | \"drop\";\n class?: string;\n backdrop?: \"blured\" | \"dark\" | \"transparent\" | \"darkBlured\";\n asForm?: boolean;\n disableAppearAnimation?: boolean;\n /** ARIA role of the dialog. */\n role?: \"dialog\" | \"alertdialog\";\n /** Close the modal when Escape is pressed. */\n closeOnEsc?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n ref?: Ref<HTMLDivElement>;\n}\n\nconst OVERLAY_CLASSNAMES = {\n appear: \"smwb-modal__overlay-appear\",\n appearActive: \"smwb-modal__overlay-appear-active\",\n appearDone: \"smwb-modal__overlay-appear-done\",\n enter: \"smwb-modal__overlay-enter\",\n enterActive: \"smwb-modal__overlay-enter-active\",\n enterDone: \"smwb-modal__overlay-enter-done\",\n exit: \"smwb-modal__overlay-exit\",\n exitActive: \"smwb-modal__overlay-exit-active\",\n};\n\n/**\n * Whether `overlay` is the last open Modal overlay; a dialog stacked above it owns Tab. Fading-out\n * ones do not count. Not `isTopOverlayLayer`: menus, select dropdowns and pickers are overlay\n * layers too, and a select dropdown open inside a Modal must not switch the Modal's trap off.\n */\nfunction isTopModal(overlay: Element | null | undefined): boolean {\n if (!overlay || typeof document === \"undefined\") return true;\n const open = document.querySelectorAll(\".smwb-modal__overlay:not(.smwb-modal__overlay-exit)\");\n return open[open.length - 1] === overlay;\n}\n\n/**\n * A modal dialog: portaled to `<body>`, animated, closed by Escape or a backdrop click.\n *\n * While open it traps Tab/Shift+Tab inside the dialog and moves the focus into it (the first tab\n * stop, else the dialog itself), unless a child has already focused itself. On close, and on\n * unmount while open, the focus goes back to the element that had it when the dialog opened —\n * unless the app has moved the focus elsewhere by then.\n * Of stacked dialogs only the topmost one handles Tab.\n */\nfunction ModalBase(props: ParentProps<ModalProps>): JSX.Element {\n const merged = mergeProps(\n {\n animation: \"fade\" as const,\n backdrop: \"dark\" as const,\n size: \"large\" as const,\n closeOnOutsideClick: true,\n asForm: false,\n disableAppearAnimation: false,\n role: \"dialog\" as const,\n closeOnEsc: true,\n },\n props\n );\n const [local, rest] = splitProps(merged, [\n \"children\",\n \"onClose\",\n \"open\",\n \"class\",\n \"animation\",\n \"backdrop\",\n \"size\",\n \"closeOnOutsideClick\",\n \"asForm\",\n \"disableAppearAnimation\",\n \"role\",\n \"closeOnEsc\",\n \"ref\",\n ]);\n\n // A signal, not a plain `let`: the dialog is built by a portal, so on a closed→open transition\n // the trap's effect runs before the ref below has assigned anything. A plain variable is not\n // tracked, so the trap bailed on the empty container and never armed itself again — Tab then\n // walked focus out of an open dialog. Writing a signal re-runs the trap once the node lands.\n const [contentEl, setContentEl] = createSignal<HTMLDivElement | undefined>();\n let overlayEl: HTMLDivElement | undefined;\n\n // Created before the transition and the trap: effects run in creation order, so the opener is read\n // before the trap's `autoFocus` moves the focus and before a child's `onMount` focuses itself.\n createEffect(\n on(\n () => local.open,\n (open) => {\n if (!open) return;\n // The element focused when the dialog opens gets focus back when it closes or unmounts while open,\n // unless the app has moved focus out of the dialog by then (see restoreFocus).\n const opener = contentEl()?.contains(document.activeElement) ? null : document.activeElement;\n onCleanup(() => restoreFocus(opener, contentEl()));\n }\n )\n );\n\n const transition = createCssTransition({\n in: () => local.open,\n timeout: { appear: 225, enter: 225, exit: 150 },\n classNames: OVERLAY_CLASSNAMES,\n appear: !local.disableAppearAnimation,\n });\n\n createFocusTrap({\n active: () => local.open && transition.mounted(),\n container: contentEl,\n restoreFocus: false,\n isTopmost: () => isTopModal(overlayEl),\n });\n\n createEffect(() => {\n if (!local.open || !local.closeOnEsc || !local.onClose) return;\n const onKeyDown = (event: KeyboardEvent): void => {\n // Only the topmost overlay layer reacts to Escape, and not to one handled inside\n // it, e.g. by a menu closing on it.\n if (event.key === \"Escape\" && !event.defaultPrevented && isTopOverlayLayer(overlayEl)) local.onClose?.();\n };\n document.addEventListener(\"keydown\", onKeyDown);\n onCleanup(() => document.removeEventListener(\"keydown\", onKeyDown));\n });\n\n // Always attached and checks the props itself. Solid binds event handlers\n // once, and the portal builds the overlay in a tracked scope, so choosing the\n // handler by these props there would rebuild the dialog, content included,\n // whenever one of them changes.\n const onOverlayClick = (): void => {\n if (local.closeOnOutsideClick) local.onClose?.();\n };\n\n return (\n <Show when={transition.mounted()}>\n <Portal mount={(isServer ? undefined : document.body) as Node}>\n <div\n ref={(el) => (overlayEl = el)}\n data-smwb-overlay-layer\n class={cn(\"smwb-modal__overlay\", `smwb-${local.backdrop}`, `smwb-${local.size}`, transition.classes())}\n onClick={onOverlayClick}\n >\n <Dynamic\n component={local.asForm ? \"form\" : \"div\"}\n {...rest}\n ref={mergeRefs(local.ref, (el) => setContentEl(el as HTMLDivElement))}\n class={cn(\"smwb-modal\", `smwb-${local.size}`, `smwb-${local.animation}`, local.class)}\n onClick={(event: MouseEvent) => event.stopPropagation()}\n tabindex={-1}\n role={local.role}\n aria-modal=\"true\"\n >\n {local.children}\n </Dynamic>\n </div>\n </Portal>\n </Show>\n );\n}\n\nexport interface ModalSlotProps {\n class?: string;\n}\n\nexport function Header(props: ParentProps<ModalSlotProps>): JSX.Element {\n return <div class={cn(\"smwb-modal__header\", props.class)}>{props.children}</div>;\n}\n\nexport function Content(props: ParentProps<ModalSlotProps>): JSX.Element {\n return <div class={cn(\"smwb-modal__content\", props.class)}>{props.children}</div>;\n}\n\nexport function Footer(props: ParentProps<ModalSlotProps>): JSX.Element {\n return <div class={cn(\"smwb-modal__footer\", props.class)}>{props.children}</div>;\n}\n\nexport const Modal = Object.assign(ModalBase, { Footer, Header, Content });\n\nexport default Modal;\n"],"mappings":"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","names":[],"file":"modal.jsx"}
|
|
@@ -7,6 +7,7 @@ import { Icon } from "../../base/icon";
|
|
|
7
7
|
import { mergeRefs } from "../../../primitives/mergeRefs";
|
|
8
8
|
import { useButtonGroup } from "../buttonGroups/buttonGroupContext";
|
|
9
9
|
import { callHandler } from "../../../primitives/callHandler";
|
|
10
|
+
import { resolveLinkRel, resolveLinkTarget } from "../../../utils/linkAttrs";
|
|
10
11
|
function Button(props) {
|
|
11
12
|
const group = useButtonGroup();
|
|
12
13
|
const merged = mergeProps(
|
|
@@ -29,6 +30,8 @@ function Button(props) {
|
|
|
29
30
|
"icon",
|
|
30
31
|
"iconProps",
|
|
31
32
|
"href",
|
|
33
|
+
"target",
|
|
34
|
+
"rel",
|
|
32
35
|
"class",
|
|
33
36
|
"disabled",
|
|
34
37
|
"children",
|
|
@@ -43,6 +46,7 @@ function Button(props) {
|
|
|
43
46
|
"ref",
|
|
44
47
|
"data-testid"
|
|
45
48
|
]);
|
|
49
|
+
const linkTarget = () => resolveLinkTarget(local.target);
|
|
46
50
|
const color = () => local.color ?? group?.color ?? local.colorTheme;
|
|
47
51
|
const disabled = () => local.disabled ?? group?.disabled;
|
|
48
52
|
const fullWidth = () => local.fullWidth ?? group?.fullWidth;
|
|
@@ -96,8 +100,8 @@ function Button(props) {
|
|
|
96
100
|
ref={mergeRefs(local.ref)}
|
|
97
101
|
class={classes()}
|
|
98
102
|
href={local.href}
|
|
99
|
-
target=
|
|
100
|
-
rel=
|
|
103
|
+
target={linkTarget()}
|
|
104
|
+
rel={resolveLinkRel(local.rel, linkTarget())}
|
|
101
105
|
onPointerDown={onPointerDown}
|
|
102
106
|
>
|
|
103
107
|
{content()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/inputs/button/button.tsx"],"sourcesContent":["import \"@smwb/ui-styles/less/tokens.entry.less\";\nimport \"@smwb/ui-styles/less/components/button/button.entry.less\";\nimport { type JSX, type ParentProps, Show, children, mergeProps, splitProps } from \"solid-js\";\nimport cn from \"clsx\";\nimport { Ripple, type RippleActionsRef } from \"../../base/ripple\";\nimport { Icon, type IconProps } from \"../../base/icon\";\nimport { mergeRefs, type Ref } from \"../../../primitives/mergeRefs\";\nimport { useButtonGroup } from \"../buttonGroups/buttonGroupContext\";\nimport { callHandler } from \"../../../primitives/callHandler\";\n\nexport interface ButtonProps extends JSX.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement> {\n /** Button text. */\n label?: string;\n /** Visual style of the button. */\n variant?: \"contained\" | \"text\" | \"outlined\";\n /** Button size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** Icon as an element (e.g. <Icon/>) or a string (icon name / url / base64). */\n icon?: JSX.Element | string;\n /** Props forwarded to the <Icon/> when `icon` is a string. */\n iconProps?: Omit<IconProps, \"name\">;\n /** @deprecated use `color`. Kept for backward compatibility. */\n colorTheme?: \"primary\";\n /** Semantic color, resolved through `--smwb-*Color*` tokens. */\n color?: \"primary\" | \"secondary\" | \"error\" | \"success\" | \"warning\" | \"info\";\n /** When set, the component renders as an <a>. */\n href?: string;\n disabled?: boolean;\n type?: \"button\" | \"submit\" | \"reset\";\n /** Stretch to the full width of the container. */\n fullWidth?: boolean;\n /** Center the ripple effect. */\n rippleCenter?: boolean;\n /** Disable the ripple effect. */\n disableRipple?: boolean;\n /** Test id of the root; `button`, or `button-link` for a link, unless given. */\n \"data-testid\"?: string | undefined;\n ref?: Ref<HTMLButtonElement | HTMLAnchorElement>;\n}\n\nexport function Button(props: ParentProps<ButtonProps>): JSX.Element {\n const group = useButtonGroup();\n const merged = mergeProps(\n {\n get variant(): NonNullable<ButtonProps[\"variant\"]> {\n return group?.variant ?? \"contained\";\n },\n get size(): NonNullable<ButtonProps[\"size\"]> {\n return group?.size ?? \"medium\";\n },\n get colorTheme(): NonNullable<ButtonProps[\"colorTheme\"]> {\n return group?.colorTheme ?? \"primary\";\n },\n },\n props\n );\n const [local, rest] = splitProps(merged, [\n \"label\",\n \"variant\",\n \"icon\",\n \"iconProps\",\n \"href\",\n \"class\",\n \"disabled\",\n \"children\",\n \"fullWidth\",\n \"rippleCenter\",\n \"disableRipple\",\n // The button sets this on its root too; its own handler calls the caller's first.\n \"onPointerDown\",\n \"size\",\n \"colorTheme\",\n \"color\",\n \"ref\",\n \"data-testid\",\n ]);\n\n const color = (): string => local.color ?? group?.color ?? local.colorTheme;\n const disabled = (): boolean | undefined => local.disabled ?? group?.disabled;\n const fullWidth = (): boolean | undefined => local.fullWidth ?? group?.fullWidth;\n let rippleActions: RippleActionsRef | undefined;\n\n const classes = (): string =>\n cn(\n \"smwb-button\",\n `smwb-${local.variant}`,\n `smwb-${local.size}`,\n color() === \"primary\" ? \"smwb-primary\" : `smwb-button_color-${color()}`,\n group && \"smwb-button-group__grouped\",\n local.class,\n {\n \"smwb-disabled\": disabled(),\n \"smwb-full-width\": fullWidth(),\n }\n );\n\n // Ripple on pointerdown so it fires for touch and pen, not just mouse.\n const onPointerDown: JSX.EventHandler<HTMLButtonElement | HTMLAnchorElement, PointerEvent> = (event) => {\n callHandler(local.onPointerDown, event);\n if (!disabled()) {\n rippleActions?.onRipple(event);\n }\n };\n\n // Read the icon once: markup passed as a prop is created anew on every read,\n // and during hydration the copy made for a <Show> test has no server DOM node.\n const icon = children(() => local.icon);\n const iconElement = (): JSX.Element => {\n const resolved = icon();\n return typeof resolved === \"string\" ? <Icon {...(local.iconProps ?? {})} name={resolved} /> : resolved;\n };\n\n const content = (): JSX.Element => (\n <>\n <Show when={icon()}>{iconElement()}</Show>\n {local.label ? local.label : local.children}\n <Show when={!local.disableRipple}>\n <Ripple actionRef={(actions) => (rippleActions = actions)} center={local.rippleCenter} />\n </Show>\n </>\n );\n\n return (\n <Show\n when={local.href}\n fallback={\n <button\n data-testid={local[\"data-testid\"] ?? \"button\"}\n {...rest}\n ref={mergeRefs(local.ref)}\n class={classes()}\n onPointerDown={onPointerDown}\n disabled={!!disabled()}\n >\n {content()}\n </button>\n }\n >\n <a\n data-testid={local[\"data-testid\"] ?? \"button-link\"}\n {...rest}\n ref={mergeRefs(local.ref)}\n class={classes()}\n href={local.href}\n target
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/inputs/button/button.tsx"],"sourcesContent":["import \"@smwb/ui-styles/less/tokens.entry.less\";\nimport \"@smwb/ui-styles/less/components/button/button.entry.less\";\nimport { type JSX, type ParentProps, Show, children, mergeProps, splitProps } from \"solid-js\";\nimport cn from \"clsx\";\nimport { Ripple, type RippleActionsRef } from \"../../base/ripple\";\nimport { Icon, type IconProps } from \"../../base/icon\";\nimport { mergeRefs, type Ref } from \"../../../primitives/mergeRefs\";\nimport { useButtonGroup } from \"../buttonGroups/buttonGroupContext\";\nimport { callHandler } from \"../../../primitives/callHandler\";\nimport { resolveLinkRel, resolveLinkTarget } from \"../../../utils/linkAttrs\";\n\nexport interface ButtonProps extends JSX.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement> {\n /** Button text. */\n label?: string;\n /** Visual style of the button. */\n variant?: \"contained\" | \"text\" | \"outlined\";\n /** Button size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** Icon as an element (e.g. <Icon/>) or a string (icon name / url / base64). */\n icon?: JSX.Element | string;\n /** Props forwarded to the <Icon/> when `icon` is a string. */\n iconProps?: Omit<IconProps, \"name\">;\n /** @deprecated use `color`. Kept for backward compatibility. */\n colorTheme?: \"primary\";\n /** Semantic color, resolved through `--smwb-*Color*` tokens. */\n color?: \"primary\" | \"secondary\" | \"error\" | \"success\" | \"warning\" | \"info\";\n /** When set, the component renders as an <a>. */\n href?: string;\n /**\n * Where a link (with `href`) opens. By default `\"_blank\"`: a new tab. `null` leaves the `target`\n * attribute out, so the link opens in place, like an internal one; an empty string does the same, and\n * any other string is used as is.\n */\n target?: string | null | undefined;\n /**\n * The `rel` of a link (with `href`). By default `\"noreferrer\"` for a link that opens another tab or\n * window, and none for one that opens in place. Your own value replaces the default, so add `noreferrer` yourself\n * if you still want it; an empty string drops the attribute.\n */\n rel?: string | undefined;\n disabled?: boolean;\n type?: \"button\" | \"submit\" | \"reset\";\n /** Stretch to the full width of the container. */\n fullWidth?: boolean;\n /** Center the ripple effect. */\n rippleCenter?: boolean;\n /** Disable the ripple effect. */\n disableRipple?: boolean;\n /** Test id of the root; `button`, or `button-link` for a link, unless given. */\n \"data-testid\"?: string | undefined;\n ref?: Ref<HTMLButtonElement | HTMLAnchorElement>;\n}\n\nexport function Button(props: ParentProps<ButtonProps>): JSX.Element {\n const group = useButtonGroup();\n const merged = mergeProps(\n {\n get variant(): NonNullable<ButtonProps[\"variant\"]> {\n return group?.variant ?? \"contained\";\n },\n get size(): NonNullable<ButtonProps[\"size\"]> {\n return group?.size ?? \"medium\";\n },\n get colorTheme(): NonNullable<ButtonProps[\"colorTheme\"]> {\n return group?.colorTheme ?? \"primary\";\n },\n },\n props\n );\n const [local, rest] = splitProps(merged, [\n \"label\",\n \"variant\",\n \"icon\",\n \"iconProps\",\n \"href\",\n \"target\",\n \"rel\",\n \"class\",\n \"disabled\",\n \"children\",\n \"fullWidth\",\n \"rippleCenter\",\n \"disableRipple\",\n // The button sets this on its root too; its own handler calls the caller's first.\n \"onPointerDown\",\n \"size\",\n \"colorTheme\",\n \"color\",\n \"ref\",\n \"data-testid\",\n ]);\n\n const linkTarget = (): string | undefined => resolveLinkTarget(local.target);\n const color = (): string => local.color ?? group?.color ?? local.colorTheme;\n const disabled = (): boolean | undefined => local.disabled ?? group?.disabled;\n const fullWidth = (): boolean | undefined => local.fullWidth ?? group?.fullWidth;\n let rippleActions: RippleActionsRef | undefined;\n\n const classes = (): string =>\n cn(\n \"smwb-button\",\n `smwb-${local.variant}`,\n `smwb-${local.size}`,\n color() === \"primary\" ? \"smwb-primary\" : `smwb-button_color-${color()}`,\n group && \"smwb-button-group__grouped\",\n local.class,\n {\n \"smwb-disabled\": disabled(),\n \"smwb-full-width\": fullWidth(),\n }\n );\n\n // Ripple on pointerdown so it fires for touch and pen, not just mouse.\n const onPointerDown: JSX.EventHandler<HTMLButtonElement | HTMLAnchorElement, PointerEvent> = (event) => {\n callHandler(local.onPointerDown, event);\n if (!disabled()) {\n rippleActions?.onRipple(event);\n }\n };\n\n // Read the icon once: markup passed as a prop is created anew on every read,\n // and during hydration the copy made for a <Show> test has no server DOM node.\n const icon = children(() => local.icon);\n const iconElement = (): JSX.Element => {\n const resolved = icon();\n return typeof resolved === \"string\" ? <Icon {...(local.iconProps ?? {})} name={resolved} /> : resolved;\n };\n\n const content = (): JSX.Element => (\n <>\n <Show when={icon()}>{iconElement()}</Show>\n {local.label ? local.label : local.children}\n <Show when={!local.disableRipple}>\n <Ripple actionRef={(actions) => (rippleActions = actions)} center={local.rippleCenter} />\n </Show>\n </>\n );\n\n return (\n <Show\n when={local.href}\n fallback={\n <button\n data-testid={local[\"data-testid\"] ?? \"button\"}\n {...rest}\n ref={mergeRefs(local.ref)}\n class={classes()}\n onPointerDown={onPointerDown}\n disabled={!!disabled()}\n >\n {content()}\n </button>\n }\n >\n <a\n data-testid={local[\"data-testid\"] ?? \"button-link\"}\n {...rest}\n ref={mergeRefs(local.ref)}\n class={classes()}\n href={local.href}\n target={linkTarget()}\n rel={resolveLinkRel(local.rel, linkTarget())}\n onPointerDown={onPointerDown}\n >\n {content()}\n </a>\n </Show>\n );\n}\n\nexport default Button;\n"],"mappings":"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","names":[],"file":"button.jsx"}
|