@keboola/design 11.6.1 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +50 -9
- package/CHANGELOG.md +241 -0
- package/COMPONENT-API.md +337 -288
- package/README.md +12 -2
- package/dist/{AIKit-CQxVwyAk.js → AIKit-BD4r7ff-.js} +807 -199
- package/dist/AIKit-BD4r7ff-.js.map +1 -0
- package/dist/{Alert-C4Y9IwMI.js → Alert-UI-CIs-1.js} +16 -16
- package/dist/Alert-UI-CIs-1.js.map +1 -0
- package/dist/{AlertModal-BGJdaRRj.js → AlertModal-Th2khjPi.js} +5 -5
- package/dist/AlertModal-Th2khjPi.js.map +1 -0
- package/dist/{AppShell-DRgJxpXW.js → AppShell-WSQabK8r.js} +15 -52
- package/dist/AppShell-WSQabK8r.js.map +1 -0
- package/dist/{AutoSaveTextarea-BeuWuszr.js → AutoSaveTextarea-C5iIr2Ts.js} +2 -2
- package/dist/{AutoSaveTextarea-BeuWuszr.js.map → AutoSaveTextarea-C5iIr2Ts.js.map} +1 -1
- package/dist/{Badge-o5jURtpB.js → Badge-DIjhwPvh.js} +4 -9
- package/dist/Badge-DIjhwPvh.js.map +1 -0
- package/dist/{BrandEditor-CS9P4r2p.js → BrandEditor-BU23Vl8V.js} +7 -7
- package/dist/{BrandEditor-CS9P4r2p.js.map → BrandEditor-BU23Vl8V.js.map} +1 -1
- package/dist/{BrandLogo-CoKBk4MI.js → BrandLogo-CKpVSZb6.js} +4 -4
- package/dist/BrandLogo-CKpVSZb6.js.map +1 -0
- package/dist/{Breadcrumb-D1id7YXd.js → Breadcrumb-p9HtMLCc.js} +8 -14
- package/dist/Breadcrumb-p9HtMLCc.js.map +1 -0
- package/dist/{Button-DsRrU5F1.js → Button-Ca4Q3VJU.js} +31 -13
- package/dist/Button-Ca4Q3VJU.js.map +1 -0
- package/dist/{Calendar-cG5NIJ4O.js → Calendar-DFtmZzbF.js} +99 -99
- package/dist/Calendar-DFtmZzbF.js.map +1 -0
- package/dist/{Card-Dyo7055Q.js → Card-Cr9MBNHu.js} +4 -4
- package/dist/Card-Cr9MBNHu.js.map +1 -0
- package/dist/{Checkbox-Bqr6zXcW.js → Checkbox-8yIIgY7g.js} +4 -4
- package/dist/Checkbox-8yIIgY7g.js.map +1 -0
- package/dist/{Clipboard-C2YBRfD8.js → Clipboard-_xf6hMDD.js} +2 -2
- package/dist/{Clipboard-C2YBRfD8.js.map → Clipboard-_xf6hMDD.js.map} +1 -1
- package/dist/{ClipboardButton-CrljClL1.js → ClipboardButton-DHa1trtI.js} +4 -4
- package/dist/{ClipboardButton-CrljClL1.js.map → ClipboardButton-DHa1trtI.js.map} +1 -1
- package/dist/{CodeEditor-C9AS8Ch0.js → CodeEditor-BSo-oLFG.js} +55 -165
- package/dist/CodeEditor-BSo-oLFG.js.map +1 -0
- package/dist/{ColorInput-Dg87lKcR.js → ColorInput-DSMqrs2-.js} +12 -27
- package/dist/ColorInput-DSMqrs2-.js.map +1 -0
- package/dist/{ColorModeSwitch-CsWLiTBX.js → ColorModeSwitch-D7EuWyJz.js} +7 -17
- package/dist/ColorModeSwitch-D7EuWyJz.js.map +1 -0
- package/dist/Combobox-CxRAYOBt.js +1069 -0
- package/dist/Combobox-CxRAYOBt.js.map +1 -0
- package/dist/{Command-CqxoI_De.js → Command-BU_cVurn.js} +4 -4
- package/dist/{Command-CqxoI_De.js.map → Command-BU_cVurn.js.map} +1 -1
- package/dist/{CopyField-Rx9HPTbJ.js → CopyField-6_c-NdLO.js} +17 -53
- package/dist/{CopyField-Rx9HPTbJ.js.map → CopyField-6_c-NdLO.js.map} +1 -1
- package/dist/{DateInput-DpifECUQ.js → DateInput-DyEErfJf.js} +6 -6
- package/dist/{DateInput-DpifECUQ.js.map → DateInput-DyEErfJf.js.map} +1 -1
- package/dist/{DatePicker-nA8YdE84.js → DatePicker-CtSa9b3V.js} +3 -3
- package/dist/{DatePicker-nA8YdE84.js.map → DatePicker-CtSa9b3V.js.map} +1 -1
- package/dist/{DateRangeInput-9MIw7P6L.js → DateRangeInput-Dg7-VUd9.js} +10 -14
- package/dist/DateRangeInput-Dg7-VUd9.js.map +1 -0
- package/dist/{DateRangePicker-DjSUFjh4.js → DateRangePicker-BoPnh4aH.js} +9 -13
- package/dist/DateRangePicker-BoPnh4aH.js.map +1 -0
- package/dist/DiffView-ppTIzh2h.js.map +1 -1
- package/dist/{DropdownMenu-CASr-jgl.js → DropdownMenu-gRM-A8qU.js} +11 -6
- package/dist/DropdownMenu-gRM-A8qU.js.map +1 -0
- package/dist/{FieldItem-DtPTzNef.js → FieldItem-2wMXQ0Qw.js} +12 -25
- package/dist/FieldItem-2wMXQ0Qw.js.map +1 -0
- package/dist/{FieldItem-vhIJW4pj.d.ts → FieldItem-CPN1xjN5.d.ts} +11 -25
- package/dist/{FileUpload-DYQCTGjU.js → FileUpload-C83tXuE2.js} +11 -16
- package/dist/{FileUpload-DYQCTGjU.js.map → FileUpload-C83tXuE2.js.map} +1 -1
- package/dist/{Form-DAaatlBk.js → Form-95rVLfX8.js} +15 -23
- package/dist/{Form-DAaatlBk.js.map → Form-95rVLfX8.js.map} +1 -1
- package/dist/{FormGroup-Bl8JmnzJ.js → FormGroup-CmNiAtU6.js} +11 -17
- package/dist/FormGroup-CmNiAtU6.js.map +1 -0
- package/dist/{FullScreenModal-CN9nAs72.js → FullScreenModal-CD7mYeTz.js} +15 -29
- package/dist/FullScreenModal-CD7mYeTz.js.map +1 -0
- package/dist/{HoverCard-B9ZMJxjn.js → HoverCard-B8OKu9XZ.js} +2 -2
- package/dist/{HoverCard-B9ZMJxjn.js.map → HoverCard-B8OKu9XZ.js.map} +1 -1
- package/dist/{InputGroup-DcZRlVnN.js → InputGroup-B4QOPxHl.js} +12 -13
- package/dist/InputGroup-B4QOPxHl.js.map +1 -0
- package/dist/{Kbd-D1Azcc4g.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-CujFxVzk.js → MermaidDiagram-BQvz6bhv.js} +16 -34
- package/dist/MermaidDiagram-BQvz6bhv.js.map +1 -0
- package/dist/{Modal-Coj-H02o.js → Modal-Driyqs_N.js} +17 -34
- package/dist/Modal-Driyqs_N.js.map +1 -0
- package/dist/{ModalTitle-C76ke2eo.js → ModalTitle-BxopkIoQ.js} +3 -3
- package/dist/ModalTitle-BxopkIoQ.js.map +1 -0
- package/dist/{MultiActionButtonGroup-CNNoBQbv.js → MultiActionButtonGroup-BPnmzBtw.js} +3 -3
- package/dist/{MultiActionButtonGroup-CNNoBQbv.js.map → MultiActionButtonGroup-BPnmzBtw.js.map} +1 -1
- package/dist/{Navbar-Liy1TPI7.js → Navbar-B_DNpv5s.js} +9 -13
- package/dist/{Navbar-Liy1TPI7.js.map → Navbar-B_DNpv5s.js.map} +1 -1
- package/dist/{OtpInput-CbbymqYs.js → OtpInput-I8B8Vjdl.js} +2 -2
- package/dist/{OtpInput-CbbymqYs.js.map → OtpInput-I8B8Vjdl.js.map} +1 -1
- package/dist/{PageHeader-Q3IpCnQd.js → PageHeader-CgfyXpf1.js} +13 -26
- package/dist/PageHeader-CgfyXpf1.js.map +1 -0
- package/dist/{PageLayout-DSVM-ASz.js → PageLayout-DiAAILuS.js} +12 -20
- package/dist/PageLayout-DiAAILuS.js.map +1 -0
- package/dist/{PageToolbar-BKVJiDAL.js → PageToolbar-DOAtAnfL.js} +12 -42
- package/dist/PageToolbar-DOAtAnfL.js.map +1 -0
- package/dist/{Pagination-C_b7Xhey.js → Pagination-LaSg-5cl.js} +3 -3
- package/dist/{Pagination-C_b7Xhey.js.map → Pagination-LaSg-5cl.js.map} +1 -1
- package/dist/{Popconfirm-5pBzT_HQ.js → Popconfirm-SLz0zodk.js} +3 -3
- package/dist/{Popconfirm-5pBzT_HQ.js.map → Popconfirm-SLz0zodk.js.map} +1 -1
- package/dist/{Popover-BEbQrC_P.js → Popover-CEk915I1.js} +4 -3
- package/dist/Popover-CEk915I1.js.map +1 -0
- package/dist/{RadioGroup-CUBsuP7r.js → RadioGroup-CBPRLRN0.js} +4 -4
- package/dist/{RadioGroup-CUBsuP7r.js.map → RadioGroup-CBPRLRN0.js.map} +1 -1
- package/dist/{Search-DVpJuzr9.js → Search-DmkQo716.js} +3 -3
- package/dist/{Search-DVpJuzr9.js.map → Search-DmkQo716.js.map} +1 -1
- package/dist/{SearchInput-Q85p8Ews.js → SearchInput-CEfQDNl3.js} +8 -13
- package/dist/SearchInput-CEfQDNl3.js.map +1 -0
- package/dist/{SectionNav-mpmSM3OC.js → SectionNav-B_qf0AXi.js} +10 -42
- package/dist/SectionNav-B_qf0AXi.js.map +1 -0
- package/dist/{Select-DV3Hak_l.js → Select-ByRvkZ3D.js} +8 -11
- package/dist/{Select-DV3Hak_l.js.map → Select-ByRvkZ3D.js.map} +1 -1
- package/dist/{Sheet-Chf0kX1E.js → Sheet-C-yXk5Da.js} +5 -9
- package/dist/Sheet-C-yXk5Da.js.map +1 -0
- package/dist/{Sidebar-CTWsHZhF.js → Sidebar-Ds0E6PbR.js} +181 -33
- package/dist/Sidebar-Ds0E6PbR.js.map +1 -0
- package/dist/{Slider-Bv0B6lI0.js → Slider-DWdu9NuM.js} +3 -3
- package/dist/{Slider-Bv0B6lI0.js.map → Slider-DWdu9NuM.js.map} +1 -1
- package/dist/{Stepper-C8sm9ZFM.js → Stepper-BLkLhfnd.js} +6 -9
- package/dist/{Stepper-C8sm9ZFM.js.map → Stepper-BLkLhfnd.js.map} +1 -1
- package/dist/{Switch-B0WdGSjz.js → Switch-DZvNePOm.js} +2 -2
- package/dist/{Switch-B0WdGSjz.js.map → Switch-DZvNePOm.js.map} +1 -1
- package/dist/{Table-CvYuTuNU.js → Table-BaVT5Tkn.js} +6 -11
- package/dist/{Table-CvYuTuNU.js.map → Table-BaVT5Tkn.js.map} +1 -1
- package/dist/{Tabs-eB974xJf.js → Tabs-Dt9oLYHC.js} +3 -3
- package/dist/{Tabs-eB974xJf.js.map → Tabs-Dt9oLYHC.js.map} +1 -1
- package/dist/{TextInput-DiEMxVF6.js → TextInput-CDG2XpBl.js} +12 -15
- package/dist/TextInput-CDG2XpBl.js.map +1 -0
- package/dist/{ThemeProvider-BI6JWBdJ.js → ThemeProvider-DXsxFg1U.js} +13 -31
- package/dist/ThemeProvider-DXsxFg1U.js.map +1 -0
- package/dist/{TimePicker-BGeqc-Ed.js → TimePicker-CDGYrRxi.js} +2 -2
- package/dist/{TimePicker-BGeqc-Ed.js.map → TimePicker-CDGYrRxi.js.map} +1 -1
- package/dist/{Timeline-BG5Xogxh.js → Timeline-B-I6sb0M.js} +2 -2
- package/dist/{Timeline-BG5Xogxh.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-U_VH3QRO.js → ZoomableSvg-BzXVfgnI.js} +5 -19
- package/dist/ZoomableSvg-BzXVfgnI.js.map +1 -0
- package/dist/charts.d.ts +21 -52
- package/dist/charts.js +13 -39
- package/dist/charts.js.map +1 -1
- package/dist/{context-D7X470dy.js → context-U293r3v-.js} +5 -9
- package/dist/context-U293r3v-.js.map +1 -0
- package/dist/editors.d.ts +27 -124
- package/dist/editors.js +29 -71
- package/dist/editors.js.map +1 -1
- package/dist/{findLiteralMatches-BGBw8Vbl.js → findLiteralMatches-DgGLzyG0.js} +8 -20
- package/dist/findLiteralMatches-DgGLzyG0.js.map +1 -0
- package/dist/flint.d.ts +3 -6
- package/dist/flint.js +31 -80
- package/dist/flint.js.map +1 -1
- package/dist/{icons-Cek151jC.js → icons-wcA70iQx.js} +105 -2
- package/dist/icons-wcA70iQx.js.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +2 -2
- package/dist/{index-m-kQEWiY.d.ts → index-B7k-09i1.d.ts} +14 -2
- package/dist/index.d.ts +1461 -1809
- package/dist/index.js +70 -67
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/AppShell.js +1 -1
- package/dist/internal/blocks/AuthLayout.js +7 -27
- package/dist/internal/blocks/AuthLayout.js.map +1 -1
- package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChartPanel.js +4 -8
- package/dist/internal/blocks/ChartPanel.js.map +1 -1
- package/dist/internal/blocks/ChipEditor.js +129 -0
- package/dist/internal/blocks/ChipEditor.js.map +1 -0
- 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 +162 -165
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +1 -1
- package/dist/internal/blocks/OtpInput.js +1 -1
- package/dist/internal/blocks/PageHeader.js +1 -1
- package/dist/internal/blocks/PageLayout.js +1 -1
- package/dist/internal/blocks/PageToolbar.js +1 -1
- package/dist/internal/blocks/PasswordInput.js +4 -4
- package/dist/internal/blocks/PasswordInput.js.map +1 -1
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +4 -4
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +3 -3
- package/dist/internal/blocks/StatCard.js +4 -8
- package/dist/internal/blocks/StatCard.js.map +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/Textarea.js +2 -2
- package/dist/internal/blocks/TimeInput.js +5 -5
- package/dist/internal/blocks/TimeInput.js.map +1 -1
- package/dist/internal/components/Alert.js +1 -1
- package/dist/internal/components/AlertModal.js +1 -1
- package/dist/internal/components/Avatar.js +1 -1
- package/dist/internal/components/Badge.js +1 -1
- package/dist/internal/components/BrandLogo.js +1 -1
- package/dist/internal/components/Breadcrumb.js +1 -1
- package/dist/internal/components/Button.js +1 -1
- package/dist/internal/components/ButtonGroup.js.map +1 -1
- package/dist/internal/components/Calendar.js +1 -1
- package/dist/internal/components/Card.js +1 -1
- package/dist/internal/components/Checkbox.js +1 -1
- package/dist/internal/components/Clipboard.js +1 -1
- package/dist/internal/components/CollapsiblePanel.js +2 -2
- package/dist/internal/components/Combobox.js +2 -2
- package/dist/internal/components/DatePicker.js +1 -1
- package/dist/internal/components/DateRangePicker.js +1 -1
- package/dist/internal/components/DropdownMenu.js +1 -1
- package/dist/internal/components/FileUpload.js +1 -1
- package/dist/internal/components/FullScreenModal.js +1 -1
- package/dist/internal/components/HoverCard.js +1 -1
- package/dist/internal/components/InputGroup.js +1 -1
- package/dist/internal/components/Kbd.js +1 -1
- package/dist/internal/components/MarkedText.js +1 -1
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +1 -1
- package/dist/internal/components/Modal.js +1 -1
- package/dist/internal/components/Navbar.js +1 -1
- package/dist/internal/components/Pagination.js +1 -1
- package/dist/internal/components/PanelWithDetails.js +1 -1
- package/dist/internal/components/Popconfirm.js +1 -1
- package/dist/internal/components/Popover.js +1 -1
- package/dist/internal/components/RadioGroup.js +1 -1
- package/dist/internal/components/Search.js +1 -1
- package/dist/internal/components/Select.js +1 -1
- package/dist/internal/components/Separator.js.map +1 -1
- package/dist/internal/components/Sheet.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Skeleton/Skeleton.js +5 -9
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/SpotlightBackdrop.js +3 -8
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
- package/dist/internal/components/StatusDot.js +60 -0
- package/dist/internal/components/StatusDot.js.map +1 -0
- 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 +2 -2
- 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/mergeRefs.js +27 -9
- package/dist/internal/utils/mergeRefs.js.map +1 -1
- package/dist/internal/utils.js +3 -3
- package/dist/markdown-editor.d.ts +15 -37
- package/dist/markdown-editor.js +17 -23
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +4 -6
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.d.ts +9 -19
- package/dist/rjsf.js +44 -84
- package/dist/rjsf.js.map +1 -1
- package/dist/{styles-BAFscjSV.js → styles-gzcjOyKv.js} +6 -6
- package/dist/styles-gzcjOyKv.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/svgTransforms-Dw2hRA-i.js +51 -0
- package/dist/svgTransforms-Dw2hRA-i.js.map +1 -0
- package/dist/testing.d.ts +3 -10
- package/dist/testing.js +5 -12
- package/dist/testing.js.map +1 -1
- package/dist/themeTokens-7DEab0kp.js +31 -0
- package/dist/themeTokens-7DEab0kp.js.map +1 -0
- package/dist/{toast-DIC0iNRf.js → toast-CyXEdaCZ.js} +3 -3
- package/dist/toast-CyXEdaCZ.js.map +1 -0
- package/dist/{themeScopeContext-D7fSyb06.js → useColorSchemeState-Cw4MCXUs.js} +14 -14
- package/dist/useColorSchemeState-Cw4MCXUs.js.map +1 -0
- package/dist/{useControllableState-M6494mCT.js → useControllableState-CUYXMsfz.js} +3 -7
- package/dist/useControllableState-CUYXMsfz.js.map +1 -0
- package/dist/useElement-D-RjrGa4.js +21 -0
- package/dist/useElement-D-RjrGa4.js.map +1 -0
- package/dist/useThemeAttributes-B199Regy.js +67 -0
- package/dist/useThemeAttributes-B199Regy.js.map +1 -0
- package/dist/{utils-DnkrFYqY.js → utils-Bd28bWgm.js} +53 -20
- 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 +11 -9
- package/src/styles.css +120 -14
- package/src/theme.css +126 -6
- package/dist/AIKit-CQxVwyAk.js.map +0 -1
- package/dist/Alert-C4Y9IwMI.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-D1id7YXd.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-Bqr6zXcW.js.map +0 -1
- package/dist/CodeEditor-C9AS8Ch0.js.map +0 -1
- package/dist/ColorInput-Dg87lKcR.js.map +0 -1
- package/dist/ColorModeSwitch-CsWLiTBX.js.map +0 -1
- package/dist/Combobox-BfanUAqY.js +0 -619
- package/dist/Combobox-BfanUAqY.js.map +0 -1
- package/dist/DateRangeInput-9MIw7P6L.js.map +0 -1
- package/dist/DateRangePicker-DjSUFjh4.js.map +0 -1
- package/dist/DropdownMenu-CASr-jgl.js.map +0 -1
- package/dist/FieldItem-DtPTzNef.js.map +0 -1
- package/dist/FormGroup-Bl8JmnzJ.js.map +0 -1
- package/dist/FullScreenModal-CN9nAs72.js.map +0 -1
- package/dist/InputGroup-DcZRlVnN.js.map +0 -1
- package/dist/Kbd-D1Azcc4g.js.map +0 -1
- package/dist/MermaidDiagram-CujFxVzk.js.map +0 -1
- package/dist/Modal-Coj-H02o.js.map +0 -1
- package/dist/ModalTitle-C76ke2eo.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-Q85p8Ews.js.map +0 -1
- package/dist/SectionNav-mpmSM3OC.js.map +0 -1
- package/dist/Sheet-Chf0kX1E.js.map +0 -1
- package/dist/Sidebar-CTWsHZhF.js.map +0 -1
- package/dist/TextInput-DiEMxVF6.js.map +0 -1
- package/dist/ThemeProvider-BI6JWBdJ.js.map +0 -1
- package/dist/ZoomableSvg-U_VH3QRO.js.map +0 -1
- package/dist/context-D7X470dy.js.map +0 -1
- package/dist/findLiteralMatches-BGBw8Vbl.js.map +0 -1
- package/dist/icons-Cek151jC.js.map +0 -1
- package/dist/styles-BAFscjSV.js.map +0 -1
- package/dist/svgTransforms-CJAYPk7o.js +0 -81
- package/dist/svgTransforms-CJAYPk7o.js.map +0 -1
- package/dist/themeScopeContext-D7fSyb06.js.map +0 -1
- package/dist/themeTokens-qP1-55O7.js +0 -119
- package/dist/themeTokens-qP1-55O7.js.map +0 -1
- package/dist/toast-DIC0iNRf.js.map +0 -1
- package/dist/useControllableState-M6494mCT.js.map +0 -1
- package/dist/useElement-DkF6esWL.js +0 -15
- package/dist/useElement-DkF6esWL.js.map +0 -1
- package/dist/utils-DnkrFYqY.js.map +0 -1
- package/dist/vegaTheme-CSvFEMBl.js.map +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/blocks/DiagramShared/svgTransforms.ts
|
|
2
|
+
const HTML_TAG = /<[^>]+>/g;
|
|
3
|
+
const FOREIGN_OBJECT = /(<foreignObject\b[^>]*>)([\s\S]*?)(<\/foreignObject>)/g;
|
|
4
|
+
const ROOT_SVG_TAG = /^(\s*<svg\b)([^>]*)(>)/i;
|
|
5
|
+
/**
|
|
6
|
+
* Collapses each `<foreignObject>`'s HTML to its text content.
|
|
7
|
+
*
|
|
8
|
+
* - DOMPurify's SVG profile strips XHTML elements (mermaid labels vanish) but keeps bare text.
|
|
9
|
+
* - Mermaid already sanitized the text (`securityLevel: 'strict'`).
|
|
10
|
+
* - Entities stay encoded: decoding could turn `<`/`>` into real markup.
|
|
11
|
+
*/
|
|
12
|
+
const flattenForeignObjectLabels = (svg) => svg.replace(FOREIGN_OBJECT, (_match, open, inner, close) => {
|
|
13
|
+
return `${open}${inner.replace(HTML_TAG, " ").replace(/\s+/g, " ").trim()}${close}`;
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Makes the root `<svg>` fluid: `width="100%"`, `max-width` from the viewBox, no fixed height.
|
|
17
|
+
*
|
|
18
|
+
* - Only the root tag: inner icon `<svg>`s keep their fixed size.
|
|
19
|
+
* - Keeps `style` (minus `max-width`): beautiful-mermaid's `--bg`/`--fg` theme vars live there.
|
|
20
|
+
*/
|
|
21
|
+
const STYLE_ATTR = /\s+style="([^"]*)"/i;
|
|
22
|
+
const makeResponsive = (svgString) => {
|
|
23
|
+
const viewBoxMatch = svgString.match(/viewBox="[^"]*\s([\d.]+)\s[\d.]+"/);
|
|
24
|
+
const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : void 0;
|
|
25
|
+
return svgString.replace(ROOT_SVG_TAG, (_match, open, attrs, close) => {
|
|
26
|
+
const styleDecls = (attrs.match(STYLE_ATTR)?.[1] ?? "").replace(/max-width:\s*[^;"]*;?\s*/gi, "").replace(/\s+/g, " ").trim().replace(/;$/, "");
|
|
27
|
+
let nextAttrs = attrs.replace(/\s+width="[^"]*"/i, "").replace(/\s+height="[^"]*"/i, "").replace(STYLE_ATTR, "");
|
|
28
|
+
nextAttrs += " width=\"100%\"";
|
|
29
|
+
const styleParts = [styleDecls, vbWidth ? `max-width: ${vbWidth}px` : ""].filter(Boolean).join("; ");
|
|
30
|
+
if (styleParts) nextAttrs += ` style="${styleParts}"`;
|
|
31
|
+
return `${open}${nextAttrs}${close}`;
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Whether an SVG has drawn content, i.e. a non-degenerate viewBox.
|
|
36
|
+
*
|
|
37
|
+
* - beautiful-mermaid may return `viewBox="0 0 0 0"` instead of throwing; mermaid must then run.
|
|
38
|
+
* - A missing viewBox counts as drawn: some mermaid types size via width/height.
|
|
39
|
+
* - Only the root `<svg>` is read; nested icon `<svg>`s carry their own viewBox.
|
|
40
|
+
* - Any quote style and spaces around `=` match; a miss would count as drawn.
|
|
41
|
+
*/
|
|
42
|
+
const ROOT_VIEWBOX = /^\s*<svg\b[^>]*\sviewBox\s*=\s*(["'])\s*[\d.eE+-]+\s+[\d.eE+-]+\s+([\d.eE+-]+)\s+([\d.eE+-]+)\s*\1/i;
|
|
43
|
+
const hasDrawnContent = (svg) => {
|
|
44
|
+
const viewBox = svg.match(ROOT_VIEWBOX);
|
|
45
|
+
if (!viewBox) return true;
|
|
46
|
+
return Number(viewBox[2]) > 0 && Number(viewBox[3]) > 0;
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { flattenForeignObjectLabels, hasDrawnContent, makeResponsive };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=svgTransforms-Dw2hRA-i.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svgTransforms-Dw2hRA-i.js","names":[],"sources":["../src/blocks/DiagramShared/svgTransforms.ts"],"sourcesContent":["// Post-processing of diagram SVG output (mermaid, vega) before ZoomableSvg's DOMPurify pass.\n\nconst HTML_TAG = /<[^>]+>/g;\nconst FOREIGN_OBJECT = /(<foreignObject\\b[^>]*>)([\\s\\S]*?)(<\\/foreignObject>)/g;\n// Root <svg> open tag only; nested icon <svg>s must not match.\nconst ROOT_SVG_TAG = /^(\\s*<svg\\b)([^>]*)(>)/i;\n\n/**\n * Collapses each `<foreignObject>`'s HTML to its text content.\n *\n * - DOMPurify's SVG profile strips XHTML elements (mermaid labels vanish) but keeps bare text.\n * - Mermaid already sanitized the text (`securityLevel: 'strict'`).\n * - Entities stay encoded: decoding could turn `<`/`>` into real markup.\n */\nexport const flattenForeignObjectLabels = (svg: string): string =>\n svg.replace(FOREIGN_OBJECT, (_match, open: string, inner: string, close: string) => {\n const text = inner.replace(HTML_TAG, ' ').replace(/\\s+/g, ' ').trim();\n return `${open}${text}${close}`;\n });\n\n/**\n * Makes the root `<svg>` fluid: `width=\"100%\"`, `max-width` from the viewBox, no fixed height.\n *\n * - Only the root tag: inner icon `<svg>`s keep their fixed size.\n * - Keeps `style` (minus `max-width`): beautiful-mermaid's `--bg`/`--fg` theme vars live there.\n */\nconst STYLE_ATTR = /\\s+style=\"([^\"]*)\"/i;\n\nexport const makeResponsive = (svgString: string): string => {\n const viewBoxMatch = svgString.match(/viewBox=\"[^\"]*\\s([\\d.]+)\\s[\\d.]+\"/);\n const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : undefined;\n\n return svgString.replace(ROOT_SVG_TAG, (_match, open: string, attrs: string, close: string) => {\n const existingStyle = attrs.match(STYLE_ATTR)?.[1] ?? '';\n const styleDecls = existingStyle\n .replace(/max-width:\\s*[^;\"]*;?\\s*/gi, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/;$/, '');\n\n let nextAttrs = attrs\n .replace(/\\s+width=\"[^\"]*\"/i, '')\n .replace(/\\s+height=\"[^\"]*\"/i, '')\n .replace(STYLE_ATTR, '');\n\n nextAttrs += ' width=\"100%\"';\n\n const styleParts = [styleDecls, vbWidth ? `max-width: ${vbWidth}px` : '']\n .filter(Boolean)\n .join('; ');\n if (styleParts) nextAttrs += ` style=\"${styleParts}\"`;\n\n return `${open}${nextAttrs}${close}`;\n });\n};\n\n/**\n * Whether an SVG has drawn content, i.e. a non-degenerate viewBox.\n *\n * - beautiful-mermaid may return `viewBox=\"0 0 0 0\"` instead of throwing; mermaid must then run.\n * - A missing viewBox counts as drawn: some mermaid types size via width/height.\n * - Only the root `<svg>` is read; nested icon `<svg>`s carry their own viewBox.\n * - Any quote style and spaces around `=` match; a miss would count as drawn.\n */\nconst ROOT_VIEWBOX =\n /^\\s*<svg\\b[^>]*\\sviewBox\\s*=\\s*([\"'])\\s*[\\d.eE+-]+\\s+[\\d.eE+-]+\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)\\s*\\1/i;\n\nexport const hasDrawnContent = (svg: string): boolean => {\n const viewBox = svg.match(ROOT_VIEWBOX);\n if (!viewBox) return true;\n return Number(viewBox[2]) > 0 && Number(viewBox[3]) > 0;\n};\n"],"mappings":";AAEA,MAAM,WAAW;AACjB,MAAM,iBAAiB;AAEvB,MAAM,eAAe;;;;;;;;AASrB,MAAa,8BAA8B,QACzC,IAAI,QAAQ,iBAAiB,QAAQ,MAAc,OAAe,UAAkB;CAElF,OAAO,GAAG,OADG,MAAM,QAAQ,UAAU,GAAG,CAAC,CAAC,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAC3C,IAAI;AAC1B,CAAC;;;;;;;AAQH,MAAM,aAAa;AAEnB,MAAa,kBAAkB,cAA8B;CAC3D,MAAM,eAAe,UAAU,MAAM,mCAAmC;CACxE,MAAM,UAAU,eAAe,KAAK,MAAM,OAAO,aAAa,EAAE,CAAC,IAAI,KAAA;CAErE,OAAO,UAAU,QAAQ,eAAe,QAAQ,MAAc,OAAe,UAAkB;EAE7F,MAAM,cADgB,MAAM,MAAM,UAAU,CAAC,GAAG,MAAM,GAAA,CAEnD,QAAQ,8BAA8B,EAAE,CAAC,CACzC,QAAQ,QAAQ,GAAG,CAAC,CACpB,KAAK,CAAC,CACN,QAAQ,MAAM,EAAE;EAEnB,IAAI,YAAY,MACb,QAAQ,qBAAqB,EAAE,CAAC,CAChC,QAAQ,sBAAsB,EAAE,CAAC,CACjC,QAAQ,YAAY,EAAE;EAEzB,aAAa;EAEb,MAAM,aAAa,CAAC,YAAY,UAAU,cAAc,QAAQ,MAAM,EAAE,CAAC,CACtE,OAAO,OAAO,CAAC,CACf,KAAK,IAAI;EACZ,IAAI,YAAY,aAAa,WAAW,WAAW;EAEnD,OAAO,GAAG,OAAO,YAAY;CAC/B,CAAC;AACH;;;;;;;;;AAUA,MAAM,eACJ;AAEF,MAAa,mBAAmB,QAAyB;CACvD,MAAM,UAAU,IAAI,MAAM,YAAY;CACtC,IAAI,CAAC,SAAS,OAAO;CACrB,OAAO,OAAO,QAAQ,EAAE,IAAI,KAAK,OAAO,QAAQ,EAAE,IAAI;AACxD"}
|
package/dist/testing.d.ts
CHANGED
|
@@ -9,16 +9,9 @@ type Options = Omit<RenderOptions, 'wrapper'> & {
|
|
|
9
9
|
/**
|
|
10
10
|
* `@testing-library/react` `render` wrapped in a `<ThemeProvider brand={...}>`.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* brand-dependent behaviour (e.g. chrome re-skins under `keboola-legacy`).
|
|
16
|
-
*
|
|
17
|
-
* `ThemeProvider` no longer drives the argo/legacy design language (that is
|
|
18
|
-
* kbc-ui-specific), so this helper also provides `ArgoDesignContext` derived
|
|
19
|
-
* from the brand — a legacy brand renders legacy chrome, any other renders
|
|
20
|
-
* argo — matching how kbc-ui wires it, so brand-dependent chrome tests keep
|
|
21
|
-
* working through a single `brand` option.
|
|
12
|
+
* - For components that call `useTheme()` or use the brand CSS variables.
|
|
13
|
+
* - Also provides `ArgoDesignContext` from the brand, as kbc-ui does: a legacy brand gets
|
|
14
|
+
* legacy chrome, any other argo.
|
|
22
15
|
*/
|
|
23
16
|
declare const renderWithTheme: (ui: ReactElement, options?: Options) => RenderResult;
|
|
24
17
|
//#endregion
|
package/dist/testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ArgoDesignContext } from "./context-
|
|
2
|
-
import { ThemeProvider } from "./ThemeProvider-
|
|
1
|
+
import { ArgoDesignContext } from "./context-U293r3v-.js";
|
|
2
|
+
import { ThemeProvider } from "./ThemeProvider-DXsxFg1U.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { keboola, keboolaLegacySidebar, keboolaLegacyTopnav } from "@keboola/brand-registry";
|
|
5
5
|
import { render } from "@testing-library/react";
|
|
@@ -8,16 +8,9 @@ const keboolaLegacyIds = [keboolaLegacySidebar.id, keboolaLegacyTopnav.id];
|
|
|
8
8
|
/**
|
|
9
9
|
* `@testing-library/react` `render` wrapped in a `<ThemeProvider brand={...}>`.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* brand-dependent behaviour (e.g. chrome re-skins under `keboola-legacy`).
|
|
15
|
-
*
|
|
16
|
-
* `ThemeProvider` no longer drives the argo/legacy design language (that is
|
|
17
|
-
* kbc-ui-specific), so this helper also provides `ArgoDesignContext` derived
|
|
18
|
-
* from the brand — a legacy brand renders legacy chrome, any other renders
|
|
19
|
-
* argo — matching how kbc-ui wires it, so brand-dependent chrome tests keep
|
|
20
|
-
* working through a single `brand` option.
|
|
11
|
+
* - For components that call `useTheme()` or use the brand CSS variables.
|
|
12
|
+
* - Also provides `ArgoDesignContext` from the brand, as kbc-ui does: a legacy brand gets
|
|
13
|
+
* legacy chrome, any other argo.
|
|
21
14
|
*/
|
|
22
15
|
const renderWithTheme = (ui, options = {}) => {
|
|
23
16
|
const { brand = keboola, ...rest } = options;
|
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","names":[],"sources":["../src/testing/renderWithTheme.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { render, type RenderOptions, type RenderResult } from '@testing-library/react';\n\nimport {\n type Brand,\n keboola,\n keboolaLegacySidebar,\n keboolaLegacyTopnav,\n} from '@keboola/brand-registry';\n\nimport { ArgoDesignContext, ThemeProvider } from '../components/ThemeProvider';\n\nconst keboolaLegacyIds = [keboolaLegacySidebar.id, keboolaLegacyTopnav.id];\n\ntype Options = Omit<RenderOptions, 'wrapper'> & {\n /** Brand to drive the wrapping `<ThemeProvider>`. Defaults to `keboola`. */\n brand?: Brand;\n};\n\n/**\n * `@testing-library/react` `render` wrapped in a `<ThemeProvider brand={...}>`.\n *\n *
|
|
1
|
+
{"version":3,"file":"testing.js","names":[],"sources":["../src/testing/renderWithTheme.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { render, type RenderOptions, type RenderResult } from '@testing-library/react';\n\nimport {\n type Brand,\n keboola,\n keboolaLegacySidebar,\n keboolaLegacyTopnav,\n} from '@keboola/brand-registry';\n\nimport { ArgoDesignContext, ThemeProvider } from '../components/ThemeProvider';\n\nconst keboolaLegacyIds = [keboolaLegacySidebar.id, keboolaLegacyTopnav.id];\n\ntype Options = Omit<RenderOptions, 'wrapper'> & {\n /** Brand to drive the wrapping `<ThemeProvider>`. Defaults to `keboola`. */\n brand?: Brand;\n};\n\n/**\n * `@testing-library/react` `render` wrapped in a `<ThemeProvider brand={...}>`.\n *\n * - For components that call `useTheme()` or use the brand CSS variables.\n * - Also provides `ArgoDesignContext` from the brand, as kbc-ui does: a legacy brand gets\n * legacy chrome, any other argo.\n */\nexport const renderWithTheme = (ui: ReactElement, options: Options = {}): RenderResult => {\n const { brand = keboola, ...rest } = options;\n const isArgo = !keboolaLegacyIds.includes(brand.id);\n return render(ui, {\n ...rest,\n wrapper: ({ children }) => (\n <ThemeProvider brands={[brand]} brandId={brand.id}>\n <ArgoDesignContext value={isArgo}>{children}</ArgoDesignContext>\n </ThemeProvider>\n ),\n });\n};\n"],"mappings":";;;;;;AAYA,MAAM,mBAAmB,CAAC,qBAAqB,IAAI,oBAAoB,EAAE;;;;;;;;AAczE,MAAa,mBAAmB,IAAkB,UAAmB,CAAC,MAAoB;CACxF,MAAM,EAAE,QAAQ,SAAS,GAAG,SAAS;CACrC,MAAM,SAAS,CAAC,iBAAiB,SAAS,MAAM,EAAE;CAClD,OAAO,OAAO,IAAI;EAChB,GAAG;EACH,UAAU,EAAE,eACV,oBAAC,eAAD;GAAe,QAAQ,CAAC,KAAK;GAAG,SAAS,MAAM;GAC7C,UAAA,oBAAC,mBAAD;IAAmB,OAAO;IAAS;GAA4B,CAAA;EAClD,CAAA;CAEnB,CAAC;AACH"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/utils/themeTokens.ts
|
|
2
|
+
const format = (channels, alpha) => alpha === void 0 ? `rgb(${channels})` : `rgb(${channels} / ${alpha})`;
|
|
3
|
+
/**
|
|
4
|
+
* A semantic `--*` token as the `rgb(...)` the browser currently computes on `<html>`.
|
|
5
|
+
*
|
|
6
|
+
* - For consumers that need a concrete colour string, not a Tailwind class.
|
|
7
|
+
* - Falls back to `fallbackChannels` with no document or undefined token (tests load no CSS).
|
|
8
|
+
*/
|
|
9
|
+
const resolveToken = (token, fallbackChannels, alpha) => {
|
|
10
|
+
const channels = typeof document === "undefined" ? fallbackChannels : getComputedStyle(document.documentElement).getPropertyValue(`--${token}`).trim() || fallbackChannels;
|
|
11
|
+
return format(channels, alpha);
|
|
12
|
+
};
|
|
13
|
+
/** {@link createTokenResolver}, answering the raw `"R G B"` channels. */
|
|
14
|
+
const createChannelResolver = (from) => {
|
|
15
|
+
const element = from ?? (typeof document === "undefined" ? null : document.documentElement);
|
|
16
|
+
const computed = element === null ? null : getComputedStyle(element);
|
|
17
|
+
return (token, fallbackChannels) => computed?.getPropertyValue(`--${token}`).trim() || fallbackChannels;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* A {@link resolveToken} bound to one `getComputedStyle` snapshot, for building a whole palette.
|
|
21
|
+
*
|
|
22
|
+
* - Create one per palette build, never at module level — tokens change with scheme and brand.
|
|
23
|
+
*/
|
|
24
|
+
const createTokenResolver = (from) => {
|
|
25
|
+
const resolve = createChannelResolver(from);
|
|
26
|
+
return (token, fallbackChannels, alpha) => format(resolve(token, fallbackChannels), alpha);
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { createChannelResolver, createTokenResolver, resolveToken };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=themeTokens-7DEab0kp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themeTokens-7DEab0kp.js","names":[],"sources":["../src/utils/themeTokens.ts"],"sourcesContent":["const format = (channels: string, alpha?: number): string =>\n alpha === undefined ? `rgb(${channels})` : `rgb(${channels} / ${alpha})`;\n\n/**\n * A semantic `--*` token as the `rgb(...)` the browser currently computes on `<html>`.\n *\n * - For consumers that need a concrete colour string, not a Tailwind class.\n * - Falls back to `fallbackChannels` with no document or undefined token (tests load no CSS).\n */\nexport const resolveToken = (token: string, fallbackChannels: string, alpha?: number): string => {\n const channels =\n typeof document === 'undefined'\n ? fallbackChannels\n : getComputedStyle(document.documentElement).getPropertyValue(`--${token}`).trim() ||\n fallbackChannels;\n return format(channels, alpha);\n};\n\n/** {@link createTokenResolver}, answering the raw `\"R G B\"` channels. */\nexport const createChannelResolver = (from?: Element | null) => {\n // `from`: a node inside a `ThemeScope`, whose tokens differ from `<html>`'s.\n const element = from ?? (typeof document === 'undefined' ? null : document.documentElement);\n const computed = element === null ? null : getComputedStyle(element);\n\n return (token: string, fallbackChannels: string): string =>\n computed?.getPropertyValue(`--${token}`).trim() || fallbackChannels;\n};\n\n/**\n * A {@link resolveToken} bound to one `getComputedStyle` snapshot, for building a whole palette.\n *\n * - Create one per palette build, never at module level — tokens change with scheme and brand.\n */\nexport const createTokenResolver = (from?: Element | null) => {\n const resolve = createChannelResolver(from);\n\n return (token: string, fallbackChannels: string, alpha?: number): string =>\n format(resolve(token, fallbackChannels), alpha);\n};\n"],"mappings":";AAAA,MAAM,UAAU,UAAkB,UAChC,UAAU,KAAA,IAAY,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,MAAM;;;;;;;AAQxE,MAAa,gBAAgB,OAAe,kBAA0B,UAA2B;CAC/F,MAAM,WACJ,OAAO,aAAa,cAChB,mBACA,iBAAiB,SAAS,eAAe,CAAC,CAAC,iBAAiB,KAAK,OAAO,CAAC,CAAC,KAAK,KAC/E;CACN,OAAO,OAAO,UAAU,KAAK;AAC/B;;AAGA,MAAa,yBAAyB,SAA0B;CAE9D,MAAM,UAAU,SAAS,OAAO,aAAa,cAAc,OAAO,SAAS;CAC3E,MAAM,WAAW,YAAY,OAAO,OAAO,iBAAiB,OAAO;CAEnE,QAAQ,OAAe,qBACrB,UAAU,iBAAiB,KAAK,OAAO,CAAC,CAAC,KAAK,KAAK;AACvD;;;;;;AAOA,MAAa,uBAAuB,SAA0B;CAC5D,MAAM,UAAU,sBAAsB,IAAI;CAE1C,QAAQ,OAAe,kBAA0B,UAC/C,OAAO,QAAQ,OAAO,gBAAgB,GAAG,KAAK;AAClD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "./classNames-BzrkDnOD.js";
|
|
2
|
-
import { useArgoDesign } from "./context-
|
|
3
|
-
import { AlertCircle, AlertTriangle, CircleCheck, Info, Loader2, X } from "./icons-
|
|
2
|
+
import { useArgoDesign } from "./context-U293r3v-.js";
|
|
3
|
+
import { AlertCircle, AlertTriangle, CircleCheck, Info, Loader2, X } from "./icons-wcA70iQx.js";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { toast } from "sonner";
|
|
@@ -181,4 +181,4 @@ toast$1.dismissAll = () => toast.dismiss();
|
|
|
181
181
|
//#endregion
|
|
182
182
|
export { toast$1 as toast };
|
|
183
183
|
|
|
184
|
-
//# sourceMappingURL=toast-
|
|
184
|
+
//# sourceMappingURL=toast-CyXEdaCZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-CyXEdaCZ.js","names":["sonnerToast","toast","sonnerToast"],"sources":["../src/components/Toast/ToastAction.tsx","../src/components/Toast/ToastDescription.tsx","../src/components/Toast/ToastDismiss.tsx","../src/components/Toast/ToastDuration.tsx","../src/components/Toast/ToastTitle.tsx","../src/components/Toast/ToastRoot.tsx","../src/components/Toast/toast.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const ToastAction = ({ ref, className, ...rest }: Props) => (\n <button\n {...rest}\n ref={ref}\n data-slot=\"toast-action\"\n type=\"button\"\n className={cn(\n // layout\n 'tw:col-start-3',\n 'tw:row-start-1',\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n // font\n 'tw:text-xs',\n 'tw:font-medium',\n 'tw:text-primary',\n\n // sizing\n 'tw:px-2',\n 'tw:h-6',\n\n // styles\n // Fixed white, not a token: non-`default` toast fills ignore the color scheme too.\n 'tw:bg-white',\n 'tw:rounded',\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const ToastDescription = ({ ref, className, children, ...rest }: Props) => (\n <div\n ref={ref}\n data-slot=\"toast-description\"\n className={cn(\n 'tw:col-start-2',\n 'tw:font-normal',\n 'tw:break-words',\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:text-muted-foreground',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n);\n","import type { ComponentProps } from 'react';\n\nimport { X } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const ToastDismiss = ({ ref, className, ...rest }: Props) => (\n <button\n ref={ref}\n data-slot=\"toast-dismiss\"\n className={cn(\n 'tw:flex',\n 'tw:justify-center',\n 'tw:col-start-4',\n 'tw:row-start-1',\n 'tailwindcss-preflight',\n 'tw:[&_svg]:aspect-square',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4',\n 'tw:[&_svg]:m-1',\n\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:[&_svg]:text-popover-foreground',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:[&_svg]:text-foreground',\n className,\n )}\n type=\"button\"\n {...rest}\n >\n <X />\n <span className=\"tw:sr-only\">Dismiss</span>\n </button>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype ToastDurationProps = ComponentProps<'span'> & {\n duration: number;\n};\n\nexport const ToastDuration = ({ ref, duration, className, style, ...rest }: ToastDurationProps) => (\n <span\n {...rest}\n ref={ref}\n className={cn(\n 'tw:bg-white/30',\n 'tw:group-data-[variant=default]/toast:bg-popover-foreground/20',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:bg-foreground/20',\n 'tw:rounded-bl-lg',\n 'tw:mx-px',\n\n // positioning\n 'tw:absolute',\n 'tw:bottom-0',\n 'tw:left-0',\n\n // sizing\n 'tw:h-1',\n\n // animation\n 'tw:animate-toast-progress',\n 'tw:group-hover/toast:[animation-play-state:paused]',\n className,\n )}\n style={{\n animationDuration: `${duration}ms`,\n ...style,\n }}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const ToastTitle = ({ ref, className, children, ...rest }: Props) => (\n <div\n ref={ref}\n data-slot=\"toast-title\"\n className={cn(\n 'tw:col-start-2',\n 'tw:text-sm',\n 'tw:leading-6',\n 'tw:min-h-6',\n 'tw:self-center',\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:text-popover-foreground',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:text-foreground',\n\n 'tw:break-words',\n 'tw:font-medium',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n);\n","import type { MouseEventHandler, ReactNode } from 'react';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\nimport { type Action, toast as sonnerToast } from 'sonner';\n\nimport { AlertCircle, AlertTriangle, CircleCheck, Info, Loader2 } from '../../icons';\nimport { cn } from '../../utils';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nimport { ToastAction } from './ToastAction';\nimport { ToastDescription } from './ToastDescription';\nimport { ToastDismiss } from './ToastDismiss';\nimport { ToastDuration } from './ToastDuration';\nimport { ToastTitle } from './ToastTitle';\n\nconst variants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:group/toast',\n 'tw:relative',\n\n // layout\n 'tw:grid',\n 'tw:grid-cols-[0_1fr_auto_auto]',\n 'tw:items-start',\n 'tw:has-[[data-slot=toast-description]]:grid-rows-[auto_auto]',\n 'tw:has-[[data-slot=toast-icon]]:grid-cols-[auto_1fr_auto_auto]',\n 'tw:[&_[data-slot=toast-icon]]:mr-2',\n 'tw:[&_[data-slot=toast-title]]:mr-2.5',\n 'tw:[&_[data-slot=toast-description]]:mr-2.5',\n 'tw:[&_[data-slot=toast-action]]:mr-2',\n 'tw:[&_[data-slot=toast-description]]:col-end-3',\n 'tw:gap-y-0',\n\n // styles\n 'tw:p-4',\n 'tw:rounded-lg',\n 'tw:shadow-md',\n ],\n {\n defaultVariants: {\n variant: 'info',\n },\n variants: {\n variant: {\n default: 'tw:border tw:border-border tw:bg-popover',\n error: 'tw:bg-error-550',\n info: 'tw:bg-blue-600',\n success: 'tw:bg-green-700',\n warning: 'tw:bg-warning-550',\n },\n },\n },\n);\n\ntype Variants = VariantProps<typeof variants>;\ntype Variant = NonNullable<Variants['variant']>;\ntype VariantIcon = Exclude<Variant, 'default'>;\n\ntype Props = {\n id: string | number;\n title: ReactNode;\n icon?: ReactNode;\n description?: ReactNode;\n action?: Action;\n loading?: boolean;\n duration?: number;\n // offset?: number;\n} & Variants;\n\nconst DEFAULT_VARIANT_ICON: Record<VariantIcon, ReactNode> = {\n error: <AlertTriangle />,\n info: <Info />,\n success: <CircleCheck />,\n warning: <AlertCircle />,\n};\n\nexport const ToastRoot = ({\n id,\n title,\n description,\n action,\n duration = Infinity,\n variant = 'info',\n loading = false,\n icon: iconProp,\n}: Props) => {\n const renderArgo = useArgoDesign();\n\n const icon: ReactNode = (() => {\n if (loading) return <Loader2 className=\"tw:animate-spin\" />;\n if (iconProp) return iconProp;\n if (variant === 'default' || variant === null) return null;\n return DEFAULT_VARIANT_ICON[variant];\n })();\n\n const handleActionClick: MouseEventHandler<HTMLButtonElement> = (event) => {\n sonnerToast.dismiss(id);\n action?.onClick(event);\n };\n\n return (\n <div\n data-variant={variant}\n data-argo={renderArgo}\n className={cn(\n variants({ variant }),\n 'tw:data-[variant=default]:data-[argo=true]:bg-background',\n )}\n >\n {icon && (\n <span\n data-slot=\"toast-icon\"\n className={cn(\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:self-center',\n 'tw:aspect-square',\n 'tw:size-5',\n 'tw:shrink-0',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-5',\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:text-popover-foreground',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:text-foreground',\n )}\n >\n {icon}\n </span>\n )}\n\n <ToastTitle>{title}</ToastTitle>\n {description && <ToastDescription>{description}</ToastDescription>}\n {action && (\n <ToastAction style={action?.actionButtonStyle} onClick={handleActionClick}>\n {action.label}\n </ToastAction>\n )}\n <ToastDismiss onClick={() => sonnerToast.dismiss(id)} />\n {duration !== Infinity && <ToastDuration duration={duration} />}\n </div>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { type ExternalToast, toast as sonnerToast } from 'sonner';\n\nimport { cn } from '../../utils';\n\nimport { ToastRoot } from './ToastRoot';\n\ntype ToastProps = ComponentProps<typeof ToastRoot>;\ntype Title = ToastProps['title'] | ((opts: { dismiss: () => void }) => ReactNode);\n\nexport type ToastOptions = { id?: string | number; title: Title } & Omit<\n ToastProps,\n 'id' | 'title'\n> &\n Pick<\n ExternalToast,\n 'onAutoClose' | 'onDismiss' | 'testId' | 'toasterId' | 'dismissible' | 'position'\n >;\ntype DerivedToastOptions = Omit<ToastOptions, 'title' | 'variant'>;\n\nexport const toast = ({\n onAutoClose,\n onDismiss,\n testId,\n toasterId,\n dismissible = true,\n position,\n title: titleProp,\n ...toast\n}: ToastOptions) => {\n const duration = (() => {\n if (typeof toast.duration === 'number') return toast.duration;\n if (toast.variant === 'error' || toast.variant === 'warning') return Infinity;\n return toast.duration ?? 5000;\n })();\n\n const renderCustomToast: Parameters<typeof sonnerToast.custom>[0] = (id) => {\n const title =\n typeof titleProp === 'function'\n ? titleProp({ dismiss: () => sonnerToast.dismiss(id) })\n : titleProp;\n\n return <ToastRoot {...toast} id={id} title={title} duration={duration} />;\n };\n\n return sonnerToast.custom(renderCustomToast, {\n // toast generated by sonner will always have an id, but we want to allow users to specify their own id if they want to\n // can not pass undefined, as it will break dismiss\n ...(toast.id != null ? { id: toast.id } : {}),\n unstyled: true,\n position,\n onAutoClose,\n onDismiss,\n testId,\n toasterId,\n dismissible,\n duration,\n // override default focus-visible styles to match our design\n className: cn('tw:rounded-lg', 'tw:focus-visible:!ring-4', 'tw:focus-visible:!ring-ring/50'),\n });\n};\n\ntoast.success = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'success',\n });\n\ntoast.error = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'error',\n duration: options?.duration ?? Infinity,\n });\n\ntoast.warning = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'warning',\n duration: options?.duration ?? Infinity,\n });\n\ntoast.info = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'info',\n });\n\ntoast.dismiss = (toastId?: ToastOptions['id']) => sonnerToast.dismiss(toastId);\ntoast.dismissAll = () => sonnerToast.dismiss();\n"],"mappings":";;;;;;;AAMA,MAAa,eAAe,EAAE,KAAK,WAAW,GAAG,WAC/C,oBAAC,UAAD;CACE,GAAI;CACC;CACL,aAAU;CACV,MAAK;CACL,WAAW,GAET,kBACA,kBACA,WACA,mBACA,qBAGA,cACA,kBACA,mBAGA,WACA,UAIA,eACA,cACA,SACF;AACD,CAAA;;;AC7BH,MAAa,oBAAoB,EAAE,KAAK,WAAW,UAAU,GAAG,WAC9D,oBAAC,OAAD;CACO;CACL,aAAU;CACV,WAAW,GACT,kBACA,kBACA,kBACA,iBACA,+DACA,SACF;CACA,GAAI;CAEH;AACE,CAAA;;;ACdP,MAAa,gBAAgB,EAAE,KAAK,WAAW,GAAG,WAChD,qBAAC,UAAD;CACO;CACL,aAAU;CACV,WAAW,GACT,WACA,qBACA,kBACA,kBACA,yBACA,4BACA,gDACA,kBAEA,iBACA,yEACA,8FACA,SACF;CACA,MAAK;CACL,GAAI;CAnBN,UAAA,CAqBE,oBAAC,GAAD,CAAI,CAAA,GACJ,oBAAC,QAAD;EAAM,WAAU;EAAa,UAAA;CAAa,CAAA,CACpC;;;;ACvBV,MAAa,iBAAiB,EAAE,KAAK,UAAU,WAAW,OAAO,GAAG,WAClE,oBAAC,QAAD;CACE,GAAI;CACC;CACL,WAAW,GACT,kBACA,kEACA,uFACA,oBACA,YAGA,eACA,eACA,aAGA,UAGA,6BACA,sDACA,SACF;CACA,OAAO;EACL,mBAAmB,GAAG,SAAS;EAC/B,GAAG;CACL;AACD,CAAA;;;AC9BH,MAAa,cAAc,EAAE,KAAK,WAAW,UAAU,GAAG,WACxD,oBAAC,OAAD;CACO;CACL,aAAU;CACV,WAAW,GACT,kBACA,cACA,gBACA,cACA,kBACA,iBACA,iEACA,sFAEA,kBACA,kBACA,SACF;CACA,GAAI;CAEH;AACE,CAAA;;;ACZP,MAAM,WAAW,IACf;CACE;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;AACF,GACA;CACE,iBAAiB,EACf,SAAS,OACX;CACA,UAAU,EACR,SAAS;EACP,SAAS;EACT,OAAO;EACP,MAAM;EACN,SAAS;EACT,SAAS;CACX,EACF;AACF,CACF;AAiBA,MAAM,uBAAuD;CAC3D,OAAO,oBAAC,eAAD,CAAgB,CAAA;CACvB,MAAM,oBAAC,MAAD,CAAO,CAAA;CACb,SAAS,oBAAC,aAAD,CAAc,CAAA;CACvB,SAAS,oBAAC,aAAD,CAAc,CAAA;AACzB;AAEA,MAAa,aAAa,EACxB,IACA,OACA,aACA,QACA,WAAW,UACX,UAAU,QACV,UAAU,OACV,MAAM,eACK;CACX,MAAM,aAAa,cAAc;CAEjC,MAAM,cAAyB;EAC7B,IAAI,SAAS,OAAO,oBAAC,SAAD,EAAS,WAAU,kBAAmB,CAAA;EAC1D,IAAI,UAAU,OAAO;EACrB,IAAI,YAAY,aAAa,YAAY,MAAM,OAAO;EACtD,OAAO,qBAAqB;CAC9B,EAAA,CAAG;CAEH,MAAM,qBAA2D,UAAU;EACzE,MAAY,QAAQ,EAAE;EACtB,QAAQ,QAAQ,KAAK;CACvB;CAEA,OACE,qBAAC,OAAD;EACE,gBAAc;EACd,aAAW;EACX,WAAW,GACT,SAAS,EAAE,QAAQ,CAAC,GACpB,0DACF;EANF,UAAA;GAQG,QACC,oBAAC,QAAD;IACE,aAAU;IACV,WAAW,GACT,kBACA,mBACA,qBACA,kBACA,oBACA,aACA,eACA,gDACA,iBACA,iEACA,oFACF;IAEC,UAAA;GACG,CAAA;GAGR,oBAAC,YAAD,EAAA,UAAa,MAAkB,CAAA;GAC9B,eAAe,oBAAC,kBAAD,EAAA,UAAmB,YAA8B,CAAA;GAChE,UACC,oBAAC,aAAD;IAAa,OAAO,QAAQ;IAAmB,SAAS;IACrD,UAAA,OAAO;GACG,CAAA;GAEf,oBAAC,cAAD,EAAc,eAAeA,MAAY,QAAQ,EAAE,EAAI,CAAA;GACtD,aAAa,YAAY,oBAAC,eAAD,EAAyB,SAAW,CAAA;EAC3D;;AAET;;;AC1HA,MAAaC,WAAS,EACpB,aACA,WACA,QACA,WACA,cAAc,MACd,UACA,OAAO,WACP,GAAGA,cACe;CAClB,MAAM,kBAAkB;EACtB,IAAI,OAAOA,QAAM,aAAa,UAAU,OAAOA,QAAM;EACrD,IAAIA,QAAM,YAAY,WAAWA,QAAM,YAAY,WAAW,OAAO;EACrE,OAAOA,QAAM,YAAY;CAC3B,EAAA,CAAG;CAEH,MAAM,qBAA+D,OAAO;EAC1E,MAAM,QACJ,OAAO,cAAc,aACjB,UAAU,EAAE,eAAeC,MAAY,QAAQ,EAAE,EAAE,CAAC,IACpD;EAEN,OAAO,oBAAC,WAAD;GAAW,GAAID;GAAW;GAAW;GAAiB;EAAW,CAAA;CAC1E;CAEA,OAAOC,MAAY,OAAO,mBAAmB;EAG3C,GAAID,QAAM,MAAM,OAAO,EAAE,IAAIA,QAAM,GAAG,IAAI,CAAC;EAC3C,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,WAAW,GAAG,iBAAiB,4BAA4B,gCAAgC;CAC7F,CAAC;AACH;AAEA,QAAM,WAAW,OAAc,YAC7BA,QAAM;CACJ,GAAG;CACH;CACA,SAAS;AACX,CAAC;AAEH,QAAM,SAAS,OAAc,YAC3BA,QAAM;CACJ,GAAG;CACH;CACA,SAAS;CACT,UAAU,SAAS,YAAY;AACjC,CAAC;AAEH,QAAM,WAAW,OAAc,YAC7BA,QAAM;CACJ,GAAG;CACH;CACA,SAAS;CACT,UAAU,SAAS,YAAY;AACjC,CAAC;AAEH,QAAM,QAAQ,OAAc,YAC1BA,QAAM;CACJ,GAAG;CACH;CACA,SAAS;AACX,CAAC;AAEH,QAAM,WAAW,YAAiCC,MAAY,QAAQ,OAAO;AAC7E,QAAM,mBAAmBA,MAAY,QAAQ"}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { DEFAULT_BRAND_ID, DEFAULT_COLOR_SCHEME } from "./defaults-i_xG2F_1.js";
|
|
2
2
|
import { createContext, useCallback, useEffect, useState } from "react";
|
|
3
|
+
//#region src/components/ThemeProvider/themeScopeContext.ts
|
|
4
|
+
/**
|
|
5
|
+
* What a `ThemeScope` publishes about itself, in its own module so a hook can read it without
|
|
6
|
+
* importing the component that provides it.
|
|
7
|
+
*
|
|
8
|
+
* - `scheme`: the scheme this subtree is pinned to, or `null` outside a scope.
|
|
9
|
+
* - `container`: a body-level node carrying the scope's `data-theme` and token vars. A canvas
|
|
10
|
+
* (chart, diagram) that resolves live `--*` values reads them off this rather than `<html>`,
|
|
11
|
+
* which is still painting the page's scheme.
|
|
12
|
+
*/
|
|
13
|
+
const ThemeScopeSchemeContext = createContext(null);
|
|
14
|
+
const ThemeScopeContainerContext = createContext(null);
|
|
15
|
+
//#endregion
|
|
3
16
|
//#region src/components/ThemeProvider/useBrandState.ts
|
|
4
17
|
const BRAND_ATTRIBUTE = "data-brand";
|
|
5
18
|
const useBrandState = ({ defaultBrandId: defaultBrand = DEFAULT_BRAND_ID, brandId: controlledBrand, onBrandIdChange: onBrandChange } = {}) => {
|
|
@@ -56,19 +69,6 @@ const useColorSchemeState = ({ defaultScheme = DEFAULT_COLOR_SCHEME, scheme: pro
|
|
|
56
69
|
};
|
|
57
70
|
};
|
|
58
71
|
//#endregion
|
|
59
|
-
//#region src/components/ThemeProvider/themeScopeContext.ts
|
|
60
|
-
/**
|
|
61
|
-
* What a `ThemeScope` publishes about itself, in its own module so a hook can read it without
|
|
62
|
-
* importing the component that provides it.
|
|
63
|
-
*
|
|
64
|
-
* - `scheme`: the scheme this subtree is pinned to, or `null` outside a scope.
|
|
65
|
-
* - `container`: a body-level node carrying the scope's `data-theme` and token vars. A canvas
|
|
66
|
-
* (chart, diagram) that resolves live `--*` values reads them off this rather than `<html>`,
|
|
67
|
-
* which is still painting the page's scheme.
|
|
68
|
-
*/
|
|
69
|
-
const ThemeScopeSchemeContext = createContext(null);
|
|
70
|
-
const ThemeScopeContainerContext = createContext(null);
|
|
71
|
-
//#endregion
|
|
72
72
|
export { BRAND_ATTRIBUTE, THEME_ATTRIBUTE, ThemeScopeContainerContext, ThemeScopeSchemeContext, useBrandState, useColorSchemeState };
|
|
73
73
|
|
|
74
|
-
//# sourceMappingURL=
|
|
74
|
+
//# sourceMappingURL=useColorSchemeState-Cw4MCXUs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useColorSchemeState-Cw4MCXUs.js","names":[],"sources":["../src/components/ThemeProvider/themeScopeContext.ts","../src/components/ThemeProvider/useBrandState.ts","../src/components/ThemeProvider/useColorSchemeState.ts"],"sourcesContent":["import { createContext } from 'react';\n\nimport type { ResolvedColorScheme } from './types';\n\n/**\n * What a `ThemeScope` publishes about itself, in its own module so a hook can read it without\n * importing the component that provides it.\n *\n * - `scheme`: the scheme this subtree is pinned to, or `null` outside a scope.\n * - `container`: a body-level node carrying the scope's `data-theme` and token vars. A canvas\n * (chart, diagram) that resolves live `--*` values reads them off this rather than `<html>`,\n * which is still painting the page's scheme.\n */\nexport const ThemeScopeSchemeContext = createContext<ResolvedColorScheme | null>(null);\nexport const ThemeScopeContainerContext = createContext<HTMLElement | null>(null);\n","import { useCallback, useEffect, useState } from 'react';\n\nimport { DEFAULT_BRAND_ID } from './defaults';\nimport type { BrandId } from './types';\n\nexport const BRAND_ATTRIBUTE = 'data-brand';\n\nexport type UseBrandOptions = {\n /** Initial active brand id for uncontrolled use. Defaults to the design-system sentinel (`DEFAULT_BRAND_ID`) — no brand tokens injected, so the stylesheet defaults apply. */\n defaultBrandId?: BrandId;\n /** Controlled active brand id. When set, the parent owns the value and `setBrand` only notifies via `onBrandIdChange` (it does not mutate internal state). */\n brandId?: BrandId;\n /** Called with the next id whenever `setBrand` runs — required to persist the choice in controlled mode. */\n onBrandIdChange?: (brandId: BrandId) => void;\n};\n\nexport const useBrandState = ({\n defaultBrandId: defaultBrand = DEFAULT_BRAND_ID,\n brandId: controlledBrand,\n onBrandIdChange: onBrandChange,\n}: UseBrandOptions = {}) => {\n const [uncontrolledBrand, setUncontrolledBrand] = useState(defaultBrand);\n\n const isControlled = controlledBrand !== undefined;\n const brandId = isControlled ? controlledBrand : uncontrolledBrand;\n\n const setBrand = useCallback(\n (next: BrandId) => {\n if (!isControlled) setUncontrolledBrand(next);\n onBrandChange?.(next);\n },\n [isControlled, onBrandChange],\n );\n\n useEffect(() => {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(BRAND_ATTRIBUTE, brandId);\n }, [brandId]);\n\n return { brandId, setBrand };\n};\n","import { useCallback, useEffect, useState } from 'react';\n\nimport { DEFAULT_COLOR_SCHEME } from './defaults';\nimport type { ColorScheme, ResolvedColorScheme } from './types';\n\nconst DARK_QUERY = '(prefers-color-scheme: dark)';\nexport const THEME_ATTRIBUTE = 'data-theme';\n\nconst getSystemColorScheme = (): ResolvedColorScheme => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return 'light';\n return window.matchMedia(DARK_QUERY).matches ? 'dark' : 'light';\n};\n\nexport type UseColorSchemeOptions = {\n /** Initial scheme when uncontrolled; defaults to `light`. */\n defaultScheme?: ColorScheme;\n /**\n * Controlled scheme; `setScheme` then only calls `onSchemeChange`.\n * `system` follows `prefers-color-scheme` live.\n */\n scheme?: ColorScheme;\n /** Required to persist the choice in controlled mode. */\n onSchemeChange?: (theme: ColorScheme) => void;\n};\n\nexport const useColorSchemeState = ({\n defaultScheme = DEFAULT_COLOR_SCHEME,\n scheme: propScheme,\n onSchemeChange,\n}: UseColorSchemeOptions = {}) => {\n const [uncontrolledScheme, setUncontrolledScheme] = useState(defaultScheme);\n const [systemScheme, setSystemScheme] = useState<ResolvedColorScheme>(getSystemColorScheme);\n\n const isControlled = propScheme !== undefined;\n const scheme = isControlled ? propScheme : uncontrolledScheme;\n\n const setScheme = useCallback(\n (next: ColorScheme) => {\n if (!isControlled) setUncontrolledScheme(next);\n onSchemeChange?.(next);\n },\n [isControlled, onSchemeChange],\n );\n\n // Keeps `system` live as the OS preference flips.\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n const mq = window.matchMedia(DARK_QUERY);\n const onChange = () => setSystemScheme(mq.matches ? 'dark' : 'light');\n onChange();\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n\n const resolvedScheme: ResolvedColorScheme = scheme === 'system' ? systemScheme : scheme;\n\n useEffect(() => {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(THEME_ATTRIBUTE, resolvedScheme);\n }, [resolvedScheme]);\n\n return { scheme, resolvedScheme, setScheme };\n};\n"],"mappings":";;;;;;;;;;;;AAaA,MAAa,0BAA0B,cAA0C,IAAI;AACrF,MAAa,6BAA6B,cAAkC,IAAI;;;ACThF,MAAa,kBAAkB;AAW/B,MAAa,iBAAiB,EAC5B,gBAAgB,eAAe,kBAC/B,SAAS,iBACT,iBAAiB,kBACE,CAAC,MAAM;CAC1B,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,YAAY;CAEvE,MAAM,eAAe,oBAAoB,KAAA;CACzC,MAAM,UAAU,eAAe,kBAAkB;CAEjD,MAAM,WAAW,aACd,SAAkB;EACjB,IAAI,CAAC,cAAc,qBAAqB,IAAI;EAC5C,gBAAgB,IAAI;CACtB,GACA,CAAC,cAAc,aAAa,CAC9B;CAEA,gBAAgB;EACd,IAAI,OAAO,aAAa,aAAa;EACrC,SAAS,gBAAgB,aAAa,iBAAiB,OAAO;CAChE,GAAG,CAAC,OAAO,CAAC;CAEZ,OAAO;EAAE;EAAS;CAAS;AAC7B;;;ACnCA,MAAM,aAAa;AACnB,MAAa,kBAAkB;AAE/B,MAAM,6BAAkD;CACtD,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY,OAAO;CACrF,OAAO,OAAO,WAAW,UAAU,CAAC,CAAC,UAAU,SAAS;AAC1D;AAcA,MAAa,uBAAuB,EAClC,gBAAgB,sBAChB,QAAQ,YACR,mBACyB,CAAC,MAAM;CAChC,MAAM,CAAC,oBAAoB,yBAAyB,SAAS,aAAa;CAC1E,MAAM,CAAC,cAAc,mBAAmB,SAA8B,oBAAoB;CAE1F,MAAM,eAAe,eAAe,KAAA;CACpC,MAAM,SAAS,eAAe,aAAa;CAE3C,MAAM,YAAY,aACf,SAAsB;EACrB,IAAI,CAAC,cAAc,sBAAsB,IAAI;EAC7C,iBAAiB,IAAI;CACvB,GACA,CAAC,cAAc,cAAc,CAC/B;CAGA,gBAAgB;EACd,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;EAC9E,MAAM,KAAK,OAAO,WAAW,UAAU;EACvC,MAAM,iBAAiB,gBAAgB,GAAG,UAAU,SAAS,OAAO;EACpE,SAAS;EACT,GAAG,iBAAiB,UAAU,QAAQ;EACtC,aAAa,GAAG,oBAAoB,UAAU,QAAQ;CACxD,GAAG,CAAC,CAAC;CAEL,MAAM,iBAAsC,WAAW,WAAW,eAAe;CAEjF,gBAAgB;EACd,IAAI,OAAO,aAAa,aAAa;EACrC,SAAS,gBAAgB,aAAa,iBAAiB,cAAc;CACvE,GAAG,CAAC,cAAc,CAAC;CAEnB,OAAO;EAAE;EAAQ;EAAgB;CAAU;AAC7C"}
|
|
@@ -3,12 +3,8 @@ import { useCallback, useRef, useState } from "react";
|
|
|
3
3
|
/**
|
|
4
4
|
* Controlled/uncontrolled state, à la Radix's `useControllableState`.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* owns state — `setValue` resolves the next value and calls `onChange`; the parent is
|
|
9
|
-
* responsible for feeding the new `prop` back. In uncontrolled mode the hook owns the value
|
|
10
|
-
* in internal state and still calls `onChange`. `onChange` fires on every `setValue` call
|
|
11
|
-
* (it is not deduped against the previous value).
|
|
6
|
+
* - Controlled: never owns state; the parent must feed the new `prop` back.
|
|
7
|
+
* - `onChange` fires on every `setValue`, not deduped.
|
|
12
8
|
*/
|
|
13
9
|
const useControllableState = ({ prop, defaultProp, onChange }) => {
|
|
14
10
|
const [uncontrolled, setUncontrolled] = useState(defaultProp);
|
|
@@ -28,4 +24,4 @@ const useControllableState = ({ prop, defaultProp, onChange }) => {
|
|
|
28
24
|
//#endregion
|
|
29
25
|
export { useControllableState };
|
|
30
26
|
|
|
31
|
-
//# sourceMappingURL=useControllableState-
|
|
27
|
+
//# sourceMappingURL=useControllableState-CUYXMsfz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useControllableState-CUYXMsfz.js","names":[],"sources":["../src/hooks/useControllableState.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\ntype UseControllableStateParams<T> = {\n /** When defined, the hook is controlled. */\n prop: T | undefined;\n defaultProp: T;\n /** Called on every `setValue`, in both modes. */\n onChange?: (value: T) => void;\n};\n\n/**\n * Controlled/uncontrolled state, à la Radix's `useControllableState`.\n *\n * - Controlled: never owns state; the parent must feed the new `prop` back.\n * - `onChange` fires on every `setValue`, not deduped.\n */\nexport const useControllableState = <T>({\n prop,\n defaultProp,\n onChange,\n}: UseControllableStateParams<T>): readonly [T, Dispatch<SetStateAction<T>>] => {\n const [uncontrolled, setUncontrolled] = useState<T>(defaultProp);\n const isControlled = prop !== undefined;\n // Inline check (not `isControlled`) so TypeScript narrows `prop`.\n const value = prop !== undefined ? prop : uncontrolled;\n\n // Refs keep `setValue`'s identity stable.\n const valueRef = useRef(value);\n valueRef.current = value;\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const setValue = useCallback<Dispatch<SetStateAction<T>>>(\n (next) => {\n const nextValue =\n typeof next === 'function' ? (next as (prev: T) => T)(valueRef.current) : next;\n // Advance now so several updaters in one tick compose.\n valueRef.current = nextValue;\n if (!isControlled) setUncontrolled(nextValue);\n onChangeRef.current?.(nextValue);\n },\n [isControlled],\n );\n\n return [value, setValue] as const;\n};\n"],"mappings":";;;;;;;;AAiBA,MAAa,wBAA2B,EACtC,MACA,aACA,eAC8E;CAC9E,MAAM,CAAC,cAAc,mBAAmB,SAAY,WAAW;CAC/D,MAAM,eAAe,SAAS,KAAA;CAE9B,MAAM,QAAQ,SAAS,KAAA,IAAY,OAAO;CAG1C,MAAM,WAAW,OAAO,KAAK;CAC7B,SAAS,UAAU;CACnB,MAAM,cAAc,OAAO,QAAQ;CACnC,YAAY,UAAU;CActB,OAAO,CAAC,OAZS,aACd,SAAS;EACR,MAAM,YACJ,OAAO,SAAS,aAAc,KAAwB,SAAS,OAAO,IAAI;EAE5E,SAAS,UAAU;EACnB,IAAI,CAAC,cAAc,gBAAgB,SAAS;EAC5C,YAAY,UAAU,SAAS;CACjC,GACA,CAAC,YAAY,CAGO,CAAC;AACzB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
//#region src/hooks/useElement.ts
|
|
3
|
+
/**
|
|
4
|
+
* A callback ref that reports the element it is attached to.
|
|
5
|
+
*
|
|
6
|
+
* - Detachment runs through the ref's cleanup, not a `null` call.
|
|
7
|
+
* - A branch swap never exposes `null` between the outgoing and incoming node.
|
|
8
|
+
* - A branch with no ref still releases the old node, so its listeners don't leak.
|
|
9
|
+
*/
|
|
10
|
+
const useElement = () => {
|
|
11
|
+
const [element, setElement] = useState(null);
|
|
12
|
+
return [element, useCallback((node) => {
|
|
13
|
+
if (node === null) return;
|
|
14
|
+
setElement(node);
|
|
15
|
+
return () => setElement((prev) => prev === node ? null : prev);
|
|
16
|
+
}, [])];
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { useElement };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=useElement-D-RjrGa4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useElement-D-RjrGa4.js","names":[],"sources":["../src/hooks/useElement.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\n\n/**\n * A callback ref that reports the element it is attached to.\n *\n * - Detachment runs through the ref's cleanup, not a `null` call.\n * - A branch swap never exposes `null` between the outgoing and incoming node.\n * - A branch with no ref still releases the old node, so its listeners don't leak.\n */\nexport const useElement = () => {\n const [element, setElement] = useState<HTMLElement | null>(null);\n\n const ref = useCallback((node: HTMLElement | null) => {\n // Ignore the legacy `null` call — it would drop the node a swap already registered.\n if (node === null) return;\n\n setElement(node);\n\n return () => setElement((prev) => (prev === node ? null : prev));\n }, []);\n\n return [element, ref] as const;\n};\n"],"mappings":";;;;;;;;;AASA,MAAa,mBAAmB;CAC9B,MAAM,CAAC,SAAS,cAAc,SAA6B,IAAI;CAW/D,OAAO,CAAC,SATI,aAAa,SAA6B;EAEpD,IAAI,SAAS,MAAM;EAEnB,WAAW,IAAI;EAEf,aAAa,YAAY,SAAU,SAAS,OAAO,OAAO,IAAK;CACjE,GAAG,CAAC,CAEe,CAAC;AACtB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DEFAULT_BRAND_ID, DEFAULT_COLOR_SCHEME } from "./defaults-i_xG2F_1.js";
|
|
2
|
+
import { BRAND_ATTRIBUTE, THEME_ATTRIBUTE, ThemeScopeContainerContext, ThemeScopeSchemeContext } from "./useColorSchemeState-Cw4MCXUs.js";
|
|
3
|
+
import { use, useMemo, useSyncExternalStore } from "react";
|
|
4
|
+
//#region src/components/ThemeProvider/useThemeAttributes.ts
|
|
5
|
+
const DEFAULT_ATTRIBUTES = {
|
|
6
|
+
cacheKey: `${DEFAULT_COLOR_SCHEME}:${DEFAULT_BRAND_ID}`,
|
|
7
|
+
scheme: DEFAULT_COLOR_SCHEME,
|
|
8
|
+
brandId: DEFAULT_BRAND_ID,
|
|
9
|
+
scope: null
|
|
10
|
+
};
|
|
11
|
+
let snapshot = DEFAULT_ATTRIBUTES;
|
|
12
|
+
const readThemeAttributes = () => {
|
|
13
|
+
if (typeof document === "undefined") return DEFAULT_ATTRIBUTES;
|
|
14
|
+
const root = document.documentElement;
|
|
15
|
+
const theme = root.getAttribute(THEME_ATTRIBUTE);
|
|
16
|
+
const scheme = theme === "dark" || theme === "light" ? theme : DEFAULT_COLOR_SCHEME;
|
|
17
|
+
const brandId = root.getAttribute("data-brand") ?? "design-system";
|
|
18
|
+
const cacheKey = `${scheme}:${brandId}`;
|
|
19
|
+
if (cacheKey !== snapshot.cacheKey) snapshot = {
|
|
20
|
+
cacheKey,
|
|
21
|
+
scheme,
|
|
22
|
+
brandId,
|
|
23
|
+
scope: null
|
|
24
|
+
};
|
|
25
|
+
return snapshot;
|
|
26
|
+
};
|
|
27
|
+
const subscribe = (onChange) => {
|
|
28
|
+
if (typeof document === "undefined") return () => {};
|
|
29
|
+
const observer = new MutationObserver(onChange);
|
|
30
|
+
observer.observe(document.documentElement, {
|
|
31
|
+
attributes: true,
|
|
32
|
+
attributeFilter: [THEME_ATTRIBUTE, BRAND_ATTRIBUTE]
|
|
33
|
+
});
|
|
34
|
+
return () => observer.disconnect();
|
|
35
|
+
};
|
|
36
|
+
const getServerSnapshot = () => DEFAULT_ATTRIBUTES;
|
|
37
|
+
/**
|
|
38
|
+
* Colour scheme and brand applied to `<html>`, plus a key for memoizing `resolveToken` output.
|
|
39
|
+
*
|
|
40
|
+
* - Read from the DOM, not `useTheme()`: `ThemeProvider` sets the attributes in passive effects,
|
|
41
|
+
* so context flips a render before the computed `--*` values do.
|
|
42
|
+
* - Key and scheme come from one read, so they cannot disagree.
|
|
43
|
+
* - Inside a `ThemeScope` its scheme wins; it commits attribute and vars with the subtree.
|
|
44
|
+
*/
|
|
45
|
+
const useThemeAttributes = () => {
|
|
46
|
+
const root = useSyncExternalStore(subscribe, readThemeAttributes, getServerSnapshot);
|
|
47
|
+
const scopedScheme = use(ThemeScopeSchemeContext);
|
|
48
|
+
const scope = use(ThemeScopeContainerContext);
|
|
49
|
+
return useMemo(() => {
|
|
50
|
+
if (scopedScheme === null && scope === null) return root;
|
|
51
|
+
const scheme = scopedScheme ?? root.scheme;
|
|
52
|
+
return {
|
|
53
|
+
scheme,
|
|
54
|
+
brandId: root.brandId,
|
|
55
|
+
scope,
|
|
56
|
+
cacheKey: `${scheme}:${root.brandId}${scope === null ? "" : ":scoped"}`
|
|
57
|
+
};
|
|
58
|
+
}, [
|
|
59
|
+
scopedScheme,
|
|
60
|
+
scope,
|
|
61
|
+
root
|
|
62
|
+
]);
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
export { useThemeAttributes };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=useThemeAttributes-B199Regy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useThemeAttributes-B199Regy.js","names":[],"sources":["../src/components/ThemeProvider/useThemeAttributes.ts"],"sourcesContent":["import { use, useMemo, useSyncExternalStore } from 'react';\n\nimport { DEFAULT_BRAND_ID, DEFAULT_COLOR_SCHEME } from './defaults';\nimport { ThemeScopeContainerContext, ThemeScopeSchemeContext } from './themeScopeContext';\nimport type { BrandId, ResolvedColorScheme } from './types';\nimport { BRAND_ATTRIBUTE } from './useBrandState';\nimport { THEME_ATTRIBUTE } from './useColorSchemeState';\n\nexport type ThemeAttributes = {\n /** Memo key for anything built from live `--*` values. */\n cacheKey: string;\n scheme: ResolvedColorScheme;\n brandId: BrandId;\n /**\n * Element to read live `--*` values off (`null` = `<html>`). Set by a `ThemeScope`\n * one commit after it mounts, hence part of `cacheKey`.\n */\n scope: HTMLElement | null;\n};\n\n// No attribute means the stylesheet's `:root` paints the default scheme.\n// Same on the server, so SSR and the first client render agree.\nconst DEFAULT_ATTRIBUTES: ThemeAttributes = {\n cacheKey: `${DEFAULT_COLOR_SCHEME}:${DEFAULT_BRAND_ID}`,\n scheme: DEFAULT_COLOR_SCHEME,\n brandId: DEFAULT_BRAND_ID,\n scope: null,\n};\n\n// `useSyncExternalStore` loops on a new reference per read; rebuild only when the key moves.\nlet snapshot = DEFAULT_ATTRIBUTES;\n\nconst readThemeAttributes = (): ThemeAttributes => {\n if (typeof document === 'undefined') return DEFAULT_ATTRIBUTES;\n\n const root = document.documentElement;\n const theme = root.getAttribute(THEME_ATTRIBUTE);\n const scheme: ResolvedColorScheme =\n theme === 'dark' || theme === 'light' ? theme : DEFAULT_COLOR_SCHEME;\n const brandId = root.getAttribute(BRAND_ATTRIBUTE) ?? DEFAULT_BRAND_ID;\n const cacheKey = `${scheme}:${brandId}`;\n\n if (cacheKey !== snapshot.cacheKey) snapshot = { cacheKey, scheme, brandId, scope: null };\n\n return snapshot;\n};\n\nconst subscribe = (onChange: () => void): (() => void) => {\n if (typeof document === 'undefined') return () => {};\n\n const observer = new MutationObserver(onChange);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [THEME_ATTRIBUTE, BRAND_ATTRIBUTE],\n });\n\n return () => observer.disconnect();\n};\n\nconst getServerSnapshot = (): ThemeAttributes => DEFAULT_ATTRIBUTES;\n\n/**\n * Colour scheme and brand applied to `<html>`, plus a key for memoizing `resolveToken` output.\n *\n * - Read from the DOM, not `useTheme()`: `ThemeProvider` sets the attributes in passive effects,\n * so context flips a render before the computed `--*` values do.\n * - Key and scheme come from one read, so they cannot disagree.\n * - Inside a `ThemeScope` its scheme wins; it commits attribute and vars with the subtree.\n */\nexport const useThemeAttributes = (): ThemeAttributes => {\n const root = useSyncExternalStore(subscribe, readThemeAttributes, getServerSnapshot);\n const scopedScheme = use(ThemeScopeSchemeContext);\n const scope = use(ThemeScopeContainerContext);\n\n // The reference is a memo key for callers, so it may only move when the values do.\n return useMemo(() => {\n if (scopedScheme === null && scope === null) return root;\n\n const scheme = scopedScheme ?? root.scheme;\n return {\n scheme,\n brandId: root.brandId,\n scope,\n cacheKey: `${scheme}:${root.brandId}${scope === null ? '' : ':scoped'}`,\n };\n }, [scopedScheme, scope, root]);\n};\n"],"mappings":";;;;AAsBA,MAAM,qBAAsC;CAC1C,UAAU,GAAG,qBAAqB,GAAG;CACrC,QAAQ;CACR,SAAS;CACT,OAAO;AACT;AAGA,IAAI,WAAW;AAEf,MAAM,4BAA6C;CACjD,IAAI,OAAO,aAAa,aAAa,OAAO;CAE5C,MAAM,OAAO,SAAS;CACtB,MAAM,QAAQ,KAAK,aAAa,eAAe;CAC/C,MAAM,SACJ,UAAU,UAAU,UAAU,UAAU,QAAQ;CAClD,MAAM,UAAU,KAAK,aAAA,YAA4B,KAAA;CACjD,MAAM,WAAW,GAAG,OAAO,GAAG;CAE9B,IAAI,aAAa,SAAS,UAAU,WAAW;EAAE;EAAU;EAAQ;EAAS,OAAO;CAAK;CAExF,OAAO;AACT;AAEA,MAAM,aAAa,aAAuC;CACxD,IAAI,OAAO,aAAa,aAAa,aAAa,CAAC;CAEnD,MAAM,WAAW,IAAI,iBAAiB,QAAQ;CAC9C,SAAS,QAAQ,SAAS,iBAAiB;EACzC,YAAY;EACZ,iBAAiB,CAAC,iBAAiB,eAAe;CACpD,CAAC;CAED,aAAa,SAAS,WAAW;AACnC;AAEA,MAAM,0BAA2C;;;;;;;;;AAUjD,MAAa,2BAA4C;CACvD,MAAM,OAAO,qBAAqB,WAAW,qBAAqB,iBAAiB;CACnF,MAAM,eAAe,IAAI,uBAAuB;CAChD,MAAM,QAAQ,IAAI,0BAA0B;CAG5C,OAAO,cAAc;EACnB,IAAI,iBAAiB,QAAQ,UAAU,MAAM,OAAO;EAEpD,MAAM,SAAS,gBAAgB,KAAK;EACpC,OAAO;GACL;GACA,SAAS,KAAK;GACd;GACA,UAAU,GAAG,OAAO,GAAG,KAAK,UAAU,UAAU,OAAO,KAAK;EAC9D;CACF,GAAG;EAAC;EAAc;EAAO;CAAI,CAAC;AAChC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cn } from "./classNames-BzrkDnOD.js";
|
|
2
|
-
import { useArgoDesign } from "./context-
|
|
2
|
+
import { useArgoDesign } from "./context-U293r3v-.js";
|
|
3
3
|
import { Slot } from "@radix-ui/react-slot";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { Content, Portal, Provider, Root as Root$1, Trigger } from "@radix-ui/react-tooltip";
|
|
@@ -71,7 +71,7 @@ const keyCodes = {
|
|
|
71
71
|
const tooltipVariants = cva([
|
|
72
72
|
"tailwindcss-preflight",
|
|
73
73
|
"tw:inline-block",
|
|
74
|
-
"tw:
|
|
74
|
+
"tw:wrap-anywhere",
|
|
75
75
|
"tw:max-h-96",
|
|
76
76
|
"tw:overflow-y-auto",
|
|
77
77
|
"tw:z-[1060]",
|
|
@@ -108,8 +108,8 @@ const tooltipVariants = cva([
|
|
|
108
108
|
"tw:text-center",
|
|
109
109
|
"tw:text-xs",
|
|
110
110
|
"tw:font-medium",
|
|
111
|
-
"tw:
|
|
112
|
-
"tw:
|
|
111
|
+
"tw:data-[tooltip-content=true]:uppercase",
|
|
112
|
+
"tw:data-[tooltip-content=true]:tracking-wider"
|
|
113
113
|
],
|
|
114
114
|
explanatory: [
|
|
115
115
|
"tw:max-w-80",
|
|
@@ -121,8 +121,9 @@ const tooltipVariants = cva([
|
|
|
121
121
|
]
|
|
122
122
|
} }
|
|
123
123
|
});
|
|
124
|
-
const TooltipContent = ({ className, variant, keepOpenOnPointerDownOutside = false, children, onPointerDownOutside, sideOffset = 8, collisionPadding = 8, hideWhenDetached = true, placement = "right", ...rest }) => {
|
|
125
|
-
const
|
|
124
|
+
const TooltipContent = ({ className, variant, keepOpenOnPointerDownOutside = false, argo, children, onPointerDownOutside, sideOffset = 8, collisionPadding = 8, hideWhenDetached = true, placement = "right", ...rest }) => {
|
|
125
|
+
const brandIsArgo = useArgoDesign();
|
|
126
|
+
const renderArgo = argo ?? brandIsArgo;
|
|
126
127
|
const handlePointerDownOutside = (event) => {
|
|
127
128
|
if (keepOpenOnPointerDownOutside) event.preventDefault();
|
|
128
129
|
onPointerDownOutside?.(event);
|
|
@@ -194,24 +195,31 @@ const TooltipTrigger = ({ ref, children, className, keepOpenOnClick = false, onC
|
|
|
194
195
|
//#endregion
|
|
195
196
|
//#region src/components/Tooltip/Tooltip.tsx
|
|
196
197
|
const ACTION_TOOLTIP_LIMIT = 30;
|
|
197
|
-
/**
|
|
198
|
+
/**
|
|
199
|
+
* New-design-only DOM; a trigger inside it gets the argo tooltip whatever the brand.
|
|
200
|
+
*
|
|
201
|
+
* - Matched on DOM ancestry, not React context, so overlays portaled to `document.body` follow the brand.
|
|
202
|
+
*/
|
|
203
|
+
const NEW_DESIGN_CHROME_SELECTOR = "[data-slot=\"navbar\"], [data-slot=\"sidebar\"]";
|
|
204
|
+
const HINT_UNDERLINE_CLASS_NAME = "tw:cursor-help tw:underline tw:decoration-dashed tw:decoration-neutral-300 tw:underline-offset-2";
|
|
205
|
+
/** Mount once at the app root so tooltips share delay state. */
|
|
198
206
|
const TooltipProvider = Provider;
|
|
199
207
|
/**
|
|
200
|
-
* Short plain-text label
|
|
208
|
+
* Short plain-text label on hover or focus.
|
|
201
209
|
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* **When NOT to use:** for rich preview content (multiple lines, formatted text, structured data) use
|
|
206
|
-
* `HoverCard`; for tooltips containing links or buttons use `Popover` (interactive elements break a11y
|
|
207
|
-
* inside a `Tooltip`).
|
|
208
|
-
* **Composition:** wrap any focusable element via `triggerAsChild` so the tooltip targets the underlying
|
|
209
|
-
* native element. Mount `TooltipProvider` once at the app root.
|
|
210
|
+
* - Use for icon-only buttons, disabled controls, truncated values.
|
|
211
|
+
* - Rich content → `HoverCard`; links or buttons → `Popover` (they break a11y here).
|
|
212
|
+
* - `variant` defaults to `"explanatory"` for strings over 30 chars, else `"action"`.
|
|
210
213
|
*
|
|
211
|
-
* @see RECIPES.md#disabled-button-tooltip
|
|
214
|
+
* @see RECIPES.md#disabled-button-tooltip
|
|
212
215
|
*/
|
|
213
|
-
const Tooltip = ({ tooltip, children, className, keepOpenOnTriggerClick = false, variant, placement = "right", forceHide = false, forceShow = false, delayDuration, triggerAsChild = false }) => {
|
|
216
|
+
const Tooltip = ({ tooltip, children, className, keepOpenOnTriggerClick = false, variant, placement = "right", forceHide = false, forceShow = false, delayDuration, chrome, triggerAsChild = false, hintUnderline = false }) => {
|
|
214
217
|
const [open, setOpen] = useState(false);
|
|
218
|
+
const [triggerElement, setTriggerElement] = useState(null);
|
|
219
|
+
const argo = (() => {
|
|
220
|
+
if (chrome) return chrome === "argo";
|
|
221
|
+
if (triggerElement?.closest(NEW_DESIGN_CHROME_SELECTOR)) return true;
|
|
222
|
+
})();
|
|
215
223
|
const resolvedVariant = (() => {
|
|
216
224
|
if (!!variant) return variant;
|
|
217
225
|
if (typeof tooltip === "string" && tooltip.length > ACTION_TOOLTIP_LIMIT) return "explanatory";
|
|
@@ -228,14 +236,17 @@ const Tooltip = ({ tooltip, children, className, keepOpenOnTriggerClick = false,
|
|
|
228
236
|
delayDuration,
|
|
229
237
|
disableHoverableContent: isActionVariant,
|
|
230
238
|
children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
239
|
+
ref: setTriggerElement,
|
|
231
240
|
asChild: triggerAsChild,
|
|
232
241
|
keepOpenOnClick: keepOpenOnTriggerClick,
|
|
233
242
|
onKeyUp: handleKeyUp,
|
|
243
|
+
className: hintUnderline ? HINT_UNDERLINE_CLASS_NAME : void 0,
|
|
234
244
|
children
|
|
235
245
|
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
236
246
|
className,
|
|
237
247
|
variant: resolvedVariant,
|
|
238
248
|
placement,
|
|
249
|
+
argo,
|
|
239
250
|
keepOpenOnPointerDownOutside: keepOpenOnTriggerClick,
|
|
240
251
|
children: tooltip
|
|
241
252
|
})]
|
|
@@ -305,6 +316,28 @@ const useSHA256 = (text) => {
|
|
|
305
316
|
return text ? hash : "";
|
|
306
317
|
};
|
|
307
318
|
//#endregion
|
|
308
|
-
|
|
319
|
+
//#region src/utils/splitEntry.ts
|
|
320
|
+
/** The separator a typed entry is split on when the caller names none. */
|
|
321
|
+
const DEFAULT_ENTRY_SEPARATOR = ",";
|
|
322
|
+
/**
|
|
323
|
+
* The strings one typed entry stands for.
|
|
324
|
+
*
|
|
325
|
+
* - Parts are trimmed; blanks dropped.
|
|
326
|
+
* - Repeats collapse case-insensitively, matching the combobox's display-string matching.
|
|
327
|
+
* - A `null` separator returns the entry verbatim, untrimmed — the caller must reject blank text.
|
|
328
|
+
*/
|
|
329
|
+
const splitEntry = (entry, separator) => {
|
|
330
|
+
if (separator === null) return [entry];
|
|
331
|
+
const seen = /* @__PURE__ */ new Set();
|
|
332
|
+
return entry.split(separator).map((part) => part.trim()).filter((part) => {
|
|
333
|
+
if (part === "") return false;
|
|
334
|
+
const key = part.toLowerCase();
|
|
335
|
+
if (seen.has(key)) return false;
|
|
336
|
+
seen.add(key);
|
|
337
|
+
return true;
|
|
338
|
+
});
|
|
339
|
+
};
|
|
340
|
+
//#endregion
|
|
341
|
+
export { DEFAULT_ENTRY_SEPARATOR, HINT_UNDERLINE_CLASS_NAME, Tooltip, TooltipProvider, copyToClipboard, createChangeInputEvent, createPrefixedString, debounce, isMac, keyCodes, noop, splitEntry, useSHA256, withHiddenFullscreen, withTooltipProvider, withVisualSettle };
|
|
309
342
|
|
|
310
|
-
//# sourceMappingURL=utils-
|
|
343
|
+
//# sourceMappingURL=utils-Bd28bWgm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-Bd28bWgm.js","names":["Root"],"sources":["../src/utils/copyToClipboard.ts","../src/utils/createChangeInputEvent.ts","../src/constants/keyCodes.ts","../src/components/Tooltip/TooltipContent.tsx","../src/components/Tooltip/TooltipRoot.tsx","../src/components/Tooltip/TooltipTrigger.tsx","../src/components/Tooltip/Tooltip.tsx","../src/utils/decorators.tsx","../src/utils/createPrefixedString.ts","../src/utils/noop.ts","../src/utils/debounce.ts","../src/utils/isMac.ts","../src/utils/useSHA256.ts","../src/utils/splitEntry.ts"],"sourcesContent":["/**\n * The async Clipboard API requires the document to be focused and rejects with\n * `NotAllowedError: Document is not focused` otherwise — which is the normal state\n * for a page inside an iframe that has not taken focus, such as Storybook's canvas\n * or an embedded preview. `execCommand` has no such requirement because it copies\n * the selection of a node we focus ourselves, so it covers that gap.\n */\nconst copyViaSelection = (text: string) => {\n const node = document.createElement('textarea');\n node.value = text;\n node.setAttribute('readonly', '');\n node.style.cssText = 'position:fixed;top:0;left:0;opacity:0';\n document.body.append(node);\n node.select();\n\n try {\n return document.execCommand('copy');\n } finally {\n node.remove();\n }\n};\n\nexport const copyToClipboard = async (text: string) => {\n try {\n await navigator.clipboard.writeText(text);\n } catch (error) {\n if (!copyViaSelection(text)) throw error;\n }\n};\n","import type { ChangeEvent } from 'react';\n\nexport const createChangeInputEvent = (input: HTMLInputElement) => {\n const changeEvent: ChangeEvent<HTMLInputElement> = {\n target: input,\n currentTarget: input,\n type: 'change',\n nativeEvent: new Event('change', { bubbles: true }),\n bubbles: true,\n cancelable: false,\n defaultPrevented: false,\n eventPhase: 2, // AT_TARGET\n isTrusted: false,\n preventDefault: () => {},\n isDefaultPrevented: () => false,\n stopPropagation: () => {},\n isPropagationStopped: () => false,\n persist: () => {},\n timeStamp: Date.now(),\n };\n\n Object.defineProperty(changeEvent, 'target', {\n value: input,\n writable: false,\n });\n\n return changeEvent;\n};\n","export const keyCodes = {\n ENTER: 'Enter',\n ESCAPE: 'Escape',\n SPACE: ' ',\n};\n","import type { ComponentProps } from 'react';\nimport { Content, Portal } from '@radix-ui/react-tooltip';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nconst tooltipVariants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:inline-block',\n 'tw:wrap-anywhere',\n 'tw:max-h-96',\n 'tw:overflow-y-auto',\n 'tw:z-[1060]',\n\n // legacy (dark) chrome — default\n 'tw:rounded',\n 'tw:bg-neutral-800',\n 'tw:text-white',\n\n // argo chrome overrides\n 'tw:data-[argo=true]:rounded-2xl',\n 'tw:data-[argo=true]:border',\n 'tw:data-[argo=true]:border-solid',\n 'tw:data-[argo=true]:border-border',\n 'tw:data-[argo=true]:bg-popover',\n 'tw:data-[argo=true]:text-popover-foreground',\n 'tw:data-[argo=true]:shadow-md',\n\n // argo open animation\n 'tw:data-[argo=true]:data-[state=delayed-open]:animate-in',\n 'tw:data-[argo=true]:data-[state=instant-open]:animate-in',\n 'tw:data-[argo=true]:data-[state=delayed-open]:fade-in-0',\n 'tw:data-[argo=true]:data-[state=instant-open]:fade-in-0',\n 'tw:data-[argo=true]:data-[state=delayed-open]:zoom-in-95',\n 'tw:data-[argo=true]:data-[state=instant-open]:zoom-in-95',\n\n // argo closed animation\n 'tw:data-[argo=true]:data-[state=closed]:animate-out',\n 'tw:data-[argo=true]:data-[state=closed]:fade-out-0',\n 'tw:data-[argo=true]:data-[state=closed]:zoom-out-95',\n\n // argo position animation\n 'tw:data-[argo=true]:data-[side=bottom]:slide-in-from-top-2',\n 'tw:data-[argo=true]:data-[side=left]:slide-in-from-right-2',\n 'tw:data-[argo=true]:data-[side=right]:slide-in-from-left-2',\n 'tw:data-[argo=true]:data-[side=top]:slide-in-from-bottom-2',\n ],\n {\n defaultVariants: {\n variant: 'action',\n },\n variants: {\n variant: {\n action: [\n 'tw:max-w-fit',\n 'tw:px-3',\n 'tw:py-2',\n\n 'tw:text-center',\n 'tw:text-xs',\n 'tw:font-medium',\n // Uppercase on legacy chrome only; argo reads standard case.\n 'tw:data-[tooltip-content=true]:uppercase',\n 'tw:data-[tooltip-content=true]:tracking-wider',\n ],\n explanatory: [\n 'tw:max-w-80',\n 'tw:px-4',\n 'tw:py-3',\n 'tw:text-left',\n\n 'tw:text-sm',\n 'tw:font-normal',\n ],\n },\n },\n },\n);\n\ntype Props = {\n keepOpenOnPointerDownOutside?: boolean;\n /** Force argo (`true`) or legacy (`false`) chrome; `undefined` follows the brand. */\n argo?: boolean;\n placement?: ComponentProps<typeof Content>['side'];\n} & Omit<ComponentProps<typeof Content>, 'side'> &\n VariantProps<typeof tooltipVariants>;\n\nexport const TooltipContent = ({\n className,\n variant,\n keepOpenOnPointerDownOutside = false,\n argo,\n children,\n onPointerDownOutside,\n sideOffset = 8,\n collisionPadding = 8,\n hideWhenDetached = true,\n placement = 'right',\n ...rest\n}: Props) => {\n const brandIsArgo = useArgoDesign();\n const renderArgo = argo ?? brandIsArgo;\n\n const handlePointerDownOutside: ComponentProps<typeof Content>['onPointerDownOutside'] = (\n event,\n ) => {\n if (keepOpenOnPointerDownOutside) event.preventDefault();\n onPointerDownOutside?.(event);\n };\n\n return (\n <Portal>\n <Content\n {...rest}\n // styles.css inverts nested `.tw\\:prose` on the dark chrome.\n data-tooltip-content={renderArgo ? undefined : true}\n data-argo={renderArgo}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n onPointerDownOutside={handlePointerDownOutside}\n className={tooltipVariants({ className, variant })}\n hideWhenDetached={hideWhenDetached}\n side={placement}\n >\n {children}\n </Content>\n </Portal>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Root } from '@radix-ui/react-tooltip';\n\ntype Props = ComponentProps<typeof Root>;\n\nconst DELAY_SHOW_TOOLTIP = 300;\n\nexport const TooltipRoot = ({ children, delayDuration = DELAY_SHOW_TOOLTIP, ...rest }: Props) => (\n <Root {...rest} delayDuration={delayDuration}>\n {children}\n </Root>\n);\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { Trigger } from '@radix-ui/react-tooltip';\n\nimport { cn } from '../../utils';\n\n/**\n * Radix stamps the tooltip's own open/closed `data-state` onto the trigger. Merged onto an\n * `asChild` child that keeps a `data-state` of its own — `ToggleGroup.Item`, `Switch`, a `Tabs`\n * trigger — it wins, because those primitives spread incoming props *after* their own attribute.\n * The child then silently loses every `data-[state=…]` style it has, which is usually the only\n * thing marking it as selected.\n *\n * The tooltip's trigger state is styled nowhere, so it is dropped before it reaches the child.\n */\nconst WithoutTooltipState = ({\n children,\n ...props\n // `Slot`'s own props, plus the one attribute this exists to remove: React's types declare no\n // `data-*`, so it has to be named to be destructured away.\n}: ComponentProps<typeof Slot> & { 'data-state'?: string }) => {\n const { 'data-state': _tooltipState, ...rest } = props;\n\n return <Slot {...rest}>{children}</Slot>;\n};\n\ntype Props = {\n keepOpenOnClick?: boolean;\n} & ComponentProps<typeof Trigger>;\n\nexport const TooltipTrigger = ({\n ref,\n children,\n className,\n keepOpenOnClick = false,\n onClick,\n onPointerDown,\n asChild,\n ...rest\n}: Props) => {\n const handleClick: ComponentProps<typeof Trigger>['onClick'] = (event) => {\n if (keepOpenOnClick) event.preventDefault();\n onClick?.(event);\n };\n\n const handlePointerDown: ComponentProps<typeof Trigger>['onPointerDown'] = (event) => {\n if (keepOpenOnClick) event.preventDefault();\n onPointerDown?.(event);\n };\n\n return (\n <Trigger\n {...rest}\n asChild\n ref={ref}\n className={cn('tailwindcss-preflight', className)}\n onClick={handleClick}\n onPointerDown={handlePointerDown}\n >\n {asChild ? (\n <WithoutTooltipState>{children}</WithoutTooltipState>\n ) : (\n // Default-mode trigger wraps children in a span so Radix has a\n // single DOM element to attach handlers to. `tailwindcss-preflight`\n // (merged in via Slot) activates Tailwind's preflight inside the\n // span, which sets `svg { display: block }` — without an inline-flex\n // container that would stack any bare Lucide icon onto its own\n // line. `tw:inline-flex tw:items-center` keeps icon + text aligned.\n <span className=\"tw:inline-flex tw:items-center\">{children}</span>\n )}\n </Trigger>\n );\n};\n","import { useState } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport type { Content, Trigger } from '@radix-ui/react-tooltip';\nimport { Provider } from '@radix-ui/react-tooltip';\n\nimport { keyCodes } from '../../constants/keyCodes';\n\nimport { TooltipContent } from './TooltipContent';\nimport { TooltipRoot } from './TooltipRoot';\nimport { TooltipTrigger } from './TooltipTrigger';\n\nconst ACTION_TOOLTIP_LIMIT = 30;\n\n/**\n * New-design-only DOM; a trigger inside it gets the argo tooltip whatever the brand.\n *\n * - Matched on DOM ancestry, not React context, so overlays portaled to `document.body` follow the brand.\n */\nconst NEW_DESIGN_CHROME_SELECTOR = '[data-slot=\"navbar\"], [data-slot=\"sidebar\"]';\n\nexport const HINT_UNDERLINE_CLASS_NAME =\n 'tw:cursor-help tw:underline tw:decoration-dashed tw:decoration-neutral-300 tw:underline-offset-2';\n\ntype TriggerProps = {\n triggerAsChild?: boolean;\n};\n\nexport type Props = {\n /** Stays open on trigger click (click-to-copy feedback). */\n keepOpenOnTriggerClick?: boolean;\n /** Plain text only — interactive content belongs in `HoverCard` / `Popover`. */\n tooltip: ReactNode;\n children: ReactNode;\n placement?: ComponentProps<typeof Content>['side'];\n /** Hides it regardless of hover. */\n forceHide?: boolean;\n /** Shows it regardless of hover (e.g. guided tours). */\n forceShow?: boolean;\n /** In ms; defaults to the shared 300ms. */\n delayDuration?: number;\n /** Dashed-underline hover hint on the trigger. */\n hintUnderline?: boolean;\n /** Force one chrome. Default: argo inside `Navbar` / `Sidebar` DOM, else the brand's. */\n chrome?: 'argo' | 'legacy';\n className?: string;\n} & TriggerProps &\n Pick<ComponentProps<typeof TooltipContent>, 'variant' | 'className'>;\n\n/** Mount once at the app root so tooltips share delay state. */\nexport const TooltipProvider = Provider;\n\n/**\n * Short plain-text label on hover or focus.\n *\n * - Use for icon-only buttons, disabled controls, truncated values.\n * - Rich content → `HoverCard`; links or buttons → `Popover` (they break a11y here).\n * - `variant` defaults to `\"explanatory\"` for strings over 30 chars, else `\"action\"`.\n *\n * @see RECIPES.md#disabled-button-tooltip\n */\nexport const Tooltip = ({\n tooltip,\n children,\n className,\n keepOpenOnTriggerClick = false,\n variant,\n placement = 'right',\n forceHide = false,\n forceShow = false,\n delayDuration,\n chrome,\n triggerAsChild = false,\n hintUnderline = false,\n}: Props) => {\n const [open, setOpen] = useState(false);\n const [triggerElement, setTriggerElement] = useState<HTMLElement | null>(null);\n\n const argo = (() => {\n if (chrome) return chrome === 'argo';\n if (triggerElement?.closest(NEW_DESIGN_CHROME_SELECTOR)) return true;\n return undefined;\n })();\n\n const resolvedVariant = (() => {\n if (!!variant) return variant;\n if (typeof tooltip === 'string' && tooltip.length > ACTION_TOOLTIP_LIMIT) return 'explanatory';\n\n return 'action';\n })();\n\n const isActionVariant = resolvedVariant === 'action';\n\n const handleKeyUp: ComponentProps<typeof Trigger>['onKeyUp'] = (event) => {\n if (![keyCodes.ENTER, keyCodes.SPACE].includes(event.key)) return;\n event.stopPropagation();\n };\n\n return (\n <TooltipRoot\n open={!!tooltip && (open || forceShow) && !forceHide}\n onOpenChange={setOpen}\n delayDuration={delayDuration}\n disableHoverableContent={isActionVariant}\n >\n <TooltipTrigger\n ref={setTriggerElement}\n asChild={triggerAsChild}\n keepOpenOnClick={keepOpenOnTriggerClick}\n onKeyUp={handleKeyUp}\n className={hintUnderline ? HINT_UNDERLINE_CLASS_NAME : undefined}\n >\n {children}\n </TooltipTrigger>\n\n <TooltipContent\n className={className}\n variant={resolvedVariant}\n placement={placement}\n argo={argo}\n keepOpenOnPointerDownOutside={keepOpenOnTriggerClick}\n >\n {tooltip}\n </TooltipContent>\n </TooltipRoot>\n );\n};\n\nTooltip.Root = TooltipRoot;\nTooltip.Content = TooltipContent;\nTooltip.Trigger = TooltipTrigger;\n","import type { ComponentType } from 'react';\n\nimport { TooltipProvider } from '../components/Tooltip';\n\nexport const withTooltipProvider = (Story: ComponentType) => (\n <TooltipProvider>\n <Story />\n </TooltipProvider>\n);\n\n// Marks a story whose final render arrives asynchronously (lazy chunk, debounced\n// parse). The visual suite waits for every `[data-skeleton]` inside this box to\n// unmount before capturing, so the baseline is the settled content, never the\n// placeholder it briefly shows.\nexport const withVisualSettle = (Story: ComponentType) => (\n <div data-visual-settle>\n <Story />\n </div>\n);\n\n// position:fixed only fills the Storybook iframe, not the browser window.\nexport const withHiddenFullscreen = (Story: ComponentType) => (\n <div className=\"tw:[&_[aria-label=Fullscreen]]:hidden\">\n <Story />\n </div>\n);\n","export const createPrefixedString = (prefix: string) => (literals: TemplateStringsArray) =>\n literals.reduce((acc, literal) => acc + literal, `${prefix}-`);\n","export const noop = () => void 0;\n","type DebouncedFn<T extends (...args: any[]) => void> = {\n (...args: Parameters<T>): void;\n cancel: () => void;\n};\n\nexport const debounce = <T extends (...args: any[]) => void>(\n fn: T,\n delay: number,\n): DebouncedFn<T> => {\n let timeoutId: ReturnType<typeof setTimeout>;\n const debounced = (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n debounced.cancel = () => clearTimeout(timeoutId);\n return debounced;\n};\n","// Platform detection\ntype NavigatorUAData = {\n platform: string;\n brands: { brand: string; version: string }[];\n mobile: boolean;\n};\n\nconst getIsMac = (): boolean => {\n // Modern approach using navigator.userAgentData\n if (typeof navigator !== 'undefined' && 'userAgentData' in navigator) {\n const platform = (navigator.userAgentData as NavigatorUAData).platform;\n\n if (typeof platform === 'string') {\n return platform.toLowerCase() === 'macos';\n }\n }\n\n if (typeof navigator !== 'undefined' && typeof navigator.platform === 'string') {\n return navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n }\n\n // Server-side rendering fallback\n return false;\n};\n\nexport const isMac = getIsMac();\n","import { useEffect, useState } from 'react';\n\n// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\nconst sha256 = async (text: string) => {\n const msgUint8 = new TextEncoder().encode(text);\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n};\n\nexport const useSHA256 = (text?: string) => {\n const [hash, setHash] = useState('');\n\n useEffect(() => {\n if (!text) return;\n let cancelled = false;\n sha256(text).then((h) => {\n if (!cancelled) setHash(h);\n });\n return () => {\n cancelled = true;\n };\n }, [text]);\n\n // Empty input has no hash — derive it during render instead of syncing state\n // in the effect (avoids the extra render and a stale-value frame).\n return text ? hash : '';\n};\n","/** The separator a typed entry is split on when the caller names none. */\nexport const DEFAULT_ENTRY_SEPARATOR = ',';\n\n/**\n * The strings one typed entry stands for.\n *\n * - Parts are trimmed; blanks dropped.\n * - Repeats collapse case-insensitively, matching the combobox's display-string matching.\n * - A `null` separator returns the entry verbatim, untrimmed — the caller must reject blank text.\n */\nexport const splitEntry = (entry: string, separator: string | RegExp | null): string[] => {\n if (separator === null) return [entry];\n\n const seen = new Set<string>();\n return entry\n .split(separator)\n .map((part) => part.trim())\n .filter((part) => {\n if (part === '') return false;\n const key = part.toLowerCase();\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n"],"mappings":"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"}
|