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.
- package/bin/bitboss-ui.mjs +133 -12
- package/dist/ai/changelog.json +1 -1
- package/dist/ai/components.json +2 -2
- package/dist/ai/guides/ai-router.md +2 -2
- package/dist/ai/guides/design-tokens.md +46 -6
- package/dist/ai/guides/installation-and-plugin-setup.md +71 -5
- package/dist/ai/guides/migration/components/bb-alert.md +37 -0
- package/dist/ai/guides/migration/components/bb-avatar.md +47 -8
- package/dist/ai/guides/migration/components/bb-badge.md +23 -1
- package/dist/ai/guides/migration/components/bb-button.md +64 -0
- package/dist/ai/guides/migration/components/bb-checkbox-group.md +55 -1
- package/dist/ai/guides/migration/components/bb-date-picker-input.md +9 -2
- package/dist/ai/guides/migration/components/bb-dialog.md +121 -11
- package/dist/ai/guides/migration/components/bb-icon.md +42 -0
- package/dist/ai/guides/migration/components/bb-offcanvas.md +35 -1
- package/dist/ai/guides/migration/components/bb-rating.md +52 -1
- package/dist/ai/guides/migration/components/bb-select.md +48 -0
- package/dist/ai/guides/migration/components/bb-table.md +156 -10
- package/dist/ai/guides/migration/components/bb-tabs.md +79 -1
- package/dist/ai/guides/migration/components/bb-text-input.md +23 -1
- package/dist/ai/guides/migration/components/bb-toast.md +44 -10
- package/dist/ai/guides/migration/components/use-confirm.md +48 -13
- package/dist/ai/guides/migration/v2-to-v3.md +626 -108
- package/dist/ai/index.md +9 -9
- package/dist/ai/source/BbDialog.md +0 -3
- package/dist/ai/source/BbDropdown.md +24 -1
- package/dist/ai/source/BbDropdownGroup.md +24 -1
- package/dist/index.d.ts +2 -1
- package/dist/llms-full.txt +1814 -367
- package/dist/llms-medium.txt +82 -16
- package/dist/llms.txt +11 -11
- package/dist/styles.css +1 -1
- package/llms.txt +12 -12
- package/package.json +2 -1
- package/scripts/lib/validate-bb-markup.mjs +105 -17
|
@@ -17,39 +17,26 @@ the per-component guides under [`migration/components/`](./components/) —
|
|
|
17
17
|
only components with **functional** changes have one; if a component has no
|
|
18
18
|
guide there, nothing about it needs migration.
|
|
19
19
|
|
|
20
|
+
**Which version to migrate to.** v3 is still a prerelease, so install it by
|
|
21
|
+
dist-tag:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install bitboss-ui@beta
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`@beta` is the current v3 channel. Do **not** pin an exact alpha: the alpha line
|
|
28
|
+
is frozen and several of its version numbers were tagged but never published, so
|
|
29
|
+
`npm install bitboss-ui@3.0.0-alpha.8` fails outright with `ETARGET`. And a bare
|
|
30
|
+
`npm install bitboss-ui` resolves to **v2** — `@latest` stays on the 2.x line
|
|
31
|
+
until v3 goes stable. Verify with `npm ls bitboss-ui` before you change a single
|
|
32
|
+
file; if it reports `2.x`, nothing below applies.
|
|
33
|
+
|
|
20
34
|
**How to read the tables:** every row is a hard break — old names are gone,
|
|
21
35
|
with no alias and no deprecation shim. Where the break is _silent_ (the app
|
|
22
36
|
compiles and runs but behaves differently), the row is marked **⚠ silent**;
|
|
23
37
|
these are the rows you cannot find by waiting for errors, so grep for them
|
|
24
38
|
explicitly (section 8).
|
|
25
39
|
|
|
26
|
-
## For agents: surface what this guide misses
|
|
27
|
-
|
|
28
|
-
This guide is the contract for the upgrade. If during a migration you hit
|
|
29
|
-
something it does not cover, **do not silently work around it** — a quiet
|
|
30
|
-
workaround hides a gap that will bite the next project. Report it to the
|
|
31
|
-
user in your migration summary, clearly separated from the routine edits.
|
|
32
|
-
|
|
33
|
-
Reportable findings, in order of severity:
|
|
34
|
-
|
|
35
|
-
1. **An undocumented break** — v2 code that compiled or behaved one way and
|
|
36
|
-
changes in v3 without a matching entry here or in the component's guide.
|
|
37
|
-
2. **A mapping that doesn't hold** — you applied a documented old→new edit
|
|
38
|
-
and the result compiles but renders or behaves differently than the guide
|
|
39
|
-
promises.
|
|
40
|
-
3. **An ambiguity you had to guess on** — two plausible migrations for the
|
|
41
|
-
same v2 usage and the guide doesn't say which is intended.
|
|
42
|
-
4. **A pattern with no v3 home** — a v2 usage (prop combination, slot trick,
|
|
43
|
-
CSS hook) whose replacement you could not find at all.
|
|
44
|
-
|
|
45
|
-
For each finding include: the component, the exact v2 usage (snippet), what
|
|
46
|
-
you expected from the guide, and what actually happened. Recommend that the
|
|
47
|
-
user forwards it to the bitboss-ui maintainers so the guide gets a row —
|
|
48
|
-
these reports are how this document stays truthful.
|
|
49
|
-
|
|
50
|
-
Routine work — renames that behaved exactly as the tables say — belongs in
|
|
51
|
-
the normal summary, not in this report. The report is only for surprises.
|
|
52
|
-
|
|
53
40
|
## 0. Upgrade strategy — do it in this order
|
|
54
41
|
|
|
55
42
|
1. **Swap the setup** (section 1): install the build plugin and the runtime
|
|
@@ -135,11 +122,54 @@ Migration deltas, one by one:
|
|
|
135
122
|
|
|
136
123
|
| v2 | v3 |
|
|
137
124
|
| -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
138
|
-
| `import 'bitboss-ui/styles.css'` in the entry file | **Delete it.** The runtime plugin auto-injects styles (`injectStyles` defaults `true`). Keep a manual import only if you set `injectStyles: false
|
|
125
|
+
| `import 'bitboss-ui/styles.css'` in the entry file | **Delete it.** The runtime plugin auto-injects styles (`injectStyles` defaults `true`). Keep a manual import only if you set `injectStyles: false` — see the Tailwind exception below. |
|
|
139
126
|
| No build plugin | **Add `bitbossUi({ iconDir })`** to `vite.config.ts` (or the `bitboss-ui/nuxt` module). The app does not build without it — components import the virtual config module. |
|
|
140
127
|
| `app.use(BbTooltipDirectivePlugin)` / `app.use(BbDropdownDirectivePlugin)` | **Delete both.** `bitbossUiPlugin` registers `v-bb-tooltip` and `v-bb-dropdown` itself (opt out with `injectDirectives: false` if the names collide). |
|
|
141
128
|
| No reset stylesheet | Optional: `resetCss: true` or `import 'bitboss-ui/reset.css'`. Skip in Tailwind apps — Preflight already does this. |
|
|
142
129
|
| Icons registered by augmenting the `IconRegistry` type | **Gone** (the `IconRegistry` export no longer exists — see section 5). Drop `.svg` files into `iconDir` and reference them as `local:<name>`; provider icons (`lucide:*`, `mdi:*`, …) need the matching `@iconify-json/*` dev dependency. |
|
|
130
|
+
| A hand-rolled icon plugin doing `app.provide('icons', { … })` | **Delete it** and move the art into `iconDir`. See the shadowing warning below — this one is silent. |
|
|
131
|
+
|
|
132
|
+
### ⚠ silent — a hand-rolled `provide('icons', …)` is shadowed, not merged
|
|
133
|
+
|
|
134
|
+
`bitbossUiPlugin` provides the icon registry under two keys: a Symbol
|
|
135
|
+
(`bitboss-ui:icons`) and the legacy string key `'icons'` — the same key an app
|
|
136
|
+
icon plugin typically uses. `BbIcon` reads the **Symbol first**
|
|
137
|
+
(`inject(ICONS_INJECTION_KEY) ?? inject('icons')`), so once the library plugin
|
|
138
|
+
is installed your own `provide('icons', …)` map never wins. Any glyph that
|
|
139
|
+
existed only in that map stops resolving, and nothing warns. Move those SVGs
|
|
140
|
+
into `iconDir` and reference them as `local:<name>`.
|
|
141
|
+
|
|
142
|
+
App code that still calls `inject('icons')` now receives the **library's**
|
|
143
|
+
registry object, not yours. The string key is a one-release compatibility shim
|
|
144
|
+
— migrate those call sites off it or delete them.
|
|
145
|
+
|
|
146
|
+
### ⚠ Tailwind Preflight cannot load before the library when styles are injected
|
|
147
|
+
|
|
148
|
+
Auto-injection always puts the library sheet at the **top** of `<head>` — the
|
|
149
|
+
guaranteed order is reset → library styles → every other stylesheet, because
|
|
150
|
+
the injector inserts before the first existing `<style>` / `<link
|
|
151
|
+
rel="stylesheet">`. Preflight is an app sheet like any other, so it lands
|
|
152
|
+
_after_ the library and wins every specificity tie. There is no option to
|
|
153
|
+
inject later.
|
|
154
|
+
|
|
155
|
+
If your v2 app depended on the opposite order (the manual
|
|
156
|
+
`import 'bitboss-ui/styles.css'` placed after your Tailwind entry), keep the
|
|
157
|
+
manual import and turn injection off:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
// vite.config.ts
|
|
161
|
+
bitbossUi({ iconDir: './src/assets/icons', injectStyles: false });
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
// main.ts — the order is yours again
|
|
166
|
+
import './app.css'; // your Tailwind entry (@import 'tailwindcss')
|
|
167
|
+
import 'bitboss-ui/styles.css'; // after Tailwind, so library rules win the ties
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Leave `resetCss` at its `false` default here — Preflight already resets.
|
|
171
|
+
`injectStyles` controls only whether the library injects its own `<style>`;
|
|
172
|
+
nothing else about the plugin changes.
|
|
143
173
|
|
|
144
174
|
### Nuxt
|
|
145
175
|
|
|
@@ -270,24 +300,36 @@ scope instead.
|
|
|
270
300
|
explicitly.
|
|
271
301
|
- `--bb-radius` went `4px` → `8px`.
|
|
272
302
|
|
|
303
|
+
Six more tokens changed value **without changing name**, so they are invisible
|
|
304
|
+
to the rename map and to every grep below — see
|
|
305
|
+
["Tokens that kept their name but changed"](#tokens-that-kept-their-name-but-changed).
|
|
306
|
+
|
|
273
307
|
### Token rename map
|
|
274
308
|
|
|
275
|
-
| v2 override
|
|
276
|
-
|
|
|
277
|
-
| `--bb-primary-base`
|
|
278
|
-
| `--bb-contrasting` / `--bb-contrasting-dark`
|
|
279
|
-
| `--bb-panel-disabled`, `--bb-input-bg-secondary`
|
|
280
|
-
| `--bb-hint`, `--bb-icon-color`, `--bb-placeholder`, `--bb-prefix-color`, `--bb-muted-color`
|
|
281
|
-
| `--bb-input-color`, `--bb-input-bg`
|
|
282
|
-
| `--bb-input-font-size`, `--bb-input-mobile-font-size`
|
|
283
|
-
| `--bb-overlay-color` + `--bb-overlay-opacity`
|
|
284
|
-
| `--bb-overlay-z-index`
|
|
285
|
-
| `--bb-
|
|
286
|
-
| `--bb-dialog-px
|
|
287
|
-
| `--bb-
|
|
288
|
-
|
|
289
|
-
**
|
|
290
|
-
|
|
309
|
+
| v2 override | v3 replacement |
|
|
310
|
+
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
311
|
+
| `--bb-primary-base` | deleted — set `--bb-primary` directly |
|
|
312
|
+
| `--bb-contrasting` / `--bb-contrasting-dark` | `--bb-primary-fg` |
|
|
313
|
+
| `--bb-panel-disabled`, `--bb-input-bg-secondary` | `--bb-muted` |
|
|
314
|
+
| `--bb-hint`, `--bb-icon-color`, `--bb-placeholder`, `--bb-prefix-color`, `--bb-muted-color` | `--bb-text-muted` |
|
|
315
|
+
| `--bb-input-color`, `--bb-input-bg` | `--bb-text`, `--bb-panel` |
|
|
316
|
+
| `--bb-input-font-size`, `--bb-input-mobile-font-size` | `--bb-input-fs`, `--bb-input-fs-mobile` |
|
|
317
|
+
| `--bb-overlay-color` + `--bb-overlay-opacity` | `--bb-overlay` (one color with alpha) |
|
|
318
|
+
| `--bb-overlay-z-index` | `--bb-z-overlay` |
|
|
319
|
+
| _(no v2 equivalent)_ | `--bb-ease` — new in v3. v2 hard-coded seven different `cubic-bezier()` curves and exposed no easing token, so there is nothing to rename; set `--bb-ease` once if you want a house curve. |
|
|
320
|
+
| `--bb-dialog-px`, `--bb-dialog-py` | `--bb-panel-p` — **one value on both axes**, for dialogs and off-canvas alike. If your v2 px ≠ py, see "Asymmetric surface padding" below. |
|
|
321
|
+
| `--bb-dialog-close` | **delete it** — do not map it onto `.bb-close-button { --size }`; v3's default already reproduces the v2 control. See below. |
|
|
322
|
+
| `--bb-dialog-title-size` | the local `--dialog-title-fs` on `.bb-dialog` / `.bb-offcanvas` (default `calc(var(--bb-fs) + 2px)`) |
|
|
323
|
+
| `--bb-dialog-title-weight` | **no knob** — the title is hardcoded `font-weight: 500`. Override with a CSS rule, see below. |
|
|
324
|
+
| `--bb-button-h`, `--bb-button-icon`, `--bb-checkbox-*`, `--bb-radio-*`, `--bb-switch-*`, `--bb-rating-*`, `--bb-slider-*`, `--bb-table-cell-h`, `--bb-select-option-*` | **no longer global.** Component dimensions hang off `--bb-control-h`, `--bb-fs`, `--bb-radius`; anything finer is an unprefixed local on the component's own class — with one exception: `--bb-select-option-px/-py` have **no** v3 local, the listbox option's inline padding is a literal (`.bb-listbox__option { padding-inline: … }` in your own CSS). |
|
|
325
|
+
|
|
326
|
+
**`--bb-input-*` and `--bb-label-*` are NOT in the row above.** They are still
|
|
327
|
+
global v3 theme tokens, declared in `variables.css` and read across the whole
|
|
328
|
+
form family — do not delete them. Several changed their default value; the
|
|
329
|
+
drift table below lists which.
|
|
330
|
+
|
|
331
|
+
**When a v2 global becomes a component token, resize only what you use.** That
|
|
332
|
+
last row is the trap: a v2 global like `--bb-button-icon` had ONE value for
|
|
291
333
|
every button because v2 had no size scale. v3 does, so the same value now lives
|
|
292
334
|
in a per-size family (`--icon-size-xs … --icon-size-2xl`) that the size class
|
|
293
335
|
re-points. Two mistakes follow, and both were made on a real migration:
|
|
@@ -305,11 +347,173 @@ doctrine in `design-tokens.md` § "Overriding one from a consumer app". And chec
|
|
|
305
347
|
first whether the v2 value was a real customisation: if it merely restated v2's
|
|
306
348
|
default, the migration is to **delete it** and inherit the v3 scale.
|
|
307
349
|
|
|
350
|
+
**Asymmetric surface padding.** `--bb-panel-p` is a single value used on both
|
|
351
|
+
axes. If your v2 theme set `--bb-dialog-px` ≠ `--bb-dialog-py`, set
|
|
352
|
+
`--bb-panel-p` to the **horizontal** value (it also positions the close button)
|
|
353
|
+
and override the vertical with a normal `padding` rule on the part classes.
|
|
354
|
+
There is no `--bb-panel-px` / `--bb-panel-py` pair.
|
|
355
|
+
|
|
356
|
+
```css
|
|
357
|
+
/* v2: --bb-dialog-px: 24px; header --bb-dialog-py: 10px; body --bb-dialog-py: 20px */
|
|
358
|
+
.my-dialog {
|
|
359
|
+
--bb-panel-p: 24px; /* horizontal + close-button inset */
|
|
360
|
+
}
|
|
361
|
+
.my-dialog .bb-dialog__header {
|
|
362
|
+
padding-block: 10px 5px;
|
|
363
|
+
}
|
|
364
|
+
.my-dialog .bb-dialog__body .bb-dialog__body-content {
|
|
365
|
+
padding-block: 0 20px;
|
|
366
|
+
}
|
|
367
|
+
.my-dialog .bb-dialog__body:first-child .bb-dialog__body-content {
|
|
368
|
+
padding-top: 20px;
|
|
369
|
+
}
|
|
370
|
+
.my-dialog .bb-dialog__footer {
|
|
371
|
+
padding-block: 20px;
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Use `padding-block`, not the `padding` shorthand, so the horizontal half keeps
|
|
376
|
+
tracking `--bb-panel-p`. Specificity: the library rules are
|
|
377
|
+
`.bb-dialog .bb-dialog__header` (0,2,0), `.bb-dialog__body-content` (0,1,0) and
|
|
378
|
+
`.bb-dialog__body:first-child .bb-dialog__body-content` (0,2,1) — the
|
|
379
|
+
three-class app selectors above beat all of them. `BbOffCanvas` is identical
|
|
380
|
+
with `.bb-offcanvas__*`.
|
|
381
|
+
|
|
382
|
+
**`--px` and `--pt` are not dialog knobs.** `.bb-dialog` declares them, but
|
|
383
|
+
nothing in the dialog or off-canvas CSS reads them, and every component that
|
|
384
|
+
_does_ read `--px` (`BbButton`, `BbAlert`, `BbTooltip`, `BbBaseSlider`)
|
|
385
|
+
re-declares it on its own root class, so an ancestor value never reaches those
|
|
386
|
+
either. Setting `--px` on a dialog part is inert — it silently leaves the
|
|
387
|
+
horizontal padding at whatever `--bb-panel-p` resolves to.
|
|
388
|
+
|
|
389
|
+
If only the **vertical rhythm between parts** differs, the local `--dialog-gap`
|
|
390
|
+
(default `--bb-panel-p`) already does it without a padding rule: it drives the
|
|
391
|
+
gap below the body content and the footer's block padding on `.bb-dialog` and
|
|
392
|
+
`.bb-offcanvas`. It does **not** cover the header's top padding, or the body's
|
|
393
|
+
top padding in the headerless case — those still take `--bb-panel-p`.
|
|
394
|
+
|
|
395
|
+
**`--bb-dialog-close` maps to nothing — delete it.** In v2 it was the close
|
|
396
|
+
**icon** width (`12px`) and the button around it added `8px` of padding, so the
|
|
397
|
+
control was 28px. v3 inverts the relationship: `.bb-close-button { --size }` is
|
|
398
|
+
the whole control box and the icon is derived as `max(--size - 2 × --p, 10px)`.
|
|
399
|
+
Inside a dialog v3 already ships `--size: 28px; --p: 7px` (a 14px glyph) — the
|
|
400
|
+
same 28px control v2's default produced. Feeding v2's `12px` into `--size`
|
|
401
|
+
yields a **12×12px** control, well under the WCAG 2.5.8 minimum target size. If
|
|
402
|
+
you must match the old glyph exactly, widen the padding instead of shrinking
|
|
403
|
+
the box:
|
|
404
|
+
|
|
405
|
+
```css
|
|
406
|
+
/* 12px glyph, 28px control */
|
|
407
|
+
.my-dialog .bb-dialog__header > .bb-close-button {
|
|
408
|
+
--p: 8px;
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
That selector needs at least three classes to beat the library's
|
|
413
|
+
`.bb-dialog .bb-dialog__header > .bb-close-button` (0,3,0).
|
|
414
|
+
|
|
415
|
+
**`--bb-dialog-title-weight` has no v3 home.** The title is `font-weight: 500`,
|
|
416
|
+
hardcoded. Restore v2's `600` with a rule that outweighs the library's
|
|
417
|
+
`.bb-dialog .bb-dialog__header .bb-dialog__title` (0,3,0):
|
|
418
|
+
|
|
419
|
+
```css
|
|
420
|
+
.my-dialog .bb-dialog__header .bb-dialog__title {
|
|
421
|
+
font-weight: 600;
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
308
425
|
A complete v3 theme is typically two small blocks of ~10 declarations
|
|
309
426
|
(`--bb-primary`, `--bb-radius`, `--bb-control-h`, `--bb-panel`, `--bb-text`,
|
|
310
427
|
`--bb-border`, `--bb-danger`, …) — one in `:root, .light`, the changed knobs
|
|
311
428
|
again in `.dark`. If your v2 theme was long, most of it maps to "delete".
|
|
312
429
|
|
|
430
|
+
### Tokens that kept their name but changed
|
|
431
|
+
|
|
432
|
+
The rename map above is keyed by _the name you must change_. These tokens kept
|
|
433
|
+
their v2 name and stayed global, so they appear in no rename row and no grep
|
|
434
|
+
finds them — the only symptom is that the app renders differently.
|
|
435
|
+
|
|
436
|
+
**Values that drifted.** Same name, same meaning, new default:
|
|
437
|
+
|
|
438
|
+
| token | v2 | v3 |
|
|
439
|
+
| --------------------- | ------------------------------------- | ----------------------------------------------------------------------------- |
|
|
440
|
+
| `--bb-input-h` | `36px` | `32px` (via `--bb-control-h`) |
|
|
441
|
+
| `--bb-input-py` | `4px` | `3px` |
|
|
442
|
+
| `--bb-input-prefix-w` | `40px` | `20px` |
|
|
443
|
+
| `--bb-label-weight` | `400` | `500` |
|
|
444
|
+
| `--bb-ring-size` | `4px` | `2px` |
|
|
445
|
+
| `--bb-leading` | `24px` (`--bb-input-font-size` × 1.5) | `21px` (`--bb-input-fs` × 1.5, and `--bb-input-fs` is now `14px`, not `16px`) |
|
|
446
|
+
|
|
447
|
+
The consequence cuts both ways, which is what makes it easy to get wrong: an
|
|
448
|
+
app that **carried its v2 theme forward** keeps the v2 look (36px inputs, 4px
|
|
449
|
+
rings) and never sees v3's proportions; an app that **deleted its theme as
|
|
450
|
+
redundant** silently shifts to shorter inputs, half-width prefix columns and a
|
|
451
|
+
half-thickness focus ring. Re-check each of these six against the v3 default
|
|
452
|
+
and delete only the declarations that merely restated a **v2** default.
|
|
453
|
+
|
|
454
|
+
**A type that narrowed.** `--bb-ring-opacity` survives by name but v3 registers
|
|
455
|
+
it with `@property … syntax: '<percentage>'`:
|
|
456
|
+
|
|
457
|
+
| token | v2 form | v3 form | symptom |
|
|
458
|
+
| ------------------- | -------------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
459
|
+
| `--bb-ring-opacity` | unitless `0.25` / `0.4`, multiplied by `100%` internally | `25%` / `40%` — a `<percentage>` | ⚠ silent: a unitless override is invalid at computed-value time, so it is discarded and the token falls back to the registered `initial-value: 25%`. v3's own defaults are `15%` light / `40%` dark. |
|
|
460
|
+
|
|
461
|
+
Nothing reports this — not `vue-tsc`, not the eslint plugin, not
|
|
462
|
+
`npx bitboss-ui check` (none of them read CSS), and not the browser console:
|
|
463
|
+
an invalid registered-property value is not a parse error, so it logs nothing.
|
|
464
|
+
Grep your stylesheets for `--bb-ring-opacity` and confirm every value carries a
|
|
465
|
+
`%`.
|
|
466
|
+
|
|
467
|
+
Nine tokens are `@property`-registered in v3 — the eight color knobs
|
|
468
|
+
(`syntax: '<color>'`) plus `--bb-ring-opacity`. Each rejects values outside its
|
|
469
|
+
declared syntax the same silent way, so treat any future registration as the
|
|
470
|
+
same class of break.
|
|
471
|
+
|
|
472
|
+
### Button and variant skin colors moved the other way
|
|
473
|
+
|
|
474
|
+
The "no longer global" row sends per-component values _down_ into unprefixed
|
|
475
|
+
locals. The button **skin** colors went the opposite direction — up into global
|
|
476
|
+
theme tokens. In v2 a skin was four locals set on your own modifier class:
|
|
477
|
+
|
|
478
|
+
```css
|
|
479
|
+
/* v2 theming.css */
|
|
480
|
+
.bb-button--outline {
|
|
481
|
+
--color: #fff;
|
|
482
|
+
--border-color: #d1d5db;
|
|
483
|
+
--text-color: #111827;
|
|
484
|
+
/* hover / pressed / ring were derived from --color automatically */
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
v3 reads none of those — the old locals are inert, so a skin ported verbatim
|
|
489
|
+
silently reverts to the library defaults. Each variant has its own `--bb-*`
|
|
490
|
+
family, declared in `variables.css` and overridable globally or on any scope:
|
|
491
|
+
|
|
492
|
+
| v2 local on `.bb-button` | v3 token family (per variant) |
|
|
493
|
+
| -------------------------------------------- | ----------------------------------- |
|
|
494
|
+
| `--color` (fill) | `--bb-<variant>` |
|
|
495
|
+
| `--text-color` | `--bb-<variant>-fg` |
|
|
496
|
+
| `--border-color` | `--bb-<variant>-border` |
|
|
497
|
+
| `--ring-color` | `--bb-<variant>-ring` |
|
|
498
|
+
| _derived_ `mix(--color 90%, black)` on hover | `--bb-<variant>-hover` (explicit) |
|
|
499
|
+
| _derived_ `mix(--color 80%, black)` on press | `--bb-<variant>-pressed` (explicit) |
|
|
500
|
+
|
|
501
|
+
`<variant>` is one of `primary`, `secondary`, `outline`, `ghost`,
|
|
502
|
+
`destructive`, `link`. Note the last two rows: v2 _derived_ hover and pressed
|
|
503
|
+
from the fill, v3 states them. Porting only `--bb-outline` leaves the hover
|
|
504
|
+
state on the library's default.
|
|
505
|
+
|
|
506
|
+
```css
|
|
507
|
+
/* v3 equivalent of the block above */
|
|
508
|
+
:root {
|
|
509
|
+
--bb-outline: #fff;
|
|
510
|
+
--bb-outline-border: #d1d5db;
|
|
511
|
+
--bb-outline-fg: #111827;
|
|
512
|
+
--bb-outline-hover: #f3f4f6;
|
|
513
|
+
--bb-outline-pressed: #e5e7eb;
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
313
517
|
## 4. Variants: from `theme` strings and class overrides to typed registries
|
|
314
518
|
|
|
315
519
|
### What changed
|
|
@@ -326,6 +530,19 @@ v3 replaces all of that with per-component `variant` props whose types are
|
|
|
326
530
|
registers. An unregistered name is a **compile error** (v2's silent
|
|
327
531
|
render-unstyled behavior is gone by design), and the `theme` prop is gone.
|
|
328
532
|
|
|
533
|
+
**⚠ v2 shipped no variant CSS at all, so adopting a variant is additive.** Grep
|
|
534
|
+
the v2 stylesheet and the only `bb-button--*` rules are `group`, `icon` and
|
|
535
|
+
`loading`; there are no `bb-alert--*`, no appearance-level `bb-badge--*`, no
|
|
536
|
+
`bb-tooltip--*` and no `bb-toast-message--*` rules. v2's components _emitted_
|
|
537
|
+
those names (`bb-alert--${theme}`, `bb-tooltip--${theme}`,
|
|
538
|
+
`bb-toast-message--${theme}`) and the library never styled them. In v2 the
|
|
539
|
+
class and the `theme` string meant **"whatever your app's CSS says, and nothing
|
|
540
|
+
else."** In v3 every one of those names is a real skin, so converting hands the
|
|
541
|
+
library a styling role it did not have — wherever your CSS does not override
|
|
542
|
+
every property v3 sets (background, border, foreground, hover, pressed, focus
|
|
543
|
+
ring), the appearance drifts. Diff a screenshot; do not assume. Section 7
|
|
544
|
+
covers the class-to-prop rewrite itself.
|
|
545
|
+
|
|
329
546
|
Built-in sets and the class each name maps to:
|
|
330
547
|
|
|
331
548
|
| Plugin option | Built-in variants | Class hook |
|
|
@@ -339,6 +556,54 @@ Built-in sets and the class each name maps to:
|
|
|
339
556
|
| `dropdownItemVariants` | `default, destructive` | `bb-dropdown__item--variant-<name>` |
|
|
340
557
|
| `tooltipVariants` | `default, destructive` | `bb-tooltip--<name>` |
|
|
341
558
|
|
|
559
|
+
### Picking a v3 name for a v2 `theme` value
|
|
560
|
+
|
|
561
|
+
v2's `theme` was free-form, so most apps carry names that are not in the table
|
|
562
|
+
above (`error`, `danger`, `info`, `success`, `blue`, …). Work through it in
|
|
563
|
+
this order:
|
|
564
|
+
|
|
565
|
+
1. **Name is in the table, and your app never styled it** → use the built-in
|
|
566
|
+
`variant`. This is the only genuinely free conversion.
|
|
567
|
+
2. **Name is in the table, but your app styled it itself** → v3's built-in now
|
|
568
|
+
paints underneath your rules. Decide explicitly: accept v3's look and delete
|
|
569
|
+
your CSS, or register the name (`alertVariants: ['warning']`) so your CSS
|
|
570
|
+
stays the sole styling source.
|
|
571
|
+
3. **Name is not in the table** → register it and keep your CSS. **Do not remap
|
|
572
|
+
onto the "nearest" built-in.** `error → destructive`, `danger →
|
|
573
|
+
destructive`, `info → primary` all compile, all look plausible in review,
|
|
574
|
+
and all silently replace your palette with the library's. Remap only as a
|
|
575
|
+
deliberate redesign decision, never as a mechanical migration step.
|
|
576
|
+
4. **Name was never styled by anyone** → see the next subsection.
|
|
577
|
+
|
|
578
|
+
Registering is cheap — one array entry per name — and it is the
|
|
579
|
+
behaviour-preserving default. Prefer it whenever you are not sure.
|
|
580
|
+
|
|
581
|
+
### ⚠ silent — a `theme` value that did nothing in v2 may do something in v3
|
|
582
|
+
|
|
583
|
+
Because v2 shipped no variant CSS, unless your app defined the rule the `theme`
|
|
584
|
+
prop was **inert**: every value rendered the same default surface. In v3 the
|
|
585
|
+
same string is a live skin, and whether it stays inert depends entirely on
|
|
586
|
+
whether the name happens to collide with a v3 built-in:
|
|
587
|
+
|
|
588
|
+
```
|
|
589
|
+
both of these rendered an identical plain alert in v2:
|
|
590
|
+
|
|
591
|
+
<BbAlert theme="success" /> v3: not an alert built-in → compile error, you WILL notice
|
|
592
|
+
<BbAlert theme="warning" /> v3: built-in → silently becomes an amber alert, you will NOT
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
So two identical-looking v2 call sites migrate to opposite outcomes. Before
|
|
596
|
+
converting any `theme=` value, check whether _anything_ styled it in v2 — your
|
|
597
|
+
stylesheet, since the library did not. If nothing did, the value was
|
|
598
|
+
decoration:
|
|
599
|
+
|
|
600
|
+
- register it as an empty custom variant (`alertVariants: ['success', 'blue']`)
|
|
601
|
+
to hold v2's appearance exactly, or
|
|
602
|
+
- drop the prop entirely and let the v3 default apply, or
|
|
603
|
+
- convert it and accept the new look **on purpose**.
|
|
604
|
+
|
|
605
|
+
What you must not do is convert it mechanically and assume nothing moved.
|
|
606
|
+
|
|
342
607
|
### Custom variants are first-class
|
|
343
608
|
|
|
344
609
|
If your v2 app invented its own look (a `theme="brand"` or a hand-written
|
|
@@ -367,6 +632,12 @@ works with a visible cast (`variant="brand" as ButtonVariantType` won't
|
|
|
367
632
|
compile — cast the value, not the prop), but the registry is the intended
|
|
368
633
|
path.
|
|
369
634
|
|
|
635
|
+
**A name you keep as a plain class should not stay in the `bb-*` namespace.**
|
|
636
|
+
An app-minted `bb-button--pressed` or `bb-table--borderless` is squatting on
|
|
637
|
+
the library's prefix and collides the day the library ships that name. Either
|
|
638
|
+
register it as a variant, or rename it into your own prefix
|
|
639
|
+
(`app-button--pressed`). Section 7 has the decision table.
|
|
640
|
+
|
|
370
641
|
## 5. API-wide changes
|
|
371
642
|
|
|
372
643
|
These patterns repeat across many components. The per-component guides list
|
|
@@ -374,20 +645,22 @@ every occurrence; this section explains each pattern once.
|
|
|
374
645
|
|
|
375
646
|
### 5.1 Components renamed, split, or removed
|
|
376
647
|
|
|
377
|
-
| v2 | v3 | What to do
|
|
378
|
-
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
379
|
-
| `BbBadge` (floating count/dot anchored to an element) | **`BbIndicator`** | `content` → `text`, `color` → `variant`, `floating` removed. New `max` prop renders `${max}+`.
|
|
380
|
-
| `BbChip` | **removed** — use `BbBadge` | v3 `BbBadge` is the inline pill/token: same `click:clear` event and `clearableLabel`, but `clearable` is now **opt-in** (v2 chips defaulted clearable).
|
|
381
|
-
| — | **`BbBadge`** (repurposed) | The v3 badge is a new component in an old name: inline label with `variant`, `icon`, `loading`, `clearable`. Any v2 `<BbBadge>` you have is an _indicator_ — rename it.
|
|
382
|
-
| `BbTab` | **`BbTabs`** | Component and types renamed (`BbTabProps` → `BbTabsProps`; deprecated type aliases remain, the component name does not).
|
|
383
|
-
| `Base*` internals (`BaseButton`, `BaseDialog`, `BaseCheckbox`, `BaseTag`, …) | **`BbBase*`** | If you imported any base primitive or targeted its BEM block in CSS (`.base-btn` → `.bb-base-button`), rename. `BbBaseButton` is now a supported public export.
|
|
384
|
-
| `BbCheckboxIcon` / `BbRadioIcon` / `BbSwitchIcon` | **`BbBaseCheckboxIcon`** / **`BbBaseRadioIcon`** / **`BbBaseSwitchIcon`** | Rename import + BEM block (`.bb-checkbox-
|
|
385
|
-
| `BbBase*` input controls + `CommonInputWrapper` / `CommonInputOuterContainer` | **no longer exported** — use the full public component | v2 exposed the styled base inputs (`BbBaseTextInput`, `BbBaseSelect`, `BbBaseSwitch`, `BbBaseDatePickerInput`, …) and the input-chrome wrappers because a few full inputs were missing. v3 ships a full public component for every input, so these are internal now. Use `BbTextInput` / `BbSelect` / `BbSwitch` / … ; for a bare/inline control with no label gap, pass **`hideLabel`**. Still exported: `BbBaseButton` and the glyphs (`BbBaseCheckboxIcon` / `BbBaseRadioIcon` / `BbBaseSwitchIcon`). |
|
|
386
|
-
| `useWizard` (+ `Step`, `WizardState`, `wizardInjectionKey`) | **removed** | No replacement — it was unused scaffolding. Copy the v2 implementation into your app if you depended on it.
|
|
387
|
-
| `BbIntersection` (+ `BbIntersectionProps` / `BbIntersectionEvents`) | **removed** | No replacement — it wrapped `IntersectionObserver` in ~40 lines and carried no styling. Use `@vueuse/core`'s `useIntersectionObserver`, or copy the v2 component. Full mapping of the `shown`/`hidden`/`intersected` events and the slot props: [components/bb-intersection.md](./components/bb-intersection.md).
|
|
388
|
-
| `useBroadcastChannelInstance` | **removed** | Same reasoning: a typed wrapper over a browser API, no markup, no styling, used by no component here. Cross-tab messaging is app architecture. Use `useBroadcastChannel` from `@vueuse/core` — already in your tree, since this library depends on it. **Two behaviours do not carry over** (handler auto-removal on unmount, and the refcount the v2 docs described but never had): [components/use-broadcast-channel-instance.md](./components/use-broadcast-channel-instance.md).
|
|
389
|
-
| `
|
|
390
|
-
| `
|
|
648
|
+
| v2 | v3 | What to do |
|
|
649
|
+
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
650
|
+
| `BbBadge` (floating count/dot anchored to an element) | **`BbIndicator`** | `content` → `text`, `color` → `variant`, `floating` removed. New `max` prop renders `${max}+`. |
|
|
651
|
+
| `BbChip` | **removed** — use `BbBadge` | v3 `BbBadge` is the inline pill/token: same `click:clear` event and `clearableLabel`, but `clearable` is now **opt-in** (v2 chips defaulted clearable). |
|
|
652
|
+
| — | **`BbBadge`** (repurposed) | The v3 badge is a new component in an old name: inline label with `variant`, `icon`, `loading`, `clearable`. Any v2 `<BbBadge>` you have is an _indicator_ — rename it. |
|
|
653
|
+
| `BbTab` | **`BbTabs`** | Component and types renamed (`BbTabProps` → `BbTabsProps`; deprecated type aliases remain, the component name does not). |
|
|
654
|
+
| `Base*` internals (`BaseButton`, `BaseDialog`, `BaseCheckbox`, `BaseTag`, …) | **`BbBase*`** | If you imported any base primitive or targeted its BEM block in CSS (`.base-btn` → `.bb-base-button`), rename. `BbBaseButton` is now a supported public export. |
|
|
655
|
+
| `BbCheckboxIcon` / `BbRadioIcon` / `BbSwitchIcon` | **`BbBaseCheckboxIcon`** / **`BbBaseRadioIcon`** / **`BbBaseSwitchIcon`** | Rename import + BEM block (`.bb-base-checkbox-container__icon` → `.bb-base-checkbox-icon`; see §5.6). |
|
|
656
|
+
| `BbBase*` input controls + `CommonInputWrapper` / `CommonInputOuterContainer` | **no longer exported** — use the full public component | v2 exposed the styled base inputs (`BbBaseTextInput`, `BbBaseSelect`, `BbBaseSwitch`, `BbBaseDatePickerInput`, …) and the input-chrome wrappers because a few full inputs were missing. v3 ships a full public component for every input, so these are internal now. Use `BbTextInput` / `BbSelect` / `BbSwitch` / … ; for a bare/inline control with no label gap, pass **`hideLabel`**. Still exported: `BbBaseButton` and the glyphs (`BbBaseCheckboxIcon` / `BbBaseRadioIcon` / `BbBaseSwitchIcon`).<br><br>**These primitives were also restructured, not just un-exported.** The outer+inner pair merged into one `CommonInputWrapper` (`.common-input-wrapper` / `__inner`), `BbBaseInputContainer` gained an inner `__layout` element that now carries the orientation modifiers, and `__input` became `__control`. Anything anchored to the old DOM — app CSS, test selectors, JS positioning a floating panel off `.bb-base-input-container__input` — fails silently: nothing throws, the element is simply never found. See §5.6.<br><br>**Built a custom control on the chrome?** If your app composed `BaseInputContainer` + `CommonInputOuterContainer` + `CommonInputInnerContainer` around an element the library does not ship (a highlight-overlay textarea, a field with a bespoke floating panel), there is no public v3 component to swap in — those wrappers exist in v3 but are internal. The sanctioned fallback is to **copy** the chrome into your app from the implementation source that ships with the package: `node_modules/bitboss-ui/dist/ai/source/BbBaseInputContainer.md` and `dist/ai/source/CommonInputWrapper.md` carry the complete `.vue` template, `types.ts` and `index.css` for each (89 components have one). Those files are banner-marked "Reference Only - Internal" — that bans _importing_ the internal component, not copying its template and CSS into a component of your own, which is the supported route here. The class names a copied template emits are styled by the public `bitboss-ui/styles.css`, so it inherits library chrome for free. Check first whether v3 already ships what you built — `BbTimePickerInput` and `BbTimePicker` are new in v3. |
|
|
657
|
+
| `useWizard` (+ `Step`, `WizardState`, `wizardInjectionKey`) | **removed** | No replacement — it was unused scaffolding. Copy the v2 implementation into your app if you depended on it. |
|
|
658
|
+
| `BbIntersection` (+ `BbIntersectionProps` / `BbIntersectionEvents`) | **removed** | No replacement — it wrapped `IntersectionObserver` in ~40 lines and carried no styling. Use `@vueuse/core`'s `useIntersectionObserver`, or copy the v2 component. Full mapping of the `shown`/`hidden`/`intersected` events and the slot props: [components/bb-intersection.md](./components/bb-intersection.md). |
|
|
659
|
+
| `useBroadcastChannelInstance` | **removed** | Same reasoning: a typed wrapper over a browser API, no markup, no styling, used by no component here. Cross-tab messaging is app architecture. Use `useBroadcastChannel` from `@vueuse/core` — already in your tree, since this library depends on it. **Two behaviours do not carry over** (handler auto-removal on unmount, and the refcount the v2 docs described but never had): [components/use-broadcast-channel-instance.md](./components/use-broadcast-channel-instance.md). |
|
|
660
|
+
| `BbRatio` (+ `BbRatioProps`, `.bb-ratio`) | **removed** | No replacement — it was a one-rule wrapper. Use the `aspect-ratio` CSS property, or copy the v2 component. |
|
|
661
|
+
| `useQueue`, `useQuery` | **removed** | Both were public v2 exports and neither has a v3 equivalent; the import fails at build. Copy the v2 implementations out of the 2.1.135 tarball (`dist/composables/useQueue.d.ts`, `useQuery.d.ts`) into your app, or replace them with `@vueuse/core` equivalents. |
|
|
662
|
+
| `BbToastMessage` type export | **removed** | Use `BbToastOptions` (the `toast()` options shape). |
|
|
663
|
+
| `IconRegistry` / `IconNameFromRegistry` exports | **removed** | Icon names are plain strings now. Local art goes in `iconDir` as `local:<name>`; delete your `IconRegistry` augmentation. |
|
|
391
664
|
|
|
392
665
|
### 5.2 The polarity wave: booleans now read as opt-in
|
|
393
666
|
|
|
@@ -409,7 +682,7 @@ to the new name (`hide-close`).
|
|
|
409
682
|
|
|
410
683
|
| Component(s) | v2 prop (default) | v3 prop (default) |
|
|
411
684
|
| -------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
412
|
-
| `BbAlert`, `BbDialog`, `BbOffCanvas` | `showClose` (`true`) | `hideClose` (`false`) — also
|
|
685
|
+
| `BbAlert`, `BbDialog`, `BbOffCanvas` | `showClose` (`true`) | `hideClose` (`false`) — also on `toast()` options, where v2 had `showClose` too and the same inversion applies (`showClose: false` → `hideClose: true`, `showClose: true` → delete). Genuinely **new** on `confirm()` options. |
|
|
413
686
|
| `BbTable` | `allowSelectAll` (`true`) | `disableSelectAll` (`false`) |
|
|
414
687
|
| `BbTabs` | `animateX` / `animateY` (`true`) | `disableAnimateX` / `disableAnimateY` (`false`) |
|
|
415
688
|
| `BbButton` | `autoLoading` (`false`) | `disableAutoLoading` (`false`) — **⚠ silent behavior flip:** async `@click` handlers now show the loading spinner and disable the button automatically. Pass `disable-auto-loading` to keep v2 behavior. |
|
|
@@ -424,16 +697,18 @@ to the new name (`hide-close`).
|
|
|
424
697
|
|
|
425
698
|
### 5.3 Straight renames
|
|
426
699
|
|
|
427
|
-
| Component | v2 | v3
|
|
428
|
-
| -------------------------------------------------- | --------------------------------- |
|
|
429
|
-
| `BbPagination`, `BbTabs` | `querykey` | `queryKey` — **⚠ silent**: a leftover `querykey` falls through to the DOM and the component uses the default key (`'page'` / `'tab'`), quietly moving your URL params.
|
|
430
|
-
| `BbTooltip` | `timeout` | `delay`
|
|
431
|
-
| `
|
|
432
|
-
| `
|
|
433
|
-
| `
|
|
434
|
-
| `
|
|
435
|
-
| `
|
|
436
|
-
| `
|
|
700
|
+
| Component | v2 | v3 |
|
|
701
|
+
| -------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
702
|
+
| `BbPagination`, `BbTabs` | `querykey` | `queryKey` — **⚠ silent**: a leftover `querykey` falls through to the DOM and the component uses the default key (`'page'` / `'tab'`), quietly moving your URL params. |
|
|
703
|
+
| `BbTooltip` | `timeout` | `delay` |
|
|
704
|
+
| `toast()`, `confirm()` options | `timeout` | `duration` — same meaning (ms before auto-dismiss). `toast()` throws on `duration <= 0`; on `confirm()` it resolves the promise `false` quietly and implies `autoClose: true`. |
|
|
705
|
+
| `useToast()` | `dismissAll()` | `dismiss()` with **no argument**. The v3 return shape is `{ toast, dismiss, update }`. |
|
|
706
|
+
| `BbIcon` | `type` (required) | `icon` |
|
|
707
|
+
| `BbColorPalette`, `BbColorInput` | `picker` | `eyeDropper` |
|
|
708
|
+
| `BbCheckboxGroup`, `BbRadioGroup`, `BbSwitchGroup` | `labelPosition` | `legendPosition` |
|
|
709
|
+
| `BbSelect` | `prefill: 'focus'` | `prefill: 'interaction'` (value rename; same default) |
|
|
710
|
+
| `BbToast` (host) | `placement` (e.g. `bottom-start`) | `position` (corner set: `top-left` … `bottom-right`) |
|
|
711
|
+
| `BbAlert`, `BbTooltip`, `toast()`, `confirm()` | `theme` | `variant` (typed — see section 4). On `confirm()` the v2 type was a free-form `theme?: string`; v3's is `ConfirmVariantType` (`default`, `destructive`). |
|
|
437
712
|
|
|
438
713
|
### 5.4 Removed props (no replacement needed — behavior became default or moved)
|
|
439
714
|
|
|
@@ -444,7 +719,18 @@ to the new name (`hide-close`).
|
|
|
444
719
|
- **`color` everywhere**: gone from `BbAvatar`, `BbIcon`, `BbSpinner`,
|
|
445
720
|
`BbCheckbox`, `BbRadio`, `BbSwitch`, `BbSlider`, `BbRating` and all three
|
|
446
721
|
groups. Components inherit `currentColor` / theme tokens; style via CSS or
|
|
447
|
-
the token knobs.
|
|
722
|
+
the token knobs. `BbAvatar`'s knobs are named: set **both** `--bg-color` and
|
|
723
|
+
`--text-color` on `.bb-avatar` (plus `--default-icon-color` for the built-in
|
|
724
|
+
icon fallback) — setting only the background leaves the initials painted
|
|
725
|
+
`--bb-primary-fg` on top of it.
|
|
726
|
+
|
|
727
|
+
```css
|
|
728
|
+
.team-avatar .bb-avatar {
|
|
729
|
+
--bg-color: #7c3aed;
|
|
730
|
+
--text-color: #fff;
|
|
731
|
+
}
|
|
732
|
+
```
|
|
733
|
+
|
|
448
734
|
- **`BbSelect`**: `showChevron` and `updateOnAnimationFrame` removed; the
|
|
449
735
|
`#chevron` slot and the four `#options:prepend/append(:outer)` slots are
|
|
450
736
|
gone (use the new `#header` / `#footer` panel slots). Same options-slot
|
|
@@ -468,7 +754,15 @@ to the new name (`hide-close`).
|
|
|
468
754
|
- **`BbPopover`**: `showClose`, `closeLabel`, `restoreFocus`, `block` removed —
|
|
469
755
|
render your own close affordance in the content (`#default="{ close }"`).
|
|
470
756
|
- **`BbDialog`**: `description`, `hideHeader`, `compact`, `overlayClasses`,
|
|
471
|
-
`panelClasses` removed (use the `header` slot and normal classes).
|
|
757
|
+
`panelClasses` removed (use the `header` slot and normal classes). The
|
|
758
|
+
`#description` and `#close` **slots** are gone too — v3's slot set is
|
|
759
|
+
`header | title | default | footer`, and a custom close control goes inside
|
|
760
|
+
`#header`, which replaces the whole default header including the ✕ (so
|
|
761
|
+
`hide-close` is not needed alongside it).
|
|
762
|
+
- **`BbOffCanvas`**: the same `description` prop and the same `#description` /
|
|
763
|
+
`#close` slots were removed, with the same replacements. The
|
|
764
|
+
`aria-describedby` wiring `description` used to provide is gone — put the
|
|
765
|
+
copy in the default slot.
|
|
472
766
|
- **`BbBreadcrumbs`**: string `divider` removed (slot-driven now);
|
|
473
767
|
`dividerWidth` default changed `5` → `16`.
|
|
474
768
|
- **`BbPagination`**: `loading` removed.
|
|
@@ -505,21 +799,161 @@ to the new name (`hide-close`).
|
|
|
505
799
|
- **`direction`** on inputs: the exported `InputDirection` union — keyword
|
|
506
800
|
typos now fail to compile; two-word ratio strings (`'1 2'`) still work.
|
|
507
801
|
|
|
508
|
-
### 5.
|
|
802
|
+
### 5.5b Fields added to public object types
|
|
509
803
|
|
|
510
|
-
|
|
804
|
+
An **added** optional field breaks a consumer as hard as a removed one, and the
|
|
805
|
+
error text does not say so. If your app intersects a library object type to
|
|
806
|
+
carry its own metadata — `BbTableColumn & { sortable?: string }` for a backend
|
|
807
|
+
sort key, say — the intersection does not widen the property, it **collapses**
|
|
808
|
+
it: `string & undefined` is `undefined`, and every column literal then fails
|
|
809
|
+
with
|
|
810
|
+
|
|
811
|
+
```
|
|
812
|
+
error TS2322: Type 'string' is not assignable to type 'undefined'.
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
which names neither the field nor the library. That one line is worth
|
|
816
|
+
searching your build log for. The fix is to rename your field (`sortKey`) or to
|
|
817
|
+
subtract the library's first:
|
|
818
|
+
`Omit<BbTableColumn, 'sortable'> & { sortable?: string }`.
|
|
819
|
+
|
|
820
|
+
The collision-prone additions in v3:
|
|
821
|
+
|
|
822
|
+
| type | added in v3 | hazard |
|
|
823
|
+
| ----------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
824
|
+
| `BbTableColumn` | `sortable?: boolean` | intersection collapse (above), **and** a behavior flip: v3 reads it as `!!column.sortable`, so a truthy sort-key string switches on the built-in header sort button. An app with its own sort UI then renders two. Strip the field at the `BbTable` boundary or rename it. |
|
|
825
|
+
| `BbTableColumn` | `rowClass?: ColumnClasses<Item>` | same collapse. Note this is the **column-level** field — the table-level `rowClass` prop is separate and both accumulate. |
|
|
826
|
+
| `BbDropdown` item | `description?: string` | collapse, plus it now renders as a second line on the item. |
|
|
827
|
+
| `BbDropdown` item | `group?: never`, `selectable?: never`, `multiple?: never` | harder than a collapse: these discriminate item-from-group, so `group: 'admin'` on a plain item literal is a **direct** type error, no intersection required. Rename the field or nest your metadata under one custom key. |
|
|
828
|
+
|
|
829
|
+
Everything else added in v3 lands on `*Props` / `*Slots` / internal projections
|
|
830
|
+
— shapes you pass or read rather than intersect — so this list is deliberately
|
|
831
|
+
short.
|
|
832
|
+
|
|
833
|
+
### 5.6 Renamed CSS blocks
|
|
511
834
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
835
|
+
If app CSS or test selectors target library internals, these blocks moved. This
|
|
836
|
+
is the complete set — a class-by-class diff of the v2 stylesheet against v3
|
|
837
|
+
leaves nothing else orphaned. All of it is **silent**: a selector on a class
|
|
838
|
+
nobody emits matches nothing and throws nothing.
|
|
839
|
+
|
|
840
|
+
**Input chrome**
|
|
841
|
+
|
|
842
|
+
| v2 | v3 |
|
|
843
|
+
| --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
844
|
+
| `.bb-common-input-inner-container` (+ `--clearable`, `__prefix`, `__suffix`, `__prepend-icon`, `__append-icon`) | `.common-input-wrapper` (+ the same suffixes) — modifiers `--active --compact --disabled --errors --loading --readonly --clearable --warnings` (note: no `bb-` prefix) |
|
|
845
|
+
| `.bb-common-input-outer-container` | merged away — the v2 outer/inner pair is one `.common-input-wrapper`, whose inner span is `.common-input-wrapper__inner` |
|
|
846
|
+
| `.bb-base-input-outer-container` (+ `--compact`) | merged into `.bb-base-input-container` (+ `--compact`) |
|
|
847
|
+
| `.bb-base-input-container__input` (+ `--left --center --right`) | `.bb-base-input-container__control` (+ the same modifiers) |
|
|
848
|
+
| `.bb-base-input-container--horizontal` / `--vertical` / `--reverse` (on the root) | `.bb-base-input-container__layout--horizontal` / `--vertical` / `--reverse` — v3 inserts an inner `__layout` element and the orientation modifiers moved onto it; the root keeps only state modifiers (`--disabled --errors --warnings --loading --readonly --compact --floating-label --inside-label` …) |
|
|
849
|
+
| `.bb-base-input-container--label-mode-floating` | `.bb-base-input-container--floating-label` |
|
|
850
|
+
| `.bb-base-input-container__errors-outer` | `.bb-base-input-container__errors-wrap` |
|
|
851
|
+
| `.bb-base-input-container__hint-container` | `.bb-base-input-container__hint-wrap` |
|
|
852
|
+
| `.base-btn`, `.base-btn--block`, … | `.bb-base-button*` |
|
|
853
|
+
| `.bb-base-checkbox-container` / `.bb-base-radio-container` / `.bb-base-switch-container` | `.bb-base-checkbox` / `.bb-base-radio` / `.bb-base-switch` (the `--disabled` modifier survives) |
|
|
854
|
+
| `.bb-base-checkbox-container__icon` / `.bb-base-radio-container__icon` / `.bb-base-switch-container__icon` (+ `__icon-thumb`) | `.bb-base-checkbox-icon` / `.bb-base-radio-icon` / `.bb-base-switch-icon` (+ `.bb-base-switch-icon__thumb`) |
|
|
855
|
+
| `.bb-cr-container*` — the shared checkbox/radio/switch group tree (root, `--vertical`, `__container`, `-option`, `-option__text`) | split into per-control blocks: `.bb-base-checkbox-group*` / `.bb-base-radio-group*` / `.bb-base-switch-group*`, same suffixes (`--warnings`, `__loading-container`, `__no-data-container`, `-option--selected` are new). **`BbRating` no longer shares the block** — use `.bb-base-rating__inner-container` / `.bb-base-rating__option`. |
|
|
856
|
+
|
|
857
|
+
**Dialogs, off-canvas, popovers**
|
|
858
|
+
|
|
859
|
+
| v2 | v3 |
|
|
860
|
+
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
861
|
+
| `.bb-base-dialog` (+ `--deny-close --fullscreen --open`, `__header __title __body __body-content __footer`) | `.bb-dialog` / `.bb-dialog__*` — 1:1 on every one of those |
|
|
862
|
+
| `.bb-base-dialog__close` / `__close-icon`, `.bb-offcanvas__close` / `__close-icon`, `.bb-popover__close` | `.bb-close-button` — one shared button, used by the dialog, the off-canvas and the popover alike |
|
|
863
|
+
| `.bb-common-popover--scrollable` | `.bb-popover__panel--scrollable` (the rest of `.bb-common-popover*` is unchanged) |
|
|
864
|
+
| `.bb-confirm__no` | **removed** — the cancel button is a plain `BbButton` with no class of its own. Restyle it through `no: { variant: … }` on the call, or through the root's `.bb-confirm--<variant>` modifier. `.bb-confirm__text` and `.bb-confirm__content` are unchanged and still the right targets for body copy. |
|
|
865
|
+
|
|
866
|
+
**Tabs** — the whole tree was renamed, and v2's block name was `bb-tab`, not
|
|
867
|
+
`bb-tabs`, so nothing of a v2 tab theme survives untouched:
|
|
868
|
+
|
|
869
|
+
| v2 | v3 |
|
|
870
|
+
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
871
|
+
| `.bb-tab` | `.bb-tabs` |
|
|
872
|
+
| `.bb-tab--vertical` / `--horizontal` | `.bb-tabs--vertical` / `--horizontal` (+ `.bb-tabs-list--vertical` / `--horizontal` on the strip) |
|
|
873
|
+
| `.bb-tab__label-boundary` | `.bb-tabs-list` |
|
|
874
|
+
| `.bb-tab__label-container` (+ `--no-transition`) | `.bb-tabs-list__tablist` (+ `--no-transition`) — the sliding active pill is still this element's `::before`, so a v2 `.bb-tab__label-boundary .bb-tab__label-container:before` rule becomes the single-class `.bb-tabs-list__tablist:before` |
|
|
875
|
+
| `.bb-tab__btn` (+ `--active`) | `.bb-tabs__trigger` (+ `--active`), with new inner `.bb-tabs__trigger-content` / `.bb-tabs__trigger-label` |
|
|
876
|
+
| `.bb-tab__pane` (+ `--shown`) | `.bb-tabs__pane` (+ `--shown`) |
|
|
877
|
+
| `.bb-tab__panes-container` | `.bb-tabs-panes` |
|
|
878
|
+
|
|
879
|
+
v2 had no full-width tab strip, so apps hand-rolled one (commonly a
|
|
880
|
+
`bb-tabs--full-width` class). v3 ships it: `<BbTabs block>` sets
|
|
881
|
+
`.bb-tabs--block` / `.bb-tabs-list--block` and gives the triggers equal widths.
|
|
882
|
+
Delete the hand-rolled modifier rather than porting it.
|
|
883
|
+
|
|
884
|
+
**Everything else**
|
|
885
|
+
|
|
886
|
+
| v2 | v3 |
|
|
887
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
888
|
+
| `.bb-chip*` | `.bb-badge*` (component replaced) |
|
|
889
|
+
| `.bb-badge*` used as a floating count/dot (`--dot --floating --positioned --left --bottom --empty`, `__wrapper`, `__content-container`) | `.bb-indicator*` (component renamed) |
|
|
890
|
+
| `.bb-color-palette__*` (canvas, canvas-thumb, canvas-wrap, controls, eyedropper, preview, preview--alpha, preview-wrap, slider-thumb, slider-track, slider-wrap, slider-wrap--alpha, sliders, swatch, swatch--active, swatch-group, swatches) | `.bb-base-color-palette__*` — 1:1 on every one |
|
|
891
|
+
| `.bb-toast--top-start` / `--top` / `--top-end` / `--bottom-start` / `--bottom` / `--bottom-end` | `.bb-toast--top-left` / `--top-center` / `--top-right` / `--bottom-left` / `--bottom-center` / `--bottom-right` (matching the `position` prop's corner set) |
|
|
892
|
+
| `.bb-toast-message__icon-container` | **removed** — style `.bb-toast-message__icon` directly |
|
|
893
|
+
| `.bb-tree--open` | `.bb-tree__node--expanded` |
|
|
894
|
+
| `.bb-tree-row` | `.bb-tree__row` |
|
|
895
|
+
| `.bb-tree-main-content` | `.bb-tree__content` |
|
|
896
|
+
| `.bb-dropdown-button__dropdown-chevron` | `.bb-dropdown-button__chevron` |
|
|
897
|
+
| `.bb-dropdown-button--loading` / `__content` / `__icon` / `__prepend-icon` / `__append-icon` | **removed** — the split button delegates to `BbButton`'s internals; target `.bb-button__*` inside it |
|
|
898
|
+
| `.bb-dropdown__wrapper` | **removed** — the extra wrapper element is gone |
|
|
899
|
+
| `.bb-select-popover__search-spinner` | `.bb-select-popover__search-icon` (one element, spinner state included) |
|
|
900
|
+
| `.bb-base-date-picker__header` (the tinted banner holding the month/year controls) | `.bb-base-date-picker__controls` (+ the inner `__nav-center`) — the banner is gone; the controls sit on the calendar surface. `__header-container` and `__header-cell` are unrelated and unchanged: they are the weekday row. |
|
|
901
|
+
| `.bb-base-date-picker__control` / `__year-control` | `.bb-base-date-picker__nav-btn` |
|
|
902
|
+
| `.bb-base-date-picker__month-button` / `__year-button` | `.bb-base-date-picker__heading-btn` (+ `--active`) |
|
|
903
|
+
| `.bb-base-date-picker__weekday` | `.bb-base-date-picker__header-cell` |
|
|
904
|
+
| `.bb-base-date-picker__monthday` | `.bb-base-date-picker__date` (+ the inner `__date-button`) |
|
|
905
|
+
| `.bb-base-date-picker__year-container` | `.bb-base-date-picker__year-selector` |
|
|
906
|
+
| `.bb-base-date-picker__header--hidden`, `__selected-day-label` | **removed** |
|
|
907
|
+
| `.bb-commabox-item--has-comma` | the select's comma list renders `.bb-base-select__comma-item` (`.bb-commabox-item` itself survives; `--has-comma` and `.bb-chipsbox-item--focused` do not) |
|
|
908
|
+
|
|
909
|
+
The date **input**'s own field tree (`.bb-base-date-picker-input__field`,
|
|
910
|
+
`__fields`, `__placeholder`, `__separator`, `__calendar-btn`) moved to a shared
|
|
911
|
+
`.bb-segmented-field__*` block — full table in
|
|
912
|
+
[bb-date-picker-input.md](./components/bb-date-picker-input.md).
|
|
913
|
+
|
|
914
|
+
**Removed with no counterpart:** `.bb-base-dialog--compact`,
|
|
915
|
+
`.bb-offcanvas--compact`, `.bb-base-textarea--compact` (compact now lives on
|
|
916
|
+
`.common-input-wrapper--compact`), `.bb-base-select--active` / `--compact` /
|
|
917
|
+
`__inner-wrapper` / `__input-container` (the select activator was rebuilt —
|
|
918
|
+
nearest hooks are `.bb-base-select__activator`, `__value`, `__display-value`;
|
|
919
|
+
`--shown` survives), `.bb-base-rating__option--highlighted` (v3 uses
|
|
920
|
+
`--filled` / `--empty`), `.bb-progress--horizontal` (`.bb-progress` /
|
|
921
|
+
`.bb-progress-bar` are the blocks), `.bb-ratio` (component removed).
|
|
922
|
+
|
|
923
|
+
### 5.7 Renamed custom properties the library WRITES
|
|
924
|
+
|
|
925
|
+
Section 3 covers the tokens you set. These are variables the library **writes
|
|
926
|
+
onto the DOM** at runtime for you to read — the usual reason to touch them is
|
|
927
|
+
nested-table column alignment. They all dropped the `bb-` prefix, and every one
|
|
928
|
+
of them is consumed through `var(name, fallback)`, so a v2 name silently
|
|
929
|
+
resolves to the fallback instead of failing.
|
|
930
|
+
|
|
931
|
+
| v2 | v3 |
|
|
932
|
+
| ----------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
933
|
+
| `--bb-table-{id}-track-{key}` | `--table-{id}-track-{key}` |
|
|
934
|
+
| `--bb-table-offset-start` / `-end` | `--offset-start` / `--offset-end` |
|
|
935
|
+
| `--bb-table-offset-internal-start` / `-end` | `--offset-internal-start` / `--offset-internal-end` |
|
|
936
|
+
| `--bb-table-fill` | `--fill` |
|
|
937
|
+
| `--bb-table-natural-width` | `--natural-width` |
|
|
938
|
+
| `--bb-select-popover-width` (on `.bb-select-popover`) | `--w` — and the supported path is now the `width` prop, not a CSS override |
|
|
939
|
+
| `--bb-icon-dimensions-w` (on `.bb-icon`) | `--w` |
|
|
940
|
+
| `--bb-breadcrumbs-flex-basis` / `-flex-grow` | `--flex-basis` / `--flex-grow` |
|
|
941
|
+
| `--bb-picker-preview-color` | `--picker-preview-color` |
|
|
942
|
+
|
|
943
|
+
A regex matching the old shape (`/--bb-table-[\w-]+-track/`) matches nothing in
|
|
944
|
+
v3. Search your app for `--bb-table-`, `--bb-select-popover-`,
|
|
945
|
+
`--bb-icon-dimensions-`, `--bb-breadcrumbs-` and `--bb-picker-` — none of those
|
|
946
|
+
names exist in v3 and all of them fail quietly. `--available-height`,
|
|
947
|
+
`--inner-width` and `--overlay-min-height` were dropped outright.
|
|
948
|
+
|
|
949
|
+
If you re-published track variables by hand to align a deeply nested table,
|
|
950
|
+
delete that code: `inherit-column-widths` takes a **table id**
|
|
951
|
+
(`inherit-column-widths="<ancestor-id>"`), not just `true`, and walks the whole
|
|
952
|
+
ancestor chain — it is not limited to the immediate parent.
|
|
519
953
|
|
|
520
954
|
## 6. Behavior changes you will feel at runtime
|
|
521
955
|
|
|
522
|
-
|
|
956
|
+
Nothing here fails to compile — these change what existing code does.
|
|
523
957
|
|
|
524
958
|
1. **`BbButton` tracks async click handlers by default.** An `async @click`
|
|
525
959
|
now disables the button and shows a spinner until it settles. Opt out per
|
|
@@ -545,7 +979,14 @@ No rename to grep for — these change what existing, still-compiling code does.
|
|
|
545
979
|
progress bar) instead of flashing to skeleton — and the rows and header go
|
|
546
980
|
`inert` during the refetch. Escape hatch: `interactive-while-loading`. The
|
|
547
981
|
`#loading` slot fires on the **first load only** now.
|
|
548
|
-
6. **
|
|
982
|
+
6. **A truthy column `sortable` switches on v3's own sort UI.** `BbTable` reads
|
|
983
|
+
the field as `!!column.sortable`, so a column carrying a backend sort key
|
|
984
|
+
(`sortable: 'created_at'`) renders the built-in header sort button and sets
|
|
985
|
+
`aria-sort` — an app with its own sort control then shows two. Sorting stays
|
|
986
|
+
a controlled model (`v-model:sort`), so nothing reorders on its own; the
|
|
987
|
+
button appears and emits. Strip or rename the field at the `BbTable`
|
|
988
|
+
boundary. The compile-time half of the same collision is in §5.5b.
|
|
989
|
+
7. **Dynamic slot names are normalized** via
|
|
549
990
|
`slotKey(key) = key.split(/\W+/g).join('_').toLowerCase()` in
|
|
550
991
|
`BbBreadcrumbs`, `BbTree`, `BbTabs`, and the date-picker day slots.
|
|
551
992
|
`#Order History` → `#order_history`. **⚠ silent**: a stale raw-key slot
|
|
@@ -554,15 +995,20 @@ No rename to grep for — these change what existing, still-compiling code does.
|
|
|
554
995
|
normalized slug (`?tab=In%20Review` → `?tab=in_review` — update deep links
|
|
555
996
|
and server code), and tab/panel DOM ids are normalized. Only `v-model` /
|
|
556
997
|
item `key` stay raw.
|
|
557
|
-
|
|
998
|
+
8. **Dialogs, popovers, dropdowns and selects open as bottom sheets on mobile**
|
|
558
999
|
by default (`adaptive`, default `true`). Set `adaptive: false` in the
|
|
559
1000
|
plugin, or per component, for v2-like floating behavior.
|
|
560
|
-
|
|
1001
|
+
9. **`confirm()` buttons**: default labels are localized (no more hard-coded
|
|
561
1002
|
"OK"/"Annulla") and footer buttons default to `md`.
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
1003
|
+
10. **`confirm()` closes itself now.** `autoClose` was opt-in in v2 — after
|
|
1004
|
+
`resolve`/`reject` the dialog stayed up until you called `close()`. In v3 it
|
|
1005
|
+
defaults to `true`. ⚠ silent: the promise settles exactly as before, the
|
|
1006
|
+
dialog just disappears. A multi-step flow that kept it open between steps
|
|
1007
|
+
has to pass `autoClose: false`.
|
|
1008
|
+
11. **Invalid enum-ish prop values** (`size`, `direction`, `BbSlider.labelMode`)
|
|
1009
|
+
now warn in dev and fall back to the documented default instead of
|
|
1010
|
+
rendering broken or throwing.
|
|
1011
|
+
12. **`BbTree` is a disclosure list, not an ARIA tree**: the unfulfilled
|
|
566
1012
|
`role="tree"` / `treeitem` / `aria-level` markup is gone, and a collapsed
|
|
567
1013
|
branch's children are now `inert` (out of the Tab order). Tests or CSS
|
|
568
1014
|
keyed on the removed roles match nothing — see
|
|
@@ -586,6 +1032,23 @@ These keep _rendering_ in v3 (the class hooks still exist), but they are now
|
|
|
586
1032
|
the wrong layer: they bypass the typed registry, silently drift when the
|
|
587
1033
|
library renames internals, and duplicate what a prop expresses. Convert them.
|
|
588
1034
|
|
|
1035
|
+
**But the conversion is additive, not neutral.** v2 shipped no variant CSS
|
|
1036
|
+
(§4): those class names carried your rules and nothing else. In v3 each one is
|
|
1037
|
+
a real skin, so every rewrite below slides the library's rules _underneath_
|
|
1038
|
+
yours — background, border, foreground, hover, pressed, focus ring. Wherever
|
|
1039
|
+
your CSS does not override all of them, the appearance drifts. Diff a
|
|
1040
|
+
screenshot; do not assume. Two consequences before you start:
|
|
1041
|
+
|
|
1042
|
+
- **Leaving the class alone is not a safe holding position.** `variant`
|
|
1043
|
+
defaults to `primary`, so in v3 `<BbButton class="bb-button--outline">`
|
|
1044
|
+
renders `bb-button--primary bb-button--outline` — the built-in skin and your
|
|
1045
|
+
class fighting in the cascade. For a pure class override, pass
|
|
1046
|
+
`variant="none"`; it is the one value that emits no variant class.
|
|
1047
|
+
- **A name that collides with a v3 built-in is the dangerous case, not the easy
|
|
1048
|
+
one.** If your app owned the look of `warning` / `destructive` / `secondary`,
|
|
1049
|
+
converting to the same-named `variant` hands that look to the library.
|
|
1050
|
+
Register the name as a custom variant (§4) to keep your CSS the only source.
|
|
1051
|
+
|
|
589
1052
|
### Finding them
|
|
590
1053
|
|
|
591
1054
|
Run in the consumer project:
|
|
@@ -596,34 +1059,54 @@ rg -n 'class="[^"]*bb-[a-z-]+--' --type vue
|
|
|
596
1059
|
rg -n ":class=\"[^\"]*'bb-[a-z-]+--" --type vue
|
|
597
1060
|
# free-form theme props (removed in v3)
|
|
598
1061
|
rg -n '(:?theme)=' --type vue
|
|
1062
|
+
# the same prop as an option-object key — toast()/confirm() live in .ts
|
|
1063
|
+
rg -n 'theme' --type ts --type js
|
|
599
1064
|
# raw component markup rebuilt from classes (no <BbX> tag on the same line)
|
|
600
1065
|
rg -n 'class="bb-(button|badge|alert|toast-message|tooltip|indicator)\b' --type vue
|
|
601
1066
|
```
|
|
602
1067
|
|
|
603
1068
|
### Correcting them
|
|
604
1069
|
|
|
605
|
-
| Found
|
|
606
|
-
|
|
|
607
|
-
| `<BbButton class="bb-button--outline">`
|
|
608
|
-
| `<BbAlert class="bb-alert--warning">` / v2 `theme="warning"`
|
|
609
|
-
| `class="bb-badge bb-badge--secondary"` on a `<span>`
|
|
610
|
-
| `bb-toast-message--success` styling / v2 `theme` on toasts
|
|
611
|
-
| `bb-tooltip--destructive`
|
|
612
|
-
| A **custom** modifier (`bb-button--brand`, any name not in section 4's table)
|
|
613
|
-
| A
|
|
1070
|
+
| Found | Rewrite as |
|
|
1071
|
+
| --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1072
|
+
| `<BbButton class="bb-button--outline">` | `<BbButton variant="outline">` (same for `secondary`, `ghost`, `destructive`, `link`) |
|
|
1073
|
+
| `<BbAlert class="bb-alert--warning">` / v2 `theme="warning"` | `<BbAlert variant="warning">` |
|
|
1074
|
+
| `class="bb-badge bb-badge--secondary"` on a `<span>` | `<BbBadge variant="secondary">` — the real component, not markup cosplay |
|
|
1075
|
+
| `bb-toast-message--success` styling / v2 `theme` on toasts | `toast({ variant: 'success' })` |
|
|
1076
|
+
| `bb-tooltip--destructive` | `<BbTooltip variant="destructive">` / `v-bb-tooltip="{ text, variant: 'destructive' }"` |
|
|
1077
|
+
| A **custom** modifier (`bb-button--brand`, any name not in section 4's table) | Register it: `buttonVariants: ['brand']` in the plugin, keep your CSS, pass `variant="brand"`. |
|
|
1078
|
+
| A modifier your app **styled itself**, whatever its name | Decide before you convert: accept v3's built-in look and delete your CSS, or register the name (§4) so your CSS stays the sole styling source. Converting silently does the former. |
|
|
1079
|
+
| A **state** modifier that stacks on a variant (`bb-button--pressed` alongside `bb-button--outline`) | Not convertible — `variant` holds exactly one value. Keep it a class and rename it out of `bb-*` (`app-button--pressed`). If it marks a real toggle, `v-model` on `BbButton` owns the state: it sets `aria-pressed` and emits `bb-button--active`, which the library deliberately leaves unstyled for you. |
|
|
1080
|
+
| A class that overrides _layout_, not look (widths, margins) | Leave it — classes remain the right tool for layout; variants own _appearance semantics_. |
|
|
614
1081
|
|
|
615
1082
|
Rule of thumb: if the class name encodes a **meaning** (state, emphasis,
|
|
616
1083
|
severity), it should be a variant; if it encodes **geometry**, it stays a
|
|
617
1084
|
class.
|
|
618
1085
|
|
|
1086
|
+
Whatever stays a class should not stay in the `bb-*` namespace. An app-minted
|
|
1087
|
+
`bb-table--borderless` or `bb-avatar--square` is squatting on the library's
|
|
1088
|
+
prefix — neither name has ever shipped, and the day one does, your rule and the
|
|
1089
|
+
library's collide silently. Rename them into your own prefix.
|
|
1090
|
+
|
|
619
1091
|
## 8. The silent-failure audit
|
|
620
1092
|
|
|
621
1093
|
Everything the compiler cannot catch, in one grep pass. Run each in the
|
|
622
1094
|
consumer project; every hit needs a decision, not necessarily a change.
|
|
623
1095
|
|
|
1096
|
+
Two surfaces have no other net. **Composable option objects live in `.ts`** —
|
|
1097
|
+
`toast({ … })` and `confirm({ … })` inside stores, interceptors and helpers —
|
|
1098
|
+
and neither gate reaches them: `npx bitboss-ui check` opens only `.vue` and
|
|
1099
|
+
`.md`, and the eslint plugin walks template ASTs. **Nothing reads CSS at all**,
|
|
1100
|
+
not the CLI, not eslint, not `vue-tsc`, not the browser console. The
|
|
1101
|
+
`--type ts --type js` lines and the token/class lines below are the whole
|
|
1102
|
+
safety net for those two. (ripgrep's `js` type already covers `*.vue`, so
|
|
1103
|
+
adding `--type vue` to them is redundant.)
|
|
1104
|
+
|
|
1105
|
+
**Props, slots and markup**
|
|
1106
|
+
|
|
624
1107
|
```bash
|
|
625
1108
|
rg -in 'querykey' # → queryKey (URL params silently move)
|
|
626
|
-
rg -n 'show-close|showClose' # → hide-close (inverted)
|
|
1109
|
+
rg -n 'show-close|showClose' # → hide-close (inverted) on BbAlert/BbDialog/BbOffCanvas and in toast() options, which had showClose in v2 too. On BbPopover and BbTooltip the close button is GONE: delete the prop, never rename it
|
|
627
1110
|
rg -n 'allow-select-all|allowSelectAll' # → disable-select-all, inverted
|
|
628
1111
|
rg -n 'auto-loading|autoLoading' # BbButton behavior flip / rename
|
|
629
1112
|
rg -n 'disabled-while-loading|disabledWhileLoading' # removed
|
|
@@ -633,11 +1116,11 @@ rg -n ':flip=|flip="' # → disable-flip on palette/select-p
|
|
|
633
1116
|
rg -n 'hide-arrow|show-arrow|arrow-padding|hideArrow|showArrow|arrowPadding' # removed off tooltips
|
|
634
1117
|
rg -n '<BbChip' # component removed → BbBadge clearable
|
|
635
1118
|
rg -n '<BbBadge' # v2 badges are v3 indicators — review each
|
|
636
|
-
rg -n '<BbTab
|
|
1119
|
+
rg -n '<BbTab\b' # → BbTabs (\b so a tag name alone on its line still matches, and <BbTabs does not)
|
|
637
1120
|
rg -n '#label-' # BbTabs label slot → #label:<slotKey>
|
|
638
|
-
rg -n 'reverse' --type
|
|
639
|
-
rg -n '
|
|
640
|
-
rg -
|
|
1121
|
+
rg -n 'reverse' --type ts --type js # BbRadio/BbSwitch default flipped
|
|
1122
|
+
rg -n 'timeout' --type vue # BbTooltip → delay (BbAvatar keeps timeout); no ':' so static attrs match too
|
|
1123
|
+
rg -nU '<BbIcon[^>]*type=' # → icon=, and prefix your own icons `local:` (bb-icon.md). -U so a multi-line tag matches
|
|
641
1124
|
rg -n '(icon|type)="[a-z][a-z0-9-]*"' # bare icon names in templates → `local:<name>` so the Iconify extension previews them
|
|
642
1125
|
rg -n 'allow-writing|allowWriting' # → disable-writing, inverted + new tokens
|
|
643
1126
|
rg -n 'show-chevron|showChevron|updateOnAnimationFrame|update-on-animation-frame' # removed
|
|
@@ -645,17 +1128,48 @@ rg -n 'label-position|labelPosition' # groups → legend-position
|
|
|
645
1128
|
rg -n 'prefill="focus"|prefill: .focus.' # → 'interaction'
|
|
646
1129
|
rg -n ':prefill="false"|prefill: false' # now search-first, not load-on-open
|
|
647
1130
|
rg -n 'role="tree|treeitem' # BbTree ARIA roles removed
|
|
648
|
-
rg -n '
|
|
1131
|
+
rg -n 'filter-by|filterBy' # function/string filterBy → string[] (camelCase spelling lives in .ts option objects)
|
|
649
1132
|
rg -n 'option:prepend|option:append|options:prepend|options:append|#chevron' # removed slots
|
|
650
1133
|
rg -n '<Bb(Checkbox|Radio|Switch|Slider|Rating|Avatar|Icon|Spinner)[^>]*color=' # removed color props
|
|
651
1134
|
rg -n 'disabled:' --type ts --type vue # item.disabled near option components → selectable
|
|
652
|
-
rg -n 'picker' --type
|
|
653
|
-
|
|
654
|
-
|
|
1135
|
+
rg -n 'picker' --type ts --type js # color input/palette → eye-dropper
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
**Composable option objects and imports (`.ts` / `.js`)**
|
|
1139
|
+
|
|
1140
|
+
```bash
|
|
1141
|
+
rg -n 'timeout' --type ts --type js # toast()/confirm() options → duration
|
|
1142
|
+
rg -n 'theme' --type ts --type js # toast()/confirm() options → variant
|
|
1143
|
+
rg -n 'dismissAll' # useToast().dismissAll() → dismiss() with no argument. useConfirm() has a NEW dismissAll — check which one each hit is
|
|
1144
|
+
rg -n 'autoClose|auto-close' # confirm(): opt-in in v2, default true in v3 (section 6)
|
|
1145
|
+
rg -n 'yesText|noText|onYes|onNo|hideHeader|setLoading' --type ts --type js # confirm() options collapsed into the yes/no configs
|
|
1146
|
+
rg -n 'BbTableColumn\s*&|DropdownItem\s*&' --type ts # intersections that collapse to `undefined` (§5.5b)
|
|
1147
|
+
rg -n "provide\('icons'|inject\('icons'" # a hand-rolled icon registry is shadowed, not merged, by the plugin's (section 1)
|
|
1148
|
+
rg -n 'IconRegistry|BbToastMessage|useWizard|useQueue|useQuery|useBroadcastChannelInstance|BaseButtonProps|BaseDialog' # removed exports
|
|
655
1149
|
rg -n 'setConfig' # only locale survives at runtime
|
|
656
|
-
rg -n -- '--bb-(contrasting|primary-base|hint|icon-color|input-|overlay-|button-|dialog-p)' # retired tokens
|
|
657
1150
|
```
|
|
658
1151
|
|
|
1152
|
+
**CSS: tokens and class names**
|
|
1153
|
+
|
|
1154
|
+
```bash
|
|
1155
|
+
rg -n -- '--bb-(contrasting|hint|icon-color|primary-(base|dark)|panel-(light|dark|disabled)|border-(light|dark|hover)|text-(light|dark|secondary|tertiary)|input-(color|compact-|font-size|inner-h|prefix(-px)?([^-a-zA-Z0-9]|$))|label-(size|compact-spacing-y)|overlay-(color|opacity|z-index)|dialog-|button-|badge-|checkbox-w|radio-space|switch-|rating-size|base-rating-spacing|slider-|table-|select-option-|select-popover-|progress-track|toast-m|breadcrumbs-|picker-|icon-dimensions-)' # every retired v2 token — v3 declares none of them (sections 3 and 5.7)
|
|
1156
|
+
rg -n -- '--bb-ring-opacity' # survives by name; every value must now carry a % (section 3)
|
|
1157
|
+
rg -n 'bb-base-dialog|bb-tab__|bb-tab--|bb-cr-container|bb-common-input-outer-container|bb-common-input-inner-container|bb-base-input-container__input|bb-base-(checkbox|radio|switch)-container|bb-tree-row|bb-tree-main-content|bb-confirm__no|bb-dropdown__wrapper|bb-offcanvas__close|bb-popover__close|bb-ratio' # renamed or deleted CSS blocks — nothing in v3 emits any of these (§5.6)
|
|
1158
|
+
rg -n 'bb-color-palette__' # → .bb-base-color-palette__*; only __popover survives under the old name
|
|
1159
|
+
rg -n 'bb-tabs--' # v3's own modifiers are --horizontal --vertical --block --compact --disabled; anything else is app-minted, and a hand-rolled full-width tab list is now <BbTabs block>
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
⚠ That first pattern is exact on purpose, and the near-misses are the point: a
|
|
1163
|
+
looser one (`input-`, `overlay-`, `dialog-p`) sweeps up tokens that are still
|
|
1164
|
+
live globals, and deleting those overrides shifts the layout silently. All of
|
|
1165
|
+
these survive in v3 under the same name — do not remove them because a pattern
|
|
1166
|
+
matched: `--bb-input-h`, `-px`, `-py`, `-icon`, `-spacing`, `-prefix-w`,
|
|
1167
|
+
`--bb-leading`, `--bb-label-spacing-x` / `-spacing-y`, `--bb-label-weight`,
|
|
1168
|
+
`--bb-ring-size`, `--bb-ring-opacity`, `--bb-arrow`, `--bb-radius`,
|
|
1169
|
+
`--bb-primary`, `--bb-panel`, `--bb-text`, `--bb-border`, `--bb-danger`,
|
|
1170
|
+
`--bb-ring`, `--bb-surface-hover` (and `--bb-overlay-blur`, new in v3). Six of
|
|
1171
|
+
them changed **default value** — the drift table in section 3 says which.
|
|
1172
|
+
|
|
659
1173
|
Also review, with no greppable signature: dialog/off-canvas **widths**
|
|
660
1174
|
(section 2), the **primary color** (section 3), `adaptive` bottom sheets on
|
|
661
1175
|
mobile (section 6), and any UX that relied on second-click-to-clear selects.
|
|
@@ -665,7 +1179,10 @@ mobile (section 6), and any UX that relied on second-click-to-clear selects.
|
|
|
665
1179
|
Detailed old→new tables and edit outlines live in
|
|
666
1180
|
[`migration/components/`](./components/). Components not listed have **no
|
|
667
1181
|
functional changes** — nothing to migrate beyond the family-wide notes above.
|
|
668
|
-
That no-migration set is: `BbNumberInput`, `BbTextarea`, `BbProgress
|
|
1182
|
+
That no-migration set is: `BbNumberInput`, `BbTextarea`, `BbProgress` — with
|
|
1183
|
+
one caveat: the family-wide CSS renames in §5.6 still reach them
|
|
1184
|
+
(`.bb-base-textarea--compact`, `.bb-progress--horizontal` and the input-chrome
|
|
1185
|
+
blocks all moved), so check your stylesheet even for these three.
|
|
669
1186
|
|
|
670
1187
|
`BbSmoothHeight` is **not** in it: its `tag` narrowed from any non-void element
|
|
671
1188
|
to `'div' | 'span'`, so anything else is now a compile error — see
|
|
@@ -684,3 +1201,4 @@ to `'div' | 'span'`, so anything else is now a compile error — see
|
|
|
684
1201
|
| Selects | [BbSelect](./components/bb-select.md) · [BbSelectPopover](./components/bb-select-popover.md) |
|
|
685
1202
|
| Choice controls | [BbCheckbox / BbRadio / BbSwitch](./components/bb-checkbox.md) · [the three groups](./components/bb-checkbox-group.md) |
|
|
686
1203
|
| Other inputs | [BbSlider](./components/bb-slider.md) · [BbRating](./components/bb-rating.md) · [BbTag](./components/bb-tag.md) · [BbDropzone](./components/bb-dropzone.md) |
|
|
1204
|
+
| Removed | [BbIntersection](./components/bb-intersection.md) · [useBroadcastChannelInstance](./components/use-broadcast-channel-instance.md) |
|