@keboola/design 11.9.0 → 12.0.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/AGENTS.md +34 -8
- package/CHANGELOG.md +155 -0
- package/COMPONENT-API.md +337 -289
- package/README.md +11 -1
- package/dist/{AIKit-ELIsegJz.js → AIKit-BD4r7ff-.js} +404 -243
- package/dist/AIKit-BD4r7ff-.js.map +1 -0
- package/dist/{Alert-BsIM_oFK.js → Alert-UI-CIs-1.js} +16 -16
- package/dist/Alert-UI-CIs-1.js.map +1 -0
- package/dist/{AlertModal-BGJdaRRj.js → AlertModal-Th2khjPi.js} +5 -5
- package/dist/AlertModal-Th2khjPi.js.map +1 -0
- package/dist/{AppShell-DRgJxpXW.js → AppShell-WSQabK8r.js} +15 -52
- package/dist/AppShell-WSQabK8r.js.map +1 -0
- package/dist/{AutoSaveTextarea-BeuWuszr.js → AutoSaveTextarea-C5iIr2Ts.js} +2 -2
- package/dist/{AutoSaveTextarea-BeuWuszr.js.map → AutoSaveTextarea-C5iIr2Ts.js.map} +1 -1
- package/dist/{Badge-o5jURtpB.js → Badge-DIjhwPvh.js} +4 -9
- package/dist/Badge-DIjhwPvh.js.map +1 -0
- package/dist/{BrandEditor-BsTBM3s6.js → BrandEditor-BU23Vl8V.js} +7 -7
- package/dist/{BrandEditor-BsTBM3s6.js.map → BrandEditor-BU23Vl8V.js.map} +1 -1
- package/dist/{BrandLogo-CoKBk4MI.js → BrandLogo-CKpVSZb6.js} +4 -4
- package/dist/BrandLogo-CKpVSZb6.js.map +1 -0
- package/dist/{Breadcrumb-xqEUxfwn.js → Breadcrumb-p9HtMLCc.js} +8 -14
- package/dist/Breadcrumb-p9HtMLCc.js.map +1 -0
- package/dist/{Button-DsRrU5F1.js → Button-Ca4Q3VJU.js} +31 -13
- package/dist/Button-Ca4Q3VJU.js.map +1 -0
- package/dist/{Calendar-cG5NIJ4O.js → Calendar-DFtmZzbF.js} +99 -99
- package/dist/Calendar-DFtmZzbF.js.map +1 -0
- package/dist/{Card-Dyo7055Q.js → Card-Cr9MBNHu.js} +4 -4
- package/dist/Card-Cr9MBNHu.js.map +1 -0
- package/dist/{Checkbox-Dq5fPNrO.js → Checkbox-8yIIgY7g.js} +4 -4
- package/dist/Checkbox-8yIIgY7g.js.map +1 -0
- package/dist/{Clipboard-BZitKiSA.js → Clipboard-_xf6hMDD.js} +2 -2
- package/dist/{Clipboard-BZitKiSA.js.map → Clipboard-_xf6hMDD.js.map} +1 -1
- package/dist/{ClipboardButton-KHQnPEh_.js → ClipboardButton-DHa1trtI.js} +4 -4
- package/dist/{ClipboardButton-KHQnPEh_.js.map → ClipboardButton-DHa1trtI.js.map} +1 -1
- package/dist/{CodeEditor-BJKJXA0c.js → CodeEditor-BSo-oLFG.js} +55 -165
- package/dist/CodeEditor-BSo-oLFG.js.map +1 -0
- package/dist/{ColorInput-Bj3dfPFA.js → ColorInput-DSMqrs2-.js} +12 -27
- package/dist/ColorInput-DSMqrs2-.js.map +1 -0
- package/dist/{ColorModeSwitch-CWt-DZGC.js → ColorModeSwitch-D7EuWyJz.js} +7 -17
- package/dist/ColorModeSwitch-D7EuWyJz.js.map +1 -0
- package/dist/Combobox-CxRAYOBt.js +1069 -0
- package/dist/Combobox-CxRAYOBt.js.map +1 -0
- package/dist/{Command-BDU3C1gg.js → Command-BU_cVurn.js} +4 -4
- package/dist/{Command-BDU3C1gg.js.map → Command-BU_cVurn.js.map} +1 -1
- package/dist/{CopyField-BHRQUyuF.js → CopyField-6_c-NdLO.js} +17 -53
- package/dist/{CopyField-BHRQUyuF.js.map → CopyField-6_c-NdLO.js.map} +1 -1
- package/dist/{DateInput-B6N8g0ra.js → DateInput-DyEErfJf.js} +6 -6
- package/dist/{DateInput-B6N8g0ra.js.map → DateInput-DyEErfJf.js.map} +1 -1
- package/dist/{DatePicker-nA8YdE84.js → DatePicker-CtSa9b3V.js} +3 -3
- package/dist/{DatePicker-nA8YdE84.js.map → DatePicker-CtSa9b3V.js.map} +1 -1
- package/dist/{DateRangeInput-7M9Z4cVO.js → DateRangeInput-Dg7-VUd9.js} +10 -14
- package/dist/DateRangeInput-Dg7-VUd9.js.map +1 -0
- package/dist/{DateRangePicker-DjSUFjh4.js → DateRangePicker-BoPnh4aH.js} +9 -13
- package/dist/DateRangePicker-BoPnh4aH.js.map +1 -0
- package/dist/DiffView-ppTIzh2h.js.map +1 -1
- package/dist/{DropdownMenu-CgVwhDvl.js → DropdownMenu-gRM-A8qU.js} +3 -3
- package/dist/DropdownMenu-gRM-A8qU.js.map +1 -0
- package/dist/{FieldItem-DZGIdiXE.js → FieldItem-2wMXQ0Qw.js} +12 -25
- package/dist/FieldItem-2wMXQ0Qw.js.map +1 -0
- package/dist/{FieldItem-vhIJW4pj.d.ts → FieldItem-CPN1xjN5.d.ts} +11 -25
- package/dist/{FileUpload-DYQCTGjU.js → FileUpload-C83tXuE2.js} +11 -16
- package/dist/{FileUpload-DYQCTGjU.js.map → FileUpload-C83tXuE2.js.map} +1 -1
- package/dist/{Form-CcK7dRrC.js → Form-95rVLfX8.js} +15 -23
- package/dist/{Form-CcK7dRrC.js.map → Form-95rVLfX8.js.map} +1 -1
- package/dist/{FormGroup-DR_gZ25-.js → FormGroup-CmNiAtU6.js} +11 -17
- package/dist/FormGroup-CmNiAtU6.js.map +1 -0
- package/dist/{FullScreenModal-CN9nAs72.js → FullScreenModal-CD7mYeTz.js} +15 -29
- package/dist/FullScreenModal-CD7mYeTz.js.map +1 -0
- package/dist/{HoverCard-B9ZMJxjn.js → HoverCard-B8OKu9XZ.js} +2 -2
- package/dist/{HoverCard-B9ZMJxjn.js.map → HoverCard-B8OKu9XZ.js.map} +1 -1
- package/dist/{InputGroup-Do8K2hvD.js → InputGroup-B4QOPxHl.js} +11 -13
- package/dist/InputGroup-B4QOPxHl.js.map +1 -0
- package/dist/{Kbd-LCFMumoq.js → Kbd-J4n1J6i4.js} +23 -13
- package/dist/Kbd-J4n1J6i4.js.map +1 -0
- package/dist/{MarkedText-DNGEUVWc.js → MarkedText-DlmlJO0u.js} +2 -2
- package/dist/{MarkedText-DNGEUVWc.js.map → MarkedText-DlmlJO0u.js.map} +1 -1
- package/dist/{MermaidDiagram-ZG0iiDV_.js → MermaidDiagram-BQvz6bhv.js} +16 -34
- package/dist/MermaidDiagram-BQvz6bhv.js.map +1 -0
- package/dist/{Modal-I3VWk2oo.js → Modal-Driyqs_N.js} +17 -34
- package/dist/Modal-Driyqs_N.js.map +1 -0
- package/dist/{ModalTitle-CeLM_mX9.js → ModalTitle-BxopkIoQ.js} +3 -3
- package/dist/ModalTitle-BxopkIoQ.js.map +1 -0
- package/dist/{MultiActionButtonGroup-CYZ8IgSf.js → MultiActionButtonGroup-BPnmzBtw.js} +3 -3
- package/dist/{MultiActionButtonGroup-CYZ8IgSf.js.map → MultiActionButtonGroup-BPnmzBtw.js.map} +1 -1
- package/dist/{Navbar-Liy1TPI7.js → Navbar-B_DNpv5s.js} +9 -13
- package/dist/{Navbar-Liy1TPI7.js.map → Navbar-B_DNpv5s.js.map} +1 -1
- package/dist/{OtpInput-CbbymqYs.js → OtpInput-I8B8Vjdl.js} +2 -2
- package/dist/{OtpInput-CbbymqYs.js.map → OtpInput-I8B8Vjdl.js.map} +1 -1
- package/dist/{PageHeader-Q3IpCnQd.js → PageHeader-CgfyXpf1.js} +13 -26
- package/dist/PageHeader-CgfyXpf1.js.map +1 -0
- package/dist/{PageLayout-DSVM-ASz.js → PageLayout-DiAAILuS.js} +12 -20
- package/dist/PageLayout-DiAAILuS.js.map +1 -0
- package/dist/{PageToolbar-BKVJiDAL.js → PageToolbar-DOAtAnfL.js} +12 -42
- package/dist/PageToolbar-DOAtAnfL.js.map +1 -0
- package/dist/{Pagination-C_b7Xhey.js → Pagination-LaSg-5cl.js} +3 -3
- package/dist/{Pagination-C_b7Xhey.js.map → Pagination-LaSg-5cl.js.map} +1 -1
- package/dist/{Popconfirm-5pBzT_HQ.js → Popconfirm-SLz0zodk.js} +3 -3
- package/dist/{Popconfirm-5pBzT_HQ.js.map → Popconfirm-SLz0zodk.js.map} +1 -1
- package/dist/{Popover-BEbQrC_P.js → Popover-CEk915I1.js} +4 -3
- package/dist/Popover-CEk915I1.js.map +1 -0
- package/dist/{RadioGroup-Byc2mym4.js → RadioGroup-CBPRLRN0.js} +4 -4
- package/dist/{RadioGroup-Byc2mym4.js.map → RadioGroup-CBPRLRN0.js.map} +1 -1
- package/dist/{Search-Dhig_hPD.js → Search-DmkQo716.js} +3 -3
- package/dist/{Search-Dhig_hPD.js.map → Search-DmkQo716.js.map} +1 -1
- package/dist/{SearchInput-92r2bkA7.js → SearchInput-CEfQDNl3.js} +8 -13
- package/dist/SearchInput-CEfQDNl3.js.map +1 -0
- package/dist/{SectionNav-CNLJsiVG.js → SectionNav-B_qf0AXi.js} +10 -42
- package/dist/SectionNav-B_qf0AXi.js.map +1 -0
- package/dist/{Select-DV3Hak_l.js → Select-ByRvkZ3D.js} +8 -11
- package/dist/{Select-DV3Hak_l.js.map → Select-ByRvkZ3D.js.map} +1 -1
- package/dist/{Sheet-OparjIi-.js → Sheet-C-yXk5Da.js} +5 -9
- package/dist/Sheet-C-yXk5Da.js.map +1 -0
- package/dist/{Sidebar-CLEbBtNY.js → Sidebar-Ds0E6PbR.js} +16 -33
- package/dist/Sidebar-Ds0E6PbR.js.map +1 -0
- package/dist/{Slider-DLclvRws.js → Slider-DWdu9NuM.js} +3 -3
- package/dist/{Slider-DLclvRws.js.map → Slider-DWdu9NuM.js.map} +1 -1
- package/dist/{Stepper-C8sm9ZFM.js → Stepper-BLkLhfnd.js} +6 -9
- package/dist/{Stepper-C8sm9ZFM.js.map → Stepper-BLkLhfnd.js.map} +1 -1
- package/dist/{Switch-B0WdGSjz.js → Switch-DZvNePOm.js} +2 -2
- package/dist/{Switch-B0WdGSjz.js.map → Switch-DZvNePOm.js.map} +1 -1
- package/dist/{Table-CvYuTuNU.js → Table-BaVT5Tkn.js} +6 -11
- package/dist/{Table-CvYuTuNU.js.map → Table-BaVT5Tkn.js.map} +1 -1
- package/dist/{Tabs-eB974xJf.js → Tabs-Dt9oLYHC.js} +3 -3
- package/dist/{Tabs-eB974xJf.js.map → Tabs-Dt9oLYHC.js.map} +1 -1
- package/dist/{TextInput-CFTf4Cz1.js → TextInput-CDG2XpBl.js} +10 -14
- package/dist/TextInput-CDG2XpBl.js.map +1 -0
- package/dist/{ThemeProvider-DAmNn9Sd.js → ThemeProvider-DXsxFg1U.js} +13 -31
- package/dist/ThemeProvider-DXsxFg1U.js.map +1 -0
- package/dist/{TimePicker-BGeqc-Ed.js → TimePicker-CDGYrRxi.js} +2 -2
- package/dist/{TimePicker-BGeqc-Ed.js.map → TimePicker-CDGYrRxi.js.map} +1 -1
- package/dist/{Timeline-C8-wnRRr.js → Timeline-B-I6sb0M.js} +2 -2
- package/dist/{Timeline-C8-wnRRr.js.map → Timeline-B-I6sb0M.js.map} +1 -1
- package/dist/{Toast-Dr6Uw7ao.js → Toast-PfQf3vj-.js} +2 -2
- package/dist/{Toast-Dr6Uw7ao.js.map → Toast-PfQf3vj-.js.map} +1 -1
- package/dist/{Workbench-UR2FBC7I.js → Workbench-DmZzpkj7.js} +2 -2
- package/dist/{Workbench-UR2FBC7I.js.map → Workbench-DmZzpkj7.js.map} +1 -1
- package/dist/{ZoomableSvg-BZlk3PFJ.js → ZoomableSvg-BzXVfgnI.js} +5 -19
- package/dist/ZoomableSvg-BzXVfgnI.js.map +1 -0
- package/dist/charts.d.ts +21 -52
- package/dist/charts.js +13 -39
- package/dist/charts.js.map +1 -1
- package/dist/{context-D7X470dy.js → context-U293r3v-.js} +5 -9
- package/dist/context-U293r3v-.js.map +1 -0
- package/dist/editors.d.ts +27 -124
- package/dist/editors.js +29 -71
- package/dist/editors.js.map +1 -1
- package/dist/{findLiteralMatches-BGBw8Vbl.js → findLiteralMatches-DgGLzyG0.js} +8 -20
- package/dist/findLiteralMatches-DgGLzyG0.js.map +1 -0
- package/dist/flint.d.ts +3 -6
- package/dist/flint.js +31 -80
- package/dist/flint.js.map +1 -1
- package/dist/{icons-Cek151jC.js → icons-wcA70iQx.js} +105 -2
- package/dist/icons-wcA70iQx.js.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +2 -2
- package/dist/{index-m-kQEWiY.d.ts → index-B7k-09i1.d.ts} +14 -2
- package/dist/index.d.ts +1151 -1838
- package/dist/index.js +68 -67
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/AppShell.js +1 -1
- package/dist/internal/blocks/AuthLayout.js +7 -27
- package/dist/internal/blocks/AuthLayout.js.map +1 -1
- package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChartPanel.js +4 -8
- package/dist/internal/blocks/ChartPanel.js.map +1 -1
- package/dist/internal/blocks/ChipEditor.js +13 -21
- package/dist/internal/blocks/ChipEditor.js.map +1 -1
- package/dist/internal/blocks/ClipboardButton.js +1 -1
- package/dist/internal/blocks/ColorInput.js +1 -1
- package/dist/internal/blocks/ColorModeSwitch.js +1 -1
- package/dist/internal/blocks/Command.js +1 -1
- package/dist/internal/blocks/CopyField.js +1 -1
- package/dist/internal/blocks/DashboardHero.js +4 -7
- package/dist/internal/blocks/DashboardHero.js.map +1 -1
- package/dist/internal/blocks/DateInput.js +1 -1
- package/dist/internal/blocks/DateRangeInput.js +1 -1
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
- package/dist/internal/blocks/EmptyState.js +5 -9
- package/dist/internal/blocks/EmptyState.js.map +1 -1
- package/dist/internal/blocks/ErrorState.js +5 -9
- package/dist/internal/blocks/ErrorState.js.map +1 -1
- package/dist/internal/blocks/ExportMenu.js +6 -10
- package/dist/internal/blocks/ExportMenu.js.map +1 -1
- package/dist/internal/blocks/Form/connectors/ComboboxField.js +40 -0
- package/dist/internal/blocks/Form/connectors/ComboboxField.js.map +1 -0
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +5 -22
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -1
- package/dist/internal/blocks/Form.js +1 -1
- package/dist/internal/blocks/FormGroup.js +1 -1
- package/dist/internal/blocks/GoogleButton.js +1 -1
- package/dist/internal/blocks/MicrosoftButton.js +1 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
- package/dist/internal/blocks/MultiCombobox.js +161 -154
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +1 -1
- package/dist/internal/blocks/OtpInput.js +1 -1
- package/dist/internal/blocks/PageHeader.js +1 -1
- package/dist/internal/blocks/PageLayout.js +1 -1
- package/dist/internal/blocks/PageToolbar.js +1 -1
- package/dist/internal/blocks/PasswordInput.js +4 -4
- package/dist/internal/blocks/PasswordInput.js.map +1 -1
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +4 -4
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +3 -3
- package/dist/internal/blocks/StatCard.js +4 -8
- package/dist/internal/blocks/StatCard.js.map +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/Textarea.js +2 -2
- package/dist/internal/blocks/TimeInput.js +5 -5
- package/dist/internal/blocks/TimeInput.js.map +1 -1
- package/dist/internal/components/Alert.js +1 -1
- package/dist/internal/components/AlertModal.js +1 -1
- package/dist/internal/components/Avatar.js +1 -1
- package/dist/internal/components/Badge.js +1 -1
- package/dist/internal/components/BrandLogo.js +1 -1
- package/dist/internal/components/Breadcrumb.js +1 -1
- package/dist/internal/components/Button.js +1 -1
- package/dist/internal/components/ButtonGroup.js.map +1 -1
- package/dist/internal/components/Calendar.js +1 -1
- package/dist/internal/components/Card.js +1 -1
- package/dist/internal/components/Checkbox.js +1 -1
- package/dist/internal/components/Clipboard.js +1 -1
- package/dist/internal/components/CollapsiblePanel.js +2 -2
- package/dist/internal/components/Combobox.js +2 -2
- package/dist/internal/components/DatePicker.js +1 -1
- package/dist/internal/components/DateRangePicker.js +1 -1
- package/dist/internal/components/DropdownMenu.js +1 -1
- package/dist/internal/components/FileUpload.js +1 -1
- package/dist/internal/components/FullScreenModal.js +1 -1
- package/dist/internal/components/HoverCard.js +1 -1
- package/dist/internal/components/InputGroup.js +1 -1
- package/dist/internal/components/Kbd.js +1 -1
- package/dist/internal/components/MarkedText.js +1 -1
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +1 -1
- package/dist/internal/components/Modal.js +1 -1
- package/dist/internal/components/Navbar.js +1 -1
- package/dist/internal/components/Pagination.js +1 -1
- package/dist/internal/components/PanelWithDetails.js +1 -1
- package/dist/internal/components/Popconfirm.js +1 -1
- package/dist/internal/components/Popover.js +1 -1
- package/dist/internal/components/RadioGroup.js +1 -1
- package/dist/internal/components/Search.js +1 -1
- package/dist/internal/components/Select.js +1 -1
- package/dist/internal/components/Separator.js.map +1 -1
- package/dist/internal/components/Sheet.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Skeleton/Skeleton.js +5 -9
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/SpotlightBackdrop.js +3 -8
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
- package/dist/internal/components/StatusDot.js +8 -15
- package/dist/internal/components/StatusDot.js.map +1 -1
- package/dist/internal/components/Stepper.js +1 -1
- package/dist/internal/components/Switch.js +1 -1
- package/dist/internal/components/Table.js +1 -1
- package/dist/internal/components/Tabs.js +1 -1
- package/dist/internal/components/ThemeProvider.js +3 -3
- package/dist/internal/components/TimePicker.js +1 -1
- package/dist/internal/components/Timeline.js +1 -1
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Tooltip.js +1 -1
- package/dist/internal/components/Truncated.js +4 -8
- package/dist/internal/components/Truncated.js.map +1 -1
- package/dist/internal/components/Workbench.js +1 -1
- package/dist/internal/components/ZoomableSvg.js +1 -1
- package/dist/internal/hooks/useScrollbarPosition.js +1 -1
- package/dist/internal/hooks/useStableCallback.js +4 -13
- package/dist/internal/hooks/useStableCallback.js.map +1 -1
- package/dist/internal/utils.js +2 -2
- package/dist/markdown-editor.d.ts +15 -37
- package/dist/markdown-editor.js +17 -23
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +4 -6
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.d.ts +9 -19
- package/dist/rjsf.js +44 -84
- package/dist/rjsf.js.map +1 -1
- package/dist/{styles-BAFscjSV.js → styles-gzcjOyKv.js} +6 -6
- package/dist/styles-gzcjOyKv.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/svgTransforms-Dw2hRA-i.js +51 -0
- package/dist/svgTransforms-Dw2hRA-i.js.map +1 -0
- package/dist/testing.d.ts +3 -10
- package/dist/testing.js +5 -12
- package/dist/testing.js.map +1 -1
- package/dist/themeTokens-7DEab0kp.js +31 -0
- package/dist/themeTokens-7DEab0kp.js.map +1 -0
- package/dist/{toast-DIC0iNRf.js → toast-CyXEdaCZ.js} +3 -3
- package/dist/toast-CyXEdaCZ.js.map +1 -0
- package/dist/{themeScopeContext-D7fSyb06.js → useColorSchemeState-Cw4MCXUs.js} +14 -14
- package/dist/useColorSchemeState-Cw4MCXUs.js.map +1 -0
- package/dist/{useControllableState-M6494mCT.js → useControllableState-CUYXMsfz.js} +3 -7
- package/dist/useControllableState-CUYXMsfz.js.map +1 -0
- package/dist/useElement-D-RjrGa4.js +21 -0
- package/dist/useElement-D-RjrGa4.js.map +1 -0
- package/dist/useThemeAttributes-B199Regy.js +67 -0
- package/dist/useThemeAttributes-B199Regy.js.map +1 -0
- package/dist/{utils-BW4AE8VP.js → utils-Bd28bWgm.js} +31 -26
- package/dist/utils-Bd28bWgm.js.map +1 -0
- package/dist/vega.d.ts +8 -30
- package/dist/vega.js +5 -13
- package/dist/vega.js.map +1 -1
- package/dist/{vegaTheme-CSvFEMBl.js → vegaTheme-VQMWTlBw.js} +7 -21
- package/dist/vegaTheme-VQMWTlBw.js.map +1 -0
- package/package.json +10 -9
- package/src/styles.css +120 -14
- package/src/theme.css +126 -6
- package/dist/AIKit-ELIsegJz.js.map +0 -1
- package/dist/Alert-BsIM_oFK.js.map +0 -1
- package/dist/AlertModal-BGJdaRRj.js.map +0 -1
- package/dist/AppShell-DRgJxpXW.js.map +0 -1
- package/dist/Badge-o5jURtpB.js.map +0 -1
- package/dist/BrandLogo-CoKBk4MI.js.map +0 -1
- package/dist/Breadcrumb-xqEUxfwn.js.map +0 -1
- package/dist/Button-DsRrU5F1.js.map +0 -1
- package/dist/Calendar-cG5NIJ4O.js.map +0 -1
- package/dist/Card-Dyo7055Q.js.map +0 -1
- package/dist/Checkbox-Dq5fPNrO.js.map +0 -1
- package/dist/CodeEditor-BJKJXA0c.js.map +0 -1
- package/dist/ColorInput-Bj3dfPFA.js.map +0 -1
- package/dist/ColorModeSwitch-CWt-DZGC.js.map +0 -1
- package/dist/Combobox-D8PrEqTG.js +0 -619
- package/dist/Combobox-D8PrEqTG.js.map +0 -1
- package/dist/DateRangeInput-7M9Z4cVO.js.map +0 -1
- package/dist/DateRangePicker-DjSUFjh4.js.map +0 -1
- package/dist/DropdownMenu-CgVwhDvl.js.map +0 -1
- package/dist/FieldItem-DZGIdiXE.js.map +0 -1
- package/dist/FormGroup-DR_gZ25-.js.map +0 -1
- package/dist/FullScreenModal-CN9nAs72.js.map +0 -1
- package/dist/InputGroup-Do8K2hvD.js.map +0 -1
- package/dist/Kbd-LCFMumoq.js.map +0 -1
- package/dist/MermaidDiagram-ZG0iiDV_.js.map +0 -1
- package/dist/Modal-I3VWk2oo.js.map +0 -1
- package/dist/ModalTitle-CeLM_mX9.js.map +0 -1
- package/dist/PageHeader-Q3IpCnQd.js.map +0 -1
- package/dist/PageLayout-DSVM-ASz.js.map +0 -1
- package/dist/PageToolbar-BKVJiDAL.js.map +0 -1
- package/dist/Popover-BEbQrC_P.js.map +0 -1
- package/dist/SearchInput-92r2bkA7.js.map +0 -1
- package/dist/SectionNav-CNLJsiVG.js.map +0 -1
- package/dist/Sheet-OparjIi-.js.map +0 -1
- package/dist/Sidebar-CLEbBtNY.js.map +0 -1
- package/dist/TextInput-CFTf4Cz1.js.map +0 -1
- package/dist/ThemeProvider-DAmNn9Sd.js.map +0 -1
- package/dist/ZoomableSvg-BZlk3PFJ.js.map +0 -1
- package/dist/context-D7X470dy.js.map +0 -1
- package/dist/findLiteralMatches-BGBw8Vbl.js.map +0 -1
- package/dist/icons-Cek151jC.js.map +0 -1
- package/dist/styles-BAFscjSV.js.map +0 -1
- package/dist/svgTransforms-CJAYPk7o.js +0 -81
- package/dist/svgTransforms-CJAYPk7o.js.map +0 -1
- package/dist/themeScopeContext-D7fSyb06.js.map +0 -1
- package/dist/themeTokens-qP1-55O7.js +0 -119
- package/dist/themeTokens-qP1-55O7.js.map +0 -1
- package/dist/toast-DIC0iNRf.js.map +0 -1
- package/dist/useControllableState-M6494mCT.js.map +0 -1
- package/dist/useElement-BK3AAiIf.js +0 -24
- package/dist/useElement-BK3AAiIf.js.map +0 -1
- package/dist/utils-BW4AE8VP.js.map +0 -1
- package/dist/vegaTheme-CSvFEMBl.js.map +0 -1
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { cn } from "./classNames-BzrkDnOD.js";
|
|
2
|
-
import { Tooltip, TooltipProvider } from "./utils-
|
|
3
|
-
import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Ban, BarChart3, Bell, Bug, Calendar, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Circle, CircleAlert, CircleCheck, CircleHelp, CirclePause, CirclePlay, CirclePlus, CircleStop, CircleX, Clock, Cog, Copy, Database, Download, Ellipsis, ExternalLink, Eye, File, FilePen, FileText, Flag, Folder, Gauge, GitBranch, GitMerge, GitPullRequest, Globe, Hand, History, Hourglass, Info, Key, Layers, LineChart, Link, List, ListChecks, Loader2, Lock, Mail, Maximize2, Minimize2, Minus, Pencil, Play, Plus, RefreshCw, Rocket, RotateCcw, RotateCw, Save, Search, Send, Settings, Sparkles, Star, Table, ThumbsDown, ThumbsUp, Trash2, TriangleAlert, Upload, User, Users, WandSparkles, Warehouse, Workflow, X, XCircle, Zap } from "./icons-
|
|
4
|
-
import { Button } from "./Button-
|
|
2
|
+
import { Tooltip, TooltipProvider } from "./utils-Bd28bWgm.js";
|
|
3
|
+
import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Ban, BarChart3, Bell, Bug, Calendar, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Circle, CircleAlert, CircleCheck, CircleHelp, CirclePause, CirclePlay, CirclePlus, CircleStop, CircleX, Clock, Cog, Copy, Database, Download, Ellipsis, ExternalLink, Eye, File, FilePen, FileText, Flag, Folder, Gauge, GitBranch, GitMerge, GitPullRequest, Globe, Hand, History, Hourglass, Info, Key, Layers, LineChart, Link, List, ListChecks, Loader2, Lock, Mail, Maximize2, Minimize2, Minus, Pencil, Play, Plus, RefreshCw, Rocket, RotateCcw, RotateCw, Save, Search, Send, Settings, Sparkles, Star, Table, ThumbsDown, ThumbsUp, Trash2, TriangleAlert, Upload, User, Users, WandSparkles, Warehouse, Workflow, X, XCircle, Zap } from "./icons-wcA70iQx.js";
|
|
4
|
+
import { Button } from "./Button-Ca4Q3VJU.js";
|
|
5
5
|
import { ButtonGroup } from "./internal/components/ButtonGroup.js";
|
|
6
|
-
import { ClipboardButton } from "./ClipboardButton-
|
|
7
|
-
import { FullScreenModal, FullScreenModalBody, FullScreenModalHeader } from "./FullScreenModal-
|
|
6
|
+
import { ClipboardButton } from "./ClipboardButton-DHa1trtI.js";
|
|
7
|
+
import { FullScreenModal, FullScreenModalBody, FullScreenModalHeader } from "./FullScreenModal-CD7mYeTz.js";
|
|
8
8
|
import { Truncated } from "./internal/components/Truncated.js";
|
|
9
|
-
import { HoverCard } from "./HoverCard-
|
|
10
|
-
import { Command } from "./Command-
|
|
11
|
-
import { TextInput } from "./TextInput-
|
|
12
|
-
import { Checkbox } from "./Checkbox-
|
|
13
|
-
import { Badge } from "./Badge-
|
|
9
|
+
import { HoverCard } from "./HoverCard-B8OKu9XZ.js";
|
|
10
|
+
import { Command } from "./Command-BU_cVurn.js";
|
|
11
|
+
import { TextInput } from "./TextInput-CDG2XpBl.js";
|
|
12
|
+
import { Checkbox } from "./Checkbox-8yIIgY7g.js";
|
|
13
|
+
import { Badge } from "./Badge-DIjhwPvh.js";
|
|
14
14
|
import { Textarea } from "./internal/blocks/Textarea.js";
|
|
15
|
-
import { Table as Table$1 } from "./Table-
|
|
15
|
+
import { Table as Table$1 } from "./Table-BaVT5Tkn.js";
|
|
16
16
|
import { DiagramSkeleton } from "./internal/blocks/DiagramShared/DiagramSkeleton.js";
|
|
17
17
|
import { DiagramSource } from "./DiagramSource-C5_d8Gdj.js";
|
|
18
18
|
import { Progress } from "./internal/components/Progress.js";
|
|
19
19
|
import { Slot } from "@radix-ui/react-slot";
|
|
20
|
-
import { createContext, isValidElement, use, useCallback, useEffect, useId, useRef, useState } from "react";
|
|
20
|
+
import { createContext, isValidElement, use, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
21
21
|
import { cva } from "class-variance-authority";
|
|
22
22
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
23
23
|
import TextareaAutosize from "react-textarea-autosize";
|
|
@@ -35,7 +35,7 @@ const DEFAULT_LABELS = {
|
|
|
35
35
|
up: "Good answer",
|
|
36
36
|
down: "Bad answer"
|
|
37
37
|
};
|
|
38
|
-
/** Roomier for a panel
|
|
38
|
+
/** Roomier for a panel; compact for a dense transcript. */
|
|
39
39
|
const SIZES = {
|
|
40
40
|
small: {
|
|
41
41
|
button: "icon-xs",
|
|
@@ -47,16 +47,11 @@ const SIZES = {
|
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
50
|
+
* Copy and thumbs up/down for a finished answer.
|
|
51
51
|
*
|
|
52
|
-
* -
|
|
53
|
-
*
|
|
54
|
-
* -
|
|
55
|
-
* - **A vote can be changed but not withdrawn.** `aria-pressed` says which one is recorded, and
|
|
56
|
-
* both buttons stay focusable so a reader can switch. Pressing the pressed one re-sends the
|
|
57
|
-
* same vote.
|
|
58
|
-
* - The recorded vote and the write are the caller's: the two chats vote against different
|
|
59
|
-
* endpoints, and only the caller knows whether a turn is finished enough to rate.
|
|
52
|
+
* - Always rendered, never hover-only, so it is reachable without a pointer.
|
|
53
|
+
* - A vote can be changed but not withdrawn; pressing the pressed one re-sends it.
|
|
54
|
+
* - The caller owns the recorded vote and the write.
|
|
60
55
|
*/
|
|
61
56
|
const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, labels = DEFAULT_LABELS, confirmation, size = "small", layout = "inline" }) => {
|
|
62
57
|
const { button, gap } = SIZES[size];
|
|
@@ -247,15 +242,9 @@ const AnswerSummary = ({ items, variant = "success", noAnswerLabel = "No answer"
|
|
|
247
242
|
/**
|
|
248
243
|
* The Lucide component each `icon:<name>` token draws.
|
|
249
244
|
*
|
|
250
|
-
* -
|
|
251
|
-
*
|
|
252
|
-
* -
|
|
253
|
-
* teaches and this map lacks is a compile error, not a token that silently disappears from an
|
|
254
|
-
* answer.
|
|
255
|
-
* - Several names map to one component on purpose: FA distinguishes `gear` from `cog` and
|
|
256
|
-
* `warning` from `triangle-exclamation`; Lucide draws each pair with one icon.
|
|
257
|
-
* - Read through `Object.hasOwn`, never by plain index: a model-emitted `icon:constructor`
|
|
258
|
-
* otherwise answers with an `Object.prototype` member and React tries to render it.
|
|
245
|
+
* - Names are FontAwesome-solid ones, published as `CHAT_INLINE_ICON_NAMES`.
|
|
246
|
+
* - The `satisfies` is the drift guard: a name the prompt teaches and this map lacks fails to compile.
|
|
247
|
+
* - Read through `Object.hasOwn`: `icon:constructor` would otherwise hit `Object.prototype`.
|
|
259
248
|
*/
|
|
260
249
|
const ICON_REGISTRY = {
|
|
261
250
|
"alert-circle": AlertCircle,
|
|
@@ -353,50 +342,29 @@ const ICON_REGISTRY = {
|
|
|
353
342
|
zap: Zap
|
|
354
343
|
};
|
|
355
344
|
/**
|
|
356
|
-
* Extra classes a single name needs
|
|
345
|
+
* Extra classes a single name needs.
|
|
357
346
|
*
|
|
358
|
-
* - `spinner`
|
|
359
|
-
*
|
|
360
|
-
* a damaged ring, not as waiting.
|
|
361
|
-
* - Read through `Object.hasOwn`, for the same reason the registry is.
|
|
347
|
+
* - `spinner` spins (per `MAINTAINING.md`): a still `Loader2` reads as a broken ring.
|
|
348
|
+
* - Read through `Object.hasOwn`, like the registry.
|
|
362
349
|
*/
|
|
363
350
|
const ICON_CLASSES = { spinner: "tw:animate-spin" };
|
|
364
351
|
/**
|
|
365
352
|
* A whole `icon:<name>` token and nothing else.
|
|
366
353
|
*
|
|
367
|
-
* -
|
|
368
|
-
*
|
|
369
|
-
* have to agree: a looser reader here accepts inline code the plugin never produced.
|
|
370
|
-
* - That is what keeps ordinary inline code ordinary. A prefix test alone claims
|
|
371
|
-
* `` `icon: database` ``, `` `icon:` `` and a fence body starting `icon:` — text the plugin
|
|
372
|
-
* never turned into a token, and none of it is an icon the author asked for.
|
|
354
|
+
* - Must match the name shape `remarkIconSyntax` (`@keboola/kai-chat`) accepts.
|
|
355
|
+
* - Anchored, so inline code like `` `icon: database` `` or `` `icon:` `` stays code.
|
|
373
356
|
*/
|
|
374
357
|
const TOKEN = /^icon:([a-z][a-z0-9-]*)$/;
|
|
375
358
|
/** Built once: an answer is re-parsed per streamed chunk, so `isArriving` runs per code node. */
|
|
376
359
|
const ICON_NAMES = Object.keys(ICON_REGISTRY);
|
|
377
|
-
/**
|
|
378
|
-
* Whether a name is only ever the start of one this registry draws.
|
|
379
|
-
*
|
|
380
|
-
* - Strictly shorter, so a whole name is never read as an unfinished one.
|
|
381
|
-
* - `tabl` → `true` (`table`); `unicorn` and `table-name` → `false`.
|
|
382
|
-
*/
|
|
360
|
+
/** Whether a name is a strict prefix of a registry name: `tabl` → `true`, `table-name` → `false`. */
|
|
383
361
|
const isArriving = (name) => ICON_NAMES.some((key) => key.length > name.length && key.startsWith(name));
|
|
384
362
|
/**
|
|
385
363
|
* The icon name in a code node's text, if the text is a token — drawn, or still arriving.
|
|
386
364
|
*
|
|
387
|
-
* -
|
|
388
|
-
*
|
|
389
|
-
* - A name
|
|
390
|
-
* fall-through keeps the text its author typed. `icon:` is an ordinary way to name a property,
|
|
391
|
-
* and this renderer draws vendor descriptions and dashboard text as well as agent answers.
|
|
392
|
-
* - A name that only starts one it draws is a token still arriving, answered with so that
|
|
393
|
-
* `<ChatInlineIcon />` draws nothing: an answer streams `icon:t`, `icon:ta`, `icon:tab` before
|
|
394
|
-
* the name lands, and each of those as code is a chip that reflows the line for a frame.
|
|
395
|
-
* - A name that is both — `save`, the start of `save-changes` — is drawn now; waiting would leave
|
|
396
|
-
* a finished token blank for the rest of the answer.
|
|
397
|
-
* - The token reaches a renderer as inline code either because the model wrote it in backticks
|
|
398
|
-
* or because a remark plugin turned the bare text into an `inlineCode` node. Parsing the
|
|
399
|
-
* token is the vocabulary's; producing it is the app's, since the plugin is workspace-internal.
|
|
365
|
+
* - An unknown name → `undefined`, so the call site's `<code>` fall-through keeps the text.
|
|
366
|
+
* - A prefix of a known name is a token still streaming; `<ChatInlineIcon />` draws it blank.
|
|
367
|
+
* - A name that is both (`save`, of `save-changes`) is drawn now.
|
|
400
368
|
*/
|
|
401
369
|
const getChatInlineIconName = (text) => {
|
|
402
370
|
const name = TOKEN.exec(text)?.[1];
|
|
@@ -406,19 +374,10 @@ const getChatInlineIconName = (text) => {
|
|
|
406
374
|
/**
|
|
407
375
|
* One inline `icon:<name>` token, drawn at the size of the text it leads.
|
|
408
376
|
*
|
|
409
|
-
* - An unknown name
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
* - `
|
|
413
|
-
* beside it, and `align-[-0.125em]` on an inline-block optically centres it against the
|
|
414
|
-
* baseline.
|
|
415
|
-
* - `mr` tops up the single source space, which is a word gap and reads as cramped between a
|
|
416
|
-
* glyph and the phrase it labels.
|
|
417
|
-
* - A heavier stroke so an outline icon holds its own next to the bold weight a heading carries.
|
|
418
|
-
* - `spinner` also spins; the mapping owns that, not the caller. See `ICON_CLASSES`.
|
|
419
|
-
* - `aria-hidden`, because the glyph is decorative: the token's text is removed from the answer and
|
|
420
|
-
* nothing replaces it as a label, so a reader that announces unnamed inline SVGs would read an
|
|
421
|
-
* unlabelled graphic before every phrase the agent decorates.
|
|
377
|
+
* - An unknown name (a token still arriving) renders nothing.
|
|
378
|
+
* - `mr` widens the single source space, which reads as cramped beside a glyph.
|
|
379
|
+
* - The heavier stroke holds its own beside a bold heading.
|
|
380
|
+
* - `aria-hidden`: the token's text is removed, so the glyph has no label to announce.
|
|
422
381
|
*/
|
|
423
382
|
const ChatInlineIcon = ({ name }) => {
|
|
424
383
|
const Icon = Object.hasOwn(ICON_REGISTRY, name) ? ICON_REGISTRY[name] : void 0;
|
|
@@ -430,34 +389,48 @@ const ChatInlineIcon = ({ name }) => {
|
|
|
430
389
|
});
|
|
431
390
|
};
|
|
432
391
|
//#endregion
|
|
433
|
-
//#region src/blocks/AIKit/
|
|
392
|
+
//#region src/blocks/AIKit/FileDownloadChip.tsx
|
|
434
393
|
/**
|
|
435
|
-
*
|
|
394
|
+
* A file the agent wrote, offered inside its own answer.
|
|
436
395
|
*
|
|
437
|
-
* -
|
|
438
|
-
*
|
|
396
|
+
* - The whole chip is the control: a small icon beside a truncating filename is hard to hit.
|
|
397
|
+
* - Presentation only — the host fetches and saves, through its own auth.
|
|
439
398
|
*/
|
|
399
|
+
const FileDownloadChip = ({ fileName, filePath, size, isPending = false, onDownload, className }) => /* @__PURE__ */ jsxs(Button, {
|
|
400
|
+
variant: "secondary",
|
|
401
|
+
size: "small",
|
|
402
|
+
isLoading: isPending,
|
|
403
|
+
"aria-disabled": isPending,
|
|
404
|
+
"aria-label": `Download ${filePath ?? fileName}`,
|
|
405
|
+
title: filePath,
|
|
406
|
+
onClick: () => {
|
|
407
|
+
if (!isPending) onDownload();
|
|
408
|
+
},
|
|
409
|
+
className: cn("tw:max-w-full tw:justify-start tw:gap-2 tw:font-normal", className),
|
|
410
|
+
children: [
|
|
411
|
+
!isPending && /* @__PURE__ */ jsx(FileText, { className: "tw:size-4 tw:shrink-0 tw:text-muted-foreground" }),
|
|
412
|
+
/* @__PURE__ */ jsx("span", {
|
|
413
|
+
className: "tw:truncate",
|
|
414
|
+
children: fileName
|
|
415
|
+
}),
|
|
416
|
+
size !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
417
|
+
className: "tw:shrink-0 tw:text-xs tw:text-muted-foreground",
|
|
418
|
+
children: size
|
|
419
|
+
}),
|
|
420
|
+
!isPending && /* @__PURE__ */ jsx(Download, { className: "tw:size-4 tw:shrink-0" })
|
|
421
|
+
]
|
|
422
|
+
});
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/blocks/AIKit/InlineStepGroup.tsx
|
|
425
|
+
/** The surface colour, as the custom property the step icons mask against. */
|
|
440
426
|
const surfaceStyle = (surface) => ({ "--inline-step-surface": surface });
|
|
441
427
|
/**
|
|
442
|
-
* A run of
|
|
428
|
+
* A collapsible run of agent steps behind one summary line; rows arrive as children.
|
|
443
429
|
*
|
|
444
|
-
* -
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
* -
|
|
448
|
-
* `size-5` icon box. Drawn once rather than per row, so it does not vanish beside a row that
|
|
449
|
-
* happens to have no icon.
|
|
450
|
-
* - `grid-template-rows` rather than height, because the rows are text of unknown length and a
|
|
451
|
-
* transition needs a number at both ends. The children stay mounted while closed: a group the
|
|
452
|
-
* reader reopens must not re-run whatever mounting a row costs. A closed group is `inert` and
|
|
453
|
-
* `aria-hidden`, so staying mounted does not mean staying reachable.
|
|
454
|
-
* - Expansion is the caller's state. Whether a group opens itself while work is happening, and
|
|
455
|
-
* whether a reader's own toggle outranks that, is a transcript-level decision.
|
|
456
|
-
* - `role="group"` rather than the `<section>`'s own landmark semantics: a transcript draws one
|
|
457
|
-
* of these per run of steps, so a long conversation would hand a screen reader a landmark
|
|
458
|
-
* list of dozens of identically named `region`s and drown the page's real landmarks in it.
|
|
459
|
-
* The name still reads — a named `group` is announced by it — and it is the role the
|
|
460
|
-
* grounding panel already gives its repeated named answer sections.
|
|
430
|
+
* - Connector sits at the icon centre line (`pl-5` + half a `size-5` box), drawn once so it
|
|
431
|
+
* survives icon-less rows.
|
|
432
|
+
* - Animates `grid-template-rows`; children stay mounted while closed.
|
|
433
|
+
* - `role="group"`, not a `region` landmark: dozens per transcript would drown real landmarks.
|
|
461
434
|
*/
|
|
462
435
|
const InlineStepGroup = ({ label, variant = "success", isExpanded, onToggle, surface = "rgb(var(--background))", "aria-label": ariaLabel, "data-testid": testId, className, children }) => /* @__PURE__ */ jsxs("section", {
|
|
463
436
|
role: "group",
|
|
@@ -491,16 +464,10 @@ const InlineStepGroup = ({ label, variant = "success", isExpanded, onToggle, sur
|
|
|
491
464
|
/**
|
|
492
465
|
* One diagram block: a skeleton while its chunk loads, the fence source plus a retry if it fails.
|
|
493
466
|
*
|
|
494
|
-
* -
|
|
495
|
-
*
|
|
496
|
-
* -
|
|
497
|
-
*
|
|
498
|
-
* a background loop would retry that one forever.
|
|
499
|
-
* - The failure is already logged by the loader, which knows the chunk's name.
|
|
500
|
-
* - A new `load` resets the block: every fence renders this same component type, so a block that
|
|
501
|
-
* switches dialect would otherwise keep drawing through the dialect it had before.
|
|
502
|
-
* - Both the renderer and the loader are functions held in state, so they go in through the
|
|
503
|
-
* setter form — React runs a bare function as a lazy initializer or an updater instead.
|
|
467
|
+
* - Each attempt is a fresh fetch; the loader drops its rejected promise and logs the failure.
|
|
468
|
+
* - Retry is manual: a chunk gone after a deploy never returns, so a timer would loop forever.
|
|
469
|
+
* - A new `load` resets the block, or a dialect switch keeps the previous renderer.
|
|
470
|
+
* - Functions in state go through the setter form, or React calls them.
|
|
504
471
|
*/
|
|
505
472
|
const DiagramBlock = ({ load, code }) => {
|
|
506
473
|
const [Diagram, setDiagram] = useState(null);
|
|
@@ -539,16 +506,12 @@ const DiagramBlock = ({ load, code }) => {
|
|
|
539
506
|
//#endregion
|
|
540
507
|
//#region src/blocks/AIKit/diagramChunk.ts
|
|
541
508
|
/**
|
|
542
|
-
* An on-demand diagram chunk
|
|
509
|
+
* An on-demand diagram chunk, shared between mounts and retryable.
|
|
543
510
|
*
|
|
544
|
-
* - `lazy()
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
* -
|
|
548
|
-
* - A failed one is cleared, so the next mount imports again. Same contract as
|
|
549
|
-
* `getFlintRuntime()` one level down, inside `FlintChart`.
|
|
550
|
-
* - The failure is logged here, where the chunk's name is known, so the swap to plain source is
|
|
551
|
-
* never silent and a retry that fails again says so.
|
|
511
|
+
* - Not `lazy()`: it memoizes a failed import, stranding every diagram until a reload.
|
|
512
|
+
* - A resolved import is kept; a failed one is cleared so the next mount retries.
|
|
513
|
+
* - Same contract as `getFlintRuntime()` in `FlintChart`.
|
|
514
|
+
* - Failures are logged here, where the chunk's name is known.
|
|
552
515
|
*/
|
|
553
516
|
const diagramChunk = (name, load) => {
|
|
554
517
|
let pending = null;
|
|
@@ -565,7 +528,10 @@ const diagramChunk = (name, load) => {
|
|
|
565
528
|
//#region src/blocks/AIKit/Markdown.tsx
|
|
566
529
|
const loadMermaid = diagramChunk("MermaidDiagram", () => import("@keboola/design/mermaid").then((module) => module.MermaidDiagram));
|
|
567
530
|
const loadFlint = diagramChunk("FlintChart", () => import("@keboola/design/flint").then((module) => module.FlintChart));
|
|
568
|
-
const
|
|
531
|
+
const PROSE_CLASS = {
|
|
532
|
+
answer: "tw:prose tw:prose-answer tw:prose-code-chip tw:break-words",
|
|
533
|
+
chrome: "tw:prose tw:prose-sm tw:prose-code-chip tw:break-words"
|
|
534
|
+
};
|
|
569
535
|
const getText = (node) => {
|
|
570
536
|
if (typeof node === "string") return node;
|
|
571
537
|
if (typeof node === "number") return String(node);
|
|
@@ -580,25 +546,14 @@ const getLanguage = (element) => {
|
|
|
580
546
|
if (typeof props.className !== "string") return void 0;
|
|
581
547
|
return props.className.match(/language-(\S+)/)?.[1];
|
|
582
548
|
};
|
|
583
|
-
/**
|
|
584
|
-
* The plugins this renderer always runs.
|
|
585
|
-
*
|
|
586
|
-
* - GFM is part of its contract: tables route through the design `Table`, and autolinks and
|
|
587
|
-
* task lists are what an assistant answer is written in.
|
|
588
|
-
* - A caller's own plugins are appended to these, never substituted for them.
|
|
589
|
-
*/
|
|
549
|
+
/** Always run; a caller's plugins are appended, never substituted. */
|
|
590
550
|
const baseRemarkPlugins = [remarkGfm];
|
|
591
551
|
/**
|
|
592
552
|
* Fence language → the on-demand chunk that draws it.
|
|
593
553
|
*
|
|
594
|
-
* -
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
* - `flint-chart` is an alias — it is the fence tag flint's own docs use, so a model emits it
|
|
598
|
-
* unprompted often enough to matter. `markdownComponents.tsx` in kbc-ui carries the same pair.
|
|
599
|
-
* - Read through `Object.hasOwn`, never by plain index: a fence tagged ```constructor or
|
|
600
|
-
* ```valueOf otherwise answers with an `Object.prototype` member, which is truthy, and calling
|
|
601
|
-
* it as a loader throws — taking the whole message subtree down with it.
|
|
554
|
+
* - Dialects come from kai-agent's prompt; keep in sync with kbc-ui `markdownComponents.tsx`.
|
|
555
|
+
* - `flint-chart`: alias models emit unprompted.
|
|
556
|
+
* - Read via `Object.hasOwn`: ```constructor would otherwise hit `Object.prototype` and throw.
|
|
602
557
|
*/
|
|
603
558
|
const DIAGRAM_CHUNKS = {
|
|
604
559
|
mermaid: loadMermaid,
|
|
@@ -608,38 +563,21 @@ const DIAGRAM_CHUNKS = {
|
|
|
608
563
|
/**
|
|
609
564
|
* The fence languages this renderer draws instead of printing.
|
|
610
565
|
*
|
|
611
|
-
* -
|
|
612
|
-
*
|
|
613
|
-
* keystroke fetches the chunk. Sharing the list is what keeps that hold-back from missing a
|
|
614
|
-
* dialect this map has and the caller does not.
|
|
615
|
-
* - Frozen, because it is that shared contract: a consumer that pushed onto it would change how
|
|
616
|
-
* every other app in the same bundle holds a fence back.
|
|
566
|
+
* - Streaming callers hold an open fence back as plain code, or every keystroke fetches the chunk.
|
|
567
|
+
* - Frozen: it is shared across every app in the bundle.
|
|
617
568
|
*/
|
|
618
569
|
const DIAGRAM_LANGUAGES = Object.freeze(Object.keys(DIAGRAM_CHUNKS));
|
|
619
570
|
/**
|
|
620
571
|
* Whether the `code` being rendered sits inside a fenced block.
|
|
621
572
|
*
|
|
622
|
-
* -
|
|
623
|
-
* code, so the class cannot tell the two apart — `pre` is the only boundary that can.
|
|
624
|
-
* - Set by the `pre` renderer, read by `code`: React renders `pre` before its children, so the
|
|
625
|
-
* value is in place by the time the `code` inside it renders.
|
|
573
|
+
* - Set by `pre`: a fence without info string has no `language-…` class, like inline code.
|
|
626
574
|
*/
|
|
627
575
|
const CodeBlockContext = createContext(false);
|
|
628
576
|
/**
|
|
629
|
-
* The `code` renderer: an `icon:<name>` token becomes the icon it names
|
|
577
|
+
* The `code` renderer: an inline `icon:<name>` token becomes the icon it names.
|
|
630
578
|
*
|
|
631
|
-
* -
|
|
632
|
-
*
|
|
633
|
-
* with no info string carries no `language-…` class either, so the class cannot.
|
|
634
|
-
* - The token reaches here as inline code because `remarkIconSyntax` (in `@keboola/kai-chat`)
|
|
635
|
-
* turned the bare text into one, or because the model wrote the backticks itself. Producing the
|
|
636
|
-
* token is the app's, drawing it is this package's.
|
|
637
|
-
* - A name no icon answers to stays code: `getChatInlineIconName` answers only for names the
|
|
638
|
-
* registry can draw or is still receiving, and this renderer draws vendor descriptions and
|
|
639
|
-
* dashboard text too, where `icon:` is an ordinary way to name a property.
|
|
640
|
-
* - A name still arriving draws nothing, so a streamed `icon:tabl` is blank for a frame rather
|
|
641
|
-
* than a code chip that reflows the line.
|
|
642
|
-
* - A component rather than an inline renderer so it can read the context.
|
|
579
|
+
* - Fenced blocks never swap.
|
|
580
|
+
* - Unknown names stay code; a name still streaming renders nothing.
|
|
643
581
|
*/
|
|
644
582
|
const MarkdownCode = ({ children, className, ...props }) => {
|
|
645
583
|
const { node: _node, ...rest } = props;
|
|
@@ -731,54 +669,60 @@ const baseComponents = {
|
|
|
731
669
|
}
|
|
732
670
|
};
|
|
733
671
|
/**
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
672
|
+
* The prose surface an answer is drawn on.
|
|
673
|
+
*
|
|
674
|
+
* - Wrap all `Block`s of one answer in one `Root`, so `:first-child`/`:last-child` span the reply.
|
|
675
|
+
* - `data-prose` is `MessageBubble`'s colour hook; Tailwind can't target `tw:prose` directly.
|
|
676
|
+
* - Spacing overrides need `!`: `tw:prose-answer` rules are `(0,2,1)`, above `[&_p]:mb-1`.
|
|
737
677
|
*/
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
};
|
|
678
|
+
const MarkdownRoot = ({ children, className, rhythm = "answer" }) => /* @__PURE__ */ jsx("div", {
|
|
679
|
+
"data-prose": true,
|
|
680
|
+
className: cn(PROSE_CLASS[rhythm], className),
|
|
681
|
+
children
|
|
682
|
+
});
|
|
683
|
+
/** One parsed piece of an answer, with no surface of its own; memoise at the call site. */
|
|
684
|
+
const MarkdownBlock = ({ children, remarkPlugins, components: componentOverrides }) => /* @__PURE__ */ jsx(ReactMarkdown, {
|
|
685
|
+
remarkPlugins: remarkPlugins === void 0 ? baseRemarkPlugins : [...baseRemarkPlugins, ...remarkPlugins],
|
|
686
|
+
components: componentOverrides === void 0 ? baseComponents : {
|
|
687
|
+
...baseComponents,
|
|
688
|
+
...componentOverrides
|
|
689
|
+
},
|
|
690
|
+
children
|
|
691
|
+
});
|
|
692
|
+
/**
|
|
693
|
+
* Read-only GFM Markdown renderer with design-token typography.
|
|
694
|
+
*
|
|
695
|
+
* - Needs a `TooltipProvider` at the app root (code copy button).
|
|
696
|
+
* - Pass `rhythm="chrome"` for content a model did not write.
|
|
697
|
+
*/
|
|
698
|
+
const Markdown = ({ className, rhythm, ...blockProps }) => /* @__PURE__ */ jsx(MarkdownRoot, {
|
|
699
|
+
className,
|
|
700
|
+
rhythm,
|
|
701
|
+
children: /* @__PURE__ */ jsx(MarkdownBlock, { ...blockProps })
|
|
702
|
+
});
|
|
703
|
+
Markdown.Root = MarkdownRoot;
|
|
704
|
+
Markdown.Block = MarkdownBlock;
|
|
752
705
|
//#endregion
|
|
753
706
|
//#region src/blocks/AIKit/MarkdownTable.tsx
|
|
754
707
|
/** How much wider than its column a table has to be before the column is the wrong surface. */
|
|
755
708
|
const EXPAND_RATIO = 1.5;
|
|
756
709
|
/**
|
|
757
|
-
* The
|
|
710
|
+
* The fade's end colour — must match the host's surface, or it draws a strip over the data.
|
|
758
711
|
*
|
|
759
|
-
* -
|
|
760
|
-
* token and it draws a contrasting strip over the data instead of hiding it.
|
|
761
|
-
* - Full class strings, not a composed `tw:from-${token}`: Tailwind reads literals.
|
|
712
|
+
* - Full class strings: Tailwind reads literals.
|
|
762
713
|
*/
|
|
763
714
|
const FADE_SURFACE = {
|
|
764
715
|
card: "tw:from-card",
|
|
765
716
|
background: "tw:from-background"
|
|
766
717
|
};
|
|
767
718
|
/**
|
|
768
|
-
* A table in an answer
|
|
719
|
+
* A table in an answer that shows when it is cut off on the right.
|
|
769
720
|
*
|
|
770
|
-
* -
|
|
771
|
-
* - The
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
* -
|
|
775
|
-
* - A painted gradient rather than the `tw:scroll-fade-x` mask, which needs scroll-driven
|
|
776
|
-
* animations: the build floor is `baseline-widely-available` (Safari 16, Firefox 104), and there
|
|
777
|
-
* the utility either fades both edges of a table that fits or, behind the `supports-` guard
|
|
778
|
-
* `PageLayout` uses, says nothing at all — which is the state this component exists to end. The
|
|
779
|
-
* mask also has to sit on the scrolling element, and that is `Table`'s own container, not ours.
|
|
780
|
-
* - Past `EXPAND_RATIO` the fade is joined by `onExpand`'s action, drawn without waiting for a
|
|
781
|
-
* hover: it reports that content is cut off, which the reader needs before going looking.
|
|
721
|
+
* - Controls sit in a fixed-height rail above the grid, so they never cover rows or shift them.
|
|
722
|
+
* - The fade shows only while content remains to the right.
|
|
723
|
+
* - A painted gradient, not `tw:scroll-fade-x`: that needs scroll-driven animations, which the
|
|
724
|
+
* `baseline-widely-available` build floor lacks, and must sit on `Table`'s own container.
|
|
725
|
+
* - Past `EXPAND_RATIO` the expand action shows without hover.
|
|
782
726
|
*/
|
|
783
727
|
const MarkdownTable = ({ children, actions, onExpand, surface = "card", className }) => {
|
|
784
728
|
const frameRef = useRef(null);
|
|
@@ -888,7 +832,7 @@ const contentClasses = cva([
|
|
|
888
832
|
"tw:py-2",
|
|
889
833
|
"tw:rounded-xl",
|
|
890
834
|
"tw:overflow-hidden",
|
|
891
|
-
"tw:
|
|
835
|
+
"tw:wrap-anywhere"
|
|
892
836
|
]
|
|
893
837
|
} },
|
|
894
838
|
defaultVariants: { variant: "assistant" }
|
|
@@ -1233,6 +1177,58 @@ const PlanRewritingIndicator = ({ label = "Rewriting the plan..." }) => /* @__PU
|
|
|
1233
1177
|
})]
|
|
1234
1178
|
});
|
|
1235
1179
|
//#endregion
|
|
1180
|
+
//#region src/blocks/AIKit/constants.ts
|
|
1181
|
+
/**
|
|
1182
|
+
* Names the container query `PromptInput`'s `inline` row reads to fold into the stacked layout.
|
|
1183
|
+
*
|
|
1184
|
+
* It has to sit on an **ancestor**: a container query matches descendants only, so the field that
|
|
1185
|
+
* would read it cannot name it, and its own wrapper is the width the fold changes. A host that
|
|
1186
|
+
* never names it keeps the one-line row at every width.
|
|
1187
|
+
*/
|
|
1188
|
+
const PROMPT_INPUT_CONTAINER = "tw:@container/composer";
|
|
1189
|
+
//#endregion
|
|
1190
|
+
//#region src/blocks/AIKit/AnimatedHeight.tsx
|
|
1191
|
+
/**
|
|
1192
|
+
* A box whose height eases to whatever its content measures.
|
|
1193
|
+
*
|
|
1194
|
+
* - Content is measured with a `ResizeObserver`; without one (jsdom) the box is plain `auto`.
|
|
1195
|
+
* - The first measurement lands without a transition, so mounting with content does not grow in.
|
|
1196
|
+
* - Overflow is clipped only while the height moves, so focus rings are not cut off at rest.
|
|
1197
|
+
* - `prefers-reduced-motion` drops the transition.
|
|
1198
|
+
*/
|
|
1199
|
+
const AnimatedHeight = ({ children, className }) => {
|
|
1200
|
+
const contentRef = useRef(null);
|
|
1201
|
+
const heightRef = useRef(void 0);
|
|
1202
|
+
const [height, setHeight] = useState();
|
|
1203
|
+
const [isAnimating, setIsAnimating] = useState(false);
|
|
1204
|
+
useLayoutEffect(() => {
|
|
1205
|
+
const node = contentRef.current;
|
|
1206
|
+
if (!node || typeof ResizeObserver === "undefined") return;
|
|
1207
|
+
const observer = new ResizeObserver(() => {
|
|
1208
|
+
const next = node.offsetHeight;
|
|
1209
|
+
const prev = heightRef.current;
|
|
1210
|
+
if (prev !== void 0 && prev !== next && hasMotion()) setIsAnimating(true);
|
|
1211
|
+
heightRef.current = next;
|
|
1212
|
+
setHeight(next);
|
|
1213
|
+
});
|
|
1214
|
+
observer.observe(node);
|
|
1215
|
+
return () => observer.disconnect();
|
|
1216
|
+
}, []);
|
|
1217
|
+
const handleTransitionEnd = (event) => {
|
|
1218
|
+
if (event.target !== event.currentTarget || event.propertyName !== "height") return;
|
|
1219
|
+
setIsAnimating(false);
|
|
1220
|
+
};
|
|
1221
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1222
|
+
style: { height },
|
|
1223
|
+
onTransitionEnd: handleTransitionEnd,
|
|
1224
|
+
className: cn("tw:transition-[height] tw:duration-200 tw:ease-out tw:motion-reduce:transition-none", isAnimating && "tw:overflow-hidden", className),
|
|
1225
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1226
|
+
ref: contentRef,
|
|
1227
|
+
children
|
|
1228
|
+
})
|
|
1229
|
+
});
|
|
1230
|
+
};
|
|
1231
|
+
//#endregion
|
|
1236
1232
|
//#region src/blocks/AIKit/PromptInputAction.tsx
|
|
1237
1233
|
const PromptInputAction = ({ ref, onMouseDown, ...rest }) => {
|
|
1238
1234
|
const handleOnMouseDown = (event) => {
|
|
@@ -1249,24 +1245,81 @@ const PromptInputAction = ({ ref, onMouseDown, ...rest }) => {
|
|
|
1249
1245
|
//#region src/blocks/AIKit/PromptInputCommands.tsx
|
|
1250
1246
|
/** What the menu needs above or below the composer before it will open on that side. */
|
|
1251
1247
|
const MENU_HEIGHT = 440;
|
|
1252
|
-
|
|
1253
|
-
|
|
1248
|
+
/** As tall as the list ever gets, however much room there is. */
|
|
1249
|
+
const MENU_MAX_HEIGHT = 416;
|
|
1250
|
+
/** Space kept from the measured edge; `POPUP_CHROME` is the popup's own border and padding. */
|
|
1251
|
+
const MENU_GUTTER = 16;
|
|
1252
|
+
const POPUP_CHROME = 10;
|
|
1253
|
+
/**
|
|
1254
|
+
* The rows a typed filter leaves.
|
|
1255
|
+
*
|
|
1256
|
+
* - An empty filter keeps everything.
|
|
1257
|
+
* - A row matches on its label or its value.
|
|
1258
|
+
* - Matching nothing falls back to the action rows.
|
|
1259
|
+
*/
|
|
1260
|
+
const matchesFilter = (items, filterValue) => {
|
|
1261
|
+
if (!filterValue) return items;
|
|
1262
|
+
const query = filterValue.toLowerCase();
|
|
1263
|
+
const matched = items.filter((item) => item.label.toLowerCase().includes(query) || item.value.toLowerCase().includes(query));
|
|
1264
|
+
return matched.length > 0 ? matched : items.filter((item) => item.onSelect !== void 0);
|
|
1265
|
+
};
|
|
1266
|
+
/**
|
|
1267
|
+
* The band the menu has to stay inside: the window, narrowed by every ancestor that clips.
|
|
1268
|
+
*
|
|
1269
|
+
* - The chat sidebar's panel clips well below the window's top edge.
|
|
1270
|
+
*/
|
|
1271
|
+
const CLIPS = /* @__PURE__ */ new Set([
|
|
1272
|
+
"hidden",
|
|
1273
|
+
"auto",
|
|
1274
|
+
"scroll",
|
|
1275
|
+
"clip",
|
|
1276
|
+
"overlay"
|
|
1277
|
+
]);
|
|
1278
|
+
const clipBand = (node) => {
|
|
1279
|
+
let top = 0;
|
|
1280
|
+
let bottom = window.innerHeight;
|
|
1281
|
+
let parent = node.parentElement;
|
|
1282
|
+
while (parent) {
|
|
1283
|
+
const { overflowY, overflowX } = window.getComputedStyle(parent);
|
|
1284
|
+
if (CLIPS.has(overflowY) || CLIPS.has(overflowX)) {
|
|
1285
|
+
const box = parent.getBoundingClientRect();
|
|
1286
|
+
top = Math.max(top, box.top);
|
|
1287
|
+
bottom = Math.min(bottom, box.bottom);
|
|
1288
|
+
}
|
|
1289
|
+
parent = parent.parentElement;
|
|
1290
|
+
}
|
|
1291
|
+
return {
|
|
1292
|
+
top,
|
|
1293
|
+
bottom
|
|
1294
|
+
};
|
|
1295
|
+
};
|
|
1296
|
+
const PromptInputCommands = ({ items, open, onSelect, filterValue, emptyText = "No commands found", panel, groupAction, groupHeading, children }) => {
|
|
1297
|
+
const filtered = matchesFilter(items, filterValue);
|
|
1254
1298
|
const [highlighted, setHighlighted] = useState();
|
|
1299
|
+
const [wasOpen, setWasOpen] = useState(open);
|
|
1300
|
+
if (open !== wasOpen) {
|
|
1301
|
+
setWasOpen(open);
|
|
1302
|
+
if (open) setHighlighted(void 0);
|
|
1303
|
+
}
|
|
1255
1304
|
/**
|
|
1256
1305
|
* Which side the menu opens on.
|
|
1257
1306
|
*
|
|
1258
|
-
* - Above by default
|
|
1259
|
-
* -
|
|
1260
|
-
* near the top of the page, where opening upward clipped the list against the header.
|
|
1261
|
-
* - Re-measured while it is open: the composer grows as the message does, and the transcript
|
|
1262
|
-
* above it moves, so the side that fit on open may not fit a moment later.
|
|
1307
|
+
* - Above by default; below when there is not room above and more room below.
|
|
1308
|
+
* - Re-measured while open: the composer and the transcript above it move.
|
|
1263
1309
|
*/
|
|
1264
1310
|
const rootRef = useRef(null);
|
|
1265
1311
|
const [below, setBelow] = useState(false);
|
|
1312
|
+
const [maxHeight, setMaxHeight] = useState(MENU_MAX_HEIGHT);
|
|
1266
1313
|
const measure = useCallback(() => {
|
|
1267
|
-
const
|
|
1268
|
-
|
|
1269
|
-
|
|
1314
|
+
const node = rootRef.current;
|
|
1315
|
+
const box = node?.getBoundingClientRect();
|
|
1316
|
+
if (!node || !box) return;
|
|
1317
|
+
const band = clipBand(node);
|
|
1318
|
+
const above = box.top - band.top;
|
|
1319
|
+
const under = band.bottom - box.bottom;
|
|
1320
|
+
const openBelow = above < MENU_HEIGHT && under > above;
|
|
1321
|
+
setBelow(openBelow);
|
|
1322
|
+
setMaxHeight(Math.max(0, Math.min(MENU_MAX_HEIGHT, (openBelow ? under : above) - MENU_GUTTER - POPUP_CHROME)));
|
|
1270
1323
|
}, []);
|
|
1271
1324
|
const attachRoot = useCallback((node) => {
|
|
1272
1325
|
rootRef.current = node;
|
|
@@ -1292,6 +1345,7 @@ const PromptInputCommands = ({ items, open, onSelect, filterValue, emptyText = "
|
|
|
1292
1345
|
acc[item.group] = group;
|
|
1293
1346
|
return acc;
|
|
1294
1347
|
}, {});
|
|
1348
|
+
const menuStyle = { "--prompt-menu-max-h": `${maxHeight}px` };
|
|
1295
1349
|
return /* @__PURE__ */ jsxs(Command, {
|
|
1296
1350
|
ref: attachRoot,
|
|
1297
1351
|
loop: true,
|
|
@@ -1299,41 +1353,45 @@ const PromptInputCommands = ({ items, open, onSelect, filterValue, emptyText = "
|
|
|
1299
1353
|
shouldFilter: false,
|
|
1300
1354
|
value: highlightedValue ?? "",
|
|
1301
1355
|
onValueChange: setHighlighted,
|
|
1302
|
-
children: [open && /* @__PURE__ */
|
|
1356
|
+
children: [open && /* @__PURE__ */ jsx("div", {
|
|
1303
1357
|
className: cn("tw:absolute tw:left-0 tw:z-50 tw:w-full tw:max-w-lg", below ? "tw:top-full tw:mt-1" : "tw:bottom-full tw:mb-1", "tw:rounded-[14px] tw:border tw:border-border tw:bg-popover tw:text-popover-foreground tw:shadow-lg", "tw:p-1"),
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
className: "tw:
|
|
1310
|
-
onMouseDown: (event) => event.preventDefault(),
|
|
1311
|
-
onClick: onClose,
|
|
1312
|
-
children: /* @__PURE__ */ jsx(X, {})
|
|
1313
|
-
}), filtered.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
1314
|
-
className: "tw:px-4 tw:py-3 tw:text-center tw:text-sm tw:text-muted-foreground",
|
|
1358
|
+
style: menuStyle,
|
|
1359
|
+
children: panel ? /* @__PURE__ */ jsx("div", {
|
|
1360
|
+
className: "tw:p-3",
|
|
1361
|
+
children: panel
|
|
1362
|
+
}) : filtered.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
1363
|
+
className: "tw:py-3 tw:pl-4 tw:text-center tw:text-sm tw:text-muted-foreground",
|
|
1315
1364
|
children: emptyText
|
|
1316
1365
|
}) : /* @__PURE__ */ jsx(Command.List, {
|
|
1317
1366
|
className: "tw:group-data-[variant=argo]/command:px-1 tw:group-data-[variant=argo]/command:pb-1",
|
|
1318
|
-
viewPortClassName: "tw:max-h-[
|
|
1367
|
+
viewPortClassName: "tw:max-h-[var(--prompt-menu-max-h)] tw:[&>div]:!block",
|
|
1319
1368
|
children: Object.entries(groups).map(([groupName, groupItems], index) => /* @__PURE__ */ jsx(Command.Group, {
|
|
1320
|
-
heading: groupName,
|
|
1321
|
-
|
|
1322
|
-
|
|
1369
|
+
heading: groupName ? /* @__PURE__ */ jsxs("span", {
|
|
1370
|
+
className: "tw:flex tw:items-center tw:justify-between tw:gap-2",
|
|
1371
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1372
|
+
className: "tw:min-w-0 tw:truncate",
|
|
1373
|
+
children: groupHeading?.(groupName) ?? groupName
|
|
1374
|
+
}), groupAction?.(groupName)]
|
|
1375
|
+
}) : void 0,
|
|
1376
|
+
className: cn("tw:[&_[cmdk-group-heading]]:normal-case", "tw:[&_[cmdk-group-heading]]:tracking-normal", "tw:[&_[cmdk-group-heading]]:border-b-0", "tw:[&_[cmdk-group-heading]]:!py-0", "tw:[&_[cmdk-group-heading]]:mt-2", "tw:[&_[cmdk-group-heading]]:mb-1", "tw:[&_[cmdk-group-heading]]:pl-2", "tw:[&_[cmdk-group-heading]]:text-xs", index > 0 && "tw:mt-3"),
|
|
1377
|
+
children: groupItems.map((item) => /* @__PURE__ */ jsxs(Command.Item, {
|
|
1323
1378
|
value: item.value,
|
|
1324
|
-
className: "tw:rounded-md",
|
|
1379
|
+
className: "tw:w-full tw:min-w-0 tw:rounded-md",
|
|
1325
1380
|
onSelect: () => onSelect(item),
|
|
1326
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1381
|
+
children: [item.icon, /* @__PURE__ */ jsxs("div", {
|
|
1327
1382
|
className: "tw:flex tw:min-w-0 tw:flex-1 tw:flex-col",
|
|
1328
|
-
children: [
|
|
1383
|
+
children: [item.content ?? /* @__PURE__ */ jsx("span", {
|
|
1384
|
+
className: "tw:truncate",
|
|
1385
|
+
children: item.label
|
|
1386
|
+
}), item.description && /* @__PURE__ */ jsx(Truncated, {
|
|
1329
1387
|
text: item.description,
|
|
1330
1388
|
twoLines: true,
|
|
1331
1389
|
className: "tw:text-xs tw:text-muted-foreground"
|
|
1332
1390
|
})]
|
|
1333
|
-
})
|
|
1391
|
+
})]
|
|
1334
1392
|
}, item.value))
|
|
1335
1393
|
}, groupName))
|
|
1336
|
-
})
|
|
1394
|
+
})
|
|
1337
1395
|
}), children]
|
|
1338
1396
|
});
|
|
1339
1397
|
};
|
|
@@ -1405,6 +1463,42 @@ const CMDK_HIJACKED_KEYS = /* @__PURE__ */ new Set([
|
|
|
1405
1463
|
"Enter"
|
|
1406
1464
|
]);
|
|
1407
1465
|
const isCmdkNavigation = (event) => event.key !== "Enter" || !(event.metaKey || event.ctrlKey || event.altKey);
|
|
1466
|
+
/**
|
|
1467
|
+
* The `@token` the caret sits at the end of, if any.
|
|
1468
|
+
*
|
|
1469
|
+
* - `@` has to open a word: it must start the value or follow whitespace.
|
|
1470
|
+
* - The token holds no whitespace or second `@` and runs past the caret, so a mid-word pick takes the word.
|
|
1471
|
+
* - `start` indexes the `@` itself, so replacing `[start, end)` removes the token.
|
|
1472
|
+
*/
|
|
1473
|
+
const findMentionToken = (value, caret) => {
|
|
1474
|
+
const before = value.slice(0, caret);
|
|
1475
|
+
const match = /(?:^|\s)@([^\s@]*)$/.exec(before);
|
|
1476
|
+
if (!match) return null;
|
|
1477
|
+
const typed = match[1] ?? "";
|
|
1478
|
+
const tail = /^[^\s@]*/.exec(value.slice(caret))?.[0] ?? "";
|
|
1479
|
+
return {
|
|
1480
|
+
start: caret - typed.length - 1,
|
|
1481
|
+
end: caret + tail.length,
|
|
1482
|
+
query: typed + tail
|
|
1483
|
+
};
|
|
1484
|
+
};
|
|
1485
|
+
/**
|
|
1486
|
+
* The `/token` a message leads with, while the caret is still on it.
|
|
1487
|
+
*
|
|
1488
|
+
* - Only the first token: the Agent SDK expands a skill only at the start of a message.
|
|
1489
|
+
* - Text may follow it.
|
|
1490
|
+
* - The caret past the token closes the menu.
|
|
1491
|
+
*/
|
|
1492
|
+
const findSlashToken = (value, caret) => {
|
|
1493
|
+
const match = /^\/(\S*)/.exec(value);
|
|
1494
|
+
if (!match) return null;
|
|
1495
|
+
const end = match[0].length;
|
|
1496
|
+
if (caret > end) return null;
|
|
1497
|
+
return {
|
|
1498
|
+
end,
|
|
1499
|
+
query: match[1] ?? ""
|
|
1500
|
+
};
|
|
1501
|
+
};
|
|
1408
1502
|
const promptInputVariants = cva([
|
|
1409
1503
|
"tailwindcss-preflight",
|
|
1410
1504
|
"tw:relative",
|
|
@@ -1443,7 +1537,7 @@ const wrapperVariants = cva(null, {
|
|
|
1443
1537
|
inline: ""
|
|
1444
1538
|
} }
|
|
1445
1539
|
});
|
|
1446
|
-
const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, attachments, className, disabled, disableSubmit, value = "", onValueChange, status = "ready", maxRows = 6, minRows, commands, autoFocus, textareaRef: publishedRef, ...textareaProps }) => {
|
|
1540
|
+
const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, attachments, className, disabled, disableSubmit, value = "", onValueChange, status = "ready", maxRows = 6, minRows, commands, commandsGroupAction, panel, mentions, onMentionSelect, mentionsEmptyText = "Nothing to attach", mentionsGroupHeading, mentionsMultiple = false, autoFocus, textareaRef: publishedRef, ...textareaProps }) => {
|
|
1447
1541
|
const defaultMinRows = variant === "inline" ? 1 : 2;
|
|
1448
1542
|
const isDisabled = (disabled || disableSubmit || !value.trim()) && status !== "streaming" && status !== "interrupted";
|
|
1449
1543
|
const textareaId = useId();
|
|
@@ -1453,16 +1547,29 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
|
|
|
1453
1547
|
if (publishedRef) publishedRef.current = node;
|
|
1454
1548
|
}, [publishedRef]);
|
|
1455
1549
|
const [dismissedValue, setDismissedValue] = useState(null);
|
|
1550
|
+
const [caret, setCaret] = useState(0);
|
|
1551
|
+
const [caretValue, setCaretValue] = useState(value);
|
|
1552
|
+
const moveCaret = (next, forValue) => {
|
|
1553
|
+
setCaret(next);
|
|
1554
|
+
setCaretValue(forValue);
|
|
1555
|
+
};
|
|
1556
|
+
if (value !== caretValue) moveCaret(value.length, value);
|
|
1456
1557
|
const autoFocusRef = useRef(autoFocus);
|
|
1457
1558
|
useEffect(() => {
|
|
1458
1559
|
if (autoFocusRef.current) textareaRef.current?.focus({ preventScroll: true });
|
|
1459
1560
|
}, []);
|
|
1460
1561
|
if (dismissedValue !== null && value !== dismissedValue) setDismissedValue(null);
|
|
1461
|
-
const
|
|
1462
|
-
const
|
|
1463
|
-
const
|
|
1464
|
-
const
|
|
1465
|
-
const
|
|
1562
|
+
const hasCommands = !!commands && commands.length > 0;
|
|
1563
|
+
const panelOpen = panel !== void 0;
|
|
1564
|
+
const hasMentions = mentions !== void 0;
|
|
1565
|
+
const hasMenus = hasCommands || hasMentions;
|
|
1566
|
+
const slashToken = hasCommands && !panelOpen && value !== dismissedValue ? findSlashToken(value, Math.min(caret, value.length)) : null;
|
|
1567
|
+
const commandsOpen = slashToken !== null;
|
|
1568
|
+
const mentionToken = hasMentions && !commandsOpen && !panelOpen && value !== dismissedValue ? findMentionToken(value, Math.min(caret, value.length)) : null;
|
|
1569
|
+
const mentionsOpen = mentionToken !== null;
|
|
1570
|
+
const menuOpen = commandsOpen || mentionsOpen || panelOpen;
|
|
1571
|
+
const menuItems = commandsOpen ? commands ?? [] : mentions ?? [];
|
|
1572
|
+
const menuFilter = commandsOpen ? slashToken.query : mentionToken?.query ?? "";
|
|
1466
1573
|
const handleSubmit = () => {
|
|
1467
1574
|
if (isDisabled) return;
|
|
1468
1575
|
if (status === "streaming") onAbort?.();
|
|
@@ -1474,20 +1581,70 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
|
|
|
1474
1581
|
handleSubmit();
|
|
1475
1582
|
};
|
|
1476
1583
|
const handleOnChange = (event) => {
|
|
1584
|
+
moveCaret(event.target.selectionStart ?? event.target.value.length, event.target.value);
|
|
1477
1585
|
onValueChange?.(event.target.value);
|
|
1478
1586
|
};
|
|
1587
|
+
const handleOnSelect = (event) => {
|
|
1588
|
+
moveCaret(event.currentTarget.selectionStart ?? 0, event.currentTarget.value);
|
|
1589
|
+
};
|
|
1479
1590
|
const handleMenuSelect = (item) => {
|
|
1480
|
-
|
|
1591
|
+
if (item.onSelect) {
|
|
1592
|
+
const start = mentionToken?.start ?? 0;
|
|
1593
|
+
const end = mentionToken?.end ?? slashToken?.end;
|
|
1594
|
+
if (end !== void 0) {
|
|
1595
|
+
const next = value.slice(0, start) + value.slice(end);
|
|
1596
|
+
onValueChange?.(next);
|
|
1597
|
+
moveCaret(start, next);
|
|
1598
|
+
}
|
|
1599
|
+
item.onSelect();
|
|
1600
|
+
textareaRef.current?.focus();
|
|
1601
|
+
return;
|
|
1602
|
+
}
|
|
1603
|
+
if (mentionToken) {
|
|
1604
|
+
const keep = mentionsMultiple ? "@" : "";
|
|
1605
|
+
const next = value.slice(0, mentionToken.start) + keep + value.slice(mentionToken.end);
|
|
1606
|
+
const nextCaret = mentionToken.start + keep.length;
|
|
1607
|
+
onValueChange?.(next);
|
|
1608
|
+
moveCaret(nextCaret, next);
|
|
1609
|
+
requestAnimationFrame(() => {
|
|
1610
|
+
textareaRef.current?.setSelectionRange(nextCaret, nextCaret);
|
|
1611
|
+
});
|
|
1612
|
+
onMentionSelect?.(item);
|
|
1613
|
+
} else {
|
|
1614
|
+
const rest = slashToken ? value.slice(slashToken.end).replace(/^\s+/, "") : "";
|
|
1615
|
+
const head = `${item.value} `;
|
|
1616
|
+
onValueChange?.(head + rest);
|
|
1617
|
+
moveCaret(head.length, head + rest);
|
|
1618
|
+
requestAnimationFrame(() => {
|
|
1619
|
+
textareaRef.current?.setSelectionRange(head.length, head.length);
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1481
1622
|
textareaRef.current?.focus();
|
|
1482
1623
|
};
|
|
1624
|
+
const dismissMenu = () => {
|
|
1625
|
+
if (value.trim() === "/" || value.trim() === "@") {
|
|
1626
|
+
onValueChange?.("");
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
1629
|
+
if (mentionToken && mentionToken.query === "") {
|
|
1630
|
+
const next = (value.slice(0, mentionToken.start) + value.slice(mentionToken.end)).replace(/\s+$/, "");
|
|
1631
|
+
onValueChange?.(next);
|
|
1632
|
+
moveCaret(next.length, next);
|
|
1633
|
+
return;
|
|
1634
|
+
}
|
|
1635
|
+
setDismissedValue(value);
|
|
1636
|
+
};
|
|
1483
1637
|
const handleOnKeyDown = (event) => {
|
|
1484
1638
|
if (menuOpen) {
|
|
1485
1639
|
if (event.key === "Escape") {
|
|
1486
1640
|
event.preventDefault();
|
|
1487
|
-
|
|
1641
|
+
if (panel) panel.onClose();
|
|
1642
|
+
else dismissMenu();
|
|
1488
1643
|
return;
|
|
1489
1644
|
}
|
|
1490
|
-
if (
|
|
1645
|
+
if (panelOpen) return;
|
|
1646
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") return;
|
|
1647
|
+
if (event.key === "Enter" && matchesFilter(menuItems, menuFilter).length > 0) return;
|
|
1491
1648
|
} else if (hasMenus && CMDK_HIJACKED_KEYS.has(event.key) && isCmdkNavigation(event)) event.stopPropagation();
|
|
1492
1649
|
if (event.key === "Enter" && !event.shiftKey && !event.ctrlKey && !event.metaKey) {
|
|
1493
1650
|
event.preventDefault();
|
|
@@ -1508,9 +1665,12 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
|
|
|
1508
1665
|
onSubmit: handleOnSubmit,
|
|
1509
1666
|
className: cn(promptInputVariants({ variant }), disabled && "tw:bg-none tw:border-border tw:shadow-[inset_0_100vw_rgb(var(--muted))] tw:cursor-default", className),
|
|
1510
1667
|
children: [
|
|
1511
|
-
|
|
1512
|
-
className: "tw
|
|
1513
|
-
children: attachments
|
|
1668
|
+
/* @__PURE__ */ jsx(AnimatedHeight, {
|
|
1669
|
+
className: "tw:-mb-2",
|
|
1670
|
+
children: attachments && /* @__PURE__ */ jsx("div", {
|
|
1671
|
+
className: "tw:flex tw:flex-col tw:gap-2 tw:pb-4",
|
|
1672
|
+
children: attachments
|
|
1673
|
+
})
|
|
1514
1674
|
}),
|
|
1515
1675
|
/* @__PURE__ */ jsx("label", {
|
|
1516
1676
|
htmlFor: textareaId,
|
|
@@ -1518,14 +1678,14 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
|
|
|
1518
1678
|
children: "Prompt Input"
|
|
1519
1679
|
}),
|
|
1520
1680
|
/* @__PURE__ */ jsxs("div", {
|
|
1521
|
-
className: cn("tw:flex tw:min-w-0 tw:gap-2", variant === "inline" ? "tw:flex-row tw:items-center" : "tw:flex-col"),
|
|
1681
|
+
className: cn("tw:flex tw:min-w-0 tw:gap-2", variant === "inline" ? "tw:flex-row tw:items-center tw:@max-[480px]/composer:flex-wrap" : "tw:flex-col"),
|
|
1522
1682
|
children: [
|
|
1523
1683
|
prefix && /* @__PURE__ */ jsx("div", {
|
|
1524
1684
|
className: "tw:flex tw:shrink-0 tw:items-center",
|
|
1525
1685
|
children: prefix
|
|
1526
1686
|
}),
|
|
1527
1687
|
/* @__PURE__ */ jsx("div", {
|
|
1528
|
-
className: "tw:flex tw:min-w-0 tw:
|
|
1688
|
+
className: cn("tw:flex tw:min-w-0 tw:items-center", variant === "inline" ? "tw:grow tw:@max-[480px]/composer:order-first tw:@max-[480px]/composer:basis-full" : "tw:flex-1"),
|
|
1529
1689
|
children: /* @__PURE__ */ jsx(TextareaAutosize, {
|
|
1530
1690
|
...textareaProps,
|
|
1531
1691
|
disabled,
|
|
@@ -1535,12 +1695,13 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
|
|
|
1535
1695
|
ref: setTextareaNode,
|
|
1536
1696
|
value,
|
|
1537
1697
|
onChange: handleOnChange,
|
|
1698
|
+
onSelect: handleOnSelect,
|
|
1538
1699
|
onKeyDown: handleOnKeyDown,
|
|
1539
|
-
className: cn("tw:resize-none", "tw:outline-hidden", "tw:min-w-32 tw:flex-1", variant === "inline" ? "tw:
|
|
1700
|
+
className: cn("tw:resize-none", "tw:outline-hidden", "tw:min-w-32 tw:flex-1", variant === "inline" ? "tw:@max-[480px]/composer:pl-2" : "tw:pl-2 tw:pr-0", "tw:bg-transparent", disabled ? "tw:text-muted-foreground" : "tw:text-foreground", "tw:text-sm", "tw:font-sans", "tw:transition-[width]", "tw:delay-75", "tw:ease-linear", "tw:overflow-auto")
|
|
1540
1701
|
})
|
|
1541
1702
|
}),
|
|
1542
1703
|
/* @__PURE__ */ jsxs("div", {
|
|
1543
|
-
className: cn("tw:flex tw:
|
|
1704
|
+
className: cn("tw:flex tw:items-center tw:gap-1", "tw:[&>*:last-child]:ml-1", "tw:shrink-0", variant === "inline" && "tw:pr-2.5 tw:@max-[480px]/composer:grow tw:@max-[480px]/composer:pr-0"),
|
|
1544
1705
|
children: [suffix, /* @__PURE__ */ jsx(PromptInputSubmit, {
|
|
1545
1706
|
disabled: isDisabled,
|
|
1546
1707
|
status
|
|
@@ -1556,8 +1717,10 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
|
|
|
1556
1717
|
open: menuOpen,
|
|
1557
1718
|
onSelect: handleMenuSelect,
|
|
1558
1719
|
filterValue: menuFilter,
|
|
1559
|
-
emptyText: "No commands found",
|
|
1560
|
-
|
|
1720
|
+
emptyText: mentionsOpen ? mentionsEmptyText : "No commands found",
|
|
1721
|
+
panel: panel?.content,
|
|
1722
|
+
groupAction: commandsOpen ? commandsGroupAction : void 0,
|
|
1723
|
+
groupHeading: mentionsOpen ? mentionsGroupHeading : void 0,
|
|
1561
1724
|
children: formEl
|
|
1562
1725
|
}) : formEl });
|
|
1563
1726
|
};
|
|
@@ -2085,9 +2248,7 @@ const formatPercentage = (value) => {
|
|
|
2085
2248
|
/**
|
|
2086
2249
|
* One budget, as a labelled row over a bar.
|
|
2087
2250
|
*
|
|
2088
|
-
* -
|
|
2089
|
-
* - `value` over 100 or `NaN` is clamped by `clampPercentage` — `Progress`'s indicator is
|
|
2090
|
-
* unclamped and would otherwise slide off the row.
|
|
2251
|
+
* - `value` is clamped by `clampPercentage` — `Progress`'s indicator is unclamped.
|
|
2091
2252
|
*/
|
|
2092
2253
|
const UsageBar = ({ value, label, variant, className, ...props }) => /* @__PURE__ */ jsxs("span", {
|
|
2093
2254
|
...props,
|
|
@@ -2162,6 +2323,6 @@ const UsageStats = ({ value, alert = false, children, className, ariaLabel, alig
|
|
|
2162
2323
|
});
|
|
2163
2324
|
};
|
|
2164
2325
|
//#endregion
|
|
2165
|
-
export { AnswerActions, AnswerSummary, ChatInlineIcon, CollapsibleStepHeader, DIAGRAM_LANGUAGES, InlineStepDetail, InlineStepGroup, InlineStepLabel, Markdown, MarkdownTable, MessageBubble, PlanApproval, PlanRewritingIndicator, PromptInput, Question, QuestionBlock, SuggestedPrompt, ThinkingIndicator, ToolCallApproval, ToolCallChip, ToolCallStatusHeader, UsageBar, UsageStats, UsageStatsRing, clampPercentage, formatPercentage, getChatInlineIconName };
|
|
2326
|
+
export { AnswerActions, AnswerSummary, ChatInlineIcon, CollapsibleStepHeader, DIAGRAM_LANGUAGES, FileDownloadChip, InlineStepDetail, InlineStepGroup, InlineStepLabel, Markdown, MarkdownTable, MessageBubble, PROMPT_INPUT_CONTAINER, PlanApproval, PlanRewritingIndicator, PromptInput, Question, QuestionBlock, SuggestedPrompt, ThinkingIndicator, ToolCallApproval, ToolCallChip, ToolCallStatusHeader, UsageBar, UsageStats, UsageStatsRing, clampPercentage, findMentionToken, findSlashToken, formatPercentage, getChatInlineIconName };
|
|
2166
2327
|
|
|
2167
|
-
//# sourceMappingURL=AIKit-
|
|
2328
|
+
//# sourceMappingURL=AIKit-BD4r7ff-.js.map
|