@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
import { createEffect as d, onCleanup as m } from "solid-js";
|
|
2
|
-
const
|
|
3
|
-
function
|
|
4
|
-
const i =
|
|
2
|
+
const p = 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
3
|
+
function b(o) {
|
|
4
|
+
const i = o.restoreFocus ?? !0, l = o.autoFocus ?? !0;
|
|
5
5
|
d(() => {
|
|
6
|
-
if (!
|
|
7
|
-
const
|
|
8
|
-
if (!
|
|
9
|
-
const
|
|
6
|
+
if (!o.active()) return;
|
|
7
|
+
const t = o.container();
|
|
8
|
+
if (!t) return;
|
|
9
|
+
const s = document.activeElement, a = () => Array.from(t.querySelectorAll(p)).filter(
|
|
10
10
|
(e) => e.offsetParent !== null || e === document.activeElement
|
|
11
11
|
);
|
|
12
|
-
l && (a()[0] ??
|
|
12
|
+
l && !t.contains(document.activeElement) && (a()[0] ?? t).focus({ preventScroll: !0 });
|
|
13
13
|
const f = (e) => {
|
|
14
|
-
if (e.key !== "Tab") return;
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
e.preventDefault();
|
|
14
|
+
if (e.key !== "Tab" || o.isTopmost && !o.isTopmost()) return;
|
|
15
|
+
const u = a(), n = u[0], r = u[u.length - 1];
|
|
16
|
+
if (!n || !r) {
|
|
17
|
+
e.preventDefault(), t.focus({ preventScroll: !0 });
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
const
|
|
21
|
-
e.shiftKey &&
|
|
20
|
+
const c = document.activeElement;
|
|
21
|
+
c === t ? (e.preventDefault(), (e.shiftKey ? r : n).focus()) : e.shiftKey && c === n ? (e.preventDefault(), r.focus()) : !e.shiftKey && c === r ? (e.preventDefault(), n.focus()) : t.contains(c) || (e.preventDefault(), n.focus());
|
|
22
22
|
};
|
|
23
23
|
document.addEventListener("keydown", f, !0), m(() => {
|
|
24
|
-
document.removeEventListener("keydown", f, !0), i &&
|
|
24
|
+
document.removeEventListener("keydown", f, !0), i && s && !t.contains(s) && s.focus({ preventScroll: !0 });
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
export {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
p as FOCUSABLE,
|
|
30
|
+
b as createFocusTrap
|
|
31
31
|
};
|
|
32
32
|
//# sourceMappingURL=createFocusTrap.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFocusTrap.js","sources":["../../../src/primitives/createFocusTrap.ts"],"sourcesContent":["import { type Accessor, createEffect, onCleanup } from \"solid-js\";\n\n/** Elements in the Tab order (hidden ones match too). */\nexport const FOCUSABLE =\n 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\nexport interface CreateFocusTrapOptions {\n /** Trap is active only while this returns true. */\n active: Accessor<boolean>;\n /** The element whose focusable descendants are trapped. */\n container: Accessor<HTMLElement | undefined>;\n /** Restore focus to the previously focused element on deactivate. */\n restoreFocus?: boolean;\n /** Focus the first focusable element on activate. */\n autoFocus?: boolean;\n}\n\n/**\n * Confines Tab/Shift+Tab focus within `container` while `active`. Restores\n * focus to the previously focused element on teardown. Solid port of\n * summer-ui's useFocusTrap.\n */\nexport function createFocusTrap(options: CreateFocusTrapOptions): void {\n const restoreFocus = options.restoreFocus ?? true;\n const autoFocus = options.autoFocus ?? true;\n\n createEffect(() => {\n if (!options.active()) return;\n const container = options.container();\n if (!container) return;\n\n const prevFocused = document.activeElement as HTMLElement | null;\n\n const focusables = (): HTMLElement[] =>\n Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE)).filter(\n (el) => el.offsetParent !== null || el === document.activeElement\n );\n\n if (autoFocus) {\n (focusables()[0] ?? container).focus({ preventScroll: true });\n }\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== \"Tab\") return;\n const items = focusables();\n const first = items[0];\n const last = items[items.length - 1];\n if (!first || !last) {\n event.preventDefault();\n return;\n }\n const activeEl = document.activeElement;\n if (event.shiftKey && activeEl === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && activeEl === last) {\n event.preventDefault();\n first.focus();\n } else if (!container.contains(activeEl)) {\n event.preventDefault();\n first.focus();\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown, true);\n onCleanup(() => {\n document.removeEventListener(\"keydown\", onKeyDown, true);\n if (restoreFocus && prevFocused) {\n prevFocused.focus({ preventScroll: true });\n }\n });\n });\n}\n"],"names":["FOCUSABLE","createFocusTrap","options","restoreFocus","autoFocus","createEffect","container","prevFocused","focusables","el","onKeyDown","event","items","first","last","activeEl","onCleanup"],"mappings":";AAGO,MAAMA,IACX;
|
|
1
|
+
{"version":3,"file":"createFocusTrap.js","sources":["../../../src/primitives/createFocusTrap.ts"],"sourcesContent":["import { type Accessor, createEffect, onCleanup } from \"solid-js\";\n\n/** Elements in the Tab order (hidden ones match too). */\nexport const FOCUSABLE =\n 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\nexport interface CreateFocusTrapOptions {\n /** Trap is active only while this returns true. */\n active: Accessor<boolean>;\n /** The element whose focusable descendants are trapped. */\n container: Accessor<HTMLElement | undefined>;\n /** Restore focus to the previously focused element on deactivate. */\n restoreFocus?: boolean;\n /** Focus the first focusable element on activate. */\n autoFocus?: boolean;\n /**\n * Checked on every Tab. While it returns false the trap leaves the key alone, so a trap stacked above\n * this one (a dialog opened from inside the container) handles it. Defaults to always true.\n */\n isTopmost?: () => boolean;\n}\n\n/**\n * Confines Tab/Shift+Tab focus within `container` while `active`. Restores\n * focus to the previously focused element on teardown. Solid port of\n * summer-ui's useFocusTrap.\n */\nexport function createFocusTrap(options: CreateFocusTrapOptions): void {\n const restoreFocus = options.restoreFocus ?? true;\n const autoFocus = options.autoFocus ?? true;\n\n createEffect(() => {\n if (!options.active()) return;\n const container = options.container();\n if (!container) return;\n\n const prevFocused = document.activeElement as HTMLElement | null;\n\n const focusables = (): HTMLElement[] =>\n Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE)).filter(\n (el) => el.offsetParent !== null || el === document.activeElement\n );\n\n // A child that has already taken the focus (one focusing itself on mount) keeps it; the trap\n // only brings in a focus that is still outside.\n if (autoFocus && !container.contains(document.activeElement)) {\n (focusables()[0] ?? container).focus({ preventScroll: true });\n }\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== \"Tab\") return;\n // Read at key time, not tracked: it is a plain callback, and a new identity per render must not\n // re-arm the trap.\n if (options.isTopmost && !options.isTopmost()) return;\n const items = focusables();\n const first = items[0];\n const last = items[items.length - 1];\n if (!first || !last) {\n event.preventDefault();\n // Nothing left to tab through (e.g. every control disabled) and Chromium has dropped the\n // focus to <body>: pull it back into the container instead of leaving it behind the dialog.\n container.focus({ preventScroll: true });\n return;\n }\n const activeEl = document.activeElement;\n if (activeEl === container) {\n // The container itself holds the focus (a press on its empty area, or the `autoFocus`\n // fallback): it is not a tab stop, so the browser would step to the page behind it.\n event.preventDefault();\n (event.shiftKey ? last : first).focus();\n } else if (event.shiftKey && activeEl === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && activeEl === last) {\n event.preventDefault();\n first.focus();\n } else if (!container.contains(activeEl)) {\n event.preventDefault();\n first.focus();\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown, true);\n onCleanup(() => {\n document.removeEventListener(\"keydown\", onKeyDown, true);\n // Restoring a node from inside the container is meaningless: that node is being torn down\n // with it, and focusing a detached element drops the focus to <body>, undoing whatever the\n // opener restored first. The element to go back to is the one focused before the trap armed,\n // which can be the container's own field when a caller focuses it before the trap gets here.\n if (restoreFocus && prevFocused && !container.contains(prevFocused)) {\n prevFocused.focus({ preventScroll: true });\n }\n });\n });\n}\n"],"names":["FOCUSABLE","createFocusTrap","options","restoreFocus","autoFocus","createEffect","container","prevFocused","focusables","el","onKeyDown","event","items","first","last","activeEl","onCleanup"],"mappings":";AAGO,MAAMA,IACX;AAuBK,SAASC,EAAgBC,GAAuC;AACrE,QAAMC,IAAeD,EAAQ,gBAAgB,IACvCE,IAAYF,EAAQ,aAAa;AAEvC,EAAAG,EAAa,MAAM;AACjB,QAAI,CAACH,EAAQ,SAAU;AACvB,UAAMI,IAAYJ,EAAQ,UAAA;AAC1B,QAAI,CAACI,EAAW;AAEhB,UAAMC,IAAc,SAAS,eAEvBC,IAAa,MACjB,MAAM,KAAKF,EAAU,iBAA8BN,CAAS,CAAC,EAAE;AAAA,MAC7D,CAACS,MAAOA,EAAG,iBAAiB,QAAQA,MAAO,SAAS;AAAA,IAAA;AAKxD,IAAIL,KAAa,CAACE,EAAU,SAAS,SAAS,aAAa,MACxDE,EAAA,EAAa,CAAC,KAAKF,GAAW,MAAM,EAAE,eAAe,IAAM;AAG9D,UAAMI,IAAY,CAACC,MAA+B;AAIhD,UAHIA,EAAM,QAAQ,SAGdT,EAAQ,aAAa,CAACA,EAAQ,YAAa;AAC/C,YAAMU,IAAQJ,EAAA,GACRK,IAAQD,EAAM,CAAC,GACfE,IAAOF,EAAMA,EAAM,SAAS,CAAC;AACnC,UAAI,CAACC,KAAS,CAACC,GAAM;AACnB,QAAAH,EAAM,eAAA,GAGNL,EAAU,MAAM,EAAE,eAAe,GAAA,CAAM;AACvC;AAAA,MACF;AACA,YAAMS,IAAW,SAAS;AAC1B,MAAIA,MAAaT,KAGfK,EAAM,eAAA,IACLA,EAAM,WAAWG,IAAOD,GAAO,MAAA,KACvBF,EAAM,YAAYI,MAAaF,KACxCF,EAAM,eAAA,GACNG,EAAK,MAAA,KACI,CAACH,EAAM,YAAYI,MAAaD,KACzCH,EAAM,eAAA,GACNE,EAAM,MAAA,KACIP,EAAU,SAASS,CAAQ,MACrCJ,EAAM,eAAA,GACNE,EAAM,MAAA;AAAA,IAEV;AAEA,aAAS,iBAAiB,WAAWH,GAAW,EAAI,GACpDM,EAAU,MAAM;AACd,eAAS,oBAAoB,WAAWN,GAAW,EAAI,GAKnDP,KAAgBI,KAAe,CAACD,EAAU,SAASC,CAAW,KAChEA,EAAY,MAAM,EAAE,eAAe,GAAA,CAAM;AAAA,IAE7C,CAAC;AAAA,EACH,CAAC;AACH;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createEffect as n, onCleanup as d } from "solid-js";
|
|
2
|
+
import { matchesKeyboardShortcut as u } from "../utils/keyboardShortcut.js";
|
|
3
|
+
function f(r) {
|
|
4
|
+
const o = r.enabled ?? (() => !0);
|
|
5
|
+
n(() => {
|
|
6
|
+
if (!o()) return;
|
|
7
|
+
const t = (e) => {
|
|
8
|
+
e.defaultPrevented || e.repeat || e.isComposing || e.keyCode === 229 || u(e, r.keys) && (e.preventDefault(), r.onTrigger(e));
|
|
9
|
+
};
|
|
10
|
+
document.addEventListener("keydown", t), d(() => document.removeEventListener("keydown", t));
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
f as createKeyboardShortcut
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=createKeyboardShortcut.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createKeyboardShortcut.js","sources":["../../../src/primitives/createKeyboardShortcut.ts"],"sourcesContent":["import { type Accessor, createEffect, onCleanup } from \"solid-js\";\nimport { matchesKeyboardShortcut } from \"../utils/keyboardShortcut\";\n\nexport interface CreateKeyboardShortcutOptions {\n /** The shortcut in `Kbd` key names, e.g. `[\"Mod\", \"K\"]` (Command on macOS, Ctrl elsewhere). */\n keys: string[];\n /** Runs on a matching keydown anywhere in the document; the event's default action is prevented. */\n onTrigger: (event: KeyboardEvent) => void;\n /** Listen only while this returns true; listening is on by default. */\n enabled?: Accessor<boolean> | undefined;\n}\n\n/**\n * Binds a global keyboard shortcut while the calling component is alive, e.g. the Mod+K that opens a\n * `CommandPalette`. The component that reacts to the shortcut binds it, not the one it opens, so two\n * palettes never bind the same keys and any other opener can use them too. The same `keys` array draws\n * the hint: `<Kbd keys={[\"Mod\", \"K\"]} />`.\n *\n * One `keydown` listener sits on the document while `enabled` is on. A press an editor already handled\n * (`defaultPrevented`), a key repeat and an IME composition are ignored. On a match the default action is\n * prevented — Chrome and Firefox otherwise move the focus to their own search box on Ctrl+K — and\n * `onTrigger` runs. `keys` and `onTrigger` are read when the key is pressed, so a getter on the options\n * object stays live. Nothing runs on the server.\n */\nexport function createKeyboardShortcut(options: CreateKeyboardShortcutOptions): void {\n const enabled = options.enabled ?? ((): boolean => true);\n\n createEffect(() => {\n if (!enabled()) return;\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.defaultPrevented || event.repeat) return;\n if (event.isComposing || event.keyCode === 229) return;\n if (!matchesKeyboardShortcut(event, options.keys)) return;\n event.preventDefault();\n options.onTrigger(event);\n };\n document.addEventListener(\"keydown\", onKeyDown);\n onCleanup(() => document.removeEventListener(\"keydown\", onKeyDown));\n });\n}\n\nexport default createKeyboardShortcut;\n"],"names":["createKeyboardShortcut","options","enabled","createEffect","onKeyDown","event","matchesKeyboardShortcut","onCleanup"],"mappings":";;AAwBO,SAASA,EAAuBC,GAA8C;AACnF,QAAMC,IAAUD,EAAQ,YAAY,MAAe;AAEnD,EAAAE,EAAa,MAAM;AACjB,QAAI,CAACD,IAAW;AAChB,UAAME,IAAY,CAACC,MAA+B;AAChD,MAAIA,EAAM,oBAAoBA,EAAM,UAChCA,EAAM,eAAeA,EAAM,YAAY,OACtCC,EAAwBD,GAAOJ,EAAQ,IAAI,MAChDI,EAAM,eAAA,GACNJ,EAAQ,UAAUI,CAAK;AAAA,IACzB;AACA,aAAS,iBAAiB,WAAWD,CAAS,GAC9CG,EAAU,MAAM,SAAS,oBAAoB,WAAWH,CAAS,CAAC;AAAA,EACpE,CAAC;AACH;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function c(t, n) {
|
|
2
|
+
if (!(t instanceof HTMLElement) || t === document.body || !t.isConnected)
|
|
3
|
+
return;
|
|
4
|
+
const e = document.activeElement;
|
|
5
|
+
e && e !== document.body && !n?.contains(e) || t.focus({ preventScroll: !0 });
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
c as restoreFocus
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=restoreFocus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoreFocus.js","sources":["../../../src/primitives/restoreFocus.ts"],"sourcesContent":["/**\n * Hands focus back to `opener`, the element that had it when an overlay opened, once the\n * overlay `root` closes. Focus the app moved elsewhere on purpose stays where it is: it\n * is restored only while it is still inside `root` or has been dropped on the body (the\n * root is gone, or the element that had it was removed). An opener that left the document\n * is skipped, and one that cannot take focus (disabled, hidden) simply ignores the call.\n */\nexport function restoreFocus(opener: Element | null, root: Element | null | undefined): void {\n if (!(opener instanceof HTMLElement) || opener === document.body || !opener.isConnected) {\n return;\n }\n const active = document.activeElement;\n if (active && active !== document.body && !root?.contains(active)) {\n return;\n }\n opener.focus({ preventScroll: true });\n}\n"],"names":["restoreFocus","opener","root","active"],"mappings":"AAOO,SAASA,EAAaC,GAAwBC,GAAwC;AAC3F,MAAI,EAAED,aAAkB,gBAAgBA,MAAW,SAAS,QAAQ,CAACA,EAAO;AAC1E;AAEF,QAAME,IAAS,SAAS;AACxB,EAAIA,KAAUA,MAAW,SAAS,QAAQ,CAACD,GAAM,SAASC,CAAM,KAGhEF,EAAO,MAAM,EAAE,eAAe,GAAA,CAAM;AACtC;"}
|
|
@@ -4,6 +4,7 @@ import { FloatingButton } from "../../inputs/floatingButton";
|
|
|
4
4
|
import { Icon } from "../../base/icon";
|
|
5
5
|
import { createControllableState } from "../../../primitives/createControllableState";
|
|
6
6
|
import { createId } from "../../../primitives/createId";
|
|
7
|
+
import { Composer } from "../../inputs/composer/composer";
|
|
7
8
|
import { ChatComposer } from "./chatComposer";
|
|
8
9
|
import { ChatHeader } from "./chatHeader";
|
|
9
10
|
import { ChatMessages } from "./chatMessages";
|
|
@@ -66,12 +67,19 @@ function Chat(props) {
|
|
|
66
67
|
});
|
|
67
68
|
const attachInputId = createId();
|
|
68
69
|
const showComposer = () => Boolean(p.onSendMessage) || fileUpload.enabled();
|
|
70
|
+
const useLegacyComposer = () => Boolean(p.legacyComposer) || fileUpload.enabled() && !p.onSendMessage;
|
|
69
71
|
const fileInput = () => <Show when={fileUpload.enabled()}>
|
|
70
72
|
<input {...fileUpload.getInputProps({ id: attachInputId })} data-testid="chat-file-input" />
|
|
71
73
|
</Show>;
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
const sendText = (text) => {
|
|
75
|
+
void p.onSendMessage?.(text);
|
|
76
|
+
};
|
|
77
|
+
const uploadFiles = (files) => {
|
|
78
|
+
void p.onUploadFiles?.(files);
|
|
79
|
+
};
|
|
80
|
+
const legacyFooter = () => <>
|
|
81
|
+
{fileInput()}
|
|
82
|
+
<ChatComposer
|
|
75
83
|
onSendMessage={p.onSendMessage}
|
|
76
84
|
placeholder={p.composerPlaceholder}
|
|
77
85
|
disabled={p.composerDisabled}
|
|
@@ -81,7 +89,33 @@ function Chat(props) {
|
|
|
81
89
|
attachInputId={fileUpload.enabled() ? attachInputId : void 0}
|
|
82
90
|
attachAriaLabel={p.attachAriaLabel}
|
|
83
91
|
/>
|
|
84
|
-
|
|
92
|
+
</>;
|
|
93
|
+
const composerOnSend = createMemo(() => p.onSendMessage ? sendText : void 0);
|
|
94
|
+
const composerOnAttach = createMemo(() => fileUpload.enabled() ? uploadFiles : void 0);
|
|
95
|
+
const composerAccept = createMemo(() => fileUpload.enabled() ? p.fileUploadAccept : void 0);
|
|
96
|
+
const composerMaxFiles = createMemo(() => fileUpload.enabled() ? fileUpload.maxFiles : void 0);
|
|
97
|
+
const composerMultiple = createMemo(() => fileUpload.enabled() ? fileUpload.maxFiles > 1 : void 0);
|
|
98
|
+
const composerFooter = () => <Composer
|
|
99
|
+
{...p.composerProps}
|
|
100
|
+
class={cn("smwb-chat__composer", p.composerProps?.class)}
|
|
101
|
+
sendKey={p.composerProps?.sendKey ?? "enter"}
|
|
102
|
+
aria-label={p.composerProps?.["aria-label"] ?? (p.composerProps?.["aria-labelledby"] ? void 0 : "Message")}
|
|
103
|
+
sendLabel={p.composerProps?.sendLabel ?? "Send message"}
|
|
104
|
+
attachLabel={p.attachAriaLabel ?? p.composerProps?.attachLabel}
|
|
105
|
+
placeholder={p.composerPlaceholder}
|
|
106
|
+
disabled={p.composerDisabled}
|
|
107
|
+
busy={p.busy}
|
|
108
|
+
onStop={p.onStop}
|
|
109
|
+
onSend={composerOnSend()}
|
|
110
|
+
onAttach={composerOnAttach()}
|
|
111
|
+
accept={composerAccept()}
|
|
112
|
+
maxFiles={composerMaxFiles()}
|
|
113
|
+
multiple={composerMultiple()}
|
|
114
|
+
dropTarget={false}
|
|
115
|
+
/>;
|
|
116
|
+
const resolvedFooter = () => p.footer ?? p.children ?? (showComposer() ? <Show when={useLegacyComposer()} fallback={composerFooter()}>
|
|
117
|
+
{legacyFooter()}
|
|
118
|
+
</Show> : void 0);
|
|
85
119
|
const closeButtonVisible = () => shouldShowChatCloseButton({
|
|
86
120
|
floatingTrigger: p.floatingTrigger,
|
|
87
121
|
embedded: p.embedded,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/components/dataDisplay/chat/chat.tsx"],"sourcesContent":["import { type JSX, type ParentProps, Show, children, createMemo, mergeProps } from \"solid-js\";\nimport cn from \"clsx\";\nimport { FloatingButton } from \"../../inputs/floatingButton\";\nimport { Icon } from \"../../base/icon\";\nimport { createControllableState } from \"../../../primitives/createControllableState\";\nimport { createId } from \"../../../primitives/createId\";\nimport { ChatComposer } from \"./chatComposer\";\nimport { ChatHeader } from \"./chatHeader\";\nimport { ChatMessages } from \"./chatMessages\";\nimport { ChatShell } from \"./chatShell\";\nimport { createChatFileUpload } from \"./useChatFileUpload\";\nimport {\n type ChatAnchor,\n type ChatLayoutMode,\n type ChatMessage,\n type ChatMessageRenderContext,\n type ChatThemeMode,\n CHAT_EXPAND_LAYOUTS,\n} from \"./types\";\nimport { pickInitialLayout, resolveAllowedLayouts, shouldShowChatCloseButton } from \"./utils\";\n\nexport interface ChatProps extends ParentProps, Omit<ChatMessageRenderContext, \"showAvatars\" | \"showAttachments\"> {\n class?: string | undefined;\n messages: ChatMessage[];\n showAvatars?: boolean | undefined;\n showAttachments?: boolean | undefined;\n headerTitle?: JSX.Element;\n headerSubtitle?: JSX.Element;\n headerActions?: JSX.Element;\n footer?: JSX.Element;\n anchor?: ChatAnchor | undefined;\n themeMode?: ChatThemeMode | undefined;\n allowedLayouts?: ChatLayoutMode[] | undefined;\n layout?: ChatLayoutMode | undefined;\n defaultLayout?: ChatLayoutMode | undefined;\n onLayoutChange?: ((layout: ChatLayoutMode) => void) | undefined;\n open?: boolean | undefined;\n defaultOpen?: boolean | undefined;\n onOpenChange?: ((open: boolean) => void) | undefined;\n floatingTrigger?: boolean | undefined;\n triggerIcon?: JSX.Element;\n triggerLabel?: string | undefined;\n onLoadMore?: (() => void | Promise<void>) | undefined;\n hasMore?: boolean | undefined;\n onSendMessage?: ((text: string) => void | Promise<void>) | undefined;\n composerPlaceholder?: string | undefined;\n composerDisabled?: boolean | undefined;\n composerShiftEnterNewline?: boolean | undefined;\n composerCtrlEnterNewline?: boolean | undefined;\n fileUpload?: boolean | undefined;\n onUploadFiles?: ((files: File[]) => void | Promise<void>) | undefined;\n fileUploadAccept?: Record<string, string[]> | string | undefined;\n fileUploadMaxFiles?: number | undefined;\n attachAriaLabel?: string | undefined;\n loading?: boolean | undefined;\n loadingMore?: boolean | undefined;\n loadingSkeletonCount?: number | undefined;\n renderMessage?: ((message: ChatMessage, ctx: ChatMessageRenderContext) => JSX.Element) | undefined;\n embedded?: boolean | undefined;\n overlayContext?: boolean | undefined;\n showCloseButton?: boolean | undefined;\n}\n\nexport function Chat(props: ChatProps): JSX.Element {\n const p = mergeProps(\n {\n showAvatars: false,\n showAttachments: false,\n anchor: \"bottom-right\" as const,\n themeMode: \"inherit\" as const,\n defaultOpen: false,\n floatingTrigger: false,\n composerPlaceholder: \"message\",\n composerShiftEnterNewline: true,\n composerCtrlEnterNewline: true,\n fileUpload: false,\n embedded: false,\n overlayContext: false,\n showStatus: false,\n },\n props\n );\n\n const allowedLayouts = createMemo(() => resolveAllowedLayouts(p.allowedLayouts ?? CHAT_EXPAND_LAYOUTS));\n\n const [open, setOpen] = createControllableState<boolean>({\n value: () => p.open,\n defaultValue: p.defaultOpen,\n onChange: p.onOpenChange,\n });\n\n const [layout, setLayout] = createControllableState<ChatLayoutMode>({\n value: () => p.layout,\n defaultValue: pickInitialLayout(allowedLayouts(), p.defaultLayout),\n onChange: p.onLayoutChange,\n });\n\n const effectiveLayout = (): ChatLayoutMode =>\n p.embedded ? \"fullHeight\" : p.floatingTrigger ? (open() ? layout() : \"closed\") : layout();\n\n const handleOpen = (): void => {\n setOpen(true);\n if (layout() === \"closed\") {\n setLayout(pickInitialLayout(allowedLayouts(), p.defaultLayout));\n }\n };\n\n const handleClose = (): void => {\n setOpen(false);\n };\n\n const handleLayoutChange = (next: ChatLayoutMode): void => {\n setOpen(true);\n setLayout(next);\n };\n\n const fileUpload = createChatFileUpload({\n enabled: () => p.fileUpload,\n accept: p.fileUploadAccept,\n maxFiles: p.fileUploadMaxFiles,\n onUploadFiles: p.onUploadFiles,\n disabled: () => Boolean(p.composerDisabled),\n });\n\n const attachInputId = createId();\n\n const showComposer = (): boolean => Boolean(p.onSendMessage) || fileUpload.enabled();\n\n const fileInput = (): JSX.Element => (\n <Show when={fileUpload.enabled()}>\n <input {...fileUpload.getInputProps({ id: attachInputId })} data-testid=\"chat-file-input\" />\n </Show>\n );\n\n const resolvedFooter = (): JSX.Element =>\n p.footer ??\n p.children ??\n (showComposer() ? (\n <>\n {fileInput()}\n <ChatComposer\n onSendMessage={p.onSendMessage}\n placeholder={p.composerPlaceholder}\n disabled={p.composerDisabled}\n shiftEnterNewline={p.composerShiftEnterNewline}\n ctrlEnterNewline={p.composerCtrlEnterNewline}\n fileUpload={fileUpload.enabled()}\n attachInputId={fileUpload.enabled() ? attachInputId : undefined}\n attachAriaLabel={p.attachAriaLabel}\n />\n </>\n ) : undefined);\n\n const closeButtonVisible = (): boolean =>\n shouldShowChatCloseButton({\n floatingTrigger: p.floatingTrigger,\n embedded: p.embedded,\n overlayContext: p.overlayContext,\n effectiveLayout: effectiveLayout(),\n showCloseButton: p.showCloseButton,\n });\n\n // The trigger icon is read once, and only while the trigger is drawn: markup\n // passed as a prop is created anew on every read, and during hydration a copy\n // the server never rendered has no DOM node.\n const triggerIcon = children(() => (p.floatingTrigger && !p.embedded && !open() ? p.triggerIcon : undefined));\n\n return (\n <div\n class={cn(\n \"smwb-chat\",\n !p.embedded && `smwb-chat_${p.anchor}`,\n p.embedded && \"smwb-chat_embedded\",\n p.overlayContext && \"smwb-chat_overlay-context\",\n p.class\n )}\n data-testid=\"chat\"\n >\n <Show when={p.floatingTrigger && !p.embedded && !open()}>\n <FloatingButton\n class=\"smwb-chat__trigger\"\n aria-label={p.triggerLabel ?? \"Open chat\"}\n data-testid=\"chat-trigger\"\n onClick={handleOpen}\n >\n <Show when={triggerIcon()} fallback={<Icon name=\"chat\" size={24} />}>\n {triggerIcon()}\n </Show>\n </FloatingButton>\n </Show>\n <ChatShell\n layout={effectiveLayout()}\n anchor={p.anchor}\n themeMode={p.themeMode}\n embedded={p.embedded}\n overlayContext={p.overlayContext}\n fileDropzoneRootProps={fileUpload.enabled() ? fileUpload.getRootProps() : undefined}\n fileDropzoneActive={fileUpload.enabled() && fileUpload.isDragActive()}\n header={\n <ChatHeader\n title={p.headerTitle}\n subtitle={p.headerSubtitle}\n actions={p.headerActions}\n layout={effectiveLayout() === \"closed\" ? layout() : effectiveLayout()}\n allowedLayouts={allowedLayouts()}\n onLayoutChange={handleLayoutChange}\n onClose={closeButtonVisible() ? handleClose : undefined}\n />\n }\n footer={resolvedFooter()}\n >\n <ChatMessages\n messages={p.messages}\n showAvatars={p.showAvatars}\n showAttachments={p.showAttachments}\n showStatus={p.showStatus}\n statusIcons={p.statusIcons}\n renderStatus={p.renderStatus}\n onLoadMore={p.onLoadMore}\n hasMore={p.hasMore}\n loading={p.loading}\n loadingMore={p.loadingMore}\n loadingSkeletonCount={p.loadingSkeletonCount}\n renderMessage={p.renderMessage}\n />\n </ChatShell>\n </div>\n );\n}\n\nexport default Chat;\n"],"mappings":"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","names":[],"file":"chat.jsx"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/components/dataDisplay/chat/chat.tsx"],"sourcesContent":["import { type JSX, type ParentProps, Show, children, createMemo, mergeProps } from \"solid-js\";\nimport cn from \"clsx\";\nimport { FloatingButton } from \"../../inputs/floatingButton\";\nimport { Icon } from \"../../base/icon\";\nimport { createControllableState } from \"../../../primitives/createControllableState\";\nimport { createId } from \"../../../primitives/createId\";\nimport { Composer } from \"../../inputs/composer/composer\";\nimport type { ComposerProps } from \"../../inputs/composer/composer\";\nimport { ChatComposer } from \"./chatComposer\";\nimport { ChatHeader } from \"./chatHeader\";\nimport { ChatMessages } from \"./chatMessages\";\nimport { ChatShell } from \"./chatShell\";\nimport { createChatFileUpload } from \"./useChatFileUpload\";\nimport {\n type ChatAnchor,\n type ChatLayoutMode,\n type ChatMessage,\n type ChatMessageRenderContext,\n type ChatThemeMode,\n CHAT_EXPAND_LAYOUTS,\n} from \"./types\";\nimport { pickInitialLayout, resolveAllowedLayouts, shouldShowChatCloseButton } from \"./utils\";\n\n/**\n * Props for the `Composer` Chat draws as its footer. The props Chat owns itself — `onSendMessage` (the composer's\n * `onSend`), `busy`, `onStop`, `composerPlaceholder` (`placeholder`), `composerDisabled` (`disabled`), the file upload\n * props (`onAttach`, `accept`, `multiple`, `maxFiles`) and `dropTarget` (always `false`: the Chat shell is the drop\n * target) — are left out, Chat passes them and does not let a caller override them.\n */\nexport type ChatFooterComposerProps = Omit<\n ComposerProps,\n | \"onSend\"\n | \"busy\"\n | \"onStop\"\n | \"disabled\"\n | \"placeholder\"\n | \"onAttach\"\n | \"accept\"\n | \"multiple\"\n | \"maxFiles\"\n | \"dropTarget\"\n>;\n\nexport interface ChatProps extends ParentProps, Omit<ChatMessageRenderContext, \"showAvatars\" | \"showAttachments\"> {\n class?: string | undefined;\n messages: ChatMessage[];\n showAvatars?: boolean | undefined;\n showAttachments?: boolean | undefined;\n headerTitle?: JSX.Element;\n headerSubtitle?: JSX.Element;\n headerActions?: JSX.Element;\n footer?: JSX.Element;\n anchor?: ChatAnchor | undefined;\n themeMode?: ChatThemeMode | undefined;\n allowedLayouts?: ChatLayoutMode[] | undefined;\n layout?: ChatLayoutMode | undefined;\n defaultLayout?: ChatLayoutMode | undefined;\n onLayoutChange?: ((layout: ChatLayoutMode) => void) | undefined;\n open?: boolean | undefined;\n defaultOpen?: boolean | undefined;\n onOpenChange?: ((open: boolean) => void) | undefined;\n floatingTrigger?: boolean | undefined;\n triggerIcon?: JSX.Element;\n triggerLabel?: string | undefined;\n onLoadMore?: (() => void | Promise<void>) | undefined;\n hasMore?: boolean | undefined;\n onSendMessage?: ((text: string) => void | Promise<void>) | undefined;\n /**\n * The agent is replying: the composer's send button turns into Stop and calls `onStop`, the keys do not send, the\n * text stays editable. Not the same as `loading` (the message list skeleton). The default composer only.\n */\n busy?: boolean | undefined;\n /** Called when Stop is pressed while `busy` (and not `composerDisabled`). The default composer only. */\n onStop?: (() => void) | undefined;\n /**\n * More props for the built-in `Composer`: `toolbar`, `attachments`, `maxLength`, `counter`, `minRows`, `maxRows`,\n * `layout`, `sendKey` (default here `\"enter\"`), `value`/`defaultValue`/`onValueChange`, `clearOnSend`, `autofocus`,\n * `inputRef`, `aria-*`, `sendLabel`, `stopLabel`, `attachLabel`, `class`, `data-*`, … Chat's own props\n * (`onSendMessage`, `busy`, `onStop`, `composerPlaceholder`, `composerDisabled`, the file upload props) win.\n */\n composerProps?: ChatFooterComposerProps | undefined;\n /**\n * Deprecated: draws the old `ChatComposer` (Enter sends, TextField DOM, `chat-composer*` test ids) instead of the\n * built-in `Composer`. Kept for the migration and removed with `ChatComposer` in the next major; `busy`, `onStop`\n * and `composerProps` are ignored in this mode.\n *\n * @deprecated Migrate to the default `Composer`; see the README section \"Migrating from ChatComposer\".\n */\n legacyComposer?: boolean | undefined;\n composerPlaceholder?: string | undefined;\n composerDisabled?: boolean | undefined;\n /**\n * Deprecated: works with `legacyComposer` only — the built-in `Composer` always inserts a newline on Shift+Enter.\n * Pass it together with `legacyComposer` until that is removed.\n *\n * @deprecated Use `legacyComposer`; the default `Composer` has no equivalent flag.\n */\n composerShiftEnterNewline?: boolean | undefined;\n /**\n * Deprecated: works with `legacyComposer` only — with the built-in `Composer` Ctrl/⌘+Enter sends. Pass it together\n * with `legacyComposer` until that is removed.\n *\n * @deprecated Use `legacyComposer`; the default `Composer` has no equivalent flag.\n */\n composerCtrlEnterNewline?: boolean | undefined;\n fileUpload?: boolean | undefined;\n onUploadFiles?: ((files: File[]) => void | Promise<void>) | undefined;\n fileUploadAccept?: Record<string, string[]> | string | undefined;\n fileUploadMaxFiles?: number | undefined;\n attachAriaLabel?: string | undefined;\n loading?: boolean | undefined;\n loadingMore?: boolean | undefined;\n loadingSkeletonCount?: number | undefined;\n renderMessage?: ((message: ChatMessage, ctx: ChatMessageRenderContext) => JSX.Element) | undefined;\n embedded?: boolean | undefined;\n overlayContext?: boolean | undefined;\n showCloseButton?: boolean | undefined;\n}\n\nexport function Chat(props: ChatProps): JSX.Element {\n const p = mergeProps(\n {\n showAvatars: false,\n showAttachments: false,\n anchor: \"bottom-right\" as const,\n themeMode: \"inherit\" as const,\n defaultOpen: false,\n floatingTrigger: false,\n composerPlaceholder: \"message\",\n composerShiftEnterNewline: true,\n composerCtrlEnterNewline: true,\n fileUpload: false,\n embedded: false,\n overlayContext: false,\n showStatus: false,\n },\n props\n );\n\n const allowedLayouts = createMemo(() => resolveAllowedLayouts(p.allowedLayouts ?? CHAT_EXPAND_LAYOUTS));\n\n const [open, setOpen] = createControllableState<boolean>({\n value: () => p.open,\n defaultValue: p.defaultOpen,\n onChange: p.onOpenChange,\n });\n\n const [layout, setLayout] = createControllableState<ChatLayoutMode>({\n value: () => p.layout,\n defaultValue: pickInitialLayout(allowedLayouts(), p.defaultLayout),\n onChange: p.onLayoutChange,\n });\n\n const effectiveLayout = (): ChatLayoutMode =>\n p.embedded ? \"fullHeight\" : p.floatingTrigger ? (open() ? layout() : \"closed\") : layout();\n\n const handleOpen = (): void => {\n setOpen(true);\n if (layout() === \"closed\") {\n setLayout(pickInitialLayout(allowedLayouts(), p.defaultLayout));\n }\n };\n\n const handleClose = (): void => {\n setOpen(false);\n };\n\n const handleLayoutChange = (next: ChatLayoutMode): void => {\n setOpen(true);\n setLayout(next);\n };\n\n const fileUpload = createChatFileUpload({\n enabled: () => p.fileUpload,\n accept: p.fileUploadAccept,\n maxFiles: p.fileUploadMaxFiles,\n onUploadFiles: p.onUploadFiles,\n disabled: () => Boolean(p.composerDisabled),\n });\n\n const attachInputId = createId();\n\n const showComposer = (): boolean => Boolean(p.onSendMessage) || fileUpload.enabled();\n // Composer has no text-less mode, so an upload without a send handler keeps the old attach-only ChatComposer.\n const useLegacyComposer = (): boolean => Boolean(p.legacyComposer) || (fileUpload.enabled() && !p.onSendMessage);\n\n const fileInput = (): JSX.Element => (\n <Show when={fileUpload.enabled()}>\n <input {...fileUpload.getInputProps({ id: attachInputId })} data-testid=\"chat-file-input\" />\n </Show>\n );\n\n // The handlers are attached always and read the props when called: a handler that appears later still works.\n const sendText = (text: string): void => {\n void p.onSendMessage?.(text);\n };\n\n const uploadFiles = (files: File[]): void => {\n void p.onUploadFiles?.(files);\n };\n\n const legacyFooter = (): JSX.Element => (\n <>\n {fileInput()}\n <ChatComposer\n onSendMessage={p.onSendMessage}\n placeholder={p.composerPlaceholder}\n disabled={p.composerDisabled}\n shiftEnterNewline={p.composerShiftEnterNewline}\n ctrlEnterNewline={p.composerCtrlEnterNewline}\n fileUpload={fileUpload.enabled()}\n attachInputId={fileUpload.enabled() ? attachInputId : undefined}\n attachAriaLabel={p.attachAriaLabel}\n />\n </>\n );\n\n // Chat's own props are plain attributes after the spread, so they win; `dropTarget` is off because the shell\n // already takes the drops. Every prop Chat owns is omitted from `ChatFooterComposerProps`, so none of them can\n // leak back from the spread when its value is `undefined`.\n // The upload gate is resolved in memos rather than inline: a conditional prop compiles to a `memo` created\n // inside the prop getter, and Composer reads `onAttach`/`accept`/`maxFiles`/`multiple` from its pick and drop\n // handlers — outside any owner, where such a computation is never disposed.\n const composerOnSend = createMemo(() => (p.onSendMessage ? sendText : undefined));\n const composerOnAttach = createMemo(() => (fileUpload.enabled() ? uploadFiles : undefined));\n const composerAccept = createMemo(() => (fileUpload.enabled() ? p.fileUploadAccept : undefined));\n const composerMaxFiles = createMemo(() => (fileUpload.enabled() ? fileUpload.maxFiles : undefined));\n const composerMultiple = createMemo(() => (fileUpload.enabled() ? fileUpload.maxFiles > 1 : undefined));\n\n const composerFooter = (): JSX.Element => (\n <Composer\n {...p.composerProps}\n class={cn(\"smwb-chat__composer\", p.composerProps?.class)}\n sendKey={p.composerProps?.sendKey ?? \"enter\"}\n aria-label={p.composerProps?.[\"aria-label\"] ?? (p.composerProps?.[\"aria-labelledby\"] ? undefined : \"Message\")}\n sendLabel={p.composerProps?.sendLabel ?? \"Send message\"}\n attachLabel={p.attachAriaLabel ?? p.composerProps?.attachLabel}\n placeholder={p.composerPlaceholder}\n disabled={p.composerDisabled}\n busy={p.busy}\n onStop={p.onStop}\n onSend={composerOnSend()}\n onAttach={composerOnAttach()}\n accept={composerAccept()}\n maxFiles={composerMaxFiles()}\n multiple={composerMultiple()}\n dropTarget={false}\n />\n );\n\n const resolvedFooter = (): JSX.Element =>\n p.footer ??\n p.children ??\n (showComposer() ? (\n <Show when={useLegacyComposer()} fallback={composerFooter()}>\n {legacyFooter()}\n </Show>\n ) : undefined);\n\n const closeButtonVisible = (): boolean =>\n shouldShowChatCloseButton({\n floatingTrigger: p.floatingTrigger,\n embedded: p.embedded,\n overlayContext: p.overlayContext,\n effectiveLayout: effectiveLayout(),\n showCloseButton: p.showCloseButton,\n });\n\n // The trigger icon is read once, and only while the trigger is drawn: markup\n // passed as a prop is created anew on every read, and during hydration a copy\n // the server never rendered has no DOM node.\n const triggerIcon = children(() => (p.floatingTrigger && !p.embedded && !open() ? p.triggerIcon : undefined));\n\n return (\n <div\n class={cn(\n \"smwb-chat\",\n !p.embedded && `smwb-chat_${p.anchor}`,\n p.embedded && \"smwb-chat_embedded\",\n p.overlayContext && \"smwb-chat_overlay-context\",\n p.class\n )}\n data-testid=\"chat\"\n >\n <Show when={p.floatingTrigger && !p.embedded && !open()}>\n <FloatingButton\n class=\"smwb-chat__trigger\"\n aria-label={p.triggerLabel ?? \"Open chat\"}\n data-testid=\"chat-trigger\"\n onClick={handleOpen}\n >\n <Show when={triggerIcon()} fallback={<Icon name=\"chat\" size={24} />}>\n {triggerIcon()}\n </Show>\n </FloatingButton>\n </Show>\n <ChatShell\n layout={effectiveLayout()}\n anchor={p.anchor}\n themeMode={p.themeMode}\n embedded={p.embedded}\n overlayContext={p.overlayContext}\n fileDropzoneRootProps={fileUpload.enabled() ? fileUpload.getRootProps() : undefined}\n fileDropzoneActive={fileUpload.enabled() && fileUpload.isDragActive()}\n header={\n <ChatHeader\n title={p.headerTitle}\n subtitle={p.headerSubtitle}\n actions={p.headerActions}\n layout={effectiveLayout() === \"closed\" ? layout() : effectiveLayout()}\n allowedLayouts={allowedLayouts()}\n onLayoutChange={handleLayoutChange}\n onClose={closeButtonVisible() ? handleClose : undefined}\n />\n }\n footer={resolvedFooter()}\n >\n <ChatMessages\n messages={p.messages}\n showAvatars={p.showAvatars}\n showAttachments={p.showAttachments}\n showStatus={p.showStatus}\n statusIcons={p.statusIcons}\n renderStatus={p.renderStatus}\n onLoadMore={p.onLoadMore}\n hasMore={p.hasMore}\n loading={p.loading}\n loadingMore={p.loadingMore}\n loadingSkeletonCount={p.loadingSkeletonCount}\n renderMessage={p.renderMessage}\n />\n </ChatShell>\n </div>\n );\n}\n\nexport default Chat;\n"],"mappings":"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","names":[],"file":"chat.jsx"}
|
|
@@ -48,6 +48,7 @@ function ChatComposer(props) {
|
|
|
48
48
|
setValue("");
|
|
49
49
|
};
|
|
50
50
|
const handleKeyDown = (event) => {
|
|
51
|
+
if (event.isComposing || event.keyCode === 229) return;
|
|
51
52
|
if (shouldComposerNewlineOnEnter(event, { shiftEnterNewline: merged.shiftEnterNewline, ctrlEnterNewline: merged.ctrlEnterNewline })) {
|
|
52
53
|
if (event.currentTarget instanceof HTMLTextAreaElement) {
|
|
53
54
|
event.preventDefault();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/components/dataDisplay/chat/chatComposer.tsx"],"sourcesContent":["import { type JSX, Show, createSignal, mergeProps } from \"solid-js\";\nimport cn from \"clsx\";\nimport { Icon } from \"../../base/icon\";\nimport { TextField } from \"../../inputs/textField\";\nimport { TextFieldWrapper } from \"../../inputs/textField/textFieldWrapper\";\nimport { ChatIconButton } from \"./chatIconButton\";\nimport { createId } from \"../../../primitives/createId\";\nimport { shouldComposerNewlineOnEnter } from \"./utils\";\n\nexport interface ChatComposerProps {\n class?: string | undefined;\n onSendMessage?: ((text: string) => void | Promise<void>) | undefined;\n placeholder?: string | undefined;\n disabled?: boolean | undefined;\n sendAriaLabel?: string | undefined;\n shiftEnterNewline?: boolean | undefined;\n ctrlEnterNewline?: boolean | undefined;\n fileUpload?: boolean | undefined;\n attachInputId?: string | undefined;\n onAttachClick?: (() => void) | undefined;\n attachAriaLabel?: string | undefined;\n}\n\nfunction stopPropagation(event: Event): void {\n event.stopPropagation();\n}\n\nfunction insertNewlineAtCursor(element: HTMLTextAreaElement, value: string, setValue: (next: string) => void): void {\n const start = element.selectionStart ?? value.length;\n const end = element.selectionEnd ?? value.length;\n const nextValue = `${value.slice(0, start)}\\n${value.slice(end)}`;\n\n setValue(nextValue);\n\n requestAnimationFrame(() => {\n element.selectionStart = start + 1;\n element.selectionEnd = start + 1;\n });\n}\n\nexport function ChatComposer(props: ChatComposerProps): JSX.Element {\n const merged = mergeProps(\n {\n placeholder: \"message\",\n disabled: false,\n sendAriaLabel: \"Send message\",\n shiftEnterNewline: true,\n ctrlEnterNewline: true,\n fileUpload: false,\n attachAriaLabel: \"Attach file\",\n },\n props\n );\n\n const [value, setValue] = createSignal(\"\");\n const [isFocused, setIsFocused] = createSignal(false);\n const inputId = createId();\n let textareaRef: HTMLTextAreaElement | undefined;\n\n const multiline = (): boolean => merged.shiftEnterNewline || merged.ctrlEnterNewline;\n const canSend = (): boolean => Boolean(merged.onSendMessage) && value().trim().length > 0 && !merged.disabled;\n const showAttach = (): boolean => merged.fileUpload && Boolean(merged.attachInputId || merged.onAttachClick);\n\n const handleSend = (): void => {\n if (!merged.onSendMessage) return;\n const text = value().trim();\n if (!text || merged.disabled) return;\n void merged.onSendMessage(text);\n setValue(\"\");\n };\n\n const handleKeyDown = (event: KeyboardEvent & { currentTarget: HTMLElement }): void => {\n if (shouldComposerNewlineOnEnter(event, { shiftEnterNewline: merged.shiftEnterNewline, ctrlEnterNewline: merged.ctrlEnterNewline })) {\n if (event.currentTarget instanceof HTMLTextAreaElement) {\n event.preventDefault();\n insertNewlineAtCursor(event.currentTarget, value(), setValue);\n }\n return;\n }\n\n if (event.key !== \"Enter\") return;\n\n event.preventDefault();\n handleSend();\n };\n\n const attachClass = (): string =>\n cn(\"smwb-chat-icon-button\", \"smwb-chat-icon-button_edge-start\", merged.disabled && \"smwb-chat-icon-button_disabled\");\n\n const attachButton = (): JSX.Element => (\n <Show when={showAttach()}>\n <Show\n when={merged.attachInputId}\n fallback={\n <ChatIconButton\n edge=\"start\"\n aria-label={merged.attachAriaLabel}\n data-testid=\"chat-composer-attach\"\n disabled={merged.disabled}\n onClick={() => merged.onAttachClick?.()}\n onMouseDown={stopPropagation}\n >\n <Icon name=\"attach_file\" size={24} />\n </ChatIconButton>\n }\n >\n {(id) => (\n <label\n for={merged.disabled ? undefined : id()}\n class={attachClass()}\n aria-label={merged.attachAriaLabel}\n aria-disabled={merged.disabled || undefined}\n data-testid=\"chat-composer-attach\"\n onMouseDown={stopPropagation}\n >\n <Icon name=\"attach_file\" size={24} />\n </label>\n )}\n </Show>\n </Show>\n );\n\n const sendButton = (): JSX.Element => (\n <Show when={merged.onSendMessage}>\n <ChatIconButton\n edge=\"end\"\n color=\"primary\"\n aria-label={merged.sendAriaLabel}\n data-testid=\"chat-composer-send\"\n disabled={!canSend()}\n onClick={handleSend}\n onMouseDown={stopPropagation}\n >\n <Icon name=\"send\" size={24} />\n </ChatIconButton>\n </Show>\n );\n\n const onHolderMouseDown: JSX.EventHandler<HTMLDivElement, MouseEvent> = (event) => {\n if (textareaRef && event.currentTarget === event.target) {\n event.preventDefault();\n textareaRef.focus();\n }\n };\n\n return (\n <Show\n when={!(showAttach() && !merged.onSendMessage)}\n fallback={\n <div class={cn(\"smwb-chat-composer\", \"smwb-chat-composer_attach-only\", merged.class)} data-testid=\"chat-composer\">\n {attachButton()}\n </div>\n }\n >\n <Show\n when={multiline()}\n fallback={\n <TextField\n class={cn(\"smwb-chat-composer\", merged.class)}\n data-testid=\"chat-composer\"\n fullWidth\n value={value()}\n disabled={merged.disabled}\n placeholder={merged.placeholder}\n onChange={(event) => setValue(event.currentTarget.value)}\n startAdornment={attachButton()}\n endAdornment={sendButton()}\n onKeyDown={handleKeyDown}\n />\n }\n >\n <TextFieldWrapper\n class={cn(\"smwb-chat-composer\", merged.class)}\n data-testid=\"chat-composer\"\n fullWidth\n disabled={merged.disabled}\n isFilledState={value().length > 0}\n isFocused={isFocused()}\n for={inputId}\n shrink={Boolean(merged.attachInputId || merged.onAttachClick) && showAttach()}\n onHolderMouseDown={onHolderMouseDown}\n startAdornment={attachButton()}\n endAdornment={sendButton()}\n >\n <textarea\n id={inputId}\n ref={(el) => (textareaRef = el)}\n class={cn(\n \"smwb-text-field__input\",\n \"smwb-chat-composer__input\",\n \"smwb-text-field__input--show-placeholder\",\n showAttach() && \"smwb-text-field__input--adornment-start\",\n merged.onSendMessage && \"smwb-text-field__input--adornment-end\"\n )}\n value={value()}\n disabled={merged.disabled}\n placeholder={merged.placeholder}\n rows={1}\n onInput={(event) => setValue(event.currentTarget.value)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n />\n </TextFieldWrapper>\n </Show>\n </Show>\n );\n}\n\nexport default ChatComposer;\n"],"mappings":"AAAA,SAAmB,MAAM,cAAc,kBAAkB;AACzD,OAAO,QAAQ;AACf,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AACzB,SAAS,oCAAoC;AAgB7C,SAAS,gBAAgB,OAAoB;AAC3C,QAAM,gBAAgB;AACxB;AAEA,SAAS,sBAAsB,SAA8B,OAAe,UAAwC;AAClH,QAAM,QAAQ,QAAQ,kBAAkB,MAAM;AAC9C,QAAM,MAAM,QAAQ,gBAAgB,MAAM;AAC1C,QAAM,YAAY,GAAG,MAAM,MAAM,GAAG,KAAK,CAAC;AAAA,EAAK,MAAM,MAAM,GAAG,CAAC;AAE/D,WAAS,SAAS;AAElB,wBAAsB,MAAM;AAC1B,YAAQ,iBAAiB,QAAQ;AACjC,YAAQ,eAAe,QAAQ;AAAA,EACjC,CAAC;AACH;AAEO,SAAS,aAAa,OAAuC;AAClE,QAAM,SAAS;AAAA,IACb;AAAA,MACE,aAAa;AAAA,MACb,UAAU;AAAA,MACV,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,MAClB,YAAY;AAAA,MACZ,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,CAAC,OAAO,QAAQ,IAAI,aAAa,EAAE;AACzC,QAAM,CAAC,WAAW,YAAY,IAAI,aAAa,KAAK;AACpD,QAAM,UAAU,SAAS;AACzB,MAAI;AAEJ,QAAM,YAAY,MAAe,OAAO,qBAAqB,OAAO;AACpE,QAAM,UAAU,MAAe,QAAQ,OAAO,aAAa,KAAK,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,CAAC,OAAO;AACrG,QAAM,aAAa,MAAe,OAAO,cAAc,QAAQ,OAAO,iBAAiB,OAAO,aAAa;AAE3G,QAAM,aAAa,MAAY;AAC7B,QAAI,CAAC,OAAO,cAAe;AAC3B,UAAM,OAAO,MAAM,EAAE,KAAK;AAC1B,QAAI,CAAC,QAAQ,OAAO,SAAU;AAC9B,SAAK,OAAO,cAAc,IAAI;AAC9B,aAAS,EAAE;AAAA,EACb;AAEA,QAAM,gBAAgB,CAAC,UAAgE;AACrF,QAAI,6BAA6B,OAAO,EAAE,mBAAmB,OAAO,mBAAmB,kBAAkB,OAAO,iBAAiB,CAAC,GAAG;AACnI,UAAI,MAAM,yBAAyB,qBAAqB;AACtD,cAAM,eAAe;AACrB,8BAAsB,MAAM,eAAe,MAAM,GAAG,QAAQ;AAAA,MAC9D;AACA;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,QAAS;AAE3B,UAAM,eAAe;AACrB,eAAW;AAAA,EACb;AAEA,QAAM,cAAc,MAClB,GAAG,yBAAyB,oCAAoC,OAAO,YAAY,gCAAgC;AAErH,QAAM,eAAe,MACnB,CAAC,KAAK,MAAM,WAAW,GAAG;AAAA,MACxB,CAAC;AAAA,IACC,MAAM,OAAO;AAAA,IACb,UACE,CAAC;AAAA,MACC,KAAK;AAAA,MACL,YAAY,OAAO;AAAA,MACnB,YAAY;AAAA,MACZ,UAAU,OAAO;AAAA,MACjB,SAAS,MAAM,OAAO,gBAAgB;AAAA,MACtC,aAAa;AAAA,KACd;AAAA,YACC,CAAC,KAAK,KAAK,cAAc,MAAM,IAAI,EAAE;AAAA,UACvC,EATC;AAAA,GAWJ;AAAA,SACE,CAAC,OACA,CAAC;AAAA,IACC,KAAK,OAAO,WAAW,SAAY,GAAG;AAAA,IACtC,OAAO,YAAY;AAAA,IACnB,YAAY,OAAO;AAAA,IACnB,eAAe,OAAO,YAAY;AAAA,IAClC,YAAY;AAAA,IACZ,aAAa;AAAA,GACd;AAAA,YACC,CAAC,KAAK,KAAK,cAAc,MAAM,IAAI,EAAE;AAAA,UACvC,EATC,OAUD;AAAA,MACJ,EA3BC,KA2BM;AAAA,IACT,EA7BC;AAgCH,QAAM,aAAa,MACjB,CAAC,KAAK,MAAM,OAAO,eAAe;AAAA,MAChC,CAAC;AAAA,IACC,KAAK;AAAA,IACL,MAAM;AAAA,IACN,YAAY,OAAO;AAAA,IACnB,YAAY;AAAA,IACZ,UAAU,CAAC,QAAQ;AAAA,IACnB,SAAS;AAAA,IACT,aAAa;AAAA,GACd;AAAA,QACC,CAAC,KAAK,KAAK,OAAO,MAAM,IAAI,EAAE;AAAA,MAChC,EAVC,eAUgB;AAAA,IACnB,EAZC;AAeH,QAAM,oBAAkE,CAAC,UAAU;AACjF,QAAI,eAAe,MAAM,kBAAkB,MAAM,QAAQ;AACvD,YAAM,eAAe;AACrB,kBAAY,MAAM;AAAA,IACpB;AAAA,EACF;AAEA,SACE,CAAC;AAAA,IACC,MAAM,EAAE,WAAW,KAAK,CAAC,OAAO;AAAA,IAChC,UACE,CAAC,IAAI,OAAO,GAAG,sBAAsB,kCAAkC,OAAO,KAAK,GAAG,YAAY,gBAAgB;AAAA,WAC/G,aAAa,EAAE;AAAA,QAClB,EAFC;AAAA,GAIJ;AAAA,MACC,CAAC;AAAA,IACC,MAAM,UAAU;AAAA,IAChB,UACE,CAAC;AAAA,MACC,OAAO,GAAG,sBAAsB,OAAO,KAAK;AAAA,MAC5C,YAAY;AAAA,MACZ;AAAA,MACA,OAAO,MAAM;AAAA,MACb,UAAU,OAAO;AAAA,MACjB,aAAa,OAAO;AAAA,MACpB,UAAU,CAAC,UAAU,SAAS,MAAM,cAAc,KAAK;AAAA,MACvD,gBAAgB,aAAa;AAAA,MAC7B,cAAc,WAAW;AAAA,MACzB,WAAW;AAAA,IACb;AAAA,GAEH;AAAA,QACC,CAAC;AAAA,IACC,OAAO,GAAG,sBAAsB,OAAO,KAAK;AAAA,IAC5C,YAAY;AAAA,IACZ;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,eAAe,MAAM,EAAE,SAAS;AAAA,IAChC,WAAW,UAAU;AAAA,IACrB,KAAK;AAAA,IACL,QAAQ,QAAQ,OAAO,iBAAiB,OAAO,aAAa,KAAK,WAAW;AAAA,IAC5E,mBAAmB;AAAA,IACnB,gBAAgB,aAAa;AAAA,IAC7B,cAAc,WAAW;AAAA,GAC1B;AAAA,UACC,CAAC;AAAA,IACC,IAAI;AAAA,IACJ,KAAK,CAAC,OAAQ,cAAc;AAAA,IAC5B,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,OAAO,iBAAiB;AAAA,IAC1B;AAAA,IACA,OAAO,MAAM;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,aAAa,OAAO;AAAA,IACpB,MAAM;AAAA,IACN,SAAS,CAAC,UAAU,SAAS,MAAM,cAAc,KAAK;AAAA,IACtD,SAAS,MAAM,aAAa,IAAI;AAAA,IAChC,QAAQ,MAAM,aAAa,KAAK;AAAA,IAChC,WAAW;AAAA,EACb,EAAE;AAAA,QACJ,EAhCC,iBAgCkB;AAAA,MACrB,EAlDC,KAkDM;AAAA,IACT,EA3DC;AA6DL;AAEA,IAAO,uBAAQ;","names":[],"file":"chatComposer.jsx"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/components/dataDisplay/chat/chatComposer.tsx"],"sourcesContent":["import { type JSX, Show, createSignal, mergeProps } from \"solid-js\";\nimport cn from \"clsx\";\nimport { Icon } from \"../../base/icon\";\nimport { TextField } from \"../../inputs/textField\";\nimport { TextFieldWrapper } from \"../../inputs/textField/textFieldWrapper\";\nimport { ChatIconButton } from \"./chatIconButton\";\nimport { createId } from \"../../../primitives/createId\";\nimport { shouldComposerNewlineOnEnter } from \"./utils\";\n\n/**\n * Deprecated: the props of the old chat input. Use `ComposerProps` — `Chat` now draws a `Composer` as its footer,\n * and the standalone `Composer` replaces these props (`onSendMessage` → `onSend`, `sendAriaLabel` → `sendLabel`,\n * `attachAriaLabel` → `attachLabel`, `fileUpload` + `attachInputId`/`onAttachClick` → `onAttach`,\n * `shiftEnterNewline` → `sendKey=\"enter\"`; `ctrlEnterNewline` has no equivalent — Ctrl/⌘+Enter always sends).\n * Removed in the next major.\n *\n * @deprecated Use `Composer` (`ComposerProps`); see the README section \"Migrating from ChatComposer\".\n */\nexport interface ChatComposerProps {\n class?: string | undefined;\n onSendMessage?: ((text: string) => void | Promise<void>) | undefined;\n placeholder?: string | undefined;\n disabled?: boolean | undefined;\n sendAriaLabel?: string | undefined;\n shiftEnterNewline?: boolean | undefined;\n ctrlEnterNewline?: boolean | undefined;\n fileUpload?: boolean | undefined;\n attachInputId?: string | undefined;\n onAttachClick?: (() => void) | undefined;\n attachAriaLabel?: string | undefined;\n}\n\nfunction stopPropagation(event: Event): void {\n event.stopPropagation();\n}\n\nfunction insertNewlineAtCursor(element: HTMLTextAreaElement, value: string, setValue: (next: string) => void): void {\n const start = element.selectionStart ?? value.length;\n const end = element.selectionEnd ?? value.length;\n const nextValue = `${value.slice(0, start)}\\n${value.slice(end)}`;\n\n setValue(nextValue);\n\n requestAnimationFrame(() => {\n element.selectionStart = start + 1;\n element.selectionEnd = start + 1;\n });\n}\n\n/**\n * Deprecated: the old chat input — Enter sends, a TextField-based DOM and the `chat-composer*` test ids.\n * `Chat` draws a `Composer` as its footer now, and the standalone `Composer` replaces this component\n * (`onSendMessage` → `onSend`, Enter-to-send → `sendKey=\"enter\"`). Kept for the migration and removed in the\n * next major; to keep this markup inside a Chat while migrating, pass `legacyComposer` to `Chat`.\n *\n * @deprecated Use `Composer`; see the README section \"Migrating from ChatComposer\".\n */\nexport function ChatComposer(props: ChatComposerProps): JSX.Element {\n const merged = mergeProps(\n {\n placeholder: \"message\",\n disabled: false,\n sendAriaLabel: \"Send message\",\n shiftEnterNewline: true,\n ctrlEnterNewline: true,\n fileUpload: false,\n attachAriaLabel: \"Attach file\",\n },\n props\n );\n\n const [value, setValue] = createSignal(\"\");\n const [isFocused, setIsFocused] = createSignal(false);\n const inputId = createId();\n let textareaRef: HTMLTextAreaElement | undefined;\n\n const multiline = (): boolean => merged.shiftEnterNewline || merged.ctrlEnterNewline;\n const canSend = (): boolean => Boolean(merged.onSendMessage) && value().trim().length > 0 && !merged.disabled;\n const showAttach = (): boolean => merged.fileUpload && Boolean(merged.attachInputId || merged.onAttachClick);\n\n const handleSend = (): void => {\n if (!merged.onSendMessage) return;\n const text = value().trim();\n if (!text || merged.disabled) return;\n void merged.onSendMessage(text);\n setValue(\"\");\n };\n\n const handleKeyDown = (event: KeyboardEvent & { currentTarget: HTMLElement }): void => {\n // Enter that commits or cancels an IME composition belongs to the IME, not to the composer.\n if (event.isComposing || event.keyCode === 229) return;\n\n if (shouldComposerNewlineOnEnter(event, { shiftEnterNewline: merged.shiftEnterNewline, ctrlEnterNewline: merged.ctrlEnterNewline })) {\n if (event.currentTarget instanceof HTMLTextAreaElement) {\n event.preventDefault();\n insertNewlineAtCursor(event.currentTarget, value(), setValue);\n }\n return;\n }\n\n if (event.key !== \"Enter\") return;\n\n event.preventDefault();\n handleSend();\n };\n\n const attachClass = (): string =>\n cn(\"smwb-chat-icon-button\", \"smwb-chat-icon-button_edge-start\", merged.disabled && \"smwb-chat-icon-button_disabled\");\n\n const attachButton = (): JSX.Element => (\n <Show when={showAttach()}>\n <Show\n when={merged.attachInputId}\n fallback={\n <ChatIconButton\n edge=\"start\"\n aria-label={merged.attachAriaLabel}\n data-testid=\"chat-composer-attach\"\n disabled={merged.disabled}\n onClick={() => merged.onAttachClick?.()}\n onMouseDown={stopPropagation}\n >\n <Icon name=\"attach_file\" size={24} />\n </ChatIconButton>\n }\n >\n {(id) => (\n <label\n for={merged.disabled ? undefined : id()}\n class={attachClass()}\n aria-label={merged.attachAriaLabel}\n aria-disabled={merged.disabled || undefined}\n data-testid=\"chat-composer-attach\"\n onMouseDown={stopPropagation}\n >\n <Icon name=\"attach_file\" size={24} />\n </label>\n )}\n </Show>\n </Show>\n );\n\n const sendButton = (): JSX.Element => (\n <Show when={merged.onSendMessage}>\n <ChatIconButton\n edge=\"end\"\n color=\"primary\"\n aria-label={merged.sendAriaLabel}\n data-testid=\"chat-composer-send\"\n disabled={!canSend()}\n onClick={handleSend}\n onMouseDown={stopPropagation}\n >\n <Icon name=\"send\" size={24} />\n </ChatIconButton>\n </Show>\n );\n\n const onHolderMouseDown: JSX.EventHandler<HTMLDivElement, MouseEvent> = (event) => {\n if (textareaRef && event.currentTarget === event.target) {\n event.preventDefault();\n textareaRef.focus();\n }\n };\n\n return (\n <Show\n when={!(showAttach() && !merged.onSendMessage)}\n fallback={\n <div class={cn(\"smwb-chat-composer\", \"smwb-chat-composer_attach-only\", merged.class)} data-testid=\"chat-composer\">\n {attachButton()}\n </div>\n }\n >\n <Show\n when={multiline()}\n fallback={\n <TextField\n class={cn(\"smwb-chat-composer\", merged.class)}\n data-testid=\"chat-composer\"\n fullWidth\n value={value()}\n disabled={merged.disabled}\n placeholder={merged.placeholder}\n onChange={(event) => setValue(event.currentTarget.value)}\n startAdornment={attachButton()}\n endAdornment={sendButton()}\n onKeyDown={handleKeyDown}\n />\n }\n >\n <TextFieldWrapper\n class={cn(\"smwb-chat-composer\", merged.class)}\n data-testid=\"chat-composer\"\n fullWidth\n disabled={merged.disabled}\n isFilledState={value().length > 0}\n isFocused={isFocused()}\n for={inputId}\n shrink={Boolean(merged.attachInputId || merged.onAttachClick) && showAttach()}\n onHolderMouseDown={onHolderMouseDown}\n startAdornment={attachButton()}\n endAdornment={sendButton()}\n >\n <textarea\n id={inputId}\n ref={(el) => (textareaRef = el)}\n class={cn(\n \"smwb-text-field__input\",\n \"smwb-chat-composer__input\",\n \"smwb-text-field__input--show-placeholder\",\n showAttach() && \"smwb-text-field__input--adornment-start\",\n merged.onSendMessage && \"smwb-text-field__input--adornment-end\"\n )}\n value={value()}\n disabled={merged.disabled}\n placeholder={merged.placeholder}\n rows={1}\n onInput={(event) => setValue(event.currentTarget.value)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n />\n </TextFieldWrapper>\n </Show>\n </Show>\n );\n}\n\nexport default ChatComposer;\n"],"mappings":"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","names":[],"file":"chatComposer.jsx"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/dataDisplay/chat/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { ChatLayout, default as ChatLayoutDefault } from \"./chatLayout\";\nexport type { ChatLayoutProps, ChatLayoutChatProps } from \"./chatLayout\";\nexport { ChatOverlayLayout } from \"./chatOverlayLayout\";\nexport type { ChatOverlayLayoutProps, ChatOverlayLayoutChatProps } from \"./chatOverlayLayout\";\nexport { Chat, default } from \"./chat\";\nexport type { ChatProps } from \"./chat\";\nexport { ChatShell } from \"./chatShell\";\nexport type { ChatShellProps } from \"./chatShell\";\nexport { ChatHeader } from \"./chatHeader\";\nexport type { ChatHeaderProps } from \"./chatHeader\";\nexport { ChatMessages } from \"./chatMessages\";\nexport type { ChatMessagesProps } from \"./chatMessages\";\nexport { ChatMessageItem } from \"./chatMessageItem\";\nexport type { ChatMessageItemProps } from \"./chatMessageItem\";\nexport { ChatMessageIncoming } from \"./chatMessageIncoming\";\nexport type { ChatMessageIncomingProps } from \"./chatMessageIncoming\";\nexport { ChatMessageOutgoing } from \"./chatMessageOutgoing\";\nexport type { ChatMessageOutgoingProps } from \"./chatMessageOutgoing\";\nexport { ChatMessageSystem } from \"./chatMessageSystem\";\nexport type { ChatMessageSystemProps } from \"./chatMessageSystem\";\nexport { ChatMessageBubble } from \"./chatMessageBubble\";\nexport type { ChatMessageBubbleProps } from \"./chatMessageBubble\";\nexport { ChatMessageSkeleton } from \"./chatMessageSkeleton\";\nexport type { ChatMessageSkeletonProps } from \"./chatMessageSkeleton\";\nexport { ChatMessageStatus } from \"./chatMessageStatus\";\nexport type { ChatMessageStatusProps } from \"./chatMessageStatus\";\nexport { ChatMessageAvatar } from \"./chatMessageAvatar\";\nexport type { ChatMessageAvatarProps } from \"./chatMessageAvatar\";\nexport { ChatAttachments } from \"./chatAttachments\";\nexport type { ChatAttachmentsProps } from \"./chatAttachments\";\nexport { ChatAttachmentImage } from \"./chatAttachmentImage\";\nexport type { ChatAttachmentImageProps } from \"./chatAttachmentImage\";\nexport { ChatIconButton } from \"./chatIconButton\";\nexport type { ChatIconButtonProps } from \"./chatIconButton\";\nexport { ChatComposer } from \"./chatComposer\";\nexport type { ChatComposerProps } from \"./chatComposer\";\nexport { createChatInfiniteScroll } from \"./useChatInfiniteScroll\";\nexport type { CreateChatInfiniteScrollParams } from \"./useChatInfiniteScroll\";\nexport { createChatFileUpload, resolveChatFileUploadMaxFiles } from \"./useChatFileUpload\";\nexport type { CreateChatFileUploadOptions, ChatFileUploadState } from \"./useChatFileUpload\";\nexport { createChatStickToBottom, isScrolledToBottom, scrollChatToBottom } from \"./useChatStickToBottom\";\nexport type { CreateChatStickToBottomParams } from \"./useChatStickToBottom\";\nexport type {\n ChatMessage,\n ChatAttachment,\n ChatAuthor,\n ChatMessageVariant,\n ChatLayoutMode,\n ChatAnchor,\n ChatThemeMode,\n ChatMessageRenderContext,\n ChatLayoutSide,\n ChatMessageDeliveryStatus,\n ChatMessageStatus as ChatMessageStatusValue,\n ChatMessageStatusIcons,\n ChatMessageStatusRenderContext,\n} from \"./types\";\nexport {\n CHAT_EXPAND_LAYOUTS,\n CHAT_DEFAULT_FILE_UPLOAD_MAX_FILES,\n CHAT_MESSAGE_DELIVERY_STATUSES,\n CHAT_MESSAGE_STATUS_ICONS,\n CHAT_MESSAGE_STATUS_LABELS,\n} from \"./types\";\nexport {\n isImageAttachment,\n formatChatTimestamp,\n resolveAllowedLayouts,\n isChatMessageDeliveryStatus,\n resolveChatMessageStatusIcon,\n resolveChatMessageStatusLabel,\n shouldComposerNewlineOnEnter,\n getChatLayoutActions,\n shouldShowChatCloseButton,\n} from \"./utils\";\nexport type { ChatComposerNewlineOptions } from \"./utils\";\n"],
|
|
4
|
+
"sourcesContent": ["export { ChatLayout, default as ChatLayoutDefault } from \"./chatLayout\";\nexport type { ChatLayoutProps, ChatLayoutChatProps } from \"./chatLayout\";\nexport { ChatOverlayLayout } from \"./chatOverlayLayout\";\nexport type { ChatOverlayLayoutProps, ChatOverlayLayoutChatProps } from \"./chatOverlayLayout\";\nexport { Chat, default } from \"./chat\";\nexport type { ChatProps, ChatFooterComposerProps } from \"./chat\";\nexport { ChatShell } from \"./chatShell\";\nexport type { ChatShellProps } from \"./chatShell\";\nexport { ChatHeader } from \"./chatHeader\";\nexport type { ChatHeaderProps } from \"./chatHeader\";\nexport { ChatMessages } from \"./chatMessages\";\nexport type { ChatMessagesProps } from \"./chatMessages\";\nexport { ChatMessageItem } from \"./chatMessageItem\";\nexport type { ChatMessageItemProps } from \"./chatMessageItem\";\nexport { ChatMessageIncoming } from \"./chatMessageIncoming\";\nexport type { ChatMessageIncomingProps } from \"./chatMessageIncoming\";\nexport { ChatMessageOutgoing } from \"./chatMessageOutgoing\";\nexport type { ChatMessageOutgoingProps } from \"./chatMessageOutgoing\";\nexport { ChatMessageSystem } from \"./chatMessageSystem\";\nexport type { ChatMessageSystemProps } from \"./chatMessageSystem\";\nexport { ChatMessageBubble } from \"./chatMessageBubble\";\nexport type { ChatMessageBubbleProps } from \"./chatMessageBubble\";\nexport { ChatMessageSkeleton } from \"./chatMessageSkeleton\";\nexport type { ChatMessageSkeletonProps } from \"./chatMessageSkeleton\";\nexport { ChatMessageStatus } from \"./chatMessageStatus\";\nexport type { ChatMessageStatusProps } from \"./chatMessageStatus\";\nexport { ChatMessageAvatar } from \"./chatMessageAvatar\";\nexport type { ChatMessageAvatarProps } from \"./chatMessageAvatar\";\nexport { ChatAttachments } from \"./chatAttachments\";\nexport type { ChatAttachmentsProps } from \"./chatAttachments\";\nexport { ChatAttachmentImage } from \"./chatAttachmentImage\";\nexport type { ChatAttachmentImageProps } from \"./chatAttachmentImage\";\nexport { ChatIconButton } from \"./chatIconButton\";\nexport type { ChatIconButtonProps } from \"./chatIconButton\";\nexport { ChatComposer } from \"./chatComposer\";\nexport type { ChatComposerProps } from \"./chatComposer\";\nexport { createChatInfiniteScroll } from \"./useChatInfiniteScroll\";\nexport type { CreateChatInfiniteScrollParams } from \"./useChatInfiniteScroll\";\nexport { createChatFileUpload, resolveChatFileUploadMaxFiles } from \"./useChatFileUpload\";\nexport type { CreateChatFileUploadOptions, ChatFileUploadState } from \"./useChatFileUpload\";\nexport { createChatStickToBottom, isScrolledToBottom, scrollChatToBottom } from \"./useChatStickToBottom\";\nexport type { CreateChatStickToBottomParams } from \"./useChatStickToBottom\";\nexport type {\n ChatMessage,\n ChatAttachment,\n ChatAuthor,\n ChatMessageVariant,\n ChatLayoutMode,\n ChatAnchor,\n ChatThemeMode,\n ChatMessageRenderContext,\n ChatLayoutSide,\n ChatMessageDeliveryStatus,\n ChatMessageStatus as ChatMessageStatusValue,\n ChatMessageStatusIcons,\n ChatMessageStatusRenderContext,\n} from \"./types\";\nexport {\n CHAT_EXPAND_LAYOUTS,\n CHAT_DEFAULT_FILE_UPLOAD_MAX_FILES,\n CHAT_MESSAGE_DELIVERY_STATUSES,\n CHAT_MESSAGE_STATUS_ICONS,\n CHAT_MESSAGE_STATUS_LABELS,\n} from \"./types\";\nexport {\n isImageAttachment,\n formatChatTimestamp,\n resolveAllowedLayouts,\n isChatMessageDeliveryStatus,\n resolveChatMessageStatusIcon,\n resolveChatMessageStatusLabel,\n shouldComposerNewlineOnEnter,\n getChatLayoutActions,\n shouldShowChatCloseButton,\n} from \"./utils\";\nexport type { ChatComposerNewlineOptions } from \"./utils\";\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,YAAuB,WAAXA,gBAAoC;AAEzD,SAAS,yBAAyB;AAElC,SAAS,MAAM,WAAAA,gBAAe;AAE9B,SAAS,iBAAiB;AAE1B,SAAS,kBAAkB;AAE3B,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAEhC,SAAS,2BAA2B;AAEpC,SAAS,2BAA2B;AAEpC,SAAS,yBAAyB;AAElC,SAAS,yBAAyB;AAElC,SAAS,2BAA2B;AAEpC,SAAS,yBAAyB;AAElC,SAAS,yBAAyB;AAElC,SAAS,uBAAuB;AAEhC,SAAS,2BAA2B;AAEpC,SAAS,sBAAsB;AAE/B,SAAS,oBAAoB;AAE7B,SAAS,gCAAgC;AAEzC,SAAS,sBAAsB,qCAAqC;AAEpE,SAAS,yBAAyB,oBAAoB,0BAA0B;AAiBhF;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;",
|
|
6
6
|
"names": ["default"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/dataDisplay/chat/utils.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type ChatAttachment,\n type ChatLayoutMode,\n CHAT_EXPAND_LAYOUTS,\n CHAT_MESSAGE_DELIVERY_STATUSES,\n CHAT_MESSAGE_STATUS_ICONS,\n CHAT_MESSAGE_STATUS_LABELS,\n type ChatMessageDeliveryStatus,\n type ChatMessageStatus,\n type ChatMessageStatusIcons,\n} from \"./types\";\n\nexport function isChatMessageDeliveryStatus(status: ChatMessageStatus): status is ChatMessageDeliveryStatus {\n return CHAT_MESSAGE_DELIVERY_STATUSES.includes(status as ChatMessageDeliveryStatus);\n}\n\nexport function resolveChatMessageStatusIcon(\n status: ChatMessageStatus,\n icons?: ChatMessageStatusIcons & Record<string, string | undefined>\n): string | undefined {\n const custom = icons?.[status];\n if (custom) {\n return custom;\n }\n\n if (isChatMessageDeliveryStatus(status)) {\n return CHAT_MESSAGE_STATUS_ICONS[status];\n }\n\n return undefined;\n}\n\nexport function resolveChatMessageStatusLabel(status: ChatMessageStatus): string {\n if (isChatMessageDeliveryStatus(status)) {\n return CHAT_MESSAGE_STATUS_LABELS[status];\n }\n\n return String(status);\n}\n\nexport function isImageAttachment(attachment: ChatAttachment): boolean {\n if (attachment.mimeType?.startsWith(\"image/\")) {\n return true;\n }\n\n return /\\.(png|jpe?g|gif|webp|bmp|svg)$/i.test(attachment.name);\n}\n\nexport function formatChatTimestamp(value?: string | Date): string {\n if (!value) {\n return \"\";\n }\n\n const date = value instanceof Date ? value : new Date(value);\n\n if (Number.isNaN(date.getTime())) {\n return String(value);\n }\n\n return new Intl.DateTimeFormat(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }).format(date);\n}\n\nexport function resolveAllowedLayouts(input?: ChatLayoutMode[]): ChatLayoutMode[] {\n if (input == null) {\n return [\"floating\"];\n }\n\n if (input.length === 0) {\n return [];\n }\n\n return CHAT_EXPAND_LAYOUTS.filter((mode) => input.includes(mode));\n}\n\nexport function pickInitialLayout(allowed: ChatLayoutMode[], preferred?: ChatLayoutMode): ChatLayoutMode {\n if (preferred && preferred !== \"closed\" && allowed.includes(preferred)) {\n return preferred;\n }\n\n return allowed[0] ?? \"floating\";\n}\n\nexport function getChatLayoutActions(\n allowedLayouts: ChatLayoutMode[],\n currentLayout?: ChatLayoutMode\n): Exclude<ChatLayoutMode, \"closed\">[] {\n return resolveAllowedLayouts(allowedLayouts).filter(\n (mode): mode is Exclude<ChatLayoutMode, \"closed\"> => mode !== \"closed\" && mode !== currentLayout\n );\n}\n\nexport function shouldShowChatCloseButton(options: {\n floatingTrigger?: boolean | undefined;\n embedded?: boolean | undefined;\n overlayContext?: boolean | undefined;\n effectiveLayout?: ChatLayoutMode | undefined;\n showCloseButton?: boolean | undefined;\n}): boolean {\n if (options.showCloseButton === false) {\n return false;\n }\n\n if (options.showCloseButton === true) {\n return true;\n }\n\n if (\n options.overlayContext &&\n options.floatingTrigger &&\n !options.embedded &&\n (options.effectiveLayout === \"floating\" || options.effectiveLayout === \"fullHeight\")\n ) {\n return true;\n }\n\n return Boolean(options.floatingTrigger && !options.embedded && options.effectiveLayout === \"floating\");\n}\n\nexport interface ChatComposerNewlineOptions {\n shiftEnterNewline?: boolean;\n ctrlEnterNewline?: boolean;\n}\n\nexport function shouldComposerNewlineOnEnter(\n event: { key: string; shiftKey: boolean; ctrlKey: boolean; metaKey: boolean },\n options: ChatComposerNewlineOptions = {}\n): boolean {\n if (event.key !== \"Enter\") {\n return false;\n }\n\n const { shiftEnterNewline = true, ctrlEnterNewline = true } = options;\n const isCtrl = event.ctrlKey || event.metaKey;\n\n if (shiftEnterNewline && event.shiftKey && !isCtrl) {\n return true;\n }\n\n if (ctrlEnterNewline && isCtrl && !event.shiftKey) {\n return true;\n }\n\n return false;\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAEA,SAAS,4BAA4B,QAAgE;AAC1G,SAAO,+BAA+B,SAAS,MAAmC;AACpF;AAEO,SAAS,6BACd,QACA,OACoB;AACpB,QAAM,SAAS,QAAQ,MAAM;AAC7B,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAEA,MAAI,4BAA4B,MAAM,GAAG;AACvC,WAAO,0BAA0B,MAAM;AAAA,EACzC;AAEA,SAAO;AACT;AAEO,SAAS,8BAA8B,QAAmC;AAC/E,MAAI,4BAA4B,MAAM,GAAG;AACvC,WAAO,2BAA2B,MAAM;AAAA,EAC1C;AAEA,SAAO,OAAO,MAAM;AACtB;AAEO,SAAS,kBAAkB,YAAqC;AACrE,MAAI,WAAW,UAAU,WAAW,QAAQ,GAAG;AAC7C,WAAO;AAAA,EACT;AAEA,SAAO,mCAAmC,KAAK,WAAW,IAAI;AAChE;AAEO,SAAS,oBAAoB,OAA+B;AACjE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AAE3D,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,SAAO,IAAI,KAAK,eAAe,QAAW;AAAA,IACxC,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC,EAAE,OAAO,IAAI;AAChB;AAEO,SAAS,sBAAsB,OAA4C;AAChF,MAAI,SAAS,MAAM;AACjB,WAAO,CAAC,UAAU;AAAA,EACpB;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,oBAAoB,OAAO,CAAC,SAAS,MAAM,SAAS,IAAI,CAAC;AAClE;AAEO,SAAS,kBAAkB,SAA2B,WAA4C;AACvG,MAAI,aAAa,cAAc,YAAY,QAAQ,SAAS,SAAS,GAAG;AACtE,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEO,SAAS,qBACd,gBACA,eACqC;AACrC,SAAO,sBAAsB,cAAc,EAAE;AAAA,IAC3C,CAAC,SAAoD,SAAS,YAAY,SAAS;AAAA,EACrF;AACF;AAEO,SAAS,0BAA0B,SAM9B;AACV,MAAI,QAAQ,oBAAoB,OAAO;AACrC,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,oBAAoB,MAAM;AACpC,WAAO;AAAA,EACT;AAEA,MACE,QAAQ,kBACR,QAAQ,mBACR,CAAC,QAAQ,aACR,QAAQ,oBAAoB,cAAc,QAAQ,oBAAoB,eACvE;AACA,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,QAAQ,mBAAmB,CAAC,QAAQ,YAAY,QAAQ,oBAAoB,UAAU;AACvG;
|
|
4
|
+
"sourcesContent": ["import {\n type ChatAttachment,\n type ChatLayoutMode,\n CHAT_EXPAND_LAYOUTS,\n CHAT_MESSAGE_DELIVERY_STATUSES,\n CHAT_MESSAGE_STATUS_ICONS,\n CHAT_MESSAGE_STATUS_LABELS,\n type ChatMessageDeliveryStatus,\n type ChatMessageStatus,\n type ChatMessageStatusIcons,\n} from \"./types\";\n\nexport function isChatMessageDeliveryStatus(status: ChatMessageStatus): status is ChatMessageDeliveryStatus {\n return CHAT_MESSAGE_DELIVERY_STATUSES.includes(status as ChatMessageDeliveryStatus);\n}\n\nexport function resolveChatMessageStatusIcon(\n status: ChatMessageStatus,\n icons?: ChatMessageStatusIcons & Record<string, string | undefined>\n): string | undefined {\n const custom = icons?.[status];\n if (custom) {\n return custom;\n }\n\n if (isChatMessageDeliveryStatus(status)) {\n return CHAT_MESSAGE_STATUS_ICONS[status];\n }\n\n return undefined;\n}\n\nexport function resolveChatMessageStatusLabel(status: ChatMessageStatus): string {\n if (isChatMessageDeliveryStatus(status)) {\n return CHAT_MESSAGE_STATUS_LABELS[status];\n }\n\n return String(status);\n}\n\nexport function isImageAttachment(attachment: ChatAttachment): boolean {\n if (attachment.mimeType?.startsWith(\"image/\")) {\n return true;\n }\n\n return /\\.(png|jpe?g|gif|webp|bmp|svg)$/i.test(attachment.name);\n}\n\nexport function formatChatTimestamp(value?: string | Date): string {\n if (!value) {\n return \"\";\n }\n\n const date = value instanceof Date ? value : new Date(value);\n\n if (Number.isNaN(date.getTime())) {\n return String(value);\n }\n\n return new Intl.DateTimeFormat(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }).format(date);\n}\n\nexport function resolveAllowedLayouts(input?: ChatLayoutMode[]): ChatLayoutMode[] {\n if (input == null) {\n return [\"floating\"];\n }\n\n if (input.length === 0) {\n return [];\n }\n\n return CHAT_EXPAND_LAYOUTS.filter((mode) => input.includes(mode));\n}\n\nexport function pickInitialLayout(allowed: ChatLayoutMode[], preferred?: ChatLayoutMode): ChatLayoutMode {\n if (preferred && preferred !== \"closed\" && allowed.includes(preferred)) {\n return preferred;\n }\n\n return allowed[0] ?? \"floating\";\n}\n\nexport function getChatLayoutActions(\n allowedLayouts: ChatLayoutMode[],\n currentLayout?: ChatLayoutMode\n): Exclude<ChatLayoutMode, \"closed\">[] {\n return resolveAllowedLayouts(allowedLayouts).filter(\n (mode): mode is Exclude<ChatLayoutMode, \"closed\"> => mode !== \"closed\" && mode !== currentLayout\n );\n}\n\nexport function shouldShowChatCloseButton(options: {\n floatingTrigger?: boolean | undefined;\n embedded?: boolean | undefined;\n overlayContext?: boolean | undefined;\n effectiveLayout?: ChatLayoutMode | undefined;\n showCloseButton?: boolean | undefined;\n}): boolean {\n if (options.showCloseButton === false) {\n return false;\n }\n\n if (options.showCloseButton === true) {\n return true;\n }\n\n if (\n options.overlayContext &&\n options.floatingTrigger &&\n !options.embedded &&\n (options.effectiveLayout === \"floating\" || options.effectiveLayout === \"fullHeight\")\n ) {\n return true;\n }\n\n return Boolean(options.floatingTrigger && !options.embedded && options.effectiveLayout === \"floating\");\n}\n\n/**\n * Deprecated: the newline flags of the old `ChatComposer`. `Composer` picks the send key with `sendKey` instead\n * (`\"enter\"` = Enter sends, Shift+Enter makes a newline; `\"modEnter\"` = Ctrl/\u2318+Enter sends). Removed with\n * `ChatComposer` in the next major.\n *\n * @deprecated Use `Composer`'s `sendKey`; see the README section \"Migrating from ChatComposer\".\n */\nexport interface ChatComposerNewlineOptions {\n shiftEnterNewline?: boolean;\n ctrlEnterNewline?: boolean;\n}\n\n/**\n * Deprecated: the key rule of the old `ChatComposer` (which Enter sends, which makes a newline).\n * `Composer` resolves the same choice through `sendKey` in `resolveComposerKeyAction`, and `Chat` draws a `Composer`\n * by default. Kept for `ChatComposer` and `legacyComposer` only; removed in the next major.\n *\n * @deprecated Use `Composer`'s `sendKey`; see the README section \"Migrating from ChatComposer\".\n */\nexport function shouldComposerNewlineOnEnter(\n event: { key: string; shiftKey: boolean; ctrlKey: boolean; metaKey: boolean },\n options: ChatComposerNewlineOptions = {}\n): boolean {\n if (event.key !== \"Enter\") {\n return false;\n }\n\n const { shiftEnterNewline = true, ctrlEnterNewline = true } = options;\n const isCtrl = event.ctrlKey || event.metaKey;\n\n if (shiftEnterNewline && event.shiftKey && !isCtrl) {\n return true;\n }\n\n if (ctrlEnterNewline && isCtrl && !event.shiftKey) {\n return true;\n }\n\n return false;\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAEA,SAAS,4BAA4B,QAAgE;AAC1G,SAAO,+BAA+B,SAAS,MAAmC;AACpF;AAEO,SAAS,6BACd,QACA,OACoB;AACpB,QAAM,SAAS,QAAQ,MAAM;AAC7B,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAEA,MAAI,4BAA4B,MAAM,GAAG;AACvC,WAAO,0BAA0B,MAAM;AAAA,EACzC;AAEA,SAAO;AACT;AAEO,SAAS,8BAA8B,QAAmC;AAC/E,MAAI,4BAA4B,MAAM,GAAG;AACvC,WAAO,2BAA2B,MAAM;AAAA,EAC1C;AAEA,SAAO,OAAO,MAAM;AACtB;AAEO,SAAS,kBAAkB,YAAqC;AACrE,MAAI,WAAW,UAAU,WAAW,QAAQ,GAAG;AAC7C,WAAO;AAAA,EACT;AAEA,SAAO,mCAAmC,KAAK,WAAW,IAAI;AAChE;AAEO,SAAS,oBAAoB,OAA+B;AACjE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AAE3D,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;AAChC,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,SAAO,IAAI,KAAK,eAAe,QAAW;AAAA,IACxC,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC,EAAE,OAAO,IAAI;AAChB;AAEO,SAAS,sBAAsB,OAA4C;AAChF,MAAI,SAAS,MAAM;AACjB,WAAO,CAAC,UAAU;AAAA,EACpB;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,oBAAoB,OAAO,CAAC,SAAS,MAAM,SAAS,IAAI,CAAC;AAClE;AAEO,SAAS,kBAAkB,SAA2B,WAA4C;AACvG,MAAI,aAAa,cAAc,YAAY,QAAQ,SAAS,SAAS,GAAG;AACtE,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEO,SAAS,qBACd,gBACA,eACqC;AACrC,SAAO,sBAAsB,cAAc,EAAE;AAAA,IAC3C,CAAC,SAAoD,SAAS,YAAY,SAAS;AAAA,EACrF;AACF;AAEO,SAAS,0BAA0B,SAM9B;AACV,MAAI,QAAQ,oBAAoB,OAAO;AACrC,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,oBAAoB,MAAM;AACpC,WAAO;AAAA,EACT;AAEA,MACE,QAAQ,kBACR,QAAQ,mBACR,CAAC,QAAQ,aACR,QAAQ,oBAAoB,cAAc,QAAQ,oBAAoB,eACvE;AACA,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,QAAQ,mBAAmB,CAAC,QAAQ,YAAY,QAAQ,oBAAoB,UAAU;AACvG;AAqBO,SAAS,6BACd,OACA,UAAsC,CAAC,GAC9B;AACT,MAAI,MAAM,QAAQ,SAAS;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,oBAAoB,MAAM,mBAAmB,KAAK,IAAI;AAC9D,QAAM,SAAS,MAAM,WAAW,MAAM;AAEtC,MAAI,qBAAqB,MAAM,YAAY,CAAC,QAAQ;AAClD,WAAO;AAAA,EACT;AAEA,MAAI,oBAAoB,UAAU,CAAC,MAAM,UAAU;AACjD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -327,6 +327,7 @@ function DagView(props) {
|
|
|
327
327
|
return now;
|
|
328
328
|
});
|
|
329
329
|
const ownTabIndex = /* @__PURE__ */ new WeakMap();
|
|
330
|
+
const writtenTabIndex = /* @__PURE__ */ new WeakMap();
|
|
330
331
|
const syncInnerTabStops = () => {
|
|
331
332
|
const stop = untrack(tabStop);
|
|
332
333
|
for (const [id, el] of elements) {
|
|
@@ -337,6 +338,7 @@ function DagView(props) {
|
|
|
337
338
|
if (inner.getAttribute("tabindex") === next) continue;
|
|
338
339
|
if (next === null) inner.removeAttribute("tabindex");
|
|
339
340
|
else inner.setAttribute("tabindex", next);
|
|
341
|
+
writtenTabIndex.set(inner, next);
|
|
340
342
|
}
|
|
341
343
|
}
|
|
342
344
|
};
|
|
@@ -344,8 +346,28 @@ function DagView(props) {
|
|
|
344
346
|
if (!local.renderNode) return;
|
|
345
347
|
createEffect(on(tabStop, syncInnerTabStops));
|
|
346
348
|
if (typeof MutationObserver !== "function") return;
|
|
347
|
-
const observer = new MutationObserver(
|
|
348
|
-
|
|
349
|
+
const observer = new MutationObserver((records) => {
|
|
350
|
+
let sync = false;
|
|
351
|
+
for (const record of records) {
|
|
352
|
+
if (record.type !== "attributes") {
|
|
353
|
+
sync = true;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const target = record.target;
|
|
357
|
+
if (target.classList.contains("smwb-dag-view__node")) continue;
|
|
358
|
+
const now = target.getAttribute("tabindex");
|
|
359
|
+
if (writtenTabIndex.has(target) && writtenTabIndex.get(target) === now) continue;
|
|
360
|
+
ownTabIndex.set(target, now);
|
|
361
|
+
sync = true;
|
|
362
|
+
}
|
|
363
|
+
if (sync) syncInnerTabStops();
|
|
364
|
+
});
|
|
365
|
+
observer.observe(root, {
|
|
366
|
+
childList: true,
|
|
367
|
+
subtree: true,
|
|
368
|
+
attributes: true,
|
|
369
|
+
attributeFilter: ["tabindex"]
|
|
370
|
+
});
|
|
349
371
|
onCleanup(() => observer.disconnect());
|
|
350
372
|
});
|
|
351
373
|
const neighbour = (id, key) => {
|
|
@@ -481,7 +503,9 @@ function DagView(props) {
|
|
|
481
503
|
if (keyboard) ensureVisible(id);
|
|
482
504
|
};
|
|
483
505
|
const onBlur = (event) => {
|
|
484
|
-
if (event.target
|
|
506
|
+
if (event.target !== event.currentTarget || focused() !== id) return;
|
|
507
|
+
if (!ids().includes(id)) return;
|
|
508
|
+
setFocused(null);
|
|
485
509
|
};
|
|
486
510
|
const content = untrack(() => (local.renderNode ?? defaultRender)(view, state));
|
|
487
511
|
return <div
|
|
@@ -597,32 +621,17 @@ function DagView(props) {
|
|
|
597
621
|
</Show>
|
|
598
622
|
<Show when={local.controls}>
|
|
599
623
|
<div class="smwb-dag-view__controls" role="group" aria-label={labels().controls}>
|
|
600
|
-
<button
|
|
601
|
-
type="button"
|
|
602
|
-
class="smwb-dag-view__control"
|
|
603
|
-
title={labels().zoomIn}
|
|
604
|
-
onClick={() => api.zoomBy(1.25)}
|
|
605
|
-
>
|
|
624
|
+
<button type="button" class="smwb-dag-view__control" title={labels().zoomIn} onClick={() => api.zoomBy(1.25)}>
|
|
606
625
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
607
626
|
<path d="M12 5v14M5 12h14" />
|
|
608
627
|
</svg>
|
|
609
628
|
</button>
|
|
610
|
-
<button
|
|
611
|
-
type="button"
|
|
612
|
-
class="smwb-dag-view__control"
|
|
613
|
-
title={labels().zoomOut}
|
|
614
|
-
onClick={() => api.zoomBy(0.8)}
|
|
615
|
-
>
|
|
629
|
+
<button type="button" class="smwb-dag-view__control" title={labels().zoomOut} onClick={() => api.zoomBy(0.8)}>
|
|
616
630
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
617
631
|
<path d="M5 12h14" />
|
|
618
632
|
</svg>
|
|
619
633
|
</button>
|
|
620
|
-
<button
|
|
621
|
-
type="button"
|
|
622
|
-
class="smwb-dag-view__control"
|
|
623
|
-
title={labels().fitView}
|
|
624
|
-
onClick={() => api.fitView()}
|
|
625
|
-
>
|
|
634
|
+
<button type="button" class="smwb-dag-view__control" title={labels().fitView} onClick={() => api.fitView()}>
|
|
626
635
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
627
636
|
<path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5" />
|
|
628
637
|
</svg>
|