@f-ewald/components 1.15.0 → 1.16.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/custom-elements.json +125 -3
- package/dist/icons.d.ts +1 -0
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +1 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/photo-gallery.d.ts +4 -0
- package/dist/photo-gallery.d.ts.map +1 -1
- package/dist/photo-gallery.js +14 -1
- package/dist/photo-gallery.js.map +1 -1
- package/dist/toast-notification.d.ts +27 -9
- package/dist/toast-notification.d.ts.map +1 -1
- package/dist/toast-notification.js +68 -17
- package/dist/toast-notification.js.map +1 -1
- package/dist/tree-view.d.ts +9 -0
- package/dist/tree-view.d.ts.map +1 -1
- package/dist/tree-view.js +66 -4
- package/dist/tree-view.js.map +1 -1
- package/docs/photo-gallery.md +5 -0
- package/docs/toast-notification.md +15 -6
- package/docs/tree-view.md +7 -1
- package/llms.txt +24 -11
- package/package.json +1 -1
package/dist/tree-view.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-view.js","sourceRoot":"","sources":["../src/tree-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, nothing, type TemplateResult } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { iconChevronDown, iconChevronRight } from \"./icons.js\";\nimport { tokens } from \"./tokens.js\";\n\n/** One tree node: a folder when `children` is set (even `[]`), a leaf otherwise. */\nexport interface TreeNode {\n id: string;\n label: string;\n children?: TreeNode[];\n data?: unknown;\n}\n\n/**\n * A generic, presentational tree shell: renders `nodes` recursively, one row\n * per node, with each row's content produced by `renderNode` (default: plain\n * label). Modeled on `data-table`'s headless pattern — knows nothing about\n * what a node's `data` means beyond what `renderNode` does with it.\n *\n * A node with a `children` array (even empty) is a folder: clicking or\n * activating its row toggles expand/collapse instead of firing `node-click`.\n * A node with no `children` is a leaf: clicking or activating its row fires\n * `node-click`. Folders start collapsed; set `default-expanded` to start\n * every folder expanded instead. Expansion state is otherwise managed\n * internally and untouched by later `nodes` updates, so a user's manual\n * toggles survive a data refresh.\n *\n * @element tree-view\n * @fires node-click - A leaf row was activated; detail is `{ id, data }`.\n */\n@customElement(\"tree-view\")\nexport class TreeView extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-size: var(--ui-font-size-sm, 0.75rem);\n }\n .row {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.5rem;\n border-radius: var(--ui-radius-sm, 0.25rem);\n color: var(--ui-text, #0f172a);\n cursor: pointer;\n }\n .row:hover {\n background: var(--ui-surface-muted, #f8fafc);\n }\n .row:focus-visible {\n outline: none;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .toggle {\n display: inline-flex;\n flex-shrink: 0;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n color: var(--ui-text-muted, #64748b);\n }\n .content {\n min-width: 0;\n flex: 1;\n }\n @media (forced-colors: active) {\n .row:focus-visible {\n outline: 2px solid CanvasText;\n outline-offset: -2px;\n box-shadow: none;\n }\n }\n `,\n ];\n\n /** Tree data; opaque to this component beyond what `renderNode` does with it. */\n @property({ attribute: false }) nodes: TreeNode[] = [];\n /** Produces a row's rendered content for `node`. Default: plain label text. */\n @property({ attribute: false }) renderNode: (node: TreeNode) => unknown = (node) => node.label;\n /** Start every folder expanded instead of the default all-collapsed. */\n @property({ type: Boolean, attribute: \"default-expanded\" }) defaultExpanded = false;\n\n @state() private expanded = new Set<string>();\n #initializedExpansion = false;\n\n override willUpdate(changed: Map<string, unknown>): void {\n if (!changed.has(\"nodes\") || this.#initializedExpansion) return;\n this.#initializedExpansion = true;\n if (!this.defaultExpanded) return;\n const all = new Set<string>();\n const collect = (list: TreeNode[]) => {\n for (const node of list) {\n if (!node.children) continue;\n all.add(node.id);\n collect(node.children);\n }\n };\n collect(this.nodes);\n this.expanded = all;\n }\n\n #toggle(id: string): void {\n const next = new Set(this.expanded);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n this.expanded = next;\n }\n\n #activate(node: TreeNode): void {\n if (node.children) {\n this.#toggle(node.id);\n return;\n }\n this.dispatchEvent(\n new CustomEvent(\"node-click\", {\n detail: { id: node.id, data: node.data },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n #onKeydown(node: TreeNode, e: KeyboardEvent): void {\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n if (e.target !== e.currentTarget) return;\n e.preventDefault();\n this.#activate(node);\n }\n\n #onRowClick(node: TreeNode, e: MouseEvent): void {\n if (this.#isNestedInteractive(e.composedPath(), e.currentTarget)) return;\n this.#activate(node);\n }\n\n #isNestedInteractive(path: EventTarget[], row: EventTarget | null): boolean {\n const selector =\n \"a, button, input, select, textarea, summary, [contenteditable], [role='button'], [role='link'], [tabindex]\";\n for (const target of path) {\n if (target === row) return false;\n if (target instanceof HTMLElement && target.matches(selector)) return true;\n }\n return false;\n }\n\n #renderNode(node: TreeNode, depth: number): TemplateResult {\n const isFolder = !!node.children;\n const isOpen = isFolder && this.expanded.has(node.id);\n return html`\n <div\n class=\"row\"\n role=${isFolder ? \"button\" : \"link\"}\n aria-expanded=${isFolder ? String(isOpen) : nothing}\n tabindex=\"0\"\n style=\"padding-left: ${depth * 1.25}rem\"\n @click=${(e: MouseEvent) => this.#onRowClick(node, e)}\n @keydown=${(e: KeyboardEvent) => this.#onKeydown(node, e)}\n >\n <span class=\"toggle\" aria-hidden=\"true\">\n ${isFolder ? (isOpen ? iconChevronDown(14) : iconChevronRight(14)) : nothing}\n </span>\n <span class=\"content\">${this.renderNode(node)}</span>\n </div>\n ${isFolder && isOpen\n ? repeat(\n node.children!,\n (child) => child.id,\n (child) => this.#renderNode(child, depth + 1),\n )\n : nothing}\n `;\n }\n\n override render() {\n return repeat(\n this.nodes,\n (node) => node.id,\n (node) => this.#renderNode(node, 0),\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"tree-view\": TreeView;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tree-view.js","sourceRoot":"","sources":["../src/tree-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, nothing, type TemplateResult } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { iconChevronDown, iconChevronRight } from \"./icons.js\";\nimport { tokens } from \"./tokens.js\";\n\n/** One tree node: a folder when `children` is set (even `[]`), a leaf otherwise. */\nexport interface TreeNode {\n id: string;\n label: string;\n children?: TreeNode[];\n data?: unknown;\n}\n\n/**\n * A generic, presentational tree shell: renders `nodes` recursively, one row\n * per node, with each row's content produced by `renderNode` (default: plain\n * label). Modeled on `data-table`'s headless pattern — knows nothing about\n * what a node's `data` means beyond what `renderNode` does with it.\n *\n * A node with a `children` array (even empty) is a folder: clicking or\n * activating its row toggles expand/collapse instead of firing `node-click`.\n * A node with no `children` is a leaf: clicking or activating its row fires\n * `node-click`. Folders start collapsed; set `default-expanded` to start\n * every folder expanded instead. Expansion state is otherwise managed\n * internally and untouched by later `nodes` updates, so a user's manual\n * toggles survive a data refresh.\n *\n * Set the `lines` boolean to draw classic file-tree connector guides: a\n * vertical line per continuing ancestor level and a branch elbow (`└`) or\n * tee (`├`) linking each node to its parent. Off by default (indentation only).\n *\n * @element tree-view\n * @fires node-click - A leaf row was activated; detail is `{ id, data }`.\n */\n@customElement(\"tree-view\")\nexport class TreeView extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-size: var(--ui-font-size-sm, 0.75rem);\n }\n .row {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.5rem;\n border-radius: var(--ui-radius-sm, 0.25rem);\n color: var(--ui-text, #0f172a);\n cursor: pointer;\n }\n .row:hover {\n background: var(--ui-surface-muted, #f8fafc);\n }\n .row:focus-visible {\n outline: none;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .toggle {\n display: inline-flex;\n flex-shrink: 0;\n width: 1rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n color: var(--ui-text-muted, #64748b);\n }\n .content {\n min-width: 0;\n flex: 1;\n }\n :host([lines]) .row {\n padding-top: 0;\n padding-bottom: 0;\n min-height: 1.5rem;\n }\n .guides {\n display: flex;\n align-self: stretch;\n flex-shrink: 0;\n }\n .guide {\n position: relative;\n flex: 0 0 auto;\n width: 1rem;\n }\n .guide.v::before,\n .guide.connector::before {\n content: \"\";\n position: absolute;\n left: 50%;\n top: 0;\n bottom: 0;\n border-left: 1px solid var(--ui-border, #e2e8f0);\n }\n .guide.connector.last::before {\n bottom: 50%;\n }\n .guide.connector::after {\n content: \"\";\n position: absolute;\n left: 50%;\n right: 0;\n top: 50%;\n border-top: 1px solid var(--ui-border, #e2e8f0);\n }\n @media (forced-colors: active) {\n .row:focus-visible {\n outline: 2px solid CanvasText;\n outline-offset: -2px;\n box-shadow: none;\n }\n .guide.v::before,\n .guide.connector::before,\n .guide.connector::after {\n border-color: CanvasText;\n }\n }\n `,\n ];\n\n /** Tree data; opaque to this component beyond what `renderNode` does with it. */\n @property({ attribute: false }) nodes: TreeNode[] = [];\n /** Produces a row's rendered content for `node`. Default: plain label text. */\n @property({ attribute: false }) renderNode: (node: TreeNode) => unknown = (node) => node.label;\n /** Start every folder expanded instead of the default all-collapsed. */\n @property({ type: Boolean, attribute: \"default-expanded\" }) defaultExpanded = false;\n /**\n * Draw classic file-tree connector guides (vertical ancestor lines plus a\n * branch elbow/tee per row) instead of indentation alone. Off by default.\n */\n @property({ type: Boolean, reflect: true }) lines = false;\n\n @state() private expanded = new Set<string>();\n #initializedExpansion = false;\n\n override willUpdate(changed: Map<string, unknown>): void {\n if (!changed.has(\"nodes\") || this.#initializedExpansion) return;\n this.#initializedExpansion = true;\n if (!this.defaultExpanded) return;\n const all = new Set<string>();\n const collect = (list: TreeNode[]) => {\n for (const node of list) {\n if (!node.children) continue;\n all.add(node.id);\n collect(node.children);\n }\n };\n collect(this.nodes);\n this.expanded = all;\n }\n\n #toggle(id: string): void {\n const next = new Set(this.expanded);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n this.expanded = next;\n }\n\n #activate(node: TreeNode): void {\n if (node.children) {\n this.#toggle(node.id);\n return;\n }\n this.dispatchEvent(\n new CustomEvent(\"node-click\", {\n detail: { id: node.id, data: node.data },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n #onKeydown(node: TreeNode, e: KeyboardEvent): void {\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n if (e.target !== e.currentTarget) return;\n e.preventDefault();\n this.#activate(node);\n }\n\n #onRowClick(node: TreeNode, e: MouseEvent): void {\n if (this.#isNestedInteractive(e.composedPath(), e.currentTarget)) return;\n this.#activate(node);\n }\n\n #isNestedInteractive(path: EventTarget[], row: EventTarget | null): boolean {\n const selector =\n \"a, button, input, select, textarea, summary, [contenteditable], [role='button'], [role='link'], [tabindex]\";\n for (const target of path) {\n if (target === row) return false;\n if (target instanceof HTMLElement && target.matches(selector)) return true;\n }\n return false;\n }\n\n #renderNode(\n node: TreeNode,\n depth: number,\n isLast: boolean,\n ancestorHasNext: boolean[],\n ): TemplateResult {\n const isFolder = !!node.children;\n const isOpen = isFolder && this.expanded.has(node.id);\n const guides = this.lines\n ? html`<span class=\"guides\" aria-hidden=\"true\">\n ${ancestorHasNext.map(\n (hasNext) => html`<span class=\"guide ${hasNext ? \"v\" : \"\"}\"></span>`,\n )}\n <span class=\"guide connector ${isLast ? \"last\" : \"\"}\"></span>\n </span>`\n : nothing;\n return html`\n <div\n class=\"row\"\n role=${isFolder ? \"button\" : \"link\"}\n aria-expanded=${isFolder ? String(isOpen) : nothing}\n tabindex=\"0\"\n style=${this.lines ? nothing : `padding-left: ${depth * 1.25}rem`}\n @click=${(e: MouseEvent) => this.#onRowClick(node, e)}\n @keydown=${(e: KeyboardEvent) => this.#onKeydown(node, e)}\n >\n ${guides}\n <span class=\"toggle\" aria-hidden=\"true\">\n ${isFolder ? (isOpen ? iconChevronDown(14) : iconChevronRight(14)) : nothing}\n </span>\n <span class=\"content\">${this.renderNode(node)}</span>\n </div>\n ${isFolder && isOpen\n ? repeat(\n node.children!,\n (child) => child.id,\n (child, i) =>\n this.#renderNode(child, depth + 1, i === node.children!.length - 1, [\n ...ancestorHasNext,\n !isLast,\n ]),\n )\n : nothing}\n `;\n }\n\n override render() {\n return repeat(\n this.nodes,\n (node) => node.id,\n (node, i) => this.#renderNode(node, 0, i === this.nodes.length - 1, []),\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"tree-view\": TreeView;\n }\n}\n"]}
|
package/docs/photo-gallery.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
Responsive, accessible image carousel composed from declarative
|
|
4
4
|
`gallery-item` children.
|
|
5
5
|
|
|
6
|
+
The image viewport keeps a fixed `aspect-ratio`, and the caption row is
|
|
7
|
+
reserved for every slide whenever any slide has a caption, so the carousel's
|
|
8
|
+
total height stays constant as it cycles — it never shifts the page below it.
|
|
9
|
+
|
|
6
10
|
## Install
|
|
7
11
|
|
|
8
12
|
```js
|
|
@@ -67,6 +71,7 @@ import "@f-ewald/components/photo-gallery.js";
|
|
|
67
71
|
| `--ui-font` |
|
|
68
72
|
| `--ui-font-size` |
|
|
69
73
|
| `--ui-font-size-sm` |
|
|
74
|
+
| `--ui-line-height-normal` |
|
|
70
75
|
| `--ui-line-height-tight` |
|
|
71
76
|
| `--ui-on-accent` |
|
|
72
77
|
| `--ui-overlay` |
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# `<toast-notification>`
|
|
2
2
|
|
|
3
3
|
Fixed-position stack of dismissible notifications, anchored top-right
|
|
4
|
-
(top-full-width on mobile).
|
|
5
|
-
|
|
4
|
+
(top-full-width on mobile). Every toast shares one fixed width so entries
|
|
5
|
+
never appear narrower or wider than one another. Not wired to any app state
|
|
6
|
+
yet — callers add toasts imperatively via the `show()` method on a live
|
|
7
|
+
element reference,
|
|
6
8
|
e.g. `document.querySelector('toast-notification')?.show('Offline', { variant: 'error' })`,
|
|
7
9
|
or via the `notifySuccess`/`notifyError`/`notifyInfo` module-level helpers
|
|
8
|
-
exported from this file.
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
exported from this file. The first argument is the required bold headline; an
|
|
11
|
+
optional `description` renders a smaller, non-bold second line. Each variant
|
|
12
|
+
leads with a matching status icon (success → check, error → exclamation
|
|
13
|
+
circle, info → information circle, warning → exclamation triangle). Each toast
|
|
14
|
+
auto-dismisses after `duration` ms and can also be dismissed via its ✕
|
|
15
|
+
button. Appears/disappears instantly — no slide/fade transitions.
|
|
11
16
|
|
|
12
17
|
## Install
|
|
13
18
|
|
|
@@ -21,7 +26,7 @@ import "@f-ewald/components/toast-notification.js";
|
|
|
21
26
|
<toast-notification></toast-notification>
|
|
22
27
|
<script type="module">
|
|
23
28
|
import { notifySuccess } from "@f-ewald/components/toast-notification.js";
|
|
24
|
-
notifySuccess("Saved!");
|
|
29
|
+
notifySuccess("Saved!", "Your changes are now live.");
|
|
25
30
|
</script>
|
|
26
31
|
```
|
|
27
32
|
|
|
@@ -45,6 +50,9 @@ _None._
|
|
|
45
50
|
| `--ui-focus-ring` |
|
|
46
51
|
| `--ui-font` |
|
|
47
52
|
| `--ui-font-size` |
|
|
53
|
+
| `--ui-font-size-sm` |
|
|
54
|
+
| `--ui-font-weight-regular` |
|
|
55
|
+
| `--ui-font-weight-semibold` |
|
|
48
56
|
| `--ui-hover-overlay` |
|
|
49
57
|
| `--ui-info` |
|
|
50
58
|
| `--ui-line-height-glyph` |
|
|
@@ -55,3 +63,4 @@ _None._
|
|
|
55
63
|
| `--ui-shadow-lg` |
|
|
56
64
|
| `--ui-success` |
|
|
57
65
|
| `--ui-text` |
|
|
66
|
+
| `--ui-warning` |
|
package/docs/tree-view.md
CHANGED
|
@@ -13,6 +13,10 @@ every folder expanded instead. Expansion state is otherwise managed
|
|
|
13
13
|
internally and untouched by later `nodes` updates, so a user's manual
|
|
14
14
|
toggles survive a data refresh.
|
|
15
15
|
|
|
16
|
+
Set the `lines` boolean to draw classic file-tree connector guides: a
|
|
17
|
+
vertical line per continuing ancestor level and a branch elbow (`└`) or
|
|
18
|
+
tee (`├`) linking each node to its parent. Off by default (indentation only).
|
|
19
|
+
|
|
16
20
|
## Install
|
|
17
21
|
|
|
18
22
|
```js
|
|
@@ -22,7 +26,7 @@ import "@f-ewald/components/tree-view.js";
|
|
|
22
26
|
## Usage
|
|
23
27
|
|
|
24
28
|
```html
|
|
25
|
-
<tree-view></tree-view>
|
|
29
|
+
<tree-view lines></tree-view>
|
|
26
30
|
<script type="module">
|
|
27
31
|
const tree = document.querySelector("tree-view");
|
|
28
32
|
tree.nodes = [
|
|
@@ -45,6 +49,7 @@ import "@f-ewald/components/tree-view.js";
|
|
|
45
49
|
| `nodes` | _(JS property only)_ | `TreeNode[]` | `[]` | Tree data; opaque to this component beyond what `renderNode` does with it. |
|
|
46
50
|
| `renderNode` | _(JS property only)_ | `(node: TreeNode) => unknown` | `—` | Produces a row's rendered content for `node`. Default: plain label text. |
|
|
47
51
|
| `defaultExpanded` | `default-expanded` | `boolean` | `false` | Start every folder expanded instead of the default all-collapsed. |
|
|
52
|
+
| `lines` | `lines` | `boolean` | `false` | Draw classic file-tree connector guides (vertical ancestor lines plus a branch elbow/tee per row) instead of indentation alone. Off by default. |
|
|
48
53
|
|
|
49
54
|
## Events
|
|
50
55
|
|
|
@@ -60,6 +65,7 @@ _None._
|
|
|
60
65
|
|
|
61
66
|
| Custom property |
|
|
62
67
|
| --- |
|
|
68
|
+
| `--ui-border` |
|
|
63
69
|
| `--ui-focus-ring` |
|
|
64
70
|
| `--ui-font` |
|
|
65
71
|
| `--ui-font-size-sm` |
|
package/llms.txt
CHANGED
|
@@ -1273,11 +1273,15 @@ Example:
|
|
|
1273
1273
|
Responsive, accessible image carousel composed from declarative
|
|
1274
1274
|
`gallery-item` children.
|
|
1275
1275
|
|
|
1276
|
+
The image viewport keeps a fixed `aspect-ratio`, and the caption row is
|
|
1277
|
+
reserved for every slide whenever any slide has a caption, so the carousel's
|
|
1278
|
+
total height stays constant as it cycles — it never shifts the page below it.
|
|
1279
|
+
|
|
1276
1280
|
Import: `import "@f-ewald/components/photo-gallery.js";`
|
|
1277
1281
|
|
|
1278
1282
|
Properties: `currentIndex` (attribute `current-index`) : number, default 0; `delay` (attribute `delay`) : number, default 0; `showControls` (attribute `show-controls`) : boolean, default true; `showCounter` (attribute `show-counter`) : boolean, default false; `showIndicators` (attribute `show-indicators`) : boolean, default false; `showAutoplayControl` (attribute `show-autoplay-control`) : boolean, default true; `paused` (attribute `paused`) : boolean, default false; `aspectRatio` (attribute `aspect-ratio`) : string, default "16 / 9"; `objectFit` (attribute `object-fit`) : PhotoGalleryObjectFit, default "cover"
|
|
1279
1283
|
Events: `slide-change`
|
|
1280
|
-
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-line-height-tight`, `--ui-on-accent`, `--ui-overlay`, `--ui-primary`, `--ui-radius`, `--ui-radius-sm`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
1284
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-line-height-normal`, `--ui-line-height-tight`, `--ui-on-accent`, `--ui-overlay`, `--ui-primary`, `--ui-radius`, `--ui-radius-sm`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
1281
1285
|
|
|
1282
1286
|
Example:
|
|
1283
1287
|
```html
|
|
@@ -1712,26 +1716,31 @@ Example:
|
|
|
1712
1716
|
## <toast-notification>
|
|
1713
1717
|
|
|
1714
1718
|
Fixed-position stack of dismissible notifications, anchored top-right
|
|
1715
|
-
(top-full-width on mobile).
|
|
1716
|
-
|
|
1719
|
+
(top-full-width on mobile). Every toast shares one fixed width so entries
|
|
1720
|
+
never appear narrower or wider than one another. Not wired to any app state
|
|
1721
|
+
yet — callers add toasts imperatively via the `show()` method on a live
|
|
1722
|
+
element reference,
|
|
1717
1723
|
e.g. `document.querySelector('toast-notification')?.show('Offline', { variant: 'error' })`,
|
|
1718
1724
|
or via the `notifySuccess`/`notifyError`/`notifyInfo` module-level helpers
|
|
1719
|
-
exported from this file.
|
|
1720
|
-
|
|
1721
|
-
|
|
1725
|
+
exported from this file. The first argument is the required bold headline; an
|
|
1726
|
+
optional `description` renders a smaller, non-bold second line. Each variant
|
|
1727
|
+
leads with a matching status icon (success → check, error → exclamation
|
|
1728
|
+
circle, info → information circle, warning → exclamation triangle). Each toast
|
|
1729
|
+
auto-dismisses after `duration` ms and can also be dismissed via its ✕
|
|
1730
|
+
button. Appears/disappears instantly — no slide/fade transitions.
|
|
1722
1731
|
|
|
1723
1732
|
Import: `import "@f-ewald/components/toast-notification.js";`
|
|
1724
1733
|
|
|
1725
1734
|
Properties: none
|
|
1726
1735
|
Events: none
|
|
1727
|
-
CSS custom properties: `--ui-danger`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-hover-overlay`, `--ui-info`, `--ui-line-height-glyph`, `--ui-line-height-normal`, `--ui-on-accent`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-success`, `--ui-text`
|
|
1736
|
+
CSS custom properties: `--ui-danger`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-font-weight-regular`, `--ui-font-weight-semibold`, `--ui-hover-overlay`, `--ui-info`, `--ui-line-height-glyph`, `--ui-line-height-normal`, `--ui-on-accent`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-success`, `--ui-text`, `--ui-warning`
|
|
1728
1737
|
|
|
1729
1738
|
Example:
|
|
1730
1739
|
```html
|
|
1731
1740
|
<toast-notification></toast-notification>
|
|
1732
1741
|
<script type="module">
|
|
1733
1742
|
import { notifySuccess } from "@f-ewald/components/toast-notification.js";
|
|
1734
|
-
notifySuccess("Saved!");
|
|
1743
|
+
notifySuccess("Saved!", "Your changes are now live.");
|
|
1735
1744
|
</script>
|
|
1736
1745
|
```
|
|
1737
1746
|
|
|
@@ -1750,15 +1759,19 @@ every folder expanded instead. Expansion state is otherwise managed
|
|
|
1750
1759
|
internally and untouched by later `nodes` updates, so a user's manual
|
|
1751
1760
|
toggles survive a data refresh.
|
|
1752
1761
|
|
|
1762
|
+
Set the `lines` boolean to draw classic file-tree connector guides: a
|
|
1763
|
+
vertical line per continuing ancestor level and a branch elbow (`└`) or
|
|
1764
|
+
tee (`├`) linking each node to its parent. Off by default (indentation only).
|
|
1765
|
+
|
|
1753
1766
|
Import: `import "@f-ewald/components/tree-view.js";`
|
|
1754
1767
|
|
|
1755
|
-
Properties: `nodes` (JS property only) : TreeNode[], default []; `renderNode` (JS property only) : (node: TreeNode) => unknown, default —; `defaultExpanded` (attribute `default-expanded`) : boolean, default false
|
|
1768
|
+
Properties: `nodes` (JS property only) : TreeNode[], default []; `renderNode` (JS property only) : (node: TreeNode) => unknown, default —; `defaultExpanded` (attribute `default-expanded`) : boolean, default false; `lines` (attribute `lines`) : boolean, default false
|
|
1756
1769
|
Events: `node-click`
|
|
1757
|
-
CSS custom properties: `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
1770
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
1758
1771
|
|
|
1759
1772
|
Example:
|
|
1760
1773
|
```html
|
|
1761
|
-
<tree-view></tree-view>
|
|
1774
|
+
<tree-view lines></tree-view>
|
|
1762
1775
|
<script type="module">
|
|
1763
1776
|
const tree = document.querySelector("tree-view");
|
|
1764
1777
|
tree.nodes = [
|