@keboola/design 11.9.0 → 13.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 +45 -14
- package/CHANGELOG.md +246 -0
- package/COMPONENT-API.md +352 -294
- package/README.md +11 -1
- package/dist/{AIKit-ELIsegJz.js → AIKit-DcOlHIBr.js} +420 -247
- package/dist/AIKit-DcOlHIBr.js.map +1 -0
- package/dist/{Alert-BsIM_oFK.js → Alert-UI-CIs-1.js} +16 -16
- package/dist/Alert-UI-CIs-1.js.map +1 -0
- package/dist/{AlertModal-BGJdaRRj.js → AlertModal-mbSnuuka.js} +8 -8
- package/dist/AlertModal-mbSnuuka.js.map +1 -0
- package/dist/{AppShell-DRgJxpXW.js → AppShell-WSQabK8r.js} +15 -52
- package/dist/AppShell-WSQabK8r.js.map +1 -0
- package/dist/{AutoSaveTextarea-BeuWuszr.js → AutoSaveTextarea-C5iIr2Ts.js} +2 -2
- package/dist/{AutoSaveTextarea-BeuWuszr.js.map → AutoSaveTextarea-C5iIr2Ts.js.map} +1 -1
- package/dist/{Badge-o5jURtpB.js → Badge-DIjhwPvh.js} +4 -9
- package/dist/Badge-DIjhwPvh.js.map +1 -0
- package/dist/{BrandEditor-BsTBM3s6.js → BrandEditor-Bkd6dhb8.js} +7 -7
- package/dist/{BrandEditor-BsTBM3s6.js.map → BrandEditor-Bkd6dhb8.js.map} +1 -1
- package/dist/{BrandLogo-CoKBk4MI.js → BrandLogo-CKpVSZb6.js} +4 -4
- package/dist/BrandLogo-CKpVSZb6.js.map +1 -0
- package/dist/{Breadcrumb-xqEUxfwn.js → Breadcrumb-BUoAZyhO.js} +8 -14
- package/dist/Breadcrumb-BUoAZyhO.js.map +1 -0
- package/dist/{Button-DsRrU5F1.js → Button-B21oVcPU.js} +31 -14
- package/dist/Button-B21oVcPU.js.map +1 -0
- package/dist/{Calendar-cG5NIJ4O.js → Calendar-DFtmZzbF.js} +99 -99
- package/dist/Calendar-DFtmZzbF.js.map +1 -0
- package/dist/{Card-Dyo7055Q.js → Card-BQmBWHXl.js} +35 -7
- package/dist/Card-BQmBWHXl.js.map +1 -0
- package/dist/{Checkbox-Dq5fPNrO.js → Checkbox-8yIIgY7g.js} +4 -4
- package/dist/Checkbox-8yIIgY7g.js.map +1 -0
- package/dist/{Clipboard-BZitKiSA.js → Clipboard-_xf6hMDD.js} +2 -2
- package/dist/{Clipboard-BZitKiSA.js.map → Clipboard-_xf6hMDD.js.map} +1 -1
- package/dist/{ClipboardButton-KHQnPEh_.js → ClipboardButton-srUgWgwH.js} +4 -4
- package/dist/{ClipboardButton-KHQnPEh_.js.map → ClipboardButton-srUgWgwH.js.map} +1 -1
- package/dist/{CodeEditor-BJKJXA0c.js → CodeEditor-jZMw1ioj.js} +55 -165
- package/dist/CodeEditor-jZMw1ioj.js.map +1 -0
- package/dist/{ColorInput-Bj3dfPFA.js → ColorInput-B3gBZ8Ya.js} +12 -27
- package/dist/ColorInput-B3gBZ8Ya.js.map +1 -0
- package/dist/{ColorModeSwitch-CWt-DZGC.js → ColorModeSwitch-Bw9wMyoL.js} +7 -17
- package/dist/ColorModeSwitch-Bw9wMyoL.js.map +1 -0
- package/dist/Combobox-C_MTpQ1l.js +1081 -0
- package/dist/Combobox-C_MTpQ1l.js.map +1 -0
- package/dist/{Command-BDU3C1gg.js → Command-BQPiZCNz.js} +4 -4
- package/dist/{Command-BDU3C1gg.js.map → Command-BQPiZCNz.js.map} +1 -1
- package/dist/{CopyField-BHRQUyuF.js → CopyField-Ba7h8MqZ.js} +19 -55
- package/dist/{CopyField-BHRQUyuF.js.map → CopyField-Ba7h8MqZ.js.map} +1 -1
- package/dist/{DateInput-B6N8g0ra.js → DateInput-D0nWUasV.js} +6 -6
- package/dist/{DateInput-B6N8g0ra.js.map → DateInput-D0nWUasV.js.map} +1 -1
- package/dist/{DatePicker-nA8YdE84.js → DatePicker-CtSa9b3V.js} +3 -3
- package/dist/{DatePicker-nA8YdE84.js.map → DatePicker-CtSa9b3V.js.map} +1 -1
- package/dist/{DateRangeInput-7M9Z4cVO.js → DateRangeInput-i6wE45-V.js} +10 -14
- package/dist/DateRangeInput-i6wE45-V.js.map +1 -0
- package/dist/{DateRangePicker-DjSUFjh4.js → DateRangePicker-BAnuz6vO.js} +9 -13
- package/dist/DateRangePicker-BAnuz6vO.js.map +1 -0
- package/dist/DiffView-ppTIzh2h.js.map +1 -1
- package/dist/{DropdownMenu-CgVwhDvl.js → DropdownMenu-gRM-A8qU.js} +3 -3
- package/dist/DropdownMenu-gRM-A8qU.js.map +1 -0
- package/dist/{FieldItem-DZGIdiXE.js → FieldItem-BHViBJS3.js} +12 -25
- package/dist/FieldItem-BHViBJS3.js.map +1 -0
- package/dist/{FieldItem-vhIJW4pj.d.ts → FieldItem-CPN1xjN5.d.ts} +11 -25
- package/dist/{FileUpload-DYQCTGjU.js → FileUpload-Ch2hrIWq.js} +11 -16
- package/dist/{FileUpload-DYQCTGjU.js.map → FileUpload-Ch2hrIWq.js.map} +1 -1
- package/dist/{Form-CcK7dRrC.js → Form-VkzfVPyT.js} +15 -23
- package/dist/{Form-CcK7dRrC.js.map → Form-VkzfVPyT.js.map} +1 -1
- package/dist/{FormGroup-DR_gZ25-.js → FormGroup-CmCppxOn.js} +11 -17
- package/dist/FormGroup-CmCppxOn.js.map +1 -0
- package/dist/{FullScreenModal-CN9nAs72.js → FullScreenModal-Cwnm8WdM.js} +15 -29
- package/dist/FullScreenModal-Cwnm8WdM.js.map +1 -0
- package/dist/{HoverCard-B9ZMJxjn.js → HoverCard-B8OKu9XZ.js} +2 -2
- package/dist/{HoverCard-B9ZMJxjn.js.map → HoverCard-B8OKu9XZ.js.map} +1 -1
- package/dist/{InputGroup-Do8K2hvD.js → InputGroup-CrlMRz4X.js} +11 -13
- package/dist/InputGroup-CrlMRz4X.js.map +1 -0
- package/dist/{Kbd-LCFMumoq.js → Kbd-J4n1J6i4.js} +23 -13
- package/dist/Kbd-J4n1J6i4.js.map +1 -0
- package/dist/{MarkedText-DNGEUVWc.js → MarkedText-DlmlJO0u.js} +2 -2
- package/dist/{MarkedText-DNGEUVWc.js.map → MarkedText-DlmlJO0u.js.map} +1 -1
- package/dist/{MermaidDiagram-ZG0iiDV_.js → MermaidDiagram-B30x2yV7.js} +16 -34
- package/dist/MermaidDiagram-B30x2yV7.js.map +1 -0
- package/dist/{Modal-I3VWk2oo.js → Modal-BkSuS9Yz.js} +17 -34
- package/dist/Modal-BkSuS9Yz.js.map +1 -0
- package/dist/{ModalTitle-CeLM_mX9.js → ModalTitle-BxopkIoQ.js} +3 -3
- package/dist/ModalTitle-BxopkIoQ.js.map +1 -0
- package/dist/{MultiActionButtonGroup-CYZ8IgSf.js → MultiActionButtonGroup-AWLj1Tg7.js} +3 -3
- package/dist/{MultiActionButtonGroup-CYZ8IgSf.js.map → MultiActionButtonGroup-AWLj1Tg7.js.map} +1 -1
- package/dist/{Navbar-Liy1TPI7.js → Navbar-B_DNpv5s.js} +9 -13
- package/dist/{Navbar-Liy1TPI7.js.map → Navbar-B_DNpv5s.js.map} +1 -1
- package/dist/{OtpInput-CbbymqYs.js → OtpInput-I8B8Vjdl.js} +2 -2
- package/dist/{OtpInput-CbbymqYs.js.map → OtpInput-I8B8Vjdl.js.map} +1 -1
- package/dist/{PageHeader-Q3IpCnQd.js → PageHeader-CgfyXpf1.js} +13 -26
- package/dist/PageHeader-CgfyXpf1.js.map +1 -0
- package/dist/{PageLayout-DSVM-ASz.js → PageLayout-DiAAILuS.js} +12 -20
- package/dist/PageLayout-DiAAILuS.js.map +1 -0
- package/dist/{PageToolbar-BKVJiDAL.js → PageToolbar-CIW0VmKe.js} +12 -42
- package/dist/PageToolbar-CIW0VmKe.js.map +1 -0
- package/dist/{Pagination-C_b7Xhey.js → Pagination-DH3f6LN0.js} +3 -3
- package/dist/{Pagination-C_b7Xhey.js.map → Pagination-DH3f6LN0.js.map} +1 -1
- package/dist/{Popconfirm-5pBzT_HQ.js → Popconfirm-Dhzn7sy6.js} +3 -3
- package/dist/{Popconfirm-5pBzT_HQ.js.map → Popconfirm-Dhzn7sy6.js.map} +1 -1
- package/dist/{Popover-BEbQrC_P.js → Popover-CEk915I1.js} +4 -3
- package/dist/Popover-CEk915I1.js.map +1 -0
- package/dist/{RadioGroup-Byc2mym4.js → RadioGroup-CBPRLRN0.js} +4 -4
- package/dist/{RadioGroup-Byc2mym4.js.map → RadioGroup-CBPRLRN0.js.map} +1 -1
- package/dist/{Search-Dhig_hPD.js → Search-DmkQo716.js} +3 -3
- package/dist/{Search-Dhig_hPD.js.map → Search-DmkQo716.js.map} +1 -1
- package/dist/{SearchInput-92r2bkA7.js → SearchInput-D3qMkHaW.js} +8 -13
- package/dist/SearchInput-D3qMkHaW.js.map +1 -0
- package/dist/{SectionNav-CNLJsiVG.js → SectionNav-TU5i3JeM.js} +10 -42
- package/dist/SectionNav-TU5i3JeM.js.map +1 -0
- package/dist/{Select-DV3Hak_l.js → Select-B4uK0QVm.js} +10 -12
- package/dist/Select-B4uK0QVm.js.map +1 -0
- package/dist/{Sheet-OparjIi-.js → Sheet-D0fAE14T.js} +5 -9
- package/dist/Sheet-D0fAE14T.js.map +1 -0
- package/dist/{Sidebar-CLEbBtNY.js → Sidebar-ZLMNIbg5.js} +16 -33
- package/dist/Sidebar-ZLMNIbg5.js.map +1 -0
- package/dist/{Slider-DLclvRws.js → Slider-B0ou9r0B.js} +3 -3
- package/dist/{Slider-DLclvRws.js.map → Slider-B0ou9r0B.js.map} +1 -1
- package/dist/{Stepper-C8sm9ZFM.js → Stepper-BLkLhfnd.js} +6 -9
- package/dist/{Stepper-C8sm9ZFM.js.map → Stepper-BLkLhfnd.js.map} +1 -1
- package/dist/{Switch-B0WdGSjz.js → Switch-DZvNePOm.js} +2 -2
- package/dist/{Switch-B0WdGSjz.js.map → Switch-DZvNePOm.js.map} +1 -1
- package/dist/{Table-CvYuTuNU.js → Table-BaVT5Tkn.js} +6 -11
- package/dist/{Table-CvYuTuNU.js.map → Table-BaVT5Tkn.js.map} +1 -1
- package/dist/{Tabs-eB974xJf.js → Tabs-CTDmye1N.js} +3 -3
- package/dist/{Tabs-eB974xJf.js.map → Tabs-CTDmye1N.js.map} +1 -1
- package/dist/{TextInput-CFTf4Cz1.js → TextInput-BWYXbfs4.js} +10 -14
- package/dist/TextInput-BWYXbfs4.js.map +1 -0
- package/dist/{ThemeProvider-DAmNn9Sd.js → ThemeProvider-VF38VfUa.js} +13 -31
- package/dist/ThemeProvider-VF38VfUa.js.map +1 -0
- package/dist/{TimePicker-BGeqc-Ed.js → TimePicker-CDGYrRxi.js} +2 -2
- package/dist/{TimePicker-BGeqc-Ed.js.map → TimePicker-CDGYrRxi.js.map} +1 -1
- package/dist/{Timeline-C8-wnRRr.js → Timeline-B-I6sb0M.js} +2 -2
- package/dist/{Timeline-C8-wnRRr.js.map → Timeline-B-I6sb0M.js.map} +1 -1
- package/dist/{Toast-Dr6Uw7ao.js → Toast-PfQf3vj-.js} +2 -2
- package/dist/{Toast-Dr6Uw7ao.js.map → Toast-PfQf3vj-.js.map} +1 -1
- package/dist/{Workbench-UR2FBC7I.js → Workbench-DmZzpkj7.js} +2 -2
- package/dist/{Workbench-UR2FBC7I.js.map → Workbench-DmZzpkj7.js.map} +1 -1
- package/dist/{ZoomableSvg-BZlk3PFJ.js → ZoomableSvg-C65nta_r.js} +5 -19
- package/dist/ZoomableSvg-C65nta_r.js.map +1 -0
- package/dist/charts.d.ts +21 -52
- package/dist/charts.js +13 -39
- package/dist/charts.js.map +1 -1
- package/dist/{context-D7X470dy.js → context-U293r3v-.js} +5 -9
- package/dist/context-U293r3v-.js.map +1 -0
- package/dist/editors.d.ts +27 -124
- package/dist/editors.js +29 -71
- package/dist/editors.js.map +1 -1
- package/dist/{findLiteralMatches-BGBw8Vbl.js → findLiteralMatches-DgGLzyG0.js} +8 -20
- package/dist/findLiteralMatches-DgGLzyG0.js.map +1 -0
- package/dist/flint.d.ts +3 -6
- package/dist/flint.js +31 -80
- package/dist/flint.js.map +1 -1
- package/dist/{icons-Cek151jC.js → icons-wcA70iQx.js} +105 -2
- package/dist/icons-wcA70iQx.js.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +2 -2
- package/dist/{index-m-kQEWiY.d.ts → index-B7k-09i1.d.ts} +14 -2
- package/dist/index.d.ts +1180 -1867
- package/dist/index.js +69 -68
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/AppShell.js +1 -1
- package/dist/internal/blocks/AuthLayout.js +7 -27
- package/dist/internal/blocks/AuthLayout.js.map +1 -1
- package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChartPanel.js +4 -8
- package/dist/internal/blocks/ChartPanel.js.map +1 -1
- package/dist/internal/blocks/ChipEditor.js +13 -21
- package/dist/internal/blocks/ChipEditor.js.map +1 -1
- package/dist/internal/blocks/ClipboardButton.js +1 -1
- package/dist/internal/blocks/ColorInput.js +1 -1
- package/dist/internal/blocks/ColorModeSwitch.js +1 -1
- package/dist/internal/blocks/Command.js +1 -1
- package/dist/internal/blocks/CopyField.js +1 -1
- package/dist/internal/blocks/DashboardHero.js +4 -7
- package/dist/internal/blocks/DashboardHero.js.map +1 -1
- package/dist/internal/blocks/DateInput.js +1 -1
- package/dist/internal/blocks/DateRangeInput.js +1 -1
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
- package/dist/internal/blocks/EmptyState.js +5 -9
- package/dist/internal/blocks/EmptyState.js.map +1 -1
- package/dist/internal/blocks/ErrorState.js +5 -9
- package/dist/internal/blocks/ErrorState.js.map +1 -1
- package/dist/internal/blocks/ExportMenu.js +6 -10
- package/dist/internal/blocks/ExportMenu.js.map +1 -1
- package/dist/internal/blocks/Form/connectors/ComboboxField.js +40 -0
- package/dist/internal/blocks/Form/connectors/ComboboxField.js.map +1 -0
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +5 -22
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -1
- package/dist/internal/blocks/Form.js +1 -1
- package/dist/internal/blocks/FormGroup.js +1 -1
- package/dist/internal/blocks/GoogleButton.js +1 -1
- package/dist/internal/blocks/MicrosoftButton.js +1 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
- package/dist/internal/blocks/MultiCombobox.js +160 -154
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +1 -1
- package/dist/internal/blocks/OtpInput.js +1 -1
- package/dist/internal/blocks/PageHeader.js +1 -1
- package/dist/internal/blocks/PageLayout.js +1 -1
- package/dist/internal/blocks/PageToolbar.js +1 -1
- package/dist/internal/blocks/PasswordInput.js +4 -4
- package/dist/internal/blocks/PasswordInput.js.map +1 -1
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +4 -4
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +3 -3
- package/dist/internal/blocks/StatCard.js +4 -8
- package/dist/internal/blocks/StatCard.js.map +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/Textarea.js +2 -2
- package/dist/internal/blocks/TimeInput.js +5 -5
- package/dist/internal/blocks/TimeInput.js.map +1 -1
- package/dist/internal/components/Alert.js +1 -1
- package/dist/internal/components/AlertModal.js +1 -1
- package/dist/internal/components/Avatar.js +1 -1
- package/dist/internal/components/Badge.js +1 -1
- package/dist/internal/components/BrandLogo.js +1 -1
- package/dist/internal/components/Breadcrumb.js +1 -1
- package/dist/internal/components/Button.js +1 -1
- package/dist/internal/components/ButtonGroup.js.map +1 -1
- package/dist/internal/components/Calendar.js +1 -1
- package/dist/internal/components/Card.js +1 -1
- package/dist/internal/components/Checkbox.js +1 -1
- package/dist/internal/components/Clipboard.js +1 -1
- package/dist/internal/components/CollapsiblePanel.js +3 -3
- package/dist/internal/components/CollapsiblePanel.js.map +1 -1
- package/dist/internal/components/Combobox.js +2 -2
- package/dist/internal/components/DatePicker.js +1 -1
- package/dist/internal/components/DateRangePicker.js +1 -1
- package/dist/internal/components/DropdownMenu.js +1 -1
- package/dist/internal/components/FileUpload.js +1 -1
- package/dist/internal/components/FullScreenModal.js +1 -1
- package/dist/internal/components/HoverCard.js +1 -1
- package/dist/internal/components/InputGroup.js +1 -1
- package/dist/internal/components/Kbd.js +1 -1
- package/dist/internal/components/MarkedText.js +1 -1
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +1 -1
- package/dist/internal/components/Modal.js +1 -1
- package/dist/internal/components/Navbar.js +1 -1
- package/dist/internal/components/Pagination.js +1 -1
- package/dist/internal/components/PanelWithDetails.js +1 -1
- package/dist/internal/components/Popconfirm.js +1 -1
- package/dist/internal/components/Popover.js +1 -1
- package/dist/internal/components/RadioGroup.js +1 -1
- package/dist/internal/components/Search.js +1 -1
- package/dist/internal/components/Select.js +1 -1
- package/dist/internal/components/Separator.js.map +1 -1
- package/dist/internal/components/Sheet.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Skeleton/Skeleton.js +5 -9
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/SpotlightBackdrop.js +3 -8
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
- package/dist/internal/components/Stepper.js +1 -1
- package/dist/internal/components/Switch.js +1 -1
- package/dist/internal/components/Table.js +1 -1
- package/dist/internal/components/Tabs.js +1 -1
- package/dist/internal/components/ThemeProvider.js +3 -3
- package/dist/internal/components/TimePicker.js +1 -1
- package/dist/internal/components/Timeline.js +1 -1
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Tooltip.js +1 -1
- package/dist/internal/components/Truncated.js +4 -8
- package/dist/internal/components/Truncated.js.map +1 -1
- package/dist/internal/components/Workbench.js +1 -1
- package/dist/internal/components/ZoomableSvg.js +1 -1
- package/dist/internal/hooks/useScrollbarPosition.js +1 -1
- package/dist/internal/hooks/useStableCallback.js +4 -13
- package/dist/internal/hooks/useStableCallback.js.map +1 -1
- package/dist/internal/utils/accessibleName.js +11 -0
- package/dist/internal/utils/accessibleName.js.map +1 -0
- package/dist/internal/utils.js +2 -2
- package/dist/markdown-editor.d.ts +15 -37
- package/dist/markdown-editor.js +17 -23
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +4 -6
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.d.ts +9 -19
- package/dist/rjsf.js +44 -84
- package/dist/rjsf.js.map +1 -1
- package/dist/{styles-BAFscjSV.js → styles-gzcjOyKv.js} +6 -6
- package/dist/styles-gzcjOyKv.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/svgTransforms-Dw2hRA-i.js +51 -0
- package/dist/svgTransforms-Dw2hRA-i.js.map +1 -0
- package/dist/testing.d.ts +3 -10
- package/dist/testing.js +7 -15
- package/dist/testing.js.map +1 -1
- package/dist/themeTokens-7DEab0kp.js +31 -0
- package/dist/themeTokens-7DEab0kp.js.map +1 -0
- package/dist/{toast-DIC0iNRf.js → toast-CyXEdaCZ.js} +3 -3
- package/dist/toast-CyXEdaCZ.js.map +1 -0
- package/dist/{themeScopeContext-D7fSyb06.js → useColorSchemeState-Cw4MCXUs.js} +14 -14
- package/dist/useColorSchemeState-Cw4MCXUs.js.map +1 -0
- package/dist/{useControllableState-M6494mCT.js → useControllableState-CUYXMsfz.js} +3 -7
- package/dist/useControllableState-CUYXMsfz.js.map +1 -0
- package/dist/useElement-D-RjrGa4.js +21 -0
- package/dist/useElement-D-RjrGa4.js.map +1 -0
- package/dist/useThemeAttributes-B199Regy.js +67 -0
- package/dist/useThemeAttributes-B199Regy.js.map +1 -0
- package/dist/{utils-BW4AE8VP.js → utils-Bd28bWgm.js} +31 -26
- package/dist/utils-Bd28bWgm.js.map +1 -0
- package/dist/vega.d.ts +8 -30
- package/dist/vega.js +5 -13
- package/dist/vega.js.map +1 -1
- package/dist/{vegaTheme-CSvFEMBl.js → vegaTheme-VQMWTlBw.js} +7 -21
- package/dist/vegaTheme-VQMWTlBw.js.map +1 -0
- package/package.json +28 -27
- package/src/styles.css +120 -14
- package/src/theme.css +130 -5
- package/dist/AIKit-ELIsegJz.js.map +0 -1
- package/dist/Alert-BsIM_oFK.js.map +0 -1
- package/dist/AlertModal-BGJdaRRj.js.map +0 -1
- package/dist/AppShell-DRgJxpXW.js.map +0 -1
- package/dist/Badge-o5jURtpB.js.map +0 -1
- package/dist/BrandLogo-CoKBk4MI.js.map +0 -1
- package/dist/Breadcrumb-xqEUxfwn.js.map +0 -1
- package/dist/Button-DsRrU5F1.js.map +0 -1
- package/dist/Calendar-cG5NIJ4O.js.map +0 -1
- package/dist/Card-Dyo7055Q.js.map +0 -1
- package/dist/Checkbox-Dq5fPNrO.js.map +0 -1
- package/dist/CodeEditor-BJKJXA0c.js.map +0 -1
- package/dist/ColorInput-Bj3dfPFA.js.map +0 -1
- package/dist/ColorModeSwitch-CWt-DZGC.js.map +0 -1
- package/dist/Combobox-D8PrEqTG.js +0 -619
- package/dist/Combobox-D8PrEqTG.js.map +0 -1
- package/dist/DateRangeInput-7M9Z4cVO.js.map +0 -1
- package/dist/DateRangePicker-DjSUFjh4.js.map +0 -1
- package/dist/DropdownMenu-CgVwhDvl.js.map +0 -1
- package/dist/FieldItem-DZGIdiXE.js.map +0 -1
- package/dist/FormGroup-DR_gZ25-.js.map +0 -1
- package/dist/FullScreenModal-CN9nAs72.js.map +0 -1
- package/dist/InputGroup-Do8K2hvD.js.map +0 -1
- package/dist/Kbd-LCFMumoq.js.map +0 -1
- package/dist/MermaidDiagram-ZG0iiDV_.js.map +0 -1
- package/dist/Modal-I3VWk2oo.js.map +0 -1
- package/dist/ModalTitle-CeLM_mX9.js.map +0 -1
- package/dist/PageHeader-Q3IpCnQd.js.map +0 -1
- package/dist/PageLayout-DSVM-ASz.js.map +0 -1
- package/dist/PageToolbar-BKVJiDAL.js.map +0 -1
- package/dist/Popover-BEbQrC_P.js.map +0 -1
- package/dist/SearchInput-92r2bkA7.js.map +0 -1
- package/dist/SectionNav-CNLJsiVG.js.map +0 -1
- package/dist/Select-DV3Hak_l.js.map +0 -1
- package/dist/Sheet-OparjIi-.js.map +0 -1
- package/dist/Sidebar-CLEbBtNY.js.map +0 -1
- package/dist/TextInput-CFTf4Cz1.js.map +0 -1
- package/dist/ThemeProvider-DAmNn9Sd.js.map +0 -1
- package/dist/ZoomableSvg-BZlk3PFJ.js.map +0 -1
- package/dist/context-D7X470dy.js.map +0 -1
- package/dist/findLiteralMatches-BGBw8Vbl.js.map +0 -1
- package/dist/icons-Cek151jC.js.map +0 -1
- package/dist/internal/components/StatusDot.js +0 -67
- package/dist/internal/components/StatusDot.js.map +0 -1
- package/dist/styles-BAFscjSV.js.map +0 -1
- package/dist/svgTransforms-CJAYPk7o.js +0 -81
- package/dist/svgTransforms-CJAYPk7o.js.map +0 -1
- package/dist/themeScopeContext-D7fSyb06.js.map +0 -1
- package/dist/themeTokens-qP1-55O7.js +0 -119
- package/dist/themeTokens-qP1-55O7.js.map +0 -1
- package/dist/toast-DIC0iNRf.js.map +0 -1
- package/dist/useControllableState-M6494mCT.js.map +0 -1
- package/dist/useElement-BK3AAiIf.js +0 -24
- package/dist/useElement-BK3AAiIf.js.map +0 -1
- package/dist/utils-BW4AE8VP.js.map +0 -1
- package/dist/vegaTheme-CSvFEMBl.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar-CLEbBtNY.js","names":[],"sources":["../src/components/Sidebar/SidebarProvider/useTransitionPresence.ts","../src/components/Sidebar/SidebarContent.tsx","../src/hooks/useMediaQuery.ts","../src/components/Sidebar/utils.ts","../src/components/Sidebar/SidebarProvider/context.ts","../src/components/Sidebar/SidebarProvider/useHoverTracking.ts","../src/components/Sidebar/SidebarProvider/useSidebarState.ts","../src/components/Sidebar/SidebarProvider/SidebarProvider.tsx","../src/components/Sidebar/SidebarFillTrigger.tsx","../src/components/Sidebar/SidebarFooter.tsx","../src/components/Sidebar/SidebarGroup/SidebarGroup.tsx","../src/components/Sidebar/SidebarGroup/SidebarGroupContent.tsx","../src/components/Sidebar/SidebarGroup/SidebarGroupAction.tsx","../src/components/Sidebar/SidebarGroup/SidebarGroupLabel.tsx","../src/components/Sidebar/SidebarInstanceContext.ts","../src/components/Sidebar/SidebarHeader.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenu.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenuIcon.tsx","../src/components/Sidebar/SidebarMenu/useDestinationDismiss.ts","../src/components/Sidebar/SidebarMenu/SidebarMenuButton.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenuItem.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenuAction.tsx","../src/components/Sidebar/SidebarMenu/SidebarSearchInput.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenuCard.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenuBadge.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenuSub.tsx","../src/components/Sidebar/SidebarMenu/SidebarMenuSubItem.tsx","../src/components/Sidebar/useResizeSidebar.ts","../src/components/Sidebar/SidebarResizeHandle.tsx","../src/components/Sidebar/SidebarSeparator.tsx","../src/components/Sidebar/SidebarTrigger.tsx","../src/components/Sidebar/Sidebar.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useMemo, useReducer } from 'react';\n\ntype MountState = 'mounted' | 'enterSuspended' | 'unmountSuspended' | 'unmounted';\ntype MountEvent = 'MOUNT' | 'ENTER' | 'TRANSITION_OUT' | 'TRANSITION_END';\n\ntype UseTransitionPresenceOptions = {\n mounted: boolean;\n keepMounted?: boolean;\n /** Hold the subtree back until the enter transition ends — a heavy mount in the same commit blocks every frame of it. */\n mountAfterEnter?: boolean;\n};\n\nconst FALLBACK_TIMEOUT_MS = 500;\n\n/** Under reduced motion there is no `transitionend` to wait for, so the mount is not deferred. */\nconst prefersReducedMotion = () =>\n typeof window !== 'undefined' &&\n (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false);\n\nconst reducer = (state: MountState, event: MountEvent): MountState => {\n switch (event) {\n case 'MOUNT':\n return 'mounted';\n case 'ENTER':\n // Already-mounted content stays put; only a cold open waits.\n return state === 'unmounted' ? 'enterSuspended' : 'mounted';\n case 'TRANSITION_OUT':\n // Closed before the content arrived: nothing to animate out.\n if (state === 'enterSuspended') return 'unmounted';\n return state === 'mounted' ? 'unmountSuspended' : state;\n case 'TRANSITION_END':\n if (state === 'unmountSuspended') return 'unmounted';\n if (state === 'enterSuspended') return 'mounted';\n return state;\n default:\n return state;\n }\n};\n\nexport const useTransitionPresence = ({\n mounted,\n keepMounted = false,\n mountAfterEnter = false,\n}: UseTransitionPresenceOptions) => {\n const [state, send] = useReducer(reducer, mounted ? 'mounted' : 'unmounted');\n\n useLayoutEffect(() => {\n if (keepMounted) return;\n if (!mounted) {\n send('TRANSITION_OUT');\n return;\n }\n send(mountAfterEnter && !prefersReducedMotion() ? 'ENTER' : 'MOUNT');\n }, [mounted, keepMounted, mountAfterEnter]);\n\n // Fallback for both suspensions when `onTransitionEnd` never fires.\n useEffect(() => {\n if (state !== 'unmountSuspended' && state !== 'enterSuspended') return;\n\n const id = setTimeout(() => send('TRANSITION_END'), FALLBACK_TIMEOUT_MS);\n return () => clearTimeout(id);\n }, [state]);\n\n return useMemo(\n () => ({\n isMounted: keepMounted || state === 'mounted' || state === 'unmountSuspended',\n /** Resolves whichever transition the subtree is waiting on. */\n completeUnmount: () => send('TRANSITION_END'),\n }),\n [state, keepMounted],\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { useScrollbarPosition } from '../../hooks/useScrollbarPosition';\nimport { cn, mergeRefs } from '../../utils';\nimport { ScrollArea } from '../ScrollArea';\n\ntype Props = {\n className?: string;\n children?: ReactNode;\n contentRef?: ComponentProps<'div'>['ref'];\n ref?: ComponentProps<'div'>['ref'];\n};\n\nexport const SidebarContent = ({ ref, className, children, contentRef }: Props) => {\n const { setElement, isBottom, isTop, isMiddle } = useScrollbarPosition();\n const mergedRefs = mergeRefs(ref ?? null, (ref) => setElement(ref));\n\n return (\n <ScrollArea\n ref={mergedRefs}\n type=\"scroll\"\n className=\"tw:group/sidebar-content tw:flex-1\"\n data-slot=\"sidebar-content\"\n scrollBarClassName=\"tw:w-1.5\"\n viewPortClassName={cn(\n 'tw:overflow-x-hidden',\n 'tw:overscroll-contain',\n 'tw:[&>div]:!flex', // overflow fix for scrollbar\n // Hide scroll-position-based borders (top/bottom) if SidebarHeader or SidebarFooter is omitted.\n 'tw:group-first/sidebar-content:before:hidden',\n 'tw:group-last/sidebar-content:after:hidden',\n 'tw:!box-border',\n {\n 'tw:before:absolute tw:before:top-0 tw:before:left-0 tw:before:right-0 tw:before:h-px tw:before:bg-sidebar-border tw:before:z-10 tw:before:content-[\"\"]':\n isBottom || isMiddle,\n 'tw:after:absolute tw:after:bottom-0 tw:after:left-0 tw:after:right-0 tw:after:h-px tw:after:bg-sidebar-border tw:after:z-10 tw:after:content-[\"\"]':\n isTop || isMiddle,\n },\n )}\n >\n <div\n ref={contentRef}\n className={cn(\n 'tw:flex',\n 'tw:flex-1',\n 'tw:flex-col',\n 'tw:gap-1',\n 'tw:overflow-x-hidden',\n 'tw:p-2',\n className,\n )}\n >\n {children}\n </div>\n </ScrollArea>\n );\n};\n","import { useCallback, useSyncExternalStore } from 'react';\n\n/**\n * Whether a CSS media query currently matches, re-rendering when it flips.\n *\n * - `false` wherever `matchMedia` is absent (SSR, a stubbed test environment), so the\n * caller renders its desktop branch rather than crashing.\n * - The subscription is the query's own `change` event — no resize listener, no polling.\n */\nexport const useMediaQuery = (query: string) => {\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n const list = globalThis.matchMedia?.(query);\n list?.addEventListener?.('change', onStoreChange);\n\n return () => list?.removeEventListener?.('change', onStoreChange);\n },\n [query],\n );\n\n const getSnapshot = useCallback(() => globalThis.matchMedia?.(query).matches ?? false, [query]);\n\n return useSyncExternalStore(subscribe, getSnapshot, () => false);\n};\n","import type { SidebarCollapsible, SidebarMode, SidebarState, SidebarVariant } from './types';\n\nexport const SidebarWidthInPx = {\n MIN_DEFAULT: 256,\n\n // 8 px / 36 px / 8 px = 52 px\n // left padding / icon width / right padding\n COLLAPSED_ICON: 52,\n\n // padding from every side for floating variant (see --sidebar-floating-padding)\n FLOATING_VARIANT_PADDING: 8,\n} as const;\n\n/**\n * The default viewport width under which a rail stops being a column and opens as a sheet.\n *\n * - Matches Tailwind's `md`, so a call site's own `tw:md:*` breakpoint utilities flip\n * in the same frame as the rail.\n */\nexport const SIDEBAR_MOBILE_BREAKPOINT_PX = 768;\n\n/**\n * The query a rail watches to know whether it is a sheet.\n *\n * - `max-width`, so it is exclusive of the breakpoint itself — the width passed in is the\n * first one at which the rail is a column again.\n * - Per side, because the width at which a rail stops fitting is the rail's own: a 320px\n * panel beside a capped reading column runs out of room long before a navigation rail does.\n */\nexport const sidebarMobileMediaQuery = (breakpointPx: number) =>\n `(max-width: ${breakpointPx - 0.02}px)`;\n\nconst floatingSideCount: Record<SidebarVariant, number> = {\n 'sided-floating': 1,\n floating: 2,\n inset: 0,\n none: 0,\n};\n\ntype Input = {\n variant: SidebarVariant;\n width?: number;\n collapsible: SidebarCollapsible;\n mode: SidebarMode;\n state: SidebarState;\n /** Below the breakpoint the rail is a sheet, so it occupies no column. */\n isMobile?: boolean;\n};\n\ntype EffectiveWidths = {\n sidebar: number;\n gap: number;\n fill: number;\n};\n\nexport const calcEffectiveWidths = ({\n variant,\n width: customWidth,\n collapsible,\n state,\n mode,\n isMobile = false,\n}: Input) => {\n if (variant === 'none' || isMobile) return { sidebar: 0, gap: 0, fill: 0 };\n\n const padding = floatingSideCount[variant] * SidebarWidthInPx.FLOATING_VARIANT_PADDING;\n const width = Math.max(customWidth ?? 0, SidebarWidthInPx.MIN_DEFAULT) + padding;\n const iconWidth = SidebarWidthInPx.COLLAPSED_ICON + padding;\n const isExpanded = state === 'expanded';\n\n // Only compensate for floating padding when this sidebar itself has padding,\n // so the opposite filled sidebar doesn't double-count the gap.\n const reduction = variant === 'inset' ? 0 : SidebarWidthInPx.FLOATING_VARIANT_PADDING;\n\n const iconWidths = ((): EffectiveWidths => {\n const sidebar = isExpanded ? width : iconWidth;\n const gap = mode === 'expand-on-hover' ? iconWidth : sidebar;\n // Use gap (not sidebar) so the opposite filled sidebar stays stable\n // during expand-on-hover — gap stays at iconWidth while sidebar grows\n const fill = gap - reduction;\n return { sidebar, gap, fill };\n })();\n\n const offCanvasWidths = ((): EffectiveWidths => {\n const sidebar = width; //We use CSS translate to hide elements because it allows for transitions without shrinking the width.\n const gap = isExpanded ? width : SidebarWidthInPx.FLOATING_VARIANT_PADDING; // The gap is invisible and needs to be shrunk to move the content to its place.\n const fill = gap - reduction;\n return { sidebar, gap, fill };\n })();\n\n return collapsible === 'icon' ? iconWidths : offCanvasWidths;\n};\n","import { createContext, use } from 'react';\n\nimport type { SidebarCollapsible, SidebarSide, SidebarVariant } from '../types';\nimport type { calcEffectiveWidths } from '../utils';\n\nimport type { useSidebarState } from './useSidebarState';\n\ntype SidebarWidths = ReturnType<typeof calcEffectiveWidths>;\ntype SidebarState = ReturnType<typeof useSidebarState>;\n\ntype SidebarSideValue = SidebarState & {\n /**\n * The viewport is under the mobile breakpoint, so this rail renders as a sheet rather\n * than a grid column.\n *\n * - `mode` and `state` both report `expanded` here — the collapse axis has nothing to\n * act on, and the call site's own `mode` prop is left untouched.\n * - `toggle` opens and closes the sheet instead of writing that prop.\n */\n isMobile: boolean;\n /** Whether this side's mobile sheet is open. Always `false` above the breakpoint. */\n isMobileOpen: boolean;\n /** Opens or closes this side's mobile sheet; opening one closes the other. */\n setMobileOpen: (open: boolean) => void;\n isFill: boolean;\n toggleFill: () => void;\n /** Idempotent counterpart to `toggleFill` — safe to call twice, or when already in that state. */\n setFill: (fill: boolean) => void;\n widths: SidebarWidths;\n collapsible: SidebarCollapsible;\n variant: SidebarVariant;\n baseWidth: number | undefined;\n onWidthChange: ((width: number) => void) | undefined;\n setDragWidth: (width: number | null) => void;\n isDragging: boolean;\n setIsDragging: (dragging: boolean) => void;\n};\n\nexport type SidebarContextValue = {\n left: SidebarSideValue;\n right: SidebarSideValue;\n};\n\nexport const SidebarContext = createContext<SidebarContextValue | null>(null);\n\n/**\n * The sidebar if there is one, `null` otherwise — for code that ENHANCES a page when the app shell is\n * around it (borrowing width, collapsing a panel) and must still render without one, in a test, a\n * story, or an embedded surface. Anything that genuinely requires a sidebar keeps `useSidebar`.\n */\nexport const useOptionalSidebar = (side: SidebarSide = 'left'): SidebarSideValue | null =>\n use(SidebarContext)?.[side] ?? null;\n\nexport const useSidebar = (side: SidebarSide = 'left'): SidebarSideValue => {\n const context = use(SidebarContext);\n if (context === null) throw new Error('useSidebar must be used within a SidebarProvider.');\n return context[side];\n};\n","import { useEffect, useRef, useState } from 'react';\n\n/**\n * CSS selectors matching portal-based overlay triggers in their open state.\n *\n * The sidebar's hover tracking ignores `mouseleave` while any of these selectors\n * match inside the sidebar DOM — preventing the sidebar from collapsing while the\n * user interacts with portal content rendered outside the sidebar tree.\n *\n * Update this list when changing or adding new components:\n */\nconst PORTAL_OPEN_SELECTORS = [\n '[aria-haspopup=\"menu\"][aria-expanded=true]', // DropdownMenu\n '[aria-haspopup=\"dialog\"][aria-expanded=true]', // Popover, Dialogs (Modal, Sheet)\n];\n\nconst PORTAL_OPEN_SELECTORS_STRING = PORTAL_OPEN_SELECTORS.join(',');\n\nexport const useHoverTracking = (sidebarElement: HTMLElement | null) => {\n // Which element the pointer is over, rather than a bare boolean. The tracked element is\n // replaced when the rail changes branch — crossing the mobile breakpoint does it — and a\n // boolean would carry the old element's hover onto the new one, leaving an\n // `expand-on-hover` rail expanded with the pointer somewhere else entirely.\n const [hoveredElement, setHoveredElement] = useState<HTMLElement | null>(null);\n const isLockedRef = useRef(false);\n\n // Release an element the pointer can no longer be over: the rail swapped branch, or it\n // became a sheet and there is no rail to track at all. Holding the detached node would\n // keep its subtree alive for as long as the provider is mounted, and hand the hover\n // straight back if the same rail is mounted again.\n //\n // - Done during render rather than in an effect: it converges (the value it clears is the\n // one that no longer matches) and lands before the listeners below are re-bound.\n if (hoveredElement !== null && hoveredElement !== sidebarElement) setHoveredElement(null);\n\n const isHovered = hoveredElement !== null;\n\n useEffect(() => {\n if (!sidebarElement) return;\n\n const handleMouseEnter = () => setHoveredElement(sidebarElement);\n const handleMouseLeave = () => {\n if (isLockedRef.current) return;\n setHoveredElement(null);\n };\n\n sidebarElement.addEventListener('mouseenter', handleMouseEnter);\n sidebarElement.addEventListener('mouseleave', handleMouseLeave);\n\n return () => {\n sidebarElement.removeEventListener('mouseenter', handleMouseEnter);\n sidebarElement.removeEventListener('mouseleave', handleMouseLeave);\n };\n }, [sidebarElement]);\n\n useEffect(() => {\n if (!sidebarElement) return;\n let animationFrameId: number;\n\n const observer = new MutationObserver(() => {\n const hasOpenPortal = sidebarElement.querySelector(PORTAL_OPEN_SELECTORS_STRING) !== null;\n isLockedRef.current = hasOpenPortal;\n\n if (hasOpenPortal) return;\n\n animationFrameId = requestAnimationFrame(() => {\n setHoveredElement(sidebarElement.matches(':hover') ? sidebarElement : null);\n });\n });\n\n // Sync lock state immediately in case a portal trigger is already open on mount.\n isLockedRef.current = sidebarElement.querySelector(PORTAL_OPEN_SELECTORS_STRING) !== null;\n\n observer.observe(sidebarElement, {\n attributes: true,\n attributeFilter: ['aria-expanded'],\n subtree: true,\n });\n\n return () => {\n cancelAnimationFrame(animationFrameId);\n observer.disconnect();\n };\n }, [sidebarElement]);\n\n return isHovered;\n};\n","import { useCallback, useMemo, useState } from 'react';\n\nimport { useElement } from '../../../hooks/useElement';\nimport type { SidebarMode, SidebarState } from '../types';\n\nimport { useHoverTracking } from './useHoverTracking';\n\ntype Props = {\n defaultMode?: SidebarMode;\n mode?: SidebarMode;\n onModeChange?: (state: SidebarMode) => void;\n};\n\nexport const useSidebarState = ({ defaultMode, mode: modeProp, onModeChange }: Props) => {\n const [sidebarElement, setSidebarElement] = useElement();\n const isHovered = useHoverTracking(sidebarElement);\n const [_mode, _setMode] = useState(defaultMode ?? 'expanded');\n const mode = modeProp ?? _mode;\n\n const setMode = useCallback(\n (dispatch: Parameters<typeof _setMode>[0]) => {\n const newState = typeof dispatch === 'function' ? dispatch(mode) : dispatch;\n const set = onModeChange ?? _setMode;\n set(newState);\n },\n [onModeChange, mode],\n );\n\n const toggle = useCallback(() => {\n setMode((currState) => (currState === 'expanded' ? 'collapsed' : 'expanded'));\n }, [setMode]);\n\n const state: SidebarState = (() => {\n if (mode === 'expand-on-hover') return isHovered ? 'expanded' : 'collapsed';\n return mode;\n })();\n\n return useMemo(\n () => ({\n isHovered,\n toggle,\n setMode,\n mode,\n state,\n sidebarElement,\n setSidebarElement,\n }),\n [isHovered, toggle, setMode, mode, state, sidebarElement, setSidebarElement],\n );\n};\n","import { type ReactNode, useCallback, useMemo, useState } from 'react';\n\nimport { useMediaQuery } from '../../../hooks/useMediaQuery';\nimport type { SidebarCollapsible, SidebarMode, SidebarSide, SidebarVariant } from '../types';\nimport {\n calcEffectiveWidths,\n SIDEBAR_MOBILE_BREAKPOINT_PX,\n sidebarMobileMediaQuery,\n} from '../utils';\n\nimport type { SidebarContextValue } from './context';\nimport { SidebarContext } from './context';\nimport { useSidebarState } from './useSidebarState';\n\nconst DEFAULT_SIDEBAR_VARIANT: SidebarVariant = 'none';\nconst DEFAULT_SIDEBAR_MODE: SidebarMode = 'expanded';\nconst DEFAULT_SIDEBAR_COLLAPSIBLE: SidebarCollapsible = 'off-canvas';\n\n/**\n * What `setMode` becomes for a rail that is currently a sheet.\n *\n * - The collapse axis has nothing to act on there, and the call site's own `mode` prop is a\n * stored desktop preference — `Sidebar.SearchInput` expands the rail on focus, which would\n * otherwise overwrite a stored `collapsed` the first time someone searches on a phone.\n */\nconst ignoreModeChange = () => {};\n\n/** The width a side watches: its own when it named one, the default when it just opted in. */\nconst mobileBreakpointOf = (mobileSheet: boolean | number) =>\n typeof mobileSheet === 'number' ? mobileSheet : SIDEBAR_MOBILE_BREAKPOINT_PX;\n\ntype Props = {\n children?: ReactNode;\n // left state\n defaultLeftMode?: SidebarMode;\n leftMode?: SidebarMode;\n onLeftModeChange?: (mode: SidebarMode) => void;\n\n // right state\n defaultRightMode?: SidebarMode;\n rightMode?: SidebarMode;\n onRightModeChange?: (mode: SidebarMode) => void;\n\n /**\n * The left rail becomes a `Sheet` under a breakpoint instead of a grid column.\n *\n * - Opt-in, and per side: a `Sidebar` is also the shape of a container rail nested in a\n * modal or a builder canvas, where a full-screen phone sheet means nothing.\n * - `true` uses the default breakpoint (768px, Tailwind's `md`); a number is the width in\n * px under which this side is a sheet, for a rail that runs out of room at its own width.\n * - An app that opts in owes the sheet a way in — a `Sidebar.Trigger` in its header, which\n * routes to whichever of the two the rail currently is.\n * - `keepMounted` and `mountAfterEnter` do not apply while this side is a sheet: the sheet\n * mounts its content on open and unmounts it on close. A side whose panel holds state\n * worth surviving a close should keep that state above the panel.\n */\n leftMobileSheet?: boolean | number;\n /** The right-side twin of `leftMobileSheet`. */\n rightMobileSheet?: boolean | number;\n\n // left\n leftVariant?: SidebarVariant;\n leftWidth?: number;\n leftCollapsible?: SidebarCollapsible;\n\n // right\n rightVariant?: SidebarVariant;\n rightWidth?: number;\n rightCollapsible?: SidebarCollapsible;\n\n // width change callbacks\n onLeftWidthChange?: (width: number) => void;\n onRightWidthChange?: (width: number) => void;\n\n // fill\n defaultFilledSide?: SidebarSide | null;\n};\n\nexport const SidebarProvider = ({\n children,\n // left state\n defaultLeftMode = DEFAULT_SIDEBAR_MODE,\n leftMode,\n onLeftModeChange,\n\n // right state\n defaultRightMode = DEFAULT_SIDEBAR_MODE,\n rightMode,\n onRightModeChange,\n\n // mobile\n leftMobileSheet = false,\n rightMobileSheet = false,\n\n // left\n leftCollapsible = DEFAULT_SIDEBAR_COLLAPSIBLE,\n leftVariant = DEFAULT_SIDEBAR_VARIANT,\n leftWidth,\n\n // right\n rightCollapsible = DEFAULT_SIDEBAR_COLLAPSIBLE,\n rightVariant = DEFAULT_SIDEBAR_VARIANT,\n rightWidth,\n\n // width change callbacks\n onLeftWidthChange,\n onRightWidthChange,\n\n // fill\n defaultFilledSide = null,\n}: Props) => {\n // One query per side: the widths differ, and a hook cannot be skipped for the side that\n // opted out — an unwatched side reads its own default query and is gated by the flag below.\n const isLeftNarrow = useMediaQuery(sidebarMobileMediaQuery(mobileBreakpointOf(leftMobileSheet)));\n const isRightNarrow = useMediaQuery(\n sidebarMobileMediaQuery(mobileBreakpointOf(rightMobileSheet)),\n );\n // A side with no rail is not a mobile side: `Sidebar` renders nothing for `variant: 'none'`,\n // while `Sidebar.Trigger` would still advertise a dialog and toggle an open state nothing\n // reads. Failing the test here also clears that state below, so a variant switched back on\n // does not arrive with a stale sheet already open.\n const isLeftMobile = isLeftNarrow && leftMobileSheet !== false && leftVariant !== 'none';\n const isRightMobile = isRightNarrow && rightMobileSheet !== false && rightVariant !== 'none';\n const [filledSide, setFilledSide] = useState<SidebarSide | null>(defaultFilledSide);\n // One slot, not a flag per side: a phone shows one sheet at a time, and opening the\n // other rail has to close the first rather than stack two overlays.\n const [openMobileSide, setOpenMobileSide] = useState<SidebarSide | null>(null);\n const [isLeftDragging, setIsLeftDragging] = useState(false);\n const [isRightDragging, setIsRightDragging] = useState(false);\n const [leftDragWidth, setLeftDragWidth] = useState<number | null>(null);\n const [rightDragWidth, setRightDragWidth] = useState<number | null>(null);\n\n // Clear the local drag override the moment it matches the controlled width, so a\n // later width prop change isn't masked by a stale override (`baseWidth` is\n // `dragWidth ?? width`). Done during render rather than in an effect: it\n // converges (the override becomes null, so it can't loop) and triggers on a\n // change to either the prop or the drag width — matching the original effect,\n // whose dependency array also watched the drag width.\n if (leftDragWidth !== null && leftWidth === leftDragWidth) setLeftDragWidth(null);\n if (rightDragWidth !== null && rightWidth === rightDragWidth) setRightDragWidth(null);\n\n // Growing past the breakpoint hands the rail back to the grid; a sheet left open\n // would otherwise sit over a page that already shows the same navigation.\n if (openMobileSide === 'left' && !isLeftMobile) setOpenMobileSide(null);\n if (openMobileSide === 'right' && !isRightMobile) setOpenMobileSide(null);\n\n const leftState = useSidebarState({\n defaultMode: defaultLeftMode,\n mode: leftMode,\n onModeChange: onLeftModeChange,\n });\n\n const rightState = useSidebarState({\n defaultMode: defaultRightMode,\n mode: rightMode,\n onModeChange: onRightModeChange,\n });\n\n const toggleLeftMobile = useCallback(\n () => setOpenMobileSide((prev) => (prev === 'left' ? null : 'left')),\n [],\n );\n const toggleRightMobile = useCallback(\n () => setOpenMobileSide((prev) => (prev === 'right' ? null : 'right')),\n [],\n );\n const setLeftMobileOpen = useCallback(\n (open: boolean) => setOpenMobileSide((prev) => (open ? 'left' : prev === 'left' ? null : prev)),\n [],\n );\n const setRightMobileOpen = useCallback(\n (open: boolean) =>\n setOpenMobileSide((prev) => (open ? 'right' : prev === 'right' ? null : prev)),\n [],\n );\n\n const toggleLeftFill = useCallback(\n () => setFilledSide((prev) => (prev === 'left' ? null : 'left')),\n [],\n );\n const toggleRightFill = useCallback(\n () => setFilledSide((prev) => (prev === 'right' ? null : 'right')),\n [],\n );\n\n // Idempotent per side: unlike `toggleFill`, these need no knowledge of the current value, so\n // repeated calls for one side land on the value they ask for. Fill is a single slot, so two\n // sides asking at once still race — the last write wins.\n const setLeftFill = useCallback(\n (fill: boolean) => setFilledSide((prev) => (fill ? 'left' : prev === 'left' ? null : prev)),\n [],\n );\n const setRightFill = useCallback(\n (fill: boolean) => setFilledSide((prev) => (fill ? 'right' : prev === 'right' ? null : prev)),\n [],\n );\n\n const value = useMemo<SidebarContextValue>(\n () => ({\n left: {\n ...leftState,\n // On a phone the rail is a sheet, so the collapse axis has nothing to act on:\n // the panel is either open at full width or not rendered. Reporting `expanded`\n // is what gives the children their labels and withholds the collapsed-rail\n // tooltips; the call site's own `mode` prop is left untouched, so the desktop\n // preference survives the trip through a narrow viewport.\n ...(isLeftMobile\n ? {\n mode: 'expanded' as const,\n state: 'expanded' as const,\n toggle: toggleLeftMobile,\n setMode: ignoreModeChange,\n }\n : null),\n isMobile: isLeftMobile,\n isMobileOpen: openMobileSide === 'left',\n setMobileOpen: setLeftMobileOpen,\n isFill: filledSide === 'left',\n toggleFill: toggleLeftFill,\n setFill: setLeftFill,\n widths: calcEffectiveWidths({\n variant: leftVariant,\n width: leftDragWidth ?? leftWidth,\n collapsible: leftCollapsible,\n state: leftState.state,\n mode: leftState.mode,\n isMobile: isLeftMobile,\n }),\n collapsible: leftCollapsible,\n variant: leftVariant,\n baseWidth: leftDragWidth ?? leftWidth,\n onWidthChange: onLeftWidthChange,\n setDragWidth: setLeftDragWidth,\n isDragging: isLeftDragging,\n setIsDragging: setIsLeftDragging,\n },\n right: {\n ...rightState,\n ...(isRightMobile\n ? {\n mode: 'expanded' as const,\n state: 'expanded' as const,\n toggle: toggleRightMobile,\n setMode: ignoreModeChange,\n }\n : null),\n isMobile: isRightMobile,\n isMobileOpen: openMobileSide === 'right',\n setMobileOpen: setRightMobileOpen,\n isFill: filledSide === 'right',\n toggleFill: toggleRightFill,\n setFill: setRightFill,\n widths: calcEffectiveWidths({\n variant: rightVariant,\n width: rightDragWidth ?? rightWidth,\n collapsible: rightCollapsible,\n state: rightState.state,\n mode: rightState.mode,\n isMobile: isRightMobile,\n }),\n collapsible: rightCollapsible,\n variant: rightVariant,\n baseWidth: rightDragWidth ?? rightWidth,\n onWidthChange: onRightWidthChange,\n setDragWidth: setRightDragWidth,\n isDragging: isRightDragging,\n setIsDragging: setIsRightDragging,\n },\n }),\n [\n isLeftMobile,\n isRightMobile,\n openMobileSide,\n toggleLeftMobile,\n setLeftMobileOpen,\n toggleRightMobile,\n setRightMobileOpen,\n leftState,\n filledSide,\n toggleLeftFill,\n setLeftFill,\n leftVariant,\n leftWidth,\n leftDragWidth,\n leftCollapsible,\n onLeftWidthChange,\n isLeftDragging,\n rightState,\n toggleRightFill,\n setRightFill,\n rightVariant,\n rightWidth,\n rightDragWidth,\n rightCollapsible,\n onRightWidthChange,\n isRightDragging,\n ],\n );\n\n return <SidebarContext value={value}>{children}</SidebarContext>;\n};\n","import type { ComponentProps, MouseEventHandler } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { useSidebar } from './SidebarProvider';\nimport type { SidebarSide } from './types';\n\ntype Props = ComponentProps<typeof Slot> & {\n side?: SidebarSide;\n};\n\nexport const SidebarFillTrigger = ({ ref, side = 'left', onClick, ...rest }: Props) => {\n const { toggleFill, isFill } = useSidebar(side);\n\n const handleOnClick: MouseEventHandler<HTMLElement> = (event) => {\n toggleFill();\n onClick?.(event);\n };\n\n return <Slot {...rest} ref={ref} onClick={handleOnClick} aria-selected={isFill} />;\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const SidebarFooter = ({ className, ...props }: Props) => (\n <div\n data-slot=\"sidebar-footer\"\n className={cn('tw:flex', 'tw:flex-col', 'tw:gap-2', 'tw:p-2', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const SidebarGroup = ({ className, ...props }: Props) => (\n <div\n className={cn(\n 'tw:group/sidebar-group',\n 'tw:relative',\n 'tw:w-full',\n\n // positioning\n 'tw:flex',\n 'tw:flex-col',\n 'tw:min-w-0',\n 'tw:rounded-lg',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const SidebarGroupContent = ({ className, ...props }: Props) => (\n <div\n className={cn(\n // positioning\n 'tw:flex',\n 'tw:flex-col',\n 'tw:gap-2',\n\n 'tw:w-full',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const SidebarGroupAction = ({\n ref,\n className,\n type = 'button',\n children,\n ...props\n}: Props) => (\n <button\n {...props}\n type={type}\n ref={ref}\n className={cn(\n 'tw:group-data-[state=collapsed]/sidebar:hidden',\n\n // positioning\n 'tw:absolute',\n 'tw:right-1.5',\n 'tw:top-2',\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n // sizing\n 'tw:size-5',\n\n // styles\n 'tw:text-neutral-800',\n 'tw:rounded-full',\n\n // svg defaults: size + colour\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3',\n 'tw:[&_svg]:text-neutral-400',\n 'tw:hover:[&_svg]:text-secondary-600',\n\n 'tw:hover:bg-neutral-100',\n\n 'tw:focus-visible:ring-4',\n 'tw:focus-visible:ring-ring/30',\n 'tw:focus-visible:outline',\n 'tw:focus-visible:outline-1',\n 'tw:focus-visible:outline-ring',\n className,\n )}\n >\n {children}\n </button>\n);\n","import type { ComponentProps, Ref } from 'react';\n\nimport { cn } from '../../../utils';\nimport { Separator } from '../../Separator';\n\ntype Props = ComponentProps<'div'>;\n\nexport const SidebarGroupLabel = ({\n ref,\n className,\n children,\n ...props\n}: Props & { ref?: Ref<HTMLDivElement> }) => (\n <div\n ref={ref}\n className={cn(\n 'tw:relative',\n // positioning\n 'tw:flex',\n 'tw:flex-col',\n 'tw:shrink-0',\n\n // styling\n 'tw:h-8',\n 'tw:px-2',\n 'tw:-mb-1',\n 'tw:rounded-lg',\n\n // text\n 'tw:uppercase',\n 'tw:font-sans',\n 'tw:text-xs',\n 'tw:tracking-[1px]',\n className,\n )}\n {...props}\n >\n <Separator\n orientation=\"horizontal\"\n size=\"3/4\"\n className={cn(\n 'tw:opacity-0',\n 'tw:group-data-[state=collapsed]/sidebar:opacity-100',\n\n // positioning\n 'tw:absolute',\n 'tw:w-full',\n 'tw:left-0',\n 'tw:top-1/2 tw:-translate-y-1/2',\n\n 'tw:transition-opacity',\n 'tw:duration-(--sidebar-motion-duration)',\n 'tw:ease-(--sidebar-motion-easing)',\n 'tw:motion-reduce:transition-none',\n )}\n />\n\n <span\n className={cn(\n 'tw:flex',\n 'tw:group-data-[state=collapsed]/sidebar:opacity-0',\n\n 'tw:items-center',\n 'tw:flex-1',\n 'tw:text-muted-foreground',\n 'tw:whitespace-nowrap',\n\n // transition\n 'tw:transition-opacity',\n 'tw:duration-(--sidebar-motion-duration)',\n 'tw:ease-(--sidebar-motion-easing)',\n 'tw:motion-reduce:transition-none',\n )}\n >\n {children}\n </span>\n </div>\n);\n","import { createContext, use } from 'react';\n\nimport type { SidebarMode, SidebarSide, SidebarState } from './types';\n\ntype SidebarInstanceContextValue = {\n state: SidebarState;\n mode: SidebarMode;\n side: SidebarSide;\n};\n\nexport const SidebarInstanceContext = createContext<SidebarInstanceContextValue | null>(null);\n\nexport const useSidebarInstance = () => {\n const context = use(SidebarInstanceContext);\n if (context === null)\n throw new Error('useSidebarInstance must be used within a SidebarInstanceContext.');\n return context;\n};\n","import { type ComponentProps, use } from 'react';\n\nimport { cn } from '../../utils';\nimport { BrandLogo } from '../BrandLogo';\n\nimport { SidebarInstanceContext } from './SidebarInstanceContext';\n\ntype Props = ComponentProps<'div'>;\n\nexport const SidebarHeader = ({ className, children, ...props }: Props) => {\n const instance = use(SidebarInstanceContext);\n // BrandLogo reads the nearest ThemeProvider (or the default context) and renders\n // null when the active brand ships no logo, so no provider gate is needed.\n const variant = instance?.state === 'collapsed' ? 'mark' : 'wordmark';\n const fallback = <BrandLogo variant={variant} className=\"tw:h-7\" />;\n\n return (\n <div\n data-slot=\"sidebar-header\"\n className={cn(\n 'tw:peer/sidebar-header',\n 'tw:flex',\n 'tw:flex-col',\n 'tw:gap-2',\n 'tw:p-2',\n className,\n )}\n {...props}\n >\n {children ?? fallback}\n </div>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'ul'>;\n\nexport const SidebarMenu = ({ className, ...props }: Props) => (\n <ul\n data-sidebar=\"menu\"\n className={cn(\n 'tw:flex',\n 'tw:w-full',\n 'tw:min-w-0',\n 'tw:flex-col',\n 'tw:gap-1',\n\n // transition\n 'tw:transition-[margin,opacity]',\n 'tw:duration-(--sidebar-motion-duration)',\n 'tw:ease-(--sidebar-motion-easing)',\n 'tw:motion-reduce:transition-none',\n\n // TODO: remove when boostrap is gone\n 'tw:pl-0',\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 SidebarMenuIcon = ({ ref, className, children, ...rest }: Props) => (\n <span\n {...rest}\n ref={ref}\n className={cn(\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:aspect-square',\n 'tw:shrink-0',\n 'tw:p-0.5',\n 'tw:text-sidebar-primary',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4',\n className,\n )}\n >\n {children}\n </span>\n);\n","import type { AriaAttributes, MouseEvent, MouseEventHandler } from 'react';\n\nimport { useSidebarInstance } from '../SidebarInstanceContext';\nimport { useSidebar } from '../SidebarProvider';\n\n/**\n * The props a click has to be measured against before it counts as a destination.\n *\n * - Each is injected by a wrapper, not written by the call site: a Radix `Slot` merges them\n * into the item's own props, and `cloneElement` reaches a component child, so they arrive\n * here as ordinary props.\n */\ntype Props = Pick<AriaAttributes, 'aria-haspopup' | 'aria-expanded'> & {\n 'data-sidebar-trigger'?: string;\n};\n\n/**\n * The click handler a sidebar menu item runs: the caller's own, then the sheet's dismissal.\n *\n * - On a phone the rail is a sheet over the page, so a chosen destination has to dismiss it —\n * otherwise the page it navigated to sits behind the overlay.\n * - Two kinds of click are not a destination:\n * - Opening a popup. `DropdownMenu.Trigger` and `Sidebar.SubMenu` both hand their child an\n * `aria-haspopup` / `aria-expanded`, and closing the sheet under their popup would take\n * the popup with it.\n * - Acting on the rail itself. `Sidebar.Trigger` marks its child `data-sidebar-trigger`; its\n * own `toggle` runs after this handler, so dismissing here would hand `toggle` a closed\n * sheet and it would open it straight back up.\n * - Above the breakpoint the caller's `onClick` is all that runs.\n */\nexport const useDestinationDismiss = <T extends HTMLElement>(\n props: Props,\n onClick: MouseEventHandler<T> | undefined,\n): MouseEventHandler<T> => {\n const { side } = useSidebarInstance();\n const { isMobile, setMobileOpen } = useSidebar(side);\n\n const isDestination =\n props['aria-haspopup'] === undefined &&\n props['aria-expanded'] === undefined &&\n props['data-sidebar-trigger'] === undefined;\n\n return (event: MouseEvent<T>) => {\n onClick?.(event);\n if (isMobile && isDestination) setMobileOpen(false);\n };\n};\n","import type { ComponentProps, ReactNode, Ref } from 'react';\nimport { Root, Slottable } from '@radix-ui/react-slot';\n\nimport { cn } from '../../../utils';\nimport { Tooltip } from '../../Tooltip';\nimport { useSidebarInstance } from '../SidebarInstanceContext';\n\nimport { SidebarMenuIcon } from './SidebarMenuIcon';\nimport { useDestinationDismiss } from './useDestinationDismiss';\n\ntype Props = ComponentProps<'button'> & {\n asChild?: boolean;\n tooltip?: ReactNode;\n icon?: ReactNode;\n /** Set by `Sidebar.Trigger` on the child it wraps — not part of a call site's API. */\n 'data-sidebar-trigger'?: string;\n};\n\nexport const SidebarMenuButton = ({\n ref,\n 'aria-selected': selected,\n className,\n children,\n asChild = false,\n icon,\n tooltip,\n onClick,\n ...props\n}: Props & { ref?: Ref<HTMLButtonElement> }) => {\n const Component = asChild ? Root : 'button';\n const { state, mode, side } = useSidebarInstance();\n const handleClick = useDestinationDismiss<HTMLButtonElement>(props, onClick);\n\n const button = (\n <Component\n {...props}\n onClick={handleClick}\n ref={ref}\n data-slot=\"sidebar-menu-button\"\n // `type` and `aria-selected` belong to a real <button>. With `asChild` the slot is\n // usually an <a> (the canonical nav item), where both are invalid — axe flags\n // `aria-selected` on a link as a critical violation. Mark the active link with\n // `aria-current=\"page\"` instead; it is styled identically below. `aria-selected`\n // is still forwarded when a caller passes it explicitly.\n {...(asChild ? {} : { type: 'button' as const })}\n {...(selected === undefined ? {} : { 'aria-selected': selected })}\n className={cn(\n 'tw:peer/sidebar-menu-button',\n 'tw:group/sidebar-menu-button',\n\n // if <SidebarMenuAction /> visible, prevent the text from being under the action button.\n 'tw:group-data-[state=expanded]/sidebar:group-has-[[data-slot=sidebar-menu-action][data-hover-only=false]]/sidebar-menu-item:pr-8',\n 'tw:group-data-[state=expanded]/sidebar:[&:has(+[data-slot=\"sidebar-menu-action\"])]:group-hover/sidebar-menu-item:pr-8',\n 'tw:group-data-[state=expanded]/sidebar:[&:has(+[data-slot=\"sidebar-menu-action\"])]:group-focus-within/sidebar-menu-item:pr-8',\n 'tw:group-data-[state=expanded]/sidebar:[&:has(+[data-slot=\"sidebar-menu-action\"][data-hover-only=true][data-state=open])]:pr-8',\n\n 'tw:flex',\n 'tw:w-full',\n 'tw:gap-2',\n 'tw:items-center',\n 'tw:z-10',\n 'tw:font-normal',\n 'tw:text-sidebar-foreground',\n 'tw:p-2',\n 'tw:whitespace-nowrap',\n 'tw:overflow-hidden',\n 'tw:rounded-lg',\n 'tw:text-start',\n 'tw:no-underline',\n 'tw:select-none',\n\n // hover\n 'tw:hover:not-disabled:bg-sidebar-accent',\n 'tw:hover:text-sidebar-accent-foreground',\n 'tw:focus:text-sidebar-accent-foreground', // anchor override\n 'tw:data-[slot=dropdown-menu-trigger]:data-[state=open]:bg-sidebar-accent',\n\n // disabled\n 'tw:disabled:opacity-50',\n 'tw:disabled:cursor-not-allowed',\n\n // active\n 'tw:aria-selected:font-medium',\n 'tw:aria-selected:bg-sidebar-accent',\n 'tw:aria-selected:cursor-default',\n // active for links https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-current\n 'tw:aria-[current=page]:bg-sidebar-accent',\n 'tw:aria-[current=page]:font-medium',\n 'tw:aria-[current=page]:focus:text-sidebar-accent-foreground',\n\n // focus-visible\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:z-10',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-sidebar-ring/50',\n 'tw:focus-visible:text-sidebar-foreground', // anchor override\n className,\n )}\n // Explicitly set the tabIndex to 0 to ensure the button is focusable; in Safari, anchors are not focusable by default.\n tabIndex={0}\n >\n {icon && <SidebarMenuIcon>{icon}</SidebarMenuIcon>}\n <Slottable>{children}</Slottable>\n </Component>\n );\n\n const shouldShowTooltip = state === 'collapsed' && mode !== 'expand-on-hover' && tooltip;\n\n if (shouldShowTooltip) {\n const tooltipPlacement = side === 'right' ? 'left' : 'right';\n\n return (\n <Tooltip tooltip={tooltip} placement={tooltipPlacement} triggerAsChild>\n {button}\n </Tooltip>\n );\n }\n\n return button;\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const SidebarMenuItem = ({ className, ...props }: Props) => (\n <li className={cn('tw:group/sidebar-menu-item', 'tw:relative', className)} {...props} />\n);\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'button'> & {\n asChild?: boolean;\n showOnHover?: boolean;\n};\n\nexport const SidebarMenuAction = ({\n ref,\n className,\n asChild = false,\n showOnHover = false,\n children,\n ...props\n}: Props) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n {...props}\n data-slot=\"sidebar-menu-action\"\n data-hover-only={showOnHover}\n ref={ref}\n className={cn(\n 'tw:absolute',\n 'tw:top-1/2',\n 'tw:-translate-y-1/2',\n 'tw:right-3',\n 'tw:z-10',\n 'tw:p-0.5',\n\n // display\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:aspect-square',\n\n // hiding\n 'tw:data-[hover-only=true]:opacity-0',\n 'tw:group-data-[state=collapsed]/sidebar:hidden',\n\n 'tw:group-data-[state=expanded]/sidebar:group-hover/sidebar-menu-item:opacity-100',\n 'tw:group-data-[state=expanded]/sidebar:group-focus-within/sidebar-menu-item:opacity-100', // keyboard navigation\n\n 'tw:group-data-[state=expanded]/sidebar:data-[hover-only=true]:data-[state=open]:opacity-100', // for triggers (dropdown, tooltip, popover)\n\n 'tw:size-4',\n 'tw:rounded',\n\n // icon styling\n 'tw:[&_svg]:shrink-0',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n 'tw:[&_svg]:text-sidebar-accent-foreground',\n\n // focus visible\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:z-10',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-sidebar-ring/50',\n 'tw:focus-visible:text-sidebar-foreground',\n className,\n )}\n >\n {children}\n </Comp>\n );\n};\n","import { useRef } from 'react';\nimport type { ComponentProps } from 'react';\n\nimport { Search } from '../../../icons';\nimport { cn, mergeRefs } from '../../../utils';\nimport { useSidebarInstance } from '../SidebarInstanceContext';\nimport { useSidebar } from '../SidebarProvider';\n\nconst wrapperClassnames = cn(\n 'tw:group/search-input',\n 'tw:relative',\n 'tw:flex',\n 'tw:items-center',\n 'tw:min-h-9',\n 'tw:rounded-lg',\n 'tw:border',\n 'tw:transition-all',\n\n // collapsed state - transparent border/bg, hover like search button\n 'tw:group-data-[state=collapsed]/sidebar:cursor-pointer',\n 'tw:group-data-[state=collapsed]/sidebar:border-transparent',\n 'tw:group-data-[state=collapsed]/sidebar:hover:bg-sidebar-accent',\n\n // expanded state - visible border/bg, padding for input, text cursor\n 'tw:group-data-[state=expanded]/sidebar:cursor-text',\n 'tw:group-data-[state=expanded]/sidebar:px-2',\n 'tw:group-data-[state=expanded]/sidebar:border-neutral-200',\n\n // focus styles (only relevant when expanded)\n 'tw:focus-within:ring-2',\n 'tw:focus-within:ring-sidebar-ring/50',\n 'tw:focus-within:text-sidebar-foreground',\n);\n\ntype Props = Omit<ComponentProps<'input'>, 'prefix'>;\n\nexport const SidebarSearchInput = ({ ref: forwardedRef, className, ...inputProps }: Props) => {\n const { side } = useSidebarInstance();\n const { setMode } = useSidebar(side);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleFocus = () => {\n setMode('expanded');\n };\n\n return (\n <div className={cn(wrapperClassnames, className)}>\n <Search\n className={cn(\n 'tw:pointer-events-none',\n 'tw:absolute',\n 'tw:left-2',\n 'tw:size-4',\n\n 'tw:text-sidebar-primary',\n 'tw:group-data-[state=expanded]/sidebar:text-neutral-400',\n )}\n />\n <input\n ref={mergeRefs(forwardedRef ?? null, inputRef)}\n {...inputProps}\n onFocus={(e) => {\n handleFocus();\n inputProps.onFocus?.(e);\n }}\n className={cn(\n 'tw:w-full',\n 'tw:bg-transparent',\n 'tw:text-sm',\n 'tw:font-sans',\n 'tw:outline-hidden',\n 'tw:placeholder:text-neutral-400',\n\n // collapsed state - visually hidden but still focusable for a11y\n 'tw:group-data-[state=collapsed]/sidebar:opacity-0',\n 'tw:group-data-[state=collapsed]/sidebar:cursor-pointer',\n\n // expanded state\n 'tw:group-data-[state=expanded]/sidebar:pl-6',\n )}\n />\n </div>\n );\n};\n","import { useCallback, useState } from 'react';\nimport type { ComponentProps, HTMLAttributes, ReactNode } from 'react';\n\nimport { cn } from '../../../utils';\nimport { HoverCard } from '../../HoverCard';\nimport { useSidebarInstance } from '../SidebarInstanceContext';\nimport { useSidebar } from '../SidebarProvider';\n\nimport { SidebarMenuIcon } from './SidebarMenuIcon';\n\nconst Title = ({ children }: { children: ReactNode }) => (\n <div className=\"tw:flex tw:select-none tw:gap-2 tw:text-sm tw:font-semibold\">{children}</div>\n);\n\nconst Content = ({ children, className }: { children: ReactNode; className?: string }) => (\n <div\n className={cn(\n 'tw:whitespace-pre-line',\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:invisible',\n className,\n )}\n >\n {children}\n </div>\n);\n\ntype Props = HTMLAttributes<HTMLDivElement> & {\n icon: ReactNode;\n title: ReactNode;\n};\n\nexport const SidebarMenuCard = ({ children, className, icon, title, ...rest }: Props) => {\n const [isOpen, setIsOpen] = useState(false);\n const { side = 'left' } = useSidebarInstance();\n const { state, isFill } = useSidebar(side);\n const isExpanded = state === 'expanded' || isFill;\n\n const handleOnOpenChange: ComponentProps<typeof HoverCard>['onOpenChange'] = useCallback(\n (open: boolean) => {\n setIsOpen(isExpanded || document.hidden ? false : open);\n },\n [isExpanded],\n );\n\n return (\n <HoverCard open={isOpen} onOpenChange={handleOnOpenChange}>\n <HoverCard.Trigger asChild>\n <div\n {...rest}\n data-slot=\"sidebar-menu-card\"\n tabIndex={isExpanded ? -1 : 0}\n className={cn(\n 'tw:group/sidebar-menu-card',\n 'tw:peer/sidebar-menu-card',\n\n 'tw:overflow-hidden',\n\n 'tw:border',\n 'tw:border-sidebar-border',\n 'tw:rounded-2xl',\n\n // layout\n 'tw:grid',\n 'tw:grid-rows-[1fr]',\n 'tw:flex-1',\n 'tw:p-4',\n\n // icon collapsed\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:p-2',\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:border-transparent',\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:grid-rows-[18px]',\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:rounded-md',\n\n // focus-visible\n 'tw:outline-hidden',\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:hover:bg-sidebar-accent',\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:focus-visible:ring-2',\n 'tw:group-data-[fill=false]/sidebar:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:focus-visible:ring-sidebar-ring/50',\n\n // transition\n 'tw:transition-[padding,border]',\n 'tw:duration-(--sidebar-motion-duration)',\n 'tw:ease-(--sidebar-motion-easing)',\n 'tw:motion-reduce:transition-none',\n )}\n >\n <div className=\"tw:flex tw:flex-col tw:gap-2\">\n <Title>\n <SidebarMenuIcon className=\"tw:p-px\">{icon}</SidebarMenuIcon>\n {title}\n </Title>\n <Content className={className}>{children}</Content>\n </div>\n </div>\n </HoverCard.Trigger>\n\n <HoverCard.Content\n sideOffset={10}\n align=\"center\"\n side={side === 'left' ? 'right' : 'left'}\n className=\"tw:flex tw:flex-col tw:gap-2\"\n >\n <Title>{title}</Title>\n <Content className={className}>{children}</Content>\n </HoverCard.Content>\n </HoverCard>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const SidebarMenuBadge = ({ ref, className, ...props }: Props) => {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:z-20',\n\n 'tw:absolute',\n\n // menu button position\n 'tw:peer-[]/sidebar-menu-button:right-2',\n // menu card position\n 'tw:peer-[]/sidebar-menu-card:right-4',\n 'tw:peer-[]/sidebar-menu-card:top-4',\n\n // icon collapsed position\n 'tw:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:right-0',\n 'tw:group-data-[state=collapsed]/sidebar:group-data-[collapsible=icon]/sidebar:-top-1',\n\n 'tw:text-xs',\n 'tw:text-sidebar-primary-foreground',\n 'tw:bg-sidebar-primary',\n 'tw:px-1',\n 'tw:min-w-5',\n 'tw:h-5',\n 'tw:rounded-full',\n 'tw:pointer-events-none',\n 'tw:font-medium',\n 'tw:tabular-nums',\n 'tw:select-none',\n\n 'tw:transition-[top,right]',\n 'tw:delay-50',\n 'tw:duration-(--sidebar-motion-duration)',\n 'tw:ease-(--sidebar-motion-easing)',\n 'tw:motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n );\n};\n","import { useState } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { ChevronDown } from '../../../icons';\nimport { cn } from '../../../utils';\nimport { Collapsible } from '../../Collapsible';\nimport { DropdownMenu } from '../../DropdownMenu';\nimport { Tooltip } from '../../Tooltip';\nimport { useSidebarInstance } from '../SidebarInstanceContext';\n\nimport { SidebarMenuButton } from './SidebarMenuButton';\n\ntype Props = {\n children: ReactNode;\n icon: ReactNode;\n isActive?: boolean;\n label: string;\n} & Pick<ComponentProps<typeof Collapsible>, 'defaultOpen' | 'open' | 'onOpenChange'>;\n\nexport const SidebarMenuSub = ({\n children,\n icon,\n isActive = false,\n label,\n\n // collapsible props\n defaultOpen = false,\n open: openProp,\n onOpenChange,\n}: Props) => {\n const { state, side, mode } = useSidebarInstance();\n const [open, setOpen] = useState<'open-tooltip' | 'open-dropdown-menu' | null>(null);\n const [innerCollapsibleOpen, setInnerCollapsibleOpen] = useState(defaultOpen);\n\n const isCollapsibleOpen = (() => {\n // In the collapsed sidebar state, it is always closed.\n if (state === 'collapsed') return false;\n return openProp ?? innerCollapsibleOpen;\n })();\n\n const isDropdownMenu = mode === 'expand-on-hover' || mode === 'collapsed';\n\n const handleCollapsibleOpenChange = (open: boolean) => {\n if (openProp === undefined) setInnerCollapsibleOpen(open);\n\n onOpenChange?.(open);\n };\n\n const handleDropdownOpenChange = (open: boolean) => {\n setOpen(open ? 'open-dropdown-menu' : null);\n };\n\n const handleTooltipOpenChange = (open: boolean) => {\n setOpen((currentOpen) => {\n // dropdown menu has higher priority than tooltip, if it's open, keep it open\n if (currentOpen === 'open-dropdown-menu') return 'open-dropdown-menu';\n // no need to show tooltip in expanded state, so return null\n if (state === 'expanded') return null;\n return open ? 'open-tooltip' : null;\n });\n };\n\n if (isDropdownMenu) {\n return (\n <DropdownMenu open={open === 'open-dropdown-menu'} onOpenChange={handleDropdownOpenChange}>\n <Tooltip.Root open={open === 'open-tooltip'} onOpenChange={handleTooltipOpenChange}>\n <Tooltip.Trigger asChild>\n <DropdownMenu.Trigger asChild>\n <SidebarMenuButton\n icon={icon}\n data-active={isActive}\n className={cn(\n 'tw:data-[active=true]:bg-sidebar-accent',\n 'tw:data-[active=true]:font-medium',\n )}\n >\n {label}\n </SidebarMenuButton>\n </DropdownMenu.Trigger>\n </Tooltip.Trigger>\n <Tooltip.Content variant=\"action\" placement={side}>\n {label}\n </Tooltip.Content>\n </Tooltip.Root>\n\n <DropdownMenu.Content side={side} align=\"start\">\n <DropdownMenu.Label>{label}</DropdownMenu.Label>\n {children}\n </DropdownMenu.Content>\n </DropdownMenu>\n );\n }\n\n return (\n <Collapsible open={isCollapsibleOpen} onOpenChange={handleCollapsibleOpenChange}>\n <Collapsible.Trigger asChild>\n <SidebarMenuButton\n icon={icon}\n data-active={isActive && !isCollapsibleOpen}\n className={cn(\n 'tw:group',\n 'tw:data-[active=true]:bg-sidebar-accent',\n 'tw:data-[active=true]:font-medium',\n )}\n >\n {label}\n <ChevronDown className=\"tw:ml-auto tw:size-5 tw:transition-transform tw:duration-200 tw:group-data-[state=open]:rotate-180\" />\n </SidebarMenuButton>\n </Collapsible.Trigger>\n <Collapsible.Content>\n <ul\n data-sidebar=\"menu-sub\"\n className={cn(\n 'tw:ml-3.5',\n 'tw:flex',\n 'tw:min-w-0',\n 'tw:translate-x-px',\n 'tw:flex-col',\n 'tw:gap-1',\n 'tw:border-l',\n 'tw:border-sidebar-border',\n 'tw:py-0.5',\n 'tw:pl-2.5',\n 'tw:pr-0',\n\n // TODO: remove when bootstrap is gone\n 'tw:list-none',\n )}\n >\n {children}\n </ul>\n </Collapsible.Content>\n </Collapsible>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Root, Slottable } from '@radix-ui/react-slot';\n\nimport { cn } from '../../../utils';\nimport { DropdownMenu } from '../../DropdownMenu';\nimport { useSidebarInstance } from '../SidebarInstanceContext';\n\nimport { useDestinationDismiss } from './useDestinationDismiss';\n\ntype Props = ComponentProps<'button'> & {\n asChild?: boolean;\n /** Set by `Sidebar.Trigger` on the child it wraps — not part of a call site's API. */\n 'data-sidebar-trigger'?: string;\n};\n\nexport const SidebarMenuSubItem = ({\n ref,\n className,\n asChild = false,\n children,\n disabled,\n onClick,\n 'aria-current': ariaCurrent,\n ...props\n}: Props) => {\n const { mode } = useSidebarInstance();\n // A nested destination is a destination: an expanded `Sidebar.SubMenu` renders its children\n // here, and choosing one navigates the page the sheet is sitting on top of.\n const handleClick = useDestinationDismiss<HTMLButtonElement>(props, onClick);\n const isDropdownMenu = mode === 'collapsed' || mode === 'expand-on-hover';\n\n if (isDropdownMenu) {\n return (\n <DropdownMenu.Item\n aria-current={ariaCurrent}\n asChild={asChild}\n disabled={disabled}\n className={cn(\n // use sidebar colors for active and focus states\n 'tw:focus:!bg-sidebar-accent',\n 'tw:aria-[current=page]:bg-sidebar-accent',\n 'tw:aria-[current=page]:focus:text-sidebar-accent-foreground',\n className,\n )}\n >\n {children}\n </DropdownMenu.Item>\n );\n }\n\n const Component = asChild ? Root : 'button';\n\n return (\n <li className=\"tw:group/sidebar-menu-sub-item tw:relative\">\n <Component\n {...props}\n onClick={handleClick}\n ref={ref}\n aria-current={ariaCurrent}\n data-slot=\"sidebar-menu-sub-button\"\n type=\"button\"\n disabled={disabled}\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n\n // sizing\n 'tw:h-7',\n 'tw:w-full',\n 'tw:min-w-0',\n 'tw:px-2',\n\n //font\n 'tw:text-sidebar-foreground',\n 'tw:text-sm',\n 'tw:font-normal',\n 'tw:text-start',\n 'tw:whitespace-nowrap',\n\n 'tw:overflow-hidden',\n 'tw:rounded-md',\n 'tw:no-underline',\n\n 'tw:select-none',\n 'tw:outline-hidden',\n\n // hover\n 'tw:hover:not-disabled:bg-sidebar-accent',\n 'tw:hover:text-sidebar-accent-foreground',\n 'tw:focus:text-sidebar-accent-foreground',\n\n // active\n 'tw:aria-selected:font-medium',\n 'tw:aria-selected:bg-sidebar-accent',\n 'tw:aria-[current=page]:bg-sidebar-accent',\n 'tw:aria-[current=page]:font-medium',\n\n // disabled\n 'tw:disabled:opacity-50',\n 'tw:disabled:cursor-not-allowed',\n\n // focus-visible\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-sidebar-ring/50',\n className,\n )}\n >\n <Slottable>{children}</Slottable>\n </Component>\n </li>\n );\n};\n","import { type MouseEventHandler, useCallback, useEffect, useRef } from 'react';\n\nimport { useSidebar } from './SidebarProvider';\nimport type { SidebarSide } from './types';\nimport { SidebarWidthInPx } from './utils';\n\nconst DEFAULT_MIN_WIDTH = 384;\nconst DEFAULT_MAX_WIDTH = 800;\n\ntype UseResizeSidebarInput = {\n side: SidebarSide;\n minWidth?: number;\n maxWidth?: number;\n};\n\nexport const useResizeSidebar = ({\n side,\n minWidth = DEFAULT_MIN_WIDTH,\n maxWidth = DEFAULT_MAX_WIDTH,\n}: UseResizeSidebarInput) => {\n const { onWidthChange, baseWidth, isFill, state, isDragging, setIsDragging, setDragWidth } =\n useSidebar(side);\n const isResizable = state === 'expanded' && !isFill && onWidthChange !== undefined;\n const startXRef = useRef(0);\n const startWidthRef = useRef(0);\n const cleanupRef = useRef<(() => void) | null>(null);\n\n useEffect(() => {\n return () => {\n cleanupRef.current?.();\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n };\n }, []);\n\n const clampToRange = useCallback(\n (width: number) => {\n const effectiveMax = Math.max(minWidth, Math.min(maxWidth, window.innerWidth * 0.5));\n return Math.round(Math.min(effectiveMax, Math.max(minWidth, width)));\n },\n [minWidth, maxWidth],\n );\n\n const handleMouseDown: MouseEventHandler = useCallback(\n (e) => {\n if (!isResizable || isDragging) return;\n\n cleanupRef.current?.();\n setIsDragging(true);\n\n startWidthRef.current = baseWidth ?? SidebarWidthInPx.MIN_DEFAULT;\n startXRef.current = e.clientX;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n const delta =\n side === 'right'\n ? startXRef.current - moveEvent.clientX\n : moveEvent.clientX - startXRef.current;\n setDragWidth(clampToRange(startWidthRef.current + delta));\n };\n\n const handleMouseUp = (upEvent: MouseEvent) => {\n const delta =\n side === 'right'\n ? startXRef.current - upEvent.clientX\n : upEvent.clientX - startXRef.current;\n onWidthChange?.(clampToRange(startWidthRef.current + delta));\n setIsDragging(false);\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n cleanupRef.current = null;\n };\n\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n\n cleanupRef.current = () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n setIsDragging(false);\n setDragWidth(null);\n };\n },\n [\n isResizable,\n isDragging,\n side,\n onWidthChange,\n baseWidth,\n setIsDragging,\n setDragWidth,\n clampToRange,\n ],\n );\n\n const handleDoubleClick = useCallback(() => {\n onWidthChange?.(minWidth);\n }, [onWidthChange, minWidth]);\n\n return {\n handleProps: {\n onMouseDown: handleMouseDown,\n onDoubleClick: handleDoubleClick,\n },\n isDragging,\n isResizable,\n };\n};\n","import { cn } from '../../utils';\n\nimport type { SidebarSide } from './types';\nimport { useResizeSidebar } from './useResizeSidebar';\n\ntype Props = {\n side: SidebarSide;\n minWidth?: number;\n maxWidth?: number;\n};\n\nexport const SidebarResizeHandle = ({ side, minWidth, maxWidth }: Props) => {\n const { handleProps, isResizable } = useResizeSidebar({ side, minWidth, maxWidth });\n\n if (!isResizable) return null;\n\n return (\n <div\n {...handleProps}\n aria-hidden\n className={cn(\n 'tw:absolute tw:inset-y-0 tw:z-10 tw:w-3',\n side === 'right' ? 'tw:left-0' : 'tw:right-0',\n 'tw:cursor-col-resize',\n )}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\nimport { Separator } from '../Separator';\n\ntype Props = Omit<ComponentProps<typeof Separator>, 'orientation' | 'size'>;\n\nexport const SidebarSeparator = ({ className, ...props }: Props) => (\n <Separator\n {...props}\n orientation=\"horizontal\"\n size=\"full\"\n className={cn('tw:before:bg-sidebar-border tw:p-2', className)}\n />\n);\n","import type { ComponentProps, MouseEventHandler } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\nimport { useSidebar } from './SidebarProvider';\nimport type { SidebarSide } from './types';\n\ntype Props = ComponentProps<typeof Slot> & {\n side?: SidebarSide;\n hideWhenCollapsed?: boolean;\n};\n\nexport const SidebarTrigger = ({\n side = 'left',\n onClick,\n hideWhenCollapsed = false,\n className,\n ...rest\n}: Props) => {\n const { toggle, state, isMobile, isMobileOpen } = useSidebar(side);\n\n const handleOnClick: MouseEventHandler<HTMLElement> = (event) => {\n toggle();\n onClick?.(event);\n };\n\n return (\n <Slot\n {...rest}\n // What this button does to the rail, for anyone who cannot see it.\n //\n // - Stating `aria-expanded` is this primitive's job, on both axes, and the two axes\n // answer different questions: a sheet is open or closed, a column expanded or collapsed.\n // A call site supplying its own would win the slot merge — a child's non-event prop\n // beats the one passed here — and announce the column's mode while the rail is a sheet.\n // - `aria-haspopup` is the one that does not carry over: a column is not a dialog, and\n // on a phone the sheet has no `Sheet.Trigger` of its own to say that it is.\n aria-expanded={isMobile ? isMobileOpen : state === 'expanded'}\n {...(isMobile ? { 'aria-haspopup': 'dialog' as const } : null)}\n // Tells a `Sidebar.MenuButton` underneath that this click is about the rail itself, not a\n // destination in it. Without it the button's own mobile dismissal runs first (a slot\n // composes the child's handler before its own) and `toggle` then reopens the sheet it\n // just closed. Lands on the DOM node when the child is a plain element; harmless there.\n data-sidebar-trigger=\"\"\n onClick={handleOnClick}\n className={cn(\n {\n 'tw:group-data-[state=collapsed]/sidebar:hidden': hideWhenCollapsed,\n },\n className,\n )}\n />\n );\n};\n","import { useEffect, useMemo, useRef } from 'react';\nimport type { ComponentProps, CSSProperties, ReactNode, TransitionEventHandler } from 'react';\n\nimport { cn } from '../../utils';\nimport { Sheet } from '../Sheet';\nimport { useThemeScopeContainer } from '../ThemeProvider/ThemeScope';\nimport { TooltipProvider } from '../Tooltip';\n\nimport { useTransitionPresence } from './SidebarProvider/useTransitionPresence';\nimport { SidebarContent } from './SidebarContent';\nimport { SidebarFillTrigger } from './SidebarFillTrigger';\nimport { SidebarFooter } from './SidebarFooter';\nimport {\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n} from './SidebarGroup';\nimport { SidebarHeader } from './SidebarHeader';\nimport { SidebarInstanceContext } from './SidebarInstanceContext';\nimport {\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuCard,\n SidebarMenuIcon,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubItem,\n SidebarSearchInput,\n} from './SidebarMenu';\nimport { useSidebar } from './SidebarProvider';\nimport { SidebarResizeHandle } from './SidebarResizeHandle';\nimport { SidebarSeparator } from './SidebarSeparator';\nimport { SidebarTrigger } from './SidebarTrigger';\nimport type { SidebarSide } from './types';\nimport { SidebarWidthInPx } from './utils';\n\n/**\n * `className` and `style` land on the inner wrapper (the rail's own box); everything else\n * (`data-*`, `aria-*`, handlers) lands on the outer element, so a `ThemeScope` around the\n * sidebar reaches it.\n */\ntype Props = Omit<ComponentProps<'div'>, 'children' | 'className' | 'style' | 'id'> & {\n children: ReactNode;\n className?: string;\n id?: string;\n side?: SidebarSide;\n style?: CSSProperties;\n container?: boolean;\n keepMounted?: boolean;\n /** Hold the panel's content back until it has finished sliding in. */\n mountAfterEnter?: boolean;\n resizable?: boolean;\n /**\n * Accessible name for the sheet the rail becomes under the mobile breakpoint.\n *\n * - Defaults to `Navigation` on the left and `Side panel` on the right.\n * - Rendered visually hidden — the sheet is a dialog and needs a name, but the rail's\n * own header is already the visible one.\n */\n mobileTitle?: string;\n};\n\nexport const Sidebar = ({\n children,\n className,\n id,\n side = 'left',\n style,\n container = false,\n keepMounted,\n mountAfterEnter,\n resizable = false,\n mobileTitle,\n ...rest\n}: Props) => {\n const oppositeSide = side === 'left' ? 'right' : 'left';\n const {\n setSidebarElement,\n state,\n mode,\n isFill,\n widths,\n collapsible,\n variant,\n isDragging,\n isMobile,\n isMobileOpen,\n setMobileOpen,\n } = useSidebar(side);\n\n // Where the sheet is portalled.\n //\n // - A `ThemeScope` publishes a body-level container carrying its scheme and its tokens;\n // `Sheet.Content` mounts at the end of <body>, so without it the sheet's own chrome\n // would paint in the page's scheme around a rail rendered in the scope's.\n // - `null` outside a scope, which is Radix's own default.\n const themeScopeContainer = useThemeScopeContainer();\n\n const { isMounted, completeUnmount } = useTransitionPresence({\n mounted: collapsible !== 'off-canvas' || mode !== 'collapsed',\n keepMounted,\n mountAfterEnter,\n });\n const { widths: oppositeWidths } = useSidebar(oppositeSide);\n const sidebarInstanceContextValue = useMemo(() => ({ state, mode, side }), [state, mode, side]);\n\n // Where focus goes when the sheet closes.\n //\n // - Radix returns focus to a `Dialog.Trigger`, and this sheet has none: it is opened from a\n // `Sidebar.Trigger` that may sit anywhere in the page chrome. Without this, closing drops\n // focus onto <body> and a keyboard user restarts at the top of the document.\n // - Recorded only while the sheet is closed, so the opener is the last element tracked and\n // focus moving inside the sheet does not overwrite it.\n // - The node is re-checked on close: a trigger that unmounted with the page it belonged to\n // would otherwise take focus into a detached tree.\n const focusOriginRef = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!isMobile || isMobileOpen) return;\n\n const remember = (event: FocusEvent) => {\n if (event.target instanceof HTMLElement) focusOriginRef.current = event.target;\n };\n\n document.addEventListener('focusin', remember);\n\n return () => document.removeEventListener('focusin', remember);\n }, [isMobile, isMobileOpen]);\n\n // Where focus goes when the viewport grows out from under an open sheet.\n //\n // - The rail is handed back to the grid by unmounting the sheet, not by closing it, so\n // Radix's `onCloseAutoFocus` never runs and whatever was focused inside the portal goes\n // with it — a keyboard user restarts at the top of the document.\n // - The opener is the target here too. A page that only shows its trigger below the\n // breakpoint has just hidden it, and `.focus()` on a hidden element is a no-op — the\n // same place focus would have landed anyway.\n const wasSheetUpRef = useRef(false);\n\n useEffect(() => {\n const wasSheetUp = wasSheetUpRef.current;\n wasSheetUpRef.current = isMobile && isMobileOpen;\n\n if (!wasSheetUp || isMobile) return;\n\n const origin = focusOriginRef.current;\n if (origin?.isConnected) origin.focus();\n }, [isMobile, isMobileOpen]);\n\n const handleTransitionEnd: TransitionEventHandler<HTMLDivElement> = (event) => {\n // Ignore bubbled transitions from child elements\n if (event.target !== event.currentTarget) return;\n completeUnmount();\n };\n\n const styles = {\n // The caller's vars ride on this element too (a `ThemeScope`'s tokens must reach the\n // gap and the wrapper alike); the sidebar's own geometry vars are listed after, so they win here.\n ...style,\n '--sidebar-floating-padding': `${SidebarWidthInPx.FLOATING_VARIANT_PADDING}px`,\n '--sidebar-width': `${widths.sidebar}px`,\n '--sidebar-width-gap': `${widths.gap}px`,\n '--opposite-sidebar-width': `${oppositeWidths.fill}px`,\n } as CSSProperties;\n\n if (variant === 'none') return null;\n\n // The rail's own data attributes and `group/sidebar` scope, minus the geometry: every\n // child selector (`group-data-[state=expanded]/sidebar:…`) has to keep resolving inside\n // the sheet, while the column, the gap and the fixed wrapper have no meaning there.\n const railAttributes = {\n 'data-state': state,\n 'data-side': side,\n 'data-mode': mode,\n 'data-collapsible': collapsible,\n 'data-variant': variant,\n 'data-fill': isFill,\n } as const;\n\n // `keepMounted` and `mountAfterEnter` are deliberately not honoured here: both exist to\n // control when the panel's content mounts relative to the column's slide, and the sheet\n // mounts its content on open and unmounts it on close — the guarantee `mountAfterEnter`\n // asks for, without a transition to wait on.\n if (isMobile) {\n return (\n <TooltipProvider>\n <SidebarInstanceContext value={sidebarInstanceContextValue}>\n <Sheet open={isMobileOpen} onOpenChange={setMobileOpen}>\n <Sheet.Content\n side={side}\n container={themeScopeContainer ?? undefined}\n // The sheet's own chrome, and nothing of the caller's: its width, its ground,\n // and the tokens it paints them with. Those reach it through the container\n // above — a `ThemeScope` carries its scheme and its vars on the node it\n // portals into — so the caller's `style` stays on the rail, where a `width`\n // or a `position` meant for a column cannot fight the sheet's geometry.\n className=\"tw:w-[min(20rem,85vw)] tw:bg-sidebar tw:text-sidebar-foreground tw:p-0\"\n onCloseAutoFocus={(event) => {\n const origin = focusOriginRef.current;\n if (!origin?.isConnected) return;\n event.preventDefault();\n origin.focus();\n }}\n >\n <Sheet.Title visuallyHidden>\n {mobileTitle ?? (side === 'left' ? 'Navigation' : 'Side panel')}\n </Sheet.Title>\n {/* No `ref={setSidebarElement}`: that element only drives `expand-on-hover`, which\n a sheet has no state to expand from, and a phone has no hover to track. */}\n <div\n {...rest}\n {...railAttributes}\n id={id}\n // The rail's own box, so `className` and `style` land together here the way\n // they land on the wrapper above the breakpoint. A class written against the\n // column's geometry has nothing to act on in a sheet, but dropping the prop\n // would drop a `ThemeScope`'s class and every rail-level style with it.\n style={style}\n className={cn(\n 'tw:flex tw:min-h-0 tw:flex-1 tw:flex-col',\n { 'tw:group/sidebar tw:peer/sidebar': !container },\n className,\n )}\n >\n <div\n data-slot=\"sidebar\"\n className={cn(\n 'tw:bg-sidebar',\n 'tw:relative',\n 'tw:flex',\n 'tw:flex-col',\n 'tw:size-full',\n 'tw:overflow-hidden',\n 'tw:border-sidebar-border',\n 'tw:group-[]/sidebar:pt-2',\n )}\n >\n {children}\n </div>\n </div>\n </Sheet.Content>\n </Sheet>\n </SidebarInstanceContext>\n </TooltipProvider>\n );\n }\n\n return (\n <TooltipProvider>\n <SidebarInstanceContext value={sidebarInstanceContextValue}>\n <div\n {...rest}\n {...railAttributes}\n id={id}\n ref={setSidebarElement}\n style={styles}\n className={cn(\n 'tailwindcss-preflight',\n 'tw:flex',\n 'tw:relative',\n // expand-on-hover needs a higher z-index so the expanding sidebar\n // overlaps the opposite filled sidebar instead of sliding behind it\n mode === 'expand-on-hover' ? 'tw:z-[51]' : 'tw:z-50',\n {\n // group/peer scoping is only for page-level sidebars — container\n // sidebars are nested inside other components and must not leak\n // group/peer selectors to avoid clashing with the outer sidebar\n 'tw:group/sidebar tw:peer/sidebar': !container,\n },\n\n // ── GAP DIV ──\n 'tw:[&>[data-slot=gap]]:w-(--sidebar-width-gap)',\n 'tw:[&[data-side=right]>[data-slot=gap]]:rotate-180',\n\n // ── SIDEBAR-WRAPPER DIV ──\n 'tw:[&>[data-slot=sidebar-wrapper]]:w-(--sidebar-width)',\n 'tw:[&[data-side=left]>[data-slot=sidebar-wrapper]]:left-0',\n 'tw:[&[data-side=right]>[data-slot=sidebar-wrapper]]:right-0',\n // Off-canvas hiding.\n // - `translate-x-*` sets the standalone `translate` property, not `transform`.\n // - The wrapper's transition list must therefore name `translate`, or the rail\n // teleports instead of sliding.\n 'tw:[&[data-state=collapsed][data-collapsible=off-canvas][data-side=left]>[data-slot=sidebar-wrapper]]:-translate-x-full',\n 'tw:[&[data-state=collapsed][data-collapsible=off-canvas][data-side=right]>[data-slot=sidebar-wrapper]]:translate-x-full',\n\n // floating variants styles\n 'tw:[&[data-variant=sided-floating]>[data-slot=sidebar-wrapper]]:pt-(--sidebar-floating-padding)',\n 'tw:[&[data-variant=sided-floating][data-side=left]>[data-slot=sidebar-wrapper]]:pr-(--sidebar-floating-padding)',\n 'tw:[&[data-variant=sided-floating][data-side=right]>[data-slot=sidebar-wrapper]]:pl-(--sidebar-floating-padding)',\n\n 'tw:[&[data-variant=floating]>[data-slot=sidebar-wrapper]]:p-(--sidebar-floating-padding)',\n\n // fill state\n 'tw:[&[data-fill=true]>[data-slot=sidebar-wrapper]]:!w-[calc(100svw-var(--opposite-sidebar-width))]',\n 'tw:[&[data-fill=true][data-variant=floating]>[data-slot=sidebar-wrapper]]:!p-(--sidebar-floating-padding)',\n 'tw:[&[data-fill=true][data-variant=sided-floating][data-side=left]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:!rounded-tr-xl',\n 'tw:[&[data-fill=true][data-variant=sided-floating][data-side=right]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:!rounded-tl-xl',\n\n // ── SIDEBAR DIV (INNERMOST) ──\n 'tw:[&[data-variant=inset][data-side=left]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:border-r',\n 'tw:[&[data-variant=inset][data-side=right]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:border-l',\n 'tw:[&[data-variant=floating]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:shadow',\n 'tw:[&[data-variant=floating]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:rounded-xl',\n 'tw:[&[data-variant=sided-floating]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:shadow',\n 'tw:[&[data-variant=sided-floating][data-side=left]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:rounded-tr-xl',\n 'tw:[&[data-variant=sided-floating][data-side=right]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:rounded-tl-xl',\n // The rail's inner edge, mirroring `inset`. The shadow above cannot carry\n // this alone: a shadow needs a lighter ground to fall on, and on the dark\n // scheme `--sidebar` is darker than `--background`, so the rail's edge\n // dissolves into the page beside it.\n 'tw:[&[data-variant=sided-floating][data-side=left]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:border-r',\n 'tw:[&[data-variant=sided-floating][data-side=right]>[data-slot=sidebar-wrapper]>[data-slot=sidebar]]:border-l',\n\n // Ease-out (linear reads as choppy). The page reflowing beside the rail is layout every frame;\n // `motion-reduce` is the lever for weak machines.\n isDragging\n ? 'tw:transition-none'\n : 'tw:transition-[width,translate,transform] tw:duration-(--sidebar-motion-duration) tw:ease-(--sidebar-motion-easing) tw:motion-reduce:transition-none',\n )}\n >\n <div\n data-slot=\"gap\"\n className={cn(\n 'tw:bg-transparent',\n isDragging\n ? ''\n : 'tw:transition-[width] tw:duration-(--sidebar-motion-duration) tw:ease-(--sidebar-motion-easing) tw:motion-reduce:transition-none',\n )}\n />\n\n <div\n data-slot=\"sidebar-wrapper\"\n onTransitionEnd={handleTransitionEnd}\n className={cn(\n 'tw:fixed',\n 'tw:inset-y-0',\n 'tw:border-border',\n\n // transition\n isDragging\n ? 'tw:transition-none'\n : 'tw:transition-[width,translate,transform] tw:duration-(--sidebar-motion-duration) tw:ease-(--sidebar-motion-easing) tw:motion-reduce:transition-none',\n // Composite the slide.\n 'tw:transform-gpu',\n className,\n )}\n style={style}\n >\n {resizable && <SidebarResizeHandle side={side} />}\n <div\n data-slot=\"sidebar\"\n className={cn(\n 'tw:bg-sidebar',\n 'tw:overflow-hidden',\n 'tw:relative',\n 'tw:flex',\n 'tw:flex-col',\n 'tw:size-full',\n 'tw:border-sidebar-border',\n 'tw:group-[]/sidebar:pt-2',\n )}\n >\n {isMounted ? children : null}\n </div>\n </div>\n </div>\n </SidebarInstanceContext>\n </TooltipProvider>\n );\n};\n\n// main layout\nSidebar.Header = SidebarHeader;\nSidebar.Content = SidebarContent;\nSidebar.Footer = SidebarFooter;\nSidebar.Trigger = SidebarTrigger;\nSidebar.FillTrigger = SidebarFillTrigger;\nSidebar.Separator = SidebarSeparator;\nSidebar.MenuIcon = SidebarMenuIcon;\n\n// group features\nSidebar.Group = SidebarGroup;\nSidebar.GroupLabel = SidebarGroupLabel;\nSidebar.GroupContent = SidebarGroupContent;\nSidebar.GroupAction = SidebarGroupAction;\n\n// menu features\nSidebar.Menu = SidebarMenu;\nSidebar.MenuItem = SidebarMenuItem;\nSidebar.MenuButton = SidebarMenuButton;\nSidebar.MenuAction = SidebarMenuAction;\nSidebar.SearchInput = SidebarSearchInput;\nSidebar.MenuCard = SidebarMenuCard;\nSidebar.MenuBadge = SidebarMenuBadge;\n\n// sub-menu features\nSidebar.SubMenu = SidebarMenuSub;\nSidebar.SubItem = SidebarMenuSubItem;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TextInput-CFTf4Cz1.js","names":[],"sources":["../src/blocks/TextInput/utils.ts","../src/blocks/TextInput/TextInput.tsx"],"sourcesContent":["import { createPrefixedString } from '../../utils';\n\nexport const genInputTestId = (prefix: string = '') => {\n const ps = createPrefixedString(prefix);\n return {\n toString: () => prefix,\n inputWrapper: ps`input-wrapper`,\n input: ps`input`,\n clearButton: ps`clear-button`,\n };\n};\n","import { useRef } from 'react';\nimport type {\n ChangeEventHandler,\n ComponentProps,\n ComponentRef,\n FocusEventHandler,\n MouseEventHandler,\n ReactNode,\n} from 'react';\n\nimport { InputGroup } from '../../components/InputGroup';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { X } from '../../icons';\nimport { cn, createChangeInputEvent, mergeRefs } from '../../utils';\n\nimport { genInputTestId } from './utils';\n\ntype InputGroupProps = Pick<\n ComponentProps<typeof InputGroup>,\n 'variant' | 'focusVariant' | 'sizing' | 'state'\n>;\n\ntype OwnProps = {\n prefix?: ReactNode;\n /**\n * Content after the input.\n *\n * - `rightSuffixVariant=\"addon\"` truncates it with an ellipsis when the group is narrower than its content.\n * - The ellipsis only renders for inline content — pass text or a `<span>`, not a block element.\n */\n rightSuffix?: ReactNode;\n rightSuffixVariant?: 'addon' | 'default';\n leftSuffix?: ReactNode;\n allowClear?: boolean;\n onClear?: () => void;\n testId?: string;\n value?: string | null;\n defaultValue?: string | null;\n /** Called with the unwrapped string value on every change. For the raw event use `onChange`. */\n onValueChange?: (value: string) => void;\n /** Called with the unwrapped string value on blur. For the raw event use `onBlur`. */\n onValueBlur?: (value: string) => void;\n type?: 'text' | 'email' | 'password' | 'datetime-local' | 'date';\n};\n\n/**\n * Props for `TextInput`. Combines `InputGroup` chrome (variant / sizing / state / focusVariant) with\n * input-specific slots (`prefix`, `leftSuffix`, `rightSuffix`, `allowClear`) and a string-typed\n * `value` / `defaultValue` plus convenience `onValueChange` / `onValueBlur` callbacks. `null` /\n * `undefined` are coerced to empty strings.\n */\nexport type Props = InputGroupProps &\n OwnProps &\n Omit<ComponentProps<'input'>, 'prefix' | 'value' | 'defaultValue' | 'type' | 'accept' | 'step'>;\n\nconst sanitizeTextInputValue = (value: string | null | undefined) => {\n if (typeof value === 'string' && value.trim() === '') return '';\n return value;\n};\n\n/**\n * Standard text input with a string-only API, built on `InputGroup` chrome — addons, clear button,\n * sizing, focus variants. The default choice for a bare text input.\n *\n * **When to use:** any plain text / email / password / date-input field outside `useAppForm`. Pair with\n * `onValueChange` instead of unwrapping `event.target.value` from `onChange`.\n * **When NOT to use:** for fields inside a labelled group use `FormGroup.TextInput`; for forms with\n * validation use `useAppForm` + `field.TextField`; for search use `SearchInput`.\n * **Composition:** wrap in a `FormGroup` for shared error / help-text state, or render directly inside\n * page layouts. Chrome resolves from the active brand automatically: a modern brand always renders argo\n * (any `variant` is ignored), while `variant` only tunes the legacy-brand chrome.\n */\nexport const TextInput = ({\n ref: forwardedRef,\n state = 'default',\n sizing = 'default',\n className,\n prefix = null,\n rightSuffix = null,\n rightSuffixVariant = 'default',\n leftSuffix = null,\n allowClear = false,\n onClear,\n disabled = false,\n testId: prefixTestId = '',\n autoFocus = false,\n id,\n name,\n variant,\n readOnly,\n type = 'text',\n focusVariant = 'default',\n onChange,\n onBlur,\n onValueChange,\n onValueBlur,\n value: valueProp,\n defaultValue,\n ...inputProps\n}: Props) => {\n const inputRef = useRef<ComponentRef<'input'>>(null);\n\n const [value, setValue] = useControllableState<string>({\n // `undefined` stays uncontrolled; any provided value (incl. `null`) is controlled and coerced\n // to a string. Whitespace-only input collapses to '' via `sanitizeTextInputValue`.\n prop: valueProp === undefined ? undefined : (sanitizeTextInputValue(valueProp) ?? ''),\n defaultProp: sanitizeTextInputValue(defaultValue) ?? '',\n onChange: onValueChange,\n });\n\n const testId = genInputTestId(prefixTestId);\n const isClearButtonVisible = (!!value && !disabled && !readOnly) || !!onClear;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n setValue(event.target.value);\n onChange?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n onValueBlur?.(event.target.value);\n onBlur?.(event);\n };\n\n const handleClear: MouseEventHandler<HTMLButtonElement> = () => {\n if (inputRef.current === null) return;\n inputRef.current.value = ''; // keep the DOM node in sync before firing the synthetic change\n inputRef.current.focus();\n onClear?.();\n handleChange(createChangeInputEvent(inputRef.current));\n };\n\n return (\n <InputGroup\n state={state}\n variant={variant}\n sizing={sizing}\n focusVariant={focusVariant}\n className={className}\n data-testid={testId.inputWrapper}\n >\n {prefix && <InputGroup.Addon align=\"inline-start\">{prefix}</InputGroup.Addon>}\n\n <InputGroup.Input\n {...inputProps}\n value={value}\n autoFocus={autoFocus}\n type={type}\n onChange={handleChange}\n onBlur={handleBlur}\n ref={mergeRefs(forwardedRef ?? null, inputRef)}\n disabled={disabled}\n id={id}\n name={name}\n readOnly={readOnly}\n data-testid={testId.input}\n />\n\n {(leftSuffix || allowClear || rightSuffix) && (\n <InputGroup.Addon\n align=\"inline-end\"\n className={cn({ 'tw:min-w-0 tw:shrink': rightSuffixVariant === 'addon' })}\n >\n {leftSuffix}\n {allowClear && isClearButtonVisible && (\n <InputGroup.Button\n aria-label=\"Clear\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={handleClear}\n data-testid={testId.clearButton}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n )}\n {rightSuffix && (\n <div\n className={cn({\n 'tw:truncate tw:min-w-0 tw:bg-muted tw:px-4 tw:-mr-4 tw:py-2.5':\n rightSuffixVariant === 'addon',\n })}\n >\n {rightSuffix}\n </div>\n )}\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":";;;;;;;;;AAEA,MAAa,kBAAkB,SAAiB,OAAO;CACrD,MAAM,KAAK,qBAAqB,MAAM;CACtC,OAAO;EACL,gBAAgB;EAChB,cAAc,EAAE;EAChB,OAAO,EAAE;EACT,aAAa,EAAE;CACjB;AACF;;;AC6CA,MAAM,0BAA0B,UAAqC;CACnE,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI,OAAO;CAC7D,OAAO;AACT;;;;;;;;;;;;;AAcA,MAAa,aAAa,EACxB,KAAK,cACL,QAAQ,WACR,SAAS,WACT,WACA,SAAS,MACT,cAAc,MACd,qBAAqB,WACrB,aAAa,MACb,aAAa,OACb,SACA,WAAW,OACX,QAAQ,eAAe,IACvB,YAAY,OACZ,IACA,MACA,SACA,UACA,OAAO,QACP,eAAe,WACf,UACA,QACA,eACA,aACA,OAAO,WACP,cACA,GAAG,iBACQ;CACX,MAAM,WAAW,OAA8B,IAAI;CAEnD,MAAM,CAAC,OAAO,YAAY,qBAA6B;EAGrD,MAAM,cAAc,KAAA,IAAY,KAAA,IAAa,uBAAuB,SAAS,KAAK;EAClF,aAAa,uBAAuB,YAAY,KAAK;EACrD,UAAU;CACZ,CAAC;CAED,MAAM,SAAS,eAAe,YAAY;CAC1C,MAAM,uBAAwB,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,YAAa,CAAC,CAAC;CAEtE,MAAM,gBAAsD,UAAU;EACpE,SAAS,MAAM,OAAO,KAAK;EAC3B,WAAW,KAAK;CAClB;CAEA,MAAM,cAAmD,UAAU;EACjE,cAAc,MAAM,OAAO,KAAK;EAChC,SAAS,KAAK;CAChB;CAEA,MAAM,oBAA0D;EAC9D,IAAI,SAAS,YAAY,MAAM;EAC/B,SAAS,QAAQ,QAAQ;EACzB,SAAS,QAAQ,MAAM;EACvB,UAAU;EACV,aAAa,uBAAuB,SAAS,OAAO,CAAC;CACvD;CAEA,OACE,qBAAC,YAAD;EACS;EACE;EACD;EACM;EACH;EACX,eAAa,OAAO;EANtB,UAAA;GAQG,UAAU,oBAAC,WAAW,OAAZ;IAAkB,OAAM;IAAgB,UAAA;GAAyB,CAAA;GAE5E,oBAAC,WAAW,OAAZ;IACE,GAAI;IACG;IACI;IACL;IACN,UAAU;IACV,QAAQ;IACR,KAAK,UAAU,gBAAgB,MAAM,QAAQ;IACnC;IACN;IACE;IACI;IACV,eAAa,OAAO;GACrB,CAAA;IAEC,cAAc,cAAc,gBAC5B,qBAAC,WAAW,OAAZ;IACE,OAAM;IACN,WAAW,GAAG,EAAE,wBAAwB,uBAAuB,QAAQ,CAAC;IAF1E,UAAA;KAIG;KACA,cAAc,wBACb,oBAAC,WAAW,QAAZ;MACE,cAAW;MACX,cAAc,MAAM,EAAE,eAAe;MACrC,SAAS;MACT,eAAa,OAAO;MAEpB,UAAA,oBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;KACT,CAAA;KAEpB,eACC,oBAAC,OAAD;MACE,WAAW,GAAG,EACZ,iEACE,uBAAuB,QAC3B,CAAC;MAEA,UAAA;KACE,CAAA;IAES;;EAEV;;AAEhB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeProvider-DAmNn9Sd.js","names":[],"sources":["../src/components/ThemeProvider/AIGradientSvg.tsx","../src/components/ThemeProvider/useThemeTokens.ts","../src/components/ThemeProvider/ThemeProvider.tsx","../src/components/ThemeProvider/ThemeScope.tsx"],"sourcesContent":["export const AIGradientsSvg = () => (\n <svg width=\"0\" height=\"0\" style={{ position: 'absolute', visibility: 'hidden' }}>\n <defs>\n {/*aigradient-600*/}\n <linearGradient id=\"aigradient-600\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#61E4FF\" />\n <stop offset=\"50%\" stopColor=\"#1F8FFF\" />\n <stop offset=\"100%\" stopColor=\"#7C5CFF\" />\n </linearGradient>\n\n {/*aigradient-700*/}\n <linearGradient id=\"aigradient-700\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#075fb8\" />\n <stop offset=\"100%\" stopColor=\"#5b2cb8\" />\n </linearGradient>\n </defs>\n </svg>\n);\n","import { useInsertionEffect } from 'react';\n\nimport type {\n BrandTheme,\n Colors,\n Gradient,\n Motion,\n Radii,\n Shadows,\n Spacing,\n Typography,\n} from '@keboola/brand-registry';\n\nimport type { ResolvedColorScheme } from './types';\nimport { createCssVars } from './utils';\n\nexport type ThemeTokens = {\n colors?: Colors;\n typography?: Typography;\n radii?: Radii;\n shadows?: Shadows;\n spacing?: Spacing;\n motion?: Motion;\n gradient?: Gradient;\n};\n\nexport const brandThemeToTokens = (\n theme: BrandTheme,\n scheme: ResolvedColorScheme,\n): ThemeTokens => ({\n colors: scheme === 'dark' ? theme.colorsDark : theme.colors,\n typography: theme.typography,\n radii: theme.radii,\n // Scheme-independent — the same values apply in light and dark.\n shadows: theme.shadows,\n spacing: theme.spacing,\n motion: theme.motion,\n gradient: theme.gradient,\n});\n\nexport const tokensToCssVars = ({\n colors,\n typography,\n radii,\n shadows,\n spacing,\n motion,\n gradient,\n}: ThemeTokens): Record<string, string> => {\n const vars = createCssVars();\n\n vars.set('--background', colors?.background);\n vars.set('--foreground', colors?.foreground);\n vars.set('--muted', colors?.muted);\n vars.set('--muted-foreground', colors?.mutedForeground);\n vars.set('--border', colors?.border);\n vars.set('--input', colors?.input);\n vars.set('--input-background', colors?.inputBackground);\n vars.set('--ring', colors?.ring);\n vars.set('--ring-offset', colors?.ringOffset);\n vars.set('--primary', colors?.primary);\n vars.set('--primary-foreground', colors?.primaryForeground);\n vars.set('--secondary', colors?.secondary);\n vars.set('--secondary-foreground', colors?.secondaryForeground);\n vars.set('--accent', colors?.accent);\n vars.set('--accent-foreground', colors?.accentForeground);\n vars.set('--card', colors?.card);\n vars.set('--card-foreground', colors?.cardForeground);\n vars.set('--popover', colors?.popover);\n vars.set('--popover-foreground', colors?.popoverForeground);\n vars.set('--destructive', colors?.destructive);\n vars.set('--destructive-foreground', colors?.destructiveForeground);\n vars.set('--success', colors?.success);\n vars.set('--success-foreground', colors?.successForeground);\n vars.set('--warning', colors?.warning);\n vars.set('--warning-foreground', colors?.warningForeground);\n vars.set('--info', colors?.info);\n vars.set('--info-foreground', colors?.infoForeground);\n\n vars.set('--chart-1', colors?.chart?.chart1);\n vars.set('--chart-2', colors?.chart?.chart2);\n vars.set('--chart-3', colors?.chart?.chart3);\n vars.set('--chart-4', colors?.chart?.chart4);\n vars.set('--chart-5', colors?.chart?.chart5);\n\n vars.set('--sidebar', colors?.sidebar?.sidebar);\n vars.set('--sidebar-foreground', colors?.sidebar?.sidebarForeground);\n vars.set('--sidebar-primary', colors?.sidebar?.sidebarPrimary);\n vars.set('--sidebar-primary-foreground', colors?.sidebar?.sidebarPrimaryForeground);\n vars.set('--sidebar-accent', colors?.sidebar?.sidebarAccent);\n vars.set('--sidebar-accent-foreground', colors?.sidebar?.sidebarAccentForeground);\n vars.set('--sidebar-border', colors?.sidebar?.sidebarBorder);\n vars.set('--sidebar-ring', colors?.sidebar?.sidebarRing);\n\n /**\n * TYPOGRAPHY\n */\n vars.set('--font-sans', typography?.fontFamily?.trim() || undefined);\n vars.set('--font-display', typography?.fontDisplay?.trim() || undefined);\n vars.set('--font-mono', typography?.fontMono?.trim() || undefined);\n\n // Chrome font-weight slots — read by Tailwind's `fontWeight` scale.\n vars.set('--font-weight-normal', typography?.weight?.normal);\n vars.set('--font-weight-medium', typography?.weight?.medium);\n vars.set('--font-weight-semibold', typography?.weight?.semibold);\n vars.set('--font-weight-bold', typography?.weight?.bold);\n\n // Chrome tracking — behind Button/Badge `tracking-chrome`.\n vars.set('--letter-spacing-chrome', typography?.letterSpacing?.chrome);\n\n // Type scale — display/heading/body steps read by `text-display/heading/body`.\n vars.set('--type-display-size', typography?.typeScale?.display?.size);\n vars.set('--type-display-weight', typography?.typeScale?.display?.weight);\n vars.set('--type-display-leading', typography?.typeScale?.display?.leading);\n vars.set('--type-display-tracking', typography?.typeScale?.display?.tracking);\n vars.set('--type-heading-size', typography?.typeScale?.heading?.size);\n vars.set('--type-heading-weight', typography?.typeScale?.heading?.weight);\n vars.set('--type-heading-leading', typography?.typeScale?.heading?.leading);\n vars.set('--type-heading-tracking', typography?.typeScale?.heading?.tracking);\n vars.set('--type-body-size', typography?.typeScale?.body?.size);\n vars.set('--type-body-weight', typography?.typeScale?.body?.weight);\n vars.set('--type-body-leading', typography?.typeScale?.body?.leading);\n vars.set('--type-body-tracking', typography?.typeScale?.body?.tracking);\n\n vars.set('--radius-sm', radii?.sm);\n vars.set('--radius-md', radii?.md);\n vars.set('--radius-lg', radii?.lg);\n\n /**\n * ELEVATION / DENSITY / MOTION / GRADIENT\n */\n vars.set('--shadow-sm', shadows?.sm);\n vars.set('--shadow-md', shadows?.md);\n vars.set('--shadow-lg', shadows?.lg);\n vars.set('--shadow-lift', shadows?.lift);\n\n vars.set('--space-gutter', spacing?.gutter);\n vars.set('--space-inset', spacing?.inset);\n\n vars.set('--motion-duration', motion?.duration);\n vars.set('--motion-easing', motion?.easing);\n\n vars.set('--gradient-brand', gradient?.brand);\n\n return vars.expose();\n};\n\nconst setTokens = (node: HTMLElement, vars: Record<string, string>) => {\n for (const [name, value] of Object.entries(vars)) {\n node.style.setProperty(name, value);\n }\n};\n\nconst removeTokens = (node: HTMLElement, vars: Record<string, string>) => {\n for (const name of Object.keys(vars)) {\n node.style.removeProperty(name);\n }\n};\n\n/**\n * Writes a brand's token overrides as inline custom properties.\n *\n * `target` defaults to `<html>` (the app-wide provider). Pass an element to\n * scope the overrides to that subtree instead — `ThemeScope` uses this so a\n * panel can run its own colour scheme: the stylesheet's `[data-theme='dark']`\n * block only re-points the *raw* tokens, while a brand injects the resolved\n * `--color-*` aliases, so a nested scheme must re-inject the brand's values for\n * its own scheme or the brand's light colours leak into a dark subtree.\n */\nexport const useThemeTokens = (tokens: ThemeTokens, target?: HTMLElement | null) => {\n // Insertion effect: runs before the DOM mutates and before any (descendant)\n // layout effect measures token-dependent geometry. Write-only, so it fits the\n // hook's constraints. Only the brand's overrides are set; unset slots fall\n // through to the stylesheet's `:root` / `[data-theme='dark']` defaults.\n useInsertionEffect(() => {\n if (typeof document === 'undefined') return;\n // `undefined` means \"app-wide\"; `null` means \"a scope whose node has not\n // mounted yet\" — nothing to write until the ref lands.\n const node = target === undefined ? document.documentElement : target;\n if (!node) return;\n\n const vars = tokensToCssVars(tokens);\n\n setTokens(node, vars);\n\n return () => removeTokens(node, vars);\n }, [tokens, target]);\n};\n","import { type ReactNode, useMemo } from 'react';\n\nimport type { Brand } from '@keboola/brand-registry';\n\nimport { TooltipProvider } from '../Tooltip';\n\nimport { AIGradientsSvg } from './AIGradientSvg';\nimport { ThemeContext, type ThemeContextValue } from './context';\nimport { DEFAULT_BRANDS, defaultBrand } from './defaults';\nimport { type UseBrandOptions, useBrandState } from './useBrandState';\nimport { type UseColorSchemeOptions, useColorSchemeState } from './useColorSchemeState';\nimport { brandThemeToTokens, useThemeTokens } from './useThemeTokens';\nimport { createTheme } from './utils';\n\ntype Props = UseColorSchemeOptions &\n UseBrandOptions & {\n /** Brands this provider knows about; the active brand id resolves against these. */\n brands?: readonly Brand[];\n children: ReactNode;\n };\n\nexport const ThemeProvider = ({\n defaultScheme,\n scheme,\n onSchemeChange,\n defaultBrandId,\n brandId,\n onBrandIdChange,\n brands = DEFAULT_BRANDS,\n children,\n}: Props) => {\n const colorSchemeState = useColorSchemeState({\n defaultScheme,\n scheme,\n onSchemeChange,\n });\n\n const brandState = useBrandState({\n defaultBrandId,\n brandId,\n onBrandIdChange,\n });\n\n // Resolve the active brand; an unknown id (incl. the default sentinel) falls\n // back to `defaultBrand`, whose empty theme injects nothing so the stylesheet\n // defaults apply.\n const brand = useMemo(\n () => brands.find((item) => item.id === brandState.brandId) ?? defaultBrand,\n [brands, brandState.brandId],\n );\n const themes = useMemo(() => brands.map(createTheme), [brands]);\n const currentTheme = useMemo(() => createTheme(brand), [brand]);\n\n // Only the brand's overrides for the resolved scheme are injected; every slot\n // it omits (including a missing dark palette) falls through to the stylesheet's\n // `:root` / `[data-theme='dark']` defaults — so dark mode works for any brand.\n const themeTokens = useMemo(\n () => brandThemeToTokens(brand.theme, colorSchemeState.resolvedScheme),\n [brand, colorSchemeState.resolvedScheme],\n );\n\n useThemeTokens(themeTokens);\n\n const { scheme: activeScheme, resolvedScheme, setScheme } = colorSchemeState;\n const { brandId: activeBrandId, setBrand } = brandState;\n const context = useMemo<ThemeContextValue>(\n () => ({\n scheme: activeScheme,\n resolvedScheme,\n setScheme,\n brandId: activeBrandId,\n setBrand,\n themes,\n currentTheme,\n brandTheme: brand.theme,\n }),\n [activeScheme, resolvedScheme, setScheme, activeBrandId, setBrand, themes, currentTheme, brand],\n );\n\n return (\n <ThemeContext value={context}>\n <AIGradientsSvg />\n <TooltipProvider>{children}</TooltipProvider>\n </ThemeContext>\n );\n};\n","import { type ReactNode, use, useEffect, useMemo, useRef, useState } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { useTheme } from './context';\nimport { ThemeScopeContainerContext, ThemeScopeSchemeContext } from './themeScopeContext';\nimport type { ColorScheme, ResolvedColorScheme } from './types';\nimport { brandThemeToTokens, tokensToCssVars, useThemeTokens } from './useThemeTokens';\n\nconst DARK_QUERY = '(prefers-color-scheme: dark)';\n\n// Portalled overlays (menus, popovers) mount at the end of <body>, outside the\n// scope, so they would render in the app's scheme. The scope keeps a body-level\n// container carrying the same tokens and hands it to consumers, which pass it to\n// a `container` prop — themed, and without the clipping that portalling back\n// into the panel would cause.\n/** The scope's themed portal container, or `null` outside a `ThemeScope`. */\nexport const useThemeScopeContainer = () => use(ThemeScopeContainerContext);\n\nconst useResolvedScheme = (scheme: ColorScheme): ResolvedColorScheme => {\n const [systemPrefersDark, setSystemPrefersDark] = useState(\n () => globalThis.matchMedia?.(DARK_QUERY).matches ?? false,\n );\n\n useEffect(() => {\n const query = globalThis.matchMedia?.(DARK_QUERY);\n if (!query) return;\n\n const onChange = (event: MediaQueryListEvent) => setSystemPrefersDark(event.matches);\n query.addEventListener('change', onChange);\n\n return () => query.removeEventListener('change', onChange);\n }, []);\n\n if (scheme === 'system') return systemPrefersDark ? 'dark' : 'light';\n\n return scheme;\n};\n\ntype Props = {\n /** Colour scheme for this subtree. `system` follows the OS preference. */\n scheme: ColorScheme;\n /** Merged onto the child element. */\n className?: string;\n /** A single element to theme. Its props are merged — no wrapper is rendered. */\n children: ReactNode;\n};\n\n/**\n * Runs one subtree in its own colour scheme while the rest of the app keeps the\n * provider's.\n *\n * Two things have to happen for that to look right, and doing only the first is\n * why a bare `data-theme` attribute produces a half-themed panel: the\n * stylesheet's `[data-theme='dark']` block re-points the *raw* tokens\n * (`--foreground`), but a brand injects the resolved aliases as inline vars on\n * `<html>`, which the subtree inherits. So the scope also re-injects the active\n * brand's tokens **for its own scheme**, where they beat the inherited ones.\n *\n * It renders **no element of its own** — the attribute, vars and className are\n * merged onto the child. An extra wrapper (even `display: contents`, which\n * layout ignores but selectors do not) silently breaks direct-child selectors\n * like `[data-fill=true] > &` in the element it wraps.\n */\nexport const ThemeScope = ({ scheme, className, children }: Props) => {\n const { brandTheme } = useTheme();\n const resolvedScheme = useResolvedScheme(scheme);\n const [portalContainer, setPortalContainer] = useState<HTMLDivElement | null>(null);\n\n const tokens = useMemo(\n () => brandThemeToTokens(brandTheme, resolvedScheme),\n [brandTheme, resolvedScheme],\n );\n const style = useMemo(() => tokensToCssVars(tokens), [tokens]);\n\n useThemeTokens(tokens, portalContainer);\n\n // Read at creation without making the container depend on the scheme, which would rebuild it\n // on every flip.\n const schemeRef = useRef(resolvedScheme);\n schemeRef.current = resolvedScheme;\n\n useEffect(() => {\n const container = document.createElement('div');\n container.dataset.themeScopePortal = '';\n // Scoped before it is published: a consumer resolving tokens off this node in the very commit\n // it arrives would otherwise read the page's palette — and cache it under this scope's key.\n container.dataset.theme = schemeRef.current;\n document.body.append(container);\n setPortalContainer(container);\n\n return () => container.remove();\n }, []);\n\n // Keeps an existing container in step; the creation above covers the first commit.\n useEffect(() => {\n portalContainer?.setAttribute('data-theme', resolvedScheme);\n }, [portalContainer, resolvedScheme]);\n\n return (\n <ThemeScopeContainerContext value={portalContainer}>\n {/* The scheme is published as well as painted: a canvas (chart, diagram, editor) builds its\n own palette from the tokens and has to resolve this scope's, not the page's. */}\n <ThemeScopeSchemeContext value={resolvedScheme}>\n <Slot data-theme={resolvedScheme} className={className} style={style}>\n {children}\n </Slot>\n </ThemeScopeSchemeContext>\n </ThemeScopeContainerContext>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ZoomableSvg-BZlk3PFJ.js","names":[],"sources":["../src/components/ZoomableSvg/ZoomableSvg.tsx","../src/components/ZoomableSvg/exportSvg.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport DOMPurify from 'dompurify';\n\nimport { ClipboardButton } from '../../blocks/ClipboardButton';\nimport { Maximize2, Minimize2 } from '../../icons';\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Tooltip } from '../Tooltip';\n\nconst MIN_SCALE = 0.5;\nconst MAX_SCALE = 3;\nconst ZOOM_STEP = 0.1;\n\ntype Props = {\n /** Raw SVG markup. Sanitized internally with DOMPurify (SVG profile) before rendering, so it is\n * safe even when it originates from user/LLM-controlled content. Non-SVG HTML is stripped. */\n html: string;\n copyText?: string;\n className?: string;\n /**\n * Opt in to keeping `<foreignObject>` elements through sanitization. Off by\n * default — the SVG profile drops `<foreignObject>` so no HTML subtree can\n * survive. Only enable when the caller pre-flattens each `<foreignObject>` to\n * bare text (the SVG profile still strips any HTML children even when the\n * element itself is allowed). `MermaidDiagram` sets this for node/icon labels.\n */\n allowForeignObject?: boolean;\n /**\n * Extra toolbar controls, rendered between the copy and fullscreen buttons.\n *\n * Injected rather than built in, so export behaviour — filenames,\n * rasterization, error reporting — stays with the consumer and this component\n * keeps shipping in the lazy `@keboola/design/mermaid` chunk with no download\n * dependencies of its own. Pass `ExportMenu` here. Receives the sanitized\n * SVG so an exporter writes exactly what is on screen.\n */\n renderActions?: (safeSvg: string) => ReactNode;\n};\n\nexport const ZoomableSvg = ({\n html,\n copyText,\n className,\n allowForeignObject,\n renderActions,\n}: Props) => {\n const safeHtml = useMemo(\n () =>\n DOMPurify.sanitize(html, {\n USE_PROFILES: { svg: true, svgFilters: true },\n ...(allowForeignObject ? { ADD_TAGS: ['foreignObject'] } : {}),\n }),\n [html, allowForeignObject],\n );\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [scale, setScale] = useState(1);\n const [translate, setTranslate] = useState({ x: 0, y: 0 });\n const [isFullscreen, setIsFullscreen] = useState(false);\n\n useEffect(() => {\n if (!isFullscreen) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n setIsFullscreen(false);\n }\n };\n document.addEventListener('keydown', onKeyDown, { capture: true });\n return () => document.removeEventListener('keydown', onKeyDown, { capture: true });\n }, [isFullscreen]);\n\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startTx: number;\n startTy: number;\n } | null>(null);\n\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const onWheel = (e: WheelEvent) => {\n if (!e.ctrlKey && !e.metaKey) return;\n e.preventDefault();\n const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;\n setScale((s) => Math.min(MAX_SCALE, Math.max(MIN_SCALE, s + delta)));\n };\n\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n // Re-bind when toggling fullscreen: the portal/inline switch remounts the\n // container element, so the listener must attach to the new node.\n }, [isFullscreen]);\n\n const didDragRef = useRef(false);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (e.button !== 0) return;\n e.preventDefault();\n didDragRef.current = false;\n dragRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startTx: translate.x,\n startTy: translate.y,\n };\n },\n [translate],\n );\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!dragRef.current) return;\n didDragRef.current = true;\n setTranslate({\n x: dragRef.current.startTx + e.clientX - dragRef.current.startX,\n y: dragRef.current.startTy + e.clientY - dragRef.current.startY,\n });\n }, []);\n\n const handleMouseUp = useCallback(() => {\n dragRef.current = null;\n }, []);\n\n const handleReset = useCallback(() => {\n setScale(1);\n setTranslate({ x: 0, y: 0 });\n }, []);\n\n const isZoomed = Math.abs(scale - 1) > 0.001 || translate.x !== 0 || translate.y !== 0;\n\n const handleClick = useCallback((e: React.MouseEvent) => {\n if (didDragRef.current) {\n e.stopPropagation();\n }\n }, []);\n\n const stopPropagation = useCallback((e: React.SyntheticEvent) => {\n e.stopPropagation();\n }, []);\n\n const diagramContent = (\n <div\n role=\"presentation\"\n className={cn('tw:group/zoom tw:relative', isFullscreen && 'tw:h-full')}\n onClick={handleClick}\n >\n <div\n role=\"presentation\"\n ref={containerRef}\n className={cn(\n 'tw:overflow-hidden tw:cursor-grab tw:active:cursor-grabbing tw:p-3',\n isFullscreen && 'tw:h-full',\n )}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n >\n <div\n className={cn(\n 'tw:flex tw:justify-center tw:origin-center',\n isFullscreen && 'tw:h-full tw:[&>svg]:h-full',\n )}\n style={{ transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})` }}\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n <div\n role=\"presentation\"\n // `focus-within` as well as hover: the toolbar is opacity-0 but still in\n // the tab order, so without this a keyboard user tabs through invisible\n // controls with no visible focus ring.\n className=\"tw:absolute tw:right-1 tw:top-1 tw:flex tw:gap-1 tw:opacity-0 tw:transition-opacity tw:focus-within:opacity-100 tw:group-hover/zoom:opacity-100\"\n onClick={stopPropagation}\n >\n {isZoomed && (\n <Tooltip tooltip=\"Reset zoom\" placement=\"top\" triggerAsChild>\n <Button size=\"small\" variant=\"outline\" onClick={handleReset}>\n Reset\n </Button>\n </Tooltip>\n )}\n {copyText && (\n <ClipboardButton text={copyText} tooltip=\"Copy code\" size=\"icon-sm\" variant=\"outline\" />\n )}\n {renderActions?.(safeHtml)}\n <Tooltip\n tooltip={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}\n placement=\"top\"\n triggerAsChild\n >\n <Button\n size=\"icon-sm\"\n variant=\"outline\"\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}\n onClick={() => setIsFullscreen((f) => !f)}\n >\n {isFullscreen ? (\n <Minimize2 className=\"tw:size-4\" />\n ) : (\n <Maximize2 className=\"tw:size-4\" />\n )}\n </Button>\n </Tooltip>\n </div>\n </div>\n );\n\n if (isFullscreen) {\n return createPortal(\n <div\n role=\"presentation\"\n data-testid=\"zoomable-svg-fullscreen\"\n /**\n * Stacking contract for this overlay, which portals to `document.body`.\n *\n * - Sits at z-1051, the Modal/Sheet band: above page chrome.\n * - Stays *below* the floating-panel layer (z-1055: DropdownMenu,\n * Popover, Select, Combobox), which portals to `document.body` too —\n * an overlay above it hides any menu opened from the toolbar.\n * - `Tooltip` (z-1060) renders above, as it does over a Modal.\n * - `SpotlightBackdrop` (z-1056) dims this overlay rather than sitting\n * under it — by design, since it deliberately covers the portalled\n * surface tier so a tour's dim can't be punched through.\n * - An app may clamp poppers into this same band, making it a tie that\n * DOM order settles; Radix mounts its portal after this one.\n */\n className=\"tw:fixed tw:inset-0 tw:z-[1051] tw:bg-muted tw:p-4 tailwindcss-preflight\"\n onClick={stopPropagation}\n >\n {diagramContent}\n </div>,\n document.body,\n );\n }\n\n return (\n <div\n className={cn(\n 'tw:overflow-hidden tw:rounded-md tw:border tw:border-border tw:bg-muted',\n className,\n )}\n >\n {diagramContent}\n </div>\n );\n};\n","const PNG_SCALE = 2;\n\n// The root `<svg …>` tag, so the namespace check looks only at its attributes.\n// A plain `includes('xmlns=')` would also match a nested element or body text,\n// and would miss `xmlns = \"…\"` — adding a second declaration, which parsers\n// reject outright with \"Attribute xmlns redefined\".\nconst ROOT_SVG_TAG = /^<svg\\b[^>]*>/i;\nconst HAS_DEFAULT_NAMESPACE = /\\bxmlns\\s*=/i;\n\n// A standalone SVG file needs the namespace declaration; mermaid's inline output\n// omits it because an inline <svg> inherits it from the host document.\n// Trim before matching: the anchored `^<svg` misses markup that arrives with a\n// leading newline or indentation, which would emit a standalone file with no\n// namespace — unopenable in an image viewer.\nconst withSvgNamespace = (svg: string) => {\n const trimmed = svg.trim();\n const rootTag = trimmed.match(ROOT_SVG_TAG)?.[0];\n\n if (!rootTag || HAS_DEFAULT_NAMESPACE.test(rootTag)) return trimmed;\n\n return trimmed.replace(/^<svg\\b/i, '<svg xmlns=\"http://www.w3.org/2000/svg\"');\n};\n\nexport const toSvgFileContent = (svg: string) =>\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n${withSvgNamespace(svg).trim()}\\n`;\n\n// A single decimal number: `12`, `12.5`, `.5`. Deliberately stricter than\n// `[\\d.]+`, which also matches `1.2.3` — and `parseFloat` truncates that to\n// `1.2` rather than rejecting it, so a malformed value would pass as a plausible\n// one.\nconst NUMBER = String.raw`\\d+(?:\\.\\d+)?|\\.\\d+`;\n\n// `parseFloat` happily reads a relative length as a number — `\"100%\"` becomes\n// `100`, `\"2em\"` becomes `2` — and `makeResponsive` sets `width=\"100%\"` on every\n// mermaid root, so an SVG with no usable viewBox would rasterize 100px wide with\n// no error. Accept only a unitless number or an explicit `px`.\nconst PIXEL_LENGTH = new RegExp(String.raw`^\\s*(?:${NUMBER})(?:px)?\\s*$`, 'i');\n\nconst parsePixelLength = (value: string | null): number | null => {\n if (!PIXEL_LENGTH.test(value ?? '')) return null;\n\n const parsed = Number.parseFloat(value ?? '');\n\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n};\n\nexport const parseSvgSize = (svg: string) => {\n const doc = new DOMParser().parseFromString(withSvgNamespace(svg), 'image/svg+xml');\n const element = doc.documentElement;\n\n const viewBox = element\n .getAttribute('viewBox')\n ?.split(/[\\s,]+/)\n .map(Number);\n // `> 0`, not truthiness: a negative extent is accepted by a truthy check, and\n // negative canvas dimensions silently fall back to the 300x150 default — an\n // export at the wrong size with no error. Falling through to width/height is\n // the better answer, since those are usually still valid.\n if (viewBox?.length === 4 && viewBox.every((value) => Number.isFinite(value))) {\n const [, , width, height] = viewBox;\n if (width !== undefined && height !== undefined && width > 0 && height > 0) {\n return { width, height };\n }\n }\n\n const width = parsePixelLength(element.getAttribute('width'));\n const height = parsePixelLength(element.getAttribute('height'));\n\n return width !== null && height !== null ? { width, height } : null;\n};\n\n// Resolve the themed page background so the exported PNG follows the active\n// brand and color scheme instead of a frozen literal. Falls back to `white`\n// (a CSS keyword, not a brand-locked hex) when the token is unset.\n//\n// The token holds Tailwind's bare channel triplet (\"249 250 251\") so utilities\n// can add an alpha. Canvas `fillStyle` rejects that form *silently* and keeps\n// its previous value (black), so wrap it back into rgb() before use.\nconst CHANNEL_TRIPLET = new RegExp(String.raw`^(?:${NUMBER})\\s+(?:${NUMBER})\\s+(?:${NUMBER})$`);\n\nexport const toCanvasColor = (token: string) => {\n const trimmed = token.trim();\n if (!trimmed) return 'white';\n\n // Only wrap a well-formed triplet. A malformed one (`1.2.3 4 5`) would produce\n // an invalid `rgb()` that `fillStyle` rejects silently, painting the PNG on\n // whatever colour was set before — passing it through unwrapped at least lets\n // a genuine CSS color value work.\n return CHANNEL_TRIPLET.test(trimmed) ? `rgb(${trimmed})` : trimmed;\n};\n\nconst resolveBackground = () =>\n toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue('--color-background'));\n\n/**\n * Rasterize SVG markup to a PNG blob at 2x for legible text.\n *\n * The SVG is loaded as a data URL rather than a blob URL: an <img> loading SVG\n * is treated as a foreign resource, so a blob URL would taint the canvas and\n * make toBlob throw a SecurityError. A background is painted first because a\n * transparent PNG reads as unusable when pasted into a slide deck.\n */\nexport const svgToPngBlob = async (svg: string, background?: string): Promise<Blob> => {\n const size = parseSvgSize(svg);\n if (!size) throw new Error('Cannot determine diagram dimensions.');\n\n const encoded = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(toSvgFileContent(svg))}`;\n\n const image = new Image();\n image.decoding = 'sync';\n await new Promise<void>((resolve, reject) => {\n image.onload = () => resolve();\n image.onerror = () => reject(new Error('Failed to load the diagram for export.'));\n image.src = encoded;\n });\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(size.width * PNG_SCALE);\n canvas.height = Math.round(size.height * PNG_SCALE);\n\n const context = canvas.getContext('2d');\n if (!context) throw new Error('Canvas is unavailable in this browser.');\n\n context.fillStyle = background ?? resolveBackground();\n context.fillRect(0, 0, canvas.width, canvas.height);\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error('Failed to encode the PNG.'))),\n 'image/png',\n );\n });\n};\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-D7X470dy.js","names":[],"sources":["../src/components/ThemeProvider/context.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\nimport type { Brand } from '@keboola/brand-registry';\n\nimport { DEFAULT_COLOR_SCHEME, defaultBrand, defaultTheme } from './defaults';\nimport type { Theme } from './types';\nimport type { useBrandState } from './useBrandState';\nimport type { useColorSchemeState } from './useColorSchemeState';\n\nexport type ThemeContextValue = ReturnType<typeof useColorSchemeState> &\n ReturnType<typeof useBrandState> & {\n themes: Theme[];\n currentTheme: Theme;\n /**\n * The active brand's raw token payload. Exposed so a nested `ThemeScope`\n * can re-derive tokens for a different colour scheme; `currentTheme` only\n * carries the switcher metadata (id/name/shell/logo), not the tokens.\n */\n brandTheme: Brand['theme'];\n };\n\nconst noop = () => void 0;\n\nconst defaultContext: ThemeContextValue = {\n scheme: DEFAULT_COLOR_SCHEME,\n resolvedScheme: DEFAULT_COLOR_SCHEME,\n setScheme: noop,\n brandId: defaultTheme.id,\n setBrand: noop,\n\n themes: [defaultTheme],\n currentTheme: defaultTheme,\n brandTheme: defaultBrand.theme,\n};\n\nexport const ThemeContext = createContext(defaultContext);\n\nexport const useTheme = () => use(ThemeContext);\n\n/**\n * TEMPORARY — kbc-ui-internal only.\n *\n * Flags whether the subtree renders the argo design language. Defaults to argo\n * (`true`) — the modern default; legacy chrome is the exception. It exists\n * solely to bridge kbc-ui while its chrome is migrated off the legacy design\n * language: kbc-ui provides `false` for legacy brands/surfaces (see its\n * `AppThemeProvider`) and reads it via `useArgoDesign`. `ThemeProvider` does\n * not set it — argo is decoupled from the brand. Once every kbc-ui surface has\n * been migrated, this context and its hook can be deleted.\n */\nexport const ArgoDesignContext = createContext<boolean>(true);\n\nexport const useArgoDesign = () => use(ArgoDesignContext);\n"],"mappings":";;;AAqBA,MAAM,aAAa,KAAK;AAExB,MAAM,iBAAoC;CACxC,QAAQ;CACR,gBAAgB;CAChB,WAAW;CACX,SAAS,aAAa;CACtB,UAAU;CAEV,QAAQ,CAAC,YAAY;CACrB,cAAc;CACd,YAAY,aAAa;AAC3B;AAEA,MAAa,eAAe,cAAc,cAAc;AAExD,MAAa,iBAAiB,IAAI,YAAY;;;;;;;;;;;;AAa9C,MAAa,oBAAoB,cAAuB,IAAI;AAE5D,MAAa,sBAAsB,IAAI,iBAAiB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"findLiteralMatches-BGBw8Vbl.js","names":[],"sources":["../src/utils/findLiteralMatches.ts"],"sourcesContent":["/**\n * Lowercase without changing the length of the string.\n *\n * - `İ` (U+0130) is the only code point in Unicode whose `toLowerCase()` is two code units, so it\n * folds to `I` first and reads as a plain `i`.\n * - Every offset this module reports indexes the caller's own text, which holds only while the\n * fold is length-preserving.\n */\nconst foldCase = (text: string) => text.replaceAll('İ', 'I').toLowerCase();\n\n// A query longer than the text cannot occur in it — checked before either side is folded, so a\n// pasted document scanned line by line costs nothing per line.\nconst canContain = (text: string, query: string) => !!query && query.length <= text.length;\n\n// Start offsets of every non-overlapping occurrence of `needle` in `haystack`, verbatim — the\n// callers own the case folding.\nconst scan = (haystack: string, needle: string) => {\n const offsets: number[] = [];\n let at = haystack.indexOf(needle);\n\n while (at !== -1) {\n offsets.push(at);\n at = haystack.indexOf(needle, at + needle.length);\n }\n\n return offsets;\n};\n\n/**\n * Whether `text` holds `query`, ignoring case.\n *\n * - For callers that only need the answer — it stops at the first occurrence and allocates no\n * offsets.\n */\nexport const hasLiteralMatch = (text: string, query: string) =>\n canContain(text, query) && foldCase(text).includes(foldCase(query));\n\n/**\n * Start offsets of every occurrence of `query` in `text`, ignoring case unless `isCaseSensitive`.\n *\n * - The scan is literal, so every character of the query stands for itself. A search query is\n * pasted code as often as it is a word, and tens of kilobytes of it exceed what V8 can compile\n * as a regular expression.\n * - Occurrences do not overlap.\n * - An empty query matches nothing.\n * - CodeMirror's own `SearchCursor` does this over a `Text`, but it would reach the root barrel\n * the whole CodeMirror bundle is kept out of, and three of the four callers hold plain strings.\n */\nexport const findLiteralMatches = (\n text: string,\n query: string,\n { isCaseSensitive = false }: { isCaseSensitive?: boolean } = {},\n) => {\n if (!canContain(text, query)) return [];\n\n return isCaseSensitive ? scan(text, query) : scan(foldCase(text), foldCase(query));\n};\n\n/**\n * `findLiteralMatches` for many queries over one text, as `{ from, to }` ranges.\n *\n * - Folds `text` once, not once per term — the per-term cost is the scan alone.\n * - Ranges arrive in term order; ranges of different terms may overlap.\n */\nexport const findLiteralTermMatches = (\n text: string,\n terms: string[],\n { isCaseSensitive = false }: { isCaseSensitive?: boolean } = {},\n) => {\n const haystack = isCaseSensitive ? text : foldCase(text);\n\n return terms.flatMap((term) => {\n if (!canContain(text, term)) return [];\n\n return scan(haystack, isCaseSensitive ? term : foldCase(term)).map((from) => ({\n from,\n to: from + term.length,\n }));\n });\n};\n"],"mappings":";;;;;;;;;AAQA,MAAM,YAAY,SAAiB,KAAK,WAAW,KAAK,GAAG,CAAC,CAAC,YAAY;AAIzE,MAAM,cAAc,MAAc,UAAkB,CAAC,CAAC,SAAS,MAAM,UAAU,KAAK;AAIpF,MAAM,QAAQ,UAAkB,WAAmB;CACjD,MAAM,UAAoB,CAAC;CAC3B,IAAI,KAAK,SAAS,QAAQ,MAAM;CAEhC,OAAO,OAAO,IAAI;EAChB,QAAQ,KAAK,EAAE;EACf,KAAK,SAAS,QAAQ,QAAQ,KAAK,OAAO,MAAM;CAClD;CAEA,OAAO;AACT;;;;;;;AAQA,MAAa,mBAAmB,MAAc,UAC5C,WAAW,MAAM,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,SAAS,KAAK,CAAC;;;;;;;;;;;;AAapE,MAAa,sBACX,MACA,OACA,EAAE,kBAAkB,UAAyC,CAAC,MAC3D;CACH,IAAI,CAAC,WAAW,MAAM,KAAK,GAAG,OAAO,CAAC;CAEtC,OAAO,kBAAkB,KAAK,MAAM,KAAK,IAAI,KAAK,SAAS,IAAI,GAAG,SAAS,KAAK,CAAC;AACnF;;;;;;;AAQA,MAAa,0BACX,MACA,OACA,EAAE,kBAAkB,UAAyC,CAAC,MAC3D;CACH,MAAM,WAAW,kBAAkB,OAAO,SAAS,IAAI;CAEvD,OAAO,MAAM,SAAS,SAAS;EAC7B,IAAI,CAAC,WAAW,MAAM,IAAI,GAAG,OAAO,CAAC;EAErC,OAAO,KAAK,UAAU,kBAAkB,OAAO,SAAS,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU;GAC5E;GACA,IAAI,OAAO,KAAK;EAClB,EAAE;CACJ,CAAC;AACH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"icons-Cek151jC.js","names":[],"sources":["../src/icons/flags/Eu.tsx","../src/icons/flags/Us.tsx","../src/icons/brandIcon.ts","../src/icons/vendors/Aws.tsx","../src/icons/vendors/Azure.tsx","../src/icons/vendors/ChatGpt.tsx","../src/icons/vendors/Claude.tsx","../src/icons/vendors/Cursor.tsx","../src/icons/vendors/Devin.tsx","../src/icons/vendors/Gcp.tsx","../src/icons/vendors/Google.tsx","../src/icons/vendors/Keboola.tsx","../src/icons/vendors/Make.tsx","../src/icons/vendors/Microsoft.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport type { LucideIcon, LucideProps } from 'lucide-react';\n\nimport { cn } from '../../utils';\n\nconst STAR =\n 'M0 -2 0.449 -0.618 1.902 -0.618 0.727 0.236 1.176 1.618 0 0.764 -1.176 1.618 -0.727 0.236 -1.902 -0.618 -0.449 -0.618Z';\n\nconst STAR_POSITIONS = Array.from({ length: 12 }, (_, index) => {\n const angle = (index * Math.PI) / 6 - Math.PI / 2;\n return { x: 12 + 5.882 * Math.cos(angle), y: 12 + 5.882 * Math.sin(angle) };\n});\n\nexport const Eu: LucideIcon = forwardRef<SVGSVGElement, LucideProps>(\n ({ size = 24, className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={cn('lucide', className)}\n {...rest}\n >\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"2\" fill=\"#039\" />\n <g fill=\"#FC0\">\n {STAR_POSITIONS.map(({ x, y }) => (\n <path key={`${x},${y}`} d={STAR} transform={`translate(${x} ${y})`} />\n ))}\n </g>\n {children}\n </svg>\n ),\n);\n\nEu.displayName = 'Eu';\n","import { forwardRef, useId } from 'react';\nimport type { LucideIcon, LucideProps } from 'lucide-react';\n\nimport { cn } from '../../utils';\n\nconst STRIPES =\n 'M2 3.538h20v1.538H2ZM2 6.615h20v1.538H2ZM2 9.692h20v1.538H2ZM2 12.769h20v1.538H2ZM2 15.846h20v1.538H2ZM2 18.923h20v1.538H2Z';\n\nexport const Us: LucideIcon = forwardRef<SVGSVGElement, LucideProps>(\n ({ size = 24, className, children, ...rest }, ref) => {\n const clipId = `${useId()}-tile`;\n\n return (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={cn('lucide', className)}\n {...rest}\n >\n <clipPath id={clipId}>\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"2\" />\n </clipPath>\n <g clipPath={`url(#${clipId})`}>\n <path fill=\"#B22234\" d=\"M2 2h20v20H2Z\" />\n <path fill=\"#fff\" d={STRIPES} />\n <path fill=\"#3C3B6E\" d=\"M2 2h8v10.769H2Z\" />\n </g>\n {children}\n </svg>\n );\n },\n);\n\nUs.displayName = 'Us';\n","import type { ForwardRefExoticComponent, RefAttributes } from 'react';\nimport type { LucideIcon, LucideProps } from 'lucide-react';\n\nimport { cn } from '../utils';\n\nexport type BrandIconProps = LucideProps & {\n /** Render the mark in `currentColor` instead of its own brand colours. */\n mono?: boolean;\n};\n\n/**\n * The vendor and flag marks: a Lucide icon plus `mono`. Intersecting `LucideIcon`\n * keeps them assignable to any `icon: LucideIcon` slot by construction.\n */\nexport type BrandIcon = LucideIcon &\n ForwardRefExoticComponent<BrandIconProps & RefAttributes<SVGSVGElement>>;\n\n/**\n * CSS wins over presentation attributes, so this recolours every shape without\n * touching the artwork. Both `defs` and its descendants are excluded: `fill` is an\n * inherited property, so recolouring `<defs>` itself would reach its children and\n * destroy a mask's `fill=\"white\"`, which is luminance rather than colour.\n */\nconst MONO = 'tw:[&_*:not(defs,defs_*)]:fill-current';\n\n/** Every brand mark's class list: the Lucide marker, the `mono` override, then caller overrides. */\nexport const brandClass = (mono: boolean | undefined, className: string | undefined) =>\n cn('lucide', mono && MONO, className);\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\n// `forwardRef` here is required for type compatibility with `LucideIcon` — see\n// `Keboola.tsx` for the full rationale. The AWS logo is a fixed two-color vendor\n// mark (`#252F3E` wordmark + `#FF9900` smile): its paths keep their own fills\n// and ignore `color`, and it must NOT re-skin under a customer brand.\nexport const Aws: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n // Lucide's grid — see `Keboola.tsx` for why every brand icon shares it.\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n {/* Wordmark + smile is a wide lockup, so the 20-unit box caps its width; it is centered\n vertically. Measured artwork bbox: (5.12, 9.49) 21.76 × 13.01. */}\n <g transform=\"translate(-2.7059 -2.7013) scale(0.919118)\">\n <path\n fill=\"#252F3E\"\n d=\"M11.253 14.22c0 .267.029.484.08.644.057.159.13.333.23.52.037.059.051.117.051.167 0 .073-.043.145-.137.217l-.456.304a.347.347 0 0 1-.188.065c-.072 0-.145-.036-.217-.1a2.232 2.232 0 0 1-.26-.341 5.574 5.574 0 0 1-.225-.427c-.565.666-1.274.999-2.128.999-.608 0-1.092-.174-1.447-.521-.355-.348-.536-.81-.536-1.39 0-.615.217-1.114.659-1.49.441-.377 1.028-.565 1.773-.565.246 0 .5.022.767.058.268.036.543.094.832.159v-.528c0-.55-.115-.934-.34-1.158-.231-.225-.622-.333-1.18-.333-.253 0-.513.029-.781.094a5.764 5.764 0 0 0-.782.246 2.07 2.07 0 0 1-.253.094.444.444 0 0 1-.116.022c-.101 0-.152-.072-.152-.224v-.355c0-.116.015-.203.051-.253a.542.542 0 0 1 .203-.152c.253-.13.557-.24.911-.326.355-.094.731-.138 1.13-.138.86 0 1.49.196 1.895.587.399.39.601.984.601 1.78v2.345h.015Zm-2.939 1.1c.24 0 .485-.044.746-.13.26-.087.492-.247.687-.464.116-.137.203-.29.246-.463a2.6 2.6 0 0 0 .073-.63v-.303a6.071 6.071 0 0 0-.666-.123 5.462 5.462 0 0 0-.68-.044c-.485 0-.84.094-1.079.29-.238.195-.354.47-.354.832 0 .34.087.593.268.767.173.18.427.268.76.268Zm5.812.781c-.13 0-.217-.021-.275-.072-.058-.043-.109-.145-.152-.282l-1.701-5.594a1.269 1.269 0 0 1-.065-.29c0-.116.058-.18.174-.18h.709c.137 0 .231.02.282.072.058.043.101.144.145.282l1.216 4.79 1.129-4.79c.036-.145.08-.239.137-.282a.498.498 0 0 1 .29-.073h.578c.138 0 .232.022.29.073.058.043.108.144.137.282l1.144 4.848 1.252-4.848c.043-.145.094-.239.145-.282a.472.472 0 0 1 .282-.073h.673c.116 0 .18.058.18.181 0 .036-.007.072-.014.116a1.03 1.03 0 0 1-.05.18l-1.745 5.595c-.043.145-.094.239-.152.282a.463.463 0 0 1-.274.072h-.623c-.137 0-.231-.021-.29-.072-.057-.05-.108-.145-.137-.29L16.29 11.08l-1.114 4.66c-.036.145-.08.24-.138.29-.057.05-.159.072-.289.072h-.622Zm9.299.196c-.376 0-.753-.044-1.114-.13-.362-.088-.645-.182-.833-.29-.116-.065-.195-.138-.224-.203a.512.512 0 0 1-.044-.202v-.37c0-.151.058-.224.167-.224.043 0 .087.008.13.022.044.014.109.043.181.072.246.109.514.196.796.254.29.057.572.086.861.086.456 0 .81-.08 1.057-.238a.78.78 0 0 0 .376-.688.705.705 0 0 0-.195-.506c-.13-.138-.376-.261-.731-.377l-1.05-.325c-.528-.167-.918-.413-1.157-.739a1.724 1.724 0 0 1-.362-1.049c0-.304.065-.572.195-.803A1.86 1.86 0 0 1 22 9.993c.217-.166.463-.29.753-.376.29-.087.593-.123.912-.123.159 0 .325.007.485.029.166.022.318.05.47.08.145.036.282.072.413.115.13.044.231.087.303.13a.626.626 0 0 1 .218.181.39.39 0 0 1 .065.24v.34c0 .152-.058.231-.167.231a.753.753 0 0 1-.275-.087 3.311 3.311 0 0 0-1.39-.282c-.412 0-.737.065-.962.203-.224.137-.34.347-.34.644 0 .202.073.376.217.514.145.137.413.274.796.397l1.028.326c.521.167.897.398 1.122.695.224.297.333.637.333 1.013 0 .311-.066.594-.189.84-.13.246-.303.463-.528.636-.224.181-.492.312-.803.406a3.442 3.442 0 0 1-1.035.152Z\"\n />\n <path\n fill=\"#F90\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M24.793 19.814c-2.381 1.758-5.84 2.692-8.815 2.692-4.168 0-7.924-1.542-10.76-4.103-.225-.203-.023-.478.245-.319 3.069 1.78 6.853 2.859 10.769 2.859 2.641 0 5.543-.55 8.213-1.68.398-.18.739.261.348.55Z\"\n />\n <path\n fill=\"#F90\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M25.784 18.685c-.304-.391-2.012-.188-2.786-.094-.232.029-.268-.174-.058-.326 1.36-.955 3.597-.68 3.857-.362.26.326-.072 2.562-1.346 3.633-.195.167-.383.08-.296-.137.29-.717.933-2.33.63-2.714Z\"\n />\n </g>\n {children}\n </svg>\n ),\n);\n\nAws.displayName = 'Aws';\n","import { forwardRef, useId } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\n// `forwardRef` here is required for type compatibility with `LucideIcon` — see\n// `Keboola.tsx` for the full rationale. The Azure mark is a fixed vendor gradient\n// (`#114A8B → #0669BC`, `#3CCBF4 → #2892DF`, plus a solid `#0078D4`): it ignores\n// `color` and must NOT re-skin under a customer brand.\n//\n// The gradients are referenced by id, so the ids are derived from `useId()` — two\n// `Azure` icons on one page would otherwise define the same ids and the first\n// definition would win for both.\nexport const Azure: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => {\n const id = useId();\n const [left, shadow, right] = [`${id}-left`, `${id}-shadow`, `${id}-right`];\n\n return (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n // Lucide's grid — see `Keboola.tsx` for why every brand icon shares it.\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n {/* Measured artwork bbox: (6.83, 7.36) 18.33 × 17.27. The gradients are\n `userSpaceOnUse`, so they resolve in this group's space and need no adjustment. */}\n <g transform=\"translate(-5.4523 -5.4523) scale(1.091107)\">\n <path\n fill={`url(#${left})`}\n d=\"M12.945 7.363h5.425l-5.631 16.685a.865.865 0 0 1-.82.589H7.698a.863.863 0 0 1-.819-1.14l5.247-15.545a.864.864 0 0 1 .82-.589Z\"\n />\n <path\n fill=\"#0078D4\"\n d=\"M20.828 18.554h-8.602a.398.398 0 0 0-.272.69l5.528 5.159c.16.15.373.234.593.233h4.87l-2.117-6.082Z\"\n />\n <path\n fill={`url(#${shadow})`}\n d=\"M12.945 7.363a.858.858 0 0 0-.821.6l-5.238 15.52a.862.862 0 0 0 .814 1.153h4.33a.925.925 0 0 0 .711-.604l1.045-3.078 3.73 3.48c.157.13.353.2.556.202h4.853l-2.128-6.082-6.205.002L18.39 7.363h-5.445Z\"\n />\n <path\n fill={`url(#${right})`}\n d=\"M19.874 7.95a.863.863 0 0 0-.818-.587H13.01a.864.864 0 0 1 .818.588l5.247 15.546a.863.863 0 0 1-.818 1.14h6.045a.863.863 0 0 0 .819-1.14L19.874 7.95Z\"\n />\n </g>\n <defs>\n <linearGradient\n id={left}\n x1=\"14.922\"\n x2=\"9.289\"\n y1=\"8.643\"\n y2=\"25.286\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#114A8B\" />\n <stop offset=\"1\" stopColor=\"#0669BC\" />\n </linearGradient>\n <linearGradient\n id={shadow}\n x1=\"16.682\"\n x2=\"15.379\"\n y1=\"16.399\"\n y2=\"16.84\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopOpacity=\".3\" />\n <stop offset=\".071\" stopOpacity=\".2\" />\n <stop offset=\".321\" stopOpacity=\".1\" />\n <stop offset=\".623\" stopOpacity=\".05\" />\n <stop offset=\"1\" stopOpacity=\"0\" />\n </linearGradient>\n <linearGradient\n id={right}\n x1=\"15.966\"\n x2=\"22.15\"\n y1=\"8.158\"\n y2=\"24.633\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#3CCBF4\" />\n <stop offset=\"1\" stopColor=\"#2892DF\" />\n </linearGradient>\n </defs>\n {children}\n </svg>\n );\n },\n);\n\nAzure.displayName = 'Azure';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\nexport const ChatGpt: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, color = 'currentColor', className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n className={brandClass(mono, className)}\n {...rest}\n >\n <g transform=\"translate(-8.178339 -8.178357) scale(0.05639)\">\n <path d=\"M508.7 317.4C516.8 287.3 509 253.9 485.4 230.3C461.8 206.7 428.4 198.9 398.3 206.9C376.2 184.9 343.4 175 311.1 183.6C278.9 192.2 255.4 217.3 247.4 247.4C217.3 255.5 192.2 278.9 183.6 311.1C175 343.4 184.9 376.2 206.9 398.3C198.9 428.4 206.7 461.8 230.3 485.4C253.9 509 287.3 516.8 317.4 508.8C339.4 530.7 372.3 540.7 404.5 532.1C436.8 523.4 460.2 498.4 468.3 468.3C498.4 460.2 523.4 436.8 532.1 404.5C540.7 372.3 530.7 339.4 508.7 317.4V317.4ZM470.9 244.8C486.9 260.8 493.5 282.6 490.7 303.4L415.6 260C412.4 258.2 408.5 258.2 405.3 260L317.4 310.8V277.5C317.4 275.2 318.7 273 320.7 271.8L387.6 233.2C414.2 218.4 448.3 222.2 470.9 244.8H470.9ZM357.8 311.1L398.3 334.5V381.2L357.8 404.5L317.4 381.2V334.5L357.8 311.1ZM264.8 269.7C265.2 239.3 285.6 211.6 316.5 203.4C338.3 197.5 360.5 202.7 377.1 215.6L302 258.9C298.8 260.8 296.9 264.1 296.9 267.8V369.3L268.1 352.7C266 351.5 264.8 349.4 264.8 347V269.7V269.7ZM203.4 316.5C209.2 294.6 224.9 278 244.3 270V356.7C244.3 360.4 246.2 363.8 249.4 365.6L337.3 416.4L308.5 433C306.5 434.2 304 434.2 301.9 433L235 394.4C208.9 378.8 195.1 347.3 203.4 316.5ZM244.8 470.9C228.8 454.9 222.2 433.1 225 412.3L300.1 455.6C303.3 457.5 307.2 457.5 310.3 455.6L398.3 404.9V438.1C398.3 440.5 397 442.7 395 443.8L328 482.5C301.5 497.3 267.3 493.5 244.8 470.9H244.8ZM450.9 446C450.5 476.4 430 504 399.2 512.3C377.4 518.1 355.2 512.9 338.5 500.1L413.7 456.7C416.8 454.9 418.8 451.5 418.8 447.9V346.3L447.6 363C449.6 364.1 450.9 366.3 450.9 368.7V446V446ZM512.3 399.2C506.4 421.1 490.8 437.7 471.4 445.7V358.9C471.4 355.3 469.4 351.9 466.3 350.1L378.3 299.3L407.2 282.7C409.2 281.5 411.7 281.5 413.7 282.7L480.7 321.3C506.8 336.9 520.5 368.4 512.3 399.2Z\" />\n </g>\n {children}\n </svg>\n ),\n);\n\nChatGpt.displayName = 'ChatGpt';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\nexport const Claude: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n <g transform=\"translate(1.473684 1.473684) scale(0.08489)\">\n <path\n d=\"M52.4 162.9L98.8 136.9L99.5 134.6L98.8 133.3H96.5L88.7 132.9L62.2 132.2L39.3 131.2L17 130L11.4 128.8L6.2 121.9L6.7 118.4L11.4 115.3L18.2 115.8L33.1 116.9L55.5 118.4L71.7 119.4L95.7 121.9H99.5L100.1 120.3L98.8 119.4L97.8 118.4L74.6 102.7L49.5 86.2L36.4 76.6L29.4 71.8L25.8 67.3L24.3 57.4L30.7 50.3L39.3 50.9L41.5 51.5L50.3 58.2L69 72.7L93.4 90.7L97 93.6L98.4 92.7L98.7 92L97 89.3L83.8 65.3L69.6 40.8L63.3 30.7L61.6 24.6C61 22.1 60.6 20 60.6 17.4L67.8 7.5L71.9 6.2L81.7 7.5L85.8 11L91.9 25L101.7 46.8L117 76.6L121.5 85.5L123.9 93.6L124.8 96.1H126.3V94.7L127.6 77.9L129.9 57.4L132.2 30.9L132.9 23.5L136.6 14.5L144 9.6L149.7 12.3L154.4 19.1L153.8 23.5L151 41.6L145.5 70.1L142 89.3H144L146.4 86.8L156.1 74L172.3 53.7L179.4 45.7L187.8 36.8L193.2 32.5H203.3L210.7 43.7L207.4 55.1L197 68.3L188.3 79.6L175.9 96.2L168.2 109.6L168.9 110.7L170.7 110.5L198.8 104.5L213.9 101.8L232 98.7L240.1 102.5L241 106.4L237.9 114.3L218.5 119L195.8 123.6L162.1 131.6L161.7 131.9L162.1 132.5L177.4 133.9L183.9 134.3H199.8L229.4 136.5L237.2 141.6L241.8 147.9L241 152.7L229.1 158.7L213 155L175.4 146L162.6 142.8H160.8V143.8L171.5 154.4L191.2 172.1L215.8 195L217.1 200.7L213.9 205.2L210.6 204.7L188.9 188.4L180.5 181.1L161.7 165.1H160.4V166.8L164.8 173.2L187.8 207.8L188.9 218.4L187.3 221.8L181.3 224L174.8 222.8L161.2 203.8L147.3 182.5L136.1 163.3L134.7 164.2L128.1 235.4L125 239.1L117.9 241.8L111.9 237.3L108.7 230L111.9 215.5L115.7 196.5L118.8 181.5L121.6 162.9L123.3 156.6L123.1 156.2L121.8 156.4L107.7 175.8L86.3 204.7L69.4 222.8L65.3 224.4L58.3 220.8L58.9 214.3L62.9 208.5L86.3 178.7L100.4 160.2L109.6 149.5L109.5 148L109 147.9L46.7 188.5L35.6 189.9L30.8 185.4L31.4 178.1L33.7 175.8L52.4 162.9Z\"\n fill=\"#D97757\"\n />\n </g>\n {children}\n </svg>\n ),\n);\n\nClaude.displayName = 'Claude';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\nexport const Cursor: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n <g transform=\"translate(-38.617225 -39.361257) scale(0.104712)\">\n <path\n d=\"M483.4 490.5L566 538.3C565.5 539.2 564.8 539.9 563.8 540.5L486.6 585.1C484.6 586.3 482.2 586.3 480.2 585.1L402.9 540.5C402 539.9 401.3 539.2 400.8 538.3L483.4 490.5Z\"\n fill=\"#72716D\"\n />\n <path\n d=\"M483.4 395V490.5L400.8 538.3C400.3 537.4 400 536.4 400 535.3V445.7C400 443.5 401.1 441.6 402.9 440.5L480.1 395.9C481.2 395.3 482.3 395 483.4 395H483.4Z\"\n fill=\"#55544F\"\n />\n <path\n d=\"M566 442.7C565.5 441.8 564.8 441.1 563.8 440.5L486.6 395.9C485.6 395.3 484.5 395 483.4 395V490.5L566 538.3C566.5 537.4 566.8 536.4 566.8 535.3V445.7C566.8 444.6 566.5 443.6 566 442.7H566Z\"\n fill=\"#43413C\"\n />\n <path\n d=\"M560.2 446C560.7 446.9 560.8 447.9 560.2 448.8L485.2 579C484.7 579.9 483.4 579.5 483.4 578.5V492.7C483.4 492 483.2 491.4 482.9 490.8L560.2 446H560.2V446Z\"\n fill=\"#D6D5D2\"\n />\n <path\n d=\"M560.2 446L482.9 490.8C482.6 490.2 482.1 489.7 481.5 489.4L407.4 446.5C406.5 446 406.9 444.7 407.9 444.7H557.8C558.9 444.7 559.8 445.2 560.2 446Z\"\n fill=\"white\"\n />\n </g>\n {children}\n </svg>\n ),\n);\n\nCursor.displayName = 'Cursor';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\nexport const Devin: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, color = 'currentColor', className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n className={brandClass(mono, className)}\n {...rest}\n >\n <g transform=\"translate(-0.993373 -0.985316) scale(0.060925)\">\n <path d=\"M70 159.3V91.3C70 88.4 71.6 85.6 74.2 84.1L133 50.1C135.6 48.6 138.8 48.6 141.4 50.1L200.3 84.1C202.9 85.6 204.4 88.4 204.4 91.3V126.1C204.7 137.6 210.8 148.7 221.5 154.9C232.3 161.1 244.9 160.8 255.1 155.3L285.1 137.9C287.7 136.4 290.9 136.4 293.5 137.9L352.4 171.9C354.9 173.4 356.5 176.2 356.5 179.2V247.1C356.5 250.1 354.9 252.9 352.4 254.4L293.5 288.4C290.9 289.8 287.7 289.8 285.1 288.4L255.3 271.1C245.1 265.5 232.3 265.1 221.5 271.4C210.8 277.6 204.7 288.7 204.5 300.2V334.9C204.5 337.9 202.9 340.7 200.3 342.2L141.4 376.2C138.8 377.6 135.6 377.6 133 376.2L74.2 342.2C71.6 340.7 70 337.9 70 334.9V267C70 264 71.6 261.2 74.2 259.7L133 225.7C135.6 224.2 138.8 224.2 141.4 225.7L171.5 243.1C181.7 248.6 194.3 248.9 205 242.7C215.8 236.5 221.9 225.2 222.1 213.6C221.8 202.1 215.7 189.7 205 183.5C194.3 177.4 181.6 177.6 171.5 183.2L141.3 200.7C138.7 202.2 135.5 202.2 132.9 200.7L74.2 166.6C71.6 165.1 70 162.3 70 159.3Z\" />\n </g>\n {children}\n </svg>\n ),\n);\n\nDevin.displayName = 'Devin';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\n// `forwardRef` here is required for type compatibility with `LucideIcon` — see\n// `Keboola.tsx` for the full rationale. The Google Cloud mark carries the fixed\n// four-color Google palette (`#EA4335 / #4285F4 / #34A853 / #FBBC05`): its paths\n// keep their own fills and ignore `color`, and it must NOT re-skin under a\n// customer brand.\nexport const Gcp: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n // Lucide's grid — see `Keboola.tsx` for why every brand icon shares it.\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n {/* Measured artwork bbox: (5.50, 7.55) 21.00 × 16.88. */}\n <g transform=\"translate(-3.2381 -3.2286) scale(0.952381)\">\n <path\n fill=\"#EA4335\"\n d=\"m19.466 12.212 1.825-1.826.122-.768C18.087 6.593 12.8 6.936 9.8 10.333a8.438 8.438 0 0 0-1.78 3.335l.654-.092 3.65-.602.282-.288c1.624-1.784 4.37-2.024 6.245-.506l.615.032Z\"\n />\n <path\n fill=\"#4285F4\"\n d=\"M23.892 13.614a8.223 8.223 0 0 0-2.479-3.996l-2.562 2.562a4.554 4.554 0 0 1 1.672 3.612v.455a2.28 2.28 0 0 1 2.28 2.28c0 1.26-1.02 2.255-2.28 2.255h-4.567l-.448.486v2.735l.448.43h4.567c3.275.025 5.951-2.584 5.977-5.86a5.931 5.931 0 0 0-2.608-4.959Z\"\n />\n <path\n fill=\"#34A853\"\n d=\"M11.396 24.433h4.56v-3.651h-4.56c-.325 0-.64-.07-.936-.205l-.646.198-1.839 1.826-.16.62a5.919 5.919 0 0 0 3.58 1.212Z\"\n />\n <path\n fill=\"#FBBC05\"\n d=\"M11.396 12.59a5.931 5.931 0 0 0-3.58 10.632l2.644-2.645a2.28 2.28 0 1 1 3.017-3.017l2.646-2.645a5.925 5.925 0 0 0-4.727-2.325Z\"\n />\n </g>\n {children}\n </svg>\n ),\n);\n\nGcp.displayName = 'Gcp';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\n// `forwardRef` here is required for type compatibility with `LucideIcon` — see\n// `Keboola.tsx` for the full rationale. The Google \"G\" is a fixed four-color\n// vendor mark (`#4285F4 / #34A853 / #FBBC04 / #EA4335`): its paths keep their\n// own fills and ignore `color`, and it must NOT re-skin under a customer brand.\nexport const Google: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n // Lucide's grid — see `Keboola.tsx` for why every brand icon shares it.\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n {/* Measured artwork bbox: (12, 10) 19.60 × 20.00. */}\n <g transform=\"translate(-9.8 -8)\">\n <path\n d=\"M31.6 20.2273C31.6 19.5182 31.5364 18.8364 31.4182 18.1818H22V22.05H27.3818C27.15 23.3 26.4455 24.3591 25.3864 25.0682V27.5773H28.6182C30.5091 25.8364 31.6 23.2727 31.6 20.2273Z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M22 30C24.7 30 26.9636 29.1045 28.6181 27.5773L25.3863 25.0682C24.4909 25.6682 23.3454 26.0227 22 26.0227C19.3954 26.0227 17.1909 24.2636 16.4045 21.9H13.0636V24.4909C14.7091 27.7591 18.0909 30 22 30Z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M16.4045 21.9C16.2045 21.3 16.0909 20.6591 16.0909 20C16.0909 19.3409 16.2045 18.7 16.4045 18.1V15.5091H13.0636C12.3864 16.8591 12 18.3864 12 20C12 21.6136 12.3864 23.1409 13.0636 24.4909L16.4045 21.9Z\"\n fill=\"#FBBC04\"\n />\n <path\n d=\"M22 13.9773C23.4681 13.9773 24.7863 14.4818 25.8227 15.4727L28.6909 12.6045C26.9591 10.9909 24.6954 10 22 10C18.0909 10 14.7091 12.2409 13.0636 15.5091L16.4045 18.1C17.1909 15.7364 19.3954 13.9773 22 13.9773Z\"\n fill=\"#EA4335\"\n />\n </g>\n {children}\n </svg>\n ),\n);\n\nGoogle.displayName = 'Google';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\n// `forwardRef` here is required for type compatibility with `LucideIcon`\n// (a `ForwardRefExoticComponent` from lucide-react). React 19's ref-as-prop\n// pattern produces a plain function component which isn't structurally\n// assignable to `LucideIcon`, so consumers couldn't pass `Keboola`\n// interchangeably with imported Lucide icons (e.g. `<Button><Keboola className=\"tw:size-4\" /></Button>`).\nexport const Keboola: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, color = 'currentColor', className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n // Lucide's own 24-unit grid, and the artwork is scaled into the same 20-unit content box\n // Lucide's icons occupy (`square` is an 18-unit rect + 2-unit stroke = 20 visual units,\n // centered). Every brand icon in this folder follows it, so a brand mark and a Lucide icon\n // render at the same optical size for a given `size` / `tw:size-*`.\n viewBox=\"0 0 24 24\"\n // Kept from when the artwork ran flush to the viewBox edge (y=0..512): an `<svg>` defaults to\n // `overflow: hidden`, and sub-pixel rounding clipped the top of the mark flat. The 2-unit\n // inset above now provides that tolerance; this stays as belt-and-braces.\n overflow=\"visible\"\n fill={color}\n className={brandClass(mono, className)}\n {...rest}\n >\n {/* Measured artwork bbox: (0.13, 0) 299.69 × 512.20. */}\n <g transform=\"translate(6.1439 2) scale(0.039047)\">\n <path d=\"M152 320C79.7 320 24.5 233.9 24.5 124.7C24.5 15.6 70.5 0 152 0s123.6 15.6 123.6 124.7C275.5 233.9 217.7 320 152 320zm-8.7-50.5c0-11.2-9.5-20.3-21.2-20.3s-21.2 9.1-21.2 20.3c0 11.2 9.5 20.3 21.2 20.3s21.2-9.1 21.2-20.3zm55.7 0c0-11.2-9.5-20.3-21.2-20.3s-21.2 9.1-21.2 20.3c0 11.2 9.5 20.3 21.2 20.3s21.2-9.1 21.2-20.3zm68.9 115.1c10.2 9.3 20.2 20.5 29 35c5.9 9.7 2.6 22.1-7.5 27.8c-3.4 1.9-7.1 2.8-10.7 2.8c-7.2 0-14.3-3.6-18.3-10c-6.8-11.1-13.8-18.9-21.7-26.1c-7.3-6.7-15.6-12.7-24.9-19.5c-.7-.5-1.4-1-2.1-1.5c-5-3.6-10-6.8-14.9-9.4c.6 1 1.2 2.1 1.8 3.2c14.4 26.4 29.2 63.1 29.2 104.9c0 11.2-9.5 20.3-21.2 20.3c-11.7 0-21.2-9.1-21.2-20.3c.1-31.8-11.6-62.3-23.8-84.9c-4-7.4-8-13.9-11.6-19.3c-3.4 5.2-7.2 11.3-11 18.3c-12.5 22.7-24.5 53.8-24.4 86c0 11.2-9.5 20.3-21.2 20.3s-21.2-9.1-21.2-20.3c.1-41.8 14.9-78.4 29.2-104.9c.6-1.1 1.2-2.1 1.8-3.2c-5 2.7-9.9 5.8-14.9 9.4c-.6 .5-1.3 .9-1.9 1.4c-9.5 6.9-17.8 12.9-25.1 19.7c-7.9 7.2-14.9 15.1-21.7 26.1c-5.9 9.7-18.9 12.9-29 7.2C.5 441.8-2.9 429.3 3.1 419.7c8.9-14.4 18.8-25.7 29-35c9.2-8.4 18.5-15.1 27.6-21.7c1-.7 2-1.4 3-2.2c4.7-3.5 9.6-6.7 14.6-9.6c-5-2.9-9.8-6.1-14.6-9.6C39.8 325 19.9 302.5 3.1 275.1c-5.9-9.7-2.6-22.1 7.5-27.8c10.1-5.7 23.1-2.5 29 7.2c14.6 23.7 31.1 42 48.7 54.9c18.9 13.7 37.4 20.5 56.5 21.5c1.7-.1 3.5-.1 5.2-.1c1.8 0 3.5 .1 5.2 .1c0 0 0 0 0 0c19.1-1.1 37.6-7.9 56.5-21.5c17.6-12.8 34.2-31.2 48.7-54.9c6-9.7 18.9-12.9 29-7.2c10.1 5.7 13.4 18.1 7.5 27.8c-16.8 27.4-36.7 49.9-59.6 66.6c-4.7 3.5-9.6 6.7-14.5 9.6c4.9 2.9 9.8 6.1 14.5 9.6c.9 .7 1.8 1.3 2.7 2c9.2 6.7 18.5 13.5 27.9 22z\" />\n </g>\n {children}\n </svg>\n ),\n);\n\nKeboola.displayName = 'Keboola';\n","import { forwardRef, useId } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\nexport const Make: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => {\n const baseId = useId().replace(/:/g, '');\n\n return (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n <defs>\n <clipPath id={`${baseId}-clip0`}>\n <path d=\"m156,44.3h33.9c2.6,0,4.7,2.1,4.7,4.7v125.1c0,2.6-2.1,4.7-4.7,4.7h-33.9c-2.6,0-4.7-2.1-4.7-4.7V49c0-2.6,2.1-4.7,4.7-4.7Z\" />\n </clipPath>\n <clipPath id={`${baseId}-clip1`}>\n <path d=\"m56.7,46L.5,157.7c-1.2,2.3-.23,5.1,2.1,6.3l30.3,15.2c2.3,1.2,5.1.23,6.3-2.1l56.2-111.8c1.2-2.3.23-5.1-2.1-6.3l-30.3-15.2c-.68-.34-1.4-.5-2.1-.5-1.7,0-3.4.94-4.2,2.6\" />\n </clipPath>\n <clipPath id={`${baseId}-clip2`}>\n <path d=\"m103.9,46.4l-24,121.8c-.5,2.5,1.1,5,3.7,5.5l33.2,6.7c2.5.51,5-1.1,5.5-3.7l24-121.8c.5-2.5-1.1-5-3.7-5.5l-33.2-6.7c-.31-.06-.62-.09-.93-.09-2.2,0-4.2,1.5-4.6,3.8\" />\n </clipPath>\n <linearGradient\n id={`${baseId}-gradient0`}\n x1=\"-167.5\"\n y1=\"470.3\"\n x2=\"-166.5\"\n y2=\"470.3\"\n gradientTransform=\"translate(16426.9 45936.4) scale(97.45 -97.45)\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop offset=\"0\" stopColor=\"#b02de9\" />\n <stop offset=\".02\" stopColor=\"#b02de9\" />\n <stop offset=\".8\" stopColor=\"#6d00cc\" />\n <stop offset=\"1\" stopColor=\"#6d00cc\" />\n </linearGradient>\n <linearGradient\n id={`${baseId}-gradient1`}\n x1=\"-167.5\"\n y1=\"470.3\"\n x2=\"-166.5\"\n y2=\"470.3\"\n gradientTransform=\"translate(17962.6 50466.15) scale(107.08 -107.08)\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop offset=\"0\" stopColor=\"#f0f\" />\n <stop offset=\"0\" stopColor=\"#f0f\" />\n <stop offset=\".17\" stopColor=\"#e90cf9\" />\n <stop offset=\".54\" stopColor=\"#c023ed\" />\n <stop offset=\".73\" stopColor=\"#b02de9\" />\n <stop offset=\"1\" stopColor=\"#b02de9\" />\n </linearGradient>\n <linearGradient\n id={`${baseId}-gradient2`}\n x1=\"-167.5\"\n y1=\"470.3\"\n x2=\"-166.5\"\n y2=\"470.3\"\n gradientTransform=\"translate(35959.81 101077.55) scale(214.7 -214.7)\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop offset=\"0\" stopColor=\"#f0f\" />\n <stop offset=\".02\" stopColor=\"#f0f\" />\n <stop offset=\".09\" stopColor=\"#e90cf9\" />\n <stop offset=\".23\" stopColor=\"#c023ed\" />\n <stop offset=\".3\" stopColor=\"#b02de9\" />\n <stop offset=\".42\" stopColor=\"#a42be3\" />\n <stop offset=\".63\" stopColor=\"#8626d5\" />\n <stop offset=\".85\" stopColor=\"#6021c3\" />\n <stop offset=\"1\" stopColor=\"#6021c3\" />\n </linearGradient>\n </defs>\n <g transform=\"translate(1.999921 0.535282) scale(0.102775)\">\n <g clipPath={`url(#${baseId}-clip0)`}>\n <rect\n x=\"129.4\"\n y=\"41\"\n width=\"87.1\"\n height=\"141.1\"\n transform=\"translate(-27.91 66.73) rotate(-20.24)\"\n fill={`url(#${baseId}-gradient0)`}\n />\n </g>\n <g clipPath={`url(#${baseId}-clip1)`}>\n <rect\n x=\"-23.9\"\n y=\"29.8\"\n width=\"143.5\"\n height=\"164.3\"\n transform=\"translate(-40.48 28.2) rotate(-23.38)\"\n fill={`url(#${baseId}-gradient1)`}\n />\n </g>\n <g clipPath={`url(#${baseId}-clip2)`}>\n <rect\n x=\"57.6\"\n y=\"35.2\"\n width=\"111\"\n height=\"153.1\"\n transform=\"translate(-31.65 45.95) rotate(-20.21)\"\n fill={`url(#${baseId}-gradient2)`}\n />\n </g>\n </g>\n {children}\n </svg>\n );\n },\n);\n\nMake.displayName = 'Make';\n","import { forwardRef } from 'react';\n\nimport type { BrandIcon, BrandIconProps } from '../brandIcon';\nimport { brandClass } from '../brandIcon';\n\n// `forwardRef` here is required for type compatibility with `LucideIcon`\n// (a `ForwardRefExoticComponent` from lucide-react). React 19's ref-as-prop\n// pattern produces a plain function component which isn't structurally\n// assignable to `LucideIcon`, so consumers couldn't pass `Microsoft`\n// interchangeably with imported Lucide icons. The four-square mark carries\n// fixed Microsoft brand colors and deliberately ignores `color` — it must NOT\n// re-skin under a customer brand.\nexport const Microsoft: BrandIcon = forwardRef<SVGSVGElement, BrandIconProps>(\n ({ size = 24, mono, className, children, ...rest }, ref) => (\n <svg\n ref={ref}\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n // Lucide's grid — see `Keboola.tsx` for why every brand icon shares it.\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={brandClass(mono, className)}\n {...rest}\n >\n {/* Measured artwork bbox: (0, 0) 21 × 21. */}\n <g transform=\"translate(2 2) scale(0.952381)\">\n <rect x=\"0\" y=\"0\" width=\"10\" height=\"10\" fill=\"#F25022\" />\n <rect x=\"11\" y=\"0\" width=\"10\" height=\"10\" fill=\"#7FBA00\" />\n <rect x=\"0\" y=\"11\" width=\"10\" height=\"10\" fill=\"#00A4EF\" />\n <rect x=\"11\" y=\"11\" width=\"10\" height=\"10\" fill=\"#FFB900\" />\n </g>\n {children}\n </svg>\n ),\n);\n\nMicrosoft.displayName = 'Microsoft';\n"],"mappings":"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"}
|