New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@zag-js/collapsible

Package Overview
Dependencies
Maintainers
0
Versions
329
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zag-js/collapsible - npm Package Compare versions

Comparing version 0.0.0-dev-20240723090825 to 0.0.0-v1-beta-20250220125322

84

dist/index.d.ts
import * as _zag_js_anatomy from '@zag-js/anatomy';
import { RequiredBy, PropTypes, DirectionProperty, CommonProperties, NormalizeProps } from '@zag-js/types';
import * as _zag_js_core from '@zag-js/core';
import { Machine, StateMachine } from '@zag-js/core';
import { Service } from '@zag-js/core';
import { CommonProperties, DirectionProperty, PropTypes, NormalizeProps } from '@zag-js/types';

@@ -16,3 +16,3 @@ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "trigger" | "content">;

}>;
interface PublicContext extends DirectionProperty, CommonProperties {
interface CollapsibleProps extends CommonProperties, DirectionProperty {
/**

@@ -23,35 +23,51 @@ * The ids of the elements in the collapsible. Useful for composition.

/**
* Function called when the animation ends in the closed state.
* Whether the collapsible is open.
*/
onExitComplete?: () => void;
open?: boolean;
/**
* Function called when the popup is opened
* The default open state of the collapsible.
*/
onOpenChange?: (details: OpenChangeDetails) => void;
defaultOpen?: boolean;
/**
* Whether the collapsible is open
* The callback invoked when the open state changes.
*/
open?: boolean;
onOpenChange?: (details: OpenChangeDetails) => void;
/**
* Whether the collapsible is disabled
* The callback invoked when the exit animation completes.
*/
disabled?: boolean;
/**
* Whether the collapsible open state is controlled by the user
*/
"open.controlled"?: boolean;
onExitComplete?: () => void;
}
type ComputedContext = Readonly<{}>;
interface PrivateContext {
interface CollapsibleSchema {
state: "open" | "closed" | "closing";
props: CollapsibleProps;
context: {
size: {
width: number;
height: number;
};
initial: boolean;
};
refs: {
stylesRef: any;
cleanup: VoidFunction | undefined;
};
guard: "isOpenControlled";
event: {
type: "controlled.open";
} | {
type: "controlled.close";
} | {
type: "open";
} | {
type: "close";
} | {
type: "size.measure";
} | {
type: "animation.end";
};
action: "setInitial" | "clearInitial" | "cleanupNode" | "measureSize" | "computeSize" | "invokeOnOpen" | "invokeOnClose" | "invokeOnExitComplete" | "toggleVisibility";
effect: "trackEnterAnimation" | "trackExitAnimation";
}
type UserDefinedContext = RequiredBy<PublicContext, "id">;
interface MachineContext extends PublicContext, PrivateContext, ComputedContext {
}
type MachineState = {
value: "open" | "closed" | "closing";
};
type State = StateMachine.State<MachineContext, MachineState>;
type Send = StateMachine.Send<StateMachine.AnyEventObject>;
type Service = Machine<MachineContext, MachineState, StateMachine.AnyEventObject>;
interface MachineApi<T extends PropTypes = PropTypes> {
type CollapsibleService = Service<CollapsibleSchema>;
interface CollapsibleApi<T extends PropTypes = PropTypes> {
/**

@@ -73,2 +89,6 @@ * Whether the collapsible is open.

setOpen(open: boolean): void;
/**
* Function to measure the size of the content.
*/
measureSize(): void;
getRootProps(): T["element"];

@@ -79,9 +99,9 @@ getTriggerProps(): T["button"];

declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T>;
declare function connect<T extends PropTypes>(service: Service<CollapsibleSchema>, normalize: NormalizeProps<T>): CollapsibleApi<T>;
declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
declare const machine: _zag_js_core.MachineConfig<CollapsibleSchema>;
declare const props: ("dir" | "id" | "getRootNode" | "open" | "disabled" | "ids" | "onExitComplete" | "onOpenChange" | "open.controlled")[];
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "dir" | "id" | "getRootNode" | "open" | "disabled" | "ids" | "onExitComplete" | "onOpenChange" | "open.controlled">];
declare const props: (keyof CollapsibleProps)[];
declare const splitProps: <Props extends Partial<CollapsibleProps>>(props: Props) => [Partial<CollapsibleProps>, Omit<Props, keyof CollapsibleProps>];
export { type MachineApi as Api, type UserDefinedContext as Context, type ElementIds, type OpenChangeDetails, type Service, anatomy, connect, machine, props, splitProps };
export { type CollapsibleApi as Api, type ElementIds, type OpenChangeDetails, type CollapsibleProps as Props, type CollapsibleService as Service, anatomy, connect, machine, props, splitProps };

@@ -1,58 +0,28 @@

"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
'use strict';
// src/index.ts
var src_exports = {};
__export(src_exports, {
anatomy: () => anatomy,
connect: () => connect,
machine: () => machine,
props: () => props,
splitProps: () => splitProps
});
module.exports = __toCommonJS(src_exports);
var anatomy$1 = require('@zag-js/anatomy');
var domQuery = require('@zag-js/dom-query');
var core = require('@zag-js/core');
var types = require('@zag-js/types');
var utils = require('@zag-js/utils');
// src/collapsible.anatomy.ts
var import_anatomy = require("@zag-js/anatomy");
var anatomy = (0, import_anatomy.createAnatomy)("collapsible").parts("root", "trigger", "content");
var anatomy = anatomy$1.createAnatomy("collapsible").parts("root", "trigger", "content");
var parts = anatomy.build();
// src/collapsible.connect.ts
var import_dom_query2 = require("@zag-js/dom-query");
// src/collapsible.dom.ts
var import_dom_query = require("@zag-js/dom-query");
var dom = (0, import_dom_query.createScope)({
getRootId: (ctx) => ctx.ids?.root ?? `collapsible:${ctx.id}`,
getContentId: (ctx) => ctx.ids?.content ?? `collapsible:${ctx.id}:content`,
getTriggerId: (ctx) => ctx.ids?.trigger ?? `collapsible:${ctx.id}:trigger`,
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx))
});
var getRootId = (ctx) => ctx.ids?.root ?? `collapsible:${ctx.id}`;
var getContentId = (ctx) => ctx.ids?.content ?? `collapsible:${ctx.id}:content`;
var getTriggerId = (ctx) => ctx.ids?.trigger ?? `collapsible:${ctx.id}:trigger`;
var getContentEl = (ctx) => ctx.getById(getContentId(ctx));
// src/collapsible.connect.ts
function connect(state, send, normalize) {
const visible = state.matches("open", "closing");
function connect(service, normalize) {
const { state, send, context, scope } = service;
const visible = state.matches("open") || state.matches("closing");
const open = state.matches("open");
const height = state.context.height;
const width = state.context.width;
const disabled = !!state.context.disabled;
const skip = !state.context.initial && open;
const { width, height } = context.get("size");
const disabled = false;
const skip = !context.get("initial") && open;
const dir = "ltr";
return {

@@ -62,5 +32,8 @@ disabled,

open,
measureSize() {
send({ type: "size.measure" });
},
setOpen(nextOpen) {
if (nextOpen === open) return;
send(nextOpen ? "OPEN" : "CLOSE");
send(nextOpen ? { type: "open" } : { type: "close" });
},

@@ -71,4 +44,4 @@ getRootProps() {

"data-state": open ? "open" : "closed",
dir: state.context.dir,
id: dom.getRootId(state.context)
dir,
id: getRootId(scope)
});

@@ -79,5 +52,6 @@ },

...parts.content.attrs,
"data-collapsible": "",
"data-state": skip ? void 0 : open ? "open" : "closed",
id: dom.getContentId(state.context),
"data-disabled": (0, import_dom_query2.dataAttr)(disabled),
id: getContentId(scope),
"data-disabled": domQuery.dataAttr(disabled),
hidden: !visible,

@@ -93,13 +67,12 @@ style: {

...parts.trigger.attrs,
id: dom.getTriggerId(state.context),
dir: state.context.dir,
id: getTriggerId(scope),
dir,
type: "button",
"data-state": open ? "open" : "closed",
"data-disabled": (0, import_dom_query2.dataAttr)(disabled),
"aria-controls": dom.getContentId(state.context),
"data-disabled": domQuery.dataAttr(disabled),
"aria-controls": getContentId(scope),
"aria-expanded": visible || false,
onClick(event) {
if (event.defaultPrevented) return;
if (disabled) return;
send({ type: open ? "CLOSE" : "OPEN", src: "trigger.click" });
send({ type: open ? "close" : "open" });
}

@@ -110,183 +83,225 @@ });

}
// src/collapsible.machine.ts
var import_core = require("@zag-js/core");
var import_dom_query3 = require("@zag-js/dom-query");
var import_utils = require("@zag-js/utils");
function machine(userContext) {
const ctx = (0, import_utils.compact)(userContext);
return (0, import_core.createMachine)(
{
id: "collapsible",
initial: ctx.open ? "open" : "closed",
context: {
...ctx,
height: 0,
width: 0,
initial: false,
stylesRef: null,
unmountAnimationName: null
},
watch: {
open: ["setInitial", "computeSize", "toggleVisibility"]
},
exit: ["clearInitial"],
states: {
closed: {
tags: ["closed"],
on: {
"CONTROLLED.OPEN": "open",
OPEN: [
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"]
},
{
target: "open",
actions: ["setInitial", "computeSize", "invokeOnOpen"]
}
]
var machine = core.createMachine({
initialState({ prop }) {
const open = prop("open") || prop("defaultOpen");
return open ? "open" : "closed";
},
context({ bindable }) {
return {
size: bindable(() => ({ defaultValue: { height: 0, width: 0 } })),
initial: bindable(() => ({ defaultValue: false }))
};
},
refs() {
return {
cleanup: void 0,
stylesRef: void 0
};
},
watch({ track, prop, action }) {
track([() => prop("open")], () => {
action(["setInitial", "computeSize", "toggleVisibility"]);
});
},
exit: ["clearInitial", "cleanupNode"],
states: {
closed: {
on: {
"controlled.open": {
target: "open"
},
open: [
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"]
},
{
target: "open",
actions: ["setInitial", "computeSize", "invokeOnOpen"]
}
]
}
},
closing: {
effects: ["trackExitAnimation"],
on: {
"controlled.close": {
target: "closed"
},
closing: {
tags: ["open"],
activities: ["trackAnimationEvents"],
on: {
"CONTROLLED.CLOSE": "closed",
"CONTROLLED.OPEN": "open",
OPEN: [
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"]
},
{
target: "open",
actions: ["setInitial", "invokeOnOpen"]
}
],
CLOSE: [
{
guard: "isOpenControlled",
actions: ["invokeOnExitComplete"]
},
{
target: "closed",
actions: ["setInitial", "computeSize", "invokeOnExitComplete"]
}
],
"ANIMATION.END": {
target: "closed",
actions: ["invokeOnExitComplete"]
}
"controlled.open": {
target: "open"
},
open: [
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"]
},
{
target: "open",
actions: ["setInitial", "invokeOnOpen"]
}
],
close: [
{
guard: "isOpenControlled",
actions: ["invokeOnExitComplete"]
},
{
target: "closed",
actions: ["setInitial", "computeSize", "invokeOnExitComplete"]
}
],
"animation.end": {
target: "closed",
actions: ["invokeOnExitComplete", "clearInitial"]
}
}
},
open: {
effects: ["trackEnterAnimation"],
on: {
"controlled.close": {
target: "closing"
},
open: {
tags: ["open"],
on: {
"CONTROLLED.CLOSE": "closing",
CLOSE: [
{
guard: "isOpenControlled",
actions: ["invokeOnClose"]
},
{
target: "closing",
actions: ["setInitial", "computeSize", "invokeOnClose"]
}
]
close: [
{
guard: "isOpenControlled",
actions: ["invokeOnClose"]
},
{
target: "closing",
actions: ["setInitial", "computeSize", "invokeOnClose"]
}
],
"size.measure": {
actions: ["measureSize"]
},
"animation.end": {
actions: ["clearInitial"]
}
}
},
{
guards: {
isOpenControlled: (ctx2) => !!ctx2["open.controlled"]
}
},
implementations: {
effects: {
trackEnterAnimation: ({ send, scope }) => {
let cleanup;
const rafCleanup = domQuery.raf(() => {
const contentEl = getContentEl(scope);
if (!contentEl) return;
const animationName = domQuery.getComputedStyle(contentEl).animationName;
const hasNoAnimation = !animationName || animationName === "none";
if (hasNoAnimation) {
send({ type: "animation.end" });
return;
}
const onEnd = (event) => {
const target = domQuery.getEventTarget(event);
if (target === contentEl) {
send({ type: "animation.end" });
}
};
contentEl.addEventListener("animationend", onEnd);
cleanup = () => {
contentEl.removeEventListener("animationend", onEnd);
};
});
return () => {
rafCleanup();
cleanup?.();
};
},
activities: {
trackAnimationEvents(ctx2, _evt, { send }) {
let cleanup;
const rafCleanup = (0, import_dom_query3.raf)(() => {
const contentEl = dom.getContentEl(ctx2);
if (!contentEl) return;
const animationName = (0, import_dom_query3.getComputedStyle)(contentEl).animationName;
const hasNoAnimation = !animationName || animationName === "none";
if (hasNoAnimation) {
send({ type: "ANIMATION.END" });
return;
trackExitAnimation: ({ send, scope }) => {
let cleanup;
const rafCleanup = domQuery.raf(() => {
const contentEl = getContentEl(scope);
if (!contentEl) return;
const animationName = domQuery.getComputedStyle(contentEl).animationName;
const hasNoAnimation = !animationName || animationName === "none";
if (hasNoAnimation) {
send({ type: "animation.end" });
return;
}
const onEnd = (event) => {
const target = domQuery.getEventTarget(event);
if (target === contentEl) {
send({ type: "animation.end" });
}
const onEnd = (event) => {
const win = contentEl.ownerDocument.defaultView || window;
const animationName2 = win.getComputedStyle(contentEl).animationName;
if (event.target === contentEl && animationName2 === ctx2.unmountAnimationName) {
send({ type: "ANIMATION.END" });
}
};
contentEl.addEventListener("animationend", onEnd);
cleanup = () => {
contentEl.removeEventListener("animationend", onEnd);
};
};
contentEl.addEventListener("animationend", onEnd);
const restoreStyles = domQuery.setStyle(contentEl, {
animationFillMode: "forwards"
});
return () => {
rafCleanup();
cleanup?.();
cleanup = () => {
contentEl.removeEventListener("animationend", onEnd);
domQuery.nextTick(() => restoreStyles());
};
}
});
return () => {
rafCleanup();
cleanup?.();
};
}
},
actions: {
setInitial: ({ context }) => {
context.set("initial", true);
},
actions: {
setInitial(ctx2) {
ctx2.initial = true;
},
clearInitial(ctx2) {
ctx2.initial = false;
},
computeSize(ctx2, evt) {
ctx2._rafCleanup?.();
ctx2._rafCleanup = (0, import_dom_query3.raf)(() => {
const contentEl = dom.getContentEl(ctx2);
if (!contentEl) return;
ctx2.stylesRef || (ctx2.stylesRef = (0, import_core.ref)({
animationName: contentEl.style.animationName,
animationDuration: contentEl.style.animationDuration
}));
if (evt.type === "CLOSE" || !ctx2.open) {
const win = contentEl.ownerDocument.defaultView || window;
ctx2.unmountAnimationName = win.getComputedStyle(contentEl).animationName;
}
const hidden = contentEl.hidden;
contentEl.style.animationName = "none";
contentEl.style.animationDuration = "0s";
contentEl.hidden = false;
const rect = contentEl.getBoundingClientRect();
ctx2.height = rect.height;
ctx2.width = rect.width;
if (ctx2.initial) {
contentEl.style.animationName = ctx2.stylesRef.animationName;
contentEl.style.animationDuration = ctx2.stylesRef.animationDuration;
}
contentEl.hidden = hidden;
clearInitial: ({ context }) => {
context.set("initial", false);
},
cleanupNode: ({ refs }) => {
refs.set("stylesRef", null);
},
measureSize: ({ context, flush, scope }) => {
const contentEl = getContentEl(scope);
if (!contentEl) return;
const { height, width } = contentEl.getBoundingClientRect();
flush(() => {
context.set("size", { height, width });
});
},
computeSize: ({ refs, scope, flush, context }) => {
refs.get("cleanup")?.();
const rafCleanup = domQuery.raf(() => {
const contentEl = getContentEl(scope);
if (!contentEl) return;
const hidden = contentEl.hidden;
contentEl.style.animationName = "none";
contentEl.style.animationDuration = "0s";
contentEl.hidden = false;
const rect = contentEl.getBoundingClientRect();
flush(() => {
context.set("size", { height: rect.height, width: rect.width });
});
},
invokeOnOpen: (ctx2) => {
ctx2.onOpenChange?.({ open: true });
},
invokeOnClose: (ctx2) => {
ctx2.onOpenChange?.({ open: false });
},
invokeOnExitComplete(ctx2) {
ctx2.onExitComplete?.();
},
toggleVisibility: (ctx2, _evt, { send }) => {
send({ type: ctx2.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE" });
}
if (context.get("initial")) {
contentEl.style.animationName = "";
contentEl.style.animationDuration = "";
}
contentEl.hidden = hidden;
});
refs.set("cleanup", rafCleanup);
},
invokeOnOpen: ({ prop }) => {
prop("onOpenChange")?.({ open: true });
},
invokeOnClose: ({ prop }) => {
prop("onOpenChange")?.({ open: false });
},
invokeOnExitComplete: ({ prop }) => {
prop("onExitComplete")?.();
},
toggleVisibility: ({ prop, send }) => {
send({ type: prop("open") ? "controlled.open" : "controlled.close" });
}
},
guards: {
isOpenControlled: ({ prop }) => {
return prop("open") != void 0;
}
}
);
}
// src/collapsible.props.ts
var import_types = require("@zag-js/types");
var import_utils2 = require("@zag-js/utils");
var props = (0, import_types.createProps)()([
}
});
var props = types.createProps()([
"dir",
"disabled",
"getRootNode",

@@ -297,14 +312,11 @@ "id",

"onOpenChange",
"open.controlled",
"defaultOpen",
"open"
]);
var splitProps = (0, import_utils2.createSplitProps)(props);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
anatomy,
connect,
machine,
props,
splitProps
});
//# sourceMappingURL=index.js.map
var splitProps = utils.createSplitProps(props);
exports.anatomy = anatomy;
exports.connect = connect;
exports.machine = machine;
exports.props = props;
exports.splitProps = splitProps;
{
"name": "@zag-js/collapsible",
"version": "0.0.0-dev-20240723090825",
"version": "0.0.0-v1-beta-20250220125322",
"description": "Core logic for the collapsible widget implemented as a state machine",

@@ -21,4 +21,3 @@ "keywords": [

"files": [
"dist",
"src"
"dist"
],

@@ -32,7 +31,7 @@ "publishConfig": {

"dependencies": {
"@zag-js/anatomy": "0.0.0-dev-20240723090825",
"@zag-js/core": "0.0.0-dev-20240723090825",
"@zag-js/dom-query": "0.0.0-dev-20240723090825",
"@zag-js/utils": "0.0.0-dev-20240723090825",
"@zag-js/types": "0.0.0-dev-20240723090825"
"@zag-js/anatomy": "0.0.0-v1-beta-20250220125322",
"@zag-js/core": "0.0.0-v1-beta-20250220125322",
"@zag-js/utils": "0.0.0-v1-beta-20250220125322",
"@zag-js/types": "0.0.0-v1-beta-20250220125322",
"@zag-js/dom-query": "0.0.0-v1-beta-20250220125322"
},

@@ -55,5 +54,5 @@ "devDependencies": {

"build": "tsup",
"lint": "eslint src --ext .ts,.tsx",
"lint": "eslint src",
"typecheck": "tsc --noEmit"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc