@c2n/mcp 0.0.11 → 0.0.13
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/data/registry.json +48 -12
- package/package.json +2 -2
package/data/registry.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"c2nVersion": "0.0.
|
|
3
|
+
"c2nVersion": "0.0.13",
|
|
4
4
|
"categories": [
|
|
5
5
|
"Inputs",
|
|
6
6
|
"Buttons",
|
|
@@ -11664,7 +11664,7 @@
|
|
|
11664
11664
|
"default": "420px",
|
|
11665
11665
|
"part": "",
|
|
11666
11666
|
"property": "max-height",
|
|
11667
|
-
"description": "The editor scrolls past this height."
|
|
11667
|
+
"description": "The editor scrolls past this height. A height set on the element itself reaches the editor (the label and supporting text keep theirs); set this to `none` to fill it."
|
|
11668
11668
|
},
|
|
11669
11669
|
{
|
|
11670
11670
|
"name": "--c2-code-editor--padding-block",
|
|
@@ -14076,7 +14076,7 @@
|
|
|
14076
14076
|
"tag": "c2-dashboard",
|
|
14077
14077
|
"className": "Dashboard",
|
|
14078
14078
|
"modulePath": "@c2n/dashboard",
|
|
14079
|
-
"description": "Grid of resizable panes. The children are `c2-dash-card` elements, placed by their `col`/`row` attributes; each\none draws drag handles on the edges it shares with a neighbour, and dragging one resizes the whole track, so the\ncards on either side stay aligned. `columns` and `rows` take a track count (`columns=\"3\"` is three equal columns)\nor an explicit track list (`columns=\"320px 1fr\"`); a track is switched to pixels the first time it is dragged, and\nthe `fr` tracks around it give up the space in proportion to their weight, down to the minimums. With a\n`storage-key` the sizes survive a reload.\n\nThe grid is the sizing authority: a card never sets its own width. Give the element a height (or place it in a\nflex/grid parent that does) whenever the rows use `fr`, since the row tracks divide the host's height.",
|
|
14079
|
+
"description": "Grid of resizable panes. The children are `c2-dash-card` elements, placed by their `col`/`row` attributes; each\none draws drag handles on the edges it shares with a neighbour, and dragging one resizes the whole track, so the\ncards on either side stay aligned. `columns` and `rows` take a track count (`columns=\"3\"` is three equal columns)\nor an explicit track list (`columns=\"320px 1fr\"`); a track is switched to pixels the first time it is dragged, and\nthe `fr` tracks around it give up the space in proportion to their weight, down to the minimums. With a\n`storage-key` the sizes survive a reload.\n\n`layouts` makes the grid responsive without a remount: each entry names a media query and the tracks and card\nplacements to use while it matches, the first match wins, and every entry keeps its own stored sizes under\n`<storage-key>@<media>`.\n\nPlacement is the application's: the grid never re-places cards on its own. A pane removed or hidden at runtime\nleaves its cells empty and its neighbours where they were, and a pane added at runtime lands exactly where its\n`col`/`row` say, on top of whatever is already there if that cell is taken. To close a gap, or to make room, set\nthe cards' `col`/`row`/`col-span`/`row-span` or hand the grid a `layout` record — both are applied in place.\n\nThe grid is the sizing authority: a card never sets its own width. Give the element a height (or place it in a\nflex/grid parent that does) whenever the rows use `fr`, since the row tracks divide the host's height.",
|
|
14080
14080
|
"attributes": [
|
|
14081
14081
|
{
|
|
14082
14082
|
"name": "columns",
|
|
@@ -14119,7 +14119,7 @@
|
|
|
14119
14119
|
{
|
|
14120
14120
|
"name": "layout-change",
|
|
14121
14121
|
"type": "CustomEvent<DashboardLayoutChangeDetail>",
|
|
14122
|
-
"description": "The track sizes changed
|
|
14122
|
+
"description": "The track sizes changed: a gesture ended, `reset()` was called, or another entry of `layouts` took over. Does not bubble: listen on the element."
|
|
14123
14123
|
}
|
|
14124
14124
|
],
|
|
14125
14125
|
"cssParts": [],
|
|
@@ -14130,7 +14130,7 @@
|
|
|
14130
14130
|
"default": "8px",
|
|
14131
14131
|
"part": "",
|
|
14132
14132
|
"property": "gap",
|
|
14133
|
-
"description": "Gutter between the cards. The
|
|
14133
|
+
"description": "Gutter between the cards. The whole gutter drags: each card's handle is centred on its edge and as thick as the gap (never under `--c2-dash-card__handle--size`)."
|
|
14134
14134
|
},
|
|
14135
14135
|
{
|
|
14136
14136
|
"name": "--c2-dashboard--padding",
|
|
@@ -14167,7 +14167,7 @@
|
|
|
14167
14167
|
"tag": "c2-dash-card",
|
|
14168
14168
|
"className": "DashCard",
|
|
14169
14169
|
"modulePath": "@c2n/dashboard/dash-card.js",
|
|
14170
|
-
"description": "One pane of a `c2-dashboard`. It owns its place in the grid (`col`, `row`, `col-span`, `row-span`), the drag\nhandles on the edges it shares with a neighbour, and the optional expand controls; it draws no surface of its\nown, so put a `c2-card` — or any markup — in the default slot.\n\nA handle resizes the whole grid track, never just this card, and it only appears where there is a neighbour to\ntake the space from: the right edge has one when another column follows, the left edge when one precedes. Drag\nit, or focus it and use the arrow keys (10px a step, 1px with Shift).\n\nFilling the `header`, `actions` or `footer` slot turns on that row; with the header and actions both empty the\nexpand controls float over the top-right corner of the pane instead. An expanded card covers its neighbours,
|
|
14170
|
+
"description": "One pane of a `c2-dashboard`. It owns its place in the grid (`col`, `row`, `col-span`, `row-span`), the drag\nhandles on the edges it shares with a neighbour, and the optional expand controls; it draws no surface of its\nown, so put a `c2-card` — or any markup — in the default slot.\n\nA handle resizes the whole grid track, never just this card, and it only appears where there is a neighbour to\ntake the space from: the right edge has one when another column follows, the left edge when one precedes. Drag\nit, or focus it and use the arrow keys (10px a step, 1px with Shift).\n\nFilling the `header`, `actions` or `footer` slot turns on that row; with the header and actions both empty the\nexpand controls float over the top-right corner of the pane instead. An expanded card covers its neighbours on\nan opaque `--c2-dash-card__expanded--background` (the theme's surface colour), while the card itself stays\ntransparent at rest.\n\nA card that arrives while the grid is already on screen fades and scales in; one that leaves — through the\ngrid's `layout` record (`visible: false`) or through `dismiss()`, which removes the element once the animation\nhas played — fades out the same way. Cards present at load do not animate, and `prefers-reduced-motion` turns\nboth off.\n\nEvery built-in icon is a slot whose fallback is the default drawing, so a pane can use the host application's own\nicon set without giving up the behaviour.",
|
|
14171
14171
|
"attributes": [
|
|
14172
14172
|
{
|
|
14173
14173
|
"name": "card-id",
|
|
@@ -14245,7 +14245,7 @@
|
|
|
14245
14245
|
"slots": [
|
|
14246
14246
|
{
|
|
14247
14247
|
"name": "",
|
|
14248
|
-
"description": "Pane content.
|
|
14248
|
+
"description": "Pane content. It fills the pane: the body is a column flex box and every slotted child is a `flex: 1` item with `min-height: 0`, so a chart or an editor follows the row track without a `height: 100%` chain."
|
|
14249
14249
|
},
|
|
14250
14250
|
{
|
|
14251
14251
|
"name": "header",
|
|
@@ -14384,10 +14384,12 @@
|
|
|
14384
14384
|
{
|
|
14385
14385
|
"name": "--c2-dash-card__expanded--background",
|
|
14386
14386
|
"type": "background",
|
|
14387
|
+
"default": "#ffffff",
|
|
14387
14388
|
"part": "",
|
|
14388
14389
|
"state": "expanded",
|
|
14389
14390
|
"property": "background",
|
|
14390
|
-
"
|
|
14391
|
+
"token": "--c2-theme--color-surface",
|
|
14392
|
+
"description": "Fill while the card is expanded over its neighbours, so they do not show through; the card's own `background` stays transparent."
|
|
14391
14393
|
},
|
|
14392
14394
|
{
|
|
14393
14395
|
"name": "--c2-dash-card__expanded--z-index",
|
|
@@ -14397,6 +14399,24 @@
|
|
|
14397
14399
|
"state": "expanded",
|
|
14398
14400
|
"property": "z-index"
|
|
14399
14401
|
},
|
|
14402
|
+
{
|
|
14403
|
+
"name": "--c2-dash-card__enter--animation-duration",
|
|
14404
|
+
"type": "duration",
|
|
14405
|
+
"default": "200ms",
|
|
14406
|
+
"part": "enter",
|
|
14407
|
+
"property": "animation-duration",
|
|
14408
|
+
"token": "--c2-theme--motion-scale",
|
|
14409
|
+
"description": "Fade and scale-in of a card added to a grid that is already on screen, or shown again through the layout record. `0ms` disables it."
|
|
14410
|
+
},
|
|
14411
|
+
{
|
|
14412
|
+
"name": "--c2-dash-card__leave--animation-duration",
|
|
14413
|
+
"type": "duration",
|
|
14414
|
+
"default": "160ms",
|
|
14415
|
+
"part": "leave",
|
|
14416
|
+
"property": "animation-duration",
|
|
14417
|
+
"token": "--c2-theme--motion-scale",
|
|
14418
|
+
"description": "Fade-out before a card is hidden by the layout record or removed by `dismiss()`. `0ms` disables it."
|
|
14419
|
+
},
|
|
14400
14420
|
{
|
|
14401
14421
|
"name": "--c2-dash-card__expanded--animation-duration",
|
|
14402
14422
|
"type": "duration",
|
|
@@ -14631,7 +14651,7 @@
|
|
|
14631
14651
|
"default": "6px",
|
|
14632
14652
|
"part": "handle",
|
|
14633
14653
|
"property": "size",
|
|
14634
|
-
"description": "
|
|
14654
|
+
"description": "Smallest thickness of the grab area on an edge. Inside a grid the handle is as thick as the gutter when that is wider, centred on the edge, so the whole gutter drags."
|
|
14635
14655
|
},
|
|
14636
14656
|
{
|
|
14637
14657
|
"name": "--c2-dash-card__handle--inset",
|
|
@@ -35480,6 +35500,19 @@
|
|
|
35480
35500
|
"html": "<c2-select multiple value=\"design;engineering\" placeholder=\"Teams\" class=\"multiple\" client:only=\"lit\"><c2-list-item value=\"design\">Design</c2-list-item><c2-list-item value=\"engineering\">Engineering</c2-list-item><c2-list-item value=\"marketing\">Marketing</c2-list-item><c2-list-item value=\"sales\">Sales</c2-list-item></c2-select>",
|
|
35481
35501
|
"css": ".multiple {\n width: 220px;\n}"
|
|
35482
35502
|
},
|
|
35503
|
+
{
|
|
35504
|
+
"kind": "gallery",
|
|
35505
|
+
"label": "Checkbox multiple",
|
|
35506
|
+
"section": "Options",
|
|
35507
|
+
"description": "Checkbox multiple Options example for c2-select.",
|
|
35508
|
+
"isDefault": false,
|
|
35509
|
+
"tags": [
|
|
35510
|
+
"c2-select",
|
|
35511
|
+
"c2-list-item"
|
|
35512
|
+
],
|
|
35513
|
+
"html": "<c2-select multiple value=\"design;engineering\" placeholder=\"Teams\" class=\"checkbox-multiple\" client:only=\"lit\">\n <c2-list-item value=\"design\"><span slot=\"prefix-icon\" class=\"box\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></span>Design</c2-list-item>\n <c2-list-item value=\"engineering\"><span slot=\"prefix-icon\" class=\"box\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></span>Engineering</c2-list-item>\n <c2-list-item value=\"marketing\"><span slot=\"prefix-icon\" class=\"box\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></span>Marketing</c2-list-item>\n <c2-list-item value=\"sales\"><span slot=\"prefix-icon\" class=\"box\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></span>Sales</c2-list-item>\n</c2-select>",
|
|
35514
|
+
"css": ".checkbox-multiple {\n width: 220px;\n --c2-list-item--gap: 10px;\n --c2-list-item__selected--background: transparent;\n --c2-list-item__selected--color: #18181b;\n --c2-list-item__selected__hover--background: #f4f4f5;\n}\n.checkbox-multiple .box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: 16px;\n height: 16px;\n border: 1px solid #bcbcc6;\n border-radius: 4px;\n color: #ffffff;\n transition:\n background 120ms ease,\n border-color 120ms ease;\n}\n.checkbox-multiple .box svg {\n width: 12px;\n height: 12px;\n visibility: hidden;\n}\n.checkbox-multiple c2-list-item[selected] .box {\n background: #476ef9;\n border-color: #476ef9;\n}\n.checkbox-multiple c2-list-item[selected] .box svg {\n visibility: visible;\n}"
|
|
35515
|
+
},
|
|
35483
35516
|
{
|
|
35484
35517
|
"kind": "gallery",
|
|
35485
35518
|
"label": "Flat rows",
|
|
@@ -50479,7 +50512,7 @@
|
|
|
50479
50512
|
"light": "#ffffff",
|
|
50480
50513
|
"dark": "#18181b",
|
|
50481
50514
|
"description": "Default surface of inputs, lists, cards, dialogs.",
|
|
50482
|
-
"usedBy":
|
|
50515
|
+
"usedBy": 48
|
|
50483
50516
|
},
|
|
50484
50517
|
{
|
|
50485
50518
|
"name": "--c2-theme--color-surface-container-low",
|
|
@@ -50673,7 +50706,7 @@
|
|
|
50673
50706
|
"category": "motion",
|
|
50674
50707
|
"light": "1",
|
|
50675
50708
|
"description": "Multiplier applied to every transition and animation duration (0 disables motion).",
|
|
50676
|
-
"usedBy":
|
|
50709
|
+
"usedBy": 23
|
|
50677
50710
|
},
|
|
50678
50711
|
{
|
|
50679
50712
|
"name": "--c2-theme--shadow-md",
|
|
@@ -51060,6 +51093,9 @@
|
|
|
51060
51093
|
"--c2-copy-button__container__focus--outline": "--c2-theme--focus-ring",
|
|
51061
51094
|
"--c2-copy-button__container__disabled--opacity": "--c2-theme--disabled-opacity",
|
|
51062
51095
|
"--c2-copy-button--transition-duration": "--c2-theme--motion-scale",
|
|
51096
|
+
"--c2-dash-card__expanded--background": "--c2-theme--color-surface",
|
|
51097
|
+
"--c2-dash-card__enter--animation-duration": "--c2-theme--motion-scale",
|
|
51098
|
+
"--c2-dash-card__leave--animation-duration": "--c2-theme--motion-scale",
|
|
51063
51099
|
"--c2-dash-card__expanded--animation-duration": "--c2-theme--motion-scale",
|
|
51064
51100
|
"--c2-dash-card__header--color": "--c2-theme--color-on-surface",
|
|
51065
51101
|
"--c2-dash-card__header--font-size": "--c2-theme--font-size-md",
|
|
@@ -51715,6 +51751,6 @@
|
|
|
51715
51751
|
"workflow": "# The c2n application workflow\n\nBuild screens from `@c2n/*` web components with as little code as possible. Three layers, applied in this order.\n\n## 1. Theme once\n\n- Install `@c2n/theme` next to the component packages you use.\n- Import `@c2n/theme/theme.css` once at the application root (tokens + base theme). If the app already owns a token system, import only `@c2n/theme/base.css` and bridge your tokens onto the `--c2-theme--*` names.\n- Override the tokens that differ from the defaults on `:root` (light) and under your dark-mode selector. About 35 tokens (`--c2-theme--color-primary`, `--c2-theme--radius-md`, `--c2-theme--font-family`, `--c2-theme--focus-ring`, …) drive every component.\n- Never set component variables globally when a token exists for the job.\n\n## 2. Use the tags directly\n\n- Register an element with a side-effect import (`import '@c2n/button'`) at the application entry, or in the module that renders it.\n- Write plain markup: `<c2-button>Save</c2-button>`. Attributes, slots and events come from the component API (MCP `get_component`, or `node_modules/@c2n/<name>/custom-elements.json`).\n- Retrieve `get_examples` next: begin from the unmodified Default sample, then select gallery examples by use case. Use `get_presets` when structured values are more useful than a complete pattern.\n- Icons are components: `c2-feather-<name>` from `@c2n/feather-icons/icons/<name>.js`, sized and coloured through `--c2-feather-icon--size|color|stroke-width`.\n- A component that appears once with the themed default look needs nothing else.\n\n## 3. Name what repeats\n\nThe decision rule, cheapest first:\n\n| Situation | Do this |\n| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |\n| The element appears once, default look is fine | plain tag |\n| Same look repeats, markup is otherwise plain | **CSS-class variant**: a class that sets `--c2-<component>__…` variables |\n| Same look **and** the same attributes / slots / accessible name repeat | **wrapper component** in your framework (Astro/React/Vue/Lit) that renders the c2 element |\n| The variant must be its own tag (used from strings, other Lit templates, shipped) | **Lit subclass** of the component with the variables baked into `static styles` |\n| Several c2 components plus some logic repeat | **composed component**: children's variables set on `:host`/a class, attributes forwarded, events re-emitted |\n| No c2 component fits | app-level component styled with the same `--c2-theme--*` tokens; avoid patching installed packages locally |\n\nEvery variant lives in one directory (`src/components/ui/`, `src/ui/`…), one file per variant, under the app's own prefix (`app-*`, `site-*`, `my-*`), never `c2-*`.\n\n## 4. Verify\n\n- Every element used is registered (no `HTMLUnknownElement`, no empty tags).\n- `@c2n/theme` is imported exactly once; tokens overridden on `:root` and the dark selector.\n- Prefer CSS custom properties. Every `::part()` selector must name a CSS part documented by `get_component`; no repeated inline `style=\"--c2-…\"`.\n- Every variable, attribute, slot and event name exists in the component API.\n- Variant tags contain a hyphen and do not start with `c2-`.\n- Light and dark both look right; build, lint and type-check pass.\n",
|
|
51716
51752
|
"theming": "# Theming c2n components\n\n## Layers\n\n1. **Tokens** `--c2-theme--<name>` (from `@c2n/theme/tokens.css`, ~35 of them). Set by the application.\n2. **Base theme** `@c2n/theme/base.css`: `--c2-<component>__<part>--<prop>: var(--c2-theme--<token>, <component default>)` on `:root`/`:host` for every mapped component variable. Generated from the component manifests.\n3. **Component variables** `--c2-<component>__<part>[__<state>]--<property>`: the fine-grained escape hatch. Set on an element, a class or any ancestor; they always win over the base theme.\n4. **Variant components** built from 2 and 3.\n\n## Install\n\n```ts\nimport '@c2n/theme/theme.css' // tokens + base theme, once\n```\n\n```css\n:root {\n --c2-theme--color-primary: #7c3aed;\n --c2-theme--color-primary-hover: #6d28d9;\n --c2-theme--radius-md: 10px;\n --c2-theme--font-family: 'Inter', system-ui, sans-serif;\n}\n```\n\n## Bring your own tokens\n\n```css\n@import '@c2n/theme/base.css';\n:root {\n --c2-theme--color-primary: var(--brand-600);\n --c2-theme--color-on-primary: var(--brand-on-600);\n --c2-theme--color-surface: var(--surface);\n --c2-theme--color-on-surface: var(--text);\n --c2-theme--color-outline: var(--border);\n --c2-theme--radius-md: var(--radius);\n --c2-theme--font-family: var(--font-sans);\n --c2-theme--focus-ring: 2px solid var(--brand-600);\n}\n```\n\nDark mode then follows the app's own switch because the bridged values flip.\n\n## Dark mode with the shipped tokens\n\n`tokens.css` sets light values on `:root` and dark values under `[data-theme='dark']` and `.c2-dark`, with `prefers-color-scheme: dark` as the fallback when no `data-theme` attribute is present. `data-theme=\"light\"` / `.c2-light` opts a subtree out. Selectors are not tied to the root element, so any subtree can be inverted.\n\n## Token groups\n\n- Colour roles: `color-primary`, `color-primary-hover`, `color-primary-active`, `color-on-primary`, `color-primary-container`, `color-surface`, `color-surface-container-low`, `color-surface-container`, `color-on-surface`, `color-on-surface-variant`, `color-outline`, `color-outline-variant`, `color-outline-strong`, `color-error`, `color-scrim`, `color-inverse-surface`, `color-on-inverse-surface`.\n- Typography: `font-family` (unset by default: components inherit the page font), `font-size-sm|md`, `font-weight-medium|semibold`.\n- Shape: `radius-sm|md|lg|xl|full`.\n- Borders: `border-width`, `border` (composite: the whole resting border shorthand; falls back to `border-width solid color-outline`).\n- Interaction: `focus-ring` (outline shorthand), `disabled-opacity`, `motion-scale` (multiplies every duration; `0` disables motion).\n- Elevation: `shadow-md`, `shadow-lg`.\n\nComposite tokens wrap their primitives: `var(--c2-theme--border, var(--c2-theme--border-width, 1px) solid var(--c2-theme--color-outline, #bcbcc6))`, so set the shorthand or just the colour.\n\n## What the base theme does not cover\n\nSizes, paddings, gaps, identity colours (avatar fallbacks), status colours, the code viewer's syntax theme, and variables without a default (they inherit). Use component variables or a variant for those. `@c2n/theme/report.json` lists what is mapped per package; MCP `get_theme` with a `tag` shows the mapping of one component.\n\n## Grammar and states\n\n`--c2-<component>__<part>[__<state>]--<property>`: `__` separates component / part / state, `--` separates the CSS property. States: `hover`, `active`, `focus`, `selected`, `disabled`, `open`, `error`, `read-only`. Example: `--c2-checkbox__container__selected--background-color`.\n",
|
|
51717
51753
|
"variant-components": "# Variant and composed components\n\nA variant is one c2 component with a fixed look (CSS variables) and, sometimes, fixed attributes, slots or accessible name. A composed component is several c2 components plus glue. Both normally set children's CSS variables on the host element or a class. Use `::part()` only for a part documented by `get_component` and only when the public variables cannot express the change.\n\n## Shape 1: CSS-class variant\n\n```css\n.danger-button {\n --c2-button__container--background-color: var(--c2-theme--color-error);\n --c2-button__container__hover--background-color: color-mix(in srgb, var(--c2-theme--color-error), black 12%);\n}\n```\n\n```html\n<c2-button class=\"danger-button\">Delete</c2-button>\n```\n\nUse when only the look differs. Keep variant classes in one stylesheet (`ui/variants.css`). Read variable names from the component API; do not invent them.\n\n## Shape 2: wrapper component\n\nWhen attributes, slots or the accessible name repeat as well. Framework-native, zero runtime cost beyond the c2 element. Example (Astro; the same idea in React/Vue/Svelte):\n\n```astro\n---\n// SiteIconButton.astro — c2-icon-button with the app's size and a tooltip that defaults to the label.\ninterface Props {\n label: string\n size?: 'sm' | 'md'\n class?: string\n [attr: string]: unknown\n}\nconst { label, size = 'md', class: className = '', ...rest } = Astro.props\n---\n\n<c2-icon-button class={`site-icon-button site-icon-button--${size} ${className}`} aria-label={label} tooltip={label} {...rest}>\n <slot />\n</c2-icon-button>\n<style is:global>\n .site-icon-button {\n --c2-icon-button--border-radius: var(--c2-theme--radius-sm);\n --c2-icon-button__hover--background-color: var(--c2-theme--color-surface-container);\n }\n .site-icon-button--sm {\n --c2-icon-button__state-layer--size: 30px;\n --c2-icon-button__icon--width: 16px;\n --c2-icon-button__icon--height: 16px;\n }\n .site-icon-button--md {\n --c2-icon-button__state-layer--size: 36px;\n --c2-icon-button__icon--width: 18px;\n --c2-icon-button__icon--height: 18px;\n }\n</style>\n```\n\nForward unknown props as attributes (`{...rest}`) so callers keep the full c2 API (`disabled`, `data-*`, `aria-*`).\n\n## Shape 3: Lit subclass\n\nWhen the variant must be a tag of its own. The docs studio's Code tab and MCP `generate_variant` produce this:\n\n```ts\nimport { css } from 'lit'\nimport { Button } from '@c2n/button'\n\nexport class DangerButton extends Button {\n static override styles = [\n Button.styles,\n css`\n :host {\n --c2-button__container--background-color: var(--c2-theme--color-error);\n }\n `,\n ]\n override connectedCallback() {\n super.connectedCallback()\n this.setAttribute('running', '') // fixed attributes go here\n }\n}\nif (!customElements.get('app-danger-button')) customElements.define('app-danger-button', DangerButton)\n```\n\nImport the class from the module that defines the element (`@c2n/tabs/tab.js` for `c2-tab`, `@c2n/feather-icons/icons/<name>.js` for icons). Importing it also registers the original `c2-*` tag, which is fine. Never `customElements.define` a `c2-` name.\nGuard registration with `customElements.get()` so development HMR or repeated module evaluation cannot define the same tag twice.\n\n## Composed components\n\nSeveral c2 components and some logic repeat: a search field (`c2-text-field` + `c2-list`), a settings dialog (`c2-modal` + form controls), a toolbar (`c2-icon-button`s + `c2-tooltip`s).\n\n- Set the children's variables on the composed component's class or `:host` (custom properties inherit through shadow boundaries): `.search-palette__field { --c2-text-field--border-top: none; }`.\n- Forward the attributes callers should control as properties/attributes of the composed component.\n- Re-emit the child events callers need. In Lit use `redispatchEvent(this, event)` from `@c2n/core/dom-helper.js`; elsewhere `dispatchEvent(new CustomEvent(...))`.\n- Let the primitives keep their responsibilities (a `c2-modal` already traps focus, closes on Escape and backdrop click, locks scrolling and restores focus): write only the glue.\n- Declare composition in JSDoc (`@internalcomponent c2-list`, `@slotcomponent c2-list-item`) when the composed component is itself a Lit element with a manifest.\n\n## Naming and placement\n\n- Own prefix: `app-*`, `site-*`, `my-*`. A custom element name must contain a hyphen.\n- One file per variant, one directory (`src/components/ui/`), exported from a barrel.\n- Three-line header comment: what it wraps, which variables it fixes, where it is used.\n",
|
|
51718
|
-
"frameworks": "# Using c2n components per framework\n\nAll components are standard custom elements (Lit 3). Register with a side-effect import; then they are plain HTML.\n\n## Events (every framework)\n\nEach component that fires events exports an event map (`TableEventMap`, `SelectEventMap`, …) from the same module as its class, and declares typed `addEventListener` overloads, so the detail narrows with no cast:\n\n```ts\ntable.addEventListener('selection-change', (event) => event.detail.rows) // TableRow[]\n```\n\n`EventMapOf<T>` from `@c2n/core/event-helper.js` recovers a component's map for code that is generic over elements. Use the map type instead of hand-writing `CustomEvent<{ value: string[] }>`.\n\n`selection-change` **does not bubble** — `c2-list`, `c2-select`, `c2-table`, `c2-tabs` and `c2-virtual-list` all fire it, so a listener goes on the element itself, never on an ancestor. `c2-tabs` fires `selection-change`, not `change`.\n\nEvery form-associated component fires plain `input` and `change` alongside its semantic event, which is what generic two-way bindings listen for.\n\nA duplicate `customElements.define` warns and keeps the first definition instead of throwing.\n\n## Plain HTML / Vite / any bundler\n\n```html\n<script type=\"module\">\n import '@c2n/theme/theme.css'\n import '@c2n/button'\n</script>\n<c2-button>Save</c2-button>\n```\n\nWith a bundler, put the imports in the entry module (`main.ts`). CSS imports work through the bundler's CSS handling.\n\n## Lit\n\nImport what you render at the top of the component module (`import '@c2n/text-field'`). Extend a component for a tag variant (`class AppField extends TextField`). Re-emit child events with `redispatchEvent` from `@c2n/core/dom-helper.js`. Set child variables in your `static styles` on `:host` or on a class.\n\n## Astro\n\n- Islands (`@astrojs/lit`): `import { Button } from '@c2n/button'` in the frontmatter, `<Button client:load>` in the template. SSR'd with declarative shadow DOM, hydrated on load. Pass **kebab-case attributes** only (a prop whose name matches an element property is set as a property and forces `defer-hydration`). A `client:only` island must not contain islands: its children end up in a `<template>` and nothing hydrates; the parent module registers the children instead.\n- Plain tags + client script: `<c2-button>` in the template and `import '@c2n/button'` inside a `<script>`. Cheaper for repeated markup (no shadow-DOM copy per instance); guard the flash with `c2-button:not(:defined) { visibility: hidden }`.\n- Scoped `<style>` does not reach elements rendered by child components; use `is:global` (or `:global()`) for variant classes.\n\n## React 19\n\nCustom elements work as JSX tags. React 19 passes primitive props as attributes and functions as event listeners for `on*` names; for custom events attach listeners with a `ref` (`ref.current.addEventListener('selection-change', …)`).\n\nTypes: `import '@c2n/<name>/react'` — one line per package, in any `.d.ts` — declares the tags in `JSX.IntrinsicElements` with props derived from the element class. Do not hand-write the mapping. React 18 and older: pass attributes as strings and use refs for events and properties.\n\n## Vue 3\n\nTell the compiler about the tags: `compilerOptions.isCustomElement = (tag) => tag.startsWith('c2-')` (in `@vitejs/plugin-vue`'s `template.compilerOptions`); without it every `c2-*` tag is treated as a Vue component and renders nothing. Register the elements at module scope before `mount()`: Vue chooses between a property and an attribute with `key in el`, so a binding on an element that has not upgraded yet falls back to an attribute.\n\nTypes: `import '@c2n/<name>/vue'` registers the tags with Volar, and `\"extends\": [..., \"@c2n/framework-types/tsconfig.vue.json\"]` supplies the matching `vueCompilerOptions` (`strictTemplates`, plus the `v-model` prop mapping so `v-model` binds `value`/`checked` rather than `modelValue`). Declare no local `vueCompilerOptions` next to it — a local one replaces the inherited object rather than merging.\n\n- Events: `@selection-change`, `@submit-message` bind by their real kebab-case name — Vue calls `addEventListener` with the name as written. The handler gets a plain `Event`, so narrow it (`(event as CustomEvent<{ value: string[] }>).detail`).\n- `v-model` works on `c2-text-field` / `c2-textarea`: on a custom element Vue compiles it to the plain-text model directive, which sets `el.value` and listens for `input`, and both components expose `value` and re-emit the native `input` event.\n- `.prop` forces a DOM property (`:value.prop=\"selected\"` for array/object values); `.attr` forces an attribute (`:align.attr=\"side\"`), needed when a property is not reflected but the component styles it with `:host([attr])` — `c2-chat-message`'s `align` is the case to know.\n- A static attribute stays an attribute, so spell it the way the component declares it (`row-key`, not `rowKey`).\n\n## Angular\n\n`CUSTOM_ELEMENTS_SCHEMA` on the component is the only required configuration. `[rows]=\"…\"` writes a property with `setProperty`; `(selection-change)` binds the event by its real name. A **static** attribute stays an attribute, so a camelCase property needs `[rowKey]=\"'id'\"` or the real attribute name (`row-key`) — the lowercase spelling `rowkey` is
|
|
51754
|
+
"frameworks": "# Using c2n components per framework\n\nAll components are standard custom elements (Lit 3). Register with a side-effect import; then they are plain HTML.\n\n## Events (every framework)\n\nEach component that fires events exports an event map (`TableEventMap`, `SelectEventMap`, …) from the same module as its class, and declares typed `addEventListener` overloads, so the detail narrows with no cast:\n\n```ts\ntable.addEventListener('selection-change', (event) => event.detail.rows) // TableRow[]\n```\n\n`EventMapOf<T>` from `@c2n/core/event-helper.js` recovers a component's map for code that is generic over elements. Use the map type instead of hand-writing `CustomEvent<{ value: string[] }>`.\n\n`selection-change` **does not bubble** — `c2-list`, `c2-select`, `c2-table`, `c2-tabs` and `c2-virtual-list` all fire it, so a listener goes on the element itself, never on an ancestor. `c2-tabs` fires `selection-change`, not `change`.\n\nEvery form-associated component fires plain `input` and `change` alongside its semantic event, which is what generic two-way bindings listen for.\n\nA duplicate `customElements.define` warns and keeps the first definition instead of throwing.\n\n## Plain HTML / Vite / any bundler\n\n```html\n<script type=\"module\">\n import '@c2n/theme/theme.css'\n import '@c2n/button'\n</script>\n<c2-button>Save</c2-button>\n```\n\nWith a bundler, put the imports in the entry module (`main.ts`). CSS imports work through the bundler's CSS handling.\n\n## Lit\n\nImport what you render at the top of the component module (`import '@c2n/text-field'`). Extend a component for a tag variant (`class AppField extends TextField`). Re-emit child events with `redispatchEvent` from `@c2n/core/dom-helper.js`. Set child variables in your `static styles` on `:host` or on a class.\n\n## Astro\n\n- Islands (`@astrojs/lit`): `import { Button } from '@c2n/button'` in the frontmatter, `<Button client:load>` in the template. SSR'd with declarative shadow DOM, hydrated on load. Pass **kebab-case attributes** only (a prop whose name matches an element property is set as a property and forces `defer-hydration`). A `client:only` island must not contain islands: its children end up in a `<template>` and nothing hydrates; the parent module registers the children instead.\n- Plain tags + client script: `<c2-button>` in the template and `import '@c2n/button'` inside a `<script>`. Cheaper for repeated markup (no shadow-DOM copy per instance); guard the flash with `c2-button:not(:defined) { visibility: hidden }`.\n- Scoped `<style>` does not reach elements rendered by child components; use `is:global` (or `:global()`) for variant classes.\n\n## React 19\n\nCustom elements work as JSX tags. React 19 passes primitive props as attributes and functions as event listeners for `on*` names; for custom events attach listeners with a `ref` (`ref.current.addEventListener('selection-change', …)`).\n\nTypes: `import '@c2n/<name>/react'` — one line per package, in any `.d.ts` — declares the tags in `JSX.IntrinsicElements` with props derived from the element class, plus each kebab-case attribute name (`row-key` next to `rowKey`). Do not hand-write the mapping. React 18 and older: pass attributes as strings and use refs for events and properties.\n\n**Server-rendered React (Next.js, React Router SSR):** write a camelCase property by its kebab-case attribute name — `min-width`, `expand-full`, `storage-key`, not `minWidth`. The server writes a custom element's props into the HTML verbatim, the parser lowercases them (`minwidth`) and hydration does not set properties, so the camelCase spelling reaches the element as an attribute it does not declare. The component forwards that lookalike to the real attribute and logs a warning, so the value is not lost, but the kebab-case name is what the types list and what needs no forwarding. Object and array props (`rows`) stringify on the server: set them in an effect through a ref.\n\n## Vue 3\n\nTell the compiler about the tags: `compilerOptions.isCustomElement = (tag) => tag.startsWith('c2-')` (in `@vitejs/plugin-vue`'s `template.compilerOptions`); without it every `c2-*` tag is treated as a Vue component and renders nothing. Register the elements at module scope before `mount()`: Vue chooses between a property and an attribute with `key in el`, so a binding on an element that has not upgraded yet falls back to an attribute.\n\nTypes: `import '@c2n/<name>/vue'` registers the tags with Volar, and `\"extends\": [..., \"@c2n/framework-types/tsconfig.vue.json\"]` supplies the matching `vueCompilerOptions` (`strictTemplates`, plus the `v-model` prop mapping so `v-model` binds `value`/`checked` rather than `modelValue`). Declare no local `vueCompilerOptions` next to it — a local one replaces the inherited object rather than merging.\n\n- Events: `@selection-change`, `@submit-message` bind by their real kebab-case name — Vue calls `addEventListener` with the name as written. The handler gets a plain `Event`, so narrow it (`(event as CustomEvent<{ value: string[] }>).detail`).\n- `v-model` works on `c2-text-field` / `c2-textarea`: on a custom element Vue compiles it to the plain-text model directive, which sets `el.value` and listens for `input`, and both components expose `value` and re-emit the native `input` event.\n- `.prop` forces a DOM property (`:value.prop=\"selected\"` for array/object values); `.attr` forces an attribute (`:align.attr=\"side\"`), needed when a property is not reflected but the component styles it with `:host([attr])` — `c2-chat-message`'s `align` is the case to know.\n- A static attribute stays an attribute, so spell it the way the component declares it (`row-key`, not `rowKey`).\n\n## Angular\n\n`CUSTOM_ELEMENTS_SCHEMA` on the component is the only required configuration. `[rows]=\"…\"` writes a property with `setProperty`; `(selection-change)` binds the event by its real name. A **static** attribute stays an attribute, so a camelCase property needs `[rowKey]=\"'id'\"` or the real attribute name (`row-key`) — the lowercase spelling `rowkey` is forwarded to `row-key` with a warning.\n\nForms: Angular's built-in value accessors match `input`/`select`/`textarea` only, so `ngModel` and `formControlName` do nothing on a c2 control without `@c2n/angular`. Add `imports: [FormsModule, ...C2_FORM_ACCESSORS]`.\n\nThe schema turns off template type checking, so `$event` is a bare `Event`: take the component's event-map type in the handler rather than `$any` at the call site.\n\n## Svelte\n\nSvelte binds attributes and `on:` events directly.\n\n## Table cells\n\n`renderCell` cannot return framework markup (it is handed to Lit). Mark the column `cell-slot` and render one light-DOM child per row into `slot=\"cell:<row key>:<field>\"`; the children stay in the document, so ordinary CSS reaches them. Requires `row-key`; `renderCell`/the column format is the fallback.\n\n## Editor support outside TypeScript\n\n`@c2n/framework-types` ships `dist/html-custom-data.json` (point `html.customData` at it for VS Code / Volar) and `dist/web-types.json` (picked up automatically by the JetBrains IDEs). Both are generated from the custom-elements manifests, and cover plain HTML, Angular templates and Vue SFCs.\n\n## Server-side rendering and static HTML\n\n- Components must not touch `document`/`window` at module scope; the c2 components guard with `isServer`.\n- Without SSR of the shadow DOM, hide unregistered tags until they upgrade: `c2-modal:not(:defined) { display: none }` (dialogs, lists) or `visibility: hidden` (layout-stable chrome).\n- Server-rendered markup only carries attributes, so spell camelCase properties as their kebab-case attribute (`row-key`); see the React section for why the camelCase spelling is lost on the way.\n- Theme CSS is plain CSS; load it in the document head so the first paint is themed.\n- \"Lit is in dev mode. Not recommended for production!\" in a dev server (Next.js, Vite) is expected: Lit publishes a `development` export condition with extra checks and warnings, and dev servers resolve it. A production build resolves the default condition and the message is gone; nothing to configure.\n"
|
|
51719
51755
|
}
|
|
51720
51756
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c2n/mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "MCP server exposing the c2n web components (API, examples, presets, theme tokens, variant generation) to AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -101,5 +101,5 @@
|
|
|
101
101
|
"@c2n/config": "*",
|
|
102
102
|
"custom-elements-manifest": "2.1.0"
|
|
103
103
|
},
|
|
104
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "aa19b641f64fbc54c36b7649a8171d7a686abbdd"
|
|
105
105
|
}
|