bitboss-ui 3.0.0-beta.58 → 3.0.0-beta.60

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 (138) hide show
  1. package/bin/bitboss-ui-mcp.mjs +5 -5
  2. package/dist/ai/BbBadgeButton.md +3 -3
  3. package/dist/ai/BbBaseButton.md +3 -3
  4. package/dist/ai/BbCheckbox.md +6 -6
  5. package/dist/ai/BbCheckboxGroup.md +6 -6
  6. package/dist/ai/BbColorInput.md +8 -8
  7. package/dist/ai/BbDatePickerInput.md +8 -8
  8. package/dist/ai/BbDialog.md +26 -7
  9. package/dist/ai/BbDropzone.md +5 -5
  10. package/dist/ai/BbForm.md +4 -4
  11. package/dist/ai/BbNumberInput.md +8 -8
  12. package/dist/ai/BbOffCanvas.md +10 -6
  13. package/dist/ai/BbRadio.md +4 -4
  14. package/dist/ai/BbRadioGroup.md +6 -6
  15. package/dist/ai/BbRating.md +7 -7
  16. package/dist/ai/BbSelect.md +106 -24
  17. package/dist/ai/BbSelectPopover.md +70 -24
  18. package/dist/ai/BbSlider.md +6 -6
  19. package/dist/ai/BbSwitch.md +6 -6
  20. package/dist/ai/BbSwitchGroup.md +6 -6
  21. package/dist/ai/BbTable.md +34 -30
  22. package/dist/ai/BbTag.md +8 -8
  23. package/dist/ai/BbTextInput.md +8 -8
  24. package/dist/ai/BbTextarea.md +8 -8
  25. package/dist/ai/BbTimePickerInput.md +6 -6
  26. package/dist/ai/BbTree.md +1 -1
  27. package/dist/ai/CommonField.md +5 -5
  28. package/dist/ai/CommonFieldInput.md +1 -1
  29. package/dist/ai/FlatListBox.md +1 -0
  30. package/dist/ai/GroupedListBox.md +1 -0
  31. package/dist/ai/ListBox.md +1 -0
  32. package/dist/ai/changelog.json +51 -4
  33. package/dist/ai/components.json +33 -32
  34. package/dist/ai/guides/agent-contract.md +3 -1
  35. package/dist/ai/guides/coherence-playbook.md +3 -2
  36. package/dist/ai/guides/fetch-items-playbook.md +3 -2
  37. package/dist/ai/guides/migration/components/bb-select.md +1 -1
  38. package/dist/ai/guides/migration/v2-to-v3.md +9 -1
  39. package/dist/ai/helpers/inertia/manifest.json +1 -1
  40. package/dist/ai/manifest/common.json +8 -8
  41. package/dist/ai/manifest/components/BbBadgeButton.json +3 -3
  42. package/dist/ai/manifest/components/BbBaseButton.json +3 -3
  43. package/dist/ai/manifest/components/BbCheckbox.json +2 -2
  44. package/dist/ai/manifest/components/BbColorInput.json +2 -2
  45. package/dist/ai/manifest/components/BbDialog.json +6 -6
  46. package/dist/ai/manifest/components/BbDropzone.json +2 -2
  47. package/dist/ai/manifest/components/BbForm.json +4 -4
  48. package/dist/ai/manifest/components/BbOffCanvas.json +5 -5
  49. package/dist/ai/manifest/components/BbRadio.json +1 -1
  50. package/dist/ai/manifest/components/BbRating.json +1 -1
  51. package/dist/ai/manifest/components/BbSelect.json +7 -5
  52. package/dist/ai/manifest/components/BbSelectPopover.json +8 -6
  53. package/dist/ai/manifest/components/BbSelectPopover.tree.json +4 -0
  54. package/dist/ai/manifest/components/BbSwitch.json +1 -1
  55. package/dist/ai/manifest/components/BbTable.json +30 -30
  56. package/dist/ai/manifest/components/BbTree.json +1 -1
  57. package/dist/ai/manifest/components/CommonField.json +5 -5
  58. package/dist/ai/manifest/components/CommonFieldInput.json +1 -1
  59. package/dist/ai/manifest/components/FlatListBox.json +1 -0
  60. package/dist/ai/manifest/components/GroupedListBox.json +1 -0
  61. package/dist/ai/manifest/components/ListBox.json +1 -0
  62. package/dist/ai/manifest/index.json +2 -2
  63. package/dist/ai/manifest/meta.json +1 -0
  64. package/dist/ai/manifest/types.api.json +1 -0
  65. package/dist/ai/source/BbBaseButton.md +9 -11
  66. package/dist/ai/source/BbButton.md +4 -3
  67. package/dist/ai/source/BbCheckbox.md +12 -12
  68. package/dist/ai/source/BbCheckboxGroup.md +12 -12
  69. package/dist/ai/source/BbColorInput.md +20 -21
  70. package/dist/ai/source/BbDatePickerInput.md +20 -21
  71. package/dist/ai/source/BbDialog.md +24 -24
  72. package/dist/ai/source/BbDropzone.md +11 -12
  73. package/dist/ai/source/BbForm.md +14 -14
  74. package/dist/ai/source/BbNumberInput.md +20 -21
  75. package/dist/ai/source/BbOffCanvas.md +18 -18
  76. package/dist/ai/source/BbRadio.md +12 -12
  77. package/dist/ai/source/BbRadioGroup.md +12 -12
  78. package/dist/ai/source/BbRating.md +16 -16
  79. package/dist/ai/source/BbSelect.md +344 -314
  80. package/dist/ai/source/BbSelectPopover.md +1068 -59
  81. package/dist/ai/source/BbSlider.md +12 -12
  82. package/dist/ai/source/BbTable.md +66 -78
  83. package/dist/ai/source/BbTag.md +20 -21
  84. package/dist/ai/source/BbTextInput.md +20 -21
  85. package/dist/ai/source/BbTextarea.md +20 -21
  86. package/dist/ai/source/BbTimePickerInput.md +14 -15
  87. package/dist/ai/source/BbTree.md +4 -5
  88. package/dist/ai/source/CommonField.md +18 -18
  89. package/dist/ai/source/CommonFieldInput.md +4 -4
  90. package/dist/ai/source/FlatListBox.md +37 -0
  91. package/dist/ai/source/GroupedListBox.md +44 -0
  92. package/dist/ai/source/ListBox.md +14 -0
  93. package/dist/components/BbBaseButton/types.d.ts +9 -11
  94. package/dist/components/BbCheckbox/types.d.ts +12 -12
  95. package/dist/components/BbCheckboxGroup/types.d.ts +12 -12
  96. package/dist/components/BbColorInput/types.d.ts +20 -21
  97. package/dist/components/BbDatePickerInput/types.d.ts +20 -21
  98. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +1 -1
  99. package/dist/components/BbDialog/types.d.ts +23 -23
  100. package/dist/components/BbDropzone/types.d.ts +11 -12
  101. package/dist/components/BbForm/BbForm.vue.d.ts +14 -14
  102. package/dist/components/BbNumberInput/types.d.ts +20 -21
  103. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +1 -1
  104. package/dist/components/BbOffCanvas/types.d.ts +17 -17
  105. package/dist/components/BbRadio/types.d.ts +12 -12
  106. package/dist/components/BbRadioGroup/types.d.ts +12 -12
  107. package/dist/components/BbRating/types.d.ts +16 -16
  108. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +297 -295
  109. package/dist/components/BbSelect/types.d.ts +40 -32
  110. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +809 -490
  111. package/dist/components/BbSelectPopover/knownItems.d.ts +60 -0
  112. package/dist/components/BbSelectPopover/knownItems.js +26 -0
  113. package/dist/components/BbSelectPopover/types.d.ts +29 -18
  114. package/dist/components/BbSlider/types.d.ts +12 -12
  115. package/dist/components/BbTable/types.d.ts +66 -78
  116. package/dist/components/BbTag/types.d.ts +20 -21
  117. package/dist/components/BbTextInput/types.d.ts +20 -21
  118. package/dist/components/BbTextarea/types.d.ts +20 -21
  119. package/dist/components/BbTimePickerInput/types.d.ts +14 -15
  120. package/dist/components/BbTree/types.d.ts +4 -5
  121. package/dist/components/CommonField/types.d.ts +18 -18
  122. package/dist/components/CommonFieldInput/types.d.ts +4 -4
  123. package/dist/components/FlatListBox/FlatListBox.vue.d.ts +2 -0
  124. package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +134 -120
  125. package/dist/components/FlatListBox/types.d.ts +6 -0
  126. package/dist/components/GroupedListBox/GroupedListBox.vue.d.ts +2 -0
  127. package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +51 -34
  128. package/dist/components/GroupedListBox/types.d.ts +6 -0
  129. package/dist/components/ListBox/ListBox.vue.d.ts +2 -0
  130. package/dist/components/ListBox/ListBox.vue_vue_type_script_setup_true_lang.js +8 -1
  131. package/dist/components/ListBox/types.d.ts +10 -0
  132. package/dist/composables/useFormBinding.d.ts +7 -9
  133. package/dist/index.d.ts +1 -1
  134. package/dist/llms-full.txt +390 -220
  135. package/dist/llms-medium.txt +3 -1
  136. package/dist/styles.css +2 -2
  137. package/dist/utils/versionCheck.js +1 -1
  138. package/package.json +1 -1
@@ -2950,13 +2950,13 @@ const platformSchema = z.enum(RECIPE_PLATFORMS);
2950
2950
  * way to know which tool answers which question, and read whole guides.
2951
2951
  */
2952
2952
  const SERVER_INSTRUCTIONS = [
2953
- 'bitboss-ui: a Vue 3 component library. Answer from these tools, never from memory — agents that guess invent props.',
2953
+ 'bitboss-ui: a Vue 3 component library. Answer from these tools, never from memory: agents that guess invent props.',
2954
2954
  "- Tailwind v4 app: set cssLayers: TAILWIND_V4_LAYERS ('bitboss-ui/vite') at setup, or utilities lose.",
2955
- '- A topic or "how do I…" question (dark mode, cascade layers, SSR, a plugin option, a CLI command): search_docs, then open the section it points to.',
2956
- '- Which component: search_components (empty query = the whole catalog). One component: get_component({ name }), one line per member; members: [names] for whole rows, sections for prose.',
2957
- '- A type in a props table (BbTableColumn, ButtonVariantType): get_component({ name }) returns its definition and values.',
2955
+ '- A topic or "how do I…" (dark mode, cascade layers, SSR, a plugin option, a CLI command): search_docs, then open the section it names.',
2956
+ '- Which component: search_components (empty query = whole catalog). One component: get_component({ name }), one line per member; members: [names] for whole rows, sections for prose.',
2957
+ '- A type in a props table (BbTableColumn, ButtonVariantType): get_component({ name }) gives its definition and values.',
2958
2958
  '- After writing markup: validate. Before custom CSS: list_tokens.',
2959
- '- An old name (v2 or earlier-beta prop, slot, item field, pt key, class) that stopped working: search_docs(the old name). What a bump breaks: list_changes({ since: <your version> }), one line per change.',
2959
+ '- An old name (v2 or earlier-beta prop, slot, item field, pt key, class) that stopped working: search_docs(old name). What a bump breaks: list_changes({ since: <your version> }), a line per change.',
2960
2960
  "- pt in <script> (a const, a wrapper's prop): type it <Name>Props['pt']; Pt* types are not exported.",
2961
2961
  '- Composables: get_composable. Whole pages: list_recipes, get_recipe (prose + files). Long docs answer with an outline: pass sections.',
2962
2962
  ].join('\n');
@@ -20,11 +20,11 @@
20
20
  | `cacheTags` | `string \| string[] \| undefined` | | | Inertia: tags to file this visit's prefetch cache under, so a later request can invalidate the whole tagged group. |
21
21
  | `component` | `string \| undefined` | | | Inertia: the page component this visit resolves to. Rarely set by hand — the server normally decides it. |
22
22
  | `data` | `object \| undefined` | | | Request payload forwarded to Inertia when navigating via `href` in an Inertia-enabled app. Ignored when not using Inertia. |
23
- | `disabled` | `boolean \| undefined` | `false` | | Disables user interaction. - When rendering as a native button, sets the `disabled` attribute. - When rendering as a link (anchor/Inertia), removes `href`, adds `aria-disabled="true"` and `tabindex="-1"`, and prevents navigation: the link stays announced as a link but leaves the tab order. |
23
+ | `disabled` | `boolean \| undefined` | `false` | | Disables user interaction. A native button gets the `disabled` attribute; a link (anchor/Inertia) loses `href`, gets `aria-disabled="true"` and `tabindex="-1"`, and never navigates: still announced as a link, but out of the tab order. |
24
24
  | `download` | `string \| boolean \| undefined` | | | Marks an `href` link as a download: a plain `<a download>` with a native navigation (never an Inertia or router visit), so `blob:` and `data:` files work too. A string sets the suggested filename. |
25
25
  | `exactActiveClass` | `string \| undefined` | `'router-link-exact-active'` | | CSS class applied when the component renders as a link and the target of the link and the url matches exactly. Ported for Inertia compatibility. |
26
26
  | `except` | `string[] \| undefined` | | | Inertia: the inverse of `only` — properties to EXCLUDE from a partial reload. Pass one or the other, not both. |
27
- | `external` | `boolean \| undefined` | `false` | | Forces an `href` link to render as a plain `<a>` (native navigation), bypassing Inertia/router interception — the same intent as Nuxt's `NuxtLink` `external`. Use for links outside the SPA. One of the native-anchor signals alongside `target` and `download`. |
27
+ | `external` | `boolean \| undefined` | `false` | | Forces an `href` link to render as a plain `<a>` (native navigation), bypassing Inertia/router interception, as Nuxt's `NuxtLink` `external` does. For links outside the SPA; a native-anchor signal alongside `target` and `download`. |
28
28
  | `headers` | `object \| undefined` | | | Additional HTTP headers forwarded to Inertia when navigating via `href` in an Inertia-enabled app. |
29
29
  | `href` | `string \| undefined` | | | Hyperlink reference used when rendering as an anchor (or as an Inertia link in Inertia-enabled apps). If provided and not disabled, the component renders as an anchor/Inertia link. |
30
30
  | `instant` | `boolean \| undefined` | `false` | | Inertia: navigate optimistically on click and reconcile when the response lands, instead of waiting for the round trip. |
@@ -48,7 +48,7 @@
48
48
  | `queryStringArrayFormat` | `"brackets" \| "indices" \| undefined` | `'brackets'` | | Format to use when serializing array values into the query string for Inertia requests. |
49
49
  | `rel` | `string \| undefined` | | | Relationship between the current document and the linked resource. Useful for security when opening new tabs (e.g. `noopener noreferrer`). |
50
50
  | `replace` | `boolean \| undefined` | `false` | | Uses history replacement instead of push navigation. - With Vue Router (`to`), calls `router.replace`. - With Inertia (`href`), performs a replace visit. |
51
- | `tag` | `'button'` \| `'div'` \| `'span'` \| `'label'` | `'button'` | | Element for the plain (non-link) button: `'button'` (default), `'div'` / `'span'` (a clickable box inside another button or link) or `'label'` (a file-upload trigger). Ignored with `href` / `to`. Off `button`, native `type` / `disabled` drop (disabled stays a class). |
51
+ | `tag` | `'button'` \| `'div'` \| `'span'` \| `'label'` | `'button'` | | Element of the plain (non-link) button: `'button'` (default), `'div'` / `'span'` (a clickable box inside a button or link) or `'label'` (a file-upload trigger). Ignored with `href` / `to`. Off `button`, native `type` / `disabled` drop (disabled stays a class). |
52
52
  | `target` | `string \| undefined` | | | Target browsing context for anchor/Inertia links (e.g. `_self`, `_blank`). Ignored when rendering as a native button. |
53
53
  | `to` | `string \| wt \| bt \| undefined` | | | Route location to navigate to. When provided (and not disabled), the component renders as a Vue Router link. |
54
54
  | `type` | `"button" \| "submit" \| "reset" \| undefined` | `'button'` | | Native `type` attribute used when rendering as a button (e.g. `button`, `submit`, `reset`). |
@@ -547,11 +547,11 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
547
547
  | `cacheTags` | `string \| string[] \| undefined` | | | Inertia: tags to file this visit's prefetch cache under, so a later request can invalidate the whole tagged group. |
548
548
  | `component` | `string \| undefined` | | | Inertia: the page component this visit resolves to. Rarely set by hand — the server normally decides it. |
549
549
  | `data` | `object \| undefined` | | | Request payload forwarded to Inertia when navigating via `href` in an Inertia-enabled app. Ignored when not using Inertia. |
550
- | `disabled` | `boolean \| undefined` | `false` | | Disables user interaction. - When rendering as a native button, sets the `disabled` attribute. - When rendering as a link (anchor/Inertia), removes `href`, adds `aria-disabled="true"` and `tabindex="-1"`, and prevents navigation: the link stays announced as a link but leaves the tab order. |
550
+ | `disabled` | `boolean \| undefined` | `false` | | Disables user interaction. A native button gets the `disabled` attribute; a link (anchor/Inertia) loses `href`, gets `aria-disabled="true"` and `tabindex="-1"`, and never navigates: still announced as a link, but out of the tab order. |
551
551
  | `download` | `string \| boolean \| undefined` | | | Marks an `href` link as a download: a plain `<a download>` with a native navigation (never an Inertia or router visit), so `blob:` and `data:` files work too. A string sets the suggested filename. |
552
552
  | `exactActiveClass` | `string \| undefined` | `'router-link-exact-active'` | | CSS class applied when the component renders as a link and the target of the link and the url matches exactly. Ported for Inertia compatibility. |
553
553
  | `except` | `string[] \| undefined` | | | Inertia: the inverse of `only` — properties to EXCLUDE from a partial reload. Pass one or the other, not both. |
554
- | `external` | `boolean \| undefined` | `false` | | Forces an `href` link to render as a plain `<a>` (native navigation), bypassing Inertia/router interception — the same intent as Nuxt's `NuxtLink` `external`. Use for links outside the SPA. One of the native-anchor signals alongside `target` and `download`. |
554
+ | `external` | `boolean \| undefined` | `false` | | Forces an `href` link to render as a plain `<a>` (native navigation), bypassing Inertia/router interception, as Nuxt's `NuxtLink` `external` does. For links outside the SPA; a native-anchor signal alongside `target` and `download`. |
555
555
  | `headers` | `object \| undefined` | | | Additional HTTP headers forwarded to Inertia when navigating via `href` in an Inertia-enabled app. |
556
556
  | `href` | `string \| undefined` | | | Hyperlink reference used when rendering as an anchor (or as an Inertia link in Inertia-enabled apps). If provided and not disabled, the component renders as an anchor/Inertia link. |
557
557
  | `instant` | `boolean \| undefined` | `false` | | Inertia: navigate optimistically on click and reconcile when the response lands, instead of waiting for the round trip. |
@@ -575,7 +575,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
575
575
  | `queryStringArrayFormat` | `"brackets" \| "indices" \| undefined` | `'brackets'` | | Format to use when serializing array values into the query string for Inertia requests. |
576
576
  | `rel` | `string \| undefined` | | | Relationship between the current document and the linked resource. Useful for security when opening new tabs (e.g. `noopener noreferrer`). |
577
577
  | `replace` | `boolean \| undefined` | `false` | | Uses history replacement instead of push navigation. - With Vue Router (`to`), calls `router.replace`. - With Inertia (`href`), performs a replace visit. |
578
- | `tag` | `'button'` \| `'div'` \| `'span'` \| `'label'` | `'button'` | | Element for the plain (non-link) button: `'button'` (default), `'div'` / `'span'` (a clickable box inside another button or link) or `'label'` (a file-upload trigger). Ignored with `href` / `to`. Off `button`, native `type` / `disabled` drop (disabled stays a class). |
578
+ | `tag` | `'button'` \| `'div'` \| `'span'` \| `'label'` | `'button'` | | Element of the plain (non-link) button: `'button'` (default), `'div'` / `'span'` (a clickable box inside a button or link) or `'label'` (a file-upload trigger). Ignored with `href` / `to`. Off `button`, native `type` / `disabled` drop (disabled stays a class). |
579
579
  | `target` | `string \| undefined` | | | Target browsing context for anchor/Inertia links (e.g. `_self`, `_blank`). Ignored when rendering as a native button. |
580
580
  | `text` | `string \| undefined` | | | Fallback text content rendered when no default slot is provided. |
581
581
  | `to` | `string \| wt \| bt \| undefined` | | | Route location to navigate to. When provided (and not disabled), the component renders as a Vue Router link. |
@@ -712,9 +712,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
712
712
  | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
713
713
  | `checked` | `boolean \| undefined` | `undefined` | | Defines the input as checked. |
714
714
  | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-label-spacing-y` for `--bb-label-spacing-y-compact`, so tune a compact field's label gap with the `-compact` token, not the base one. The same meaning as on the checkbox, radio and switch groups. |
715
- | `description` | `string \| undefined` | | | Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via `aria-describedby` (after any `errors` / `warnings`, before the `hint`). |
715
+ | `description` | `string \| undefined` | | | Text between the label and the input. Unlike the hint it is always visible; it joins the input's `aria-describedby` after any `errors` / `warnings`, before the `hint`. |
716
716
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
717
- | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
717
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or array, in an `aria-live="polite"` region and first in the control's `aria-describedby`, so they are re-read when it regains focus. |
718
718
  | `falseValue` | `any` | | | Value of the input when unchecked. It handles any kind of serializable object. |
719
719
  | `formless` | `boolean \| undefined` | `false` | | Keep this control out of the enclosing `BbForm` entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch). |
720
720
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
@@ -728,7 +728,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
728
728
  | `label` | `string` | | yes | Text content of the label of the element. |
729
729
  | `labelAlign` | `FieldCrossAlign \| undefined` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
730
730
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
731
- | `layout` | `Responsive<FieldLayout> \| undefined` | `"auto"` | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map such as `{ default: 'vertical', md: 'xx xxxxx' }`. |
731
+ | `layout` | `Responsive<FieldLayout> \| undefined` | `"auto"` | | How label and input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map (`{ default: 'vertical', md: 'xx xxxxx' }`). |
732
732
  | `modelValue` | `any` | | | Used by v-model. Can be any serializable type. |
733
733
  | `name` | `string \| undefined` | | | Defines the name of the input. |
734
734
  | `persistentHint` | `boolean \| undefined` | `false` | | Keeps the hint displayed. |
@@ -738,9 +738,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
738
738
  | `rules` | `RuleExpression<any>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
739
739
  | `submitWhenFalse` | `boolean \| undefined` | `false` | | Will submit "falseValue" if the input is not checked. Otherwise "trueValue" will be submitted. |
740
740
  | `trueValue` | `any` | | | Value of the input when checked. It handles any kind of serializable object. |
741
- | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
742
- | `validationMode` | `ValidationMode \| undefined` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
743
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
741
+ | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; never the `name`. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). `BbForm` only. |
742
+ | `validationMode` | `ValidationMode \| undefined` | | | When the field validates: `aggressive` (each change), `balanced` (on leave, then live while in error), `lazy` (on leave), `submit-only`, `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). `BbForm` only. |
743
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or array: amber, in their own `aria-live` region and in the control's `aria-describedby` after the errors. Non-empty turns on the warning state; errors win when both are set. |
744
744
 
745
745
  ## Passthrough parts and states
746
746
 
@@ -987,11 +987,11 @@ for a preset that fits any row type (never `<any>`), not an imported
987
987
  | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-label-spacing-y` for `--bb-label-spacing-y-compact`, so tune a compact group's label gap with the `-compact` token, not the base one. |
988
988
  | `dependencies` | `unknown[] \| undefined` | | | Defines an array of dependencies that will trigger actions in the component upon change. |
989
989
  | `depsDebounceTime` | `number \| undefined` | | | Timeout used to debounce response to changes to dependencies. |
990
- | `description` | `string \| undefined` | | | Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via `aria-describedby` (after any `errors` / `warnings`, before the `hint`). |
990
+ | `description` | `string \| undefined` | | | Text between the label and the input. Unlike the hint it is always visible; it joins the input's `aria-describedby` after any `errors` / `warnings`, before the `hint`. |
991
991
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
992
992
  | `emptyText` | `string \| undefined` | | | String displayed when there are no items to display. |
993
993
  | `enforceCoherence` | `boolean \| undefined` | `false` | | After every applied, successful load (an empty one included), drops the model values the options no longer contain (a single value resets to `null`). A failed load never prunes. |
994
- | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
994
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or array, in an `aria-live="polite"` region and first in the control's `aria-describedby`, so they are re-read when it regains focus. |
995
995
  | `failedText` | `string \| undefined` | `the localized `common.failedText` ("Couldn't load items")` | | String displayed in the empty state while the latest load FAILED (the `items` provider threw): the twin of `emptyText` for that case. |
996
996
  | `formless` | `boolean \| undefined` | `false` | | Keep this control out of the enclosing `BbForm` entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch). |
997
997
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
@@ -1011,7 +1011,7 @@ for a preset that fits any row type (never `<any>`), not an imported
1011
1011
  | `itemText` | `ItemAccessor<T, string> \| undefined` | `own `label`, else `text`, else `JSON.stringify(item)`` | | Defines a path that returns a property of the object to use as text or a function that returns a string. Unset: own `label`, else `text` (`{ label, value }` needs no accessor). |
1012
1012
  | `itemValue` | `ItemAccessor<T> \| undefined` | `own `value`, else the whole item` | | Defines a path that returns a property of the object to use as value or a function that returns any value. Unset: own `value`, even `null`. |
1013
1013
  | `labelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
1014
- | `layout` | `Responsive<FieldLayout> \| undefined` | | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map such as `{ default: 'vertical', md: 'xx xxxxx' }`. |
1014
+ | `layout` | `Responsive<FieldLayout> \| undefined` | | | How label and input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map (`{ default: 'vertical', md: 'xx xxxxx' }`). |
1015
1015
  | `legend` | `string` | | yes | Text content of the legend. |
1016
1016
  | `legendMode` | `"outside" \| "inside" \| undefined` | | | Legend rendering mode. `'outside'` renders the legend above the fieldset in the normal flow; `'inside'` overlays the legend inside the fieldset border. Floating mode is not supported for option groups (checkbox, radio or switch) — there is no single field for the legend to float against. |
1017
1017
  | `legendPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
@@ -1027,9 +1027,9 @@ for a preset that fits any row type (never `<any>`), not an imported
1027
1027
  | `reverse` | `boolean \| undefined` | `false` | | Reverses the layout. Applicable in every direction the order of the label and the input is swapped. |
1028
1028
  | `rules` | `RuleExpression<any>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
1029
1029
  | `selectable` | `boolean \| ((item: T) => boolean) \| undefined` | `true` | | Defines whether options are selectable. Can be a global boolean that affects all options or a function that accepts an item and returns a boolean that only affects that item. Non-selectable options are rendered disabled. |
1030
- | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
1031
- | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
1032
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
1030
+ | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; never the `name`. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). `BbForm` only. |
1031
+ | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When the field validates: `aggressive` (each change), `balanced` (on leave, then live while in error), `lazy` (on leave), `submit-only`, `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). `BbForm` only. |
1032
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or array: amber, in their own `aria-live` region and in the control's `aria-describedby` after the errors. Non-empty turns on the warning state; errors win when both are set. |
1033
1033
 
1034
1034
  ## Passthrough parts and states
1035
1035
 
@@ -689,10 +689,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
689
689
  | `autocomplete` | `string \| undefined` | `"off"` | | Guides the browser as to the type of information expected in the field. |
690
690
  | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
691
691
  | `clearable` | `boolean \| undefined` | `false` | | Displays a clear button when the input has a value and is being interacted with. |
692
- | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-input-h`, `--bb-input-py` and `--bb-label-spacing-y` for their `-compact` twins on the field, so a `--bb-input-h` you set on the component is ignored while `compact` is on: size a compact field with `--bb-input-h-compact` (and `--bb-input-py-compact`) instead. |
693
- | `description` | `string \| undefined` | | | Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via `aria-describedby` (after any `errors` / `warnings`, before the `hint`). |
692
+ | `compact` | `boolean \| undefined` | `false` | | Compact density: the field uses the `-compact` twins of `--bb-input-h`, `--bb-input-py` and `--bb-label-spacing-y`, so a `--bb-input-h` set on the component is ignored while it is on. Size a compact field with `--bb-input-h-compact` (and `--bb-input-py-compact`). |
693
+ | `description` | `string \| undefined` | | | Text between the label and the input. Unlike the hint it is always visible; it joins the input's `aria-describedby` after any `errors` / `warnings`, before the `hint`. |
694
694
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
695
- | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
695
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or array, in an `aria-live="polite"` region and first in the control's `aria-describedby`, so they are re-read when it regains focus. |
696
696
  | `eyeDropper` | `boolean \| undefined` | `false` | | Show an eyedropper button to sample any color on screen. Uses the native EyeDropper API — hidden automatically on unsupported browsers. |
697
697
  | `formless` | `boolean \| undefined` | `false` | | Keep this control out of the enclosing `BbForm` entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch). |
698
698
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
@@ -705,7 +705,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
705
705
  | `labelAlign` | `FieldCrossAlign \| undefined` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
706
706
  | `labelMode` | `"outside" \| "floating" \| "inside" \| undefined` | | | Label rendering mode: `outside` places the label above the input, `floating` overlays it on the field and shrinks it when a value is set, `inside` keeps it inside the field. |
707
707
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
708
- | `layout` | `Responsive<FieldLayout> \| undefined` | | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map such as `{ default: 'vertical', md: 'xx xxxxx' }`. |
708
+ | `layout` | `Responsive<FieldLayout> \| undefined` | | | How label and input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map (`{ default: 'vertical', md: 'xx xxxxx' }`). |
709
709
  | `loading` | `boolean \| undefined` | `false` | | Sets the component in a loading state, usually triggering some visual styles. |
710
710
  | `modelValue` | `string \| null \| undefined` | `null` | | Used by v-model. |
711
711
  | `name` | `string \| undefined` | | | Defines the name of the input. |
@@ -718,10 +718,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
718
718
  | `reverse` | `boolean \| undefined` | `false` | | Reverses the layout. Applicable in every direction the order of the label and the input is swapped. |
719
719
  | `rules` | `RuleExpression<string \| null>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
720
720
  | `swatches` | `boolean \| string[][] \| undefined` | | | Controls swatches display in the picker: - `true` — show the built-in Material-palette swatches - `string[][]` — show custom swatches (each inner array = a column of shades) - `false` / omitted — no swatches section |
721
- | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
722
- | `validationMode` | `ValidationMode \| undefined` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
723
- | `variant` | `InputVariantType \| undefined` | `'outline'` | | Visual variant of the field box, with the `BbButton` names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, and `'none'` takes no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
724
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
721
+ | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; never the `name`. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). `BbForm` only. |
722
+ | `validationMode` | `ValidationMode \| undefined` | | | When the field validates: `aggressive` (each change), `balanced` (on leave, then live while in error), `lazy` (on leave), `submit-only`, `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). `BbForm` only. |
723
+ | `variant` | `InputVariantType \| undefined` | `'outline'` | | The field box's look, with `BbButton`'s names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, `'none'` no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
724
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or array: amber, in their own `aria-live` region and in the control's `aria-describedby` after the errors. Non-empty turns on the warning state; errors win when both are set. |
725
725
 
726
726
  ## Passthrough parts and states
727
727
 
@@ -885,12 +885,12 @@ label>')` matches nothing; query each segment by its own label instead. See
885
885
  | `autocomplete` | `string \| undefined` | `"off"` | | Guides the browser as to the type of information expected in the field. |
886
886
  | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
887
887
  | `clearable` | `boolean \| undefined` | `false` | | Displays a clear button when the input has a value and is being interacted with. |
888
- | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-input-h`, `--bb-input-py` and `--bb-label-spacing-y` for their `-compact` twins on the field, so a `--bb-input-h` you set on the component is ignored while `compact` is on: size a compact field with `--bb-input-h-compact` (and `--bb-input-py-compact`) instead. |
889
- | `description` | `string \| undefined` | | | Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via `aria-describedby` (after any `errors` / `warnings`, before the `hint`). |
888
+ | `compact` | `boolean \| undefined` | `false` | | Compact density: the field uses the `-compact` twins of `--bb-input-h`, `--bb-input-py` and `--bb-label-spacing-y`, so a `--bb-input-h` set on the component is ignored while it is on. Size a compact field with `--bb-input-h-compact` (and `--bb-input-py-compact`). |
889
+ | `description` | `string \| undefined` | | | Text between the label and the input. Unlike the hint it is always visible; it joins the input's `aria-describedby` after any `errors` / `warnings`, before the `hint`. |
890
890
  | `disableCalendar` | `boolean \| "mobile" \| "desktop" \| undefined` | `false` | | Disables the calendar: hides the trigger button and prevents the popover from opening. Use `'desktop'` to disable it on desktop only (keeping the calendar for mobile, complementing `disableWriting: 'mobile'`) or `'mobile'` to disable it on mobile only. |
891
891
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
892
892
  | `disableWriting` | `boolean \| "mobile" \| "desktop" \| undefined` | `false` | | Disables typing into the input. Use `'mobile'` to disable typing only on mobile, `'desktop'` to disable typing only on desktop. |
893
- | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
893
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or array, in an `aria-live="polite"` region and first in the control's `aria-describedby`, so they are re-read when it regains focus. |
894
894
  | `firstDayOfWeek` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| undefined` | `the locale's week start` | | First day of the week (0 = Sunday … 6 = Saturday). Omitted, the active locale's week start: Monday for `it`, `de`, `fr`, `en-gb`…, Sunday for bare `en` (US) and `pt` (Brazil). |
895
895
  | `floating` | `boolean \| undefined` | `false` | | If true the date will have a format YYYY-MM-DD instead of the default ISO string. |
896
896
  | `formless` | `boolean \| undefined` | `false` | | Keep this control out of the enclosing `BbForm` entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch). |
@@ -904,7 +904,7 @@ label>')` matches nothing; query each segment by its own label instead. See
904
904
  | `labelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
905
905
  | `labelMode` | `"outside" \| "floating" \| "inside" \| undefined` | | | Label rendering mode. |
906
906
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
907
- | `layout` | `Responsive<FieldLayout> \| undefined` | | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map such as `{ default: 'vertical', md: 'xx xxxxx' }`. |
907
+ | `layout` | `Responsive<FieldLayout> \| undefined` | | | How label and input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map (`{ default: 'vertical', md: 'xx xxxxx' }`). |
908
908
  | `loading` | `boolean \| undefined` | `false` | | Sets the component in a loading state, usually triggering some visual styles. |
909
909
  | `max` | `string \| undefined` | | | Maximum selectable date in `YYYY-MM-DD` format — or, with `type="datetime"`, `YYYY-MM-DDTHH:mm` to tighten the boundary day to a minute. Values outside both patterns throw during setup to surface configuration mistakes. |
910
910
  | `min` | `string \| undefined` | | | Minimum selectable date in `YYYY-MM-DD` format — or, with `type="datetime"`, `YYYY-MM-DDTHH:mm` to tighten the boundary day to a minute. Values outside both patterns throw during setup to surface configuration mistakes. |
@@ -926,10 +926,10 @@ label>')` matches nothing; query each segment by its own label instead. See
926
926
  | `transitionDuration` | `number \| undefined` | | | Transition duration, in milliseconds, for the popover appearance. |
927
927
  | `type` | `'date'` \| `'month'` \| `'year'` \| `'datetime'` | `"date"` | | What the field edits, and so its segments and emitted shape: `date` (`DD/MM/YYYY`), `datetime` (adds the time segments and rail), `month` (`MM/YYYY`, emits `YYYY-MM`) or `year` (`YYYY`). `month` / `year` force `floating`, ignore `utc`, and leave the time props inert. |
928
928
  | `utc` | `boolean \| undefined` | `false` | | Emits UTC ISO strings (`…Z`) instead of the local offset (`…+01:00`). Emission only: incoming values parse the same either way, and the field always displays local time. Ignored with `floating`. |
929
- | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
930
- | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
931
- | `variant` | `'outline'` \| `'secondary'` \| `'none'` \| `'ghost'` | `'outline'` | | Visual variant of the field box, with the `BbButton` names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, and `'none'` takes no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
932
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
929
+ | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; never the `name`. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). `BbForm` only. |
930
+ | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When the field validates: `aggressive` (each change), `balanced` (on leave, then live while in error), `lazy` (on leave), `submit-only`, `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). `BbForm` only. |
931
+ | `variant` | `'outline'` \| `'secondary'` \| `'none'` \| `'ghost'` | `'outline'` | | The field box's look, with `BbButton`'s names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, `'none'` no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
932
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or array: amber, in their own `aria-live` region and in the control's `aria-describedby` after the errors. Non-empty turns on the warning state; errors win when both are set. |
933
933
 
934
934
  ## Passthrough parts and states
935
935
 
@@ -1520,7 +1520,26 @@ const route = useRoute();
1520
1520
  ```
1521
1521
 
1522
1522
  Template dialogs only: a dialog opened on demand has no place in the page URL
1523
- (`navigation` is ignored there, with a dev warning). On the phone the adaptive
1523
+ (`navigation` is ignored there, with a dev warning). A wrapper component that
1524
+ should live in the URL is rendered in the page and opened by id: reload opens
1525
+ it, Back closes it, closing strips the key. State it needs fresh on every
1526
+ opening (a form object made in setup) goes in its body, a small component
1527
+ inside the BbDialog whose setup runs per opening, or in the opening's `data`
1528
+ with `default-data`:
1529
+
1530
+ ```vue
1531
+ <!-- CreatePatientDialog.vue renders
1532
+ <BbDialog id="create-patient" navigation query-key="create">
1533
+ <PatientForm /> (its own setup: a fresh form per opening)
1534
+ </BbDialog> -->
1535
+ <CreatePatientDialog />
1536
+ <BbButton v-bb-dialog="'create-patient'">New patient</BbButton>
1537
+ ```
1538
+
1539
+ On demand stays for openings with no page to live in (a command palette, a
1540
+ store action, stacked copies of one dialog), which want no URL anyway.
1541
+
1542
+ On the phone the adaptive
1524
1543
  sheet is the same dialog: one key, and Back is refused by the sheet's own
1525
1544
  gates. Under Inertia, a Back that changes only dialog keys never reaches
1526
1545
  Inertia, so the page is not remounted; this needs `bitbossUiPlugin` installed
@@ -1757,7 +1776,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1757
1776
  | --- | --- | --- | --- | --- |
1758
1777
  | `pt:<part>`, `pt:<part>:<state>`, `pt` | `PtValue` | | | Passthrough — a class list, or `{ class, style, attrs }`, bound to one named part of the component; the state form applies only while that state is on. Parts: `close`, `content`, `description`, `footer`, `header`, `root`, `sheet`, `title`. States: `fullscreen`, `open`. What each one is: _Passthrough parts and states_ below. `pt` is the object form with the same keys minus the prefix (`{ icon: '…', 'icon:loading': '…' }`). See `guides/passthrough.md`. In `<script>` a `pt` value is typed `BbDialogProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
1759
1778
  | `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile, renders as a `BbOffCanvas` drawer instead of a centred dialog; the surface is chosen when the dialog opens and kept until it closes. Unset: the global `config.adaptive`. |
1760
- | `defaultData` | `Record<string, any> \| undefined` | | | The `data` of an opening that passes none (a create), as an object: copied at once and exposed as `data`, so inputs bind `data.x` with no guard. An opening with data lays it over this (`{ ...defaultData, ...row }`, one level). `reset()` restores its keys, keeping an edit's `id`; a close restores it. |
1779
+ | `defaultData` | `Record<string, any> \| undefined` | | | What `data` is when an opening passes none (a create): an object, copied at once, so inputs bind `data.x` with no guard. An opening's data lays over it (`{ ...defaultData, ...row }`, one level). `reset()` restores its keys but keeps an edit's `id`; a close restores it. |
1761
1780
  | `description` | `string \| undefined` | | | One short line under the title, muted (the shadcn `DialogDescription` shape), and the only element `aria-describedby` points at. Keep it to a sentence; anything longer belongs in the body. |
1762
1781
  | `eager` | `boolean \| undefined` | `false` | | Keep the body mounted while closed, from before the first opening. Without it the body mounts per opening and unmounts after `@hidden`. `data` still clears while closed, so an eager body guards its reads. |
1763
1782
  | `focusTarget` | `string \| undefined` | | | CSS selector of the element to focus after opening. Defaults to the first tabbable element. |
@@ -1765,16 +1784,16 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1765
1784
  | `hideClose` | `boolean \| undefined` | `false` | | Hide the default close (×) button. The button is shown by default; set this to remove it (e.g. for a `persistent` dialog you don't want dismissible — the × otherwise still closes a persistent dialog). |
1766
1785
  | `id` | `string \| undefined` | | | Names the dialog for `v-bb-dialog="'edit'"` and `useBbDialogContext`, found nearest to the trigger, so two pages may reuse an id. Also the DOM `id`: one dialog per id, rows pass `data`. |
1767
1786
  | `modelValue` | `boolean \| undefined` | `false` | | Used by v-model to open / close the dialog. A dialog with no `v-model` starts closed. |
1768
- | `navigation` | `boolean \| undefined` | `false` | | Syncs the open state with the URL: opening writes `?<queryKey>=true`, closing removes it, a URL carrying the key opens the dialog on load, and Back closes it (refused like Escape when locked). Template dialogs only; a record id stays in your own query. |
1787
+ | `navigation` | `boolean \| undefined` | `false` | | Syncs the open state with the URL: opening writes `?<queryKey>=true`, closing removes it, a URL with the key opens the dialog on load, and Back closes it (refused whenever Escape is). Template dialogs only; keep a record id in your own query. |
1769
1788
  | `offCanvasProps` | `Partial<BbOffCanvasProps> \| undefined` | | | Props for the phone sheet (the `BbOffCanvas` that `adaptive` renders on mobile), spread over its defaults. A `pt` inside it styles only the sheet (passthrough guide § Inside the sheet). |
1770
- | `persistent` | `boolean \| undefined` | `false` | | Prevent closing via outside clicks or Escape key. The header close (×) button STILL closes a persistent dialog — that is the documented escape hatch; combine with `hideClose` to remove it, or use `preventClose` to block every dismissal. Programmatic close is still allowed. |
1771
- | `preventClose` | `boolean \| undefined` | ``undefined` (follows a saving form inside)` | | Refuses every user close (backdrop, Escape and the ✕, and the slots' `close`) with the deny nudge; `v-model` still closes. Unset: locked while a `BbForm` inside saves (an async `@submit`). `true`: always. `false`: never, not even mid-save. Beside a form: `busy \|\| undefined`. |
1789
+ | `persistent` | `boolean \| undefined` | `false` | | Blocks closing by outside click or Escape. The header close (×) STILL closes a persistent dialog, the documented escape hatch: add `hideClose` to remove it, or use `preventClose` to block every dismissal. Programmatic close still works. |
1790
+ | `preventClose` | `boolean \| undefined` | ``undefined` (follows a saving form inside)` | | Refuses every user close (backdrop, Escape, the ✕, the slots' `close`) with the deny nudge; `v-model` still closes. Unset: locked while a `BbForm` inside saves (an async `@submit`). `true`: always; `false`: never, not even mid-save. Beside a form: `busy \|\| undefined`. |
1772
1791
  | `queryKey` | `string \| undefined` | `"dialog"` | | The query key `navigation` writes. |
1773
1792
  | `replace` | `boolean \| undefined` | `false` | | With `navigation`, replaces the history entry instead of pushing one, so Back leaves the page instead of closing the dialog. |
1774
1793
  | `size` | `Responsive<NonNullable<number \| CssSize \| keyof BbDialogSizes \| undefined>> \| undefined` | `"sm"` | | Controls the maximum width of the dialog. Accepts named presets from `'xs'` to `'2xl'`, a custom CSS width string, or a numeric pixel value — or a per-breakpoint map (e.g. `{ default: 'sm', lg: 'lg' }`) to switch width responsively. |
1775
1794
  | `snap` | `BbSnapPoint \| undefined` | | | The phone sheet's snap stop (Q71.8), one of the `snapPoints` entries. The desktop dialog ignores it. |
1776
- | `snapPoints` | `BbSnapPoint[] \| undefined` | | | Heights the phone sheet rests at, smallest first: a fraction of the screen (`0.5`; `1` = as tall as it gets) or a pixel height (`'240px'`). The first stop is the opening height; `v-model:snap` reads and sets the stop. Phone sheet only: the desktop dialog ignores it. |
1777
- | `stack` | `string \| undefined` | | | Name of the stack this dialog belongs to. Dialogs sharing the same `stack` value replace one another: only the most recently opened stays visible while the others in the stack are hidden beneath it. Dialogs in different stacks — or with no `stack` — never affect each other and remain fully visible. |
1795
+ | `snapPoints` | `BbSnapPoint[] \| undefined` | | | Heights the phone sheet rests at, smallest first: a screen fraction (`0.5`; `1` = as tall as it gets) or pixels (`'240px'`). The first is the opening height; `v-model:snap` reads and sets the stop. Sheet only: the centred dialog ignores it. |
1796
+ | `stack` | `string \| undefined` | | | Name of this dialog's stack. Dialogs with the same `stack` replace one another: only the latest opened shows, the rest of the stack hide beneath it. Dialogs in different stacks, or with no `stack`, never affect each other and stay fully visible. |
1778
1797
  | `title` | `string \| undefined` | | | Title text announced to assistive technologies. If omitted, no header is rendered (unless a `header` slot is supplied) and accessibility must be handled manually. |
1779
1798
  | `transitionDuration` | `number \| undefined` | `250` | | Controls the duration of the open and close animations. |
1780
1799
 
@@ -1664,7 +1664,7 @@ button, grows with every file added, and changes mid-drag. So:
1664
1664
  | `accept` | `string[] \| undefined` | | | File filter: MIME types (`'image/png'`), wildcards (`'image/*'`), extensions (`'.png'`) or bare tokens (`'png'`, upgraded to the extension and its MIME type from the lazily imported `mime` database; files that arrive earlier wait for it). |
1665
1665
  | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
1666
1666
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component |
1667
- | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
1667
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or array, in an `aria-live="polite"` region and first in the control's `aria-describedby`, so they are re-read when it regains focus. |
1668
1668
  | `formless` | `boolean \| undefined` | `false` | | Keep this control out of the enclosing `BbForm` entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch). |
1669
1669
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
1670
1670
  | `hasWarnings` | `boolean \| undefined` | `false` | | Define if the component should be in a warning state. Same chrome as errors with `--bb-warn`; errors take priority. |
@@ -1674,11 +1674,11 @@ button, grows with every file added, and changes mid-drag. So:
1674
1674
  | `modelValue` | `File \| File[] \| null \| undefined` | | | Used by v-model. |
1675
1675
  | `multiple` | `boolean \| undefined` | `false` | | Allows the selection of multiple items. |
1676
1676
  | `name` | `string \| undefined` | | | Defines the name of the input. |
1677
- | `readonly` | `boolean \| undefined` | `false` | | Shows the files without letting the user change them: drop, the file picker and the `open()` slot prop do nothing, while the input stays focusable and a `name`d zone still submits its files (unlike `disabled`). Your slot renders the list, so hide your remove buttons with the `readonly` slot prop. |
1677
+ | `readonly` | `boolean \| undefined` | `false` | | Shows the files; the user cannot change them: drop, the file picker and the `open()` slot prop do nothing, yet the input stays focusable and a `name`d zone still submits its files (unlike `disabled`). Your slot renders the list: hide your remove buttons with the slot's `readonly`. |
1678
1678
  | `rules` | `RuleExpression<File \| File[] \| null>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
1679
1679
  | `tag` | `'div'` \| `'span'` | `"div"` | | Element rendered as the component's wrapper. |
1680
- | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
1681
- | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
1680
+ | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; never the `name`. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). `BbForm` only. |
1681
+ | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When the field validates: `aggressive` (each change), `balanced` (on leave, then live while in error), `lazy` (on leave), `submit-only`, `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). `BbForm` only. |
1682
1682
  | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the dropzone, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
1683
1683
 
1684
1684
  ## Passthrough parts and states
@@ -1704,7 +1704,7 @@ States are listed in precedence order: when two are on at once and their entries
1704
1704
  ## Events
1705
1705
 
1706
1706
  - `blur` — `(event: FocusEvent): void` — Emitted when the file input loses focus. Forwards the original DOM `FocusEvent`.
1707
- - `error` — `(errors: DropZoneError[]): void` — Emitted once per drop or pick that rejected at least one file, AFTER that gesture's `update:modelValue`: every rejection of the gesture (size, type, uniqueness, max count), in file order. A clean drop emits none, so clear your messages on `update:modelValue` and set them here.
1707
+ - `error` — `(errors: DropZoneError[]): void` — Emitted once per drop or pick that rejected any file, AFTER that gesture's `update:modelValue` (if any): all its rejections (size, type, uniqueness, max count), in file order. A clean drop emits none: clear your messages on `update:modelValue`, set them here.
1708
1708
  - `focus` — `(event: FocusEvent): void` — Emitted when the file input receives focus. Forwards the original DOM `FocusEvent`.
1709
1709
  - `update:modelValue` — `(value: File \| File[] \| null): void` — Emitted when the selected files change. Payload is the new file or file array.
1710
1710
 
package/dist/ai/BbForm.md CHANGED
@@ -1761,12 +1761,12 @@ marker stays consistent with the rules.
1761
1761
  | Prop | Type | Default | Required | Description |
1762
1762
  | --- | --- | --- | --- | --- |
1763
1763
  | `disableSubmitLock` | `boolean \| undefined` | `false` | | Keeps the fields editable while a `@submit` promise is pending (by default every joined field is read-only until it settles; a `@submit` that returns nothing never locks). Submit buttons spin either way. |
1764
- | `fieldErrors` | `Record<string, unknown> \| null \| undefined` | | | A server's validation errors by field path (Inertia's `form.errors`, a Laravel 422 body), shown on their fields for as long as they are in the object. They never block a submit; a key no field has is in `unmatchedErrors`. A one-off message: `setErrors`. |
1764
+ | `fieldErrors` | `Record<string, unknown> \| null \| undefined` | | | Server validation errors by field path (Inertia's `form.errors`, a Laravel 422 body), shown on their fields while they are in the object. They never block a submit; a key no field has is in `unmatchedErrors`. A one-off message: `setErrors`. |
1765
1765
  | `id` | `string \| undefined` | | | Lets anything outside the form read and drive it through `useBbFormContext(id)` (a dialog footer, a toolbar, a leave guard). It is also the `<form>`'s id, so `<button form="id" type="submit">` outside it submits it. |
1766
1766
  | `keepValuesOnUnmount` | `boolean \| Ref<boolean, boolean> \| undefined` | | | Keep a field's value (and its place in `@submit`) when it unmounts — the `v-if` wizard step you left, a collapsed section. Off, an unmounted field drops out of the values. |
1767
- | `model` | `Record<string, any> \| undefined` | | | The object the fields edit (`reactive()`, a `ref`, Pinia state, Inertia `useForm()`), written in place: bind it one way, `:model`, never `v-model`. A field without its own `v-model` reads and writes the value at its `name` path. Nothing is written on mount. |
1768
- | `schema` | `MaybeRef<S \| undefined>` | | | One Standard Schema for the whole form (Zod, Valibot, ArkType, Yup, Joi, Effect), passed as is. Errors land on the field whose `name` is the issue path; `@submit` gets the typed output. Set it at mount (a `computed` may change it); per-field `rules` are then ignored. |
1769
- | `validationMode` | `ValidationMode \| undefined` | | | When the fields inside check themselves while the user works: `aggressive`, `balanced`, `lazy`, `submit-only` or `submit-live` (see `ValidationMode`). A field's own `validation-mode` wins. Unset, the app's `formControls.validationMode` applies (`'balanced'` by default). |
1767
+ | `model` | `Record<string, any> \| undefined` | | | The object the fields edit in place (`reactive()`, a `ref`, Pinia state, Inertia `useForm()`): bind it one way, `:model`, never `v-model`. A field without its own `v-model` reads and writes the value at its `name` path. Nothing is written on mount. |
1768
+ | `schema` | `MaybeRef<S \| undefined>` | | | One Standard Schema for the form (Zod, Valibot, ArkType, Yup, Joi, Effect), passed as is. An issue lands on the field whose `name` is its path; `@submit` gets the typed output. Set it at mount (a `computed` may change it); per-field `rules` are then ignored. |
1769
+ | `validationMode` | `ValidationMode \| undefined` | | | When the fields inside validate as the user works: `aggressive`, `balanced`, `lazy`, `submit-only` or `submit-live` (see `ValidationMode`). A field's own `validation-mode` wins. Unset: the app's `formControls.validationMode` (default `'balanced'`). |
1770
1770
 
1771
1771
  ## Events
1772
1772
 
@@ -863,12 +863,12 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
863
863
  | `autocomplete` | `string \| undefined` | `"off"` | | Guides the browser as to the type of information expected in the field. |
864
864
  | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
865
865
  | `clearable` | `boolean \| undefined` | `false` | | Displays a clear button when the input has a value and is being interacted with. |
866
- | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-input-h`, `--bb-input-py` and `--bb-label-spacing-y` for their `-compact` twins on the field, so a `--bb-input-h` you set on the component is ignored while `compact` is on: size a compact field with `--bb-input-h-compact` (and `--bb-input-py-compact`) instead. |
866
+ | `compact` | `boolean \| undefined` | `false` | | Compact density: the field uses the `-compact` twins of `--bb-input-h`, `--bb-input-py` and `--bb-label-spacing-y`, so a `--bb-input-h` set on the component is ignored while it is on. Size a compact field with `--bb-input-h-compact` (and `--bb-input-py-compact`). |
867
867
  | `currency` | `string \| undefined` | | | An ISO 4217 code (`'EUR'`): the amount shows the locale's way, symbol inside the text (`1.234,56 €`), leaving `#prefix` / `#suffix` free; the model is the number. Decimals default to the currency's; `minPrecision` / `maxPrecision` win. Not with `unit`. |
868
- | `description` | `string \| undefined` | | | Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via `aria-describedby` (after any `errors` / `warnings`, before the `hint`). |
868
+ | `description` | `string \| undefined` | | | Text between the label and the input. Unlike the hint it is always visible; it joins the input's `aria-describedby` after any `errors` / `warnings`, before the `hint`. |
869
869
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
870
870
  | `disableFormatting` | `boolean \| undefined` | `false` | | Shows the number as typed (period decimal, no grouping), with `name` on the visible input. Without it the field formats the locale's way while typing (`10.005,6`) and posts the raw value (`10005.6`) through a hidden input carrying `name`. |
871
- | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
871
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or array, in an `aria-live="polite"` region and first in the control's `aria-describedby`, so they are re-read when it regains focus. |
872
872
  | `formless` | `boolean \| undefined` | `false` | | Keep this control out of the enclosing `BbForm` entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch). |
873
873
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
874
874
  | `hasWarnings` | `boolean \| undefined` | `false` | | Define if the component should be in a warning state. Same chrome as errors with `--bb-warn`; errors take priority. |
@@ -880,7 +880,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
880
880
  | `labelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
881
881
  | `labelMode` | `"outside" \| "floating" \| "inside" \| undefined` | | | Label rendering mode. |
882
882
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
883
- | `layout` | `Responsive<FieldLayout> \| undefined` | | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map such as `{ default: 'vertical', md: 'xx xxxxx' }`. |
883
+ | `layout` | `Responsive<FieldLayout> \| undefined` | | | How label and input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map (`{ default: 'vertical', md: 'xx xxxxx' }`). |
884
884
  | `loading` | `boolean \| undefined` | `false` | | Sets the component in a loading state, usually triggering some visual styles. |
885
885
  | `max` | `number \| undefined` | `Number.MAX_SAFE_INTEGER` | | Maximum value cap. |
886
886
  | `maxPrecision` | `number \| undefined` | `8` | | Maximum precision of the number: fraction digits past it are refused as typed (never rounded). With `currency`, the currency's own digits (`2` for EUR, `0` for JPY, `3` for KWD), or `minPrecision` when that is larger. |
@@ -897,10 +897,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
897
897
  | `rules` | `RuleExpression<string \| number \| null>` | | | vee-validate rules for this field. Only inside a `BbForm`. |
898
898
  | `step` | `number \| undefined` | `1` | | Incremental unit used by ArrowUp / ArrowDown and by the `increase` and `decrease` functions the slots receive. It is NOT applied to manual input as a step of 5 would prevent the user from inserting a value like `115` because of rounding down. |
899
899
  | `unit` | `BbNumberUnit \| undefined` | | | A unit `Intl.NumberFormat` knows (`'kilogram'`, `'celsius'`, `'percent'`), shown the locale's way inside the text (`20 kg`). The model is the number you see: `percent` showing `15 %` holds `15`. Not with `currency` (which wins). |
900
- | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; the field's `name` never shows. Set it when the label is not a good noun for a sentence (an icon-only label, a question) or is hidden. Only inside a `BbForm`. |
901
- | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When this field validates as the user works: `aggressive` (every change), `balanced` (on leave, then live while it shows an error), `lazy` (on leave), `submit-only` or `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). Only in a `BbForm`. |
902
- | `variant` | `'outline'` \| `'secondary'` \| `'none'` \| `'ghost'` | `'outline'` | | Visual variant of the field box, with the `BbButton` names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, and `'none'` takes no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
903
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
900
+ | `validationLabel` | `string \| undefined` | | | The field's name in validation messages (`{field}`): "Email is not valid". Defaults to the `label` (or `legend`), then "This field"; never the `name`. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). `BbForm` only. |
901
+ | `validationMode` | `'aggressive'` \| `'balanced'` \| `'lazy'` \| `'submit-only'` \| `'submit-live'` | | | When the field validates: `aggressive` (each change), `balanced` (on leave, then live while in error), `lazy` (on leave), `submit-only`, `submit-live`. Unset: the `BbForm`'s `validation-mode`, then `formControls.validationMode` (`'balanced'`). `BbForm` only. |
902
+ | `variant` | `'outline'` \| `'secondary'` \| `'none'` \| `'ghost'` | `'outline'` | | The field box's look, with `BbButton`'s names and tokens. Colours only, so a form never reflows; `'ghost'` has no border in any state, `'none'` no look at all (you own hover, focus and the states). Register more with the plugin's `inputVariants`. |
903
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or array: amber, in their own `aria-live` region and in the control's `aria-describedby` after the errors. Non-empty turns on the warning state; errors win when both are set. |
904
904
 
905
905
  ## Passthrough parts and states
906
906
 
@@ -167,6 +167,8 @@ It works exactly like `v-bb-dialog` (see the BbDialog guide):
167
167
  - On Android, the system back button closes the top panel like Escape (it is the browser's close request), so `prevent-close` and a saving form refuse it the same way; iOS swipe-back and the desktop back button are page navigation.
168
168
  - The button gets `aria-haspopup="dialog"`, `aria-expanded` and
169
169
  `aria-controls`, and focus returns to it on close.
170
+ - A native `<button commandfor="…" command="show-modal">` (or `"close"`) is
171
+ safe: it takes the same open and user-close paths. Prefer `v-bb-off-canvas`.
170
172
 
171
173
  An adaptive `BbDialog` that shows as a sheet on a phone is still a dialog:
172
174
  open it with `v-bb-dialog`.
@@ -1130,7 +1132,9 @@ import { BbButton, BbOffCanvas, BbTextInput } from 'bitboss-ui';
1130
1132
  `?offcanvas=true` (`query-key` renames it), closing removes it, a link or
1131
1133
  reload carrying the key opens the panel, and Back closes it with
1132
1134
  `reason: 'escape'`, refused like Escape by `persistent`, `prevent-close` or a
1133
- saving form. `replace` skips the history entry. Same rules as
1135
+ saving form. `replace` skips the history entry. Template panels only: a
1136
+ wrapper that should live in the URL is rendered in the page and opened by id
1137
+ (`v-bb-off-canvas`), with per-opening state in its body. Same rules as
1134
1138
  [BbDialog § In the URL](./BbDialog.md#in-the-url-navigation).
1135
1139
 
1136
1140
  ```vue
@@ -1370,7 +1374,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1370
1374
  | Prop | Type | Default | Required | Description |
1371
1375
  | --- | --- | --- | --- | --- |
1372
1376
  | `pt:<part>`, `pt:<part>:<state>`, `pt` | `PtValue` | | | Passthrough — a class list, or `{ class, style, attrs }`, bound to one named part of the component; the state form applies only while that state is on. Parts: `close`, `content`, `description`, `footer`, `header`, `root`, `title`. States: `fullscreen`, `open`. What each one is: _Passthrough parts and states_ below. `pt` is the object form with the same keys minus the prefix (`{ icon: '…', 'icon:loading': '…' }`). See `guides/passthrough.md`. In `<script>` a `pt` value is typed `BbOffCanvasProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
1373
- | `defaultData` | `Record<string, any> \| undefined` | | | The `data` of an opening that passes none (a create), as an object: copied at once and exposed as `data`, so inputs bind `data.x` with no guard. An opening with data lays it over this (`{ ...defaultData, ...row }`, one level). `reset()` restores its keys, keeping an edit's `id`; a close restores it. |
1377
+ | `defaultData` | `Record<string, any> \| undefined` | | | What `data` is when an opening passes none (a create): an object, copied at once, so inputs bind `data.x` with no guard. An opening's data lays over it (`{ ...defaultData, ...row }`, one level). `reset()` restores its keys but keeps an edit's `id`; a close restores it. |
1374
1378
  | `description` | `string \| undefined` | | | One short line under the title, muted (the shadcn `DialogDescription` shape), and the only element `aria-describedby` points at. Keep it to a sentence; anything longer belongs in the body. |
1375
1379
  | `draggable` | `boolean \| undefined` | `false` | | Drag-to-dismiss: a ~50px swipe toward the exit edge (also from the body once it is scrolled to its edge), with a grab handle as the cue. A gesture that starts inside `data-bb-no-drag` never drags the panel. |
1376
1380
  | `eager` | `boolean \| undefined` | `false` | | Keep the body mounted while closed, from before the first opening. Without it the body mounts per opening and unmounts after `@hidden`. `data` still clears while closed, so an eager body guards its reads. |
@@ -1379,13 +1383,13 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1379
1383
  | `hideClose` | `boolean \| undefined` | `false` | | Hides the default close (×) button in the header (e.g. for a `persistent` drawer you don't want dismissible — the × otherwise still closes a persistent drawer). |
1380
1384
  | `id` | `string \| undefined` | | | Names the panel for `v-bb-off-canvas="'filters'"` and `useBbOffCanvasContext`, found nearest to the trigger, so two pages may reuse an id. Also the DOM `id`: one panel per id. |
1381
1385
  | `modelValue` | `boolean \| undefined` | `false` | | Used by v-model to open / close the panel. A panel with no `v-model` starts closed. |
1382
- | `navigation` | `boolean \| undefined` | `false` | | Syncs the open state with the URL: opening writes `?<queryKey>=true`, closing removes it, a URL carrying the key opens the panel on load, and Back closes it (refused like Escape when locked). Template panels only; a record id stays in your own query. |
1383
- | `persistent` | `boolean \| undefined` | `false` | | Prevent closing via outside clicks, Escape key or drag-to-dismiss. The header close (×) button STILL closes a persistent drawer — that is the documented escape hatch; combine with `hideClose` to remove it, or use `preventClose` to block every dismissal. Programmatic close is still allowed. |
1384
- | `preventClose` | `boolean \| undefined` | ``undefined` (follows a saving form inside)` | | Refuses every user close (backdrop, Escape, drag and the ✕, and the slots' `close`) with the deny nudge; `v-model` still closes. Unset: locked while a `BbForm` inside saves (an async `@submit`). `true`: always. `false`: never, not even mid-save. Beside a form: `busy \|\| undefined`. |
1386
+ | `navigation` | `boolean \| undefined` | `false` | | Syncs the open state with the URL: opening writes `?<queryKey>=true`, closing removes it, a URL with the key opens the panel on load, and Back closes it (refused whenever Escape is). Template panels only; keep a record id in your own query. |
1387
+ | `persistent` | `boolean \| undefined` | `false` | | Blocks closing by an outside click, Escape or drag-to-dismiss. The header close (×) STILL closes a persistent drawer, the documented escape hatch: add `hideClose` to remove it, or use `preventClose` to block every dismissal. Programmatic close still works. |
1388
+ | `preventClose` | `boolean \| undefined` | ``undefined` (follows a saving form inside)` | | Refuses every user close (backdrop, Escape, drag, the ✕, the slots' `close`) with the deny nudge; `v-model` still closes. Unset: locked while a `BbForm` inside saves (an async `@submit`). `true`: always; `false`: never, not even mid-save. Beside a form: `busy \|\| undefined`. |
1385
1389
  | `queryKey` | `string \| undefined` | `"offcanvas"` | | The query key `navigation` writes. |
1386
1390
  | `replace` | `boolean \| undefined` | `false` | | With `navigation`, replaces the history entry instead of pushing one, so Back leaves the page instead of closing the panel. |
1387
1391
  | `side` | `"left" \| "top" \| "bottom" \| "right" \| undefined` | `"left"` | | Which viewport edge the offcanvas docks to (and slides in from). |
1388
- | `size` | `Responsive<OffCanvasSize> \| undefined` | `"sm"` | | The panel's extent along its axis: the width of a left/right panel (shrinking with a narrower viewport) or the height of a top/bottom one (capped at the viewport). A preset `'xs'`–`'2xl'`, `'auto'`, a CSS size, a pixel number, or a per-breakpoint map (e.g. `{ default: 'sm', lg: 'lg' }`). |
1392
+ | `size` | `Responsive<OffCanvasSize> \| undefined` | `"sm"` | | The panel's extent along its axis: a left/right panel's width (shrinks with a narrower viewport) or a top/bottom one's height (capped at the viewport). A preset `'xs'`–`'2xl'`, `'auto'`, a CSS size, a pixel number, or a per-breakpoint map (e.g. `{ default: 'sm', lg: 'lg' }`). |
1389
1393
  | `snap` | `BbSnapPoint \| undefined` | | | The snap stop the sheet rests at, written as one of the `snapPoints` entries (Q71.8). Updated once the sheet settles on another stop; setting it moves the sheet there. Unbound, every opening starts at the first stop. |
1390
1394
  | `snapPoints` | `BbSnapPoint[] \| undefined` | | | Heights a draggable bottom sheet rests at, smallest first: a fraction of the screen (`0.5`, `1` = full) or `'240px'`. The first is the opening height; `v-model:snap` holds the stop. Ignored on other sides and `fullscreen` (guide § Snap points). |
1391
1395
  | `stack` | `string \| undefined` | | | Name of the stack this drawer belongs to. Drawers sharing the same `stack` value step back behind one another as later ones open; drawers in different stacks never affect each other. When omitted, the drawer stacks with nothing. |
@@ -505,9 +505,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
505
505
  | `autofocus` | `Booleanish \| undefined` | | | Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field. |
506
506
  | `checked` | `boolean \| undefined` | `undefined` | | Defines the input as checked. |
507
507
  | `compact` | `boolean \| undefined` | `false` | | Compact density. Swaps `--bb-label-spacing-y` for `--bb-label-spacing-y-compact`, so tune a compact field's label gap with the `-compact` token, not the base one. The same meaning as on the checkbox, radio and switch groups. |
508
- | `description` | `string \| undefined` | | | Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via `aria-describedby` (after any `errors` / `warnings`, before the `hint`). |
508
+ | `description` | `string \| undefined` | | | Text between the label and the input. Unlike the hint it is always visible; it joins the input's `aria-describedby` after any `errors` / `warnings`, before the `hint`. |
509
509
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component. |
510
- | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or string array. They render in an `aria-live="polite"` region and are referenced first from the control's `aria-describedby`, so they are re-read when it regains focus. |
510
+ | `errors` | `string \| string[] \| undefined` | | | Error messages under the field, a string or array, in an `aria-live="polite"` region and first in the control's `aria-describedby`, so they are re-read when it regains focus. |
511
511
  | `hasErrors` | `boolean \| undefined` | `false` | | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
512
512
  | `hasWarnings` | `boolean \| undefined` | `false` | | Define if the component should be in a warning state. Same chrome as errors with `--bb-warn`; errors take priority. |
513
513
  | `hideLabel` | `boolean \| undefined` | `false` | | Visually hides the label of the input while maintaining accessibility. |
@@ -518,7 +518,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
518
518
  | `label` | `string` | | yes | Text content of the label of the element. |
519
519
  | `labelAlign` | `'top'` \| `'center'` \| `'bottom'` | | | Vertical position of the label block in a side-by-side row; not `labelPosition`, the horizontal one. Omitted, the label's first line meets the control's. |
520
520
  | `labelPosition` | `"left" \| "center" \| "right" \| undefined` | | | Sets the text alignment of the label. |
521
- | `layout` | `Responsive<FieldLayout> \| undefined` | `"auto"` | | How the label and the input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map such as `{ default: 'vertical', md: 'xx xxxxx' }`. |
521
+ | `layout` | `Responsive<FieldLayout> \| undefined` | `"auto"` | | How label and input sit together: `'vertical'`, `'horizontal'` (50/50), `'auto'`, `'label-fill'`, `'input-fill'`, a ratio like `'xx xxxxx'`, or a per-breakpoint map (`{ default: 'vertical', md: 'xx xxxxx' }`). |
522
522
  | `modelValue` | `any` | | | Used by v-model. Can be any serializable type. |
523
523
  | `name` | `string \| undefined` | | | Name of the input. Optional: a generated one is unique to this radio, so radios that form ONE exclusive group must share an explicit `name`. Pass one too for a native (non-JS) form post under a known key. |
524
524
  | `persistentHint` | `boolean \| undefined` | `false` | | Keeps the hint displayed. |
@@ -526,7 +526,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
526
526
  | `required` | `boolean \| undefined` | `false` | | Sets the input as required. |
527
527
  | `reverse` | `boolean \| undefined` | `false` | | Reverses the layout: in every direction the order of the label and the input is swapped from the standard arrangement. |
528
528
  | `value` | `any` | | yes | Defines the value of the radio input. It can be any serializable value. |
529
- | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or string array: amber, in their own `aria-live` region, and in the control's `aria-describedby` after the errors. A non-empty list implies the warning state; errors win when both are set. |
529
+ | `warnings` | `string \| string[] \| undefined` | | | Warning messages under the field, a string or array: amber, in their own `aria-live` region and in the control's `aria-describedby` after the errors. Non-empty turns on the warning state; errors win when both are set. |
530
530
 
531
531
  ## Passthrough parts and states
532
532