bitboss-ui 3.0.0-beta.4 → 3.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -29
- package/dist/ai/BbBadge.md +10 -5
- package/dist/ai/BbSelect.md +8 -0
- package/dist/ai/BbTable.md +257 -51
- package/dist/ai/changelog.json +86 -2
- package/dist/ai/components.json +25 -15
- package/dist/ai/guides/design-language.md +14 -14
- package/dist/ai/guides/design-tokens.md +25 -18
- package/dist/ai/guides/installation-and-plugin-setup.md +1 -1
- package/dist/ai/guides/migration/components/bb-dialog.md +35 -29
- package/dist/ai/guides/migration/components/bb-table.md +406 -28
- package/dist/ai/guides/migration/v2-to-v3.md +175 -75
- package/dist/ai/index.md +1 -1
- package/dist/ai/recipes/inertia/layout-scaffold.md +5 -1
- package/dist/ai/recipes/inertia/ownership-atlas.md +41 -20
- package/dist/ai/recipes/inertia/records-workspace.md +26 -7
- package/dist/ai/recipes/nuxt/layout-scaffold.md +5 -1
- package/dist/ai/recipes/nuxt/records-workspace.md +26 -7
- package/dist/ai/recipes/vue/layout-scaffold.md +5 -1
- package/dist/ai/recipes/vue/records-workspace.md +26 -7
- package/dist/ai/source/BbBaseInputContainer.md +26 -0
- package/dist/ai/source/BbBreadcrumbs.md +31 -0
- package/dist/ai/source/BbDialog.md +15 -9
- package/dist/ai/source/BbOffCanvas.md +17 -11
- package/dist/ai/source/BbProgress.md +2 -2
- package/dist/ai/source/BbTable.md +837 -787
- package/dist/ai/source/CommonInputWrapper.md +4 -0
- package/dist/components/BbPagination/BbPagination.vue.d.ts +1 -1
- package/dist/components/BbTable/BbTable.vue.d.ts +5 -2
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +439 -484
- package/dist/components/BbTable/types.d.ts +83 -21
- package/dist/components/BbTable/utils.d.ts +18 -3
- package/dist/components/BbTable/utils.js +36 -28
- package/dist/index.d.ts +5 -1
- package/dist/index.js +68 -67
- package/dist/llms-full.txt +1065 -265
- package/dist/llms-medium.txt +15 -15
- package/dist/llms.txt +1 -1
- package/dist/styles.css +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/dist/assets/svgs/sort.svg_raw.js +0 -4
package/dist/ai/changelog.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"library": "bitboss-ui",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.8",
|
|
5
5
|
"upgrade": "v2-to-v3",
|
|
6
6
|
"guide": "ai/guides/migration/v2-to-v3.md",
|
|
7
7
|
"summary": {
|
|
8
8
|
"renames": 9,
|
|
9
|
-
"behaviourBreaks":
|
|
9
|
+
"behaviourBreaks": 43
|
|
10
10
|
},
|
|
11
11
|
"breaking": [
|
|
12
12
|
{
|
|
@@ -279,6 +279,90 @@
|
|
|
279
279
|
"description": "BbTable #no-data fills the table's own full-width <td> (was: the slot replaced the empty-state <tr>)",
|
|
280
280
|
"ruling": "F#/no-data-shell",
|
|
281
281
|
"guide": "components/bb-table.md"
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
"kind": "behaviour",
|
|
285
|
+
"description": "BbTable row events click:row / contextmenu:row / dblclick:row emit (event, item) with item the RAW record (was the internal row wrapper with the record at row.item) and no trailing selected boolean",
|
|
286
|
+
"ruling": "owner 2026-08-25, plans/BBTABLE-GRID.md",
|
|
287
|
+
"guide": "components/bb-table.md § Row events"
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"kind": "behaviour",
|
|
291
|
+
"description": "BbTable: hiding a column with thClass/tdClass + display: none (the v2/early-v3 narrow-screen recipe) no longer works — a hidden grid item keeps its track and shifts the following cells; remove the column from columns instead",
|
|
292
|
+
"ruling": "grid substrate, plans/BBTABLE-GRID.md",
|
|
293
|
+
"guide": "components/bb-table.md § Do not override; guide § Narrow screens"
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"kind": "behaviour",
|
|
297
|
+
"description": "BbTable renders a CSS grid of divs with ARIA roles, not a <table>: every element selector under .bb-table (table/thead/tbody/tfoot/caption/tr/th/td/colgroup/col) matches nothing. Every .bb-table* class survives; .bb-table__table/__head/__body/__foot + [role=row]/[role=columnheader]/[role=cell] are the blessed translation (no data-* hooks, no shim classes)",
|
|
298
|
+
"ruling": "plans/BBTABLE-GRID.md § Migration & ecosystem",
|
|
299
|
+
"guide": "components/bb-table.md § Selector translation"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"kind": "behaviour",
|
|
303
|
+
"description": "BbTable #thead / #tbody / #tfoot inner markup: role-complete <div role=\"row\"> holding <div role=\"columnheader\\",
|
|
304
|
+
"ruling": "cell\"> — never <tr>/<th>/<td>; #tfoot's columnCount now feeds grid-column: span N / 1 / -1 (+ aria-colspan), not colspan. A custom #thead over an empty table publishes no tracks",
|
|
305
|
+
"guide": "plans/BBTABLE-GRID.md § Non-negotiables (exception 1)"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"kind": "behaviour",
|
|
309
|
+
"description": "BbTable --fill custom property removed (not republished) — it fed the fixed-layout self-correction loop the grid does not have",
|
|
310
|
+
"ruling": "plans/BBTABLE-GRID.md § Tracks (RULED 2026-08-26)",
|
|
311
|
+
"guide": "components/bb-table.md § --fill and --natural-width are removed"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"kind": "behaviour",
|
|
315
|
+
"description": "BbTable --natural-width custom property removed (not republished) — republishing the resolved-track sum would publish the container width under a \"natural\" name",
|
|
316
|
+
"ruling": "plans/BBTABLE-GRID.md § Tracks (RULED 2026-08-26)",
|
|
317
|
+
"guide": "components/bb-table.md § --fill and --natural-width are removed"
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"kind": "behaviour",
|
|
321
|
+
"description": "BbTable track-distribution drift: surplus split equally among auto columns (748/52 → 544/256), constrained wrapping grows tracks by equal increments (~22% narrower long column, taller rows), frozen+auto ≤ ~19px/column, all-frozen tables no longer inflate the select/actions columns, scroll-container cells no longer floor the column (max-width: 0 ellipsis trick breaks), % widths in an overflowing table resolve against min-content (30%: 181 → 303px), expand-row content never widens parent columns, orphan snap → auto. Overflow threshold, wrap floor, frozen px and fixed equal split are exact",
|
|
322
|
+
"ruling": "plans/BBTABLE-GRID.md § Tracks + § v2.1",
|
|
323
|
+
"guide": "components/bb-table.md § Column widths: what holds and what drifts"
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
"kind": "behaviour",
|
|
327
|
+
"description": "BbTable copy-to-spreadsheet degrades: Chrome's selection serializer keys off computed display, so a selected grid pastes one value per line (was one cell per column). Accepted; sanctioned path = app-level \"copy as TSV from the items model\" recipe (queued, not shipped)",
|
|
328
|
+
"ruling": "plans/BBTABLE-GRID.md § Migration & ecosystem (7)",
|
|
329
|
+
"guide": "components/bb-table.md § Copy-to-spreadsheet degrades"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"kind": "behaviour",
|
|
333
|
+
"description": "BbTable print header repetition lost — <thead> page-repetition has no grid equivalent; data rows get break-inside: avoid",
|
|
334
|
+
"ruling": "plans/BBTABLE-GRID.md § Migration & ecosystem (8)",
|
|
335
|
+
"guide": "components/bb-table.md § Print: header repetition is gone"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"kind": "behaviour",
|
|
339
|
+
"description": "BbTable: global element CSS (table/td resets, .prose table, stray td { padding }) silently stops reaching the table — immunity benefit AND a silent look change on pages that leaned on it",
|
|
340
|
+
"ruling": "plans/BBTABLE-GRID.md § Migration & ecosystem (9)",
|
|
341
|
+
"guide": "components/bb-table.md § Global element CSS no longer reaches the table"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"kind": "behaviour",
|
|
345
|
+
"description": "BbTable browser floor raised to subgrid engines (Chrome/Edge 117, Firefox 71, Safari 16), block align-content centring from Chrome 123 / Safari 17.4 / Firefox 125; no @supports fallback",
|
|
346
|
+
"ruling": "plans/BBTABLE-GRID.md § Non-negotiables + § CSS port rules",
|
|
347
|
+
"guide": "components/bb-table.md § Browser floor"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
"kind": "behaviour",
|
|
351
|
+
"description": "BbTable contain: inline-size (+ min-width: 0, grid-column: 1 / -1) on the expand / no-data / loading cells is load-bearing — overriding it lets full-span content resize the tracks (runaway loop with a nested inheriting table); joins gap: 0 on the root and nowrap on the actions cell in the do-not-override list",
|
|
352
|
+
"ruling": "plans/BBTABLE-GRID.md § Measurement & track publishing",
|
|
353
|
+
"guide": "components/bb-table.md § Do not override"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"kind": "behaviour",
|
|
357
|
+
"description": "BbTable caption reading-order micro-drift: .bb-table-caption is a div before the role=table root (named via aria-labelledby), no longer the table's first child",
|
|
358
|
+
"ruling": "plans/BBTABLE-GRID.md § Accessibility",
|
|
359
|
+
"guide": "components/bb-table.md § Small semantic and visual changes"
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"kind": "behaviour",
|
|
363
|
+
"description": "BbTable busy bar now rides with the stuck header under fixed-headers (sticky moved to the .bb-table__head rowgroup; multi-row #thead heads stack instead of overlapping; aria-rowcount = totalItems + 1)",
|
|
364
|
+
"ruling": "plans/BBTABLE-GRID.md § Sticky + § v2.1",
|
|
365
|
+
"guide": "components/bb-table.md § Small semantic and visual changes"
|
|
282
366
|
}
|
|
283
367
|
]
|
|
284
368
|
}
|
package/dist/ai/components.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"library": "bitboss-ui",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
5
|
-
"generatedAt": "2026-08-
|
|
4
|
+
"version": "3.0.0-beta.8",
|
|
5
|
+
"generatedAt": "2026-08-26T17:02:06.381Z",
|
|
6
6
|
"composables": [
|
|
7
7
|
{
|
|
8
8
|
"name": "useBbConfig",
|
|
@@ -12674,7 +12674,7 @@
|
|
|
12674
12674
|
"name": "fixed",
|
|
12675
12675
|
"type": "boolean | undefined",
|
|
12676
12676
|
"required": false,
|
|
12677
|
-
"description": "
|
|
12677
|
+
"description": "Splits the width equally among the columns that declare no `width`\n(each undeclared column becomes a `minmax(0, 1fr)` track)\nmaking each column take up the same amount of space."
|
|
12678
12678
|
},
|
|
12679
12679
|
{
|
|
12680
12680
|
"name": "fixedColumns",
|
|
@@ -12693,7 +12693,7 @@
|
|
|
12693
12693
|
"name": "headerRowClass",
|
|
12694
12694
|
"type": "Classes | undefined",
|
|
12695
12695
|
"required": false,
|
|
12696
|
-
"description": "Defines the classes to be passed to the header
|
|
12696
|
+
"description": "Defines the classes to be passed to the header row."
|
|
12697
12697
|
},
|
|
12698
12698
|
{
|
|
12699
12699
|
"name": "highlighted",
|
|
@@ -12712,7 +12712,7 @@
|
|
|
12712
12712
|
"name": "inheritColumnWidths",
|
|
12713
12713
|
"type": "string | boolean | undefined",
|
|
12714
12714
|
"required": false,
|
|
12715
|
-
"description": "Opt a nested table into inheriting its column widths from an ancestor\ntable's matching tracks (accounting for `select`/`actions` columns). This\nalso
|
|
12715
|
+
"description": "Opt a nested table into inheriting its column widths from an ancestor\ntable's matching tracks (accounting for `select`/`actions` columns). This\nalso makes the parent's tracks authoritative, so it is **off by default** — a nested\ntable renders independently unless you ask for alignment.\n- `false` (the default): do not inherit; size independently.\n- `true`: inherit from the nearest ancestor table.\n- a table id (string): inherit from the specific ancestor in the chain with\n that id rather than the immediate parent. Use this when an intermediate\n table has a different column count, so the extra columns would otherwise\n misalign against it."
|
|
12716
12716
|
},
|
|
12717
12717
|
{
|
|
12718
12718
|
"name": "interactiveWhileLoading",
|
|
@@ -12811,7 +12811,7 @@
|
|
|
12811
12811
|
"name": "rowClass",
|
|
12812
12812
|
"type": "RowClasses<Item> | undefined",
|
|
12813
12813
|
"required": false,
|
|
12814
|
-
"description": "Defines the classes to be passed to each data
|
|
12814
|
+
"description": "Defines the classes to be passed to each data row. Can also be a\nfunction of the row's item for dynamic values."
|
|
12815
12815
|
},
|
|
12816
12816
|
{
|
|
12817
12817
|
"name": "selectable",
|
|
@@ -12849,13 +12849,13 @@
|
|
|
12849
12849
|
"name": "tdClass",
|
|
12850
12850
|
"type": "ColumnClasses<Item> | undefined",
|
|
12851
12851
|
"required": false,
|
|
12852
|
-
"description": "Defines the classes to be passed to
|
|
12852
|
+
"description": "Defines the classes to be passed to every data cell. Can also be a function for dynamic values."
|
|
12853
12853
|
},
|
|
12854
12854
|
{
|
|
12855
12855
|
"name": "thClass",
|
|
12856
12856
|
"type": "Classes | undefined",
|
|
12857
12857
|
"required": false,
|
|
12858
|
-
"description": "Defines the classes to be passed to
|
|
12858
|
+
"description": "Defines the classes to be passed to every header cell."
|
|
12859
12859
|
},
|
|
12860
12860
|
{
|
|
12861
12861
|
"name": "totalItems",
|
|
@@ -12880,15 +12880,15 @@
|
|
|
12880
12880
|
"events": [
|
|
12881
12881
|
{
|
|
12882
12882
|
"name": "click:row",
|
|
12883
|
-
"signature": "(e: \"click:row\", event: MouseEvent, item: any
|
|
12883
|
+
"signature": "(e: \"click:row\", event: MouseEvent, item: any): void"
|
|
12884
12884
|
},
|
|
12885
12885
|
{
|
|
12886
12886
|
"name": "contextmenu:row",
|
|
12887
|
-
"signature": "(e: \"contextmenu:row\", event: MouseEvent, item: any
|
|
12887
|
+
"signature": "(e: \"contextmenu:row\", event: MouseEvent, item: any): void"
|
|
12888
12888
|
},
|
|
12889
12889
|
{
|
|
12890
12890
|
"name": "dblclick:row",
|
|
12891
|
-
"signature": "(e: \"dblclick:row\", event: MouseEvent, item: any
|
|
12891
|
+
"signature": "(e: \"dblclick:row\", event: MouseEvent, item: any): void"
|
|
12892
12892
|
},
|
|
12893
12893
|
{
|
|
12894
12894
|
"name": "item:selected",
|
|
@@ -12939,6 +12939,16 @@
|
|
|
12939
12939
|
"type": "{ text: string; }",
|
|
12940
12940
|
"description": "Replaces the default actions header cell content."
|
|
12941
12941
|
},
|
|
12942
|
+
{
|
|
12943
|
+
"name": "header:append",
|
|
12944
|
+
"type": "BbTableHeaderAffixSlotProps<Item>",
|
|
12945
|
+
"description": "Content rendered after every data column's header cell content — the\nlabel + sort control, or the column's own `header:<key>` replacement.\nA column's `header:<key>:append` slot wins over this one for that\ncolumn; they never stack. Branch on `columnKey` for per-column output."
|
|
12946
|
+
},
|
|
12947
|
+
{
|
|
12948
|
+
"name": "header:prepend",
|
|
12949
|
+
"type": "BbTableHeaderAffixSlotProps<Item>",
|
|
12950
|
+
"description": "Content rendered before every data column's header cell content — the\nlabel + sort control, or the column's own `header:<key>` replacement.\nA column's `header:<key>:prepend` slot wins over this one for that\ncolumn; they never stack. Branch on `columnKey` for per-column output."
|
|
12951
|
+
},
|
|
12942
12952
|
{
|
|
12943
12953
|
"name": "header:select",
|
|
12944
12954
|
"type": "{ multiple: boolean; selectAll: boolean; text: string; }",
|
|
@@ -12952,7 +12962,7 @@
|
|
|
12952
12962
|
{
|
|
12953
12963
|
"name": "no-data",
|
|
12954
12964
|
"type": "object",
|
|
12955
|
-
"description": "Content shown when the items list is empty and not loading. It fills the\ntable's own full-width empty-state cell (
|
|
12965
|
+
"description": "Content shown when the items list is empty and not loading. It fills the\ntable's own full-width empty-state cell (it already spans the\nselection/actions columns), so provide the *content* — a message, an\nillustration, a \"clear filters\" button — never a row/cell of your own."
|
|
12956
12966
|
},
|
|
12957
12967
|
{
|
|
12958
12968
|
"name": "select",
|
|
@@ -12962,17 +12972,17 @@
|
|
|
12962
12972
|
{
|
|
12963
12973
|
"name": "tbody",
|
|
12964
12974
|
"type": "object",
|
|
12965
|
-
"description": "Replaces the
|
|
12975
|
+
"description": "Replaces the content of the body row group (`.bb-table__body`). Use when\nyou need full control over the body markup. Provide role-complete rows —\n`<div role=\"row\">` holding one `<div role=\"cell\">` per column — never a\n`<tr>`/`<td>`. A full-width cell spans with `grid-column: 1 / -1`."
|
|
12966
12976
|
},
|
|
12967
12977
|
{
|
|
12968
12978
|
"name": "tfoot",
|
|
12969
12979
|
"type": "{ columnCount: number; }",
|
|
12970
|
-
"description": "
|
|
12980
|
+
"description": "Fills the footer row group (`.bb-table__foot`). Use when you need a\nfooter. Provide role-complete rows — `<div role=\"row\">` holding\n`<div role=\"cell\">` elements — never a `<tr>`/`<td>`."
|
|
12971
12981
|
},
|
|
12972
12982
|
{
|
|
12973
12983
|
"name": "thead",
|
|
12974
12984
|
"type": "object",
|
|
12975
|
-
"description": "Replaces the
|
|
12985
|
+
"description": "Replaces the content of the header row group (`.bb-table__head`). Use when\nyou need full control over the header markup. The table is a CSS grid,\nnot a `<table>`: provide role-complete rows — `<div role=\"row\">` holding\none `<div role=\"columnheader\">` per column — and never a `<tr>`/`<th>`.\nRows are subgrid rows, so each cell lands on the matching column track."
|
|
12976
12986
|
}
|
|
12977
12987
|
],
|
|
12978
12988
|
"exposed": [],
|
|
@@ -53,20 +53,20 @@ naming rules, the emphasis ladder) lives in
|
|
|
53
53
|
|
|
54
54
|
### Surfaces & structure
|
|
55
55
|
|
|
56
|
-
| Token | Meaning
|
|
57
|
-
| --------------------- |
|
|
58
|
-
| `--bb-panel` | Surface/background color of panels, popovers, dialogs
|
|
59
|
-
| `--bb-muted` | Subtle/disabled surface (derived, neutral)
|
|
60
|
-
| `--bb-hover` | Hover fill for **affordances** (buttons, links, controls)
|
|
61
|
-
| `--bb-surface-hover` | Hover fill for **passive surfaces** (rows, cells, days) — fainter
|
|
62
|
-
| `--bb-pressed` | Neutral pressed/active fill
|
|
63
|
-
| `--bb-border` | Border color; pair with `--bb-border-w` (1px)
|
|
64
|
-
| `--bb-radius` | Corner radius of controls (8px)
|
|
65
|
-
| `--bb-radius-surface` | Corner radius of large surfaces (derived, ×1.8)
|
|
66
|
-
| `--bb-radius-sm` | Corner radius of small nested elements (derived)
|
|
67
|
-
| `--bb-shadow` | Global elevation shadow
|
|
68
|
-
| `--bb-panel-p` | Content padding of large surfaces (dialog, off-canvas)
|
|
69
|
-
| `--bb-z-overlay` | Z-index for overlays (10)
|
|
56
|
+
| Token | Meaning |
|
|
57
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `--bb-panel` | Surface/background color of panels, popovers, dialogs |
|
|
59
|
+
| `--bb-muted` | Subtle/disabled surface (derived, neutral) |
|
|
60
|
+
| `--bb-hover` | Hover fill for **affordances** (buttons, links, controls) |
|
|
61
|
+
| `--bb-surface-hover` | Hover fill for **passive surfaces** (rows, cells, days) — fainter |
|
|
62
|
+
| `--bb-pressed` | Neutral pressed/active fill |
|
|
63
|
+
| `--bb-border` | Border color; pair with `--bb-border-w` (1px) |
|
|
64
|
+
| `--bb-radius` | Corner radius of controls (8px) |
|
|
65
|
+
| `--bb-radius-surface` | Corner radius of large surfaces (derived, ×1.8) |
|
|
66
|
+
| `--bb-radius-sm` | Corner radius of small nested elements (derived) |
|
|
67
|
+
| `--bb-shadow` | Global elevation shadow |
|
|
68
|
+
| `--bb-panel-p` | Content padding of large surfaces (dialog, off-canvas); axis split via the locals `--px`/`--py` on `.bb-dialog` / `.bb-offcanvas` |
|
|
69
|
+
| `--bb-z-overlay` | Z-index for overlays (10) |
|
|
70
70
|
|
|
71
71
|
### Color semantics
|
|
72
72
|
|
|
@@ -190,11 +190,11 @@ multipliers — never literals.
|
|
|
190
190
|
|
|
191
191
|
### Scale
|
|
192
192
|
|
|
193
|
-
| Token | Default | Notes
|
|
194
|
-
| ---------------- | ------- |
|
|
195
|
-
| `--bb-control-h` | `32px` | Master control height. Inputs are exactly this; buttons/tabs derive their size scale from it via `calc()` offsets
|
|
196
|
-
| `--bb-fs` | `14px` | Master font size. Component font sizes derive via `calc()` offsets
|
|
197
|
-
| `--bb-panel-p` | `16px` | Content padding of large surfaces (dialog, off-canvas; header/footer paddings derive from it)
|
|
193
|
+
| Token | Default | Notes |
|
|
194
|
+
| ---------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
195
|
+
| `--bb-control-h` | `32px` | Master control height. Inputs are exactly this; buttons/tabs derive their size scale from it via `calc()` offsets |
|
|
196
|
+
| `--bb-fs` | `14px` | Master font size. Component font sizes derive via `calc()` offsets |
|
|
197
|
+
| `--bb-panel-p` | `16px` | Content padding of large surfaces (dialog, off-canvas; header/footer paddings derive from it). Axis split via the component locals `--px`/`--py` on `.bb-dialog` / `.bb-offcanvas`, each branching off `var(--bb-panel-p)`; set the pair (on the component's class) only when the axes differ |
|
|
198
198
|
|
|
199
199
|
### Motion
|
|
200
200
|
|
|
@@ -272,10 +272,13 @@ Rules:
|
|
|
272
272
|
component seals itself.
|
|
273
273
|
3. **Short names are for self-consumption only.** `--h`, `--px`, `--gap`,
|
|
274
274
|
`--fs`, `--r` are fine while the rules using them target the component's
|
|
275
|
-
own boxes. If a value must be read _inside a nested foreign component_
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
own boxes. If a value must be read _inside a nested foreign component_,
|
|
276
|
+
prefer moving the formula to an element the component owns, or a
|
|
277
|
+
distinctive name. One ruled exception (2026-08-25): the dialog/off-canvas
|
|
278
|
+
padding pair `--px`/`--py` is read by the nested close button's inset
|
|
279
|
+
formula — safe because `BbCloseButton` declares neither, a constraint that
|
|
280
|
+
component must keep (minting `--px`/`--py` there would silently mask the
|
|
281
|
+
surface's value and break the inset).
|
|
279
282
|
4. **Mint only what varies.** A size variant that overrides four locals is
|
|
280
283
|
four tokens, not four × six sizes. Per-size lookup tables
|
|
281
284
|
(`--h-xs … --h-2xl`) are allowed only when a responsive matrix genuinely
|
|
@@ -443,19 +446,22 @@ every derivation that mixes it. It is also the trap. Write
|
|
|
443
446
|
} /* wrong: not a <percentage> */
|
|
444
447
|
```
|
|
445
448
|
|
|
446
|
-
and nothing errors — not the build, not the console. The
|
|
447
|
-
|
|
448
|
-
|
|
449
|
+
and nothing errors — not the build, not the console. The declaration is
|
|
450
|
+
discarded and the token lands on the registered `initial-value: 15%` — which
|
|
451
|
+
happens to be the very value this override asked for, so a light page looks
|
|
452
|
+
right by accident. Write `0.4` on a dark page instead and the ring quietly
|
|
453
|
+
drops from the shipped `40%` to `15%` (opacity is the ring's strength; its
|
|
454
|
+
thickness is `--bb-ring-size`).
|
|
449
455
|
Percentages need the `%`; colors must be a `<color>` (`transparent` and
|
|
450
456
|
`currentColor` qualify, `none` and a mistyped hex do not). Nothing in the
|
|
451
457
|
toolchain catches it either: `bitboss-ui check` reads `.vue`/`.md`, never
|
|
452
458
|
stylesheets.
|
|
453
459
|
|
|
454
460
|
Fail-soft is only soft when the initial value is close to the real one. Every
|
|
455
|
-
|
|
456
|
-
renders the library's own light theme.
|
|
457
|
-
|
|
458
|
-
|
|
461
|
+
registered knob — `--bb-ring-opacity` included — is registered at its light
|
|
462
|
+
default, so a rejected override renders the library's own light theme. On a
|
|
463
|
+
dark page that is still visible: a rejected `--bb-ring-opacity` lands on the
|
|
464
|
+
light `15%` against the shipped dark `40%`.
|
|
459
465
|
|
|
460
466
|
Typed knobs are also **animatable**. Add `.theme-animated`
|
|
461
467
|
(main.css) to the element that carries the scheme class or theme overrides:
|
|
@@ -609,9 +615,10 @@ escape the host dialog's `overflow: hidden` and centering transform.
|
|
|
609
615
|
| `--bb-overlay-color` + `--bb-overlay-opacity` | `--bb-overlay` (one color with alpha) |
|
|
610
616
|
| `--bb-overlay-z-index` | `--bb-z-overlay` |
|
|
611
617
|
| inline ring `color-mix()` formulas | `--bb-ring` / `--bb-ring-danger` (strength knob: `--bb-ring-opacity`) |
|
|
612
|
-
| `--bb-dialog-px/pt/pb/gap/…` | `--bb-panel-p`
|
|
618
|
+
| `--bb-dialog-px/pt/pb/gap/…` | `--bb-panel-p` + the local axis pair `--px`/`--py` on the surface roots |
|
|
613
619
|
| `--bb-button-*`, `--bb-tabs-*`, `--bb-checkbox-*`, `--bb-radio-*`, `--bb-switch-*`, `--bb-rating-*`, `--bb-slider-*`, `--bb-table-cell-h`, `--bb-progress-track` | unprefixed locals in each component's CSS |
|
|
614
|
-
| `--bb-table-offset
|
|
620
|
+
| `--bb-table-offset-*` (JS plumbing) | unprefixed locals on `.bb-table` (`--offset-*`) |
|
|
621
|
+
| `--bb-table-fill`, `--bb-table-natural-width` | **removed** with the grid substrate — nothing publishes them any more (v3.0) |
|
|
615
622
|
| `--bb-table-{id}-track-{key}` (parent→nested width bridge) | `--table-{id}-track-{key}` (distinctive cross-component name, rule 3) |
|
|
616
623
|
| `--bb-select-option-*`, `--bb-primary-base`, all `--x-light`/`--x-dark` shadows | deleted (dead) |
|
|
617
624
|
|
|
@@ -506,7 +506,7 @@ template emits are already styled by the public `bitboss-ui/styles.css`.
|
|
|
506
506
|
|
|
507
507
|
Add `--mcp` to also register a live MCP server (`npx bitboss-ui@<installed version> mcp`, pinned so npx can never fetch a different version from the registry) the harness launches on demand — it merges the entry (never overwriting other servers) into `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), `.vscode/mcp.json` (VS Code / Copilot), and `~/.codeium/windsurf/mcp_config.json` (Windsurf). **Windsurf's config is global** — it has no per-project scope, so registering it affects every project on the machine; that is why only the explicit `ai-init --mcp` command writes it, while the plugin's `mcp: true` dev-server flag (§7) auto-registers the project-scoped harnesses only. Install the server's optional peers first — `npm i -D @modelcontextprotocol/sdk zod` — they are not dependencies of the library (~12 MB used only by the MCP server); the command warns if they are absent. **`--mcp` is optional and skipping it loses you nothing but the transport** — the server only reads the `dist/ai/` files listed above, so run plain `ai-init` and let the agent read that directory if you cannot add the peers (see `mcp?: boolean` in §7).
|
|
508
508
|
|
|
509
|
-
For a human-in-the-loop (and agent) safety net, add the `bitboss-ui/eslint-plugin` flat-config plugin (`...bitbossUi.configs.recommended`) so unknown/removed `Bb*` props surface as ESLint errors in the editor and CI — the same manifest checks as `bitboss-ui check`, reusing your `eslint-plugin-vue` parser. Real HTML attributes fall through untouched; escape hatches are the standard `<!-- eslint-disable-next-line bitboss-ui/no-unknown-attributes -->` and the rule's `allowAttributes` / `allowComponents` options. **`eslint --fix` also auto-migrates deprecated v2 props** (renames, boolean-polarity inversions like `allowWriting`→`disableWriting`, value remaps like BbToast `placement`→`position`, and deletion of inert removed props); structural migrations that need a slot/directive/CSS are reported but left by hand. **This library is TS-first (recipes ship `<script setup lang="ts">`, some with `generic="T"`), so wire `@typescript-eslint/parser` for both `.ts` and `.vue` files** — without it `vue-eslint-parser` throws a `Parsing error` on those files, which means no rule (including `no-unknown-attributes`) runs on them at all. See the README "ESLint plugin" section for the full config snippet (both parser blocks + the `npm i -D @typescript-eslint/parser` line) and the fix table. `recommended` also enables `bitboss-ui/no-active-class-on-root-link`: `active-class` on a link-capable `Bb*` component (`BbButton`/`BbBaseButton`/`BbBadgeButton`) matches by path PREFIX, so a link whose target is the literal root (`href="/"` / `to="/"`) reads as "active" on every URL — the rule flags that combination and points you at `exact-active-class` instead.
|
|
509
|
+
For a human-in-the-loop (and agent) safety net, add the `bitboss-ui/eslint-plugin` flat-config plugin (`...bitbossUi.configs.recommended`) so unknown/removed `Bb*` props surface as ESLint errors in the editor and CI — the same manifest checks as `bitboss-ui check`, reusing your `eslint-plugin-vue` parser. Real HTML attributes fall through untouched; escape hatches are the standard `<!-- eslint-disable-next-line bitboss-ui/no-unknown-attributes -->` and the rule's `allowAttributes` / `allowComponents` options. **`eslint --fix` also auto-migrates deprecated v2 props** (renames, boolean-polarity inversions like `allowWriting`→`disableWriting`, value remaps like BbToast `placement`→`position`, and deletion of inert removed props); structural migrations that need a slot/directive/CSS are reported but left by hand. One deliberate boundary: the rule's "did you mean `<prop>`?" hints for a mistyped/unknown attribute are advisory message text, not fixes — `eslint --fix` (including an unattended run in a pre-commit hook) never applies them; only the registered v2→v3 migrations above are auto-fixed. A guess applied blind across a codebase would be a silent behavior change, so acting on a hint is always a per-site decision. **This library is TS-first (recipes ship `<script setup lang="ts">`, some with `generic="T"`), so wire `@typescript-eslint/parser` for both `.ts` and `.vue` files** — without it `vue-eslint-parser` throws a `Parsing error` on those files, which means no rule (including `no-unknown-attributes`) runs on them at all. See the README "ESLint plugin" section for the full config snippet (both parser blocks + the `npm i -D @typescript-eslint/parser` line) and the fix table. `recommended` also enables `bitboss-ui/no-active-class-on-root-link`: `active-class` on a link-capable `Bb*` component (`BbButton`/`BbBaseButton`/`BbBadgeButton`) matches by path PREFIX, so a link whose target is the literal root (`href="/"` / `to="/"`) reads as "active" on every URL — the rule flags that combination and points you at `exact-active-class` instead.
|
|
510
510
|
|
|
511
511
|
**The manifest ships with the package** — `dist/ai/components.json` is inside
|
|
512
512
|
the tarball, and the rules resolve it relative to their own file, so a normal
|
|
@@ -50,16 +50,18 @@ v2's `BbDialog` was a re-export of `BaseDialog`; v3 makes it first-class
|
|
|
50
50
|
## CSS and tokens
|
|
51
51
|
|
|
52
52
|
The `--bb-dialog-*` family is gone. Padding comes from the shared
|
|
53
|
-
`--bb-panel-p
|
|
54
|
-
|
|
53
|
+
`--bb-panel-p` and the local axis pair `--px` / `--py` on `.bb-dialog`; the
|
|
54
|
+
rest are unprefixed locals on `.bb-dialog` or plain CSS rules. `BbOffCanvas`
|
|
55
|
+
is identical throughout with `.bb-offcanvas__*` parts and the same `--px` /
|
|
56
|
+
`--py` names.
|
|
55
57
|
|
|
56
58
|
| v2 token | v3 |
|
|
57
59
|
| -------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
58
|
-
| `--bb-dialog-px` / `--bb-dialog-py` (`24px`) | `--bb-panel-p` (`16px`)
|
|
60
|
+
| `--bb-dialog-px` / `--bb-dialog-py` (`24px`) | local `--px` / `--py` on `.bb-dialog`, each branching off `--bb-panel-p` (`16px`) |
|
|
59
61
|
| `--bb-dialog-close` (`12px`) | **delete it** — v3's default already reproduces v2's control size |
|
|
60
62
|
| `--bb-dialog-title-size` (`18px`) | local `--dialog-title-fs` on `.bb-dialog`, default `calc(var(--bb-fs) + 2px)` = `16px` |
|
|
61
63
|
| `--bb-dialog-title-weight` (`600`) | no knob — `500` is hard-coded; override with a CSS rule |
|
|
62
|
-
| — | local `--dialog-gap`, default `--
|
|
64
|
+
| — | local `--dialog-gap`, default `--py` — the body↔footer vertical rhythm |
|
|
63
65
|
|
|
64
66
|
### `--bb-dialog-close` → delete it
|
|
65
67
|
|
|
@@ -102,43 +104,46 @@ specificity — a two-class `.my-dialog .bb-dialog__title` loses.
|
|
|
102
104
|
|
|
103
105
|
### Asymmetric padding
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
The local pair `--px` / `--py` splits the axes; each branches off
|
|
108
|
+
`var(--bb-panel-p)`, so setting `--bb-panel-p` alone still moves both. Like
|
|
109
|
+
every unprefixed component token, set the pair on the component's class, never
|
|
110
|
+
`:root` (other components also use `--px` as a sealed local of their own, so a
|
|
111
|
+
dialog-scoped value never leaks into the buttons or alerts inside). v2's `--bb-dialog-px` / `--bb-dialog-py` map onto it directly:
|
|
110
112
|
|
|
111
|
-
|
|
112
|
-
/* v2: --bb-dialog-px: 24px;
|
|
113
|
+
````css
|
|
114
|
+
/* v2: --bb-dialog-px: 24px; --bb-dialog-py: 10px */
|
|
113
115
|
.my-dialog {
|
|
114
|
-
--
|
|
116
|
+
--px: 24px; /* horizontal padding + close-button inline inset */
|
|
117
|
+
--py: 10px; /* vertical padding + close-button block inset */
|
|
115
118
|
}
|
|
119
|
+
``` Per-**part** vertical differences (header `py: 10px`,
|
|
120
|
+
body `py: 20px`) work by scoping the token to the part class — the padding
|
|
121
|
+
rules resolve it on the part elements and the token inherits:
|
|
122
|
+
|
|
123
|
+
```css
|
|
116
124
|
.my-dialog .bb-dialog__header {
|
|
117
|
-
|
|
125
|
+
--py: 10px; /* top 10px, bottom py/2 = 5px; the × inset follows */
|
|
118
126
|
}
|
|
119
|
-
.my-dialog .bb-dialog__body
|
|
120
|
-
|
|
127
|
+
.my-dialog .bb-dialog__body-content {
|
|
128
|
+
--py: 20px; /* bottom padding, and top in the headerless case */
|
|
121
129
|
}
|
|
122
|
-
|
|
123
|
-
padding-top: 20px;
|
|
124
|
-
}
|
|
125
|
-
.my-dialog .bb-dialog__footer {
|
|
126
|
-
padding-block: 20px;
|
|
127
|
-
}
|
|
128
|
-
```
|
|
130
|
+
````
|
|
129
131
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
Derived spacings scale with it (header bottom is `py / 2`; the close button's
|
|
133
|
+
block inset tracks the header's `py`). For exact literals instead of those
|
|
134
|
+
ratios, use a `padding-block` rule on the part class — `padding-block`, not
|
|
135
|
+
the `padding` shorthand, so the horizontal half keeps tracking
|
|
136
|
+
`--px`. Library selectors are `.bb-dialog .bb-dialog__header`
|
|
132
137
|
(0,2,0), `.bb-dialog__body-content` (0,1,0),
|
|
133
138
|
`.bb-dialog__body:first-child .bb-dialog__body-content` (0,2,1) and
|
|
134
|
-
`.bb-dialog .bb-dialog__footer` (0,2,0) —
|
|
135
|
-
|
|
139
|
+
`.bb-dialog .bb-dialog__footer` (0,2,0) — a three-class app rule beats all
|
|
140
|
+
four.
|
|
136
141
|
|
|
137
142
|
### `--dialog-gap`
|
|
138
143
|
|
|
139
144
|
If only the vertical rhythm _between parts_ differs, `--dialog-gap` does it
|
|
140
|
-
without a padding rule — it replaces `--
|
|
141
|
-
and the footer's block padding:
|
|
145
|
+
without a padding rule — it replaces `--py` in the body's bottom
|
|
146
|
+
padding and the footer's block padding:
|
|
142
147
|
|
|
143
148
|
```css
|
|
144
149
|
.my-dialog {
|
|
@@ -147,7 +152,8 @@ and the footer's block padding:
|
|
|
147
152
|
```
|
|
148
153
|
|
|
149
154
|
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 `--
|
|
155
|
+
body's top padding in the headerless case; those still read `--py` (and
|
|
156
|
+
`--px` for the horizontal slots).
|
|
151
157
|
|
|
152
158
|
### `.bb-confirm`
|
|
153
159
|
|