bestax-mcp 1.16.2 → 1.16.3
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/catalog.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"generatedFrom": {
|
|
4
4
|
"package": "@allxsmith/bestax-bulma",
|
|
5
|
-
"version": "5.
|
|
5
|
+
"version": "5.40.0"
|
|
6
6
|
},
|
|
7
7
|
"docsBase": "https://bestax.io/docs",
|
|
8
8
|
"categories": [
|
|
@@ -1200,8 +1200,8 @@
|
|
|
1200
1200
|
"slug": "components/treeview",
|
|
1201
1201
|
"import": "import { TreeView } from '@allxsmith/bestax-bulma';",
|
|
1202
1202
|
"compound": true,
|
|
1203
|
-
"propCount":
|
|
1204
|
-
"exampleCount":
|
|
1203
|
+
"propCount": 27,
|
|
1204
|
+
"exampleCount": 9
|
|
1205
1205
|
},
|
|
1206
1206
|
{
|
|
1207
1207
|
"name": "UnorderedList",
|
|
@@ -23,7 +23,11 @@
|
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"title": "Folders That Load",
|
|
26
|
-
"code": "function example() {\n interface Folder {\n id: string;\n name: string;\n hasFolders: boolean;\n }\n\n // A pretend server: each folder holds two more, three levels down.\n const listFolders = (id: string) =>\n new Promise<Folder[]>(resolve =>\n setTimeout(\n ()
|
|
26
|
+
"code": "function example() {\n interface Folder {\n id: string;\n name: string;\n hasFolders: boolean;\n }\n\n // A pretend server: each folder holds two more, three levels down.\n const listFolders = (id: string, fail: boolean) =>\n new Promise<Folder[]>((resolve, reject) =>\n setTimeout(() => {\n if (fail) {\n reject(new Error(`Couldn't reach ${id}`));\n return;\n }\n resolve(\n ['a', 'b'].map(name => ({\n id: `${id}/${name}`,\n name: `Folder ${name.toUpperCase()}`,\n hasFolders: id.split('/').length < 3,\n }))\n );\n }, 800)\n );\n\n const [expanded, setExpanded] = useState<string[]>([]);\n // A folder's children, or how loading them is going.\n const [found, setFound] = useState<\n Record<string, Folder[] | 'loading' | 'error'>\n >({});\n // Shared fails the first time, so there's a Retry to press.\n const [sharedFails, setSharedFails] = useState(true);\n\n function load(id: string) {\n const fail = id === 'shared' && sharedFails;\n if (fail) setSharedFails(false);\n setFound(current => ({ ...current, [id]: 'loading' }));\n listFolders(id, fail).then(\n folders => setFound(current => ({ ...current, [id]: folders })),\n () => setFound(current => ({ ...current, [id]: 'error' }))\n );\n }\n\n function changeOpen(next: string[]) {\n setExpanded(next);\n for (const id of next) {\n if (!found[id]) load(id);\n }\n }\n\n const items = (folders: Folder[]): React.ReactNode =>\n folders.map(folder => {\n const state = found[folder.id];\n return (\n <TreeView.Item\n key={folder.id}\n value={folder.id}\n label={folder.name}\n icon=\"folder\"\n hasChildren={folder.hasFolders}\n isLoading={state === 'loading'}\n loadError={\n state === 'error' ? `Couldn't load ${folder.name}` : undefined\n }\n onRetry={() => load(folder.id)}\n >\n {Array.isArray(state) && items(state)}\n </TreeView.Item>\n );\n });\n\n return (\n <TreeView\n aria-label=\"Folders\"\n expanded={expanded}\n onExpandedChange={changeOpen}\n >\n {items([\n { id: 'home', name: 'Home', hasFolders: true },\n { id: 'shared', name: 'Shared', hasFolders: true },\n ])}\n </TreeView>\n );\n}"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"title": "Folders That Load",
|
|
30
|
+
"code": "<TreeView\n aria-label=\"Dossiers\"\n loadingLabel=\"Chargement…\"\n retryLabel=\"Réessayer\"\n loadingAnnouncement={name => `Chargement de ${name}`}\n loadedAnnouncement={name => `${name} chargé`}\n>\n {/* … */}\n</TreeView>"
|
|
27
31
|
},
|
|
28
32
|
{
|
|
29
33
|
"title": "An Outline With Expand All and Collapse All",
|
|
@@ -38,8 +42,15 @@
|
|
|
38
42
|
"code": "<TreeView\n aria-label=\"Files\"\n selectionMode=\"single\"\n defaultSelected=\"src/App.tsx\"\n defaultExpanded={['src']}\n>\n <TreeView.Item value=\"src\" label=\"src\" icon=\"folder\">\n <TreeView.Item value=\"src/index.ts\" label=\"index.ts\" icon=\"file\" />\n <TreeView.Item value=\"src/App.tsx\" label=\"App.tsx\" icon=\"file\" />\n <TreeView.Item value=\"src/legacy.ts\" label=\"legacy.ts\" disabled />\n </TreeView.Item>\n <TreeView.Item value=\"package.json\" label=\"package.json\" icon=\"file\" />\n</TreeView>"
|
|
39
43
|
}
|
|
40
44
|
],
|
|
41
|
-
"accessibility": "`TreeView` follows the [APG Tree View Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/).\n\n- **Roles:** the root is a `<ul role=\"tree\">`, each item an `<li role=\"treeitem\">`, and an open\n parent's children sit in a `<ul role=\"group\">` inside it. A closed item's children have no\n markup.\n- **A name:** a tree needs one, from `aria-label` or `aria-labelledby`, and a development build\n warns when it has neither. Each item is named by `aria-labelledby` pointing at its own label, and\n declares its `aria-level`, which VoiceOver needs according to\n [GitHub's testing](https://github.blog/engineering/user-experience/considerations-for-making-a-tree-view-component-accessible/).\n `aria-expanded` is on parents only.\n- **One tab stop, with real focus:** one item holds `tabIndex={0}` and the rest `-1`, and focus\n moves from item to item, rather than through `aria-activedescendant`. When focus comes into the\n tree, it lands on the selected item, or in a checkbox tree on the first checked item on the page.\n Without one, it lands where focus last was, or on the first item. If the item holding the stop\n goes away, its nearest ancestor on the page takes it, and focus goes too if it had focus.\n- **Selection:** a `single` tree marks each enabled item `aria-selected`, `true` or `false`. A\n `checkbox` tree marks `aria-checked` on every item, `true`, `false` or `mixed`, disabled ones\n included, and adds `aria-multiselectable=\"true\"` to the tree. A tree never has both, and a tree\n with no `selectionMode` has neither. Selection doesn't follow focus.\n- **The box** is a [`Checkbox`](https://bestax.io/docs/api/form/checkbox) inside an `aria-hidden` span, with\n `tabIndex={-1}`, so it's neither a tab stop nor a second thing for a screen reader to read. The\n item's `aria-checked` is what a screen reader hears.\n- **Disabled items** are `aria-disabled` and stay reachable from the arrow keys, Home, End and\n typing, so a screen reader user finds them. They're never selected, checked, opened or closed.\n One that's already open stays open, so what's under it is still reachable.\n\nEnter and Space do the item's one thing, which depends on the mode:\n\n| Key | No `selectionMode` | `single` | `checkbox` |\n| ----- | ------------------------ | ---------------- | ------------------------ |\n| Enter | Opens or closes a parent | Selects the item | Opens or closes a parent |\n| Space | Opens or closes a parent | Selects the item | Checks or unchecks it |\n\
|
|
42
|
-
"related": [
|
|
45
|
+
"accessibility": "`TreeView` follows the [APG Tree View Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/).\n\n- **Roles:** the root is a `<ul role=\"tree\">`, each item an `<li role=\"treeitem\">`, and an open\n parent's children sit in a `<ul role=\"group\">` inside it. A closed item's children have no\n markup.\n- **A name:** a tree needs one, from `aria-label` or `aria-labelledby`, and a development build\n warns when it has neither. Each item is named by `aria-labelledby` pointing at its own label, and\n declares its `aria-level`, which VoiceOver needs according to\n [GitHub's testing](https://github.blog/engineering/user-experience/considerations-for-making-a-tree-view-component-accessible/).\n `aria-expanded` is on parents only.\n- **One tab stop, with real focus:** one item holds `tabIndex={0}` and the rest `-1`, and focus\n moves from item to item, rather than through `aria-activedescendant`. When focus comes into the\n tree, it lands on the selected item, or in a checkbox tree on the first checked item on the page.\n Without one, it lands where focus last was, or on the first item. If the item holding the stop\n goes away, its nearest ancestor on the page takes it, and focus goes too if it had focus.\n- **Selection:** a `single` tree marks each enabled item `aria-selected`, `true` or `false`. A\n `checkbox` tree marks `aria-checked` on every item, `true`, `false` or `mixed`, disabled ones\n included, and adds `aria-multiselectable=\"true\"` to the tree. A tree never has both, and a tree\n with no `selectionMode` has neither. Selection doesn't follow focus.\n- **The box** is a [`Checkbox`](https://bestax.io/docs/api/form/checkbox) inside an `aria-hidden` span, with\n `tabIndex={-1}`, so it's neither a tab stop nor a second thing for a screen reader to read. The\n item's `aria-checked` is what a screen reader hears.\n- **Disabled items** are `aria-disabled` and stay reachable from the arrow keys, Home, End and\n typing, so a screen reader user finds them. They're never selected, checked, opened or closed.\n One that's already open stays open, so what's under it is still reachable.\n- **A loading item's row** is a `treeitem` that says Loading…, marked `aria-disabled` and reached\n the way a disabled item is, so a screen reader user who moves into the folder hears what's\n happening. It has no value: it's never selected or checked, it has no `aria-selected` or\n `aria-checked`, and a checkbox tree doesn't count it. If it goes with focus on it, focus moves to\n the item it was loading for. Bulma's loader turns in its chevron's place, hidden from assistive\n tech.\n- **A failed load's row** is a `treeitem` named by its message and the Retry button's text, such\n as \"Couldn't load src Retry\". Enter, Space or a click on the row calls `onRetry`, in every mode.\n The button is drawn inside an `aria-hidden` span and takes no focus, the way an item's box is,\n so the tree keeps its one tab stop, and nothing in the message should be a link or a button\n either. A retry that starts loading keeps the same row, so focus stays on it. With no `onRetry`,\n the row is disabled and shows the message alone.\n- **Announcements:** a visually hidden `role=\"status\"` region with `aria-live=\"polite\"` sits right\n after the tree, one for the whole tree, from the moment it mounts, so a screen reader is already\n listening when something is written into it. It says \"Loading src\" when an open item starts\n loading, a failed load's message, and \"src loaded\" when the loading row or a failed load's row\n goes with the item still open.\n The name is the item's label as a screen reader reads it. A closed item, or one in a closed\n branch, says nothing. Each announcement is written a moment after the change and cleared soon\n after, so the page doesn't keep a second copy of the text.\n\nEnter and Space do the item's one thing, which depends on the mode:\n\n| Key | No `selectionMode` | `single` | `checkbox` |\n| ----- | ------------------------ | ---------------- | ------------------------ |\n| Enter | Opens or closes a parent | Selects the item | Opens or closes a parent |\n| Space | Opens or closes a parent | Selects the item | Checks or unchecks it |\n\nOn a failed load's row, both retry, whatever the mode. The rest work the same in every mode:\n\n| Key | What it does |\n| ---------- | ----------------------------------------------------------------------------------------- |\n| Down, Up | The next or previous item on the page, without wrapping |\n| Right | Opens a closed parent, and focus stays. On an open parent, moves to its first child |\n| Left | Closes an open parent. Otherwise moves to its parent |\n| Home, End | The first item, and the last one on the page |\n| `*` | Opens every closed parent beside the focused item, itself included. Focus stays |\n| Characters | Moves to the next item whose label starts with what's typed, several characters adding up |\n| Tab | Leaves the tree |\n\n- **Right to left:** Right and Left swap in a right-to-left page, and the chevron points to the\n left while closed.\n- **Keys it leaves alone:** anything with Control, Alt or Meta held, anything while an input method\n is composing, and Escape, so it reaches a Modal or Popover around the tree. An item's own\n `onKeyDown` runs first, and calling `preventDefault()` there keeps the tree from acting on the\n key.\n- **Clicks:** the chevron only opens and closes. The rest of the row does the item's one thing:\n opens or closes it with no `selectionMode`, selects it (and opens or closes a parent) in a\n `single` tree, and checks it in a `checkbox` tree. A click moves focus and the tab stop to the\n item.\n- **Not for site navigation:** APG's own\n [navigation tree example](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/examples/treeview-navigation/)\n says \"A pattern more suited for typical site navigation with expandable groups of links is the\n disclosure pattern\", and a tree's items aren't links. Keep a sidebar on [`Menu`](https://bestax.io/docs/api/components/menu).\n- **Focus and the selected look differ:** the focus ring sits outside the row, so it shows on the\n selected fill as well as on a plain row.\n- **Forced colors:** in Windows high contrast mode the selected row is the system's Highlight and\n HighlightText, a disabled row or a loading one is GrayText, and the focus ring, the chevrons and\n the guide lines stay visible, since they're outlines and borders. A mixed box keeps its dash, and\n the loader's ring stays open.\n- **Motion:** the chevron turns with a short transition, and the loader spins. Both stop when the\n reader asks for reduced motion, and the loader stays drawn.",
|
|
46
|
+
"related": [
|
|
47
|
+
"Checkbox",
|
|
48
|
+
"Collapse",
|
|
49
|
+
"Loader",
|
|
50
|
+
"Menu",
|
|
51
|
+
"Sidebar",
|
|
52
|
+
"useBulmaClasses"
|
|
53
|
+
],
|
|
43
54
|
"storybook": "https://bestax.io/storybook/?path=/story/components-treeview--default",
|
|
44
55
|
"summary": "The `TreeView` component renders a tree of items you browse and pick from, the way a file explorer works: one tab stop, the arrow keys to move, and Right and Left to open and close. It's the APG Tree View pattern, drawn to look like Bulma's menu. It isn't for site navigation: items aren't links, and a sidebar whose sections open and close is `Menu`'s job. The root owns which items are open, through `expanded`, `defaultExpanded` and `onExpandedChange`. `selectionMode` picks one of three trees. With `none`, nothing is picked. With `single`, one item is, and `selected` says which. With `checkbox`, each item has a box, a check reaches every enabled item under it, closed branches included, and a parent with some of its items checked is mixed. `selected` is read in a `single` tree only, and `checked` in a `checkbox` tree only. Selection never follows focus. Disabled items stay reachable from the keys, so a screen reader finds them. The tree needs a name, from `aria-label` or `aria-labelledby`, and a development build warns when it has neither.",
|
|
45
56
|
"import": "import { TreeView } from '@allxsmith/bestax-bulma';",
|
|
@@ -159,6 +170,42 @@
|
|
|
159
170
|
"inherited": false,
|
|
160
171
|
"deprecated": false
|
|
161
172
|
},
|
|
173
|
+
{
|
|
174
|
+
"name": "loadingLabel",
|
|
175
|
+
"type": "string",
|
|
176
|
+
"default": "'Loading…'",
|
|
177
|
+
"description": "What the row in a loading item's group says. In your app's language.",
|
|
178
|
+
"required": false,
|
|
179
|
+
"inherited": false,
|
|
180
|
+
"deprecated": false
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"name": "retryLabel",
|
|
184
|
+
"type": "string",
|
|
185
|
+
"default": "'Retry'",
|
|
186
|
+
"description": "The Retry button's text on a failed load's row. In your app's language.",
|
|
187
|
+
"required": false,
|
|
188
|
+
"inherited": false,
|
|
189
|
+
"deprecated": false
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "loadingAnnouncement",
|
|
193
|
+
"type": "(name: string) => string",
|
|
194
|
+
"default": null,
|
|
195
|
+
"description": "What the live region says when an open item starts loading, built from the item's name. In your app's language. Default: `` `Loading ${name}` ``.",
|
|
196
|
+
"required": false,
|
|
197
|
+
"inherited": false,
|
|
198
|
+
"deprecated": false
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"name": "loadedAnnouncement",
|
|
202
|
+
"type": "(name: string) => string",
|
|
203
|
+
"default": null,
|
|
204
|
+
"description": "What the live region says when that load finishes. In your app's language. Default: `` `${name} loaded` ``.",
|
|
205
|
+
"required": false,
|
|
206
|
+
"inherited": false,
|
|
207
|
+
"deprecated": false
|
|
208
|
+
},
|
|
162
209
|
{
|
|
163
210
|
"name": "className",
|
|
164
211
|
"type": "string",
|
|
@@ -251,6 +298,33 @@
|
|
|
251
298
|
"inherited": false,
|
|
252
299
|
"deprecated": false
|
|
253
300
|
},
|
|
301
|
+
{
|
|
302
|
+
"name": "isLoading",
|
|
303
|
+
"type": "boolean",
|
|
304
|
+
"default": "false",
|
|
305
|
+
"description": "Its children are on their way. While it's open, its group ends in a row that says so, and the tree's live region says it's loading, then that it's loaded once this goes back to `false`. A parent only: pair it with `hasChildren`, or with the children it already has.",
|
|
306
|
+
"required": false,
|
|
307
|
+
"inherited": false,
|
|
308
|
+
"deprecated": false
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"name": "loadError",
|
|
312
|
+
"type": "React.ReactNode",
|
|
313
|
+
"default": null,
|
|
314
|
+
"description": "Its children didn't load. While it's open, its group ends in a row with this message, and a Retry button when there's an `onRetry`, and the live region reads the message out, so name the item in it (\"Couldn't load src\"), then says it's loaded once this goes with the item still open. A parent only, like `isLoading`. Nothing in it should be a link or a button: the row is what's pressed. `isLoading` wins while both are given.",
|
|
315
|
+
"required": false,
|
|
316
|
+
"inherited": false,
|
|
317
|
+
"deprecated": false
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"name": "onRetry",
|
|
321
|
+
"type": "() => void",
|
|
322
|
+
"default": null,
|
|
323
|
+
"description": "Called by the Retry button on a failed load's row, and by Enter or Space there. Set `isLoading` while the retry runs, so the live region says it's loading, and reads the message out again if it fails again. The same message passed a second time with no loading between is no change the tree can see.",
|
|
324
|
+
"required": false,
|
|
325
|
+
"inherited": false,
|
|
326
|
+
"deprecated": false
|
|
327
|
+
},
|
|
254
328
|
{
|
|
255
329
|
"name": "disabled",
|
|
256
330
|
"type": "boolean",
|
|
@@ -110,8 +110,12 @@ Centered; a collection of items → Card grid. For mixed requests, pick the domi
|
|
|
110
110
|
other: `<TreeView aria-label="Files" selectionMode="single">` with `selected`/`onSelectedChange`
|
|
111
111
|
picks one, and `selectionMode="checkbox"` with `checked`/`onCheckedChange` draws boxes with
|
|
112
112
|
mixed parents, where a parent's value checks its whole branch. Map the data with a recursive
|
|
113
|
-
function, and render an item's children whether it's open or not.
|
|
114
|
-
|
|
113
|
+
function, and render an item's children whether it's open or not. A folder that loads when it
|
|
114
|
+
opens takes `hasChildren`, `isLoading` while its children are on their way, and
|
|
115
|
+
`loadError="Couldn't load src"` with `onRetry` when the load fails, setting `isLoading` again
|
|
116
|
+
while the retry runs: the tree draws the Loading… and Retry rows and announces them, so don't
|
|
117
|
+
hand-write a placeholder item. Its items aren't
|
|
118
|
+
links, so the app's sidebar and any list of pages stay on `Menu` with `Menu.Item href`.
|
|
115
119
|
- Link lists (footer nav, sidebars): a bare `UnorderedList` of `ListItem`s is already
|
|
116
120
|
marker-less and flush — Bulma's reset unstyles `ul` — so no prop or CSS is needed;
|
|
117
121
|
bullets appear only inside `Content`.
|
|
@@ -400,7 +400,8 @@ Run on an HTML page (`bestax-migrate bulma-classes page.html`, or a folder with
|
|
|
400
400
|
codemod writes a module beside the page and runs everything above on it, so a page gets the same
|
|
401
401
|
TODOs its markup would as JSX. What a component can't carry gets an `html-*` rule. TODOs about the
|
|
402
402
|
whole page sit above the component, the rest above its `return`, and each ends with the page and
|
|
403
|
-
the line it came from (`(index.html:42)`)
|
|
403
|
+
the line it came from (`(index.html:42)`), or every line, for a TODO several elements share
|
|
404
|
+
(`(index.html:42, 57)`). The page itself stays as it was, so the code a TODO
|
|
404
405
|
points at is still there to read. A rule names only a tag, an attribute or a fixed word, never
|
|
405
406
|
anything the page says.
|
|
406
407
|
|
|
@@ -414,6 +415,11 @@ A component renders into the `<body>` of the app's own document, so nothing in t
|
|
|
414
415
|
it into the head; React 18 leaves it in the body, so use `document.title` in an effect there.
|
|
415
416
|
- **`html-head:meta`**: `charset` and `viewport` go once in the app's `index.html`. A page's own
|
|
416
417
|
(a description, Open Graph tags) go where the app sets each page's head.
|
|
418
|
+
- **`html-head:csp`**: a `<meta http-equiv="Content-Security-Policy">`. Its policy was written for
|
|
419
|
+
what the page loads, and copied into `index.html` as it is, it can block what the app loads
|
|
420
|
+
instead: a Vite dev server runs an inline script for React's fast refresh and opens a socket for
|
|
421
|
+
hot reloading, and the build serves the app's own scripts, styles and fonts. Write the app's own
|
|
422
|
+
policy, best sent as a response header, and try it under both the dev server and the build.
|
|
417
423
|
- **`html-head:link`**: icons, preconnects and preloads are app-wide, so keep them in
|
|
418
424
|
`index.html`; a `canonical` is per page.
|
|
419
425
|
- **`html-head:style`**: the `<style>` block was dropped. Move its rules into the app's stylesheet.
|
|
@@ -586,7 +592,9 @@ read for the burger, a carousel and a theme toggle too, and its TODO names the f
|
|
|
586
592
|
app loads paints the right one, and the toggle's state starts from what it wrote. The
|
|
587
593
|
bestax-theming skill covers `Theme` and `colorMode`, and its `examples/dark-mode.tsx` has the
|
|
588
594
|
script and the app's side.
|
|
589
|
-
- **`html-script:json-ld`** is structured data for search engines.
|
|
595
|
+
- **`html-script:json-ld`** is structured data for search engines. Data about the whole site, or
|
|
596
|
+
about a single-page app's one page, goes in the app's `index.html` as it is, where a crawler that
|
|
597
|
+
runs no JavaScript still reads it. Data that differs from page to page goes where the app sets
|
|
590
598
|
each page's head, as
|
|
591
599
|
`<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />`.
|
|
592
600
|
- **`html-script`**: any other inline script, or a `<script type>` that isn't code (a template,
|
|
@@ -604,8 +612,9 @@ The app's document has its own `<html>` and `<body>`, which a component can't re
|
|
|
604
612
|
bestax's `Navbar` adds none there, whatever its `fixed` says.
|
|
605
613
|
- **`html-document:data-theme`**, **`html-document:theme-dark`**, **`html-document:theme-light`**:
|
|
606
614
|
the page's color scheme. Put it on the `<html>` in `index.html`, where the first paint has it.
|
|
607
|
-
|
|
608
|
-
|
|
615
|
+
For a scheme the visitor switches, `Theme colorMode` writes the choice only after that paint,
|
|
616
|
+
so write a saved one before it too, as `html-script:theme` says and the bestax-theming skill's
|
|
617
|
+
`examples/dark-mode.tsx` does.
|
|
609
618
|
- **`html-document:lang`**, **`html-document:dir`**: set them on the `<html>` in `index.html`.
|
|
610
619
|
- **`html-document:class`**: the page's own classes on `<html>` or `<body>`. Put them on the
|
|
611
620
|
app's own `<body>` (or `<html>`), or on an element around the page's content if the styles
|
|
@@ -656,6 +665,12 @@ than `this`. A `<body onload>` becomes an effect.
|
|
|
656
665
|
- **`html-attr:name`**: an attribute JSX can't write (`@click`, `:class`, `x-on:click`), or one the
|
|
657
666
|
element already had under another spelling, was left out. A framework's directive is code to port
|
|
658
667
|
into the component.
|
|
668
|
+
- **`html-attr:stray`**: a stray character in a tag, with no letter or digit in it (`\` in
|
|
669
|
+
`<figure class="image" \>`, a typo for `/>`), which the browser read as the name of an empty
|
|
670
|
+
attribute. It was left out, so there is nothing to port; delete it from the page too.
|
|
671
|
+
- **`html-attr:ignored`**: an attribute HTML gives the element no meaning for, so the browser
|
|
672
|
+
ignored it, and React's types reject it there: `type` on a `<textarea>`. It was left out, so the
|
|
673
|
+
module typechecks. Nothing reads it, unless a stylesheet or script of the page's selects on it.
|
|
659
674
|
- **`html-attr:unknown`**: an attribute React has no prop for by that name, written as it was.
|
|
660
675
|
React renders it. Whether a TypeScript build takes it depends on the element (React's types
|
|
661
676
|
list `valign` on a `<td>` and not on a `<th>`), so the TODO doesn't say; what to do depends on
|
package/data/skills.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bestax-mcp",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.3",
|
|
4
4
|
"mcpName": "io.github.allxsmith/bestax-mcp",
|
|
5
5
|
"description": "MCP server for @allxsmith/bestax-bulma — component props, examples, CSS variables and agent skills, served offline from a version-pinned index",
|
|
6
6
|
"type": "module",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.31.0",
|
|
44
44
|
"zod": "^4.4.3",
|
|
45
|
-
"@allxsmith/bestax-bulma": "^5.
|
|
45
|
+
"@allxsmith/bestax-bulma": "^5.40.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@jest/globals": "^30.0.0",
|