bestax-mcp 1.2.2 → 1.2.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/README.md +1 -1
- package/data/catalog.json +22 -22
- package/data/components/Button.json +15 -1
- package/data/components/Buttons.json +35 -2
- package/data/components/Control.json +4 -4
- package/data/components/DateInput.json +2 -2
- package/data/components/DateTimeInput.json +2 -2
- package/data/components/Dialog.json +14 -1
- package/data/components/Dropdown.json +25 -2
- package/data/components/Field.json +4 -4
- package/data/components/Icon.json +40 -27
- package/data/components/IconText.json +38 -29
- package/data/components/Input.json +2 -2
- package/data/components/LinkButton.json +15 -1
- package/data/components/Message.json +10 -1
- package/data/components/Modal.json +47 -2
- package/data/components/Navbar.json +58 -5
- package/data/components/Panel.json +23 -14
- package/data/components/Select.json +1 -1
- package/data/components/Sidebar.json +1 -1
- package/data/components/Tags.json +21 -7
- package/data/components/TimeInput.json +2 -2
- package/data/components/Valid value constants.json +1 -1
- package/data/components/useBulmaClasses.json +13 -1
- package/data/skills/bestax-custom-component/references/component-catalog.md +1 -1
- package/data/skills/bestax-icons/SKILL.md +28 -0
- package/data/skills/bestax-migrate/SKILL.md +65 -31
- package/data/skills/bestax-migrate/references/css-migration.md +17 -10
- package/data/skills/bestax-migrate/references/rbx/component-map.md +171 -0
- package/data/skills/bestax-migrate/references/rbx/prop-map.md +153 -0
- package/data/skills/bestax-migrate/references/rbx/unmappables.md +169 -0
- package/data/skills/bestax-migrate/references/{component-map.md → react-bulma-components/component-map.md} +1 -1
- package/data/skills/bestax-migrate/references/{prop-map.md → react-bulma-components/prop-map.md} +1 -1
- package/data/skills/bestax-migrate/references/{unmappables.md → react-bulma-components/unmappables.md} +36 -6
- package/data/skills.json +31 -12
- package/package.json +3 -3
|
@@ -103,9 +103,9 @@
|
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
105
|
"name": "iconProps",
|
|
106
|
-
"type": "IconProps",
|
|
106
|
+
"type": "IconProps | React.ReactNode",
|
|
107
107
|
"default": null,
|
|
108
|
-
"description": "Props for a single Icon component
|
|
108
|
+
"description": "Props for a single Icon component, or a custom node, for single icon mode.",
|
|
109
109
|
"required": false,
|
|
110
110
|
"inherited": false,
|
|
111
111
|
"deprecated": false
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
"name": "items",
|
|
124
|
-
"type": "{ iconProps: IconProps; text?: string }[]",
|
|
124
|
+
"type": "{ iconProps: IconProps | React.ReactNode; text?: string }[]",
|
|
125
125
|
"default": null,
|
|
126
126
|
"description": "Array of icon/text pairs (for multiple icons mode).",
|
|
127
127
|
"required": false,
|
|
@@ -138,13 +138,31 @@
|
|
|
138
138
|
"summary": "The `Icon` component is a Bulma-styled wrapper for displaying icons from various libraries (Font Awesome, Material Design Icons, Ionicons, Google Material Icons, Material Symbols, etc.).",
|
|
139
139
|
"component": "Icon",
|
|
140
140
|
"props": [
|
|
141
|
+
{
|
|
142
|
+
"name": "name",
|
|
143
|
+
"type": "string | undefined",
|
|
144
|
+
"default": null,
|
|
145
|
+
"description": "The icon name, with or without its library prefix (e.g. `'star'` or `'fa-star'`). Mutually exclusive with `children`.",
|
|
146
|
+
"required": false,
|
|
147
|
+
"inherited": true,
|
|
148
|
+
"deprecated": false
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"name": "children",
|
|
152
|
+
"type": "Exclude<React.ReactNode, undefined>",
|
|
153
|
+
"default": null,
|
|
154
|
+
"description": "A custom node (an inline SVG, a `react-icons` component, …) rendered inside the icon container in place of a class-based glyph. Mutually exclusive with `name`.",
|
|
155
|
+
"required": false,
|
|
156
|
+
"inherited": true,
|
|
157
|
+
"deprecated": false
|
|
158
|
+
},
|
|
141
159
|
{
|
|
142
160
|
"name": "className",
|
|
143
161
|
"type": "string",
|
|
144
162
|
"default": null,
|
|
145
163
|
"description": "Additional CSS classes to apply.",
|
|
146
164
|
"required": false,
|
|
147
|
-
"inherited":
|
|
165
|
+
"inherited": true,
|
|
148
166
|
"deprecated": false
|
|
149
167
|
},
|
|
150
168
|
{
|
|
@@ -153,7 +171,7 @@
|
|
|
153
171
|
"default": null,
|
|
154
172
|
"description": "Text color helper.",
|
|
155
173
|
"required": false,
|
|
156
|
-
"inherited":
|
|
174
|
+
"inherited": true,
|
|
157
175
|
"deprecated": false,
|
|
158
176
|
"valuesRef": "helpers/valid-values"
|
|
159
177
|
},
|
|
@@ -163,7 +181,7 @@
|
|
|
163
181
|
"default": null,
|
|
164
182
|
"description": "Bulma color modifier for the icon.",
|
|
165
183
|
"required": false,
|
|
166
|
-
"inherited":
|
|
184
|
+
"inherited": true,
|
|
167
185
|
"deprecated": false
|
|
168
186
|
},
|
|
169
187
|
{
|
|
@@ -172,53 +190,44 @@
|
|
|
172
190
|
"default": null,
|
|
173
191
|
"description": "Background color helper.",
|
|
174
192
|
"required": false,
|
|
175
|
-
"inherited":
|
|
193
|
+
"inherited": true,
|
|
176
194
|
"deprecated": false,
|
|
177
195
|
"valuesRef": "helpers/valid-values"
|
|
178
196
|
},
|
|
179
|
-
{
|
|
180
|
-
"name": "name",
|
|
181
|
-
"type": "string",
|
|
182
|
-
"default": null,
|
|
183
|
-
"description": "The icon name, with or without its library prefix (e.g. `'star'` or `'fa-star'`).",
|
|
184
|
-
"required": false,
|
|
185
|
-
"inherited": false,
|
|
186
|
-
"deprecated": false
|
|
187
|
-
},
|
|
188
197
|
{
|
|
189
198
|
"name": "icon",
|
|
190
199
|
"type": "string",
|
|
191
200
|
"default": null,
|
|
192
201
|
"description": "DEPRECATED: Legacy prop, use `name` instead.",
|
|
193
202
|
"required": false,
|
|
194
|
-
"inherited":
|
|
203
|
+
"inherited": true,
|
|
195
204
|
"deprecated": false
|
|
196
205
|
},
|
|
197
206
|
{
|
|
198
207
|
"name": "library",
|
|
199
208
|
"type": "'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols'",
|
|
200
209
|
"default": "'fa'",
|
|
201
|
-
"description": "The icon library to use ('fa' = Font Awesome, 'mdi' = Material Design Icons, 'ion' = Ionicons Web Components, 'material-icons' = Google Material Icons, 'material-symbols' = Google Material Symbols). Defaults to the value set in ConfigProvider or 'fa' if not configured.",
|
|
210
|
+
"description": "The icon library to use ('fa' = Font Awesome, 'mdi' = Material Design Icons, 'ion' = Ionicons Web Components, 'material-icons' = Google Material Icons, 'material-symbols' = Google Material Symbols). Defaults to the value set in ConfigProvider or 'fa' if not configured. Ignored when `children` supplies the glyph instead of `name`.",
|
|
202
211
|
"required": false,
|
|
203
|
-
"inherited":
|
|
212
|
+
"inherited": true,
|
|
204
213
|
"deprecated": false
|
|
205
214
|
},
|
|
206
215
|
{
|
|
207
216
|
"name": "variant",
|
|
208
217
|
"type": "string",
|
|
209
218
|
"default": null,
|
|
210
|
-
"description": "Icon style variant (e.g. `'solid'`, `'outlined'`, `'rounded'`).",
|
|
219
|
+
"description": "Icon style variant (e.g. `'solid'`, `'outlined'`, `'rounded'`). Ignored when `children` supplies the glyph instead of `name`.",
|
|
211
220
|
"required": false,
|
|
212
|
-
"inherited":
|
|
221
|
+
"inherited": true,
|
|
213
222
|
"deprecated": false
|
|
214
223
|
},
|
|
215
224
|
{
|
|
216
225
|
"name": "features",
|
|
217
226
|
"type": "string | string[]",
|
|
218
227
|
"default": null,
|
|
219
|
-
"description": "Additional modifiers (e.g. `'fa-lg'`, `'fa-spin'`, `'is-size-1'`).",
|
|
228
|
+
"description": "Additional modifiers (e.g. `'fa-lg'`, `'fa-spin'`, `'is-size-1'`). Ignored when `children` supplies the glyph instead of `name`.",
|
|
220
229
|
"required": false,
|
|
221
|
-
"inherited":
|
|
230
|
+
"inherited": true,
|
|
222
231
|
"deprecated": false
|
|
223
232
|
},
|
|
224
233
|
{
|
|
@@ -227,7 +236,7 @@
|
|
|
227
236
|
"default": null,
|
|
228
237
|
"description": "**DEPRECATED:** Use `variant` and `features` instead.",
|
|
229
238
|
"required": false,
|
|
230
|
-
"inherited":
|
|
239
|
+
"inherited": true,
|
|
231
240
|
"deprecated": false
|
|
232
241
|
},
|
|
233
242
|
{
|
|
@@ -236,16 +245,16 @@
|
|
|
236
245
|
"default": null,
|
|
237
246
|
"description": "Size modifier for the icon container.",
|
|
238
247
|
"required": false,
|
|
239
|
-
"inherited":
|
|
248
|
+
"inherited": true,
|
|
240
249
|
"deprecated": false
|
|
241
250
|
},
|
|
242
251
|
{
|
|
243
252
|
"name": "ariaLabel",
|
|
244
253
|
"type": "string",
|
|
245
254
|
"default": "'icon'",
|
|
246
|
-
"description": "ARIA label for accessibility (default
|
|
255
|
+
"description": "ARIA label for accessibility. Applied unconditionally to the container span, so an icon that never sets it still renders `aria-label=\"icon\"`. For an icon-only control, put the real `aria-label` on the control (e.g. `Button`) and set `aria-hidden` here instead — otherwise the control's accessible name is announced as just \"icon\". For a decorative icon beside visible text, set `aria-hidden` here rather than leaving the default, so it doesn't add \"icon\" to the text's accessible name.",
|
|
247
256
|
"required": false,
|
|
248
|
-
"inherited":
|
|
257
|
+
"inherited": true,
|
|
249
258
|
"deprecated": false
|
|
250
259
|
},
|
|
251
260
|
{
|
|
@@ -254,7 +263,7 @@
|
|
|
254
263
|
"default": null,
|
|
255
264
|
"description": "Inline style object.",
|
|
256
265
|
"required": false,
|
|
257
|
-
"inherited":
|
|
266
|
+
"inherited": true,
|
|
258
267
|
"deprecated": false
|
|
259
268
|
},
|
|
260
269
|
{
|
|
@@ -263,7 +272,7 @@
|
|
|
263
272
|
"default": null,
|
|
264
273
|
"description": "Override the default `'icon'` container class (e.g., `'panel-icon'`).",
|
|
265
274
|
"required": false,
|
|
266
|
-
"inherited":
|
|
275
|
+
"inherited": true,
|
|
267
276
|
"deprecated": false
|
|
268
277
|
}
|
|
269
278
|
],
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
"name": "iconLeft",
|
|
172
|
-
"type": "IconProps",
|
|
172
|
+
"type": "IconProps | React.ReactNode",
|
|
173
173
|
"default": null,
|
|
174
174
|
"description": "Icon props for left icon.",
|
|
175
175
|
"required": false,
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
},
|
|
179
179
|
{
|
|
180
180
|
"name": "iconRight",
|
|
181
|
-
"type": "IconProps",
|
|
181
|
+
"type": "IconProps | React.ReactNode",
|
|
182
182
|
"default": null,
|
|
183
183
|
"description": "Icon props for right icon.",
|
|
184
184
|
"required": false,
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
{
|
|
41
41
|
"title": "Polymorphic `as` (Router Links)",
|
|
42
42
|
"code": "import { Link as RouterLink } from 'react-router-dom';\nimport { LinkButton } from '@allxsmith/bestax-bulma';\n\n<LinkButton as={RouterLink} to=\"/dashboard\" variant=\"underline\">\n Go to Dashboard\n</LinkButton>;"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"title": "Forwarded ref",
|
|
46
|
+
"code": "function example() {\n const defaultRef = React.useRef(null);\n const anchorRef = React.useRef(null);\n const [tags, setTags] = React.useState(null);\n\n return (\n <>\n <LinkButton ref={defaultRef}>Default</LinkButton>\n <LinkButton as=\"a\" href=\"#forwarded-ref\" ml=\"2\" ref={anchorRef}>\n As an anchor\n </LinkButton>\n <Button\n ml=\"2\"\n onClick={() =>\n setTags(\n `${defaultRef.current?.tagName} / ${anchorRef.current?.tagName}`\n )\n }\n >\n Read both from their refs\n </Button>\n <p>Rendered elements: {tags ?? '—'}</p>\n </>\n );\n}"
|
|
43
47
|
}
|
|
44
48
|
],
|
|
45
49
|
"accessibility": "- **Semantic HTML:** Renders a native `<button>` element, providing correct keyboard navigation, focus management, and screen reader announcements.\n- **States:** The `isDisabled` and `disabled` props ensure correct `aria-disabled` and `disabled` attributes.\n- **Keyboard:** Fully keyboard accessible with Enter and Space activation.\n- **Replaces anti-patterns:** Use this instead of `<div onClick>` or `<span onClick>` for interactive elements that should not navigate.\n\n:::note\nIf your LinkButton has only an icon, use `aria-label` to provide accessible text.\n:::",
|
|
@@ -248,7 +252,17 @@
|
|
|
248
252
|
"deprecated": false
|
|
249
253
|
}
|
|
250
254
|
],
|
|
251
|
-
"extraProps": [
|
|
255
|
+
"extraProps": [
|
|
256
|
+
{
|
|
257
|
+
"name": "ref",
|
|
258
|
+
"type": "React.Ref<HTMLButtonElement | HTMLAnchorElement>",
|
|
259
|
+
"default": null,
|
|
260
|
+
"description": "Ref forwarded to the rendered button or anchor element.",
|
|
261
|
+
"required": false,
|
|
262
|
+
"inherited": false,
|
|
263
|
+
"deprecated": false
|
|
264
|
+
}
|
|
265
|
+
],
|
|
252
266
|
"catchAll": "All standard <button> attributes and Bulma helper props",
|
|
253
267
|
"types": []
|
|
254
268
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"title": "Sizes",
|
|
22
|
-
"code": "<>\n <Message title=\"Default Size\">This is the default size message.</Message>\n <Message title=\"Small\"
|
|
22
|
+
"code": "<>\n <Message title=\"Default Size\">This is the default size message.</Message>\n <Message size=\"small\" title=\"Small\">\n This is a small message.\n </Message>\n <Message size=\"medium\" title=\"Medium\">\n This is a medium message.\n </Message>\n <Message size=\"large\" title=\"Large\">\n This is a large message.\n </Message>\n</>"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"title": "Compound (dot-notation) usage",
|
|
@@ -98,6 +98,15 @@
|
|
|
98
98
|
"deprecated": false,
|
|
99
99
|
"valuesRef": "helpers/valid-values"
|
|
100
100
|
},
|
|
101
|
+
{
|
|
102
|
+
"name": "size",
|
|
103
|
+
"type": "'small' | 'medium' | 'large'",
|
|
104
|
+
"default": null,
|
|
105
|
+
"description": "Size of the message.",
|
|
106
|
+
"required": false,
|
|
107
|
+
"inherited": false,
|
|
108
|
+
"deprecated": false
|
|
109
|
+
},
|
|
101
110
|
{
|
|
102
111
|
"name": "onClose",
|
|
103
112
|
"type": "() => void",
|
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
"title": "Explicit Modal Types",
|
|
30
30
|
"code": "function example() {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n <Button color=\"success\" onClick={() => setOpen(true)}>\n Show Modal\n </Button>\n <Modal active={open} onClose={() => setOpen(false)} type=\"card\">\n Modal card body (forced type=\"card\")\n </Modal>\n </>\n );\n}"
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
"title": "Portal",
|
|
34
|
+
"code": "function example() {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n <Button color=\"success\" onClick={() => setOpen(true)}>\n Show Portaled Modal\n </Button>\n <Modal\n active={open}\n onClose={() => setOpen(false)}\n modalCardTitle=\"Rendered in document.body\"\n portal\n >\n This modal is portaled, so it escapes any ancestor with an `overflow:\n hidden` style.\n </Modal>\n </>\n );\n}"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"title": "Forwarded ref",
|
|
38
|
+
"code": "function example() {\n const [open, setOpen] = React.useState(false);\n const [width, setWidth] = React.useState(null);\n const modalRef = React.useRef(null);\n\n return (\n <>\n <Button color=\"info\" onClick={() => setOpen(true)}>\n Open and measure\n </Button>\n <Modal\n active={open}\n onClose={() => setOpen(false)}\n ref={modalRef}\n modalCardTitle=\"Measured through the ref\"\n >\n <Button\n onClick={() =>\n setWidth(modalRef.current?.getBoundingClientRect().width ?? null)\n }\n >\n Measure\n </Button>\n <p>Width: {width === null ? '—' : `${Math.round(width)}px`}</p>\n </Modal>\n </>\n );\n}"
|
|
39
|
+
},
|
|
32
40
|
{
|
|
33
41
|
"title": "Compound (dot-notation) usage",
|
|
34
42
|
"code": "function example() {\n const [open, setOpen] = useState(false);\n const closeModal = () => setOpen(false);\n\n return (\n <>\n <Button color=\"success\" onClick={() => setOpen(true)}>\n Show Modal\n </Button>\n <Modal isActive={open}>\n <Modal.Background onClick={closeModal} />\n <Modal.Card>\n <Modal.Card.Head>\n <Modal.Card.Title>Compound Component Modal</Modal.Card.Title>\n <Modal.Close onClick={closeModal} />\n </Modal.Card.Head>\n <Modal.Card.Body>\n This modal uses the compound components API for better control and\n readability.\n </Modal.Card.Body>\n <Modal.Card.Foot>\n <Buttons>\n <Button color=\"success\" onClick={closeModal}>\n Save\n </Button>\n <Button onClick={closeModal}>Cancel</Button>\n </Buttons>\n </Modal.Card.Foot>\n </Modal.Card>\n </Modal>\n </>\n );\n}"
|
|
@@ -38,7 +46,7 @@
|
|
|
38
46
|
"code": "function example() {\n const [open, setOpen] = useState(false);\n const closeModal = () => setOpen(false);\n\n return (\n <>\n <Button color=\"success\" onClick={() => setOpen(true)}>\n Show Modal\n </Button>\n <Modal isActive={open}>\n <Modal.Background onClick={closeModal} />\n <Modal.Content>\n <Box>\n <Title size=\"4\">Custom Content</Title>\n <Paragraph>Using compound components for full control!</Paragraph>\n </Box>\n </Modal.Content>\n <Modal.Close variant=\"floating\" onClick={closeModal} />\n </Modal>\n </>\n );\n}"
|
|
39
47
|
}
|
|
40
48
|
],
|
|
41
|
-
"accessibility": "- The modal root
|
|
49
|
+
"accessibility": "- The modal root gets `role=\"dialog\"` and `aria-modal=\"true\"` while active — pass an explicit `role` to override (e.g. `Dialog` passes `role=\"presentation\"` on the `Modal` it wraps so its own `role=\"alertdialog\"` is the only one announced).\n- **Give the dialog an accessible name.** With the legacy API, `modalCardTitle` is wired up as `aria-labelledby` for you. With the compound API, pass your own `aria-label` or `aria-labelledby` on `<Modal>` — a `role=\"dialog\"` with no name is announced as just \"dialog\". An explicit `aria-labelledby` always wins over the generated one.\n- Escape closes the modal (calls `onClose`) by default; opt out with `closeOnEscape={false}`. Only the topmost open modal responds, so Escape closes one layer at a time rather than dismissing a whole stack.\n- Body scroll is locked while the modal is active; opt out with `lockScroll={false}`. The lock is ref-counted and shared with `Dialog`, `Sidebar` and `Loading`, so whichever overlay closes first doesn't unlock the page underneath one that is still open.\n- Focus moves to the first enabled focusable element (or the modal itself) on open, and is restored to the previously focused element on close — unless another modal is still open on top, in which case that one keeps focus.\n- Tab and Shift+Tab cycle within the topmost modal while it is open, so the keyboard order agrees with what `aria-modal=\"true\"` tells assistive technology. Note that `aria-modal` does not by itself make background content inert, and no `inert` attribute is applied — background content remains reachable by pointer and by browser UI such as find-in-page.\n- The modal background closes the modal on click (`onClose` required).\n- Close buttons are provided for both modal-card and modal-content variants.\n\n:::note\nAlways provide an `onClose` handler for accessibility and to allow users to dismiss the modal.\n:::",
|
|
42
50
|
"related": ["Button", "Dialog", "Field", "Input", "useBulmaClasses"],
|
|
43
51
|
"storybook": "https://bestax.io/storybook/?path=/story/components-modal--modal-card",
|
|
44
52
|
"summary": "The `Modal` component provides an empty, accessible overlay for arbitrary content — for a ready-made confirm or alert, reach for `Dialog` instead.",
|
|
@@ -142,9 +150,46 @@
|
|
|
142
150
|
"required": false,
|
|
143
151
|
"inherited": false,
|
|
144
152
|
"deprecated": false
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"name": "closeOnEscape",
|
|
156
|
+
"type": "boolean",
|
|
157
|
+
"default": "true",
|
|
158
|
+
"description": "Close the modal when the Escape key is pressed (calls `onClose`). Only the topmost open modal responds, so Escape closes one layer at a time.",
|
|
159
|
+
"required": false,
|
|
160
|
+
"inherited": false,
|
|
161
|
+
"deprecated": false
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"name": "lockScroll",
|
|
165
|
+
"type": "boolean",
|
|
166
|
+
"default": "true",
|
|
167
|
+
"description": "Lock body scroll while the modal is active. Ref-counted and shared with `Dialog`, `Sidebar` and `Loading`, so whichever overlay closes first does not unlock the page underneath one that is still open.",
|
|
168
|
+
"required": false,
|
|
169
|
+
"inherited": false,
|
|
170
|
+
"deprecated": false
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "portal",
|
|
174
|
+
"type": "boolean | string | HTMLElement",
|
|
175
|
+
"default": "false",
|
|
176
|
+
"description": "Renders the modal into a portal target instead of inline, so it isn't clipped by an ancestor with `overflow: hidden`, `filter` or `transform`. `true` portals to `document.body`; a string is used as a `document.querySelector` selector; an element is used directly. Renders inline on the server and while hydrating, moving into the portal once the client takes over, so hydration matches.",
|
|
177
|
+
"required": false,
|
|
178
|
+
"inherited": false,
|
|
179
|
+
"deprecated": false
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
"extraProps": [
|
|
183
|
+
{
|
|
184
|
+
"name": "ref",
|
|
185
|
+
"type": "React.Ref<HTMLDivElement>",
|
|
186
|
+
"default": null,
|
|
187
|
+
"description": "Ref forwarded to the root `.modal` element.",
|
|
188
|
+
"required": false,
|
|
189
|
+
"inherited": false,
|
|
190
|
+
"deprecated": false
|
|
145
191
|
}
|
|
146
192
|
],
|
|
147
|
-
"extraProps": [],
|
|
148
193
|
"catchAll": "All standard <div> attributes and Bulma helper props",
|
|
149
194
|
"types": []
|
|
150
195
|
},
|
|
@@ -65,12 +65,16 @@
|
|
|
65
65
|
"title": "Color Modifiers",
|
|
66
66
|
"code": "function example() {\n const colors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n 'black',\n 'dark',\n 'light',\n 'white',\n ];\n return (\n <>\n {colors.map(color => (\n <Navbar key={color} color={color} mb=\"2\">\n <Navbar.Brand>\n <Navbar.Item href=\"#\">\n <img src=\"/img/logo.svg\" alt=\"Logo\" width=\"28\" height=\"28\" />\n </Navbar.Item>\n </Navbar.Brand>\n <Navbar.Menu active>\n <Navbar.Start>\n <Navbar.Item href=\"#\">Home</Navbar.Item>\n <Navbar.Item href=\"#\">Docs</Navbar.Item>\n <Navbar.Item href=\"#\">Components</Navbar.Item>\n </Navbar.Start>\n </Navbar.Menu>\n </Navbar>\n ))}\n </>\n );\n}"
|
|
67
67
|
},
|
|
68
|
+
{
|
|
69
|
+
"title": "Forwarded ref",
|
|
70
|
+
"code": "function example() {\n const navRef = React.useRef(null);\n const [height, setHeight] = React.useState(null);\n\n return (\n <>\n <Navbar ref={navRef}>\n <Navbar.Brand>\n <Navbar.Item href=\"#\">Home</Navbar.Item>\n </Navbar.Brand>\n </Navbar>\n <Button mt=\"3\" onClick={() => setHeight(navRef.current?.offsetHeight)}>\n Measure the navbar\n </Button>\n <p>Height: {height == null ? '—' : `${height}px`}</p>\n </>\n );\n}"
|
|
71
|
+
},
|
|
68
72
|
{
|
|
69
73
|
"title": "Compound (dot-notation) usage",
|
|
70
74
|
"code": "<Navbar>\n <Navbar.Brand>\n <Navbar.Item href=\"#\">\n <img src=\"/img/logo.svg\" alt=\"Logo\" width=\"28\" height=\"28\" />\n </Navbar.Item>\n <Navbar.Burger aria-label=\"menu\" />\n </Navbar.Brand>\n <Navbar.Menu active>\n <Navbar.Start>\n <Navbar.Item href=\"#\">Home</Navbar.Item>\n <Navbar.Item href=\"#\">Docs</Navbar.Item>\n </Navbar.Start>\n <Navbar.End>\n <Navbar.Item href=\"#\">Log in</Navbar.Item>\n </Navbar.End>\n </Navbar.Menu>\n</Navbar>"
|
|
71
75
|
}
|
|
72
76
|
],
|
|
73
|
-
"accessibility": "- The root `Navbar` renders as `<nav role=\"navigation\" aria-label=\"main navigation\">`.\n- Use semantic links (`<a>`) and buttons, and provide clear `aria-label` and `aria-expanded` for the burger toggle.\n-
|
|
77
|
+
"accessibility": "- The root `Navbar` renders as `<nav role=\"navigation\" aria-label=\"main navigation\">`.\n- Use semantic links (`<a>`) and buttons, and provide clear `aria-label` and `aria-expanded` for the burger toggle.\n- `Navbar.Link` inside a `Navbar.Dropdown` automatically gets `aria-haspopup=\"true\"` and\n `aria-expanded` synced to the dropdown's open state — no manual wiring required.\n <kbd>Enter</kbd>/<kbd>Space</kbd> toggle the dropdown open/closed, and <kbd>Escape</kbd>\n closes it and keeps focus on the link. When the link has no `href` and isn't rendered with\n `as=\"button\"`, it also gets `role=\"button\"` and `tabIndex={0}` so it's reachable and\n operable by keyboard, and a mouse/touch click on it toggles the dropdown too (a\n caller-supplied `onClick` still runs, and can `preventDefault()` to opt out).\n- `hoverable` dropdowns keep working with a mouse (hover-to-open); the keyboard path above\n opens and closes them independently of hover.\n\n:::note\nThere's no arrow-key roving between navbar items and no outside-click handling for\n`Navbar.Dropdown` — Bulma navbar dropdowns are hover/click surfaces, so this is intentionally\nkept simple.\n:::",
|
|
74
78
|
"related": ["Button", "Icon", "useBulmaClasses"],
|
|
75
79
|
"storybook": "https://bestax.io/storybook/?path=/story/components-navbar--default",
|
|
76
80
|
"summary": "The `Navbar` component implements Bulma's powerful, responsive navigation bar for your Bulma React UI.",
|
|
@@ -149,7 +153,17 @@
|
|
|
149
153
|
"deprecated": false
|
|
150
154
|
}
|
|
151
155
|
],
|
|
152
|
-
"extraProps": [
|
|
156
|
+
"extraProps": [
|
|
157
|
+
{
|
|
158
|
+
"name": "ref",
|
|
159
|
+
"type": "React.Ref<HTMLElement>",
|
|
160
|
+
"default": null,
|
|
161
|
+
"description": "Ref forwarded to the root `<nav>` element.",
|
|
162
|
+
"required": false,
|
|
163
|
+
"inherited": false,
|
|
164
|
+
"deprecated": false
|
|
165
|
+
}
|
|
166
|
+
],
|
|
153
167
|
"catchAll": "All standard HTML attributes and Bulma helper props",
|
|
154
168
|
"types": []
|
|
155
169
|
},
|
|
@@ -328,7 +342,17 @@
|
|
|
328
342
|
"deprecated": false
|
|
329
343
|
}
|
|
330
344
|
],
|
|
331
|
-
"extraProps": [
|
|
345
|
+
"extraProps": [
|
|
346
|
+
{
|
|
347
|
+
"name": "ref",
|
|
348
|
+
"type": "React.Ref<HTMLAnchorElement | HTMLButtonElement>",
|
|
349
|
+
"default": null,
|
|
350
|
+
"description": "Ref forwarded to the rendered link or button element.",
|
|
351
|
+
"required": false,
|
|
352
|
+
"inherited": false,
|
|
353
|
+
"deprecated": false
|
|
354
|
+
}
|
|
355
|
+
],
|
|
332
356
|
"catchAll": "All standard <a> attributes and Bulma helper props",
|
|
333
357
|
"types": []
|
|
334
358
|
},
|
|
@@ -411,7 +435,17 @@
|
|
|
411
435
|
"deprecated": false
|
|
412
436
|
}
|
|
413
437
|
],
|
|
414
|
-
"extraProps": [
|
|
438
|
+
"extraProps": [
|
|
439
|
+
{
|
|
440
|
+
"name": "ref",
|
|
441
|
+
"type": "React.Ref<HTMLButtonElement>",
|
|
442
|
+
"default": null,
|
|
443
|
+
"description": "Ref forwarded to the burger button element.",
|
|
444
|
+
"required": false,
|
|
445
|
+
"inherited": false,
|
|
446
|
+
"deprecated": false
|
|
447
|
+
}
|
|
448
|
+
],
|
|
415
449
|
"catchAll": "All standard <button> attributes and Bulma helper props",
|
|
416
450
|
"types": []
|
|
417
451
|
},
|
|
@@ -615,6 +649,15 @@
|
|
|
615
649
|
"inherited": false,
|
|
616
650
|
"deprecated": false
|
|
617
651
|
},
|
|
652
|
+
{
|
|
653
|
+
"name": "onActiveChange",
|
|
654
|
+
"type": "(active: boolean) => void",
|
|
655
|
+
"default": null,
|
|
656
|
+
"description": "Callback when dropdown active state changes.",
|
|
657
|
+
"required": false,
|
|
658
|
+
"inherited": false,
|
|
659
|
+
"deprecated": false
|
|
660
|
+
},
|
|
618
661
|
{
|
|
619
662
|
"name": "children",
|
|
620
663
|
"type": "React.ReactNode",
|
|
@@ -625,7 +668,17 @@
|
|
|
625
668
|
"deprecated": false
|
|
626
669
|
}
|
|
627
670
|
],
|
|
628
|
-
"extraProps": [
|
|
671
|
+
"extraProps": [
|
|
672
|
+
{
|
|
673
|
+
"name": "ref",
|
|
674
|
+
"type": "React.Ref<HTMLDivElement>",
|
|
675
|
+
"default": null,
|
|
676
|
+
"description": "Ref forwarded to the dropdown container element.",
|
|
677
|
+
"required": false,
|
|
678
|
+
"inherited": false,
|
|
679
|
+
"deprecated": false
|
|
680
|
+
}
|
|
681
|
+
],
|
|
629
682
|
"catchAll": "All standard <div> attributes",
|
|
630
683
|
"types": []
|
|
631
684
|
},
|
|
@@ -158,9 +158,27 @@
|
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
160
|
"path": "Panel.Icon",
|
|
161
|
-
"summary": "Icon wrapper with panel styling (renders as `<span class=\"panel-icon\"
|
|
161
|
+
"summary": "Icon wrapper with panel styling (renders as `<span class=\"panel-icon\">`, containing an `<i/>` when a `name` is given, or the custom node passed as `children`). Accepts all Icon props (`name`, `variant`, `features`, etc.), or `children` for a custom node.",
|
|
162
162
|
"component": null,
|
|
163
163
|
"props": [
|
|
164
|
+
{
|
|
165
|
+
"name": "name",
|
|
166
|
+
"type": "string | undefined",
|
|
167
|
+
"default": null,
|
|
168
|
+
"description": "The icon name, with or without its library prefix (e.g. `'star'` or `'fa-star'`). Mutually exclusive with `children`.",
|
|
169
|
+
"required": false,
|
|
170
|
+
"inherited": true,
|
|
171
|
+
"deprecated": false
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"name": "children",
|
|
175
|
+
"type": "Exclude<React.ReactNode, undefined>",
|
|
176
|
+
"default": null,
|
|
177
|
+
"description": "A custom node (an inline SVG, a `react-icons` component, …) rendered inside the icon container in place of a class-based glyph. Mutually exclusive with `name`.",
|
|
178
|
+
"required": false,
|
|
179
|
+
"inherited": true,
|
|
180
|
+
"deprecated": false
|
|
181
|
+
},
|
|
164
182
|
{
|
|
165
183
|
"name": "className",
|
|
166
184
|
"type": "string",
|
|
@@ -199,15 +217,6 @@
|
|
|
199
217
|
"deprecated": false,
|
|
200
218
|
"valuesRef": "helpers/valid-values"
|
|
201
219
|
},
|
|
202
|
-
{
|
|
203
|
-
"name": "name",
|
|
204
|
-
"type": "string",
|
|
205
|
-
"default": null,
|
|
206
|
-
"description": "The icon name, with or without its library prefix (e.g. `'star'` or `'fa-star'`).",
|
|
207
|
-
"required": false,
|
|
208
|
-
"inherited": true,
|
|
209
|
-
"deprecated": false
|
|
210
|
-
},
|
|
211
220
|
{
|
|
212
221
|
"name": "icon",
|
|
213
222
|
"type": "string",
|
|
@@ -221,7 +230,7 @@
|
|
|
221
230
|
"name": "library",
|
|
222
231
|
"type": "'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols'",
|
|
223
232
|
"default": "'fa'",
|
|
224
|
-
"description": "The icon library to use ('fa' = Font Awesome, 'mdi' = Material Design Icons, 'ion' = Ionicons Web Components, 'material-icons' = Google Material Icons, 'material-symbols' = Google Material Symbols). Defaults to the value set in ConfigProvider or 'fa' if not configured.",
|
|
233
|
+
"description": "The icon library to use ('fa' = Font Awesome, 'mdi' = Material Design Icons, 'ion' = Ionicons Web Components, 'material-icons' = Google Material Icons, 'material-symbols' = Google Material Symbols). Defaults to the value set in ConfigProvider or 'fa' if not configured. Ignored when `children` supplies the glyph instead of `name`.",
|
|
225
234
|
"required": false,
|
|
226
235
|
"inherited": true,
|
|
227
236
|
"deprecated": false
|
|
@@ -230,7 +239,7 @@
|
|
|
230
239
|
"name": "variant",
|
|
231
240
|
"type": "string",
|
|
232
241
|
"default": null,
|
|
233
|
-
"description": "Icon style variant (e.g. `'solid'`, `'outlined'`, `'rounded'`).",
|
|
242
|
+
"description": "Icon style variant (e.g. `'solid'`, `'outlined'`, `'rounded'`). Ignored when `children` supplies the glyph instead of `name`.",
|
|
234
243
|
"required": false,
|
|
235
244
|
"inherited": true,
|
|
236
245
|
"deprecated": false
|
|
@@ -239,7 +248,7 @@
|
|
|
239
248
|
"name": "features",
|
|
240
249
|
"type": "string | string[]",
|
|
241
250
|
"default": null,
|
|
242
|
-
"description": "Additional modifiers (e.g. `'fa-lg'`, `'fa-spin'`, `'is-size-1'`).",
|
|
251
|
+
"description": "Additional modifiers (e.g. `'fa-lg'`, `'fa-spin'`, `'is-size-1'`). Ignored when `children` supplies the glyph instead of `name`.",
|
|
243
252
|
"required": false,
|
|
244
253
|
"inherited": true,
|
|
245
254
|
"deprecated": false
|
|
@@ -266,7 +275,7 @@
|
|
|
266
275
|
"name": "ariaLabel",
|
|
267
276
|
"type": "string",
|
|
268
277
|
"default": "'icon'",
|
|
269
|
-
"description": "ARIA label for accessibility (default
|
|
278
|
+
"description": "ARIA label for accessibility. Applied unconditionally to the container span, so an icon that never sets it still renders `aria-label=\"icon\"`. For an icon-only control, put the real `aria-label` on the control (e.g. `Button`) and set `aria-hidden` here instead — otherwise the control's accessible name is announced as just \"icon\". For a decorative icon beside visible text, set `aria-hidden` here rather than leaving the default, so it doesn't add \"icon\" to the text's accessible name.",
|
|
270
279
|
"required": false,
|
|
271
280
|
"inherited": true,
|
|
272
281
|
"deprecated": false
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"code": "function example() {\n const [isOpen, setIsOpen] = useState(false);\n return (\n <>\n <Button color=\"primary\" onClick={() => setIsOpen(true)}>\n Open Sidebar\n </Button>\n <Sidebar inline isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <Sidebar.Header>\n <Sidebar.Title>Dot Notation</Sidebar.Title>\n <Sidebar.Close onClick={() => setIsOpen(false)} />\n </Sidebar.Header>\n <Sidebar.Body>\n <Paragraph>\n Header, Title, Close, Body, and Footer are all available from the\n single Sidebar import.\n </Paragraph>\n </Sidebar.Body>\n <Sidebar.Footer>\n <Button color=\"primary\" onClick={() => setIsOpen(false)}>\n Done\n </Button>\n </Sidebar.Footer>\n </Sidebar>\n </>\n );\n}"
|
|
39
39
|
}
|
|
40
40
|
],
|
|
41
|
-
"accessibility": "- Uses `role=\"dialog\"` for proper screen reader announcement\n- Has `aria-modal=\"true\"` when overlay is shown\n- Focus is trapped within the sidebar when open\n- Escape key closes the sidebar by default\n- Body scroll is prevented when sidebar is open",
|
|
41
|
+
"accessibility": "- Uses `role=\"dialog\"` for proper screen reader announcement\n- Has `aria-modal=\"true\"` when overlay is shown\n- Focus is trapped within the sidebar when open\n- Escape key closes the sidebar by default\n- Body scroll is prevented when the sidebar is open with an overlay, through the ref-counted lock shared with `Modal`, `Dialog` and `Loading` — so closing one overlay never unlocks the page underneath another that is still open",
|
|
42
42
|
"related": ["Menu", "Modal"],
|
|
43
43
|
"storybook": "https://bestax.io/storybook/?path=/story/components-sidebar",
|
|
44
44
|
"summary": "The `Sidebar` component provides a slide-out navigation panel that appears from the left or right side of the screen.",
|
|
@@ -14,8 +14,12 @@
|
|
|
14
14
|
"code": "<Tags hasAddons>\n <Tag color=\"primary\">Package</Tag>\n <Tag color=\"success\">Ready</Tag>\n <Tag isDelete onDelete={() => alert('Deleted!')} />\n</Tags>"
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
|
-
"title": "
|
|
18
|
-
"code": "<Tags
|
|
17
|
+
"title": "Wrapping (Default)",
|
|
18
|
+
"code": "<Tags>\n <Tag color=\"primary\">Bulma</Tag>\n <Tag color=\"success\">React</Tag>\n <Tag color=\"warning\">Typescript</Tag>\n <Tag color=\"danger\">Library</Tag>\n <Tag color=\"link\">UI</Tag>\n</Tags>"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"title": "Group Size",
|
|
22
|
+
"code": "<>\n <Tags size=\"medium\">\n <Tag color=\"primary\">Medium</Tag>\n <Tag color=\"info\">Medium</Tag>\n </Tags>\n <Tags size=\"large\">\n <Tag color=\"primary\">Large</Tag>\n <Tag color=\"info\">Large</Tag>\n </Tags>\n</>"
|
|
19
23
|
},
|
|
20
24
|
{
|
|
21
25
|
"title": "With Margin",
|
|
@@ -23,7 +27,7 @@
|
|
|
23
27
|
},
|
|
24
28
|
{
|
|
25
29
|
"title": "Mixed Tags",
|
|
26
|
-
"code": "function example() {\n const [show, setShow] = useState();\n\n return (\n <Tags
|
|
30
|
+
"code": "function example() {\n const [show, setShow] = useState();\n\n return (\n <Tags>\n <Tag color=\"primary\" size=\"medium\">\n Primary Medium\n </Tag>\n <Tag color=\"success\" isRounded>\n Success Rounded\n </Tag>\n {/* Dismissible tag */}\n {show && <Tag color=\"danger\" isDelete onDelete={() => setShow(false)} />}\n <Tag color=\"info\">Info</Tag>\n </Tags>\n );\n}"
|
|
27
31
|
},
|
|
28
32
|
{
|
|
29
33
|
"title": "Add-ons with Delete Tag",
|
|
@@ -34,17 +38,17 @@
|
|
|
34
38
|
"code": "<Tags>\n <Tags.Tag color=\"primary\">React</Tags.Tag>\n <Tags.Tag color=\"info\">TypeScript</Tags.Tag>\n</Tags>"
|
|
35
39
|
}
|
|
36
40
|
],
|
|
37
|
-
"accessibility": "- **Grouping:** The container is a `<div class=\"tags\">`, which is semantically neutral.\n- **Delete buttons:** If using delete tags, ensure each has an accessible label.\n- **
|
|
41
|
+
"accessibility": "- **Grouping:** The container is a `<div class=\"tags\">`, which is semantically neutral.\n- **Delete buttons:** If using delete tags, ensure each has an accessible label.\n- **Wrapping:** Tags wrap onto multiple lines by default for better readability on small screens.\n\n:::tip\nUse `hasAddons` for tightly grouped tags (no space between them).\n:::",
|
|
38
42
|
"related": ["Delete", "Tag", "useBulmaClasses"],
|
|
39
43
|
"storybook": "https://bestax.io/storybook/?path=/story/elements-tag--default",
|
|
40
|
-
"summary": "The `Tags` component groups multiple `Tag` components together in a
|
|
44
|
+
"summary": "The `Tags` component groups multiple `Tag` components together in a Bulma-styled container that wraps onto multiple lines by default.",
|
|
41
45
|
"import": "import { Tags } from '@allxsmith/bestax-bulma';",
|
|
42
46
|
"sourceFile": "bulma-ui/src/elements/Tags.tsx",
|
|
43
47
|
"rootClass": "tags",
|
|
44
48
|
"parts": [
|
|
45
49
|
{
|
|
46
50
|
"path": "Tags",
|
|
47
|
-
"summary": "The `Tags` component groups multiple `Tag` components together in a
|
|
51
|
+
"summary": "The `Tags` component groups multiple `Tag` components together in a Bulma-styled container that wraps onto multiple lines by default.",
|
|
48
52
|
"component": null,
|
|
49
53
|
"props": [
|
|
50
54
|
{
|
|
@@ -69,7 +73,17 @@
|
|
|
69
73
|
"name": "isMultiline",
|
|
70
74
|
"type": "boolean",
|
|
71
75
|
"default": "false",
|
|
72
|
-
"description": "
|
|
76
|
+
"description": "No-op retained for backwards compatibility.",
|
|
77
|
+
"required": false,
|
|
78
|
+
"inherited": false,
|
|
79
|
+
"deprecated": true,
|
|
80
|
+
"deprecationNote": "Bulma's `.tags` wraps by default (no shipped `are-multiline` CSS exists for it) — this prop has never had a visual effect and will be removed in the next major version."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "size",
|
|
84
|
+
"type": "'medium' | 'large'",
|
|
85
|
+
"default": null,
|
|
86
|
+
"description": "Size of every tag in the group.",
|
|
73
87
|
"required": false,
|
|
74
88
|
"inherited": false,
|
|
75
89
|
"deprecated": false
|