bitboss-ui 3.0.0-beta.0 → 3.0.0-beta.2

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 (35) hide show
  1. package/bin/bitboss-ui.mjs +133 -12
  2. package/dist/ai/changelog.json +1 -1
  3. package/dist/ai/components.json +2 -2
  4. package/dist/ai/guides/ai-router.md +2 -2
  5. package/dist/ai/guides/design-tokens.md +46 -6
  6. package/dist/ai/guides/installation-and-plugin-setup.md +71 -5
  7. package/dist/ai/guides/migration/components/bb-alert.md +37 -0
  8. package/dist/ai/guides/migration/components/bb-avatar.md +47 -8
  9. package/dist/ai/guides/migration/components/bb-badge.md +23 -1
  10. package/dist/ai/guides/migration/components/bb-button.md +64 -0
  11. package/dist/ai/guides/migration/components/bb-checkbox-group.md +55 -1
  12. package/dist/ai/guides/migration/components/bb-date-picker-input.md +9 -2
  13. package/dist/ai/guides/migration/components/bb-dialog.md +121 -11
  14. package/dist/ai/guides/migration/components/bb-icon.md +42 -0
  15. package/dist/ai/guides/migration/components/bb-offcanvas.md +35 -1
  16. package/dist/ai/guides/migration/components/bb-rating.md +52 -1
  17. package/dist/ai/guides/migration/components/bb-select.md +48 -0
  18. package/dist/ai/guides/migration/components/bb-table.md +156 -10
  19. package/dist/ai/guides/migration/components/bb-tabs.md +79 -1
  20. package/dist/ai/guides/migration/components/bb-text-input.md +23 -1
  21. package/dist/ai/guides/migration/components/bb-toast.md +44 -10
  22. package/dist/ai/guides/migration/components/use-confirm.md +48 -13
  23. package/dist/ai/guides/migration/v2-to-v3.md +626 -108
  24. package/dist/ai/index.md +9 -9
  25. package/dist/ai/source/BbDialog.md +0 -3
  26. package/dist/ai/source/BbDropdown.md +24 -1
  27. package/dist/ai/source/BbDropdownGroup.md +24 -1
  28. package/dist/index.d.ts +2 -1
  29. package/dist/llms-full.txt +1814 -367
  30. package/dist/llms-medium.txt +82 -16
  31. package/dist/llms.txt +11 -11
  32. package/dist/styles.css +1 -1
  33. package/llms.txt +12 -12
  34. package/package.json +2 -1
  35. package/scripts/lib/validate-bb-markup.mjs +105 -17
@@ -53,3 +53,67 @@ The `v-bb-tooltip` directive is registered by the runtime plugin (see the
53
53
  `<BbButton class="bb-button--outline">` → `<BbButton variant="outline">`.
54
54
  See [main guide §7](../v2-to-v3.md) for the full pattern and how to register
55
55
  custom variant names.
56
+
57
+ ## Skin colors: four locals became six theme tokens per variant
58
+
59
+ v2 shipped **no** variant CSS — `.bb-button--outline`, `--secondary`, `--ghost`
60
+ and friends had zero rules in the library sheet. If your app has buttons that
61
+ look like anything but the primary fill, your stylesheet built the skin, by
62
+ setting locals that `.bb-button` read:
63
+
64
+ ```css
65
+ /* v2 theming.css — you wrote this, and it was the whole variant */
66
+ .bb-button--outline {
67
+ --color: #fff;
68
+ --border-color: #d1d5db;
69
+ --text-color: #111827;
70
+ /* hover / pressed / focus were DERIVED from --color automatically */
71
+ }
72
+ ```
73
+
74
+ v3 reads none of those four names. Each variant paints from its own `--bb-*`
75
+ family, declared in `variables.css` and overridable globally or on any scope:
76
+
77
+ | v2 local on `.bb-button` | v3 |
78
+ | ------------------------------------------ | ------------------------ |
79
+ | `--color` (fill) | `--bb-<variant>` |
80
+ | `--text-color` | `--bb-<variant>-fg` |
81
+ | `--border-color` | `--bb-<variant>-border` |
82
+ | `--ring-color` | `--bb-<variant>-ring` |
83
+ | _derived_ `mix(--color 90%, black)`, hover | `--bb-<variant>-hover` |
84
+ | _derived_ `mix(--color 80%, black)`, press | `--bb-<variant>-pressed` |
85
+
86
+ `<variant>` is `primary`, `secondary`, `outline`, `ghost`, `destructive` or
87
+ `link`.
88
+
89
+ ⚠ Note the last two rows. v2 **derived** hover and pressed from the fill; v3
90
+ **states** them. Port only `--bb-outline` and the button keeps the library's
91
+ default hover, which will not be a shade of your color.
92
+
93
+ ```css
94
+ /* v3 equivalent of the v2 block above */
95
+ :root {
96
+ --bb-outline: #fff;
97
+ --bb-outline-border: #d1d5db;
98
+ --bb-outline-fg: #111827;
99
+ --bb-outline-hover: #f3f4f6;
100
+ --bb-outline-pressed: #e5e7eb;
101
+ }
102
+ ```
103
+
104
+ Silent by construction: a rule setting `--color` on `.bb-button` still parses,
105
+ still applies, and is read by nothing. `rg -n -- '--color|--text-color|--border-color|--ring-color'`
106
+ across your CSS and find the ones scoped to a button.
107
+
108
+ Don't confuse this with the `--bb-button-*` row in
109
+ [main guide §3](../v2-to-v3.md): the button's **dimensions** went down into
110
+ component locals, its **colors** went up into global theme tokens. Opposite
111
+ directions, same component.
112
+
113
+ ## `loading-text` was never a BbButton prop
114
+
115
+ Not in v2, not in v3. If you find `loading-text` on a v2 button it was landing
116
+ in `$attrs` and rendering nothing — delete it rather than looking for the
117
+ replacement. The prop is real on the list and group surfaces — `BbSelect`,
118
+ `BbCheckboxGroup`, `BbRadioGroup`, `BbTable`, `BbSelectPopover` — where it
119
+ carries over to v3 under the same name.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 'Migration v2→v3: BbCheckboxGroup / BbRadioGroup / BbSwitchGroup'
3
- summary: labelPosition renamed legendPosition, per-item disabled is now inert (use selectable), color and the option affix slots removed, BbRadioGroup's name no longer required.
3
+ summary: labelPosition renamed legendPosition, per-item disabled is now inert (use selectable), color and the option affix slots removed, BbRadioGroup's name no longer required, and the shared bb-cr-container CSS block split into one per group.
4
4
  ---
5
5
 
6
6
  # BbCheckboxGroup / BbRadioGroup / BbSwitchGroup — v2 → v3
@@ -53,3 +53,57 @@ unchanged.
53
53
  The `item.disabled` change is the dangerous one: nothing errors, options that
54
54
  used to render disabled simply become selectable. Grep item-building code for
55
55
  `disabled:` near these groups.
56
+
57
+ ## DOM: the shared `bb-cr-container` block split three ways
58
+
59
+ v2 rendered one prefix for all three groups — `bb-cr-container` ("checkbox /
60
+ radio") — so a rule written for one group hit all of them. v3 gives each group
61
+ its own block; the suffixes are otherwise identical.
62
+
63
+ | v2 | v3 (`{checkbox,radio,switch}`) |
64
+ | ------------------------------------- | ----------------------------------------- |
65
+ | `.bb-cr-container` | `.bb-base-{checkbox,radio,switch}-group` |
66
+ | `.bb-cr-container--horizontal` | `.bb-base-…-group--horizontal` |
67
+ | `.bb-cr-container--vertical` | `.bb-base-…-group--vertical` |
68
+ | `.bb-cr-container--errors` | `.bb-base-…-group--errors` |
69
+ | `.bb-cr-container__container` | `.bb-base-…-group__container` |
70
+ | `.bb-cr-container__loading-container` | `.bb-base-…-group__loading-container` |
71
+ | `.bb-cr-container__no-data-container` | `.bb-base-…-group__no-data-container` |
72
+ | `.bb-cr-container-option` | `.bb-base-…-group-option` |
73
+ | `.bb-cr-container-option__text` | `.bb-base-…-group-option__text` |
74
+ | — | `.bb-base-…-group--warnings` (new) |
75
+ | — | `.bb-base-…-group-option--selected` (new) |
76
+
77
+ Nothing in v3 renders any `bb-cr-container` class, and nothing warns — the rules
78
+ simply stop matching. **Grep your CSS and test selectors for `bb-cr-container`.**
79
+
80
+ One rule that used to cover three components is now three rules. If you were
81
+ relying on the shared prefix, group the selectors:
82
+
83
+ ```css
84
+ .bb-base-checkbox-group-option__text,
85
+ .bb-base-radio-group-option__text,
86
+ .bb-base-switch-group-option__text {
87
+ font-weight: 500;
88
+ }
89
+ ```
90
+
91
+ **`BbRating` is not in this family.** v2's stylesheet carried
92
+ `.bb-rating … .bb-cr-container__container` rules, but the component never
93
+ rendered those classes on either version — it has always used
94
+ `.bb-base-rating__inner-container` / `.bb-base-rating__option`. See
95
+ [bb-rating.md](./bb-rating.md).
96
+
97
+ ## `legend` is required — and always was
98
+
99
+ `legend: string` is a required prop on `BbCheckboxGroup`, `BbRadioGroup` and
100
+ `BbSwitchGroup` in **v2 and v3 alike** (v2 `dist/components/BbCheckboxGroup/types.d.ts`
101
+ declares `legend: string`, not `legend?`). If the upgrade surfaced missing-legend
102
+ errors across your app, that is a pre-existing bug the stricter v3 build made
103
+ visible — not a v3 break, and not something to "fix" as part of the upgrade.
104
+
105
+ Treat it as its own change, separately from the migration. One migration team
106
+ added `legend` to six groups mid-upgrade; supplying it let the generic `T`
107
+ resolve properly, which unblocked type inference on the whole subtree and
108
+ surfaced a cascade of unrelated downstream type errors. They reverted the lot.
109
+ Land the migration first, then add legends one component at a time.
@@ -133,8 +133,15 @@ friends, rename it:
133
133
  | `…__calendar-btn--active` | `.bb-segmented-field__trigger-btn--active` |
134
134
  | `.bb-base-date-picker-input__calendar-icon` | `.bb-segmented-field__trigger-icon` |
135
135
  | `…__calendar--sheet` | `.bb-base-time-picker-input__panel--sheet` (time input) |
136
- | `…__calendar`, `…__calendar--shown` | removed — they were styled nowhere |
137
- | `.bb-base-time-picker-input__clock-btn` | removed — use `.bb-segmented-field__trigger-btn` |
136
+ | `.bb-base-date-picker-input__inner-wrapper` | **removed** — see below |
137
+
138
+ `__inner-wrapper` has no v3 counterpart. It was a bare layout box
139
+ (`flex: auto; display: block`) between the input chrome and the fields; v3
140
+ drops the element and `.bb-segmented-field__fields` carries the layout. A rule
141
+ hanging off it stops matching with nothing to rename it to — delete it, and if
142
+ it was doing real work, move the declarations onto `__fields`.
143
+ | `…__calendar`, `…__calendar--shown` | removed — they were styled nowhere |
144
+ | `.bb-base-time-picker-input__clock-btn` | removed — use `.bb-segmented-field__trigger-btn` |
138
145
 
139
146
  **The block names are unchanged.** `.bb-base-date-picker-input` and
140
147
  `.bb-base-time-picker-input` are still the roots, so a rule that has to reach
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 'Migration v2→v3: BbDialog'
3
- summary: showClose inverted to hideClose, several presentation props removed, default widths changed, adaptive bottom sheet on mobile by default.
3
+ summary: 'showClose inverted to hideClose, several presentation props and the #close/#description slots removed, default widths changed, adaptive bottom sheet on mobile by default, --bb-dialog-* tokens replaced by --bb-panel-p plus locals.'
4
4
  ---
5
5
 
6
6
  # BbDialog — v2 → v3
@@ -10,16 +10,18 @@ v2's `BbDialog` was a re-export of `BaseDialog`; v3 makes it first-class
10
10
 
11
11
  ## Changes
12
12
 
13
- | v2 | v3 | Kind |
14
- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
15
- | `showClose?: boolean` (default `true`) | `hideClose?: boolean` (default `false`) | rename, polarity inverted |
16
- | `description` | removed | put it in the default slot / `header` slot |
17
- | `hideHeader` | removed | omit `title` and the header collapses; or use the `header` slot |
18
- | `compact` | removed | spacing is token-driven now (`--bb-panel-p`) |
19
- | `overlayClasses`, `panelClasses` (deprecated in v2) | removed | use normal `class` / CSS on `.bb-dialog*` |
20
- | `size?: 'sm' \| 'md' \| 'lg'` | `size?: Responsive<'xs'…'2xl' \| CSS length>` | widened — **but defaults changed, see below** |
21
- | `transitionDuration` default `300` | default `250` | visual |
22
- | — | `adaptive` (default from config, **on**), `offCanvasProps`, `stack`, `fullscreen`, `persistent`, `disabled`, `focusTarget`, `eager` | additive |
13
+ | v2 | v3 | Kind |
14
+ | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
15
+ | `showClose?: boolean` (default `true`) | `hideClose?: boolean` (default `false`) | rename, polarity inverted |
16
+ | `description` | removed | put it in the default slot / `header` slot |
17
+ | `#description` slot | removed | same — and the `aria-describedby` wiring goes with it |
18
+ | `#close` slot | removed | a custom close control goes inside `#header`, which replaces the default ✕ — no `hide-close` alongside it |
19
+ | `hideHeader` | removed | omit `title` and the header collapses; or use the `header` slot |
20
+ | `compact` | removed | spacing is token-driven now (`--bb-panel-p`) |
21
+ | `overlayClasses`, `panelClasses` (deprecated in v2) | removed | use normal `class` / CSS on `.bb-dialog*` |
22
+ | `size?: 'sm' \| 'md' \| 'lg'` | `size?: Responsive<'xs'…'2xl' \| CSS length>` | widened — **but defaults changed, see below** |
23
+ | `transitionDuration` default `300` | default `250` | visual |
24
+ | — | `adaptive` (default from config, **on**), `offCanvasProps`, `stack`, `fullscreen`, `persistent`, `disabled`, `focusTarget`, `eager` | additive |
23
25
 
24
26
  ## ⚠ The two silent ones
25
27
 
@@ -44,3 +46,111 @@ v2's `BbDialog` was a re-export of `BaseDialog`; v3 makes it first-class
44
46
  …
45
47
  </BbDialog>
46
48
  ```
49
+
50
+ ## CSS and tokens
51
+
52
+ The `--bb-dialog-*` family is gone. Padding comes from the shared
53
+ `--bb-panel-p`; the rest are unprefixed locals on `.bb-dialog` or plain CSS
54
+ rules. `BbOffCanvas` is identical throughout with `.bb-offcanvas__*` parts.
55
+
56
+ | v2 token | v3 |
57
+ | -------------------------------------------- | -------------------------------------------------------------------------------------- |
58
+ | `--bb-dialog-px` / `--bb-dialog-py` (`24px`) | `--bb-panel-p` (`16px`) — **one** value on both axes; asymmetry needs a CSS rule |
59
+ | `--bb-dialog-close` (`12px`) | **delete it** — v3's default already reproduces v2's control size |
60
+ | `--bb-dialog-title-size` (`18px`) | local `--dialog-title-fs` on `.bb-dialog`, default `calc(var(--bb-fs) + 2px)` = `16px` |
61
+ | `--bb-dialog-title-weight` (`600`) | no knob — `500` is hard-coded; override with a CSS rule |
62
+ | — | local `--dialog-gap`, default `--bb-panel-p` — the body↔footer vertical rhythm |
63
+
64
+ ### `--bb-dialog-close` → delete it
65
+
66
+ v2's `--bb-dialog-close` was the close **icon** width; the button around it
67
+ added `padding: 8px`, so the control measured `12 + 16 = 28px`. v3 inverts the
68
+ relationship: `.bb-close-button { --size }` is the whole control box and the
69
+ glyph is derived — `max(--size - 2 × --p, 10px)`. Inside a dialog v3 already
70
+ ships `--size: 28px; --p: 7px`, a 14px glyph in the same 28px control v2's
71
+ default produced.
72
+
73
+ So carrying the old number across shrinks the target: `--size: 12px` gives a
74
+ 12×12px control, well under the 24px WCAG 2.5.8 minimum. To get the old 12px
75
+ glyph back, widen the padding — never shrink the box:
76
+
77
+ ```css
78
+ /* 12px glyph, still a 28px control */
79
+ .my-dialog .bb-dialog__header > .bb-close-button {
80
+ --p: 8px;
81
+ }
82
+ ```
83
+
84
+ The library rule is `.bb-dialog .bb-dialog__header > .bb-close-button` (0,3,0),
85
+ so your selector needs three classes to win. A headerless dialog puts the ✕ at
86
+ `.bb-dialog__body:first-child .bb-dialog__body-content > .bb-close-button`.
87
+
88
+ ### The title
89
+
90
+ ```css
91
+ .my-dialog {
92
+ --dialog-title-fs: 18px; /* v2 --bb-dialog-title-size; drives line-height too */
93
+ }
94
+ .my-dialog .bb-dialog__header .bb-dialog__title {
95
+ font-weight: 600; /* v2 --bb-dialog-title-weight */
96
+ }
97
+ ```
98
+
99
+ There is no weight token in v3. `500` is hard-coded on
100
+ `.bb-dialog .bb-dialog__header .bb-dialog__title` (0,3,0), so match that
101
+ specificity — a two-class `.my-dialog .bb-dialog__title` loses.
102
+
103
+ ### Asymmetric padding
104
+
105
+ `--bb-panel-p` is a single value used on both axes; there is no
106
+ `--bb-panel-px`/`--bb-panel-py` pair. If your v2 theme set `--bb-dialog-px` ≠
107
+ `--bb-dialog-py`, set `--bb-panel-p` to the **horizontal** value (it also
108
+ positions the close button) and override the vertical with a `padding-block`
109
+ rule on the part classes.
110
+
111
+ ```css
112
+ /* v2: --bb-dialog-px: 24px; header --bb-dialog-py: 10px; body --bb-dialog-py: 20px */
113
+ .my-dialog {
114
+ --bb-panel-p: 24px; /* horizontal + close-button inset */
115
+ }
116
+ .my-dialog .bb-dialog__header {
117
+ padding-block: 10px 5px; /* the library halves the header's bottom padding */
118
+ }
119
+ .my-dialog .bb-dialog__body .bb-dialog__body-content {
120
+ padding-block: 0 20px;
121
+ }
122
+ .my-dialog .bb-dialog__body:first-child .bb-dialog__body-content {
123
+ padding-top: 20px;
124
+ }
125
+ .my-dialog .bb-dialog__footer {
126
+ padding-block: 20px;
127
+ }
128
+ ```
129
+
130
+ Use `padding-block`, not the `padding` shorthand, so the horizontal half keeps
131
+ tracking `--bb-panel-p`. Library selectors are `.bb-dialog .bb-dialog__header`
132
+ (0,2,0), `.bb-dialog__body-content` (0,1,0),
133
+ `.bb-dialog__body:first-child .bb-dialog__body-content` (0,2,1) and
134
+ `.bb-dialog .bb-dialog__footer` (0,2,0) — the three-class app rules above beat
135
+ all four.
136
+
137
+ ### `--dialog-gap`
138
+
139
+ If only the vertical rhythm _between parts_ differs, `--dialog-gap` does it
140
+ without a padding rule — it replaces `--bb-panel-p` in the body's bottom padding
141
+ and the footer's block padding:
142
+
143
+ ```css
144
+ .my-dialog {
145
+ --dialog-gap: 8px;
146
+ }
147
+ ```
148
+
149
+ It does **not** reach the header's top padding, any horizontal padding, or the
150
+ body's top padding in the headerless case; those still read `--bb-panel-p`.
151
+
152
+ ### `.bb-confirm`
153
+
154
+ `confirm()` renders through the same `.bb-dialog__*` parts, so everything above
155
+ reaches it. Its own button hooks changed — see
156
+ [use-confirm.md](./use-confirm.md).
@@ -26,6 +26,48 @@ Provider prefixes now require the matching `@iconify-json/<prefix>` dev
26
26
  dependency, and names must be **literal strings** (the build scans statically;
27
27
  dynamically assembled names won't be bundled).
28
28
 
29
+ ## Your own icon plugin is probably redundant now
30
+
31
+ Most v2 apps hand-rolled one, because v2 shipped no registry:
32
+
33
+ ```ts
34
+ // resources/js/plugins/icons.ts — the v2 shape: glob the SVG folder yourself,
35
+ // build a name → loader map, hand it to BbIcon under the string key.
36
+ const icons = import.meta.glob('../../assets/icons/*.svg', { as: 'raw' });
37
+ app.provide('icons', toRegistry(icons));
38
+ ```
39
+
40
+ v3 does both halves itself. The **build** plugin scans `iconDir` recursively
41
+ and turns every `.svg` into `local:<basename>`; the **runtime** plugin provides
42
+ that registry to `BbIcon`. If your plugin scanned the same folder and provided
43
+ it under `'icons'`, it is now duplicating both.
44
+
45
+ ⚠ It is not merely duplicate — it is **inert for `BbIcon`, silently**.
46
+ `bitbossUiPlugin` provides the registry under a Symbol
47
+ (`bitboss-ui:icons`) _and_ under the legacy string key `'icons'`, and `BbIcon`
48
+ reads `inject(Symbol.for('bitboss-ui:icons')) ?? inject('icons')`. The Symbol wins,
49
+ so your map is shadowed rather than merged. Any glyph that exists only in your
50
+ map stops rendering and nothing warns.
51
+
52
+ Check before you delete — the plugin is dead only if both hold:
53
+
54
+ 1. **Every SVG it registers also lives under `iconDir`.** Diff the two folders.
55
+ If the plugin globbed a different directory (`resources/js/icons`,
56
+ a package's `assets/`), move those files into `iconDir` first — otherwise
57
+ deletion and non-deletion both leave you with missing icons.
58
+ 2. **Nothing else injects `'icons'`.** `rg -n "inject\(['\"]icons['\"]\)"` — an
59
+ app component reading the map to render `<img>` or to enumerate names is
60
+ real usage, not `BbIcon` usage. It now receives whichever provide ran last
61
+ (yours, if you `app.use()` your plugin after `bitbossUiPlugin`), which is a
62
+ coin-flip you do not want to keep. Rewrite those call sites to import your
63
+ map as a plain module export — or, if what they want is the library's
64
+ registry, `inject(Symbol.for('bitboss-ui:icons'))`. The key is not exported
65
+ from the package, but it is a `Symbol.for`, so recreating it resolves the
66
+ same symbol.
67
+
68
+ The string key `'icons'` is a compatibility shim kept for one release. Do not
69
+ build on it.
70
+
29
71
  ## Prefix your own icons with `local:` while you are in there
30
72
 
31
73
  A v2 `type` naming an icon from your own `iconDir` was bare — `type="user-circle"`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 'Migration v2→v3: BbOffCanvas'
3
- summary: direction→side; showClose→hideClose; size defaults change; adaptive drawer configs unify on offCanvasProps.
3
+ summary: 'direction→side; showClose→hideClose; description and the #close/#description slots removed; size defaults change; adaptive drawer configs unify on offCanvasProps.'
4
4
  ---
5
5
 
6
6
  # BbOffCanvas — v2 → v3
@@ -11,6 +11,9 @@ summary: direction→side; showClose→hideClose; size defaults change; adaptive
11
11
  | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
12
12
  | `direction?: 'left' \| 'top' \| 'right' \| 'bottom'` (default `'left'`) | `side?: 'left' \| 'top' \| 'right' \| 'bottom'` (default `'left'`) | **⚠ silent** — a leftover `direction` is ignored and the panel falls back to `'left'` |
13
13
  | `showClose?: boolean` (default `true`) | `hideClose?: boolean` (default `false`) | rename, polarity inverted |
14
+ | `description?: string` | removed | put the copy in the default slot or own the header via `#header`; the `aria-describedby` wiring goes with it |
15
+ | `#description` slot | removed | same — nothing links body copy to the panel automatically now |
16
+ | `#close` slot | removed | a custom close control goes inside `#header`, see below |
14
17
  | `size?: 'sm' \| 'md' \| 'lg'` | `size?: Responsive<'xs'…'2xl' \| 'auto' \| CSS length>` | widened — **defaults changed**, same trap as BbDialog: v2 `{ sm: 384, md: 652, lg: 896 }` → v3 `{ xs: 320, sm: 384, md: 448, lg: 512, xl: 576, '2xl': 672 }`. Pin via `offCanvasDefaultSizes` if needed. |
15
18
  | — | `draggable`, `stack` / `stackGap`, `persistent`, `disabled`, `fullscreen`, `eager`, `focusTarget`, `title` | additive |
16
19
 
@@ -61,3 +64,34 @@ Pure rename — the `Partial<BbOffCanvasProps>` object is unchanged.
61
64
  ```
62
65
 
63
66
  Also silent on upgrade; `eslint --fix` auto-renames it.
67
+
68
+ ## `description` and `#close` are gone
69
+
70
+ v3's slot set is `header | title | default | footer` — no `#close`, no
71
+ `#description`, and no `description` prop. Same removal as
72
+ [BbDialog](./bb-dialog.md).
73
+
74
+ `description` copy moves into the default slot. Nothing wires
75
+ `aria-describedby` for you any more; add it yourself if a screen reader needs
76
+ the panel described rather than just labelled.
77
+
78
+ **`#header` replaces the ✕, so `hide-close` is redundant beside it.** The
79
+ default header renders `#title` + a `CloseButton`; providing `#header` replaces
80
+ both, which is why a custom close control belongs inside it. The slot receives
81
+ `{ titleId, close, title }` — put `titleId` on your title element to keep
82
+ `aria-labelledby` intact, and call `close` from your own control.
83
+
84
+ ```diff
85
+ - <BbOffCanvas v-model="open" title="Edit" :show-close="true">
86
+ - <template #close><SaveGuardIcon /></template>
87
+ - </BbOffCanvas>
88
+ + <BbOffCanvas v-model="open" title="Edit">
89
+ + <template #header="{ titleId, close, title }">
90
+ + <span :id="titleId" class="bb-offcanvas__title">{{ title }}</span>
91
+ + <button @click="guardUnsaved(close)"><SaveGuardIcon /></button>
92
+ + </template>
93
+ + </BbOffCanvas>
94
+ ```
95
+
96
+ A header renders when `title` is set **or** `#header` is provided, so the slot
97
+ alone is enough — you do not also need a `title`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 'Migration v2→v3: BbRating'
3
- summary: color removed; name no longer required.
3
+ summary: color removed; name no longer required; the star state modifier renamed --highlighted to --filled/--empty; --bb-rating-size demoted to a local --size; input-position finally works.
4
4
  ---
5
5
 
6
6
  # BbRating — v2 → v3
@@ -22,3 +22,54 @@ summary: color removed; name no longer required.
22
22
 
23
23
  Adding `clearable` is recommended: the old "re-click to clear" folklore is
24
24
  now a visible affordance.
25
+
26
+ `legend` is required here too, in v2 as in v3 — see the note in
27
+ [bb-checkbox-group.md](./bb-checkbox-group.md); a missing one is a pre-existing
28
+ bug, not an upgrade break.
29
+
30
+ ## DOM
31
+
32
+ The block name is unchanged; the star's state modifier is not.
33
+
34
+ | v2 | v3 |
35
+ | -------------------------------------- | ------------------------------------------------------- |
36
+ | `.bb-base-rating__option--highlighted` | `.bb-base-rating__option--filled` / `--empty` |
37
+ | — | `.bb-base-rating__option--disabled`, `--readonly` (new) |
38
+ | — | `.bb-base-rating--warnings`, `--forced-clear` (new) |
39
+
40
+ v2 styled unfilled stars with `:not(--highlighted)`; v3 gives them a positive
41
+ name. Everything else survives unchanged: `.bb-base-rating`, `--disabled`,
42
+ `--errors`, `--readonly`, `--has-value`, `__inner-container`, `__option`,
43
+ `__label-text`. Nothing warns — a `--highlighted` rule just stops matching.
44
+
45
+ `BbRating` is not part of the checkbox/radio/switch `bb-cr-container` tree, and
46
+ was not in v2 either despite v2 shipping rules that said otherwise (below).
47
+ Target `.bb-base-rating__inner-container` and `.bb-base-rating__option`.
48
+
49
+ ## `input-position="right"` / `"center"` now does something
50
+
51
+ v2 shipped the alignment rules under `.bb-rating … .bb-cr-container__container`
52
+ — a class `BbRating` never rendered (its container was already
53
+ `.bb-base-rating__inner-container`). So the prop was accepted and typed on both
54
+ versions but was a **no-op in v2**. v3 repoints the rules at the element the
55
+ component actually renders.
56
+
57
+ If your app worked around the dead prop with a hand-rolled alignment rule, that
58
+ rule now fights the library's. Delete the workaround and keep the prop.
59
+
60
+ ## Tokens
61
+
62
+ `--bb-rating-size` was a `:root` global in v2, read as
63
+ `.bb-base-rating { --size: var(--bb-rating-size) }`. v3 drops the global and
64
+ hard-defaults the local:
65
+
66
+ ```diff
67
+ - :root { --bb-rating-size: 32px; }
68
+ + .bb-base-rating { --size: 32px; }
69
+ ```
70
+
71
+ Set it on `.bb-base-rating` itself (or on a rule that also matches it) — the
72
+ local is declared on that block, so a value inherited from an ancestor is
73
+ overridden before it is read. `--spacing` (star gap) is the companion local;
74
+ v2's `--bb-base-rating-spacing` was referenced but never declared anywhere in
75
+ the shipped sheet, so it never worked.
@@ -93,3 +93,51 @@ Applies to every surface built on the select engine — `BbSelect`,
93
93
  `BbSelectPopover`, and the flat/grouped listboxes. **Grep for
94
94
  `autocomplete-option` in your CSS and test selectors**; nothing warns, the rules
95
95
  simply stop matching.
96
+
97
+ ## Tokens: `--bb-select-option-px` / `--bb-select-option-py` are gone
98
+
99
+ v2 declared both on `:root` (`16px` / `8px`) and read them in the option row, the
100
+ group header and the no-results row. v3 declares neither, and — unlike most of
101
+ the retired component globals — **nothing replaced them with a local**.
102
+ `.bb-listbox__option` hard-codes its inline padding:
103
+
104
+ ```css
105
+ /* src/components/BbSelectPopover/index.css */
106
+ .bb-listbox__option {
107
+ height: var(--option-h);
108
+ padding-left: 0.5rem;
109
+ padding-right: 0.5rem;
110
+ }
111
+ ```
112
+
113
+ So `--bb-select-option-px`, and the `--px` local you might expect by analogy with
114
+ `BbButton` or `BbDialog`, are both silent no-ops — no rule in the select tree
115
+ reads either. Override with a plain declaration instead. The library's rule is
116
+ six classes deep, so a two-class app rule loses the cascade; match the chain or
117
+ force it:
118
+
119
+ ```css
120
+ /* specificity-matched — needs your sheet to load after the library's */
121
+ .bb-select-popover
122
+ .bb-listbox
123
+ .bb-listbox__outer-container
124
+ .bb-listbox__inner-container
125
+ span[role='listbox']
126
+ .bb-listbox__option {
127
+ padding-inline: 1rem;
128
+ }
129
+
130
+ /* or, order-independent */
131
+ .bb-listbox__option {
132
+ padding-inline: 1rem !important;
133
+ }
134
+ ```
135
+
136
+ Row **height** is not yours to set in CSS. `--option-h` reads `--option-height`,
137
+ which the component writes inline because the same number feeds the
138
+ virtualizer's `estimateSize`; a CSS override desynchronises the paint from the
139
+ scroll math and the list mispositions. Use `item-height` / `header-height` (or
140
+ `compact`) instead — they move both halves together.
141
+
142
+ The panel is teleported, so a wrapper class on your `<BbSelect>` does not reach
143
+ it — scope on `.bb-select-popover` or on the surrounding page/theme class.