@ht-rnd/merge-conflict-viewer 1.0.1 → 1.1.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/README.md +49 -4
- package/dist/lib/main.cjs +2 -2
- package/dist/lib/main.es.js +562 -467
- package/dist/types/index.d.ts +58 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ It ships in two parts:
|
|
|
17
17
|
|
|
18
18
|
- Compares **by structure, not by line**: keys and array items are matched, so a key that only exists on one side gets blank space opposite it instead of being lined up with an unrelated key.
|
|
19
19
|
- **"All changes resolved"** is a first-class state: a banner, a `status` object and a `Next unresolved` button.
|
|
20
|
-
- **Editable result** (opt in), **undo and redo**, **folded unchanged lines**, previous/next change navigation, stacked layout on narrow screens, light and dark.
|
|
20
|
+
- **Editable result** (opt in), **undo and redo**, **folded unchanged lines**, **wrap or scroll long lines** (the three panes scroll sideways together), previous/next change navigation, stacked layout on narrow screens, light and dark.
|
|
21
21
|
- Works with **Tailwind v3.4 and v4** and with React 18 and 19.
|
|
22
22
|
|
|
23
23
|
## Is this the right tool?
|
|
@@ -121,7 +121,7 @@ A change starts **unresolved**: the Result pane shows the incoming value on an a
|
|
|
121
121
|
| Export | What it renders |
|
|
122
122
|
|---|---|
|
|
123
123
|
| `MergeConflictViewer` | The root. Takes either `viewer` (from `useMergeViewer`) or the hook options. With no children it renders the toolbar, the banner and the panes. Accepts the props of a `div`. |
|
|
124
|
-
| `MergeConflictToolbar` | Apply all, previous/next change, undo/redo, fold
|
|
124
|
+
| `MergeConflictToolbar` | Apply all, previous/next change, undo/redo, fold and wrap toggles, summary. Accepts `children` to add your own buttons. |
|
|
125
125
|
| `MergeConflictStatus` | The banner with the progress bar and `Next unresolved`. |
|
|
126
126
|
| `MergeConflictPanes` | The three scrolling panes (or the stacked layout). |
|
|
127
127
|
| `MergeConflictValueEditor` | The popover editor used by the pencil button. |
|
|
@@ -154,6 +154,7 @@ These are the options of `useMergeViewer`, also accepted as props by `MergeConfl
|
|
|
154
154
|
| `layout` | `"horizontal" \| "vertical" \| "responsive"` | `"responsive"` | Side by side, stacked, or stacked below `stackBelow` |
|
|
155
155
|
| `stackBelow` | `number` | `900` | Container width (px) below which `"responsive"` stacks |
|
|
156
156
|
| `collapseUnchanged` | `boolean \| number` | `false` | Fold unchanged runs; a number sets the context lines (default 3) |
|
|
157
|
+
| `wrapLines` | `boolean` | `true` | Wrap long lines. `false` keeps one row per line and scrolls the panes sideways together, see [Long lines](#long-lines) |
|
|
157
158
|
| `labels` | `MergeViewerLabels` | English | Every text in the UI, see [Labels](#labels) |
|
|
158
159
|
|
|
159
160
|
`layout="vertical"` stacks the panes as Current, Incoming, Result.
|
|
@@ -316,6 +317,18 @@ Every line is rendered (there is no virtualization), so for big documents fold t
|
|
|
316
317
|
|
|
317
318
|
Long unchanged runs collapse into a `⋯ 120 unchanged lines` row that expands on click. Users can toggle it from the toolbar.
|
|
318
319
|
|
|
320
|
+
### Long lines
|
|
321
|
+
|
|
322
|
+
Long lines wrap by default. The toolbar has a `Wrap lines` button, and `wrapLines` sets where it starts:
|
|
323
|
+
|
|
324
|
+
```tsx
|
|
325
|
+
<MergeConflictViewer wrapLines={false} ... /> // one row per line, scroll sideways
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
With wrapping off, every line stays on one row and a scrollbar appears under the panes. **All three panes scroll together**, so the same part of every line stays lined up, and the Shift + wheel and horizontal trackpad gestures work over the lines too. The scrollbar is only shown when some line is wider than its pane. The accept, remove and edit buttons stay in place while the text slides.
|
|
329
|
+
|
|
330
|
+
`wrapLines` is where wrapping starts: the toolbar button changes it afterwards, and passing a different value sets it again.
|
|
331
|
+
|
|
319
332
|
### Labels
|
|
320
333
|
|
|
321
334
|
Every text goes through one `labels` option. Set what you need; the rest keeps its English default. Functions receive what they need to build the sentence.
|
|
@@ -340,7 +353,8 @@ Every text goes through one `labels` option. Set what you need; the rest keeps i
|
|
|
340
353
|
| `current`, `result`, `incoming` | `Current`, `Result`, `Incoming` |
|
|
341
354
|
| `applyAllCurrent`, `applyAllIncoming` | `Apply all from current`, `Apply all from incoming` |
|
|
342
355
|
| `previousChange`, `nextChange`, `undo`, `redo` | `Previous change`, `Next change`, `Undo`, `Redo` |
|
|
343
|
-
| `hideUnchanged` | `Hide unchanged lines` |
|
|
356
|
+
| `hideUnchanged`, `wrapLines` | `Hide unchanged lines`, `Wrap lines` |
|
|
357
|
+
| `scrollLines` | `Scroll lines sideways` (accessible name of the scrollbar under the panes) |
|
|
344
358
|
| `summary(status)` | `11 changes` / `No differences` |
|
|
345
359
|
| `noChanges` | `No differences. Nothing to merge.` |
|
|
346
360
|
| `unresolved(status)` | `3 of 11 changes still need a decision.` |
|
|
@@ -453,6 +467,35 @@ Style it with the data attributes:
|
|
|
453
467
|
|
|
454
468
|
For per-change buttons, read `line.actions` (`accept`, `remove`, `edit`, `revert`: each `{ label, pressed, run }`) and render the `number` and `actions` columns with `getCellProps(item, pane, "number" | "actions")`. The shadcn component in `demo/src/components/ui/merge-conflict-viewer.tsx` is a complete reference implementation.
|
|
455
469
|
|
|
470
|
+
### Scroll long lines sideways
|
|
471
|
+
|
|
472
|
+
`useMergeViewer` wraps long lines unless you pass `wrapLines: false` or call `viewer.toggleWrapLines()` (also `setWrapLines(boolean)`). `getCellProps` already sets `white-space` and `overflow` on the `code` cells and `data-wrap="wrap" | "nowrap"`, so wrapping works with the markup above. To let users scroll sideways while lines do not wrap, add two things:
|
|
473
|
+
|
|
474
|
+
```tsx
|
|
475
|
+
const viewer = useMergeViewer({ currentJson, incomingJson, wrapLines: false })
|
|
476
|
+
const { ref: scrollbarRef, ...scrollbarProps } = viewer.getScrollbarProps()
|
|
477
|
+
|
|
478
|
+
<div ref={scrollRef} style={{ overflow: "auto", height: 500 }}>
|
|
479
|
+
<div {...viewer.getGridProps()}>
|
|
480
|
+
{/* ... */}
|
|
481
|
+
<div {...viewer.getCellProps(item, pane, "code")}>
|
|
482
|
+
{/* the text of the line goes in an element with these props */}
|
|
483
|
+
<span {...viewer.getTextProps()}>{line.text}</span>
|
|
484
|
+
</div>
|
|
485
|
+
</div>
|
|
486
|
+
|
|
487
|
+
{/* a scrollbar for all three panes: hidden while lines wrap or fit */}
|
|
488
|
+
<div ref={scrollbarRef} {...scrollbarProps}>
|
|
489
|
+
<div {...viewer.getScrollbarContentProps()} />
|
|
490
|
+
</div>
|
|
491
|
+
</div>
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
- The three panes share one grid, so they cannot each scroll. Instead the scrollbar sets one length, the CSS variable `--merge-scroll-x` (exported as `SCROLL_X_VARIABLE`), on the root element, and `getTextProps` slides the text of every pane by it. That keeps the panes exactly in step.
|
|
495
|
+
- The scrollbar props make it `position: sticky; bottom: 0`, so it stays in view; give it a `z-index` and a background. Shift + wheel and horizontal wheel or trackpad gestures over the scroll element move it as well.
|
|
496
|
+
- Cells use `overflow-x: clip`, not a scrolling overflow, so buttons and popovers you put in a cell keep their place.
|
|
497
|
+
- `getScrollbarProps().hidden` is `true` while lines wrap or none is wider than its pane. Add `[hidden] { display: none }` if your CSS reset does not.
|
|
498
|
+
|
|
456
499
|
## API
|
|
457
500
|
|
|
458
501
|
### `useMergeViewer(options)`
|
|
@@ -463,10 +506,12 @@ Takes the [options](#options) above. Returns everything `useMergeConflicts` retu
|
|
|
463
506
|
|---|---|
|
|
464
507
|
| `items` | Everything shown, in order: rows (`current`, `result` and `incoming` lines) and folds of unchanged lines |
|
|
465
508
|
| `labels`, `stacked`, `statusState`, `statusText` | Resolved texts, whether the panes are stacked, and the banner state (`"empty" \| "pending" \| "resolved"`) |
|
|
466
|
-
| `collapsed`, `toggleCollapsed` | Whether unchanged runs are folded |
|
|
509
|
+
| `collapsed`, `toggleCollapsed` | Whether unchanged runs are folded. `collapsed` turns `false` when the user opens a run by hand, and `toggleCollapsed` then folds them all again before it switches folding off |
|
|
510
|
+
| `wrapLines`, `setWrapLines(wrap)`, `toggleWrapLines()` | Whether long lines wrap. While they do not, the panes scroll sideways together (see [headless scrolling](#scroll-long-lines-sideways)) |
|
|
467
511
|
| `activeId`, `goToChange(dir)`, `goToNextUnresolved()` | Navigation between changes |
|
|
468
512
|
| `editable`, `editingId`, `startEdit(id)`, `cancelEdit()`, `editorText(id)`, `commitEdit(id, text)` | Editing; `commitEdit` returns the parser's message when the text is not valid JSON |
|
|
469
513
|
| `getRootProps()`, `getScrollProps()`, `getGridProps()`, `getHeaderProps(pane)`, `getCellProps(row, pane, column)`, `getFoldProps(fold, pane)` | Prop getters to spread on your elements |
|
|
514
|
+
| `getTextProps()`, `getScrollbarProps()`, `getScrollbarContentProps()` | Prop getters for lines that do not wrap, see [headless scrolling](#scroll-long-lines-sideways) |
|
|
470
515
|
|
|
471
516
|
`MergeViewerProvider` and `useMergeViewerContext` let parts share one viewer without prop drilling (this is how the shadcn component's parts work).
|
|
472
517
|
|
package/dist/lib/main.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
`),c=o.length-1,i=e===null?"":`${JSON.stringify(e)}: `;return o.map((h,u)=>{const d=u===0?`${i}${h}`:h;return`${n}${d}${u===c&&r?",":""}`})}function De(e,t){const s=[],r=[],n=(u,d,$,k=null)=>{s.push({index:s.length,blockId:k,blockRow:0,blockSize:1,left:u,right:d,result:$,leftNo:null,rightNo:null,resultNo:null})},o=(u,d)=>{const $=u.map(a=>a.type!=="conflict"||a.hasLeft),k=u.map(a=>a.type!=="conflict"||a.hasRight),M=u.map(a=>a.type!=="conflict"||Z(a,t[a.id]).present),A=$.lastIndexOf(!0),w=k.lastIndexOf(!0),S=M.lastIndexOf(!0);u.forEach((a,O)=>{const v=O!==A,N=O!==w,C=O!==S;if(a.type==="equal"){const g=H(a.key,a.value,d,v),b=H(a.key,a.value,d,N),D=H(a.key,a.value,d,C);g.forEach((J,E)=>{n(J,b[E],D[E])});return}if(a.type==="container"){const g=Le.repeat(d),b=a.key===null?"":`${JSON.stringify(a.key)}: `,[D,J]=a.container==="array"?["[","]"]:["{","}"],E=`${g}${b}${D}`;n(E,E,E),o(a.children,d+1),n(`${g}${J}${v?",":""}`,`${g}${J}${N?",":""}`,`${g}${J}${C?",":""}`);return}const z=a.hasLeft?H(a.key,a.left,d,v):[],T=a.hasRight?H(a.key,a.right,d,N):[],I=Z(a,t[a.id]),P=I.present?H(a.key,I.value,d,C):[],K=Math.max(z.length,T.length,P.length),W=s.length;for(let g=0;g<K;g++)n(z[g]??null,T[g]??null,P[g]??null,a.id);r.push({id:a.id,entry:a,kind:a.kind,start:W,size:K,selection:ct(a,t[a.id])})})};n("{","{","{"),o(e.children,1),n("}","}","}");for(const u of r)for(let d=0;d<u.size;d++)s[u.start+d].blockRow=d,s[u.start+d].blockSize=u.size;let c=0,i=0,h=0;for(const u of s)u.leftNo=u.left===null?null:++c,u.rightNo=u.right===null?null:++i,u.resultNo=u.result===null?null:++h;return{rows:s,blocks:r}}const _e=y.createContext(null);function it({viewer:e,children:t}){return Qe.jsx(_e.Provider,{value:e,children:t})}function ut(){const e=y.useContext(_e);if(!e)throw new Error("useMergeViewerContext must be used inside a MergeViewerProvider");return e}const at="minmax(0, 1fr) 3.5rem 3.5ch 3.5ch minmax(0, 1fr) 3.5ch 3.5rem minmax(0, 1fr)",dt="3.5ch 3.5rem minmax(0, 1fr)",ft={current:{code:"1",actions:"2",number:"3",header:"1 / 4",fold:"1 / 4"},result:{number:"4",code:"5",header:"4 / 6",fold:"4 / 6"},incoming:{number:"6",actions:"7",code:"8",header:"6 / 9",fold:"6 / 9"}},ht={current:{number:"1",actions:"2",code:"3",header:"1 / -1",fold:"1 / -1"},incoming:{number:"1",actions:"2",code:"3",header:"1 / -1",fold:"1 / -1"},result:{number:"1",code:"2 / 4",header:"1 / -1",fold:"1 / -1"}},gt={current:0,incoming:1,result:2};function Q(e,t,s,r,n){const c=(e==="stacked"?ht:ft)[t][s]??"auto";if(e==="horizontal")return{gridRow:s==="header"?1:r+2,gridColumn:c};const i=gt[t]*(n+1);return{gridRow:s==="header"?i+1:i+r+2,gridColumn:c}}function ze(e){return e==="stacked"?dt:at}const pt=100;function Je({currentJson:e,incomingJson:t,initialMergedJson:s,startUnresolved:r,decisions:n,onDecisionsChange:o}){const c=y.useMemo(()=>JSON.stringify(e),[e]),i=y.useMemo(()=>JSON.stringify(t),[t]),h=y.useMemo(()=>s===void 0?void 0:JSON.stringify(s),[s]),u=y.useMemo(()=>Me(e,t),[c,i]),d=y.useMemo(()=>Ke(u,s),[u,h]),$=r??s===void 0,k=()=>$?{}:d,[M,A]=y.useState(k),w=y.useRef({past:[],future:[]}),[,S]=y.useState(0),[a,O]=y.useState(u);a!==u&&(O(u),A(k()),w.current={past:[],future:[]});const v=n!==void 0,N=v?n:M,C=y.useRef(N);C.current=N;const z=y.useRef(o);z.current=o;const T=g=>{C.current=g,v||A(g),z.current?.(g),S(b=>b+1)},I=g=>{if(j(g,C.current))return;const b=w.current;b.past.push(C.current),b.past.length>pt&&b.past.shift(),b.future=[],T(g)},P=y.useMemo(()=>({...d,...N}),[d,N]),K=y.useMemo(()=>ae(u,P),[u,P]),W=y.useMemo(()=>Pe(u,N),[u,N]);return{tree:u,decisions:N,selection:P,merged:K,status:W,isResolved:g=>Object.hasOwn(N,g),choose:(g,b)=>I({...C.current,[g]:b}),revert:g=>{const b={...C.current},D=k();Object.hasOwn(D,g)?b[g]=D[g]:delete b[g],I(b)},applyAll:g=>I(Y(u,g)),reset:()=>I(k()),undo:()=>{const g=w.current,b=g.past.pop();b&&(g.future.push(C.current),T(b))},redo:()=>{const g=w.current,b=g.future.pop();b&&(g.past.push(C.current),T(b))},canUndo:w.current.past.length>0,canRedo:w.current.future.length>0}}const yt=900,mt=3,vt=typeof window>"u"?y.useEffect:y.useLayoutEffect,le=e=>e?"":void 0;function bt({onMergeChange:e,editable:t=!1,labels:s,layout:r="responsive",stackBelow:n=yt,collapseUnchanged:o=!1,...c}){const i=y.useMemo(()=>Ie(s),[s]),h=Je(c),{tree:u,selection:d,merged:$,status:k,isResolved:M}=h,A=y.useMemo(()=>De(u,d),[u,d]),w=y.useMemo(()=>{const l=new Map;for(const f of A.blocks)l.set(f.id,f);return l},[A]),S=y.useRef(e);S.current=e,y.useEffect(()=>{S.current?.($,k)},[$,k]);const[a,O]=y.useState(null),[v,N]=y.useState(null),[C,z]=y.useState(!1);vt(()=>{if(r!=="responsive"||!v||typeof ResizeObserver>"u")return;const l=new ResizeObserver(([f])=>{z(f.contentRect.width<n)});return l.observe(v),()=>l.disconnect()},[r,v,n]);const T=r==="vertical"||r==="responsive"&&C,I=T?"stacked":"horizontal",P=typeof o=="number"?o:mt,[K,W]=y.useState(o!==!1),[g,b]=y.useState(()=>new Set),D=y.useMemo(()=>K?we(A.rows,P,g):A.rows.map(l=>({type:"row",row:l})),[K,A,P,g]),J=l=>{b(f=>new Set(f).add(l))},[E,te]=y.useState(null),[de,ne]=y.useState(null),V=y.useMemo(()=>u.conflicts.map(l=>l.id),[u]),Ue=l=>{const f=Array.from(a?.querySelectorAll("[data-merge-block]")??[]).filter(L=>L.dataset.mergeBlock===l),p=f.find(L=>getComputedStyle(L).display!=="none")??f[0],R=window.matchMedia?.("(prefers-reduced-motion: reduce)").matches??!1;p?.scrollIntoView?.({block:"center",behavior:R?"auto":"smooth"})},fe=l=>{te(l),Ue(l)},he=(l,f)=>{if(l.length===0)return null;const p=E===null?-1:V.indexOf(E);if(f==="next")return l.find(L=>V.indexOf(L)>p)??l[0];const R=p===-1?V.length:p;return[...l].reverse().find(L=>V.indexOf(L)<R)??l[l.length-1]},Fe=()=>{const l=he(V.filter(f=>!M(f)),"next");return l===null?!1:(fe(l),!0)},Ve=l=>{const f=he(V,l);f!==null&&fe(f)},G=(l,f)=>{h.choose(l,f),te(l)},ge=l=>{const f=w.get(l);if(!f)return"null";const p=Z(f.entry,d[l]),R=p.present?p.value:f.entry.hasRight?f.entry.right:f.entry.left;return JSON.stringify(R,null,2)??"null"},pe=l=>{te(l),ne(l)},qe=()=>ne(null),Be=(l,f)=>{let p;try{p=JSON.parse(f)}catch(R){return R instanceof Error?R.message:"Invalid JSON"}return G(l,{custom:p}),ne(null),null},oe=(l,f,p,R,L)=>{const m=f.blockId?w.get(f.blockId):void 0,re=!!m&&f.blockRow===0,Ye=!!m&&f.blockRow===f.blockSize-1,X=m?M(m.id):!0,x=m?.entry,Ze=l==="current"?m?.selection==="left":l==="incoming"?m?.selection==="right":!0;let q="unchanged";m&&(p===null?q="filler":l==="result"&&!X?q="pending":l==="result"&&m.selection==="custom"?q="edited":X&&!Ze?q="rejected":q="changed");const U={};if(m&&x&&re){const be=()=>({label:i.removeChange(x.label),pressed:X&&m.selection==="deleted",run:()=>G(m.id,"deleted")}),ke=(Se,Xe)=>({label:Xe,pressed:X&&m.selection===Se,run:()=>G(m.id,Se)});l==="current"&&x.hasLeft?(U.remove=be(),U.accept=ke("left",i.acceptCurrent(x.label))):l==="incoming"&&x.hasRight?(U.accept=ke("right",i.acceptIncoming(x.label)),U.remove=be()):l==="result"&&t&&(m.selection==="custom"&&(U.revert={label:i.revertEdit(x.label),pressed:!1,run:()=>h.revert(m.id)}),U.edit={label:i.editChange(x.label),pressed:!1,run:()=>pe(m.id)})}const Ge=l==="result"&&t&&re&&m!==void 0&&de===m.id;return{pane:l,text:p,segments:p===null?[]:Ce(p,l!=="result"&&m?.kind==="modified"?L:void 0),lineNo:R,state:q,kind:m?.kind??null,blockId:m?.id??null,blockStart:re,blockEnd:Ye,active:!!m&&E===m?.id,actions:U,editor:Ge&&m&&x?{title:i.editorTitle(x.label),inputLabel:i.editorInput(x.label),initialText:ge(m.id)}:void 0}},ye=D.map((l,f)=>{if(l.type==="fold")return{type:"fold",key:`fold-${l.key}`,index:f,hidden:l.hidden,label:i.unchangedLines(l.hidden),showLabel:i.showUnchanged(l.hidden),expand:()=>J(l.key)};const{row:p}=l;return{type:"row",key:`row-${p.index}`,index:f,row:p,current:oe("current",p,p.left,p.leftNo,p.right),result:oe("result",p,p.result,p.resultNo,null),incoming:oe("incoming",p,p.right,p.rightNo,p.left)}}),me=k.total,ve=me===0?"empty":k.allResolved?"resolved":"pending",He=me===0?i.noChanges:k.allResolved?i.allResolved(k):i.unresolved(k),We=l=>{const f=l.target;if(!(l.ctrlKey||l.metaKey)||f.closest("textarea, input"))return;const p=l.key.toLowerCase();p==="z"&&!l.shiftKey?(l.preventDefault(),h.undo()):(p==="z"&&l.shiftKey||p==="y")&&(l.preventDefault(),h.redo())},se=ye.length;return{...h,choose:G,items:ye,labels:i,stacked:T,statusState:ve,statusText:He,collapsed:K,toggleCollapsed:()=>W(l=>!l),activeId:E,goToChange:Ve,goToNextUnresolved:Fe,editable:t,editingId:de,startEdit:pe,cancelEdit:qe,editorText:ge,commitEdit:Be,getRootProps:()=>({ref:O,onKeyDown:We,"data-merge-status":ve}),getScrollProps:()=>({ref:N}),getGridProps:()=>({style:{display:"grid",gridTemplateColumns:ze(I)},"data-layout":I}),getHeaderProps:l=>({style:{...Q(I,l,"header",0,se)},"data-pane":l,"data-column":"header"}),getCellProps:(l,f,p)=>{const R=l[f],L={...Q(I,f,p,l.index,se)};return T&&R.state==="filler"&&(L.display="none"),{style:L,"data-pane":f,"data-column":p,"data-state":R.state,"data-kind":R.kind??void 0,"data-block-start":le(R.blockStart),"data-block-end":le(R.blockEnd),"data-active":le(R.active),"data-merge-block":p==="code"&&R.blockStart?R.blockId??void 0:void 0}},getFoldProps:(l,f)=>({type:"button",style:{...Q(I,f,"fold",l.index,se)},tabIndex:f==="current"?0:-1,"aria-hidden":f==="current"?void 0:!0,"aria-label":l.showLabel,"data-pane":f,"data-column":"fold",onClick:l.expand})}}exports.MergeViewerProvider=it;exports.buildMergeLayout=De;exports.buildMergeTree=Me;exports.buildMergedJson=ae;exports.deepEqual=j;exports.defaultLabels=Ae;exports.foldRows=we;exports.getMergeStatus=Pe;exports.gridTemplateColumns=ze;exports.initialSelection=Ke;exports.inlineSegments=Ce;exports.isCustomChoice=ue;exports.placeCell=Q;exports.resolveLabels=Ie;exports.selectAll=Y;exports.splitInlineEdit=Ne;exports.useMergeConflicts=Je;exports.useMergeViewer=bt;exports.useMergeViewerContext=ut;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ht=require("react/jsx-runtime"),y=require("react"),gt=3;function pe(e,t,r){const l=[],n=(c,f)=>{for(let d=c;d<f;d++)l.push({type:"row",row:e[d]})};let o=0;for(;o<e.length;){if(e[o].blockId!==null){l.push({type:"row",row:e[o]}),o++;continue}let c=o;for(;c<e.length&&e[c].blockId===null;)c++;const f=o===0?1:t,d=c===e.length?1:t,i=c-o-f-d,h=`${e[o-1]?.blockId??"start"}>${e[c]?.blockId??"end"}`;i<gt||r.has(h)?n(o,c):(n(o,o+f),l.push({type:"fold",key:h,hidden:i}),n(c-d,c)),o=c}return l}function Pe(e,t){if(t===null)return[e,"",""];const r=e.endsWith(",")?",":"",l=r?e.slice(0,-1):e,n=t.endsWith(",")?t.slice(0,-1):t;let o=0;const c=Math.min(l.length,n.length);for(;o<c&&l[o]===n[o];)o++;let f=l.length,d=n.length;for(;f>o&&d>o&&l[f-1]===n[d-1];)f--,d--;return[l.slice(0,o),l.slice(o,f),l.slice(f)+r]}function _e(e,t){if(t==null)return[{text:e,changed:!1}];const[r,l,n]=Pe(e,t);if(!l)return[{text:e,changed:!1}];const o=[];return r&&o.push({text:r,changed:!1}),o.push({text:l,changed:!0}),n&&o.push({text:n,changed:!1}),o}function Y(e,t,r){return e===1?t:r}const Ke={current:"Current",result:"Result",incoming:"Incoming",applyAllCurrent:"Apply all from current",applyAllIncoming:"Apply all from incoming",previousChange:"Previous change",nextChange:"Next change",hideUnchanged:"Hide unchanged lines",wrapLines:"Wrap lines",undo:"Undo",redo:"Redo",summary:({total:e})=>e===0?"No differences":`${e} ${Y(e,"change","changes")}`,noChanges:"No differences. Nothing to merge.",unresolved:({unresolved:e,total:t})=>`${e} of ${t} ${Y(t,"change","changes")} still ${Y(e,"needs","need")} a decision.`,allResolved:({total:e})=>`All ${e} ${Y(e,"change","changes")} resolved. Safe to merge.`,nextUnresolved:"Next unresolved",scrollLines:"Scroll lines sideways",unchangedLines:e=>`${e} unchanged ${Y(e,"line","lines")}`,showUnchanged:e=>`Show ${e} unchanged ${Y(e,"line","lines")}`,acceptCurrent:e=>`Accept current ${e}`,acceptIncoming:e=>`Accept incoming ${e}`,removeChange:e=>`Remove ${e} from result`,editChange:e=>`Edit ${e} in result`,revertEdit:e=>`Revert edit of ${e}`,editorTitle:e=>`Edit ${e} (JSON value)`,editorInput:e=>`JSON value of ${e}`,apply:"Apply",cancel:"Cancel"};function We(e){const t={...Ke};for(const[r,l]of Object.entries(e??{}))l!==void 0&&(t[r]=l);return t}const ze=" ",pt=["id","@id","key","name","code","uuid","slug"];function be(e){return typeof e=="object"&&e!==null&&"custom"in e}function B(e,t){return Object.hasOwn(e,t)}function J(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function j(e,t){if(e===t)return!0;if(Array.isArray(e)||Array.isArray(t))return Array.isArray(e)&&Array.isArray(t)&&e.length===t.length&&e.every((r,l)=>j(r,t[l]));if(J(e)&&J(t)){const r=Object.keys(e),l=Object.keys(t);return r.length===l.length&&r.every(n=>B(t,n)&&j(e[n],t[n]))}return!1}function ye(e){return Array.isArray(e)?`[${e.map(ye).join(",")}]`:J(e)?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${ye(e[t])}`).join(",")}}`:JSON.stringify(e)??"null"}function me(e){return e===void 0?e:JSON.parse(JSON.stringify(e))}const yt=/^[A-Za-z_$][\w$]*$/;function mt(e,t){return yt.test(t)?e?`${e}.${t}`:t:`${e}[${JSON.stringify(t)}]`}function bt(e,t){const r=[...t],l=new Set(t);let n=-1;for(const o of e){if(l.has(o)){n=r.indexOf(o);continue}n+=1,r.splice(n,0,o),l.add(o)}return r}function Me(e,t){const r=e.length,l=t.length,n=l+1,o=new Uint32Array((r+1)*n);for(let i=r-1;i>=0;i--)for(let h=l-1;h>=0;h--)o[i*n+h]=e[i]===t[h]?o[(i+1)*n+h+1]+1:Math.max(o[(i+1)*n+h],o[i*n+h+1]);const c=[];let f=0,d=0;for(;f<r&&d<l;)e[f]===t[d]?(c.push([f,d]),f++,d++):o[(f+1)*n+d]>=o[f*n+d+1]?f++:d++;return c}function vt(e,t){return pt.find(r=>[e,t].every(l=>{const n=new Set;return l.every(o=>{if(!J(o)||!B(o,r))return!1;const c=o[r];return typeof c!="string"&&typeof c!="number"||n.has(c)?!1:(n.add(c),!0)})}))}function le(e,t,r,l,n,o){const c={type:"conflict",id:JSON.stringify(r),key:t,label:l,path:r,kind:e==="left"?"left-only":"right-only",hasLeft:e==="left",hasRight:e==="right",left:e==="left"?n:void 0,right:e==="right"?n:void 0};return o.push(c),c}function De(e,t,r,l,n,o){if(j(l,n))return{type:"equal",key:e,value:l};if(J(l)&&J(n))return{type:"container",key:e,container:"object",children:Fe(l,n,t,r,o)};if(Array.isArray(l)&&Array.isArray(n))return{type:"container",key:e,container:"array",children:St(l,n,t,r,o)};const c={type:"conflict",id:JSON.stringify(t),key:e,label:r,path:t,kind:"modified",hasLeft:!0,hasRight:!0,left:l,right:n};return o.push(c),c}function Fe(e,t,r,l,n){const o=[];for(const c of bt(Object.keys(e),Object.keys(t))){const f=B(e,c),d=B(t,c),i=[...r,c],h=mt(l,c);f&&d?o.push(De(c,i,h,e[c],t[c],n)):f?o.push(le("left",c,i,h,e[c],n)):o.push(le("right",c,i,h,t[c],n))}return o}function St(e,t,r,l,n){const o=vt(e,t),c=(R,a)=>R.map(w=>a?`${typeof w[a]}:${w[a]}`:ye(w));let f=Me(c(e,o),c(t,o)),d=o!==void 0;d&&f.length===0&&(d=!1,f=Me(c(e,void 0),c(t,void 0)));const i=[];let h=0,$=0;const A=R=>`${l}[${R}]`,N=()=>[...r,i.length],M=(R,a)=>{i.push(De(null,N(),A(a),e[R],t[a],n))},O=(R,a)=>{const w=d?0:Math.min(R-h,a-$);for(let S=0;S<w;S++)M(h+S,$+S);for(let S=h+w;S<R;S++)i.push(le("left",null,N(),A(S),e[S],n));for(let S=$+w;S<a;S++)i.push(le("right",null,N(),A(S),t[S],n));h=R,$=a};for(const[R,a]of f)O(R,a),M(R,a),h=R+1,$=a+1;return O(e.length,t.length),i}function Je(e,t){const r=[];return{children:Fe(e,t,[],"",r),conflicts:r}}function ee(e,t){const r=t??"right";return be(r)?{present:!0,value:r.custom,side:null,custom:!0}:r==="left"&&e.hasLeft?{present:!0,value:e.left,side:"left"}:r==="right"&&e.hasRight?{present:!0,value:e.right,side:"right"}:{present:!1,side:null}}function kt(e,t){const r=ee(e,t);return r.custom?"custom":r.side??"deleted"}function Q(e,t){const r={};for(const l of e.conflicts)r[l.id]=t;return r}function Ue(e,t,r){const l={},n=[];for(const o of e){let c;if(o.type==="equal")c=me(o.value);else if(o.type==="container")c=Ue(o.children,t,o.container);else{const f=ee(o,t[o.id]);if(!f.present)continue;c=me(f.value)}r==="array"?n.push(c):o.key!==null&&(l[o.key]=c)}return r==="array"?n:l}function ve(e,t){return Ue(e.children,t,"object")}const Te=Symbol("unknown");function je(e){return e.hasLeft&&e.hasRight?"deleted":e.hasLeft?"right":"left"}function Ve(e,t,r,l){for(const n of e){if(n.type==="equal")continue;if(n.type==="container"){const f=r==="object"&&n.key!==null&&J(t)&&B(t,n.key)?t[n.key]:Te;Ve(n.children,f,n.container,l);continue}if(t===Te){l[n.id]="right";continue}let o=!1,c=!1;if(r==="object"){if(n.key===null||!J(t)||!B(t,n.key)){l[n.id]=je(n);continue}const f=t[n.key];if(o=n.hasLeft&&j(f,n.left),c=n.hasRight&&j(f,n.right),!o&&!c){l[n.id]={custom:me(f)};continue}}else{const f=Array.isArray(t)?t:[];if(o=n.hasLeft&&f.some(d=>j(d,n.left)),c=n.hasRight&&f.some(d=>j(d,n.right)),!o&&!c){l[n.id]=je(n);continue}}l[n.id]=o&&!c?"left":"right"}}function qe(e,t){let r=0,l=0;for(const o of e.conflicts)B(t,o.id)&&(r++,be(t[o.id])&&l++);const n=e.conflicts.length;return{total:n,resolved:r,unresolved:n-r,edited:l,allResolved:r===n}}function Be(e,t){if(!t)return Q(e,"right");for(const l of["left","right"]){const n=Q(e,l);if(j(t,ve(e,n)))return n}const r=Q(e,"right");return Ve(e.children,t,"object",r),r}function Z(e,t,r,l){const n=ze.repeat(r),o=(JSON.stringify(t,null,2)??"null").split(`
|
|
2
|
+
`),c=o.length-1,f=e===null?"":`${JSON.stringify(e)}: `;return o.map((d,i)=>{const h=i===0?`${f}${d}`:d;return`${n}${h}${i===c&&l?",":""}`})}function Xe(e,t){const r=[],l=[],n=(i,h,$,A=null)=>{r.push({index:r.length,blockId:A,blockRow:0,blockSize:1,left:i,right:h,result:$,leftNo:null,rightNo:null,resultNo:null})},o=(i,h)=>{const $=i.map(a=>a.type!=="conflict"||a.hasLeft),A=i.map(a=>a.type!=="conflict"||a.hasRight),N=i.map(a=>a.type!=="conflict"||ee(a,t[a.id]).present),M=$.lastIndexOf(!0),O=A.lastIndexOf(!0),R=N.lastIndexOf(!0);i.forEach((a,w)=>{const S=w!==M,k=w!==O,x=w!==R;if(a.type==="equal"){const p=Z(a.key,a.value,h,S),v=Z(a.key,a.value,h,k),_=Z(a.key,a.value,h,x);p.forEach((T,K)=>{n(T,v[K],_[K])});return}if(a.type==="container"){const p=ze.repeat(h),v=a.key===null?"":`${JSON.stringify(a.key)}: `,[_,T]=a.container==="array"?["[","]"]:["{","}"],K=`${p}${v}${_}`;n(K,K,K),o(a.children,h+1),n(`${p}${T}${S?",":""}`,`${p}${T}${k?",":""}`,`${p}${T}${x?",":""}`);return}const U=a.hasLeft?Z(a.key,a.left,h,S):[],z=a.hasRight?Z(a.key,a.right,h,k):[],C=ee(a,t[a.id]),E=C.present?Z(a.key,C.value,h,x):[],P=Math.max(U.length,z.length,E.length),D=r.length;for(let p=0;p<P;p++)n(U[p]??null,z[p]??null,E[p]??null,a.id);l.push({id:a.id,entry:a,kind:a.kind,start:D,size:P,selection:kt(a,t[a.id])})})};n("{","{","{"),o(e.children,1),n("}","}","}");for(const i of l)for(let h=0;h<i.size;h++)r[i.start+h].blockRow=h,r[i.start+h].blockSize=i.size;let c=0,f=0,d=0;for(const i of r)i.leftNo=i.left===null?null:++c,i.rightNo=i.right===null?null:++f,i.resultNo=i.result===null?null:++d;return{rows:r,blocks:l}}const He=y.createContext(null);function wt({viewer:e,children:t}){return ht.jsx(He.Provider,{value:e,children:t})}function Rt(){const e=y.useContext(He);if(!e)throw new Error("useMergeViewerContext must be used inside a MergeViewerProvider");return e}const Lt="minmax(0, 1fr) 3.5rem 3.5ch 3.5ch minmax(0, 1fr) 3.5ch 3.5rem minmax(0, 1fr)",Ot="3.5ch 3.5rem minmax(0, 1fr)",$t={current:{code:"1",actions:"2",number:"3",header:"1 / 4",fold:"1 / 4"},result:{number:"4",code:"5",header:"4 / 6",fold:"4 / 6"},incoming:{number:"6",actions:"7",code:"8",header:"6 / 9",fold:"6 / 9"}},At={current:{number:"1",actions:"2",code:"3",header:"1 / -1",fold:"1 / -1"},incoming:{number:"1",actions:"2",code:"3",header:"1 / -1",fold:"1 / -1"},result:{number:"1",code:"2 / 4",header:"1 / -1",fold:"1 / -1"}},Nt={current:0,incoming:1,result:2};function re(e,t,r,l,n){const c=(e==="stacked"?At:$t)[t][r]??"auto";if(e==="horizontal")return{gridRow:r==="header"?1:l+2,gridColumn:c};const f=Nt[t]*(n+1);return{gridRow:r==="header"?f+1:f+l+2,gridColumn:c}}function Ye(e){return e==="stacked"?Ot:Lt}const xt=100;function Ze({currentJson:e,incomingJson:t,initialMergedJson:r,startUnresolved:l,decisions:n,onDecisionsChange:o}){const c=y.useMemo(()=>JSON.stringify(e),[e]),f=y.useMemo(()=>JSON.stringify(t),[t]),d=y.useMemo(()=>r===void 0?void 0:JSON.stringify(r),[r]),i=y.useMemo(()=>Je(e,t),[c,f]),h=y.useMemo(()=>Be(i,r),[i,d]),$=l??r===void 0,A=()=>$?{}:h,[N,M]=y.useState(A),O=y.useRef({past:[],future:[]}),[,R]=y.useState(0),[a,w]=y.useState(i);a!==i&&(w(i),M(A()),O.current={past:[],future:[]});const S=n!==void 0,k=S?n:N,x=y.useRef(k);x.current=k;const U=y.useRef(o);U.current=o;const z=p=>{x.current=p,S||M(p),U.current?.(p),R(v=>v+1)},C=p=>{if(j(p,x.current))return;const v=O.current;v.past.push(x.current),v.past.length>xt&&v.past.shift(),v.future=[],z(p)},E=y.useMemo(()=>({...h,...k}),[h,k]),P=y.useMemo(()=>ve(i,E),[i,E]),D=y.useMemo(()=>qe(i,k),[i,k]);return{tree:i,decisions:k,selection:E,merged:P,status:D,isResolved:p=>Object.hasOwn(k,p),choose:(p,v)=>C({...x.current,[p]:v}),revert:p=>{const v={...x.current},_=A();Object.hasOwn(_,p)?v[p]=_[p]:delete v[p],C(v)},applyAll:p=>C(Q(i,p)),reset:()=>C(A()),undo:()=>{const p=O.current,v=p.past.pop();v&&(p.future.push(x.current),z(v))},redo:()=>{const p=O.current,v=p.future.pop();v&&(p.past.push(x.current),z(v))},canUndo:O.current.past.length>0,canRedo:O.current.future.length>0}}const Ct=900,Et=3,he=typeof window>"u"?y.useEffect:y.useLayoutEffect,se="--merge-scroll-x",ge=e=>e?"":void 0;function It({onMergeChange:e,editable:t=!1,labels:r,layout:l="responsive",stackBelow:n=Ct,collapseUnchanged:o=!1,wrapLines:c=!0,...f}){const d=y.useMemo(()=>We(r),[r]),i=Ze(f),{tree:h,selection:$,merged:A,status:N,isResolved:M}=i,O=y.useMemo(()=>Xe(h,$),[h,$]),R=y.useMemo(()=>{const s=new Map;for(const u of O.blocks)s.set(u.id,u);return s},[O]),a=y.useRef(e);a.current=e,y.useEffect(()=>{a.current?.(A,N)},[A,N]);const[w,S]=y.useState(null),[k,x]=y.useState(null),[U,z]=y.useState(!1);he(()=>{if(l!=="responsive"||!k||typeof ResizeObserver>"u")return;const s=new ResizeObserver(([u])=>{z(u.contentRect.width<n)});return s.observe(k),()=>s.disconnect()},[l,k,n]);const C=l==="vertical"||l==="responsive"&&U,E=C?"stacked":"horizontal",P=typeof o=="number"?o:Et,[D,p]=y.useState(o!==!1),[v,_]=y.useState(()=>new Set),T=y.useMemo(()=>D?pe(O.rows,P,v):O.rows.map(s=>({type:"row",row:s})),[D,O,P,v]),K=s=>s.filter(u=>u.type==="fold").length,Se=y.useMemo(()=>D&&K(T)===K(pe(O.rows,P,new Set)),[D,T,O,P]),Ge=()=>{_(new Set),p(!Se)},Qe=s=>{_(u=>new Set(u).add(s))},[V,ce]=y.useState(c);y.useEffect(()=>ce(c),[c]);const et=()=>ce(s=>!s),[F,tt]=y.useState(null),[ke,ie]=y.useState(0),G=!V&&ke>0;he(()=>{if(V||!w){ie(0);return}const s=()=>{let g=0;for(const W of w.querySelectorAll("[data-merge-text]"))g=Math.max(g,W.offsetWidth);let m=null;for(const W of w.querySelectorAll('[data-column="code"]'))W.clientWidth>0&&(m===null||W.clientWidth<m.clientWidth)&&(m=W);if(!m){ie(0);return}const L=getComputedStyle(m),b=(Number.parseFloat(L.paddingLeft)||0)+(Number.parseFloat(L.paddingRight)||0);ie(Math.max(0,Math.ceil(g+b-m.clientWidth)))};if(s(),!k||typeof ResizeObserver>"u")return;const u=new ResizeObserver(s);return u.observe(k),()=>u.disconnect()},[V,w,k,T,C]),he(()=>{w?.style.setProperty(se,`${G&&F?F.scrollLeft:0}px`)},[w,F,G]),y.useEffect(()=>{if(!G||!k||!F)return;const s=u=>{const g=u.shiftKey?u.deltaX||u.deltaY:Math.abs(u.deltaX)>Math.abs(u.deltaY)?u.deltaX:0;if(g===0)return;const m=F.scrollLeft;F.scrollLeft+=g,F.scrollLeft!==m&&u.preventDefault()};return k.addEventListener("wheel",s,{passive:!1}),()=>k.removeEventListener("wheel",s)},[G,k,F]);const[te,ue]=y.useState(null),[we,ae]=y.useState(null),X=y.useMemo(()=>h.conflicts.map(s=>s.id),[h]),nt=s=>{const u=Array.from(w?.querySelectorAll("[data-merge-block]")??[]).filter(L=>L.dataset.mergeBlock===s),g=u.find(L=>getComputedStyle(L).display!=="none")??u[0],m=window.matchMedia?.("(prefers-reduced-motion: reduce)").matches??!1;g?.scrollIntoView?.({block:"center",behavior:m?"auto":"smooth"})},Re=s=>{ue(s),nt(s)},Le=(s,u)=>{if(s.length===0)return null;const g=te===null?-1:X.indexOf(te);if(u==="next")return s.find(L=>X.indexOf(L)>g)??s[0];const m=g===-1?X.length:g;return[...s].reverse().find(L=>X.indexOf(L)<m)??s[s.length-1]},ot=()=>{const s=Le(X.filter(u=>!M(u)),"next");return s===null?!1:(Re(s),!0)},rt=s=>{const u=Le(X,s);u!==null&&Re(u)},ne=(s,u)=>{i.choose(s,u),ue(s)},Oe=s=>{const u=R.get(s);if(!u)return"null";const g=ee(u.entry,$[s]),m=g.present?g.value:u.entry.hasRight?u.entry.right:u.entry.left;return JSON.stringify(m,null,2)??"null"},$e=s=>{ue(s),ae(s)},st=()=>ae(null),lt=(s,u)=>{let g;try{g=JSON.parse(u)}catch(m){return m instanceof Error?m.message:"Invalid JSON"}return ne(s,{custom:g}),ae(null),null},de=(s,u,g,m,L)=>{const b=u.blockId?R.get(u.blockId):void 0,W=!!b&&u.blockRow===0,ut=!!b&&u.blockRow===u.blockSize-1,oe=b?M(b.id):!0,I=b?.entry,at=s==="current"?b?.selection==="left":s==="incoming"?b?.selection==="right":!0;let H="unchanged";b&&(g===null?H="filler":s==="result"&&!oe?H="pending":s==="result"&&b.selection==="custom"?H="edited":oe&&!at?H="rejected":H="changed");const q={};if(b&&I&&W){const Ce=()=>({label:d.removeChange(I.label),pressed:oe&&b.selection==="deleted",run:()=>ne(b.id,"deleted")}),Ee=(Ie,ft)=>({label:ft,pressed:oe&&b.selection===Ie,run:()=>ne(b.id,Ie)});s==="current"&&I.hasLeft?(q.remove=Ce(),q.accept=Ee("left",d.acceptCurrent(I.label))):s==="incoming"&&I.hasRight?(q.accept=Ee("right",d.acceptIncoming(I.label)),q.remove=Ce()):s==="result"&&t&&(b.selection==="custom"&&(q.revert={label:d.revertEdit(I.label),pressed:!1,run:()=>i.revert(b.id)}),q.edit={label:d.editChange(I.label),pressed:!1,run:()=>$e(b.id)})}const dt=s==="result"&&t&&W&&b!==void 0&&we===b.id;return{pane:s,text:g,segments:g===null?[]:_e(g,s!=="result"&&b?.kind==="modified"?L:void 0),lineNo:m,state:H,kind:b?.kind??null,blockId:b?.id??null,blockStart:W,blockEnd:ut,active:!!b&&te===b?.id,actions:q,editor:dt&&b&&I?{title:d.editorTitle(I.label),inputLabel:d.editorInput(I.label),initialText:Oe(b.id)}:void 0}},Ae=T.map((s,u)=>{if(s.type==="fold")return{type:"fold",key:`fold-${s.key}`,index:u,hidden:s.hidden,label:d.unchangedLines(s.hidden),showLabel:d.showUnchanged(s.hidden),expand:()=>Qe(s.key)};const{row:g}=s;return{type:"row",key:`row-${g.index}`,index:u,row:g,current:de("current",g,g.left,g.leftNo,g.right),result:de("result",g,g.result,g.resultNo,null),incoming:de("incoming",g,g.right,g.rightNo,g.left)}}),Ne=N.total,xe=Ne===0?"empty":N.allResolved?"resolved":"pending",ct=Ne===0?d.noChanges:N.allResolved?d.allResolved(N):d.unresolved(N),it=s=>{const u=s.target;if(!(s.ctrlKey||s.metaKey)||u.closest("textarea, input"))return;const g=s.key.toLowerCase();g==="z"&&!s.shiftKey?(s.preventDefault(),i.undo()):(g==="z"&&s.shiftKey||g==="y")&&(s.preventDefault(),i.redo())},fe=Ae.length;return{...i,choose:ne,items:Ae,labels:d,stacked:C,statusState:xe,statusText:ct,collapsed:Se,toggleCollapsed:Ge,wrapLines:V,setWrapLines:ce,toggleWrapLines:et,activeId:te,goToChange:rt,goToNextUnresolved:ot,editable:t,editingId:we,startEdit:$e,cancelEdit:st,editorText:Oe,commitEdit:lt,getRootProps:()=>({ref:S,onKeyDown:it,"data-merge-status":xe}),getScrollProps:()=>({ref:x}),getGridProps:()=>({style:{display:"grid",gridTemplateColumns:Ye(E)},"data-layout":E}),getTextProps:()=>({style:V?{}:{display:"block",width:"max-content",transform:`translateX(calc(var(${se}, 0px) * -1))`},"data-merge-text":""}),getScrollbarProps:()=>({ref:tt,hidden:!G,role:"group",tabIndex:0,"aria-label":d.scrollLines,"data-merge-scrollbar":"",style:{position:"sticky",bottom:0,overflowX:"auto",overflowY:"hidden"},onScroll:s=>{w?.style.setProperty(se,`${s.currentTarget.scrollLeft}px`)}}),getScrollbarContentProps:()=>({style:{width:`calc(100% + ${ke}px)`,height:1}}),getHeaderProps:s=>({style:{...re(E,s,"header",0,fe)},"data-pane":s,"data-column":"header"}),getCellProps:(s,u,g)=>{const m=s[u],L={...re(E,u,g,s.index,fe)};return g==="code"&&(L.minWidth=0,V?(L.whiteSpace="pre-wrap",L.overflowWrap="anywhere"):(L.whiteSpace="pre",L.overflowX="clip")),C&&m.state==="filler"&&(L.display="none"),{style:L,"data-pane":u,"data-column":g,"data-state":m.state,"data-kind":m.kind??void 0,"data-block-start":ge(m.blockStart),"data-block-end":ge(m.blockEnd),"data-active":ge(m.active),"data-wrap":g==="code"?V?"wrap":"nowrap":void 0,"data-merge-block":g==="code"&&m.blockStart?m.blockId??void 0:void 0}},getFoldProps:(s,u)=>({type:"button",style:{...re(E,u,"fold",s.index,fe)},tabIndex:u==="current"?0:-1,"aria-hidden":u==="current"?void 0:!0,"aria-label":s.showLabel,"data-pane":u,"data-column":"fold",onClick:s.expand})}}exports.MergeViewerProvider=wt;exports.SCROLL_X_VARIABLE=se;exports.buildMergeLayout=Xe;exports.buildMergeTree=Je;exports.buildMergedJson=ve;exports.deepEqual=j;exports.defaultLabels=Ke;exports.foldRows=pe;exports.getMergeStatus=qe;exports.gridTemplateColumns=Ye;exports.initialSelection=Be;exports.inlineSegments=_e;exports.isCustomChoice=be;exports.placeCell=re;exports.resolveLabels=We;exports.selectAll=Q;exports.splitInlineEdit=Pe;exports.useMergeConflicts=Ze;exports.useMergeViewer=It;exports.useMergeViewerContext=Rt;
|