@excom/content-drawer 0.1.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.
Files changed (43) hide show
  1. package/.rush/temp/chunked-rush-logs/content-drawer.apply-exports.chunks.jsonl +1 -0
  2. package/.rush/temp/chunked-rush-logs/content-drawer.build_docs.chunks.jsonl +1 -0
  3. package/.rush/temp/chunked-rush-logs/content-drawer.build_package-metas.chunks.jsonl +1 -0
  4. package/.rush/temp/operation/apply-exports/all.log +1 -0
  5. package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
  6. package/.rush/temp/operation/apply-exports/state.json +3 -0
  7. package/.rush/temp/operation/build_docs/all.log +1 -0
  8. package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
  9. package/.rush/temp/operation/build_docs/state.json +3 -0
  10. package/.rush/temp/operation/build_package-metas/all.log +1 -0
  11. package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
  12. package/.rush/temp/operation/build_package-metas/state.json +3 -0
  13. package/.rush/temp/shrinkwrap-deps.json +3 -0
  14. package/config/rig.json +5 -0
  15. package/content-drawer.ts +205 -0
  16. package/index.css +5 -0
  17. package/index.ts +17 -0
  18. package/package.json +44 -0
  19. package/rush-logs/content-drawer.apply-exports.cache.log +1 -0
  20. package/rush-logs/content-drawer.apply-exports.log +1 -0
  21. package/rush-logs/content-drawer.build_docs.cache.log +1 -0
  22. package/rush-logs/content-drawer.build_docs.log +1 -0
  23. package/rush-logs/content-drawer.build_package-metas.cache.log +1 -0
  24. package/rush-logs/content-drawer.build_package-metas.log +1 -0
  25. package/src/content-drawer.css +344 -0
  26. package/support/custom-elements.json +360 -0
  27. package/support/demos/disappear.html +8 -0
  28. package/support/demos/dismiss.html +16 -0
  29. package/support/demos/from-side.html +9 -0
  30. package/support/demos/simple.html +12 -0
  31. package/support/demos/singleton.html +16 -0
  32. package/support/demos/stages.html +18 -0
  33. package/support/dist-docs/content-drawer.md +252 -0
  34. package/support/docs/README.md +69 -0
  35. package/support/package-meta.json +299 -0
  36. package/support/tests/content-drawer.test.ts +388 -0
  37. package/support/tests/disappear.view.test.ts +32 -0
  38. package/support/tests/dismiss.view.test.ts +61 -0
  39. package/support/tests/from-side.view.test.ts +32 -0
  40. package/support/tests/simple.view.test.ts +40 -0
  41. package/support/tests/singleton.view.test.ts +35 -0
  42. package/support/tests/stages.view.test.ts +39 -0
  43. package/tsconfig.json +5 -0
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
@@ -0,0 +1 @@
1
+ Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 33.706642999999985
3
+ }
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 54.51659700000005
3
+ }
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 109.20764600000007
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "../../packages/content-drawer": "../../packages/content-drawer:jBi1kG66FeHydRSlEDv+j1OmUyYZvtYazxNti9QBCwU=:"
3
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
3
+ "rigPackageName": "@excom/heft-rig",
4
+ "rigProfile": "default"
5
+ }
@@ -0,0 +1,205 @@
1
+ import {
2
+ ConstructorType,
3
+ Neutron,
4
+ NeutronElement,
5
+ TEvent,
6
+ } from "@excom/neutron";
7
+
8
+ /**
9
+ * Props the invoker of `--open` / `--toggle` may set through its `data-*`
10
+ * attributes (`data-open-stage="1"` → `openStage`). Keys are whitelisted
11
+ * against declared, non-private props; `isOpen` is always the command's.
12
+ */
13
+ export type ContentDrawerCommandData = Partial<{
14
+ openStage: number;
15
+ fromSide: string;
16
+ disappearAfter: number;
17
+ singletonName: string;
18
+ }>;
19
+
20
+ export type ContentDrawerOpenedEvent = TEvent & {
21
+ type: "content-drawer-opened";
22
+ detail: HTMLElement;
23
+ };
24
+
25
+ export type ContentDrawerClosedEvent = TEvent & {
26
+ type: "content-drawer-closed";
27
+ detail: HTMLElement;
28
+ };
29
+
30
+ /**
31
+ * Panel / sheet that slides in from an edge of its positioned parent —
32
+ * bottom sheets, nav drawers, filter panels, toast-style confirmations.
33
+ * Drive it with the `--open` / `--close` / `--toggle` commands (`<button
34
+ * command="--toggle" commandfor="…">`). Pair with a sibling
35
+ * `[role="presentation"]` / `.tag-backdrop` (Valence.css dialog dimmer) and
36
+ * `<event-handler>` / `<dismiss-watcher>` for click / Escape dismissal.
37
+ *
38
+ * @summary Slide-in drawer / sheet — bottom, top, left, or right, with peek stages.
39
+ *
40
+ * @command --open - Opens the drawer (`is-open` set). `data-*` attributes on
41
+ * the invoker that name a declared prop (`data-open-stage`,
42
+ * `data-from-side`, …) are applied first; unknown, private and `isOpen`
43
+ * keys are ignored.
44
+ * @command --close - Closes the drawer (`is-open` unset).
45
+ * @command --toggle - Toggles open / closed. Reads the invoker's `data-*`
46
+ * like `--open`.
47
+ *
48
+ * @fires content-drawer-opened - After open (`is-open` set), `detail` is the
49
+ * drawer. When `singleton-name` is set it is also broadcast so drawers
50
+ * sharing that name close.
51
+ * @type ContentDrawerOpenedEvent
52
+ * @fires content-drawer-closed - After close (`is-open` unset), `detail` is
53
+ * the drawer.
54
+ * @type ContentDrawerClosedEvent
55
+ */
56
+ export const ContentDrawer = Neutron({
57
+ tag: "content-drawer",
58
+ props: {
59
+ /**
60
+ * @option
61
+ * Edge the drawer slides from.
62
+ * @values bottom | top | left | right
63
+ * @default bottom
64
+ */
65
+ fromSide: String,
66
+ /**
67
+ * @option
68
+ * Auto-close after this many seconds once opened — toast-style /
69
+ * transient confirmations.
70
+ */
71
+ disappearAfter: Number,
72
+ /**
73
+ * @option
74
+ * Shared group name. Opening one drawer closes others with the same
75
+ * name (singleton coordination).
76
+ */
77
+ singletonName: String,
78
+ /**
79
+ * @option
80
+ * @state
81
+ * How far the drawer opens: `0` full, `1` half, `2` peek. Unset = full.
82
+ * Set statically, or per open through `data-open-stage` on the
83
+ * `--open` / `--toggle` invoker.
84
+ * @values 0 | 1 | 2
85
+ */
86
+ openStage: {
87
+ type: Number,
88
+ isValid: (value: number) => value >= 0 && value <= 2,
89
+ },
90
+ /**
91
+ * @option
92
+ * @state
93
+ * Open state. Toggle directly, or through the `--open` / `--close` /
94
+ * `--toggle` commands. For Escape / outside-click dismissal pair with
95
+ * `<dismiss-watcher command-name="--close">`.
96
+ */
97
+ isOpen: Boolean,
98
+ // private state
99
+ _timeoutId: Object as unknown as ConstructorType<
100
+ ReturnType<typeof setTimeout>
101
+ >,
102
+ },
103
+ })
104
+ .defineMethods({
105
+ _timeoutCallback: () => ({
106
+ isOpen: false,
107
+ }),
108
+ _emitClosed: (element) => ({
109
+ emit: ["content-drawer-closed", { detail: element }],
110
+ }),
111
+ _singletonCallback: (element, { detail }: CustomEvent<typeof element>) => {
112
+ if (
113
+ element !== detail &&
114
+ element.singletonName &&
115
+ detail?.singletonName &&
116
+ element.singletonName === detail.singletonName
117
+ ) {
118
+ return {
119
+ isOpen: false,
120
+ };
121
+ }
122
+ },
123
+ })
124
+ .onConnected(
125
+ ({ singletonName, _singletonCallback }) =>
126
+ // Re-register after a DOM move / reconnect so the drawer still coordinates
127
+ !!singletonName && {
128
+ toggleBroadcastListeners: [
129
+ ["content-drawer-opened", _singletonCallback, true],
130
+ ],
131
+ }
132
+ )
133
+ .onDisconnected(({ isMoving, _timeoutId }) => {
134
+ // A DOM move keeps the disappear timer running
135
+ if (isMoving || !_timeoutId) {
136
+ return;
137
+ }
138
+ clearTimeout(_timeoutId);
139
+ return {
140
+ _timeoutId: null,
141
+ };
142
+ })
143
+ .onPropUnset("isOpen", ({ _timeoutId }) => {
144
+ if (_timeoutId) {
145
+ clearTimeout(_timeoutId);
146
+ }
147
+ return {
148
+ _timeoutId: null,
149
+ _emitClosed: [],
150
+ };
151
+ })
152
+ .onPropSet(
153
+ "isOpen",
154
+ ({ disappearAfter, _timeoutId, _timeoutCallback }) =>
155
+ !!disappearAfter &&
156
+ !_timeoutId && {
157
+ _timeoutId: setTimeout(_timeoutCallback, disappearAfter * 1000),
158
+ }
159
+ )
160
+ .onPropSet("isOpen", (el) => ({
161
+ emit: ["content-drawer-opened", { detail: el }],
162
+ ...(el.singletonName
163
+ ? { broadcast: ["content-drawer-opened", { detail: el }] }
164
+ : {}),
165
+ }))
166
+ .onPropChanged("singletonName", ({ singletonName, _singletonCallback }) => ({
167
+ toggleBroadcastListeners: [
168
+ ["content-drawer-opened", _singletonCallback, !!singletonName],
169
+ ],
170
+ }))
171
+ .onCommand("--close", () => ({
172
+ isOpen: false,
173
+ }))
174
+ .onCommand("--open", (el, { source }) => ({
175
+ ...propsFromSource(el, source),
176
+ isOpen: true,
177
+ }))
178
+ .onCommand("--toggle", (el, { source }) => ({
179
+ ...propsFromSource(el, source),
180
+ isOpen: !el.isOpen,
181
+ }));
182
+
183
+ /**
184
+ * Props from the invoker's `data-*` attributes (`data-open-stage` →
185
+ * `openStage`), keeping only keys that name a declared, non-`_` prop.
186
+ * Spread the result *before* the command's own writes so an invoker
187
+ * can't force those through its dataset.
188
+ */
189
+ export function propsFromSource(
190
+ element: HTMLElement,
191
+ source: Element | null | undefined
192
+ ): Record<string, unknown> {
193
+ if (!(source instanceof HTMLElement)) {
194
+ return {};
195
+ }
196
+ const config = (element.constructor as typeof NeutronElement).getConfig();
197
+ const declared = new Set(
198
+ Object.values(config?.props ?? {})
199
+ .map((prop) => prop.prop)
200
+ .filter((name) => !name.startsWith("_"))
201
+ );
202
+ return Object.fromEntries(
203
+ Object.entries(source.dataset).filter(([key]) => declared.has(key))
204
+ );
205
+ }
package/index.css ADDED
@@ -0,0 +1,5 @@
1
+ @import "./src/content-drawer.css";
2
+
3
+ @layer {
4
+ @mixin module-content-drawer;
5
+ }
package/index.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { ContentDrawer } from "./content-drawer";
2
+
3
+ ContentDrawer.define();
4
+
5
+ export { ContentDrawer };
6
+
7
+ type T_HTMLContentDrawerElement = typeof ContentDrawer.CustomElement;
8
+ declare global {
9
+ interface HTMLContentDrawerElement extends T_HTMLContentDrawerElement {}
10
+ interface Window {
11
+ HTMLContentDrawerElement: HTMLContentDrawerElement;
12
+ }
13
+ interface HTMLElementTagNameMap {
14
+ "content-drawer": HTMLContentDrawerElement;
15
+ }
16
+ }
17
+ export type { HTMLContentDrawerElement };
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@excom/content-drawer",
3
+ "version": "0.1.0",
4
+ "description": "<content-drawer> custom element",
5
+ "license": "MIT",
6
+ "engines": {
7
+ "node": ">=24.13.0"
8
+ },
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@excom/kit-utils": "^0.1.0",
12
+ "@excom/valence": "^0.1.0",
13
+ "@excom/neutron": "^0.1.0"
14
+ },
15
+ "peerDependencies": {},
16
+ "devDependencies": {
17
+ "@excom/heft-rig": "^0.1.0"
18
+ },
19
+ "repository": {
20
+ "url": "excom-dev/nucleus",
21
+ "directory": "packages/content-drawer"
22
+ },
23
+ "homepage": "https://github.com/excom-dev/nucleus/tree/main/packages/content-drawer/support/docs/README.md",
24
+ "bugs": "https://github.com/excom-dev/nucleus/issues",
25
+ "keywords": [
26
+ "content-drawer",
27
+ "neutron",
28
+ "custom-elements"
29
+ ],
30
+ "excom": {
31
+ "packageType": "kit-element"
32
+ },
33
+ "scripts": {
34
+ "build": "node node_modules/@excom/heft-rig/scripts/vite-build.mjs",
35
+ "build:watch": "node node_modules/@excom/heft-rig/scripts/vite-build-watch.mjs",
36
+ "format": "node node_modules/@excom/heft-rig/scripts/format.mjs",
37
+ "test": "node node_modules/@excom/heft-rig/scripts/vitest.mjs",
38
+ "coverage": "node node_modules/@excom/heft-rig/scripts/coverage.mjs",
39
+ "dev": "node node_modules/@excom/heft-rig/scripts/vite-dev.mjs",
40
+ "preview": "node node_modules/@excom/heft-rig/scripts/vite-preview.mjs",
41
+ "build:package-metas": "node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs",
42
+ "build:docs": "node node_modules/@excom/heft-rig/scripts/build-docs.mjs"
43
+ }
44
+ }
@@ -0,0 +1 @@
1
+ Caching has been disabled for this project's "apply-exports" command.
@@ -0,0 +1 @@
1
+ Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
@@ -0,0 +1 @@
1
+ This project does not define the caching behavior of the "build:docs" command, so caching has been disabled.
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
@@ -0,0 +1 @@
1
+ This project does not define the caching behavior of the "build:package-metas" command, so caching has been disabled.
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs