bestax-mcp 1.14.2 → 1.14.4

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.
Files changed (33) hide show
  1. package/data/catalog.json +3 -2
  2. package/data/components/Autocomplete.json +5 -5
  3. package/data/components/DateInput.json +1 -1
  4. package/data/components/DateRangeInput.json +1 -1
  5. package/data/components/DateTimeInput.json +1 -1
  6. package/data/components/Delete.json +4 -4
  7. package/data/components/Field.json +5 -5
  8. package/data/components/File.json +2 -2
  9. package/data/components/Input.json +7 -7
  10. package/data/components/Notification.json +7 -1
  11. package/data/components/Numberinput.json +1 -1
  12. package/data/components/Select.json +5 -5
  13. package/data/components/Slider.json +12 -4
  14. package/data/components/Taginput.json +1 -1
  15. package/data/components/TextArea.json +4 -4
  16. package/data/components/Theme.json +2 -2
  17. package/data/components/TimeInput.json +1 -1
  18. package/data/skills/bestax-form/SKILL.md +42 -26
  19. package/data/skills/bestax-form/references/api.md +12 -10
  20. package/data/skills/bestax-form/references/patterns.md +26 -6
  21. package/data/skills/bestax-icons/SKILL.md +8 -1
  22. package/data/skills/bestax-icons/references/icon-libraries.md +42 -4
  23. package/data/skills/bestax-migrate/references/bulma-classes/component-map.md +8 -0
  24. package/data/skills/bestax-migrate/references/bulma-classes/unmappables.md +5 -0
  25. package/data/skills/bestax-optimize/SKILL.md +2 -0
  26. package/data/skills/bestax-optimize/references/modular-build.md +17 -8
  27. package/data/skills/bestax-theming/SKILL.md +4 -1
  28. package/data/skills/bestax-theming/references/css-variables.md +34 -1
  29. package/data/skills.json +7 -7
  30. package/dist/bulma-classes.d.ts +6 -0
  31. package/dist/bulma-classes.d.ts.map +1 -1
  32. package/dist/bulma-classes.js +23 -2
  33. package/package.json +4 -4
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.27.1"
5
+ "version": "5.27.8"
6
6
  },
7
7
  "docsBase": "https://bestax.io/docs",
8
8
  "categories": [
@@ -917,7 +917,7 @@
917
917
  "import": "import { Slider } from '@allxsmith/bestax-bulma';",
918
918
  "compound": false,
919
919
  "propCount": 30,
920
- "exampleCount": 11
920
+ "exampleCount": 13
921
921
  },
922
922
  {
923
923
  "name": "Span",
@@ -2007,6 +2007,7 @@
2007
2007
  "--bulma-notification-background-l": ["Notification"],
2008
2008
  "--bulma-notification-code-background-color": ["Notification"],
2009
2009
  "--bulma-notification-color-l": ["Notification"],
2010
+ "--bulma-notification-delete-padding-inline-end": ["Notification"],
2010
2011
  "--bulma-notification-h": ["Notification"],
2011
2012
  "--bulma-notification-padding": ["Notification"],
2012
2013
  "--bulma-notification-radius": ["Notification"],
@@ -47,14 +47,14 @@
47
47
  },
48
48
  {
49
49
  "title": "Context-Aware Rendering",
50
- "code": "function example() {\n return (\n <Field horizontal label=\"Fruit\" labelProps={{ htmlFor: 'fruit-field' }}>\n <Field.Body>\n <Field>\n <Autocomplete\n id=\"fruit-field\"\n data={['Apple', 'Banana', 'Cherry']}\n placeholder=\"Search fruit...\"\n />\n </Field>\n </Field.Body>\n </Field>\n );\n}"
50
+ "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Fruit\"\n labelProps={{ htmlFor: 'fruit-field', id: 'fruit-field-label' }}\n >\n <Field.Body>\n <Field>\n <Autocomplete\n id=\"fruit-field\"\n data={['Apple', 'Banana', 'Cherry']}\n placeholder=\"Search fruit...\"\n />\n </Field>\n </Field.Body>\n </Field>\n );\n}"
51
51
  },
52
52
  {
53
53
  "title": "Context-Aware Rendering",
54
- "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Fruit\"\n labelProps={{ htmlFor: 'fruit-field-control' }}\n >\n <Field.Body>\n <Field>\n <Control iconLeftName=\"search\">\n <Autocomplete\n id=\"fruit-field-control\"\n data={['Apple', 'Banana', 'Cherry']}\n placeholder=\"Search fruit...\"\n />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
54
+ "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Fruit\"\n labelProps={{\n htmlFor: 'fruit-field-control',\n id: 'fruit-field-control-label',\n }}\n >\n <Field.Body>\n <Field>\n <Control iconLeftName=\"search\">\n <Autocomplete\n id=\"fruit-field-control\"\n data={['Apple', 'Banana', 'Cherry']}\n placeholder=\"Search fruit...\"\n />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
55
55
  }
56
56
  ],
57
- "accessibility": "- The `label` prop is automatically associated with the inner text input (`htmlFor` plus a generated `id`, or your own `id` if you pass one), so clicking the label focuses the input and assistive technology announces it. Inside a labeled `Field`, that `Field`'s label names the input the same way.\n- A user-supplied `id` is applied to the inner input (the labellable control), not the wrapper div.\n- Uses `role=\"combobox\"` with `aria-expanded`, which is true only while the list is on screen\n- Has `aria-haspopup=\"listbox\"` and `aria-autocomplete=\"list\"`, and, while the list is on screen, `aria-controls` pointing at it\n- Focus stays in the input, which points `aria-activedescendant` at the highlighted option as the arrow keys move it\n- The list is a `role=\"listbox\"` named by the `label` prop's label. Inside an outer `Field`, or with no `label`, it falls back to `aria-label=\"Suggestions\"`\n- Dropdown items use `role=\"option\"` with `aria-selected`\n- Disabled items have `aria-disabled`\n- The `clearable` clear button is a native button named \"Clear\": `Tab` from the input reaches it, and `Enter` or `Space` clears the input and puts focus back in it\n- Full keyboard navigation support",
57
+ "accessibility": "- The `label` prop is automatically associated with the inner text input (`htmlFor` plus a generated `id`, or your own `id` if you pass one), so clicking the label focuses the input and assistive technology announces it. Inside a labeled `Field`, that `Field`'s label names the input instead when it points at it: a `Field` that is not `grouped` or `hasAddons` points it there on its own when the Autocomplete has no `id` and no inner `Field` sits between them, and a label you wire by hand with `labelProps.htmlFor` points at the input with that `id`.\n- A user-supplied `id` is applied to the inner input (the labellable control), not the wrapper div.\n- Uses `role=\"combobox\"` with `aria-expanded`, which is true only while the list is on screen\n- Has `aria-haspopup=\"listbox\"` and `aria-autocomplete=\"list\"`, and, while the list is on screen, `aria-controls` pointing at it\n- Focus stays in the input, which points `aria-activedescendant` at the highlighted option as the arrow keys move it\n- The list is a `role=\"listbox\"` named through `aria-labelledby` by the label that names the input, when that label has an id: the `label` prop's label always has one, and so does a `Field`'s label that the `Field` wires itself. A `Field` label you wire by hand with `labelProps.htmlFor`, which is how a horizontal form names an Autocomplete in an inner `Field`, needs an `id` in its `labelProps` as well. Otherwise the list falls back to `aria-label=\"Suggestions\"`\n- Dropdown items use `role=\"option\"` with `aria-selected`\n- Disabled items have `aria-disabled`\n- The `clearable` clear button is a native button named \"Clear\": `Tab` from the input reaches it, and `Enter` or `Space` clears the input and puts focus back in it\n- Full keyboard navigation support",
58
58
  "related": ["Input", "Select", "Taginput"],
59
59
  "storybook": "https://bestax.io/storybook/?path=/story/form-autocomplete",
60
60
  "summary": "The `Autocomplete` component provides an input field with dropdown suggestions that filter based on user input.",
@@ -71,7 +71,7 @@
71
71
  "name": "label",
72
72
  "type": "React.ReactNode",
73
73
  "default": null,
74
- "description": "Field label. Automatically associated with the text input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
74
+ "description": "Field label, associated with the text input via `htmlFor`: through your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose label names the input instead when it points at it. The `Field` points its label there itself when the Autocomplete has no `id` and no inner `Field` sits between them (and the `Field` is not `grouped` or `hasAddons`); a label you wire by hand with `labelProps.htmlFor` points at the input with that `id`. The label naming the input also names the open suggestion list, through `aria-labelledby`, when it has an id: this label always does, and an outer `Field`'s does unless you wired it by hand without an `id` in its `labelProps`. Otherwise the list is named \"Suggestions\".",
75
75
  "required": false,
76
76
  "inherited": false,
77
77
  "deprecated": false
@@ -80,7 +80,7 @@
80
80
  "name": "labelProps",
81
81
  "type": "React.LabelHTMLAttributes<HTMLLabelElement> & { [key: string]: unknown; }",
82
82
  "default": null,
83
- "description": "Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then).",
83
+ "description": "Props for the label element. An explicit `htmlFor` here overrides the automatic association (the input then gets no generated id). While the label names the input, the suggestion list's `aria-labelledby` points at it, through an `id` here when you give one and a generated one otherwise.",
84
84
  "required": false,
85
85
  "inherited": false,
86
86
  "deprecated": false
@@ -191,7 +191,7 @@
191
191
  "name": "label",
192
192
  "type": "React.ReactNode",
193
193
  "default": null,
194
- "description": "Field label (component auto-wraps in a `Field` if not already inside). Automatically associated with the input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Not wired in `inline` mode (no visible input to label). Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
194
+ "description": "Field label (component auto-wraps in a `Field` if not already inside). Automatically associated with the input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Not wired in `inline` mode (no visible input to label). Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here.",
195
195
  "required": false,
196
196
  "inherited": false,
197
197
  "deprecated": false
@@ -46,7 +46,7 @@
46
46
  "code": "<Field label=\"Leave\">\n <Control iconLeftName=\"calendar-alt\">\n <DateRangeInput />\n </Control>\n</Field>"
47
47
  }
48
48
  ],
49
- "accessibility": "- The root is a `role=\"group\"` named by `label` through `aria-labelledby`, since the label names two inputs rather than one. Inside a labeled `Field`, that `Field`'s label names the group the same way. An `aria-label` or `aria-labelledby` you give the group wins over either label.\n- Each input is a `role=\"combobox\"` with `aria-haspopup=\"dialog\"`, `aria-expanded` and `aria-controls`, and its own name: \"Start date\" or \"End date\", from the `labels` keys `rangeStart` and `rangeEnd`. The separator between them is hidden from assistive technology.\n- The popover is a `role=\"dialog\"` named \"Choose date range\" (`labels.chooseDateRange`). Opening it puts focus on the calendar's focused day, and closing it returns focus to the input you were last in, or to the start input.\n- The day grid is `aria-multiselectable`, and its days sit in a `role=\"row\"` per week. Every day of the range is `aria-selected`, both ends included. While the end is still being picked, only the start is: the preview is not a selection.\n- The start and end days are described as \"Start date\" and \"End date\", so moving onto either says which it is. While the end is still being picked, the day the range would end on is described as \"Choose as end date\" (`labels.rangePreviewEnd`).\n- A polite live region in the calendar states the range in words, such as \"Start date: June 10, 2024, End date: June 13, 2024\", and announces each pick. The grid points at it too, so moving into the grid reads the current range.\n- Everything else is the calendar `DateInput` uses: a roving `tabindex`, `aria-disabled` on disabled days and `aria-current=\"date\"` on today.",
49
+ "accessibility": "- The root is a `role=\"group\"` named by `label` through `aria-labelledby`, since the label names two inputs rather than one. Inside a labeled `Field`, that `Field`'s label names the group the same way, whether the `Field` holds `DateRangeInput` or a `DateRangeInputBase` you composed in a `Control` yourself, `inline` or not. An `aria-label` or `aria-labelledby` you give the group wins over either label.\n- Each input is a `role=\"combobox\"` with `aria-haspopup=\"dialog\"`, `aria-expanded` and `aria-controls`, and its own name: \"Start date\" or \"End date\", from the `labels` keys `rangeStart` and `rangeEnd`. The separator between them is hidden from assistive technology.\n- The popover is a `role=\"dialog\"` named \"Choose date range\" (`labels.chooseDateRange`). Opening it puts focus on the calendar's focused day, and closing it returns focus to the input you were last in, or to the start input.\n- The day grid is `aria-multiselectable`, and its days sit in a `role=\"row\"` per week. Every day of the range is `aria-selected`, both ends included. While the end is still being picked, only the start is: the preview is not a selection.\n- The start and end days are described as \"Start date\" and \"End date\", so moving onto either says which it is. While the end is still being picked, the day the range would end on is described as \"Choose as end date\" (`labels.rangePreviewEnd`).\n- A polite live region in the calendar states the range in words, such as \"Start date: June 10, 2024, End date: June 13, 2024\", and announces each pick. The grid points at it too, so moving into the grid reads the current range.\n- Everything else is the calendar `DateInput` uses: a roving `tabindex`, `aria-disabled` on disabled days and `aria-current=\"date\"` on today.",
50
50
  "related": ["DateInput", "DateTimeInput", "Field"],
51
51
  "storybook": "https://bestax.io/storybook/?path=/story/form-daterangeinput",
52
52
  "summary": "The `DateRangeInput` component is a form input for a start and end date, picked from one popover calendar or typed into two segmented inputs.",
@@ -187,7 +187,7 @@
187
187
  "name": "label",
188
188
  "type": "React.ReactNode",
189
189
  "default": null,
190
- "description": "Field label. Automatically associated with the input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Not wired in `inline` mode (no visible input to label). Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
190
+ "description": "Field label. Automatically associated with the input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Not wired in `inline` mode (no visible input to label). Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here.",
191
191
  "required": false,
192
192
  "inherited": false,
193
193
  "deprecated": false
@@ -129,25 +129,25 @@
129
129
  "css": "--bulma-delete-dimensions",
130
130
  "sass": null,
131
131
  "default": "1.25rem",
132
- "scope": "global"
132
+ "scope": "compound"
133
133
  },
134
134
  {
135
135
  "css": "--bulma-delete-background-l",
136
136
  "sass": null,
137
137
  "default": "0%",
138
- "scope": "global"
138
+ "scope": "root"
139
139
  },
140
140
  {
141
141
  "css": "--bulma-delete-background-alpha",
142
142
  "sass": null,
143
143
  "default": "0.5",
144
- "scope": "global"
144
+ "scope": "root"
145
145
  },
146
146
  {
147
147
  "css": "--bulma-delete-color",
148
148
  "sass": null,
149
149
  "default": "var(--bulma-white)",
150
- "scope": "global"
150
+ "scope": "root"
151
151
  }
152
152
  ]
153
153
  }
@@ -83,10 +83,10 @@
83
83
  },
84
84
  {
85
85
  "title": "Compound (dot-notation) usage",
86
- "code": "<Field horizontal>\n <Field.Label>Name</Field.Label>\n <Field.Body>\n <Field.Control>\n <Input placeholder=\"Jane Doe\" />\n </Field.Control>\n </Field.Body>\n</Field>"
86
+ "code": "<Field horizontal>\n <Field.Label size=\"normal\">\n <label className=\"label\" htmlFor=\"compound-name\">\n Name\n </label>\n </Field.Label>\n <Field.Body>\n <Field.Control>\n <Input id=\"compound-name\" placeholder=\"Jane Doe\" />\n </Field.Control>\n </Field.Body>\n</Field>"
87
87
  }
88
88
  ],
89
- "accessibility": "- The `label` prop names the one control the Field holds. A composed `InputBase`, `SelectBase`, or `TextAreaBase`, or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id the label's `for` points at, so clicking the label focuses the control and assistive technology announces it.\n- A group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`) can't take a `for`, so the label gets an id (yours from `labelProps.id`, otherwise a generated one) and the group points `aria-labelledby` at it. An `aria-label` or `aria-labelledby` you set on the group wins over the Field's label, as it does over a group's own `label`.\n- An `id` you set on the control wins too: it keeps that id, and the label then names it only if you point `labelProps={{ htmlFor }}` at it. Pass `labelProps={{ htmlFor: undefined }}` to opt out of the association entirely.\n- Association is skipped for `grouped`/`hasAddons` fields (they hold several controls), and a `Field` nested inside a labeled one starts its own scope. A horizontal Field wraps its children in a `Field.Body` of its own and keeps the association, but the pattern with an inner `Field` in that body needs it wired by hand.\n- Two controls in one plain labeled Field would both adopt its id. Give each an `id` of its own and label it individually.\n- A labeled Field whose content takes no `for`, a group included, renders its `for` unmatched. `Checkbox`, `Radio` and `Switch` take nothing from the label at all: each is named by its own children, so put the text there rather than in the Field's `label`. Where you point content at the label by hand, as with a group in an inner `Field`, pass `labelProps={{ id, htmlFor: undefined }}` so the label keeps its id and drops the `for`.\n- Grouped/horizontal layouts use Bulma’s grid for layout.\n- Always use the `label` prop or a custom label for clarity.",
89
+ "accessibility": "- For a single control, prefer the control's own `label` prop, with `horizontal` for a side-by-side row. It renders this `Field` and its label and wires the `for` itself, to your `id` when you pass one: `<Input label=\"Email\" id=\"email\" horizontal />`.\n- The `label` prop names the one control the Field holds. A composed `InputBase`, `SelectBase`, `TextAreaBase`, `DateInputBase`, `TimeInputBase`, or `DateTimeInputBase`, or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id the label's `for` points at, so clicking the label focuses the control and assistive technology announces it. An `inline` picker renders no input, so it takes nothing.\n- A control with an `id` of its own keeps it and never takes the generated one, so `<Field label=\"Email\"><Input id=\"email\" /></Field>` renders a label that names nothing. Leave the `id` off, or pass the same value as `labelProps={{ htmlFor: 'email' }}`. Pass `labelProps={{ htmlFor: undefined }}` to opt out of the association entirely.\n- A range `Slider` takes that id on its low thumb, and its thumbs also point `aria-labelledby` at the label (at `labelProps.id` when you set one), so under a label of \"Price range\" they announce as \"Price range Minimum value\" and \"Price range Maximum value\". An `ariaLabel` entry names its thumb instead, and an `aria-label` or `aria-labelledby` on the Slider takes the label's place in both names. A label you wire by hand with `labelProps={{ htmlFor }}` gets no generated id, so it reaches the thumbs' names only when you give it an `id` there too, as in `labelProps={{ htmlFor: 'price', id: 'price-label' }}`.\n- An `Autocomplete` points its open suggestion list's `aria-labelledby` at the label the same way, so under a label of \"Country\" the list announces as \"Country\" rather than its fallback name, \"Suggestions\". A label you wire by hand needs an `id` in `labelProps` for this too, as in `labelProps={{ htmlFor: 'country', id: 'country-label' }}`.\n- A group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`, or a composed `DateRangeInputBase`, `inline` or not) can't take a `for`, so the label gets an id (yours from `labelProps.id`, otherwise a generated one) and the group points `aria-labelledby` at it. An `aria-label` or `aria-labelledby` you set on the group wins over the Field's label, as it does over a group's own `label`.\n- Association is skipped for `grouped`/`hasAddons` fields (they hold several controls), and a `Field` nested inside a labeled one starts its own scope. A horizontal Field wraps its children in a `Field.Body` of its own and keeps the association, but the pattern with an inner `Field` in that body needs it wired by hand. A label you wire by hand names the control its `for` points at in a `grouped` or `hasAddons` field too, and with an `id` in `labelProps` it names a range `Slider`'s thumbs and an `Autocomplete`'s list there as well. No group points at it on its own.\n- Two controls in one plain labeled Field would both adopt its id. Give each an `id` of its own and label it individually.\n- Once a labeled Field's content has mounted, its label keeps the generated `for` only while one of the inputs above holds the id, and drops it over anything else: a group, a `Checkbox`, `Radio` or `Switch`, an `inline` picker, an inner `Field`, an input with an `id` of its own, markup of your own, or nothing at all. A server render, and the first render while hydrating, still write the `for`, so hydration matches, and an input that mounts later puts it back. A `for` you set with `labelProps={{ htmlFor }}` always stays. `Checkbox`, `Radio` and `Switch` take nothing from the label on their own: each is named by its own children, so put the text there, and the label names one only when you wire it as you would any control with an `id` of its own, `labelProps={{ htmlFor }}` plus that control's `id`. Where you point content at the label by hand, as with a group in an inner `Field`, `labelProps={{ id }}` is enough in the browser, and `labelProps={{ id, htmlFor: undefined }}` keeps the `for` out of server-rendered HTML too.\n- Grouped/horizontal layouts use Bulma’s grid for layout.",
90
90
  "related": [
91
91
  "Checkbox",
92
92
  "Checkboxes",
@@ -149,7 +149,7 @@
149
149
  "name": "label",
150
150
  "type": "React.ReactNode",
151
151
  "default": null,
152
- "description": "Field label, rendered above the widget. Automatically names the one control the Field holds: a composed `InputBase`, `SelectBase` or `TextAreaBase`, or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id that the label's `htmlFor` points at, and a group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`) points `aria-labelledby` at the label's own id unless you gave the group an `aria-label` or `aria-labelledby`. Nothing else takes the label: `Checkbox`, `Radio` and `Switch` are named by their own children. Only the single inputs take the `htmlFor`, so with a group or any other content it matches nothing. Pass `labelProps={{ htmlFor }}` to wire your own `id`, or `labelProps={{ htmlFor: undefined }}` to opt out. Skipped for `grouped`/`hasAddons` fields (multiple controls), and a nested `Field` starts its own scope, so a horizontal Field whose body holds an inner `Field` names the control there only when you wire it. Two controls in one plain labeled Field would both adopt the id, so give each an `id` of its own.",
152
+ "description": "Field label, rendered above the widget. Automatically names the one control the Field holds: a composed `InputBase`, `SelectBase`, `TextAreaBase`, `DateInputBase`, `TimeInputBase` or `DateTimeInputBase` (an `inline` picker has no input, so it takes nothing), or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id that the label's `htmlFor` points at, and a group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`, or a composed `DateRangeInputBase`, `inline` or not) points `aria-labelledby` at the label's own id unless you gave the group an `aria-label` or `aria-labelledby`. A range `Slider` takes the id on its low thumb and also starts each thumb's name with the label through `aria-labelledby`, unless its `ariaLabel` names that thumb or its own `aria-label` or `aria-labelledby` takes the label's place. An `Autocomplete` also names its open suggestion list after the label through `aria-labelledby`. Nothing else takes the label: `Checkbox`, `Radio` and `Switch` are named by their own children, and the label names one only when you wire it as you would any control with an `id` of its own, `labelProps={{ htmlFor }}` plus that control's `id`. Only the single inputs take the `htmlFor`, so once the Field's content has mounted the label keeps it only while one of them holds the id, and drops it over anything else: a group, a `Checkbox`, `Radio` or `Switch`, an `inline` picker, an inner `Field`, an input with an `id` of its own, markup of your own, or nothing at all. A server render, and the first render while hydrating, still write the `htmlFor`, which keeps hydration matching, and an input that mounts later puts it back. The label names an input with an `id` of your own only through `labelProps={{ htmlFor }}` set to that `id`, a `for` it always keeps; `labelProps={{ htmlFor: undefined }}` opts out. Skipped for `grouped`/`hasAddons` fields (multiple controls), and a nested `Field` starts its own scope, so a horizontal Field whose body holds an inner `Field` names the control there only when you wire it. Two controls in one plain labeled Field would both adopt the id, so give each an `id` of its own.",
153
153
  "required": false,
154
154
  "inherited": false,
155
155
  "deprecated": false
@@ -167,7 +167,7 @@
167
167
  "name": "labelProps",
168
168
  "type": "React.LabelHTMLAttributes<HTMLLabelElement> & { [key: string]: unknown; }",
169
169
  "default": null,
170
- "description": "Props for the label element. An explicit `htmlFor` key — even set to `undefined` — takes over the association. An `id` here is the one a group control's `aria-labelledby` points at; otherwise the label gets a generated one while the association is on. To point a group in an inner `Field` at this label by hand, pass that `id` with `htmlFor: undefined`, or the label keeps a generated `htmlFor` that nothing takes.",
170
+ "description": "Props for the label element. An explicit `htmlFor` key — even set to `undefined` — takes over the association. While the association is on, the label renders with the `id` given here, or a generated one, and a group control, a range `Slider`'s thumbs and an `Autocomplete`'s suggestion list point `aria-labelledby` at it. A label you take over gets no generated id, and no group points at it on its own. With an `id` here, though, a range `Slider` or an `Autocomplete` whose `id` your `htmlFor` names still points its thumbs or its suggestion list at it, in a `grouped` or `hasAddons` Field too. To point a group in an inner `Field` at this label by hand, pass that `id`. Nothing in the inner `Field` takes the generated `htmlFor`, so the label drops it after mounting, and adding `htmlFor: undefined` keeps it out of server-rendered markup too.",
171
171
  "required": false,
172
172
  "inherited": false,
173
173
  "deprecated": false
@@ -226,7 +226,7 @@
226
226
  },
227
227
  {
228
228
  "path": "Field.Label",
229
- "summary": "FieldLabel component for rendering a Bulma field label.",
229
+ "summary": "FieldLabel component for rendering a Bulma field label. It renders the label column of a horizontal `Field` (a `div` with the `field-label` class), not a `<label>`, so text placed straight in it names nothing. Put a `<label>` with the `label` class inside it and point its `htmlFor` at the control's `id`, or give the horizontal `Field` a `label` prop, which renders this column and its `<label>` for you. A `<label>` you put here names the control through its `htmlFor` alone: a range `Slider`'s thumbs and an `Autocomplete`'s suggestion list point `aria-labelledby` at a `Field`'s label only when its `label` prop renders it and it names the control. Where it would not name the control on its own, as in an inner `Field`, pass `labelProps={{ htmlFor, id }}` with a matching `id` on the control.",
230
230
  "component": null,
231
231
  "props": [
232
232
  {
@@ -91,7 +91,7 @@
91
91
  "name": "label",
92
92
  "type": "React.ReactNode",
93
93
  "default": null,
94
- "description": "Field label. Automatically associated with the file input via `htmlFor` — uses your `id` when provided, otherwise a generated one. The input then has two labels (this one plus the wrapping `file-label`); assistive tech reads both. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
94
+ "description": "Field label. Automatically associated with the file input via `htmlFor` — uses your `id` when provided, otherwise a generated one. The input then has two labels (this one plus the wrapping `file-label`); assistive tech reads both. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here.",
95
95
  "required": false,
96
96
  "inherited": false,
97
97
  "deprecated": false
@@ -173,7 +173,7 @@
173
173
  "name": "hasName",
174
174
  "type": "boolean",
175
175
  "default": "false",
176
- "description": "Show a file name area. Without `fileName` it shows what the user picked: the file's name, or a count when `multiple` lets them pick several (see `pickedFilesLabel`). Before a pick there is no name area. A reset of the input's form clears the name, but clearing the input from code fires no change event and leaves it showing, so pass `fileName` to control the text then.",
176
+ "description": "Show a file name area. Without `fileName` it shows what the user picked: the file's name, or a count when `multiple` lets them pick several (see `pickedFilesLabel`). Before a pick there is no name area, and the root takes Bulma's `is-empty`. A reset of the input's form clears the name, but clearing the input from code fires no change event and leaves it showing, so pass `fileName` to control the text then.",
177
177
  "required": false,
178
178
  "inherited": false,
179
179
  "deprecated": false
@@ -99,15 +99,15 @@
99
99
  },
100
100
  {
101
101
  "title": "Horizontal — Validation Error",
102
- "code": "<Field horizontal label=\"Email\">\n <Field.Body>\n <Field>\n <Control iconLeftName=\"envelope\" iconRightName=\"exclamation-triangle\">\n <Input type=\"email\" color=\"danger\" value=\"hello@\" onChange={() => {}} />\n </Control>\n <p className=\"help is-danger\">This email is invalid</p>\n </Field>\n </Field.Body>\n</Field>"
102
+ "code": "<Field horizontal label=\"Email\" labelProps={{ htmlFor: 'invalid-email' }}>\n <Field.Body>\n <Field>\n <Control iconLeftName=\"envelope\" iconRightName=\"exclamation-triangle\">\n <Input\n id=\"invalid-email\"\n type=\"email\"\n color=\"danger\"\n value=\"hello@\"\n onChange={() => {}}\n />\n </Control>\n <p className=\"help is-danger\">This email is invalid</p>\n </Field>\n </Field.Body>\n</Field>"
103
103
  },
104
104
  {
105
105
  "title": "Horizontal — Addons (Phone with Country Code)",
106
- "code": "<Field horizontal label=\"Phone\">\n <Field.Body>\n <Field hasAddons>\n <Control>\n <Button isStatic>+44</Button>\n </Control>\n <Control isExpanded>\n <Input type=\"tel\" placeholder=\"Your phone number\" />\n </Control>\n </Field>\n </Field.Body>\n</Field>"
106
+ "code": "<Field horizontal label=\"Phone\" labelProps={{ htmlFor: 'phone-number' }}>\n <Field.Body>\n <Field hasAddons>\n <Control>\n <Button isStatic>+44</Button>\n </Control>\n <Control isExpanded>\n <Input id=\"phone-number\" type=\"tel\" placeholder=\"Your phone number\" />\n </Control>\n </Field>\n </Field.Body>\n</Field>"
107
107
  },
108
108
  {
109
109
  "title": "Horizontal — Submit Row",
110
- "code": "<>\n <Field horizontal label=\"Name\">\n <Field.Body>\n <Field>\n <Control>\n <Input placeholder=\"Your name\" />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n <Field horizontal>\n <Field.Label />\n <Field.Body>\n <Field>\n <Control>\n <Button color=\"primary\">Submit</Button>\n </Control>\n </Field>\n </Field.Body>\n </Field>\n</>"
110
+ "code": "<>\n <Field horizontal label=\"Name\" labelProps={{ htmlFor: 'submit-row-name' }}>\n <Field.Body>\n <Field>\n <Control>\n <Input id=\"submit-row-name\" placeholder=\"Your name\" />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n <Field horizontal>\n <Field.Label />\n <Field.Body>\n <Field>\n <Control>\n <Button color=\"primary\">Submit</Button>\n </Control>\n </Field>\n </Field.Body>\n </Field>\n</>"
111
111
  },
112
112
  {
113
113
  "title": "Disabled Fieldset",
@@ -119,14 +119,14 @@
119
119
  },
120
120
  {
121
121
  "title": "Context-Aware Rendering",
122
- "code": "function example() {\n return (\n <Field horizontal label=\"Username\">\n <Field.Body>\n <Field>\n <Input placeholder=\"Enter username\" />\n </Field>\n </Field.Body>\n </Field>\n );\n}"
122
+ "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Username\"\n labelProps={{ htmlFor: 'username-field' }}\n >\n <Field.Body>\n <Field>\n <Input id=\"username-field\" placeholder=\"Enter username\" />\n </Field>\n </Field.Body>\n </Field>\n );\n}"
123
123
  },
124
124
  {
125
125
  "title": "Context-Aware Rendering",
126
- "code": "function example() {\n return (\n <Field horizontal label=\"Username\">\n <Field.Body>\n <Field>\n <Control iconLeftName=\"user\">\n <Input placeholder=\"Enter username\" />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
126
+ "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Username\"\n labelProps={{ htmlFor: 'username-field-control' }}\n >\n <Field.Body>\n <Field>\n <Control iconLeftName=\"user\">\n <Input id=\"username-field-control\" placeholder=\"Enter username\" />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
127
127
  }
128
128
  ],
129
- "accessibility": "- Always provide a label. The `label` prop is automatically associated with the input (`htmlFor` plus a generated `id`, or your own `id` if you pass one), so clicking the label focuses the input and assistive technology announces it.\n- When composing with `Field` instead, the `Field`'s own `label` associates with the input automatically when the input sits directly in that labeled `Field` — a nested unlabeled `Field` (as in horizontal multi-field layouts) starts its own scope. Pass `labelProps={{ htmlFor }}` and a matching `id` for a stable id or to label across a nested `Field`.\n- Use the correct input `type` for semantics (`text`, `email`, etc.).",
129
+ "accessibility": "- Always provide a label. The `label` prop is automatically associated with the input (`htmlFor` plus a generated `id`, or your own `id` if you pass one), so clicking the label focuses the input and assistive technology announces it.\n- When composing with `Field` instead, the `Field`'s own `label` associates with the input automatically when the input sits directly in that labeled `Field` and has no `id` of its own. A nested unlabeled `Field` (as in horizontal multi-field layouts) starts its own scope. With an `id` of your own, or across a nested `Field`, the label names the input only when you pass that `id` as `labelProps={{ htmlFor }}`.\n- Use the correct input `type` for semantics (`text`, `email`, etc.).",
130
130
  "related": ["Control", "Field"],
131
131
  "storybook": "https://bestax.io/storybook/?path=/story/form-input--default",
132
132
  "summary": "The `Input` component provides a Bulma-styled text input, supporting colors, sizes, rounded corners, static state, hover/focus/loading states, and all Bulma helper props.",
@@ -143,7 +143,7 @@
143
143
  "name": "label",
144
144
  "type": "React.ReactNode",
145
145
  "default": null,
146
- "description": "Field label. Automatically associated with the input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
146
+ "description": "Field label. Automatically associated with the input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here.",
147
147
  "required": false,
148
148
  "inherited": false,
149
149
  "deprecated": false
@@ -89,7 +89,7 @@
89
89
  "name": "hasDelete",
90
90
  "type": "boolean",
91
91
  "default": "false",
92
- "description": "Shows a close (delete) button in the notification. It renders `type=\"button\"`, so it does not submit a form around it.",
92
+ "description": "Shows a close (delete) button in the notification. It renders `type=\"button\"`, so it does not submit a form around it. The notification also takes `has-delete`, which pads its end by `--bulma-notification-delete-padding-inline-end` so the text clears the button. That rule ships in bestax's stylesheets, not Bulma's, so an app styled by Bulma's CSS alone keeps Bulma's padding.",
93
93
  "required": false,
94
94
  "inherited": false,
95
95
  "deprecated": false
@@ -119,6 +119,12 @@
119
119
  }
120
120
  ],
121
121
  "cssVars": [
122
+ {
123
+ "css": "--bulma-notification-delete-padding-inline-end",
124
+ "sass": "$notification-delete-padding-inline-end",
125
+ "default": "calc(1rem + 1.25rem + 0.75rem)",
126
+ "scope": "root"
127
+ },
122
128
  {
123
129
  "css": "--bulma-notification-h",
124
130
  "sass": null,
@@ -71,7 +71,7 @@
71
71
  "name": "label",
72
72
  "type": "React.ReactNode",
73
73
  "default": null,
74
- "description": "Field label. Automatically associated with the number input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`). Not rendered either by a plusminus `bare` Numberinput outside a `Field`.",
74
+ "description": "Field label. Automatically associated with the number input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. Not rendered either by a plusminus `bare` Numberinput outside a `Field`.",
75
75
  "required": false,
76
76
  "inherited": false,
77
77
  "deprecated": false
@@ -55,7 +55,7 @@
55
55
  },
56
56
  {
57
57
  "title": "Horizontal — Select in Narrow Field",
58
- "code": "<Field horizontal label=\"Department\">\n <Field.Body>\n <Field narrow>\n <Control>\n <Select isFullwidth>\n <option>Business development</option>\n <option>Marketing</option>\n <option>Sales</option>\n </Select>\n </Control>\n </Field>\n </Field.Body>\n</Field>"
58
+ "code": "<Field\n horizontal\n label=\"Department\"\n labelProps={{ htmlFor: 'department-field' }}\n>\n <Field.Body>\n <Field narrow>\n <Control>\n <Select id=\"department-field\" isFullwidth>\n <option>Business development</option>\n <option>Marketing</option>\n <option>Sales</option>\n </Select>\n </Control>\n </Field>\n </Field.Body>\n</Field>"
59
59
  },
60
60
  {
61
61
  "title": "Context-Aware Rendering",
@@ -63,14 +63,14 @@
63
63
  },
64
64
  {
65
65
  "title": "Context-Aware Rendering",
66
- "code": "function example() {\n return (\n <Field horizontal label=\"Country\">\n <Field.Body>\n <Field>\n <Select>\n <option value=\"\">Please select</option>\n <option value=\"us\">United States</option>\n <option value=\"uk\">United Kingdom</option>\n <option value=\"ca\">Canada</option>\n </Select>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
66
+ "code": "function example() {\n return (\n <Field horizontal label=\"Country\" labelProps={{ htmlFor: 'country-field' }}>\n <Field.Body>\n <Field>\n <Select id=\"country-field\">\n <option value=\"\">Please select</option>\n <option value=\"us\">United States</option>\n <option value=\"uk\">United Kingdom</option>\n <option value=\"ca\">Canada</option>\n </Select>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
67
67
  },
68
68
  {
69
69
  "title": "Context-Aware Rendering",
70
- "code": "function example() {\n return (\n <Field horizontal label=\"Country\">\n <Field.Body>\n <Field>\n <Control iconLeftName=\"globe\">\n <Select>\n <option value=\"\">Please select</option>\n <option value=\"us\">United States</option>\n <option value=\"uk\">United Kingdom</option>\n <option value=\"ca\">Canada</option>\n </Select>\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
70
+ "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Country\"\n labelProps={{ htmlFor: 'country-field-control' }}\n >\n <Field.Body>\n <Field>\n <Control iconLeftName=\"globe\">\n <Select id=\"country-field-control\">\n <option value=\"\">Please select</option>\n <option value=\"us\">United States</option>\n <option value=\"uk\">United Kingdom</option>\n <option value=\"ca\">Canada</option>\n </Select>\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
71
71
  }
72
72
  ],
73
- "accessibility": "- Always provide a label. Select's `label` prop is automatically associated with the `<select>` (`htmlFor` plus a generated `id`, or your own `id` if you pass one).\n- When composing with `Field` instead, the `Field`'s own `label` associates with the select automatically when the select sits directly in that labeled `Field` — a nested unlabeled `Field` (as in horizontal multi-field layouts) starts its own scope. Pass `labelProps={{ htmlFor }}` and a matching `id` for a stable id or to label across a nested `Field`.\n- Use the `multiple` and `multipleSize` props for multi-select dropdowns.",
73
+ "accessibility": "- Always provide a label. Select's `label` prop is automatically associated with the `<select>` (`htmlFor` plus a generated `id`, or your own `id` if you pass one).\n- When composing with `Field` instead, the `Field`'s own `label` associates with the select automatically when the select sits directly in that labeled `Field` and has no `id` of its own. A nested unlabeled `Field` (as in horizontal multi-field layouts) starts its own scope. With an `id` of your own, or across a nested `Field`, the label names the select only when you pass that `id` as `labelProps={{ htmlFor }}`.\n- Use the `multiple` and `multipleSize` props for multi-select dropdowns.",
74
74
  "related": ["Control", "Field"],
75
75
  "storybook": "https://bestax.io/storybook/?path=/story/form-select--default",
76
76
  "summary": "The `Select` component provides a Bulma-styled dropdown for selecting one or more options.",
@@ -87,7 +87,7 @@
87
87
  "name": "label",
88
88
  "type": "React.ReactNode",
89
89
  "default": null,
90
- "description": "Field label. Automatically associated with the select via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
90
+ "description": "Field label. Automatically associated with the select via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here.",
91
91
  "required": false,
92
92
  "inherited": false,
93
93
  "deprecated": false
@@ -29,6 +29,14 @@
29
29
  "title": "Custom Range",
30
30
  "code": "function example() {\n const [value, setValue] = useState(500);\n return (\n <Block>\n <Slider\n value={value}\n onChange={setValue}\n min={0}\n max={1000}\n step={50}\n showOutput\n color=\"primary\"\n />\n <Paragraph mt=\"4\">Value: ${value}</Paragraph>\n </Block>\n );\n}"
31
31
  },
32
+ {
33
+ "title": "Range Slider",
34
+ "code": "function example() {\n const [range, setRange] = useState<[number, number]>([200, 800]);\n return (\n <Block>\n <Slider\n range\n label=\"Price range\"\n value={range}\n onChange={setRange}\n min={0}\n max={1000}\n step={50}\n color=\"primary\"\n />\n <Paragraph mt=\"4\">\n ${range[0]} to ${range[1]}\n </Paragraph>\n </Block>\n );\n}"
35
+ },
36
+ {
37
+ "title": "Range Slider",
38
+ "code": "<Slider\n range\n label=\"Price range\"\n ariaLabel={['Lowest price', 'Highest price']}\n defaultValue={[200, 800]}\n max={1000}\n/>"
39
+ },
32
40
  {
33
41
  "title": "Custom Output Format",
34
42
  "code": "function example() {\n const [value, setValue] = useState(50);\n return (\n <Block>\n <Slider\n value={value}\n onChange={setValue}\n showOutput\n color=\"success\"\n formatOutput={v => `${v}%`}\n />\n <Paragraph mt=\"4\">Progress: {value}%</Paragraph>\n </Block>\n );\n}"
@@ -50,7 +58,7 @@
50
58
  "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Volume\"\n labelProps={{ htmlFor: 'volume-field-control' }}\n >\n <Field.Body>\n <Field>\n <Control iconLeftName=\"volume-up\">\n <Slider\n id=\"volume-field-control\"\n defaultValue={50}\n color=\"primary\"\n />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
51
59
  }
52
60
  ],
53
- "accessibility": "- Uses native `<input type=\"range\">` element\n- The `label` prop, or the label of a `Field` the slider sits in, names its input. In range mode the label targets the low thumb, but each thumb keeps its own `aria-label` (`ariaLabel`, or \"Minimum value\" and \"Maximum value\"), which wins.\n- Has `aria-valuenow`, `aria-valuemin`, and `aria-valuemax` attributes\n- Fully keyboard accessible with arrow keys\n- Focus states clearly visible",
61
+ "accessibility": "- Uses native `<input type=\"range\">` element\n- The `label` prop, or the label of a `Field` the slider sits in, names its input.\n- In range mode the label starts each thumb's name, so `<Slider range label=\"Price range\" />` announces \"Price range Minimum value\" and \"Price range Maximum value\". Each thumb points `aria-labelledby` at the label and at a hidden span holding its own text, because an `aria-label` would outrank the label. The label's `for` still lands on the low thumb, so clicking the label focuses it.\n- `ariaLabel` wins over the label. In range mode each entry is that thumb's whole name, with no label in front, and an empty entry counts as unset.\n- An `aria-label` or `aria-labelledby` you pass straight to a range Slider names the whole Slider, so it takes the label's place at the start of both thumbs' names: `<Slider range aria-label=\"Budget\" />` announces \"Budget Minimum value\" and \"Budget Maximum value\". An `ariaLabel` entry still wins for its own thumb. To keep a label out of the thumbs' names altogether, pass `aria-labelledby={undefined}`, and they stay \"Minimum value\" and \"Maximum value\".\n- A `Field` label you wire by hand with `labelProps={{ htmlFor }}`, as in a horizontal form, gets no generated id, so give it one of your own there as well, as in `labelProps={{ htmlFor: 'price', id: 'price-label' }}`, and it starts both thumbs' names the same way. Without that `id` it reaches a range Slider only through its `for`, which the thumbs' default `aria-label` outranks, so they stay \"Minimum value\" and \"Maximum value\".\n- Has `aria-valuenow`, `aria-valuemin`, and `aria-valuemax` attributes\n- Fully keyboard accessible with arrow keys\n- Focus states clearly visible",
54
62
  "related": ["Numberinput", "Progress"],
55
63
  "storybook": "https://bestax.io/storybook/?path=/story/form-slider",
56
64
  "summary": "The `Slider` component provides a range slider input for selecting values within a range.",
@@ -112,7 +120,7 @@
112
120
  "name": "ariaLabel",
113
121
  "type": "string | [string, string]",
114
122
  "default": null,
115
- "description": "ARIA label(s) for the slider thumb(s).",
123
+ "description": "ARIA label(s) for the slider thumb(s), which win over a label, the Slider's own or a surrounding `Field`'s. In range mode each entry is that thumb's whole name, and a thumb without one is named \"Minimum value\" or \"Maximum value\", after whatever names the Slider: a label, or in its place an `aria-label` or `aria-labelledby` given to the Slider, as in \"Budget Minimum value\" and \"Budget Maximum value\". An `aria-labelledby` set to `undefined` keeps every label out of both names.",
116
124
  "required": false,
117
125
  "inherited": true,
118
126
  "deprecated": false
@@ -139,7 +147,7 @@
139
147
  "name": "label",
140
148
  "type": "React.ReactNode",
141
149
  "default": null,
142
- "description": "Field label. Automatically associated with the slider input via `htmlFor` — uses your `id` when provided, otherwise a generated one. In range mode the label targets the low (minimum) thumb. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
150
+ "description": "Field label. Automatically associated with the slider input via `htmlFor` — uses your `id` when provided, otherwise a generated one. In range mode the `htmlFor` targets the low (minimum) thumb, and the label also starts each thumb's name through `aria-labelledby`, as in \"Price Minimum value\" and \"Price Maximum value\", unless an `aria-label` or `aria-labelledby` on the Slider takes its place there. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here, naming a range Slider's thumbs the same way. A `Field` label you wire by hand to the low thumb with `labelProps.htmlFor` names the thumbs too when you also give it an `id` there, since the `Field` generates none for it.",
143
151
  "required": false,
144
152
  "inherited": true,
145
153
  "deprecated": false
@@ -148,7 +156,7 @@
148
156
  "name": "labelProps",
149
157
  "type": "React.LabelHTMLAttributes<HTMLLabelElement> & { [key: string]: unknown; }",
150
158
  "default": null,
151
- "description": "Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then).",
159
+ "description": "Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). In range mode an `id` here is the one the thumbs' `aria-labelledby` points at, in place of a generated one.",
152
160
  "required": false,
153
161
  "inherited": true,
154
162
  "deprecated": false
@@ -75,7 +75,7 @@
75
75
  "name": "label",
76
76
  "type": "React.ReactNode",
77
77
  "default": null,
78
- "description": "Field label. Automatically associated with the text input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Not wired when the tag limit is reached (the input is not rendered). Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`); it then replaces the `aria-label=\"Add tag\"` fallback too.",
78
+ "description": "Field label. Automatically associated with the text input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Not wired when the tag limit is reached (the input is not rendered). Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here; it then replaces the `aria-label=\"Add tag\"` fallback too.",
79
79
  "required": false,
80
80
  "inherited": false,
81
81
  "deprecated": false
@@ -47,14 +47,14 @@
47
47
  },
48
48
  {
49
49
  "title": "Context-Aware Rendering",
50
- "code": "function example() {\n return (\n <Field horizontal label=\"Message\">\n <Field.Body>\n <Field>\n <TextArea placeholder=\"Enter your message\" />\n </Field>\n </Field.Body>\n </Field>\n );\n}"
50
+ "code": "function example() {\n return (\n <Field horizontal label=\"Message\" labelProps={{ htmlFor: 'message-field' }}>\n <Field.Body>\n <Field>\n <TextArea id=\"message-field\" placeholder=\"Enter your message\" />\n </Field>\n </Field.Body>\n </Field>\n );\n}"
51
51
  },
52
52
  {
53
53
  "title": "Context-Aware Rendering",
54
- "code": "function example() {\n return (\n <Field horizontal label=\"Message\">\n <Field.Body>\n <Field>\n <Control iconLeftName=\"comment\">\n <TextArea placeholder=\"Enter your message\" />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
54
+ "code": "function example() {\n return (\n <Field\n horizontal\n label=\"Message\"\n labelProps={{ htmlFor: 'message-field-control' }}\n >\n <Field.Body>\n <Field>\n <Control iconLeftName=\"comment\">\n <TextArea\n id=\"message-field-control\"\n placeholder=\"Enter your message\"\n />\n </Control>\n </Field>\n </Field.Body>\n </Field>\n );\n}"
55
55
  }
56
56
  ],
57
- "accessibility": "- Always provide a label. TextArea's `label` prop is automatically associated with the `<textarea>` (`htmlFor` plus a generated `id`, or your own `id` if you pass one).\n- When composing with `Field` instead, the `Field`'s own `label` associates with the textarea automatically when the textarea sits directly in that labeled `Field` — a nested unlabeled `Field` (as in horizontal multi-field layouts) starts its own scope. Pass `labelProps={{ htmlFor }}` and a matching `id` for a stable id or to label across a nested `Field`.\n- Use the `rows` prop to set an appropriate height for your content.",
57
+ "accessibility": "- Always provide a label. TextArea's `label` prop is automatically associated with the `<textarea>` (`htmlFor` plus a generated `id`, or your own `id` if you pass one).\n- When composing with `Field` instead, the `Field`'s own `label` associates with the textarea automatically when the textarea sits directly in that labeled `Field` and has no `id` of its own. A nested unlabeled `Field` (as in horizontal multi-field layouts) starts its own scope. With an `id` of your own, or across a nested `Field`, the label names the textarea only when you pass that `id` as `labelProps={{ htmlFor }}`.\n- Use the `rows` prop to set an appropriate height for your content.",
58
58
  "related": ["Control", "Field"],
59
59
  "storybook": "https://bestax.io/storybook/?path=/story/form-textarea--default",
60
60
  "summary": "The `TextArea` component provides a Bulma-styled multi-line text input, supporting color, size, hover/focus/loading states, fixed size, and all Bulma helper props.",
@@ -71,7 +71,7 @@
71
71
  "name": "label",
72
72
  "type": "React.ReactNode",
73
73
  "default": null,
74
- "description": "Field label. Automatically associated with the textarea via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`).",
74
+ "description": "Field label. Automatically associated with the textarea via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here.",
75
75
  "required": false,
76
76
  "inherited": false,
77
77
  "deprecated": false