@smwb/ui-mcp-solid 0.13.0 → 1.0.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.
@@ -6,7 +6,7 @@
6
6
  "rendering": "universal"
7
7
  },
8
8
  "extends": [
9
- "JSX.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement>"
9
+ "Omit<JSX.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement>, \"onClose\">"
10
10
  ],
11
11
  "inheritedAttributes": "Also accepts standard HTML attributes for the underlying element (see extends clause in TypeScript).",
12
12
  "styles": {
@@ -18,10 +18,11 @@
18
18
  "@smwb/ui-styles/less/components/tabs/tab/tab.entry.less"
19
19
  ],
20
20
  "dependencies": [
21
+ "@smwb/ui-styles/less/components/icon/icon.entry.less",
21
22
  "@smwb/ui-styles/less/components/ripple/ripple.entry.less",
22
23
  "@smwb/ui-styles/less/components/tabs/tabs.entry.less"
23
24
  ],
24
- "importExample": "@import (less) \"node_modules/@smwb/ui-styles/less/foundation.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/theme.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tab/tab.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/ripple/ripple.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tabs.entry.less\";"
25
+ "importExample": "@import (less) \"node_modules/@smwb/ui-styles/less/foundation.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/theme.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tab/tab.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/icon/icon.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/ripple/ripple.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tabs.entry.less\";"
25
26
  },
26
27
  "props": {
27
28
  "label": {
@@ -34,6 +35,11 @@
34
35
  "required": false,
35
36
  "description": "Is Active. Optional. Type: boolean."
36
37
  },
38
+ "tabStop": {
39
+ "type": "boolean",
40
+ "required": false,
41
+ "description": "Whether the tab is the one in the page's Tab order (`tabindex` 0, the others -1). `Tabs` sets\nit: the focused tab while focus is in the row, the selected one otherwise. On its own a tab\nis the stop while `isActive`."
42
+ },
37
43
  "contentRef": {
38
44
  "type": "Ref<HTMLSpanElement>",
39
45
  "required": false,
@@ -42,7 +48,7 @@
42
48
  "icon": {
43
49
  "type": "JSX.Element",
44
50
  "required": false,
45
- "description": "Icon node or image source."
51
+ "description": "A decorative status marker drawn left of the label (a running/done/failed icon). Its\nwrapper renders `aria-hidden=\"true\"`, so the tab's accessible name stays the label\nalone: the icon is not announced on top of it. To have the status read out, put it\nin the `label` itself."
46
52
  },
47
53
  "stacked": {
48
54
  "type": "boolean",
@@ -52,18 +58,38 @@
52
58
  "tag": {
53
59
  "type": "string",
54
60
  "required": false,
55
- "description": "Tag. Optional. Type: string."
61
+ "description": "The element to render. A tab with an `href` is an `a` unless you say otherwise."
56
62
  },
57
63
  "href": {
58
64
  "type": "string",
59
65
  "required": false,
60
- "description": "With `tag=\"a\"`: where the link goes, so the tab stays a real link."
66
+ "description": "Navigation mode: where the tab goes. The tab is then a real link (`<a href role=\"tab\">`, with\nno `target`: a tab never opens another window), so it opens in place and middle click, copy\nlink and the like work. A router takes over the plain click in `onClick` with\n`event.preventDefault()`; `Tabs` still calls `onChange` for it. A modified or non-primary click\n(Ctrl, Meta, Shift or Alt held, or a button other than the main one) is the browser's, as\n\"open in a new tab\": the router must let it through, and `Tabs` does not call `onChange`.\nThe one exception is a middle press on a `closable` tab: it closes the tab instead, as in an\neditor, and its default is prevented so nothing opens."
61
67
  },
62
68
  "disabled": {
63
69
  "type": "boolean",
64
70
  "required": false,
65
71
  "description": "Whether the control is disabled and non-interactive."
66
72
  },
73
+ "closable": {
74
+ "type": "boolean",
75
+ "required": false,
76
+ "description": "Draw a close button after the tab, and let Delete or Backspace on the focused tab close it too\n(Backspace because a Mac has no Delete key); the tab lists them in `aria-keyshortcuts`. A\nmiddle click on the tab closes it as well (`reason` \"middleClick\"): the browser's own\nmiddle-click action (autoscroll, opening a link tab in a new window) is suppressed, and the\nclick never selects. The tab does not close itself: `onClose` asks for it and the owner\nremoves the `Tab`. The button is a sibling of the tab, not inside its `role=\"tab\"`, so the\ntab's accessible name is its label alone.\nIt is out of the Tab order (`tabindex` -1), so the row keeps one tab stop, and a press on it takes\nno focus and never selects the tab. When the tab that has focus closes, `Tabs` moves focus to the\ntab that takes its place (the previous one if it was last), skipping disabled tabs. A disabled tab\nhas a disabled button.\n\nThe button stays in the accessibility tree, named by `closeLabel`: it is how a screen reader user\nwho cannot press Delete, as on a touch screen, closes the tab. It sits in the tab list beside its\ntab, though, and ARIA 1.2 lets a `tablist` own only `tab`s: a linter that applies that strictly\n(axe `aria-required-children`) can flag the button, and whatever `actions` holds.\n\nTo switch it off on a tab, pass `false` rather than leaving it out: a tab given `closable` or\n`actions` is wrapped in an item with them, a tab given neither is not, and moving between the two\nrecreates the tab and drops its focus."
77
+ },
78
+ "onClose": {
79
+ "type": "(event: Event, reason: TabCloseReason) => void",
80
+ "required": false,
81
+ "description": "Asks for the tab to close, and receives what asked for it: the close button's click (`reason`\n\"button\"), the key press of Delete or Backspace on the tab (`reason` \"key\", its default is\nprevented), the middle press on the tab (`reason` \"middleClick\", its default is prevented too),\nor the event passed to `close` by the tab's `actions` (`reason` \"actions\"). The owner removes\nthe `Tab`."
82
+ },
83
+ "closeLabel": {
84
+ "type": "string",
85
+ "required": false,
86
+ "description": "Accessible label of the close button. English by default; set it to localise, or to name the tab (\"Close Terminal 1\")."
87
+ },
88
+ "actions": {
89
+ "type": "JSX.Element | ((api: TabActionsApi) => JSX.Element)",
90
+ "required": false,
91
+ "description": "Content after the tab, before the close button: a trigger with a `Menu` (\"Rename\", \"Terminate\"),\nor any control. Give a function to get `{ close }` (see `TabActionsApi`); it is called once.\nLike the close button the content is a sibling of the tab, so it is not part of the tab's name;\nthe tab's own `ref`, `class` and handlers stay on the `role=\"tab\"` element. It stays in the\naccessibility tree as written, inside the tab list (see `closable`).\n\nThe row has one tab stop, so give the trigger `tabindex={-1}`. Shift+F10 or the Menu key on the\nfocused tab, which the tab lists in `aria-keyshortcuts`, focuses the first control in `actions`\nand clicks it, unless that control says `aria-expanded=\"true\"` (it is already open). If the\ncontrol names its popup in `aria-controls`, the first enabled `menuitem` in that element then\ntakes focus, as the WAI-ARIA menu button pattern asks: ArrowDown moves on, Enter chooses, and\nEscape hands focus back to the trigger. Without `aria-controls` focus stays on the trigger.\n\nThe row clips what overflows it: draw the menu in a `Portal`, anchored to the trigger and with\nthe `id` the trigger names. A choice that removes the tab (\"Terminate\") should call `close` with\nits event, so that `onClose` removes the tab and `Tabs` moves focus on to the neighbour; a tab\nremoved some other way leaves focus on the page."
92
+ },
67
93
  "ref": {
68
94
  "type": "Ref<HTMLButtonElement | HTMLAnchorElement>",
69
95
  "required": false,
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "TabPanel",
3
+ "description": "Content panel of one tab, linked to it by aria-labelledby; shown while the tab is selected. Goes in the panels of Tabs.",
4
+ "ssr": {
5
+ "safe": true,
6
+ "rendering": "universal"
7
+ },
8
+ "extends": [
9
+ "JSX.HTMLAttributes<HTMLDivElement>"
10
+ ],
11
+ "inheritedAttributes": "Also accepts standard HTML attributes for the underlying element (see extends clause in TypeScript).",
12
+ "styles": {
13
+ "base": [
14
+ "@smwb/ui-styles/less/foundation.less",
15
+ "@smwb/ui-styles/less/theme.less"
16
+ ],
17
+ "entries": [
18
+ "@smwb/ui-styles/less/components/tabs/tabPanel/tabPanel.entry.less"
19
+ ],
20
+ "dependencies": [
21
+ "@smwb/ui-styles/less/components/tabs/tabs.entry.less"
22
+ ],
23
+ "importExample": "@import (less) \"node_modules/@smwb/ui-styles/less/foundation.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/theme.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tabPanel/tabPanel.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tabs.entry.less\";"
24
+ },
25
+ "props": {
26
+ "index": {
27
+ "type": "number",
28
+ "required": true,
29
+ "description": "The tab this panel belongs to: its index, counted as for the `value` of `Tabs`. The panel\nshows while that tab is selected and is hidden otherwise."
30
+ },
31
+ "class": {
32
+ "type": "string",
33
+ "required": false,
34
+ "description": "Extra class on the panel."
35
+ },
36
+ "children": {
37
+ "type": "JSX.Element",
38
+ "required": false,
39
+ "description": "The panel's content. It stays in the document while the panel is hidden."
40
+ }
41
+ }
42
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Tabs",
3
- "description": "Tab list container controlling associated panels.",
3
+ "description": "Tab list with arrow-key navigation (manual activation), optional TabPanels, link tabs for route navigation, drag-to-reorder, an overflow menu of the clipped tabs, and close/switch keyboard chords.",
4
4
  "ssr": {
5
5
  "safe": true,
6
6
  "rendering": "universal"
@@ -15,10 +15,12 @@
15
15
  ],
16
16
  "dependencies": [
17
17
  "@smwb/ui-styles/less/components/icon/icon.entry.less",
18
+ "@smwb/ui-styles/less/components/kbd/kbd.entry.less",
19
+ "@smwb/ui-styles/less/components/menu/menu.entry.less",
18
20
  "@smwb/ui-styles/less/components/ripple/ripple.entry.less",
19
21
  "@smwb/ui-styles/less/components/tabs/tab/tab.entry.less"
20
22
  ],
21
- "importExample": "@import (less) \"node_modules/@smwb/ui-styles/less/foundation.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/theme.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tabs.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/icon/icon.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/ripple/ripple.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tab/tab.entry.less\";"
23
+ "importExample": "@import (less) \"node_modules/@smwb/ui-styles/less/foundation.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/theme.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tabs.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/icon/icon.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/kbd/kbd.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/menu/menu.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/ripple/ripple.entry.less\";\n@import (less) \"node_modules/@smwb/ui-styles/less/components/tabs/tab/tab.entry.less\";"
22
24
  },
23
25
  "props": {
24
26
  "value": {
@@ -29,7 +31,22 @@
29
31
  "onChange": {
30
32
  "type": "(event: MouseEvent & { currentTarget: HTMLElement; target: Element }, index: number) => void",
31
33
  "required": true,
32
- "description": "Called with the index of the clicked tab, counted as for `value`."
34
+ "description": "Called with the index of the clicked tab, counted as for `value`. A tab chosen from the keyboard\n(Enter or Space on the focused tab) calls it with that click too. A modified or non-primary\nclick (Ctrl, Meta, Shift or Alt held, or a button other than the main one) on a link tab\n(`Tab` with `href`) is the browser's, as \"open in a new tab\": it does not call `onChange`."
35
+ },
36
+ "orientation": {
37
+ "type": "\"horizontal\" | \"vertical\"",
38
+ "required": false,
39
+ "description": "Which way the tabs run. It sets `aria-orientation` on the tab list and picks the arrow keys that\nmove between tabs: Left and Right when horizontal, Up and Down when vertical. The styles draw\na horizontal row; a vertical list is yours to lay out."
40
+ },
41
+ "panels": {
42
+ "type": "JSX.Element",
43
+ "required": false,
44
+ "description": "The content of the tabs: `TabPanel`s, rendered after the tab row. With them each tab gets\n`aria-controls` its panel and each panel `aria-labelledby` its tab. Without them the tabs link\nto nothing, as before. Give a panel to every tab: a tab whose panel is left out still names it.\nA `TabPanel` placed anywhere else is not linked to the tabs and is always shown."
45
+ },
46
+ "id": {
47
+ "type": "string",
48
+ "required": false,
49
+ "description": "Base of the ids that link tabs and panels: tab `n` is `{id}-tab-{n}`, its panel `{id}-panel-{n}`.\nIt is also the id of the root element. A generated one by default."
33
50
  },
34
51
  "indicatorContent": {
35
52
  "type": "boolean",
@@ -44,7 +61,22 @@
44
61
  "scrollButtons": {
45
62
  "type": "boolean",
46
63
  "required": false,
47
- "description": "With `scrollable`: buttons at both ends that scroll the row while it overflows."
64
+ "description": "With `scrollable`: buttons at both ends that scroll the row while it overflows. They are for\nthe pointer and stay out of the Tab order: the arrow keys reach every tab and scroll it into\nview."
65
+ },
66
+ "onReorder": {
67
+ "type": "(from: number, to: number) => void",
68
+ "required": false,
69
+ "description": "Present ⇒ the row is reorderable by dragging a tab onto another (pointer-only; there is no\nkeyboard reorder). `Tabs` does not move the tabs itself: it reports the drag with\n`onReorder(from, to)` — indexes counted as for `value` — and the owner reorders its state.\nThe tabs keep their focus through a reorder; when the moved tab is the selected one,\n`onChange` reports its new index too, so a controlled owner keeps it selected. That `onChange`\ncarries the drop's own event standing in for the click's: the index argument is authoritative —\n`currentTarget` is the scroll area the drop delegates to, not the tab."
70
+ },
71
+ "overflowMenu": {
72
+ "type": "boolean",
73
+ "required": false,
74
+ "description": "With `scrollable`: when the row overflows, a trigger button is rendered beside the scroller\n(in the scroll buttons' spot) that opens a menu of the tabs the viewport clips — any clipped\npart beyond a 1px tolerance counts. Each entry shows the tab's icon and label, the selected one is marked\n`aria-current=\"true\"`, and choosing one calls `onChange` for it and scrolls it into view.\nThe trigger appears only after the browser has measured an overflow, so the server markup\nshows none."
75
+ },
76
+ "overflowMenuAriaLabel": {
77
+ "type": "string",
78
+ "required": false,
79
+ "description": "Accessible label of the overflow-menu trigger. English by default; set it to localise."
48
80
  },
49
81
  "dense": {
50
82
  "type": "boolean",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smwb/ui-mcp-solid",
3
- "version": "0.13.0",
3
+ "version": "1.0.0",
4
4
  "description": "Model Context Protocol server exposing the @smwb/ui-solid (SolidJS) component catalog and customization guide.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,8 +28,8 @@
28
28
  "zod": "^4.4.3"
29
29
  },
30
30
  "devDependencies": {
31
- "@smwb/ui-solid": "^0.13.0",
32
- "@smwb/ui-styles": "^1.6.0",
31
+ "@smwb/ui-solid": "^1.0.0",
32
+ "@smwb/ui-styles": "^2.0.0",
33
33
  "glob": "^13.0.6",
34
34
  "typescript": "^6.0.3",
35
35
  "vitest": "^2.1.9"