@keboola/design 15.0.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +6 -5
- package/CHANGELOG.md +94 -0
- package/COMPONENT-API.md +62 -61
- package/dist/{AIKit-CaAW4GLx.js → AIKit-Cf5plya2.js} +381 -224
- package/dist/AIKit-Cf5plya2.js.map +1 -0
- package/dist/{Alert-Chz6KZ7e.js → Alert-DziS8n1H.js} +12 -19
- package/dist/{Alert-Chz6KZ7e.js.map → Alert-DziS8n1H.js.map} +1 -1
- package/dist/{AlertModal-D4AtpvLS.js → AlertModal-De04fFoy.js} +16 -26
- package/dist/AlertModal-De04fFoy.js.map +1 -0
- package/dist/{AppShell-C8V1KRr_.js → AppShell-BUa3U7-e.js} +6 -9
- package/dist/{AppShell-C8V1KRr_.js.map → AppShell-BUa3U7-e.js.map} +1 -1
- package/dist/{AutoSaveTextarea-BbMhC5Aq.js → AutoSaveTextarea-CXHOQSun.js} +4 -5
- package/dist/{AutoSaveTextarea-BbMhC5Aq.js.map → AutoSaveTextarea-CXHOQSun.js.map} +1 -1
- package/dist/{Badge-5GHIsgRS.js → Badge-CFRhducL.js} +18 -23
- package/dist/Badge-CFRhducL.js.map +1 -0
- package/dist/{BrandEditor-CTGtQUFZ.js → BrandEditor-hiLBX7az.js} +16 -23
- package/dist/{BrandEditor-CTGtQUFZ.js.map → BrandEditor-hiLBX7az.js.map} +1 -1
- package/dist/{BrandLogo-DkESE19K.js → BrandLogo-Dn7hhp2c.js} +4 -5
- package/dist/{BrandLogo-DkESE19K.js.map → BrandLogo-Dn7hhp2c.js.map} +1 -1
- package/dist/{Breadcrumb-B2YSNON4.js → Breadcrumb-uGFEIjFF.js} +17 -28
- package/dist/{Breadcrumb-B2YSNON4.js.map → Breadcrumb-uGFEIjFF.js.map} +1 -1
- package/dist/{Button-BNkyYU8u.js → Button-DbvGzEDb.js} +24 -20
- package/dist/Button-DbvGzEDb.js.map +1 -0
- package/dist/{Calendar-BnKi1kPu.js → Calendar-lJBTETbk.js} +752 -905
- package/dist/Calendar-lJBTETbk.js.map +1 -0
- package/dist/{Card-DxjGiqH8.js → Card-VIPfOVW5.js} +8 -14
- package/dist/{Card-DxjGiqH8.js.map → Card-VIPfOVW5.js.map} +1 -1
- package/dist/{Checkbox-CHDDJyAA.js → Checkbox-B2jLlyaO.js} +6 -8
- package/dist/{Checkbox-CHDDJyAA.js.map → Checkbox-B2jLlyaO.js.map} +1 -1
- package/dist/{Clipboard-DlwVZS1P.js → Clipboard-fAkDdpEu.js} +4 -5
- package/dist/{Clipboard-DlwVZS1P.js.map → Clipboard-fAkDdpEu.js.map} +1 -1
- package/dist/{ClipboardButton-B1Hr_n_Z.js → ClipboardButton-71Ugbl8c.js} +6 -8
- package/dist/{ClipboardButton-B1Hr_n_Z.js.map → ClipboardButton-71Ugbl8c.js.map} +1 -1
- package/dist/{CodeEditor-DVSPdfdo.js → CodeEditor-D_b-ZCng.js} +19 -31
- package/dist/{CodeEditor-DVSPdfdo.js.map → CodeEditor-D_b-ZCng.js.map} +1 -1
- package/dist/{Collapsible-DD4xTL75.js → Collapsible-zsXk4Vpp.js} +5 -8
- package/dist/{Collapsible-DD4xTL75.js.map → Collapsible-zsXk4Vpp.js.map} +1 -1
- package/dist/{ColorInput-B_eZIu39.js → ColorInput-Cjr1jkvy.js} +9 -12
- package/dist/{ColorInput-B_eZIu39.js.map → ColorInput-Cjr1jkvy.js.map} +1 -1
- package/dist/{ColorModeSwitch-B6UEzG0H.js → ColorModeSwitch-CuPYnJ2V.js} +5 -6
- package/dist/{ColorModeSwitch-B6UEzG0H.js.map → ColorModeSwitch-CuPYnJ2V.js.map} +1 -1
- package/dist/{Combobox-CaKqgstG.js → Combobox-DYjvYgl3.js} +38 -67
- package/dist/Combobox-DYjvYgl3.js.map +1 -0
- package/dist/{Command-DhXmqFLT.js → Command-BcTb6GsR.js} +14 -24
- package/dist/{Command-DhXmqFLT.js.map → Command-BcTb6GsR.js.map} +1 -1
- package/dist/{CopyField-D0Pg4Z0R.js → CopyField-CnwAvQz9.js} +16 -28
- package/dist/{CopyField-D0Pg4Z0R.js.map → CopyField-CnwAvQz9.js.map} +1 -1
- package/dist/{DateInput-BgbMDJkm.js → DateInput-DJNX7Vdx.js} +8 -10
- package/dist/{DateInput-BgbMDJkm.js.map → DateInput-DJNX7Vdx.js.map} +1 -1
- package/dist/{DatePicker-BXpDRo-R.js → DatePicker-CI59gF3S.js} +4 -5
- package/dist/{DatePicker-BXpDRo-R.js.map → DatePicker-CI59gF3S.js.map} +1 -1
- package/dist/{DateRangeInput-BW0-_jV0.js → DateRangeInput-B3g8cyS0.js} +8 -10
- package/dist/{DateRangeInput-BW0-_jV0.js.map → DateRangeInput-B3g8cyS0.js.map} +1 -1
- package/dist/{DateRangePicker-C4-DoWac.js → DateRangePicker-48yOB2qV.js} +9 -10
- package/dist/{DateRangePicker-C4-DoWac.js.map → DateRangePicker-48yOB2qV.js.map} +1 -1
- package/dist/{DiffView-Dy4z-n-1.js → DiffView-DITZdVbh.js} +7 -12
- package/dist/{DiffView-Dy4z-n-1.js.map → DiffView-DITZdVbh.js.map} +1 -1
- package/dist/{DropdownMenu-CcVbZ_5u.js → DropdownMenu-Ba9atqDa.js} +21 -37
- package/dist/DropdownMenu-Ba9atqDa.js.map +1 -0
- package/dist/{FieldBox-BrxLkY9C.js → FieldBox-DdSdJ3ZN.js} +6 -10
- package/dist/{FieldBox-BrxLkY9C.js.map → FieldBox-DdSdJ3ZN.js.map} +1 -1
- package/dist/{FieldItem-BHUqgSO1.js → FieldItem-D7eCMfMB.js} +6 -8
- package/dist/{FieldItem-BHUqgSO1.js.map → FieldItem-D7eCMfMB.js.map} +1 -1
- package/dist/{FieldItem-CPN1xjN5.d.ts → FieldItem-fqm3CNR8.d.ts} +7 -6
- package/dist/{FileUpload-BYFONpEl.js → FileUpload-DskvxhAr.js} +25 -45
- package/dist/{FileUpload-BYFONpEl.js.map → FileUpload-DskvxhAr.js.map} +1 -1
- package/dist/{Form-CAofWyMI.js → Form-BUNW7nlt.js} +24 -38
- package/dist/{Form-CAofWyMI.js.map → Form-BUNW7nlt.js.map} +1 -1
- package/dist/{FormGroup-V5kIgQRN.js → FormGroup-QJB21LKp.js} +12 -20
- package/dist/{FormGroup-V5kIgQRN.js.map → FormGroup-QJB21LKp.js.map} +1 -1
- package/dist/{FullScreenModal-DAvvlGOz.js → FullScreenModal-RzY5XxiG.js} +8 -12
- package/dist/{FullScreenModal-DAvvlGOz.js.map → FullScreenModal-RzY5XxiG.js.map} +1 -1
- package/dist/HoverCard-OGWKRXJ7.js +24 -0
- package/dist/HoverCard-OGWKRXJ7.js.map +1 -0
- package/dist/{InlineEdit-D4P0SvCB.js → InlineEdit-CXL0ZslO.js} +7 -8
- package/dist/{InlineEdit-D4P0SvCB.js.map → InlineEdit-CXL0ZslO.js.map} +1 -1
- package/dist/{InputGroup-CZv_7QlM.js → InputGroup-BWeanEo7.js} +9 -15
- package/dist/{InputGroup-CZv_7QlM.js.map → InputGroup-BWeanEo7.js.map} +1 -1
- package/dist/{Kbd-CflKthfu.js → Kbd-BprYCICe.js} +8 -13
- package/dist/{Kbd-CflKthfu.js.map → Kbd-BprYCICe.js.map} +1 -1
- package/dist/{MarkedText-DlmlJO0u.js → MarkedText-BrganZ_V.js} +4 -6
- package/dist/{MarkedText-DlmlJO0u.js.map → MarkedText-BrganZ_V.js.map} +1 -1
- package/dist/{MermaidDiagram-Te-5gOCU.js → MermaidDiagram-E3azndPk.js} +9 -11
- package/dist/{MermaidDiagram-Te-5gOCU.js.map → MermaidDiagram-E3azndPk.js.map} +1 -1
- package/dist/{Modal-CbUz-5YH.js → Modal-Cf_kPEBW.js} +14 -22
- package/dist/Modal-Cf_kPEBW.js.map +1 -0
- package/dist/{ModalTitle-cy0Ht9VY.js → ModalTitle-7vgpfc6B.js} +6 -9
- package/dist/ModalTitle-7vgpfc6B.js.map +1 -0
- package/dist/{MultiActionButtonGroup-Dzig87s1.js → MultiActionButtonGroup-8WQwL4UQ.js} +6 -8
- package/dist/{MultiActionButtonGroup-Dzig87s1.js.map → MultiActionButtonGroup-8WQwL4UQ.js.map} +1 -1
- package/dist/{Navbar-DHUS7XiU.js → Navbar-CRjxVboE.js} +13 -22
- package/dist/{Navbar-DHUS7XiU.js.map → Navbar-CRjxVboE.js.map} +1 -1
- package/dist/{OtpInput-CY8yCaJk.js → OtpInput-C5plPzGU.js} +7 -11
- package/dist/{OtpInput-CY8yCaJk.js.map → OtpInput-C5plPzGU.js.map} +1 -1
- package/dist/{PageHeader-CL1A6jFM.js → PageHeader-DosMyar2.js} +6 -10
- package/dist/{PageHeader-CL1A6jFM.js.map → PageHeader-DosMyar2.js.map} +1 -1
- package/dist/{PageLayout-C9aXTpqV.js → PageLayout-LcvJccOW.js} +5 -8
- package/dist/{PageLayout-C9aXTpqV.js.map → PageLayout-LcvJccOW.js.map} +1 -1
- package/dist/{PageToolbar-DJ5tdYla.js → PageToolbar-By2HznxO.js} +8 -10
- package/dist/{PageToolbar-DJ5tdYla.js.map → PageToolbar-By2HznxO.js.map} +1 -1
- package/dist/{Pagination-D27x5KmH.js → Pagination-DrXTrvfD.js} +11 -18
- package/dist/{Pagination-D27x5KmH.js.map → Pagination-DrXTrvfD.js.map} +1 -1
- package/dist/{Popconfirm-DwLCYNaF.js → Popconfirm-BJuDOHdv.js} +46 -25
- package/dist/Popconfirm-BJuDOHdv.js.map +1 -0
- package/dist/{Popover-DtUDwUVO.js → Popover-DhOPlWgF.js} +5 -7
- package/dist/Popover-DhOPlWgF.js.map +1 -0
- package/dist/{RadioGroup-B0TwHjBb.js → RadioGroup-B9oC8P15.js} +12 -18
- package/dist/{RadioGroup-B0TwHjBb.js.map → RadioGroup-B9oC8P15.js.map} +1 -1
- package/dist/{Resizable-D8zs0kcq.js → Resizable-Co-L3qg7.js} +4 -6
- package/dist/{Resizable-D8zs0kcq.js.map → Resizable-Co-L3qg7.js.map} +1 -1
- package/dist/{Search-vyZwGKMU.js → Search-OgaNjqQM.js} +26 -21
- package/dist/Search-OgaNjqQM.js.map +1 -0
- package/dist/{SearchInput-DyYXyw3u.js → SearchInput-eLS-uvOn.js} +18 -29
- package/dist/SearchInput-eLS-uvOn.js.map +1 -0
- package/dist/{SectionNav-tLK3iF6c.js → SectionNav-L81iJBo3.js} +11 -14
- package/dist/{SectionNav-tLK3iF6c.js.map → SectionNav-L81iJBo3.js.map} +1 -1
- package/dist/{Select-B22hB_-w.js → Select-DRdkdzBp.js} +29 -26
- package/dist/Select-DRdkdzBp.js.map +1 -0
- package/dist/{Sheet-0TWKTqid.js → Sheet-DVb4XoJ5.js} +13 -20
- package/dist/Sheet-DVb4XoJ5.js.map +1 -0
- package/dist/{Sidebar-C5hdANBU.js → Sidebar-DYvodJWN.js} +43 -75
- package/dist/{Sidebar-C5hdANBU.js.map → Sidebar-DYvodJWN.js.map} +1 -1
- package/dist/{Slider-DrcsM8_G.js → Slider-B9IskDxf.js} +8 -12
- package/dist/{Slider-DrcsM8_G.js.map → Slider-B9IskDxf.js.map} +1 -1
- package/dist/{Stepper-CQrUPVFL.js → Stepper-D7VspVEt.js} +11 -19
- package/dist/{Stepper-CQrUPVFL.js.map → Stepper-D7VspVEt.js.map} +1 -1
- package/dist/{Switch-DccpSpzC.js → Switch-DONWW7ju.js} +4 -6
- package/dist/{Switch-DccpSpzC.js.map → Switch-DONWW7ju.js.map} +1 -1
- package/dist/{Table-CilEvpMq.js → Table-BwgBm3hJ.js} +12 -21
- package/dist/{Table-CilEvpMq.js.map → Table-BwgBm3hJ.js.map} +1 -1
- package/dist/{Tabs-Ck4uWf8U.js → Tabs-DmJB4l_N.js} +9 -14
- package/dist/{Tabs-Ck4uWf8U.js.map → Tabs-DmJB4l_N.js.map} +1 -1
- package/dist/{TextInput-CR0_USaY.js → TextInput--1CfZybC.js} +8 -10
- package/dist/TextInput--1CfZybC.js.map +1 -0
- package/dist/{ThemeProvider-BTK7AL-T.js → ThemeProvider-BCHllN7d.js} +8 -13
- package/dist/{ThemeProvider-BTK7AL-T.js.map → ThemeProvider-BCHllN7d.js.map} +1 -1
- package/dist/{TimePicker-CoRpiEM3.js → TimePicker-CCV3SOw5.js} +4 -6
- package/dist/{TimePicker-CoRpiEM3.js.map → TimePicker-CCV3SOw5.js.map} +1 -1
- package/dist/{Timeline-DUXgByUE.js → Timeline-EMOpTLAT.js} +8 -13
- package/dist/{Timeline-DUXgByUE.js.map → Timeline-EMOpTLAT.js.map} +1 -1
- package/dist/{Toast-937n7n8i.js → Toast-BOTINeTX.js} +4 -6
- package/dist/{Toast-937n7n8i.js.map → Toast-BOTINeTX.js.map} +1 -1
- package/dist/{ToggleAllTooltip-DEjbWFoj.js → ToggleAllTooltip-BFmA6TXf.js} +4 -6
- package/dist/{ToggleAllTooltip-DEjbWFoj.js.map → ToggleAllTooltip-BFmA6TXf.js.map} +1 -1
- package/dist/{ToggleGroup-BOz1yyz6.js → ToggleGroup-DsDS7k70.js} +3 -4
- package/dist/{ToggleGroup-BOz1yyz6.js.map → ToggleGroup-DsDS7k70.js.map} +1 -1
- package/dist/{Workbench-CxgNCs3I.js → Workbench-4s0xP6XU.js} +18 -32
- package/dist/{Workbench-CxgNCs3I.js.map → Workbench-4s0xP6XU.js.map} +1 -1
- package/dist/{ZoomableSvg-DnFXo2L4.js → ZoomableSvg-BRPGgaWJ.js} +9 -11
- package/dist/{ZoomableSvg-DnFXo2L4.js.map → ZoomableSvg-BRPGgaWJ.js.map} +1 -1
- package/dist/charts.d.ts +0 -16
- package/dist/charts.js +10 -19
- package/dist/charts.js.map +1 -1
- package/dist/{classNames-DcGnTh2N.js → classNames-DkX30VJU.js} +2 -3
- package/dist/{classNames-DcGnTh2N.js.map → classNames-DkX30VJU.js.map} +1 -1
- package/dist/editors.d.ts +2 -16
- package/dist/editors.js +16 -26
- package/dist/editors.js.map +1 -1
- package/dist/{findLiteralMatches-DgGLzyG0.js → findLiteralMatches-BaLZTPtx.js} +2 -3
- package/dist/{findLiteralMatches-DgGLzyG0.js.map → findLiteralMatches-BaLZTPtx.js.map} +1 -1
- package/dist/flint.d.ts +0 -2
- package/dist/flint.js +10 -14
- package/dist/flint.js.map +1 -1
- package/dist/{highlightCode-D354tCXO.js → highlightCode-2spZP7ZA.js} +2 -3
- package/dist/{highlightCode-D354tCXO.js.map → highlightCode-2spZP7ZA.js.map} +1 -1
- package/dist/{icons-ZIeZXXS7.js → icons-DDR9dFSr.js} +21 -40
- package/dist/{icons-ZIeZXXS7.js.map → icons-DDR9dFSr.js.map} +1 -1
- package/dist/icons.d.ts +1 -1
- package/dist/icons.js +1 -2
- package/dist/{index-D-itZ3VP.d.ts → index-BljYaTWL.d.ts} +1 -39
- package/dist/index.d.ts +452 -1296
- package/dist/index.js +76 -74
- package/dist/internal/blocks/AIKit.js +1 -2
- package/dist/internal/blocks/AppShell.js +1 -2
- package/dist/internal/blocks/AuthLayout.js +3 -4
- package/dist/internal/blocks/AutoSaveTextarea.js +1 -2
- package/dist/internal/blocks/BrandEditor.js +1 -2
- package/dist/internal/blocks/ChartPanel.js +3 -4
- package/dist/internal/blocks/ChipEditor.js +6 -7
- package/dist/internal/blocks/ClipboardButton.js +1 -2
- package/dist/internal/blocks/ColorInput.js +1 -2
- package/dist/internal/blocks/ColorModeSwitch.js +1 -2
- package/dist/internal/blocks/Command.js +1 -2
- package/dist/internal/blocks/CopyField.js +1 -2
- package/dist/internal/blocks/DashboardHero.js +2 -3
- package/dist/internal/blocks/DateInput.js +1 -2
- package/dist/internal/blocks/DateRangeInput.js +1 -2
- package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js +1 -2
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +2 -3
- package/dist/internal/blocks/EmptyState.js +1 -2
- package/dist/internal/blocks/ErrorState.js +1 -2
- package/dist/internal/blocks/ExportMenu.js +5 -6
- package/dist/internal/blocks/FacebookButton.js +3 -4
- package/dist/internal/blocks/Form/connectors/ComboboxField.js +3 -4
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +2 -3
- package/dist/internal/blocks/Form.js +3 -2
- package/dist/internal/blocks/FormGroup.js +1 -2
- package/dist/internal/blocks/GoogleButton.js +3 -4
- package/dist/internal/blocks/InlineEdit.js +1 -2
- package/dist/internal/blocks/MicrosoftButton.js +3 -4
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -2
- package/dist/internal/blocks/MultiCombobox.js +7 -8
- package/dist/internal/blocks/NumberInput.js +2 -3
- package/dist/internal/blocks/OtpInput.js +1 -2
- package/dist/internal/blocks/PageHeader.js +1 -2
- package/dist/internal/blocks/PageLayout.js +1 -2
- package/dist/internal/blocks/PageToolbar.js +1 -2
- package/dist/internal/blocks/PasswordInput.js +5 -6
- package/dist/internal/blocks/SearchInput.js +1 -2
- package/dist/internal/blocks/SearchInputWithNavigation.js +6 -7
- package/dist/internal/blocks/SectionNav.js +1 -2
- package/dist/internal/blocks/SplitButton.js +4 -5
- package/dist/internal/blocks/StatCard.js +4 -6
- package/dist/internal/blocks/StatCard.js.map +1 -1
- package/dist/internal/blocks/TextInput.js +1 -2
- package/dist/internal/blocks/Textarea.js +3 -4
- package/dist/internal/blocks/TimeInput.js +6 -7
- package/dist/internal/components/Alert.js +1 -2
- package/dist/internal/components/AlertModal.js +1 -2
- package/dist/internal/components/Avatar.js +3 -4
- package/dist/internal/components/Badge.js +1 -2
- package/dist/internal/components/BrandLogo.js +1 -2
- package/dist/internal/components/Breadcrumb.js +1 -2
- package/dist/internal/components/Button.js +1 -2
- package/dist/internal/components/ButtonGroup.js +2 -3
- package/dist/internal/components/Calendar.js +1 -2
- package/dist/internal/components/Card.js +1 -2
- package/dist/internal/components/Checkbox.js +1 -2
- package/dist/internal/components/Clipboard.js +1 -2
- package/dist/internal/components/Collapsible.js +1 -2
- package/dist/internal/components/CollapsiblePanel.js +5 -6
- package/dist/internal/components/Combobox.js +1 -2
- package/dist/internal/components/DatePicker.js +1 -2
- package/dist/internal/components/DateRangePicker.js +1 -2
- package/dist/internal/components/DiffView.js +1 -2
- package/dist/internal/components/DotsLoader.js +2 -3
- package/dist/internal/components/DropdownMenu.js +1 -2
- package/dist/internal/components/EmptySearchContent.js +1 -2
- package/dist/internal/components/FileUpload.js +1 -2
- package/dist/internal/components/FullScreenModal.js +1 -2
- package/dist/internal/components/HelpBlock.js +1 -2
- package/dist/internal/components/HoverCard.js +1 -2
- package/dist/internal/components/InputGroup.js +1 -2
- package/dist/internal/components/Kbd.js +1 -2
- package/dist/internal/components/Label.js +2 -3
- package/dist/internal/components/Link.js +2 -3
- package/dist/internal/components/MarkedText.js +1 -2
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +3 -4
- package/dist/internal/components/MergeEditor/PaneHeader.js +1 -2
- package/dist/internal/components/MergeEditor/constants.js +1 -2
- package/dist/internal/components/MergeEditor/useMergeDiff.js +1 -2
- package/dist/internal/components/Modal.js +1 -2
- package/dist/internal/components/Navbar.js +1 -2
- package/dist/internal/components/Pagination.js +1 -2
- package/dist/internal/components/PanelWithDetails.js +4 -5
- package/dist/internal/components/Popconfirm.js +1 -2
- package/dist/internal/components/Popover.js +1 -2
- package/dist/internal/components/Progress.js +2 -3
- package/dist/internal/components/RadioGroup.js +1 -2
- package/dist/internal/components/Resizable.js +1 -2
- package/dist/internal/components/ScrollArea.js +3 -5
- package/dist/internal/components/ScrollArea.js.map +1 -1
- package/dist/internal/components/Search.js +1 -2
- package/dist/internal/components/Select.js +1 -2
- package/dist/internal/components/Separator.js +2 -3
- package/dist/internal/components/Sheet.js +1 -2
- package/dist/internal/components/Sidebar.js +1 -2
- package/dist/internal/components/Skeleton/Skeleton.js +2 -3
- package/dist/internal/components/Skeleton/SkeletonList.js +2 -3
- package/dist/internal/components/Slider.js +1 -2
- package/dist/internal/components/SpotlightBackdrop.js +3 -5
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
- package/dist/internal/components/Stepper.js +1 -2
- package/dist/internal/components/Switch.js +1 -2
- package/dist/internal/components/Table.js +1 -2
- package/dist/internal/components/Tabs.js +1 -2
- package/dist/internal/components/ThemeProvider.js +2 -2
- package/dist/internal/components/TimePicker.js +1 -2
- package/dist/internal/components/Timeline.js +1 -2
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Toggle.js +2 -3
- package/dist/internal/components/ToggleGroup.js +1 -2
- package/dist/internal/components/Tooltip.js +1 -2
- package/dist/internal/components/Truncated.js +3 -4
- package/dist/internal/components/Workbench.js +1 -2
- package/dist/internal/components/ZoomableSvg.js +1 -2
- package/dist/internal/hooks/useAltDigitHotkey.js +1 -2
- package/dist/internal/hooks/useAutosizeInput.js +1 -2
- package/dist/internal/hooks/useScrollbarPosition.js +2 -3
- package/dist/internal/hooks/useStableCallback.js +1 -2
- package/dist/internal/hooks/useTimeout.js +18 -0
- package/dist/internal/hooks/useTimeout.js.map +1 -0
- package/dist/internal/utils/accessibleName.js +1 -2
- package/dist/internal/utils/mergeRefs.js +1 -2
- package/dist/internal/utils.js +3 -3
- package/dist/markdown-editor.d.ts +0 -4
- package/dist/markdown-editor.js +30 -49
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +0 -2
- package/dist/mermaid.js +1 -2
- package/dist/rjsf.d.ts +0 -8
- package/dist/rjsf.js +47 -78
- package/dist/rjsf.js.map +1 -1
- package/dist/{rolldown-runtime-Bdc48AWt.js → rolldown-runtime-BrwM56v-.js} +2 -3
- package/dist/{styles-T8xwr0sR.js → styles-BXXXosW_.js} +2 -3
- package/dist/{styles-T8xwr0sR.js.map → styles-BXXXosW_.js.map} +1 -1
- package/dist/{styles-DxazJ8Mz.js → styles-nwtCRF7y.js} +2 -3
- package/dist/{styles-DxazJ8Mz.js.map → styles-nwtCRF7y.js.map} +1 -1
- package/dist/styles.css +1 -1
- package/dist/{svgCache-Dhmbe-7i.js → svgCache-BzvN_fgr.js} +2 -3
- package/dist/{svgCache-Dhmbe-7i.js.map → svgCache-BzvN_fgr.js.map} +1 -1
- package/dist/{svgTransforms-Hnvev3Vs.js → svgTransforms-BBxxO9T6.js} +4 -6
- package/dist/{svgTransforms-Hnvev3Vs.js.map → svgTransforms-BBxxO9T6.js.map} +1 -1
- package/dist/testing.d.ts +0 -2
- package/dist/testing.js +2 -3
- package/dist/{themeScopeContext-CEVXbYvZ.js → themeScopeContext-BZGPdyG8.js} +6 -11
- package/dist/{themeScopeContext-CEVXbYvZ.js.map → themeScopeContext-BZGPdyG8.js.map} +1 -1
- package/dist/{themeTokens-DCeb62ap.js → themeTokens-B60cQtAY.js} +4 -6
- package/dist/{themeTokens-DCeb62ap.js.map → themeTokens-B60cQtAY.js.map} +1 -1
- package/dist/{toast-Y3cTMBW8.js → toast-Dzj1EFOb.js} +10 -17
- package/dist/{toast-Y3cTMBW8.js.map → toast-Dzj1EFOb.js.map} +1 -1
- package/dist/{types-BPcAjMG0.d.ts → types-CsZuwfxc.d.ts} +1 -3
- package/dist/{useControllableState-CUYXMsfz.js → useControllableState-BCvUOC6G.js} +2 -3
- package/dist/{useControllableState-CUYXMsfz.js.map → useControllableState-BCvUOC6G.js.map} +1 -1
- package/dist/{useElement-D-RjrGa4.js → useElement-Dcoo9Jlr.js} +2 -3
- package/dist/{useElement-D-RjrGa4.js.map → useElement-Dcoo9Jlr.js.map} +1 -1
- package/dist/{useMergeDiff-CvowEXJ1.js → useMergeDiff-DFIATaTw.js} +3 -5
- package/dist/{useMergeDiff-CvowEXJ1.js.map → useMergeDiff-DFIATaTw.js.map} +1 -1
- package/dist/{utils-DwC9u0tM.js → utils-DjFceY3H.js} +18 -34
- package/dist/utils-DjFceY3H.js.map +1 -0
- package/dist/vega.d.ts +1 -5
- package/dist/vega.js +3 -4
- package/dist/{vegaTheme-ISwGXvof.js → vegaTheme-BcTNRmVS.js} +3 -4
- package/dist/{vegaTheme-ISwGXvof.js.map → vegaTheme-BcTNRmVS.js.map} +1 -1
- package/dist/{vegaTokens-DCkvpIVE.js → vegaTokens-DnCcy7JY.js} +3 -4
- package/dist/{vegaTokens-DCkvpIVE.js.map → vegaTokens-DnCcy7JY.js.map} +1 -1
- package/package.json +40 -40
- package/src/styles.css +70 -4
- package/src/theme.css +117 -11
- package/dist/AIKit-CaAW4GLx.js.map +0 -1
- package/dist/AlertModal-D4AtpvLS.js.map +0 -1
- package/dist/Badge-5GHIsgRS.js.map +0 -1
- package/dist/Button-BNkyYU8u.js.map +0 -1
- package/dist/Calendar-BnKi1kPu.js.map +0 -1
- package/dist/Combobox-CaKqgstG.js.map +0 -1
- package/dist/DropdownMenu-CcVbZ_5u.js.map +0 -1
- package/dist/HoverCard-Cv5rmvJq.js +0 -26
- package/dist/HoverCard-Cv5rmvJq.js.map +0 -1
- package/dist/Modal-CbUz-5YH.js.map +0 -1
- package/dist/ModalTitle-cy0Ht9VY.js.map +0 -1
- package/dist/Popconfirm-DwLCYNaF.js.map +0 -1
- package/dist/Popover-DtUDwUVO.js.map +0 -1
- package/dist/Search-vyZwGKMU.js.map +0 -1
- package/dist/SearchInput-DyYXyw3u.js.map +0 -1
- package/dist/Select-B22hB_-w.js.map +0 -1
- package/dist/Sheet-0TWKTqid.js.map +0 -1
- package/dist/TextInput-CR0_USaY.js.map +0 -1
- package/dist/utils-DwC9u0tM.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMergeDiff-CvowEXJ1.js","names":[],"sources":["../src/components/MergeEditor/helpers.ts","../src/components/MergeEditor/useMergeDiff.ts"],"sourcesContent":["import { diffLines } from 'diff';\n\nimport { type ChangeClassification, CHUNK_TYPE, type DiffChunk } from './constants';\n\n/**\n * Computes diff chunks between oldText and newText using line-level diffing.\n * Adjacent removed+added pairs are kept as separate chunks so the consumer\n * can pair them into \"modifications\" for accept controls.\n */\nexport const computeDiffChunks = (oldText: string, newText: string): DiffChunk[] => {\n const changes = diffLines(oldText, newText);\n const chunks: DiffChunk[] = [];\n let oldLine = 1;\n let newLine = 1;\n\n for (const change of changes) {\n if (change.value === '') continue;\n\n const lineCount = change.count || change.value.replace(/\\n$/, '').split('\\n').length;\n\n if (change.removed) {\n // newStart/newEnd anchor to the current new-side position (insertion point) for alignment\n chunks.push({\n type: CHUNK_TYPE.REMOVED,\n value: change.value,\n oldStart: oldLine,\n oldEnd: oldLine + lineCount - 1,\n newStart: newLine,\n newEnd: newLine,\n });\n oldLine += lineCount;\n } else if (change.added) {\n // oldStart/oldEnd anchor to the current old-side position (insertion point) for alignment\n chunks.push({\n type: CHUNK_TYPE.ADDED,\n value: change.value,\n oldStart: oldLine,\n oldEnd: oldLine,\n newStart: newLine,\n newEnd: newLine + lineCount - 1,\n });\n newLine += lineCount;\n } else {\n chunks.push({\n type: CHUNK_TYPE.UNCHANGED,\n value: change.value,\n oldStart: oldLine,\n oldEnd: oldLine + lineCount - 1,\n newStart: newLine,\n newEnd: newLine + lineCount - 1,\n });\n oldLine += lineCount;\n newLine += lineCount;\n }\n }\n\n return chunks;\n};\n\n/**\n * Collects 1-indexed line numbers that are marked as changed (added or removed)\n * from a set of diff chunks. `side` determines which line range to use.\n */\nexport const getChangedLineNumbers = (chunks: DiffChunk[], side: 'old' | 'new'): Set<number> => {\n const lines = new Set<number>();\n\n for (const chunk of chunks) {\n if (chunk.type === CHUNK_TYPE.UNCHANGED) continue;\n\n if (side === 'old' && chunk.type === CHUNK_TYPE.REMOVED) {\n for (let i = chunk.oldStart; i <= chunk.oldEnd; i++) lines.add(i);\n }\n if (side === 'new' && chunk.type === CHUNK_TYPE.ADDED) {\n for (let i = chunk.newStart; i <= chunk.newEnd; i++) lines.add(i);\n }\n }\n\n return lines;\n};\n\n/**\n * Filters changed line numbers, keeping only those that are classified\n * and not suppressed (resolved/dismissed).\n *\n * `classification` and `suppressedLines` must be keyed by line numbers\n * from the same `side` (old-side lines for 'old', new-side lines for 'new').\n */\nexport const filterHighlightedLines = (\n chunks: DiffChunk[],\n side: 'old' | 'new',\n classification: Map<number, ChangeClassification>,\n suppressedLines: Set<number>,\n): Set<number> => {\n const filtered = new Set<number>();\n for (const line of getChangedLineNumbers(chunks, side)) {\n if (classification.has(line) && !suppressedLines.has(line)) filtered.add(line);\n }\n return filtered;\n};\n\n/**\n * Replaces lines in `text` between `startLine` and `endLine` (1-indexed, inclusive)\n * with `replacementLines`. If startLine > endLine, inserts before startLine.\n */\nexport const replaceLines = (\n text: string,\n startLine: number,\n endLine: number,\n replacement: string,\n): string => {\n const lines = text.split('\\n');\n const before = lines.slice(0, startLine - 1);\n const after = startLine > endLine ? lines.slice(startLine - 1) : lines.slice(endLine);\n\n const replacementArr = replacement === '' ? [] : replacement.replace(/\\n$/, '').split('\\n');\n\n return [...before, ...replacementArr, ...after].join('\\n');\n};\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { diff3Merge } from 'node-diff3';\n\nimport {\n CHANGE_CLASS,\n type ChangeClassification,\n CHUNK_TYPE,\n type DiffChunk,\n type MergeConflict,\n} from './constants';\nimport {\n computeDiffChunks,\n filterHighlightedLines,\n getChangedLineNumbers,\n replaceLines,\n} from './helpers';\n\nconst DEBOUNCE_MS = 150;\n\ntype ConflictPair = {\n id: string;\n leftStart: number;\n leftEnd: number;\n rightStart: number;\n rightEnd: number;\n};\n\ntype Side = 'left' | 'right';\n\nconst rangesOverlap = (s1: number, e1: number, s2: number, e2: number) => s1 <= e2 && e1 >= s2;\n\nconst computeSuppressedLines = (\n dismissedLines: Set<number>,\n pairs: ConflictPair[],\n resolvedIds: Set<string>,\n getRange: (p: ConflictPair) => [number, number],\n): Set<number> => {\n const lines = new Set(dismissedLines);\n for (const pair of pairs) {\n if (resolvedIds.has(pair.id)) {\n const [start, end] = getRange(pair);\n for (let i = start; i <= end; i++) lines.add(i);\n }\n }\n return lines;\n};\n\nconst filterVisibleConflicts = (\n conflicts: MergeConflict[],\n classification: Map<number, ChangeClassification>,\n dismissedLines: Set<number>,\n getRange: (c: MergeConflict) => [number, number],\n findPair: (c: MergeConflict) => ConflictPair | undefined,\n fullyResolvedPairIds: Set<string>,\n): MergeConflict[] =>\n conflicts.filter((c) => {\n const [start, end] = getRange(c);\n let hasClassifiedLine = false;\n let allDismissed = true;\n for (let i = start; i <= end; i++) {\n if (classification.has(i)) hasClassifiedLine = true;\n if (!dismissedLines.has(i)) allDismissed = false;\n }\n if (!hasClassifiedLine || allDismissed) return false;\n\n const pair = findPair(c);\n return !pair || !fullyResolvedPairIds.has(pair.id);\n });\n\nexport const useMergeDiff = (baseText: string, leftText: string, rightText: string) => {\n const [mergeValue, setMergeValue] = useState(baseText);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [debouncedMergeValue, setDebouncedMergeValue] = useState(mergeValue);\n const [acceptedPairSides, setAcceptedPairSides] = useState<Map<string, Set<Side>>>(\n () => new Map(),\n );\n const [dismissedLeftLines, setDismissedLeftLines] = useState<Set<number>>(() => new Set());\n const [dismissedRightLines, setDismissedRightLines] = useState<Set<number>>(() => new Set());\n\n const reset = useCallback(() => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n\n setMergeValue(baseText);\n setDebouncedMergeValue(baseText);\n setAcceptedPairSides(new Map());\n setDismissedLeftLines(new Set());\n setDismissedRightLines(new Set());\n }, [baseText]);\n\n // Reset all state when input texts change (e.g. async data arrives).\n // useLayoutEffect prevents a one-frame flash of incorrect diff rendering\n // when mergeValue is still '' but the real texts have arrived.\n useLayoutEffect(() => {\n reset();\n }, [baseText, leftText, rightText]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Clean up debounce timer on unmount\n useEffect(() => {\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, []);\n\n const handleMergeChange = useCallback((value: string) => {\n setMergeValue(value);\n\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n debounceRef.current = setTimeout(() => {\n setDebouncedMergeValue(value);\n }, DEBOUNCE_MS);\n }, []);\n\n // diff(production, mergeResult) — highlights for left pane\n const leftDiffChunks = useMemo(\n () => computeDiffChunks(leftText, debouncedMergeValue),\n [leftText, debouncedMergeValue],\n );\n\n // diff(mergeResult, branch) — highlights for right pane\n const rightDiffChunks = useMemo(\n () => computeDiffChunks(debouncedMergeValue, rightText),\n [debouncedMergeValue, rightText],\n );\n\n // Recompute conflict positions based on current merge value vs both sides\n const leftConflicts = useMemo(() => pairChunksIntoConflicts(leftDiffChunks), [leftDiffChunks]);\n\n const rightConflicts = useMemo(() => pairChunksIntoConflicts(rightDiffChunks), [rightDiffChunks]);\n\n // Base-vs-side diffs (stable unless source texts change)\n const leftVsBase = useMemo(() => computeDiffChunks(baseText, leftText), [baseText, leftText]);\n const rightVsBase = useMemo(() => computeDiffChunks(baseText, rightText), [baseText, rightText]);\n\n const { leftClassification, rightClassification, conflictPairs } = useMemo(() => {\n const baseLines = baseText.split('\\n');\n const leftLines = leftText.split('\\n');\n const rightLines = rightText.split('\\n');\n\n const result = diff3Merge(leftLines, baseLines, rightLines);\n\n const leftConflictLineSet = new Set<number>();\n const rightConflictLineSet = new Set<number>();\n const pairs: ConflictPair[] = [];\n\n for (const block of result) {\n if ('conflict' in block && block.conflict) {\n const { a, aIndex, b, bIndex } = block.conflict;\n for (let i = 0; i < a.length; i++) leftConflictLineSet.add(aIndex + i + 1);\n for (let i = 0; i < b.length; i++) rightConflictLineSet.add(bIndex + i + 1);\n\n pairs.push({\n id: `pair-${aIndex}-${bIndex}`,\n leftStart: aIndex + 1,\n leftEnd: aIndex + a.length,\n rightStart: bIndex + 1,\n rightEnd: bIndex + b.length,\n });\n }\n }\n\n const leftChanged = getChangedLineNumbers(leftVsBase, 'new');\n const rightChanged = getChangedLineNumbers(rightVsBase, 'new');\n\n const leftMap = new Map<number, ChangeClassification>();\n for (const line of leftChanged) {\n leftMap.set(line, leftConflictLineSet.has(line) ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE);\n }\n\n const rightMap = new Map<number, ChangeClassification>();\n for (const line of rightChanged) {\n rightMap.set(\n line,\n rightConflictLineSet.has(line) ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE,\n );\n }\n\n return {\n leftClassification: leftMap,\n rightClassification: rightMap,\n conflictPairs: pairs,\n };\n }, [baseText, leftText, rightText, leftVsBase, rightVsBase]);\n\n const findPairForLeft = useCallback(\n (conflict: MergeConflict) =>\n conflictPairs.find((p) =>\n rangesOverlap(conflict.oldStartLine, conflict.oldEndLine, p.leftStart, p.leftEnd),\n ),\n [conflictPairs],\n );\n\n const findPairForRight = useCallback(\n (conflict: MergeConflict) =>\n conflictPairs.find((p) =>\n rangesOverlap(conflict.newStartLine, conflict.newEndLine, p.rightStart, p.rightEnd),\n ),\n [conflictPairs],\n );\n\n const markSideAccepted = useCallback((pair: ConflictPair | undefined, side: Side) => {\n if (!pair) return;\n setAcceptedPairSides((prev) => {\n const next = new Map(prev);\n const sides = new Set(prev.get(pair.id) ?? []);\n sides.add(side);\n next.set(pair.id, sides);\n return next;\n });\n }, []);\n\n const isOtherSideAccepted = useCallback(\n (pair: ConflictPair | undefined, side: Side) => {\n if (!pair) return false;\n const otherSide = side === 'left' ? 'right' : 'left';\n return acceptedPairSides.get(pair.id)?.has(otherSide) ?? false;\n },\n [acceptedPairSides],\n );\n\n const acceptSide = useCallback(\n (conflict: MergeConflict, side: Side) => {\n const findPair = side === 'left' ? findPairForLeft : findPairForRight;\n const pair = findPair(conflict);\n const otherAccepted = isOtherSideAccepted(pair, side);\n const sourceValue = side === 'left' ? conflict.oldValue : conflict.newValue;\n const targetStart = side === 'left' ? conflict.newStartLine : conflict.oldStartLine;\n const targetEnd = side === 'left' ? conflict.newEndLine : conflict.oldEndLine;\n\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n\n const mergeTargetEmpty =\n side === 'left' ? conflict.newValue === '' : conflict.oldValue === '';\n const newValue = otherAccepted\n ? replaceLines(mergeValue, targetEnd + 1, targetEnd, sourceValue)\n : mergeTargetEmpty\n ? replaceLines(mergeValue, targetStart, targetStart - 1, sourceValue)\n : replaceLines(mergeValue, targetStart, targetEnd, sourceValue);\n\n setMergeValue(newValue);\n setDebouncedMergeValue(newValue);\n markSideAccepted(pair, side);\n\n if (!pair) {\n // Dismiss the source side-pane lines so the change doesn't reappear\n // if the user later edits the accepted text in the merge pane\n const setDismissedSide = side === 'left' ? setDismissedLeftLines : setDismissedRightLines;\n const [sideStart, sideEnd] =\n side === 'left'\n ? [conflict.oldStartLine, conflict.oldEndLine]\n : [conflict.newStartLine, conflict.newEndLine];\n\n setDismissedSide((prev) => {\n const next = new Set(prev);\n for (let i = sideStart; i <= sideEnd; i++) next.add(i);\n return next;\n });\n }\n },\n [mergeValue, findPairForLeft, findPairForRight, isOtherSideAccepted, markSideAccepted],\n );\n\n const acceptLeft = useCallback(\n (conflict: MergeConflict) => acceptSide(conflict, 'left'),\n [acceptSide],\n );\n\n const acceptRight = useCallback(\n (conflict: MergeConflict) => acceptSide(conflict, 'right'),\n [acceptSide],\n );\n\n const dismissSide = useCallback((conflict: MergeConflict, side: Side) => {\n const setDismissed = side === 'left' ? setDismissedLeftLines : setDismissedRightLines;\n const [sideStart, sideEnd] =\n side === 'left'\n ? [conflict.oldStartLine, conflict.oldEndLine]\n : [conflict.newStartLine, conflict.newEndLine];\n\n setDismissed((prev) => {\n const next = new Set(prev);\n for (let i = sideStart; i <= sideEnd; i++) next.add(i);\n return next;\n });\n }, []);\n\n const dismissLeft = useCallback(\n (conflict: MergeConflict) => dismissSide(conflict, 'left'),\n [dismissSide],\n );\n\n const dismissRight = useCallback(\n (conflict: MergeConflict) => dismissSide(conflict, 'right'),\n [dismissSide],\n );\n\n const fullyResolvedPairIds = useMemo(() => {\n const ids = new Set<string>();\n for (const pair of conflictPairs) {\n const leftAccepted = acceptedPairSides.get(pair.id)?.has('left') ?? false;\n const rightAccepted = acceptedPairSides.get(pair.id)?.has('right') ?? false;\n\n let leftDismissed = true;\n for (let i = pair.leftStart; i <= pair.leftEnd; i++) {\n if (!dismissedLeftLines.has(i)) {\n leftDismissed = false;\n break;\n }\n }\n\n let rightDismissed = true;\n for (let i = pair.rightStart; i <= pair.rightEnd; i++) {\n if (!dismissedRightLines.has(i)) {\n rightDismissed = false;\n break;\n }\n }\n\n if ((leftAccepted || leftDismissed) && (rightAccepted || rightDismissed)) {\n ids.add(pair.id);\n }\n }\n return ids;\n }, [conflictPairs, acceptedPairSides, dismissedLeftLines, dismissedRightLines]);\n\n const visibleLeftConflicts = useMemo(\n () =>\n filterVisibleConflicts(\n leftConflicts,\n leftClassification,\n dismissedLeftLines,\n (c) => [c.oldStartLine, c.oldEndLine],\n findPairForLeft,\n fullyResolvedPairIds,\n ),\n [leftConflicts, leftClassification, dismissedLeftLines, findPairForLeft, fullyResolvedPairIds],\n );\n\n const visibleRightConflicts = useMemo(\n () =>\n filterVisibleConflicts(\n rightConflicts,\n rightClassification,\n dismissedRightLines,\n (c) => [c.newStartLine, c.newEndLine],\n findPairForRight,\n fullyResolvedPairIds,\n ),\n [\n rightConflicts,\n rightClassification,\n dismissedRightLines,\n findPairForRight,\n fullyResolvedPairIds,\n ],\n );\n\n const suppressedLeftLines = useMemo(\n () =>\n computeSuppressedLines(dismissedLeftLines, conflictPairs, fullyResolvedPairIds, (p) => [\n p.leftStart,\n p.leftEnd,\n ]),\n [conflictPairs, fullyResolvedPairIds, dismissedLeftLines],\n );\n\n const suppressedRightLines = useMemo(\n () =>\n computeSuppressedLines(dismissedRightLines, conflictPairs, fullyResolvedPairIds, (p) => [\n p.rightStart,\n p.rightEnd,\n ]),\n [conflictPairs, fullyResolvedPairIds, dismissedRightLines],\n );\n\n const { mergeHighlightedLines, mergeClassification } = useMemo(() => {\n const mergeLeftLines = getChangedLineNumbers(leftDiffChunks, 'new');\n const mergeRightLines = getChangedLineNumbers(rightDiffChunks, 'old');\n\n const mergeLineToPair = new Map<number, string>();\n\n for (const conflict of leftConflicts) {\n const pair = findPairForLeft(conflict);\n if (pair) {\n for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) {\n mergeLineToPair.set(i, pair.id);\n }\n }\n }\n\n for (const conflict of rightConflicts) {\n const pair = findPairForRight(conflict);\n if (pair) {\n for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) {\n mergeLineToPair.set(i, pair.id);\n }\n }\n }\n\n // Derive suppressed merge lines from side-pane dismissals.\n // Side texts are static, so their line numbers never go stale.\n const suppressedMergeLines = new Set<number>();\n\n for (const conflict of leftConflicts) {\n if (findPairForLeft(conflict)) continue;\n if (conflict.oldStartLine > conflict.oldEndLine) continue;\n let allDismissed = true;\n for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) {\n if (!dismissedLeftLines.has(i)) {\n allDismissed = false;\n break;\n }\n }\n if (allDismissed) {\n for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) {\n suppressedMergeLines.add(i);\n }\n }\n }\n\n for (const conflict of rightConflicts) {\n if (findPairForRight(conflict)) continue;\n if (conflict.newStartLine > conflict.newEndLine) continue;\n let allDismissed = true;\n for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) {\n if (!dismissedRightLines.has(i)) {\n allDismissed = false;\n break;\n }\n }\n if (allDismissed) {\n for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) {\n suppressedMergeLines.add(i);\n }\n }\n }\n\n const allMergeLines = new Set<number>();\n for (const line of mergeLeftLines) allMergeLines.add(line);\n for (const line of mergeRightLines) allMergeLines.add(line);\n\n const highlighted = new Set<number>();\n const classification = new Map<number, ChangeClassification>();\n\n for (const line of allMergeLines) {\n if (suppressedMergeLines.has(line)) continue;\n\n const pairId = mergeLineToPair.get(line);\n if (pairId && fullyResolvedPairIds.has(pairId)) continue;\n\n highlighted.add(line);\n classification.set(line, pairId ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE);\n }\n\n return { mergeHighlightedLines: highlighted, mergeClassification: classification };\n }, [\n leftDiffChunks,\n rightDiffChunks,\n leftConflicts,\n rightConflicts,\n findPairForLeft,\n findPairForRight,\n fullyResolvedPairIds,\n dismissedLeftLines,\n dismissedRightLines,\n ]);\n\n const leftHighlightedLines = useMemo(\n () => filterHighlightedLines(leftDiffChunks, 'old', leftClassification, suppressedLeftLines),\n [leftDiffChunks, leftClassification, suppressedLeftLines],\n );\n\n const rightHighlightedLines = useMemo(\n () => filterHighlightedLines(rightDiffChunks, 'new', rightClassification, suppressedRightLines),\n [rightDiffChunks, rightClassification, suppressedRightLines],\n );\n\n const remainingSafeChanges = useMemo(() => {\n const leftSafe = visibleLeftConflicts.filter((c) => !findPairForLeft(c)).length;\n const rightSafe = visibleRightConflicts.filter((c) => !findPairForRight(c)).length;\n return leftSafe + rightSafe;\n }, [visibleLeftConflicts, visibleRightConflicts, findPairForLeft, findPairForRight]);\n\n return {\n mergeValue,\n handleMergeChange,\n leftConflicts: visibleLeftConflicts,\n rightConflicts: visibleRightConflicts,\n leftHighlightedLines,\n rightHighlightedLines,\n leftClassification,\n rightClassification,\n mergeHighlightedLines,\n mergeClassification,\n acceptLeft,\n acceptRight,\n dismissLeft,\n dismissRight,\n totalConflicts: conflictPairs.length,\n resolvedConflicts: fullyResolvedPairIds.size,\n remainingSafeChanges,\n isDirty: mergeValue !== baseText || dismissedLeftLines.size > 0 || dismissedRightLines.size > 0,\n reset,\n };\n};\n\n/**\n * Pairs adjacent removed+added chunks into MergeConflicts.\n * A standalone REMOVED or ADDED chunk becomes a conflict with\n * the other side empty.\n */\nconst pairChunksIntoConflicts = (chunks: DiffChunk[]): MergeConflict[] => {\n const conflicts: MergeConflict[] = [];\n let i = 0;\n\n while (i < chunks.length) {\n const chunk = chunks[i]!;\n\n if (chunk.type === CHUNK_TYPE.UNCHANGED) {\n i++;\n continue;\n }\n\n if (chunk.type === CHUNK_TYPE.REMOVED) {\n const next = chunks[i + 1];\n\n if (next?.type === CHUNK_TYPE.ADDED) {\n conflicts.push({\n id: `${chunk.oldStart}-${next.newStart}`,\n oldValue: chunk.value,\n oldStartLine: chunk.oldStart,\n oldEndLine: chunk.oldEnd,\n newValue: next.value,\n newStartLine: next.newStart,\n newEndLine: next.newEnd,\n });\n i += 2;\n } else {\n conflicts.push({\n id: `${chunk.oldStart}-del`,\n oldValue: chunk.value,\n oldStartLine: chunk.oldStart,\n oldEndLine: chunk.oldEnd,\n newValue: '',\n newStartLine: chunk.newStart,\n newEndLine: chunk.newStart,\n });\n i++;\n }\n } else {\n conflicts.push({\n id: `add-${chunk.newStart}`,\n oldValue: '',\n oldStartLine: chunk.oldStart,\n oldEndLine: chunk.oldStart,\n newValue: chunk.value,\n newStartLine: chunk.newStart,\n newEndLine: chunk.newEnd,\n });\n i++;\n }\n }\n\n return conflicts;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useMergeDiff-DFIATaTw.js","names":[],"sources":["../src/components/MergeEditor/helpers.ts","../src/components/MergeEditor/useMergeDiff.ts"],"sourcesContent":["import { diffLines } from 'diff';\n\nimport { type ChangeClassification, CHUNK_TYPE, type DiffChunk } from './constants';\n\n/**\n * Computes diff chunks between oldText and newText using line-level diffing.\n * Adjacent removed+added pairs are kept as separate chunks so the consumer\n * can pair them into \"modifications\" for accept controls.\n */\nexport const computeDiffChunks = (oldText: string, newText: string): DiffChunk[] => {\n const changes = diffLines(oldText, newText);\n const chunks: DiffChunk[] = [];\n let oldLine = 1;\n let newLine = 1;\n\n for (const change of changes) {\n if (change.value === '') continue;\n\n const lineCount = change.count || change.value.replace(/\\n$/, '').split('\\n').length;\n\n if (change.removed) {\n // newStart/newEnd anchor to the current new-side position (insertion point) for alignment\n chunks.push({\n type: CHUNK_TYPE.REMOVED,\n value: change.value,\n oldStart: oldLine,\n oldEnd: oldLine + lineCount - 1,\n newStart: newLine,\n newEnd: newLine,\n });\n oldLine += lineCount;\n } else if (change.added) {\n // oldStart/oldEnd anchor to the current old-side position (insertion point) for alignment\n chunks.push({\n type: CHUNK_TYPE.ADDED,\n value: change.value,\n oldStart: oldLine,\n oldEnd: oldLine,\n newStart: newLine,\n newEnd: newLine + lineCount - 1,\n });\n newLine += lineCount;\n } else {\n chunks.push({\n type: CHUNK_TYPE.UNCHANGED,\n value: change.value,\n oldStart: oldLine,\n oldEnd: oldLine + lineCount - 1,\n newStart: newLine,\n newEnd: newLine + lineCount - 1,\n });\n oldLine += lineCount;\n newLine += lineCount;\n }\n }\n\n return chunks;\n};\n\n/**\n * Collects 1-indexed line numbers that are marked as changed (added or removed)\n * from a set of diff chunks. `side` determines which line range to use.\n */\nexport const getChangedLineNumbers = (chunks: DiffChunk[], side: 'old' | 'new'): Set<number> => {\n const lines = new Set<number>();\n\n for (const chunk of chunks) {\n if (chunk.type === CHUNK_TYPE.UNCHANGED) continue;\n\n if (side === 'old' && chunk.type === CHUNK_TYPE.REMOVED) {\n for (let i = chunk.oldStart; i <= chunk.oldEnd; i++) lines.add(i);\n }\n if (side === 'new' && chunk.type === CHUNK_TYPE.ADDED) {\n for (let i = chunk.newStart; i <= chunk.newEnd; i++) lines.add(i);\n }\n }\n\n return lines;\n};\n\n/**\n * Filters changed line numbers, keeping only those that are classified\n * and not suppressed (resolved/dismissed).\n *\n * `classification` and `suppressedLines` must be keyed by line numbers\n * from the same `side` (old-side lines for 'old', new-side lines for 'new').\n */\nexport const filterHighlightedLines = (\n chunks: DiffChunk[],\n side: 'old' | 'new',\n classification: Map<number, ChangeClassification>,\n suppressedLines: Set<number>,\n): Set<number> => {\n const filtered = new Set<number>();\n for (const line of getChangedLineNumbers(chunks, side)) {\n if (classification.has(line) && !suppressedLines.has(line)) filtered.add(line);\n }\n return filtered;\n};\n\n/**\n * Replaces lines in `text` between `startLine` and `endLine` (1-indexed, inclusive)\n * with `replacementLines`. If startLine > endLine, inserts before startLine.\n */\nexport const replaceLines = (\n text: string,\n startLine: number,\n endLine: number,\n replacement: string,\n): string => {\n const lines = text.split('\\n');\n const before = lines.slice(0, startLine - 1);\n const after = startLine > endLine ? lines.slice(startLine - 1) : lines.slice(endLine);\n\n const replacementArr = replacement === '' ? [] : replacement.replace(/\\n$/, '').split('\\n');\n\n return [...before, ...replacementArr, ...after].join('\\n');\n};\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { diff3Merge } from 'node-diff3';\n\nimport {\n CHANGE_CLASS,\n type ChangeClassification,\n CHUNK_TYPE,\n type DiffChunk,\n type MergeConflict,\n} from './constants';\nimport {\n computeDiffChunks,\n filterHighlightedLines,\n getChangedLineNumbers,\n replaceLines,\n} from './helpers';\n\nconst DEBOUNCE_MS = 150;\n\ntype ConflictPair = {\n id: string;\n leftStart: number;\n leftEnd: number;\n rightStart: number;\n rightEnd: number;\n};\n\ntype Side = 'left' | 'right';\n\nconst rangesOverlap = (s1: number, e1: number, s2: number, e2: number) => s1 <= e2 && e1 >= s2;\n\nconst computeSuppressedLines = (\n dismissedLines: Set<number>,\n pairs: ConflictPair[],\n resolvedIds: Set<string>,\n getRange: (p: ConflictPair) => [number, number],\n): Set<number> => {\n const lines = new Set(dismissedLines);\n for (const pair of pairs) {\n if (resolvedIds.has(pair.id)) {\n const [start, end] = getRange(pair);\n for (let i = start; i <= end; i++) lines.add(i);\n }\n }\n return lines;\n};\n\nconst filterVisibleConflicts = (\n conflicts: MergeConflict[],\n classification: Map<number, ChangeClassification>,\n dismissedLines: Set<number>,\n getRange: (c: MergeConflict) => [number, number],\n findPair: (c: MergeConflict) => ConflictPair | undefined,\n fullyResolvedPairIds: Set<string>,\n): MergeConflict[] =>\n conflicts.filter((c) => {\n const [start, end] = getRange(c);\n let hasClassifiedLine = false;\n let allDismissed = true;\n for (let i = start; i <= end; i++) {\n if (classification.has(i)) hasClassifiedLine = true;\n if (!dismissedLines.has(i)) allDismissed = false;\n }\n if (!hasClassifiedLine || allDismissed) return false;\n\n const pair = findPair(c);\n return !pair || !fullyResolvedPairIds.has(pair.id);\n });\n\nexport const useMergeDiff = (baseText: string, leftText: string, rightText: string) => {\n const [mergeValue, setMergeValue] = useState(baseText);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [debouncedMergeValue, setDebouncedMergeValue] = useState(mergeValue);\n const [acceptedPairSides, setAcceptedPairSides] = useState<Map<string, Set<Side>>>(\n () => new Map(),\n );\n const [dismissedLeftLines, setDismissedLeftLines] = useState<Set<number>>(() => new Set());\n const [dismissedRightLines, setDismissedRightLines] = useState<Set<number>>(() => new Set());\n\n const reset = useCallback(() => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n\n setMergeValue(baseText);\n setDebouncedMergeValue(baseText);\n setAcceptedPairSides(new Map());\n setDismissedLeftLines(new Set());\n setDismissedRightLines(new Set());\n }, [baseText]);\n\n // Reset all state when input texts change (e.g. async data arrives).\n // useLayoutEffect prevents a one-frame flash of incorrect diff rendering\n // when mergeValue is still '' but the real texts have arrived.\n useLayoutEffect(() => {\n reset();\n }, [baseText, leftText, rightText]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Clean up debounce timer on unmount\n useEffect(() => {\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, []);\n\n const handleMergeChange = useCallback((value: string) => {\n setMergeValue(value);\n\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n debounceRef.current = setTimeout(() => {\n setDebouncedMergeValue(value);\n }, DEBOUNCE_MS);\n }, []);\n\n // diff(production, mergeResult) — highlights for left pane\n const leftDiffChunks = useMemo(\n () => computeDiffChunks(leftText, debouncedMergeValue),\n [leftText, debouncedMergeValue],\n );\n\n // diff(mergeResult, branch) — highlights for right pane\n const rightDiffChunks = useMemo(\n () => computeDiffChunks(debouncedMergeValue, rightText),\n [debouncedMergeValue, rightText],\n );\n\n // Recompute conflict positions based on current merge value vs both sides\n const leftConflicts = useMemo(() => pairChunksIntoConflicts(leftDiffChunks), [leftDiffChunks]);\n\n const rightConflicts = useMemo(() => pairChunksIntoConflicts(rightDiffChunks), [rightDiffChunks]);\n\n // Base-vs-side diffs (stable unless source texts change)\n const leftVsBase = useMemo(() => computeDiffChunks(baseText, leftText), [baseText, leftText]);\n const rightVsBase = useMemo(() => computeDiffChunks(baseText, rightText), [baseText, rightText]);\n\n const { leftClassification, rightClassification, conflictPairs } = useMemo(() => {\n const baseLines = baseText.split('\\n');\n const leftLines = leftText.split('\\n');\n const rightLines = rightText.split('\\n');\n\n const result = diff3Merge(leftLines, baseLines, rightLines);\n\n const leftConflictLineSet = new Set<number>();\n const rightConflictLineSet = new Set<number>();\n const pairs: ConflictPair[] = [];\n\n for (const block of result) {\n if ('conflict' in block && block.conflict) {\n const { a, aIndex, b, bIndex } = block.conflict;\n for (let i = 0; i < a.length; i++) leftConflictLineSet.add(aIndex + i + 1);\n for (let i = 0; i < b.length; i++) rightConflictLineSet.add(bIndex + i + 1);\n\n pairs.push({\n id: `pair-${aIndex}-${bIndex}`,\n leftStart: aIndex + 1,\n leftEnd: aIndex + a.length,\n rightStart: bIndex + 1,\n rightEnd: bIndex + b.length,\n });\n }\n }\n\n const leftChanged = getChangedLineNumbers(leftVsBase, 'new');\n const rightChanged = getChangedLineNumbers(rightVsBase, 'new');\n\n const leftMap = new Map<number, ChangeClassification>();\n for (const line of leftChanged) {\n leftMap.set(line, leftConflictLineSet.has(line) ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE);\n }\n\n const rightMap = new Map<number, ChangeClassification>();\n for (const line of rightChanged) {\n rightMap.set(\n line,\n rightConflictLineSet.has(line) ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE,\n );\n }\n\n return {\n leftClassification: leftMap,\n rightClassification: rightMap,\n conflictPairs: pairs,\n };\n }, [baseText, leftText, rightText, leftVsBase, rightVsBase]);\n\n const findPairForLeft = useCallback(\n (conflict: MergeConflict) =>\n conflictPairs.find((p) =>\n rangesOverlap(conflict.oldStartLine, conflict.oldEndLine, p.leftStart, p.leftEnd),\n ),\n [conflictPairs],\n );\n\n const findPairForRight = useCallback(\n (conflict: MergeConflict) =>\n conflictPairs.find((p) =>\n rangesOverlap(conflict.newStartLine, conflict.newEndLine, p.rightStart, p.rightEnd),\n ),\n [conflictPairs],\n );\n\n const markSideAccepted = useCallback((pair: ConflictPair | undefined, side: Side) => {\n if (!pair) return;\n setAcceptedPairSides((prev) => {\n const next = new Map(prev);\n const sides = new Set(prev.get(pair.id) ?? []);\n sides.add(side);\n next.set(pair.id, sides);\n return next;\n });\n }, []);\n\n const isOtherSideAccepted = useCallback(\n (pair: ConflictPair | undefined, side: Side) => {\n if (!pair) return false;\n const otherSide = side === 'left' ? 'right' : 'left';\n return acceptedPairSides.get(pair.id)?.has(otherSide) ?? false;\n },\n [acceptedPairSides],\n );\n\n const acceptSide = useCallback(\n (conflict: MergeConflict, side: Side) => {\n const findPair = side === 'left' ? findPairForLeft : findPairForRight;\n const pair = findPair(conflict);\n const otherAccepted = isOtherSideAccepted(pair, side);\n const sourceValue = side === 'left' ? conflict.oldValue : conflict.newValue;\n const targetStart = side === 'left' ? conflict.newStartLine : conflict.oldStartLine;\n const targetEnd = side === 'left' ? conflict.newEndLine : conflict.oldEndLine;\n\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n\n const mergeTargetEmpty =\n side === 'left' ? conflict.newValue === '' : conflict.oldValue === '';\n const newValue = otherAccepted\n ? replaceLines(mergeValue, targetEnd + 1, targetEnd, sourceValue)\n : mergeTargetEmpty\n ? replaceLines(mergeValue, targetStart, targetStart - 1, sourceValue)\n : replaceLines(mergeValue, targetStart, targetEnd, sourceValue);\n\n setMergeValue(newValue);\n setDebouncedMergeValue(newValue);\n markSideAccepted(pair, side);\n\n if (!pair) {\n // Dismiss the source side-pane lines so the change doesn't reappear\n // if the user later edits the accepted text in the merge pane\n const setDismissedSide = side === 'left' ? setDismissedLeftLines : setDismissedRightLines;\n const [sideStart, sideEnd] =\n side === 'left'\n ? [conflict.oldStartLine, conflict.oldEndLine]\n : [conflict.newStartLine, conflict.newEndLine];\n\n setDismissedSide((prev) => {\n const next = new Set(prev);\n for (let i = sideStart; i <= sideEnd; i++) next.add(i);\n return next;\n });\n }\n },\n [mergeValue, findPairForLeft, findPairForRight, isOtherSideAccepted, markSideAccepted],\n );\n\n const acceptLeft = useCallback(\n (conflict: MergeConflict) => acceptSide(conflict, 'left'),\n [acceptSide],\n );\n\n const acceptRight = useCallback(\n (conflict: MergeConflict) => acceptSide(conflict, 'right'),\n [acceptSide],\n );\n\n const dismissSide = useCallback((conflict: MergeConflict, side: Side) => {\n const setDismissed = side === 'left' ? setDismissedLeftLines : setDismissedRightLines;\n const [sideStart, sideEnd] =\n side === 'left'\n ? [conflict.oldStartLine, conflict.oldEndLine]\n : [conflict.newStartLine, conflict.newEndLine];\n\n setDismissed((prev) => {\n const next = new Set(prev);\n for (let i = sideStart; i <= sideEnd; i++) next.add(i);\n return next;\n });\n }, []);\n\n const dismissLeft = useCallback(\n (conflict: MergeConflict) => dismissSide(conflict, 'left'),\n [dismissSide],\n );\n\n const dismissRight = useCallback(\n (conflict: MergeConflict) => dismissSide(conflict, 'right'),\n [dismissSide],\n );\n\n const fullyResolvedPairIds = useMemo(() => {\n const ids = new Set<string>();\n for (const pair of conflictPairs) {\n const leftAccepted = acceptedPairSides.get(pair.id)?.has('left') ?? false;\n const rightAccepted = acceptedPairSides.get(pair.id)?.has('right') ?? false;\n\n let leftDismissed = true;\n for (let i = pair.leftStart; i <= pair.leftEnd; i++) {\n if (!dismissedLeftLines.has(i)) {\n leftDismissed = false;\n break;\n }\n }\n\n let rightDismissed = true;\n for (let i = pair.rightStart; i <= pair.rightEnd; i++) {\n if (!dismissedRightLines.has(i)) {\n rightDismissed = false;\n break;\n }\n }\n\n if ((leftAccepted || leftDismissed) && (rightAccepted || rightDismissed)) {\n ids.add(pair.id);\n }\n }\n return ids;\n }, [conflictPairs, acceptedPairSides, dismissedLeftLines, dismissedRightLines]);\n\n const visibleLeftConflicts = useMemo(\n () =>\n filterVisibleConflicts(\n leftConflicts,\n leftClassification,\n dismissedLeftLines,\n (c) => [c.oldStartLine, c.oldEndLine],\n findPairForLeft,\n fullyResolvedPairIds,\n ),\n [leftConflicts, leftClassification, dismissedLeftLines, findPairForLeft, fullyResolvedPairIds],\n );\n\n const visibleRightConflicts = useMemo(\n () =>\n filterVisibleConflicts(\n rightConflicts,\n rightClassification,\n dismissedRightLines,\n (c) => [c.newStartLine, c.newEndLine],\n findPairForRight,\n fullyResolvedPairIds,\n ),\n [\n rightConflicts,\n rightClassification,\n dismissedRightLines,\n findPairForRight,\n fullyResolvedPairIds,\n ],\n );\n\n const suppressedLeftLines = useMemo(\n () =>\n computeSuppressedLines(dismissedLeftLines, conflictPairs, fullyResolvedPairIds, (p) => [\n p.leftStart,\n p.leftEnd,\n ]),\n [conflictPairs, fullyResolvedPairIds, dismissedLeftLines],\n );\n\n const suppressedRightLines = useMemo(\n () =>\n computeSuppressedLines(dismissedRightLines, conflictPairs, fullyResolvedPairIds, (p) => [\n p.rightStart,\n p.rightEnd,\n ]),\n [conflictPairs, fullyResolvedPairIds, dismissedRightLines],\n );\n\n const { mergeHighlightedLines, mergeClassification } = useMemo(() => {\n const mergeLeftLines = getChangedLineNumbers(leftDiffChunks, 'new');\n const mergeRightLines = getChangedLineNumbers(rightDiffChunks, 'old');\n\n const mergeLineToPair = new Map<number, string>();\n\n for (const conflict of leftConflicts) {\n const pair = findPairForLeft(conflict);\n if (pair) {\n for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) {\n mergeLineToPair.set(i, pair.id);\n }\n }\n }\n\n for (const conflict of rightConflicts) {\n const pair = findPairForRight(conflict);\n if (pair) {\n for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) {\n mergeLineToPair.set(i, pair.id);\n }\n }\n }\n\n // Derive suppressed merge lines from side-pane dismissals.\n // Side texts are static, so their line numbers never go stale.\n const suppressedMergeLines = new Set<number>();\n\n for (const conflict of leftConflicts) {\n if (findPairForLeft(conflict)) continue;\n if (conflict.oldStartLine > conflict.oldEndLine) continue;\n let allDismissed = true;\n for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) {\n if (!dismissedLeftLines.has(i)) {\n allDismissed = false;\n break;\n }\n }\n if (allDismissed) {\n for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) {\n suppressedMergeLines.add(i);\n }\n }\n }\n\n for (const conflict of rightConflicts) {\n if (findPairForRight(conflict)) continue;\n if (conflict.newStartLine > conflict.newEndLine) continue;\n let allDismissed = true;\n for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) {\n if (!dismissedRightLines.has(i)) {\n allDismissed = false;\n break;\n }\n }\n if (allDismissed) {\n for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) {\n suppressedMergeLines.add(i);\n }\n }\n }\n\n const allMergeLines = new Set<number>();\n for (const line of mergeLeftLines) allMergeLines.add(line);\n for (const line of mergeRightLines) allMergeLines.add(line);\n\n const highlighted = new Set<number>();\n const classification = new Map<number, ChangeClassification>();\n\n for (const line of allMergeLines) {\n if (suppressedMergeLines.has(line)) continue;\n\n const pairId = mergeLineToPair.get(line);\n if (pairId && fullyResolvedPairIds.has(pairId)) continue;\n\n highlighted.add(line);\n classification.set(line, pairId ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE);\n }\n\n return { mergeHighlightedLines: highlighted, mergeClassification: classification };\n }, [\n leftDiffChunks,\n rightDiffChunks,\n leftConflicts,\n rightConflicts,\n findPairForLeft,\n findPairForRight,\n fullyResolvedPairIds,\n dismissedLeftLines,\n dismissedRightLines,\n ]);\n\n const leftHighlightedLines = useMemo(\n () => filterHighlightedLines(leftDiffChunks, 'old', leftClassification, suppressedLeftLines),\n [leftDiffChunks, leftClassification, suppressedLeftLines],\n );\n\n const rightHighlightedLines = useMemo(\n () => filterHighlightedLines(rightDiffChunks, 'new', rightClassification, suppressedRightLines),\n [rightDiffChunks, rightClassification, suppressedRightLines],\n );\n\n const remainingSafeChanges = useMemo(() => {\n const leftSafe = visibleLeftConflicts.filter((c) => !findPairForLeft(c)).length;\n const rightSafe = visibleRightConflicts.filter((c) => !findPairForRight(c)).length;\n return leftSafe + rightSafe;\n }, [visibleLeftConflicts, visibleRightConflicts, findPairForLeft, findPairForRight]);\n\n return {\n mergeValue,\n handleMergeChange,\n leftConflicts: visibleLeftConflicts,\n rightConflicts: visibleRightConflicts,\n leftHighlightedLines,\n rightHighlightedLines,\n leftClassification,\n rightClassification,\n mergeHighlightedLines,\n mergeClassification,\n acceptLeft,\n acceptRight,\n dismissLeft,\n dismissRight,\n totalConflicts: conflictPairs.length,\n resolvedConflicts: fullyResolvedPairIds.size,\n remainingSafeChanges,\n isDirty: mergeValue !== baseText || dismissedLeftLines.size > 0 || dismissedRightLines.size > 0,\n reset,\n };\n};\n\n/**\n * Pairs adjacent removed+added chunks into MergeConflicts.\n * A standalone REMOVED or ADDED chunk becomes a conflict with\n * the other side empty.\n */\nconst pairChunksIntoConflicts = (chunks: DiffChunk[]): MergeConflict[] => {\n const conflicts: MergeConflict[] = [];\n let i = 0;\n\n while (i < chunks.length) {\n const chunk = chunks[i]!;\n\n if (chunk.type === CHUNK_TYPE.UNCHANGED) {\n i++;\n continue;\n }\n\n if (chunk.type === CHUNK_TYPE.REMOVED) {\n const next = chunks[i + 1];\n\n if (next?.type === CHUNK_TYPE.ADDED) {\n conflicts.push({\n id: `${chunk.oldStart}-${next.newStart}`,\n oldValue: chunk.value,\n oldStartLine: chunk.oldStart,\n oldEndLine: chunk.oldEnd,\n newValue: next.value,\n newStartLine: next.newStart,\n newEndLine: next.newEnd,\n });\n i += 2;\n } else {\n conflicts.push({\n id: `${chunk.oldStart}-del`,\n oldValue: chunk.value,\n oldStartLine: chunk.oldStart,\n oldEndLine: chunk.oldEnd,\n newValue: '',\n newStartLine: chunk.newStart,\n newEndLine: chunk.newStart,\n });\n i++;\n }\n } else {\n conflicts.push({\n id: `add-${chunk.newStart}`,\n oldValue: '',\n oldStartLine: chunk.oldStart,\n oldEndLine: chunk.oldStart,\n newValue: chunk.value,\n newStartLine: chunk.newStart,\n newEndLine: chunk.newEnd,\n });\n i++;\n }\n }\n\n return conflicts;\n};\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { cn } from "./classNames-
|
|
1
|
+
import { cn } from "./classNames-DkX30VJU.js";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { Slot } from "@radix-ui/react-slot";
|
|
4
4
|
import { Content, Portal, Provider, Root as Root$1, Trigger } from "@radix-ui/react-tooltip";
|
|
5
5
|
import { cva } from "class-variance-authority";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/utils/copyToClipboard.ts
|
|
8
8
|
/**
|
|
9
9
|
* The async Clipboard API requires the document to be focused and rejects with
|
|
10
10
|
* `NotAllowedError: Document is not focused` otherwise — which is the normal state
|
|
@@ -32,8 +32,7 @@ const copyToClipboard = async (text) => {
|
|
|
32
32
|
if (!copyViaSelection(text)) throw error;
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
|
-
|
|
36
|
-
//#region src/utils/createChangeInputEvent.ts
|
|
35
|
+
// src/utils/createChangeInputEvent.ts
|
|
37
36
|
const createChangeInputEvent = (input) => {
|
|
38
37
|
const changeEvent = {
|
|
39
38
|
target: input,
|
|
@@ -58,15 +57,13 @@ const createChangeInputEvent = (input) => {
|
|
|
58
57
|
});
|
|
59
58
|
return changeEvent;
|
|
60
59
|
};
|
|
61
|
-
|
|
62
|
-
//#region src/constants/keyCodes.ts
|
|
60
|
+
// src/constants/keyCodes.ts
|
|
63
61
|
const keyCodes = {
|
|
64
62
|
ENTER: "Enter",
|
|
65
63
|
ESCAPE: "Escape",
|
|
66
64
|
SPACE: " "
|
|
67
65
|
};
|
|
68
|
-
|
|
69
|
-
//#region src/components/Tooltip/TooltipContent.tsx
|
|
66
|
+
// src/components/Tooltip/TooltipContent.tsx
|
|
70
67
|
const tooltipVariants = cva([
|
|
71
68
|
"tailwindcss-preflight",
|
|
72
69
|
"tw:inline-block",
|
|
@@ -137,16 +134,14 @@ const TooltipContent = ({ className, variant, keepOpenOnPointerDownOutside = fal
|
|
|
137
134
|
children
|
|
138
135
|
}) });
|
|
139
136
|
};
|
|
140
|
-
|
|
141
|
-
//#region src/components/Tooltip/TooltipRoot.tsx
|
|
137
|
+
// src/components/Tooltip/TooltipRoot.tsx
|
|
142
138
|
const DELAY_SHOW_TOOLTIP = 300;
|
|
143
139
|
const TooltipRoot = ({ children, delayDuration = DELAY_SHOW_TOOLTIP, ...rest }) => /* @__PURE__ */ jsx(Root$1, {
|
|
144
140
|
...rest,
|
|
145
141
|
delayDuration,
|
|
146
142
|
children
|
|
147
143
|
});
|
|
148
|
-
|
|
149
|
-
//#region src/components/Tooltip/TooltipTitle.tsx
|
|
144
|
+
// src/components/Tooltip/TooltipTitle.tsx
|
|
150
145
|
/**
|
|
151
146
|
* Small uppercase heading above a rich tooltip's body copy, in the tooltip's text colour.
|
|
152
147
|
*/
|
|
@@ -154,8 +149,7 @@ const TooltipTitle = ({ className, ...rest }) => /* @__PURE__ */ jsx("div", {
|
|
|
154
149
|
className: cn("tw:mb-2 tw:text-xs tw:leading-5 tw:font-semibold tw:uppercase", className),
|
|
155
150
|
...rest
|
|
156
151
|
});
|
|
157
|
-
|
|
158
|
-
//#region src/components/Tooltip/TooltipTrigger.tsx
|
|
152
|
+
// src/components/Tooltip/TooltipTrigger.tsx
|
|
159
153
|
/**
|
|
160
154
|
* Radix stamps the tooltip's own open/closed `data-state` onto the trigger. Merged onto an
|
|
161
155
|
* `asChild` child that keeps a `data-state` of its own — `ToggleGroup.Item`, `Switch`, a `Tabs`
|
|
@@ -194,8 +188,7 @@ const TooltipTrigger = ({ ref, children, className, keepOpenOnClick = false, onC
|
|
|
194
188
|
})
|
|
195
189
|
});
|
|
196
190
|
};
|
|
197
|
-
|
|
198
|
-
//#region src/components/Tooltip/Tooltip.tsx
|
|
191
|
+
// src/components/Tooltip/Tooltip.tsx
|
|
199
192
|
const ACTION_TOOLTIP_LIMIT = 30;
|
|
200
193
|
const HINT_UNDERLINE_CLASS_NAME = "tw:cursor-help tw:underline tw:decoration-dashed tw:decoration-muted-foreground/50 tw:underline-offset-2";
|
|
201
194
|
/** Mount once at the app root so tooltips share delay state. */
|
|
@@ -206,8 +199,7 @@ const TooltipProvider = Provider;
|
|
|
206
199
|
* - Use for icon-only buttons, disabled controls, truncated values.
|
|
207
200
|
* - Rich content → `HoverCard`; links or buttons → `Popover` (they break a11y here).
|
|
208
201
|
* - `variant` defaults to `"explanatory"` for strings over 30 chars, else `"action"`.
|
|
209
|
-
*
|
|
210
|
-
* @see RECIPES.md#disabled-button-tooltip
|
|
202
|
+
* - A disabled `Button` takes `disabledReason` instead.
|
|
211
203
|
*/
|
|
212
204
|
const Tooltip = ({ tooltip, children, className, keepOpenOnTriggerClick = false, variant, placement = "right", forceHide = false, forceShow = false, delayDuration, triggerAsChild = false, hintUnderline = false }) => {
|
|
213
205
|
const [open, setOpen] = useState(false);
|
|
@@ -245,8 +237,7 @@ Tooltip.Root = TooltipRoot;
|
|
|
245
237
|
Tooltip.Content = TooltipContent;
|
|
246
238
|
Tooltip.Trigger = TooltipTrigger;
|
|
247
239
|
Tooltip.Title = TooltipTitle;
|
|
248
|
-
|
|
249
|
-
//#region src/utils/decorators.tsx
|
|
240
|
+
// src/utils/decorators.tsx
|
|
250
241
|
const withTooltipProvider = (Story) => /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(Story, {}) });
|
|
251
242
|
const withVisualSettle = (Story) => /* @__PURE__ */ jsx("div", {
|
|
252
243
|
"data-visual-settle": true,
|
|
@@ -256,14 +247,11 @@ const withHiddenFullscreen = (Story) => /* @__PURE__ */ jsx("div", {
|
|
|
256
247
|
className: "tw:[&_[aria-label=Fullscreen]]:hidden",
|
|
257
248
|
children: /* @__PURE__ */ jsx(Story, {})
|
|
258
249
|
});
|
|
259
|
-
|
|
260
|
-
//#region src/utils/createPrefixedString.ts
|
|
250
|
+
// src/utils/createPrefixedString.ts
|
|
261
251
|
const createPrefixedString = (prefix) => (literals) => literals.reduce((acc, literal) => acc + literal, `${prefix}-`);
|
|
262
|
-
|
|
263
|
-
//#region src/utils/noop.ts
|
|
252
|
+
// src/utils/noop.ts
|
|
264
253
|
const noop = () => void 0;
|
|
265
|
-
|
|
266
|
-
//#region src/utils/debounce.ts
|
|
254
|
+
// src/utils/debounce.ts
|
|
267
255
|
const debounce = (fn, delay) => {
|
|
268
256
|
let timeoutId;
|
|
269
257
|
const debounced = (...args) => {
|
|
@@ -273,8 +261,7 @@ const debounce = (fn, delay) => {
|
|
|
273
261
|
debounced.cancel = () => clearTimeout(timeoutId);
|
|
274
262
|
return debounced;
|
|
275
263
|
};
|
|
276
|
-
|
|
277
|
-
//#region src/utils/isMac.ts
|
|
264
|
+
// src/utils/isMac.ts
|
|
278
265
|
const getIsMac = () => {
|
|
279
266
|
if (typeof navigator !== "undefined" && "userAgentData" in navigator) {
|
|
280
267
|
const platform = navigator.userAgentData.platform;
|
|
@@ -284,8 +271,7 @@ const getIsMac = () => {
|
|
|
284
271
|
return false;
|
|
285
272
|
};
|
|
286
273
|
const isMac = getIsMac();
|
|
287
|
-
|
|
288
|
-
//#region src/utils/useSHA256.ts
|
|
274
|
+
// src/utils/useSHA256.ts
|
|
289
275
|
const sha256 = async (text) => {
|
|
290
276
|
const msgUint8 = new TextEncoder().encode(text);
|
|
291
277
|
const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8);
|
|
@@ -305,8 +291,7 @@ const useSHA256 = (text) => {
|
|
|
305
291
|
}, [text]);
|
|
306
292
|
return text ? hash : "";
|
|
307
293
|
};
|
|
308
|
-
|
|
309
|
-
//#region src/utils/splitEntry.ts
|
|
294
|
+
// src/utils/splitEntry.ts
|
|
310
295
|
/** The separator a typed entry is split on when the caller names none. */
|
|
311
296
|
const DEFAULT_ENTRY_SEPARATOR = ",";
|
|
312
297
|
/**
|
|
@@ -327,7 +312,6 @@ const splitEntry = (entry, separator) => {
|
|
|
327
312
|
return true;
|
|
328
313
|
});
|
|
329
314
|
};
|
|
330
|
-
//#endregion
|
|
331
315
|
export { DEFAULT_ENTRY_SEPARATOR, HINT_UNDERLINE_CLASS_NAME, Tooltip, TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger, copyToClipboard, createChangeInputEvent, createPrefixedString, debounce, isMac, keyCodes, noop, splitEntry, useSHA256, withHiddenFullscreen, withTooltipProvider, withVisualSettle };
|
|
332
316
|
|
|
333
|
-
//# sourceMappingURL=utils-
|
|
317
|
+
//# sourceMappingURL=utils-DjFceY3H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-DjFceY3H.js","names":["Root"],"sources":["../src/utils/copyToClipboard.ts","../src/utils/createChangeInputEvent.ts","../src/constants/keyCodes.ts","../src/components/Tooltip/TooltipContent.tsx","../src/components/Tooltip/TooltipRoot.tsx","../src/components/Tooltip/TooltipTitle.tsx","../src/components/Tooltip/TooltipTrigger.tsx","../src/components/Tooltip/Tooltip.tsx","../src/utils/decorators.tsx","../src/utils/createPrefixedString.ts","../src/utils/noop.ts","../src/utils/debounce.ts","../src/utils/isMac.ts","../src/utils/useSHA256.ts","../src/utils/splitEntry.ts"],"sourcesContent":["/**\n * The async Clipboard API requires the document to be focused and rejects with\n * `NotAllowedError: Document is not focused` otherwise — which is the normal state\n * for a page inside an iframe that has not taken focus, such as Storybook's canvas\n * or an embedded preview. `execCommand` has no such requirement because it copies\n * the selection of a node we focus ourselves, so it covers that gap.\n */\nconst copyViaSelection = (text: string) => {\n const node = document.createElement('textarea');\n node.value = text;\n node.setAttribute('readonly', '');\n node.style.cssText = 'position:fixed;top:0;left:0;opacity:0';\n document.body.append(node);\n node.select();\n\n try {\n return document.execCommand('copy');\n } finally {\n node.remove();\n }\n};\n\nexport const copyToClipboard = async (text: string) => {\n try {\n await navigator.clipboard.writeText(text);\n } catch (error) {\n if (!copyViaSelection(text)) throw error;\n }\n};\n","import type { ChangeEvent } from 'react';\n\nexport const createChangeInputEvent = (input: HTMLInputElement) => {\n const changeEvent: ChangeEvent<HTMLInputElement> = {\n target: input,\n currentTarget: input,\n type: 'change',\n nativeEvent: new Event('change', { bubbles: true }),\n bubbles: true,\n cancelable: false,\n defaultPrevented: false,\n eventPhase: 2, // AT_TARGET\n isTrusted: false,\n preventDefault: () => {},\n isDefaultPrevented: () => false,\n stopPropagation: () => {},\n isPropagationStopped: () => false,\n persist: () => {},\n timeStamp: Date.now(),\n };\n\n Object.defineProperty(changeEvent, 'target', {\n value: input,\n writable: false,\n });\n\n return changeEvent;\n};\n","export const keyCodes = {\n ENTER: 'Enter',\n ESCAPE: 'Escape',\n SPACE: ' ',\n};\n","import type { ComponentProps } from 'react';\nimport { Content, Portal } from '@radix-ui/react-tooltip';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nconst tooltipVariants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:inline-block',\n 'tw:wrap-anywhere',\n 'tw:max-h-96',\n 'tw:overflow-y-auto',\n // Above `z-overlay` — every modal, menu and popup.\n 'tw:z-[1060]',\n\n // rich content\n 'tw:[&_hr]:my-3',\n 'tw:[&_hr]:border-current/20',\n 'tw:[&_p:last-of-type]:mb-0',\n\n // chrome\n 'tw:rounded-popover',\n 'tw:border',\n 'tw:border-solid',\n 'tw:border-border',\n 'tw:bg-popover',\n 'tw:text-popover-foreground',\n 'tw:shadow-md',\n\n // open animation\n 'tw:data-[state=delayed-open]:animate-in',\n 'tw:data-[state=instant-open]:animate-in',\n 'tw:data-[state=delayed-open]:fade-in-0',\n 'tw:data-[state=instant-open]:fade-in-0',\n 'tw:data-[state=delayed-open]:zoom-in-95',\n 'tw:data-[state=instant-open]:zoom-in-95',\n\n // closed animation\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 // position animation\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 {\n defaultVariants: {\n variant: 'action',\n },\n variants: {\n variant: {\n action: [\n 'tw:max-w-fit',\n 'tw:px-3',\n 'tw:py-2',\n\n 'tw:text-center',\n 'tw:text-xs',\n 'tw:font-medium',\n ],\n explanatory: [\n 'tw:max-w-80',\n 'tw:px-4',\n 'tw:py-3',\n 'tw:text-left',\n\n 'tw:text-sm',\n 'tw:font-normal',\n ],\n },\n },\n },\n);\n\ntype Props = {\n keepOpenOnPointerDownOutside?: boolean;\n placement?: ComponentProps<typeof Content>['side'];\n} & Omit<ComponentProps<typeof Content>, 'side'> &\n VariantProps<typeof tooltipVariants>;\n\nexport const TooltipContent = ({\n className,\n variant,\n keepOpenOnPointerDownOutside = false,\n children,\n onPointerDownOutside,\n sideOffset = 8,\n collisionPadding = 8,\n hideWhenDetached = true,\n placement = 'right',\n ...rest\n}: Props) => {\n const handlePointerDownOutside: ComponentProps<typeof Content>['onPointerDownOutside'] = (\n event,\n ) => {\n if (keepOpenOnPointerDownOutside) event.preventDefault();\n onPointerDownOutside?.(event);\n };\n\n return (\n <Portal>\n <Content\n {...rest}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n onPointerDownOutside={handlePointerDownOutside}\n className={tooltipVariants({ className, variant })}\n hideWhenDetached={hideWhenDetached}\n side={placement}\n >\n {children}\n </Content>\n </Portal>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Root } from '@radix-ui/react-tooltip';\n\ntype Props = ComponentProps<typeof Root>;\n\nconst DELAY_SHOW_TOOLTIP = 300;\n\nexport const TooltipRoot = ({ children, delayDuration = DELAY_SHOW_TOOLTIP, ...rest }: Props) => (\n <Root {...rest} delayDuration={delayDuration}>\n {children}\n </Root>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\n/**\n * Small uppercase heading above a rich tooltip's body copy, in the tooltip's text colour.\n */\nexport const TooltipTitle = ({ className, ...rest }: ComponentProps<'div'>) => (\n <div\n className={cn('tw:mb-2 tw:text-xs tw:leading-5 tw:font-semibold tw:uppercase', className)}\n {...rest}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { Trigger } from '@radix-ui/react-tooltip';\n\nimport { cn } from '../../utils';\n\n/**\n * Radix stamps the tooltip's own open/closed `data-state` onto the trigger. Merged onto an\n * `asChild` child that keeps a `data-state` of its own — `ToggleGroup.Item`, `Switch`, a `Tabs`\n * trigger — it wins, because those primitives spread incoming props *after* their own attribute.\n * The child then silently loses every `data-[state=…]` style it has, which is usually the only\n * thing marking it as selected.\n *\n * The tooltip's trigger state is styled nowhere, so it is dropped before it reaches the child.\n */\nconst WithoutTooltipState = ({\n children,\n ...props\n // `Slot`'s own props, plus the one attribute this exists to remove: React's types declare no\n // `data-*`, so it has to be named to be destructured away.\n}: ComponentProps<typeof Slot> & { 'data-state'?: string }) => {\n const { 'data-state': _tooltipState, ...rest } = props;\n\n return <Slot {...rest}>{children}</Slot>;\n};\n\ntype Props = {\n keepOpenOnClick?: boolean;\n} & ComponentProps<typeof Trigger>;\n\nexport const TooltipTrigger = ({\n ref,\n children,\n className,\n keepOpenOnClick = false,\n onClick,\n onPointerDown,\n asChild,\n ...rest\n}: Props) => {\n const handleClick: ComponentProps<typeof Trigger>['onClick'] = (event) => {\n if (keepOpenOnClick) event.preventDefault();\n onClick?.(event);\n };\n\n const handlePointerDown: ComponentProps<typeof Trigger>['onPointerDown'] = (event) => {\n if (keepOpenOnClick) event.preventDefault();\n onPointerDown?.(event);\n };\n\n return (\n <Trigger\n {...rest}\n asChild\n ref={ref}\n className={cn('tailwindcss-preflight', className)}\n onClick={handleClick}\n onPointerDown={handlePointerDown}\n >\n {asChild ? (\n <WithoutTooltipState>{children}</WithoutTooltipState>\n ) : (\n // Default-mode trigger wraps children in a span so Radix has a\n // single DOM element to attach handlers to. `tailwindcss-preflight`\n // (merged in via Slot) activates Tailwind's preflight inside the\n // span, which sets `svg { display: block }` — without an inline-flex\n // container that would stack any bare Lucide icon onto its own\n // line. `tw:inline-flex tw:items-center` keeps icon + text aligned.\n <span className=\"tw:inline-flex tw:items-center\">{children}</span>\n )}\n </Trigger>\n );\n};\n","import { useState } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport type { Content, Trigger } from '@radix-ui/react-tooltip';\nimport { Provider } from '@radix-ui/react-tooltip';\n\nimport { keyCodes } from '../../constants/keyCodes';\n\nimport { TooltipContent } from './TooltipContent';\nimport { TooltipRoot } from './TooltipRoot';\nimport { TooltipTitle } from './TooltipTitle';\nimport { TooltipTrigger } from './TooltipTrigger';\n\nconst ACTION_TOOLTIP_LIMIT = 30;\n\nexport const HINT_UNDERLINE_CLASS_NAME =\n 'tw:cursor-help tw:underline tw:decoration-dashed tw:decoration-muted-foreground/50 tw:underline-offset-2';\n\ntype TriggerProps = {\n triggerAsChild?: boolean;\n};\n\nexport type Props = {\n /** Stays open on trigger click (click-to-copy feedback). */\n keepOpenOnTriggerClick?: boolean;\n /** Plain text only — interactive content belongs in `HoverCard` / `Popover`. */\n tooltip: ReactNode;\n children: ReactNode;\n placement?: ComponentProps<typeof Content>['side'];\n /** Hides it regardless of hover. */\n forceHide?: boolean;\n /** Shows it regardless of hover (e.g. guided tours). */\n forceShow?: boolean;\n /** In ms; defaults to the shared 300ms. */\n delayDuration?: number;\n /** Dashed-underline hover hint on the trigger. */\n hintUnderline?: boolean;\n className?: string;\n} & TriggerProps &\n Pick<ComponentProps<typeof TooltipContent>, 'variant' | 'className'>;\n\n/** Mount once at the app root so tooltips share delay state. */\nexport const TooltipProvider = Provider;\n\n/**\n * Short plain-text label on hover or focus.\n *\n * - Use for icon-only buttons, disabled controls, truncated values.\n * - Rich content → `HoverCard`; links or buttons → `Popover` (they break a11y here).\n * - `variant` defaults to `\"explanatory\"` for strings over 30 chars, else `\"action\"`.\n * - A disabled `Button` takes `disabledReason` instead.\n */\nexport const Tooltip = ({\n tooltip,\n children,\n className,\n keepOpenOnTriggerClick = false,\n variant,\n placement = 'right',\n forceHide = false,\n forceShow = false,\n delayDuration,\n triggerAsChild = false,\n hintUnderline = false,\n}: Props) => {\n const [open, setOpen] = useState(false);\n\n const resolvedVariant = (() => {\n if (!!variant) return variant;\n if (typeof tooltip === 'string' && tooltip.length > ACTION_TOOLTIP_LIMIT) return 'explanatory';\n\n return 'action';\n })();\n\n const isActionVariant = resolvedVariant === 'action';\n\n const handleKeyUp: ComponentProps<typeof Trigger>['onKeyUp'] = (event) => {\n if (![keyCodes.ENTER, keyCodes.SPACE].includes(event.key)) return;\n event.stopPropagation();\n };\n\n return (\n <TooltipRoot\n open={!!tooltip && (open || forceShow) && !forceHide}\n onOpenChange={setOpen}\n delayDuration={delayDuration}\n disableHoverableContent={isActionVariant}\n >\n <TooltipTrigger\n asChild={triggerAsChild}\n keepOpenOnClick={keepOpenOnTriggerClick}\n onKeyUp={handleKeyUp}\n className={hintUnderline ? HINT_UNDERLINE_CLASS_NAME : undefined}\n >\n {children}\n </TooltipTrigger>\n\n <TooltipContent\n className={className}\n variant={resolvedVariant}\n placement={placement}\n keepOpenOnPointerDownOutside={keepOpenOnTriggerClick}\n >\n {tooltip}\n </TooltipContent>\n </TooltipRoot>\n );\n};\n\nTooltip.Root = TooltipRoot;\nTooltip.Content = TooltipContent;\nTooltip.Trigger = TooltipTrigger;\nTooltip.Title = TooltipTitle;\n","import type { ComponentType } from 'react';\n\nimport { TooltipProvider } from '../components/Tooltip';\n\nexport const withTooltipProvider = (Story: ComponentType) => (\n <TooltipProvider>\n <Story />\n </TooltipProvider>\n);\n\n// Marks a story whose final render arrives asynchronously (lazy chunk, debounced\n// parse). The visual suite waits for every `[data-skeleton]` inside this box to\n// unmount before capturing, so the baseline is the settled content, never the\n// placeholder it briefly shows.\nexport const withVisualSettle = (Story: ComponentType) => (\n <div data-visual-settle>\n <Story />\n </div>\n);\n\n// position:fixed only fills the Storybook iframe, not the browser window.\nexport const withHiddenFullscreen = (Story: ComponentType) => (\n <div className=\"tw:[&_[aria-label=Fullscreen]]:hidden\">\n <Story />\n </div>\n);\n","export const createPrefixedString = (prefix: string) => (literals: TemplateStringsArray) =>\n literals.reduce((acc, literal) => acc + literal, `${prefix}-`);\n","export const noop = () => void 0;\n","type DebouncedFn<T extends (...args: any[]) => void> = {\n (...args: Parameters<T>): void;\n cancel: () => void;\n};\n\nexport const debounce = <T extends (...args: any[]) => void>(\n fn: T,\n delay: number,\n): DebouncedFn<T> => {\n let timeoutId: ReturnType<typeof setTimeout>;\n const debounced = (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n debounced.cancel = () => clearTimeout(timeoutId);\n return debounced;\n};\n","// Platform detection\ntype NavigatorUAData = {\n platform: string;\n brands: { brand: string; version: string }[];\n mobile: boolean;\n};\n\nconst getIsMac = (): boolean => {\n // Modern approach using navigator.userAgentData\n if (typeof navigator !== 'undefined' && 'userAgentData' in navigator) {\n const platform = (navigator.userAgentData as NavigatorUAData).platform;\n\n if (typeof platform === 'string') {\n return platform.toLowerCase() === 'macos';\n }\n }\n\n if (typeof navigator !== 'undefined' && typeof navigator.platform === 'string') {\n return navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n }\n\n // Server-side rendering fallback\n return false;\n};\n\nexport const isMac = getIsMac();\n","import { useEffect, useState } from 'react';\n\n// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\nconst sha256 = async (text: string) => {\n const msgUint8 = new TextEncoder().encode(text);\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n};\n\nexport const useSHA256 = (text?: string) => {\n const [hash, setHash] = useState('');\n\n useEffect(() => {\n if (!text) return;\n let cancelled = false;\n sha256(text).then((h) => {\n if (!cancelled) setHash(h);\n });\n return () => {\n cancelled = true;\n };\n }, [text]);\n\n // Empty input has no hash — derive it during render instead of syncing state\n // in the effect (avoids the extra render and a stale-value frame).\n return text ? hash : '';\n};\n","/** The separator a typed entry is split on when the caller names none. */\nexport const DEFAULT_ENTRY_SEPARATOR = ',';\n\n/**\n * The strings one typed entry stands for.\n *\n * - Parts are trimmed; blanks dropped.\n * - Repeats collapse case-insensitively, matching the combobox's display-string matching.\n * - A `null` separator returns the entry verbatim, untrimmed — the caller must reject blank text.\n */\nexport const splitEntry = (entry: string, separator: string | RegExp | null): string[] => {\n if (separator === null) return [entry];\n\n const seen = new Set<string>();\n return entry\n .split(separator)\n .map((part) => part.trim())\n .filter((part) => {\n if (part === '') return false;\n const key = part.toLowerCase();\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n"],"mappings":"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"}
|
package/dist/vega.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { ResolvedColorScheme } from "./types-
|
|
1
|
+
import { ResolvedColorScheme } from "./types-CsZuwfxc.js";
|
|
2
2
|
import { Config } from "vega-lite";
|
|
3
|
-
//#region src/vega/useVegaTheme.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* {@link vegaTheme} for the current scheme and brand, rebuilt when either changes.
|
|
6
5
|
*
|
|
@@ -8,8 +7,6 @@ import { Config } from "vega-lite";
|
|
|
8
7
|
* `useThemeAttributes().cacheKey`) and re-render the chart.
|
|
9
8
|
*/
|
|
10
9
|
declare const useVegaTheme: () => Config;
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/vega/vegaTheme.d.ts
|
|
13
10
|
/**
|
|
14
11
|
* The design system's Vega-Lite chart look, following scheme and brand.
|
|
15
12
|
*
|
|
@@ -19,6 +16,5 @@ declare const useVegaTheme: () => Config;
|
|
|
19
16
|
* scheme or brand change; `useVegaTheme` does.
|
|
20
17
|
*/
|
|
21
18
|
declare const vegaTheme: (scheme: ResolvedColorScheme, from?: Element | null) => Config;
|
|
22
|
-
//#endregion
|
|
23
19
|
export { useVegaTheme, vegaTheme };
|
|
24
20
|
//# sourceMappingURL=vega.d.ts.map
|
package/dist/vega.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useThemeAttributes } from "./themeTokens-
|
|
2
|
-
import { vegaTheme } from "./vegaTheme-
|
|
1
|
+
import { useThemeAttributes } from "./themeTokens-B60cQtAY.js";
|
|
2
|
+
import { vegaTheme } from "./vegaTheme-BcTNRmVS.js";
|
|
3
3
|
import { useMemo } from "react";
|
|
4
|
-
|
|
4
|
+
// src/vega/useVegaTheme.ts
|
|
5
5
|
/**
|
|
6
6
|
* {@link vegaTheme} for the current scheme and brand, rebuilt when either changes.
|
|
7
7
|
*
|
|
@@ -12,7 +12,6 @@ const useVegaTheme = () => {
|
|
|
12
12
|
const theme = useThemeAttributes();
|
|
13
13
|
return useMemo(() => vegaTheme(theme.scheme, theme.scope), [theme]);
|
|
14
14
|
};
|
|
15
|
-
//#endregion
|
|
16
15
|
export { useVegaTheme, vegaTheme };
|
|
17
16
|
|
|
18
17
|
//# sourceMappingURL=vega.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SERIES_TOKENS, createVegaColorResolver } from "./vegaTokens-
|
|
2
|
-
|
|
1
|
+
import { SERIES_TOKENS, createVegaColorResolver } from "./vegaTokens-DnCcy7JY.js";
|
|
2
|
+
// src/vega/vegaTheme.ts
|
|
3
3
|
const CHART_FONT = "Inter, system-ui, sans-serif";
|
|
4
4
|
/**
|
|
5
5
|
* The design system's Vega-Lite chart look, following scheme and brand.
|
|
@@ -43,7 +43,6 @@ const vegaTheme = (scheme, from) => {
|
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
45
|
};
|
|
46
|
-
//#endregion
|
|
47
46
|
export { vegaTheme };
|
|
48
47
|
|
|
49
|
-
//# sourceMappingURL=vegaTheme-
|
|
48
|
+
//# sourceMappingURL=vegaTheme-BcTNRmVS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vegaTheme-
|
|
1
|
+
{"version":3,"file":"vegaTheme-BcTNRmVS.js","names":[],"sources":["../src/vega/vegaTheme.ts"],"sourcesContent":["import type { Config } from 'vega-lite';\n\nimport type { ResolvedColorScheme } from '../components/ThemeProvider/types';\n\nimport { createVegaColorResolver, SERIES_TOKENS } from './vegaTokens';\n\nconst CHART_FONT = 'Inter, system-ui, sans-serif';\n\n/**\n * The design system's Vega-Lite chart look, following scheme and brand.\n *\n * - `range.category` is `--chart-1..5`, the same palette as `@keboola/design/charts`.\n * - A range set on the spec's own scale still wins (Flint charts rely on it).\n * - Colours are concrete `rgb()` strings — vega never reads the stylesheet — so rebuild on a\n * scheme or brand change; `useVegaTheme` does.\n */\nexport const vegaTheme = (scheme: ResolvedColorScheme, from?: Element | null): Config => {\n const token = createVegaColorResolver(scheme, from);\n\n const label = token('muted-foreground');\n const heading = token('foreground');\n const line = token('border');\n\n return {\n background: 'transparent',\n font: CHART_FONT,\n axis: {\n labelColor: label,\n titleColor: heading,\n gridColor: token('border', 0.6),\n domainColor: line,\n tickColor: line,\n },\n legend: { labelColor: label, titleColor: heading },\n header: { labelColor: label, titleColor: heading },\n title: { color: heading, subtitleColor: label },\n text: { color: heading },\n range: {\n category: SERIES_TOKENS.map((name) => token(name)),\n ramp: [token('accent'), token('chart-1')],\n },\n };\n};\n"],"mappings":";;AAMA,MAAM,aAAa;;;;;;;;;AAUnB,MAAa,aAAa,QAA6B,SAAkC;CACvF,MAAM,QAAQ,wBAAwB,QAAQ,IAAI;CAElD,MAAM,QAAQ,MAAM,kBAAkB;CACtC,MAAM,UAAU,MAAM,YAAY;CAClC,MAAM,OAAO,MAAM,QAAQ;CAE3B,OAAO;EACL,YAAY;EACZ,MAAM;EACN,MAAM;GACJ,YAAY;GACZ,YAAY;GACZ,WAAW,MAAM,UAAU,EAAG;GAC9B,aAAa;GACb,WAAW;EACb;EACA,QAAQ;GAAE,YAAY;GAAO,YAAY;EAAQ;EACjD,QAAQ;GAAE,YAAY;GAAO,YAAY;EAAQ;EACjD,OAAO;GAAE,OAAO;GAAS,eAAe;EAAM;EAC9C,MAAM,EAAE,OAAO,QAAQ;EACvB,OAAO;GACL,UAAU,cAAc,KAAK,SAAS,MAAM,IAAI,CAAC;GACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC;EAC1C;CACF;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createChannelResolver } from "./themeTokens-
|
|
2
|
-
|
|
1
|
+
import { createChannelResolver } from "./themeTokens-B60cQtAY.js";
|
|
2
|
+
// src/vega/vegaTokens.ts
|
|
3
3
|
/**
|
|
4
4
|
* Serializes `"R G B"` channels comma-separated, the only form vega parses.
|
|
5
5
|
*
|
|
@@ -118,7 +118,6 @@ const tierTwoColour = (colour, scheme) => {
|
|
|
118
118
|
const shifted = channels.slice(0, 3).map((c) => Math.round(Number(c) + (towards - Number(c)) * amount));
|
|
119
119
|
return vegaRgb(shifted.join(" "));
|
|
120
120
|
};
|
|
121
|
-
//#endregion
|
|
122
121
|
export { SERIES_TOKENS, createVegaColorResolver, tierTwoColour };
|
|
123
122
|
|
|
124
|
-
//# sourceMappingURL=vegaTokens-
|
|
123
|
+
//# sourceMappingURL=vegaTokens-DnCcy7JY.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vegaTokens-
|
|
1
|
+
{"version":3,"file":"vegaTokens-DnCcy7JY.js","names":[],"sources":["../src/vega/vegaTokens.ts"],"sourcesContent":["import type { ResolvedColorScheme } from '../components/ThemeProvider/types';\nimport { createChannelResolver } from '../utils/themeTokens';\n\n/**\n * Serializes `\"R G B\"` channels comma-separated, the only form vega parses.\n *\n * - vega reads colours through d3-color 3.1, which answers `null` for the\n * space-separated CSS Color 4 form the rest of the package emits.\n * - A flat fill survives that anyway — the string reaches the SVG attribute and\n * the browser parses it. An interpolated one does not: both endpoints of a\n * sequential ramp collapse, and a quantitative scale paints solid black.\n */\nconst vegaRgb = (channels: string, alpha?: number): string => {\n const c = channels.split(/\\s+/).join(', ');\n return alpha === undefined ? `rgb(${c})` : `rgba(${c}, ${alpha})`;\n};\n\n/** The `--chart-*` slots, in series order. */\nexport const SERIES_TOKENS = ['chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5'] as const;\n\n/**\n * Fallback channels for the tokens a vega chart reads, mirroring the `:root` /\n * `[data-theme='dark']` blocks of `styles.css`. The resolver reaches these only\n * when the live custom property is missing — SSR, or a unit test that loads no\n * CSS.\n */\nconst FALLBACK_CHANNELS = {\n foreground: { light: '30 41 59', dark: '229 230 236' },\n 'muted-foreground': { light: '100 116 139', dark: '141 144 153' },\n border: { light: '229 231 235', dark: '52 53 62' },\n 'chart-1': { light: '31 143 255', dark: '92 173 255' },\n 'chart-2': { light: '0 194 135', dark: '0 230 161' },\n 'chart-3': { light: '146 92 255', dark: '173 133 255' },\n 'chart-4': { light: '245 147 0', dark: '255 190 92' },\n 'chart-5': { light: '237 94 223', dark: '242 140 232' },\n // The sequential ramp's low end and the surface it must stay legible against.\n accent: { light: '224 242 254', dark: '30 58 95' },\n card: { light: '255 255 255', dark: '34 34 40' },\n // Diagram surfaces and accents (`MermaidDiagram`).\n muted: { light: '241 245 249', dark: '38 38 45' },\n primary: { light: '37 99 235', dark: '31 143 255' },\n destructive: { light: '220 38 38', dark: '229 72 77' },\n} as const;\n\nexport type VegaTokenName = keyof typeof FALLBACK_CHANNELS;\n\n/**\n * A vega-serializing token resolver bound to one `getComputedStyle` snapshot.\n *\n * - Answers `rgb(R, G, B)` / `rgba(R, G, B, a)` — see {@link vegaRgb}.\n * - Falls back per scheme when the custom property is not painted.\n * - Build one per palette, never at module level: the values change whenever\n * the scheme or the brand does.\n */\nexport const createVegaColorResolver = (scheme: ResolvedColorScheme, from?: Element | null) => {\n const resolve = createChannelResolver(from);\n\n return (token: VegaTokenName, alpha?: number): string =>\n vegaRgb(resolve(token, FALLBACK_CHANNELS[token][scheme]), alpha);\n};\n\n/**\n * How the second palette tier (series 6-10) is derived from the core hues.\n *\n * - Each hue moves *away* from its surface: darker on light, lighter on dark.\n * Darkening on dark would drop contrast from ~6.7:1 to ~3.7:1.\n * - `amount` is the fraction of the distance travelled toward `towards`.\n */\nconst TIER_TWO_SHIFT = {\n light: { towards: 0, amount: 0.38 },\n dark: { towards: 255, amount: 0.35 },\n} as const;\n\n/** A series colour's second-tier variant; an input not shaped like `rgb()` comes back unchanged. */\nexport const tierTwoColour = (colour: string, scheme: ResolvedColorScheme): string => {\n const channels = colour.match(/\\d+/g);\n if (!channels || channels.length < 3) return colour;\n const { towards, amount } = TIER_TWO_SHIFT[scheme];\n const shifted = channels\n .slice(0, 3)\n .map((c) => Math.round(Number(c) + (towards - Number(c)) * amount));\n return vegaRgb(shifted.join(' '));\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,WAAW,UAAkB,UAA2B;CAC5D,MAAM,IAAI,SAAS,MAAM,KAAK,CAAC,CAAC,KAAK,IAAI;CACzC,OAAO,UAAU,KAAA,IAAY,OAAO,EAAE,KAAK,QAAQ,EAAE,IAAI,MAAM;AACjE;;AAGA,MAAa,gBAAgB;CAAC;CAAW;CAAW;CAAW;CAAW;AAAS;;;;;;;AAQnF,MAAM,oBAAoB;CACxB,YAAY;EAAE,OAAO;EAAY,MAAM;CAAc;CACrD,oBAAoB;EAAE,OAAO;EAAe,MAAM;CAAc;CAChE,QAAQ;EAAE,OAAO;EAAe,MAAM;CAAW;CACjD,WAAW;EAAE,OAAO;EAAc,MAAM;CAAa;CACrD,WAAW;EAAE,OAAO;EAAa,MAAM;CAAY;CACnD,WAAW;EAAE,OAAO;EAAc,MAAM;CAAc;CACtD,WAAW;EAAE,OAAO;EAAa,MAAM;CAAa;CACpD,WAAW;EAAE,OAAO;EAAc,MAAM;CAAc;CAEtD,QAAQ;EAAE,OAAO;EAAe,MAAM;CAAW;CACjD,MAAM;EAAE,OAAO;EAAe,MAAM;CAAW;CAE/C,OAAO;EAAE,OAAO;EAAe,MAAM;CAAW;CAChD,SAAS;EAAE,OAAO;EAAa,MAAM;CAAa;CAClD,aAAa;EAAE,OAAO;EAAa,MAAM;CAAY;AACvD;;;;;;;;;AAYA,MAAa,2BAA2B,QAA6B,SAA0B;CAC7F,MAAM,UAAU,sBAAsB,IAAI;CAE1C,QAAQ,OAAsB,UAC5B,QAAQ,QAAQ,OAAO,kBAAkB,MAAM,CAAC,OAAO,GAAG,KAAK;AACnE;;;;;;;;AASA,MAAM,iBAAiB;CACrB,OAAO;EAAE,SAAS;EAAG,QAAQ;CAAK;CAClC,MAAM;EAAE,SAAS;EAAK,QAAQ;CAAK;AACrC;;AAGA,MAAa,iBAAiB,QAAgB,WAAwC;CACpF,MAAM,WAAW,OAAO,MAAM,MAAM;CACpC,IAAI,CAAC,YAAY,SAAS,SAAS,GAAG,OAAO;CAC7C,MAAM,EAAE,SAAS,WAAW,eAAe;CAC3C,MAAM,UAAU,SACb,MAAM,GAAG,CAAC,CAAC,CACX,KAAK,MAAM,KAAK,MAAM,OAAO,CAAC,KAAK,UAAU,OAAO,CAAC,KAAK,MAAM,CAAC;CACpE,OAAO,QAAQ,QAAQ,KAAK,GAAG,CAAC;AAClC"}
|