@keboola/design 13.2.0 → 15.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 +16 -24
- package/CHANGELOG.md +194 -0
- package/COMPONENT-API.md +109 -105
- package/dist/{AIKit-C5FbKjwa.js → AIKit-CaAW4GLx.js} +2216 -307
- package/dist/AIKit-CaAW4GLx.js.map +1 -0
- package/dist/{Alert-DuAGeYyM.js → Alert-Chz6KZ7e.js} +11 -20
- package/dist/Alert-Chz6KZ7e.js.map +1 -0
- package/dist/{AlertModal-BDle9ZVQ.js → AlertModal-D4AtpvLS.js} +15 -35
- package/dist/AlertModal-D4AtpvLS.js.map +1 -0
- package/dist/{AppShell-B03fj1j7.js → AppShell-C8V1KRr_.js} +2 -2
- package/dist/{AppShell-B03fj1j7.js.map → AppShell-C8V1KRr_.js.map} +1 -1
- package/dist/{AutoSaveTextarea-jiqNeeE4.js → AutoSaveTextarea-BbMhC5Aq.js} +3 -3
- package/dist/AutoSaveTextarea-BbMhC5Aq.js.map +1 -0
- package/dist/{Badge-Ba3epgcI.js → Badge-5GHIsgRS.js} +14 -3
- package/dist/Badge-5GHIsgRS.js.map +1 -0
- package/dist/{BrandEditor-Dq168RJc.js → BrandEditor-CTGtQUFZ.js} +8 -10
- package/dist/BrandEditor-CTGtQUFZ.js.map +1 -0
- package/dist/{BrandLogo-BfITD0im.js → BrandLogo-DkESE19K.js} +2 -2
- package/dist/{BrandLogo-BfITD0im.js.map → BrandLogo-DkESE19K.js.map} +1 -1
- package/dist/{Breadcrumb-CUyYu5Bi.js → Breadcrumb-B2YSNON4.js} +55 -13
- package/dist/Breadcrumb-B2YSNON4.js.map +1 -0
- package/dist/{Button-D2JqBAq7.js → Button-BNkyYU8u.js} +9 -185
- package/dist/Button-BNkyYU8u.js.map +1 -0
- package/dist/{Card-Bpc_ZlL4.js → Card-DxjGiqH8.js} +11 -18
- package/dist/Card-DxjGiqH8.js.map +1 -0
- package/dist/{Checkbox-D9rafoKh.js → Checkbox-CHDDJyAA.js} +20 -45
- package/dist/Checkbox-CHDDJyAA.js.map +1 -0
- package/dist/{Clipboard-BHWUodAx.js → Clipboard-DlwVZS1P.js} +2 -2
- package/dist/{Clipboard-BHWUodAx.js.map → Clipboard-DlwVZS1P.js.map} +1 -1
- package/dist/{ClipboardButton-Urg-kZbh.js → ClipboardButton-B1Hr_n_Z.js} +3 -3
- package/dist/{ClipboardButton-Urg-kZbh.js.map → ClipboardButton-B1Hr_n_Z.js.map} +1 -1
- package/dist/{CodeEditor-Y0iE-SwV.js → CodeEditor-DVSPdfdo.js} +24 -31
- package/dist/CodeEditor-DVSPdfdo.js.map +1 -0
- package/dist/{ColorInput-D1nC0X6i.js → ColorInput-B_eZIu39.js} +5 -7
- package/dist/ColorInput-B_eZIu39.js.map +1 -0
- package/dist/{ColorModeSwitch-Cxee8jnB.js → ColorModeSwitch-B6UEzG0H.js} +3 -3
- package/dist/{ColorModeSwitch-Cxee8jnB.js.map → ColorModeSwitch-B6UEzG0H.js.map} +1 -1
- package/dist/{Combobox-B1Kjoy5J.js → Combobox-CaKqgstG.js} +250 -56
- package/dist/Combobox-CaKqgstG.js.map +1 -0
- package/dist/{Command-BuOA3V18.js → Command-DhXmqFLT.js} +51 -33
- package/dist/Command-DhXmqFLT.js.map +1 -0
- package/dist/{CopyField-DsOVtV2Q.js → CopyField-D0Pg4Z0R.js} +2 -2
- package/dist/{CopyField-DsOVtV2Q.js.map → CopyField-D0Pg4Z0R.js.map} +1 -1
- package/dist/{DateInput-BlKkequE.js → DateInput-BgbMDJkm.js} +5 -7
- package/dist/DateInput-BgbMDJkm.js.map +1 -0
- package/dist/{DatePicker-CgHAu9KX.js → DatePicker-BXpDRo-R.js} +2 -2
- package/dist/{DatePicker-CgHAu9KX.js.map → DatePicker-BXpDRo-R.js.map} +1 -1
- package/dist/{DateRangeInput-DOxJHw8V.js → DateRangeInput-BW0-_jV0.js} +5 -7
- package/dist/DateRangeInput-BW0-_jV0.js.map +1 -0
- package/dist/{DateRangePicker-CXpXPMoh.js → DateRangePicker-C4-DoWac.js} +7 -12
- package/dist/DateRangePicker-C4-DoWac.js.map +1 -0
- package/dist/{DropdownMenu-DtRYcKEx.js → DropdownMenu-CcVbZ_5u.js} +35 -64
- package/dist/DropdownMenu-CcVbZ_5u.js.map +1 -0
- package/dist/{FieldItem-Cf1E3rfQ.js → FieldItem-BHUqgSO1.js} +3 -3
- package/dist/{FieldItem-Cf1E3rfQ.js.map → FieldItem-BHUqgSO1.js.map} +1 -1
- package/dist/{FileUpload-D6vPG3WB.js → FileUpload-BYFONpEl.js} +3 -3
- package/dist/FileUpload-BYFONpEl.js.map +1 -0
- package/dist/{Form-CuaAn-lR.js → Form-CAofWyMI.js} +8 -8
- package/dist/{Form-CuaAn-lR.js.map → Form-CAofWyMI.js.map} +1 -1
- package/dist/{FormGroup-D4O96YPm.js → FormGroup-V5kIgQRN.js} +3 -3
- package/dist/{FormGroup-D4O96YPm.js.map → FormGroup-V5kIgQRN.js.map} +1 -1
- package/dist/{FullScreenModal-CUuAakh3.js → FullScreenModal-DAvvlGOz.js} +2 -5
- package/dist/FullScreenModal-DAvvlGOz.js.map +1 -0
- package/dist/HoverCard-Cv5rmvJq.js +26 -0
- package/dist/HoverCard-Cv5rmvJq.js.map +1 -0
- package/dist/{InlineEdit-DSMIEUUa.js → InlineEdit-D4P0SvCB.js} +5 -9
- package/dist/InlineEdit-D4P0SvCB.js.map +1 -0
- package/dist/{InputGroup-Dm014ruw.js → InputGroup-CZv_7QlM.js} +39 -146
- package/dist/InputGroup-CZv_7QlM.js.map +1 -0
- package/dist/{Kbd-Du93F3o4.js → Kbd-CflKthfu.js} +5 -14
- package/dist/Kbd-CflKthfu.js.map +1 -0
- package/dist/MermaidDiagram-Te-5gOCU.js +199 -0
- package/dist/MermaidDiagram-Te-5gOCU.js.map +1 -0
- package/dist/{Modal-DQIauzar.js → Modal-CbUz-5YH.js} +19 -37
- package/dist/Modal-CbUz-5YH.js.map +1 -0
- package/dist/{ModalTitle-CTECVgL8.js → ModalTitle-cy0Ht9VY.js} +2 -2
- package/dist/{ModalTitle-CTECVgL8.js.map → ModalTitle-cy0Ht9VY.js.map} +1 -1
- package/dist/{MultiActionButtonGroup-xKqiucAN.js → MultiActionButtonGroup-Dzig87s1.js} +3 -3
- package/dist/{MultiActionButtonGroup-xKqiucAN.js.map → MultiActionButtonGroup-Dzig87s1.js.map} +1 -1
- package/dist/{Navbar-CtVYcRFn.js → Navbar-DHUS7XiU.js} +2 -2
- package/dist/{Navbar-CtVYcRFn.js.map → Navbar-DHUS7XiU.js.map} +1 -1
- package/dist/OtpInput-CY8yCaJk.js.map +1 -1
- package/dist/{PageToolbar-B_e7HGva.js → PageToolbar-DJ5tdYla.js} +4 -4
- package/dist/{PageToolbar-B_e7HGva.js.map → PageToolbar-DJ5tdYla.js.map} +1 -1
- package/dist/{Pagination-DDp6PRqf.js → Pagination-D27x5KmH.js} +2 -2
- package/dist/{Pagination-DDp6PRqf.js.map → Pagination-D27x5KmH.js.map} +1 -1
- package/dist/{Popconfirm-BgV6a0sl.js → Popconfirm-DwLCYNaF.js} +3 -3
- package/dist/{Popconfirm-BgV6a0sl.js.map → Popconfirm-DwLCYNaF.js.map} +1 -1
- package/dist/{Popover-BU7nGOv-.js → Popover-DtUDwUVO.js} +24 -37
- package/dist/Popover-DtUDwUVO.js.map +1 -0
- package/dist/{RadioGroup-C2vk5acr.js → RadioGroup-B0TwHjBb.js} +9 -13
- package/dist/RadioGroup-B0TwHjBb.js.map +1 -0
- package/dist/{Search-CVrv3hqf.js → Search-vyZwGKMU.js} +3 -3
- package/dist/{Search-CVrv3hqf.js.map → Search-vyZwGKMU.js.map} +1 -1
- package/dist/{SearchInput-BnU6YHgT.js → SearchInput-DyYXyw3u.js} +4 -6
- package/dist/SearchInput-DyYXyw3u.js.map +1 -0
- package/dist/{SectionNav-XlhvXXdF.js → SectionNav-tLK3iF6c.js} +5 -5
- package/dist/{SectionNav-XlhvXXdF.js.map → SectionNav-tLK3iF6c.js.map} +1 -1
- package/dist/{Select-CjQgU_6K.js → Select-B22hB_-w.js} +11 -25
- package/dist/Select-B22hB_-w.js.map +1 -0
- package/dist/{Sheet-utw4_rUa.js → Sheet-0TWKTqid.js} +12 -15
- package/dist/Sheet-0TWKTqid.js.map +1 -0
- package/dist/{Sidebar-CKaxOPwY.js → Sidebar-C5hdANBU.js} +11 -11
- package/dist/Sidebar-C5hdANBU.js.map +1 -0
- package/dist/{Slider-Rcc2qVct.js → Slider-DrcsM8_G.js} +4 -4
- package/dist/Slider-DrcsM8_G.js.map +1 -0
- package/dist/{Stepper-BBPembeK.js → Stepper-CQrUPVFL.js} +2 -2
- package/dist/Stepper-CQrUPVFL.js.map +1 -0
- package/dist/Switch-DccpSpzC.js +66 -0
- package/dist/Switch-DccpSpzC.js.map +1 -0
- package/dist/{Table-CgSC-fSo.js → Table-CilEvpMq.js} +62 -3
- package/dist/Table-CilEvpMq.js.map +1 -0
- package/dist/{Tabs-C0uvkPHc.js → Tabs-Ck4uWf8U.js} +2 -2
- package/dist/{Tabs-C0uvkPHc.js.map → Tabs-Ck4uWf8U.js.map} +1 -1
- package/dist/{TextInput-B5TDDOty.js → TextInput-CR0_USaY.js} +4 -7
- package/dist/TextInput-CR0_USaY.js.map +1 -0
- package/dist/{ThemeProvider-Dt9b67sW.js → ThemeProvider-BTK7AL-T.js} +21 -8
- package/dist/ThemeProvider-BTK7AL-T.js.map +1 -0
- package/dist/{TimePicker-DyyV3nw8.js → TimePicker-CoRpiEM3.js} +2 -2
- package/dist/{TimePicker-DyyV3nw8.js.map → TimePicker-CoRpiEM3.js.map} +1 -1
- package/dist/{Toast-BGnUL4jV.js → Toast-937n7n8i.js} +2 -2
- package/dist/{Toast-BGnUL4jV.js.map → Toast-937n7n8i.js.map} +1 -1
- package/dist/ToggleAllTooltip-DEjbWFoj.js +37 -0
- package/dist/ToggleAllTooltip-DEjbWFoj.js.map +1 -0
- package/dist/{ZoomableSvg-D8sXKpoV.js → ZoomableSvg-DnFXo2L4.js} +85 -81
- package/dist/ZoomableSvg-DnFXo2L4.js.map +1 -0
- package/dist/editors.js +4 -4
- package/dist/flint.js +10 -45
- package/dist/flint.js.map +1 -1
- package/dist/highlightCode-D354tCXO.js +81 -0
- package/dist/highlightCode-D354tCXO.js.map +1 -0
- package/dist/index.d.ts +843 -443
- package/dist/index.js +62 -63
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/AppShell.js +1 -1
- package/dist/internal/blocks/AuthLayout.js +1 -1
- package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChartPanel.js +1 -1
- package/dist/internal/blocks/ChipEditor.js +5 -9
- package/dist/internal/blocks/ChipEditor.js.map +1 -1
- package/dist/internal/blocks/ClipboardButton.js +1 -1
- package/dist/internal/blocks/ColorInput.js +1 -1
- package/dist/internal/blocks/ColorModeSwitch.js +1 -1
- package/dist/internal/blocks/Command.js +1 -1
- package/dist/internal/blocks/CopyField.js +1 -1
- package/dist/internal/blocks/DateInput.js +1 -1
- package/dist/internal/blocks/DateRangeInput.js +1 -1
- package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js.map +1 -1
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
- package/dist/internal/blocks/ErrorState.js +18 -29
- package/dist/internal/blocks/ErrorState.js.map +1 -1
- package/dist/internal/blocks/ExportMenu.js +3 -3
- package/dist/internal/blocks/ExportMenu.js.map +1 -1
- package/dist/internal/blocks/Form/connectors/ComboboxField.js +2 -2
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
- package/dist/internal/blocks/Form.js +1 -1
- package/dist/internal/blocks/FormGroup.js +1 -1
- package/dist/internal/blocks/InlineEdit.js +1 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
- package/dist/internal/blocks/MultiCombobox.js +202 -70
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +2 -4
- package/dist/internal/blocks/NumberInput.js.map +1 -1
- package/dist/internal/blocks/PageToolbar.js +1 -1
- package/dist/internal/blocks/PasswordInput.js +3 -5
- package/dist/internal/blocks/PasswordInput.js.map +1 -1
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +6 -7
- package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -1
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +2 -2
- package/dist/internal/blocks/StatCard.js +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/Textarea.js +3 -8
- package/dist/internal/blocks/Textarea.js.map +1 -1
- package/dist/internal/blocks/TimeInput.js +4 -6
- 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 +2 -2
- package/dist/internal/components/ButtonGroup.js +1 -1
- package/dist/internal/components/ButtonGroup.js.map +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 +1 -1
- package/dist/internal/components/Combobox.js +1 -1
- 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/Modal.js +1 -1
- package/dist/internal/components/Navbar.js +1 -1
- package/dist/internal/components/Pagination.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/Sheet.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Skeleton/Skeleton.js +2 -2
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/Stepper.js +1 -1
- package/dist/internal/components/Switch.js +1 -1
- package/dist/internal/components/Table.js +1 -1
- package/dist/internal/components/Tabs.js +1 -1
- package/dist/internal/components/ThemeProvider.js +3 -4
- package/dist/internal/components/TimePicker.js +1 -1
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Toggle.js +13 -3
- package/dist/internal/components/Toggle.js.map +1 -1
- package/dist/internal/components/Tooltip.js +1 -1
- package/dist/internal/components/Truncated.js +1 -1
- package/dist/internal/components/ZoomableSvg.js +1 -1
- package/dist/internal/utils.js +1 -1
- package/dist/markdown-editor.js +16 -18
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +1 -2
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.js +121 -43
- package/dist/rjsf.js.map +1 -1
- package/dist/styles-DxazJ8Mz.js +81 -0
- package/dist/styles-DxazJ8Mz.js.map +1 -0
- package/dist/styles-T8xwr0sR.js +73 -0
- package/dist/styles-T8xwr0sR.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/svgCache-Dhmbe-7i.js +26 -0
- package/dist/svgCache-Dhmbe-7i.js.map +1 -0
- package/dist/svgTransforms-Hnvev3Vs.js +38 -0
- package/dist/svgTransforms-Hnvev3Vs.js.map +1 -0
- package/dist/testing.d.ts +0 -2
- package/dist/testing.js +3 -10
- package/dist/testing.js.map +1 -1
- package/dist/{useColorSchemeState-Cw4MCXUs.js → themeScopeContext-CEVXbYvZ.js} +43 -15
- package/dist/themeScopeContext-CEVXbYvZ.js.map +1 -0
- package/dist/{useThemeAttributes-B199Regy.js → themeTokens-DCeb62ap.js} +22 -4
- package/dist/themeTokens-DCeb62ap.js.map +1 -0
- package/dist/{toast-D6Z6MOB5.js → toast-Y3cTMBW8.js} +7 -10
- package/dist/toast-Y3cTMBW8.js.map +1 -0
- package/dist/{utils-p6tjltbX.js → utils-DwC9u0tM.js} +39 -49
- package/dist/utils-DwC9u0tM.js.map +1 -0
- package/dist/vega.js +2 -2
- package/dist/vegaTheme-ISwGXvof.js +49 -0
- package/dist/vegaTheme-ISwGXvof.js.map +1 -0
- package/dist/{vegaTheme-VQMWTlBw.js → vegaTokens-DCkvpIVE.js} +36 -44
- package/dist/vegaTokens-DCkvpIVE.js.map +1 -0
- package/package.json +3 -4
- package/src/styles.css +4 -39
- package/src/theme.css +42 -0
- package/dist/AIKit-C5FbKjwa.js.map +0 -1
- package/dist/Alert-DuAGeYyM.js.map +0 -1
- package/dist/AlertModal-BDle9ZVQ.js.map +0 -1
- package/dist/AutoSaveTextarea-jiqNeeE4.js.map +0 -1
- package/dist/Badge-Ba3epgcI.js.map +0 -1
- package/dist/BrandEditor-Dq168RJc.js.map +0 -1
- package/dist/Breadcrumb-CUyYu5Bi.js.map +0 -1
- package/dist/Button-D2JqBAq7.js.map +0 -1
- package/dist/Card-Bpc_ZlL4.js.map +0 -1
- package/dist/Checkbox-D9rafoKh.js.map +0 -1
- package/dist/CodeEditor-Y0iE-SwV.js.map +0 -1
- package/dist/ColorInput-D1nC0X6i.js.map +0 -1
- package/dist/Combobox-B1Kjoy5J.js.map +0 -1
- package/dist/Command-BuOA3V18.js.map +0 -1
- package/dist/DateInput-BlKkequE.js.map +0 -1
- package/dist/DateRangeInput-DOxJHw8V.js.map +0 -1
- package/dist/DateRangePicker-CXpXPMoh.js.map +0 -1
- package/dist/DiagramSource-jTwmmi9g.js +0 -11
- package/dist/DiagramSource-jTwmmi9g.js.map +0 -1
- package/dist/DropdownMenu-DtRYcKEx.js.map +0 -1
- package/dist/FileUpload-D6vPG3WB.js.map +0 -1
- package/dist/FullScreenModal-CUuAakh3.js.map +0 -1
- package/dist/HoverCard-Cy6nhg4u.js +0 -31
- package/dist/HoverCard-Cy6nhg4u.js.map +0 -1
- package/dist/InlineEdit-DSMIEUUa.js.map +0 -1
- package/dist/InputGroup-Dm014ruw.js.map +0 -1
- package/dist/Kbd-Du93F3o4.js.map +0 -1
- package/dist/MermaidDiagram-D2ThT8Q-.js +0 -302
- package/dist/MermaidDiagram-D2ThT8Q-.js.map +0 -1
- package/dist/Modal-DQIauzar.js.map +0 -1
- package/dist/Popover-BU7nGOv-.js.map +0 -1
- package/dist/RadioGroup-C2vk5acr.js.map +0 -1
- package/dist/SearchInput-BnU6YHgT.js.map +0 -1
- package/dist/Select-CjQgU_6K.js.map +0 -1
- package/dist/Sheet-utw4_rUa.js.map +0 -1
- package/dist/Sidebar-CKaxOPwY.js.map +0 -1
- package/dist/Slider-Rcc2qVct.js.map +0 -1
- package/dist/Stepper-BBPembeK.js.map +0 -1
- package/dist/Switch-Dw4tvQls.js +0 -201
- package/dist/Switch-Dw4tvQls.js.map +0 -1
- package/dist/Table-CgSC-fSo.js.map +0 -1
- package/dist/TextInput-B5TDDOty.js.map +0 -1
- package/dist/ThemeProvider-Dt9b67sW.js.map +0 -1
- package/dist/ZoomableSvg-D8sXKpoV.js.map +0 -1
- package/dist/context-U293r3v-.js +0 -29
- package/dist/context-U293r3v-.js.map +0 -1
- package/dist/defaults-i_xG2F_1.js +0 -32
- package/dist/defaults-i_xG2F_1.js.map +0 -1
- package/dist/styles-BDA5rQz3.js +0 -127
- package/dist/styles-BDA5rQz3.js.map +0 -1
- package/dist/styles-YQdM7G8c.js +0 -159
- package/dist/styles-YQdM7G8c.js.map +0 -1
- package/dist/svgTransforms-Dw2hRA-i.js +0 -51
- package/dist/svgTransforms-Dw2hRA-i.js.map +0 -1
- package/dist/themeTokens-7DEab0kp.js +0 -31
- package/dist/themeTokens-7DEab0kp.js.map +0 -1
- package/dist/toast-D6Z6MOB5.js.map +0 -1
- package/dist/useColorSchemeState-Cw4MCXUs.js.map +0 -1
- package/dist/useThemeAttributes-B199Regy.js.map +0 -1
- package/dist/utils-p6tjltbX.js.map +0 -1
- package/dist/vegaTheme-VQMWTlBw.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Form-CuaAn-lR.js","names":[],"sources":["../src/blocks/Form/components/FormBody.tsx","../src/blocks/Form/components/SubmitButton.tsx","../src/blocks/Form/components/SubmitErrorAlert.tsx","../src/blocks/Form/connectors/CheckboxField.tsx","../src/blocks/Form/connectors/NumberField.tsx","../src/blocks/Form/connectors/OtpInputField.tsx","../src/blocks/Form/connectors/PasswordField.tsx","../src/blocks/Form/connectors/SelectField.tsx","../src/blocks/Form/connectors/SwitchField.tsx","../src/blocks/Form/connectors/TextareaField.tsx","../src/blocks/Form/connectors/TextField.tsx","../src/blocks/Form/formHook.ts","../src/blocks/Form/setServerFieldErrors.ts","../src/blocks/Form/setSubmitError.ts"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../../../utils';\nimport { useFormContext } from '../contexts';\n\ntype Props = {\n children: ReactNode;\n} & Omit<ComponentProps<'form'>, 'onSubmit'>;\n\nexport const FormBody = ({ children, className, ...formProps }: Props) => {\n const form = useFormContext();\n\n return (\n <form\n {...formProps}\n className={cn('tw:flex tw:flex-col tw:gap-4', className)}\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n void form.handleSubmit();\n }}\n >\n {children}\n </form>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../../components/Button';\nimport { useFormContext } from '../contexts';\n\ntype Props = {\n children?: ReactNode;\n} & Omit<ComponentProps<typeof Button>, 'type' | 'isLoading' | 'disabled'>;\n\nexport const SubmitButton = ({ children = 'Submit', ...buttonProps }: Props) => {\n const form = useFormContext();\n\n return (\n <form.Subscribe\n selector={(state) => ({ isSubmitting: state.isSubmitting, canSubmit: state.canSubmit })}\n >\n {({ isSubmitting, canSubmit }) => (\n <Button\n {...buttonProps}\n type=\"submit\"\n isLoading={isSubmitting}\n disabled={!canSubmit || isSubmitting}\n >\n {children}\n </Button>\n )}\n </form.Subscribe>\n );\n};\n","import { Alert } from '../../../components/Alert';\nimport { useFormContext } from '../contexts';\n\n/**\n * Renders the form-level submit error (set via `setSubmitError` → `errorMap.onSubmit`) as an error\n * `Alert`. Place inside `form.FormBody`, typically just above the submit button. Renders nothing when\n * there is no submit error.\n */\nexport const SubmitErrorAlert = () => {\n const form = useFormContext();\n\n return (\n <form.Subscribe selector={(state) => state.errorMap.onSubmit}>\n {(submitError) =>\n typeof submitError === 'string' ? <Alert variant=\"error\" title={submitError} /> : null\n }\n </form.Subscribe>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { Checkbox } from '../../../components/Checkbox';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\n// Checkbox owns its own label + description (via children), so only the wrapper className applies.\ntype Props = Pick<FieldItemProps, 'className'> &\n Omit<ComponentProps<typeof Checkbox>, 'id' | 'name' | 'checked' | 'onCheckedChange'>;\n\nexport const CheckboxField = ({ className, children, ...checkboxProps }: Props) => {\n // Strictly boolean: coerce Radix's `'indeterminate'` to `false` so a non-boolean never leaks into\n // form state (submit payloads / validators). `'indeterminate'` stays a purely visual state.\n const field = useFieldContext<boolean>();\n\n return (\n <FieldItem className={className}>\n {(control) => (\n <Checkbox\n {...checkboxProps}\n {...control}\n checked={field.state.value ?? false}\n onCheckedChange={(checked) => field.handleChange(checked === true)}\n onBlur={field.handleBlur}\n >\n {children}\n </Checkbox>\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport type { FormGroup } from '../../FormGroup';\nimport { NumberInput } from '../../NumberInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n ComponentProps<typeof FormGroup.NumberInput>,\n 'id' | 'name' | 'value' | 'onValueChange' | 'onBlur'\n >;\n\nexport const NumberField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<number | null>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <NumberInput\n {...inputProps}\n {...control}\n value={field.state.value ?? null}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import { OtpInput, type OtpInputProps } from '../../OtpInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n OtpInputProps,\n | 'value'\n | 'onChange'\n | 'children'\n | 'id'\n | 'name'\n | 'aria-describedby'\n | 'aria-required'\n | 'aria-invalid'\n >;\n\nexport const OtpInputField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n maxLength,\n ...otpProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <OtpInput\n {...otpProps}\n {...control}\n maxLength={maxLength}\n value={field.state.value ?? ''}\n onChange={field.handleChange}\n onBlur={field.handleBlur}\n >\n <OtpInput.Group>\n {Array.from({ length: maxLength }, (_, index) => (\n <OtpInput.Slot key={index} index={index} />\n ))}\n </OtpInput.Group>\n </OtpInput>\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { PasswordInput } from '../../PasswordInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<ComponentProps<typeof PasswordInput>, 'id' | 'name' | 'value' | 'onValueChange' | 'onBlur'>;\n\nexport const PasswordField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <PasswordInput\n {...inputProps}\n {...control}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import {\n Select,\n type SelectItem,\n type SelectItemGroup,\n type SelectProps,\n} from '../../../components/Select';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n SelectProps,\n // Owned by the field / `FieldItem` — see the connector rules in AGENTS.md. The naming props\n // are on that list too: `FieldItem` renders the label and hands the control its `id`, so a\n // name from the call site could only disagree with it.\n | 'id'\n | 'aria-label'\n | 'aria-labelledby'\n | 'name'\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'onBlur'\n | 'aria-describedby'\n | 'aria-invalid'\n | 'aria-required'\n // `className` styles the field frame, so the trigger gets its own prop below.\n | 'className'\n | 'items'\n > & {\n items: readonly (SelectItem | SelectItemGroup)[];\n triggerClassName?: string;\n };\n\nexport const SelectField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n triggerClassName,\n ...selectProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n // `required` deliberately stays on `FieldItem` (which turns it into `aria-required` via\n // `control`) and is not forwarded to the Radix root: a required hidden native select would\n // fail browser constraint validation and swallow the submit event before the form sees it.\n <Select\n {...selectProps}\n {...control}\n className={triggerClassName ?? 'tw:w-full'}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { Switch } from '../../../components/Switch';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\n// Switch owns its own label + description (via children), so only the wrapper className applies.\ntype Props = Pick<FieldItemProps, 'className'> &\n Omit<ComponentProps<typeof Switch>, 'id' | 'name' | 'checked' | 'onCheckedChange'>;\n\nexport const SwitchField = ({ className, children, ...switchProps }: Props) => {\n const field = useFieldContext<boolean>();\n\n return (\n <FieldItem className={className}>\n {(control) => (\n <Switch\n {...switchProps}\n {...control}\n checked={field.state.value ?? false}\n onCheckedChange={field.handleChange}\n onBlur={field.handleBlur}\n >\n {children}\n </Switch>\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport type { FormGroup } from '../../FormGroup';\nimport { Textarea } from '../../Textarea';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n ComponentProps<typeof FormGroup.Textarea>,\n 'id' | 'name' | 'value' | 'onValueChange' | 'onBlur'\n >;\n\nexport const TextareaField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <Textarea\n {...inputProps}\n {...control}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport type { FormGroup } from '../../FormGroup';\nimport { TextInput } from '../../TextInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<ComponentProps<typeof FormGroup.TextInput>, 'id' | 'name' | 'value' | 'onChange' | 'onBlur'>;\n\nexport const TextField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <TextInput\n {...inputProps}\n {...control}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import { createFormHook } from '@tanstack/react-form';\n\nimport { FormBody } from './components/FormBody';\nimport { SubmitButton } from './components/SubmitButton';\nimport { SubmitErrorAlert } from './components/SubmitErrorAlert';\nimport { CheckboxField } from './connectors/CheckboxField';\nimport { NumberField } from './connectors/NumberField';\nimport { OtpInputField } from './connectors/OtpInputField';\nimport { PasswordField } from './connectors/PasswordField';\nimport { SelectField } from './connectors/SelectField';\nimport { SwitchField } from './connectors/SwitchField';\nimport { TextareaField } from './connectors/TextareaField';\nimport { TextField } from './connectors/TextField';\nimport { fieldContext, formContext } from './contexts';\n\n/**\n * Typed form hook + `withForm` binding for forms with validation, server errors or a submit state.\n *\n * - Render `field.*` inside `form.AppForm` → `form.FormBody`; submit via `form.SubmitButton`.\n * - `ComboboxField`, `MultiComboboxField`, `CodeEditorField` are imported by name: no tree-shaking.\n * - Not for a lone `<input>` (`TextInput`) or an unvalidated label + input (`FormGroup`).\n * - Takes any [Standard Schema](https://standardschema.dev/) validator.\n *\n * @see RECIPES.md#modal-form\n */\nexport const { useAppForm, withForm } = createFormHook({\n fieldContext,\n formContext,\n fieldComponents: {\n TextField,\n NumberField,\n PasswordField,\n TextareaField,\n SelectField,\n CheckboxField,\n SwitchField,\n OtpInputField,\n },\n formComponents: {\n FormBody,\n SubmitButton,\n SubmitErrorAlert,\n },\n});\n","import type { AnyFormApi } from '@tanstack/form-core';\n\nexport type ServerFieldError = {\n field: string;\n message: string;\n};\n\n/**\n * Map a list of server-returned field errors onto a TanStack form instance.\n *\n * - Marks each field blurred — that is what `FieldItem` gates the error reveal on.\n * - `isTouched` alongside it, for anything reading TanStack's own meta (`canSubmit`, dirty checks).\n * - Both are needed. Called from a mutation's `onError` there is no submit attempt to fall back on, so\n * without `isBlurred` the message would sit in `errorMap` and render nowhere.\n */\nexport const setServerFieldErrors = (form: AnyFormApi, errors: readonly ServerFieldError[]) => {\n for (const { field, message } of errors) {\n form.setFieldMeta(field, (meta) => ({\n ...meta,\n isBlurred: true,\n isTouched: true,\n errors: [message],\n errorMap: { ...meta.errorMap, onServer: message },\n }));\n }\n};\n","// `form-core`, not `react-form`: a declared dep, so `dist` imports it rather than inlining its own copy.\nimport type { AnyFormApi } from '@tanstack/form-core';\n\n/**\n * Set a **form-level** submit error on a TanStack form instance — a failed submission that isn't tied\n * to a single field (bad credentials, 5xx, network). Stored on `errorMap.onSubmit` and rendered by\n * `SubmitErrorAlert`. For field-specific server errors use `setServerFieldErrors` instead.\n *\n * Note: any error entry makes the form \"invalid\", so pair this with `canSubmitWhenInvalid: true` on\n * the form to keep the submit button retryable (a resubmit re-runs the validators and clears it).\n */\nexport const setSubmitError = (form: AnyFormApi, message: string) => {\n form.setErrorMap({ onSubmit: { form: message, fields: {} } });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Form-CAofWyMI.js","names":[],"sources":["../src/blocks/Form/components/FormBody.tsx","../src/blocks/Form/components/SubmitButton.tsx","../src/blocks/Form/components/SubmitErrorAlert.tsx","../src/blocks/Form/connectors/CheckboxField.tsx","../src/blocks/Form/connectors/NumberField.tsx","../src/blocks/Form/connectors/OtpInputField.tsx","../src/blocks/Form/connectors/PasswordField.tsx","../src/blocks/Form/connectors/SelectField.tsx","../src/blocks/Form/connectors/SwitchField.tsx","../src/blocks/Form/connectors/TextareaField.tsx","../src/blocks/Form/connectors/TextField.tsx","../src/blocks/Form/formHook.ts","../src/blocks/Form/setServerFieldErrors.ts","../src/blocks/Form/setSubmitError.ts"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../../../utils';\nimport { useFormContext } from '../contexts';\n\ntype Props = {\n children: ReactNode;\n} & Omit<ComponentProps<'form'>, 'onSubmit'>;\n\nexport const FormBody = ({ children, className, ...formProps }: Props) => {\n const form = useFormContext();\n\n return (\n <form\n {...formProps}\n className={cn('tw:flex tw:flex-col tw:gap-4', className)}\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n void form.handleSubmit();\n }}\n >\n {children}\n </form>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../../components/Button';\nimport { useFormContext } from '../contexts';\n\ntype Props = {\n children?: ReactNode;\n} & Omit<ComponentProps<typeof Button>, 'type' | 'isLoading' | 'disabled'>;\n\nexport const SubmitButton = ({ children = 'Submit', ...buttonProps }: Props) => {\n const form = useFormContext();\n\n return (\n <form.Subscribe\n selector={(state) => ({ isSubmitting: state.isSubmitting, canSubmit: state.canSubmit })}\n >\n {({ isSubmitting, canSubmit }) => (\n <Button\n {...buttonProps}\n type=\"submit\"\n isLoading={isSubmitting}\n disabled={!canSubmit || isSubmitting}\n >\n {children}\n </Button>\n )}\n </form.Subscribe>\n );\n};\n","import { Alert } from '../../../components/Alert';\nimport { useFormContext } from '../contexts';\n\n/**\n * Renders the form-level submit error (set via `setSubmitError` → `errorMap.onSubmit`) as an error\n * `Alert`. Place inside `form.FormBody`, typically just above the submit button. Renders nothing when\n * there is no submit error.\n */\nexport const SubmitErrorAlert = () => {\n const form = useFormContext();\n\n return (\n <form.Subscribe selector={(state) => state.errorMap.onSubmit}>\n {(submitError) =>\n typeof submitError === 'string' ? <Alert variant=\"error\" title={submitError} /> : null\n }\n </form.Subscribe>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { Checkbox } from '../../../components/Checkbox';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\n// Checkbox owns its own label + description (via children), so only the wrapper className applies.\ntype Props = Pick<FieldItemProps, 'className'> &\n Omit<ComponentProps<typeof Checkbox>, 'id' | 'name' | 'checked' | 'onCheckedChange'>;\n\nexport const CheckboxField = ({ className, children, ...checkboxProps }: Props) => {\n // Strictly boolean: coerce Radix's `'indeterminate'` to `false` so a non-boolean never leaks into\n // form state (submit payloads / validators). `'indeterminate'` stays a purely visual state.\n const field = useFieldContext<boolean>();\n\n return (\n <FieldItem className={className}>\n {(control) => (\n <Checkbox\n {...checkboxProps}\n {...control}\n checked={field.state.value ?? false}\n onCheckedChange={(checked) => field.handleChange(checked === true)}\n onBlur={field.handleBlur}\n >\n {children}\n </Checkbox>\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport type { FormGroup } from '../../FormGroup';\nimport { NumberInput } from '../../NumberInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n ComponentProps<typeof FormGroup.NumberInput>,\n 'id' | 'name' | 'value' | 'onValueChange' | 'onBlur'\n >;\n\nexport const NumberField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<number | null>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <NumberInput\n {...inputProps}\n {...control}\n value={field.state.value ?? null}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import { OtpInput, type OtpInputProps } from '../../OtpInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n OtpInputProps,\n | 'value'\n | 'onChange'\n | 'children'\n | 'id'\n | 'name'\n | 'aria-describedby'\n | 'aria-required'\n | 'aria-invalid'\n >;\n\nexport const OtpInputField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n maxLength,\n ...otpProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <OtpInput\n {...otpProps}\n {...control}\n maxLength={maxLength}\n value={field.state.value ?? ''}\n onChange={field.handleChange}\n onBlur={field.handleBlur}\n >\n <OtpInput.Group>\n {Array.from({ length: maxLength }, (_, index) => (\n <OtpInput.Slot key={index} index={index} />\n ))}\n </OtpInput.Group>\n </OtpInput>\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { PasswordInput } from '../../PasswordInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<ComponentProps<typeof PasswordInput>, 'id' | 'name' | 'value' | 'onValueChange' | 'onBlur'>;\n\nexport const PasswordField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <PasswordInput\n {...inputProps}\n {...control}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import {\n Select,\n type SelectItem,\n type SelectItemGroup,\n type SelectProps,\n} from '../../../components/Select';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n SelectProps,\n // Owned by the field / `FieldItem` — see the connector rules in AGENTS.md. The naming props\n // are on that list too: `FieldItem` renders the label and hands the control its `id`, so a\n // name from the call site could only disagree with it.\n | 'id'\n | 'aria-label'\n | 'aria-labelledby'\n | 'name'\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'onBlur'\n | 'aria-describedby'\n | 'aria-invalid'\n | 'aria-required'\n // `className` styles the field frame, so the trigger gets its own prop below.\n | 'className'\n | 'items'\n > & {\n items: readonly (SelectItem | SelectItemGroup)[];\n triggerClassName?: string;\n };\n\nexport const SelectField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n triggerClassName,\n ...selectProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n // `required` deliberately stays on `FieldItem` (which turns it into `aria-required` via\n // `control`) and is not forwarded to the Radix root: a required hidden native select would\n // fail browser constraint validation and swallow the submit event before the form sees it.\n <Select\n {...selectProps}\n {...control}\n className={triggerClassName ?? 'tw:w-full'}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { Switch } from '../../../components/Switch';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\n// Switch owns its own label + description (via children), so only the wrapper className applies.\ntype Props = Pick<FieldItemProps, 'className'> &\n Omit<ComponentProps<typeof Switch>, 'id' | 'name' | 'checked' | 'onCheckedChange'>;\n\nexport const SwitchField = ({ className, children, ...switchProps }: Props) => {\n const field = useFieldContext<boolean>();\n\n return (\n <FieldItem className={className}>\n {(control) => (\n <Switch\n {...switchProps}\n {...control}\n checked={field.state.value ?? false}\n onCheckedChange={field.handleChange}\n onBlur={field.handleBlur}\n >\n {children}\n </Switch>\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport type { FormGroup } from '../../FormGroup';\nimport { Textarea } from '../../Textarea';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<\n ComponentProps<typeof FormGroup.Textarea>,\n 'id' | 'name' | 'value' | 'onValueChange' | 'onBlur'\n >;\n\nexport const TextareaField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <Textarea\n {...inputProps}\n {...control}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport type { FormGroup } from '../../FormGroup';\nimport { TextInput } from '../../TextInput';\nimport { useFieldContext } from '../contexts';\n\nimport { FieldItem, type FieldItemProps } from './FieldItem';\n\ntype Props = FieldItemProps &\n Omit<ComponentProps<typeof FormGroup.TextInput>, 'id' | 'name' | 'value' | 'onChange' | 'onBlur'>;\n\nexport const TextField = ({\n label,\n action,\n required,\n requiredMark,\n help,\n tooltip,\n className,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n}: Props) => {\n const field = useFieldContext<string>();\n\n return (\n <FieldItem\n label={label}\n action={action}\n required={required}\n requiredMark={requiredMark}\n help={help}\n tooltip={tooltip}\n className={className}\n aria-describedby={ariaDescribedBy}\n >\n {(control) => (\n <TextInput\n {...inputProps}\n {...control}\n value={field.state.value ?? ''}\n onValueChange={field.handleChange}\n onBlur={field.handleBlur}\n />\n )}\n </FieldItem>\n );\n};\n","import { createFormHook } from '@tanstack/react-form';\n\nimport { FormBody } from './components/FormBody';\nimport { SubmitButton } from './components/SubmitButton';\nimport { SubmitErrorAlert } from './components/SubmitErrorAlert';\nimport { CheckboxField } from './connectors/CheckboxField';\nimport { NumberField } from './connectors/NumberField';\nimport { OtpInputField } from './connectors/OtpInputField';\nimport { PasswordField } from './connectors/PasswordField';\nimport { SelectField } from './connectors/SelectField';\nimport { SwitchField } from './connectors/SwitchField';\nimport { TextareaField } from './connectors/TextareaField';\nimport { TextField } from './connectors/TextField';\nimport { fieldContext, formContext } from './contexts';\n\n/**\n * Typed form hook + `withForm` binding for forms with validation, server errors or a submit state.\n *\n * - Render `field.*` inside `form.AppForm` → `form.FormBody`; submit via `form.SubmitButton`.\n * - `ComboboxField`, `MultiComboboxField`, `CodeEditorField` are imported by name: no tree-shaking.\n * - Not for a lone `<input>` (`TextInput`) or an unvalidated label + input (`FormGroup`).\n * - Takes any [Standard Schema](https://standardschema.dev/) validator.\n *\n * @see RECIPES.md#modal-form\n */\nexport const { useAppForm, withForm } = createFormHook({\n fieldContext,\n formContext,\n fieldComponents: {\n TextField,\n NumberField,\n PasswordField,\n TextareaField,\n SelectField,\n CheckboxField,\n SwitchField,\n OtpInputField,\n },\n formComponents: {\n FormBody,\n SubmitButton,\n SubmitErrorAlert,\n },\n});\n","import type { AnyFormApi } from '@tanstack/form-core';\n\nexport type ServerFieldError = {\n field: string;\n message: string;\n};\n\n/**\n * Map a list of server-returned field errors onto a TanStack form instance.\n *\n * - Marks each field blurred — that is what `FieldItem` gates the error reveal on.\n * - `isTouched` alongside it, for anything reading TanStack's own meta (`canSubmit`, dirty checks).\n * - Both are needed. Called from a mutation's `onError` there is no submit attempt to fall back on, so\n * without `isBlurred` the message would sit in `errorMap` and render nowhere.\n */\nexport const setServerFieldErrors = (form: AnyFormApi, errors: readonly ServerFieldError[]) => {\n for (const { field, message } of errors) {\n form.setFieldMeta(field, (meta) => ({\n ...meta,\n isBlurred: true,\n isTouched: true,\n errors: [message],\n errorMap: { ...meta.errorMap, onServer: message },\n }));\n }\n};\n","// `form-core`, not `react-form`: a declared dep, so `dist` imports it rather than inlining its own copy.\nimport type { AnyFormApi } from '@tanstack/form-core';\n\n/**\n * Set a **form-level** submit error on a TanStack form instance — a failed submission that isn't tied\n * to a single field (bad credentials, 5xx, network). Stored on `errorMap.onSubmit` and rendered by\n * `SubmitErrorAlert`. For field-specific server errors use `setServerFieldErrors` instead.\n *\n * Note: any error entry makes the form \"invalid\", so pair this with `canSubmitWhenInvalid: true` on\n * the form to keep the submit button retryable (a resubmit re-runs the validators and clears it).\n */\nexport const setSubmitError = (form: AnyFormApi, message: string) => {\n form.setErrorMap({ onSubmit: { form: message, fields: {} } });\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "./classNames-DcGnTh2N.js";
|
|
2
|
-
import { TextInput } from "./TextInput-
|
|
3
|
-
import { ColorInput } from "./ColorInput-
|
|
2
|
+
import { TextInput } from "./TextInput-CR0_USaY.js";
|
|
3
|
+
import { ColorInput } from "./ColorInput-B_eZIu39.js";
|
|
4
4
|
import { HelpBlock } from "./internal/components/HelpBlock.js";
|
|
5
5
|
import { NumberInput } from "./internal/blocks/NumberInput.js";
|
|
6
6
|
import { Textarea } from "./internal/blocks/Textarea.js";
|
|
@@ -115,4 +115,4 @@ FormGroup.Textarea = FormGroupTextarea;
|
|
|
115
115
|
//#endregion
|
|
116
116
|
export { FormGroup };
|
|
117
117
|
|
|
118
|
-
//# sourceMappingURL=FormGroup-
|
|
118
|
+
//# sourceMappingURL=FormGroup-V5kIgQRN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormGroup-
|
|
1
|
+
{"version":3,"file":"FormGroup-V5kIgQRN.js","names":[],"sources":["../src/blocks/FormGroup/context.ts","../src/blocks/FormGroup/FormGroupColorInput.tsx","../src/blocks/FormGroup/FormGroupError.tsx","../src/blocks/FormGroup/FormGroupHelp.tsx","../src/blocks/FormGroup/FormGroupNumberInput.tsx","../src/blocks/FormGroup/FormGroupTextarea.tsx","../src/blocks/FormGroup/FormGroupTextInput.tsx","../src/blocks/FormGroup/FormGroup.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\nimport type { FormGroupContext } from './types';\n\nconst FormGroupContext = createContext<FormGroupContext>({\n state: 'default',\n});\n\nexport const FormGroupProvider = FormGroupContext;\n\nexport const useFormGroupContext = () => use(FormGroupContext);\n","import type { ComponentProps } from 'react';\n\nimport { ColorInput } from '../ColorInput';\n\nimport { useFormGroupContext } from './context';\n\ntype Props = Omit<ComponentProps<typeof ColorInput>, 'state'>;\n\nexport const FormGroupColorInput = ({ ref, ...props }: Props) => {\n const { state } = useFormGroupContext();\n return <ColorInput state={state} {...props} ref={ref} />;\n};\n","import { useMemo } from 'react';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentPropsWithRef<'div'> & {\n /**\n * TanStack Form errors: strings or `{ message }` objects; several render as a list.\n * Ignored when `children` is provided.\n */\n errors?: readonly (string | { message?: string } | undefined)[];\n};\n\nconst toMessage = (entry: string | { message?: string } | undefined): string | undefined =>\n typeof entry === 'string' ? entry : entry?.message;\n\n/**\n * Field validation error.\n *\n * - `role=\"alert\"` announces it even when focus is elsewhere (e.g. on submit).\n * - A `<div>`, not `<p>`, so several errors can render as a `<ul>`.\n */\nexport const FormGroupError = ({ children, className, errors, ...rest }: Props) => {\n const content = useMemo<ReactNode>(() => {\n if (children) return children;\n\n // Deduplicated: a schema on both `onChange` and `onBlur` yields the same message twice.\n const messages = [...new Set((errors ?? []).map(toMessage).filter((message) => !!message))];\n if (messages.length === 0) return null;\n if (messages.length === 1) return messages[0];\n\n return (\n <ul className=\"tw:m-0 tw:flex tw:list-disc tw:flex-col tw:gap-0 tw:pl-4\">\n {messages.map((message) => (\n // Unique after the dedupe above.\n <li key={message}>{message}</li>\n ))}\n </ul>\n );\n }, [children, errors]);\n\n if (!content) return null;\n\n return (\n <div {...rest} role=\"alert\" className={cn('tw:m-0 tw:text-xs tw:text-destructive', className)}>\n {content}\n </div>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { HelpBlock } from '../../components/HelpBlock';\n\nimport { useFormGroupContext } from './context';\n\ntype Props = Omit<ComponentProps<typeof HelpBlock>, 'state'>;\n\nexport const FormGroupHelp = ({ children, ...rest }: Props) => {\n const formGroupContext = useFormGroupContext();\n\n // Help stays advisory; a group's error state surfaces via FormGroup.Error, not here.\n return (\n <HelpBlock state={formGroupContext.state === 'warning' ? 'warning' : 'default'} {...rest}>\n {children}\n </HelpBlock>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { NumberInput } from '../NumberInput';\n\nimport { useFormGroupContext } from './context';\n\ntype Props = Omit<ComponentProps<typeof NumberInput>, 'state'>;\n\nexport const FormGroupNumberInput = ({ ref, ...props }: Props) => {\n const { state } = useFormGroupContext();\n return <NumberInput {...props} ref={ref} state={state} />;\n};\n","import type { ComponentProps } from 'react';\n\nimport { Textarea } from '../Textarea';\n\nimport { useFormGroupContext } from './context';\n\ntype Props = Omit<ComponentProps<typeof Textarea>, 'state'>;\n\nexport const FormGroupTextarea = (props: Props) => {\n const { state } = useFormGroupContext();\n return <Textarea state={state} {...props} />;\n};\n","import type { ComponentProps } from 'react';\n\nimport { TextInput } from '../TextInput';\n\nimport { useFormGroupContext } from './context';\n\ntype Props = Omit<ComponentProps<typeof TextInput>, 'state'>;\n\nexport const FormGroupTextInput = ({ ref, ...props }: Props) => {\n const { state } = useFormGroupContext();\n return <TextInput state={state} {...props} ref={ref} />;\n};\n","import type { ComponentPropsWithRef } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { FormGroupProvider } from './context';\nimport { FormGroupColorInput } from './FormGroupColorInput';\nimport { FormGroupError } from './FormGroupError';\nimport { FormGroupHelp } from './FormGroupHelp';\nimport { FormGroupNumberInput } from './FormGroupNumberInput';\nimport { FormGroupTextarea } from './FormGroupTextarea';\nimport { FormGroupTextInput } from './FormGroupTextInput';\nimport type { FormGroupContext } from './types';\n\n/**\n * - `state` propagates via context to nested inputs.\n * - `FormGroup.Help` reacts only to \"warning\"; errors render through `FormGroup.Error`.\n */\ntype FormGroupProps = ComponentPropsWithRef<'div'> & FormGroupContext;\n\n/**\n * Label + input + help/error text for one field, with shared validation state.\n *\n * - **Use:** a single field outside `useAppForm`.\n * - **Don't use:** for a full form — `useAppForm` from `blocks/Form` composes `FormGroup` itself.\n * - **Composition:** `Label`, one `FormGroup.*Input` / `Textarea`, then optional `Help` or `Error`.\n */\nexport const FormGroup = ({ className, children, state, ...rest }: FormGroupProps) => {\n return (\n <FormGroupProvider value={{ state }}>\n <div {...rest} className={cn('tw:flex tw:flex-col tw:gap-1', className)}>\n {children}\n </div>\n </FormGroupProvider>\n );\n};\n\nFormGroup.Help = FormGroupHelp;\nFormGroup.Error = FormGroupError;\nFormGroup.TextInput = FormGroupTextInput;\nFormGroup.NumberInput = FormGroupNumberInput;\nFormGroup.ColorInput = FormGroupColorInput;\nFormGroup.Textarea = FormGroupTextarea;\n"],"mappings":";;;;;;;;;AAIA,MAAM,mBAAmB,cAAgC,EACvD,OAAO,UACT,CAAC;AAED,MAAa,oBAAoB;AAEjC,MAAa,4BAA4B,IAAI,gBAAgB;;;ACF7D,MAAa,uBAAuB,EAAE,KAAK,GAAG,YAAmB;CAC/D,MAAM,EAAE,UAAU,oBAAoB;CACtC,OAAO,oBAAC,YAAD;EAAmB;EAAO,GAAI;EAAY;CAAM,CAAA;AACzD;;;ACEA,MAAM,aAAa,UACjB,OAAO,UAAU,WAAW,QAAQ,OAAO;;;;;;;AAQ7C,MAAa,kBAAkB,EAAE,UAAU,WAAW,QAAQ,GAAG,WAAkB;CACjF,MAAM,UAAU,cAAyB;EACvC,IAAI,UAAU,OAAO;EAGrB,MAAM,WAAW,CAAC,GAAG,IAAI,KAAK,UAAU,CAAC,EAAA,CAAG,IAAI,SAAS,CAAC,CAAC,QAAQ,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;EAC1F,IAAI,SAAS,WAAW,GAAG,OAAO;EAClC,IAAI,SAAS,WAAW,GAAG,OAAO,SAAS;EAE3C,OACE,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,SAAS,KAAK,YAEb,oBAAC,MAAD,EAAA,UAAmB,QAAY,GAAtB,OAAsB,CAChC;EACC,CAAA;CAER,GAAG,CAAC,UAAU,MAAM,CAAC;CAErB,IAAI,CAAC,SAAS,OAAO;CAErB,OACE,oBAAC,OAAD;EAAK,GAAI;EAAM,MAAK;EAAQ,WAAW,GAAG,yCAAyC,SAAS;EACzF,UAAA;CACE,CAAA;AAET;;;ACxCA,MAAa,iBAAiB,EAAE,UAAU,GAAG,WAAkB;CAC7D,MAAM,mBAAmB,oBAAoB;CAG7C,OACE,oBAAC,WAAD;EAAW,OAAO,iBAAiB,UAAU,YAAY,YAAY;EAAW,GAAI;EACjF;CACQ,CAAA;AAEf;;;ACTA,MAAa,wBAAwB,EAAE,KAAK,GAAG,YAAmB;CAChE,MAAM,EAAE,UAAU,oBAAoB;CACtC,OAAO,oBAAC,aAAD;EAAa,GAAI;EAAY;EAAY;CAAQ,CAAA;AAC1D;;;ACHA,MAAa,qBAAqB,UAAiB;CACjD,MAAM,EAAE,UAAU,oBAAoB;CACtC,OAAO,oBAAC,UAAD;EAAiB;EAAO,GAAI;CAAQ,CAAA;AAC7C;;;ACHA,MAAa,sBAAsB,EAAE,KAAK,GAAG,YAAmB;CAC9D,MAAM,EAAE,UAAU,oBAAoB;CACtC,OAAO,oBAAC,WAAD;EAAkB;EAAO,GAAI;EAAY;CAAM,CAAA;AACxD;;;;;;;;;;ACeA,MAAa,aAAa,EAAE,WAAW,UAAU,OAAO,GAAG,WAA2B;CACpF,OACE,oBAAC,mBAAD;EAAmB,OAAO,EAAE,MAAM;EAChC,UAAA,oBAAC,OAAD;GAAK,GAAI;GAAM,WAAW,GAAG,gCAAgC,SAAS;GACnE;EACE,CAAA;CACY,CAAA;AAEvB;AAEA,UAAU,OAAO;AACjB,UAAU,QAAQ;AAClB,UAAU,YAAY;AACtB,UAAU,cAAc;AACxB,UAAU,aAAa;AACvB,UAAU,WAAW"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { cn } from "./classNames-DcGnTh2N.js";
|
|
2
|
-
import { useArgoDesign } from "./context-U293r3v-.js";
|
|
3
2
|
import { ChevronLeft } from "./icons-ZIeZXXS7.js";
|
|
4
|
-
import { Button } from "./Button-
|
|
3
|
+
import { Button } from "./Button-BNkyYU8u.js";
|
|
5
4
|
import { Truncated } from "./internal/components/Truncated.js";
|
|
6
5
|
import { useEffect, useMemo, useRef } from "react";
|
|
7
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -61,7 +60,6 @@ const BODY_LOCK_CLASS = "full-screen-modal-open";
|
|
|
61
60
|
let overflowBeforeLock = "";
|
|
62
61
|
const FullScreenModalRoot = ({ children, className, lockBodyScroll = true, onEscapeKeyDown, onKeyDown, ...props }) => {
|
|
63
62
|
const modalRef = useRef(null);
|
|
64
|
-
const renderArgo = useArgoDesign();
|
|
65
63
|
/**
|
|
66
64
|
* Locks the page's scroll while this modal is open with `lockBodyScroll`.
|
|
67
65
|
*
|
|
@@ -126,7 +124,6 @@ const FullScreenModalRoot = ({ children, className, lockBodyScroll = true, onEsc
|
|
|
126
124
|
tabIndex: -1,
|
|
127
125
|
"data-fullscreen-modal": true,
|
|
128
126
|
"data-fullscreen-modal-lock": lockBodyScroll || void 0,
|
|
129
|
-
"data-argo": renderArgo,
|
|
130
127
|
onKeyDown: handleKeyDown,
|
|
131
128
|
className: cn("tailwindcss-preflight", "tw:fixed", "tw:inset-0", "tw:z-[1039]", "tw:flex", "tw:flex-col", "tw:bg-background", "tw:text-foreground", "tw:focus-visible:outline-hidden", className),
|
|
132
129
|
children
|
|
@@ -141,4 +138,4 @@ const FullScreenModal = Object.assign(FullScreenModalRoot, {
|
|
|
141
138
|
//#endregion
|
|
142
139
|
export { FullScreenModal, FullScreenModalBody, FullScreenModalHeader };
|
|
143
140
|
|
|
144
|
-
//# sourceMappingURL=FullScreenModal-
|
|
141
|
+
//# sourceMappingURL=FullScreenModal-DAvvlGOz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FullScreenModal-DAvvlGOz.js","names":[],"sources":["../src/components/FullScreenModal/FullScreenModalBody.tsx","../src/components/FullScreenModal/FullScreenModalHeader.tsx","../src/components/FullScreenModal/FullScreenModalRoot.tsx","../src/components/FullScreenModal/FullScreenModal.tsx"],"sourcesContent":["import type { HTMLAttributes, Ref } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = HTMLAttributes<HTMLDivElement>;\n\nexport const FullScreenModalBody = ({\n ref,\n className,\n children,\n ...props\n}: Props & { ref?: Ref<HTMLDivElement> }) => (\n <div ref={ref} className={cn('tw:flex-1 tw:min-h-0 tw:overflow-auto', className)} {...props}>\n {children}\n </div>\n);\n","import { useMemo } from 'react';\nimport type { HTMLAttributes, PropsWithChildren, ReactNode } from 'react';\n\nimport { ChevronLeft } from '../../icons';\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Truncated } from '../Truncated';\n\nconst DEFAULT_TITLE_STYLES =\n 'tw:text-2xl tw:leading-8 tw:font-normal tw:text-foreground tw:overflow-hidden';\n\ntype Props = PropsWithChildren<\n Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {\n title: ReactNode;\n titleClassName?: string;\n titleWrapperClassName?: string;\n defaultTitleStyles?: boolean;\n isTitleWithIcon?: boolean;\n onClose?: () => void;\n showPreviousTitle?: boolean;\n }\n>;\n\nexport const FullScreenModalHeader = ({\n title,\n titleClassName,\n titleWrapperClassName,\n defaultTitleStyles = true,\n isTitleWithIcon = false,\n children,\n onClose,\n className,\n showPreviousTitle = true,\n ...props\n}: Props) => {\n const previousTitle = useMemo(() => {\n const modals = Array.from(document.querySelectorAll('[data-fullscreen-modal]'));\n return (\n showPreviousTitle &&\n modals?.length > 0 &&\n modals.at(-1)?.querySelector('[data-modal-title]')?.textContent\n );\n }, [showPreviousTitle]);\n\n return (\n <div\n className={cn('tw:p-4 tw:flex tw:shrink-0 tw:items-center tw:justify-between', className)}\n {...props}\n >\n <div className={cn('tw:flex tw:flex-1 tw:items-center', titleWrapperClassName)}>\n {previousTitle && onClose && (\n <Button onClick={onClose} size=\"icon\" className=\"tw:mr-6\">\n <ChevronLeft className=\"tw:size-4\" />\n </Button>\n )}\n\n <div className=\"tw:w-full\">\n <div\n className={cn('tw:m-0', defaultTitleStyles && DEFAULT_TITLE_STYLES, titleClassName)}\n data-modal-title\n >\n {previousTitle && onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"tailwindcss-preflight\"\n aria-label={`Go back to ${previousTitle}`}\n >\n <Truncated\n text={previousTitle}\n className={cn(\n 'tw:relative tw:top-0 tw:cursor-pointer tw:text-base tw:font-normal tw:text-muted-foreground tw:underline',\n 'tw:hover:text-foreground tw:hover:no-underline',\n isTitleWithIcon && 'tw:ml-14',\n )}\n />\n </button>\n )}\n <div\n className={cn('tw:flex tw:items-center', {\n 'tw:[&>img]:-mt-6': previousTitle,\n })}\n >\n {title}\n </div>\n </div>\n </div>\n </div>\n {children}\n </div>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport type { HTMLAttributes, KeyboardEvent, ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { cn } from '../../utils';\n\ntype Props = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n /** Lock body scroll when modal is open. Default: true */\n lockBodyScroll?: boolean;\n /** Callback when ESC key is pressed */\n onEscapeKeyDown?: (event: KeyboardEvent<HTMLDivElement>) => void;\n};\n\nconst BODY_LOCK_CLASS = 'full-screen-modal-open';\n\n/** `<body>`'s own inline `overflow`, from before the first open modal locked it. */\nlet overflowBeforeLock = '';\n\nexport const FullScreenModalRoot = ({\n children,\n className,\n lockBodyScroll = true,\n onEscapeKeyDown,\n onKeyDown,\n ...props\n}: Props) => {\n const modalRef = useRef<HTMLDivElement>(null);\n\n /**\n * Locks the page's scroll while this modal is open with `lockBodyScroll`.\n *\n * - Stays locked until the last locking modal closes; `lockBodyScroll={false}` ones don't count.\n * - Hands `<body>` back the inline `overflow` it had before the first lock.\n */\n useEffect(() => {\n if (!lockBodyScroll) return;\n const modalElement = modalRef.current;\n\n if (!document.body.classList.contains(BODY_LOCK_CLASS)) {\n overflowBeforeLock = document.body.style.overflow;\n }\n document.body.classList.add(BODY_LOCK_CLASS);\n document.body.style.overflow = 'hidden';\n\n return () => {\n // Exclude this modal: it is still in the DOM when `lockBodyScroll` flips to false.\n const hasOtherLockingModals = Array.from(\n document.querySelectorAll('[data-fullscreen-modal-lock]'),\n ).some((el) => el !== modalElement);\n if (hasOtherLockingModals) return;\n\n document.body.classList.remove(BODY_LOCK_CLASS);\n document.body.style.overflow = overflowBeforeLock;\n };\n }, [lockBodyScroll]);\n\n /**\n * The element focused when this modal first rendered.\n *\n * - Read during render: a child's `autoFocus` lands at commit, before any effect (layout too).\n */\n const openerRef = useRef<Element | null>(null);\n openerRef.current ??= document.activeElement;\n\n /**\n * Moves focus into the modal on open and back to the opener on close.\n *\n * - Needed for Escape: `onEscapeKeyDown` only fires while focus is inside.\n * - Skipped when the content already autofocused its own field.\n * - Not a focus trap: trapping or `inert` would need this element to own the background.\n */\n useEffect(() => {\n const modal = modalRef.current;\n if (!modal) return;\n\n if (!modal.contains(document.activeElement)) modal.focus();\n\n return () => {\n const opener = openerRef.current;\n if (opener instanceof HTMLElement && opener.isConnected) opener.focus();\n };\n }, []);\n\n /**\n * Escape only dismisses the modal it was pressed in.\n *\n * - React bubbles a nested (portalled) modal's Escape up to the outer one too.\n * - The DOM target check filters it: the inner modal is the outer's sibling, not a descendant.\n * - Not `stopPropagation`: it would also stop the native event at `document.body`, cutting off\n * `document`-level `keydown` handlers (kbc-ui's wrapper closes from one).\n */\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.key !== 'Escape' || event.defaultPrevented) return;\n\n const target = event.target;\n if (!(target instanceof Node) || !modalRef.current?.contains(target)) return;\n\n onEscapeKeyDown?.(event);\n };\n\n return createPortal(\n <div\n {...props}\n ref={modalRef}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n data-fullscreen-modal\n data-fullscreen-modal-lock={lockBodyScroll || undefined}\n onKeyDown={handleKeyDown}\n className={cn(\n 'tailwindcss-preflight',\n 'tw:fixed',\n 'tw:inset-0',\n 'tw:z-[1039]',\n 'tw:flex',\n 'tw:flex-col',\n // `text-foreground` travels with the background: portalled to `document.body`,\n // the modal inherits no app-level foreground.\n 'tw:bg-background',\n 'tw:text-foreground',\n 'tw:focus-visible:outline-hidden',\n className,\n )}\n >\n {children}\n </div>,\n document.body,\n );\n};\n","import { FullScreenModalBody } from './FullScreenModalBody';\nimport { FullScreenModalHeader } from './FullScreenModalHeader';\nimport { FullScreenModalRoot } from './FullScreenModalRoot';\n\nexport const FullScreenModal = Object.assign(FullScreenModalRoot, {\n Header: FullScreenModalHeader,\n Body: FullScreenModalBody,\n});\n"],"mappings":";;;;;;;;AAMA,MAAa,uBAAuB,EAClC,KACA,WACA,UACA,GAAG,YAEH,oBAAC,OAAD;CAAU;CAAK,WAAW,GAAG,yCAAyC,SAAS;CAAG,GAAI;CACnF;AACE,CAAA;;;ACNP,MAAM,uBACJ;AAcF,MAAa,yBAAyB,EACpC,OACA,gBACA,uBACA,qBAAqB,MACrB,kBAAkB,OAClB,UACA,SACA,WACA,oBAAoB,MACpB,GAAG,YACQ;CACX,MAAM,gBAAgB,cAAc;EAClC,MAAM,SAAS,MAAM,KAAK,SAAS,iBAAiB,yBAAyB,CAAC;EAC9E,OACE,qBACA,QAAQ,SAAS,KACjB,OAAO,GAAG,EAAE,CAAC,EAAE,cAAc,oBAAoB,CAAC,EAAE;CAExD,GAAG,CAAC,iBAAiB,CAAC;CAEtB,OACE,qBAAC,OAAD;EACE,WAAW,GAAG,iEAAiE,SAAS;EACxF,GAAI;EAFN,UAAA,CAIE,qBAAC,OAAD;GAAK,WAAW,GAAG,qCAAqC,qBAAqB;GAA7E,UAAA,CACG,iBAAiB,WAChB,oBAAC,QAAD;IAAQ,SAAS;IAAS,MAAK;IAAO,WAAU;IAC9C,UAAA,oBAAC,aAAD,EAAa,WAAU,YAAa,CAAA;GAC9B,CAAA,GAGV,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,qBAAC,OAAD;KACE,WAAW,GAAG,UAAU,sBAAsB,sBAAsB,cAAc;KAClF,oBAAA;KAFF,UAAA,CAIG,iBAAiB,WAChB,oBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;MACV,cAAY,cAAc;MAE1B,UAAA,oBAAC,WAAD;OACE,MAAM;OACN,WAAW,GACT,4GACA,kDACA,mBAAmB,UACrB;MACD,CAAA;KACK,CAAA,GAEV,oBAAC,OAAD;MACE,WAAW,GAAG,2BAA2B,EACvC,oBAAoB,cACtB,CAAC;MAEA,UAAA;KACE,CAAA,CACF;;GACF,CAAA,CACF;EACJ,CAAA,GAAA,QACE;;AAET;;;AC7EA,MAAM,kBAAkB;;AAGxB,IAAI,qBAAqB;AAEzB,MAAa,uBAAuB,EAClC,UACA,WACA,iBAAiB,MACjB,iBACA,WACA,GAAG,YACQ;CACX,MAAM,WAAW,OAAuB,IAAI;;;;;;;CAQ5C,gBAAgB;EACd,IAAI,CAAC,gBAAgB;EACrB,MAAM,eAAe,SAAS;EAE9B,IAAI,CAAC,SAAS,KAAK,UAAU,SAAS,eAAe,GACnD,qBAAqB,SAAS,KAAK,MAAM;EAE3C,SAAS,KAAK,UAAU,IAAI,eAAe;EAC3C,SAAS,KAAK,MAAM,WAAW;EAE/B,aAAa;GAKX,IAH8B,MAAM,KAClC,SAAS,iBAAiB,8BAA8B,CAC1D,CAAC,CAAC,MAAM,OAAO,OAAO,YACE,GAAG;GAE3B,SAAS,KAAK,UAAU,OAAO,eAAe;GAC9C,SAAS,KAAK,MAAM,WAAW;EACjC;CACF,GAAG,CAAC,cAAc,CAAC;;;;;;CAOnB,MAAM,YAAY,OAAuB,IAAI;CAC7C,UAAU,YAAY,SAAS;;;;;;;;CAS/B,gBAAgB;EACd,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,OAAO;EAEZ,IAAI,CAAC,MAAM,SAAS,SAAS,aAAa,GAAG,MAAM,MAAM;EAEzD,aAAa;GACX,MAAM,SAAS,UAAU;GACzB,IAAI,kBAAkB,eAAe,OAAO,aAAa,OAAO,MAAM;EACxE;CACF,GAAG,CAAC,CAAC;;;;;;;;;CAUL,MAAM,iBAAiB,UAAyC;EAC9D,YAAY,KAAK;EACjB,IAAI,MAAM,QAAQ,YAAY,MAAM,kBAAkB;EAEtD,MAAM,SAAS,MAAM;EACrB,IAAI,EAAE,kBAAkB,SAAS,CAAC,SAAS,SAAS,SAAS,MAAM,GAAG;EAEtE,kBAAkB,KAAK;CACzB;CAEA,OAAO,aACL,oBAAC,OAAD;EACE,GAAI;EACJ,KAAK;EACL,MAAK;EACL,cAAW;EACX,UAAU;EACV,yBAAA;EACA,8BAA4B,kBAAkB,KAAA;EAC9C,WAAW;EACX,WAAW,GACT,yBACA,YACA,cACA,eACA,WACA,eAGA,oBACA,sBACA,mCACA,SACF;EAEC;CACE,CAAA,GACL,SAAS,IACX;AACF;;;AC/HA,MAAa,kBAAkB,OAAO,OAAO,qBAAqB;CAChE,QAAQ;CACR,MAAM;AACR,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { cn } from "./classNames-DcGnTh2N.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Content, Portal, Root, Trigger } from "@radix-ui/react-hover-card";
|
|
4
|
+
//#region src/components/HoverCard/HoverCardContent.tsx
|
|
5
|
+
const HoverCardContent = ({ ref, className, align = "center", sideOffset = 4, children, ...props }) => /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, {
|
|
6
|
+
ref,
|
|
7
|
+
align,
|
|
8
|
+
sideOffset,
|
|
9
|
+
"data-slot": "hover-card-content",
|
|
10
|
+
className: cn("tailwindcss-preflight", "tw:z-[1051]", "tw:box-border", "tw:border", "tw:rounded-popover", "tw:min-w-32", "tw:origin-(--radix-hover-card-content-transform-origin)", "tw:max-h-[var(--radix-hover-card-content-available-height)]", "tw:p-4", "tw:shadow-md", "tw:border-solid tw:border-border tw:bg-popover tw:text-popover-foreground", "tw:data-[side=bottom]:slide-in-from-top-2", "tw:data-[side=left]:slide-in-from-right-2", "tw:data-[side=right]:slide-in-from-left-2", "tw:data-[side=top]:slide-in-from-bottom-2", "tw:data-[state=open]:animate-in", "tw:data-[state=open]:fade-in-0", "tw:data-[state=open]:zoom-in-95", "tw:data-[state=closed]:animate-out", "tw:data-[state=closed]:fade-out-0", "tw:data-[state=closed]:zoom-out-95", "tw:[&_svg.lucide:not([class*='tw:size-'])]:size-4", "tw:[&_svg]:shrink-0", className),
|
|
11
|
+
...props,
|
|
12
|
+
children
|
|
13
|
+
}) });
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/components/HoverCard/HoverCard.tsx
|
|
16
|
+
const HoverCard = ({ openDelay = 200, closeDelay = 200, ...rest }) => /* @__PURE__ */ jsx(Root, {
|
|
17
|
+
...rest,
|
|
18
|
+
openDelay,
|
|
19
|
+
closeDelay
|
|
20
|
+
});
|
|
21
|
+
HoverCard.Content = HoverCardContent;
|
|
22
|
+
HoverCard.Trigger = Trigger;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { HoverCard };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=HoverCard-Cv5rmvJq.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HoverCard-Cv5rmvJq.js","names":[],"sources":["../src/components/HoverCard/HoverCardContent.tsx","../src/components/HoverCard/HoverCard.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport { Content, Portal } from '@radix-ui/react-hover-card';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof Content>;\n\nexport const HoverCardContent = ({\n ref,\n className,\n align = 'center',\n sideOffset = 4,\n children,\n ...props\n}: Props) => (\n <Portal>\n <Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n data-slot=\"hover-card-content\"\n className={cn(\n 'tailwindcss-preflight',\n 'tw:z-[1051]',\n\n // border\n 'tw:box-border',\n 'tw:border',\n 'tw:rounded-popover',\n\n // sizing\n 'tw:min-w-32',\n 'tw:origin-(--radix-hover-card-content-transform-origin)',\n 'tw:max-h-[var(--radix-hover-card-content-available-height)]',\n\n // padding + shared shadow\n 'tw:p-4',\n 'tw:shadow-md',\n\n // semantic floating-panel tokens\n 'tw:border-solid tw:border-border tw:bg-popover tw:text-popover-foreground',\n\n // directional animations\n 'tw:data-[side=bottom]:slide-in-from-top-2',\n 'tw:data-[side=left]:slide-in-from-right-2',\n 'tw:data-[side=right]:slide-in-from-left-2',\n 'tw:data-[side=top]:slide-in-from-bottom-2',\n\n // animations\n 'tw:data-[state=open]:animate-in',\n 'tw:data-[state=open]:fade-in-0',\n 'tw:data-[state=open]:zoom-in-95',\n 'tw:data-[state=closed]:animate-out',\n 'tw:data-[state=closed]:fade-out-0',\n 'tw:data-[state=closed]:zoom-out-95',\n\n // Default size for nested Lucide icons; callers can override on the icon.\n \"tw:[&_svg.lucide:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n\n className,\n )}\n {...props}\n >\n {children}\n </Content>\n </Portal>\n);\n","import type { ComponentProps } from 'react';\nimport { Root, Trigger } from '@radix-ui/react-hover-card';\n\nimport { HoverCardContent } from './HoverCardContent';\n\ntype Props = ComponentProps<typeof Root>;\n\nexport const HoverCard = ({ openDelay = 200, closeDelay = 200, ...rest }: Props) => (\n <Root {...rest} openDelay={openDelay} closeDelay={closeDelay} />\n);\n\nHoverCard.Content = HoverCardContent;\nHoverCard.Trigger = Trigger;\n"],"mappings":";;;;AAOA,MAAa,oBAAoB,EAC/B,KACA,WACA,QAAQ,UACR,aAAa,GACb,UACA,GAAG,YAEH,oBAAC,QAAD,EAAA,UACE,oBAAC,SAAD;CACO;CACE;CACK;CACZ,aAAU;CACV,WAAW,GACT,yBACA,eAGA,iBACA,aACA,sBAGA,eACA,2DACA,+DAGA,UACA,gBAGA,6EAGA,6CACA,6CACA,6CACA,6CAGA,mCACA,kCACA,mCACA,sCACA,qCACA,sCAGA,qDACA,uBAEA,SACF;CACA,GAAI;CAEH;AACM,CAAA,EACH,CAAA;;;AC3DV,MAAa,aAAa,EAAE,YAAY,KAAK,aAAa,KAAK,GAAG,WAChE,oBAAC,MAAD;CAAM,GAAI;CAAiB;CAAuB;AAAa,CAAA;AAGjE,UAAU,UAAU;AACpB,UAAU,UAAU"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { cn } from "./classNames-DcGnTh2N.js";
|
|
2
|
-
import { Tooltip } from "./utils-
|
|
3
|
-
import { ArgoDesignContext } from "./context-U293r3v-.js";
|
|
2
|
+
import { Tooltip } from "./utils-DwC9u0tM.js";
|
|
4
3
|
import { Check, Loader2, X } from "./icons-ZIeZXXS7.js";
|
|
5
|
-
import { Button } from "./Button-
|
|
6
|
-
import { Kbd, keys } from "./Kbd-
|
|
4
|
+
import { Button } from "./Button-BNkyYU8u.js";
|
|
5
|
+
import { Kbd, keys } from "./Kbd-CflKthfu.js";
|
|
7
6
|
import { useAutosizeInput } from "./internal/hooks/useAutosizeInput.js";
|
|
8
7
|
import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
9
8
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -356,10 +355,7 @@ const InlineEdit = ({ value, onChange, onSubmit, onCancel, isEditing, onEditStar
|
|
|
356
355
|
inert: !isEditing,
|
|
357
356
|
"aria-hidden": !isEditing || void 0,
|
|
358
357
|
className: cn(fill ? "tw:self-start" : "tw:self-center", !isEditing && "tw:max-w-0 tw:overflow-x-clip", stackButtons && isEditing && "tw:basis-full"),
|
|
359
|
-
children:
|
|
360
|
-
value: true,
|
|
361
|
-
children: buttons
|
|
362
|
-
})
|
|
358
|
+
children: buttons
|
|
363
359
|
})
|
|
364
360
|
]
|
|
365
361
|
});
|
|
@@ -367,4 +363,4 @@ const InlineEdit = ({ value, onChange, onSubmit, onCancel, isEditing, onEditStar
|
|
|
367
363
|
//#endregion
|
|
368
364
|
export { InlineEdit };
|
|
369
365
|
|
|
370
|
-
//# sourceMappingURL=InlineEdit-
|
|
366
|
+
//# sourceMappingURL=InlineEdit-D4P0SvCB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InlineEdit-D4P0SvCB.js","names":[],"sources":["../src/blocks/InlineEdit/InlineEdit.tsx"],"sourcesContent":["import { useEffect, useId, useLayoutEffect, useRef, useState } from 'react';\nimport type { ChangeEvent, FocusEvent, KeyboardEvent, MouseEvent, ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Kbd, keys } from '../../components/Kbd';\nimport { Tooltip } from '../../components/Tooltip';\nimport { useAutosizeInput } from '../../hooks/useAutosizeInput';\nimport { Check, Loader2, X } from '../../icons';\nimport { cn } from '../../utils';\n\n/** A sized `fill` row at least this wide shows Save / Cancel as text; a narrower one as icons. */\nconst LABELLED_BUTTONS_MIN_WIDTH = 480;\n/** Below this a `multiline` field keeps the row and Save / Cancel move under it. */\nconst INLINE_BUTTONS_MIN_WIDTH = 320;\n/** How long the field and the buttons take to open and close. */\nconst EXPAND_MS = 200;\n\ntype Size = 'auto' | 'sm' | 'md' | 'lg' | 'title';\n\n/**\n * Box and button height per size; the font is always the surrounding one.\n *\n * - Buttons take the box's height, not the brand's own button height, so the row lines up.\n * - The box overhangs its line by the same amount it pads it, so the line box never changes.\n * - `auto` scales the icon buttons with the text instead of picking a fixed height.\n */\n// Class names are spelled out in full: Tailwind only generates the ones it can read here.\nconst SIZES = {\n auto: { box: 'tw:py-px tw:-my-[2px]', icon: 'icon-xs', label: 'medium', fit: '', iconFit: '' },\n sm: {\n box: 'tw:py-[max(1px,calc((1.5rem-1lh)/2-1px))] tw:-my-[max(2px,calc((1.5rem-1lh)/2))]',\n icon: 'icon-xs',\n label: 'small',\n fit: 'tw:h-6 tw:min-h-6 tw:max-h-6',\n iconFit: 'tw:size-6',\n },\n md: {\n box: 'tw:py-[max(1px,calc((2rem-1lh)/2-1px))] tw:-my-[max(2px,calc((2rem-1lh)/2))]',\n icon: 'icon-sm',\n label: 'small',\n fit: 'tw:h-8 tw:min-h-8 tw:max-h-8',\n iconFit: 'tw:size-8',\n },\n lg: {\n box: 'tw:py-[max(1px,calc((2.5rem-1lh)/2-1px))] tw:-my-[max(2px,calc((2.5rem-1lh)/2))]',\n icon: 'icon',\n label: 'medium',\n fit: 'tw:h-10 tw:min-h-10 tw:max-h-10',\n iconFit: 'tw:size-10',\n },\n title: {\n box: 'tw:py-[max(1px,calc((2.5rem-1lh)/2-1px))] tw:-my-[max(2px,calc((2.5rem-1lh)/2))]',\n icon: 'icon',\n label: 'medium',\n fit: 'tw:h-10 tw:min-h-10 tw:max-h-10',\n iconFit: 'tw:size-10',\n },\n} as const satisfies Record<\n Size,\n { box: string; icon: string; label: string; fit: string; iconFit: string }\n>;\n\n// One box in view and edit; only its colours change, so nothing moves and the change can animate.\n// - 1px border + 5px padding = the 6px the box shifts left, so the text stays where it was.\n// - A shift, not a negative margin: that would shrink the width a fit-content parent gives it.\n// - `leading-[inherit]` beats the 1.5 a Tooltip trigger's scoped preflight would set.\nconst BOX_CLASS = cn(\n 'tw:relative tw:-left-1.5 tw:rounded-md tw:border tw:px-[5px] tw:leading-[inherit]',\n 'tw:transition-[border-color,background-color,box-shadow] tw:duration-150 tw:ease-out',\n);\n\nconst VIEW_BOX_CLASS = cn(\n 'tw:border-transparent',\n 'tw:hover:border-input tw:hover:bg-muted-foreground/10',\n 'tw:has-[:focus-visible]:border-input tw:has-[:focus-visible]:bg-muted-foreground/10',\n);\n\n// The field takes the surrounding typography instead of the browser's form-control defaults.\nconst FIELD_CLASS = cn(\n 'tw:m-0 tw:block tw:border-0 tw:bg-transparent tw:p-0 tw:outline-hidden',\n 'tw:[font:inherit] tw:[letter-spacing:inherit] tw:[color:inherit]',\n 'tw:placeholder:text-muted-foreground',\n);\n\n// `auto` icon buttons scale with the text: 24px beside body copy, ~33px beside a page title.\nconst AUTO_ICON_BUTTON_CLASS = 'tw:size-[max(1.5rem,1.1em)] tw:text-[length:inherit]';\n\nconst ShortcutLabel = ({ label, shortcut }: { label: string; shortcut: string }) => (\n <span className=\"tw:inline-flex tw:items-center tw:gap-2\">\n {label}\n <Kbd variant=\"primary\">{shortcut}</Kbd>\n </span>\n);\n\n// Keeps focus in the field, so pressing a button never blurs it into an early save first.\nconst keepFieldFocus = (event: MouseEvent) => event.preventDefault();\n\ntype Props = {\n /** The text shown, and the draft while editing. */\n value: string;\n onChange: (value: string) => void;\n /** Enter, Save, or a blur with a valid change. */\n onSubmit: () => void;\n /** Escape, Cancel, or leaving the field with nothing changed. */\n onCancel: () => void;\n isEditing: boolean;\n /** Opens the editor from view mode; omit when the caller opens it some other way. */\n onEditStart?: () => void;\n /** Whether `value` differs from the saved value; nothing to save while false. */\n isChanged: boolean;\n /** A save is in flight: buttons and keys are held until it settles. */\n isSaving?: boolean;\n /** Why the draft can't be saved; disables Save and becomes its tooltip. */\n invalidReason?: string | null;\n /** Renders the value as plain text. */\n readOnly?: boolean;\n /** Fills the row while editing (default); `false` keeps the field as wide as its text. */\n fill?: boolean;\n /** Long text wraps and the field grows a line at a time; without it the field stays one line. */\n multiline?: boolean;\n /** Box height and buttons: sm 24, md 32, lg and title 40px, or `auto` to follow the text. */\n size?: Size;\n /** One line with an ellipsis in view mode; otherwise up to two lines. */\n truncate?: boolean;\n placeholder?: string;\n /** Tooltip on the value in view mode. */\n editTooltip?: ReactNode;\n tooltipPlacement?: 'top' | 'bottom' | 'left' | 'right';\n maxLength?: number;\n /** Accessible name of the field; defaults to `placeholder`. */\n 'aria-label'?: string;\n className?: string;\n};\n\n/**\n * Click-to-edit text: a page title, an entity name, a short label in a row.\n *\n * - The caller owns the draft and the editing flag, so it can validate, save and fail on its own terms.\n * - Enter saves a change and closes an unchanged edit; Escape cancels.\n * - Not for multi-paragraph or markdown text: use `MarkdownEditor`.\n */\nexport const InlineEdit = ({\n value,\n onChange,\n onSubmit,\n onCancel,\n isEditing,\n onEditStart,\n isChanged,\n isSaving = false,\n invalidReason = null,\n readOnly = false,\n fill = true,\n multiline = false,\n size = 'auto',\n truncate = false,\n placeholder = 'Click to edit',\n editTooltip = 'Click to edit',\n tooltipPlacement = 'top',\n maxLength,\n 'aria-label': ariaLabel,\n className,\n}: Props) => {\n const formRef = useRef<HTMLFormElement>(null);\n const viewButtonRef = useRef<HTMLButtonElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const wasEditingRef = useRef(isEditing);\n const reasonId = useId();\n const { inputRef, inputStyle, sizerElement } = useAutosizeInput({ value, placeholder });\n const [rowWidth, setRowWidth] = useState(0);\n const boxRef = useRef<HTMLDivElement>(null);\n const buttonsRef = useRef<HTMLDivElement>(null);\n const boxWidthRef = useRef(0);\n // The width sizer mounts on first hover or focus, before the first open, not with every row.\n const [isPrimed, setIsPrimed] = useState(false);\n // Focus returning after an edit doesn't pop \"Click to edit\"; it shows again once the user moves on.\n const [isTipQuiet, setIsTipQuiet] = useState(false);\n\n const isValid = !invalidReason;\n const canSave = isChanged && isValid && !isSaving;\n // Text labels only beside a sized box: next to small `auto` text a 40px label would tower.\n const showLabels = fill && size !== 'auto' && rowWidth >= LABELLED_BUTTONS_MIN_WIDTH;\n const stackButtons = fill && multiline && rowWidth > 0 && rowWidth < INLINE_BUTTONS_MIN_WIDTH;\n const sizing = SIZES[size];\n\n useEffect(() => {\n const wasEditing = wasEditingRef.current;\n wasEditingRef.current = isEditing;\n\n if (isEditing) {\n const field = textareaRef.current ?? inputRef.current;\n field?.focus();\n field?.setSelectionRange(field.value.length, field.value.length);\n return;\n }\n\n if (!wasEditing) return;\n // oxlint-disable-next-line react-x/set-state-in-effect -- the close is a prop change, seen only here\n setIsTipQuiet(true);\n // Closing the editor removed the focused field; hand focus back to the value, not to <body>.\n if (!document.activeElement || document.activeElement === document.body) {\n viewButtonRef.current?.focus();\n }\n }, [isEditing, inputRef]);\n\n // Tracks the box's width, so a toggle knows where its animation starts.\n useLayoutEffect(() => {\n const box = boxRef.current;\n if (!box || typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver(() => {\n boxWidthRef.current = box.offsetWidth;\n });\n observer.observe(box);\n return () => observer.disconnect();\n }, []);\n\n // Grows the box from its text to the row and slides Save / Cancel open, then reverses both.\n // - Measured widths, not `fr` tracks: an `fr` track sized by its content doesn't transition.\n useLayoutEffect(() => {\n const box = boxRef.current;\n const buttons = buttonsRef.current;\n const from = boxWidthRef.current;\n if (!box || !buttons || !from) return;\n\n // A toggle mid-animation measures the box's own size, not the one the last animation holds.\n for (const running of box.getAnimations()) running.cancel();\n const to = box.offsetWidth;\n boxWidthRef.current = to;\n const reduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n if (reduceMotion || typeof box.animate !== 'function') return;\n\n const timing = { duration: EXPAND_MS, easing: 'ease-out' };\n if (from !== to) {\n // An open `fill` box is a growing flex item, which ignores `width`; `max-width` holds it.\n const property = fill && isEditing ? 'maxWidth' : 'width';\n const field = textareaRef.current;\n // One line while it grows, so the text doesn't wrap and unwrap as the box widens.\n if (field) field.style.whiteSpace = 'nowrap';\n const animation = box.animate(\n [{ [property]: `${from}px` }, { [property]: `${to}px` }],\n timing,\n );\n // A closing `fill` field holds its row until it has shrunk:\n // - `data-expanded` stays on until the animation ends;\n // - `data-settled` then marks that a rename closed here, so what the row hid fades back in.\n const heldRow = fill && !isEditing ? formRef.current : null;\n if (heldRow) heldRow.dataset.expanded = 'true';\n animation.onfinish = () => {\n if (field) field.style.whiteSpace = '';\n if (!heldRow) return;\n delete heldRow.dataset.expanded;\n heldRow.dataset.settled = 'true';\n };\n }\n\n // - Clips only sideways, so buttons taller than the line keep their borders.\n // - Open buttons aren't clipped at all, so their focus rings show.\n for (const running of buttons.getAnimations()) running.cancel();\n const buttonsWidth = `${buttons.scrollWidth}px`;\n buttons.style.overflowX = 'clip';\n buttons.animate(\n isEditing\n ? [{ maxWidth: '0px' }, { maxWidth: buttonsWidth }]\n : [{ maxWidth: buttonsWidth }, { maxWidth: '0px' }],\n timing,\n ).onfinish = () => {\n buttons.style.overflowX = '';\n };\n }, [isEditing, fill]);\n\n useLayoutEffect(() => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n\n const fitHeight = () => {\n textarea.style.height = 'auto';\n textarea.style.height = `${textarea.scrollHeight}px`;\n };\n fitHeight();\n if (typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver(fitHeight);\n observer.observe(textarea);\n return () => observer.disconnect();\n }, [isEditing, value]);\n\n useLayoutEffect(() => {\n const form = formRef.current;\n if (!fill || !isEditing || !form) return;\n\n // Measured before paint, so the buttons never render at one size and settle at another.\n // `offsetWidth` is the layout width: a scale transform (an opening modal) doesn't change it.\n // oxlint-disable-next-line react-x/set-state-in-effect -- a layout read has to happen before paint\n const fitButtons = (width: number) => setRowWidth(width);\n fitButtons(form.offsetWidth);\n if (typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver(() => fitButtons(form.offsetWidth));\n observer.observe(form);\n return () => observer.disconnect();\n }, [fill, isEditing]);\n\n if (readOnly) {\n return <span className={cn(truncate && 'tw:block tw:truncate', className)}>{value}</span>;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n event.stopPropagation();\n\n if (event.key === 'Escape') {\n event.preventDefault();\n if (!isSaving) onCancel();\n return;\n }\n\n if (event.key === 'Enter') {\n event.preventDefault();\n if (isSaving) return;\n if (!isChanged) onCancel();\n else if (isValid) onSubmit();\n }\n };\n\n const handleBlur = (event: FocusEvent<HTMLFormElement>) => {\n if (!isEditing || isSaving) return;\n // Focus left the window (resizing it, switching apps), not the field: keep editing.\n if (!document.hasFocus()) return;\n const next = event.relatedTarget;\n if (next instanceof Node && event.currentTarget.contains(next)) return;\n if (!isChanged) onCancel();\n else if (isValid) onSubmit();\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n onChange(multiline ? event.target.value.replace(/[\\r\\n]+/g, ' ') : event.target.value);\n };\n\n const fieldProps = {\n value,\n placeholder,\n maxLength,\n readOnly: isSaving,\n 'aria-label': ariaLabel ?? placeholder,\n 'aria-invalid': !isValid || undefined,\n 'aria-describedby': invalidReason ? reasonId : undefined,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onKeyUp: (event: KeyboardEvent) => event.stopPropagation(),\n onClick: (event: MouseEvent) => event.stopPropagation(),\n };\n\n const saveTooltip = (() => {\n if (isSaving) return 'Saving…';\n if (!isChanged) return 'No changes to save';\n if (invalidReason) return invalidReason;\n return <ShortcutLabel label=\"Save\" shortcut={keys.enter.symbol} />;\n })();\n\n const iconButtonClass = size === 'auto' ? AUTO_ICON_BUTTON_CLASS : sizing.iconFit;\n // Labelled buttons match the box's height whatever the brand's own button height is.\n const labelButtonClass = sizing.fit;\n const buttonSize = showLabels ? sizing.label : sizing.icon;\n\n const view = (\n <Tooltip\n tooltip={editTooltip}\n placement={tooltipPlacement}\n forceHide={isTipQuiet}\n triggerAsChild\n >\n <button\n ref={viewButtonRef}\n type=\"button\"\n data-testid=\"inline-edit-trigger\"\n className={cn(\n 'tw:block tw:max-w-full tw:cursor-text tw:text-left tw:outline-hidden',\n 'tw:[font:inherit] tw:leading-[inherit] tw:[color:inherit]',\n // The whole box takes the click, not just the glyphs.\n 'tw:after:absolute tw:after:inset-0',\n truncate && 'tw:min-w-0 tw:truncate',\n )}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onEditStart?.();\n }}\n onBlur={() => setIsTipQuiet(false)}\n onPointerLeave={() => setIsTipQuiet(false)}\n >\n {value ? (\n <span className={cn(!truncate && !multiline && 'tw:line-clamp-2', 'tw:break-words')}>\n {value}\n </span>\n ) : (\n <span className=\"tw:text-muted-foreground\">{placeholder}</span>\n )}\n </button>\n </Tooltip>\n );\n\n const field = multiline ? (\n <textarea\n ref={textareaRef}\n rows={1}\n className={cn(FIELD_CLASS, 'tw:w-full tw:resize-none tw:overflow-hidden tw:break-words')}\n {...fieldProps}\n />\n ) : (\n <input\n ref={inputRef}\n type=\"text\"\n className={cn(FIELD_CLASS, fill ? 'tw:w-full' : 'tw:max-w-full')}\n style={fill ? undefined : inputStyle}\n {...fieldProps}\n />\n );\n\n const buttons = (\n <div\n className={cn(\n 'tw:flex tw:items-center tw:gap-1',\n // - The gap lives inside the collapsing track, so a closed field leaves no trailing space.\n // - Beside the field the row is one line tall, so taller buttons overhang it evenly.\n stackButtons ? 'tw:pt-2' : 'tw:h-[1lh] tw:pl-2',\n 'tw:transition-opacity tw:duration-200 tw:ease-out',\n isEditing ? 'tw:opacity-100' : 'tw:opacity-0',\n )}\n >\n <Tooltip tooltip={saveTooltip} placement=\"top\" triggerAsChild>\n <span className={cn('tw:inline-flex', !canSave && 'tw:cursor-not-allowed')}>\n <Button\n type=\"submit\"\n variant=\"primary\"\n size={buttonSize}\n aria-label={showLabels ? undefined : 'Save'}\n isLoading={!showLabels && isSaving}\n disabled={!canSave}\n onMouseDown={keepFieldFocus}\n className={cn(\n 'tw:transition-colors',\n showLabels ? labelButtonClass : iconButtonClass,\n !canSave && 'tw:pointer-events-none',\n )}\n >\n {showLabels ? (\n // The spinner overlays the label, so Save keeps its width and Cancel stays put.\n <>\n <span className={cn(isSaving && 'tw:invisible')}>Save</span>\n {isSaving && <Loader2 className=\"tw:absolute tw:size-4 tw:animate-spin\" />}\n </>\n ) : (\n <Check />\n )}\n </Button>\n </span>\n </Tooltip>\n <Tooltip\n tooltip={<ShortcutLabel label=\"Cancel\" shortcut=\"Esc\" />}\n placement=\"top\"\n triggerAsChild\n >\n <Button\n type=\"button\"\n variant=\"outline\"\n size={buttonSize}\n aria-label={showLabels ? undefined : 'Cancel'}\n disabled={isSaving}\n className={cn('tw:transition-colors', showLabels ? labelButtonClass : iconButtonClass)}\n onMouseDown={keepFieldFocus}\n onClick={(event) => {\n event.stopPropagation();\n onCancel();\n }}\n >\n {showLabels ? 'Cancel' : <X />}\n </Button>\n </Tooltip>\n </div>\n );\n\n return (\n <form\n ref={formRef}\n data-slot=\"inline-edit\"\n data-state={isEditing ? 'edit' : 'view'}\n data-expanded={(fill && isEditing) || undefined}\n aria-busy={isSaving || undefined}\n className={cn(\n 'tw:leading-[inherit]',\n // Top-aligned: Save / Cancel sit on the first line however many lines the text wraps to.\n fill && isEditing\n ? 'tw:flex tw:w-full tw:min-w-0 tw:items-start'\n : 'tw:inline-flex tw:max-w-full tw:items-center',\n // Only a wrapping title moves Save / Cancel under the field; one line keeps them beside it.\n fill && isEditing && multiline && 'tw:flex-wrap',\n truncate && !isEditing && 'tw:flex tw:min-w-0',\n className,\n )}\n onSubmit={(event) => {\n event.preventDefault();\n if (canSave) onSubmit();\n }}\n onBlur={handleBlur}\n // Escape on Save / Cancel cancels too; the field handles its own keys first.\n onKeyDown={(event) => {\n if (event.key !== 'Escape' || !isEditing) return;\n event.preventDefault();\n event.stopPropagation();\n if (!isSaving) onCancel();\n }}\n >\n <div\n ref={boxRef}\n onPointerEnter={() => setIsPrimed(true)}\n onFocus={() => setIsPrimed(true)}\n className={cn(\n BOX_CLASS,\n sizing.box,\n 'tw:min-w-0',\n fill && isEditing && 'tw:flex-1',\n fill && isEditing && multiline && 'tw:min-w-[min(100%,12rem)]',\n !isEditing && VIEW_BOX_CLASS,\n isEditing &&\n (isValid\n ? 'tw:border-ring tw:bg-input-background tw:ring-3 tw:ring-ring/25'\n : 'tw:border-destructive tw:bg-input-background tw:ring-3 tw:ring-destructive/20'),\n isEditing && !fill && !multiline && 'tw:inline-flex',\n )}\n >\n {isEditing ? field : view}\n {/* Measures from first hover, so the first open already knows the field's width. */}\n {!fill && !multiline && (isPrimed || isEditing) && (\n <span aria-hidden className=\"tw:absolute tw:size-0 tw:overflow-hidden\">\n {sizerElement}\n </span>\n )}\n </div>\n {isEditing && invalidReason && (\n <span id={reasonId} className=\"tw:sr-only\" aria-live=\"polite\">\n {invalidReason}\n </span>\n )}\n {/* Stays mounted, inert while closed, so it can slide shut after Save / Cancel. */}\n <div\n ref={buttonsRef}\n inert={!isEditing}\n aria-hidden={!isEditing || undefined}\n className={cn(\n fill ? 'tw:self-start' : 'tw:self-center',\n !isEditing && 'tw:max-w-0 tw:overflow-x-clip',\n stackButtons && isEditing && 'tw:basis-full',\n )}\n >\n {buttons}\n </div>\n </form>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { cn } from "./classNames-DcGnTh2N.js";
|
|
2
|
-
import {
|
|
3
|
-
import { Button } from "./Button-D2JqBAq7.js";
|
|
2
|
+
import { Button } from "./Button-BNkyYU8u.js";
|
|
4
3
|
import { cva } from "class-variance-authority";
|
|
5
4
|
import { jsx } from "react/jsx-runtime";
|
|
6
5
|
import TextareaAutosize from "react-textarea-autosize";
|
|
@@ -103,17 +102,22 @@ const inputGroupVariants = cva([
|
|
|
103
102
|
"tw:flex",
|
|
104
103
|
"tw:items-center",
|
|
105
104
|
"tw:min-w-0",
|
|
106
|
-
"tw:rounded",
|
|
105
|
+
"tw:rounded-[var(--radius-lg,0.25rem)]",
|
|
107
106
|
"tw:border",
|
|
108
107
|
"tw:border-solid",
|
|
109
108
|
"tw:border-input",
|
|
109
|
+
"tw:bg-muted",
|
|
110
110
|
"tw:text-foreground",
|
|
111
111
|
"tw:transition",
|
|
112
112
|
"tw:has-[:is(input,textarea):focus]:ring-4",
|
|
113
|
-
"tw:has-[:is(input,textarea)[readonly]]:bg-muted",
|
|
114
113
|
"tw:has-[:is(input,textarea)[readonly]]:focus-within:ring-0",
|
|
115
114
|
"tw:has-[:is(input,textarea)[readonly]]:border-input",
|
|
115
|
+
"tw:has-[:is(input,textarea)[readonly]:focus]:border-input",
|
|
116
116
|
"tw:has-[:is(input,textarea):disabled]:cursor-not-allowed",
|
|
117
|
+
"tw:has-[:is(input,textarea):disabled]:opacity-disabled",
|
|
118
|
+
"tw:has-[:is(input,textarea)[aria-invalid=true]]:border-destructive",
|
|
119
|
+
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:border-destructive",
|
|
120
|
+
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:ring-destructive/20",
|
|
117
121
|
"tw:has-[textarea]:items-start",
|
|
118
122
|
"tw:has-[[data-align=block-start]:not(:empty)]:flex-wrap",
|
|
119
123
|
"tw:has-[[data-align=block-end]:not(:empty)]:flex-wrap",
|
|
@@ -123,170 +127,59 @@ const inputGroupVariants = cva([
|
|
|
123
127
|
"tw:[&>input]:has-[[data-align=block-end]:not(:empty)]:flex-1",
|
|
124
128
|
"tw:[&_input]:px-4",
|
|
125
129
|
"tw:[&>input]:has-[[data-align=inline-start]:not(:empty)]:pl-2",
|
|
126
|
-
"tw:[&>input]:has-[[data-align=inline-end]:not(:empty)]:pr-2"
|
|
130
|
+
"tw:[&>input]:has-[[data-align=inline-end]:not(:empty)]:pr-2",
|
|
131
|
+
"tw:[&_:is(input,textarea)]:py-2",
|
|
132
|
+
"tw:[&_:is(input,textarea)]:leading-[18px]",
|
|
133
|
+
"tw:[&_textarea]:!min-h-[calc(2.25rem-2px)]"
|
|
127
134
|
], {
|
|
128
135
|
defaultVariants: {
|
|
129
|
-
variant: "primary",
|
|
130
136
|
state: "default",
|
|
131
|
-
sizing: "medium",
|
|
132
137
|
focusVariant: "default"
|
|
133
138
|
},
|
|
134
|
-
compoundVariants: [
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
className: ["tw:bg-warning-100", "tw:text-neutral-800"]
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
variant: "primary",
|
|
147
|
-
state: "default",
|
|
148
|
-
focusVariant: "off",
|
|
149
|
-
className: ["tw:has-[:is(input,textarea):focus]:border-neutral-200"]
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
variant: "secondary",
|
|
153
|
-
state: "default",
|
|
154
|
-
focusVariant: "off",
|
|
155
|
-
className: ["tw:has-[:is(input,textarea):focus]:border-secondary"]
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
variant: ["primary", "secondary"],
|
|
159
|
-
state: "error",
|
|
160
|
-
focusVariant: "on",
|
|
161
|
-
className: ["tw:!border-error-500", "tw:!ring-error-200"]
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
variant: ["primary", "secondary"],
|
|
165
|
-
state: "warning",
|
|
166
|
-
focusVariant: "on",
|
|
167
|
-
className: ["tw:!border-warning-500", "tw:!ring-warning-200"]
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
variant: "argo",
|
|
171
|
-
state: "default",
|
|
172
|
-
className: ["tw:has-[:is(input,textarea):focus]:border-primary", "tw:has-[:is(input,textarea):focus]:ring-ring/50"]
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
variant: "argo",
|
|
176
|
-
state: "error",
|
|
177
|
-
className: [
|
|
178
|
-
"tw:border-destructive",
|
|
179
|
-
"tw:has-[:is(input,textarea):focus]:border-destructive",
|
|
180
|
-
"tw:has-[:is(input,textarea):focus]:ring-destructive/20"
|
|
181
|
-
]
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
variant: "argo",
|
|
185
|
-
focusVariant: "on",
|
|
186
|
-
className: ["tw:!border-primary", "tw:!ring-ring/50"]
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
variant: "argo",
|
|
190
|
-
state: "error",
|
|
191
|
-
focusVariant: "on",
|
|
192
|
-
className: ["tw:!border-destructive", "tw:!ring-destructive/20"]
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
variant: "argo",
|
|
196
|
-
state: "default",
|
|
197
|
-
focusVariant: "off",
|
|
198
|
-
className: ["tw:has-[:is(input,textarea):focus]:border-input"]
|
|
199
|
-
}
|
|
200
|
-
],
|
|
139
|
+
compoundVariants: [{
|
|
140
|
+
state: "error",
|
|
141
|
+
focusVariant: "on",
|
|
142
|
+
className: ["tw:!border-destructive", "tw:!ring-destructive/20"]
|
|
143
|
+
}, {
|
|
144
|
+
state: "default",
|
|
145
|
+
focusVariant: "off",
|
|
146
|
+
className: ["tw:has-[:is(input,textarea):focus]:border-input"]
|
|
147
|
+
}],
|
|
201
148
|
variants: {
|
|
202
149
|
focusVariant: {
|
|
203
150
|
default: [],
|
|
204
151
|
on: [
|
|
205
|
-
"tw:!border-
|
|
206
|
-
"tw:!ring-ring/
|
|
152
|
+
"tw:!border-primary",
|
|
153
|
+
"tw:!ring-ring/50",
|
|
207
154
|
"tw:!ring-4"
|
|
208
155
|
],
|
|
209
156
|
off: ["tw:has-[:is(input,textarea):focus]:!ring-0"]
|
|
210
157
|
},
|
|
211
|
-
variant: {
|
|
212
|
-
primary: [
|
|
213
|
-
"tw:bg-input-background",
|
|
214
|
-
"tw:text-foreground",
|
|
215
|
-
"tw:has-[:is(input,textarea):disabled]:opacity-40",
|
|
216
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]]:border-error-500",
|
|
217
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:border-error-500",
|
|
218
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:ring-error-200"
|
|
219
|
-
],
|
|
220
|
-
secondary: [
|
|
221
|
-
"tw:bg-secondary",
|
|
222
|
-
"tw:border-secondary",
|
|
223
|
-
"tw:has-[:is(input,textarea):disabled]:opacity-40",
|
|
224
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]]:border-error-500",
|
|
225
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:border-error-500",
|
|
226
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:ring-error-200"
|
|
227
|
-
],
|
|
228
|
-
argo: [
|
|
229
|
-
"tw:rounded-[var(--radius-lg,0.25rem)]",
|
|
230
|
-
"tw:bg-muted",
|
|
231
|
-
"tw:border-input",
|
|
232
|
-
"tw:text-foreground",
|
|
233
|
-
"tw:has-[:is(input,textarea):disabled]:opacity-disabled",
|
|
234
|
-
"tw:has-[:is(input,textarea)[readonly]]:bg-muted",
|
|
235
|
-
"tw:has-[:is(input,textarea)[readonly]]:border-input",
|
|
236
|
-
"tw:has-[:is(input,textarea)[readonly]:focus]:border-input",
|
|
237
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]]:border-destructive",
|
|
238
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:border-destructive",
|
|
239
|
-
"tw:has-[:is(input,textarea)[aria-invalid=true]:focus]:ring-destructive/20"
|
|
240
|
-
]
|
|
241
|
-
},
|
|
242
|
-
sizing: {
|
|
243
|
-
default: [
|
|
244
|
-
"tw:[&_:is(input,textarea)]:py-2.5",
|
|
245
|
-
"tw:[&_:is(input,textarea)]:leading-[18px]",
|
|
246
|
-
"tw:[&_textarea]:!min-h-[calc(2.5rem-2px)]"
|
|
247
|
-
],
|
|
248
|
-
small: [
|
|
249
|
-
"tw:[&_:is(input,textarea)]:py-2",
|
|
250
|
-
"tw:[&_:is(input,textarea)]:leading-[16px]",
|
|
251
|
-
"tw:[&_textarea]:!min-h-[calc(2rem-2px)]"
|
|
252
|
-
],
|
|
253
|
-
medium: [
|
|
254
|
-
"tw:[&_:is(input,textarea)]:py-2",
|
|
255
|
-
"tw:[&_:is(input,textarea)]:leading-[18px]",
|
|
256
|
-
"tw:[&_textarea]:!min-h-[calc(2.25rem-2px)]"
|
|
257
|
-
]
|
|
258
|
-
},
|
|
259
158
|
state: {
|
|
260
|
-
default: ["tw:has-[:is(input,textarea):focus]:border-
|
|
159
|
+
default: ["tw:has-[:is(input,textarea):focus]:border-primary", "tw:has-[:is(input,textarea):focus]:ring-ring/50"],
|
|
261
160
|
error: [
|
|
262
|
-
"tw:border-
|
|
263
|
-
"tw:has-[:is(input,textarea):focus]:border-
|
|
264
|
-
"tw:has-[:is(input,textarea):focus]:ring-
|
|
161
|
+
"tw:border-destructive",
|
|
162
|
+
"tw:has-[:is(input,textarea):focus]:border-destructive",
|
|
163
|
+
"tw:has-[:is(input,textarea):focus]:ring-destructive/20"
|
|
265
164
|
],
|
|
266
165
|
warning: [
|
|
267
166
|
"tw:border-warning-500",
|
|
268
167
|
"tw:has-[:is(input,textarea):focus]:border-warning-500",
|
|
269
|
-
"tw:has-[:is(input,textarea):focus]:ring-warning
|
|
168
|
+
"tw:has-[:is(input,textarea):focus]:ring-warning/20"
|
|
270
169
|
]
|
|
271
170
|
}
|
|
272
171
|
}
|
|
273
172
|
});
|
|
274
|
-
const InputGroupRoot = ({ ref, children, state,
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
className
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
focusVariant,
|
|
285
|
-
className
|
|
286
|
-
})),
|
|
287
|
-
children
|
|
288
|
-
});
|
|
289
|
-
};
|
|
173
|
+
const InputGroupRoot = ({ ref, children, state, focusVariant, className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
174
|
+
...props,
|
|
175
|
+
ref,
|
|
176
|
+
className: cn(inputGroupVariants({
|
|
177
|
+
state,
|
|
178
|
+
focusVariant,
|
|
179
|
+
className
|
|
180
|
+
})),
|
|
181
|
+
children
|
|
182
|
+
});
|
|
290
183
|
const InputGroup = InputGroupRoot;
|
|
291
184
|
InputGroup.Input = InputGroupInput;
|
|
292
185
|
InputGroup.Addon = InputGroupAddon;
|
|
@@ -296,4 +189,4 @@ InputGroup.Text = InputGroupText;
|
|
|
296
189
|
//#endregion
|
|
297
190
|
export { InputGroup };
|
|
298
191
|
|
|
299
|
-
//# sourceMappingURL=InputGroup-
|
|
192
|
+
//# sourceMappingURL=InputGroup-CZv_7QlM.js.map
|