@keenmate/web-components-devkit 0.0.0-stage → 1.0.0-rc01
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/CHANGELOG.md +76 -0
- package/LICENSE +21 -0
- package/README.md +417 -2
- package/components.json +189 -0
- package/package.json +75 -4
- package/src/cli/args.js +16 -0
- package/src/cli/commands/check-release.js +66 -0
- package/src/cli/commands/check-vars.js +116 -0
- package/src/cli/commands/doctor.js +289 -0
- package/src/cli/commands/new.js +302 -0
- package/src/cli/commands/readme.js +111 -0
- package/src/cli/commands/sync.js +48 -0
- package/src/cli/kmwc.js +72 -0
- package/src/cli/sync-plan.js +163 -0
- package/src/config.d.ts +147 -0
- package/src/config.js +257 -0
- package/src/examples/auto.js +20 -0
- package/src/examples/chapter-nav.js +246 -0
- package/src/examples/constants.js +80 -0
- package/src/examples/controls-persistence.js +97 -0
- package/src/examples/copy-link.js +89 -0
- package/src/examples/css/base.css +215 -0
- package/src/examples/css/chapter-nav.css +179 -0
- package/src/examples/css/content.css +251 -0
- package/src/examples/css/controls.css +205 -0
- package/src/examples/css/copy-link.css +82 -0
- package/src/examples/css/demo.css +50 -0
- package/src/examples/css/index-page.css +118 -0
- package/src/examples/css/style.css +30 -0
- package/src/examples/css/theme-switch.css +38 -0
- package/src/examples/css/tokens.css +110 -0
- package/src/examples/css/widgets.css +133 -0
- package/src/examples/demo-code.js +30 -0
- package/src/examples/index-page.js +78 -0
- package/src/examples/index.d.ts +107 -0
- package/src/examples/index.js +18 -0
- package/src/examples/kit.js +22 -0
- package/src/examples/page-config.js +30 -0
- package/src/examples/sections.js +53 -0
- package/src/examples/theme-switch.js +72 -0
- package/src/examples/version-badge.js +23 -0
- package/src/playwright/index.d.ts +15 -0
- package/src/playwright/index.js +66 -0
- package/src/template.js +11 -0
- package/src/vite/index.d.ts +28 -0
- package/src/vite/index.js +243 -0
- package/src/vite/page-composer.js +209 -0
- package/templates/Dockerfile.tmpl +39 -0
- package/templates/Makefile.tmpl +136 -0
- package/templates/claude-block.md +40 -0
- package/templates/dockerignore.tmpl +10 -0
- package/templates/examples-layout.html +13 -0
- package/templates/new/.claude/commands/publish.md +226 -0
- package/templates/new/CHANGELOG.md +13 -0
- package/templates/new/LICENSE +21 -0
- package/templates/new/README.md +71 -0
- package/templates/new/_gitignore +7 -0
- package/templates/new/component-variables.manifest.json +32 -0
- package/templates/new/custom-elements-manifest.config.mjs +23 -0
- package/templates/new/docs/accessibility.md +24 -0
- package/templates/new/docs/examples.md +33 -0
- package/templates/new/docs/theming.md +54 -0
- package/templates/new/docs/usage.md +51 -0
- package/templates/new/e2e/dark-mode.spec.ts +30 -0
- package/templates/new/e2e/smoke.spec.ts +26 -0
- package/templates/new/examples-basic.html +57 -0
- package/templates/new/examples-theming.html +28 -0
- package/templates/new/index.html +16 -0
- package/templates/new/partials/note.html +5 -0
- package/templates/new/playwright.config.ts +4 -0
- package/templates/new/src/__FEATURE__.ts +55 -0
- package/templates/new/src/css/animations.css +1 -0
- package/templates/new/src/css/base.css +43 -0
- package/templates/new/src/css/controls.css +20 -0
- package/templates/new/src/css/dark-mode.css +36 -0
- package/templates/new/src/css/floating.css +1 -0
- package/templates/new/src/css/main.css +27 -0
- package/templates/new/src/css/states.css +22 -0
- package/templates/new/src/css/variables.css +40 -0
- package/templates/new/src/env.d.ts +7 -0
- package/templates/new/src/index.ts +17 -0
- package/templates/new/src/logger.ts +11 -0
- package/templates/new/src/types.ts +25 -0
- package/templates/new/src/web-component.ts +73 -0
- package/templates/new/test/dark-mode.html +18 -0
- package/templates/new/test/fixture.html +11 -0
- package/templates/new/tsconfig.json +15 -0
- package/templates/new/vite.config.ts +5 -0
- package/templates/new-minimal/CHANGELOG.md +13 -0
- package/templates/new-minimal/README.md +71 -0
- package/templates/new-minimal/component-variables.manifest.json +24 -0
- package/templates/new-minimal/docs/accessibility.md +20 -0
- package/templates/new-minimal/docs/examples.md +17 -0
- package/templates/new-minimal/docs/theming.md +53 -0
- package/templates/new-minimal/docs/usage.md +43 -0
- package/templates/new-minimal/e2e/smoke.spec.ts +10 -0
- package/templates/new-minimal/examples-basic.html +23 -0
- package/templates/new-minimal/examples-theming.html +28 -0
- package/templates/new-minimal/src/__FEATURE__.ts +37 -0
- package/templates/new-minimal/src/css/base.css +48 -0
- package/templates/new-minimal/src/css/controls.css +1 -0
- package/templates/new-minimal/src/css/states.css +1 -0
- package/templates/new-minimal/src/css/variables.css +26 -0
- package/templates/new-minimal/src/index.ts +17 -0
- package/templates/new-minimal/src/types.ts +10 -0
- package/templates/new-minimal/src/web-component.ts +48 -0
- package/templates/new-minimal/test/dark-mode.html +18 -0
- package/templates/new-minimal/test/fixture.html +11 -0
- package/templates/nginx.conf.tmpl +43 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.0-rc01] - 2026-10-12 [PUBLISHED]
|
|
4
|
+
|
|
5
|
+
First release of `@keenmate/web-components-devkit`, plus the component catalogue.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Catalogue**: `components.json` registry (ids, CSS prefixes, port blocks, links);
|
|
10
|
+
the README tables (components, libraries, showcases/tests — with each repo's
|
|
11
|
+
dev port, no versions/status that would go stale) are generated by
|
|
12
|
+
`npm run readme`. Port blocks of 100 per repo (dev = block, preview = +1,
|
|
13
|
+
examples image = +10), numbered by 100 inside a range per kind with headroom —
|
|
14
|
+
components 12100–14900, libraries 15000–15900, showcases/docs 16000–16900,
|
|
15
|
+
tests 17000–17900 — so repos run side by side without collisions and new
|
|
16
|
+
components land next to the existing ones.
|
|
17
|
+
- **Vite preset** `defineComponentConfig()` (Vite 7): dev server on a strict
|
|
18
|
+
registry port, library build (es + umd + `style.css` + rolled-up d.ts), and
|
|
19
|
+
`--mode examples` multi-page static build with relative asset URLs.
|
|
20
|
+
- **Examples kit**, injected into every root page: `@layer kmwc` design system
|
|
21
|
+
merged from six diverged `examples-shared.css` copies, with `--kmwc-*` tokens
|
|
22
|
+
read through the rulebook's `--base-*` taxonomy (`light-dark()` fallbacks) and
|
|
23
|
+
a light / dark / auto theme switch that drives `data-theme` on `<html>`;
|
|
24
|
+
kit-generated DOM is `kmwc-` prefixed BEM. Chapter nav (bundled Floating UI,
|
|
25
|
+
shared slug logic, last-chapter highlight at page bottom), copy-link, version
|
|
26
|
+
badge with build stamp, build-only Plausible. Helpers:
|
|
27
|
+
`attachControlsPersistence`, `renderExamplesIndex` (its footer links the
|
|
28
|
+
devkit version that built the site), `mountExamplesKit`.
|
|
29
|
+
- **Playwright preset** `definePlaywrightConfig()`.
|
|
30
|
+
- **CLI** `kmwc`: `sync` (Dockerfile, nginx.conf with immutable `/assets/`
|
|
31
|
+
caching, Makefile + `Makefile.local`, .dockerignore, CLAUDE.md block, scripts),
|
|
32
|
+
`doctor` (devkit checks + the BlissFramework rulebook's `*.checks.sh` suites),
|
|
33
|
+
`check-vars` (declared/consumed modes; replaces three script copies),
|
|
34
|
+
`check-release` (dist-tag ⇔ version, not yet on npm — gates `make publish*`),
|
|
35
|
+
`new` (rulebook-shaped scaffold with intake: npm availability, reserved-prefix
|
|
36
|
+
check, next free block in the component port range — a taken or misaligned
|
|
37
|
+
`--port` is refused), `readme`.
|
|
38
|
+
- **Fragment pages**: a page without `<html>` gets the devkit layout (head, entry
|
|
39
|
+
script, header, container) from `<meta name="kmwc:…">` tags; `<kmwc-include>` pulls
|
|
40
|
+
shared partials (parameters, nesting, cycle detection); `<kmwc-demo>` renders live
|
|
41
|
+
markup plus a code block of exactly that markup (and `<script data-kmwc-show>`), so
|
|
42
|
+
snippets can't drift from demos. `kmwc doctor` lists pages still repeating the boilerplate.
|
|
43
|
+
- **Scaffold** (`kmwc new`): Element / Logic / types / logger layers, the
|
|
44
|
+
canonical eight-file CSS set, Strategy-B dark mode, Custom Elements Manifest,
|
|
45
|
+
README + `docs/`, CHANGELOG, LICENSE, `.claude/commands/publish.md`, examples,
|
|
46
|
+
smoke + dark-mode e2e specs — example pages are fragments. `--minimal` gives an
|
|
47
|
+
empty skeleton instead of the sample toggle. A fresh scaffold passes every rulebook suite.
|
|
48
|
+
- **Playground** (`playground/`): a component scaffolded with `kmwc new`, linked to
|
|
49
|
+
the devkit and registered in the catalogue (port 17300) — the e2e test bed for
|
|
50
|
+
the kit, the presets and the scaffold, in dev and in the built site.
|
|
51
|
+
|
|
52
|
+
- **Package-contents check** in `kmwc doctor`: `npm pack --dry-run` must not ship
|
|
53
|
+
`CLAUDE.md` / `.claude/` (at any depth), tests and specs, example pages,
|
|
54
|
+
partials, build/test output or local make config (`--no-pack` skips it).
|
|
55
|
+
`kmwc new` ends `files` with `!**/CLAUDE.md` and `!**/.claude`.
|
|
56
|
+
|
|
57
|
+
- **`/publish` command** (`.claude/commands/publish.md`) for the devkit itself, in
|
|
58
|
+
the rulebook's canonical shape (passes `publish-command.checks.sh`): gates are the
|
|
59
|
+
unit tests, the playground e2e (dev + built), the playground doctor, `sync --check`
|
|
60
|
+
and `readme:check`; "build" is an entry-point smoke test, since `src/` ships as-is.
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- **Flash of unstyled page on every reload in dev** (FOUC): the kit stylesheet was
|
|
65
|
+
imported from the kit's module script, which Vite dev applies only after the script
|
|
66
|
+
runs. The plugin now loads it render-blocking: a `<link>` in `<head>` in dev, a CSS
|
|
67
|
+
import (extracted to a `<head>` `<link>`) in builds. `auto.js` no longer imports
|
|
68
|
+
it. An e2e spec loads a page with JavaScript off and checks it is styled.
|
|
69
|
+
- **Fragment detection** (`checkIsFragment`): a page is a full document only when it
|
|
70
|
+
*starts* with `<!DOCTYPE` / `<html>` (after a BOM, whitespace or comments). A fragment
|
|
71
|
+
whose script or code sample mentions `<html>` was passed through without the layout
|
|
72
|
+
(found migrating web-commandpalette's playground page).
|
|
73
|
+
|
|
74
|
+
### Migrated
|
|
75
|
+
|
|
76
|
+
- **web-commandpalette** (1.0.0-rc02) — the first component on the devkit.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Keenmate s.r.o.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,418 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Keenmate Web Components
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The index of Keenmate's web components **and** the shared tooling that keeps
|
|
4
|
+
them in the same shape: `@keenmate/web-components-devkit`.
|
|
5
|
+
|
|
6
|
+
- **[Catalogue](#catalogue)**: every component, library, showcase and test
|
|
7
|
+
harness, with CSS prefixes, dev ports and links. It's
|
|
8
|
+
generated from [`components.json`](components.json).
|
|
9
|
+
- **[Devkit](#the-devkit)**: one Vite preset, one examples kit, one Playwright
|
|
10
|
+
preset and the `kmwc` CLI, instead of a diverged copy of each in every repo.
|
|
11
|
+
|
|
12
|
+
> **The rules** — component structure, naming, CSS, theming, README, Custom
|
|
13
|
+
> Elements Manifest, publishing — live in the BlissFramework rulebook
|
|
14
|
+
> (`BlissFramework/guidelines/web-components/`, plus the JS coding guidelines
|
|
15
|
+
> in `BlissFramework/web/docs/coding-guidelines-javascript/`). The devkit
|
|
16
|
+
> **generates** what the rulebook asks for (`kmwc new`) and **checks** it
|
|
17
|
+
> (`kmwc doctor` runs the rulebook's `*.checks.sh` suites). Runtime code shared
|
|
18
|
+
> between components (BlissElement, the input table, converters, logging,
|
|
19
|
+
> positioning) lives in [`@keenmate/web-components-core`](../web-components-core).
|
|
20
|
+
> Nothing here ships inside a component's bundle.
|
|
21
|
+
|
|
22
|
+
## What's New in v1.0.0-rc01
|
|
23
|
+
|
|
24
|
+
- **Devkit — one shared toolchain for every Keenmate web component** — Each `web-*` repo used to carry its own copy of the example helpers, the shared stylesheet, the Vite/Playwright configs and the deploy files, and every session "fixed" its own copy until they drifted apart. `@keenmate/web-components-devkit` owns all of it now: a component describes itself once in `package.json#kmwc` (title, prefix, ports, accent colours, analytics, image) and `defineComponentConfig()`, `definePlaywrightConfig()` and the `kmwc` CLI read it from there. A shared concern is fixed once in the devkit and every component picks it up on the next install.
|
|
25
|
+
- **Vite preset — dev, library and examples-site builds from one config** — `defineComponentConfig()` (Vite 7) runs the dev server on the repo's registry port with `strictPort`, builds the library (`es` + `umd`, `style.css` kept under its historical name, rolled-up `.d.ts`) and, with `--mode examples`, builds every root `*.html` into a static multi-page site in `dist-examples/` with relative asset URLs. The examples plugin injects the kit into each page and loads its stylesheet render-blocking, so pages don't flash unstyled on reload.
|
|
26
|
+
- **Examples kit — one design system and set of page helpers instead of six forks** — The `@layer kmwc` stylesheet merges six diverged `examples-shared.css` copies; its `--kmwc-*` tokens read the rulebook's `--base-*` taxonomy with `light-dark()` fallbacks, so a theme-designer theme restyles the demo page together with the component. Every page gets a light / dark / auto theme switch (it sets `data-theme` on `<html>`, the signal components react to), a chapter nav and copy-link buttons that share one slug algorithm, a version badge with the build stamp, and build-only Plausible. `attachControlsPersistence()` and `renderExamplesIndex()` replace the per-repo controls store and the 150-line inline index page.
|
|
27
|
+
- **Fragment pages — no more copied page boilerplate** — A page without `<html>` is a fragment: `<meta name="kmwc:title">` and friends drive the shared layout (head, entry script, header with back link, container), `<kmwc-include>` pulls parameterised partials (nesting, cycle detection), and `<kmwc-demo>` renders live markup plus a code block of exactly that markup, so a snippet can no longer drift from its demo. Full documents pass through untouched, so pages migrate one at a time.
|
|
28
|
+
- **`kmwc` CLI — generate, check and gate instead of hand-edit** — `kmwc sync` writes the Dockerfile, nginx.conf, Makefile (repo targets in `Makefile.local`), .dockerignore and a managed CLAUDE.md block from templates. `kmwc doctor` runs the devkit checks, an `npm pack` contents check (no CLAUDE.md, tests or example pages in the package) and every BlissFramework rulebook `*.checks.sh` suite. `kmwc check-vars` replaces three diverged manifest scripts (declared or consumed mode), and `kmwc check-release` gates `make publish*` on the dist-tag ⇔ version rule.
|
|
29
|
+
- **`kmwc new` — a rulebook-shaped component on the first commit** — The scaffold runs the rulebook intake (npm name free, CSS prefix 2–4 letters and not reserved, next free port block) and generates the Element / Logic / types / logger layers, the canonical eight-file CSS set with Strategy-B dark mode, a Custom Elements Manifest, README + `docs/`, CHANGELOG, `/publish`, fragment example pages and smoke + dark-mode e2e specs. It passes every rulebook suite as generated; `--minimal` gives an empty skeleton instead of the sample toggle.
|
|
30
|
+
- **Catalogue and port registry — every component listed, no port collisions** — `components.json` registers every Keenmate repo with its CSS prefix and a 100-port block (dev = block, preview = +1, image = +10), numbered inside a range per kind (components 12100–14900, libraries 15000–, showcases 16000–, tests 17000–), so any number of repos run side by side. The README catalogue is generated from it, with a ✅ for each repo on the devkit; web-commandpalette is the first.
|
|
31
|
+
|
|
32
|
+
## Catalogue
|
|
33
|
+
|
|
34
|
+
<!-- kmwc:catalogue:start — generated by `npm run readme`, do not edit inside -->
|
|
35
|
+
### Components
|
|
36
|
+
|
|
37
|
+
| Component | Package | Prefix | Dev port | Links | Devkit | About |
|
|
38
|
+
|---|---|---|---:|---|:---:|---|
|
|
39
|
+
| **web-multiselect** | `@keenmate/web-multiselect` | `ms` | 12100 | [repo](https://github.com/keenmate/web-multiselect) · [examples](https://examples.web-multiselect.keenmate.dev) · [docs](https://web-multiselect.keenmate.dev) · `web-multiselect-showcase` · `web-multiselect-docs` | — | Lightweight multiselect web component with typeahead search, rich content support, and excellent keyboard… |
|
|
40
|
+
| **web-daterangepicker** | `@keenmate/web-daterangepicker` | `drp` | 12200 | [repo](https://github.com/keenmate/web-daterangepicker) · [docs](https://web-daterangepicker.keenmate.dev) · `web-daterangepicker-showcase` | — | Lightweight date picker web component with excellent keyboard navigation and range selection |
|
|
41
|
+
| **web-treeview** | `@keenmate/web-treeview` | `wtv` | 12300 | [repo](https://github.com/keenmate/web-treeview) · `web-treeview-showcase` | — | Lightweight treeview web component with hierarchical data display, search, expand/collapse, drag-drop, and… |
|
|
42
|
+
| **web-commandpalette** | `@keenmate/web-commandpalette` | `cp` | 12400 | [repo](https://github.com/keenmate/web-commandpalette) · [examples](https://examples.web-commandpalette.keenmate.dev) | ✅ | Framework-agnostic command-palette web component — modes, multi-step commands, scoped + global search,… |
|
|
43
|
+
| **web-dropzone** | `@keenmate/web-dropzone` | `dz` | 12500 | [repo](https://github.com/keenmate/web-dropzone) | — | Lightweight file dropzone web component with drag-drop, previews, validation, and multiple display modes. |
|
|
44
|
+
| **web-grid** | `@keenmate/web-grid` | `wg` | 12600 | [repo](https://github.com/keenmate/web-grid) · [docs](https://web-grid.keenmate.com) · [showcase](https://web-grid.keenmate.com) | — | Framework-agnostic data grid web component with sorting, filtering, inline editing, and keyboard navigation |
|
|
45
|
+
| **web-editor** | `@keenmate/web-editor` | — | 12700 | [examples](https://examples.web-editor.keenmate.dev) | — | KeenMate Web Editor monorepo — a framework-agnostic WYSIWYG / Markdown editor built on ProseMirror. |
|
|
46
|
+
| **web-switch** | `@keenmate/web-switch` | — | 12800 | [repo](https://github.com/keenmate/web-switch) | — | Framework-agnostic web component wrapper for @keenmate/svelte-switch. Works with React, Vue, Angular, or… |
|
|
47
|
+
| **web-timepicker** | — | — | 12900 | — | — | Vanilla-JS prototypes (spiral / slider time pickers); no package yet. |
|
|
48
|
+
| **web-wysiwyg** | — | — | 13000 | — | — | ProseMirror exploration; superseded by web-editor. |
|
|
49
|
+
|
|
50
|
+
### Shared libraries
|
|
51
|
+
|
|
52
|
+
| Library | Package | Dev port | About |
|
|
53
|
+
|---|---|---:|---|
|
|
54
|
+
| **web-components-core** | `@keenmate/web-components-core` | 15000 | Runtime foundation: BlissElement, reactive input table, converters, logging, positioning, CEM preset. |
|
|
55
|
+
| **web-components** | `@keenmate/web-components-devkit` | 15100 | This repo — dev/demo/build tooling (Vite preset, examples kit, kmwc CLI). |
|
|
56
|
+
|
|
57
|
+
### Showcases, docs & test harnesses
|
|
58
|
+
|
|
59
|
+
| Repo | Kind | For | Dev port | About |
|
|
60
|
+
|---|---|---|---:|---|
|
|
61
|
+
| web-multiselect-showcase | showcase | web-multiselect | 16000 | |
|
|
62
|
+
| web-daterangepicker-showcase | showcase | web-daterangepicker | 16100 | |
|
|
63
|
+
| web-treeview-showcase | showcase | web-treeview | 16200 | |
|
|
64
|
+
| web-grid-showcase | showcase | web-grid | 16300 | [https://web-grid.keenmate.com](https://web-grid.keenmate.com) |
|
|
65
|
+
| web-multiselect-docs | docs | web-multiselect | 16400 | Content-only docs (keendocs). |
|
|
66
|
+
| web-component-framework-test | test | — | 17000 | Smoke + contrast tests inside CSS host frameworks (plain / Bootstrap / …). |
|
|
67
|
+
| web-multiselect-test | test | web-multiselect | 17100 | npm-install vs direct-file consumption checks before publishing. |
|
|
68
|
+
| web-multiselect-positioning-demo | test | web-multiselect | 17200 | Single-page positioning repro. |
|
|
69
|
+
| web-playground | test | web-components | 17300 | Devkit e2e test bed — a component scaffolded with `kmwc new`, linked to this repo. |
|
|
70
|
+
|
|
71
|
+
**Ports** — a block of 100 per repo: dev server = **Dev port**, preview = +1, examples image = +10. Each kind numbers its blocks by 100 inside its own range (component 12100–14900 · library 15000–15900 · showcase & docs 16000–16900 · test 17000–17900), so any number of repos run side by side without collisions and a new component lands next to the others. `kmwc doctor` checks a repo against its block; `kmwc new` takes the next free one.
|
|
72
|
+
<!-- kmwc:catalogue:end -->
|
|
73
|
+
|
|
74
|
+
To add or change a row, edit [`components.json`](components.json) and run
|
|
75
|
+
`npm run readme`. Descriptions and the Devkit ✅ are read from the
|
|
76
|
+
sibling checkouts next to this repo. `npm run readme:check` fails when the
|
|
77
|
+
table is stale. Prefixes mirror the reserved-prefix table in the rulebook's
|
|
78
|
+
`base-variables.md`, which stays the authority.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## The devkit
|
|
83
|
+
|
|
84
|
+
### Why
|
|
85
|
+
|
|
86
|
+
Before the devkit, every component repo carried its own copy of
|
|
87
|
+
`examples-shared.css` (six copies, six different versions),
|
|
88
|
+
`examples-chapter-nav.js` (three versions), `examples-copy-link.js`,
|
|
89
|
+
`examples-controls-store.js`, `plausible-snippet.html`,
|
|
90
|
+
`check-variable-manifest.mjs`, a `vite.config.ts`, a `Dockerfile`, an
|
|
91
|
+
`nginx.conf` and a `Makefile`. A fix made in one repo never reached the others.
|
|
92
|
+
web-treeview forked the whole 980-line stylesheet just to change purple to
|
|
93
|
+
green. Two components shared a dev port and three shared an image port.
|
|
94
|
+
|
|
95
|
+
The devkit owns all of that. A component states what's specific to it **once**,
|
|
96
|
+
in `package.json#kmwc`, and gets the rest.
|
|
97
|
+
|
|
98
|
+
### What a component gets
|
|
99
|
+
|
|
100
|
+
| Piece | Import / command | Replaces |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| Vite preset | `@keenmate/web-components-devkit/vite` → `defineComponentConfig()` | per-repo `vite.config.ts`, `vite.examples.config.ts` |
|
|
103
|
+
| Examples kit (auto-injected) | shared styles, chapter nav, copy-link buttons, theme switch, version badge, analytics | `examples-shared.css`, `examples-chapter-nav.js`, `examples-copy-link.js`, `plausible-snippet.html`, Dockerfile `sed` |
|
|
104
|
+
| Fragment pages | `<meta name="kmwc:title">` pages + `<kmwc-include>` partials + `<kmwc-demo>` (live markup = snippet) | the head / header / container boilerplate copied into every page, hand-copied `.code-block` snippets |
|
|
105
|
+
| Examples helpers | `@keenmate/web-components-devkit/examples` → `attachControlsPersistence`, `renderExamplesIndex`, `mountExamplesKit` | `examples-controls-store.js`, 150 lines of inline index-page CSS |
|
|
106
|
+
| Playwright preset | `@keenmate/web-components-devkit/playwright` → `definePlaywrightConfig()` | per-repo `playwright.config.ts` |
|
|
107
|
+
| Generated files | `kmwc sync` | hand-edited `Dockerfile`, `nginx.conf`, `Makefile`, `.dockerignore` |
|
|
108
|
+
| Standard check | `kmwc doctor` (devkit checks + the rulebook's `*.checks.sh`) | — |
|
|
109
|
+
| Manifest check | `kmwc check-vars` | 3 diverged `check-variable-manifest.mjs` |
|
|
110
|
+
| Release gate | `kmwc check-release` (used by `make publish` / `publish-rc`) | — |
|
|
111
|
+
| Scaffolder | `kmwc new web-<name> --prefix <p>` | copy-pasting the last repo |
|
|
112
|
+
|
|
113
|
+
### Install
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
npm i -D @keenmate/web-components-devkit vite@^7
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
To develop against a local checkout of this repo, keep the semver range in
|
|
120
|
+
`package.json` (Docker builds install from the registry) and link it:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
cd ../web-components && npm link
|
|
124
|
+
cd ../web-<component> && npm link @keenmate/web-components-devkit
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Peer dependencies (`vite`, `@playwright/test`) are always resolved from the
|
|
128
|
+
**component's** `node_modules`, so a linked devkit doesn't load a second copy.
|
|
129
|
+
|
|
130
|
+
### `package.json#kmwc`
|
|
131
|
+
|
|
132
|
+
Every field is optional. Defaults are derived from the package.
|
|
133
|
+
|
|
134
|
+
```jsonc
|
|
135
|
+
"kmwc": {
|
|
136
|
+
"title": "Web MultiSelect", // examples index header
|
|
137
|
+
"tagline": "Feature-rich multiselect …", // default: package.json description
|
|
138
|
+
"tag": "web-multiselect",
|
|
139
|
+
"prefix": "ms", // reserved CSS prefix (rulebook base-variables.md)
|
|
140
|
+
"library": {
|
|
141
|
+
"entry": "src/index.ts", // default
|
|
142
|
+
"globalName": "MultiSelect", // UMD global
|
|
143
|
+
"fileName": "multiselect", // → dist/multiselect.js + .umd.js
|
|
144
|
+
"cssFileName": "style", // default; keeps dist/style.css on Vite 7
|
|
145
|
+
"shouldEmitTypes": true, // rolled-up .d.ts (typesPluginConfig to tune)
|
|
146
|
+
"shouldEmitSourcemap": false,
|
|
147
|
+
"external": []
|
|
148
|
+
},
|
|
149
|
+
"ports": { "dev": 12100, "image": 12110 }, // the repo's components.json port block (+10 = image)
|
|
150
|
+
"theme": { "accentColor": "#667eea", "accentEndColor": "#764ba2" },
|
|
151
|
+
"examples": {
|
|
152
|
+
"canonicalOrigin": "https://examples.web-multiselect.keenmate.dev",
|
|
153
|
+
"staticPaths": ["examples-data", "docs"], // copied verbatim into the built site
|
|
154
|
+
"excludedPages": [], // root *.html that aren't example pages
|
|
155
|
+
"outDir": "dist-examples"
|
|
156
|
+
},
|
|
157
|
+
"analytics": { "plausibleSiteId": "pa-5vUESDVyztHMyzN5gs5A4" },
|
|
158
|
+
"image": {
|
|
159
|
+
"name": "registry.km8.es/web-multiselect-examples:prod",
|
|
160
|
+
"runner": "podman",
|
|
161
|
+
"packageJsonPaths": ["package.json"] // monorepos: list workspace package.jsons too
|
|
162
|
+
},
|
|
163
|
+
"cssVariables": {
|
|
164
|
+
"sources": ["src/css"], // dirs (stylesheets) or explicit files (any type)
|
|
165
|
+
"internalVariables": ["ms-input-current-width"], // runtime internals, not theming knobs
|
|
166
|
+
"checkMode": "declared" // or "consumed" (var() reads)
|
|
167
|
+
},
|
|
168
|
+
"rulebook": {
|
|
169
|
+
"path": "../../BlissFramework/guidelines/web-components", // default; env KMWC_RULEBOOK_PATH wins
|
|
170
|
+
"skippedChecks": [] // e.g. ["responsive-overlay"]
|
|
171
|
+
},
|
|
172
|
+
"sync": { "skippedFiles": [] } // e.g. ["Makefile"] to opt a file out
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Vite preset
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
// vite.config.ts
|
|
180
|
+
import { defineComponentConfig } from '@keenmate/web-components-devkit/vite';
|
|
181
|
+
export default defineComponentConfig();
|
|
182
|
+
|
|
183
|
+
// with repo-specific bits
|
|
184
|
+
export default defineComponentConfig({
|
|
185
|
+
plugins: [shadowCssPlugin()],
|
|
186
|
+
overrides: { optimizeDeps: { entries: ['index.html', 'examples-*.html'] } },
|
|
187
|
+
getOverridesCallback: (env, config) => ({ /* env-dependent bits */ }),
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Command | Result |
|
|
192
|
+
|---|---|
|
|
193
|
+
| `vite` | dev server on `kmwc.ports.dev` (strict, never hops ports) |
|
|
194
|
+
| `vite build` | library: `dist/<fileName>.js`, `.umd.js`, `style.css`, rolled-up `.d.ts` |
|
|
195
|
+
| `vite build --mode examples` | static examples site → `dist-examples/` (every root `*.html` is a page) |
|
|
196
|
+
| `vite preview --mode examples` | serves the built site on the preview port (`ports.dev + 1`) |
|
|
197
|
+
|
|
198
|
+
The preset defines `__VERSION__`, `__PACKAGE_NAME__`, `__AUTHOR__`,
|
|
199
|
+
`__LICENSE__`, `__REPOSITORY__` and `__HOMEPAGE__`. For a hand-assembled config
|
|
200
|
+
(monorepos, showcases), use the plugin on its own: `createExamplesPlugin()`.
|
|
201
|
+
|
|
202
|
+
### Examples kit
|
|
203
|
+
|
|
204
|
+
The plugin injects the kit into every **root-level** `*.html` page. Pages under
|
|
205
|
+
`test/` (Playwright fixtures) are left alone, and any page can opt out with
|
|
206
|
+
`<html data-kmwc="off">`.
|
|
207
|
+
|
|
208
|
+
#### Fragment pages — no copied boilerplate
|
|
209
|
+
|
|
210
|
+
A page without `<html>` is a **fragment**: it carries only its own content,
|
|
211
|
+
and the plugin wraps it in the devkit layout (head, entry script, header with
|
|
212
|
+
back link / title / subtitle, container). The whole file:
|
|
213
|
+
|
|
214
|
+
```html
|
|
215
|
+
<meta name="kmwc:title" content="Tree of Options">
|
|
216
|
+
<meta name="kmwc:subtitle" content="Hierarchical options via a materialized path-member…">
|
|
217
|
+
<link rel="stylesheet" href="examples-local.css"> <!-- moved into <head> -->
|
|
218
|
+
|
|
219
|
+
<kmwc-include src="partials/no-collapse-note.html" title="No collapse"></kmwc-include>
|
|
220
|
+
|
|
221
|
+
<div class="card"> <!-- each h2 = a chapter -->
|
|
222
|
+
<h2>TR01 · Basic tree</h2>
|
|
223
|
+
<kmwc-demo>
|
|
224
|
+
<web-multiselect id="tree" path-member="path"></web-multiselect>
|
|
225
|
+
<script type="module" data-kmwc-show>
|
|
226
|
+
document.getElementById('tree').options = [{ value: 'fruit', label: 'Fruit', path: '1' }];
|
|
227
|
+
</script>
|
|
228
|
+
</kmwc-demo>
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<script type="module">
|
|
232
|
+
import { attachControlsPersistence } from '@keenmate/web-components-devkit/examples';
|
|
233
|
+
attachControlsPersistence('tree');
|
|
234
|
+
</script>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
| Construct | Does |
|
|
238
|
+
|---|---|
|
|
239
|
+
| `<meta name="kmwc:title">` (required), `kmwc:subtitle`, `kmwc:body-class` | header + `<title>`, body classes |
|
|
240
|
+
| `<meta name="kmwc:layout" content="bare">` | head only, no header/container (the index page) |
|
|
241
|
+
| `<meta name="kmwc:entry" content="none">` | skip the component entry script (default `/<kmwc.library.entry>`, loaded in `<head>` so the element is defined before page scripts run) |
|
|
242
|
+
| `<link>` / `<style>` anywhere in a fragment | moved into `<head>` |
|
|
243
|
+
| `<kmwc-include src="partials/x.html" some-param="v">inner</kmwc-include>` | the partial with `{{someParam}}` and `{{content}}` filled in; nests; cycles are an error; unknown `{{…}}` stay as written |
|
|
244
|
+
| `<kmwc-demo>markup</kmwc-demo>` | the markup live **and** as a code block of exactly that markup (copy button included) — a snippet can't drift from its demo. `<script data-kmwc-show>` inside runs and is shown too. Attributes: `preview-class`, `markup-hidden`, `code-hidden` |
|
|
245
|
+
|
|
246
|
+
Tags inside HTML comments are never expanded. Partials live in the repo's
|
|
247
|
+
`partials/` folder (a change reloads the dev server page); shared demo data
|
|
248
|
+
belongs in `examples-data/*.js` modules imported by pages. Full documents
|
|
249
|
+
(`<html>…`) pass through untouched, so pages migrate one at a time — `kmwc
|
|
250
|
+
doctor` lists the ones still repeating the head/header boilerplate.
|
|
251
|
+
|
|
252
|
+
- **Styles** live in `@layer kmwc`, so any unlayered rule beats them
|
|
253
|
+
regardless of order (and the layered reset can never clobber a component).
|
|
254
|
+
Tokens (`--kmwc-*`) read through the rulebook's `--base-*` taxonomy with
|
|
255
|
+
`light-dark()` fallbacks, so a theme-designer theme restyles the demo page
|
|
256
|
+
together with the component; colour literals live only in `tokens.css`.
|
|
257
|
+
Re-theme a site with `kmwc.theme.accentColor`. The page vocabulary is
|
|
258
|
+
unchanged from the old shared CSS — `.card`, `.example-section`, `.controls`,
|
|
259
|
+
`.demo-area`, `.demo-card`, `.code-block`, `.note(.warning|.info|.success|.error)`,
|
|
260
|
+
`.grid`/`.card-grid`, `.reference-table`, `.log-panel`, `.pill`,
|
|
261
|
+
`.status-dot`, `.control-group`, buttons (`.btn-secondary`, `.btn-outline`,
|
|
262
|
+
`.btn-danger`) — while everything the kit **generates** is prefixed BEM
|
|
263
|
+
(`kmwc-chapter-nav__item--active`, `kmwc-copy-link--copied`, …).
|
|
264
|
+
- **Theme switch** (top right) cycles light → dark → auto and sets
|
|
265
|
+
`data-theme` on `<html>` — the same signal components react to via
|
|
266
|
+
`:host-context([data-theme])`, so every example page is a dark-mode smoke
|
|
267
|
+
test. The saved choice is applied before first paint.
|
|
268
|
+
- **Chapter nav and copy-link** share one section/slug algorithm, so the
|
|
269
|
+
jump-list hashes and copied links always match. Floating UI is bundled (no
|
|
270
|
+
CDN). At the bottom of a short page, the last chapter gets highlighted.
|
|
271
|
+
- **Version badge**: any `[data-kmwc-version]` (or legacy `#version-badge`)
|
|
272
|
+
shows `v1.2.3`, or `v1.2.3 (built …)` in a built site.
|
|
273
|
+
- **Landing page**: `renderExamplesIndex({ pages })` renders the header, cards,
|
|
274
|
+
footer and cross-page nav from the registry plus `kmwc` config.
|
|
275
|
+
- **Late content**: the kit mounts one task after DOM-ready. Pages that render
|
|
276
|
+
sections after a fetch call `mountExamplesKit()`.
|
|
277
|
+
- **Analytics**: the Plausible snippet goes into **built** pages only, and only
|
|
278
|
+
when `kmwc.analytics.plausibleSiteId` is set.
|
|
279
|
+
|
|
280
|
+
### Playwright preset
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
import { definePlaywrightConfig, devices } from '@keenmate/web-components-devkit/playwright';
|
|
284
|
+
export default definePlaywrightConfig({
|
|
285
|
+
projects: [
|
|
286
|
+
{ name: 'chromium', use: { ...devices['Desktop Chrome'] }, testIgnore: ['**/mobile.spec.ts'] },
|
|
287
|
+
{ name: 'mobile', use: { ...devices['Pixel 7'] }, testMatch: ['**/mobile.spec.ts'] },
|
|
288
|
+
],
|
|
289
|
+
});
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
baseURL and the `npm run dev` web server come from `kmwc.ports.dev`.
|
|
293
|
+
|
|
294
|
+
### CLI
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
kmwc sync [--check] regenerate Dockerfile, nginx.conf, Makefile, .dockerignore, the
|
|
298
|
+
CLAUDE.md devkit block, .gitignore entries, missing standard scripts
|
|
299
|
+
kmwc doctor [--json] devkit checks + package contents + the rulebook's *.checks.sh suites
|
|
300
|
+
(exit 1 on errors). --verbose lists passes, --no-rulebook skips the
|
|
301
|
+
suites, --no-pack skips the package-contents check
|
|
302
|
+
kmwc check-vars [--strict] component-variables.manifest.json ⇔ CSS
|
|
303
|
+
kmwc check-release --tag t latest ⇔ release version, rc ⇔ -rcN, version not yet on npm
|
|
304
|
+
kmwc new web-<name> scaffold a component (--prefix, --title, --tag, --dir, --port, --minimal, --register)
|
|
305
|
+
kmwc readme [--check] regenerate this README's catalogue (devkit repo only)
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Generated files start with a `GENERATED by kmwc sync` header. Repo-specific
|
|
309
|
+
make targets go in `Makefile.local`, which the generated Makefile includes at
|
|
310
|
+
the end. Per-developer overrides (`DOCKER_RUNNER`, `IMAGE_PORT`) go in
|
|
311
|
+
`.makefile.env`. `make publish` / `make publish-rc` run `kmwc check-release`
|
|
312
|
+
and the e2e suite before building and publishing.
|
|
313
|
+
|
|
314
|
+
**`kmwc doctor` and the rulebook.** Doctor runs every suite in the rulebook
|
|
315
|
+
(component-structure, naming-conventions, css-structure, theme-container,
|
|
316
|
+
base-variables, color-scheme, readme-structure, custom-elements-manifest,
|
|
317
|
+
responsive-overlay, publish-command) with `bash`, passing `kmwc.prefix`, and
|
|
318
|
+
reports each `FAIL` as an error pointing at the matching `.checks.md` entry.
|
|
319
|
+
When the rulebook isn't checked out (or there's no bash) the suites are
|
|
320
|
+
skipped with a warning — the rulebook stays the single source of truth; the
|
|
321
|
+
devkit never copies its rules.
|
|
322
|
+
|
|
323
|
+
**Package contents.** Doctor runs `npm pack --dry-run` and fails on anything
|
|
324
|
+
dev-only that would reach a consumer's `node_modules`: `CLAUDE.md` at any
|
|
325
|
+
depth and `.claude/` (AI-assistant guidance, which a directory entry such as
|
|
326
|
+
`src/css` in `files` sweeps in), `test/` / `e2e/` / `*.spec.*` / `*.test.*`,
|
|
327
|
+
example pages and `partials/`, build/test output, and local make config. Keep
|
|
328
|
+
`"!**/CLAUDE.md"` and `"!**/.claude"` at the end of `files`; the scaffold adds them.
|
|
329
|
+
|
|
330
|
+
### Scaffolding a component
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
npx kmwc new web-colorpicker --prefix cpk --title "Web Color Picker" --register
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
`kmwc new` runs the rulebook intake: the npm name must be free and the CSS
|
|
337
|
+
prefix must be 2–4 lowercase letters not reserved in `base-variables.md` or
|
|
338
|
+
`components.json` (it's derived only when unambiguous — hyphenated words, or a
|
|
339
|
+
short single word — otherwise pass `--prefix`). The result passes every
|
|
340
|
+
rulebook suite on its first commit:
|
|
341
|
+
|
|
342
|
+
- `src/web-component.ts` (`ColorpickerElement`, Element layer, `ATTRIBUTE_TABLE`,
|
|
343
|
+
`change` event with `onChange` twin) · `src/colorpicker.ts` (`WebColorpicker`,
|
|
344
|
+
logic class) · `src/types.ts` · `src/logger.ts` · `src/index.ts`
|
|
345
|
+
- `src/css/` — the canonical eight files, `@layer variables, component, overrides`,
|
|
346
|
+
`--cpk-*` ⇢ `--base-*` ⇢ `light-dark()` chains, Strategy-B dark mode, FOUC rule
|
|
347
|
+
- Custom Elements Manifest config + package.json `customElements` / `web-types`,
|
|
348
|
+
`component-variables.manifest.json` (exported as `/manifest`)
|
|
349
|
+
- README in the canonical shape, `docs/{usage,theming,examples,accessibility}.md`,
|
|
350
|
+
CHANGELOG (`## [0.1.0] - <date>`), LICENSE, `.claude/commands/publish.md`
|
|
351
|
+
- a `files` allowlist (dist, docs, manifests, editor-integration JSON) ending in
|
|
352
|
+
`!**/CLAUDE.md` and `!**/.claude`, so AI-assistant guidance never ships
|
|
353
|
+
- examples (index, basic, theming), fixtures + smoke and dark-mode e2e specs,
|
|
354
|
+
and the `kmwc sync` files
|
|
355
|
+
|
|
356
|
+
By default the component is a small working sample (a toggle with `label` /
|
|
357
|
+
`active` inputs and a `change` event) to rename or replace. Add `--minimal`
|
|
358
|
+
for an empty skeleton instead: the same files and structure, but an empty
|
|
359
|
+
`ATTRIBUTE_TABLE`, no events, a root that renders its slotted content, and
|
|
360
|
+
stub feature CSS — it passes the same rulebook suites.
|
|
361
|
+
|
|
362
|
+
Reserve the new prefix in the rulebook's `base-variables.md` afterwards — the
|
|
363
|
+
command prints the reminder.
|
|
364
|
+
|
|
365
|
+
### Migrating a component
|
|
366
|
+
|
|
367
|
+
`kmwc doctor` lists everything that's left, so run it after each step.
|
|
368
|
+
|
|
369
|
+
1. `npm i -D @keenmate/web-components-devkit vite@^7` (plus `@playwright/test`
|
|
370
|
+
if the repo has e2e tests).
|
|
371
|
+
2. Add `package.json#kmwc`. Take the port block (`ports.dev` = block,
|
|
372
|
+
`ports.image` = block + 10) and prefix from
|
|
373
|
+
[`components.json`](components.json), the Plausible id from the old
|
|
374
|
+
`plausible-snippet.html` (`analytics.plausibleSiteId`), the image name and
|
|
375
|
+
runner from the old Makefile, the canonical origin from the old
|
|
376
|
+
`examples-copy-link.js`, and internals from the old
|
|
377
|
+
`check-variable-manifest.mjs` (`cssVariables.internalVariables`).
|
|
378
|
+
3. Replace `vite.config.ts` (and any `vite.examples.config.ts`) with
|
|
379
|
+
`defineComponentConfig()`. Move genuinely specific bits to `plugins` and
|
|
380
|
+
`overrides`. Do the same for `playwright.config.ts`.
|
|
381
|
+
4. Pages: delete the `<link href="examples-shared.css">` and the
|
|
382
|
+
`examples-chapter-nav.js` / `examples-copy-link.js` script tags. Change
|
|
383
|
+
`import { persistControls } from './examples-controls-store.js'` to
|
|
384
|
+
`import { attachControlsPersistence } from '@keenmate/web-components-devkit/examples'`
|
|
385
|
+
(same storage keys — saved demo state survives). Move component-only CSS into
|
|
386
|
+
`examples-local.css`.
|
|
387
|
+
5. Swap `index.html` for `renderExamplesIndex({ pages })`, keeping the page
|
|
388
|
+
registry. The inline `<style>` and header markup go away.
|
|
389
|
+
6. Delete the legacy files: `examples-chapter-nav.js`, `examples-copy-link.js`,
|
|
390
|
+
`examples-controls-store.js`, `examples-shared.css`,
|
|
391
|
+
`plausible-snippet.html`, `scripts/check-variable-manifest.mjs`.
|
|
392
|
+
7. Set `"check:vars": "kmwc check-vars"` and run it.
|
|
393
|
+
8. `npx kmwc sync`, then review the diff. Repo-specific Makefile targets move
|
|
394
|
+
to `Makefile.local`.
|
|
395
|
+
9. Check it runs: `npm run dev`, `npm run build`, `npm run build:examples`,
|
|
396
|
+
`npm run preview:examples`, the e2e tests, and finally `npx kmwc doctor`
|
|
397
|
+
(devkit + rulebook — rulebook failures are real findings to fix or to
|
|
398
|
+
document under `## Known limitations`, per the rulebook).
|
|
399
|
+
|
|
400
|
+
### Developing the devkit
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
npm install
|
|
404
|
+
npm test # unit tests (config, registry, templates, sync, checks, intake, plugin, kit)
|
|
405
|
+
npm run test:e2e # playground: the kit + scaffold in a real browser, dev server AND built site
|
|
406
|
+
npm run readme # regenerate the catalogue
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
[`playground/`](playground) is a real component scaffolded with `kmwc new` and
|
|
410
|
+
linked to this checkout. It's the reference for "what a component looks like",
|
|
411
|
+
the e2e target for every kit feature, and `npx kmwc doctor` inside it must
|
|
412
|
+
report every rulebook suite green. When you change the kit or a template, add
|
|
413
|
+
a spec there.
|
|
414
|
+
|
|
415
|
+
Releases are prepared with the `/publish` Claude command
|
|
416
|
+
(`.claude/commands/publish.md`, the rulebook's canonical `/publish` with devkit
|
|
417
|
+
steps: unit + e2e + playground doctor + catalogue check, entry-point smoke
|
|
418
|
+
test, `npm pack` review). It never publishes or pushes. That's yours.
|