@keboola/design 10.1.0 → 11.0.1
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 +2 -0
- package/dist/AIKit-Dre37SJr.js +1320 -0
- package/dist/AIKit-Dre37SJr.js.map +1 -0
- package/dist/Alert-DfZq9kGe.js +133 -0
- package/dist/Alert-DfZq9kGe.js.map +1 -0
- package/dist/AlertModal-BUC4Es8o.js +222 -0
- package/dist/AlertModal-BUC4Es8o.js.map +1 -0
- package/dist/AppShell-B5GQN6Zs.js +143 -0
- package/dist/AppShell-B5GQN6Zs.js.map +1 -0
- package/dist/AutoSaveTextarea-BeuWuszr.js +58 -0
- package/dist/AutoSaveTextarea-BeuWuszr.js.map +1 -0
- package/dist/Badge-Ch26CXoP.js +195 -0
- package/dist/Badge-Ch26CXoP.js.map +1 -0
- package/dist/BrandEditor-B8o9zdZO.js +903 -0
- package/dist/BrandEditor-B8o9zdZO.js.map +1 -0
- package/dist/BrandLogo-CJkRd0F8.js +46 -0
- package/dist/BrandLogo-CJkRd0F8.js.map +1 -0
- package/dist/Breadcrumb-DJp7WwSv.js +330 -0
- package/dist/Breadcrumb-DJp7WwSv.js.map +1 -0
- package/dist/Button-nzmDNS2q.js +391 -0
- package/dist/Button-nzmDNS2q.js.map +1 -0
- package/dist/Calendar-cG5NIJ4O.js +6768 -0
- package/dist/Calendar-cG5NIJ4O.js.map +1 -0
- package/dist/Card-BAoZ35CV.js +105 -0
- package/dist/Card-BAoZ35CV.js.map +1 -0
- package/dist/Checkbox-GJ8-srt4.js +97 -0
- package/dist/Checkbox-GJ8-srt4.js.map +1 -0
- package/dist/Clipboard-CBJZiviP.js +58 -0
- package/dist/Clipboard-CBJZiviP.js.map +1 -0
- package/dist/ClipboardButton-ez5V3fkk.js +43 -0
- package/dist/ClipboardButton-ez5V3fkk.js.map +1 -0
- package/dist/CodeEditor-BfQJfbhL.js +952 -0
- package/dist/CodeEditor-BfQJfbhL.js.map +1 -0
- package/dist/Collapsible-BQXWEOBC.js +34 -0
- package/dist/Collapsible-BQXWEOBC.js.map +1 -0
- package/dist/ColorInput-Dx8Dsv7Y.js +180 -0
- package/dist/ColorInput-Dx8Dsv7Y.js.map +1 -0
- package/dist/ColorModeSwitch-CCqj7tjE.js +77 -0
- package/dist/ColorModeSwitch-CCqj7tjE.js.map +1 -0
- package/dist/Combobox-c_xBjf0P.js +439 -0
- package/dist/Combobox-c_xBjf0P.js.map +1 -0
- package/dist/Command-CQ_bQsJp.js +102 -0
- package/dist/Command-CQ_bQsJp.js.map +1 -0
- package/dist/CopyField-BJ96zvXs.js +322 -0
- package/dist/CopyField-BJ96zvXs.js.map +1 -0
- package/dist/DateInput-CMD3dY-T.js +141 -0
- package/dist/DateInput-CMD3dY-T.js.map +1 -0
- package/dist/DatePicker-BbFbmsGl.js +24 -0
- package/dist/DatePicker-BbFbmsGl.js.map +1 -0
- package/dist/DateRangeInput-D3BhiKyk.js +139 -0
- package/dist/DateRangeInput-D3BhiKyk.js.map +1 -0
- package/dist/DateRangePicker-BiUgtt_M.js +159 -0
- package/dist/DateRangePicker-BiUgtt_M.js.map +1 -0
- package/dist/DiagramSkeleton-lwBS2YBa.js +11 -0
- package/dist/DiagramSkeleton-lwBS2YBa.js.map +1 -0
- package/dist/DiffView-ppTIzh2h.js +429 -0
- package/dist/DiffView-ppTIzh2h.js.map +1 -0
- package/dist/DropdownMenu-B6ZbYvaM.js +327 -0
- package/dist/DropdownMenu-B6ZbYvaM.js.map +1 -0
- package/dist/FieldBox-D7DYtX_m.js +70 -0
- package/dist/FieldBox-D7DYtX_m.js.map +1 -0
- package/dist/FileUpload-sXRv7JiY.js +2527 -0
- package/dist/FileUpload-sXRv7JiY.js.map +1 -0
- package/dist/Form-BDCef6O9.js +371 -0
- package/dist/Form-BDCef6O9.js.map +1 -0
- package/dist/FormGroup-S9mPNHKH.js +124 -0
- package/dist/FormGroup-S9mPNHKH.js.map +1 -0
- package/dist/FullScreenModal-CJa2VkJ2.js +96 -0
- package/dist/FullScreenModal-CJa2VkJ2.js.map +1 -0
- package/dist/HoverCard-WfDkLK1s.js +31 -0
- package/dist/HoverCard-WfDkLK1s.js.map +1 -0
- package/dist/InputGroup-BJWsI35s.js +292 -0
- package/dist/InputGroup-BJWsI35s.js.map +1 -0
- package/dist/Kbd-CxHAo1oo.js +111 -0
- package/dist/Kbd-CxHAo1oo.js.map +1 -0
- package/dist/MarkedText-Ckbft5mw.js +44 -0
- package/dist/MarkedText-Ckbft5mw.js.map +1 -0
- package/dist/MermaidDiagram-BB06gymm.js +399 -0
- package/dist/MermaidDiagram-BB06gymm.js.map +1 -0
- package/dist/Modal-BA5Wc3sx.js +185 -0
- package/dist/Modal-BA5Wc3sx.js.map +1 -0
- package/dist/ModalTitle-C76ke2eo.js +28 -0
- package/dist/ModalTitle-C76ke2eo.js.map +1 -0
- package/dist/MultiActionButtonGroup-CiBHxsSk.js +33 -0
- package/dist/MultiActionButtonGroup-CiBHxsSk.js.map +1 -0
- package/dist/Navbar-t16usFZQ.js +322 -0
- package/dist/Navbar-t16usFZQ.js.map +1 -0
- package/dist/OtpInput-CbbymqYs.js +93 -0
- package/dist/OtpInput-CbbymqYs.js.map +1 -0
- package/dist/PageHeader-Q3IpCnQd.js +177 -0
- package/dist/PageHeader-Q3IpCnQd.js.map +1 -0
- package/dist/PageLayout-DSVM-ASz.js +176 -0
- package/dist/PageLayout-DSVM-ASz.js.map +1 -0
- package/dist/PageToolbar-0_1OBzaZ.js +153 -0
- package/dist/PageToolbar-0_1OBzaZ.js.map +1 -0
- package/dist/Pagination-CM_Rszz-.js +70 -0
- package/dist/Pagination-CM_Rszz-.js.map +1 -0
- package/dist/Popconfirm-BGe1jLov.js +170 -0
- package/dist/Popconfirm-BGe1jLov.js.map +1 -0
- package/dist/Popover-Ca0V6AD1.js +92 -0
- package/dist/Popover-Ca0V6AD1.js.map +1 -0
- package/dist/RadioGroup-sIveSsNa.js +233 -0
- package/dist/RadioGroup-sIveSsNa.js.map +1 -0
- package/dist/Resizable-D3vYToZH.js +52 -0
- package/dist/Resizable-D3vYToZH.js.map +1 -0
- package/dist/Search-3UiqNZRj.js +184 -0
- package/dist/Search-3UiqNZRj.js.map +1 -0
- package/dist/SearchInput-D2fcOv7E.js +102 -0
- package/dist/SearchInput-D2fcOv7E.js.map +1 -0
- package/dist/SectionNav--7bw2b6u.js +276 -0
- package/dist/SectionNav--7bw2b6u.js.map +1 -0
- package/dist/Select-4YX38G5h.js +181 -0
- package/dist/Select-4YX38G5h.js.map +1 -0
- package/dist/Sheet-BQrX8-h5.js +169 -0
- package/dist/Sheet-BQrX8-h5.js.map +1 -0
- package/dist/Sidebar-ROaR_AqC.js +799 -0
- package/dist/Sidebar-ROaR_AqC.js.map +1 -0
- package/dist/Slider-Da_3mS5v.js +127 -0
- package/dist/Slider-Da_3mS5v.js.map +1 -0
- package/dist/Stepper-C8sm9ZFM.js +325 -0
- package/dist/Stepper-C8sm9ZFM.js.map +1 -0
- package/dist/Switch-CX2A0v50.js +201 -0
- package/dist/Switch-CX2A0v50.js.map +1 -0
- package/dist/Table-CvYuTuNU.js +104 -0
- package/dist/Table-CvYuTuNU.js.map +1 -0
- package/dist/Tabs-EAihyqCt.js +74 -0
- package/dist/Tabs-EAihyqCt.js.map +1 -0
- package/dist/TextInput-BGed-V13.js +110 -0
- package/dist/TextInput-BGed-V13.js.map +1 -0
- package/dist/ThemeProvider-QncUrfJn.js +203 -0
- package/dist/ThemeProvider-QncUrfJn.js.map +1 -0
- package/dist/TimePicker-B_NegL-7.js +98 -0
- package/dist/TimePicker-B_NegL-7.js.map +1 -0
- package/dist/Timeline-6btyJl4D.js +154 -0
- package/dist/Timeline-6btyJl4D.js.map +1 -0
- package/dist/Toast-DQSbs3oA.js +49 -0
- package/dist/Toast-DQSbs3oA.js.map +1 -0
- package/dist/ToggleGroup-Cy_10Mvu.js +47 -0
- package/dist/ToggleGroup-Cy_10Mvu.js.map +1 -0
- package/dist/Workbench-BzE-Vvd9.js +293 -0
- package/dist/Workbench-BzE-Vvd9.js.map +1 -0
- package/dist/ZoomableSvg-DG9PnAm8.js +248 -0
- package/dist/ZoomableSvg-DG9PnAm8.js.map +1 -0
- package/dist/charts.d.ts +124 -111
- package/dist/charts.js +303 -249
- package/dist/charts.js.map +1 -1
- package/dist/classNames-BzrkDnOD.js +9 -0
- package/dist/classNames-BzrkDnOD.js.map +1 -0
- package/dist/constants-D6JcsD4_.d.ts +41 -0
- package/dist/context-KxxeMHbR.js +62 -0
- package/dist/context-KxxeMHbR.js.map +1 -0
- package/dist/editors.d.ts +180 -173
- package/dist/editors.js +747 -420
- package/dist/editors.js.map +1 -1
- package/dist/escapeStringRegexp-8MxP2knR.js +6 -0
- package/dist/escapeStringRegexp-8MxP2knR.js.map +1 -0
- package/dist/icons-Cek151jC.js +640 -0
- package/dist/icons-Cek151jC.js.map +1 -0
- package/dist/icons.d.ts +2 -41
- package/dist/icons.js +2 -4
- package/dist/index-m-kQEWiY.d.ts +54 -0
- package/dist/index.d.ts +6192 -9904
- package/dist/index.js +112 -15803
- package/dist/internal/blocks/AIKit.js +2 -0
- package/dist/internal/blocks/AppShell.js +2 -0
- package/dist/internal/blocks/AutoSaveTextarea.js +2 -0
- package/dist/internal/blocks/BrandEditor.js +2 -0
- package/dist/internal/blocks/ChartPanel.js +46 -0
- package/dist/internal/blocks/ChartPanel.js.map +1 -0
- package/dist/internal/blocks/ClipboardButton.js +2 -0
- package/dist/internal/blocks/ColorInput.js +2 -0
- package/dist/internal/blocks/ColorModeSwitch.js +2 -0
- package/dist/internal/blocks/Command.js +2 -0
- package/dist/internal/blocks/CopyField.js +2 -0
- package/dist/internal/blocks/DashboardHero.js +59 -0
- package/dist/internal/blocks/DashboardHero.js.map +1 -0
- package/dist/internal/blocks/DateInput.js +2 -0
- package/dist/internal/blocks/DateRangeInput.js +2 -0
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +16 -0
- package/dist/internal/blocks/EmptyConfigurationActionCard.js.map +1 -0
- package/dist/internal/blocks/EmptyState.js +142 -0
- package/dist/internal/blocks/EmptyState.js.map +1 -0
- package/dist/internal/blocks/ErrorState.js +179 -0
- package/dist/internal/blocks/ErrorState.js.map +1 -0
- package/dist/internal/blocks/ExportMenu.js +41 -0
- package/dist/internal/blocks/ExportMenu.js.map +1 -0
- package/dist/internal/blocks/Form.js +2 -0
- package/dist/internal/blocks/FormGroup.js +2 -0
- package/dist/internal/blocks/GoogleButton.js +95 -0
- package/dist/internal/blocks/GoogleButton.js.map +1 -0
- package/dist/internal/blocks/MicrosoftButton.js +64 -0
- package/dist/internal/blocks/MicrosoftButton.js.map +1 -0
- package/dist/internal/blocks/MultiActionButtonGroup.js +2 -0
- package/dist/internal/blocks/MultiCombobox.js +188 -0
- package/dist/internal/blocks/MultiCombobox.js.map +1 -0
- package/dist/internal/blocks/NumberInput.js +44 -0
- package/dist/internal/blocks/NumberInput.js.map +1 -0
- package/dist/internal/blocks/OtpInput.js +2 -0
- package/dist/internal/blocks/PageHeader.js +2 -0
- package/dist/internal/blocks/PageLayout.js +2 -0
- package/dist/internal/blocks/PageToolbar.js +2 -0
- package/dist/internal/blocks/PasswordInput.js +97 -0
- package/dist/internal/blocks/PasswordInput.js.map +1 -0
- package/dist/internal/blocks/SearchInput.js +2 -0
- package/dist/internal/blocks/SearchInputWithNavigation.js +65 -0
- package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -0
- package/dist/internal/blocks/SectionNav.js +2 -0
- package/dist/internal/blocks/SplitButton.js +46 -0
- package/dist/internal/blocks/SplitButton.js.map +1 -0
- package/dist/internal/blocks/StatCard.js +97 -0
- package/dist/internal/blocks/StatCard.js.map +1 -0
- package/dist/internal/blocks/TextInput.js +2 -0
- package/dist/internal/blocks/Textarea.js +32 -0
- package/dist/internal/blocks/Textarea.js.map +1 -0
- package/dist/internal/blocks/TimeInput.js +77 -0
- package/dist/internal/blocks/TimeInput.js.map +1 -0
- package/dist/internal/components/Alert.js +2 -0
- package/dist/internal/components/AlertModal.js +2 -0
- package/dist/internal/components/Avatar.js +53 -0
- package/dist/internal/components/Avatar.js.map +1 -0
- package/dist/internal/components/Badge.js +2 -0
- package/dist/internal/components/BrandLogo.js +2 -0
- package/dist/internal/components/Breadcrumb.js +2 -0
- package/dist/internal/components/Button.js +2 -0
- package/dist/internal/components/ButtonGroup.js +66 -0
- package/dist/internal/components/ButtonGroup.js.map +1 -0
- package/dist/internal/components/Calendar.js +2 -0
- package/dist/internal/components/Card.js +2 -0
- package/dist/internal/components/Checkbox.js +2 -0
- package/dist/internal/components/Clipboard.js +2 -0
- package/dist/internal/components/Collapsible.js +2 -0
- package/dist/internal/components/CollapsiblePanel.js +87 -0
- package/dist/internal/components/CollapsiblePanel.js.map +1 -0
- package/dist/internal/components/Combobox.js +2 -0
- package/dist/internal/components/DatePicker.js +2 -0
- package/dist/internal/components/DateRangePicker.js +2 -0
- package/dist/internal/components/DiffView.js +2 -0
- package/dist/internal/components/DotsLoader.js +18 -0
- package/dist/internal/components/DotsLoader.js.map +1 -0
- package/dist/internal/components/DropdownMenu.js +2 -0
- package/dist/internal/components/EmptySearchContent.js +12 -0
- package/dist/internal/components/EmptySearchContent.js.map +1 -0
- package/dist/internal/components/FileUpload.js +2 -0
- package/dist/internal/components/FullScreenModal.js +2 -0
- package/dist/internal/components/HelpBlock.js +25 -0
- package/dist/internal/components/HelpBlock.js.map +1 -0
- package/dist/internal/components/HoverCard.js +2 -0
- package/dist/internal/components/InputGroup.js +2 -0
- package/dist/internal/components/Kbd.js +2 -0
- package/dist/internal/components/Label.js +39 -0
- package/dist/internal/components/Label.js.map +1 -0
- package/dist/internal/components/Link.js +22 -0
- package/dist/internal/components/Link.js.map +1 -0
- package/dist/internal/components/MarkedText.js +2 -0
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +20 -0
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js.map +1 -0
- package/dist/internal/components/MergeEditor/PaneHeader.js +13 -0
- package/dist/internal/components/MergeEditor/PaneHeader.js.map +1 -0
- package/dist/internal/components/MergeEditor/constants.js +18 -0
- package/dist/internal/components/MergeEditor/constants.js.map +1 -0
- package/dist/internal/components/MergeEditor/useMergeDiff.js +2 -0
- package/dist/internal/components/Modal.js +2 -0
- package/dist/internal/components/Navbar.js +2 -0
- package/dist/internal/components/Pagination.js +2 -0
- package/dist/internal/components/PanelWithDetails.js +31 -0
- package/dist/internal/components/PanelWithDetails.js.map +1 -0
- package/dist/internal/components/Popconfirm.js +2 -0
- package/dist/internal/components/Popover.js +2 -0
- package/dist/internal/components/Progress.js +47 -0
- package/dist/internal/components/Progress.js.map +1 -0
- package/dist/internal/components/RadioGroup.js +2 -0
- package/dist/internal/components/Resizable.js +2 -0
- package/dist/internal/components/ScrollArea.js +42 -0
- package/dist/internal/components/ScrollArea.js.map +1 -0
- package/dist/internal/components/Search.js +2 -0
- package/dist/internal/components/Select.js +2 -0
- package/dist/internal/components/Separator.js +84 -0
- package/dist/internal/components/Separator.js.map +1 -0
- package/dist/internal/components/Sheet.js +2 -0
- package/dist/internal/components/Sidebar.js +2 -0
- package/dist/internal/components/Skeleton/Skeleton.js +39 -0
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -0
- package/dist/internal/components/Skeleton/SkeletonList.js +41 -0
- package/dist/internal/components/Skeleton/SkeletonList.js.map +1 -0
- package/dist/internal/components/Slider.js +2 -0
- package/dist/internal/components/SpotlightBackdrop.js +132 -0
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -0
- package/dist/internal/components/Stepper.js +2 -0
- package/dist/internal/components/Switch.js +2 -0
- package/dist/internal/components/Table.js +2 -0
- package/dist/internal/components/Tabs.js +2 -0
- package/dist/internal/components/ThemeProvider.js +3 -0
- package/dist/internal/components/TimePicker.js +2 -0
- package/dist/internal/components/Timeline.js +2 -0
- package/dist/internal/components/Toast.js +3 -0
- package/dist/internal/components/Toggle.js +169 -0
- package/dist/internal/components/Toggle.js.map +1 -0
- package/dist/internal/components/ToggleGroup.js +2 -0
- package/dist/internal/components/Tooltip.js +2 -0
- package/dist/internal/components/Truncated.js +45 -0
- package/dist/internal/components/Truncated.js.map +1 -0
- package/dist/internal/components/Workbench.js +2 -0
- package/dist/internal/components/ZoomableSvg.js +2 -0
- package/dist/internal/hooks/useAutosizeInput.js +77 -0
- package/dist/internal/hooks/useAutosizeInput.js.map +1 -0
- package/dist/internal/hooks/useScrollbarPosition.js +45 -0
- package/dist/internal/hooks/useScrollbarPosition.js.map +1 -0
- package/dist/internal/hooks/useStableCallback.js +29 -0
- package/dist/internal/hooks/useStableCallback.js.map +1 -0
- package/dist/internal/utils/mergeRefs.js +20 -0
- package/dist/internal/utils/mergeRefs.js.map +1 -0
- package/dist/internal/utils.js +5 -0
- package/dist/markdown-editor.d.ts +72 -72
- package/dist/markdown-editor.js +1122 -1193
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +12 -12
- package/dist/mermaid.js +2 -10
- package/dist/rjsf.d.ts +33 -34
- package/dist/rjsf.js +1543 -1600
- package/dist/rjsf.js.map +1 -1
- package/dist/rolldown-runtime-Bdc48AWt.js +33 -0
- package/dist/styles-DSUP_-9Z.js +158 -0
- package/dist/styles-DSUP_-9Z.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/testing.d.ts +8 -7
- package/dist/testing.js +36 -16
- package/dist/testing.js.map +1 -1
- package/dist/themeTokens-BNg98Mu9.js +85 -0
- package/dist/themeTokens-BNg98Mu9.js.map +1 -0
- package/dist/toast-CjkURw0M.js +184 -0
- package/dist/toast-CjkURw0M.js.map +1 -0
- package/dist/useColorSchemeState-CYqcUfSH.js +61 -0
- package/dist/useColorSchemeState-CYqcUfSH.js.map +1 -0
- package/dist/useControllableState-M6494mCT.js +31 -0
- package/dist/useControllableState-M6494mCT.js.map +1 -0
- package/dist/useElement-DkF6esWL.js +15 -0
- package/dist/useElement-DkF6esWL.js.map +1 -0
- package/dist/useMergeDiff-CvowEXJ1.js +465 -0
- package/dist/useMergeDiff-CvowEXJ1.js.map +1 -0
- package/dist/utils-D0c5VAyF.js +308 -0
- package/dist/utils-D0c5VAyF.js.map +1 -0
- package/package.json +10 -9
- package/src/styles.css +35 -7
- package/src/theme.css +64 -0
- package/dist/MermaidDiagram-EOKJHQQV.js +0 -10
- package/dist/MermaidDiagram-EOKJHQQV.js.map +0 -1
- package/dist/chunk-63NSN2VL.js +0 -274
- package/dist/chunk-63NSN2VL.js.map +0 -1
- package/dist/chunk-6FPEI4EM.js +0 -6683
- package/dist/chunk-6FPEI4EM.js.map +0 -1
- package/dist/chunk-7PUUHEJQ.js +0 -1313
- package/dist/chunk-7PUUHEJQ.js.map +0 -1
- package/dist/chunk-BOHNXTMM.js +0 -606
- package/dist/chunk-BOHNXTMM.js.map +0 -1
- package/dist/chunk-C3L3TBBT.js +0 -242
- package/dist/chunk-C3L3TBBT.js.map +0 -1
- package/dist/chunk-CTCFYWJC.js +0 -407
- package/dist/chunk-CTCFYWJC.js.map +0 -1
- package/dist/chunk-ESBL3IPF.js +0 -23
- package/dist/chunk-ESBL3IPF.js.map +0 -1
- package/dist/chunk-IJTHFNNJ.js +0 -261
- package/dist/chunk-IJTHFNNJ.js.map +0 -1
- package/dist/chunk-JP7PNHLH.js +0 -40
- package/dist/chunk-JP7PNHLH.js.map +0 -1
- package/dist/chunk-KPNAW5MU.js +0 -229
- package/dist/chunk-KPNAW5MU.js.map +0 -1
- package/dist/chunk-L37JJ6MR.js +0 -152
- package/dist/chunk-L37JJ6MR.js.map +0 -1
- package/dist/chunk-Q7NWXLCT.js +0 -90
- package/dist/chunk-Q7NWXLCT.js.map +0 -1
- package/dist/chunk-SYIEF644.js +0 -1016
- package/dist/chunk-SYIEF644.js.map +0 -1
- package/dist/chunk-VMFSRV5H.js +0 -16
- package/dist/chunk-VMFSRV5H.js.map +0 -1
- package/dist/chunk-VPPM7UUQ.js +0 -47
- package/dist/chunk-VPPM7UUQ.js.map +0 -1
- package/dist/chunk-XV3UUOYF.js +0 -845
- package/dist/chunk-XV3UUOYF.js.map +0 -1
- package/dist/constants-D3gaMY-W.d.ts +0 -39
- package/dist/icons.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/mermaid.js.map +0 -1
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import { CHANGE_CLASS, CHUNK_TYPE } from "./internal/components/MergeEditor/constants.js";
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { diffLines } from "diff";
|
|
4
|
+
import { diff3Merge } from "node-diff3";
|
|
5
|
+
//#region src/components/MergeEditor/helpers.ts
|
|
6
|
+
/**
|
|
7
|
+
* Computes diff chunks between oldText and newText using line-level diffing.
|
|
8
|
+
* Adjacent removed+added pairs are kept as separate chunks so the consumer
|
|
9
|
+
* can pair them into "modifications" for accept controls.
|
|
10
|
+
*/
|
|
11
|
+
const computeDiffChunks = (oldText, newText) => {
|
|
12
|
+
const changes = diffLines(oldText, newText);
|
|
13
|
+
const chunks = [];
|
|
14
|
+
let oldLine = 1;
|
|
15
|
+
let newLine = 1;
|
|
16
|
+
for (const change of changes) {
|
|
17
|
+
if (change.value === "") continue;
|
|
18
|
+
const lineCount = change.count || change.value.replace(/\n$/, "").split("\n").length;
|
|
19
|
+
if (change.removed) {
|
|
20
|
+
chunks.push({
|
|
21
|
+
type: CHUNK_TYPE.REMOVED,
|
|
22
|
+
value: change.value,
|
|
23
|
+
oldStart: oldLine,
|
|
24
|
+
oldEnd: oldLine + lineCount - 1,
|
|
25
|
+
newStart: newLine,
|
|
26
|
+
newEnd: newLine
|
|
27
|
+
});
|
|
28
|
+
oldLine += lineCount;
|
|
29
|
+
} else if (change.added) {
|
|
30
|
+
chunks.push({
|
|
31
|
+
type: CHUNK_TYPE.ADDED,
|
|
32
|
+
value: change.value,
|
|
33
|
+
oldStart: oldLine,
|
|
34
|
+
oldEnd: oldLine,
|
|
35
|
+
newStart: newLine,
|
|
36
|
+
newEnd: newLine + lineCount - 1
|
|
37
|
+
});
|
|
38
|
+
newLine += lineCount;
|
|
39
|
+
} else {
|
|
40
|
+
chunks.push({
|
|
41
|
+
type: CHUNK_TYPE.UNCHANGED,
|
|
42
|
+
value: change.value,
|
|
43
|
+
oldStart: oldLine,
|
|
44
|
+
oldEnd: oldLine + lineCount - 1,
|
|
45
|
+
newStart: newLine,
|
|
46
|
+
newEnd: newLine + lineCount - 1
|
|
47
|
+
});
|
|
48
|
+
oldLine += lineCount;
|
|
49
|
+
newLine += lineCount;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return chunks;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Collects 1-indexed line numbers that are marked as changed (added or removed)
|
|
56
|
+
* from a set of diff chunks. `side` determines which line range to use.
|
|
57
|
+
*/
|
|
58
|
+
const getChangedLineNumbers = (chunks, side) => {
|
|
59
|
+
const lines = /* @__PURE__ */ new Set();
|
|
60
|
+
for (const chunk of chunks) {
|
|
61
|
+
if (chunk.type === CHUNK_TYPE.UNCHANGED) continue;
|
|
62
|
+
if (side === "old" && chunk.type === CHUNK_TYPE.REMOVED) for (let i = chunk.oldStart; i <= chunk.oldEnd; i++) lines.add(i);
|
|
63
|
+
if (side === "new" && chunk.type === CHUNK_TYPE.ADDED) for (let i = chunk.newStart; i <= chunk.newEnd; i++) lines.add(i);
|
|
64
|
+
}
|
|
65
|
+
return lines;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Filters changed line numbers, keeping only those that are classified
|
|
69
|
+
* and not suppressed (resolved/dismissed).
|
|
70
|
+
*
|
|
71
|
+
* `classification` and `suppressedLines` must be keyed by line numbers
|
|
72
|
+
* from the same `side` (old-side lines for 'old', new-side lines for 'new').
|
|
73
|
+
*/
|
|
74
|
+
const filterHighlightedLines = (chunks, side, classification, suppressedLines) => {
|
|
75
|
+
const filtered = /* @__PURE__ */ new Set();
|
|
76
|
+
for (const line of getChangedLineNumbers(chunks, side)) if (classification.has(line) && !suppressedLines.has(line)) filtered.add(line);
|
|
77
|
+
return filtered;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Replaces lines in `text` between `startLine` and `endLine` (1-indexed, inclusive)
|
|
81
|
+
* with `replacementLines`. If startLine > endLine, inserts before startLine.
|
|
82
|
+
*/
|
|
83
|
+
const replaceLines = (text, startLine, endLine, replacement) => {
|
|
84
|
+
const lines = text.split("\n");
|
|
85
|
+
const before = lines.slice(0, startLine - 1);
|
|
86
|
+
const after = startLine > endLine ? lines.slice(startLine - 1) : lines.slice(endLine);
|
|
87
|
+
const replacementArr = replacement === "" ? [] : replacement.replace(/\n$/, "").split("\n");
|
|
88
|
+
return [
|
|
89
|
+
...before,
|
|
90
|
+
...replacementArr,
|
|
91
|
+
...after
|
|
92
|
+
].join("\n");
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region src/components/MergeEditor/useMergeDiff.ts
|
|
96
|
+
const DEBOUNCE_MS = 150;
|
|
97
|
+
const rangesOverlap = (s1, e1, s2, e2) => s1 <= e2 && e1 >= s2;
|
|
98
|
+
const computeSuppressedLines = (dismissedLines, pairs, resolvedIds, getRange) => {
|
|
99
|
+
const lines = new Set(dismissedLines);
|
|
100
|
+
for (const pair of pairs) if (resolvedIds.has(pair.id)) {
|
|
101
|
+
const [start, end] = getRange(pair);
|
|
102
|
+
for (let i = start; i <= end; i++) lines.add(i);
|
|
103
|
+
}
|
|
104
|
+
return lines;
|
|
105
|
+
};
|
|
106
|
+
const filterVisibleConflicts = (conflicts, classification, dismissedLines, getRange, findPair, fullyResolvedPairIds) => conflicts.filter((c) => {
|
|
107
|
+
const [start, end] = getRange(c);
|
|
108
|
+
let hasClassifiedLine = false;
|
|
109
|
+
let allDismissed = true;
|
|
110
|
+
for (let i = start; i <= end; i++) {
|
|
111
|
+
if (classification.has(i)) hasClassifiedLine = true;
|
|
112
|
+
if (!dismissedLines.has(i)) allDismissed = false;
|
|
113
|
+
}
|
|
114
|
+
if (!hasClassifiedLine || allDismissed) return false;
|
|
115
|
+
const pair = findPair(c);
|
|
116
|
+
return !pair || !fullyResolvedPairIds.has(pair.id);
|
|
117
|
+
});
|
|
118
|
+
const useMergeDiff = (baseText, leftText, rightText) => {
|
|
119
|
+
const [mergeValue, setMergeValue] = useState(baseText);
|
|
120
|
+
const debounceRef = useRef(null);
|
|
121
|
+
const [debouncedMergeValue, setDebouncedMergeValue] = useState(mergeValue);
|
|
122
|
+
const [acceptedPairSides, setAcceptedPairSides] = useState(() => /* @__PURE__ */ new Map());
|
|
123
|
+
const [dismissedLeftLines, setDismissedLeftLines] = useState(() => /* @__PURE__ */ new Set());
|
|
124
|
+
const [dismissedRightLines, setDismissedRightLines] = useState(() => /* @__PURE__ */ new Set());
|
|
125
|
+
const reset = useCallback(() => {
|
|
126
|
+
if (debounceRef.current) {
|
|
127
|
+
clearTimeout(debounceRef.current);
|
|
128
|
+
debounceRef.current = null;
|
|
129
|
+
}
|
|
130
|
+
setMergeValue(baseText);
|
|
131
|
+
setDebouncedMergeValue(baseText);
|
|
132
|
+
setAcceptedPairSides(/* @__PURE__ */ new Map());
|
|
133
|
+
setDismissedLeftLines(/* @__PURE__ */ new Set());
|
|
134
|
+
setDismissedRightLines(/* @__PURE__ */ new Set());
|
|
135
|
+
}, [baseText]);
|
|
136
|
+
useLayoutEffect(() => {
|
|
137
|
+
reset();
|
|
138
|
+
}, [
|
|
139
|
+
baseText,
|
|
140
|
+
leftText,
|
|
141
|
+
rightText
|
|
142
|
+
]);
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
return () => {
|
|
145
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
146
|
+
};
|
|
147
|
+
}, []);
|
|
148
|
+
const handleMergeChange = useCallback((value) => {
|
|
149
|
+
setMergeValue(value);
|
|
150
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
151
|
+
debounceRef.current = setTimeout(() => {
|
|
152
|
+
setDebouncedMergeValue(value);
|
|
153
|
+
}, DEBOUNCE_MS);
|
|
154
|
+
}, []);
|
|
155
|
+
const leftDiffChunks = useMemo(() => computeDiffChunks(leftText, debouncedMergeValue), [leftText, debouncedMergeValue]);
|
|
156
|
+
const rightDiffChunks = useMemo(() => computeDiffChunks(debouncedMergeValue, rightText), [debouncedMergeValue, rightText]);
|
|
157
|
+
const leftConflicts = useMemo(() => pairChunksIntoConflicts(leftDiffChunks), [leftDiffChunks]);
|
|
158
|
+
const rightConflicts = useMemo(() => pairChunksIntoConflicts(rightDiffChunks), [rightDiffChunks]);
|
|
159
|
+
const leftVsBase = useMemo(() => computeDiffChunks(baseText, leftText), [baseText, leftText]);
|
|
160
|
+
const rightVsBase = useMemo(() => computeDiffChunks(baseText, rightText), [baseText, rightText]);
|
|
161
|
+
const { leftClassification, rightClassification, conflictPairs } = useMemo(() => {
|
|
162
|
+
const baseLines = baseText.split("\n");
|
|
163
|
+
const leftLines = leftText.split("\n");
|
|
164
|
+
const rightLines = rightText.split("\n");
|
|
165
|
+
const result = diff3Merge(leftLines, baseLines, rightLines);
|
|
166
|
+
const leftConflictLineSet = /* @__PURE__ */ new Set();
|
|
167
|
+
const rightConflictLineSet = /* @__PURE__ */ new Set();
|
|
168
|
+
const pairs = [];
|
|
169
|
+
for (const block of result) if ("conflict" in block && block.conflict) {
|
|
170
|
+
const { a, aIndex, b, bIndex } = block.conflict;
|
|
171
|
+
for (let i = 0; i < a.length; i++) leftConflictLineSet.add(aIndex + i + 1);
|
|
172
|
+
for (let i = 0; i < b.length; i++) rightConflictLineSet.add(bIndex + i + 1);
|
|
173
|
+
pairs.push({
|
|
174
|
+
id: `pair-${aIndex}-${bIndex}`,
|
|
175
|
+
leftStart: aIndex + 1,
|
|
176
|
+
leftEnd: aIndex + a.length,
|
|
177
|
+
rightStart: bIndex + 1,
|
|
178
|
+
rightEnd: bIndex + b.length
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
const leftChanged = getChangedLineNumbers(leftVsBase, "new");
|
|
182
|
+
const rightChanged = getChangedLineNumbers(rightVsBase, "new");
|
|
183
|
+
const leftMap = /* @__PURE__ */ new Map();
|
|
184
|
+
for (const line of leftChanged) leftMap.set(line, leftConflictLineSet.has(line) ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE);
|
|
185
|
+
const rightMap = /* @__PURE__ */ new Map();
|
|
186
|
+
for (const line of rightChanged) rightMap.set(line, rightConflictLineSet.has(line) ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE);
|
|
187
|
+
return {
|
|
188
|
+
leftClassification: leftMap,
|
|
189
|
+
rightClassification: rightMap,
|
|
190
|
+
conflictPairs: pairs
|
|
191
|
+
};
|
|
192
|
+
}, [
|
|
193
|
+
baseText,
|
|
194
|
+
leftText,
|
|
195
|
+
rightText,
|
|
196
|
+
leftVsBase,
|
|
197
|
+
rightVsBase
|
|
198
|
+
]);
|
|
199
|
+
const findPairForLeft = useCallback((conflict) => conflictPairs.find((p) => rangesOverlap(conflict.oldStartLine, conflict.oldEndLine, p.leftStart, p.leftEnd)), [conflictPairs]);
|
|
200
|
+
const findPairForRight = useCallback((conflict) => conflictPairs.find((p) => rangesOverlap(conflict.newStartLine, conflict.newEndLine, p.rightStart, p.rightEnd)), [conflictPairs]);
|
|
201
|
+
const markSideAccepted = useCallback((pair, side) => {
|
|
202
|
+
if (!pair) return;
|
|
203
|
+
setAcceptedPairSides((prev) => {
|
|
204
|
+
const next = new Map(prev);
|
|
205
|
+
const sides = new Set(prev.get(pair.id) ?? []);
|
|
206
|
+
sides.add(side);
|
|
207
|
+
next.set(pair.id, sides);
|
|
208
|
+
return next;
|
|
209
|
+
});
|
|
210
|
+
}, []);
|
|
211
|
+
const isOtherSideAccepted = useCallback((pair, side) => {
|
|
212
|
+
if (!pair) return false;
|
|
213
|
+
const otherSide = side === "left" ? "right" : "left";
|
|
214
|
+
return acceptedPairSides.get(pair.id)?.has(otherSide) ?? false;
|
|
215
|
+
}, [acceptedPairSides]);
|
|
216
|
+
const acceptSide = useCallback((conflict, side) => {
|
|
217
|
+
const pair = (side === "left" ? findPairForLeft : findPairForRight)(conflict);
|
|
218
|
+
const otherAccepted = isOtherSideAccepted(pair, side);
|
|
219
|
+
const sourceValue = side === "left" ? conflict.oldValue : conflict.newValue;
|
|
220
|
+
const targetStart = side === "left" ? conflict.newStartLine : conflict.oldStartLine;
|
|
221
|
+
const targetEnd = side === "left" ? conflict.newEndLine : conflict.oldEndLine;
|
|
222
|
+
if (debounceRef.current) {
|
|
223
|
+
clearTimeout(debounceRef.current);
|
|
224
|
+
debounceRef.current = null;
|
|
225
|
+
}
|
|
226
|
+
const mergeTargetEmpty = side === "left" ? conflict.newValue === "" : conflict.oldValue === "";
|
|
227
|
+
const newValue = otherAccepted ? replaceLines(mergeValue, targetEnd + 1, targetEnd, sourceValue) : mergeTargetEmpty ? replaceLines(mergeValue, targetStart, targetStart - 1, sourceValue) : replaceLines(mergeValue, targetStart, targetEnd, sourceValue);
|
|
228
|
+
setMergeValue(newValue);
|
|
229
|
+
setDebouncedMergeValue(newValue);
|
|
230
|
+
markSideAccepted(pair, side);
|
|
231
|
+
if (!pair) {
|
|
232
|
+
const setDismissedSide = side === "left" ? setDismissedLeftLines : setDismissedRightLines;
|
|
233
|
+
const [sideStart, sideEnd] = side === "left" ? [conflict.oldStartLine, conflict.oldEndLine] : [conflict.newStartLine, conflict.newEndLine];
|
|
234
|
+
setDismissedSide((prev) => {
|
|
235
|
+
const next = new Set(prev);
|
|
236
|
+
for (let i = sideStart; i <= sideEnd; i++) next.add(i);
|
|
237
|
+
return next;
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}, [
|
|
241
|
+
mergeValue,
|
|
242
|
+
findPairForLeft,
|
|
243
|
+
findPairForRight,
|
|
244
|
+
isOtherSideAccepted,
|
|
245
|
+
markSideAccepted
|
|
246
|
+
]);
|
|
247
|
+
const acceptLeft = useCallback((conflict) => acceptSide(conflict, "left"), [acceptSide]);
|
|
248
|
+
const acceptRight = useCallback((conflict) => acceptSide(conflict, "right"), [acceptSide]);
|
|
249
|
+
const dismissSide = useCallback((conflict, side) => {
|
|
250
|
+
const setDismissed = side === "left" ? setDismissedLeftLines : setDismissedRightLines;
|
|
251
|
+
const [sideStart, sideEnd] = side === "left" ? [conflict.oldStartLine, conflict.oldEndLine] : [conflict.newStartLine, conflict.newEndLine];
|
|
252
|
+
setDismissed((prev) => {
|
|
253
|
+
const next = new Set(prev);
|
|
254
|
+
for (let i = sideStart; i <= sideEnd; i++) next.add(i);
|
|
255
|
+
return next;
|
|
256
|
+
});
|
|
257
|
+
}, []);
|
|
258
|
+
const dismissLeft = useCallback((conflict) => dismissSide(conflict, "left"), [dismissSide]);
|
|
259
|
+
const dismissRight = useCallback((conflict) => dismissSide(conflict, "right"), [dismissSide]);
|
|
260
|
+
const fullyResolvedPairIds = useMemo(() => {
|
|
261
|
+
const ids = /* @__PURE__ */ new Set();
|
|
262
|
+
for (const pair of conflictPairs) {
|
|
263
|
+
const leftAccepted = acceptedPairSides.get(pair.id)?.has("left") ?? false;
|
|
264
|
+
const rightAccepted = acceptedPairSides.get(pair.id)?.has("right") ?? false;
|
|
265
|
+
let leftDismissed = true;
|
|
266
|
+
for (let i = pair.leftStart; i <= pair.leftEnd; i++) if (!dismissedLeftLines.has(i)) {
|
|
267
|
+
leftDismissed = false;
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
let rightDismissed = true;
|
|
271
|
+
for (let i = pair.rightStart; i <= pair.rightEnd; i++) if (!dismissedRightLines.has(i)) {
|
|
272
|
+
rightDismissed = false;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
if ((leftAccepted || leftDismissed) && (rightAccepted || rightDismissed)) ids.add(pair.id);
|
|
276
|
+
}
|
|
277
|
+
return ids;
|
|
278
|
+
}, [
|
|
279
|
+
conflictPairs,
|
|
280
|
+
acceptedPairSides,
|
|
281
|
+
dismissedLeftLines,
|
|
282
|
+
dismissedRightLines
|
|
283
|
+
]);
|
|
284
|
+
const visibleLeftConflicts = useMemo(() => filterVisibleConflicts(leftConflicts, leftClassification, dismissedLeftLines, (c) => [c.oldStartLine, c.oldEndLine], findPairForLeft, fullyResolvedPairIds), [
|
|
285
|
+
leftConflicts,
|
|
286
|
+
leftClassification,
|
|
287
|
+
dismissedLeftLines,
|
|
288
|
+
findPairForLeft,
|
|
289
|
+
fullyResolvedPairIds
|
|
290
|
+
]);
|
|
291
|
+
const visibleRightConflicts = useMemo(() => filterVisibleConflicts(rightConflicts, rightClassification, dismissedRightLines, (c) => [c.newStartLine, c.newEndLine], findPairForRight, fullyResolvedPairIds), [
|
|
292
|
+
rightConflicts,
|
|
293
|
+
rightClassification,
|
|
294
|
+
dismissedRightLines,
|
|
295
|
+
findPairForRight,
|
|
296
|
+
fullyResolvedPairIds
|
|
297
|
+
]);
|
|
298
|
+
const suppressedLeftLines = useMemo(() => computeSuppressedLines(dismissedLeftLines, conflictPairs, fullyResolvedPairIds, (p) => [p.leftStart, p.leftEnd]), [
|
|
299
|
+
conflictPairs,
|
|
300
|
+
fullyResolvedPairIds,
|
|
301
|
+
dismissedLeftLines
|
|
302
|
+
]);
|
|
303
|
+
const suppressedRightLines = useMemo(() => computeSuppressedLines(dismissedRightLines, conflictPairs, fullyResolvedPairIds, (p) => [p.rightStart, p.rightEnd]), [
|
|
304
|
+
conflictPairs,
|
|
305
|
+
fullyResolvedPairIds,
|
|
306
|
+
dismissedRightLines
|
|
307
|
+
]);
|
|
308
|
+
const { mergeHighlightedLines, mergeClassification } = useMemo(() => {
|
|
309
|
+
const mergeLeftLines = getChangedLineNumbers(leftDiffChunks, "new");
|
|
310
|
+
const mergeRightLines = getChangedLineNumbers(rightDiffChunks, "old");
|
|
311
|
+
const mergeLineToPair = /* @__PURE__ */ new Map();
|
|
312
|
+
for (const conflict of leftConflicts) {
|
|
313
|
+
const pair = findPairForLeft(conflict);
|
|
314
|
+
if (pair) for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) mergeLineToPair.set(i, pair.id);
|
|
315
|
+
}
|
|
316
|
+
for (const conflict of rightConflicts) {
|
|
317
|
+
const pair = findPairForRight(conflict);
|
|
318
|
+
if (pair) for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) mergeLineToPair.set(i, pair.id);
|
|
319
|
+
}
|
|
320
|
+
const suppressedMergeLines = /* @__PURE__ */ new Set();
|
|
321
|
+
for (const conflict of leftConflicts) {
|
|
322
|
+
if (findPairForLeft(conflict)) continue;
|
|
323
|
+
if (conflict.oldStartLine > conflict.oldEndLine) continue;
|
|
324
|
+
let allDismissed = true;
|
|
325
|
+
for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) if (!dismissedLeftLines.has(i)) {
|
|
326
|
+
allDismissed = false;
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
if (allDismissed) for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) suppressedMergeLines.add(i);
|
|
330
|
+
}
|
|
331
|
+
for (const conflict of rightConflicts) {
|
|
332
|
+
if (findPairForRight(conflict)) continue;
|
|
333
|
+
if (conflict.newStartLine > conflict.newEndLine) continue;
|
|
334
|
+
let allDismissed = true;
|
|
335
|
+
for (let i = conflict.newStartLine; i <= conflict.newEndLine; i++) if (!dismissedRightLines.has(i)) {
|
|
336
|
+
allDismissed = false;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
if (allDismissed) for (let i = conflict.oldStartLine; i <= conflict.oldEndLine; i++) suppressedMergeLines.add(i);
|
|
340
|
+
}
|
|
341
|
+
const allMergeLines = /* @__PURE__ */ new Set();
|
|
342
|
+
for (const line of mergeLeftLines) allMergeLines.add(line);
|
|
343
|
+
for (const line of mergeRightLines) allMergeLines.add(line);
|
|
344
|
+
const highlighted = /* @__PURE__ */ new Set();
|
|
345
|
+
const classification = /* @__PURE__ */ new Map();
|
|
346
|
+
for (const line of allMergeLines) {
|
|
347
|
+
if (suppressedMergeLines.has(line)) continue;
|
|
348
|
+
const pairId = mergeLineToPair.get(line);
|
|
349
|
+
if (pairId && fullyResolvedPairIds.has(pairId)) continue;
|
|
350
|
+
highlighted.add(line);
|
|
351
|
+
classification.set(line, pairId ? CHANGE_CLASS.CONFLICT : CHANGE_CLASS.SAFE);
|
|
352
|
+
}
|
|
353
|
+
return {
|
|
354
|
+
mergeHighlightedLines: highlighted,
|
|
355
|
+
mergeClassification: classification
|
|
356
|
+
};
|
|
357
|
+
}, [
|
|
358
|
+
leftDiffChunks,
|
|
359
|
+
rightDiffChunks,
|
|
360
|
+
leftConflicts,
|
|
361
|
+
rightConflicts,
|
|
362
|
+
findPairForLeft,
|
|
363
|
+
findPairForRight,
|
|
364
|
+
fullyResolvedPairIds,
|
|
365
|
+
dismissedLeftLines,
|
|
366
|
+
dismissedRightLines
|
|
367
|
+
]);
|
|
368
|
+
const leftHighlightedLines = useMemo(() => filterHighlightedLines(leftDiffChunks, "old", leftClassification, suppressedLeftLines), [
|
|
369
|
+
leftDiffChunks,
|
|
370
|
+
leftClassification,
|
|
371
|
+
suppressedLeftLines
|
|
372
|
+
]);
|
|
373
|
+
const rightHighlightedLines = useMemo(() => filterHighlightedLines(rightDiffChunks, "new", rightClassification, suppressedRightLines), [
|
|
374
|
+
rightDiffChunks,
|
|
375
|
+
rightClassification,
|
|
376
|
+
suppressedRightLines
|
|
377
|
+
]);
|
|
378
|
+
const remainingSafeChanges = useMemo(() => {
|
|
379
|
+
return visibleLeftConflicts.filter((c) => !findPairForLeft(c)).length + visibleRightConflicts.filter((c) => !findPairForRight(c)).length;
|
|
380
|
+
}, [
|
|
381
|
+
visibleLeftConflicts,
|
|
382
|
+
visibleRightConflicts,
|
|
383
|
+
findPairForLeft,
|
|
384
|
+
findPairForRight
|
|
385
|
+
]);
|
|
386
|
+
return {
|
|
387
|
+
mergeValue,
|
|
388
|
+
handleMergeChange,
|
|
389
|
+
leftConflicts: visibleLeftConflicts,
|
|
390
|
+
rightConflicts: visibleRightConflicts,
|
|
391
|
+
leftHighlightedLines,
|
|
392
|
+
rightHighlightedLines,
|
|
393
|
+
leftClassification,
|
|
394
|
+
rightClassification,
|
|
395
|
+
mergeHighlightedLines,
|
|
396
|
+
mergeClassification,
|
|
397
|
+
acceptLeft,
|
|
398
|
+
acceptRight,
|
|
399
|
+
dismissLeft,
|
|
400
|
+
dismissRight,
|
|
401
|
+
totalConflicts: conflictPairs.length,
|
|
402
|
+
resolvedConflicts: fullyResolvedPairIds.size,
|
|
403
|
+
remainingSafeChanges,
|
|
404
|
+
isDirty: mergeValue !== baseText || dismissedLeftLines.size > 0 || dismissedRightLines.size > 0,
|
|
405
|
+
reset
|
|
406
|
+
};
|
|
407
|
+
};
|
|
408
|
+
/**
|
|
409
|
+
* Pairs adjacent removed+added chunks into MergeConflicts.
|
|
410
|
+
* A standalone REMOVED or ADDED chunk becomes a conflict with
|
|
411
|
+
* the other side empty.
|
|
412
|
+
*/
|
|
413
|
+
const pairChunksIntoConflicts = (chunks) => {
|
|
414
|
+
const conflicts = [];
|
|
415
|
+
let i = 0;
|
|
416
|
+
while (i < chunks.length) {
|
|
417
|
+
const chunk = chunks[i];
|
|
418
|
+
if (chunk.type === CHUNK_TYPE.UNCHANGED) {
|
|
419
|
+
i++;
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
if (chunk.type === CHUNK_TYPE.REMOVED) {
|
|
423
|
+
const next = chunks[i + 1];
|
|
424
|
+
if (next?.type === CHUNK_TYPE.ADDED) {
|
|
425
|
+
conflicts.push({
|
|
426
|
+
id: `${chunk.oldStart}-${next.newStart}`,
|
|
427
|
+
oldValue: chunk.value,
|
|
428
|
+
oldStartLine: chunk.oldStart,
|
|
429
|
+
oldEndLine: chunk.oldEnd,
|
|
430
|
+
newValue: next.value,
|
|
431
|
+
newStartLine: next.newStart,
|
|
432
|
+
newEndLine: next.newEnd
|
|
433
|
+
});
|
|
434
|
+
i += 2;
|
|
435
|
+
} else {
|
|
436
|
+
conflicts.push({
|
|
437
|
+
id: `${chunk.oldStart}-del`,
|
|
438
|
+
oldValue: chunk.value,
|
|
439
|
+
oldStartLine: chunk.oldStart,
|
|
440
|
+
oldEndLine: chunk.oldEnd,
|
|
441
|
+
newValue: "",
|
|
442
|
+
newStartLine: chunk.newStart,
|
|
443
|
+
newEndLine: chunk.newStart
|
|
444
|
+
});
|
|
445
|
+
i++;
|
|
446
|
+
}
|
|
447
|
+
} else {
|
|
448
|
+
conflicts.push({
|
|
449
|
+
id: `add-${chunk.newStart}`,
|
|
450
|
+
oldValue: "",
|
|
451
|
+
oldStartLine: chunk.oldStart,
|
|
452
|
+
oldEndLine: chunk.oldStart,
|
|
453
|
+
newValue: chunk.value,
|
|
454
|
+
newStartLine: chunk.newStart,
|
|
455
|
+
newEndLine: chunk.newEnd
|
|
456
|
+
});
|
|
457
|
+
i++;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return conflicts;
|
|
461
|
+
};
|
|
462
|
+
//#endregion
|
|
463
|
+
export { useMergeDiff };
|
|
464
|
+
|
|
465
|
+
//# sourceMappingURL=useMergeDiff-CvowEXJ1.js.map
|
|
@@ -0,0 +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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"}
|