Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@zag-js/collapsible

Package Overview
Dependencies
Maintainers
1
Versions
309
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.37.0 to 0.37.1

9

dist/index.d.ts

@@ -55,2 +55,6 @@ import * as _zag_js_anatomy from '@zag-js/anatomy';

/**
* Whether the collapsible is visible (open or closing)
*/
isVisible: boolean;
/**
* Whether the collapsible is disabled

@@ -76,2 +80,5 @@ */

export { type MachineApi as Api, type UserDefinedContext as Context, type ElementIds, type OpenChangeDetails, anatomy, connect, machine };
declare const props: ("dir" | "open" | "disabled" | "id" | "ids" | "onOpenChange" | "open.controlled" | "getRootNode")[];
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "dir" | "open" | "disabled" | "id" | "ids" | "onOpenChange" | "open.controlled" | "getRootNode">];
export { type MachineApi as Api, type UserDefinedContext as Context, type ElementIds, type OpenChangeDetails, anatomy, connect, machine, props, splitProps };

190

dist/index.js

@@ -25,3 +25,5 @@ "use strict";

connect: () => connect,
machine: () => machine
machine: () => machine,
props: () => props,
splitProps: () => splitProps
});

@@ -55,6 +57,7 @@ module.exports = __toCommonJS(src_exports);

const width = state.context.width;
const disabled = state.context.disabled;
const skipDataAttr = state.context.isMountAnimationPrevented && isOpen;
const isDisabled = !!state.context.disabled;
const skipMountAnimation = state.context.isMountAnimationPrevented && isOpen;
return {
isDisabled: !!disabled,
isDisabled,
isVisible,
isOpen,

@@ -69,3 +72,3 @@ open() {

...parts.root.attrs,
"data-state": isVisible ? "open" : "closed",
"data-state": isOpen ? "open" : "closed",
dir: state.context.dir,

@@ -76,5 +79,5 @@ id: dom.getRootId(state.context)

...parts.content.attrs,
"data-state": skipDataAttr ? void 0 : isOpen ? "open" : "closed",
"data-state": skipMountAnimation ? void 0 : isOpen ? "open" : "closed",
id: dom.getContentId(state.context),
"data-disabled": (0, import_dom_query2.dataAttr)(disabled),
"data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
hidden: !isVisible,

@@ -91,7 +94,8 @@ style: {

type: "button",
"data-disabled": (0, import_dom_query2.dataAttr)(disabled),
"data-state": isOpen ? "open" : "closed",
"data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
"aria-controls": dom.getContentId(state.context),
"aria-expanded": isVisible || false,
onClick() {
if (disabled)
if (isDisabled)
return;

@@ -122,7 +126,5 @@ send({ type: isOpen ? "CLOSE" : "OPEN", src: "trigger.click" });

watch: {
open: ["toggleVisibility"]
open: ["allowAnimation", "toggleVisibility"]
},
entry: ["computeSize"],
exit: ["clearAnimationStyles"],
activities: ["trackMountAnimation"],
states: {

@@ -133,6 +135,15 @@ closed: {

on: {
"CONTROLLED.OPEN": "open",
"CONTROLLED.OPEN": {
target: "open",
actions: ["computeSize"]
},
OPEN: [
{ guard: "isOpenControlled", actions: ["invokeOnOpen"] },
{ target: "open", actions: ["invokeOnOpen"] }
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"]
},
{
target: "open",
actions: ["allowAnimation", "invokeOnOpen"]
}
]

@@ -148,8 +159,20 @@ }

OPEN: [
{ guard: "isOpenControlled", actions: ["invokeOnOpen"] },
{ target: "open", actions: ["invokeOnOpen"] }
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"]
},
{
target: "open",
actions: ["allowAnimation", "invokeOnOpen"]
}
],
CLOSE: [
{ guard: "isOpenControlled", actions: ["invokeOnClose"] },
{ target: "closed", actions: ["computeSize"] }
{
guard: "isOpenControlled",
actions: ["invokeOnClose"]
},
{
target: "closed",
actions: ["allowAnimation", "computeSize"]
}
],

@@ -162,6 +185,15 @@ "ANIMATION.END": "closed"

on: {
"CONTROLLED.CLOSE": { target: "closing", actions: ["computeSize"] },
"CONTROLLED.CLOSE": {
target: "closing",
actions: ["computeSize"]
},
CLOSE: [
{ guard: "isOpenControlled", actions: ["invokeOnClose"] },
{ target: "closing", actions: ["computeSize"] }
{
guard: "isOpenControlled",
actions: ["invokeOnClose"]
},
{
target: "closing",
actions: ["allowAnimation", "computeSize"]
}
]

@@ -177,25 +209,28 @@ }

activities: {
trackMountAnimation(ctx2) {
const cleanup = (0, import_dom_query3.raf)(() => {
ctx2.isMountAnimationPrevented = false;
});
return () => {
ctx2.isMountAnimationPrevented = true;
cleanup();
};
},
trackAnimationEvents(ctx2, _evt, { send }) {
const contentEl = dom.getContentEl(ctx2);
if (!contentEl)
return;
const onEnd = (event) => {
if (event.target !== contentEl)
let cleanup;
const rafCleanup = (0, import_dom_query3.raf)(() => {
const contentEl = dom.getContentEl(ctx2);
if (!contentEl)
return;
send({ type: "ANIMATION.END" });
};
contentEl.addEventListener("animationend", onEnd);
contentEl.addEventListener("animationcancel", onEnd);
const isAnimationNone = (0, import_dom_query3.getComputedStyle)(contentEl).animationName === "none";
if (isAnimationNone) {
send({ type: "ANIMATION.END" });
return;
}
const onEnd = (event) => {
if (event.target !== contentEl)
return;
send({ type: "ANIMATION.END" });
};
contentEl.addEventListener("animationend", onEnd);
contentEl.addEventListener("animationcancel", onEnd);
cleanup = () => {
contentEl.removeEventListener("animationend", onEnd);
contentEl.removeEventListener("animationcancel", onEnd);
};
});
return () => {
contentEl.removeEventListener("animationend", onEnd);
contentEl.removeEventListener("animationcancel", onEnd);
rafCleanup();
cleanup?.();
};

@@ -205,22 +240,27 @@ }

actions: {
allowAnimation(ctx2) {
ctx2.isMountAnimationPrevented = false;
},
computeSize: (ctx2) => {
const contentEl = dom.getContentEl(ctx2);
if (!contentEl)
return;
ctx2.stylesRef || (ctx2.stylesRef = (0, import_core.ref)({
animationName: contentEl.style.animationName,
animationDuration: contentEl.style.animationDuration
}));
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.isMountAnimationPrevented) {
contentEl.style.animationName = ctx2.stylesRef.animationName;
contentEl.style.animationDuration = ctx2.stylesRef.animationDuration;
}
contentEl.hidden = hidden;
(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
}));
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.isMountAnimationPrevented) {
contentEl.style.animationName = ctx2.stylesRef.animationName;
contentEl.style.animationDuration = ctx2.stylesRef.animationDuration;
}
contentEl.hidden = hidden;
});
},

@@ -235,11 +275,2 @@ invokeOnOpen: (ctx2) => {

send({ type: ctx2.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE" });
},
clearAnimationStyles: (ctx2) => {
const contentEl = dom.getContentEl(ctx2);
if (!contentEl)
return;
(0, import_dom_query3.raf)(() => {
contentEl.style.animationName = "";
contentEl.style.animationDuration = "";
});
}

@@ -250,2 +281,17 @@ }

}
// src/collapsible.props.ts
var import_types = require("@zag-js/types");
var import_utils2 = require("@zag-js/utils");
var props = (0, import_types.createProps)()([
"dir",
"disabled",
"getRootNode",
"id",
"ids",
"onOpenChange",
"open.controlled",
"open"
]);
var splitProps = (0, import_utils2.createSplitProps)(props);
// Annotate the CommonJS export names for ESM import in node:

@@ -255,4 +301,6 @@ 0 && (module.exports = {

connect,
machine
machine,
props,
splitProps
});
//# sourceMappingURL=index.js.map
{
"name": "@zag-js/collapsible",
"version": "0.37.0",
"version": "0.37.1",
"description": "Core logic for the collapsible widget implemented as a state machine",

@@ -31,7 +31,7 @@ "keywords": [

"dependencies": {
"@zag-js/anatomy": "0.37.0",
"@zag-js/core": "0.37.0",
"@zag-js/dom-query": "0.37.0",
"@zag-js/utils": "0.37.0",
"@zag-js/types": "0.37.0"
"@zag-js/anatomy": "0.37.1",
"@zag-js/core": "0.37.1",
"@zag-js/dom-query": "0.37.1",
"@zag-js/utils": "0.37.1",
"@zag-js/types": "0.37.1"
},

@@ -38,0 +38,0 @@ "devDependencies": {

@@ -13,8 +13,9 @@ import { dataAttr } from "@zag-js/dom-query"

const width = state.context.width
const disabled = state.context.disabled
const isDisabled = !!state.context.disabled
const skipDataAttr = state.context.isMountAnimationPrevented && isOpen
const skipMountAnimation = state.context.isMountAnimationPrevented && isOpen
return {
isDisabled: !!disabled,
isDisabled,
isVisible,
isOpen,

@@ -30,3 +31,3 @@ open() {

...parts.root.attrs,
"data-state": isVisible ? "open" : "closed",
"data-state": isOpen ? "open" : "closed",
dir: state.context.dir,

@@ -38,5 +39,5 @@ id: dom.getRootId(state.context),

...parts.content.attrs,
"data-state": skipDataAttr ? undefined : isOpen ? "open" : "closed",
"data-state": skipMountAnimation ? undefined : isOpen ? "open" : "closed",
id: dom.getContentId(state.context),
"data-disabled": dataAttr(disabled),
"data-disabled": dataAttr(isDisabled),
hidden: !isVisible,

@@ -54,7 +55,8 @@ style: {

type: "button",
"data-disabled": dataAttr(disabled),
"data-state": isOpen ? "open" : "closed",
"data-disabled": dataAttr(isDisabled),
"aria-controls": dom.getContentId(state.context),
"aria-expanded": isVisible || false,
onClick() {
if (disabled) return
if (isDisabled) return
send({ type: isOpen ? "CLOSE" : "OPEN", src: "trigger.click" })

@@ -61,0 +63,0 @@ },

import { createMachine, ref } from "@zag-js/core"
import { raf } from "@zag-js/dom-query"
import { getComputedStyle, raf } from "@zag-js/dom-query"
import { compact } from "@zag-js/utils"

@@ -23,10 +23,7 @@ import { dom } from "./collapsible.dom"

watch: {
open: ["toggleVisibility"],
open: ["allowAnimation", "toggleVisibility"],
},
entry: ["computeSize"],
exit: ["clearAnimationStyles"],
activities: ["trackMountAnimation"],
states: {

@@ -37,6 +34,15 @@ closed: {

on: {
"CONTROLLED.OPEN": "open",
"CONTROLLED.OPEN": {
target: "open",
actions: ["computeSize"],
},
OPEN: [
{ guard: "isOpenControlled", actions: ["invokeOnOpen"] },
{ target: "open", actions: ["invokeOnOpen"] },
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"],
},
{
target: "open",
actions: ["allowAnimation", "invokeOnOpen"],
},
],

@@ -53,8 +59,20 @@ },

OPEN: [
{ guard: "isOpenControlled", actions: ["invokeOnOpen"] },
{ target: "open", actions: ["invokeOnOpen"] },
{
guard: "isOpenControlled",
actions: ["invokeOnOpen"],
},
{
target: "open",
actions: ["allowAnimation", "invokeOnOpen"],
},
],
CLOSE: [
{ guard: "isOpenControlled", actions: ["invokeOnClose"] },
{ target: "closed", actions: ["computeSize"] },
{
guard: "isOpenControlled",
actions: ["invokeOnClose"],
},
{
target: "closed",
actions: ["allowAnimation", "computeSize"],
},
],

@@ -68,6 +86,15 @@ "ANIMATION.END": "closed",

on: {
"CONTROLLED.CLOSE": { target: "closing", actions: ["computeSize"] },
"CONTROLLED.CLOSE": {
target: "closing",
actions: ["computeSize"],
},
CLOSE: [
{ guard: "isOpenControlled", actions: ["invokeOnClose"] },
{ target: "closing", actions: ["computeSize"] },
{
guard: "isOpenControlled",
actions: ["invokeOnClose"],
},
{
target: "closing",
actions: ["allowAnimation", "computeSize"],
},
],

@@ -83,25 +110,34 @@ },

activities: {
trackMountAnimation(ctx) {
const cleanup = raf(() => {
ctx.isMountAnimationPrevented = false
})
return () => {
ctx.isMountAnimationPrevented = true
cleanup()
}
},
trackAnimationEvents(ctx, _evt, { send }) {
const contentEl = dom.getContentEl(ctx)
if (!contentEl) return
let cleanup: VoidFunction | undefined
const onEnd = (event: AnimationEvent) => {
if (event.target !== contentEl) return
send({ type: "ANIMATION.END" })
}
const rafCleanup = raf(() => {
const contentEl = dom.getContentEl(ctx)
if (!contentEl) return
contentEl.addEventListener("animationend", onEnd)
contentEl.addEventListener("animationcancel", onEnd)
// if there's no animation, send ANIMATION.END immediately
const isAnimationNone = getComputedStyle(contentEl).animationName === "none"
if (isAnimationNone) {
send({ type: "ANIMATION.END" })
return
}
const onEnd = (event: AnimationEvent) => {
if (event.target !== contentEl) return
send({ type: "ANIMATION.END" })
}
contentEl.addEventListener("animationend", onEnd)
contentEl.addEventListener("animationcancel", onEnd)
cleanup = () => {
contentEl.removeEventListener("animationend", onEnd)
contentEl.removeEventListener("animationcancel", onEnd)
}
})
return () => {
contentEl.removeEventListener("animationend", onEnd)
contentEl.removeEventListener("animationcancel", onEnd)
rafCleanup()
cleanup?.()
}

@@ -111,29 +147,34 @@ },

actions: {
allowAnimation(ctx) {
ctx.isMountAnimationPrevented = false
},
computeSize: (ctx) => {
const contentEl = dom.getContentEl(ctx)
if (!contentEl) return
raf(() => {
const contentEl = dom.getContentEl(ctx)
if (!contentEl) return
ctx.stylesRef ||= ref({
animationName: contentEl.style.animationName,
animationDuration: contentEl.style.animationDuration,
})
ctx.stylesRef ||= ref({
animationName: contentEl.style.animationName,
animationDuration: contentEl.style.animationDuration,
})
const hidden = contentEl.hidden
const hidden = contentEl.hidden
// block any animations/transitions so the element renders at its full dimensions
contentEl.style.animationName = "none"
contentEl.style.animationDuration = "0s"
contentEl.hidden = false
// block any animations/transitions so the element renders at its full dimensions
contentEl.style.animationName = "none"
contentEl.style.animationDuration = "0s"
contentEl.hidden = false
const rect = contentEl.getBoundingClientRect()
ctx.height = rect.height
ctx.width = rect.width
const rect = contentEl.getBoundingClientRect()
ctx.height = rect.height
ctx.width = rect.width
// kick off any animations/transitions that were originally set up if it isn't the initial mount
if (!ctx.isMountAnimationPrevented) {
contentEl.style.animationName = ctx.stylesRef.animationName
contentEl.style.animationDuration = ctx.stylesRef.animationDuration
}
// kick off any animations/transitions that were originally set up if it isn't the initial mount
if (!ctx.isMountAnimationPrevented) {
contentEl.style.animationName = ctx.stylesRef.animationName
contentEl.style.animationDuration = ctx.stylesRef.animationDuration
}
contentEl.hidden = hidden
contentEl.hidden = hidden
})
},

@@ -149,11 +190,2 @@ invokeOnOpen: (ctx) => {

},
clearAnimationStyles: (ctx) => {
// cleanup any animation properties that were set (esp for React.StrictMode)
const contentEl = dom.getContentEl(ctx)
if (!contentEl) return
raf(() => {
contentEl.style.animationName = ""
contentEl.style.animationDuration = ""
})
},
},

@@ -160,0 +192,0 @@ },

import { createProps } from "@zag-js/types"
import { createSplitProps } from "@zag-js/utils"
import type { UserDefinedContext } from "./collapsible.types"

@@ -14,1 +15,2 @@

])
export const splitProps = createSplitProps<Partial<UserDefinedContext>>(props)

@@ -92,2 +92,6 @@ import type { StateMachine as S } from "@zag-js/core"

/**
* Whether the collapsible is visible (open or closing)
*/
isVisible: boolean
/**
* Whether the collapsible is disabled

@@ -94,0 +98,0 @@ */

export { anatomy } from "./collapsible.anatomy"
export { connect } from "./collapsible.connect"
export { machine } from "./collapsible.machine"
export * from "./collapsible.props"
export type {

@@ -5,0 +6,0 @@ MachineApi as Api,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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