All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.dist.index.js Maven / Gradle / Ivy

The newest version!
'use strict';

var anatomy$1 = require('@zag-js/anatomy');
var domEvent = require('@zag-js/dom-event');
var domQuery = require('@zag-js/dom-query');
var core = require('@zag-js/core');
var utils = require('@zag-js/utils');
var types = require('@zag-js/types');

// src/splitter.anatomy.ts
var anatomy = anatomy$1.createAnatomy("splitter").parts("root", "panel", "resizeTrigger");
var parts = anatomy.build();
var dom = domQuery.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}`,
  getGlobalCursorId: (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 domQuery.queryAll(dom.getRootEl(ctx), `[role=separator][data-ownedby='${ownerId}']`);
  },
  setupGlobalCursor(ctx) {
    const styleEl = dom.getById(ctx, dom.getGlobalCursorId(ctx));
    const textContent = `* { cursor: ${dom.getCursor(ctx)} !important; }`;
    if (styleEl) {
      styleEl.textContent = textContent;
    } else {
      const style = dom.getDoc(ctx).createElement("style");
      style.id = dom.getGlobalCursorId(ctx);
      style.textContent = textContent;
      dom.getDoc(ctx).head.appendChild(style);
    }
  },
  removeGlobalCursor(ctx) {
    dom.getById(ctx, dom.getGlobalCursorId(ctx))?.remove();
  }
});

// src/splitter.utils.ts
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);
}

// src/splitter.connect.ts
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 });
    },
    getRootProps() {
      return 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": domQuery.dataAttr(triggerState.focused),
        "data-disabled": domQuery.dataAttr(disabled),
        style: {
          touchAction: "none",
          userSelect: "none",
          WebkitUserSelect: "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 = domEvent.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 = domEvent.getEventKey(event, state.context);
          const exec = keyMap[key];
          if (exec) {
            exec(event);
            event.preventDefault();
          }
        }
      });
    }
  };
}
function machine(userContext) {
  const ctx = utils.compact(userContext);
  return core.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 domEvent.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) {
          domQuery.raf(() => {
            dom.getActiveHandleEl(ctx2)?.focus({ preventScroll: true });
          });
        },
        blurResizeHandle(ctx2) {
          domQuery.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 = domEvent.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;
        }
      }
    }
  );
}
var props = types.createProps()([
  "dir",
  "getRootNode",
  "id",
  "ids",
  "onSizeChange",
  "onSizeChangeEnd",
  "orientation",
  "size"
]);
var splitProps = utils.createSplitProps(props);
var panelProps = types.createProps()(["id", "snapSize"]);
var splitPanelProps = utils.createSplitProps(panelProps);
var resizeTriggerProps = types.createProps()(["disabled", "id", "step"]);
var splitResizeTriggerProps = utils.createSplitProps(resizeTriggerProps);

exports.anatomy = anatomy;
exports.connect = connect;
exports.machine = machine;
exports.panelProps = panelProps;
exports.props = props;
exports.resizeTriggerProps = resizeTriggerProps;
exports.splitPanelProps = splitPanelProps;
exports.splitProps = splitProps;
exports.splitResizeTriggerProps = splitResizeTriggerProps;




© 2015 - 2025 Weber Informatics LLC | Privacy Policy