@zag-js/splitter 0.53.0 → 0.54.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/dist/index.mjs CHANGED
@@ -1,2 +1,658 @@
1
- import{createAnatomy}from"@zag-js/anatomy";var anatomy=createAnatomy("splitter").parts("root","panel","resizeTrigger");var parts=anatomy.build();import{getEventKey,getEventStep}from"@zag-js/dom-event";import{dataAttr}from"@zag-js/dom-query";import{createScope,queryAll}from"@zag-js/dom-query";var dom=createScope({getRootId:ctx=>ctx.ids?.root??`splitter:${ctx.id}`,getResizeTriggerId:(ctx,id)=>ctx.ids?.resizeTrigger?.(id)??`splitter:${ctx.id}:splitter:${id}`,getLabelId:ctx=>ctx.ids?.label??`splitter:${ctx.id}:label`,getPanelId:(ctx,id)=>ctx.ids?.panel?.(id)??`splitter:${ctx.id}:panel:${id}`,globalCursorId:ctx=>`splitter:${ctx.id}:global-cursor`,getRootEl:ctx=>dom.getById(ctx,dom.getRootId(ctx)),getResizeTriggerEl:(ctx,id)=>dom.getById(ctx,dom.getResizeTriggerId(ctx,id)),getPanelEl:(ctx,id)=>dom.getById(ctx,dom.getPanelId(ctx,id)),getCursor(ctx){const x=ctx.isHorizontal;let cursor=x?"col-resize":"row-resize";if(ctx.activeResizeState.isAtMin)cursor=x?"e-resize":"s-resize";if(ctx.activeResizeState.isAtMax)cursor=x?"w-resize":"n-resize";return cursor},getPanelStyle(ctx,id){const flexGrow=ctx.panels.find(panel=>panel.id===id)?.size??"0";return{flexBasis:0,flexGrow,flexShrink:1,overflow:"hidden"}},getActiveHandleEl(ctx){const activeId=ctx.activeResizeId;if(activeId==null)return;return dom.getById(ctx,dom.getResizeTriggerId(ctx,activeId))},getResizeTriggerEls(ctx){const ownerId=CSS.escape(dom.getRootId(ctx));return queryAll(dom.getRootEl(ctx),`[role=separator][data-ownedby='${ownerId}']`)},setupGlobalCursor(ctx){const styleEl=dom.getById(ctx,dom.globalCursorId(ctx));const textContent=`* { cursor: ${dom.getCursor(ctx)} !important; }`;if(styleEl){styleEl.textContent=textContent}else{const style=dom.getDoc(ctx).createElement("style");style.id=dom.globalCursorId(ctx);style.textContent=textContent;dom.getDoc(ctx).head.appendChild(style)}},removeGlobalCursor(ctx){dom.getById(ctx,dom.globalCursorId(ctx))?.remove()}});function validateSize(key,size){if(Math.floor(size)>100){throw new Error(`Total ${key} of panels cannot be greater than 100`)}}function getNormalizedPanels(ctx){let numOfPanelsWithoutSize=0;let totalSize=0;let totalMinSize=0;const panels=ctx.size.map(panel=>{const minSize=panel.minSize??0;const maxSize=panel.maxSize??100;totalMinSize+=minSize;if(panel.size==null){numOfPanelsWithoutSize++}else{totalSize+=panel.size}return{...panel,minSize,maxSize}});validateSize("minSize",totalMinSize);validateSize("size",totalSize);let end=0;let remainingSize=0;const result=panels.map(panel=>{let start=end;if(panel.size!=null){end+=panel.size;remainingSize=panel.size-panel.minSize;return{...panel,start,end,remainingSize}}const size=(100-totalSize)/numOfPanelsWithoutSize;end+=size;remainingSize=size-panel.minSize;return{...panel,size,start,end,remainingSize}});return result}function getHandlePanels(ctx,id=ctx.activeResizeId){const[beforeId,afterId]=id?.split(":")??[];if(!beforeId||!afterId)return;const beforeIndex=ctx.previousPanels.findIndex(panel=>panel.id===beforeId);const afterIndex=ctx.previousPanels.findIndex(panel=>panel.id===afterId);if(beforeIndex===-1||afterIndex===-1)return;const before=ctx.previousPanels[beforeIndex];const after=ctx.previousPanels[afterIndex];return{before:{...before,index:beforeIndex},after:{...after,index:afterIndex}}}function getHandleBounds(ctx,id=ctx.activeResizeId){const panels=getHandlePanels(ctx,id);if(!panels)return;const{before,after}=panels;return{min:Math.max(before.start+before.minSize,after.end-after.maxSize),max:Math.min(after.end-after.minSize,before.maxSize+before.start)}}function getPanelBounds(ctx,id){const bounds=getHandleBounds(ctx,id);const panels=getHandlePanels(ctx,id);if(!bounds||!panels)return;const{before,after}=panels;const beforeMin=Math.abs(before.start-bounds.min);const afterMin=after.size+(before.size-beforeMin);const beforeMax=Math.abs(before.start-bounds.max);const afterMax=after.size-(beforeMax-before.size);return{before:{index:before.index,min:beforeMin,max:beforeMax,isAtMin:beforeMin===before.size,isAtMax:beforeMax===before.size,up(step){return Math.min(before.size+step,beforeMax)},down(step){return Math.max(before.size-step,beforeMin)}},after:{index:after.index,min:afterMin,max:afterMax,isAtMin:afterMin===after.size,isAtMax:afterMax===after.size,up(step){return Math.min(after.size+step,afterMin)},down(step){return Math.max(after.size-step,afterMax)}}}}function clamp(value,min,max){return Math.min(Math.max(value,min),max)}function connect(state,send,normalize){const horizontal=state.context.isHorizontal;const focused=state.hasTag("focus");const dragging=state.matches("dragging");const panels=state.context.panels;function getResizeTriggerState(props2){const{id,disabled}=props2;const ids=id.split(":");const panelIds=ids.map(id2=>dom.getPanelId(state.context,id2));const panels2=getHandleBounds(state.context,id);return{disabled:!!disabled,focused:state.context.activeResizeId===id&&focused,panelIds,min:panels2?.min,max:panels2?.max,value:0}}return{focused,dragging,getResizeTriggerState,bounds:getHandleBounds(state.context),setToMinSize(id){const panel=panels.find(panel2=>panel2.id===id);send({type:"SET_PANEL_SIZE",id,size:panel?.minSize,src:"setToMinSize"})},setToMaxSize(id){const panel=panels.find(panel2=>panel2.id===id);send({type:"SET_PANEL_SIZE",id,size:panel?.maxSize,src:"setToMaxSize"})},setSize(id,size){send({type:"SET_PANEL_SIZE",id,size})},rootProps:normalize.element({...parts.root.attrs,"data-orientation":state.context.orientation,id:dom.getRootId(state.context),dir:state.context.dir,style:{display:"flex",flexDirection:horizontal?"row":"column",height:"100%",width:"100%",overflow:"hidden"}}),getPanelProps(props2){const{id}=props2;return normalize.element({...parts.panel.attrs,"data-orientation":state.context.orientation,dir:state.context.dir,id:dom.getPanelId(state.context,id),"data-ownedby":dom.getRootId(state.context),style:dom.getPanelStyle(state.context,id)})},getResizeTriggerProps(props2){const{id,disabled,step=1}=props2;const triggerState=getResizeTriggerState(props2);return normalize.element({...parts.resizeTrigger.attrs,dir:state.context.dir,id:dom.getResizeTriggerId(state.context,id),role:"separator","data-ownedby":dom.getRootId(state.context),tabIndex:disabled?void 0:0,"aria-valuenow":triggerState.value,"aria-valuemin":triggerState.min,"aria-valuemax":triggerState.max,"data-orientation":state.context.orientation,"aria-orientation":state.context.orientation,"aria-controls":triggerState.panelIds.join(" "),"data-focus":dataAttr(triggerState.focused),"data-disabled":dataAttr(disabled),style:{touchAction:"none",userSelect:"none",flex:"0 0 auto",pointerEvents:dragging&&!triggerState.focused?"none":void 0,cursor:horizontal?"col-resize":"row-resize",[horizontal?"minHeight":"minWidth"]:"0"},onPointerDown(event){if(disabled){event.preventDefault();return}send({type:"POINTER_DOWN",id});event.currentTarget.setPointerCapture(event.pointerId);event.preventDefault();event.stopPropagation()},onPointerUp(event){if(disabled)return;if(event.currentTarget.hasPointerCapture(event.pointerId)){event.currentTarget.releasePointerCapture(event.pointerId)}},onPointerOver(){if(disabled)return;send({type:"POINTER_OVER",id})},onPointerLeave(){if(disabled)return;send({type:"POINTER_LEAVE",id})},onBlur(){send("BLUR")},onFocus(){send({type:"FOCUS",id})},onDoubleClick(){if(disabled)return;send({type:"DOUBLE_CLICK",id})},onKeyDown(event){if(event.defaultPrevented)return;if(disabled)return;const moveStep=getEventStep(event)*step;const keyMap={Enter(){send("ENTER")},ArrowUp(){send({type:"ARROW_UP",step:moveStep})},ArrowDown(){send({type:"ARROW_DOWN",step:moveStep})},ArrowLeft(){send({type:"ARROW_LEFT",step:moveStep})},ArrowRight(){send({type:"ARROW_RIGHT",step:moveStep})},Home(){send("HOME")},End(){send("END")}};const key=getEventKey(event,state.context);const exec=keyMap[key];if(exec){exec(event);event.preventDefault()}}})}}}import{createMachine}from"@zag-js/core";import{getRelativePoint,trackPointerMove}from"@zag-js/dom-event";import{raf}from"@zag-js/dom-query";import{compact}from"@zag-js/utils";function machine(userContext){const ctx=compact(userContext);return createMachine({id:"splitter",initial:"idle",context:{orientation:"horizontal",activeResizeId:null,previousPanels:[],size:[],initialSize:[],activeResizeState:{isAtMin:false,isAtMax:false},...ctx},created:["setPreviousPanels","setInitialSize"],watch:{size:["setActiveResizeState"]},computed:{isHorizontal:ctx2=>ctx2.orientation==="horizontal",panels:ctx2=>getNormalizedPanels(ctx2)},on:{SET_PANEL_SIZE:{actions:"setPanelSize"}},states:{idle:{entry:["clearActiveHandleId"],on:{POINTER_OVER:{target:"hover:temp",actions:["setActiveHandleId"]},FOCUS:{target:"focused",actions:["setActiveHandleId"]},DOUBLE_CLICK:{actions:["resetStartPanel","setPreviousPanels"]}}},"hover:temp":{after:{HOVER_DELAY:"hover"},on:{POINTER_DOWN:{target:"dragging",actions:["setActiveHandleId"]},POINTER_LEAVE:"idle"}},hover:{tags:["focus"],on:{POINTER_DOWN:"dragging",POINTER_LEAVE:"idle"}},focused:{tags:["focus"],on:{BLUR:"idle",POINTER_DOWN:{target:"dragging",actions:["setActiveHandleId"]},ARROW_LEFT:{guard:"isHorizontal",actions:["shrinkStartPanel","setPreviousPanels"]},ARROW_RIGHT:{guard:"isHorizontal",actions:["expandStartPanel","setPreviousPanels"]},ARROW_UP:{guard:"isVertical",actions:["shrinkStartPanel","setPreviousPanels"]},ARROW_DOWN:{guard:"isVertical",actions:["expandStartPanel","setPreviousPanels"]},ENTER:[{guard:"isStartPanelAtMax",actions:["setStartPanelToMin","setPreviousPanels"]},{actions:["setStartPanelToMax","setPreviousPanels"]}],HOME:{actions:["setStartPanelToMin","setPreviousPanels"]},END:{actions:["setStartPanelToMax","setPreviousPanels"]}}},dragging:{tags:["focus"],entry:"focusResizeHandle",activities:["trackPointerMove"],on:{POINTER_MOVE:{actions:["setPointerValue","setGlobalCursor","invokeOnResize"]},POINTER_UP:{target:"focused",actions:["setPreviousPanels","clearGlobalCursor","blurResizeHandle","invokeOnResizeEnd"]}}}}},{activities:{trackPointerMove:(ctx2,_evt,{send})=>{const doc=dom.getDoc(ctx2);return trackPointerMove(doc,{onPointerMove(info){send({type:"POINTER_MOVE",point:info.point})},onPointerUp(){send("POINTER_UP")}})}},guards:{isStartPanelAtMin:ctx2=>ctx2.activeResizeState.isAtMin,isStartPanelAtMax:ctx2=>ctx2.activeResizeState.isAtMax,isHorizontal:ctx2=>ctx2.isHorizontal,isVertical:ctx2=>!ctx2.isHorizontal},delays:{HOVER_DELAY:250},actions:{setGlobalCursor(ctx2){dom.setupGlobalCursor(ctx2)},clearGlobalCursor(ctx2){dom.removeGlobalCursor(ctx2)},invokeOnResize(ctx2){ctx2.onSizeChange?.({size:Array.from(ctx2.size),activeHandleId:ctx2.activeResizeId})},invokeOnResizeEnd(ctx2){ctx2.onSizeChangeEnd?.({size:Array.from(ctx2.size),activeHandleId:ctx2.activeResizeId})},setActiveHandleId(ctx2,evt){ctx2.activeResizeId=evt.id},clearActiveHandleId(ctx2){ctx2.activeResizeId=null},setInitialSize(ctx2){ctx2.initialSize=ctx2.panels.slice().map(panel=>({id:panel.id,size:panel.size}))},setPanelSize(ctx2,evt){const{id,size}=evt;ctx2.size=ctx2.size.map(panel=>{const panelSize=clamp(size,panel.minSize??0,panel.maxSize??100);return panel.id===id?{...panel,size:panelSize}:panel})},setStartPanelToMin(ctx2){const bounds=getPanelBounds(ctx2);if(!bounds)return;const{before,after}=bounds;ctx2.size[before.index].size=before.min;ctx2.size[after.index].size=after.min},setStartPanelToMax(ctx2){const bounds=getPanelBounds(ctx2);if(!bounds)return;const{before,after}=bounds;ctx2.size[before.index].size=before.max;ctx2.size[after.index].size=after.max},expandStartPanel(ctx2,evt){const bounds=getPanelBounds(ctx2);if(!bounds)return;const{before,after}=bounds;ctx2.size[before.index].size=before.up(evt.step);ctx2.size[after.index].size=after.down(evt.step)},shrinkStartPanel(ctx2,evt){const bounds=getPanelBounds(ctx2);if(!bounds)return;const{before,after}=bounds;ctx2.size[before.index].size=before.down(evt.step);ctx2.size[after.index].size=after.up(evt.step)},resetStartPanel(ctx2,evt){const bounds=getPanelBounds(ctx2,evt.id);if(!bounds)return;const{before,after}=bounds;ctx2.size[before.index].size=ctx2.initialSize[before.index].size;ctx2.size[after.index].size=ctx2.initialSize[after.index].size},focusResizeHandle(ctx2){raf(()=>{dom.getActiveHandleEl(ctx2)?.focus({preventScroll:true})})},blurResizeHandle(ctx2){raf(()=>{dom.getActiveHandleEl(ctx2)?.blur()})},setPreviousPanels(ctx2){ctx2.previousPanels=ctx2.panels.slice()},setActiveResizeState(ctx2){const panels=getPanelBounds(ctx2);if(!panels)return;const{before}=panels;ctx2.activeResizeState={isAtMin:before.isAtMin,isAtMax:before.isAtMax}},setPointerValue(ctx2,evt){const panels=getHandlePanels(ctx2);const bounds=getHandleBounds(ctx2);if(!panels||!bounds)return;const rootEl=dom.getRootEl(ctx2);if(!rootEl)return;const relativePoint=getRelativePoint(evt.point,rootEl);const percentValue=relativePoint.getPercentValue({dir:ctx2.dir,orientation:ctx2.orientation});let pointValue=percentValue*100;ctx2.activeResizeState={isAtMin:pointValue<bounds.min,isAtMax:pointValue>bounds.max};pointValue=clamp(pointValue,bounds.min,bounds.max);const{before,after}=panels;const offset=pointValue-before.end;ctx2.size[before.index].size=before.size+offset;ctx2.size[after.index].size=after.size-offset}}})}import{createProps}from"@zag-js/types";import{createSplitProps}from"@zag-js/utils";var props=createProps()(["dir","getRootNode","id","ids","onSizeChange","onSizeChangeEnd","orientation","size"]);var splitProps=createSplitProps(props);var panelProps=createProps()(["id","snapSize"]);var splitPanelProps=createSplitProps(panelProps);var resizeTriggerProps=createProps()(["disabled","id","step"]);var splitResizeTriggerProps=createSplitProps(resizeTriggerProps);export{anatomy,connect,machine,panelProps,props,resizeTriggerProps,splitPanelProps,splitProps,splitResizeTriggerProps};
1
+ // src/splitter.anatomy.ts
2
+ import { createAnatomy } from "@zag-js/anatomy";
3
+ var anatomy = createAnatomy("splitter").parts("root", "panel", "resizeTrigger");
4
+ var parts = anatomy.build();
5
+
6
+ // src/splitter.connect.ts
7
+ import { getEventKey, getEventStep } from "@zag-js/dom-event";
8
+ import { dataAttr } from "@zag-js/dom-query";
9
+
10
+ // src/splitter.dom.ts
11
+ import { createScope, queryAll } from "@zag-js/dom-query";
12
+ var dom = createScope({
13
+ getRootId: (ctx) => ctx.ids?.root ?? `splitter:${ctx.id}`,
14
+ getResizeTriggerId: (ctx, id) => ctx.ids?.resizeTrigger?.(id) ?? `splitter:${ctx.id}:splitter:${id}`,
15
+ getLabelId: (ctx) => ctx.ids?.label ?? `splitter:${ctx.id}:label`,
16
+ getPanelId: (ctx, id) => ctx.ids?.panel?.(id) ?? `splitter:${ctx.id}:panel:${id}`,
17
+ globalCursorId: (ctx) => `splitter:${ctx.id}:global-cursor`,
18
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
19
+ getResizeTriggerEl: (ctx, id) => dom.getById(ctx, dom.getResizeTriggerId(ctx, id)),
20
+ getPanelEl: (ctx, id) => dom.getById(ctx, dom.getPanelId(ctx, id)),
21
+ getCursor(ctx) {
22
+ const x = ctx.isHorizontal;
23
+ let cursor = x ? "col-resize" : "row-resize";
24
+ if (ctx.activeResizeState.isAtMin)
25
+ cursor = x ? "e-resize" : "s-resize";
26
+ if (ctx.activeResizeState.isAtMax)
27
+ cursor = x ? "w-resize" : "n-resize";
28
+ return cursor;
29
+ },
30
+ getPanelStyle(ctx, id) {
31
+ const flexGrow = ctx.panels.find((panel) => panel.id === id)?.size ?? "0";
32
+ return {
33
+ flexBasis: 0,
34
+ flexGrow,
35
+ flexShrink: 1,
36
+ overflow: "hidden"
37
+ };
38
+ },
39
+ getActiveHandleEl(ctx) {
40
+ const activeId = ctx.activeResizeId;
41
+ if (activeId == null)
42
+ return;
43
+ return dom.getById(ctx, dom.getResizeTriggerId(ctx, activeId));
44
+ },
45
+ getResizeTriggerEls(ctx) {
46
+ const ownerId = CSS.escape(dom.getRootId(ctx));
47
+ return queryAll(dom.getRootEl(ctx), `[role=separator][data-ownedby='${ownerId}']`);
48
+ },
49
+ setupGlobalCursor(ctx) {
50
+ const styleEl = dom.getById(ctx, dom.globalCursorId(ctx));
51
+ const textContent = `* { cursor: ${dom.getCursor(ctx)} !important; }`;
52
+ if (styleEl) {
53
+ styleEl.textContent = textContent;
54
+ } else {
55
+ const style = dom.getDoc(ctx).createElement("style");
56
+ style.id = dom.globalCursorId(ctx);
57
+ style.textContent = textContent;
58
+ dom.getDoc(ctx).head.appendChild(style);
59
+ }
60
+ },
61
+ removeGlobalCursor(ctx) {
62
+ dom.getById(ctx, dom.globalCursorId(ctx))?.remove();
63
+ }
64
+ });
65
+
66
+ // src/splitter.utils.ts
67
+ function validateSize(key, size) {
68
+ if (Math.floor(size) > 100) {
69
+ throw new Error(`Total ${key} of panels cannot be greater than 100`);
70
+ }
71
+ }
72
+ function getNormalizedPanels(ctx) {
73
+ let numOfPanelsWithoutSize = 0;
74
+ let totalSize = 0;
75
+ let totalMinSize = 0;
76
+ const panels = ctx.size.map((panel) => {
77
+ const minSize = panel.minSize ?? 0;
78
+ const maxSize = panel.maxSize ?? 100;
79
+ totalMinSize += minSize;
80
+ if (panel.size == null) {
81
+ numOfPanelsWithoutSize++;
82
+ } else {
83
+ totalSize += panel.size;
84
+ }
85
+ return {
86
+ ...panel,
87
+ minSize,
88
+ maxSize
89
+ };
90
+ });
91
+ validateSize("minSize", totalMinSize);
92
+ validateSize("size", totalSize);
93
+ let end = 0;
94
+ let remainingSize = 0;
95
+ const result = panels.map((panel) => {
96
+ let start = end;
97
+ if (panel.size != null) {
98
+ end += panel.size;
99
+ remainingSize = panel.size - panel.minSize;
100
+ return {
101
+ ...panel,
102
+ start,
103
+ end,
104
+ remainingSize
105
+ };
106
+ }
107
+ const size = (100 - totalSize) / numOfPanelsWithoutSize;
108
+ end += size;
109
+ remainingSize = size - panel.minSize;
110
+ return { ...panel, size, start, end, remainingSize };
111
+ });
112
+ return result;
113
+ }
114
+ function getHandlePanels(ctx, id = ctx.activeResizeId) {
115
+ const [beforeId, afterId] = id?.split(":") ?? [];
116
+ if (!beforeId || !afterId)
117
+ return;
118
+ const beforeIndex = ctx.previousPanels.findIndex((panel) => panel.id === beforeId);
119
+ const afterIndex = ctx.previousPanels.findIndex((panel) => panel.id === afterId);
120
+ if (beforeIndex === -1 || afterIndex === -1)
121
+ return;
122
+ const before = ctx.previousPanels[beforeIndex];
123
+ const after = ctx.previousPanels[afterIndex];
124
+ return {
125
+ before: {
126
+ ...before,
127
+ index: beforeIndex
128
+ },
129
+ after: {
130
+ ...after,
131
+ index: afterIndex
132
+ }
133
+ };
134
+ }
135
+ function getHandleBounds(ctx, id = ctx.activeResizeId) {
136
+ const panels = getHandlePanels(ctx, id);
137
+ if (!panels)
138
+ return;
139
+ const { before, after } = panels;
140
+ return {
141
+ min: Math.max(before.start + before.minSize, after.end - after.maxSize),
142
+ max: Math.min(after.end - after.minSize, before.maxSize + before.start)
143
+ };
144
+ }
145
+ function getPanelBounds(ctx, id) {
146
+ const bounds = getHandleBounds(ctx, id);
147
+ const panels = getHandlePanels(ctx, id);
148
+ if (!bounds || !panels)
149
+ return;
150
+ const { before, after } = panels;
151
+ const beforeMin = Math.abs(before.start - bounds.min);
152
+ const afterMin = after.size + (before.size - beforeMin);
153
+ const beforeMax = Math.abs(before.start - bounds.max);
154
+ const afterMax = after.size - (beforeMax - before.size);
155
+ return {
156
+ before: {
157
+ index: before.index,
158
+ min: beforeMin,
159
+ max: beforeMax,
160
+ isAtMin: beforeMin === before.size,
161
+ isAtMax: beforeMax === before.size,
162
+ up(step) {
163
+ return Math.min(before.size + step, beforeMax);
164
+ },
165
+ down(step) {
166
+ return Math.max(before.size - step, beforeMin);
167
+ }
168
+ },
169
+ after: {
170
+ index: after.index,
171
+ min: afterMin,
172
+ max: afterMax,
173
+ isAtMin: afterMin === after.size,
174
+ isAtMax: afterMax === after.size,
175
+ up(step) {
176
+ return Math.min(after.size + step, afterMin);
177
+ },
178
+ down(step) {
179
+ return Math.max(after.size - step, afterMax);
180
+ }
181
+ }
182
+ };
183
+ }
184
+ function clamp(value, min, max) {
185
+ return Math.min(Math.max(value, min), max);
186
+ }
187
+
188
+ // src/splitter.connect.ts
189
+ function connect(state, send, normalize) {
190
+ const horizontal = state.context.isHorizontal;
191
+ const focused = state.hasTag("focus");
192
+ const dragging = state.matches("dragging");
193
+ const panels = state.context.panels;
194
+ function getResizeTriggerState(props2) {
195
+ const { id, disabled } = props2;
196
+ const ids = id.split(":");
197
+ const panelIds = ids.map((id2) => dom.getPanelId(state.context, id2));
198
+ const panels2 = getHandleBounds(state.context, id);
199
+ return {
200
+ disabled: !!disabled,
201
+ focused: state.context.activeResizeId === id && focused,
202
+ panelIds,
203
+ min: panels2?.min,
204
+ max: panels2?.max,
205
+ value: 0
206
+ };
207
+ }
208
+ return {
209
+ focused,
210
+ dragging,
211
+ getResizeTriggerState,
212
+ bounds: getHandleBounds(state.context),
213
+ setToMinSize(id) {
214
+ const panel = panels.find((panel2) => panel2.id === id);
215
+ send({ type: "SET_PANEL_SIZE", id, size: panel?.minSize, src: "setToMinSize" });
216
+ },
217
+ setToMaxSize(id) {
218
+ const panel = panels.find((panel2) => panel2.id === id);
219
+ send({ type: "SET_PANEL_SIZE", id, size: panel?.maxSize, src: "setToMaxSize" });
220
+ },
221
+ setSize(id, size) {
222
+ send({ type: "SET_PANEL_SIZE", id, size });
223
+ },
224
+ getRootProps() {
225
+ return normalize.element({
226
+ ...parts.root.attrs,
227
+ "data-orientation": state.context.orientation,
228
+ id: dom.getRootId(state.context),
229
+ dir: state.context.dir,
230
+ style: {
231
+ display: "flex",
232
+ flexDirection: horizontal ? "row" : "column",
233
+ height: "100%",
234
+ width: "100%",
235
+ overflow: "hidden"
236
+ }
237
+ });
238
+ },
239
+ getPanelProps(props2) {
240
+ const { id } = props2;
241
+ return normalize.element({
242
+ ...parts.panel.attrs,
243
+ "data-orientation": state.context.orientation,
244
+ dir: state.context.dir,
245
+ id: dom.getPanelId(state.context, id),
246
+ "data-ownedby": dom.getRootId(state.context),
247
+ style: dom.getPanelStyle(state.context, id)
248
+ });
249
+ },
250
+ getResizeTriggerProps(props2) {
251
+ const { id, disabled, step = 1 } = props2;
252
+ const triggerState = getResizeTriggerState(props2);
253
+ return normalize.element({
254
+ ...parts.resizeTrigger.attrs,
255
+ dir: state.context.dir,
256
+ id: dom.getResizeTriggerId(state.context, id),
257
+ role: "separator",
258
+ "data-ownedby": dom.getRootId(state.context),
259
+ tabIndex: disabled ? void 0 : 0,
260
+ "aria-valuenow": triggerState.value,
261
+ "aria-valuemin": triggerState.min,
262
+ "aria-valuemax": triggerState.max,
263
+ "data-orientation": state.context.orientation,
264
+ "aria-orientation": state.context.orientation,
265
+ "aria-controls": triggerState.panelIds.join(" "),
266
+ "data-focus": dataAttr(triggerState.focused),
267
+ "data-disabled": dataAttr(disabled),
268
+ style: {
269
+ touchAction: "none",
270
+ userSelect: "none",
271
+ flex: "0 0 auto",
272
+ pointerEvents: dragging && !triggerState.focused ? "none" : void 0,
273
+ cursor: horizontal ? "col-resize" : "row-resize",
274
+ [horizontal ? "minHeight" : "minWidth"]: "0"
275
+ },
276
+ onPointerDown(event) {
277
+ if (disabled) {
278
+ event.preventDefault();
279
+ return;
280
+ }
281
+ send({ type: "POINTER_DOWN", id });
282
+ event.currentTarget.setPointerCapture(event.pointerId);
283
+ event.preventDefault();
284
+ event.stopPropagation();
285
+ },
286
+ onPointerUp(event) {
287
+ if (disabled)
288
+ return;
289
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) {
290
+ event.currentTarget.releasePointerCapture(event.pointerId);
291
+ }
292
+ },
293
+ onPointerOver() {
294
+ if (disabled)
295
+ return;
296
+ send({ type: "POINTER_OVER", id });
297
+ },
298
+ onPointerLeave() {
299
+ if (disabled)
300
+ return;
301
+ send({ type: "POINTER_LEAVE", id });
302
+ },
303
+ onBlur() {
304
+ send("BLUR");
305
+ },
306
+ onFocus() {
307
+ send({ type: "FOCUS", id });
308
+ },
309
+ onDoubleClick() {
310
+ if (disabled)
311
+ return;
312
+ send({ type: "DOUBLE_CLICK", id });
313
+ },
314
+ onKeyDown(event) {
315
+ if (event.defaultPrevented)
316
+ return;
317
+ if (disabled)
318
+ return;
319
+ const moveStep = getEventStep(event) * step;
320
+ const keyMap = {
321
+ Enter() {
322
+ send("ENTER");
323
+ },
324
+ ArrowUp() {
325
+ send({ type: "ARROW_UP", step: moveStep });
326
+ },
327
+ ArrowDown() {
328
+ send({ type: "ARROW_DOWN", step: moveStep });
329
+ },
330
+ ArrowLeft() {
331
+ send({ type: "ARROW_LEFT", step: moveStep });
332
+ },
333
+ ArrowRight() {
334
+ send({ type: "ARROW_RIGHT", step: moveStep });
335
+ },
336
+ Home() {
337
+ send("HOME");
338
+ },
339
+ End() {
340
+ send("END");
341
+ }
342
+ };
343
+ const key = getEventKey(event, state.context);
344
+ const exec = keyMap[key];
345
+ if (exec) {
346
+ exec(event);
347
+ event.preventDefault();
348
+ }
349
+ }
350
+ });
351
+ }
352
+ };
353
+ }
354
+
355
+ // src/splitter.machine.ts
356
+ import { createMachine } from "@zag-js/core";
357
+ import { getRelativePoint, trackPointerMove } from "@zag-js/dom-event";
358
+ import { raf } from "@zag-js/dom-query";
359
+ import { compact } from "@zag-js/utils";
360
+ function machine(userContext) {
361
+ const ctx = compact(userContext);
362
+ return createMachine(
363
+ {
364
+ id: "splitter",
365
+ initial: "idle",
366
+ context: {
367
+ orientation: "horizontal",
368
+ activeResizeId: null,
369
+ previousPanels: [],
370
+ size: [],
371
+ initialSize: [],
372
+ activeResizeState: {
373
+ isAtMin: false,
374
+ isAtMax: false
375
+ },
376
+ ...ctx
377
+ },
378
+ created: ["setPreviousPanels", "setInitialSize"],
379
+ watch: {
380
+ size: ["setActiveResizeState"]
381
+ },
382
+ computed: {
383
+ isHorizontal: (ctx2) => ctx2.orientation === "horizontal",
384
+ panels: (ctx2) => getNormalizedPanels(ctx2)
385
+ },
386
+ on: {
387
+ SET_PANEL_SIZE: {
388
+ actions: "setPanelSize"
389
+ }
390
+ },
391
+ states: {
392
+ idle: {
393
+ entry: ["clearActiveHandleId"],
394
+ on: {
395
+ POINTER_OVER: {
396
+ target: "hover:temp",
397
+ actions: ["setActiveHandleId"]
398
+ },
399
+ FOCUS: {
400
+ target: "focused",
401
+ actions: ["setActiveHandleId"]
402
+ },
403
+ DOUBLE_CLICK: {
404
+ actions: ["resetStartPanel", "setPreviousPanels"]
405
+ }
406
+ }
407
+ },
408
+ "hover:temp": {
409
+ after: {
410
+ HOVER_DELAY: "hover"
411
+ },
412
+ on: {
413
+ POINTER_DOWN: {
414
+ target: "dragging",
415
+ actions: ["setActiveHandleId"]
416
+ },
417
+ POINTER_LEAVE: "idle"
418
+ }
419
+ },
420
+ hover: {
421
+ tags: ["focus"],
422
+ on: {
423
+ POINTER_DOWN: "dragging",
424
+ POINTER_LEAVE: "idle"
425
+ }
426
+ },
427
+ focused: {
428
+ tags: ["focus"],
429
+ on: {
430
+ BLUR: "idle",
431
+ POINTER_DOWN: {
432
+ target: "dragging",
433
+ actions: ["setActiveHandleId"]
434
+ },
435
+ ARROW_LEFT: {
436
+ guard: "isHorizontal",
437
+ actions: ["shrinkStartPanel", "setPreviousPanels"]
438
+ },
439
+ ARROW_RIGHT: {
440
+ guard: "isHorizontal",
441
+ actions: ["expandStartPanel", "setPreviousPanels"]
442
+ },
443
+ ARROW_UP: {
444
+ guard: "isVertical",
445
+ actions: ["shrinkStartPanel", "setPreviousPanels"]
446
+ },
447
+ ARROW_DOWN: {
448
+ guard: "isVertical",
449
+ actions: ["expandStartPanel", "setPreviousPanels"]
450
+ },
451
+ ENTER: [
452
+ {
453
+ guard: "isStartPanelAtMax",
454
+ actions: ["setStartPanelToMin", "setPreviousPanels"]
455
+ },
456
+ { actions: ["setStartPanelToMax", "setPreviousPanels"] }
457
+ ],
458
+ HOME: {
459
+ actions: ["setStartPanelToMin", "setPreviousPanels"]
460
+ },
461
+ END: {
462
+ actions: ["setStartPanelToMax", "setPreviousPanels"]
463
+ }
464
+ }
465
+ },
466
+ dragging: {
467
+ tags: ["focus"],
468
+ entry: "focusResizeHandle",
469
+ activities: ["trackPointerMove"],
470
+ on: {
471
+ POINTER_MOVE: {
472
+ actions: ["setPointerValue", "setGlobalCursor", "invokeOnResize"]
473
+ },
474
+ POINTER_UP: {
475
+ target: "focused",
476
+ actions: ["setPreviousPanels", "clearGlobalCursor", "blurResizeHandle", "invokeOnResizeEnd"]
477
+ }
478
+ }
479
+ }
480
+ }
481
+ },
482
+ {
483
+ activities: {
484
+ trackPointerMove: (ctx2, _evt, { send }) => {
485
+ const doc = dom.getDoc(ctx2);
486
+ return trackPointerMove(doc, {
487
+ onPointerMove(info) {
488
+ send({ type: "POINTER_MOVE", point: info.point });
489
+ },
490
+ onPointerUp() {
491
+ send("POINTER_UP");
492
+ }
493
+ });
494
+ }
495
+ },
496
+ guards: {
497
+ isStartPanelAtMin: (ctx2) => ctx2.activeResizeState.isAtMin,
498
+ isStartPanelAtMax: (ctx2) => ctx2.activeResizeState.isAtMax,
499
+ isHorizontal: (ctx2) => ctx2.isHorizontal,
500
+ isVertical: (ctx2) => !ctx2.isHorizontal
501
+ },
502
+ delays: {
503
+ HOVER_DELAY: 250
504
+ },
505
+ actions: {
506
+ setGlobalCursor(ctx2) {
507
+ dom.setupGlobalCursor(ctx2);
508
+ },
509
+ clearGlobalCursor(ctx2) {
510
+ dom.removeGlobalCursor(ctx2);
511
+ },
512
+ invokeOnResize(ctx2) {
513
+ ctx2.onSizeChange?.({ size: Array.from(ctx2.size), activeHandleId: ctx2.activeResizeId });
514
+ },
515
+ invokeOnResizeEnd(ctx2) {
516
+ ctx2.onSizeChangeEnd?.({ size: Array.from(ctx2.size), activeHandleId: ctx2.activeResizeId });
517
+ },
518
+ setActiveHandleId(ctx2, evt) {
519
+ ctx2.activeResizeId = evt.id;
520
+ },
521
+ clearActiveHandleId(ctx2) {
522
+ ctx2.activeResizeId = null;
523
+ },
524
+ setInitialSize(ctx2) {
525
+ ctx2.initialSize = ctx2.panels.slice().map((panel) => ({
526
+ id: panel.id,
527
+ size: panel.size
528
+ }));
529
+ },
530
+ setPanelSize(ctx2, evt) {
531
+ const { id, size } = evt;
532
+ ctx2.size = ctx2.size.map((panel) => {
533
+ const panelSize = clamp(size, panel.minSize ?? 0, panel.maxSize ?? 100);
534
+ return panel.id === id ? { ...panel, size: panelSize } : panel;
535
+ });
536
+ },
537
+ setStartPanelToMin(ctx2) {
538
+ const bounds = getPanelBounds(ctx2);
539
+ if (!bounds)
540
+ return;
541
+ const { before, after } = bounds;
542
+ ctx2.size[before.index].size = before.min;
543
+ ctx2.size[after.index].size = after.min;
544
+ },
545
+ setStartPanelToMax(ctx2) {
546
+ const bounds = getPanelBounds(ctx2);
547
+ if (!bounds)
548
+ return;
549
+ const { before, after } = bounds;
550
+ ctx2.size[before.index].size = before.max;
551
+ ctx2.size[after.index].size = after.max;
552
+ },
553
+ expandStartPanel(ctx2, evt) {
554
+ const bounds = getPanelBounds(ctx2);
555
+ if (!bounds)
556
+ return;
557
+ const { before, after } = bounds;
558
+ ctx2.size[before.index].size = before.up(evt.step);
559
+ ctx2.size[after.index].size = after.down(evt.step);
560
+ },
561
+ shrinkStartPanel(ctx2, evt) {
562
+ const bounds = getPanelBounds(ctx2);
563
+ if (!bounds)
564
+ return;
565
+ const { before, after } = bounds;
566
+ ctx2.size[before.index].size = before.down(evt.step);
567
+ ctx2.size[after.index].size = after.up(evt.step);
568
+ },
569
+ resetStartPanel(ctx2, evt) {
570
+ const bounds = getPanelBounds(ctx2, evt.id);
571
+ if (!bounds)
572
+ return;
573
+ const { before, after } = bounds;
574
+ ctx2.size[before.index].size = ctx2.initialSize[before.index].size;
575
+ ctx2.size[after.index].size = ctx2.initialSize[after.index].size;
576
+ },
577
+ focusResizeHandle(ctx2) {
578
+ raf(() => {
579
+ dom.getActiveHandleEl(ctx2)?.focus({ preventScroll: true });
580
+ });
581
+ },
582
+ blurResizeHandle(ctx2) {
583
+ raf(() => {
584
+ dom.getActiveHandleEl(ctx2)?.blur();
585
+ });
586
+ },
587
+ setPreviousPanels(ctx2) {
588
+ ctx2.previousPanels = ctx2.panels.slice();
589
+ },
590
+ setActiveResizeState(ctx2) {
591
+ const panels = getPanelBounds(ctx2);
592
+ if (!panels)
593
+ return;
594
+ const { before } = panels;
595
+ ctx2.activeResizeState = {
596
+ isAtMin: before.isAtMin,
597
+ isAtMax: before.isAtMax
598
+ };
599
+ },
600
+ setPointerValue(ctx2, evt) {
601
+ const panels = getHandlePanels(ctx2);
602
+ const bounds = getHandleBounds(ctx2);
603
+ if (!panels || !bounds)
604
+ return;
605
+ const rootEl = dom.getRootEl(ctx2);
606
+ if (!rootEl)
607
+ return;
608
+ const relativePoint = getRelativePoint(evt.point, rootEl);
609
+ const percentValue = relativePoint.getPercentValue({
610
+ dir: ctx2.dir,
611
+ orientation: ctx2.orientation
612
+ });
613
+ let pointValue = percentValue * 100;
614
+ ctx2.activeResizeState = {
615
+ isAtMin: pointValue < bounds.min,
616
+ isAtMax: pointValue > bounds.max
617
+ };
618
+ pointValue = clamp(pointValue, bounds.min, bounds.max);
619
+ const { before, after } = panels;
620
+ const offset = pointValue - before.end;
621
+ ctx2.size[before.index].size = before.size + offset;
622
+ ctx2.size[after.index].size = after.size - offset;
623
+ }
624
+ }
625
+ }
626
+ );
627
+ }
628
+
629
+ // src/splitter.props.ts
630
+ import { createProps } from "@zag-js/types";
631
+ import { createSplitProps } from "@zag-js/utils";
632
+ var props = createProps()([
633
+ "dir",
634
+ "getRootNode",
635
+ "id",
636
+ "ids",
637
+ "onSizeChange",
638
+ "onSizeChangeEnd",
639
+ "orientation",
640
+ "size"
641
+ ]);
642
+ var splitProps = createSplitProps(props);
643
+ var panelProps = createProps()(["id", "snapSize"]);
644
+ var splitPanelProps = createSplitProps(panelProps);
645
+ var resizeTriggerProps = createProps()(["disabled", "id", "step"]);
646
+ var splitResizeTriggerProps = createSplitProps(resizeTriggerProps);
647
+ export {
648
+ anatomy,
649
+ connect,
650
+ machine,
651
+ panelProps,
652
+ props,
653
+ resizeTriggerProps,
654
+ splitPanelProps,
655
+ splitProps,
656
+ splitResizeTriggerProps
657
+ };
2
658
  //# sourceMappingURL=index.mjs.map