@f-ewald/components 0.5.0 → 0.7.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 +61 -0
- package/custom-elements.json +3808 -930
- package/dist/chat-message.d.ts +39 -0
- package/dist/chat-message.d.ts.map +1 -0
- package/dist/chat-message.js +155 -0
- package/dist/chat-message.js.map +1 -0
- package/dist/data-table.d.ts +39 -0
- package/dist/data-table.d.ts.map +1 -0
- package/dist/data-table.js +119 -0
- package/dist/data-table.js.map +1 -0
- package/dist/dropdown-button.d.ts +37 -0
- package/dist/dropdown-button.d.ts.map +1 -0
- package/dist/dropdown-button.js +219 -0
- package/dist/dropdown-button.js.map +1 -0
- package/dist/editable-text.d.ts +52 -0
- package/dist/editable-text.d.ts.map +1 -0
- package/dist/editable-text.js +224 -0
- package/dist/editable-text.js.map +1 -0
- package/dist/form-select.d.ts +46 -0
- package/dist/form-select.d.ts.map +1 -0
- package/dist/form-select.js +245 -0
- package/dist/form-select.js.map +1 -0
- package/dist/frame-box.d.ts +22 -0
- package/dist/frame-box.d.ts.map +1 -0
- package/dist/frame-box.js +68 -0
- package/dist/frame-box.js.map +1 -0
- package/dist/gallery-item-variant.d.ts +21 -0
- package/dist/gallery-item-variant.d.ts.map +1 -0
- package/dist/gallery-item-variant.js +44 -0
- package/dist/gallery-item-variant.js.map +1 -0
- package/dist/gallery-item.d.ts +28 -0
- package/dist/gallery-item.d.ts.map +1 -0
- package/dist/gallery-item.js +54 -0
- package/dist/gallery-item.js.map +1 -0
- package/dist/icon-button.d.ts +27 -0
- package/dist/icon-button.d.ts.map +1 -0
- package/dist/icon-button.js +83 -0
- package/dist/icon-button.js.map +1 -0
- package/dist/icons.d.ts +8 -0
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +8 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/live-timer.d.ts +31 -0
- package/dist/live-timer.d.ts.map +1 -0
- package/dist/live-timer.js +78 -0
- package/dist/live-timer.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +82 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/photo-gallery.d.ts +117 -0
- package/dist/photo-gallery.d.ts.map +1 -0
- package/dist/photo-gallery.js +620 -0
- package/dist/photo-gallery.js.map +1 -0
- package/dist/popover-panel.d.ts +37 -0
- package/dist/popover-panel.d.ts.map +1 -0
- package/dist/popover-panel.js +184 -0
- package/dist/popover-panel.js.map +1 -0
- package/dist/status-pill.d.ts +24 -0
- package/dist/status-pill.d.ts.map +1 -0
- package/dist/status-pill.js +101 -0
- package/dist/status-pill.js.map +1 -0
- package/dist/tile-grid.d.ts +32 -0
- package/dist/tile-grid.d.ts.map +1 -0
- package/dist/tile-grid.js +102 -0
- package/dist/tile-grid.js.map +1 -0
- package/dist/tokens.css +39 -0
- package/dist/tokens.d.ts +28 -3
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +42 -43
- package/dist/tokens.js.map +1 -1
- package/dist/user-avatar.d.ts +5 -2
- package/dist/user-avatar.d.ts.map +1 -1
- package/dist/user-avatar.js +22 -6
- package/dist/user-avatar.js.map +1 -1
- package/dist/utils/duration.d.ts +12 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/duration.js +27 -0
- package/dist/utils/duration.js.map +1 -0
- package/docs/chat-message.md +59 -0
- package/docs/data-table.md +63 -0
- package/docs/dropdown-button.md +61 -0
- package/docs/editable-text.md +51 -0
- package/docs/form-select.md +70 -0
- package/docs/frame-box.md +43 -0
- package/docs/gallery-item-variant.md +37 -0
- package/docs/gallery-item.md +47 -0
- package/docs/icon-button.md +52 -0
- package/docs/live-timer.md +39 -0
- package/docs/mcp-evaluation.md +18 -11
- package/docs/photo-gallery.md +77 -0
- package/docs/popover-panel.md +70 -0
- package/docs/status-pill.md +43 -0
- package/docs/tile-grid.md +58 -0
- package/docs/user-avatar.md +1 -1
- package/llms.txt +357 -1
- package/package.json +10 -3
package/llms.txt
CHANGED
|
@@ -104,6 +104,30 @@ Example:
|
|
|
104
104
|
</script>
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
## <chat-message>
|
|
108
|
+
|
|
109
|
+
One conversation entry in a chat-style activity feed. Tool calls and
|
|
110
|
+
"thinking" traces are variants of this component rather than separate
|
|
111
|
+
ones — they share the same header, collapse behavior, and body card as a
|
|
112
|
+
normal message, just dimmed and collapsible with an always-visible summary.
|
|
113
|
+
|
|
114
|
+
Import: `import "@f-ewald/components/chat-message.js";`
|
|
115
|
+
|
|
116
|
+
Properties: `role` (attribute `role`) : ChatMessageRole, default "agent"; `variant` (attribute `variant`) : ChatMessageVariant, default "normal"; `author` (attribute `author`) : string, default ""; `timestamp` (attribute `timestamp`) : string | null, default null; `summary` (attribute `summary`) : string, default ""; `collapsible` (attribute `collapsible`) : boolean, default false; `collapsed` (attribute `collapsed`) : boolean, default false
|
|
117
|
+
Events: `toggle`
|
|
118
|
+
CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size`, `--ui-primary`, `--ui-radius`, `--ui-surface`, `--ui-text`, `--ui-text-muted`
|
|
119
|
+
|
|
120
|
+
Example:
|
|
121
|
+
```html
|
|
122
|
+
<chat-message role="user" author="Freddy" timestamp="2026-07-19T12:00:00Z">
|
|
123
|
+
Write notes.md containing a haiku.
|
|
124
|
+
</chat-message>
|
|
125
|
+
<chat-message role="agent" variant="tool" collapsible collapsed summary='file_write · {"filename": "notes.md"}'>
|
|
126
|
+
directory: .
|
|
127
|
+
filename: notes.md
|
|
128
|
+
</chat-message>
|
|
129
|
+
```
|
|
130
|
+
|
|
107
131
|
## <confirm-dialog>
|
|
108
132
|
|
|
109
133
|
Reusable confirmation dialog: overlay + centered card with a slotted body,
|
|
@@ -144,6 +168,40 @@ Example:
|
|
|
144
168
|
<copy-link-button value="https://example.com/listing/42" label="Copy listing link"></copy-link-button>
|
|
145
169
|
```
|
|
146
170
|
|
|
171
|
+
## <data-table>
|
|
172
|
+
|
|
173
|
+
A generic, presentational table shell: renders a `<thead>` from `columns`
|
|
174
|
+
and one `<tr>` per entry in `rows`, with each cell's content produced by
|
|
175
|
+
`renderCell` (default: plain property lookup on the row object). Knows
|
|
176
|
+
nothing about what a "row" means — callers own the data shape entirely.
|
|
177
|
+
|
|
178
|
+
Optional `rowHref` makes whole rows clickable (navigating via `location.hash`),
|
|
179
|
+
without hijacking clicks on nested interactive elements (links/buttons) a
|
|
180
|
+
cell's rendered content might contain.
|
|
181
|
+
|
|
182
|
+
Import: `import "@f-ewald/components/data-table.js";`
|
|
183
|
+
|
|
184
|
+
Properties: `columns` (JS property only) : DataTableColumn[], default []; `rows` (JS property only) : unknown[], default []; `rowKey` (JS property only) : (row: unknown, index: number) => string | number, default —; `renderCell` (JS property only) : (row: unknown, key: string) => unknown, default —; `rowHref` (JS property only) : ((row: unknown) => string | null) | null, default null
|
|
185
|
+
Events: none
|
|
186
|
+
CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
187
|
+
|
|
188
|
+
Example:
|
|
189
|
+
```html
|
|
190
|
+
<data-table></data-table>
|
|
191
|
+
<script type="module">
|
|
192
|
+
const table = document.querySelector("data-table");
|
|
193
|
+
table.columns = [
|
|
194
|
+
{ key: "title", label: "Title" },
|
|
195
|
+
{ key: "state", label: "State" },
|
|
196
|
+
];
|
|
197
|
+
table.rows = [
|
|
198
|
+
{ id: "tsk_1", title: "Write onboarding docs", state: "Backlog" },
|
|
199
|
+
{ id: "tsk_2", title: "Fix the login bug", state: "Done" },
|
|
200
|
+
];
|
|
201
|
+
table.rowHref = (row) => `#/tasks/${row.id}`;
|
|
202
|
+
</script>
|
|
203
|
+
```
|
|
204
|
+
|
|
147
205
|
## <distance-value>
|
|
148
206
|
|
|
149
207
|
Inline distance display. Renders miles/feet or km/m, switching units at
|
|
@@ -188,6 +246,191 @@ Example:
|
|
|
188
246
|
</script>
|
|
189
247
|
```
|
|
190
248
|
|
|
249
|
+
## <dropdown-button>
|
|
250
|
+
|
|
251
|
+
A primary-styled button with a label and chevron that opens an anchored
|
|
252
|
+
menu of actions — essentially `form-select` minus "current value"
|
|
253
|
+
semantics: a menu, not a select. Use for a set of mutually exclusive
|
|
254
|
+
next-step actions (e.g. a failed task's Retry / Close / Backlog).
|
|
255
|
+
|
|
256
|
+
Import: `import "@f-ewald/components/dropdown-button.js";`
|
|
257
|
+
|
|
258
|
+
Properties: `label` (attribute `label`) : string, default ""; `options` (JS property only) : DropdownOption[], default []; `disabled` (attribute `disabled`) : boolean, default false
|
|
259
|
+
Events: `select`
|
|
260
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`
|
|
261
|
+
|
|
262
|
+
Example:
|
|
263
|
+
```html
|
|
264
|
+
<dropdown-button label="Resolve…"></dropdown-button>
|
|
265
|
+
<script type="module">
|
|
266
|
+
const dropdown = document.querySelector("dropdown-button");
|
|
267
|
+
dropdown.options = [
|
|
268
|
+
{ value: "retry", label: "Retry" },
|
|
269
|
+
{ value: "close", label: "Close" },
|
|
270
|
+
{ value: "backlog", label: "Backlog" },
|
|
271
|
+
];
|
|
272
|
+
dropdown.addEventListener("select", (e) => console.log(e.detail.value));
|
|
273
|
+
</script>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## <editable-text>
|
|
277
|
+
|
|
278
|
+
Jira/GitHub-style click-to-edit text: a display span that turns into an
|
|
279
|
+
`<input>` (or auto-growing `<textarea>` when `multiline`) on click. The
|
|
280
|
+
input/textarea inherits the host's font, so a title wrapped in an `<h1>`
|
|
281
|
+
edits at title size.
|
|
282
|
+
|
|
283
|
+
Import: `import "@f-ewald/components/editable-text.js";`
|
|
284
|
+
|
|
285
|
+
Properties: `value` (attribute `value`) : string, default ""; `multiline` (attribute `multiline`) : boolean, default false; `placeholder` (attribute `placeholder`) : string, default ""; `readonly` (attribute `readonly`) : boolean, default false; `label` (attribute `label`) : string, default ""
|
|
286
|
+
Events: `change`
|
|
287
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-primary`, `--ui-radius-sm`, `--ui-surface`, `--ui-surface-muted`, `--ui-text-muted`
|
|
288
|
+
|
|
289
|
+
Example:
|
|
290
|
+
```html
|
|
291
|
+
<editable-text value="Write the quarterly report" label="Title"></editable-text>
|
|
292
|
+
<editable-text multiline placeholder="Add a description…" label="Description"></editable-text>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## <form-select>
|
|
296
|
+
|
|
297
|
+
A styled dropdown select: a trigger button showing the current option's
|
|
298
|
+
label, opening a listbox popover on click. Drop-in generic replacement for
|
|
299
|
+
a native `<select>` wherever consistent cross-browser styling and a
|
|
300
|
+
`change` event carrying `{ value }` are wanted (e.g. a task's status
|
|
301
|
+
picker).
|
|
302
|
+
|
|
303
|
+
The trigger fills its host's width (`justify-content: space-between`
|
|
304
|
+
pushes the chevron to the far edge), but the host itself stays
|
|
305
|
+
`display: inline-block` — so usages that never size the host (a filter
|
|
306
|
+
bar, a status picker) keep shrink-to-fit auto-width unchanged. To make an
|
|
307
|
+
instance full-width, size the host itself: `form-select { width: 100%; }`.
|
|
308
|
+
|
|
309
|
+
Import: `import "@f-ewald/components/form-select.js";`
|
|
310
|
+
|
|
311
|
+
Properties: `options` (JS property only) : SelectOption[], default []; `value` (attribute `value`) : string, default ""; `label` (attribute `label`) : string, default ""; `disabled` (attribute `disabled`) : boolean, default false
|
|
312
|
+
Events: `change`
|
|
313
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
314
|
+
|
|
315
|
+
Example:
|
|
316
|
+
```html
|
|
317
|
+
<form-select label="Task state"></form-select>
|
|
318
|
+
<script type="module">
|
|
319
|
+
const select = document.querySelector("form-select");
|
|
320
|
+
select.options = [
|
|
321
|
+
{ value: "open", label: "Open" },
|
|
322
|
+
{ value: "in_progress", label: "In progress" },
|
|
323
|
+
{ value: "done", label: "Done" },
|
|
324
|
+
];
|
|
325
|
+
select.value = "open";
|
|
326
|
+
select.addEventListener("change", (e) => console.log(e.detail.value));
|
|
327
|
+
</script>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## <frame-box>
|
|
331
|
+
|
|
332
|
+
A titled frame around a slot: a gray border with a small uppercase,
|
|
333
|
+
muted label overlapping the top edge (fieldset/legend-style). Generic —
|
|
334
|
+
the label text is entirely up to the consumer (e.g. "Debug" to visually
|
|
335
|
+
fence off dev-only chrome from the product UI).
|
|
336
|
+
|
|
337
|
+
Import: `import "@f-ewald/components/frame-box.js";`
|
|
338
|
+
|
|
339
|
+
Properties: `label` (attribute `label`) : string, default ""
|
|
340
|
+
Events: none
|
|
341
|
+
CSS custom properties: `--ui-border`, `--ui-radius-sm`, `--ui-surface`, `--ui-text-muted`
|
|
342
|
+
|
|
343
|
+
Example:
|
|
344
|
+
```html
|
|
345
|
+
<frame-box label="Debug">
|
|
346
|
+
Framed content goes here.
|
|
347
|
+
</frame-box>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## <gallery-item>
|
|
351
|
+
|
|
352
|
+
Declarative image metadata consumed by a parent `photo-gallery`.
|
|
353
|
+
|
|
354
|
+
Import: `import "@f-ewald/components/gallery-item.js";`
|
|
355
|
+
|
|
356
|
+
Properties: `src` (attribute `src`) : string, default ""; `alt` (attribute `alt`) : string, default ""; `caption` (attribute `caption`) : string | undefined, default —; `variants` (JS property only) : GalleryItemVariant[], default —
|
|
357
|
+
Events: none
|
|
358
|
+
CSS custom properties: none
|
|
359
|
+
|
|
360
|
+
Example:
|
|
361
|
+
```html
|
|
362
|
+
<gallery-item
|
|
363
|
+
src="/photos/coast.jpg"
|
|
364
|
+
alt="Rocky California coastline"
|
|
365
|
+
caption="California coast"
|
|
366
|
+
>
|
|
367
|
+
<gallery-item-variant
|
|
368
|
+
media="(max-width: 640px)"
|
|
369
|
+
srcset="/photos/coast-portrait.jpg"
|
|
370
|
+
></gallery-item-variant>
|
|
371
|
+
</gallery-item>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## <gallery-item-variant>
|
|
375
|
+
|
|
376
|
+
Responsive image source metadata for a parent `gallery-item`.
|
|
377
|
+
|
|
378
|
+
Import: `import "@f-ewald/components/gallery-item-variant.js";`
|
|
379
|
+
|
|
380
|
+
Properties: `media` (attribute `media`) : string | undefined, default —; `srcset` (attribute `srcset`) : string, default ""
|
|
381
|
+
Events: none
|
|
382
|
+
CSS custom properties: none
|
|
383
|
+
|
|
384
|
+
Example:
|
|
385
|
+
```html
|
|
386
|
+
<gallery-item-variant
|
|
387
|
+
media="(max-width: 640px)"
|
|
388
|
+
srcset="/photos/coast-portrait.jpg"
|
|
389
|
+
></gallery-item-variant>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## <icon-button>
|
|
393
|
+
|
|
394
|
+
A borderless button wrapping a passed-in icon, with a rounded
|
|
395
|
+
hover-highlight background. Use for a low-emphasis affordance next to
|
|
396
|
+
content it acts on (e.g. an "Edit" pencil at the end of a table row)
|
|
397
|
+
where a bordered `ui-button` would be too heavy.
|
|
398
|
+
|
|
399
|
+
Import: `import "@f-ewald/components/icon-button.js";`
|
|
400
|
+
|
|
401
|
+
Properties: `icon` (JS property only) : TemplateResult | null, default null; `label` (attribute `label`) : string, default ""; `disabled` (attribute `disabled`) : boolean, default false
|
|
402
|
+
Events: `click`
|
|
403
|
+
CSS custom properties: `--ui-focus-ring`, `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
404
|
+
|
|
405
|
+
Example:
|
|
406
|
+
```html
|
|
407
|
+
<icon-button label="Edit"></icon-button>
|
|
408
|
+
<script type="module">
|
|
409
|
+
import { iconPencil } from "@f-ewald/components/icons.js";
|
|
410
|
+
const btn = document.querySelector("icon-button");
|
|
411
|
+
btn.icon = iconPencil(16);
|
|
412
|
+
btn.addEventListener("click", () => console.log("edit clicked"));
|
|
413
|
+
</script>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## <live-timer>
|
|
417
|
+
|
|
418
|
+
Per-second ticking count-up timer, e.g. a live "running for 12s" or
|
|
419
|
+
"Sleeping for 3 seconds" indicator. Renders nothing while `since` is unset
|
|
420
|
+
or unparseable.
|
|
421
|
+
|
|
422
|
+
Import: `import "@f-ewald/components/live-timer.js";`
|
|
423
|
+
|
|
424
|
+
Properties: `since` (attribute `since`) : string | null, default null; `format` (attribute `format`) : DurationFormat, default "seconds"; `prefix` (attribute `prefix`) : string, default ""; `suffix` (attribute `suffix`) : string, default ""
|
|
425
|
+
Events: none
|
|
426
|
+
CSS custom properties: none
|
|
427
|
+
|
|
428
|
+
Example:
|
|
429
|
+
```html
|
|
430
|
+
<live-timer since="2026-07-19T12:00:00Z" prefix="Sleeping for "></live-timer>
|
|
431
|
+
<live-timer since="2026-07-19T12:00:00Z" format="compact" prefix="running for "></live-timer>
|
|
432
|
+
```
|
|
433
|
+
|
|
191
434
|
## <map-circle>
|
|
192
435
|
|
|
193
436
|
A plain circular map marker: a light-to-dark gradient fill with a white
|
|
@@ -273,6 +516,72 @@ Example:
|
|
|
273
516
|
</script>
|
|
274
517
|
```
|
|
275
518
|
|
|
519
|
+
## <photo-gallery>
|
|
520
|
+
|
|
521
|
+
Responsive, accessible image carousel composed from declarative
|
|
522
|
+
`gallery-item` children.
|
|
523
|
+
|
|
524
|
+
Import: `import "@f-ewald/components/photo-gallery.js";`
|
|
525
|
+
|
|
526
|
+
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"
|
|
527
|
+
Events: `slide-change`
|
|
528
|
+
CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-overlay`, `--ui-primary`, `--ui-radius`, `--ui-radius-sm`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
529
|
+
|
|
530
|
+
Example:
|
|
531
|
+
```html
|
|
532
|
+
<photo-gallery delay="5000" show-counter show-indicators>
|
|
533
|
+
<gallery-item
|
|
534
|
+
src="/photos/coast.jpg"
|
|
535
|
+
alt="Rocky California coastline"
|
|
536
|
+
caption="California coast"
|
|
537
|
+
>
|
|
538
|
+
<gallery-item-variant
|
|
539
|
+
media="(max-width: 640px)"
|
|
540
|
+
srcset="/photos/coast-portrait.jpg"
|
|
541
|
+
></gallery-item-variant>
|
|
542
|
+
</gallery-item>
|
|
543
|
+
<gallery-item src="/photos/bridge.jpg" alt="Golden Gate Bridge"></gallery-item>
|
|
544
|
+
</photo-gallery>
|
|
545
|
+
<script type="module">
|
|
546
|
+
document.querySelector("photo-gallery").addEventListener("slide-change", (event) => {
|
|
547
|
+
console.log(event.detail.currentIndex);
|
|
548
|
+
});
|
|
549
|
+
</script>
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
## <popover-panel>
|
|
553
|
+
|
|
554
|
+
Generic anchored popover shell: a floating card positioned relative to its
|
|
555
|
+
nearest `position: relative` ancestor (place it next to its trigger button
|
|
556
|
+
inside such a wrapper), as opposed to `slide-panel`'s fixed screen-edge
|
|
557
|
+
drawer. Closes on outside click or Escape. Header chrome and close button
|
|
558
|
+
match `slide-panel`'s API (`heading`, `panel-close`) so either can be
|
|
559
|
+
swapped in for the other with no consumer-side changes beyond the wrapper.
|
|
560
|
+
|
|
561
|
+
Set `centered` to render as a screen-centered modal with a translucent
|
|
562
|
+
backdrop instead of the default anchored placement.
|
|
563
|
+
|
|
564
|
+
Import: `import "@f-ewald/components/popover-panel.js";`
|
|
565
|
+
|
|
566
|
+
Properties: `open` (attribute `open`) : boolean, default false; `heading` (attribute `heading`) : string, default ""; `centered` (attribute `centered`) : boolean, default false
|
|
567
|
+
Events: `panel-close`
|
|
568
|
+
CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
|
|
569
|
+
|
|
570
|
+
Example:
|
|
571
|
+
```html
|
|
572
|
+
<div style="position: relative; display: inline-block;">
|
|
573
|
+
<button id="new-task-btn">New task</button>
|
|
574
|
+
<popover-panel heading="New task">
|
|
575
|
+
Popover body content goes here.
|
|
576
|
+
</popover-panel>
|
|
577
|
+
</div>
|
|
578
|
+
<script type="module">
|
|
579
|
+
const popover = document.querySelector("popover-panel");
|
|
580
|
+
document.querySelector("#new-task-btn").addEventListener("click", () => (popover.open = true));
|
|
581
|
+
popover.addEventListener("panel-close", () => (popover.open = false));
|
|
582
|
+
</script>
|
|
583
|
+
```
|
|
584
|
+
|
|
276
585
|
## <price-history-chart>
|
|
277
586
|
|
|
278
587
|
D3-powered SVG line chart for property price history.
|
|
@@ -447,6 +756,53 @@ Example:
|
|
|
447
756
|
<stat-meter label="GPU" percent="88" color="#dc2626"></stat-meter>
|
|
448
757
|
```
|
|
449
758
|
|
|
759
|
+
## <status-pill>
|
|
760
|
+
|
|
761
|
+
Small colored status pill, optionally with a spinning icon — for task/run
|
|
762
|
+
states ("Open", "Blocked", "Done") and live-activity indicators ("Running").
|
|
763
|
+
|
|
764
|
+
Import: `import "@f-ewald/components/status-pill.js";`
|
|
765
|
+
|
|
766
|
+
Properties: `label` (attribute `label`) : string, default ""; `color` (attribute `color`) : StatusPillColor, default "neutral"; `spinner` (attribute `spinner`) : boolean, default false
|
|
767
|
+
Events: none
|
|
768
|
+
CSS custom properties: `--ui-danger`, `--ui-font`, `--ui-primary`, `--ui-success`, `--ui-text-muted`
|
|
769
|
+
|
|
770
|
+
Example:
|
|
771
|
+
```html
|
|
772
|
+
<status-pill label="Running" color="primary" spinner></status-pill>
|
|
773
|
+
<status-pill label="Blocked" color="danger"></status-pill>
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
## <tile-grid>
|
|
777
|
+
|
|
778
|
+
A generic, presentational grid shell: renders one bordered card per entry
|
|
779
|
+
in `items`, with each tile's content produced by `renderTile` (default:
|
|
780
|
+
stringify). Knows nothing about what an "item" means — callers own the
|
|
781
|
+
data shape entirely. Modeled directly on `data-table`'s headless pattern.
|
|
782
|
+
|
|
783
|
+
Optional `itemHref` makes whole tiles clickable (navigating via
|
|
784
|
+
`location.hash`), without hijacking clicks on nested interactive elements
|
|
785
|
+
(links/buttons) a tile's rendered content might contain.
|
|
786
|
+
|
|
787
|
+
Import: `import "@f-ewald/components/tile-grid.js";`
|
|
788
|
+
|
|
789
|
+
Properties: `items` (JS property only) : unknown[], default []; `itemKey` (JS property only) : (item: unknown, index: number) => string | number, default —; `renderTile` (JS property only) : (item: unknown) => unknown, default —; `itemHref` (JS property only) : ((item: unknown) => string | null) | null, default null
|
|
790
|
+
Events: none
|
|
791
|
+
CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-radius`, `--ui-surface-muted`, `--ui-text`
|
|
792
|
+
|
|
793
|
+
Example:
|
|
794
|
+
```html
|
|
795
|
+
<tile-grid></tile-grid>
|
|
796
|
+
<script type="module">
|
|
797
|
+
const grid = document.querySelector("tile-grid");
|
|
798
|
+
grid.items = [
|
|
799
|
+
{ name: "notes.txt" },
|
|
800
|
+
{ name: "photo.jpg" },
|
|
801
|
+
];
|
|
802
|
+
grid.renderTile = (item) => item.name;
|
|
803
|
+
</script>
|
|
804
|
+
```
|
|
805
|
+
|
|
450
806
|
## <toast-notification>
|
|
451
807
|
|
|
452
808
|
Fixed-position stack of dismissible notifications, anchored top-right
|
|
@@ -514,7 +870,7 @@ circle.
|
|
|
514
870
|
|
|
515
871
|
Import: `import "@f-ewald/components/user-avatar.js";`
|
|
516
872
|
|
|
517
|
-
Properties: `src` (attribute `src`) : string | null, default null; `name` (attribute `name`) : string | null, default null; `size` (attribute `size`) : number, default 32
|
|
873
|
+
Properties: `src` (attribute `src`) : string | null, default null; `name` (attribute `name`) : string | null, default null; `size` (attribute `size`) : string | number, default 32
|
|
518
874
|
Events: none
|
|
519
875
|
CSS custom properties: `--ui-font`, `--ui-primary`
|
|
520
876
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@f-ewald/components",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"description": "A collection of universally usable web components for various tasks.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"module": "dist/index.js",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"f-ewald-components-mcp": "dist/mcp-server.js"
|
|
12
|
+
},
|
|
10
13
|
"exports": {
|
|
11
14
|
".": {
|
|
12
15
|
"types": "./dist/index.d.ts",
|
|
@@ -31,11 +34,12 @@
|
|
|
31
34
|
],
|
|
32
35
|
"scripts": {
|
|
33
36
|
"dev": "vite",
|
|
34
|
-
"build": "rm -rf dist && tsc && node scripts/generate-tokens-css.mjs",
|
|
37
|
+
"build": "rm -rf dist && tsc && node scripts/generate-tokens-css.mjs && chmod +x dist/mcp-server.js",
|
|
35
38
|
"build:demo": "vite build",
|
|
36
39
|
"analyze": "cem analyze --litelement --globs \"src/**/*.ts\"",
|
|
37
40
|
"docs": "npm run analyze && node scripts/generate-docs.mjs",
|
|
38
41
|
"icons": "node scripts/generate-icons.mjs",
|
|
42
|
+
"mcp": "node dist/mcp-server.js",
|
|
39
43
|
"test": "playwright test",
|
|
40
44
|
"prepublishOnly": "npm run build && npm run docs && npm run test"
|
|
41
45
|
},
|
|
@@ -45,10 +49,12 @@
|
|
|
45
49
|
"author": "Friedrich Ewald",
|
|
46
50
|
"license": "BSD-3-Clause",
|
|
47
51
|
"dependencies": {
|
|
52
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
48
53
|
"d3-array": "^3.2.4",
|
|
49
54
|
"d3-scale": "^4.0.2",
|
|
50
55
|
"d3-shape": "^3.2.0",
|
|
51
|
-
"lit": "^3.3.3"
|
|
56
|
+
"lit": "^3.3.3",
|
|
57
|
+
"zod": "^4.4.3"
|
|
52
58
|
},
|
|
53
59
|
"publishConfig": {
|
|
54
60
|
"access": "public"
|
|
@@ -61,6 +67,7 @@
|
|
|
61
67
|
"@types/d3-array": "^3.2.2",
|
|
62
68
|
"@types/d3-scale": "^4.0.9",
|
|
63
69
|
"@types/d3-shape": "^3.1.8",
|
|
70
|
+
"@types/node": "^26.1.1",
|
|
64
71
|
"heroicons": "^2.2.0",
|
|
65
72
|
"tailwindcss": "^4.3.3",
|
|
66
73
|
"typescript": "^7.0.2",
|