@ark-ui/solid
Version:
A collection of unstyled, accessible UI components for Solid, utilizing state machines for seamless interaction.
1,521 lines (1,516 loc) • 56.7 kB
JavaScript
import { createGuards, createMachine } from './PKUUD527.js';
import { usePresenceContext, splitPresenceProps, usePresence, PresenceProvider } from './7S3N5UQH.js';
import { createSplitProps as createSplitProps$1 } from './ZMHI4GDJ.js';
import { ark } from './EPLBB4QN.js';
import { useEnvironmentContext } from './YO2MCGXO.js';
import { useLocaleContext } from './OKZ64GSY.js';
import { createContext } from './TROPIN4C.js';
import { runIfFn } from './DT73WLR4.js';
import { __export } from './ESLJRKWD.js';
import { createComponent } from 'solid-js/web';
import { mergeProps, useMachine, normalizeProps } from '@zag-js/solid';
import { createAnatomy } from '@zag-js/anatomy';
import { raf, isHTMLElement, addDomEvent, trackPointerMove, dataAttr, isLeftClick, getEventTarget, isSelfTarget, getEventStep, getEventKey } from '@zag-js/dom-query';
import { invariant, match, pick, clampValue, ensureProps, createSplitProps, toPx } from '@zag-js/utils';
import { createProps } from '@zag-js/types';
import { createUniqueId, createMemo } from 'solid-js';
// src/components/floating-panel/use-floating-panel-context.ts
var [FloatingPanelProvider, useFloatingPanelContext] = createContext({
hookName: "useFloatingPanelContext",
providerName: "<FloatingPanelProvider />"
});
// src/components/floating-panel/floating-panel-body.tsx
var FloatingPanelBody = (props2) => {
const floatingPanel = useFloatingPanelContext();
const mergedProps = mergeProps(() => floatingPanel().getBodyProps(), props2);
return createComponent(ark.div, mergedProps);
};
var FloatingPanelCloseTrigger = (props2) => {
const floatingPanel = useFloatingPanelContext();
const mergedProps = mergeProps(() => floatingPanel().getCloseTriggerProps(), props2);
return createComponent(ark.button, mergedProps);
};
var FloatingPanelContent = (props2) => {
const floatingPanel = useFloatingPanelContext();
const presence = usePresenceContext();
const mergedProps = mergeProps(() => floatingPanel().getContentProps(), () => presence().presenceProps, props2);
if (presence().unmounted) {
return null;
}
return createComponent(ark.div, mergedProps);
};
// src/components/floating-panel/floating-panel-context.tsx
var FloatingPanelContext = (props2) => props2.children(useFloatingPanelContext());
var FloatingPanelDragTrigger = (props2) => {
const floatingPanel = useFloatingPanelContext();
const mergedProps = mergeProps(() => floatingPanel().getDragTriggerProps(), props2);
return createComponent(ark.div, mergedProps);
};
var FloatingPanelHeader = (props2) => {
const floatingPanel = useFloatingPanelContext();
const mergedProps = mergeProps(() => floatingPanel().getHeaderProps(), props2);
return createComponent(ark.div, mergedProps);
};
var FloatingPanelPositioner = (props2) => {
const floatingPanel = useFloatingPanelContext();
const mergedProps = mergeProps(() => floatingPanel().getPositionerProps(), props2);
const presence = usePresenceContext();
if (presence().unmounted) {
return null;
}
return createComponent(ark.div, mergedProps);
};
var FloatingPanelResizeTrigger = (props2) => {
const [resizeProps, localProps] = createSplitProps$1()(props2, ["axis"]);
const floatingPanel = useFloatingPanelContext();
const mergedProps = mergeProps(() => floatingPanel().getResizeTriggerProps(resizeProps), localProps);
return createComponent(ark.div, mergedProps);
};
var FloatingPanelStageTrigger = (props2) => {
const [stage, localProps] = createSplitProps$1()(props2, ["stage"]);
const floatingPanel = useFloatingPanelContext();
const mergedProps = mergeProps(() => floatingPanel().getStageTriggerProps(stage), localProps);
return createComponent(ark.button, mergedProps);
};
// ../../node_modules/@zag-js/rect-utils/dist/index.mjs
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var AffineTransform = class _AffineTransform {
constructor([m00, m01, m02, m10, m11, m12] = [0, 0, 0, 0, 0, 0]) {
__publicField(this, "m00");
__publicField(this, "m01");
__publicField(this, "m02");
__publicField(this, "m10");
__publicField(this, "m11");
__publicField(this, "m12");
__publicField(this, "rotate", (...args) => {
return this.prepend(_AffineTransform.rotate(...args));
});
__publicField(this, "scale", (...args) => {
return this.prepend(_AffineTransform.scale(...args));
});
__publicField(this, "translate", (...args) => {
return this.prepend(_AffineTransform.translate(...args));
});
this.m00 = m00;
this.m01 = m01;
this.m02 = m02;
this.m10 = m10;
this.m11 = m11;
this.m12 = m12;
}
applyTo(point) {
const { x, y } = point;
const { m00, m01, m02, m10, m11, m12 } = this;
return {
x: m00 * x + m01 * y + m02,
y: m10 * x + m11 * y + m12
};
}
prepend(other) {
return new _AffineTransform([
this.m00 * other.m00 + this.m01 * other.m10,
// m00
this.m00 * other.m01 + this.m01 * other.m11,
// m01
this.m00 * other.m02 + this.m01 * other.m12 + this.m02,
// m02
this.m10 * other.m00 + this.m11 * other.m10,
// m10
this.m10 * other.m01 + this.m11 * other.m11,
// m11
this.m10 * other.m02 + this.m11 * other.m12 + this.m12
// m12
]);
}
append(other) {
return new _AffineTransform([
other.m00 * this.m00 + other.m01 * this.m10,
// m00
other.m00 * this.m01 + other.m01 * this.m11,
// m01
other.m00 * this.m02 + other.m01 * this.m12 + other.m02,
// m02
other.m10 * this.m00 + other.m11 * this.m10,
// m10
other.m10 * this.m01 + other.m11 * this.m11,
// m11
other.m10 * this.m02 + other.m11 * this.m12 + other.m12
// m12
]);
}
get determinant() {
return this.m00 * this.m11 - this.m01 * this.m10;
}
get isInvertible() {
const det = this.determinant;
return isFinite(det) && isFinite(this.m02) && isFinite(this.m12) && det !== 0;
}
invert() {
const det = this.determinant;
return new _AffineTransform([
this.m11 / det,
// m00
-this.m01 / det,
// m01
(this.m01 * this.m12 - this.m11 * this.m02) / det,
// m02
-this.m10 / det,
// m10
this.m00 / det,
// m11
(this.m10 * this.m02 - this.m00 * this.m12) / det
// m12
]);
}
get array() {
return [this.m00, this.m01, this.m02, this.m10, this.m11, this.m12, 0, 0, 1];
}
get float32Array() {
return new Float32Array(this.array);
}
// Static
static get identity() {
return new _AffineTransform([1, 0, 0, 0, 1, 0]);
}
static rotate(theta, origin) {
const rotation = new _AffineTransform([Math.cos(theta), -Math.sin(theta), 0, Math.sin(theta), Math.cos(theta), 0]);
if (origin && (origin.x !== 0 || origin.y !== 0)) {
return _AffineTransform.multiply(
_AffineTransform.translate(origin.x, origin.y),
rotation,
_AffineTransform.translate(-origin.x, -origin.y)
);
}
return rotation;
}
static scale(sx, sy = sx, origin = { x: 0, y: 0 }) {
const scale = new _AffineTransform([sx, 0, 0, 0, sy, 0]);
if (origin.x !== 0 || origin.y !== 0) {
return _AffineTransform.multiply(
_AffineTransform.translate(origin.x, origin.y),
scale,
_AffineTransform.translate(-origin.x, -origin.y)
);
}
return scale;
}
static translate(tx, ty) {
return new _AffineTransform([1, 0, tx, 0, 1, ty]);
}
static multiply(...[first, ...rest]) {
if (!first) return _AffineTransform.identity;
return rest.reduce((result, item) => result.prepend(item), first);
}
get a() {
return this.m00;
}
get b() {
return this.m10;
}
get c() {
return this.m01;
}
get d() {
return this.m11;
}
get tx() {
return this.m02;
}
get ty() {
return this.m12;
}
get scaleComponents() {
return { x: this.a, y: this.d };
}
get translationComponents() {
return { x: this.tx, y: this.ty };
}
get skewComponents() {
return { x: this.c, y: this.b };
}
toString() {
return `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.tx}, ${this.ty})`;
}
};
var clamp = (value, min3, max2) => Math.min(Math.max(value, min3), max2);
var clampPoint = (position, size, boundaryRect) => {
const x = clamp(position.x, boundaryRect.x, boundaryRect.x + boundaryRect.width - size.width);
const y = clamp(position.y, boundaryRect.y, boundaryRect.y + boundaryRect.height - size.height);
return { x, y };
};
var defaultMinSize = {
width: 0,
height: 0
};
var defaultMaxSize = {
width: Infinity,
height: Infinity
};
var clampSize = (size, minSize = defaultMinSize, maxSize = defaultMaxSize) => {
return {
width: Math.min(Math.max(size.width, minSize.width), maxSize.width),
height: Math.min(Math.max(size.height, minSize.height), maxSize.height)
};
};
var createPoint = (x, y) => ({ x, y });
var subtractPoints = (a, b) => {
if (!b) return a;
return createPoint(a.x - b.x, a.y - b.y);
};
var addPoints = (a, b) => createPoint(a.x + b.x, a.y + b.y);
function createRect(r) {
const { x, y, width, height } = r;
const midX = x + width / 2;
const midY = y + height / 2;
return {
x,
y,
width,
height,
minX: x,
minY: y,
maxX: x + width,
maxY: y + height,
midX,
midY,
center: createPoint(midX, midY)
};
}
var constrainRect = (rect, boundary) => {
const left = Math.max(boundary.x, Math.min(rect.x, boundary.x + boundary.width - rect.width));
const top = Math.max(boundary.y, Math.min(rect.y, boundary.y + boundary.height - rect.height));
return {
x: left,
y: top,
width: Math.min(rect.width, boundary.width),
height: Math.min(rect.height, boundary.height)
};
};
var isSizeEqual = (a, b) => {
return a.width === b?.width && a.height === b?.height;
};
var isPointEqual = (a, b) => {
return a.x === b?.x && a.y === b?.y;
};
var styleCache = /* @__PURE__ */ new WeakMap();
function getCacheComputedStyle(el) {
if (!styleCache.has(el)) {
const win = el.ownerDocument.defaultView || window;
styleCache.set(el, win.getComputedStyle(el));
}
return styleCache.get(el);
}
function getElementRect(el, opts = {}) {
return createRect(getClientRect(el, opts));
}
function getClientRect(el, opts = {}) {
const { excludeScrollbar = false, excludeBorders = false } = opts;
const { x, y, width, height } = el.getBoundingClientRect();
const r = { x, y, width, height };
const style = getCacheComputedStyle(el);
const { borderLeftWidth, borderTopWidth, borderRightWidth, borderBottomWidth } = style;
const borderXWidth = sum(borderLeftWidth, borderRightWidth);
const borderYWidth = sum(borderTopWidth, borderBottomWidth);
if (excludeBorders) {
r.width -= borderXWidth;
r.height -= borderYWidth;
r.x += px(borderLeftWidth);
r.y += px(borderTopWidth);
}
if (excludeScrollbar) {
const scrollbarWidth = el.offsetWidth - el.clientWidth - borderXWidth;
const scrollbarHeight = el.offsetHeight - el.clientHeight - borderYWidth;
r.width -= scrollbarWidth;
r.height -= scrollbarHeight;
}
return r;
}
var px = (v) => parseFloat(v.replace("px", ""));
var sum = (...vals) => vals.reduce((sum2, v) => sum2 + (v ? px(v) : 0), 0);
function getWindowRect(win, opts = {}) {
return createRect(getViewportRect(win, opts));
}
function getViewportRect(win, opts) {
const { excludeScrollbar = false } = opts;
const { innerWidth, innerHeight, document: doc, visualViewport } = win;
const width = visualViewport?.width || innerWidth;
const height = visualViewport?.height || innerHeight;
const rect = { x: 0, y: 0, width, height };
if (excludeScrollbar) {
const scrollbarWidth = innerWidth - doc.documentElement.clientWidth;
const scrollbarHeight = innerHeight - doc.documentElement.clientHeight;
rect.width -= scrollbarWidth;
rect.height -= scrollbarHeight;
}
return rect;
}
var compassDirectionMap = {
n: { x: 0.5, y: 0 },
ne: { x: 1, y: 0 },
e: { x: 1, y: 0.5 },
se: { x: 1, y: 1 },
s: { x: 0.5, y: 1 },
sw: { x: 0, y: 1 },
w: { x: 0, y: 0.5 },
nw: { x: 0, y: 0 }
};
var oppositeDirectionMap = {
n: "s",
ne: "sw",
e: "w",
se: "nw",
s: "n",
sw: "ne",
w: "e",
nw: "se"
};
var { sign, abs, min: min2 } = Math;
function getRectExtentPoint(rect, direction) {
const { minX, minY, maxX, maxY, midX, midY } = rect;
const x = direction.includes("w") ? minX : direction.includes("e") ? maxX : midX;
const y = direction.includes("n") ? minY : direction.includes("s") ? maxY : midY;
return { x, y };
}
function getOppositeDirection(direction) {
return oppositeDirectionMap[direction];
}
function resizeRect(rect, offset, direction, opts) {
const { scalingOriginMode, lockAspectRatio } = opts;
const extent = getRectExtentPoint(rect, direction);
const oppositeDirection = getOppositeDirection(direction);
const oppositeExtent = getRectExtentPoint(rect, oppositeDirection);
if (scalingOriginMode === "center") {
offset = { x: offset.x * 2, y: offset.y * 2 };
}
const newExtent = {
x: extent.x + offset.x,
y: extent.y + offset.y
};
const multiplier = {
x: compassDirectionMap[direction].x * 2 - 1,
y: compassDirectionMap[direction].y * 2 - 1
};
const newSize = {
width: newExtent.x - oppositeExtent.x,
height: newExtent.y - oppositeExtent.y
};
const scaleX = multiplier.x * newSize.width / rect.width;
const scaleY = multiplier.y * newSize.height / rect.height;
const largestMagnitude = abs(scaleX) > abs(scaleY) ? scaleX : scaleY;
const scale = lockAspectRatio ? { x: largestMagnitude, y: largestMagnitude } : {
x: extent.x === oppositeExtent.x ? 1 : scaleX,
y: extent.y === oppositeExtent.y ? 1 : scaleY
};
if (extent.y === oppositeExtent.y) {
scale.y = abs(scale.y);
} else if (sign(scale.y) !== sign(scaleY)) {
scale.y *= -1;
}
if (extent.x === oppositeExtent.x) {
scale.x = abs(scale.x);
} else if (sign(scale.x) !== sign(scaleX)) {
scale.x *= -1;
}
switch (scalingOriginMode) {
case "extent":
return transformRect(rect, AffineTransform.scale(scale.x, scale.y, oppositeExtent), false);
case "center":
return transformRect(
rect,
AffineTransform.scale(scale.x, scale.y, {
x: rect.midX,
y: rect.midY
}),
false
);
}
}
function createRectFromPoints(initialPoint, finalPoint, normalized = true) {
if (normalized) {
return {
x: min2(finalPoint.x, initialPoint.x),
y: min2(finalPoint.y, initialPoint.y),
width: abs(finalPoint.x - initialPoint.x),
height: abs(finalPoint.y - initialPoint.y)
};
}
return {
x: initialPoint.x,
y: initialPoint.y,
width: finalPoint.x - initialPoint.x,
height: finalPoint.y - initialPoint.y
};
}
function transformRect(rect, transform, normalized = true) {
const p1 = transform.applyTo({ x: rect.minX, y: rect.minY });
const p2 = transform.applyTo({ x: rect.maxX, y: rect.maxY });
return createRectFromPoints(p1, p2, normalized);
}
var GET_ORIGINAL_SYMBOL = Symbol();
var getProto = Object.getPrototypeOf;
var objectsToTrack = /* @__PURE__ */ new WeakMap();
var isObjectToTrack = (obj) => obj && (objectsToTrack.has(obj) ? objectsToTrack.get(obj) : getProto(obj) === Object.prototype || getProto(obj) === Array.prototype);
var getUntracked = (obj) => {
if (isObjectToTrack(obj)) {
return obj[GET_ORIGINAL_SYMBOL] || null;
}
return null;
};
var markToTrack = (obj, mark = true) => {
objectsToTrack.set(obj, mark);
};
// ../../node_modules/@zag-js/store/dist/index.mjs
function glob() {
if (typeof globalThis !== "undefined") return globalThis;
if (typeof self !== "undefined") return self;
if (typeof window !== "undefined") return window;
if (typeof global !== "undefined") return global;
}
function globalRef(key, value) {
const g = glob();
if (!g) return value();
g[key] || (g[key] = value());
return g[key];
}
var refSet = globalRef("__zag__refSet", () => /* @__PURE__ */ new WeakSet());
var isReactElement = (x) => typeof x === "object" && x !== null && "$$typeof" in x && "props" in x;
var isVueElement = (x) => typeof x === "object" && x !== null && "__v_isVNode" in x;
var isDOMElement = (x) => typeof x === "object" && x !== null && "nodeType" in x && typeof x.nodeName === "string";
var isElement = (x) => isReactElement(x) || isVueElement(x) || isDOMElement(x);
var isObject = (x) => x !== null && typeof x === "object";
var canProxy = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !isElement(x) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer) && !(x instanceof Promise);
var proxyStateMap = globalRef("__zag__proxyStateMap", () => /* @__PURE__ */ new WeakMap());
var buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) => new Proxy(target, handler), snapCache = /* @__PURE__ */ new WeakMap(), createSnapshot = (target, version) => {
const cache = snapCache.get(target);
if (cache?.[0] === version) {
return cache[1];
}
const snap = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
markToTrack(snap, true);
snapCache.set(target, [version, snap]);
Reflect.ownKeys(target).forEach((key) => {
const value = Reflect.get(target, key);
if (refSet.has(value)) {
markToTrack(value, false);
snap[key] = value;
} else if (proxyStateMap.has(value)) {
snap[key] = snapshot(value);
} else {
snap[key] = value;
}
});
return Object.freeze(snap);
}, proxyCache = /* @__PURE__ */ new WeakMap(), versionHolder = [1, 1], proxyFunction2 = (initialObject) => {
if (!isObject(initialObject)) {
throw new Error("object required");
}
const found = proxyCache.get(initialObject);
if (found) {
return found;
}
let version = versionHolder[0];
const listeners = /* @__PURE__ */ new Set();
const notifyUpdate = (op, nextVersion = ++versionHolder[0]) => {
if (version !== nextVersion) {
version = nextVersion;
listeners.forEach((listener) => listener(op, nextVersion));
}
};
let checkVersion = versionHolder[1];
const ensureVersion = (nextCheckVersion = ++versionHolder[1]) => {
if (checkVersion !== nextCheckVersion && !listeners.size) {
checkVersion = nextCheckVersion;
propProxyStates.forEach(([propProxyState]) => {
const propVersion = propProxyState[1](nextCheckVersion);
if (propVersion > version) {
version = propVersion;
}
});
}
return version;
};
const createPropListener = (prop) => (op, nextVersion) => {
const newOp = [...op];
newOp[1] = [prop, ...newOp[1]];
notifyUpdate(newOp, nextVersion);
};
const propProxyStates = /* @__PURE__ */ new Map();
const addPropListener = (prop, propProxyState) => {
if (propProxyStates.has(prop)) {
throw new Error("prop listener already exists");
}
if (listeners.size) {
const remove = propProxyState[3](createPropListener(prop));
propProxyStates.set(prop, [propProxyState, remove]);
} else {
propProxyStates.set(prop, [propProxyState]);
}
};
const removePropListener = (prop) => {
const entry = propProxyStates.get(prop);
if (entry) {
propProxyStates.delete(prop);
entry[1]?.();
}
};
const addListener = (listener) => {
listeners.add(listener);
if (listeners.size === 1) {
propProxyStates.forEach(([propProxyState, prevRemove], prop) => {
if (prevRemove) {
throw new Error("remove already exists");
}
const remove = propProxyState[3](createPropListener(prop));
propProxyStates.set(prop, [propProxyState, remove]);
});
}
const removeListener = () => {
listeners.delete(listener);
if (listeners.size === 0) {
propProxyStates.forEach(([propProxyState, remove], prop) => {
if (remove) {
remove();
propProxyStates.set(prop, [propProxyState]);
}
});
}
};
return removeListener;
};
const baseObject = Array.isArray(initialObject) ? [] : Object.create(Object.getPrototypeOf(initialObject));
const handler = {
deleteProperty(target, prop) {
const prevValue = Reflect.get(target, prop);
removePropListener(prop);
const deleted = Reflect.deleteProperty(target, prop);
if (deleted) {
notifyUpdate(["delete", [prop], prevValue]);
}
return deleted;
},
set(target, prop, value, receiver) {
const hasPrevValue = Reflect.has(target, prop);
const prevValue = Reflect.get(target, prop, receiver);
if (hasPrevValue && (objectIs(prevValue, value) || proxyCache.has(value) && objectIs(prevValue, proxyCache.get(value)))) {
return true;
}
removePropListener(prop);
if (isObject(value)) {
value = getUntracked(value) || value;
}
let nextValue = value;
if (Object.getOwnPropertyDescriptor(target, prop)?.set) ;
else {
if (!proxyStateMap.has(value) && canProxy(value)) {
nextValue = proxy(value);
}
const childProxyState = !refSet.has(nextValue) && proxyStateMap.get(nextValue);
if (childProxyState) {
addPropListener(prop, childProxyState);
}
}
Reflect.set(target, prop, nextValue, receiver);
notifyUpdate(["set", [prop], value, prevValue]);
return true;
}
};
const proxyObject = newProxy(baseObject, handler);
proxyCache.set(initialObject, proxyObject);
const proxyState = [baseObject, ensureVersion, createSnapshot, addListener];
proxyStateMap.set(proxyObject, proxyState);
Reflect.ownKeys(initialObject).forEach((key) => {
const desc = Object.getOwnPropertyDescriptor(initialObject, key);
if (desc.get || desc.set) {
Object.defineProperty(baseObject, key, desc);
} else {
proxyObject[key] = initialObject[key];
}
});
return proxyObject;
}) => [
// public functions
proxyFunction2,
// shared state
proxyStateMap,
refSet,
// internal things
objectIs,
newProxy,
canProxy,
snapCache,
createSnapshot,
proxyCache,
versionHolder
];
var [proxyFunction] = buildProxyFunction();
function proxy(initialObject = {}) {
return proxyFunction(initialObject);
}
function subscribe(proxyObject, callback, notifyInSync) {
const proxyState = proxyStateMap.get(proxyObject);
let promise;
const ops = [];
const addListener = proxyState[3];
let isListenerActive = false;
const listener = (op) => {
ops.push(op);
if (!promise) {
promise = Promise.resolve().then(() => {
promise = void 0;
if (isListenerActive) {
callback(ops.splice(0));
}
});
}
};
const removeListener = addListener(listener);
isListenerActive = true;
return () => {
isListenerActive = false;
removeListener();
};
}
function snapshot(proxyObject) {
const proxyState = proxyStateMap.get(proxyObject);
const [target, ensureVersion, createSnapshot] = proxyState;
return createSnapshot(target, ensureVersion());
}
var anatomy = createAnatomy("floating-panel").parts(
"trigger",
"positioner",
"content",
"header",
"body",
"title",
"resizeTrigger",
"dragTrigger",
"stageTrigger",
"closeTrigger",
"control"
);
var parts = anatomy.build();
var getTriggerId = (ctx) => ctx.ids?.trigger ?? `float:${ctx.id}:trigger`;
var getPositionerId = (ctx) => ctx.ids?.positioner ?? `float:${ctx.id}:positioner`;
var getContentId = (ctx) => ctx.ids?.content ?? `float:${ctx.id}:content`;
var getTitleId = (ctx) => ctx.ids?.title ?? `float:${ctx.id}:title`;
var getHeaderId = (ctx) => ctx.ids?.header ?? `float:${ctx.id}:header`;
var getTriggerEl = (ctx) => ctx.getById(getTriggerId(ctx));
var getPositionerEl = (ctx) => ctx.getById(getPositionerId(ctx));
var getContentEl = (ctx) => ctx.getById(getContentId(ctx));
var getHeaderEl = (ctx) => ctx.getById(getHeaderId(ctx));
var getBoundaryRect = (ctx, boundaryEl, allowOverflow) => {
let boundaryRect;
if (isHTMLElement(boundaryEl)) {
boundaryRect = getElementRect(boundaryEl);
} else {
boundaryRect = getWindowRect(ctx.getWin());
}
if (allowOverflow) {
boundaryRect = createRect({
x: -boundaryRect.width,
// empty(left)
y: boundaryRect.minY,
width: boundaryRect.width * 3,
// empty(left) + win + empty(right)
height: boundaryRect.height * 2
// win + empty(bottom)
});
}
return pick(boundaryRect, ["x", "y", "width", "height"]);
};
function getResizeAxisStyle(axis) {
switch (axis) {
case "n":
return {
cursor: "n-resize",
width: "100%",
left: "50%",
translate: "-50%"
};
case "e":
return {
cursor: "e-resize",
height: "100%",
right: 0,
top: "50%",
translate: "0 -50%"
};
case "s":
return {
cursor: "s-resize",
width: "100%",
bottom: 0,
left: "50%",
translate: "-50%"
};
case "w":
return {
cursor: "w-resize",
height: "100%",
left: 0,
top: "50%",
translate: "0 -50%"
};
case "se":
return {
cursor: "se-resize",
bottom: 0,
right: 0
};
case "sw":
return {
cursor: "sw-resize",
bottom: 0,
left: 0
};
case "ne":
return {
cursor: "ne-resize",
top: 0,
right: 0
};
case "nw":
return {
cursor: "nw-resize",
top: 0,
left: 0
};
default:
throw new Error(`Invalid axis: ${axis}`);
}
}
var validStages = /* @__PURE__ */ new Set(["minimized", "maximized", "default"]);
function connect(service, normalize) {
const { state, send, scope, prop, computed, context } = service;
const open = state.hasTag("open");
const dragging = state.matches("open.dragging");
const resizing = state.matches("open.resizing");
const isTopmost = context.get("isTopmost");
const size = context.get("size");
const position = context.get("position");
const isMaximized = computed("isMaximized");
const isMinimized = computed("isMinimized");
const isStaged = computed("isStaged");
const canResize = computed("canResize");
const canDrag = computed("canDrag");
return {
open,
resizable: prop("resizable"),
draggable: prop("draggable"),
setOpen(nextOpen) {
const open2 = state.hasTag("open");
if (open2 === nextOpen) return;
send({ type: nextOpen ? "OPEN" : "CLOSE" });
},
dragging,
resizing,
position,
size,
setPosition(position2) {
send({ type: "SET_POSITION", position: position2 });
},
setSize(size2) {
send({ type: "SET_SIZE", size: size2 });
},
minimize() {
send({ type: "MINIMIZE" });
},
maximize() {
send({ type: "MAXIMIZE" });
},
restore() {
send({ type: "RESTORE" });
},
getTriggerProps() {
return normalize.button({
...parts.trigger.attrs,
type: "button",
disabled: prop("disabled"),
id: getTriggerId(scope),
"data-state": open ? "open" : "closed",
"data-dragging": dataAttr(dragging),
"aria-controls": getContentId(scope),
onClick(event) {
if (event.defaultPrevented) return;
if (prop("disabled")) return;
const open2 = state.hasTag("open");
send({ type: open2 ? "CLOSE" : "OPEN", src: "trigger" });
}
});
},
getPositionerProps() {
return normalize.element({
...parts.positioner.attrs,
id: getPositionerId(scope),
style: {
"--width": toPx(size?.width),
"--height": toPx(size?.height),
"--x": toPx(position?.x),
"--y": toPx(position?.y),
position: prop("strategy"),
top: "var(--y)",
left: "var(--x)"
}
});
},
getContentProps() {
return normalize.element({
...parts.content.attrs,
role: "dialog",
tabIndex: 0,
hidden: !open,
id: getContentId(scope),
"aria-labelledby": getTitleId(scope),
"data-state": open ? "open" : "closed",
"data-dragging": dataAttr(dragging),
"data-topmost": dataAttr(isTopmost),
"data-behind": dataAttr(!isTopmost),
style: {
width: "var(--width)",
height: "var(--height)",
overflow: isMinimized ? "hidden" : void 0
},
onFocus() {
send({ type: "CONTENT_FOCUS" });
},
onKeyDown(event) {
if (event.defaultPrevented) return;
if (!isSelfTarget(event)) return;
const step = getEventStep(event) * prop("gridSize");
const keyMap = {
Escape() {
if (!isTopmost) return;
send({ type: "ESCAPE" });
},
ArrowLeft() {
send({ type: "MOVE", direction: "left", step });
},
ArrowRight() {
send({ type: "MOVE", direction: "right", step });
},
ArrowUp() {
send({ type: "MOVE", direction: "up", step });
},
ArrowDown() {
send({ type: "MOVE", direction: "down", step });
}
};
const handler = keyMap[getEventKey(event, { dir: prop("dir") })];
if (handler) {
event.preventDefault();
handler(event);
}
}
});
},
getCloseTriggerProps() {
return normalize.button({
...parts.closeTrigger.attrs,
disabled: prop("disabled"),
"aria-label": "Close Window",
type: "button",
onClick(event) {
if (event.defaultPrevented) return;
send({ type: "CLOSE" });
}
});
},
getStageTriggerProps(props2) {
if (!validStages.has(props2.stage)) {
throw new Error(`[zag-js] Invalid stage: ${props2.stage}. Must be one of: ${Array.from(validStages).join(", ")}`);
}
const translations = prop("translations");
const actionProps = match(props2.stage, {
minimized: () => ({
"aria-label": translations.minimize,
hidden: isStaged
}),
maximized: () => ({
"aria-label": translations.maximize,
hidden: isStaged
}),
default: () => ({
"aria-label": translations.restore,
hidden: !isStaged
})
});
return normalize.button({
...parts.stageTrigger.attrs,
disabled: prop("disabled"),
...actionProps,
type: "button",
onClick(event) {
if (event.defaultPrevented) return;
const type = match(props2.stage, {
minimized: () => "MINIMIZE",
maximized: () => "MAXIMIZE",
default: () => "RESTORE"
});
send({ type: type.toUpperCase() });
}
});
},
getResizeTriggerProps(props2) {
return normalize.element({
...parts.resizeTrigger.attrs,
"data-disabled": dataAttr(!canResize),
"data-axis": props2.axis,
onPointerDown(event) {
if (!canResize) return;
if (!isLeftClick(event)) return;
event.currentTarget.setPointerCapture(event.pointerId);
event.stopPropagation();
send({
type: "RESIZE_START",
axis: props2.axis,
position: { x: event.clientX, y: event.clientY }
});
},
onPointerUp(event) {
if (!canResize) return;
const node = event.currentTarget;
if (node.hasPointerCapture(event.pointerId)) {
node.releasePointerCapture(event.pointerId);
}
},
style: {
position: "absolute",
touchAction: "none",
...getResizeAxisStyle(props2.axis)
}
});
},
getDragTriggerProps() {
return normalize.element({
...parts.dragTrigger.attrs,
"data-disabled": dataAttr(!canDrag),
onPointerDown(event) {
if (!canDrag) return;
if (!isLeftClick(event)) return;
const target = getEventTarget(event);
if (target?.closest("button") || target?.closest("[data-no-drag]")) {
return;
}
event.currentTarget.setPointerCapture(event.pointerId);
event.stopPropagation();
send({
type: "DRAG_START",
pointerId: event.pointerId,
position: { x: event.clientX, y: event.clientY }
});
},
onPointerUp(event) {
if (!canDrag) return;
const node = event.currentTarget;
if (node.hasPointerCapture(event.pointerId)) {
node.releasePointerCapture(event.pointerId);
}
},
onDoubleClick() {
send({ type: isMaximized ? "RESTORE" : "MAXIMIZE" });
},
style: {
WebkitUserSelect: "none",
userSelect: "none",
touchAction: "none",
cursor: "move"
}
});
},
getControlProps() {
return normalize.element({
...parts.control.attrs,
"data-disabled": dataAttr(prop("disabled")),
"data-stage": context.get("stage")
});
},
getTitleProps() {
return normalize.element({
...parts.title.attrs,
id: getTitleId(scope)
});
},
getHeaderProps() {
return normalize.element({
...parts.header.attrs,
id: getHeaderId(scope),
"data-dragging": dataAttr(dragging),
"data-topmost": dataAttr(isTopmost),
"data-behind": dataAttr(!isTopmost)
});
},
getBodyProps() {
return normalize.element({
...parts.body.attrs,
"data-dragging": dataAttr(dragging),
hidden: isMinimized
});
}
};
}
var panelStack = proxy({
stack: [],
count() {
return this.stack.length;
},
add(panelId) {
if (this.stack.includes(panelId)) return;
this.stack.push(panelId);
},
remove(panelId) {
const index = this.stack.indexOf(panelId);
if (index < 0) return;
this.stack.splice(index, 1);
},
bringToFront(id) {
this.remove(id);
this.add(id);
},
isTopmost(id) {
return this.stack[this.stack.length - 1] === id;
},
indexOf(id) {
return this.stack.indexOf(id);
}
});
var { not, and } = createGuards();
var defaultTranslations = {
minimize: "Minimize window",
maximize: "Maximize window",
restore: "Restore window"
};
var machine = createMachine({
props({ props: props2 }) {
ensureProps(props2, ["id"], "floating-panel");
return {
strategy: "fixed",
gridSize: 1,
defaultSize: { width: 320, height: 240 },
defaultPosition: { x: 300, y: 100 },
allowOverflow: true,
resizable: true,
draggable: true,
...props2,
hasSpecifiedPosition: !!props2.defaultPosition || !!props2.position,
translations: {
...defaultTranslations,
...props2.translations
}
};
},
initialState({ prop }) {
const open = prop("open") || prop("defaultOpen");
return open ? "open" : "closed";
},
context({ prop, bindable }) {
return {
size: bindable(() => ({
defaultValue: prop("defaultSize"),
value: prop("size"),
isEqual: isSizeEqual,
sync: true,
hash(v) {
return `W:${v.width} H:${v.height}`;
},
onChange(value) {
prop("onSizeChange")?.({ size: value });
}
})),
position: bindable(() => ({
defaultValue: prop("defaultPosition"),
value: prop("position"),
isEqual: isPointEqual,
sync: true,
hash(v) {
return `X:${v.x} Y:${v.y}`;
},
onChange(value) {
prop("onPositionChange")?.({ position: value });
}
})),
stage: bindable(() => ({
defaultValue: "default",
onChange(value) {
prop("onStageChange")?.({ stage: value });
}
})),
lastEventPosition: bindable(() => ({
defaultValue: null
})),
prevPosition: bindable(() => ({
defaultValue: null
})),
prevSize: bindable(() => ({
defaultValue: null
})),
isTopmost: bindable(() => ({
defaultValue: void 0
}))
};
},
computed: {
isMaximized: ({ context }) => context.get("stage") === "maximized",
isMinimized: ({ context }) => context.get("stage") === "minimized",
isStaged: ({ context }) => context.get("stage") !== "default",
canResize: ({ context, prop }) => (prop("resizable") || !prop("disabled")) && context.get("stage") === "default",
canDrag: ({ prop, computed }) => (prop("draggable") || !prop("disabled")) && !computed("isMaximized")
},
watch({ track, context, action, prop }) {
track([() => context.hash("position")], () => {
action(["setPositionStyle"]);
});
track([() => context.hash("size")], () => {
action(["setSizeStyle"]);
});
track([() => prop("open")], () => {
action(["toggleVisibility"]);
});
},
effects: ["trackPanelStack"],
on: {
CONTENT_FOCUS: {
actions: ["bringToFrontOfPanelStack"]
},
SET_POSITION: {
actions: ["setPosition"]
},
SET_SIZE: {
actions: ["setSize"]
}
},
states: {
closed: {
tags: ["closed"],
on: {
"CONTROLLED.OPEN": {
target: "open",
actions: ["setAnchorPosition", "setPositionStyle", "setSizeStyle", "focusContentEl"]
},
OPEN: [
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"]
},
{
target: "open",
actions: ["invokeOnOpen", "setAnchorPosition", "setPositionStyle", "setSizeStyle", "focusContentEl"]
}
]
}
},
open: {
tags: ["open"],
entry: ["bringToFrontOfPanelStack"],
effects: ["trackBoundaryRect"],
on: {
DRAG_START: {
guard: not("isMaximized"),
target: "open.dragging",
actions: ["setPrevPosition"]
},
RESIZE_START: {
guard: not("isMinimized"),
target: "open.resizing",
actions: ["setPrevSize"]
},
"CONTROLLED.CLOSE": {
target: "closed",
actions: ["resetRect", "focusTriggerEl"]
},
CLOSE: [
{
guard: "isOpenControlled",
target: "closed",
actions: ["invokeOnClose"]
},
{
target: "closed",
actions: ["invokeOnClose", "resetRect", "focusTriggerEl"]
}
],
ESCAPE: [
{
guard: and("isOpenControlled", "closeOnEsc"),
actions: ["invokeOnClose"]
},
{
guard: "closeOnEsc",
target: "closed",
actions: ["invokeOnClose", "resetRect", "focusTriggerEl"]
}
],
MINIMIZE: {
actions: ["setMinimized"]
},
MAXIMIZE: {
actions: ["setMaximized"]
},
RESTORE: {
actions: ["setRestored"]
},
MOVE: {
actions: ["setPositionFromKeyboard"]
}
}
},
"open.dragging": {
tags: ["open"],
effects: ["trackPointerMove"],
exit: ["clearPrevPosition"],
on: {
DRAG: {
actions: ["setPosition"]
},
DRAG_END: {
target: "open",
actions: ["invokeOnDragEnd"]
},
"CONTROLLED.CLOSE": {
target: "closed",
actions: ["resetRect"]
},
CLOSE: [
{
guard: "isOpenControlled",
target: "closed",
actions: ["invokeOnClose"]
},
{
target: "closed",
actions: ["invokeOnClose", "resetRect"]
}
],
ESCAPE: {
target: "open"
}
}
},
"open.resizing": {
tags: ["open"],
effects: ["trackPointerMove"],
exit: ["clearPrevSize"],
on: {
DRAG: {
actions: ["setSize"]
},
DRAG_END: {
target: "open",
actions: ["invokeOnResizeEnd"]
},
"CONTROLLED.CLOSE": {
target: "closed",
actions: ["resetRect"]
},
CLOSE: [
{
guard: "isOpenControlled",
target: "closed",
actions: ["invokeOnClose"]
},
{
target: "closed",
actions: ["invokeOnClose", "resetRect"]
}
],
ESCAPE: {
target: "open"
}
}
}
},
implementations: {
guards: {
closeOnEsc: ({ prop }) => !!prop("closeOnEscape"),
isMaximized: ({ context }) => context.get("stage") === "maximized",
isMinimized: ({ context }) => context.get("stage") === "minimized",
isOpenControlled: ({ prop }) => prop("open") != void 0
},
effects: {
trackPointerMove({ scope, send, event: evt, prop }) {
const doc = scope.getDoc();
const boundaryEl = prop("getBoundaryEl")?.();
const boundaryRect = getBoundaryRect(scope, boundaryEl, false);
return trackPointerMove(doc, {
onPointerMove({ point, event }) {
const { altKey, shiftKey } = event;
let x = clampValue(point.x, boundaryRect.x, boundaryRect.x + boundaryRect.width);
let y = clampValue(point.y, boundaryRect.y, boundaryRect.y + boundaryRect.height);
send({ type: "DRAG", position: { x, y }, axis: evt.axis, altKey, shiftKey });
},
onPointerUp() {
send({ type: "DRAG_END" });
}
});
},
trackBoundaryRect({ context, scope, prop, computed }) {
const win = scope.getWin();
let skip = true;
const exec = () => {
if (skip) {
skip = false;
return;
}
const boundaryEl2 = prop("getBoundaryEl")?.();
let boundaryRect = getBoundaryRect(scope, boundaryEl2, false);
if (!computed("isMaximized")) {
const rect = { ...context.get("position"), ...context.get("size") };
boundaryRect = constrainRect(rect, boundaryRect);
}
context.set("size", pick(boundaryRect, ["width", "height"]));
context.set("position", pick(boundaryRect, ["x", "y"]));
};
const boundaryEl = prop("getBoundaryEl")?.();
if (isHTMLElement(boundaryEl)) {
const obs = new win.ResizeObserver(exec);
obs.observe(boundaryEl);
return () => obs.disconnect();
}
return addDomEvent(win, "resize", exec);
},
trackPanelStack({ context, scope }) {
const unsub = subscribe(panelStack, () => {
context.set("isTopmost", panelStack.isTopmost(scope.id));
const contentEl = getContentEl(scope);
if (!contentEl) return;
const index = panelStack.indexOf(scope.id);
if (index === -1) return;
contentEl.style.setProperty("--z-index", `${index + 1}`);
});
return () => {
panelStack.remove(scope.id);
unsub();
};
}
},
actions: {
setAnchorPosition({ context, prop, scope }) {
if (prop("hasSpecifiedPosition")) return;
const hasPrevRect = context.get("prevPosition") || context.get("prevSize");
if (prop("persistRect") && hasPrevRect) return;
raf(() => {
const triggerRect = getTriggerEl(scope);
const boundaryRect = getBoundaryRect(scope, prop("getBoundaryEl")?.(), false);
let anchorPosition = prop("getAnchorPosition")?.({
triggerRect: triggerRect ? DOMRect.fromRect(getElementRect(triggerRect)) : null,
boundaryRect: DOMRect.fromRect(boundaryRect)
});
if (!anchorPosition) {
const size = context.get("size");
anchorPosition = {
x: boundaryRect.x + (boundaryRect.width - size.width) / 2,
y: boundaryRect.y + (boundaryRect.height - size.height) / 2
};
}
if (!anchorPosition) return;
context.set("position", anchorPosition);
});
},
setPrevPosition({ context, event }) {
context.set("prevPosition", { ...context.get("position") });
context.set("lastEventPosition", event.position);
},
clearPrevPosition({ context, prop }) {
if (!prop("persistRect")) context.set("prevPosition", null);
context.set("lastEventPosition", null);
},
setPosition({ context, event, prop, scope }) {
let diff = subtractPoints(event.position, context.get("lastEventPosition"));
diff.x = Math.round(diff.x / prop("gridSize")) * prop("gridSize");
diff.y = Math.round(diff.y / prop("gridSize")) * prop("gridSize");
const prevPosition = context.get("prevPosition");
if (!prevPosition) return;
let position = addPoints(prevPosition, diff);
const boundaryEl = prop("getBoundaryEl")?.();
const boundaryRect = getBoundaryRect(scope, boundaryEl, prop("allowOverflow"));
position = clampPoint(position, context.get("size"), boundaryRect);
context.set("position", position);
},
setPositionStyle({ scope, context }) {
const el = getPositionerEl(scope);
const position = context.get("position");
el?.style.setProperty("--x", `${position.x}px`);
el?.style.setProperty("--y", `${position.y}px`);
},
resetRect({ context, prop }) {
context.set("stage", "default");
if (!prop("persistRect")) {
context.set("position", context.initial("position"));
context.set("size", context.initial("size"));
}
},
setPrevSize({ context, event }) {
context.set("prevSize", { ...context.get("size") });
context.set("prevPosition", { ...context.get("position") });
context.set("lastEventPosition", event.position);
},
clearPrevSize({ context }) {
context.set("prevSize", null);
context.set("prevPosition", null);
context.set("lastEventPosition", null);
},
setSize({ context, event, scope, prop }) {
const prevSize = context.get("prevSize");
const prevPosition = context.get("prevPosition");
const lastEventPosition = context.get("lastEventPosition");
if (!prevSize || !prevPosition || !lastEventPosition) return;
const prevRect = createRect({ ...prevPosition, ...prevSize });
const offset = subtractPoints(event.position, lastEventPosition);
const nextRect = resizeRect(prevRect, offset, event.axis, {
scalingOriginMode: event.altKey ? "center" : "extent",
lockAspectRatio: !!prop("lockAspectRatio") || event.shiftKey
});
let nextSize = pick(nextRect, ["width", "height"]);
let nextPosition = pick(nextRect, ["x", "y"]);
const boundaryEl = prop("getBoundaryEl")?.();
const boundaryRect = getBoundaryRect(scope, boundaryEl, false);
nextSize = clampSize(nextSize, prop("minSize"), prop("maxSize"));
nextSize = clampSize(nextSize, prop("minSize"), boundaryRect);
context.set("size", nextSize);
if (nextPosition) {
const point = clampPoint(nextPosition, nextSize, boundaryRect);
context.set("position", point);
}
},
setSizeStyle({ scope, context }) {
queueMicrotask(() => {
const el = getPositionerEl(scope);
const size = context.get("size");
el?.style.setProperty("--width", `${size.width}px`);
el?.style.setProperty("--height", `${size.height}px`);
});
},
setMaximized({ context, prop, scope }) {
context.set("stage", "maximized");
context.set("prevSize", context.get("size"));
context.set("prevPosition", context.get("position"));
const boundaryEl = prop("getBoundaryEl")?.();
const boundaryRect = getBoundaryRect(scope, boundaryEl, false);
context.set("position", pick(boundaryRect, ["x", "y"]));
context.set("size", pick(boundaryRect, ["height", "width"]));
},
setMinimized({ context, scope }) {
context.set("stage", "minimized");
context.set("prevSize", context.get("size"));
context.set("prevPosition", context.get("position"));
const headerEl = getHeaderEl(scope);
if (!headerEl) return;
const size = {
...context.get("size"),
height: headerEl?.offsetHeight
};
context.set("size", size);
},
setRestored({ context, prop, scope }) {
const boundaryRect = getBoundaryRect(scope, prop("getBoundaryEl")?.(), false);
context.set("stage", "default");
const prevSize = context.get("prevSize");
if (prevSize) {
let nextSize = prevSize;
nextSize = clampSize(nextSize, prop("minSize"), prop("maxSize"));
nextSize = clampSize(nextSize, prop("minSize"), boundaryRect);
context.set("size", nextSize);
context.set("prevSize", null);
}
if (context.get("prevPosi