@zealakit/disclosure-vanilla 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +190 -2
- package/dist/accordion.d.ts +5 -0
- package/dist/animation.d.ts +38 -0
- package/dist/collapsible.d.ts +5 -0
- package/dist/create-disclosure.d.ts +31 -0
- package/dist/dom.d.ts +26 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.global.js +743 -0
- package/dist/index.global.min.js +31 -0
- package/dist/index.js +529 -0
- package/dist/styles.d.ts +2 -0
- package/package.json +69 -4
package/README.md
CHANGED
|
@@ -1,3 +1,191 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @zealakit/disclosure-vanilla
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[English](https://github.com/zealakit/disclosure/blob/main/packages/vanilla/README.md) | [Tiếng Việt](https://github.com/zealakit/disclosure/blob/main/packages/vanilla/README_VI.md) | [中文](https://github.com/zealakit/disclosure/blob/main/packages/vanilla/README_CN.md)
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
Headless Collapsible and Accordion for vanilla JavaScript and static HTML. Provides state, accessibility, and a built-in height animation — no React, Vue, or Svelte required. You own visual styling.
|
|
8
|
+
|
|
9
|
+
Author semantic HTML with `data-*` attributes, then call `createDisclosure()` once. Put padding, borders, and backgrounds on the content element’s class (moved onto `[data-collapsible-content-wrapper]` at init) so exit animations collapse cleanly.
|
|
10
|
+
|
|
11
|
+
> **Note**
|
|
12
|
+
>
|
|
13
|
+
> Disclosure is not a replacement for a full UI library. Use it when Accordion or Collapsible in your kit is hard to restyle — or when you only need that one primitive and don’t want to pull in a large design system.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
### npm / bundler
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i @zealakit/disclosure-vanilla
|
|
21
|
+
# or: pnpm add / yarn add / bun add
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
No peer dependencies. Works with a bundler (Vite, esbuild, …) or a browser import map pointing at the ESM build.
|
|
25
|
+
|
|
26
|
+
### CDN (static HTML)
|
|
27
|
+
|
|
28
|
+
Pin a published version in production. Do **not** use unversioned `latest` CDN URLs.
|
|
29
|
+
|
|
30
|
+
Published browser artifacts:
|
|
31
|
+
|
|
32
|
+
| File | Use |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| `dist/index.js` | ESM (bundlers, import maps, jsDelivr `/+esm`, esm.sh) |
|
|
35
|
+
| `dist/index.d.ts` | TypeScript declarations |
|
|
36
|
+
| `dist/index.global.js` | IIFE script tag (readable) |
|
|
37
|
+
| `dist/index.global.min.js` | IIFE script tag (minified, preferred for CDN) |
|
|
38
|
+
|
|
39
|
+
Global namespace for the IIFE build: **`ZealakitDisclosure`**.
|
|
40
|
+
|
|
41
|
+
#### 1. Native ESM CDN
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<script type="module">
|
|
45
|
+
import { createDisclosure } from "https://cdn.jsdelivr.net/npm/@zealakit/disclosure-vanilla@1.0.0/+esm";
|
|
46
|
+
|
|
47
|
+
const disclosure = createDisclosure();
|
|
48
|
+
</script>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Also works with esm.sh:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<script type="module">
|
|
55
|
+
import { createDisclosure } from "https://esm.sh/@zealakit/disclosure-vanilla@1.0.0";
|
|
56
|
+
|
|
57
|
+
const disclosure = createDisclosure();
|
|
58
|
+
</script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### 2. Direct script CDN (IIFE)
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<script src="https://cdn.jsdelivr.net/npm/@zealakit/disclosure-vanilla@1.0.0/dist/index.global.min.js"></script>
|
|
65
|
+
<script>
|
|
66
|
+
const disclosure = ZealakitDisclosure.createDisclosure();
|
|
67
|
+
</script>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Unminified IIFE (debugging): `…/dist/index.global.js`.
|
|
71
|
+
|
|
72
|
+
## Quick start
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<div data-disclosure>
|
|
76
|
+
<button type="button" data-disclosure-trigger aria-expanded="false">
|
|
77
|
+
Toggle content
|
|
78
|
+
</button>
|
|
79
|
+
<div id="content-1" data-disclosure-content hidden>
|
|
80
|
+
Content
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<script type="module">
|
|
85
|
+
import { createDisclosure } from "@zealakit/disclosure-vanilla";
|
|
86
|
+
const disclosure = createDisclosure();
|
|
87
|
+
// disclosure.refresh() after inserting new markup
|
|
88
|
+
// disclosure.destroy() when tearing down
|
|
89
|
+
</script>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Public API
|
|
93
|
+
|
|
94
|
+
| Export | Description |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `createDisclosure(root?)` | Initialize all `[data-disclosure]` / `[data-accordion]` under `document` or a root node |
|
|
97
|
+
| `createDisclosure({ root })` | Same, options object form |
|
|
98
|
+
| `DisclosureController.destroy()` | Remove listeners and restore content nodes |
|
|
99
|
+
| `DisclosureController.refresh()` | Destroy + re-scan (for dynamically inserted markup) |
|
|
100
|
+
| `DEFAULT_ANIMATION_*` | Same animation defaults as framework packages |
|
|
101
|
+
| `resolveAnimationConfig` / `getCollapsibleAnimationStyle` | Shared animation helpers |
|
|
102
|
+
|
|
103
|
+
## Collapsible markup
|
|
104
|
+
|
|
105
|
+
| Attribute | On | Description |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| `data-disclosure` | root | Marks a Collapsible root |
|
|
108
|
+
| `data-disclosure-trigger` | `<button type="button">` | Toggle control |
|
|
109
|
+
| `data-disclosure-content` | content region | Panel body |
|
|
110
|
+
| `data-default-open` | root | Start expanded (`false` by default) |
|
|
111
|
+
| `data-disabled` | root | Disable interaction |
|
|
112
|
+
| `data-force-mount` | content | Keep content in the DOM while closed |
|
|
113
|
+
| `data-animated` | root | `"false"` disables height animation (default on) |
|
|
114
|
+
| `data-animation-timing-function` | root | `linear` \| `ease-in-out` (default `ease-in-out`) |
|
|
115
|
+
| `data-animation-duration` | root | Duration ms (default `200`) |
|
|
116
|
+
| `data-animation-delay` | root | Delay ms (default `0`) |
|
|
117
|
+
|
|
118
|
+
Root attributes after init: `data-slot="collapsible"`, `data-state="open" \| "closed"`, `data-disabled` when disabled. Triggers get `aria-expanded` / `aria-controls`.
|
|
119
|
+
|
|
120
|
+
## Accordion markup
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<div data-accordion data-accordion-type="single" data-collapsible>
|
|
124
|
+
<section data-accordion-item data-value="item-1">
|
|
125
|
+
<h3>
|
|
126
|
+
<button type="button" data-accordion-trigger>
|
|
127
|
+
First item
|
|
128
|
+
</button>
|
|
129
|
+
</h3>
|
|
130
|
+
<div id="accordion-content-1" data-accordion-content hidden>
|
|
131
|
+
First content
|
|
132
|
+
</div>
|
|
133
|
+
</section>
|
|
134
|
+
</div>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
| Attribute | On | Description |
|
|
138
|
+
| --- | --- | --- |
|
|
139
|
+
| `data-accordion` | root | Marks an Accordion root |
|
|
140
|
+
| `data-accordion-type` | root | `single` (default) \| `multiple` |
|
|
141
|
+
| `data-collapsible` | root | Allow closing the open item in single mode |
|
|
142
|
+
| `data-default-value` | root | Initial value(s); space/comma-separated for `multiple` |
|
|
143
|
+
| `data-disabled` | root or item | Disable root or a single item |
|
|
144
|
+
| `data-accordion-item` + `data-value` | item | Stable item id |
|
|
145
|
+
| `data-accordion-trigger` | `<button>` | Item trigger (prefer inside `h2`–`h6`) |
|
|
146
|
+
| `data-accordion-content` | panel | Item content region |
|
|
147
|
+
| Animation attrs | root | Same as Collapsible |
|
|
148
|
+
|
|
149
|
+
Keyboard (enabled triggers): `ArrowDown` / `ArrowUp` / `Home` / `End`. Nested accordions are independent.
|
|
150
|
+
|
|
151
|
+
## Animation
|
|
152
|
+
|
|
153
|
+
Height animation uses CSS `grid-template-rows` (`minmax(0, 0fr)` ↔ `minmax(0, 1fr)`), enabled by default. `prefers-reduced-motion: reduce` disables motion. Content stays mounted through the exit transition, then detaches unless `data-force-mount` is set.
|
|
154
|
+
|
|
155
|
+
CSS variables on the content viewport:
|
|
156
|
+
|
|
157
|
+
- `--collapsible-animation-duration`
|
|
158
|
+
- `--collapsible-animation-easing`
|
|
159
|
+
- `--collapsible-animation-delay`
|
|
160
|
+
|
|
161
|
+
## Styling
|
|
162
|
+
|
|
163
|
+
Headless — no themes or icons. Style via your CSS and:
|
|
164
|
+
|
|
165
|
+
- `data-slot` — `collapsible`, `collapsible-trigger`, `collapsible-content`, `accordion`, `accordion-item`, `accordion-heading`, `accordion-trigger`, `accordion-content`
|
|
166
|
+
- `data-state` — `open` \| `closed`
|
|
167
|
+
- `data-disabled`
|
|
168
|
+
|
|
169
|
+
Put chrome on the content element’s class/style (applied to `[data-collapsible-content-wrapper]`).
|
|
170
|
+
|
|
171
|
+
## Lifecycle
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
const disclosure = createDisclosure(document.getElementById("app"));
|
|
175
|
+
|
|
176
|
+
// After dynamically inserting markup:
|
|
177
|
+
disclosure.refresh();
|
|
178
|
+
|
|
179
|
+
// On page teardown / SPA unmount:
|
|
180
|
+
disclosure.destroy();
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Calling `createDisclosure()` twice on the same roots does not register duplicate listeners. Use `refresh()` or `destroy()` + `createDisclosure()` when markup changes.
|
|
184
|
+
|
|
185
|
+
## Agent skill
|
|
186
|
+
|
|
187
|
+
Practical agent instructions: [skills/disclosure-vanilla.md](https://github.com/zealakit/disclosure/blob/main/skills/disclosure-vanilla.md)
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT © Zealakit
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type AnimationTimingFunction = "linear" | "ease-in-out";
|
|
2
|
+
export type CollapsibleAnimationProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Whether expand/collapse uses the built-in height animation.
|
|
5
|
+
* @default true
|
|
6
|
+
*/
|
|
7
|
+
animated?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* CSS timing function for expand/collapse.
|
|
10
|
+
* @default "ease-in-out"
|
|
11
|
+
*/
|
|
12
|
+
animationTimingFunction?: AnimationTimingFunction;
|
|
13
|
+
/**
|
|
14
|
+
* Transition duration in milliseconds.
|
|
15
|
+
* @default 200
|
|
16
|
+
*/
|
|
17
|
+
animationDuration?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Transition delay in milliseconds.
|
|
20
|
+
* @default 0
|
|
21
|
+
*/
|
|
22
|
+
animationDelay?: number;
|
|
23
|
+
};
|
|
24
|
+
export type ResolvedAnimationConfig = {
|
|
25
|
+
animated: boolean;
|
|
26
|
+
animationTimingFunction: AnimationTimingFunction;
|
|
27
|
+
animationDuration: number;
|
|
28
|
+
animationDelay: number;
|
|
29
|
+
};
|
|
30
|
+
export declare const DEFAULT_ANIMATION_DURATION_MS = 200;
|
|
31
|
+
export declare const DEFAULT_ANIMATION_DELAY_MS = 0;
|
|
32
|
+
export declare const DEFAULT_ANIMATION_TIMING_FUNCTION: AnimationTimingFunction;
|
|
33
|
+
export declare function resolveAnimationConfig(props?: CollapsibleAnimationProps): ResolvedAnimationConfig;
|
|
34
|
+
export declare function getCollapsibleAnimationStyle(config: Pick<ResolvedAnimationConfig, "animationTimingFunction" | "animationDuration" | "animationDelay">): {
|
|
35
|
+
"--collapsible-animation-duration": string;
|
|
36
|
+
"--collapsible-animation-easing": AnimationTimingFunction;
|
|
37
|
+
"--collapsible-animation-delay": string;
|
|
38
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type CreateDisclosureOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* Scope initialization to this subtree. Defaults to `document`.
|
|
4
|
+
*/
|
|
5
|
+
root?: ParentNode | null;
|
|
6
|
+
};
|
|
7
|
+
export type DisclosureController = {
|
|
8
|
+
/**
|
|
9
|
+
* Tear down all managed instances and restore content nodes.
|
|
10
|
+
*/
|
|
11
|
+
destroy: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Destroy current instances and re-scan the root for markup.
|
|
14
|
+
* Use after dynamically inserting disclosure/accordion HTML.
|
|
15
|
+
*/
|
|
16
|
+
refresh: () => void;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Initialize all `[data-disclosure]` and `[data-accordion]` trees under `root`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { createDisclosure } from "@zealakit/disclosure-vanilla";
|
|
24
|
+
*
|
|
25
|
+
* const disclosure = createDisclosure();
|
|
26
|
+
* // later…
|
|
27
|
+
* disclosure.refresh();
|
|
28
|
+
* disclosure.destroy();
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createDisclosure(options?: CreateDisclosureOptions | ParentNode | null): DisclosureController;
|
package/dist/dom.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare function nextId(prefix: string): string;
|
|
2
|
+
export declare function parseBooleanAttribute(element: Element, name: string, defaultValue?: boolean): boolean;
|
|
3
|
+
export declare function parseNumberAttribute(element: Element, name: string): number | undefined;
|
|
4
|
+
export declare function setDataState(element: Element, open: boolean): void;
|
|
5
|
+
export declare function setDisabledAttr(element: Element, disabled: boolean): void;
|
|
6
|
+
export declare function setInert(element: HTMLElement, inert: boolean): void;
|
|
7
|
+
/**
|
|
8
|
+
* Find descendants matching `selector` that belong to `owner` via `closestAttr`,
|
|
9
|
+
* without descending into nested owners with the same attribute.
|
|
10
|
+
*/
|
|
11
|
+
export declare function queryOwned(owner: Element, closestAttr: string, selector: string): HTMLElement[];
|
|
12
|
+
export declare function ensureContentWrapper(content: HTMLElement): HTMLElement;
|
|
13
|
+
export type PresenceController = {
|
|
14
|
+
sync: (open: boolean) => void;
|
|
15
|
+
destroy: () => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Mirrors framework presence: keep content mounted through exit animation,
|
|
19
|
+
* then detach from the DOM unless forceMount is set.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createPresence(options: {
|
|
22
|
+
content: HTMLElement;
|
|
23
|
+
animated: boolean;
|
|
24
|
+
forceMount: boolean;
|
|
25
|
+
getOpen: () => boolean;
|
|
26
|
+
}): PresenceController;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createDisclosure, type CreateDisclosureOptions, type DisclosureController, } from "./create-disclosure";
|
|
2
|
+
export type { AnimationTimingFunction, CollapsibleAnimationProps, ResolvedAnimationConfig, } from "./animation";
|
|
3
|
+
export { DEFAULT_ANIMATION_DELAY_MS, DEFAULT_ANIMATION_DURATION_MS, DEFAULT_ANIMATION_TIMING_FUNCTION, getCollapsibleAnimationStyle, resolveAnimationConfig, } from "./animation";
|
|
4
|
+
export { ensureCollapsibleStyles, prefersReducedMotion } from "./styles";
|