bitboss-ui 3.0.0-beta.59 → 3.0.0-beta.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/ai/BbSelect.md +2 -0
  2. package/dist/ai/BbSelectPopover.md +64 -18
  3. package/dist/ai/changelog.json +13 -3
  4. package/dist/ai/components.json +4 -4
  5. package/dist/ai/guides/agent-contract.md +3 -1
  6. package/dist/ai/guides/coherence-playbook.md +3 -3
  7. package/dist/ai/guides/fetch-items-playbook.md +3 -3
  8. package/dist/ai/helpers/inertia/manifest.json +1 -1
  9. package/dist/ai/manifest/components/BbSelectPopover.json +2 -0
  10. package/dist/ai/manifest/index.json +2 -2
  11. package/dist/ai/manifest/types.api.json +1 -1
  12. package/dist/ai/source/BbSelect.md +23 -34
  13. package/dist/ai/source/BbSelectPopover.md +141 -30
  14. package/dist/ai/source/FlatListBox.md +23 -0
  15. package/dist/ai/source/GroupedListBox.md +30 -0
  16. package/dist/ai/source/ListBox.md +6 -0
  17. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +201 -207
  18. package/dist/components/BbSelect/types.d.ts +2 -6
  19. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +624 -591
  20. package/dist/components/BbSelectPopover/knownItems.d.ts +6 -6
  21. package/dist/components/BbSelectPopover/types.d.ts +13 -0
  22. package/dist/components/FlatListBox/FlatListBox.vue.d.ts +2 -0
  23. package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +106 -97
  24. package/dist/components/GroupedListBox/GroupedListBox.vue.d.ts +2 -0
  25. package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +22 -10
  26. package/dist/components/ListBox/ListBox.vue.d.ts +2 -0
  27. package/dist/components/ListBox/ListBox.vue_vue_type_script_setup_true_lang.js +3 -1
  28. package/dist/components/ListBox/types.d.ts +4 -0
  29. package/dist/llms-full.txt +74 -24
  30. package/dist/llms-medium.txt +3 -1
  31. package/dist/styles.css +1 -1
  32. package/dist/utils/versionCheck.js +1 -1
  33. package/package.json +1 -1
@@ -1895,6 +1895,8 @@ Shipped behavior — never reimplement it:
1895
1895
  - Picking in single mode closes the panel and refocuses the control; in
1896
1896
  multiple mode the panel stays open and focus returns to the search field.
1897
1897
  - Clicks or focus outside the control and panel close it.
1898
+ - The list opens scrolled to its first selected option, else to the top, and
1899
+ every new query scrolls it back to its first match.
1898
1900
  - `disabled`, `readonly` and `loading` suppress the open/navigate bindings
1899
1901
  (`Esc` still closes an open panel).
1900
1902
 
@@ -201,16 +201,19 @@ open/close handlers. The full slot scope:
201
201
  - `text` — display text of the current selection — **popover state** (see below).
202
202
  - `disabled` / `readonly` / `loading` — state mirrors for styling the trigger.
203
203
 
204
- **The trigger must not depend on the popover's state — label it from your own
205
- data.** The popover is an _optional_ editing affordance: it may never be opened,
206
- and whether it has been opened must never change how the trigger reads. `text`
207
- and `selectedOptions` resolve the model against **loaded options**, so with a
208
- provider they stay empty until that provider first runs — by default, the first
209
- open. A trigger fed from them renders blank and then flickers into truth; a
210
- trigger fed from your own data is correct on first paint and stays that way.
211
-
212
- The robust pattern — used in the example — is a `computed` that resolves the
213
- label from the model against your own data:
204
+ **The trigger must not depend on whether the popover was opened — pass known
205
+ rows, or label it yourself.** The popover is an _optional_ editing affordance:
206
+ it may never be opened, and whether it has been opened must never change how
207
+ the trigger reads. `text` and `selectedOptions` resolve the model against
208
+ **loaded options**, so with a provider they stay empty until that provider
209
+ first runs — by default, the first open — unless `known-items` name the value
210
+ (see [Rows you already hold](#rows-you-already-hold-known-items)). A trigger
211
+ fed from loaded options alone renders blank and then flickers into truth; a
212
+ trigger fed from known rows or from your own data is correct on first paint and
213
+ stays that way.
214
+
215
+ The other robust pattern — used in the example — is a `computed` that resolves
216
+ the label from the model against your own data:
214
217
 
215
218
  ```ts
216
219
  const assigneeLabel = computed(
@@ -527,6 +530,43 @@ const destinationLabel = computed(
527
530
  </script>
528
531
  ```
529
532
 
533
+ #### Rows you already hold: `known-items`
534
+
535
+ When you already hold the selected record (`task.assignee` is
536
+ `{ id, name }`), pass it as a `{ value, label }` row in `known-items`, whatever
537
+ shape the options have. The activator's `text` and `selectedOptions` name the
538
+ value from the first paint, with **no request** until the first open
539
+ (`prefill: true` still loads on mount). A `null` entry names nothing, so an
540
+ unassigned task falls back to your own text. With `multiple`, rows that name
541
+ only some of the picks name none of them until the first open:
542
+
543
+ ```vue
544
+ <BbSelectPopover
545
+ v-model="assigneeId"
546
+ item-text="name"
547
+ item-value="id"
548
+ :items="searchPeople"
549
+ :known-items="[
550
+ task.assignee && { value: task.assignee.id, label: task.assignee.name },
551
+ ]"
552
+ :filter-by="false"
553
+ >
554
+ <template #activator="{ props, text }">
555
+ <BbButton v-bind="props" :text="text || 'Unassigned'" />
556
+ </template>
557
+ </BbSelectPopover>
558
+ ```
559
+
560
+ It is the same prop as `BbSelect`'s, with the same rules: the provider does
561
+ not change (the first open still asks for the picks by id), a value no row
562
+ names loads as it would without the prop, the options' accessors never run on
563
+ a known row (slots get it as `item` until the list brings its own), the rows
564
+ are never listed unless selected, they vouch for their values under
565
+ `enforce-coherence` until a parent change, and a selected row the list lacks is
566
+ listed first. The details are in the BbSelect guide (_Rows the form already
567
+ holds_). A row per table cell is the inline-edit case below: there a label
568
+ from data you already hold is just as good.
569
+
530
570
  ### Laziness, prefill and the trigger label
531
571
 
532
572
  `prefill` controls **when the first load happens**: `'interaction'` (default) on
@@ -536,6 +576,10 @@ but only on a host that can transfer the result — see
536
576
  Opening the panel is not a search, so it loads nothing; until the first query the
537
577
  list shows a _"search to begin"_ hint instead of "no data".
538
578
 
579
+ Opening never waits for the first load: the panel shows its loading state and the
580
+ search field (or, with writing disabled, the focus proxy) takes focus at once, so
581
+ keys typed while the first load runs land in the search.
582
+
539
583
  Reach for `false` when the result set is too large or too expensive to browse and
540
584
  the query is the only sensible entry point — a user picker over thousands of
541
585
  rows. Note the panel is deliberately empty on open: that is the mode telling the
@@ -567,9 +611,10 @@ a seeded model to an eager prefill the way in-field `BbSelect` does. That
567
611
  laziness is deliberate: a fetch per instance must be something you ask for (see
568
612
  _One popover per table row_).
569
613
 
570
- **Do not reach for `prefill: true` to fix a trigger label.** Resolve the label
571
- from your own state instead (above) — a trigger that needs a fetch to render is
572
- a trigger that renders wrong until the fetch lands.
614
+ **Do not reach for `prefill: true` to fix a trigger label.** Pass
615
+ `known-items`, or resolve the label from your own state (above) — a trigger
616
+ that needs a fetch to render is a trigger that renders wrong until the fetch
617
+ lands.
573
618
 
574
619
  ### Dependent fields and coherence
575
620
 
@@ -1659,8 +1704,8 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1659
1704
 
1660
1705
  - `multiple` with a non-array model **throws at setup** — seed `ref([])`.
1661
1706
  - A seeded model shows **no trigger `text`** until the first load (no eager
1662
- prefill upgrade, by design) — resolve the label from your own state. Array
1663
- `items` resolve on mount, so this only bites providers.
1707
+ prefill upgrade, by design) — pass `known-items`, or resolve the label from
1708
+ your own state. Array `items` resolve on mount, so this only bites providers.
1664
1709
  - The local substring filter also applies to provider results — server matches
1665
1710
  whose text doesn't contain the query are hidden — unless you set
1666
1711
  `:filter-by="false"`, which a provider that searches on the server needs.
@@ -1700,9 +1745,9 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1700
1745
 
1701
1746
  ### Anti-patterns
1702
1747
 
1703
- - Reading `text` (or `selectedOptions`) for the trigger label instead of
1704
- computing it from your own state — with a provider they are empty until the
1705
- first load, so the trigger's appearance ends up depending on whether the panel
1748
+ - Reading `text` (or `selectedOptions`) for the trigger label with neither
1749
+ `known-items` nor a label from your own state — with a provider they are
1750
+ empty until the first load, so the trigger's appearance ends up depending on whether the panel
1706
1751
  was ever opened.
1707
1752
  - Binding many instances to **one shared ref**: each judges the same value against
1708
1753
  its own options and every instance that disagrees emits `null`, so the user's
@@ -1803,6 +1848,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
1803
1848
  | `items` | `Item[] \| ((context: BbSelectPopoverItemsContext) => Item[] \| Promise<Item[]>)` | `[]` | yes | The options: an array, or a sync or async provider given a `BbSelectPopoverItemsContext` (`query`, `reason`, `modelValue`, `signal`). Branch on `reason !== 'search'` to resolve the selection by id. A provider fails by THROWING, never by returning `[]`. |
1804
1849
  | `itemText` | `ItemAccessor<Item, string> \| undefined` | `own `label`, else `text`, else `JSON.stringify(item)`` | | Path to item property for display text or function to extract it. Unset: own `label`, else `text` (`{ label, value }` needs no accessor). |
1805
1850
  | `itemValue` | `ItemAccessor<Item> \| undefined` | `own `value`, else the whole item` | | Path to item property for value or function to extract it. Unset: own `value`, even `null`. |
1851
+ | `knownItems` | `(BbSelectKnownItem \| null \| undefined)[] \| undefined` | | | `{ value, label }` rows naming the value the app already holds, whatever the options' shape: the activator's `text` with no request until the first open (`prefill: true` still loads). Not options; the options' accessors never run on them; slots get the row as `item` until the list brings its own. |
1806
1852
  | `loading` | `boolean \| undefined` | `false` | | Display the loading state styles. |
1807
1853
  | `loadingText` | `string \| undefined` | | | Message shown while items are being loaded. |
1808
1854
  | `max` | `number \| undefined` | `Infinity` | | Maximum number of selectable items (limits selection when `multiple` is true). |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 3,
3
3
  "library": "bitboss-ui",
4
- "version": "3.0.0-beta.59",
4
+ "version": "3.0.0-beta.60",
5
5
  "upgrade": "v2-to-v3",
6
6
  "guide": "ai/guides/migration/v2-to-v3.md",
7
7
  "legend": {
@@ -69,7 +69,8 @@
69
69
  "3.0.0-beta.56",
70
70
  "3.0.0-beta.57",
71
71
  "3.0.0-beta.58",
72
- "3.0.0-beta.59"
72
+ "3.0.0-beta.59",
73
+ "3.0.0-beta.60"
73
74
  ],
74
75
  "unpublished": [
75
76
  "3.0.0-alpha.2",
@@ -103,7 +104,7 @@
103
104
  "class": 138
104
105
  },
105
106
  "unreleased": 0,
106
- "added": 408
107
+ "added": 409
107
108
  },
108
109
  "added": {
109
110
  "3.0.0-alpha.1": [
@@ -2056,6 +2057,15 @@
2056
2057
  "BbSelectPopover"
2057
2058
  ]
2058
2059
  }
2060
+ ],
2061
+ "3.0.0-beta.60": [
2062
+ {
2063
+ "text": "select-popover · known-items prop names the activator text at rest",
2064
+ "components": [
2065
+ "BbSelect",
2066
+ "BbSelectPopover"
2067
+ ]
2068
+ }
2059
2069
  ]
2060
2070
  },
2061
2071
  "breaking": [