@f-ewald/components 0.6.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.
Files changed (42) hide show
  1. package/README.md +34 -0
  2. package/custom-elements.json +424 -1
  3. package/dist/dropdown-button.d.ts +37 -0
  4. package/dist/dropdown-button.d.ts.map +1 -0
  5. package/dist/dropdown-button.js +219 -0
  6. package/dist/dropdown-button.js.map +1 -0
  7. package/dist/form-select.d.ts +6 -0
  8. package/dist/form-select.d.ts.map +1 -1
  9. package/dist/form-select.js +9 -0
  10. package/dist/form-select.js.map +1 -1
  11. package/dist/frame-box.d.ts +22 -0
  12. package/dist/frame-box.d.ts.map +1 -0
  13. package/dist/frame-box.js +68 -0
  14. package/dist/frame-box.js.map +1 -0
  15. package/dist/icon-button.d.ts +27 -0
  16. package/dist/icon-button.d.ts.map +1 -0
  17. package/dist/icon-button.js +83 -0
  18. package/dist/icon-button.js.map +1 -0
  19. package/dist/icons.d.ts +1 -0
  20. package/dist/icons.d.ts.map +1 -1
  21. package/dist/icons.js +1 -0
  22. package/dist/icons.js.map +1 -1
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +3 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/mcp-server.d.ts +3 -0
  28. package/dist/mcp-server.d.ts.map +1 -0
  29. package/dist/mcp-server.js +82 -0
  30. package/dist/mcp-server.js.map +1 -0
  31. package/dist/popover-panel.d.ts +3 -0
  32. package/dist/popover-panel.d.ts.map +1 -1
  33. package/dist/popover-panel.js +11 -0
  34. package/dist/popover-panel.js.map +1 -1
  35. package/docs/dropdown-button.md +61 -0
  36. package/docs/form-select.md +6 -0
  37. package/docs/frame-box.md +43 -0
  38. package/docs/icon-button.md +52 -0
  39. package/docs/mcp-evaluation.md +18 -11
  40. package/docs/popover-panel.md +5 -1
  41. package/llms.txt +77 -0
  42. package/package.json +10 -3
@@ -1,31 +1,38 @@
1
1
  # MCP server evaluation
2
2
 
3
- **Recommendation: do not build an MCP server for this package now.**
3
+ **Update (0.6.0 era, 34 components): built.** The catalog crossed the ~30+
4
+ revisit threshold below, so the upgrade path described here was implemented
5
+ as `src/mcp-server.ts`. See the "MCP server" section in the root `CLAUDE.md`
6
+ for the current tools, build step, and how consuming projects wire it up.
7
+ The original evaluation is kept below for the reasoning that justified
8
+ waiting until this point.
9
+
10
+ ## Original recommendation (superseded): do not build an MCP server yet
4
11
 
5
12
  ## Rationale
6
13
 
7
- The component catalog is small (14 tags). `llms.txt` ships in the npm
14
+ The component catalog was small (14 tags). `llms.txt` ships in the npm
8
15
  package and is fetchable directly from unpkg or GitHub raw, so any LLM or
9
16
  agent can load the full API surface — every component's attributes,
10
17
  properties, events, slots, tokens, and a usage example — in one small file,
11
18
  with no server, process, or additional versioning/packaging burden. An MCP
12
19
  server would duplicate that same data behind a stdio process that needs its
13
20
  own install, auth-free-but-still-a-process lifecycle, and release cadence
14
- kept in sync with the package — for zero functional gain at this scale.
21
+ kept in sync with the package — for zero functional gain at that scale.
15
22
 
16
- ## When to revisit
23
+ ## When to revisit (met)
17
24
 
18
25
  - The catalog grows past a size where `llms.txt` stops being comfortable to
19
- load into a single context window (rule of thumb: ~30+ components).
26
+ load into a single context window (rule of thumb: ~30+ components).
27
+ **met at 34 components.**
20
28
  - Consumers want live search, fuzzy matching, or filtered/paginated results
21
29
  instead of "load everything."
22
30
  - Consumers want examples or docs that go beyond what's derivable from
23
31
  `custom-elements.json` (e.g. runnable playground snippets, live preview).
24
32
 
25
- ## Upgrade path
33
+ ## Upgrade path (implemented)
26
34
 
27
- If/when it's warranted, a thin stdio MCP server exposing two tools —
28
- `list_components` and `get_component_docs(tag)` — backed by the same
29
- `custom-elements.json` this package already generates and ships. No new
30
- data source would be needed; the server would just be a different transport
31
- over data that already exists.
35
+ A thin stdio MCP server exposing two tools — `list_components` and
36
+ `get_component_docs(tag)` — backed by the same `custom-elements.json` this
37
+ package already generates and ships. No new data source was needed; the
38
+ server is just a different transport over data that already existed.
@@ -48,7 +48,11 @@ import "@f-ewald/components/popover-panel.js";
48
48
 
49
49
  ## Slots
50
50
 
51
- _None._
51
+ | Slot | Description |
52
+ | --- | --- |
53
+ | `(default)` | Popover body content. |
54
+ | `title` | Overrides the plain `heading` text with custom markup. |
55
+ | `actions` | Extra header controls (e.g. an icon+label link) rendered between the title and the close button. |
52
56
 
53
57
  ## CSS custom properties
54
58
 
package/llms.txt CHANGED
@@ -246,6 +246,33 @@ Example:
246
246
  </script>
247
247
  ```
248
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
+
249
276
  ## <editable-text>
250
277
 
251
278
  Jira/GitHub-style click-to-edit text: a display span that turns into an
@@ -273,6 +300,12 @@ a native `<select>` wherever consistent cross-browser styling and a
273
300
  `change` event carrying `{ value }` are wanted (e.g. a task's status
274
301
  picker).
275
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
+
276
309
  Import: `import "@f-ewald/components/form-select.js";`
277
310
 
278
311
  Properties: `options` (JS property only) : SelectOption[], default []; `value` (attribute `value`) : string, default ""; `label` (attribute `label`) : string, default ""; `disabled` (attribute `disabled`) : boolean, default false
@@ -294,6 +327,26 @@ Example:
294
327
  </script>
295
328
  ```
296
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
+
297
350
  ## <gallery-item>
298
351
 
299
352
  Declarative image metadata consumed by a parent `photo-gallery`.
@@ -336,6 +389,30 @@ Example:
336
389
  ></gallery-item-variant>
337
390
  ```
338
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
+
339
416
  ## <live-timer>
340
417
 
341
418
  Per-second ticking count-up timer, e.g. a live "running for 12s" or
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@f-ewald/components",
3
3
  "private": false,
4
- "version": "0.6.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",