@keboola/design 15.0.0 → 16.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 +6 -5
- package/CHANGELOG.md +94 -0
- package/COMPONENT-API.md +62 -61
- package/dist/{AIKit-CaAW4GLx.js → AIKit-Cf5plya2.js} +381 -224
- package/dist/AIKit-Cf5plya2.js.map +1 -0
- package/dist/{Alert-Chz6KZ7e.js → Alert-DziS8n1H.js} +12 -19
- package/dist/{Alert-Chz6KZ7e.js.map → Alert-DziS8n1H.js.map} +1 -1
- package/dist/{AlertModal-D4AtpvLS.js → AlertModal-De04fFoy.js} +16 -26
- package/dist/AlertModal-De04fFoy.js.map +1 -0
- package/dist/{AppShell-C8V1KRr_.js → AppShell-BUa3U7-e.js} +6 -9
- package/dist/{AppShell-C8V1KRr_.js.map → AppShell-BUa3U7-e.js.map} +1 -1
- package/dist/{AutoSaveTextarea-BbMhC5Aq.js → AutoSaveTextarea-CXHOQSun.js} +4 -5
- package/dist/{AutoSaveTextarea-BbMhC5Aq.js.map → AutoSaveTextarea-CXHOQSun.js.map} +1 -1
- package/dist/{Badge-5GHIsgRS.js → Badge-CFRhducL.js} +18 -23
- package/dist/Badge-CFRhducL.js.map +1 -0
- package/dist/{BrandEditor-CTGtQUFZ.js → BrandEditor-hiLBX7az.js} +16 -23
- package/dist/{BrandEditor-CTGtQUFZ.js.map → BrandEditor-hiLBX7az.js.map} +1 -1
- package/dist/{BrandLogo-DkESE19K.js → BrandLogo-Dn7hhp2c.js} +4 -5
- package/dist/{BrandLogo-DkESE19K.js.map → BrandLogo-Dn7hhp2c.js.map} +1 -1
- package/dist/{Breadcrumb-B2YSNON4.js → Breadcrumb-uGFEIjFF.js} +17 -28
- package/dist/{Breadcrumb-B2YSNON4.js.map → Breadcrumb-uGFEIjFF.js.map} +1 -1
- package/dist/{Button-BNkyYU8u.js → Button-DbvGzEDb.js} +24 -20
- package/dist/Button-DbvGzEDb.js.map +1 -0
- package/dist/{Calendar-BnKi1kPu.js → Calendar-lJBTETbk.js} +752 -905
- package/dist/Calendar-lJBTETbk.js.map +1 -0
- package/dist/{Card-DxjGiqH8.js → Card-VIPfOVW5.js} +8 -14
- package/dist/{Card-DxjGiqH8.js.map → Card-VIPfOVW5.js.map} +1 -1
- package/dist/{Checkbox-CHDDJyAA.js → Checkbox-B2jLlyaO.js} +6 -8
- package/dist/{Checkbox-CHDDJyAA.js.map → Checkbox-B2jLlyaO.js.map} +1 -1
- package/dist/{Clipboard-DlwVZS1P.js → Clipboard-fAkDdpEu.js} +4 -5
- package/dist/{Clipboard-DlwVZS1P.js.map → Clipboard-fAkDdpEu.js.map} +1 -1
- package/dist/{ClipboardButton-B1Hr_n_Z.js → ClipboardButton-71Ugbl8c.js} +6 -8
- package/dist/{ClipboardButton-B1Hr_n_Z.js.map → ClipboardButton-71Ugbl8c.js.map} +1 -1
- package/dist/{CodeEditor-DVSPdfdo.js → CodeEditor-D_b-ZCng.js} +19 -31
- package/dist/{CodeEditor-DVSPdfdo.js.map → CodeEditor-D_b-ZCng.js.map} +1 -1
- package/dist/{Collapsible-DD4xTL75.js → Collapsible-zsXk4Vpp.js} +5 -8
- package/dist/{Collapsible-DD4xTL75.js.map → Collapsible-zsXk4Vpp.js.map} +1 -1
- package/dist/{ColorInput-B_eZIu39.js → ColorInput-Cjr1jkvy.js} +9 -12
- package/dist/{ColorInput-B_eZIu39.js.map → ColorInput-Cjr1jkvy.js.map} +1 -1
- package/dist/{ColorModeSwitch-B6UEzG0H.js → ColorModeSwitch-CuPYnJ2V.js} +5 -6
- package/dist/{ColorModeSwitch-B6UEzG0H.js.map → ColorModeSwitch-CuPYnJ2V.js.map} +1 -1
- package/dist/{Combobox-CaKqgstG.js → Combobox-DYjvYgl3.js} +38 -67
- package/dist/Combobox-DYjvYgl3.js.map +1 -0
- package/dist/{Command-DhXmqFLT.js → Command-BcTb6GsR.js} +14 -24
- package/dist/{Command-DhXmqFLT.js.map → Command-BcTb6GsR.js.map} +1 -1
- package/dist/{CopyField-D0Pg4Z0R.js → CopyField-CnwAvQz9.js} +16 -28
- package/dist/{CopyField-D0Pg4Z0R.js.map → CopyField-CnwAvQz9.js.map} +1 -1
- package/dist/{DateInput-BgbMDJkm.js → DateInput-DJNX7Vdx.js} +8 -10
- package/dist/{DateInput-BgbMDJkm.js.map → DateInput-DJNX7Vdx.js.map} +1 -1
- package/dist/{DatePicker-BXpDRo-R.js → DatePicker-CI59gF3S.js} +4 -5
- package/dist/{DatePicker-BXpDRo-R.js.map → DatePicker-CI59gF3S.js.map} +1 -1
- package/dist/{DateRangeInput-BW0-_jV0.js → DateRangeInput-B3g8cyS0.js} +8 -10
- package/dist/{DateRangeInput-BW0-_jV0.js.map → DateRangeInput-B3g8cyS0.js.map} +1 -1
- package/dist/{DateRangePicker-C4-DoWac.js → DateRangePicker-48yOB2qV.js} +9 -10
- package/dist/{DateRangePicker-C4-DoWac.js.map → DateRangePicker-48yOB2qV.js.map} +1 -1
- package/dist/{DiffView-Dy4z-n-1.js → DiffView-DITZdVbh.js} +7 -12
- package/dist/{DiffView-Dy4z-n-1.js.map → DiffView-DITZdVbh.js.map} +1 -1
- package/dist/{DropdownMenu-CcVbZ_5u.js → DropdownMenu-Ba9atqDa.js} +21 -37
- package/dist/DropdownMenu-Ba9atqDa.js.map +1 -0
- package/dist/{FieldBox-BrxLkY9C.js → FieldBox-DdSdJ3ZN.js} +6 -10
- package/dist/{FieldBox-BrxLkY9C.js.map → FieldBox-DdSdJ3ZN.js.map} +1 -1
- package/dist/{FieldItem-BHUqgSO1.js → FieldItem-D7eCMfMB.js} +6 -8
- package/dist/{FieldItem-BHUqgSO1.js.map → FieldItem-D7eCMfMB.js.map} +1 -1
- package/dist/{FieldItem-CPN1xjN5.d.ts → FieldItem-fqm3CNR8.d.ts} +7 -6
- package/dist/{FileUpload-BYFONpEl.js → FileUpload-DskvxhAr.js} +25 -45
- package/dist/{FileUpload-BYFONpEl.js.map → FileUpload-DskvxhAr.js.map} +1 -1
- package/dist/{Form-CAofWyMI.js → Form-BUNW7nlt.js} +24 -38
- package/dist/{Form-CAofWyMI.js.map → Form-BUNW7nlt.js.map} +1 -1
- package/dist/{FormGroup-V5kIgQRN.js → FormGroup-QJB21LKp.js} +12 -20
- package/dist/{FormGroup-V5kIgQRN.js.map → FormGroup-QJB21LKp.js.map} +1 -1
- package/dist/{FullScreenModal-DAvvlGOz.js → FullScreenModal-RzY5XxiG.js} +8 -12
- package/dist/{FullScreenModal-DAvvlGOz.js.map → FullScreenModal-RzY5XxiG.js.map} +1 -1
- package/dist/HoverCard-OGWKRXJ7.js +24 -0
- package/dist/HoverCard-OGWKRXJ7.js.map +1 -0
- package/dist/{InlineEdit-D4P0SvCB.js → InlineEdit-CXL0ZslO.js} +7 -8
- package/dist/{InlineEdit-D4P0SvCB.js.map → InlineEdit-CXL0ZslO.js.map} +1 -1
- package/dist/{InputGroup-CZv_7QlM.js → InputGroup-BWeanEo7.js} +9 -15
- package/dist/{InputGroup-CZv_7QlM.js.map → InputGroup-BWeanEo7.js.map} +1 -1
- package/dist/{Kbd-CflKthfu.js → Kbd-BprYCICe.js} +8 -13
- package/dist/{Kbd-CflKthfu.js.map → Kbd-BprYCICe.js.map} +1 -1
- package/dist/{MarkedText-DlmlJO0u.js → MarkedText-BrganZ_V.js} +4 -6
- package/dist/{MarkedText-DlmlJO0u.js.map → MarkedText-BrganZ_V.js.map} +1 -1
- package/dist/{MermaidDiagram-Te-5gOCU.js → MermaidDiagram-E3azndPk.js} +9 -11
- package/dist/{MermaidDiagram-Te-5gOCU.js.map → MermaidDiagram-E3azndPk.js.map} +1 -1
- package/dist/{Modal-CbUz-5YH.js → Modal-Cf_kPEBW.js} +14 -22
- package/dist/Modal-Cf_kPEBW.js.map +1 -0
- package/dist/{ModalTitle-cy0Ht9VY.js → ModalTitle-7vgpfc6B.js} +6 -9
- package/dist/ModalTitle-7vgpfc6B.js.map +1 -0
- package/dist/{MultiActionButtonGroup-Dzig87s1.js → MultiActionButtonGroup-8WQwL4UQ.js} +6 -8
- package/dist/{MultiActionButtonGroup-Dzig87s1.js.map → MultiActionButtonGroup-8WQwL4UQ.js.map} +1 -1
- package/dist/{Navbar-DHUS7XiU.js → Navbar-CRjxVboE.js} +13 -22
- package/dist/{Navbar-DHUS7XiU.js.map → Navbar-CRjxVboE.js.map} +1 -1
- package/dist/{OtpInput-CY8yCaJk.js → OtpInput-C5plPzGU.js} +7 -11
- package/dist/{OtpInput-CY8yCaJk.js.map → OtpInput-C5plPzGU.js.map} +1 -1
- package/dist/{PageHeader-CL1A6jFM.js → PageHeader-DosMyar2.js} +6 -10
- package/dist/{PageHeader-CL1A6jFM.js.map → PageHeader-DosMyar2.js.map} +1 -1
- package/dist/{PageLayout-C9aXTpqV.js → PageLayout-LcvJccOW.js} +5 -8
- package/dist/{PageLayout-C9aXTpqV.js.map → PageLayout-LcvJccOW.js.map} +1 -1
- package/dist/{PageToolbar-DJ5tdYla.js → PageToolbar-By2HznxO.js} +8 -10
- package/dist/{PageToolbar-DJ5tdYla.js.map → PageToolbar-By2HznxO.js.map} +1 -1
- package/dist/{Pagination-D27x5KmH.js → Pagination-DrXTrvfD.js} +11 -18
- package/dist/{Pagination-D27x5KmH.js.map → Pagination-DrXTrvfD.js.map} +1 -1
- package/dist/{Popconfirm-DwLCYNaF.js → Popconfirm-BJuDOHdv.js} +46 -25
- package/dist/Popconfirm-BJuDOHdv.js.map +1 -0
- package/dist/{Popover-DtUDwUVO.js → Popover-DhOPlWgF.js} +5 -7
- package/dist/Popover-DhOPlWgF.js.map +1 -0
- package/dist/{RadioGroup-B0TwHjBb.js → RadioGroup-B9oC8P15.js} +12 -18
- package/dist/{RadioGroup-B0TwHjBb.js.map → RadioGroup-B9oC8P15.js.map} +1 -1
- package/dist/{Resizable-D8zs0kcq.js → Resizable-Co-L3qg7.js} +4 -6
- package/dist/{Resizable-D8zs0kcq.js.map → Resizable-Co-L3qg7.js.map} +1 -1
- package/dist/{Search-vyZwGKMU.js → Search-OgaNjqQM.js} +26 -21
- package/dist/Search-OgaNjqQM.js.map +1 -0
- package/dist/{SearchInput-DyYXyw3u.js → SearchInput-eLS-uvOn.js} +18 -29
- package/dist/SearchInput-eLS-uvOn.js.map +1 -0
- package/dist/{SectionNav-tLK3iF6c.js → SectionNav-L81iJBo3.js} +11 -14
- package/dist/{SectionNav-tLK3iF6c.js.map → SectionNav-L81iJBo3.js.map} +1 -1
- package/dist/{Select-B22hB_-w.js → Select-DRdkdzBp.js} +29 -26
- package/dist/Select-DRdkdzBp.js.map +1 -0
- package/dist/{Sheet-0TWKTqid.js → Sheet-DVb4XoJ5.js} +13 -20
- package/dist/Sheet-DVb4XoJ5.js.map +1 -0
- package/dist/{Sidebar-C5hdANBU.js → Sidebar-DYvodJWN.js} +43 -75
- package/dist/{Sidebar-C5hdANBU.js.map → Sidebar-DYvodJWN.js.map} +1 -1
- package/dist/{Slider-DrcsM8_G.js → Slider-B9IskDxf.js} +8 -12
- package/dist/{Slider-DrcsM8_G.js.map → Slider-B9IskDxf.js.map} +1 -1
- package/dist/{Stepper-CQrUPVFL.js → Stepper-D7VspVEt.js} +11 -19
- package/dist/{Stepper-CQrUPVFL.js.map → Stepper-D7VspVEt.js.map} +1 -1
- package/dist/{Switch-DccpSpzC.js → Switch-DONWW7ju.js} +4 -6
- package/dist/{Switch-DccpSpzC.js.map → Switch-DONWW7ju.js.map} +1 -1
- package/dist/{Table-CilEvpMq.js → Table-BwgBm3hJ.js} +12 -21
- package/dist/{Table-CilEvpMq.js.map → Table-BwgBm3hJ.js.map} +1 -1
- package/dist/{Tabs-Ck4uWf8U.js → Tabs-DmJB4l_N.js} +9 -14
- package/dist/{Tabs-Ck4uWf8U.js.map → Tabs-DmJB4l_N.js.map} +1 -1
- package/dist/{TextInput-CR0_USaY.js → TextInput--1CfZybC.js} +8 -10
- package/dist/TextInput--1CfZybC.js.map +1 -0
- package/dist/{ThemeProvider-BTK7AL-T.js → ThemeProvider-BCHllN7d.js} +8 -13
- package/dist/{ThemeProvider-BTK7AL-T.js.map → ThemeProvider-BCHllN7d.js.map} +1 -1
- package/dist/{TimePicker-CoRpiEM3.js → TimePicker-CCV3SOw5.js} +4 -6
- package/dist/{TimePicker-CoRpiEM3.js.map → TimePicker-CCV3SOw5.js.map} +1 -1
- package/dist/{Timeline-DUXgByUE.js → Timeline-EMOpTLAT.js} +8 -13
- package/dist/{Timeline-DUXgByUE.js.map → Timeline-EMOpTLAT.js.map} +1 -1
- package/dist/{Toast-937n7n8i.js → Toast-BOTINeTX.js} +4 -6
- package/dist/{Toast-937n7n8i.js.map → Toast-BOTINeTX.js.map} +1 -1
- package/dist/{ToggleAllTooltip-DEjbWFoj.js → ToggleAllTooltip-BFmA6TXf.js} +4 -6
- package/dist/{ToggleAllTooltip-DEjbWFoj.js.map → ToggleAllTooltip-BFmA6TXf.js.map} +1 -1
- package/dist/{ToggleGroup-BOz1yyz6.js → ToggleGroup-DsDS7k70.js} +3 -4
- package/dist/{ToggleGroup-BOz1yyz6.js.map → ToggleGroup-DsDS7k70.js.map} +1 -1
- package/dist/{Workbench-CxgNCs3I.js → Workbench-4s0xP6XU.js} +18 -32
- package/dist/{Workbench-CxgNCs3I.js.map → Workbench-4s0xP6XU.js.map} +1 -1
- package/dist/{ZoomableSvg-DnFXo2L4.js → ZoomableSvg-BRPGgaWJ.js} +9 -11
- package/dist/{ZoomableSvg-DnFXo2L4.js.map → ZoomableSvg-BRPGgaWJ.js.map} +1 -1
- package/dist/charts.d.ts +0 -16
- package/dist/charts.js +10 -19
- package/dist/charts.js.map +1 -1
- package/dist/{classNames-DcGnTh2N.js → classNames-DkX30VJU.js} +2 -3
- package/dist/{classNames-DcGnTh2N.js.map → classNames-DkX30VJU.js.map} +1 -1
- package/dist/editors.d.ts +2 -16
- package/dist/editors.js +16 -26
- package/dist/editors.js.map +1 -1
- package/dist/{findLiteralMatches-DgGLzyG0.js → findLiteralMatches-BaLZTPtx.js} +2 -3
- package/dist/{findLiteralMatches-DgGLzyG0.js.map → findLiteralMatches-BaLZTPtx.js.map} +1 -1
- package/dist/flint.d.ts +0 -2
- package/dist/flint.js +10 -14
- package/dist/flint.js.map +1 -1
- package/dist/{highlightCode-D354tCXO.js → highlightCode-2spZP7ZA.js} +2 -3
- package/dist/{highlightCode-D354tCXO.js.map → highlightCode-2spZP7ZA.js.map} +1 -1
- package/dist/{icons-ZIeZXXS7.js → icons-DDR9dFSr.js} +21 -40
- package/dist/{icons-ZIeZXXS7.js.map → icons-DDR9dFSr.js.map} +1 -1
- package/dist/icons.d.ts +1 -1
- package/dist/icons.js +1 -2
- package/dist/{index-D-itZ3VP.d.ts → index-BljYaTWL.d.ts} +1 -39
- package/dist/index.d.ts +452 -1296
- package/dist/index.js +76 -74
- package/dist/internal/blocks/AIKit.js +1 -2
- package/dist/internal/blocks/AppShell.js +1 -2
- package/dist/internal/blocks/AuthLayout.js +3 -4
- package/dist/internal/blocks/AutoSaveTextarea.js +1 -2
- package/dist/internal/blocks/BrandEditor.js +1 -2
- package/dist/internal/blocks/ChartPanel.js +3 -4
- package/dist/internal/blocks/ChipEditor.js +6 -7
- package/dist/internal/blocks/ClipboardButton.js +1 -2
- package/dist/internal/blocks/ColorInput.js +1 -2
- package/dist/internal/blocks/ColorModeSwitch.js +1 -2
- package/dist/internal/blocks/Command.js +1 -2
- package/dist/internal/blocks/CopyField.js +1 -2
- package/dist/internal/blocks/DashboardHero.js +2 -3
- package/dist/internal/blocks/DateInput.js +1 -2
- package/dist/internal/blocks/DateRangeInput.js +1 -2
- package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js +1 -2
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +2 -3
- package/dist/internal/blocks/EmptyState.js +1 -2
- package/dist/internal/blocks/ErrorState.js +1 -2
- package/dist/internal/blocks/ExportMenu.js +5 -6
- package/dist/internal/blocks/FacebookButton.js +3 -4
- package/dist/internal/blocks/Form/connectors/ComboboxField.js +3 -4
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +2 -3
- package/dist/internal/blocks/Form.js +3 -2
- package/dist/internal/blocks/FormGroup.js +1 -2
- package/dist/internal/blocks/GoogleButton.js +3 -4
- package/dist/internal/blocks/InlineEdit.js +1 -2
- package/dist/internal/blocks/MicrosoftButton.js +3 -4
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -2
- package/dist/internal/blocks/MultiCombobox.js +7 -8
- package/dist/internal/blocks/NumberInput.js +2 -3
- package/dist/internal/blocks/OtpInput.js +1 -2
- package/dist/internal/blocks/PageHeader.js +1 -2
- package/dist/internal/blocks/PageLayout.js +1 -2
- package/dist/internal/blocks/PageToolbar.js +1 -2
- package/dist/internal/blocks/PasswordInput.js +5 -6
- package/dist/internal/blocks/SearchInput.js +1 -2
- package/dist/internal/blocks/SearchInputWithNavigation.js +6 -7
- package/dist/internal/blocks/SectionNav.js +1 -2
- package/dist/internal/blocks/SplitButton.js +4 -5
- package/dist/internal/blocks/StatCard.js +4 -6
- package/dist/internal/blocks/StatCard.js.map +1 -1
- package/dist/internal/blocks/TextInput.js +1 -2
- package/dist/internal/blocks/Textarea.js +3 -4
- package/dist/internal/blocks/TimeInput.js +6 -7
- package/dist/internal/components/Alert.js +1 -2
- package/dist/internal/components/AlertModal.js +1 -2
- package/dist/internal/components/Avatar.js +3 -4
- package/dist/internal/components/Badge.js +1 -2
- package/dist/internal/components/BrandLogo.js +1 -2
- package/dist/internal/components/Breadcrumb.js +1 -2
- package/dist/internal/components/Button.js +1 -2
- package/dist/internal/components/ButtonGroup.js +2 -3
- package/dist/internal/components/Calendar.js +1 -2
- package/dist/internal/components/Card.js +1 -2
- package/dist/internal/components/Checkbox.js +1 -2
- package/dist/internal/components/Clipboard.js +1 -2
- package/dist/internal/components/Collapsible.js +1 -2
- package/dist/internal/components/CollapsiblePanel.js +5 -6
- package/dist/internal/components/Combobox.js +1 -2
- package/dist/internal/components/DatePicker.js +1 -2
- package/dist/internal/components/DateRangePicker.js +1 -2
- package/dist/internal/components/DiffView.js +1 -2
- package/dist/internal/components/DotsLoader.js +2 -3
- package/dist/internal/components/DropdownMenu.js +1 -2
- package/dist/internal/components/EmptySearchContent.js +1 -2
- package/dist/internal/components/FileUpload.js +1 -2
- package/dist/internal/components/FullScreenModal.js +1 -2
- package/dist/internal/components/HelpBlock.js +1 -2
- package/dist/internal/components/HoverCard.js +1 -2
- package/dist/internal/components/InputGroup.js +1 -2
- package/dist/internal/components/Kbd.js +1 -2
- package/dist/internal/components/Label.js +2 -3
- package/dist/internal/components/Link.js +2 -3
- package/dist/internal/components/MarkedText.js +1 -2
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +3 -4
- package/dist/internal/components/MergeEditor/PaneHeader.js +1 -2
- package/dist/internal/components/MergeEditor/constants.js +1 -2
- package/dist/internal/components/MergeEditor/useMergeDiff.js +1 -2
- package/dist/internal/components/Modal.js +1 -2
- package/dist/internal/components/Navbar.js +1 -2
- package/dist/internal/components/Pagination.js +1 -2
- package/dist/internal/components/PanelWithDetails.js +4 -5
- package/dist/internal/components/Popconfirm.js +1 -2
- package/dist/internal/components/Popover.js +1 -2
- package/dist/internal/components/Progress.js +2 -3
- package/dist/internal/components/RadioGroup.js +1 -2
- package/dist/internal/components/Resizable.js +1 -2
- package/dist/internal/components/ScrollArea.js +3 -5
- package/dist/internal/components/ScrollArea.js.map +1 -1
- package/dist/internal/components/Search.js +1 -2
- package/dist/internal/components/Select.js +1 -2
- package/dist/internal/components/Separator.js +2 -3
- package/dist/internal/components/Sheet.js +1 -2
- package/dist/internal/components/Sidebar.js +1 -2
- package/dist/internal/components/Skeleton/Skeleton.js +2 -3
- package/dist/internal/components/Skeleton/SkeletonList.js +2 -3
- package/dist/internal/components/Slider.js +1 -2
- package/dist/internal/components/SpotlightBackdrop.js +3 -5
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
- package/dist/internal/components/Stepper.js +1 -2
- package/dist/internal/components/Switch.js +1 -2
- package/dist/internal/components/Table.js +1 -2
- package/dist/internal/components/Tabs.js +1 -2
- package/dist/internal/components/ThemeProvider.js +2 -2
- package/dist/internal/components/TimePicker.js +1 -2
- package/dist/internal/components/Timeline.js +1 -2
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Toggle.js +2 -3
- package/dist/internal/components/ToggleGroup.js +1 -2
- package/dist/internal/components/Tooltip.js +1 -2
- package/dist/internal/components/Truncated.js +3 -4
- package/dist/internal/components/Workbench.js +1 -2
- package/dist/internal/components/ZoomableSvg.js +1 -2
- package/dist/internal/hooks/useAltDigitHotkey.js +1 -2
- package/dist/internal/hooks/useAutosizeInput.js +1 -2
- package/dist/internal/hooks/useScrollbarPosition.js +2 -3
- package/dist/internal/hooks/useStableCallback.js +1 -2
- package/dist/internal/hooks/useTimeout.js +18 -0
- package/dist/internal/hooks/useTimeout.js.map +1 -0
- package/dist/internal/utils/accessibleName.js +1 -2
- package/dist/internal/utils/mergeRefs.js +1 -2
- package/dist/internal/utils.js +3 -3
- package/dist/markdown-editor.d.ts +0 -4
- package/dist/markdown-editor.js +30 -49
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +0 -2
- package/dist/mermaid.js +1 -2
- package/dist/rjsf.d.ts +0 -8
- package/dist/rjsf.js +47 -78
- package/dist/rjsf.js.map +1 -1
- package/dist/{rolldown-runtime-Bdc48AWt.js → rolldown-runtime-BrwM56v-.js} +2 -3
- package/dist/{styles-T8xwr0sR.js → styles-BXXXosW_.js} +2 -3
- package/dist/{styles-T8xwr0sR.js.map → styles-BXXXosW_.js.map} +1 -1
- package/dist/{styles-DxazJ8Mz.js → styles-nwtCRF7y.js} +2 -3
- package/dist/{styles-DxazJ8Mz.js.map → styles-nwtCRF7y.js.map} +1 -1
- package/dist/styles.css +1 -1
- package/dist/{svgCache-Dhmbe-7i.js → svgCache-BzvN_fgr.js} +2 -3
- package/dist/{svgCache-Dhmbe-7i.js.map → svgCache-BzvN_fgr.js.map} +1 -1
- package/dist/{svgTransforms-Hnvev3Vs.js → svgTransforms-BBxxO9T6.js} +4 -6
- package/dist/{svgTransforms-Hnvev3Vs.js.map → svgTransforms-BBxxO9T6.js.map} +1 -1
- package/dist/testing.d.ts +0 -2
- package/dist/testing.js +2 -3
- package/dist/{themeScopeContext-CEVXbYvZ.js → themeScopeContext-BZGPdyG8.js} +6 -11
- package/dist/{themeScopeContext-CEVXbYvZ.js.map → themeScopeContext-BZGPdyG8.js.map} +1 -1
- package/dist/{themeTokens-DCeb62ap.js → themeTokens-B60cQtAY.js} +4 -6
- package/dist/{themeTokens-DCeb62ap.js.map → themeTokens-B60cQtAY.js.map} +1 -1
- package/dist/{toast-Y3cTMBW8.js → toast-Dzj1EFOb.js} +10 -17
- package/dist/{toast-Y3cTMBW8.js.map → toast-Dzj1EFOb.js.map} +1 -1
- package/dist/{types-BPcAjMG0.d.ts → types-CsZuwfxc.d.ts} +1 -3
- package/dist/{useControllableState-CUYXMsfz.js → useControllableState-BCvUOC6G.js} +2 -3
- package/dist/{useControllableState-CUYXMsfz.js.map → useControllableState-BCvUOC6G.js.map} +1 -1
- package/dist/{useElement-D-RjrGa4.js → useElement-Dcoo9Jlr.js} +2 -3
- package/dist/{useElement-D-RjrGa4.js.map → useElement-Dcoo9Jlr.js.map} +1 -1
- package/dist/{useMergeDiff-CvowEXJ1.js → useMergeDiff-DFIATaTw.js} +3 -5
- package/dist/{useMergeDiff-CvowEXJ1.js.map → useMergeDiff-DFIATaTw.js.map} +1 -1
- package/dist/{utils-DwC9u0tM.js → utils-DjFceY3H.js} +18 -34
- package/dist/utils-DjFceY3H.js.map +1 -0
- package/dist/vega.d.ts +1 -5
- package/dist/vega.js +3 -4
- package/dist/{vegaTheme-ISwGXvof.js → vegaTheme-BcTNRmVS.js} +3 -4
- package/dist/{vegaTheme-ISwGXvof.js.map → vegaTheme-BcTNRmVS.js.map} +1 -1
- package/dist/{vegaTokens-DCkvpIVE.js → vegaTokens-DnCcy7JY.js} +3 -4
- package/dist/{vegaTokens-DCkvpIVE.js.map → vegaTokens-DnCcy7JY.js.map} +1 -1
- package/package.json +40 -40
- package/src/styles.css +70 -4
- package/src/theme.css +117 -11
- package/dist/AIKit-CaAW4GLx.js.map +0 -1
- package/dist/AlertModal-D4AtpvLS.js.map +0 -1
- package/dist/Badge-5GHIsgRS.js.map +0 -1
- package/dist/Button-BNkyYU8u.js.map +0 -1
- package/dist/Calendar-BnKi1kPu.js.map +0 -1
- package/dist/Combobox-CaKqgstG.js.map +0 -1
- package/dist/DropdownMenu-CcVbZ_5u.js.map +0 -1
- package/dist/HoverCard-Cv5rmvJq.js +0 -26
- package/dist/HoverCard-Cv5rmvJq.js.map +0 -1
- package/dist/Modal-CbUz-5YH.js.map +0 -1
- package/dist/ModalTitle-cy0Ht9VY.js.map +0 -1
- package/dist/Popconfirm-DwLCYNaF.js.map +0 -1
- package/dist/Popover-DtUDwUVO.js.map +0 -1
- package/dist/Search-vyZwGKMU.js.map +0 -1
- package/dist/SearchInput-DyYXyw3u.js.map +0 -1
- package/dist/Select-B22hB_-w.js.map +0 -1
- package/dist/Sheet-0TWKTqid.js.map +0 -1
- package/dist/TextInput-CR0_USaY.js.map +0 -1
- package/dist/utils-DwC9u0tM.js.map +0 -1
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import { cn } from "./classNames-
|
|
2
|
-
import { Tooltip } from "./utils-
|
|
3
|
-
import { Circle } from "./icons-
|
|
4
|
-
import { radioCircleVariants, radioIndicatorVariants, radioItemButtonVariants, radioVariants } from "./styles-
|
|
5
|
-
import { FieldBox } from "./FieldBox-
|
|
1
|
+
import { cn } from "./classNames-DkX30VJU.js";
|
|
2
|
+
import { Tooltip } from "./utils-DjFceY3H.js";
|
|
3
|
+
import { Circle } from "./icons-DDR9dFSr.js";
|
|
4
|
+
import { radioCircleVariants, radioIndicatorVariants, radioItemButtonVariants, radioVariants } from "./styles-nwtCRF7y.js";
|
|
5
|
+
import { FieldBox } from "./FieldBox-DdSdJ3ZN.js";
|
|
6
6
|
import { Separator } from "./internal/components/Separator.js";
|
|
7
7
|
import { createContext, use, useId } from "react";
|
|
8
8
|
import { cva } from "class-variance-authority";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import * as RRadioGroup from "@radix-ui/react-radio-group";
|
|
11
11
|
import { Indicator, Item } from "@radix-ui/react-radio-group";
|
|
12
|
-
|
|
12
|
+
// src/components/RadioGroup/context.ts
|
|
13
13
|
const RadioGroupContext = createContext({
|
|
14
14
|
variant: "radio",
|
|
15
15
|
orientation: "horizontal"
|
|
16
16
|
});
|
|
17
17
|
const RadioGroupProvider = RadioGroupContext;
|
|
18
18
|
const useRadioGroupContext = () => use(RadioGroupContext);
|
|
19
|
-
|
|
20
|
-
//#region src/components/RadioGroup/Radio.tsx
|
|
19
|
+
// src/components/RadioGroup/Radio.tsx
|
|
21
20
|
const Radio = ({ className, ...props }) => /* @__PURE__ */ jsx(Item, {
|
|
22
21
|
...props,
|
|
23
22
|
className: cn(radioCircleVariants(), radioVariants(), className),
|
|
@@ -26,16 +25,14 @@ const Radio = ({ className, ...props }) => /* @__PURE__ */ jsx(Item, {
|
|
|
26
25
|
children: /* @__PURE__ */ jsx(Circle, { className: radioIndicatorVariants() })
|
|
27
26
|
})
|
|
28
27
|
});
|
|
29
|
-
|
|
30
|
-
//#region src/components/RadioGroup/RadioGroupItemButton.tsx
|
|
28
|
+
// src/components/RadioGroup/RadioGroupItemButton.tsx
|
|
31
29
|
const RadioGroupItemButton = ({ ref, className, children, ...props }) => /* @__PURE__ */ jsx(Item, {
|
|
32
30
|
ref,
|
|
33
31
|
...props,
|
|
34
32
|
className: cn(radioItemButtonVariants(), className),
|
|
35
33
|
children
|
|
36
34
|
});
|
|
37
|
-
|
|
38
|
-
//#region src/components/RadioGroup/RadioGroupItem.tsx
|
|
35
|
+
// src/components/RadioGroup/RadioGroupItem.tsx
|
|
39
36
|
const RadioGroupItem = ({ children, className, tooltip, tooltipVariant, tooltipPlacement, description, ...props }) => {
|
|
40
37
|
const { variant } = useRadioGroupContext();
|
|
41
38
|
const id = useId();
|
|
@@ -65,8 +62,7 @@ const RadioGroupItem = ({ children, className, tooltip, tooltipVariant, tooltipP
|
|
|
65
62
|
children: item
|
|
66
63
|
});
|
|
67
64
|
};
|
|
68
|
-
|
|
69
|
-
//#region src/components/RadioGroup/RadioGroupSeparator.tsx
|
|
65
|
+
// src/components/RadioGroup/RadioGroupSeparator.tsx
|
|
70
66
|
const RadioGroupSeparator = () => {
|
|
71
67
|
const { orientation } = useRadioGroupContext();
|
|
72
68
|
return /* @__PURE__ */ jsx(Separator, {
|
|
@@ -75,8 +71,7 @@ const RadioGroupSeparator = () => {
|
|
|
75
71
|
className: orientation === "horizontal" ? "tw:mx-2" : "tw:my-2"
|
|
76
72
|
});
|
|
77
73
|
};
|
|
78
|
-
|
|
79
|
-
//#region src/components/RadioGroup/RadioGroup.tsx
|
|
74
|
+
// src/components/RadioGroup/RadioGroup.tsx
|
|
80
75
|
const radioGroupVariants = cva(["tw:flex"], { variants: {
|
|
81
76
|
orientation: {
|
|
82
77
|
horizontal: ["tw:gap-2"],
|
|
@@ -110,7 +105,6 @@ const RadioGroup = ({ variant = "radio", className, disabled = false, orientatio
|
|
|
110
105
|
});
|
|
111
106
|
RadioGroup.Item = RadioGroupItem;
|
|
112
107
|
RadioGroup.Separator = RadioGroupSeparator;
|
|
113
|
-
//#endregion
|
|
114
108
|
export { RadioGroup };
|
|
115
109
|
|
|
116
|
-
//# sourceMappingURL=RadioGroup-
|
|
110
|
+
//# sourceMappingURL=RadioGroup-B9oC8P15.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioGroup-
|
|
1
|
+
{"version":3,"file":"RadioGroup-B9oC8P15.js","names":[],"sources":["../src/components/RadioGroup/context.ts","../src/components/RadioGroup/Radio.tsx","../src/components/RadioGroup/RadioGroupItemButton.tsx","../src/components/RadioGroup/RadioGroupItem.tsx","../src/components/RadioGroup/RadioGroupSeparator.tsx","../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\nexport type Variant = 'radio' | 'button' | 'radio-block';\nexport type Orientation = 'vertical' | 'horizontal';\n\nconst RadioGroupContext = createContext<{\n variant: Variant;\n orientation: Orientation;\n}>({\n variant: 'radio',\n orientation: 'horizontal',\n});\n\nexport const RadioGroupProvider = RadioGroupContext;\n\nexport const useRadioGroupContext = () => use(RadioGroupContext);\n","import type { ComponentProps } from 'react';\nimport { Indicator, Item } from '@radix-ui/react-radio-group';\n\nimport { Circle } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { radioCircleVariants, radioIndicatorVariants, radioVariants } from './styles';\n\nexport const Radio = ({ className, ...props }: ComponentProps<typeof Item>) => (\n <Item {...props} className={cn(radioCircleVariants(), radioVariants(), className)}>\n <Indicator className={cn('tw:flex', 'tw:items-center', 'tw:justify-center')}>\n {/* Lucide Circle is stroke-only — force fill to match the stroke (currentColor)\n so the indicator reads as a solid dot. */}\n <Circle className={radioIndicatorVariants()} />\n </Indicator>\n </Item>\n);\n","import type { ComponentProps } from 'react';\nimport { Item } from '@radix-ui/react-radio-group';\n\nimport { cn } from '../../utils';\n\nimport { radioItemButtonVariants } from './styles';\n\ntype Props = ComponentProps<typeof Item>;\n\nexport const RadioGroupItemButton = ({ ref, className, children, ...props }: Props) => (\n <Item ref={ref} {...props} className={cn(radioItemButtonVariants(), className)}>\n {children}\n </Item>\n);\n","import { useId } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport type { Item } from '@radix-ui/react-radio-group';\n\nimport { cn } from '../../utils';\nimport { FieldBox } from '../FieldBox';\nimport type { Props as TooltipProps } from '../Tooltip';\nimport { Tooltip } from '../Tooltip';\n\nimport { useRadioGroupContext } from './context';\nimport { Radio } from './Radio';\nimport { RadioGroupItemButton } from './RadioGroupItemButton';\n\ntype ItemProps = Omit<ComponentProps<typeof Item>, 'asChild' | 'value'>;\n\ntype Props<T extends string = string> = ItemProps & {\n value: T;\n tooltip?: ReactNode;\n tooltipVariant?: TooltipProps['variant'];\n tooltipPlacement?: TooltipProps['placement'];\n description?: ReactNode;\n};\n\nexport const RadioGroupItem = <T extends string = string>({\n children,\n className,\n tooltip,\n tooltipVariant,\n tooltipPlacement,\n description,\n ...props\n}: Props<T>) => {\n const { variant } = useRadioGroupContext();\n const id = useId();\n\n const item = (() => {\n if (variant === 'button')\n return (\n <RadioGroupItemButton {...props} className={className}>\n {children}\n </RadioGroupItemButton>\n );\n\n return (\n <FieldBox\n variant={variant === 'radio-block' ? 'boxed' : 'default'}\n htmlFor={id}\n control={<Radio {...props} id={id} />}\n className={cn(variant === 'radio-block' && 'tw:flex-1', className)}\n >\n <FieldBox.Title>{children}</FieldBox.Title>\n {description && <FieldBox.Description>{description}</FieldBox.Description>}\n </FieldBox>\n );\n })();\n\n if (!tooltip) {\n return item;\n }\n\n return (\n <Tooltip tooltip={tooltip} variant={tooltipVariant} placement={tooltipPlacement} triggerAsChild>\n {item}\n </Tooltip>\n );\n};\n","import { Separator } from '../Separator';\n\nimport { useRadioGroupContext } from './context';\n\nexport const RadioGroupSeparator = () => {\n const { orientation } = useRadioGroupContext();\n const invertedOrientation = orientation === 'horizontal' ? 'vertical' : 'horizontal';\n const size = orientation === 'horizontal' ? '1/2' : 'full';\n const className = orientation === 'horizontal' ? 'tw:mx-2' : 'tw:my-2';\n\n return <Separator orientation={invertedOrientation} size={size} className={className} />;\n};\n","import type { ComponentProps } from 'react';\nimport * as RRadioGroup from '@radix-ui/react-radio-group';\nimport { cva } from 'class-variance-authority';\n\nimport { cn } from '../../utils';\n\nimport type { Orientation, Variant } from './context';\nimport { RadioGroupProvider } from './context';\nimport { RadioGroupItem } from './RadioGroupItem';\nimport { RadioGroupSeparator } from './RadioGroupSeparator';\n\nconst radioGroupVariants = cva(['tw:flex'], {\n variants: {\n orientation: {\n horizontal: ['tw:gap-2'],\n vertical: ['tw:flex-col', 'tw:gap-3'],\n },\n variant: {\n button: [],\n radio: [],\n 'radio-block': ['tw:w-full'],\n },\n },\n});\n\ntype Props<Value> = {\n variant?: Variant;\n orientation?: Orientation;\n onValueChange?: (value: Value) => void;\n value?: Value | null;\n defaultValue?: Value | null;\n} & Omit<\n ComponentProps<typeof RRadioGroup.Root>,\n 'asChild' | 'orientation' | 'onValueChange' | 'onChange' | 'value' | 'defaultValue'\n>;\n\nexport const RadioGroup = <Value extends string = string>({\n variant = 'radio',\n className,\n disabled = false,\n orientation = 'horizontal',\n onValueChange,\n children,\n value,\n defaultValue,\n ...props\n}: Props<Value>) => (\n <RRadioGroup.Root\n {...props}\n onValueChange={onValueChange}\n orientation={orientation}\n className={cn(radioGroupVariants({ orientation, variant, className }))}\n disabled={disabled}\n value={value ?? void 0}\n defaultValue={defaultValue ?? void 0}\n >\n <RadioGroupProvider value={{ variant, orientation }}>{children}</RadioGroupProvider>\n </RRadioGroup.Root>\n);\n\nRadioGroup.Item = RadioGroupItem;\nRadioGroup.Separator = RadioGroupSeparator;\n"],"mappings":";;;;;;;;;;;;AAKA,MAAM,oBAAoB,cAGvB;CACD,SAAS;CACT,aAAa;AACf,CAAC;AAED,MAAa,qBAAqB;AAElC,MAAa,6BAA6B,IAAI,iBAAiB;;ACP/D,MAAa,SAAS,EAAE,WAAW,GAAG,YACpC,oBAAC,MAAD;CAAM,GAAI;CAAO,WAAW,GAAG,oBAAoB,GAAG,cAAc,GAAG,SAAS;CAC9E,UAAA,oBAAC,WAAD;EAAW,WAAW,GAAG,WAAW,mBAAmB,mBAAmB;EAGxE,UAAA,oBAAC,QAAD,EAAQ,WAAW,uBAAuB,EAAI,CAAA;CACrC,CAAA;AACP,CAAA;;ACNR,MAAa,wBAAwB,EAAE,KAAK,WAAW,UAAU,GAAG,YAClE,oBAAC,MAAD;CAAW;CAAK,GAAI;CAAO,WAAW,GAAG,wBAAwB,GAAG,SAAS;CAC1E;AACG,CAAA;;ACWR,MAAa,kBAA6C,EACxD,UACA,WACA,SACA,gBACA,kBACA,aACA,GAAG,YACW;CACd,MAAM,EAAE,YAAY,qBAAqB;CACzC,MAAM,KAAK,MAAM;CAEjB,MAAM,cAAc;EAClB,IAAI,YAAY,UACd,OACE,oBAAC,sBAAD;GAAsB,GAAI;GAAkB;GACzC;EACmB,CAAA;EAG1B,OACE,qBAAC,UAAD;GACE,SAAS,YAAY,gBAAgB,UAAU;GAC/C,SAAS;GACT,SAAS,oBAAC,OAAD;IAAO,GAAI;IAAW;GAAK,CAAA;GACpC,WAAW,GAAG,YAAY,iBAAiB,aAAa,SAAS;GAJnE,UAAA,CAME,oBAAC,SAAS,OAAV,EAAiB,SAAyB,CAAA,GACzC,eAAe,oBAAC,SAAS,aAAV,EAAA,UAAuB,YAAkC,CAAA,CACjE;;CAEd,EAAA,CAAG;CAEH,IAAI,CAAC,SACH,OAAO;CAGT,OACE,oBAAC,SAAD;EAAkB;EAAS,SAAS;EAAgB,WAAW;EAAkB,gBAAA;EAC9E,UAAA;CACM,CAAA;AAEb;;AC7DA,MAAa,4BAA4B;CACvC,MAAM,EAAE,gBAAgB,qBAAqB;CAK7C,OAAO,oBAAC,WAAD;EAAW,aAJU,gBAAgB,eAAe,aAAa;EAIpB,MAHvC,gBAAgB,eAAe,QAAQ;EAGY,WAF9C,gBAAgB,eAAe,YAAY;CAE0B,CAAA;AACzF;;ACAA,MAAM,qBAAqB,IAAI,CAAC,SAAS,GAAG,EAC1C,UAAU;CACR,aAAa;EACX,YAAY,CAAC,UAAU;EACvB,UAAU,CAAC,eAAe,UAAU;CACtC;CACA,SAAS;EACP,QAAQ,CAAC;EACT,OAAO,CAAC;EACR,eAAe,CAAC,WAAW;CAC7B;AACF,EACF,CAAC;AAaD,MAAa,cAA6C,EACxD,UAAU,SACV,WACA,WAAW,OACX,cAAc,cACd,eACA,UACA,OACA,cACA,GAAG,YAEH,oBAAC,YAAY,MAAb;CACE,GAAI;CACW;CACF;CACb,WAAW,GAAG,mBAAmB;EAAE;EAAa;EAAS;CAAU,CAAC,CAAC;CAC3D;CACV,OAAO,SAAS,KAAK;CACrB,cAAc,gBAAgB,KAAK;CAEnC,UAAA,oBAAC,oBAAD;EAAoB,OAAO;GAAE;GAAS;EAAY;EAAI;CAA6B,CAAA;AACnE,CAAA;AAGpB,WAAW,OAAO;AAClB,WAAW,YAAY"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { cn } from "./classNames-
|
|
1
|
+
import { cn } from "./classNames-DkX30VJU.js";
|
|
2
2
|
import { cva } from "class-variance-authority";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { Group, Panel as ResizablePanel, Separator, useDefaultLayout } from "react-resizable-panels";
|
|
5
|
-
|
|
5
|
+
// src/components/Resizable/ResizableHandle.tsx
|
|
6
6
|
const resizableHandleVariants = cva([
|
|
7
7
|
"tw:bg-border",
|
|
8
8
|
"tw:relative",
|
|
@@ -37,8 +37,7 @@ const ResizableHandle = ({ className, ...props }) => {
|
|
|
37
37
|
...props
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
|
-
|
|
41
|
-
//#region src/components/Resizable/ResizablePanelGroup.tsx
|
|
40
|
+
// src/components/Resizable/ResizablePanelGroup.tsx
|
|
42
41
|
const ResizablePanelGroup = ({ className, orientation = "horizontal", ...props }) => {
|
|
43
42
|
return /* @__PURE__ */ jsx(Group, {
|
|
44
43
|
orientation,
|
|
@@ -46,7 +45,6 @@ const ResizablePanelGroup = ({ className, orientation = "horizontal", ...props }
|
|
|
46
45
|
...props
|
|
47
46
|
});
|
|
48
47
|
};
|
|
49
|
-
//#endregion
|
|
50
48
|
export { ResizableHandle, ResizablePanel, ResizablePanelGroup, useDefaultLayout };
|
|
51
49
|
|
|
52
|
-
//# sourceMappingURL=Resizable-
|
|
50
|
+
//# sourceMappingURL=Resizable-Co-L3qg7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Resizable-
|
|
1
|
+
{"version":3,"file":"Resizable-Co-L3qg7.js","names":[],"sources":["../src/components/Resizable/ResizableHandle.tsx","../src/components/Resizable/ResizablePanelGroup.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport { Separator } from 'react-resizable-panels';\nimport { cva } from 'class-variance-authority';\n\n// v4 renders the separator with `aria-orientation`: a separator between horizontally-arranged\n// panels is vertical (default here); one between vertically-stacked panels is horizontal.\nconst resizableHandleVariants = cva([\n // base styles\n 'tw:bg-border',\n 'tw:relative',\n 'tw:flex',\n 'tw:w-px',\n 'tw:items-center',\n 'tw:justify-center',\n\n // focus styles\n 'tw:focus-visible:ring-ring',\n 'tw:focus-visible:ring-1',\n 'tw:focus-visible:ring-offset-1',\n 'tw:focus-visible:ring-offset-ring-offset',\n 'tw:focus-visible:outline-hidden',\n\n // after pseudo-element for horizontal\n 'tw:after:absolute',\n 'tw:after:inset-y-0',\n 'tw:after:left-1/2',\n 'tw:after:w-1',\n 'tw:after:-translate-x-1/2',\n\n // horizontal separator (vertical panel group): center a full-width 4px hit target;\n // top-1/2 + bottom-auto override the base inset-y-0 so the height takes effect\n 'tw:aria-[orientation=horizontal]:h-px',\n 'tw:aria-[orientation=horizontal]:w-full',\n 'tw:aria-[orientation=horizontal]:after:left-0',\n 'tw:aria-[orientation=horizontal]:after:top-1/2',\n 'tw:aria-[orientation=horizontal]:after:bottom-auto',\n 'tw:aria-[orientation=horizontal]:after:h-1',\n 'tw:aria-[orientation=horizontal]:after:w-full',\n 'tw:aria-[orientation=horizontal]:after:translate-x-0',\n 'tw:aria-[orientation=horizontal]:after:-translate-y-1/2',\n\n // handle icon rotation for horizontal separator\n 'tw:[&[aria-orientation=horizontal]>div]:rotate-90',\n]);\n\nexport const ResizableHandle = ({ className, ...props }: ComponentProps<typeof Separator>) => {\n return <Separator className={resizableHandleVariants({ className })} {...props} />;\n};\n","import type { ComponentProps } from 'react';\nimport { Group } from 'react-resizable-panels';\n\nimport { cn } from '../../utils';\n\nexport { useDefaultLayout } from 'react-resizable-panels';\n\nexport const ResizablePanelGroup = ({\n className,\n orientation = 'horizontal',\n ...props\n}: ComponentProps<typeof Group>) => {\n return (\n <Group\n orientation={orientation}\n className={cn(\n 'tw:flex tw:h-full tw:w-full',\n orientation === 'vertical' && 'tw:flex-col',\n className,\n )}\n {...props}\n />\n );\n};\n"],"mappings":";;;;;AAMA,MAAM,0BAA0B,IAAI;CAElC;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CAIA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;AACF,CAAC;AAED,MAAa,mBAAmB,EAAE,WAAW,GAAG,YAA8C;CAC5F,OAAO,oBAAC,WAAD;EAAW,WAAW,wBAAwB,EAAE,UAAU,CAAC;EAAG,GAAI;CAAQ,CAAA;AACnF;;ACxCA,MAAa,uBAAuB,EAClC,WACA,cAAc,cACd,GAAG,YAC+B;CAClC,OACE,oBAAC,OAAD;EACe;EACb,WAAW,GACT,+BACA,gBAAgB,cAAc,eAC9B,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { cn } from "./classNames-
|
|
2
|
-
import { createPrefixedString, debounce, noop } from "./utils-
|
|
3
|
-
import { Search as Search$1, Sparkles, X } from "./icons-
|
|
4
|
-
import {
|
|
1
|
+
import { cn } from "./classNames-DkX30VJU.js";
|
|
2
|
+
import { createPrefixedString, debounce, noop } from "./utils-DjFceY3H.js";
|
|
3
|
+
import { Search as Search$1, Sparkles, X } from "./icons-DDR9dFSr.js";
|
|
4
|
+
import { useStableCallback } from "./internal/hooks/useStableCallback.js";
|
|
5
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
6
|
import { cva } from "class-variance-authority";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
|
|
8
|
+
// src/components/Search/ClearButton.tsx
|
|
8
9
|
const ClearButton = ({ onClick, testId }) => {
|
|
9
10
|
const handleMouseDown = (event) => {
|
|
10
11
|
event.preventDefault();
|
|
@@ -19,8 +20,7 @@ const ClearButton = ({ onClick, testId }) => {
|
|
|
19
20
|
children: /* @__PURE__ */ jsx(X, { className: "tw:size-4" })
|
|
20
21
|
});
|
|
21
22
|
};
|
|
22
|
-
|
|
23
|
-
//#region src/components/Search/styles.ts
|
|
23
|
+
// src/components/Search/styles.ts
|
|
24
24
|
const searchWrapperVariants = cva([
|
|
25
25
|
"tw:flex",
|
|
26
26
|
"tw:items-center",
|
|
@@ -80,8 +80,7 @@ const searchInputClassnames = [
|
|
|
80
80
|
"tw:placeholder:text-muted-foreground",
|
|
81
81
|
"tw:disabled:cursor-not-allowed"
|
|
82
82
|
].join(" ");
|
|
83
|
-
|
|
84
|
-
//#region src/components/Search/utils.ts
|
|
83
|
+
// src/components/Search/utils.ts
|
|
85
84
|
const genSearchTestId = (prefix = "") => {
|
|
86
85
|
const ps = createPrefixedString(prefix);
|
|
87
86
|
return {
|
|
@@ -91,8 +90,7 @@ const genSearchTestId = (prefix = "") => {
|
|
|
91
90
|
clearButton: ps`search-clear-button`
|
|
92
91
|
};
|
|
93
92
|
};
|
|
94
|
-
|
|
95
|
-
//#region src/components/Search/Search.tsx
|
|
93
|
+
// src/components/Search/Search.tsx
|
|
96
94
|
/**
|
|
97
95
|
* @deprecated Use `SearchInput` instead. `Search` is kept only for the legacy (non-sidebar) layout.
|
|
98
96
|
*/
|
|
@@ -100,19 +98,26 @@ const Search = ({ ref, suffix, className, onBlur, onChange = noop, disabled = fa
|
|
|
100
98
|
const [internalValue, setInternalValue] = useState(() => externalValue != null ? externalValue : defaultValue);
|
|
101
99
|
const isClearButtonVisible = internalValue !== "" && !disabled && !readOnly;
|
|
102
100
|
const testId = genSearchTestId(prefixTestId);
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
onChange
|
|
107
|
-
|
|
101
|
+
const debounceInFlightRef = useRef(false);
|
|
102
|
+
const handleDebouncedChange = useStableCallback((value, event) => {
|
|
103
|
+
debounceInFlightRef.current = false;
|
|
104
|
+
onChange(value, event);
|
|
105
|
+
});
|
|
106
|
+
const debouncedOnChange = useMemo(() => debounce(handleDebouncedChange, debounceDelay), [handleDebouncedChange, debounceDelay]);
|
|
107
|
+
useEffect(() => () => debouncedOnChange.cancel(), [debouncedOnChange]);
|
|
108
108
|
useEffect(() => {
|
|
109
109
|
if (externalValue == null) return;
|
|
110
|
+
if (debounceInFlightRef.current) return;
|
|
110
111
|
setInternalValue(externalValue);
|
|
111
112
|
}, [externalValue]);
|
|
112
113
|
const handleChange = (event) => {
|
|
113
114
|
const currentValue = event.target.value;
|
|
114
115
|
setInternalValue(currentValue);
|
|
115
|
-
|
|
116
|
+
if (disableDebounce) onChange(currentValue, event);
|
|
117
|
+
else {
|
|
118
|
+
debounceInFlightRef.current = true;
|
|
119
|
+
debouncedOnChange(currentValue, event);
|
|
120
|
+
}
|
|
116
121
|
};
|
|
117
122
|
const handleBlur = (event) => {
|
|
118
123
|
const currentValue = event.target.value;
|
|
@@ -120,6 +125,8 @@ const Search = ({ ref, suffix, className, onBlur, onChange = noop, disabled = fa
|
|
|
120
125
|
onBlur?.(currentValue, event);
|
|
121
126
|
};
|
|
122
127
|
const handleClear = (event) => {
|
|
128
|
+
debouncedOnChange.cancel();
|
|
129
|
+
debounceInFlightRef.current = false;
|
|
123
130
|
setInternalValue("");
|
|
124
131
|
onChange?.("", event);
|
|
125
132
|
onClear?.();
|
|
@@ -157,8 +164,7 @@ const Search = ({ ref, suffix, className, onBlur, onChange = noop, disabled = fa
|
|
|
157
164
|
]
|
|
158
165
|
});
|
|
159
166
|
};
|
|
160
|
-
|
|
161
|
-
//#region src/components/Search/SearchForm.tsx
|
|
167
|
+
// src/components/Search/SearchForm.tsx
|
|
162
168
|
const SearchForm = ({ ref, onSubmit, name = "search-field", ...props }) => {
|
|
163
169
|
const handleSubmit = (event) => {
|
|
164
170
|
event.preventDefault();
|
|
@@ -178,7 +184,6 @@ const SearchForm = ({ ref, onSubmit, name = "search-field", ...props }) => {
|
|
|
178
184
|
})
|
|
179
185
|
});
|
|
180
186
|
};
|
|
181
|
-
//#endregion
|
|
182
187
|
export { Search, SearchForm };
|
|
183
188
|
|
|
184
|
-
//# sourceMappingURL=Search-
|
|
189
|
+
//# sourceMappingURL=Search-OgaNjqQM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Search-OgaNjqQM.js","names":["SearchIcon"],"sources":["../src/components/Search/ClearButton.tsx","../src/components/Search/styles.ts","../src/components/Search/utils.ts","../src/components/Search/Search.tsx","../src/components/Search/SearchForm.tsx"],"sourcesContent":["import type { MouseEventHandler } from 'react';\n\nimport { X } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = {\n onClick: MouseEventHandler<HTMLButtonElement>;\n testId?: string;\n};\n\nexport const ClearButton = ({ onClick, testId }: Props) => {\n // Prevent default, as we do not want to lose input focus.\n const handleMouseDown: MouseEventHandler<HTMLButtonElement> = (event) => {\n event.preventDefault();\n };\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n tabIndex={-1} // clear button should not be focusable\n onMouseDown={handleMouseDown}\n className={cn(\n // reset\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:p-0',\n\n // positioning\n 'tw:flex',\n 'tw:items-center',\n\n 'tw:cursor-pointer',\n 'tw:text-muted-foreground',\n 'tw:hover:text-foreground',\n )}\n data-testid={testId}\n >\n <X className=\"tw:size-4\" />\n </button>\n );\n};\n","import { cva } from 'class-variance-authority';\n\nexport const searchWrapperVariants = cva(\n [\n // positioning\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2.5',\n\n // base\n 'tw:text-card-foreground',\n 'tw:transition-all',\n 'tw:font-sans',\n\n // readonly — `secondary` over `muted`, which is too close to the `card` fill to\n // read as non-editable in either scheme\n 'tw:has-[input[readonly]]:bg-secondary',\n 'tw:has-[input[readonly]]:focus-within:ring-0',\n 'tw:has-[input[readonly]]:outline-0',\n\n // disabled\n 'tw:disabled:opacity-40',\n\n // default input padding (was sizing.default)\n 'tw:[&>input]:py-[15px]',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: [\n 'tw:rounded-lg',\n 'tw:px-5',\n 'tw:bg-card',\n 'tw:shadow-raised',\n // outline\n 'tw:outline',\n 'tw:outline-1',\n 'tw:outline-transparent',\n // focus\n 'tw:has-[input:focus]:outline-1',\n 'tw:has-[input:focus]:ring-4',\n 'tw:has-[input:focus]:outline-ring',\n 'tw:has-[input:focus]:ring-ring/30',\n ],\n ai: [\n 'tailwindcss-preflight',\n 'tw:relative',\n 'tw:rounded-card',\n 'tw:px-4',\n 'tw:cursor-text',\n 'tw:border-2',\n 'tw:border-transparent',\n 'tw:bg-gradient-to-br',\n 'tw:from-secondary-600',\n 'tw:to-purple-600',\n 'tw:bg-origin-border',\n // Floods the interior so the gradient shows only in the 2px border box.\n 'tw:shadow-[inset_0_100vw_rgb(var(--card))]',\n // focus\n 'tw:has-[input:focus]:ring-4',\n 'tw:has-[input:focus]:ring-ring/30',\n ],\n },\n },\n },\n);\n\nexport const searchInputClassnames = [\n // reset\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:outline-hidden',\n 'tw:w-full',\n 'tw:p-0',\n\n // base\n 'tw:text-base',\n 'tw:leading-6',\n 'tw:font-normal',\n 'tw:font-sans',\n\n // placeholder\n 'tw:placeholder:text-muted-foreground',\n\n // disabled\n 'tw:disabled:cursor-not-allowed',\n].join(' ');\n","import { createPrefixedString } from '../../utils';\n\nexport const genSearchTestId = (prefix: string = '') => {\n const ps = createPrefixedString(prefix);\n return {\n toString: () => prefix,\n wrapper: ps`search-wrapper`,\n input: ps`search-input`,\n clearButton: ps`search-clear-button`,\n };\n};\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n ChangeEvent,\n ChangeEventHandler,\n ComponentProps,\n FocusEvent,\n FocusEventHandler,\n MouseEvent,\n MouseEventHandler,\n ReactNode,\n} from 'react';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { Search as SearchIcon, Sparkles } from '../../icons';\nimport { cn, debounce, noop } from '../../utils';\n\nimport { ClearButton } from './ClearButton';\nimport { searchInputClassnames, searchWrapperVariants } from './styles';\nimport { genSearchTestId } from './utils';\n\ntype SearchChangeEventHandler = (\n value: string,\n event: ChangeEvent<HTMLInputElement> | MouseEvent<HTMLButtonElement>,\n) => void;\n\ntype SearchBlurEventHandler = (value: string, event: FocusEvent<HTMLInputElement, Element>) => void;\n\ntype Props = {\n suffix?: ReactNode;\n disableDebounce?: boolean;\n debounceDelay?: number;\n onChange?: SearchChangeEventHandler;\n onBlur?: SearchBlurEventHandler;\n value?: string | null;\n defaultValue?: string | null;\n testId?: string;\n onClear?: () => void;\n variant?: 'default' | 'ai';\n} & Omit<\n ComponentProps<'input'>,\n 'type' | 'onBlur' | 'onChange' | 'value' | 'defaultValue' | 'prefix' | 'suffix'\n>;\n\n/**\n * @deprecated Use `SearchInput` instead. `Search` is kept only for the legacy (non-sidebar) layout.\n */\nexport const Search = ({\n ref,\n suffix,\n className,\n onBlur,\n onChange = noop,\n disabled = false,\n readOnly = false,\n disableDebounce = false,\n debounceDelay = 300,\n value: externalValue,\n defaultValue,\n testId: prefixTestId = '',\n placeholder = 'Search',\n onClear,\n variant = 'default',\n ...rest\n}: Props) => {\n const [internalValue, setInternalValue] = useState(() =>\n externalValue != null ? externalValue : defaultValue,\n );\n const hasValue = internalValue !== '';\n\n const isClearButtonVisible = hasValue && !disabled && !readOnly;\n const testId = genSearchTestId(prefixTestId);\n\n // A pending debounced call; the controlled-value sync skips while set so typed characters survive.\n const debounceInFlightRef = useRef(false);\n\n // Stable, so a new `onChange` never recreates the debounce and strands a pending call.\n const handleDebouncedChange = useStableCallback(\n (value: string, event: ChangeEvent<HTMLInputElement>) => {\n debounceInFlightRef.current = false;\n onChange(value, event);\n },\n );\n\n const debouncedOnChange = useMemo(\n () => debounce(handleDebouncedChange, debounceDelay),\n [handleDebouncedChange, debounceDelay],\n );\n\n useEffect(() => () => debouncedOnChange.cancel(), [debouncedOnChange]);\n\n // Skipped while a debounced call is in flight, so the input doesn't snap back mid-typing.\n useEffect(() => {\n if (externalValue == null) return; // uncontrolled state\n if (debounceInFlightRef.current) return;\n // oxlint-disable-next-line react-x/set-state-in-effect\n setInternalValue(externalValue);\n }, [externalValue]);\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const currentValue = event.target.value;\n setInternalValue(currentValue);\n if (disableDebounce) {\n onChange(currentValue, event);\n } else {\n debounceInFlightRef.current = true;\n debouncedOnChange(currentValue, event);\n }\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n const currentValue = event.target.value;\n setInternalValue(currentValue);\n onBlur?.(currentValue, event);\n };\n\n const handleClear: MouseEventHandler<HTMLButtonElement> = (event) => {\n debouncedOnChange.cancel();\n debounceInFlightRef.current = false;\n setInternalValue('');\n onChange?.('', event);\n onClear?.();\n };\n\n // Clicking anywhere in the field that isn't an interactive control (the leading icon,\n // the empty chrome) focuses the input — the whole pill acts as one click target.\n const handleWrapperMouseDown: MouseEventHandler<HTMLDivElement> = (event) => {\n if (disabled || readOnly) return;\n if ((event.target as HTMLElement).closest('button, a, input, textarea, [role=\"button\"]')) {\n return;\n }\n event.preventDefault();\n event.currentTarget.querySelector('input')?.focus();\n };\n\n return (\n // Mouse-only convenience: clicking the chrome focuses the input. The input itself is the\n // real interactive/focusable target, so no extra role or key handler is needed here.\n // oxlint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n className={cn(\n searchWrapperVariants({ variant }),\n {\n 'tw:cursor-not-allowed tw:opacity-40': disabled,\n },\n className,\n )}\n data-testid={testId.wrapper}\n onMouseDown={handleWrapperMouseDown}\n >\n {variant === 'ai' ? (\n <Sparkles className=\"tw:size-4 tw:shrink-0 tw:[&_*]:stroke-aigradient-600\" />\n ) : (\n <SearchIcon className=\"tw:size-4 tw:shrink-0 tw:text-muted-foreground\" />\n )}\n\n <input\n {...rest}\n ref={ref}\n placeholder={placeholder}\n data-testid={testId.input}\n type=\"text\"\n value={internalValue ?? ''}\n onChange={handleChange}\n onBlur={handleBlur}\n className={searchInputClassnames}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {isClearButtonVisible && <ClearButton onClick={handleClear} testId={testId.clearButton} />}\n\n {suffix}\n </div>\n );\n};\n","import type { ComponentProps, FormEventHandler } from 'react';\n\nimport { Search } from './Search';\n\ntype Props = {\n onSubmit: (value: string) => void;\n} & Omit<ComponentProps<typeof Search>, 'onClear' | 'onBlur' | 'onSubmit'>;\n\nexport const SearchForm = ({ ref, onSubmit, name = 'search-field', ...props }: Props) => {\n const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {\n event.preventDefault();\n const searchEl = event.currentTarget.elements.namedItem(name) as HTMLInputElement;\n onSubmit(searchEl.value);\n };\n\n const onClear = () => {\n onSubmit('');\n };\n\n return (\n <form onSubmit={handleSubmit}>\n <Search\n {...props}\n ref={ref}\n onClear={onClear}\n name={name}\n // Debounce has no meaning when we use submit, which is triggered by pressing enter.\n disableDebounce\n />\n </form>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { debounce } from "./utils-
|
|
2
|
-
import { Search, X } from "./icons-
|
|
3
|
-
import {
|
|
1
|
+
import { debounce } from "./utils-DjFceY3H.js";
|
|
2
|
+
import { Search, X } from "./icons-DDR9dFSr.js";
|
|
3
|
+
import { useStableCallback } from "./internal/hooks/useStableCallback.js";
|
|
4
|
+
import { InputGroup } from "./InputGroup-BWeanEo7.js";
|
|
4
5
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
|
|
7
|
+
// src/blocks/SearchInput/SearchInput.tsx
|
|
7
8
|
/**
|
|
8
9
|
* Debounced search input with a search icon and optional clear button.
|
|
9
10
|
*
|
|
@@ -15,26 +16,12 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
15
16
|
const SearchInput = ({ ref, state, focusVariant, className, value: valueProp, defaultValue, onValueChange, onValueBlur, onChange, onBlur, onClear, allowClear = false, disableDebounce = false, debounceDelay = 300, disabled, readOnly, ...restInputProps }) => {
|
|
16
17
|
const [internalValue, setInternalValue] = useState(valueProp != null ? valueProp : defaultValue ?? "");
|
|
17
18
|
const debounceInFlightRef = useRef(false);
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const d = debounce((val) => {
|
|
25
|
-
debounceInFlightRef.current = false;
|
|
26
|
-
onValueChange(val);
|
|
27
|
-
}, debounceDelay);
|
|
28
|
-
cancelRef.current = d.cancel;
|
|
29
|
-
return d;
|
|
30
|
-
}, [
|
|
31
|
-
onValueChange,
|
|
32
|
-
disableDebounce,
|
|
33
|
-
debounceDelay
|
|
34
|
-
]);
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
return () => cancelRef.current();
|
|
37
|
-
}, [debouncedOnValueChange]);
|
|
19
|
+
const handleDebouncedValueChange = useStableCallback((val) => {
|
|
20
|
+
debounceInFlightRef.current = false;
|
|
21
|
+
onValueChange?.(val);
|
|
22
|
+
});
|
|
23
|
+
const debouncedOnValueChange = useMemo(() => debounce(handleDebouncedValueChange, debounceDelay), [handleDebouncedValueChange, debounceDelay]);
|
|
24
|
+
useEffect(() => () => debouncedOnValueChange.cancel(), [debouncedOnValueChange]);
|
|
38
25
|
useEffect(() => {
|
|
39
26
|
if (valueProp == null) return;
|
|
40
27
|
if (debounceInFlightRef.current) return;
|
|
@@ -44,8 +31,11 @@ const SearchInput = ({ ref, state, focusVariant, className, value: valueProp, de
|
|
|
44
31
|
const handleChange = (event) => {
|
|
45
32
|
const val = event.target.value;
|
|
46
33
|
setInternalValue(val);
|
|
47
|
-
if (
|
|
48
|
-
|
|
34
|
+
if (disableDebounce) onValueChange?.(val);
|
|
35
|
+
else if (onValueChange) {
|
|
36
|
+
debounceInFlightRef.current = true;
|
|
37
|
+
debouncedOnValueChange(val);
|
|
38
|
+
}
|
|
49
39
|
onChange?.(event);
|
|
50
40
|
};
|
|
51
41
|
const handleBlur = (event) => {
|
|
@@ -53,7 +43,7 @@ const SearchInput = ({ ref, state, focusVariant, className, value: valueProp, de
|
|
|
53
43
|
onBlur?.(event);
|
|
54
44
|
};
|
|
55
45
|
const handleClear = () => {
|
|
56
|
-
|
|
46
|
+
debouncedOnValueChange.cancel();
|
|
57
47
|
debounceInFlightRef.current = false;
|
|
58
48
|
setInternalValue("");
|
|
59
49
|
onValueChange?.("");
|
|
@@ -89,7 +79,6 @@ const SearchInput = ({ ref, state, focusVariant, className, value: valueProp, de
|
|
|
89
79
|
]
|
|
90
80
|
});
|
|
91
81
|
};
|
|
92
|
-
//#endregion
|
|
93
82
|
export { SearchInput };
|
|
94
83
|
|
|
95
|
-
//# sourceMappingURL=SearchInput-
|
|
84
|
+
//# sourceMappingURL=SearchInput-eLS-uvOn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchInput-eLS-uvOn.js","names":[],"sources":["../src/blocks/SearchInput/SearchInput.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { ChangeEventHandler, ComponentProps, FocusEventHandler } from 'react';\n\nimport { InputGroup } from '../../components/InputGroup';\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { Search, X } from '../../icons';\nimport { debounce } from '../../utils';\n\ntype InputGroupProps = Pick<ComponentProps<typeof InputGroup>, 'focusVariant' | 'state'>;\n\ntype InputGroupInputProps = Omit<ComponentProps<typeof InputGroup.Input>, 'value' | 'defaultValue'>;\n\n/**\n * - `onValueChange` is debounced by default (300ms).\n * - `value={null}` / `undefined` is uncontrolled (falls back to `defaultValue`, else empty).\n * - `value={\"\"}` is controlled-empty.\n */\ntype Props = InputGroupProps &\n InputGroupInputProps & {\n value?: string | null;\n defaultValue?: string | null;\n /** Debounced; fires at once on clear and with `disableDebounce`. Use `onChange` per keystroke. */\n onValueChange?: (value: string) => void;\n /** Called with the value on blur. */\n onValueBlur?: (value: string) => void;\n onClear?: () => void;\n /** Shows the clear (x) button while the value is non-empty. */\n allowClear?: boolean;\n /** `onValueChange` fires on every keystroke. */\n disableDebounce?: boolean;\n /** In ms, default 300; ignored with `disableDebounce`. */\n debounceDelay?: number;\n };\n\n/**\n * Debounced search input with a search icon and optional clear button.\n *\n * - Use for list / table search and free-text filters, e.g. in `PageToolbar.Search`.\n * - Not for plain text (`TextInput`) or picking from a known list (`Combobox`).\n *\n * @see RECIPES.md#filter-toolbar\n */\nexport const SearchInput = ({\n ref,\n\n // group props\n state,\n focusVariant,\n className,\n\n // own props\n value: valueProp,\n defaultValue,\n onValueChange,\n onValueBlur,\n onChange,\n onBlur,\n onClear,\n allowClear = false,\n disableDebounce = false,\n debounceDelay = 300,\n\n // input props\n disabled,\n readOnly,\n ...restInputProps\n}: Props) => {\n const [internalValue, setInternalValue] = useState<string>(\n valueProp != null ? valueProp : (defaultValue ?? ''),\n );\n\n // A pending debounced call; the controlled-value sync skips while set so typed characters survive.\n const debounceInFlightRef = useRef(false);\n\n // Stable, so a new `onValueChange` never recreates the debounce and strands a pending call.\n const handleDebouncedValueChange = useStableCallback((val: string) => {\n debounceInFlightRef.current = false;\n onValueChange?.(val);\n });\n\n const debouncedOnValueChange = useMemo(\n () => debounce(handleDebouncedValueChange, debounceDelay),\n [handleDebouncedValueChange, debounceDelay],\n );\n\n useEffect(() => () => debouncedOnValueChange.cancel(), [debouncedOnValueChange]);\n\n // Skipped while a debounced call is in flight, so the input doesn't snap back mid-typing.\n useEffect(() => {\n if (valueProp == null) return;\n if (debounceInFlightRef.current) return;\n setInternalValue(valueProp);\n }, [valueProp]);\n\n const canClear = allowClear && !!internalValue && !disabled && !readOnly;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const val = event.target.value;\n setInternalValue(val);\n if (disableDebounce) {\n onValueChange?.(val);\n } else if (onValueChange) {\n debounceInFlightRef.current = true;\n debouncedOnValueChange(val);\n }\n onChange?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n onValueBlur?.(event.target.value);\n onBlur?.(event);\n };\n\n const handleClear = () => {\n debouncedOnValueChange.cancel();\n debounceInFlightRef.current = false;\n setInternalValue('');\n onValueChange?.('');\n onClear?.();\n };\n\n return (\n <InputGroup state={state} focusVariant={focusVariant} className={className}>\n <InputGroup.Addon align=\"inline-start\">\n <Search className=\"tw:size-4 tw:shrink-0 tw:text-muted-foreground\" />\n </InputGroup.Addon>\n\n <InputGroup.Input\n {...restInputProps}\n ref={ref}\n value={internalValue}\n onChange={handleChange}\n onBlur={handleBlur}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {canClear && (\n <InputGroup.Addon align=\"inline-end\">\n <InputGroup.Button\n aria-label=\"Clear search\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AA0CA,MAAa,eAAe,EAC1B,KAGA,OACA,cACA,WAGA,OAAO,WACP,cACA,eACA,aACA,UACA,QACA,SACA,aAAa,OACb,kBAAkB,OAClB,gBAAgB,KAGhB,UACA,UACA,GAAG,qBACQ;CACX,MAAM,CAAC,eAAe,oBAAoB,SACxC,aAAa,OAAO,YAAa,gBAAgB,EACnD;CAGA,MAAM,sBAAsB,OAAO,KAAK;CAGxC,MAAM,6BAA6B,mBAAmB,QAAgB;EACpE,oBAAoB,UAAU;EAC9B,gBAAgB,GAAG;CACrB,CAAC;CAED,MAAM,yBAAyB,cACvB,SAAS,4BAA4B,aAAa,GACxD,CAAC,4BAA4B,aAAa,CAC5C;CAEA,sBAAsB,uBAAuB,OAAO,GAAG,CAAC,sBAAsB,CAAC;CAG/E,gBAAgB;EACd,IAAI,aAAa,MAAM;EACvB,IAAI,oBAAoB,SAAS;EACjC,iBAAiB,SAAS;CAC5B,GAAG,CAAC,SAAS,CAAC;CAEd,MAAM,WAAW,cAAc,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC;CAEhE,MAAM,gBAAsD,UAAU;EACpE,MAAM,MAAM,MAAM,OAAO;EACzB,iBAAiB,GAAG;EACpB,IAAI,iBACF,gBAAgB,GAAG;OACd,IAAI,eAAe;GACxB,oBAAoB,UAAU;GAC9B,uBAAuB,GAAG;EAC5B;EACA,WAAW,KAAK;CAClB;CAEA,MAAM,cAAmD,UAAU;EACjE,cAAc,MAAM,OAAO,KAAK;EAChC,SAAS,KAAK;CAChB;CAEA,MAAM,oBAAoB;EACxB,uBAAuB,OAAO;EAC9B,oBAAoB,UAAU;EAC9B,iBAAiB,EAAE;EACnB,gBAAgB,EAAE;EAClB,UAAU;CACZ;CAEA,OACE,qBAAC,YAAD;EAAmB;EAAqB;EAAyB;EAAjE,UAAA;GACE,oBAAC,WAAW,OAAZ;IAAkB,OAAM;IACtB,UAAA,oBAAC,QAAD,EAAQ,WAAU,iDAAkD,CAAA;GACpD,CAAA;GAElB,oBAAC,WAAW,OAAZ;IACE,GAAI;IACC;IACL,OAAO;IACP,UAAU;IACV,QAAQ;IACE;IACA;GACX,CAAA;GAEA,YACC,oBAAC,WAAW,OAAZ;IAAkB,OAAM;IACtB,UAAA,oBAAC,WAAW,QAAZ;KACE,cAAW;KACX,cAAc,UAAU,MAAM,eAAe;KAC7C,SAAS;KAET,UAAA,oBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;IACT,CAAA;GACH,CAAA;EAEV;;AAEhB"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { cn } from "./classNames-
|
|
2
|
-
import { noop } from "./utils-
|
|
3
|
-
import { ChevronDown } from "./icons-
|
|
4
|
-
import { Button } from "./Button-
|
|
5
|
-
import { DropdownMenu } from "./DropdownMenu-
|
|
6
|
-
import { Badge } from "./Badge-
|
|
7
|
-
import { Collapsible } from "./Collapsible-
|
|
1
|
+
import { cn } from "./classNames-DkX30VJU.js";
|
|
2
|
+
import { noop } from "./utils-DjFceY3H.js";
|
|
3
|
+
import { ChevronDown } from "./icons-DDR9dFSr.js";
|
|
4
|
+
import { Button } from "./Button-DbvGzEDb.js";
|
|
5
|
+
import { DropdownMenu } from "./DropdownMenu-Ba9atqDa.js";
|
|
6
|
+
import { Badge } from "./Badge-CFRhducL.js";
|
|
7
|
+
import { Collapsible } from "./Collapsible-zsXk4Vpp.js";
|
|
8
8
|
import { useState } from "react";
|
|
9
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
-
|
|
10
|
+
// src/blocks/SectionNav/SectionNavItemContent.tsx
|
|
11
11
|
/** One row's body, shared by the tree and the collapsed dropdown. */
|
|
12
12
|
const SectionNavItemContent = ({ item, active, showDescription = false, expanded, showIcon = true }) => {
|
|
13
13
|
const Icon = item.icon;
|
|
@@ -35,8 +35,7 @@ const SectionNavItemContent = ({ item, active, showDescription = false, expanded
|
|
|
35
35
|
})]
|
|
36
36
|
});
|
|
37
37
|
};
|
|
38
|
-
|
|
39
|
-
//#region src/blocks/SectionNav/SectionNavGroupRow.tsx
|
|
38
|
+
// src/blocks/SectionNav/SectionNavGroupRow.tsx
|
|
40
39
|
/**
|
|
41
40
|
* The ring is **inset**, not an outline. A row is exactly as wide as the nav column, and
|
|
42
41
|
* `PageLayout.Content nav` makes that column a scroll container (`overflow-y-auto`, which forces
|
|
@@ -114,8 +113,7 @@ const SectionNavGroupRow = ({ group, activeId, renderItem, showDescriptions }) =
|
|
|
114
113
|
}) })]
|
|
115
114
|
});
|
|
116
115
|
};
|
|
117
|
-
|
|
118
|
-
//#region src/blocks/SectionNav/SectionNav.tsx
|
|
116
|
+
// src/blocks/SectionNav/SectionNav.tsx
|
|
119
117
|
/**
|
|
120
118
|
* One page's grouped section nav: a tree when wide, a dropdown when narrow, both rendered via `renderItem`.
|
|
121
119
|
*
|
|
@@ -238,7 +236,6 @@ const SectionNav = ({ groups, activeId, renderItem, showDescriptions = false, la
|
|
|
238
236
|
})] })
|
|
239
237
|
})] });
|
|
240
238
|
};
|
|
241
|
-
//#endregion
|
|
242
239
|
export { SectionNav };
|
|
243
240
|
|
|
244
|
-
//# sourceMappingURL=SectionNav-
|
|
241
|
+
//# sourceMappingURL=SectionNav-L81iJBo3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav-tLK3iF6c.js","names":[],"sources":["../src/blocks/SectionNav/SectionNavItemContent.tsx","../src/blocks/SectionNav/SectionNavGroupRow.tsx","../src/blocks/SectionNav/SectionNav.tsx"],"sourcesContent":["import { Badge } from '../../components/Badge';\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\n\nimport type { SectionNavItem } from './types';\n\ntype Props = {\n item: SectionNavItem;\n active: boolean;\n showDescription?: boolean;\n /** Group rows only — renders the chevron. */\n expanded?: boolean;\n /** `false` on sub-section rows: the group's icon covers them; `icon` stays for flattened surfaces. */\n showIcon?: boolean;\n};\n\n/** One row's body, shared by the tree and the collapsed dropdown. */\nexport const SectionNavItemContent = ({\n item,\n active,\n showDescription = false,\n expanded,\n showIcon = true,\n}: Props) => {\n const Icon = item.icon;\n\n return (\n <span className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-0.5\">\n <span className=\"tw:flex tw:items-center tw:gap-2\">\n {showIcon && Icon && <Icon className=\"tw:size-4 tw:shrink-0\" />}\n <span\n className={cn(\n 'tw:flex-1 tw:truncate tw:text-sm',\n active ? 'tw:font-medium tw:text-selected-foreground' : 'tw:text-foreground',\n )}\n >\n {item.title}\n </span>\n {item.isNew && (\n <Badge\n color=\"blue-inverse\"\n className=\"tw:min-h-0 tw:text-[10px]\"\n labelClassName=\"tw:px-1.5 tw:py-0\"\n >\n New\n </Badge>\n )}\n {expanded !== undefined && (\n <ChevronDown\n className={cn(\n 'tw:size-4 tw:shrink-0 tw:text-muted-foreground tw:transition-transform tw:duration-200',\n expanded && 'tw:rotate-180',\n )}\n />\n )}\n </span>\n {/* Wraps, and breaks unbreakable tokens that would overflow the 256px column. */}\n {showDescription && item.description && (\n <span className=\"tw:text-xs tw:break-words tw:text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n );\n};\n","import { useState } from 'react';\nimport type { MouseEvent, ReactNode } from 'react';\n\nimport { Collapsible } from '../../components/Collapsible';\nimport { cn, noop } from '../../utils';\n\nimport { SectionNavItemContent } from './SectionNavItemContent';\nimport type { SectionNavGroup, SectionNavItemRenderProps } from './types';\n\ntype Props = {\n group: SectionNavGroup;\n activeId: string | undefined;\n renderItem: (props: SectionNavItemRenderProps) => ReactNode;\n showDescriptions: boolean;\n};\n\n/**\n * The ring is **inset**, not an outline. A row is exactly as wide as the nav column, and\n * `PageLayout.Content nav` makes that column a scroll container (`overflow-y-auto`, which forces\n * `overflow-x` to `auto` too) — so there is 0px of slack for anything painted outside the border\n * box, and the browser's default `outline-offset: 1px` ring gets clipped on both edges. Painting\n * inside the box cannot be clipped, at any column width, by any ancestor.\n */\nconst FOCUS_RING =\n 'tw:focus-visible:outline-hidden tw:focus-visible:ring-2 tw:focus-visible:ring-inset tw:focus-visible:ring-ring';\n\nconst rowClass = (active: boolean) =>\n cn(\n 'tw:flex tw:w-full tw:cursor-pointer tw:items-center tw:gap-2 tw:rounded-md tw:border-none tw:px-3 tw:py-2 tw:text-left tw:text-sm tw:no-underline tw:transition-colors',\n FOCUS_RING,\n active\n ? 'tw:bg-selected tw:font-medium tw:text-selected-foreground'\n : 'tw:bg-transparent tw:text-foreground tw:hover:bg-[var(--hover,rgb(var(--muted)))]',\n );\n\nconst childRowClass = (active: boolean) =>\n cn(\n 'tw:flex tw:w-full tw:cursor-pointer tw:rounded-md tw:border-none tw:px-3 tw:py-1.5 tw:text-left tw:no-underline tw:transition-colors',\n FOCUS_RING,\n active ? 'tw:bg-selected' : 'tw:bg-transparent tw:hover:bg-[var(--hover,rgb(var(--muted)))]',\n );\n\n/**\n * One group row and its sub-sections. The row is a single control: it opens the group **and** goes to\n * its first section, and only collapses once you are already there — so the chevron never becomes a\n * separate thing to aim at, and one click always makes progress.\n */\nexport const SectionNavGroupRow = ({ group, activeId, renderItem, showDescriptions }: Props) => {\n // Open on arrival: the nav is short enough that hiding any of it costs more than it saves.\n const [open, setOpen] = useState(true);\n\n const hasChildren = group.children.length > 0;\n const targetId = group.children[0]?.id ?? group.id;\n const isCurrent = group.id === activeId;\n const holdsCurrent = isCurrent || group.children.some((child) => child.id === activeId);\n\n const onClick = (event: MouseEvent<HTMLElement>) => {\n if (!hasChildren) return;\n\n // Already on the row's target, so navigating would be a no-op and the only thing left for the\n // click to do is toggle. `preventDefault` is what tells the caller's link not to navigate.\n if (activeId === targetId) {\n event.preventDefault();\n setOpen((isOpen) => !isOpen);\n\n return;\n }\n\n setOpen(true);\n };\n\n return (\n <Collapsible open={open} onOpenChange={setOpen} className=\"tw:flex tw:flex-col tw:gap-0.5\">\n {renderItem({\n targetId,\n isActive: isCurrent,\n children: (\n <SectionNavItemContent\n item={group}\n active={holdsCurrent}\n expanded={hasChildren ? open : undefined}\n />\n ),\n itemProps: {\n className: rowClass(holdsCurrent),\n 'aria-current': isCurrent ? 'page' : undefined,\n 'aria-expanded': hasChildren ? open : undefined,\n 'data-active': holdsCurrent && !isCurrent ? true : undefined,\n onClick,\n },\n })}\n\n {hasChildren && (\n <Collapsible.Content>\n {/* `pl-1` keeps each row's background box off the group's rule — without it an active\n row's `bg-selected` sits flush against the line. 4px is also what lines the child titles\n (20 + 1 + 4 + 12 = 37px) up with the parent's, which its icon puts at 12 + 16 + 8 = 36px. */}\n {/* `my-0 mr-0` and not `m-0`: a host app emits its own `.tw\\:m-0` from its own source, and\n its stylesheet is the later one — shorthand and longhand at equal specificity means the\n app's `m-0` would land after this `ml-5` and flatten the indent. Longhands only, so\n nothing here can be overridden by a copy of a class this block also uses. */}\n <ul className=\"tw:my-0 tw:mr-0 tw:ml-5 tw:flex tw:list-none tw:flex-col tw:gap-0.5 tw:border-l tw:border-border tw:py-0.5 tw:pl-1\">\n {group.children.map((child) => {\n const active = child.id === activeId;\n\n return (\n <li key={child.id}>\n {renderItem({\n targetId: child.id,\n isActive: active,\n children: (\n <SectionNavItemContent\n item={child}\n active={active}\n showDescription={showDescriptions}\n showIcon={false}\n />\n ),\n itemProps: {\n className: childRowClass(active),\n 'aria-current': active ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </li>\n );\n })}\n {group.note && (\n <li className=\"tw:py-1 tw:pl-3 tw:text-xs tw:text-muted-foreground\">{group.note}</li>\n )}\n </ul>\n </Collapsible.Content>\n )}\n </Collapsible>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { DropdownMenu } from '../../components/DropdownMenu';\nimport { ChevronDown } from '../../icons';\nimport { cn, noop } from '../../utils';\n\nimport { SectionNavGroupRow } from './SectionNavGroupRow';\nimport { SectionNavItemContent } from './SectionNavItemContent';\nimport type { SectionNavGroup, SectionNavItemRenderProps } from './types';\n\ntype Props = {\n /** Already filtered: visibility, permissions and flags stay in the app; rendered as given. */\n groups: SectionNavGroup[];\n /** `id` of the current section: a child's, or a childless group's. */\n activeId?: string;\n /** Return a router link / `<a>` to `targetId` with `itemProps` spread on it. */\n renderItem: (props: SectionNavItemRenderProps) => ReactNode;\n /** Show each section's `description` under its title. */\n showDescriptions?: boolean;\n /** Accessible name for the tree's `<nav>`, and the collapsed label with nothing active. */\n label?: string;\n /** Applied to the tree's `<nav>`; the column geometry belongs to `PageLayout.Content nav`. */\n className?: string;\n};\n\n/**\n * One page's grouped section nav: a tree when wide, a dropdown when narrow, both rendered via `renderItem`.\n *\n * - Not `Sidebar` (the app-level rail); this lives in `PageLayout.Content` and owns no global state.\n * - The switch is a container query; standalone, put `tw:@container/section-nav` on an ancestor.\n *\n * @see RECIPES.md#section-nav\n */\nexport const SectionNav = ({\n groups,\n activeId,\n renderItem,\n showDescriptions = false,\n label = 'Sections',\n className,\n}: Props) => {\n // The collapsed trigger names a sub-section with its group: \"Developer settings / CLI agents\".\n const activeChild = groups\n .flatMap((group) => group.children.map((child) => ({ group, child })))\n .find(({ child }) => child.id === activeId);\n const activeGroup = groups.find((group) => group.id === activeId);\n const current = activeChild\n ? {\n icon: activeChild.group.icon,\n title: activeChild.child.title,\n parent: activeChild.group.title,\n }\n : { icon: activeGroup?.icon, title: activeGroup?.title ?? label, parent: undefined };\n const CurrentIcon = current.icon;\n // Tinted like the tree's row, but not `aria-current`.\n const holdsActive = (group: SectionNavGroup) =>\n group.id === activeId || group.children.some((child) => child.id === activeId);\n\n return (\n <>\n {/* - `tailwindcss-preflight` covers the caller's `<a>` rows; without it they're `content-box`\n and overflow the column.\n - `display` comes only from the two container variants: a plain `tw:flex` / `tw:hidden`\n would lose to the host app's identical, later rule. */}\n <nav\n aria-label={label}\n className={cn(\n 'tailwindcss-preflight',\n 'tw:w-full tw:flex-col tw:gap-0.5 tw:@[640px]/section-nav:flex tw:@max-[640px]/section-nav:hidden',\n className,\n )}\n >\n {groups.map((group) => (\n <SectionNavGroupRow\n key={group.id}\n group={group}\n activeId={activeId}\n renderItem={renderItem}\n showDescriptions={showDescriptions}\n />\n ))}\n </nav>\n\n <div className=\"tw:w-full tw:bg-background tw:@[640px]/section-nav:hidden tw:@max-[640px]/section-nav:block\">\n <DropdownMenu>\n <DropdownMenu.Trigger asChild>\n <Button variant=\"outline\" className=\"tw:w-full tw:justify-between\">\n <span className=\"tw:flex tw:min-w-0 tw:items-center tw:gap-2\">\n {CurrentIcon && <CurrentIcon className=\"tw:size-4 tw:shrink-0\" />}\n {current.parent && (\n <>\n <span className=\"tw:truncate tw:font-normal tw:text-muted-foreground\">\n {current.parent}\n </span>\n <span className=\"tw:text-border\">/</span>\n </>\n )}\n <span className=\"tw:truncate tw:font-medium tw:text-foreground\">\n {current.title}\n </span>\n </span>\n <ChevronDown className=\"tw:size-4 tw:shrink-0\" />\n </Button>\n </DropdownMenu.Trigger>\n\n <DropdownMenu.Content\n align=\"start\"\n className=\"tw:w-(--radix-dropdown-menu-trigger-width)\"\n >\n {groups.map((group) =>\n group.children.length > 0 ? (\n <DropdownMenu.Group key={group.id}>\n {/* A clickable item, not a label: in the tree it navigates to the first section. */}\n <DropdownMenu.Item asChild>\n {renderItem({\n targetId: group.children[0]?.id ?? group.id,\n isActive: false,\n children: <SectionNavItemContent item={group} active={holdsActive(group)} />,\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': undefined,\n 'aria-expanded': undefined,\n 'data-active': holdsActive(group) ? true : undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n <div className=\"tw:ml-5 tw:border-l tw:border-border tw:py-0.5 tw:pl-1\">\n {group.children.map((child) => (\n <DropdownMenu.Item key={child.id} asChild>\n {renderItem({\n targetId: child.id,\n isActive: child.id === activeId,\n children: (\n <SectionNavItemContent\n item={child}\n active={child.id === activeId}\n showDescription={showDescriptions}\n showIcon={false}\n />\n ),\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': child.id === activeId ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n ))}\n </div>\n </DropdownMenu.Group>\n ) : (\n <DropdownMenu.Item key={group.id} asChild>\n {renderItem({\n targetId: group.id,\n isActive: group.id === activeId,\n children: <SectionNavItemContent item={group} active={group.id === activeId} />,\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': group.id === activeId ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n ),\n )}\n </DropdownMenu.Content>\n </DropdownMenu>\n </div>\n </>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SectionNav-L81iJBo3.js","names":[],"sources":["../src/blocks/SectionNav/SectionNavItemContent.tsx","../src/blocks/SectionNav/SectionNavGroupRow.tsx","../src/blocks/SectionNav/SectionNav.tsx"],"sourcesContent":["import { Badge } from '../../components/Badge';\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\n\nimport type { SectionNavItem } from './types';\n\ntype Props = {\n item: SectionNavItem;\n active: boolean;\n showDescription?: boolean;\n /** Group rows only — renders the chevron. */\n expanded?: boolean;\n /** `false` on sub-section rows: the group's icon covers them; `icon` stays for flattened surfaces. */\n showIcon?: boolean;\n};\n\n/** One row's body, shared by the tree and the collapsed dropdown. */\nexport const SectionNavItemContent = ({\n item,\n active,\n showDescription = false,\n expanded,\n showIcon = true,\n}: Props) => {\n const Icon = item.icon;\n\n return (\n <span className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-0.5\">\n <span className=\"tw:flex tw:items-center tw:gap-2\">\n {showIcon && Icon && <Icon className=\"tw:size-4 tw:shrink-0\" />}\n <span\n className={cn(\n 'tw:flex-1 tw:truncate tw:text-sm',\n active ? 'tw:font-medium tw:text-selected-foreground' : 'tw:text-foreground',\n )}\n >\n {item.title}\n </span>\n {item.isNew && (\n <Badge\n color=\"blue-inverse\"\n className=\"tw:min-h-0 tw:text-[10px]\"\n labelClassName=\"tw:px-1.5 tw:py-0\"\n >\n New\n </Badge>\n )}\n {expanded !== undefined && (\n <ChevronDown\n className={cn(\n 'tw:size-4 tw:shrink-0 tw:text-muted-foreground tw:transition-transform tw:duration-200',\n expanded && 'tw:rotate-180',\n )}\n />\n )}\n </span>\n {/* Wraps, and breaks unbreakable tokens that would overflow the 256px column. */}\n {showDescription && item.description && (\n <span className=\"tw:text-xs tw:break-words tw:text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n );\n};\n","import { useState } from 'react';\nimport type { MouseEvent, ReactNode } from 'react';\n\nimport { Collapsible } from '../../components/Collapsible';\nimport { cn, noop } from '../../utils';\n\nimport { SectionNavItemContent } from './SectionNavItemContent';\nimport type { SectionNavGroup, SectionNavItemRenderProps } from './types';\n\ntype Props = {\n group: SectionNavGroup;\n activeId: string | undefined;\n renderItem: (props: SectionNavItemRenderProps) => ReactNode;\n showDescriptions: boolean;\n};\n\n/**\n * The ring is **inset**, not an outline. A row is exactly as wide as the nav column, and\n * `PageLayout.Content nav` makes that column a scroll container (`overflow-y-auto`, which forces\n * `overflow-x` to `auto` too) — so there is 0px of slack for anything painted outside the border\n * box, and the browser's default `outline-offset: 1px` ring gets clipped on both edges. Painting\n * inside the box cannot be clipped, at any column width, by any ancestor.\n */\nconst FOCUS_RING =\n 'tw:focus-visible:outline-hidden tw:focus-visible:ring-2 tw:focus-visible:ring-inset tw:focus-visible:ring-ring';\n\nconst rowClass = (active: boolean) =>\n cn(\n 'tw:flex tw:w-full tw:cursor-pointer tw:items-center tw:gap-2 tw:rounded-md tw:border-none tw:px-3 tw:py-2 tw:text-left tw:text-sm tw:no-underline tw:transition-colors',\n FOCUS_RING,\n active\n ? 'tw:bg-selected tw:font-medium tw:text-selected-foreground'\n : 'tw:bg-transparent tw:text-foreground tw:hover:bg-[var(--hover,rgb(var(--muted)))]',\n );\n\nconst childRowClass = (active: boolean) =>\n cn(\n 'tw:flex tw:w-full tw:cursor-pointer tw:rounded-md tw:border-none tw:px-3 tw:py-1.5 tw:text-left tw:no-underline tw:transition-colors',\n FOCUS_RING,\n active ? 'tw:bg-selected' : 'tw:bg-transparent tw:hover:bg-[var(--hover,rgb(var(--muted)))]',\n );\n\n/**\n * One group row and its sub-sections. The row is a single control: it opens the group **and** goes to\n * its first section, and only collapses once you are already there — so the chevron never becomes a\n * separate thing to aim at, and one click always makes progress.\n */\nexport const SectionNavGroupRow = ({ group, activeId, renderItem, showDescriptions }: Props) => {\n // Open on arrival: the nav is short enough that hiding any of it costs more than it saves.\n const [open, setOpen] = useState(true);\n\n const hasChildren = group.children.length > 0;\n const targetId = group.children[0]?.id ?? group.id;\n const isCurrent = group.id === activeId;\n const holdsCurrent = isCurrent || group.children.some((child) => child.id === activeId);\n\n const onClick = (event: MouseEvent<HTMLElement>) => {\n if (!hasChildren) return;\n\n // Already on the row's target, so navigating would be a no-op and the only thing left for the\n // click to do is toggle. `preventDefault` is what tells the caller's link not to navigate.\n if (activeId === targetId) {\n event.preventDefault();\n setOpen((isOpen) => !isOpen);\n\n return;\n }\n\n setOpen(true);\n };\n\n return (\n <Collapsible open={open} onOpenChange={setOpen} className=\"tw:flex tw:flex-col tw:gap-0.5\">\n {renderItem({\n targetId,\n isActive: isCurrent,\n children: (\n <SectionNavItemContent\n item={group}\n active={holdsCurrent}\n expanded={hasChildren ? open : undefined}\n />\n ),\n itemProps: {\n className: rowClass(holdsCurrent),\n 'aria-current': isCurrent ? 'page' : undefined,\n 'aria-expanded': hasChildren ? open : undefined,\n 'data-active': holdsCurrent && !isCurrent ? true : undefined,\n onClick,\n },\n })}\n\n {hasChildren && (\n <Collapsible.Content>\n {/* `pl-1` keeps each row's background box off the group's rule — without it an active\n row's `bg-selected` sits flush against the line. 4px is also what lines the child titles\n (20 + 1 + 4 + 12 = 37px) up with the parent's, which its icon puts at 12 + 16 + 8 = 36px. */}\n {/* `my-0 mr-0` and not `m-0`: a host app emits its own `.tw\\:m-0` from its own source, and\n its stylesheet is the later one — shorthand and longhand at equal specificity means the\n app's `m-0` would land after this `ml-5` and flatten the indent. Longhands only, so\n nothing here can be overridden by a copy of a class this block also uses. */}\n <ul className=\"tw:my-0 tw:mr-0 tw:ml-5 tw:flex tw:list-none tw:flex-col tw:gap-0.5 tw:border-l tw:border-border tw:py-0.5 tw:pl-1\">\n {group.children.map((child) => {\n const active = child.id === activeId;\n\n return (\n <li key={child.id}>\n {renderItem({\n targetId: child.id,\n isActive: active,\n children: (\n <SectionNavItemContent\n item={child}\n active={active}\n showDescription={showDescriptions}\n showIcon={false}\n />\n ),\n itemProps: {\n className: childRowClass(active),\n 'aria-current': active ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </li>\n );\n })}\n {group.note && (\n <li className=\"tw:py-1 tw:pl-3 tw:text-xs tw:text-muted-foreground\">{group.note}</li>\n )}\n </ul>\n </Collapsible.Content>\n )}\n </Collapsible>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { DropdownMenu } from '../../components/DropdownMenu';\nimport { ChevronDown } from '../../icons';\nimport { cn, noop } from '../../utils';\n\nimport { SectionNavGroupRow } from './SectionNavGroupRow';\nimport { SectionNavItemContent } from './SectionNavItemContent';\nimport type { SectionNavGroup, SectionNavItemRenderProps } from './types';\n\ntype Props = {\n /** Already filtered: visibility, permissions and flags stay in the app; rendered as given. */\n groups: SectionNavGroup[];\n /** `id` of the current section: a child's, or a childless group's. */\n activeId?: string;\n /** Return a router link / `<a>` to `targetId` with `itemProps` spread on it. */\n renderItem: (props: SectionNavItemRenderProps) => ReactNode;\n /** Show each section's `description` under its title. */\n showDescriptions?: boolean;\n /** Accessible name for the tree's `<nav>`, and the collapsed label with nothing active. */\n label?: string;\n /** Applied to the tree's `<nav>`; the column geometry belongs to `PageLayout.Content nav`. */\n className?: string;\n};\n\n/**\n * One page's grouped section nav: a tree when wide, a dropdown when narrow, both rendered via `renderItem`.\n *\n * - Not `Sidebar` (the app-level rail); this lives in `PageLayout.Content` and owns no global state.\n * - The switch is a container query; standalone, put `tw:@container/section-nav` on an ancestor.\n *\n * @see RECIPES.md#section-nav\n */\nexport const SectionNav = ({\n groups,\n activeId,\n renderItem,\n showDescriptions = false,\n label = 'Sections',\n className,\n}: Props) => {\n // The collapsed trigger names a sub-section with its group: \"Developer settings / CLI agents\".\n const activeChild = groups\n .flatMap((group) => group.children.map((child) => ({ group, child })))\n .find(({ child }) => child.id === activeId);\n const activeGroup = groups.find((group) => group.id === activeId);\n const current = activeChild\n ? {\n icon: activeChild.group.icon,\n title: activeChild.child.title,\n parent: activeChild.group.title,\n }\n : { icon: activeGroup?.icon, title: activeGroup?.title ?? label, parent: undefined };\n const CurrentIcon = current.icon;\n // Tinted like the tree's row, but not `aria-current`.\n const holdsActive = (group: SectionNavGroup) =>\n group.id === activeId || group.children.some((child) => child.id === activeId);\n\n return (\n <>\n {/* - `tailwindcss-preflight` covers the caller's `<a>` rows; without it they're `content-box`\n and overflow the column.\n - `display` comes only from the two container variants: a plain `tw:flex` / `tw:hidden`\n would lose to the host app's identical, later rule. */}\n <nav\n aria-label={label}\n className={cn(\n 'tailwindcss-preflight',\n 'tw:w-full tw:flex-col tw:gap-0.5 tw:@[640px]/section-nav:flex tw:@max-[640px]/section-nav:hidden',\n className,\n )}\n >\n {groups.map((group) => (\n <SectionNavGroupRow\n key={group.id}\n group={group}\n activeId={activeId}\n renderItem={renderItem}\n showDescriptions={showDescriptions}\n />\n ))}\n </nav>\n\n <div className=\"tw:w-full tw:bg-background tw:@[640px]/section-nav:hidden tw:@max-[640px]/section-nav:block\">\n <DropdownMenu>\n <DropdownMenu.Trigger asChild>\n <Button variant=\"outline\" className=\"tw:w-full tw:justify-between\">\n <span className=\"tw:flex tw:min-w-0 tw:items-center tw:gap-2\">\n {CurrentIcon && <CurrentIcon className=\"tw:size-4 tw:shrink-0\" />}\n {current.parent && (\n <>\n <span className=\"tw:truncate tw:font-normal tw:text-muted-foreground\">\n {current.parent}\n </span>\n <span className=\"tw:text-border\">/</span>\n </>\n )}\n <span className=\"tw:truncate tw:font-medium tw:text-foreground\">\n {current.title}\n </span>\n </span>\n <ChevronDown className=\"tw:size-4 tw:shrink-0\" />\n </Button>\n </DropdownMenu.Trigger>\n\n <DropdownMenu.Content\n align=\"start\"\n className=\"tw:w-(--radix-dropdown-menu-trigger-width)\"\n >\n {groups.map((group) =>\n group.children.length > 0 ? (\n <DropdownMenu.Group key={group.id}>\n {/* A clickable item, not a label: in the tree it navigates to the first section. */}\n <DropdownMenu.Item asChild>\n {renderItem({\n targetId: group.children[0]?.id ?? group.id,\n isActive: false,\n children: <SectionNavItemContent item={group} active={holdsActive(group)} />,\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': undefined,\n 'aria-expanded': undefined,\n 'data-active': holdsActive(group) ? true : undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n <div className=\"tw:ml-5 tw:border-l tw:border-border tw:py-0.5 tw:pl-1\">\n {group.children.map((child) => (\n <DropdownMenu.Item key={child.id} asChild>\n {renderItem({\n targetId: child.id,\n isActive: child.id === activeId,\n children: (\n <SectionNavItemContent\n item={child}\n active={child.id === activeId}\n showDescription={showDescriptions}\n showIcon={false}\n />\n ),\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': child.id === activeId ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n ))}\n </div>\n </DropdownMenu.Group>\n ) : (\n <DropdownMenu.Item key={group.id} asChild>\n {renderItem({\n targetId: group.id,\n isActive: group.id === activeId,\n children: <SectionNavItemContent item={group} active={group.id === activeId} />,\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': group.id === activeId ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n ),\n )}\n </DropdownMenu.Content>\n </DropdownMenu>\n </div>\n </>\n );\n};\n"],"mappings":"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"}
|