bitboss-ui 3.0.0-beta.51 → 3.0.0-beta.53
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-mcp.mjs +16 -8
- package/dist/ai/BbBadge.md +3 -2
- package/dist/ai/BbColorPalette.md +4 -3
- package/dist/ai/BbDatePicker.md +1 -1
- package/dist/ai/BbDropdown.md +6 -2
- package/dist/ai/BbForm.md +25 -17
- package/dist/ai/BbHoverCard.md +1 -1
- package/dist/ai/BbPopover.md +5 -3
- package/dist/ai/BbSelectPopover.md +1 -1
- package/dist/ai/BbTable.md +176 -51
- package/dist/ai/BbTimePicker.md +1 -1
- package/dist/ai/BbTooltip.md +1 -1
- package/dist/ai/CommonPopover.md +1 -1
- package/dist/ai/changelog.json +77 -3
- package/dist/ai/components.json +14 -14
- package/dist/ai/guides/component-picker.md +3 -3
- package/dist/ai/guides/migration/components/bb-table.md +32 -31
- package/dist/ai/guides/migration/from-async-validator.md +60 -46
- package/dist/ai/guides/migration/v2-to-v3.md +46 -0
- package/dist/ai/guides/options-items-playbook.md +5 -5
- package/dist/ai/guides/validated-forms.md +19 -8
- package/dist/ai/helpers/inertia/manifest.json +1 -1
- package/dist/ai/manifest/components/BbBadge.json +1 -1
- package/dist/ai/manifest/components/BbColorPalette.json +1 -1
- package/dist/ai/manifest/components/BbDatePicker.json +1 -1
- package/dist/ai/manifest/components/BbDropdown.json +1 -1
- package/dist/ai/manifest/components/BbHoverCard.json +1 -1
- package/dist/ai/manifest/components/BbPopover.json +1 -1
- package/dist/ai/manifest/components/BbSelectPopover.json +1 -1
- package/dist/ai/manifest/components/BbTable.json +6 -5
- package/dist/ai/manifest/components/BbTable.tree.json +19 -0
- package/dist/ai/manifest/components/BbTimePicker.json +1 -1
- package/dist/ai/manifest/components/BbTooltip.json +1 -1
- package/dist/ai/manifest/components/CommonPopover.json +1 -1
- package/dist/ai/manifest/index.json +2 -2
- package/dist/ai/manifest/types.api.json +1 -1
- package/dist/ai/recipes/inertia/approvals-inbox.md +1 -1
- package/dist/ai/recipes/nuxt/approvals-inbox.md +1 -1
- package/dist/ai/recipes/vue/approvals-inbox.md +1 -1
- package/dist/ai/source/BbBadge.md +3 -4
- package/dist/ai/source/BbBadgeButton.md +3 -4
- package/dist/ai/source/BbColorPalette.md +3 -1
- package/dist/ai/source/BbDatePicker.md +4 -1
- package/dist/ai/source/BbDropdown.md +5 -3
- package/dist/ai/source/BbDropdownGroup.md +5 -3
- package/dist/ai/source/BbHoverCard.md +3 -2
- package/dist/ai/source/BbHoverCardPortal.md +3 -2
- package/dist/ai/source/BbPopover.md +3 -2
- package/dist/ai/source/BbPopoverPortal.md +3 -2
- package/dist/ai/source/BbSelectPopover.md +3 -1
- package/dist/ai/source/BbTable.md +405 -141
- package/dist/ai/source/BbTimePicker.md +4 -1
- package/dist/ai/source/BbTooltip.md +3 -2
- package/dist/ai/source/CommonPopover.md +11 -8
- package/dist/components/BbBadge/types.d.ts +3 -4
- package/dist/components/BbColorPalette/types.d.ts +3 -1
- package/dist/components/BbDatePicker/types.d.ts +4 -1
- package/dist/components/BbDropdown/types.d.ts +5 -3
- package/dist/components/BbForm/bindFormField.js +4 -4
- package/dist/components/BbHoverCard/types.d.ts +3 -2
- package/dist/components/BbPopover/types.d.ts +3 -2
- package/dist/components/BbSelectPopover/types.d.ts +3 -1
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +999 -957
- package/dist/components/BbTable/BbTableDataRow.js +77 -78
- package/dist/components/BbTable/types.d.ts +32 -9
- package/dist/components/BbTable/useRowReorder.d.ts +6 -0
- package/dist/components/BbTable/useRowReorder.js +217 -195
- package/dist/components/BbTable/utils.d.ts +21 -0
- package/dist/components/BbTable/utils.js +19 -16
- package/dist/components/BbTable/warroom/harness.d.ts +7 -0
- package/dist/components/BbTimePicker/types.d.ts +4 -1
- package/dist/components/BbTooltip/types.d.ts +3 -2
- package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/CommonPopover/types.d.ts +4 -4
- package/dist/composables/useBaseOptions.d.ts +3 -3
- package/dist/composables/useBaseOptions.js +11 -11
- package/dist/composables/useBbTableContext.js +1 -0
- package/dist/composables/useItemText.d.ts +5 -0
- package/dist/composables/useItemText.js +14 -14
- package/dist/composables/useItemValue.js +9 -9
- package/dist/composables/useItemsGetter.js +55 -51
- package/dist/composables/useSegmentedFields.js +6 -1
- package/dist/composables/useTableWidthContext.d.ts +6 -0
- package/dist/composables/useTableWidthContext.js +2 -1
- package/dist/llms-full.txt +390 -177
- package/dist/llms-medium.txt +3 -3
- package/dist/styles.css +2 -2
- package/dist/utils/versionCheck.js +1 -1
- package/package.json +2 -1
- package/scripts/lib/hand-roll-hints.mjs +11 -2
package/dist/ai/BbTable.md
CHANGED
|
@@ -373,7 +373,7 @@ scope in `#<key>:header`. With it each name gets its own scope, as on `BbTable`.
|
|
|
373
373
|
**Add beside a header instead of replacing it** with
|
|
374
374
|
`#<key>:header:prepend` / `#<key>:header:append` — rendered before / after the
|
|
375
375
|
column's existing header content (the label + sort control, or your own
|
|
376
|
-
`#<key>:header` replacement), so a resize
|
|
376
|
+
`#<key>:header` replacement), so a resize handle or reorder handle no longer
|
|
377
377
|
costs you the built-in sort button. The table-wide pair `#header:prepend` /
|
|
378
378
|
`#header:append` applies one template to every data column's header (never the
|
|
379
379
|
structural select/actions cells); both forms receive the header scope above
|
|
@@ -953,6 +953,20 @@ a native `<input>` / `<select>`:
|
|
|
953
953
|
<BbTable :items="filteredItems" :columns="columns" caption="Invoices" />
|
|
954
954
|
```
|
|
955
955
|
|
|
956
|
+
```ts
|
|
957
|
+
// An emptied (or cleared) BbTextInput writes `null`, not '' — type it so.
|
|
958
|
+
const search = ref<string | null>('');
|
|
959
|
+
const statuses = ref<string[]>([]);
|
|
960
|
+
const filteredItems = computed(() => {
|
|
961
|
+
const q = search.value?.trim().toLowerCase() ?? '';
|
|
962
|
+
return invoices.value.filter(
|
|
963
|
+
(row) =>
|
|
964
|
+
(!q || row.client.toLowerCase().includes(q)) &&
|
|
965
|
+
(!statuses.value.length || statuses.value.includes(row.status))
|
|
966
|
+
);
|
|
967
|
+
});
|
|
968
|
+
```
|
|
969
|
+
|
|
956
970
|
Pick the shape by where the rows come from:
|
|
957
971
|
|
|
958
972
|
| Your situation | The filter mechanism |
|
|
@@ -1172,7 +1186,7 @@ const sortedInvoices = computed(() => {
|
|
|
1172
1186
|
A custom `#<key>:header` slot replaces the built-in sort button, but its scope
|
|
1173
1187
|
hands you `sortOrder` and `toggleSort` so your header can keep sorting alive
|
|
1174
1188
|
(render your own button and call `toggleSort`). To merely add something next
|
|
1175
|
-
to the control — a resize
|
|
1189
|
+
to the control — a resize handle, a filter icon — use
|
|
1176
1190
|
`#<key>:header:prepend/append` instead and keep the built-in button (see
|
|
1177
1191
|
"Custom cells and headers"). The column-level `sorted`
|
|
1178
1192
|
field only seeds the header's `aria-sort` when no live model entry exists — it
|
|
@@ -1471,11 +1485,17 @@ Add `selectable` for multi-select (`multiple` is the default) bound with
|
|
|
1471
1485
|
`v-model` — the model **must** be an array in multiple mode (the table throws
|
|
1472
1486
|
otherwise). With `item-value` set, the model holds ids rather than whole rows.
|
|
1473
1487
|
Pass `selectable` a predicate (`(item) => boolean`) to gate specific rows: the
|
|
1474
|
-
excluded rows' controls disable and `toggleSelected` refuses them too.
|
|
1488
|
+
excluded rows' controls disable and `toggleSelected` refuses them too. Under
|
|
1489
|
+
`select-all` an excluded row stays unticked (select-all covers the rows the
|
|
1490
|
+
user can select); one the model names explicitly still shows ticked.
|
|
1475
1491
|
|
|
1476
1492
|
To drive a toolbar that lives **outside** the table subtree, give the table an
|
|
1477
1493
|
`id` and read `useBbTableContext(id).selected` — the handle mirrors the
|
|
1478
|
-
table's selection both ways, so a bulk-action bar needs no prop drilling.
|
|
1494
|
+
table's selection both ways, so a bulk-action bar needs no prop drilling.
|
|
1495
|
+
Count from `all` and `unselected` too: the header checkbox is select-all,
|
|
1496
|
+
which leaves `selected` empty (see [§ Single select, select-all and
|
|
1497
|
+
limits](#single-select-select-all-and-limits)), so a bar that reads
|
|
1498
|
+
`selected` alone vanishes while every row shows ticked. As
|
|
1479
1499
|
everywhere in the library, the destructive bulk action is gated by
|
|
1480
1500
|
`useConfirm` before it touches the data.
|
|
1481
1501
|
|
|
@@ -1564,14 +1584,27 @@ const selected = ref<string[]>([]);
|
|
|
1564
1584
|
|
|
1565
1585
|
// Same id as the table — the handle mirrors the table's selection both ways.
|
|
1566
1586
|
const ctx = useBbTableContext('member-selection', { selected: [] });
|
|
1567
|
-
|
|
1568
|
-
|
|
1587
|
+
// The header checkbox is "select all": it sets `all` and leaves `selected`
|
|
1588
|
+
// empty (built for "all across pages"), with the rows unticked since in
|
|
1589
|
+
// `unselected`. A client-side table reads the chosen rows from both.
|
|
1590
|
+
const chosenIds = computed<string[]>(() =>
|
|
1591
|
+
ctx.all.value
|
|
1592
|
+
? members.value
|
|
1593
|
+
.map((member) => member.id)
|
|
1594
|
+
.filter((id) => !ctx.unselected.value.includes(id))
|
|
1595
|
+
: (ctx.selected.value ?? [])
|
|
1596
|
+
);
|
|
1597
|
+
const selectedCount = computed(() => chosenIds.value.length);
|
|
1598
|
+
const clear = () => {
|
|
1599
|
+
ctx.all.value = false;
|
|
1600
|
+
ctx.selected.value = [];
|
|
1601
|
+
};
|
|
1569
1602
|
|
|
1570
1603
|
const { confirm } = useConfirm();
|
|
1571
1604
|
|
|
1572
1605
|
// Destructive bulk action: `await` the decision, act only on a yes.
|
|
1573
1606
|
const removeSelected = async () => {
|
|
1574
|
-
const ids
|
|
1607
|
+
const ids = chosenIds.value;
|
|
1575
1608
|
const ok = await confirm({
|
|
1576
1609
|
title: `Delete ${ids.length} ${ids.length === 1 ? 'member' : 'members'}?`,
|
|
1577
1610
|
text: 'They will lose access to this workspace immediately.',
|
|
@@ -1979,7 +2012,7 @@ _detail about the row_ rather than _children of it_.
|
|
|
1979
2012
|
|
|
1980
2013
|
### Reordering rows
|
|
1981
2014
|
|
|
1982
|
-
`reorderable-rows` adds a slim
|
|
2015
|
+
`reorderable-rows` adds a slim drag handle at the start of every row: the user drags
|
|
1983
2016
|
a row to a new place and the table reports the move with **`reorder:rows`**.
|
|
1984
2017
|
The table never reorders `items` itself. Your handler splices the array, and
|
|
1985
2018
|
saves the order if it should outlive the page:
|
|
@@ -1991,8 +2024,8 @@ saves the order if it should outlive the page:
|
|
|
1991
2024
|
<div class="flex max-w-2xl flex-col gap-3">
|
|
1992
2025
|
<!-- The table only REPORTS the move: `reorder:rows` says which item went
|
|
1993
2026
|
from where to where, and the handler below splices the array and
|
|
1994
|
-
saves the order. Drag a row by its
|
|
1995
|
-
mouse), or focus a
|
|
2027
|
+
saves the order. Drag a row by its handle (or anywhere on it with a
|
|
2028
|
+
mouse), or focus a handle and use Space, the arrow keys and Space. -->
|
|
1996
2029
|
<div
|
|
1997
2030
|
class="overflow-hidden rounded-(--bb-radius) border border-(--bb-border)"
|
|
1998
2031
|
>
|
|
@@ -2106,11 +2139,11 @@ function move({ from, to }: { from: number; to: number }) {
|
|
|
2106
2139
|
`items` (`items.indexOf(item)` finds it); `from` and `to` index the `items`
|
|
2107
2140
|
the table holds. Remove at `from`, insert at `to`. A drop where the row
|
|
2108
2141
|
already was emits nothing.
|
|
2109
|
-
- **Mouse and pen** drag from the
|
|
2142
|
+
- **Mouse and pen** drag from the handle, or from anywhere on the row once the
|
|
2110
2143
|
pointer has moved 5px. A press on a control inside the row never starts a
|
|
2111
2144
|
drag (a button, a link, an input, the select checkbox, anything with a
|
|
2112
2145
|
widget role or `draggable`), and a press that sets off sideways selects text
|
|
2113
|
-
instead. **Touch** drags from the
|
|
2146
|
+
instead. **Touch** drags from the handle only, at once (no long-press), so a
|
|
2114
2147
|
finger on the row still scrolls. The click that ends a drag is not a row
|
|
2115
2148
|
click: no `click:row`, no highlight.
|
|
2116
2149
|
- **While it drags**, a copy of the row follows the pointer with its real cell
|
|
@@ -2119,10 +2152,10 @@ function move({ from, to }: { from: number; to: number }) {
|
|
|
2119
2152
|
Near the top or bottom edge the nearest scroll container scrolls, `virtual`
|
|
2120
2153
|
tables included, and the rows that scroll in are targets; the wheel scrolls
|
|
2121
2154
|
too.
|
|
2122
|
-
- **Keyboard:** the
|
|
2155
|
+
- **Keyboard:** the drag handle is a button. Space or Enter picks the row up, ↑ / ↓ /
|
|
2123
2156
|
Home / End move it, Space or Enter drops it, Esc or Tab cancels. Under
|
|
2124
|
-
`keyboard-navigation`, Space or Enter on the
|
|
2125
|
-
- **Accessibility:** each
|
|
2157
|
+
`keyboard-navigation`, Space or Enter on the handle's cell picks it up at once.
|
|
2158
|
+
- **Accessibility:** each drag handle is named "Move row" + the row's label (its
|
|
2126
2159
|
cell in the `rowHeader: true` column, else the first column) and described by the keyboard
|
|
2127
2160
|
instructions. A polite live region announces the pick-up, each position
|
|
2128
2161
|
("Position 3 of 6"), the drop and a cancel.
|
|
@@ -2135,10 +2168,16 @@ function move({ from, to }: { from: number; to: number }) {
|
|
|
2135
2168
|
- **Server pages:** the indexes are into the page the table holds. For the
|
|
2136
2169
|
whole list, add the page's offset (`(page - 1) * perPage + from`). Moving a
|
|
2137
2170
|
row to another page is not supported.
|
|
2138
|
-
- **Sorting:** the
|
|
2139
|
-
is reported against the sorted rows
|
|
2140
|
-
|
|
2141
|
-
|
|
2171
|
+
- **Sorting:** the drag handles stay enabled while a column sort is active, and a
|
|
2172
|
+
move is reported against the sorted rows, the order the user sees. This is
|
|
2173
|
+
easy to get wrong: splicing your stored array changes nothing a sort shows,
|
|
2174
|
+
so the row snaps back. Give the drop a meaning the sort can show. Sorted by
|
|
2175
|
+
a rank the drag edits (priority, position), write the new ranks in the order
|
|
2176
|
+
the user now sees and the sort reproduces the drop. Sorted by something the
|
|
2177
|
+
drag cannot change (a name, a date), turn the drag handles off for that sort
|
|
2178
|
+
(`:reorderable-rows="!sort.length || sort[0][0] === 'priority'"`) rather
|
|
2179
|
+
than snapping back or clearing the user's sort behind their back.
|
|
2180
|
+
- **Pinning and RTL:** the drag handle column is structural, like the select column:
|
|
2142
2181
|
it never appears in `order` and never moves, it pins with the first
|
|
2143
2182
|
left-pinned column, and in RTL it sits at the logical start (the right
|
|
2144
2183
|
edge).
|
|
@@ -2146,7 +2185,7 @@ function move({ from, to }: { from: number; to: number }) {
|
|
|
2146
2185
|
goes on while its row is still there, and cancels cleanly, announced, when
|
|
2147
2186
|
it is gone. Expanding or collapsing one of the table's own rows cancels it.
|
|
2148
2187
|
While `loading`, no new drag starts.
|
|
2149
|
-
- **No
|
|
2188
|
+
- **No drag handles** with a custom `#tbody`.
|
|
2150
2189
|
- **Styling:** `pt:dragHandle` takes a class list or an object (no per-row
|
|
2151
2190
|
function).
|
|
2152
2191
|
|
|
@@ -2194,6 +2233,13 @@ put, and both columns are reported. A table that inherits its widths from a
|
|
|
2194
2233
|
parent (`inherit-column-widths`) renders no handles — its tracks are the
|
|
2195
2234
|
parent's.
|
|
2196
2235
|
|
|
2236
|
+
**Lock one column with `resizable: false`** on its definition, the way
|
|
2237
|
+
`reorderable: false` locks its place: its header has no handle, Alt+←/→ on
|
|
2238
|
+
it does nothing, and a neighbour's Shift+drag resizes the neighbour alone. Use
|
|
2239
|
+
it for control columns sized to their content (an expand chevron, a row
|
|
2240
|
+
number at `width: 'max-content'`). The lock stops the user, not your code: a
|
|
2241
|
+
`width` you set still applies.
|
|
2242
|
+
|
|
2197
2243
|
**Resizable columns reporting widths back into the definition**
|
|
2198
2244
|
|
|
2199
2245
|
```vue
|
|
@@ -2340,7 +2386,7 @@ above it. The mechanics:
|
|
|
2340
2386
|
</template>
|
|
2341
2387
|
|
|
2342
2388
|
<template #expand="{ item }">
|
|
2343
|
-
<div class="bg-(--bb-muted)
|
|
2389
|
+
<div class="bg-(--bb-muted) py-1">
|
|
2344
2390
|
<BbTable
|
|
2345
2391
|
:caption="`Line items of ${item.number}`"
|
|
2346
2392
|
:columns="lineColumns"
|
|
@@ -2476,7 +2522,42 @@ Two rules keep them honest:
|
|
|
2476
2522
|
2. **Never add nest padding on the body only.** Padding the child's body
|
|
2477
2523
|
(`.bb-table__body`) but not its header (or vice versa) reintroduces exactly
|
|
2478
2524
|
the offset the snap just removed. Put the inset on the nest container, where
|
|
2479
|
-
both row groups inherit it
|
|
2525
|
+
both row groups inherit it, and keep it **vertical** (`py-1`): the child
|
|
2526
|
+
inherits the parent's track widths, not their positions, so horizontal
|
|
2527
|
+
padding moves every column off its rail by that much and pushes the child
|
|
2528
|
+
past the parent's edge into its scroll.
|
|
2529
|
+
|
|
2530
|
+
#### Indenting nested levels
|
|
2531
|
+
|
|
2532
|
+
Two CSS tokens on the **root** table step each nested level in, the way a
|
|
2533
|
+
tree reads, while every other column stays on the parent's columns:
|
|
2534
|
+
|
|
2535
|
+
- `--indent` — the step per level (a length; `0px` by default, no indent).
|
|
2536
|
+
- `--indent-at` — where the step goes: `drag-handle`, `select` (the default) or
|
|
2537
|
+
`content`.
|
|
2538
|
+
|
|
2539
|
+
```css
|
|
2540
|
+
.services-table {
|
|
2541
|
+
--indent: 24px;
|
|
2542
|
+
--indent-at: select;
|
|
2543
|
+
}
|
|
2544
|
+
```
|
|
2545
|
+
|
|
2546
|
+
| `--indent-at` | Stays in one column at every level | Steps in per level |
|
|
2547
|
+
| ------------- | ---------------------------------- | ---------------------------------------- |
|
|
2548
|
+
| `drag-handle` | nothing before the content | the drag handle, the select, the content |
|
|
2549
|
+
| `select` | the drag handle | the select and the content |
|
|
2550
|
+
| `content` | the drag handle and the select | the first column's content |
|
|
2551
|
+
|
|
2552
|
+
Each nested level adds one step before the anchor and takes it from its
|
|
2553
|
+
first content column, so Status, Total or any other column never moves and
|
|
2554
|
+
level three lands two steps in by itself. A missing anchor falls through: no
|
|
2555
|
+
drag handle column behaves as `select`, no select column as `content`. Set the tokens
|
|
2556
|
+
on the root table (nested tables inherit them), or on one nested table to
|
|
2557
|
+
change the anchor from that level down. `--indent-at` is read when the table
|
|
2558
|
+
measures (mount, resize): set it in CSS, not from an animation. A nested
|
|
2559
|
+
table also carries `--depth` (1, 2, …) for styling by level, e.g. a group bar:
|
|
2560
|
+
`border-inline-start: calc(var(--depth) * 2px) solid var(--bb-primary)`.
|
|
2480
2561
|
|
|
2481
2562
|
### Row highlight (master–detail)
|
|
2482
2563
|
|
|
@@ -2485,37 +2566,63 @@ details are open" — independent of selection. Clicking anywhere on a row
|
|
|
2485
2566
|
toggles it: a new click replaces the previous highlight, and clicking the
|
|
2486
2567
|
highlighted row clears it back to `null`. **Highlight is single by design** —
|
|
2487
2568
|
one row is "the open one" — so bind a single item value, never an array. Two kinds of
|
|
2488
|
-
clicks are
|
|
2489
|
-
|
|
2490
|
-
selection (dragging to copy a cell must not
|
|
2569
|
+
clicks are not row clicks: those starting on a control inside the row (a link,
|
|
2570
|
+
a button, an input, the select checkbox, any ARIA widget — they keep their own
|
|
2571
|
+
semantics) and those ending a text selection (dragging to copy a cell must not
|
|
2572
|
+
mutate state). Neither highlights the row nor emits `click:row`.
|
|
2491
2573
|
|
|
2492
|
-
**Highlight is opt-in
|
|
2493
|
-
|
|
2574
|
+
**Highlight is opt-in: it is on when it is bound.** Bind nothing and the
|
|
2575
|
+
mechanic is entirely off — a row click emits `click:row` and does nothing
|
|
2494
2576
|
else: no class, no `aria-current`, no state. That matters because the table has
|
|
2495
2577
|
nowhere to put a highlight it invents; a table that highlighted itself would
|
|
2496
|
-
drive a cursor the app can neither read nor clear.
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
empty" and turns it on.** So initialise the model:
|
|
2578
|
+
drive a cursor the app can neither read nor clear. Bound means
|
|
2579
|
+
`v-model:highlighted` (whatever its value — `ref()` and `ref(null)` both mean
|
|
2580
|
+
"nothing open yet"), or `highlighted` provided through the shared context,
|
|
2581
|
+
which binds two ways just like the prop:
|
|
2501
2582
|
|
|
2502
2583
|
```ts
|
|
2503
|
-
const highlighted = ref(null);
|
|
2504
|
-
|
|
2584
|
+
const highlighted = ref<number | null>(null);
|
|
2585
|
+
useBbTableContext('invoices-table', { highlighted });
|
|
2505
2586
|
```
|
|
2506
2587
|
|
|
2507
|
-
|
|
2508
|
-
|
|
2588
|
+
**`highlightable` decides which rows a click may open.** `false` turns the
|
|
2589
|
+
click off for every row (a user without the privilege to open details), and a
|
|
2590
|
+
function of the row's item turns it off for some. A refused row ignores a
|
|
2591
|
+
click, Enter and `toggleHighlighted`, loses the pointer cursor highlightable
|
|
2592
|
+
rows get, and never clears the row that is open. It gates the user only: a
|
|
2593
|
+
value your code puts in `highlighted` (a deep link to a record) shows on a
|
|
2594
|
+
refused row too — the table reflects your state, it does not correct it, just
|
|
2595
|
+
as a `selectable`-refused row the model names stays ticked.
|
|
2596
|
+
|
|
2597
|
+
Fetching the details belongs in a watcher on the model, not in `click:row`
|
|
2598
|
+
(the model also changes on the click that closes, on Enter, and from your own
|
|
2599
|
+
code). Abort the previous fetch when the highlight moves on, so a slow answer
|
|
2600
|
+
never paints over a newer one:
|
|
2509
2601
|
|
|
2510
2602
|
```ts
|
|
2511
|
-
const
|
|
2512
|
-
|
|
2603
|
+
const openTaskId = ref<string | null>(null);
|
|
2604
|
+
watch(openTaskId, (id, _previous, onCleanup) => {
|
|
2605
|
+
if (id === null) return taskStore.closeDetails();
|
|
2606
|
+
const controller = new AbortController();
|
|
2607
|
+
onCleanup(() => controller.abort());
|
|
2608
|
+
void taskStore.showDetails(id, { signal: controller.signal });
|
|
2609
|
+
});
|
|
2610
|
+
```
|
|
2611
|
+
|
|
2612
|
+
```vue
|
|
2613
|
+
<BbTable
|
|
2614
|
+
v-model:highlighted="openTaskId"
|
|
2615
|
+
:highlightable="can(Privilege.TASKS_SHOW)"
|
|
2616
|
+
item-value="id"
|
|
2617
|
+
:items="tasks"
|
|
2618
|
+
:columns="columns"
|
|
2619
|
+
/>
|
|
2513
2620
|
```
|
|
2514
2621
|
|
|
2515
|
-
`click:row` is never gated — it fires on every row click whether
|
|
2516
|
-
highlight is
|
|
2517
|
-
`toggleHighlighted` from a cell slot on an
|
|
2518
|
-
warns once in dev.
|
|
2622
|
+
`click:row` is never gated by highlight — it fires on every row click whether
|
|
2623
|
+
or not highlight is bound or the row highlightable, so listening for clicks
|
|
2624
|
+
costs you nothing. Calling `toggleHighlighted` from a cell slot on an unbound
|
|
2625
|
+
table does nothing and warns once in dev.
|
|
2519
2626
|
|
|
2520
2627
|
Highlight ships with a **default cursor**: the row gets `aria-current="true"`
|
|
2521
2628
|
and the `bb-table__row--highlighted` class, and the shipped stylesheet
|
|
@@ -2743,7 +2850,11 @@ Row events: `click:row`, `dblclick:row` and `contextmenu:row` fire with
|
|
|
2743
2850
|
`(event, item)` — the native event and **your record exactly as you passed it
|
|
2744
2851
|
in `items`**, nothing else. No wrapper to unpack, no third argument; selection
|
|
2745
2852
|
state is already yours through the `v-model`, and the row's value resolves
|
|
2746
|
-
from the record through `item-value` exactly as the models do.
|
|
2853
|
+
from the record through `item-value` exactly as the models do. A click that
|
|
2854
|
+
starts on a control inside the row (the select checkbox, a link, a button, any
|
|
2855
|
+
ARIA widget) is the control's, not the row's: none of the three fires, so a
|
|
2856
|
+
cell's button needs no `@click.stop` and a right-click on a cell link keeps
|
|
2857
|
+
the browser's menu. Reserve these
|
|
2747
2858
|
events for side effects that are not navigation —
|
|
2748
2859
|
logging, opening a drawer (though `v-model:highlighted` usually covers that
|
|
2749
2860
|
without any handler).
|
|
@@ -3851,8 +3962,13 @@ for a preset that fits any row type (never `<any>`), not an imported
|
|
|
3851
3962
|
- `loading-text` is `sr-only` — it is announced, never painted. The visible
|
|
3852
3963
|
loading signal is the skeleton (or your `#loading` slot). It defaults to the
|
|
3853
3964
|
localized `common.loadingText`, so an unset value still announces.
|
|
3854
|
-
- Row selection labels default to
|
|
3855
|
-
"select" template (`Select {0}`, `{0} auswählen`)
|
|
3965
|
+
- Row selection labels default to the row's **name** inside the locale's
|
|
3966
|
+
"select" template (`Select {0}`, `{0} auswählen`): its `rowHeader` cells,
|
|
3967
|
+
else its first column ("Select INV-1041"), the same name the drag handle
|
|
3968
|
+
uses. Not every cell: a name tells rows apart, and a screen reader reads the
|
|
3969
|
+
other cells with their headers in table navigation. Mark the identity
|
|
3970
|
+
column `rowHeader` when it is not the first (a receipt thumbnail leads).
|
|
3971
|
+
`accessible-label` overrides that per row — it is called
|
|
3856
3972
|
`(columns, item)` with the mapped cells (in **render** order — look them up
|
|
3857
3973
|
by `key`, never by position) and the raw record, and whatever it returns
|
|
3858
3974
|
becomes the checkbox's label.
|
|
@@ -3907,8 +4023,9 @@ for a preset that fits any row type (never `<any>`), not an imported
|
|
|
3907
4023
|
(`role="rowheader"`), and a screen reader reading across a row, or down
|
|
3908
4024
|
another column, announces that name with each value — "Ada Lovelace,
|
|
3909
4025
|
ada@x.io" instead of a bare "ada@x.io". The cells look the same.
|
|
3910
|
-
|
|
3911
|
-
|
|
4026
|
+
It also names the row's selection checkbox and drag handle ("Select Ada
|
|
4027
|
+
Lovelace", "Move row Ada Lovelace"); `accessible-label` overrides only the
|
|
4028
|
+
checkbox. The column:
|
|
3912
4029
|
`{ key: 'name', label: 'Name', rowHeader: true }`.
|
|
3913
4030
|
|
|
3914
4031
|
- Set `item-value` so selection, expansion and highlight track rows by stable
|
|
@@ -3972,7 +4089,7 @@ for a preset that fits any row type (never `<any>`), not an imported
|
|
|
3972
4089
|
| Prop | Type | Default | Required | Description |
|
|
3973
4090
|
| --- | --- | --- | --- | --- |
|
|
3974
4091
|
| `pt:<part>`, `pt:<part>:<state>`, `pt` | `PtValue` | | | Passthrough — a class list, or `{ class, style, attrs }`, bound to one named part of the component; the state form applies only while that state is on. Parts: `body`, `caption`, `cell`, `cellColumnHeader`, `dragHandle`, `dragIcon`, `firstRow`, `foot`, `head`, `headerRow`, `lastRow`, `root`, `row`, `selectIcon`, `sortIcon`, `table`. States: `disabled`, `empty`, `expanded`, `highlighted`, `indeterminate`, `loading`, `selected`, `sorted`, `sortedDesc`. What each one is: _Passthrough parts and states_ below. `pt` is the object form with the same keys minus the prefix (`{ icon: '…', 'icon:loading': '…' }`). See `guides/passthrough.md`. In `<script>` a `pt` value is typed `BbTableProps<Row>['pt']` (`BbTableProps['pt']` for a preset that fits any row type, never `<any>`) (`PtValue` is not exported): § Typing `pt` in `<script>`. |
|
|
3975
|
-
| `accessibleLabel` | `((columns: MappedCell[], item: any) => string) \| undefined` | | |
|
|
4092
|
+
| `accessibleLabel` | `((columns: MappedCell[], item: any) => string) \| undefined` | | | The row's selection checkbox label, from `(columns, item)`. Unset: the row's name in the locale's select template (its `rowHeader` cells, else its first column: "Select INV-1041"). The cells arrive in render order: look one up by `key`, never by position. |
|
|
3976
4093
|
| `actionsText` | `string \| undefined` | | | Label used in the header of the actions column. |
|
|
3977
4094
|
| `align` | `"left" \| "center" \| "right" \| undefined` | `"left"` | | Text alignment of the columns. |
|
|
3978
4095
|
| `caption` | `string \| undefined` | | | Caption that describes the content of the table. Used for accessibility purposes. |
|
|
@@ -3994,7 +4111,8 @@ for a preset that fits any row type (never `<any>`), not an imported
|
|
|
3994
4111
|
| `fixedLast` | `boolean \| undefined` | `false` | | Sticks the `#<key>:last` row (a totals row) to the bottom of the scrollport. |
|
|
3995
4112
|
| `fixedSelect` | `boolean \| undefined` | `false` | | Pins the selection column to the left edge, `position: sticky`, in place. Data columns pin through `column.fixed`; this is the same feature for the structural column that has no definition to carry it. No effect unless the table is `selectable`. |
|
|
3996
4113
|
| `headerRowClass` | `Classes \| undefined` | | | Defines the classes to be passed to the header row. |
|
|
3997
|
-
| `
|
|
4114
|
+
| `highlightable` | `boolean \| ((item: Item) => boolean) \| undefined` | `undefined` | | Which rows a click, Enter or `toggleHighlighted` may highlight: `false` for none, or a function of the row's item. Unset: every row, when `highlighted` is bound. A value the app sets still shows on a refused row. |
|
|
4115
|
+
| `highlighted` | `any` | `undefined` | | Used by `v-model:highlighted`: the one row the UI is about ("the row whose details are open"), a single item value or `null`. Opt-in: bound, a row click highlights; unbound, it only emits `click:row`. The row gets `aria-current="true"` and a shipped tint. |
|
|
3998
4116
|
| `id` | `string \| undefined` | | | Stable id for this table's width context. When omitted a unique id is generated. Nested tables use the nearest ancestor id to inherit widths. |
|
|
3999
4117
|
| `inheritColumnWidths` | `string \| boolean \| undefined` | | | A nested table snaps its columns to an ancestor table's tracks: `true` = the nearest ancestor, a table `id` = that ancestor (when an intermediate table has a different column count). Off by default: a nested table sizes itself. |
|
|
4000
4118
|
| `interactiveWhileLoading` | `boolean \| undefined` | `false` | | Keeps the header and rows interactive while loading (by default they are `inert`: a refetch is about to replace them). For background refreshes that must not interrupt an open editor. |
|
|
@@ -4013,7 +4131,7 @@ for a preset that fits any row type (never `<any>`), not an imported
|
|
|
4013
4131
|
| `perPage` | `string \| number \| undefined` | | | Rows per page, for `aria-rowindex` and a paired `BbPagination`. Doesn't slice `items`. Unset, an array `items` infers it from its length; an explicit value wins. Numeric strings are coerced. |
|
|
4014
4132
|
| `readonly` | `boolean \| undefined` | `false` | | Sets the input in a readonly state. |
|
|
4015
4133
|
| `reorderable` | `boolean \| undefined` | `false` | | Lets the user reorder the data columns: drag a header, or Shift+←/→ on a focused header. Every move writes `v-model:order`; a column panel that only writes `order` does not need it. `select` / `actions` and a custom `#thead` never move. |
|
|
4016
|
-
| `reorderableRows` | `boolean \| undefined` | `false` | | Adds a
|
|
4134
|
+
| `reorderableRows` | `boolean \| undefined` | `false` | | Adds a drag handle at the start of each row: the user drags a row, or lifts it with Space / Enter and the arrow keys, and `reorder:rows` reports `{ item, from, to }`. The table never reorders `items`: splice it in the handler. |
|
|
4017
4135
|
| `resizable` | `boolean \| undefined` | `false` | | Lets the user resize the data columns (drag a header's trailing edge, or Alt+←/→; double-click resets). Each commit fires `resize:column(key, width)` once: write the width back into the column definition to keep it. Ignored when inheriting widths. |
|
|
4018
4136
|
| `rowClass` | `BbTableRowClasses<Item> \| undefined` | | | Defines the classes to be passed to each data row. Can also be a function of the row's item for dynamic values. |
|
|
4019
4137
|
| `selectable` | `boolean \| ((item: Item) => boolean) \| undefined` | | | Defines whether the table is selectable. Can be a global boolean that affects all rows or a function that accepts an item and returns a boolean that only affects that item. |
|
|
@@ -4048,7 +4166,7 @@ for a preset that fits any row type (never `<any>`), not an imported
|
|
|
4048
4166
|
| `lastRow` | The row of `#<key>:last` cells, after the data rows (a totals row: `pt:lastRow="font-semibold"`). |
|
|
4049
4167
|
| `selectIcon` | The selection glyph: each row's checkbox (radio with single selection) and the select-all checkbox — resolved per node. Not rendered when the `select` / `select:header` slots replace them. |
|
|
4050
4168
|
| `dragIcon` | The move glyph on the chip that follows a column drag (`reorderable`). |
|
|
4051
|
-
| `dragHandle` | Each row's
|
|
4169
|
+
| `dragHandle` | Each row's drag handle button (`reorderable-rows`), resolved with its row's states. A class list or an object; no per-row function. |
|
|
4052
4170
|
| `foot` | The footer row group (the `tfoot` slot's container). |
|
|
4053
4171
|
|
|
4054
4172
|
States are listed in precedence order: when two are on at once and their entries conflict, the later one wins.
|
|
@@ -4117,6 +4235,13 @@ Set these on the element, or on a class you put on it, to retune this component
|
|
|
4117
4235
|
| `--actions-spacing` | `.bb-table` | `8px` | |
|
|
4118
4236
|
| `--offset-start` | `.bb-table` | `0px` | Raw structural edge offset measured by the component (the parent's select/actions track width). Default 0 keeps every calc at its base. |
|
|
4119
4237
|
| `--offset-end` | `.bb-table` | `0px` | |
|
|
4238
|
+
| `--ig` | `.bb-table` | `0px` | Nested indent locals (see `indentAnchor` in BbTable.vue): the step lands on ONE cell's leading padding. Reset on every table so a parent's step never inherits into a child's cells; the modifier picks the anchor. |
|
|
4239
|
+
| `--is` | `.bb-table` | `0px` | |
|
|
4240
|
+
| `--ic` | `.bb-table` | `0px` | |
|
|
4241
|
+
| `--depth` | `.bb-table` | `0` | Nesting depth (0 at the root) and the parent-region floors of the own structural tracks, both set inline by the component on nested tables; declared here so a parent's values never inherit into a child. |
|
|
4242
|
+
| `--min-g` | `.bb-table` | `0px` | |
|
|
4243
|
+
| `--min-s` | `.bb-table` | `0px` | |
|
|
4244
|
+
| `--min-a` | `.bb-table` | `0px` | |
|
|
4120
4245
|
| `--offset-internal-start` | `.bb-table` | `var(--offset-start)` | Routing of that offset. By default it is "internal": added to the first/last cell padding and folded into the first/last column width. Swap internal↔external (set internal to 0 and external to the raw offset) to pad the whole table instead of the edge cells. |
|
|
4121
4246
|
| `--offset-internal-end` | `.bb-table` | `var(--offset-end)` | |
|
|
4122
4247
|
| `--offset-external-start` | `.bb-table` | `0px` | |
|
package/dist/ai/BbTimePicker.md
CHANGED
|
@@ -289,7 +289,7 @@ typeahead. Always pass a `label` when the trigger is an unlabelled cell or icon.
|
|
|
289
289
|
| `adaptive` | `boolean \| undefined` | ``config.adaptive` (`true`)` | | On mobile, open in a bottom off-canvas sheet instead of a floating popover. When unset, falls back to the global `config.adaptive`. |
|
|
290
290
|
| `ampm` | `boolean \| undefined` | `false` | | 12-hour display with an AM/PM column; emitted values stay 24-hour. |
|
|
291
291
|
| `anchor` | `ElementOrComponentRef \| undefined` | | | Element or component ref the popover positions itself relative to. Defaults to the activator when omitted (anchor to a larger row while a smaller element stays the click target). |
|
|
292
|
-
| `boundary` | `ElementOrComponentRefOrSelector \| undefined` | | | Constrains the popover within a bounding element or CSS selector. |
|
|
292
|
+
| `boundary` | `ElementOrComponentRefOrSelector \| undefined` | | | Constrains the popover within a bounding element or CSS selector: sideways only, alongside the trigger; it flips at the viewport. |
|
|
293
293
|
| `disabled` | `boolean \| undefined` | `false` | | Disables the activator and the columns. |
|
|
294
294
|
| `disableFlip` | `boolean \| undefined` | `false` | | Disable the automatic flip to the opposite side on overflow. |
|
|
295
295
|
| `eager` | `boolean \| undefined` | `false` | | Render popover content before it is first shown. |
|
package/dist/ai/BbTooltip.md
CHANGED
|
@@ -597,7 +597,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
|
|
|
597
597
|
| `pt:<part>`, `pt:<part>:<state>`, `pt` | `PtValue` | | | Passthrough — a class list, or `{ class, style, attrs }`, bound to one named part of the component; the state form applies only while that state is on. Parts: `panel`, `root`. States: `open`. What each one is: _Passthrough parts and states_ below. `pt` is the object form with the same keys minus the prefix (`{ icon: '…', 'icon:loading': '…' }`). See `guides/passthrough.md`. In `<script>` a `pt` value is typed `BbTooltipProps['pt']` (`PtValue` is not exported): § Typing `pt` in `<script>`. |
|
|
598
598
|
| `activator` | `ElementOrComponentRef \| undefined` | | | External activator element or component ref. When provided, the activator slot is not rendered and event listeners are attached programmatically to the referenced element. |
|
|
599
599
|
| `arrowPadding` | `number \| undefined` | `10` | | Space the arrow will maintain to the edge of the tooltip bubble. Useful when the floating element has border radius so it won't appear broken |
|
|
600
|
-
| `boundary` | `ElementOrComponentRefOrSelector \| undefined` | | | Constrains the tooltip within a bounding element
|
|
600
|
+
| `boundary` | `ElementOrComponentRefOrSelector \| undefined` | | | Constrains the tooltip within a bounding element: it stays inside it alongside its trigger (sideways for a tooltip above or below); away from the trigger it may pass the edge, and it flips at the viewport only. Accepts an HTMLElement, a Vue component ref, or a CSS selector string. |
|
|
601
601
|
| `delay` | `number \| undefined` | `100` | | Milliseconds a pointer rests on the activator before the tooltip shows (`0`: at once). Keyboard focus shows it at once, and so does a pointer arriving while another tooltip shows or within 300 ms of one closing. |
|
|
602
602
|
| `disabled` | `boolean \| undefined` | `false` | | Disables the component |
|
|
603
603
|
| `eager` | `boolean \| undefined` | `false` | | Renders the tooltip's popover and content at mount instead of on the first open. The description screen readers hear exists from mount either way. |
|
package/dist/ai/CommonPopover.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
| --- | --- | --- | --- | --- |
|
|
19
19
|
| `anchor` | `any` | | | The element the popover positions itself relative to. Accepts an HTMLElement, a Vue component ref, or a virtual element with a `getBoundingClientRect` method. |
|
|
20
20
|
| `arrowPadding` | `number \| undefined` | | | Space the arrow will maintain to the edge of the dropdown. Useful when the floating element has border radius so it won't appear broken |
|
|
21
|
-
| `boundary` | `string \| Record<string, any> \| HTMLElement \| null \| undefined` | | |
|
|
21
|
+
| `boundary` | `string \| Record<string, any> \| HTMLElement \| null \| undefined` | | | Keeps the popover inside this element alongside its anchor (sideways above or below, vertically beside it); away from the anchor it may pass the edge, and only the viewport flips it. It never clamps the size (that is `overflowBoundary`). An HTMLElement, component ref or selector. |
|
|
22
22
|
| `bubbleAttrs` | `Record<string, unknown> \| ((space: CommonPopoverAvailableSpace) => Record<string, unknown>) \| undefined` | | | Attributes bound on the bubble (`class`, `style`, `inert`, …) after its own class, so the owner can make the bubble its layout container. The function form receives the default slot's free space (for a height cap). |
|
|
23
23
|
| `dialog` | `boolean \| undefined` | `false` | | Renders the popover as a `<dialog>` element (modal overlay) instead of a `<span>` with the Popover API. |
|
|
24
24
|
| `disableFlip` | `boolean \| undefined` | `false` | | Disables the automatic flip to the opposite side when the popover would overflow (flipping is on by default). |
|
package/dist/ai/changelog.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 3,
|
|
3
3
|
"library": "bitboss-ui",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.53",
|
|
5
5
|
"upgrade": "v2-to-v3",
|
|
6
6
|
"guide": "ai/guides/migration/v2-to-v3.md",
|
|
7
7
|
"legend": {
|
|
@@ -62,7 +62,9 @@
|
|
|
62
62
|
"3.0.0-beta.48",
|
|
63
63
|
"3.0.0-beta.49",
|
|
64
64
|
"3.0.0-beta.50",
|
|
65
|
-
"3.0.0-beta.51"
|
|
65
|
+
"3.0.0-beta.51",
|
|
66
|
+
"3.0.0-beta.52",
|
|
67
|
+
"3.0.0-beta.53"
|
|
66
68
|
],
|
|
67
69
|
"unpublished": [
|
|
68
70
|
"3.0.0-alpha.2",
|
|
@@ -83,7 +85,7 @@
|
|
|
83
85
|
],
|
|
84
86
|
"summary": {
|
|
85
87
|
"renames": 220,
|
|
86
|
-
"behaviourBreaks":
|
|
88
|
+
"behaviourBreaks": 193,
|
|
87
89
|
"bySurface": {
|
|
88
90
|
"prop": 15,
|
|
89
91
|
"option": 1,
|
|
@@ -5901,6 +5903,78 @@
|
|
|
5901
5903
|
"ruling": "owner 2026-10-08 (Q60.31 option B)",
|
|
5902
5904
|
"guide": "v2-to-v3.md § 6 item 56 + useBbFormField.md + validated-forms.md § validationMode",
|
|
5903
5905
|
"firstReleasedIn": "3.0.0-beta.51"
|
|
5906
|
+
},
|
|
5907
|
+
{
|
|
5908
|
+
"id": "f328",
|
|
5909
|
+
"kind": "behaviour",
|
|
5910
|
+
"summary": "BbTable row events (`click:row`, `dblclick:row`, `contextmenu:row`) skip clicks on controls inside the row (select checkbox, link, button, ARIA widget); drop `@click.stop` guards",
|
|
5911
|
+
"components": [
|
|
5912
|
+
"BbTable"
|
|
5913
|
+
],
|
|
5914
|
+
"description": "BbTable: a click that starts on a control inside a row (the select checkbox, a link, a button, an input, any ARIA widget, contenteditable, [draggable]) emits no click:row, dblclick:row or contextmenu:row (they emitted for every click; the highlight already ignored them, now one rule for all, the row drag's); a click ending a text selection emits no click:row either. A cell button needs no @click.stop; a page guard on .bb-table__cell--select can go; a right-click on a cell link keeps the browser menu",
|
|
5915
|
+
"ruling": "owner 2026-10-09 (progetto-32 report)",
|
|
5916
|
+
"guide": "v2-to-v3.md § 6 item 57 + BbTable.guide.md § Row events",
|
|
5917
|
+
"firstReleasedIn": "3.0.0-beta.52"
|
|
5918
|
+
},
|
|
5919
|
+
{
|
|
5920
|
+
"id": "f329",
|
|
5921
|
+
"kind": "behaviour",
|
|
5922
|
+
"summary": "BbTable highlight is on when bound (any value; `undefined` no longer turns it off); new `highlightable` (bool or row function) gates which rows a click may highlight, app-set values still show",
|
|
5923
|
+
"components": [
|
|
5924
|
+
"BbTable"
|
|
5925
|
+
],
|
|
5926
|
+
"description": "BbTable highlight is on when BOUND (v-model:highlighted with any value, ref() included, or highlighted provided through useBbTableContext); the model's value no longer switches it (undefined was off, null on, with a dev warning for a bound undefined — gone). New highlightable (boolean | (item) => boolean; unset = on exactly when highlight is bound) gates which rows a click / Enter / toggleHighlighted may highlight; a refused row never clears the open one, and a value the app sets still shows on it. Highlightable rows get bb-table__row--highlightable and a pointer cursor. A page that kept highlight off by binding undefined moves to :highlightable=\"false\"",
|
|
5927
|
+
"ruling": "owner 2026-10-09 (progetto-32, panel)",
|
|
5928
|
+
"guide": "v2-to-v3.md § 6 item 58 + BbTable.guide.md § Row highlight + components/bb-table.md",
|
|
5929
|
+
"firstReleasedIn": "3.0.0-beta.52"
|
|
5930
|
+
},
|
|
5931
|
+
{
|
|
5932
|
+
"id": "f330",
|
|
5933
|
+
"kind": "behaviour",
|
|
5934
|
+
"summary": "Option components: a function `item-text` runs on string items (was skipped: raw codes showed); a path on a primitive keeps the primitive as text and value",
|
|
5935
|
+
"components": [
|
|
5936
|
+
"BbSelect",
|
|
5937
|
+
"BbSelectPopover",
|
|
5938
|
+
"BbCheckboxGroup",
|
|
5939
|
+
"BbRadioGroup",
|
|
5940
|
+
"BbSwitchGroup",
|
|
5941
|
+
"BbDropdown"
|
|
5942
|
+
],
|
|
5943
|
+
"description": "Option surfaces (BbSelect, BbSelectPopover, BbCheckboxGroup, BbRadioGroup, BbSwitchGroup, a BbDropdown pipeline group): on a primitive item (string[], number[]) a FUNCTION item-text now runs (strings skipped it and showed the raw string, numbers ran it), and a path item-text / item-value keeps the primitive (a number blanked its text, every primitive got undefined as its value). :item-text=\"(code) => labels[code]\" over a list of codes shows the labels and keeps the codes as values",
|
|
5944
|
+
"ruling": "owner 2026-10-12 (docs paragraph review)",
|
|
5945
|
+
"guide": "v2-to-v3.md § 6 item 59 + options-items-playbook.md § Primitive items",
|
|
5946
|
+
"firstReleasedIn": "3.0.0-beta.53"
|
|
5947
|
+
},
|
|
5948
|
+
{
|
|
5949
|
+
"id": "f331",
|
|
5950
|
+
"kind": "behaviour",
|
|
5951
|
+
"summary": "Floating panels: `boundary` confines a panel sideways only; it no longer flips at the boundary edge (only the viewport flips), so a table's last-row menu opens below",
|
|
5952
|
+
"components": [
|
|
5953
|
+
"BbDropdown",
|
|
5954
|
+
"BbPopover",
|
|
5955
|
+
"BbTooltip",
|
|
5956
|
+
"BbHoverCard",
|
|
5957
|
+
"BbSelectPopover",
|
|
5958
|
+
"BbColorPalette",
|
|
5959
|
+
"BbDatePicker",
|
|
5960
|
+
"BbTimePicker"
|
|
5961
|
+
],
|
|
5962
|
+
"description": "Floating panels (BbDropdown + v-bb-dropdown, BbPopover, BbTooltip + v-bb-tooltip, BbHoverCard, BbSelectPopover, BbColorPalette, BbDatePicker, BbTimePicker): boundary keeps the panel inside it ALONGSIDE the trigger only (sideways for a panel above or below); away from the trigger it may pass the boundary, and it flips at the viewport, never at the boundary's edge (it flipped there: a menu in a table's last rows, bounded by the table, opened above its row)",
|
|
5963
|
+
"ruling": "owner 2026-10-12 (table matrix review)",
|
|
5964
|
+
"guide": "v2-to-v3.md § 6 item 60 + BbPopover.guide.md § Placement, offset and boundary",
|
|
5965
|
+
"firstReleasedIn": "3.0.0-beta.53"
|
|
5966
|
+
},
|
|
5967
|
+
{
|
|
5968
|
+
"id": "f332",
|
|
5969
|
+
"kind": "behaviour",
|
|
5970
|
+
"summary": "BbTable row checkbox name is the row's name (rowHeader cells, else first column), not every cell; mark the identity column rowHeader when it is not first",
|
|
5971
|
+
"components": [
|
|
5972
|
+
"BbTable"
|
|
5973
|
+
],
|
|
5974
|
+
"description": "BbTable: a row's selection checkbox is named by the row's NAME, its rowHeader cells else its first column (\"Select INV-1041\"), the same name the drag grip uses; it read every cell (\"Select INV-1041 Northwind €4,200 Paid 2026-09-01 …\"). A test or e2e finding the checkbox by the long name, or by a prefix with more text after the name, matches the short one now; a table whose first column is not its identity (a thumbnail) marks the identity column rowHeader. accessible-label still overrides",
|
|
5975
|
+
"ruling": "owner 2026-10-12 (table matrix review)",
|
|
5976
|
+
"guide": "v2-to-v3.md § 6 item 61 + BbTable.guide.md § Accessibility",
|
|
5977
|
+
"firstReleasedIn": "3.0.0-beta.53"
|
|
5904
5978
|
}
|
|
5905
5979
|
]
|
|
5906
5980
|
}
|