bitboss-ui 3.0.0-beta.51 → 3.0.0-beta.52

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.
@@ -2733,7 +2733,7 @@ function listChanges({
2733
2733
  : compareVersions(a, b)
2734
2734
  )
2735
2735
  ),
2736
- hint: 'Counts only. What breaks when you bump: list_changes({ since: "<the version you have>" }) — one line per change; coming from v2: since: "2". One component: { component: "BbSelect" }. Full rows: detail: "rows".',
2736
+ hint: 'Counts only. What a bump breaks: list_changes({ since: "<your version>" }), one line per change; from v2: since: "2". One component: { component: "BbSelect" }. Full rows: detail: "rows".',
2737
2737
  };
2738
2738
  }
2739
2739
 
@@ -1471,7 +1471,9 @@ Add `selectable` for multi-select (`multiple` is the default) bound with
1471
1471
  `v-model` — the model **must** be an array in multiple mode (the table throws
1472
1472
  otherwise). With `item-value` set, the model holds ids rather than whole rows.
1473
1473
  Pass `selectable` a predicate (`(item) => boolean`) to gate specific rows: the
1474
- excluded rows' controls disable and `toggleSelected` refuses them too.
1474
+ excluded rows' controls disable and `toggleSelected` refuses them too. Under
1475
+ `select-all` an excluded row stays unticked (select-all covers the rows the
1476
+ user can select); one the model names explicitly still shows ticked.
1475
1477
 
1476
1478
  To drive a toolbar that lives **outside** the table subtree, give the table an
1477
1479
  `id` and read `useBbTableContext(id).selected` — the handle mirrors the
@@ -2485,37 +2487,63 @@ details are open" — independent of selection. Clicking anywhere on a row
2485
2487
  toggles it: a new click replaces the previous highlight, and clicking the
2486
2488
  highlighted row clears it back to `null`. **Highlight is single by design** —
2487
2489
  one row is "the open one" — so bind a single item value, never an array. Two kinds of
2488
- clicks are ignored on purpose: those inside interactive elements (links,
2489
- buttons, inputs, labels keep their own semantics) and those ending a text
2490
- selection (dragging to copy a cell must not mutate state).
2490
+ clicks are not row clicks: those starting on a control inside the row (a link,
2491
+ a button, an input, the select checkbox, any ARIA widget — they keep their own
2492
+ semantics) and those ending a text selection (dragging to copy a cell must not
2493
+ mutate state). Neither highlights the row nor emits `click:row`.
2491
2494
 
2492
- **Highlight is opt-in, and the model's value is the switch.** Bind nothing and
2493
- the mechanic is entirely off — a row click emits `click:row` and does nothing
2495
+ **Highlight is opt-in: it is on when it is bound.** Bind nothing and the
2496
+ mechanic is entirely off — a row click emits `click:row` and does nothing
2494
2497
  else: no class, no `aria-current`, no state. That matters because the table has
2495
2498
  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
- The switch reads the value, not the binding: **`undefined` means "never
2499
- initialised" and keeps highlight off; `null` means "initialised and currently
2500
- empty" and turns it on.** So initialise the model:
2499
+ drive a cursor the app can neither read nor clear. Bound means
2500
+ `v-model:highlighted` (whatever its value — `ref()` and `ref(null)` both mean
2501
+ "nothing open yet"), or `highlighted` provided through the shared context,
2502
+ which binds two ways just like the prop:
2501
2503
 
2502
2504
  ```ts
2503
- const highlighted = ref(null); // ✅ connected
2504
- const highlighted = ref(); // ❌ undefined — highlight stays off (warns in dev)
2505
+ const highlighted = ref<number | null>(null);
2506
+ useBbTableContext('invoices-table', { highlighted });
2505
2507
  ```
2506
2508
 
2507
- A value seeded through the shared context counts exactly the same, and binds
2508
- two ways just like the prop:
2509
+ **`highlightable` decides which rows a click may open.** `false` turns the
2510
+ click off for every row (a user without the privilege to open details), and a
2511
+ function of the row's item turns it off for some. A refused row ignores a
2512
+ click, Enter and `toggleHighlighted`, loses the pointer cursor highlightable
2513
+ rows get, and never clears the row that is open. It gates the user only: a
2514
+ value your code puts in `highlighted` (a deep link to a record) shows on a
2515
+ refused row too — the table reflects your state, it does not correct it, just
2516
+ as a `selectable`-refused row the model names stays ticked.
2517
+
2518
+ Fetching the details belongs in a watcher on the model, not in `click:row`
2519
+ (the model also changes on the click that closes, on Enter, and from your own
2520
+ code). Abort the previous fetch when the highlight moves on, so a slow answer
2521
+ never paints over a newer one:
2509
2522
 
2510
2523
  ```ts
2511
- const highlighted = ref(null);
2512
- useBbTableContext('invoices-table', { highlighted });
2524
+ const openTaskId = ref<string | null>(null);
2525
+ watch(openTaskId, (id, _previous, onCleanup) => {
2526
+ if (id === null) return taskStore.closeDetails();
2527
+ const controller = new AbortController();
2528
+ onCleanup(() => controller.abort());
2529
+ void taskStore.showDetails(id, { signal: controller.signal });
2530
+ });
2531
+ ```
2532
+
2533
+ ```vue
2534
+ <BbTable
2535
+ v-model:highlighted="openTaskId"
2536
+ :highlightable="can(Privilege.TASKS_SHOW)"
2537
+ item-value="id"
2538
+ :items="tasks"
2539
+ :columns="columns"
2540
+ />
2513
2541
  ```
2514
2542
 
2515
- `click:row` is never gated — it fires on every row click whether or not
2516
- highlight is connected, so listening for clicks costs you nothing. Calling
2517
- `toggleHighlighted` from a cell slot on an unconnected table does nothing and
2518
- warns once in dev.
2543
+ `click:row` is never gated by highlight — it fires on every row click whether
2544
+ or not highlight is bound or the row highlightable, so listening for clicks
2545
+ costs you nothing. Calling `toggleHighlighted` from a cell slot on an unbound
2546
+ table does nothing and warns once in dev.
2519
2547
 
2520
2548
  Highlight ships with a **default cursor**: the row gets `aria-current="true"`
2521
2549
  and the `bb-table__row--highlighted` class, and the shipped stylesheet
@@ -2743,7 +2771,11 @@ Row events: `click:row`, `dblclick:row` and `contextmenu:row` fire with
2743
2771
  `(event, item)` — the native event and **your record exactly as you passed it
2744
2772
  in `items`**, nothing else. No wrapper to unpack, no third argument; selection
2745
2773
  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. Reserve these
2774
+ from the record through `item-value` exactly as the models do. A click that
2775
+ starts on a control inside the row (the select checkbox, a link, a button, any
2776
+ ARIA widget) is the control's, not the row's: none of the three fires, so a
2777
+ cell's button needs no `@click.stop` and a right-click on a cell link keeps
2778
+ the browser's menu. Reserve these
2747
2779
  events for side effects that are not navigation —
2748
2780
  logging, opening a drawer (though `v-model:highlighted` usually covers that
2749
2781
  without any handler).
@@ -3994,7 +4026,8 @@ for a preset that fits any row type (never `<any>`), not an imported
3994
4026
  | `fixedLast` | `boolean \| undefined` | `false` | | Sticks the `#<key>:last` row (a totals row) to the bottom of the scrollport. |
3995
4027
  | `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
4028
  | `headerRowClass` | `Classes \| undefined` | | | Defines the classes to be passed to the header row. |
3997
- | `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: bind `ref(null)`, not `ref()`; unbound or `undefined`, a row click only emits `click:row`. The row gets `aria-current="true"` and a shipped tint. |
4029
+ | `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. |
4030
+ | `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
4031
  | `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
4032
  | `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
4033
  | `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. |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 3,
3
3
  "library": "bitboss-ui",
4
- "version": "3.0.0-beta.51",
4
+ "version": "3.0.0-beta.52",
5
5
  "upgrade": "v2-to-v3",
6
6
  "guide": "ai/guides/migration/v2-to-v3.md",
7
7
  "legend": {
@@ -62,7 +62,8 @@
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"
66
67
  ],
67
68
  "unpublished": [
68
69
  "3.0.0-alpha.2",
@@ -83,7 +84,7 @@
83
84
  ],
84
85
  "summary": {
85
86
  "renames": 220,
86
- "behaviourBreaks": 188,
87
+ "behaviourBreaks": 190,
87
88
  "bySurface": {
88
89
  "prop": 15,
89
90
  "option": 1,
@@ -5901,6 +5902,30 @@
5901
5902
  "ruling": "owner 2026-10-08 (Q60.31 option B)",
5902
5903
  "guide": "v2-to-v3.md § 6 item 56 + useBbFormField.md + validated-forms.md § validationMode",
5903
5904
  "firstReleasedIn": "3.0.0-beta.51"
5905
+ },
5906
+ {
5907
+ "id": "f328",
5908
+ "kind": "behaviour",
5909
+ "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",
5910
+ "components": [
5911
+ "BbTable"
5912
+ ],
5913
+ "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",
5914
+ "ruling": "owner 2026-10-09 (progetto-32 report)",
5915
+ "guide": "v2-to-v3.md § 6 item 57 + BbTable.guide.md § Row events",
5916
+ "firstReleasedIn": "3.0.0-beta.52"
5917
+ },
5918
+ {
5919
+ "id": "f329",
5920
+ "kind": "behaviour",
5921
+ "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",
5922
+ "components": [
5923
+ "BbTable"
5924
+ ],
5925
+ "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\"",
5926
+ "ruling": "owner 2026-10-09 (progetto-32, panel)",
5927
+ "guide": "v2-to-v3.md § 6 item 58 + BbTable.guide.md § Row highlight + components/bb-table.md",
5928
+ "firstReleasedIn": "3.0.0-beta.52"
5904
5929
  }
5905
5930
  ]
5906
5931
  }