@keboola/design 15.1.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 +69 -0
- package/COMPONENT-API.md +62 -61
- package/dist/{AIKit-BR6jfsdI.js → AIKit-Cf5plya2.js} +328 -210
- 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-DMsn62JJ.js → AlertModal-De04fFoy.js} +14 -24
- package/dist/{AlertModal-DMsn62JJ.js.map → AlertModal-De04fFoy.js.map} +1 -1
- 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-CqlOE5A2.js → Badge-CFRhducL.js} +9 -14
- package/dist/{Badge-CqlOE5A2.js.map → Badge-CFRhducL.js.map} +1 -1
- package/dist/{BrandEditor-D61pzWRq.js → BrandEditor-hiLBX7az.js} +16 -23
- package/dist/{BrandEditor-D61pzWRq.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-DbqvDnYl.js → Breadcrumb-uGFEIjFF.js} +17 -28
- package/dist/{Breadcrumb-DbqvDnYl.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-BlrH8jAi.js → ColorModeSwitch-CuPYnJ2V.js} +5 -6
- package/dist/{ColorModeSwitch-BlrH8jAi.js.map → ColorModeSwitch-CuPYnJ2V.js.map} +1 -1
- package/dist/{Combobox-BLqX-Tdh.js → Combobox-DYjvYgl3.js} +37 -66
- package/dist/{Combobox-BLqX-Tdh.js.map → Combobox-DYjvYgl3.js.map} +1 -1
- 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-duinbI9_.js → DateInput-DJNX7Vdx.js} +8 -10
- package/dist/{DateInput-duinbI9_.js.map → DateInput-DJNX7Vdx.js.map} +1 -1
- package/dist/{DatePicker-Cg_aG_N4.js → DatePicker-CI59gF3S.js} +4 -5
- package/dist/{DatePicker-Cg_aG_N4.js.map → DatePicker-CI59gF3S.js.map} +1 -1
- package/dist/{DateRangeInput-BYVHf9zo.js → DateRangeInput-B3g8cyS0.js} +8 -10
- package/dist/{DateRangeInput-BYVHf9zo.js.map → DateRangeInput-B3g8cyS0.js.map} +1 -1
- package/dist/{DateRangePicker-m47cSV1r.js → DateRangePicker-48yOB2qV.js} +9 -10
- package/dist/{DateRangePicker-m47cSV1r.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-Bum99mVf.js → DropdownMenu-Ba9atqDa.js} +20 -36
- package/dist/{DropdownMenu-Bum99mVf.js.map → DropdownMenu-Ba9atqDa.js.map} +1 -1
- 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-Dqbt_tIs.js → Form-BUNW7nlt.js} +24 -38
- package/dist/{Form-Dqbt_tIs.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-Cf9iYyaW.js → HoverCard-OGWKRXJ7.js} +4 -6
- package/dist/{HoverCard-Cf9iYyaW.js.map → HoverCard-OGWKRXJ7.js.map} +1 -1
- 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-2-EuNu1i.js → MermaidDiagram-E3azndPk.js} +9 -11
- package/dist/{MermaidDiagram-2-EuNu1i.js.map → MermaidDiagram-E3azndPk.js.map} +1 -1
- package/dist/{Modal-DwuvuiUx.js → Modal-Cf_kPEBW.js} +13 -21
- package/dist/{Modal-DwuvuiUx.js.map → Modal-Cf_kPEBW.js.map} +1 -1
- package/dist/{ModalTitle-RGWwIMU6.js → ModalTitle-7vgpfc6B.js} +5 -8
- package/dist/{ModalTitle-RGWwIMU6.js.map → ModalTitle-7vgpfc6B.js.map} +1 -1
- 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-LKP6PiP_.js → PageToolbar-By2HznxO.js} +8 -10
- package/dist/{PageToolbar-LKP6PiP_.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-p72DiagN.js → Popconfirm-BJuDOHdv.js} +46 -25
- package/dist/Popconfirm-BJuDOHdv.js.map +1 -0
- package/dist/{Popover-DnBw5Uay.js → Popover-DhOPlWgF.js} +4 -6
- package/dist/{Popover-DnBw5Uay.js.map → Popover-DhOPlWgF.js.map} +1 -1
- 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-6hcIpZLO.js → SectionNav-L81iJBo3.js} +11 -14
- package/dist/{SectionNav-6hcIpZLO.js.map → SectionNav-L81iJBo3.js.map} +1 -1
- package/dist/{Select-C6zKeip5.js → Select-DRdkdzBp.js} +28 -25
- package/dist/{Select-C6zKeip5.js.map → Select-DRdkdzBp.js.map} +1 -1
- package/dist/{Sheet-DKG20J7W.js → Sheet-DVb4XoJ5.js} +12 -19
- package/dist/{Sheet-DKG20J7W.js.map → Sheet-DVb4XoJ5.js.map} +1 -1
- package/dist/{Sidebar-BlYqasnX.js → Sidebar-DYvodJWN.js} +43 -75
- package/dist/{Sidebar-BlYqasnX.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-lk3NGqeK.js → TimePicker-CCV3SOw5.js} +4 -6
- package/dist/{TimePicker-lk3NGqeK.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-CxXKanUR.js → ZoomableSvg-BRPGgaWJ.js} +8 -10
- package/dist/{ZoomableSvg-CxXKanUR.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 +418 -1296
- package/dist/index.js +75 -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 +1 -2
- 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-DwC9u0tM.js.map → utils-DjFceY3H.js.map} +1 -1
- 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 +113 -11
- package/dist/AIKit-BR6jfsdI.js.map +0 -1
- package/dist/Button-BNkyYU8u.js.map +0 -1
- package/dist/Calendar-BnKi1kPu.js.map +0 -1
- package/dist/Popconfirm-p72DiagN.js.map +0 -1
- package/dist/Search-vyZwGKMU.js.map +0 -1
- package/dist/SearchInput-DyYXyw3u.js.map +0 -1
- package/dist/TextInput-CR0_USaY.js.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { cn } from "./classNames-
|
|
2
|
-
import { ChevronDown, ChevronRight, Ellipsis } from "./icons-
|
|
3
|
-
import { Popover } from "./Popover-
|
|
4
|
-
import { ToggleAllTooltip, isToggleAllClick } from "./ToggleAllTooltip-
|
|
5
|
-
import { SearchInput } from "./SearchInput-
|
|
1
|
+
import { cn } from "./classNames-DkX30VJU.js";
|
|
2
|
+
import { ChevronDown, ChevronRight, Ellipsis } from "./icons-DDR9dFSr.js";
|
|
3
|
+
import { Popover } from "./Popover-DhOPlWgF.js";
|
|
4
|
+
import { ToggleAllTooltip, isToggleAllClick } from "./ToggleAllTooltip-BFmA6TXf.js";
|
|
5
|
+
import { SearchInput } from "./SearchInput-eLS-uvOn.js";
|
|
6
6
|
import { Children, createContext, isValidElement, use, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { Slot } from "@radix-ui/react-slot";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
-
|
|
9
|
+
// src/components/Breadcrumb/BreadcrumbDropdownContext.ts
|
|
10
10
|
const NO_TOGGLES = {};
|
|
11
11
|
/** Records `toggle` under `scope`, keeping the toggles made without a search. */
|
|
12
12
|
const withToggle = (toggles, scope, toggle) => ({
|
|
@@ -44,8 +44,7 @@ const useMatchRegistry = () => {
|
|
|
44
44
|
anyVisible: useMemo(() => [...matches.values()].some(Boolean), [matches])
|
|
45
45
|
};
|
|
46
46
|
};
|
|
47
|
-
|
|
48
|
-
//#region src/components/Breadcrumb/BreadcrumbDropdownGroup.tsx
|
|
47
|
+
// src/components/Breadcrumb/BreadcrumbDropdownGroup.tsx
|
|
49
48
|
const headerClass = cn("tw:flex", "tw:w-full", "tw:items-center", "tw:gap-2", "tw:box-border", "tw:rounded-md", "tw:border-none", "tw:bg-transparent", "tw:px-2", "tw:py-1.5", "tw:text-left", "tw:text-sm", "tw:font-medium", "tw:text-foreground", "tw:min-w-0", "tw:overflow-hidden", "tw:[&_svg:not([class*='tw:size-'])]:size-4", "tw:[&_svg]:shrink-0");
|
|
50
49
|
const collapsibleHeaderClass = cn("tw:cursor-pointer", "tw:hover:bg-hover", "tw:focus-visible:outline-hidden", "tw:focus-visible:ring-2", "tw:focus-visible:ring-ring/50");
|
|
51
50
|
/**
|
|
@@ -136,8 +135,7 @@ const BreadcrumbDropdownGroup = ({ label, textValue, collapsible = false, defaul
|
|
|
136
135
|
})]
|
|
137
136
|
});
|
|
138
137
|
};
|
|
139
|
-
|
|
140
|
-
//#region src/components/Breadcrumb/BreadcrumbDropdownItem.tsx
|
|
138
|
+
// src/components/Breadcrumb/BreadcrumbDropdownItem.tsx
|
|
141
139
|
const itemClass = cn("tw:flex", "tw:w-full", "tw:items-center", "tw:gap-2", "tw:box-border", "tw:rounded-md", "tw:border-none", "tw:bg-transparent", "tw:px-2", "tw:py-1.5", "tw:cursor-pointer", "tw:text-left", "tw:text-sm", "tw:font-normal", "tw:text-foreground", "tw:no-underline", "tw:min-w-0", "tw:overflow-hidden", "tw:hover:bg-hover", "tw:data-[active]:bg-selected", "tw:data-[active]:font-medium", "tw:focus-visible:outline-hidden", "tw:focus-visible:ring-2", "tw:focus-visible:ring-ring/50", "tw:[&_svg:not([class*='tw:size-'])]:size-4", "tw:[&_svg]:shrink-0");
|
|
142
140
|
/**
|
|
143
141
|
* One selectable entity row inside `Breadcrumb.Dropdown`. Self-hides when it doesn't match the
|
|
@@ -169,8 +167,7 @@ const BreadcrumbDropdownItem = ({ ref, asChild = false, textValue, active = fals
|
|
|
169
167
|
children
|
|
170
168
|
});
|
|
171
169
|
};
|
|
172
|
-
|
|
173
|
-
//#region src/components/Breadcrumb/BreadcrumbLink.tsx
|
|
170
|
+
// src/components/Breadcrumb/BreadcrumbLink.tsx
|
|
174
171
|
const BreadcrumbLink = ({ ref, asChild = false, className, ...props }) => {
|
|
175
172
|
return /* @__PURE__ */ jsx(asChild ? Slot : "a", {
|
|
176
173
|
ref,
|
|
@@ -178,8 +175,7 @@ const BreadcrumbLink = ({ ref, asChild = false, className, ...props }) => {
|
|
|
178
175
|
...props
|
|
179
176
|
});
|
|
180
177
|
};
|
|
181
|
-
|
|
182
|
-
//#region src/components/Breadcrumb/BreadcrumbDropdown.tsx
|
|
178
|
+
// src/components/Breadcrumb/BreadcrumbDropdown.tsx
|
|
183
179
|
const chevronButtonClass = cn("tw:flex", "tw:items-center", "tw:justify-center", "tw:rounded-md", "tw:border-none", "tw:bg-transparent", "tw:cursor-pointer", "tw:size-5", "tw:text-muted-foreground", "tw:transition-colors", "tw:hover:bg-hover", "tw:hover:text-foreground", "tw:data-[state=open]:bg-hover", "tw:data-[state=open]:text-foreground", "tw:focus-visible:outline-hidden", "tw:focus-visible:ring-2", "tw:focus-visible:ring-ring/50", "tw:[&_svg]:transition-transform", "tw:[&[data-state=open]_svg]:rotate-180");
|
|
184
180
|
const plainLabelClass = cn("tw:flex", "tw:items-center", "tw:gap-1.5", "tw:text-muted-foreground", "tw:font-normal", "tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5");
|
|
185
181
|
const PANEL_BASE = "tw:max-h-[min(640px,var(--radix-popover-content-available-height))]";
|
|
@@ -300,8 +296,7 @@ const BreadcrumbDropdown = ({ label, splitTrigger = false, triggerLabel, open, d
|
|
|
300
296
|
};
|
|
301
297
|
BreadcrumbDropdown.Item = BreadcrumbDropdownItem;
|
|
302
298
|
BreadcrumbDropdown.Group = BreadcrumbDropdownGroup;
|
|
303
|
-
|
|
304
|
-
//#region src/components/Breadcrumb/BreadcrumbEllipsis.tsx
|
|
299
|
+
// src/components/Breadcrumb/BreadcrumbEllipsis.tsx
|
|
305
300
|
const BreadcrumbEllipsis = ({ ref, className, ...props }) => /* @__PURE__ */ jsxs("button", {
|
|
306
301
|
ref,
|
|
307
302
|
type: "button",
|
|
@@ -312,20 +307,17 @@ const BreadcrumbEllipsis = ({ ref, className, ...props }) => /* @__PURE__ */ jsx
|
|
|
312
307
|
children: "More"
|
|
313
308
|
})]
|
|
314
309
|
});
|
|
315
|
-
|
|
316
|
-
//#region src/components/Breadcrumb/BreadcrumbItem.tsx
|
|
310
|
+
// src/components/Breadcrumb/BreadcrumbItem.tsx
|
|
317
311
|
const BreadcrumbItem = ({ className, ...props }) => /* @__PURE__ */ jsx("li", {
|
|
318
312
|
className: cn("tw:inline-flex", "tw:items-center", className),
|
|
319
313
|
...props
|
|
320
314
|
});
|
|
321
|
-
|
|
322
|
-
//#region src/components/Breadcrumb/BreadcrumbList.tsx
|
|
315
|
+
// src/components/Breadcrumb/BreadcrumbList.tsx
|
|
323
316
|
const BreadcrumbList = ({ className, ...props }) => /* @__PURE__ */ jsx("ol", {
|
|
324
317
|
className: cn("tw:flex", "tw:flex-wrap", "tw:items-center", "tw:gap-2", "tw:m-0", "tw:p-0", "tw:break-words", "tw:text-sm", "tw:text-muted-foreground", className),
|
|
325
318
|
...props
|
|
326
319
|
});
|
|
327
|
-
|
|
328
|
-
//#region src/components/Breadcrumb/BreadcrumbPage.tsx
|
|
320
|
+
// src/components/Breadcrumb/BreadcrumbPage.tsx
|
|
329
321
|
const BreadcrumbPage = ({ ref, className, ...props }) => /* @__PURE__ */ jsx("span", {
|
|
330
322
|
ref,
|
|
331
323
|
role: "link",
|
|
@@ -334,8 +326,7 @@ const BreadcrumbPage = ({ ref, className, ...props }) => /* @__PURE__ */ jsx("sp
|
|
|
334
326
|
className: cn("tw:font-medium", "tw:text-foreground", className),
|
|
335
327
|
...props
|
|
336
328
|
});
|
|
337
|
-
|
|
338
|
-
//#region src/components/Breadcrumb/BreadcrumbSeparator.tsx
|
|
329
|
+
// src/components/Breadcrumb/BreadcrumbSeparator.tsx
|
|
339
330
|
const BreadcrumbSeparator = ({ children, className, ...props }) => /* @__PURE__ */ jsx("li", {
|
|
340
331
|
role: "presentation",
|
|
341
332
|
"aria-hidden": "true",
|
|
@@ -346,8 +337,7 @@ const BreadcrumbSeparator = ({ children, className, ...props }) => /* @__PURE__
|
|
|
346
337
|
children: "/"
|
|
347
338
|
})
|
|
348
339
|
});
|
|
349
|
-
|
|
350
|
-
//#region src/components/Breadcrumb/Breadcrumb.tsx
|
|
340
|
+
// src/components/Breadcrumb/Breadcrumb.tsx
|
|
351
341
|
const Breadcrumb = ({ className, ...props }) => /* @__PURE__ */ jsx("nav", {
|
|
352
342
|
"aria-label": "breadcrumb",
|
|
353
343
|
className: cn("tailwindcss-preflight", className),
|
|
@@ -360,7 +350,6 @@ Breadcrumb.Page = BreadcrumbPage;
|
|
|
360
350
|
Breadcrumb.Separator = BreadcrumbSeparator;
|
|
361
351
|
Breadcrumb.Ellipsis = BreadcrumbEllipsis;
|
|
362
352
|
Breadcrumb.Dropdown = BreadcrumbDropdown;
|
|
363
|
-
//#endregion
|
|
364
353
|
export { Breadcrumb };
|
|
365
354
|
|
|
366
|
-
//# sourceMappingURL=Breadcrumb-
|
|
355
|
+
//# sourceMappingURL=Breadcrumb-uGFEIjFF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb-DbqvDnYl.js","names":[],"sources":["../src/components/Breadcrumb/BreadcrumbDropdownContext.ts","../src/components/Breadcrumb/BreadcrumbDropdownGroup.tsx","../src/components/Breadcrumb/BreadcrumbDropdownItem.tsx","../src/components/Breadcrumb/BreadcrumbLink.tsx","../src/components/Breadcrumb/BreadcrumbDropdown.tsx","../src/components/Breadcrumb/BreadcrumbEllipsis.tsx","../src/components/Breadcrumb/BreadcrumbItem.tsx","../src/components/Breadcrumb/BreadcrumbList.tsx","../src/components/Breadcrumb/BreadcrumbPage.tsx","../src/components/Breadcrumb/BreadcrumbSeparator.tsx","../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import { createContext, isValidElement, useCallback, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\n/** A fold toggle, stamped so the later of two decides. */\nexport type BreadcrumbDropdownToggle = { expanded: boolean; at: number };\n\n/**\n * Toggles keyed by the query they were made under; `''` is no search.\n *\n * - Only the toggles of the current query apply, so a search starts with every match open.\n * - Holds `''` and the latest query only.\n */\nexport type BreadcrumbDropdownToggles = Readonly<Record<string, BreadcrumbDropdownToggle>>;\n\nexport const NO_TOGGLES: BreadcrumbDropdownToggles = {};\n\n/** Records `toggle` under `scope`, keeping the toggles made without a search. */\nexport const withToggle = (\n toggles: BreadcrumbDropdownToggles,\n scope: string,\n toggle: BreadcrumbDropdownToggle,\n): BreadcrumbDropdownToggles => ({ ...(toggles[''] && { '': toggles[''] }), [scope]: toggle });\n\nexport type BreadcrumbDropdownContextValue = {\n /** Current (trimmed, lowercased) filter query. Empty string = no filtering. */\n query: string;\n /** An ancestor group's label matched the query — descendants render regardless of their own match. */\n forceVisible: boolean;\n /** Filtering is off (`filter={false}` or `shouldFilter={false}`) — items never self-hide. */\n filterDisabled: boolean;\n /** Report this node's visibility to the parent scope. Returns the unregister cleanup. */\n register: (id: string, visible: boolean) => () => void;\n /** Close the panel (fired by items on select). */\n close: () => void;\n /** The last expand- or collapse-all per query; a group's own toggle after it wins. */\n allExpanded: BreadcrumbDropdownToggles;\n setAllExpanded: (expanded: boolean, scope: string) => void;\n /** A stamp later than every earlier one, to order a group's own toggle against `allExpanded`. */\n stamp: () => number;\n};\n\nexport const BreadcrumbDropdownContext = createContext<BreadcrumbDropdownContextValue | null>(null);\n\nexport const matchesQuery = (text: string, query: string) => text.toLowerCase().includes(query);\n\n/** Text content of a React tree — the default filter text when no `textValue` is given. */\nexport const getNodeText = (node: ReactNode): string => {\n if (typeof node === 'string' || typeof node === 'number') return String(node);\n if (Array.isArray(node)) return node.map(getNodeText).join('');\n if (isValidElement<{ children?: ReactNode }>(node)) return getNodeText(node.props.children);\n return '';\n};\n\nexport const normalizeQuery = (query: string) => query.trim().toLowerCase();\n\n/**\n * Visibility registry for one filtering scope (the panel root, or one group). Items and groups\n * report their visibility here; `anyVisible` drives the group header / empty-state rendering.\n */\nexport const useMatchRegistry = () => {\n const [matches, setMatches] = useState<ReadonlyMap<string, boolean>>(new Map());\n\n const register = useCallback((id: string, visible: boolean) => {\n setMatches((prev) => (prev.get(id) === visible ? prev : new Map(prev).set(id, visible)));\n return () => {\n setMatches((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n };\n }, []);\n\n const anyVisible = useMemo(() => [...matches.values()].some(Boolean), [matches]);\n\n return { register, anyVisible };\n};\n","import { Children, use, useEffect, useId, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { ChevronDown, ChevronRight } from '../../icons';\nimport { cn } from '../../utils';\nimport { isToggleAllClick } from '../Tooltip/toggleAll';\nimport { ToggleAllTooltip } from '../Tooltip/ToggleAllTooltip';\n\nimport {\n BreadcrumbDropdownContext,\n type BreadcrumbDropdownToggles,\n getNodeText,\n matchesQuery,\n NO_TOGGLES,\n useMatchRegistry,\n withToggle,\n} from './BreadcrumbDropdownContext';\n\nconst headerClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-medium',\n 'tw:text-foreground',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\nconst collapsibleHeaderClass = cn(\n 'tw:cursor-pointer',\n 'tw:hover:bg-hover',\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n);\n\ntype BreadcrumbDropdownGroupProps = {\n /** Group header (e.g. bucket name + stage badge). */\n label: ReactNode;\n /**\n * Text the built-in filter matches against. When the group label matches, all its items stay\n * visible. Defaults to the label's rendered text content.\n */\n textValue?: string;\n /** Render the header as a toggle that expands / collapses the group's items. Default `false`. */\n collapsible?: boolean;\n /** Initial expanded state for `collapsible` groups. Default `true`. */\n defaultExpanded?: boolean;\n className?: string;\n children: ReactNode;\n};\n\n/**\n * A labelled group of `Breadcrumb.Dropdown.Item`s (e.g. one bucket with its tables). The group\n * hides itself when neither its label nor any child matches the filter query; an active query\n * opens collapsible groups, and a fold made under it lasts until the query changes. Non-empty `collapsible` groups toggle their items behind the\n * header with an animated expand / collapse; a `collapsible` group with no items renders a\n * non-interactive, greyed header that can't toggle.\n */\nexport const BreadcrumbDropdownGroup = ({\n label,\n textValue,\n collapsible = false,\n defaultExpanded = true,\n className,\n children,\n}: BreadcrumbDropdownGroupProps) => {\n const parent = use(BreadcrumbDropdownContext);\n if (!parent) {\n throw new Error('Breadcrumb.Dropdown.Group must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n const { register: registerChild, anyVisible } = useMatchRegistry();\n const [own, setOwn] = useState<BreadcrumbDropdownToggles>(NO_TOGGLES);\n\n const text = textValue ?? getNodeText(label);\n const filtering = !parent.filterDisabled && !!parent.query;\n const scope = filtering ? parent.query : '';\n // The later of this group's own toggle and the panel's expand- or collapse-all under this query.\n const ownToggle = own[scope];\n const allToggle = parent.allExpanded[scope];\n const toggle = allToggle && (!ownToggle || allToggle.at > ownToggle.at) ? allToggle : ownToggle;\n const labelMatched = filtering && matchesQuery(text, parent.query);\n const visible = !filtering || parent.forceVisible || labelMatched || anyVisible;\n\n useEffect(() => parent.register(id, visible), [parent, id, visible]);\n\n const childContext = useMemo(\n () => ({\n query: parent.query,\n forceVisible: parent.forceVisible || labelMatched,\n filterDisabled: parent.filterDisabled,\n register: registerChild,\n close: parent.close,\n allExpanded: parent.allExpanded,\n setAllExpanded: parent.setAllExpanded,\n stamp: parent.stamp,\n }),\n [parent, labelMatched, registerChild],\n );\n\n // A search opens every group; a fold made under it lasts until the query changes.\n const isExpanded = !collapsible || (toggle ? toggle.expanded : filtering || defaultExpanded);\n // A collapsible group with no items has nothing to toggle — render a non-interactive header.\n // oxlint-disable-next-line react-x/no-children-count -- emptiness check, no child transformation\n const isEmpty = Children.count(children) === 0;\n\n return (\n <div\n className={cn('tw:flex tw:flex-col', className)}\n style={visible ? undefined : { display: 'none' }}\n >\n {collapsible && isEmpty ? (\n <span\n aria-disabled\n className={cn(\n headerClass,\n 'tw:text-muted-foreground',\n // Fade just the leading chevron lighter than the label text.\n 'tw:[&>svg:first-child]:opacity-50',\n )}\n >\n <ChevronRight />\n {label}\n </span>\n ) : collapsible && !isEmpty ? (\n <button\n type=\"button\"\n aria-expanded={isExpanded}\n className={cn(headerClass, collapsibleHeaderClass)}\n onClick={(event) =>\n isToggleAllClick(event)\n ? parent.setAllExpanded(!isExpanded, scope)\n : setOwn((prev) =>\n withToggle(prev, scope, { expanded: !isExpanded, at: parent.stamp() }),\n )\n }\n >\n <ToggleAllTooltip expanded={isExpanded}>\n <span className=\"tw:inline-flex\">\n {isExpanded ? <ChevronDown /> : <ChevronRight />}\n </span>\n </ToggleAllTooltip>\n {label}\n </button>\n ) : (\n <span className={headerClass}>{label}</span>\n )}\n <BreadcrumbDropdownContext value={childContext}>\n {collapsible && !isEmpty ? (\n // Animated expand / collapse via a CSS grid-rows transition (0fr ↔ 1fr). The children stay\n // mounted while collapsed so the filter registry keeps receiving their visibility; `inert`\n // + `aria-hidden` take the collapsed content out of the a11y tree and tab order. An active\n // filter query force-expands (`isExpanded` includes `filtering`).\n <div\n className={cn(\n 'tw:grid tw:transition-[grid-template-rows] tw:duration-200 tw:ease-out',\n 'tw:motion-reduce:transition-none',\n isExpanded ? 'tw:grid-rows-[1fr]' : 'tw:grid-rows-[0fr]',\n )}\n >\n <div\n className=\"tw:overflow-hidden\"\n inert={!isExpanded}\n aria-hidden={isExpanded ? undefined : true}\n >\n <div className=\"tw:flex tw:flex-col tw:pl-6\">{children}</div>\n </div>\n </div>\n ) : (\n <div\n className=\"tw:flex tw:flex-col tw:pl-6\"\n style={isExpanded ? undefined : { display: 'none' }}\n >\n {children}\n </div>\n )}\n </BreadcrumbDropdownContext>\n </div>\n );\n};\n","import { use, useEffect, useId } from 'react';\nimport type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdownContext, getNodeText, matchesQuery } from './BreadcrumbDropdownContext';\n\nconst itemClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:cursor-pointer',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-normal',\n 'tw:text-foreground',\n 'tw:no-underline',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // hover / active entity\n 'tw:hover:bg-hover',\n 'tw:data-[active]:bg-selected',\n 'tw:data-[active]:font-medium',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\ntype BreadcrumbDropdownItemProps = ComponentProps<'button'> & {\n /** Render the consumer's element (typically a router link) instead of a `button`. */\n asChild?: boolean;\n /**\n * Text the built-in filter matches against. Defaults to the item's rendered text content\n * (extracted recursively, so `asChild` links with icons work out of the box).\n */\n textValue?: string;\n /** Marks the currently open entity (highlight + `aria-current`). */\n active?: boolean;\n /** Close the panel when the item is selected. Default `true`. */\n closeOnSelect?: boolean;\n};\n\n/**\n * One selectable entity row inside `Breadcrumb.Dropdown`. Self-hides when it doesn't match the\n * panel's filter query and closes the panel on select. Use `asChild` to render a router link.\n */\nexport const BreadcrumbDropdownItem = ({\n ref,\n asChild = false,\n textValue,\n active = false,\n closeOnSelect = true,\n className,\n children,\n onClick,\n ...props\n}: BreadcrumbDropdownItemProps) => {\n const context = use(BreadcrumbDropdownContext);\n if (!context) {\n throw new Error('Breadcrumb.Dropdown.Item must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n\n const text = textValue ?? getNodeText(children);\n const visible =\n context.filterDisabled ||\n !context.query ||\n context.forceVisible ||\n matchesQuery(text, context.query);\n\n useEffect(() => context.register(id, visible), [context, id, visible]);\n\n if (!visible) return null;\n\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n {...(asChild ? {} : { type: 'button' as const })}\n data-active={active || undefined}\n aria-current={active || undefined}\n className={cn(itemClass, className)}\n onClick={(event) => {\n onClick?.(event);\n if (closeOnSelect && !event.defaultPrevented) {\n context.close();\n }\n }}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'a'> & {\n asChild?: boolean;\n};\n\nexport const BreadcrumbLink = ({ ref, asChild = false, className, ...props }: Props) => {\n const Comp = asChild ? Slot : 'a';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n // font\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:no-underline',\n\n // hover\n 'tw:hover:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n 'tw:focus-visible:rounded-sm',\n\n // Icon\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n\n // transition\n 'tw:transition-colors',\n className,\n )}\n {...props}\n />\n );\n};\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport type { ComponentRef, ReactNode } from 'react';\n\nimport { SearchInput } from '../../blocks/SearchInput';\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Popover } from '../Popover';\n\nimport {\n BreadcrumbDropdownContext,\n type BreadcrumbDropdownToggles,\n NO_TOGGLES,\n normalizeQuery,\n useMatchRegistry,\n withToggle,\n} from './BreadcrumbDropdownContext';\nimport { BreadcrumbDropdownGroup } from './BreadcrumbDropdownGroup';\nimport { BreadcrumbDropdownItem } from './BreadcrumbDropdownItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\n\n// Chevron trigger, the only button in the crumb; no outline, only a hover / open background.\nconst chevronButtonClass = cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n 'tw:size-5',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n 'tw:hover:bg-hover',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-hover',\n 'tw:data-[state=open]:text-foreground',\n\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n 'tw:[&_svg]:transition-transform',\n 'tw:[&[data-state=open]_svg]:rotate-180',\n);\n\n// Plain label: `BreadcrumbLink` typography without hover / focus, as it isn't interactive.\nconst plainLabelClass = cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n);\n\n// Fixed width per `size`, clamped to the viewport; long names truncate instead of widening it.\nconst PANEL_BASE = 'tw:max-h-[min(640px,var(--radix-popover-content-available-height))]';\n\nconst PANEL_WIDTH = {\n small: 'tw:w-[min(360px,var(--radix-popover-content-available-width))]',\n medium: 'tw:w-[min(440px,var(--radix-popover-content-available-width))]',\n large: 'tw:w-[min(560px,var(--radix-popover-content-available-width))]',\n} as const;\n\ntype PanelSize = keyof typeof PANEL_WIDTH;\n\ntype BreadcrumbDropdownProps = {\n /** Never the trigger. With `splitTrigger`, pass an anchor-like element so it navigates. */\n label: ReactNode;\n /** Renders `label` through `Breadcrumb.Link asChild`; default `false` (plain text). */\n splitTrigger?: boolean;\n /** Chevron's accessible name; defaults to `\"${label} menu\"`, or `\"Open menu\"` for a node label. */\n triggerLabel?: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Panel width: `small` 360px, `medium` 440px (default), `large` 560px. */\n size?: PanelSize;\n /**\n * Pinned filter input, focused on open; default on. Non-matching items / groups hide\n * (by `textValue` / string content).\n */\n filter?: boolean;\n /** `false` keeps the input but disables built-in matching; the consumer filters. */\n shouldFilter?: boolean;\n /** Controlled filter value. */\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n /** Rendered when the built-in filter hides everything. Default `\"No results.\"`. */\n emptyMessage?: ReactNode;\n /** The panel's own classes, e.g. a background the search row shares with the list. */\n panelClassName?: string;\n /** `Breadcrumb.Dropdown.Group` / `Breadcrumb.Dropdown.Item` elements. */\n children: ReactNode;\n};\n\n/**\n * Breadcrumb segment opening a filterable switcher of sibling entities.\n *\n * - Use on the leftmost segment with siblings worth switching between; at most one per breadcrumb.\n * - Not for row actions (`PageHeader.Detail` `overflowActions`) or a collapsed middle (`Ellipsis`).\n * - Render inside `Breadcrumb.Item` in place of `Breadcrumb.Link`.\n */\nexport const BreadcrumbDropdown = ({\n label,\n splitTrigger = false,\n triggerLabel,\n open,\n defaultOpen = false,\n onOpenChange,\n size = 'medium',\n filter = true,\n shouldFilter = true,\n searchValue,\n onSearchChange,\n searchPlaceholder = 'Search…',\n emptyMessage = 'No results.',\n panelClassName,\n children,\n}: BreadcrumbDropdownProps) => {\n const searchRef = useRef<ComponentRef<'input'>>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [internalQuery, setInternalQuery] = useState('');\n const stampRef = useRef(0);\n const stamp = useCallback(() => ++stampRef.current, []);\n const [allExpanded, setAllExpandedState] = useState<BreadcrumbDropdownToggles>(NO_TOGGLES);\n const setAllExpanded = useCallback(\n (expanded: boolean, scope: string) =>\n setAllExpandedState((prev) => withToggle(prev, scope, { expanded, at: stamp() })),\n [stamp],\n );\n const { register, anyVisible } = useMatchRegistry();\n\n const isOpen = open ?? internalOpen;\n // Reopening starts from each group's own default again, however the panel closed.\n const [wasOpen, setWasOpen] = useState(isOpen);\n if (wasOpen !== isOpen) {\n setWasOpen(isOpen);\n if (!isOpen) setAllExpandedState(NO_TOGGLES);\n }\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n setInternalOpen(nextOpen);\n if (!nextOpen) setInternalQuery('');\n onOpenChange?.(nextOpen);\n },\n [onOpenChange],\n );\n const close = useCallback(() => handleOpenChange(false), [handleOpenChange]);\n\n const effectiveTriggerLabel =\n triggerLabel ?? (typeof label === 'string' ? `${label} menu` : 'Open menu');\n\n const rawQuery = searchValue ?? internalQuery;\n const filterDisabled = !filter || !shouldFilter;\n const query = filterDisabled ? '' : normalizeQuery(rawQuery);\n\n const contextValue = useMemo(\n () => ({\n query,\n forceVisible: false,\n filterDisabled,\n register,\n close,\n allExpanded,\n setAllExpanded,\n stamp,\n }),\n [query, filterDisabled, register, close, allExpanded, setAllExpanded, stamp],\n );\n\n return (\n <Popover open={isOpen} onOpenChange={handleOpenChange}>\n <span className=\"tw:flex tw:items-center tw:gap-0.5\">\n {splitTrigger ? (\n <BreadcrumbLink asChild>{label}</BreadcrumbLink>\n ) : (\n <span className={plainLabelClass}>{label}</span>\n )}\n <Popover.Trigger asChild>\n <button type=\"button\" aria-label={effectiveTriggerLabel} className={chevronButtonClass}>\n <ChevronDown className=\"tw:size-3.5\" />\n </button>\n </Popover.Trigger>\n </span>\n <Popover.Content\n align=\"start\"\n sideOffset={8}\n collisionPadding={16}\n data-size={size}\n className={cn('tw:overflow-hidden tw:p-0', PANEL_BASE, PANEL_WIDTH[size], panelClassName)}\n onOpenAutoFocus={\n filter\n ? (event) => {\n event.preventDefault();\n searchRef.current?.focus();\n }\n : undefined\n }\n >\n {filter && (\n <div\n data-slot=\"breadcrumb-dropdown-search\"\n className=\"tw:shrink-0 tw:border-0 tw:border-b tw:border-solid tw:border-border tw:p-2\"\n >\n <SearchInput\n ref={searchRef}\n value={rawQuery}\n onValueChange={(value) => {\n setInternalQuery(value);\n onSearchChange?.(value);\n }}\n placeholder={searchPlaceholder}\n allowClear\n // Debounce only when the consumer filters itself (e.g. server-side).\n disableDebounce={shouldFilter}\n />\n </div>\n )}\n <div className=\"tw:flex tw:flex-1 tw:flex-col tw:overflow-y-auto tw:p-2\">\n <BreadcrumbDropdownContext value={contextValue}>{children}</BreadcrumbDropdownContext>\n {!filterDisabled && !!query && !anyVisible && (\n <span className=\"tw:px-2 tw:py-1.5 tw:text-sm tw:text-muted-foreground\">\n {emptyMessage}\n </span>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n};\n\nBreadcrumbDropdown.Item = BreadcrumbDropdownItem;\nBreadcrumbDropdown.Group = BreadcrumbDropdownGroup;\n","import type { ComponentProps } from 'react';\n\nimport { Ellipsis } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const BreadcrumbEllipsis = ({ ref, className, ...props }: Props) => (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n // Match the Breadcrumb.Dropdown chevron trigger: background + colour lift on hover / while the\n // menu is open, so the two interactive breadcrumb affordances read consistently.\n 'tw:hover:bg-hover',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-hover',\n 'tw:data-[state=open]:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n 'tw:p-1',\n className,\n )}\n {...props}\n >\n <Ellipsis className=\"tw:size-4\" />\n <span className=\"tw:sr-only\">More</span>\n </button>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbItem = ({ className, ...props }: Props) => (\n <li className={cn('tw:inline-flex', 'tw:items-center', className)} {...props} />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'ol'>;\n\nexport const BreadcrumbList = ({ className, ...props }: Props) => (\n <ol\n className={cn(\n // layout\n 'tw:flex',\n 'tw:flex-wrap',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:m-0',\n 'tw:p-0',\n\n // font\n 'tw:break-words',\n 'tw:text-sm',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'span'>;\n\nexport const BreadcrumbPage = ({ ref, className, ...props }: Props) => (\n <span\n ref={ref}\n // Do not use the anchor, as this item is not clickable\n // oxlint-disable-next-line jsx_a11y/prefer-tag-over-role\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('tw:font-medium', 'tw:text-foreground', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbSeparator = ({ children, className, ...props }: Props) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:aspect-square',\n 'tw:size-[15px]',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-2.5',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n >\n {children ?? <span className=\"tw:select-none tw:text-sm tw:text-muted-foreground/50\">/</span>}\n </li>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdown } from './BreadcrumbDropdown';\nimport { BreadcrumbEllipsis } from './BreadcrumbEllipsis';\nimport { BreadcrumbItem } from './BreadcrumbItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\nimport { BreadcrumbList } from './BreadcrumbList';\nimport { BreadcrumbPage } from './BreadcrumbPage';\nimport { BreadcrumbSeparator } from './BreadcrumbSeparator';\n\ntype Props = ComponentProps<'nav'>;\n\nexport const Breadcrumb = ({ className, ...props }: Props) => (\n <nav aria-label=\"breadcrumb\" className={cn('tailwindcss-preflight', className)} {...props} />\n);\n\nBreadcrumb.List = BreadcrumbList;\nBreadcrumb.Item = BreadcrumbItem;\nBreadcrumb.Link = BreadcrumbLink;\nBreadcrumb.Page = BreadcrumbPage;\nBreadcrumb.Separator = BreadcrumbSeparator;\nBreadcrumb.Ellipsis = BreadcrumbEllipsis;\nBreadcrumb.Dropdown = BreadcrumbDropdown;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Breadcrumb-uGFEIjFF.js","names":[],"sources":["../src/components/Breadcrumb/BreadcrumbDropdownContext.ts","../src/components/Breadcrumb/BreadcrumbDropdownGroup.tsx","../src/components/Breadcrumb/BreadcrumbDropdownItem.tsx","../src/components/Breadcrumb/BreadcrumbLink.tsx","../src/components/Breadcrumb/BreadcrumbDropdown.tsx","../src/components/Breadcrumb/BreadcrumbEllipsis.tsx","../src/components/Breadcrumb/BreadcrumbItem.tsx","../src/components/Breadcrumb/BreadcrumbList.tsx","../src/components/Breadcrumb/BreadcrumbPage.tsx","../src/components/Breadcrumb/BreadcrumbSeparator.tsx","../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import { createContext, isValidElement, useCallback, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\n/** A fold toggle, stamped so the later of two decides. */\nexport type BreadcrumbDropdownToggle = { expanded: boolean; at: number };\n\n/**\n * Toggles keyed by the query they were made under; `''` is no search.\n *\n * - Only the toggles of the current query apply, so a search starts with every match open.\n * - Holds `''` and the latest query only.\n */\nexport type BreadcrumbDropdownToggles = Readonly<Record<string, BreadcrumbDropdownToggle>>;\n\nexport const NO_TOGGLES: BreadcrumbDropdownToggles = {};\n\n/** Records `toggle` under `scope`, keeping the toggles made without a search. */\nexport const withToggle = (\n toggles: BreadcrumbDropdownToggles,\n scope: string,\n toggle: BreadcrumbDropdownToggle,\n): BreadcrumbDropdownToggles => ({ ...(toggles[''] && { '': toggles[''] }), [scope]: toggle });\n\nexport type BreadcrumbDropdownContextValue = {\n /** Current (trimmed, lowercased) filter query. Empty string = no filtering. */\n query: string;\n /** An ancestor group's label matched the query — descendants render regardless of their own match. */\n forceVisible: boolean;\n /** Filtering is off (`filter={false}` or `shouldFilter={false}`) — items never self-hide. */\n filterDisabled: boolean;\n /** Report this node's visibility to the parent scope. Returns the unregister cleanup. */\n register: (id: string, visible: boolean) => () => void;\n /** Close the panel (fired by items on select). */\n close: () => void;\n /** The last expand- or collapse-all per query; a group's own toggle after it wins. */\n allExpanded: BreadcrumbDropdownToggles;\n setAllExpanded: (expanded: boolean, scope: string) => void;\n /** A stamp later than every earlier one, to order a group's own toggle against `allExpanded`. */\n stamp: () => number;\n};\n\nexport const BreadcrumbDropdownContext = createContext<BreadcrumbDropdownContextValue | null>(null);\n\nexport const matchesQuery = (text: string, query: string) => text.toLowerCase().includes(query);\n\n/** Text content of a React tree — the default filter text when no `textValue` is given. */\nexport const getNodeText = (node: ReactNode): string => {\n if (typeof node === 'string' || typeof node === 'number') return String(node);\n if (Array.isArray(node)) return node.map(getNodeText).join('');\n if (isValidElement<{ children?: ReactNode }>(node)) return getNodeText(node.props.children);\n return '';\n};\n\nexport const normalizeQuery = (query: string) => query.trim().toLowerCase();\n\n/**\n * Visibility registry for one filtering scope (the panel root, or one group). Items and groups\n * report their visibility here; `anyVisible` drives the group header / empty-state rendering.\n */\nexport const useMatchRegistry = () => {\n const [matches, setMatches] = useState<ReadonlyMap<string, boolean>>(new Map());\n\n const register = useCallback((id: string, visible: boolean) => {\n setMatches((prev) => (prev.get(id) === visible ? prev : new Map(prev).set(id, visible)));\n return () => {\n setMatches((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n };\n }, []);\n\n const anyVisible = useMemo(() => [...matches.values()].some(Boolean), [matches]);\n\n return { register, anyVisible };\n};\n","import { Children, use, useEffect, useId, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { ChevronDown, ChevronRight } from '../../icons';\nimport { cn } from '../../utils';\nimport { isToggleAllClick } from '../Tooltip/toggleAll';\nimport { ToggleAllTooltip } from '../Tooltip/ToggleAllTooltip';\n\nimport {\n BreadcrumbDropdownContext,\n type BreadcrumbDropdownToggles,\n getNodeText,\n matchesQuery,\n NO_TOGGLES,\n useMatchRegistry,\n withToggle,\n} from './BreadcrumbDropdownContext';\n\nconst headerClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-medium',\n 'tw:text-foreground',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\nconst collapsibleHeaderClass = cn(\n 'tw:cursor-pointer',\n 'tw:hover:bg-hover',\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n);\n\ntype BreadcrumbDropdownGroupProps = {\n /** Group header (e.g. bucket name + stage badge). */\n label: ReactNode;\n /**\n * Text the built-in filter matches against. When the group label matches, all its items stay\n * visible. Defaults to the label's rendered text content.\n */\n textValue?: string;\n /** Render the header as a toggle that expands / collapses the group's items. Default `false`. */\n collapsible?: boolean;\n /** Initial expanded state for `collapsible` groups. Default `true`. */\n defaultExpanded?: boolean;\n className?: string;\n children: ReactNode;\n};\n\n/**\n * A labelled group of `Breadcrumb.Dropdown.Item`s (e.g. one bucket with its tables). The group\n * hides itself when neither its label nor any child matches the filter query; an active query\n * opens collapsible groups, and a fold made under it lasts until the query changes. Non-empty `collapsible` groups toggle their items behind the\n * header with an animated expand / collapse; a `collapsible` group with no items renders a\n * non-interactive, greyed header that can't toggle.\n */\nexport const BreadcrumbDropdownGroup = ({\n label,\n textValue,\n collapsible = false,\n defaultExpanded = true,\n className,\n children,\n}: BreadcrumbDropdownGroupProps) => {\n const parent = use(BreadcrumbDropdownContext);\n if (!parent) {\n throw new Error('Breadcrumb.Dropdown.Group must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n const { register: registerChild, anyVisible } = useMatchRegistry();\n const [own, setOwn] = useState<BreadcrumbDropdownToggles>(NO_TOGGLES);\n\n const text = textValue ?? getNodeText(label);\n const filtering = !parent.filterDisabled && !!parent.query;\n const scope = filtering ? parent.query : '';\n // The later of this group's own toggle and the panel's expand- or collapse-all under this query.\n const ownToggle = own[scope];\n const allToggle = parent.allExpanded[scope];\n const toggle = allToggle && (!ownToggle || allToggle.at > ownToggle.at) ? allToggle : ownToggle;\n const labelMatched = filtering && matchesQuery(text, parent.query);\n const visible = !filtering || parent.forceVisible || labelMatched || anyVisible;\n\n useEffect(() => parent.register(id, visible), [parent, id, visible]);\n\n const childContext = useMemo(\n () => ({\n query: parent.query,\n forceVisible: parent.forceVisible || labelMatched,\n filterDisabled: parent.filterDisabled,\n register: registerChild,\n close: parent.close,\n allExpanded: parent.allExpanded,\n setAllExpanded: parent.setAllExpanded,\n stamp: parent.stamp,\n }),\n [parent, labelMatched, registerChild],\n );\n\n // A search opens every group; a fold made under it lasts until the query changes.\n const isExpanded = !collapsible || (toggle ? toggle.expanded : filtering || defaultExpanded);\n // A collapsible group with no items has nothing to toggle — render a non-interactive header.\n // oxlint-disable-next-line react-x/no-children-count -- emptiness check, no child transformation\n const isEmpty = Children.count(children) === 0;\n\n return (\n <div\n className={cn('tw:flex tw:flex-col', className)}\n style={visible ? undefined : { display: 'none' }}\n >\n {collapsible && isEmpty ? (\n <span\n aria-disabled\n className={cn(\n headerClass,\n 'tw:text-muted-foreground',\n // Fade just the leading chevron lighter than the label text.\n 'tw:[&>svg:first-child]:opacity-50',\n )}\n >\n <ChevronRight />\n {label}\n </span>\n ) : collapsible && !isEmpty ? (\n <button\n type=\"button\"\n aria-expanded={isExpanded}\n className={cn(headerClass, collapsibleHeaderClass)}\n onClick={(event) =>\n isToggleAllClick(event)\n ? parent.setAllExpanded(!isExpanded, scope)\n : setOwn((prev) =>\n withToggle(prev, scope, { expanded: !isExpanded, at: parent.stamp() }),\n )\n }\n >\n <ToggleAllTooltip expanded={isExpanded}>\n <span className=\"tw:inline-flex\">\n {isExpanded ? <ChevronDown /> : <ChevronRight />}\n </span>\n </ToggleAllTooltip>\n {label}\n </button>\n ) : (\n <span className={headerClass}>{label}</span>\n )}\n <BreadcrumbDropdownContext value={childContext}>\n {collapsible && !isEmpty ? (\n // Animated expand / collapse via a CSS grid-rows transition (0fr ↔ 1fr). The children stay\n // mounted while collapsed so the filter registry keeps receiving their visibility; `inert`\n // + `aria-hidden` take the collapsed content out of the a11y tree and tab order. An active\n // filter query force-expands (`isExpanded` includes `filtering`).\n <div\n className={cn(\n 'tw:grid tw:transition-[grid-template-rows] tw:duration-200 tw:ease-out',\n 'tw:motion-reduce:transition-none',\n isExpanded ? 'tw:grid-rows-[1fr]' : 'tw:grid-rows-[0fr]',\n )}\n >\n <div\n className=\"tw:overflow-hidden\"\n inert={!isExpanded}\n aria-hidden={isExpanded ? undefined : true}\n >\n <div className=\"tw:flex tw:flex-col tw:pl-6\">{children}</div>\n </div>\n </div>\n ) : (\n <div\n className=\"tw:flex tw:flex-col tw:pl-6\"\n style={isExpanded ? undefined : { display: 'none' }}\n >\n {children}\n </div>\n )}\n </BreadcrumbDropdownContext>\n </div>\n );\n};\n","import { use, useEffect, useId } from 'react';\nimport type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdownContext, getNodeText, matchesQuery } from './BreadcrumbDropdownContext';\n\nconst itemClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:cursor-pointer',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-normal',\n 'tw:text-foreground',\n 'tw:no-underline',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // hover / active entity\n 'tw:hover:bg-hover',\n 'tw:data-[active]:bg-selected',\n 'tw:data-[active]:font-medium',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\ntype BreadcrumbDropdownItemProps = ComponentProps<'button'> & {\n /** Render the consumer's element (typically a router link) instead of a `button`. */\n asChild?: boolean;\n /**\n * Text the built-in filter matches against. Defaults to the item's rendered text content\n * (extracted recursively, so `asChild` links with icons work out of the box).\n */\n textValue?: string;\n /** Marks the currently open entity (highlight + `aria-current`). */\n active?: boolean;\n /** Close the panel when the item is selected. Default `true`. */\n closeOnSelect?: boolean;\n};\n\n/**\n * One selectable entity row inside `Breadcrumb.Dropdown`. Self-hides when it doesn't match the\n * panel's filter query and closes the panel on select. Use `asChild` to render a router link.\n */\nexport const BreadcrumbDropdownItem = ({\n ref,\n asChild = false,\n textValue,\n active = false,\n closeOnSelect = true,\n className,\n children,\n onClick,\n ...props\n}: BreadcrumbDropdownItemProps) => {\n const context = use(BreadcrumbDropdownContext);\n if (!context) {\n throw new Error('Breadcrumb.Dropdown.Item must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n\n const text = textValue ?? getNodeText(children);\n const visible =\n context.filterDisabled ||\n !context.query ||\n context.forceVisible ||\n matchesQuery(text, context.query);\n\n useEffect(() => context.register(id, visible), [context, id, visible]);\n\n if (!visible) return null;\n\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n {...(asChild ? {} : { type: 'button' as const })}\n data-active={active || undefined}\n aria-current={active || undefined}\n className={cn(itemClass, className)}\n onClick={(event) => {\n onClick?.(event);\n if (closeOnSelect && !event.defaultPrevented) {\n context.close();\n }\n }}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'a'> & {\n asChild?: boolean;\n};\n\nexport const BreadcrumbLink = ({ ref, asChild = false, className, ...props }: Props) => {\n const Comp = asChild ? Slot : 'a';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n // font\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:no-underline',\n\n // hover\n 'tw:hover:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n 'tw:focus-visible:rounded-sm',\n\n // Icon\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n\n // transition\n 'tw:transition-colors',\n className,\n )}\n {...props}\n />\n );\n};\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport type { ComponentRef, ReactNode } from 'react';\n\nimport { SearchInput } from '../../blocks/SearchInput';\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Popover } from '../Popover';\n\nimport {\n BreadcrumbDropdownContext,\n type BreadcrumbDropdownToggles,\n NO_TOGGLES,\n normalizeQuery,\n useMatchRegistry,\n withToggle,\n} from './BreadcrumbDropdownContext';\nimport { BreadcrumbDropdownGroup } from './BreadcrumbDropdownGroup';\nimport { BreadcrumbDropdownItem } from './BreadcrumbDropdownItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\n\n// Chevron trigger, the only button in the crumb; no outline, only a hover / open background.\nconst chevronButtonClass = cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n 'tw:size-5',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n 'tw:hover:bg-hover',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-hover',\n 'tw:data-[state=open]:text-foreground',\n\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n 'tw:[&_svg]:transition-transform',\n 'tw:[&[data-state=open]_svg]:rotate-180',\n);\n\n// Plain label: `BreadcrumbLink` typography without hover / focus, as it isn't interactive.\nconst plainLabelClass = cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n);\n\n// Fixed width per `size`, clamped to the viewport; long names truncate instead of widening it.\nconst PANEL_BASE = 'tw:max-h-[min(640px,var(--radix-popover-content-available-height))]';\n\nconst PANEL_WIDTH = {\n small: 'tw:w-[min(360px,var(--radix-popover-content-available-width))]',\n medium: 'tw:w-[min(440px,var(--radix-popover-content-available-width))]',\n large: 'tw:w-[min(560px,var(--radix-popover-content-available-width))]',\n} as const;\n\ntype PanelSize = keyof typeof PANEL_WIDTH;\n\ntype BreadcrumbDropdownProps = {\n /** Never the trigger. With `splitTrigger`, pass an anchor-like element so it navigates. */\n label: ReactNode;\n /** Renders `label` through `Breadcrumb.Link asChild`; default `false` (plain text). */\n splitTrigger?: boolean;\n /** Chevron's accessible name; defaults to `\"${label} menu\"`, or `\"Open menu\"` for a node label. */\n triggerLabel?: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Panel width: `small` 360px, `medium` 440px (default), `large` 560px. */\n size?: PanelSize;\n /**\n * Pinned filter input, focused on open; default on. Non-matching items / groups hide\n * (by `textValue` / string content).\n */\n filter?: boolean;\n /** `false` keeps the input but disables built-in matching; the consumer filters. */\n shouldFilter?: boolean;\n /** Controlled filter value. */\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n /** Rendered when the built-in filter hides everything. Default `\"No results.\"`. */\n emptyMessage?: ReactNode;\n /** The panel's own classes, e.g. a background the search row shares with the list. */\n panelClassName?: string;\n /** `Breadcrumb.Dropdown.Group` / `Breadcrumb.Dropdown.Item` elements. */\n children: ReactNode;\n};\n\n/**\n * Breadcrumb segment opening a filterable switcher of sibling entities.\n *\n * - Use on the leftmost segment with siblings worth switching between; at most one per breadcrumb.\n * - Not for row actions (`PageHeader.Detail` `overflowActions`) or a collapsed middle (`Ellipsis`).\n * - Render inside `Breadcrumb.Item` in place of `Breadcrumb.Link`.\n */\nexport const BreadcrumbDropdown = ({\n label,\n splitTrigger = false,\n triggerLabel,\n open,\n defaultOpen = false,\n onOpenChange,\n size = 'medium',\n filter = true,\n shouldFilter = true,\n searchValue,\n onSearchChange,\n searchPlaceholder = 'Search…',\n emptyMessage = 'No results.',\n panelClassName,\n children,\n}: BreadcrumbDropdownProps) => {\n const searchRef = useRef<ComponentRef<'input'>>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [internalQuery, setInternalQuery] = useState('');\n const stampRef = useRef(0);\n const stamp = useCallback(() => ++stampRef.current, []);\n const [allExpanded, setAllExpandedState] = useState<BreadcrumbDropdownToggles>(NO_TOGGLES);\n const setAllExpanded = useCallback(\n (expanded: boolean, scope: string) =>\n setAllExpandedState((prev) => withToggle(prev, scope, { expanded, at: stamp() })),\n [stamp],\n );\n const { register, anyVisible } = useMatchRegistry();\n\n const isOpen = open ?? internalOpen;\n // Reopening starts from each group's own default again, however the panel closed.\n const [wasOpen, setWasOpen] = useState(isOpen);\n if (wasOpen !== isOpen) {\n setWasOpen(isOpen);\n if (!isOpen) setAllExpandedState(NO_TOGGLES);\n }\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n setInternalOpen(nextOpen);\n if (!nextOpen) setInternalQuery('');\n onOpenChange?.(nextOpen);\n },\n [onOpenChange],\n );\n const close = useCallback(() => handleOpenChange(false), [handleOpenChange]);\n\n const effectiveTriggerLabel =\n triggerLabel ?? (typeof label === 'string' ? `${label} menu` : 'Open menu');\n\n const rawQuery = searchValue ?? internalQuery;\n const filterDisabled = !filter || !shouldFilter;\n const query = filterDisabled ? '' : normalizeQuery(rawQuery);\n\n const contextValue = useMemo(\n () => ({\n query,\n forceVisible: false,\n filterDisabled,\n register,\n close,\n allExpanded,\n setAllExpanded,\n stamp,\n }),\n [query, filterDisabled, register, close, allExpanded, setAllExpanded, stamp],\n );\n\n return (\n <Popover open={isOpen} onOpenChange={handleOpenChange}>\n <span className=\"tw:flex tw:items-center tw:gap-0.5\">\n {splitTrigger ? (\n <BreadcrumbLink asChild>{label}</BreadcrumbLink>\n ) : (\n <span className={plainLabelClass}>{label}</span>\n )}\n <Popover.Trigger asChild>\n <button type=\"button\" aria-label={effectiveTriggerLabel} className={chevronButtonClass}>\n <ChevronDown className=\"tw:size-3.5\" />\n </button>\n </Popover.Trigger>\n </span>\n <Popover.Content\n align=\"start\"\n sideOffset={8}\n collisionPadding={16}\n data-size={size}\n className={cn('tw:overflow-hidden tw:p-0', PANEL_BASE, PANEL_WIDTH[size], panelClassName)}\n onOpenAutoFocus={\n filter\n ? (event) => {\n event.preventDefault();\n searchRef.current?.focus();\n }\n : undefined\n }\n >\n {filter && (\n <div\n data-slot=\"breadcrumb-dropdown-search\"\n className=\"tw:shrink-0 tw:border-0 tw:border-b tw:border-solid tw:border-border tw:p-2\"\n >\n <SearchInput\n ref={searchRef}\n value={rawQuery}\n onValueChange={(value) => {\n setInternalQuery(value);\n onSearchChange?.(value);\n }}\n placeholder={searchPlaceholder}\n allowClear\n // Debounce only when the consumer filters itself (e.g. server-side).\n disableDebounce={shouldFilter}\n />\n </div>\n )}\n <div className=\"tw:flex tw:flex-1 tw:flex-col tw:overflow-y-auto tw:p-2\">\n <BreadcrumbDropdownContext value={contextValue}>{children}</BreadcrumbDropdownContext>\n {!filterDisabled && !!query && !anyVisible && (\n <span className=\"tw:px-2 tw:py-1.5 tw:text-sm tw:text-muted-foreground\">\n {emptyMessage}\n </span>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n};\n\nBreadcrumbDropdown.Item = BreadcrumbDropdownItem;\nBreadcrumbDropdown.Group = BreadcrumbDropdownGroup;\n","import type { ComponentProps } from 'react';\n\nimport { Ellipsis } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const BreadcrumbEllipsis = ({ ref, className, ...props }: Props) => (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n // Match the Breadcrumb.Dropdown chevron trigger: background + colour lift on hover / while the\n // menu is open, so the two interactive breadcrumb affordances read consistently.\n 'tw:hover:bg-hover',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-hover',\n 'tw:data-[state=open]:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n 'tw:p-1',\n className,\n )}\n {...props}\n >\n <Ellipsis className=\"tw:size-4\" />\n <span className=\"tw:sr-only\">More</span>\n </button>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbItem = ({ className, ...props }: Props) => (\n <li className={cn('tw:inline-flex', 'tw:items-center', className)} {...props} />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'ol'>;\n\nexport const BreadcrumbList = ({ className, ...props }: Props) => (\n <ol\n className={cn(\n // layout\n 'tw:flex',\n 'tw:flex-wrap',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:m-0',\n 'tw:p-0',\n\n // font\n 'tw:break-words',\n 'tw:text-sm',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'span'>;\n\nexport const BreadcrumbPage = ({ ref, className, ...props }: Props) => (\n <span\n ref={ref}\n // Do not use the anchor, as this item is not clickable\n // oxlint-disable-next-line jsx_a11y/prefer-tag-over-role\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('tw:font-medium', 'tw:text-foreground', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbSeparator = ({ children, className, ...props }: Props) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:aspect-square',\n 'tw:size-[15px]',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-2.5',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n >\n {children ?? <span className=\"tw:select-none tw:text-sm tw:text-muted-foreground/50\">/</span>}\n </li>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdown } from './BreadcrumbDropdown';\nimport { BreadcrumbEllipsis } from './BreadcrumbEllipsis';\nimport { BreadcrumbItem } from './BreadcrumbItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\nimport { BreadcrumbList } from './BreadcrumbList';\nimport { BreadcrumbPage } from './BreadcrumbPage';\nimport { BreadcrumbSeparator } from './BreadcrumbSeparator';\n\ntype Props = ComponentProps<'nav'>;\n\nexport const Breadcrumb = ({ className, ...props }: Props) => (\n <nav aria-label=\"breadcrumb\" className={cn('tailwindcss-preflight', className)} {...props} />\n);\n\nBreadcrumb.List = BreadcrumbList;\nBreadcrumb.Item = BreadcrumbItem;\nBreadcrumb.Link = BreadcrumbLink;\nBreadcrumb.Page = BreadcrumbPage;\nBreadcrumb.Separator = BreadcrumbSeparator;\nBreadcrumb.Ellipsis = BreadcrumbEllipsis;\nBreadcrumb.Dropdown = BreadcrumbDropdown;\n"],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { cn } from "./classNames-
|
|
1
|
+
import { cn } from "./classNames-DkX30VJU.js";
|
|
2
|
+
import { Tooltip } from "./utils-DjFceY3H.js";
|
|
2
3
|
import { mergeRefs } from "./internal/utils/mergeRefs.js";
|
|
3
|
-
import { Loader2 } from "./icons-
|
|
4
|
+
import { Loader2 } from "./icons-DDR9dFSr.js";
|
|
4
5
|
import { Fragment, createElement, isValidElement, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
6
|
import { Root, Slottable } from "@radix-ui/react-slot";
|
|
6
7
|
import { cva } from "class-variance-authority";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
|
|
9
|
+
// src/components/Button/motion.ts
|
|
9
10
|
const ends = (animation) => Number.isFinite(animation.effect?.getComputedTiming().endTime);
|
|
10
11
|
/** Runs `callback` once the finite `animations` have finished or been cancelled; returns a cancel. */
|
|
11
12
|
const afterAnimations = (animations, callback) => {
|
|
@@ -41,8 +42,7 @@ const armMotion = (node) => {
|
|
|
41
42
|
requestAnimationFrame(tick);
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
|
-
|
|
45
|
-
//#region src/components/Button/ButtonLabel.tsx
|
|
45
|
+
// src/components/Button/ButtonLabel.tsx
|
|
46
46
|
const isText = (node) => typeof node === "string" || typeof node === "number";
|
|
47
47
|
/** Milliseconds from a computed `transition-duration` such as `0.3s`. */
|
|
48
48
|
const toMs = (duration) => parseFloat(duration) * (duration.endsWith("ms") ? 1 : 1e3);
|
|
@@ -128,8 +128,7 @@ const withLabels = (children) => {
|
|
|
128
128
|
});
|
|
129
129
|
return createElement(Fragment, null, ...wrapped);
|
|
130
130
|
};
|
|
131
|
-
|
|
132
|
-
//#region src/components/Button/styles.ts
|
|
131
|
+
// src/components/Button/styles.ts
|
|
133
132
|
const buttonVariants = cva([
|
|
134
133
|
"tailwindcss-preflight",
|
|
135
134
|
"tw:relative",
|
|
@@ -257,8 +256,7 @@ const buttonVariants = cva([
|
|
|
257
256
|
}
|
|
258
257
|
}
|
|
259
258
|
});
|
|
260
|
-
|
|
261
|
-
//#region src/components/Button/Button.tsx
|
|
259
|
+
// src/components/Button/Button.tsx
|
|
262
260
|
/** The children that render anything, looking through arrays and fragments. */
|
|
263
261
|
const renderedChildren = (node) => {
|
|
264
262
|
if (Array.isArray(node)) return node.flatMap(renderedChildren);
|
|
@@ -269,12 +267,11 @@ const renderedChildren = (node) => {
|
|
|
269
267
|
* Any user-initiated action; `size="icon-*"` with no children is the icon-only button.
|
|
270
268
|
*
|
|
271
269
|
* - Not for: inline text links (`ButtonInline`), URL navigation (`Link`), action + dropdown (`SplitButton`).
|
|
272
|
-
* - Wrap in `Tooltip` when icon-only
|
|
270
|
+
* - Wrap in `Tooltip` when icon-only; `disabledReason` when disabled; `Popconfirm` for destructive actions.
|
|
273
271
|
*
|
|
274
|
-
* @see RECIPES.md#disabled-button-tooltip
|
|
275
272
|
* @see RECIPES.md#confirm-dialog
|
|
276
273
|
*/
|
|
277
|
-
const Button = ({ ref, children, disabled = false, className, type = "button", isLoading = false, asChild = false, onClick, variant = "primary", size = "medium", block = false, ...buttonProps }) => {
|
|
274
|
+
const Button = ({ ref, children, disabled = false, className, type = "button", isLoading = false, asChild = false, onClick, variant = "primary", size = "medium", block = false, disabledReason, ...buttonProps }) => {
|
|
278
275
|
const Comp = asChild ? Root : "button";
|
|
279
276
|
const isIconOnly = String(size).startsWith("icon");
|
|
280
277
|
const classNames = buttonVariants({
|
|
@@ -334,18 +331,19 @@ const Button = ({ ref, children, disabled = false, className, type = "button", i
|
|
|
334
331
|
const entries = [...node.querySelectorAll(":scope > svg")].flatMap((icon) => icon.getAnimations?.() ?? []);
|
|
335
332
|
return afterAnimations(entries, () => setIconEnter("fade"));
|
|
336
333
|
}, [iconEnter]);
|
|
334
|
+
const hasDisabledReason = !!disabledReason;
|
|
337
335
|
const handleClick = (event) => {
|
|
338
|
-
if (event.currentTarget.tagName === "A" && disabled) {
|
|
336
|
+
if (event.currentTarget.tagName === "A" && disabled || hasDisabledReason) {
|
|
339
337
|
event.preventDefault();
|
|
340
338
|
return;
|
|
341
339
|
}
|
|
342
340
|
onClick?.(event);
|
|
343
341
|
};
|
|
344
|
-
|
|
342
|
+
const button = /* @__PURE__ */ jsxs(Comp, {
|
|
345
343
|
...buttonProps,
|
|
346
344
|
ref: mergedRef,
|
|
347
|
-
disabled,
|
|
348
|
-
"aria-disabled": buttonProps["aria-disabled"] ?? disabled,
|
|
345
|
+
disabled: disabled && !hasDisabledReason,
|
|
346
|
+
"aria-disabled": buttonProps["aria-disabled"] ?? (disabled || hasDisabledReason),
|
|
349
347
|
"data-variant": variant,
|
|
350
348
|
"data-icon-only": isIconOnly,
|
|
351
349
|
"data-icon-enter": iconEnter,
|
|
@@ -362,9 +360,16 @@ const Button = ({ ref, children, disabled = false, className, type = "button", i
|
|
|
362
360
|
children: /* @__PURE__ */ jsx(Loader2, { className: "tw:animate-spin" })
|
|
363
361
|
}), /* @__PURE__ */ jsx(Slottable, { children: asChild ? children : withLabels(children) })]
|
|
364
362
|
});
|
|
363
|
+
if (!hasDisabledReason) return button;
|
|
364
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
365
|
+
tooltip: disabledReason,
|
|
366
|
+
placement: "top",
|
|
367
|
+
variant: "explanatory",
|
|
368
|
+
triggerAsChild: true,
|
|
369
|
+
children: button
|
|
370
|
+
});
|
|
365
371
|
};
|
|
366
|
-
|
|
367
|
-
//#region src/components/Button/ButtonInline.tsx
|
|
372
|
+
// src/components/Button/ButtonInline.tsx
|
|
368
373
|
const buttonInlineVariants = cva([
|
|
369
374
|
"tailwindcss-preflight",
|
|
370
375
|
"tw:inline-flex",
|
|
@@ -419,7 +424,6 @@ const ButtonInline = ({ ref, children, className, variant, color, type = "button
|
|
|
419
424
|
children
|
|
420
425
|
});
|
|
421
426
|
};
|
|
422
|
-
//#endregion
|
|
423
427
|
export { Button, ButtonInline, buttonVariants };
|
|
424
428
|
|
|
425
|
-
//# sourceMappingURL=Button-
|
|
429
|
+
//# sourceMappingURL=Button-DbvGzEDb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button-DbvGzEDb.js","names":[],"sources":["../src/components/Button/motion.ts","../src/components/Button/ButtonLabel.tsx","../src/components/Button/styles.ts","../src/components/Button/Button.tsx","../src/components/Button/ButtonInline.tsx"],"sourcesContent":["const ends = (animation: Animation) =>\n Number.isFinite(animation.effect?.getComputedTiming().endTime);\n\n/** Runs `callback` once the finite `animations` have finished or been cancelled; returns a cancel. */\nexport const afterAnimations = (animations: Animation[], callback: () => void) => {\n let isCurrent = true;\n Promise.allSettled(animations.filter(ends).map((animation) => animation.finished)).then(() => {\n if (isCurrent) callback();\n });\n return () => {\n isCurrent = false;\n };\n};\n\nlet waiting = new Set<Element>();\nlet framed = new Set<Element>();\nlet isTicking = false;\n\nconst tick = () => {\n for (const node of framed) if (node.isConnected) node.setAttribute('data-button-ready', '');\n framed = waiting;\n waiting = new Set();\n isTicking = framed.size > 0;\n if (isTicking) requestAnimationFrame(tick);\n};\n\n/**\n * Sets `data-button-ready` on `node` two frames after it mounts, arming its entry animations.\n *\n * - One shared frame loop serves every Button mounting at once.\n * - Arming twice is a no-op, so a re-attached ref doesn't restart the countdown.\n */\nexport const armMotion = (node: Element) => {\n if (node.hasAttribute('data-button-ready') || waiting.has(node) || framed.has(node)) return;\n waiting.add(node);\n if (!isTicking) {\n isTicking = true;\n requestAnimationFrame(tick);\n }\n};\n","import {\n createElement,\n Fragment,\n isValidElement,\n type ReactNode,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { afterAnimations } from './motion';\n\nconst isText = (node: ReactNode): node is string | number =>\n typeof node === 'string' || typeof node === 'number';\n\n/** Milliseconds from a computed `transition-duration` such as `0.3s`. */\nconst toMs = (duration: string) => parseFloat(duration) * (duration.endsWith('ms') ? 1 : 1000);\n\n/**\n * A button's text, rolled over when it changes.\n *\n * - The new text rolls in; the old one stays absolutely positioned while it rolls out.\n * - The width animates from the old text's to the new one's, so neighbours slide instead of jumping.\n * - Motion lives in `styles.css` under `[data-slot='button-label']`.\n */\nconst ButtonLabel = ({ text }: { text: string }) => {\n const ref = useRef<HTMLSpanElement>(null);\n const exitRef = useRef<HTMLSpanElement>(null);\n const interruptedWidthRef = useRef<number | null>(null);\n const [shown, setShown] = useState(text);\n const [exiting, setExiting] = useState<string | null>(null);\n const [hasChanged, setHasChanged] = useState(false);\n if (shown !== text) {\n setShown(text);\n setExiting(shown);\n setHasChanged(true);\n }\n\n useLayoutEffect(() => {\n const node = ref.current;\n // An interrupted animation's on-screen width, else the outgoing text's, still in the DOM.\n const from = interruptedWidthRef.current ?? exitRef.current?.offsetWidth;\n interruptedWidthRef.current = null;\n if (!node || !from || !node.closest('[data-button-ready]')) return;\n\n const to = node.offsetWidth;\n if (\n Math.abs(to - from) < 0.5 ||\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches\n )\n return;\n\n const { transitionDuration, transitionTimingFunction } = getComputedStyle(node);\n const animation = node.animate?.(\n [\n { width: `${from}px`, overflowX: 'clip', textAlign: 'start' },\n { width: `${to}px`, overflowX: 'clip', textAlign: 'start' },\n ],\n { duration: toMs(transitionDuration), easing: transitionTimingFunction },\n );\n return () => {\n if (animation?.playState === 'running') {\n interruptedWidthRef.current = node.offsetWidth;\n }\n animation?.cancel();\n };\n }, [text]);\n\n useEffect(() => {\n const node = exitRef.current;\n if (!node) return;\n return afterAnimations(node.getAnimations?.() ?? [], () => setExiting(null));\n }, [exiting]);\n\n // Bare text until the first change, so an unchanged button keeps its markup.\n if (!hasChanged) return text;\n\n return (\n <span ref={ref} data-slot=\"button-label\">\n <span key={text} data-slot=\"button-label-text\">\n {text}\n </span>\n {exiting !== null && (\n <span key={exiting} ref={exitRef} aria-hidden data-slot=\"button-label-exit\">\n {exiting}\n </span>\n )}\n </span>\n );\n};\n\n/**\n * `children` with each run of text wrapped in a `ButtonLabel`.\n *\n * - Positions are kept: a joined run leaves `null` behind, so siblings keep their identity.\n * - Whitespace-only text stays bare: as a span it would become a flex item and take a gap.\n */\nexport const withLabels = (children: ReactNode): ReactNode => {\n if (isValidElement<{ children?: ReactNode }>(children) && children.type === Fragment) {\n return withLabels(children.props.children);\n }\n const items = Array.isArray(children) ? children : [children];\n const wrapped = items.map((item: ReactNode, index) => {\n if (!isText(item)) return item;\n if (index > 0 && isText(items[index - 1])) return null;\n\n let text = '';\n for (let i = index; i < items.length && isText(items[i]); i++) text += String(items[i]);\n return text.trim() ? <ButtonLabel key={index} text={text} /> : text;\n });\n return createElement(Fragment, null, ...wrapped);\n};\n","import { cva } from 'class-variance-authority';\n\n// Opaque tints use `bg-[color-mix(in_oklab,rgb(var(--tint))_N%,rgb(var(--base)))]`, not `bg-<token>/N`.\n//\n// - `bg-<token>/N` mixes into `transparent`, showing whatever the button overlaps.\n// - Raw `--*` triples: `--color-*` exist at build time only; unresolved → `transparent`.\n// - Write the whole class literally — Tailwind scans source; assembled strings get no CSS.\n\nexport const buttonVariants = cva(\n [\n 'tailwindcss-preflight',\n\n // layout\n 'tw:relative',\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:whitespace-nowrap',\n 'tw:gap-2',\n\n // border\n 'tw:border',\n 'tw:border-transparent',\n 'tw:rounded-[var(--radius-lg,0.25rem)]',\n\n // text\n 'tw:font-medium',\n 'tw:select-none',\n\n // focus visible\n 'tw:!outline-hidden',\n 'tw:focus-visible:ring-2',\n\n // disabled\n 'tw:disabled:cursor-not-allowed',\n 'tw:disabled:opacity-disabled',\n 'tw:active:opacity-60',\n\n 'tw:transition-all',\n\n // anchor support\n 'tw:!no-underline',\n 'tw:aria-disabled:cursor-not-allowed',\n 'tw:aria-disabled:opacity-disabled',\n\n // icon\n 'tw:shrink-0',\n 'tw:[&_svg]:pointer-events-none',\n 'tw:[&_svg]:shrink-0',\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n ],\n {\n defaultVariants: {\n variant: 'primary',\n size: 'medium',\n },\n variants: {\n block: {\n true: ['tw:w-full'],\n },\n variant: {\n primary: [\n 'tw:bg-primary',\n 'tw:text-primary-foreground',\n 'tw:[a]:hover:bg-primary/80',\n 'tw:hover:not-disabled:bg-primary/90',\n 'tw:hover:text-primary-foreground',\n 'tw:focus:text-primary-foreground',\n\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-ring/50',\n ],\n secondary: [\n 'tw:bg-primary/10',\n 'tw:text-primary',\n 'tw:hover:not-disabled:bg-primary/20',\n\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-ring/50',\n ],\n\n // Kai's actions: its gradient, three light pools drifting behind the label.\n // The gradient sits on the primary blue, so the label is primary's own foreground.\n kai: [\n 'tw:bg-kai',\n 'tw:animate-kai-drift',\n 'tw:motion-reduce:animate-none',\n 'tw:text-primary-foreground',\n 'tw:hover:text-primary-foreground',\n 'tw:focus:text-primary-foreground',\n 'tw:hover:not-disabled:brightness-110',\n 'tw:focus-visible:ring-ring/50',\n ],\n // should be called \"destructive\" by Figma\n danger: [\n 'tw:bg-destructive',\n 'tw:text-destructive-foreground',\n 'tw:hover:not-disabled:bg-destructive/90',\n 'tw:hover:text-destructive-foreground',\n 'tw:focus:text-destructive-foreground',\n\n 'tw:focus-visible:border-destructive',\n 'tw:focus-visible:ring-destructive/20',\n ],\n outline: [\n 'tw:!border-input',\n 'tw:bg-background',\n 'tw:bg-clip-padding',\n // Semantic text color so the label/icon flips in dark mode (matches `invisible`).\n 'tw:text-foreground',\n // Hover hue comes from the brand primary, not the fixed `accent` blue.\n //\n // - Fill mixes into `--background`: `bg-clip-padding` gives a translucent fill no backing.\n // - The *chrome* border carries the state (fill is ~1.5:1); `--primary` is for `focus-visible`.\n // - Border is solid, not a tint: its contrast would depend on the call site.\n 'tw:hover:not-disabled:bg-[color-mix(in_oklab,rgb(var(--primary))_10%,rgb(var(--background)))]',\n 'tw:hover:not-disabled:!border-muted-foreground',\n 'tw:hover:not-disabled:text-primary',\n 'tw:hover:active:bg-background',\n 'tw:focus-visible:!border-primary',\n 'tw:focus-visible:ring-ring/50',\n ],\n\n // should be called \"ghost\" by Figma\n invisible: [\n 'tw:bg-transparent',\n 'tw:bg-clip-padding',\n 'tw:text-foreground',\n 'tw:hover:not-disabled:bg-primary/10',\n 'tw:hover:not-disabled:text-primary',\n 'tw:hover:not-disabled:border-primary/10',\n\n 'tw:focus-visible:ring-ring/50',\n ],\n // should be called \"link\" by Figma\n inline: [\n 'tw:bg-transparent',\n 'tw:text-primary',\n 'tw:hover:underline',\n 'tw:hover:active:bg-transparent',\n 'tw:focus-visible:ring-ring/50',\n ],\n },\n size: {\n // should be called \"default\" by Figma\n medium: ['tw:max-h-9', 'tw:py-2', 'tw:px-4', 'tw:text-sm'],\n // should be called \"small\" by Figma\n small: ['tw:max-h-8', 'tw:py-2', 'tw:px-3', 'tw:text-xs'],\n // should be called \"large\" by Figma\n large: ['tw:max-h-10', 'tw:py-2.5', 'tw:px-6', 'tw:text-sm'],\n\n 'icon-lg': ['tw:size-10'],\n icon: ['tw:size-9'],\n 'icon-sm': ['tw:size-8'],\n 'icon-xs': ['tw:size-6'],\n // No size of their own: the button takes its content's.\n 'icon-2xs': [],\n 'icon-3xs': [],\n },\n },\n },\n);\n","import {\n type ComponentProps,\n Fragment,\n isValidElement,\n type ReactNode,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Root, Slottable } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { Loader2 } from '../../icons';\nimport { cn, mergeRefs } from '../../utils';\nimport { Tooltip } from '../Tooltip';\n\nimport { withLabels } from './ButtonLabel';\nimport { afterAnimations, armMotion } from './motion';\nimport { buttonVariants } from './styles';\n\n/** Props for `Button`; icons are composed as children. */\ntype Props = {\n /** Shows a spinner in place of the leading icon, or before the label when there is none. The caller still controls `disabled`. */\n isLoading?: boolean;\n /** Render as a Radix `Slot` so the parent JSX (e.g. a `react-router` `<Link>`) becomes the button element. */\n asChild?: boolean;\n /** Disables the button and shows this on hover and focus; the button stays focusable. */\n disabledReason?: ReactNode;\n} & ComponentProps<'button'> &\n VariantProps<typeof buttonVariants>;\n\n/** The children that render anything, looking through arrays and fragments. */\nconst renderedChildren = (node: ReactNode): ReactNode[] => {\n if (Array.isArray(node)) return node.flatMap(renderedChildren);\n if (isValidElement<{ children?: ReactNode }>(node) && node.type === Fragment) {\n return renderedChildren(node.props.children);\n }\n const isBlank =\n node == null || typeof node === 'boolean' || (typeof node === 'string' && !node.trim());\n return isBlank ? [] : [node];\n};\n\n/**\n * Any user-initiated action; `size=\"icon-*\"` with no children is the icon-only button.\n *\n * - Not for: inline text links (`ButtonInline`), URL navigation (`Link`), action + dropdown (`SplitButton`).\n * - Wrap in `Tooltip` when icon-only; `disabledReason` when disabled; `Popconfirm` for destructive actions.\n *\n * @see RECIPES.md#confirm-dialog\n */\nexport const Button = ({\n ref,\n children,\n disabled = false,\n className,\n type = 'button',\n isLoading = false,\n asChild = false,\n onClick,\n variant = 'primary',\n size = 'medium',\n block = false,\n disabledReason,\n ...buttonProps\n}: Props) => {\n const Comp = asChild ? Root : 'button';\n const isIconOnly = String(size).startsWith('icon');\n const classNames = buttonVariants({ variant, size, block, className });\n\n const content =\n asChild && isValidElement<{ children?: ReactNode }>(children)\n ? children.props.children\n : children;\n const rendered = renderedChildren(content);\n const leadsWithElement = isValidElement(rendered[0]);\n const elementTypes = rendered.flatMap((child) => (isValidElement(child) ? [child.type] : []));\n\n // The previous render's children, which decide how the spinner and a new icon enter.\n const [prev, setPrev] = useState({ leadsWithElement, elementTypes });\n const [spinnerEnter, setSpinnerEnter] = useState<'grow' | 'fade' | null>(\n isLoading ? 'fade' : null,\n );\n const [iconEnter, setIconEnter] = useState<'grow' | 'fade'>('fade');\n const placement = isIconOnly ? 'center' : leadsWithElement ? 'leading' : 'inline';\n\n if (isLoading && !spinnerEnter) {\n // `fade` also when the caller dropped its leading icon this render: the spinner takes that icon's place.\n setSpinnerEnter(placement === 'inline' && !prev.leadsWithElement ? 'grow' : 'fade');\n }\n const typesChanged =\n prev.elementTypes.length !== elementTypes.length ||\n prev.elementTypes.some((type, index) => type !== elementTypes[index]);\n if (typesChanged || prev.leadsWithElement !== leadsWithElement) {\n setPrev({ leadsWithElement, elementTypes });\n }\n if (typesChanged) {\n const isAdded = elementTypes.length > prev.elementTypes.length;\n setIconEnter(isAdded && !isLoading && !spinnerEnter ? 'grow' : 'fade');\n }\n\n // The spinner stays mounted through its exit transition and unmounts when that ends.\n const spinnerRef = useRef<HTMLSpanElement>(null);\n useEffect(() => {\n const node = spinnerRef.current;\n if (isLoading || !node) return;\n return afterAnimations(node.getAnimations?.() ?? [], () => setSpinnerEnter(null));\n }, [isLoading]);\n\n // A leading spinner is kept centred over the leading icon while the button resizes.\n useLayoutEffect(() => {\n const slot = spinnerRef.current;\n const button = slot?.offsetParent;\n if (!slot || !button || placement !== 'leading') return;\n const centre = () => {\n const icon = slot.nextElementSibling;\n if (!(icon instanceof SVGElement)) return;\n const [iconBox, buttonBox] = [icon.getBoundingClientRect(), button.getBoundingClientRect()];\n const scale = buttonBox.width / (button instanceof HTMLElement ? button.offsetWidth : 1) || 1;\n const x = (iconBox.left - buttonBox.left + iconBox.width / 2) / scale - button.clientLeft;\n slot.style.left = `${x - parseFloat(getComputedStyle(slot).width) / 2}px`;\n };\n centre();\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(centre);\n observer.observe(button);\n return () => observer.disconnect();\n }, [placement, spinnerEnter]);\n\n // `data-button-ready` arms the entry animations a frame after mount, so nothing animates on page load.\n const buttonRef = useRef<HTMLButtonElement>(null);\n const armRef = useCallback(\n (node: HTMLButtonElement | null) => (node ? armMotion(node) : undefined),\n [],\n );\n const mergedRef = useMemo(() => mergeRefs(ref, buttonRef, armRef), [ref, armRef]);\n\n // `grow` lasts only through the entry, so a later rotation or swap keeps the default origin.\n useEffect(() => {\n const node = buttonRef.current;\n if (iconEnter !== 'grow' || !node) return;\n const entries = [...node.querySelectorAll(':scope > svg')].flatMap(\n (icon) => icon.getAnimations?.() ?? [],\n );\n return afterAnimations(entries, () => setIconEnter('fade'));\n }, [iconEnter]);\n\n const hasDisabledReason = !!disabledReason;\n\n const handleClick: ComponentProps<'button'>['onClick'] = (event) => {\n const isAnchor = event.currentTarget.tagName === 'A';\n\n // <a/> does not support disabled by default, and we cannot use pointer-events: none because cursor-not-allowed would not work.\n if ((isAnchor && disabled) || hasDisabledReason) {\n event.preventDefault();\n return;\n }\n\n onClick?.(event);\n };\n\n const button = (\n <Comp\n {...buttonProps}\n ref={mergedRef}\n // A disabled reason keeps the button focusable and hoverable, so its tooltip can show.\n disabled={disabled && !hasDisabledReason}\n // An explicit `aria-disabled` wins: unavailable yet focusable, unlike `disabled`.\n aria-disabled={buttonProps['aria-disabled'] ?? (disabled || hasDisabledReason)}\n data-variant={variant}\n // Icon-only flag; `ButtonGroup space=\"block\"` stretches only non-icon children.\n data-icon-only={isIconOnly}\n data-icon-enter={iconEnter}\n type={type}\n onClick={handleClick}\n className={cn(classNames)}\n >\n {spinnerEnter && (\n // Motion lives in `styles.css` under `[data-slot='button-spinner']`.\n <span\n ref={spinnerRef}\n aria-hidden\n data-slot=\"button-spinner\"\n data-state={isLoading ? 'open' : 'closed'}\n data-placement={placement}\n data-enter={spinnerEnter}\n >\n <Loader2 className=\"tw:animate-spin\" />\n </span>\n )}\n <Slottable>{asChild ? children : withLabels(children)}</Slottable>\n </Comp>\n );\n\n if (!hasDisabledReason) return button;\n return (\n <Tooltip tooltip={disabledReason} placement=\"top\" variant=\"explanatory\" triggerAsChild>\n {button}\n </Tooltip>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Root } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nconst buttonInlineVariants = cva(\n [\n 'tailwindcss-preflight',\n\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:gap-2',\n\n 'tw:underline-offset-2',\n\n 'tw:disabled:opacity-40',\n 'tw:disabled:cursor-not-allowed',\n 'tw:disabled:text-muted-foreground',\n 'tw:disabled:no-underline',\n 'tw:disabled:[&_svg]:text-muted-foreground',\n\n // Default size for nested Lucide icons; callers can override on the icon.\n \"tw:[&_svg.lucide:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n ],\n {\n defaultVariants: {\n variant: 'link',\n color: 'link',\n },\n variants: {\n color: {\n link: ['tw:text-primary', 'tw:hover:text-primary/90', 'tw:[&_svg]:text-primary'],\n dark: ['tw:text-foreground tw:[&_svg]:text-muted-foreground'],\n danger: ['tw:text-error-500 tw:[&_svg]:text-error-500'],\n muted: ['tw:text-muted-foreground tw:[&_svg]:text-muted-foreground'],\n custom: [],\n },\n variant: {\n link: ['tw:underline', 'tw:hover:no-underline'],\n 'link-reverse': ['tw:no-underline', '', 'tw:hover:underline'],\n custom: [],\n },\n },\n },\n);\n\ntype Props = ComponentProps<'button'> &\n VariantProps<typeof buttonInlineVariants> & { asChild?: boolean };\n\nexport const ButtonInline = ({\n ref,\n children,\n className,\n variant,\n color,\n type = 'button',\n asChild = false,\n ...buttonProps\n}: Props) => {\n const Comp = asChild ? Root : 'button';\n\n return (\n <Comp\n {...buttonProps}\n ref={ref}\n type={asChild ? undefined : type}\n className={buttonInlineVariants({ variant, color, className })}\n >\n {children}\n </Comp>\n );\n};\n"],"mappings":"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"}
|