@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.
- package/.rush/temp/chunked-rush-logs/content-drawer.apply-exports.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/content-drawer.build_docs.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/content-drawer.build_package-metas.chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/all.log +1 -0
- package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/state.json +3 -0
- package/.rush/temp/operation/build_docs/all.log +1 -0
- package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_docs/state.json +3 -0
- package/.rush/temp/operation/build_package-metas/all.log +1 -0
- package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_package-metas/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +3 -0
- package/config/rig.json +5 -0
- package/content-drawer.ts +205 -0
- package/index.css +5 -0
- package/index.ts +17 -0
- package/package.json +44 -0
- package/rush-logs/content-drawer.apply-exports.cache.log +1 -0
- package/rush-logs/content-drawer.apply-exports.log +1 -0
- package/rush-logs/content-drawer.build_docs.cache.log +1 -0
- package/rush-logs/content-drawer.build_docs.log +1 -0
- package/rush-logs/content-drawer.build_package-metas.cache.log +1 -0
- package/rush-logs/content-drawer.build_package-metas.log +1 -0
- package/src/content-drawer.css +344 -0
- package/support/custom-elements.json +360 -0
- package/support/demos/disappear.html +8 -0
- package/support/demos/dismiss.html +16 -0
- package/support/demos/from-side.html +9 -0
- package/support/demos/simple.html +12 -0
- package/support/demos/singleton.html +16 -0
- package/support/demos/stages.html +18 -0
- package/support/dist-docs/content-drawer.md +252 -0
- package/support/docs/README.md +69 -0
- package/support/package-meta.json +299 -0
- package/support/tests/content-drawer.test.ts +388 -0
- package/support/tests/disappear.view.test.ts +32 -0
- package/support/tests/dismiss.view.test.ts +61 -0
- package/support/tests/from-side.view.test.ts +32 -0
- package/support/tests/simple.view.test.ts +40 -0
- package/support/tests/singleton.view.test.ts +35 -0
- package/support/tests/stages.view.test.ts +39 -0
- 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 @@
|
|
|
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 @@
|
|
|
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"}
|
package/config/rig.json
ADDED
|
@@ -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
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
|