bitboss-ui 3.0.0-alpha.6 → 3.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/bitboss-ui.mjs +0 -123
- package/dist/ai/BbBaseRating.md +1 -0
- package/dist/ai/BbDatePickerInput.md +7 -3
- package/dist/ai/BbIcon.md +6 -1
- package/dist/ai/BbNumberInput.md +5 -2
- package/dist/ai/BbTextInput.md +5 -3
- package/dist/ai/BbTextarea.md +5 -3
- package/dist/ai/BbToast.md +3 -1
- package/dist/ai/changelog.json +1 -1
- package/dist/ai/components.json +66 -7
- package/dist/ai/guides/agent-contract.md +3 -4
- package/dist/ai/guides/component-picker.md +7 -8
- package/dist/ai/guides/design-tokens.md +45 -0
- package/dist/ai/guides/installation-and-plugin-setup.md +15 -54
- package/dist/ai/guides/migration/components/bb-icon.md +26 -0
- package/dist/ai/guides/migration/components/bb-intersection.md +70 -0
- package/dist/ai/guides/migration/components/bb-tooltip.md +32 -7
- package/dist/ai/guides/migration/components/use-broadcast-channel-instance.md +56 -0
- package/dist/ai/guides/migration/components/use-confirm.md +18 -10
- package/dist/ai/guides/migration/v2-to-v3.md +34 -2
- package/dist/ai/guides/validated-forms.md +18 -4
- package/dist/ai/index.md +3 -2
- package/dist/ai/source/BbBadge.md +28 -1
- package/dist/ai/source/BbBaseRadioIcon.md +1 -1
- package/dist/ai/source/BbBaseRating.md +36 -2
- package/dist/ai/source/BbBaseSelect.md +33 -4
- package/dist/ai/source/BbBaseSwitchIcon.md +6 -2
- package/dist/ai/source/BbCheckboxGroup.md +2 -2
- package/dist/ai/source/BbIndicator.md +15 -1
- package/dist/ai/source/BbRadioGroup.md +2 -2
- package/dist/ai/source/BbRating.md +16 -3
- package/dist/ai/source/BbSwitchGroup.md +2 -2
- package/dist/ai/source/BbToast.md +10 -4
- package/dist/ai/source/BbToastPortal.md +10 -4
- package/dist/ai/source/BbTooltip.md +11 -2
- package/dist/ai/source/ChipsBox.md +24 -0
- package/dist/ai/source/CommaBox.md +16 -0
- package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +56 -48
- package/dist/components/BbBaseRating/BbBaseRating.vue_vue_type_script_setup_true_lang.js +33 -25
- package/dist/components/BbBaseRating/types.d.ts +8 -0
- package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +35 -32
- package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +28 -26
- package/dist/components/BbTooltip/BbTooltip.vue.d.ts +1 -1
- package/dist/components/ChipsBox/ChipsBox.vue_vue_type_script_setup_true_lang.js +64 -61
- package/dist/components/CommaBox/CommaBox.vue_vue_type_script_setup_true_lang.js +62 -59
- package/dist/composables/useConfirm.js +6 -4
- package/dist/composables/useLocale.js +2 -2
- package/dist/composables/useToast.js +37 -33
- package/dist/deprecation/ai-deprecations.json.d.ts +44 -0
- package/dist/deprecation/ai-deprecations.json.js +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +50 -51
- package/dist/llms-full.txt +359 -199
- package/dist/llms-medium.txt +25 -66
- package/dist/llms.txt +3 -2
- package/dist/styles.css +1 -1
- package/dist/types/Config.d.ts +8 -17
- package/dist/validated/useValidatedField.js +19 -19
- package/dist/vite-plugin.d.ts +3 -25
- package/dist/vite.js +116 -158
- package/llms.txt +3 -2
- package/package.json +5 -5
- package/scripts/lib/hand-roll-hints.mjs +29 -24
- package/scripts/lib/validate-bb-markup.mjs +118 -1
- package/dist/ai/composables/useBroadcastChannelInstance.md +0 -97
- package/dist/composables/useBroadcastChannelInstance.d.ts +0 -14
- package/dist/composables/useBroadcastChannelInstance.js +0 -39
package/bin/bitboss-ui.mjs
CHANGED
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
* - .windsurf/rules/bitboss-ui.md (Windsurf)
|
|
14
14
|
* Accepts an optional --mcp flag (combinable with --update) to also
|
|
15
15
|
* register the `bitboss-ui mcp` server in .mcp.json.
|
|
16
|
-
* locale Generate a custom locale blueprint (.locale.ts)
|
|
17
16
|
* check Validate Bb* markup in .vue/.md files against the installed
|
|
18
17
|
* components.json manifest (unknown props, removed props, bad
|
|
19
18
|
* v-models, unknown `<template #slot>` names, `href`/`to`/
|
|
@@ -36,7 +35,6 @@ import {
|
|
|
36
35
|
writeFileSync,
|
|
37
36
|
} from 'node:fs';
|
|
38
37
|
import { findHandRollHints } from '../scripts/lib/hand-roll-hints.mjs';
|
|
39
|
-
import { createRequire } from 'node:module';
|
|
40
38
|
import { dirname, isAbsolute, join, relative } from 'node:path';
|
|
41
39
|
import { fileURLToPath } from 'node:url';
|
|
42
40
|
import { parseArgs } from 'node:util';
|
|
@@ -285,112 +283,6 @@ function aiInit({ mcp = false } = {}) {
|
|
|
285
283
|
}
|
|
286
284
|
}
|
|
287
285
|
|
|
288
|
-
/**
|
|
289
|
-
* Serialize the blueprint dictionary as a readable TS object literal
|
|
290
|
-
* (single-quoted, tab-indented, matching the library's own locale files).
|
|
291
|
-
*/
|
|
292
|
-
function localeObjectLiteral(dictionary) {
|
|
293
|
-
const quote = (s) =>
|
|
294
|
-
`'${String(s).replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
295
|
-
const sections = Object.entries(dictionary)
|
|
296
|
-
.map(([section, entries]) => {
|
|
297
|
-
const lines = Object.entries(entries)
|
|
298
|
-
.map(([key, value]) => `\t\t${key}: ${quote(value)},`)
|
|
299
|
-
.join('\n');
|
|
300
|
-
return `\t${section}: {\n${lines}\n\t},`;
|
|
301
|
-
})
|
|
302
|
-
.join('\n');
|
|
303
|
-
return `{\n${sections}\n}`;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
function localeBlueprint(key) {
|
|
307
|
-
const projectRoot = process.cwd();
|
|
308
|
-
|
|
309
|
-
if (!key) {
|
|
310
|
-
console.error(
|
|
311
|
-
'[bitboss-ui] Usage: npx bitboss-ui locale <key> (e.g. `npx bitboss-ui locale nl`)'
|
|
312
|
-
);
|
|
313
|
-
process.exit(1);
|
|
314
|
-
}
|
|
315
|
-
// Keys double as dayjs module names (`dayjs/locale/<key>`) — keep them tame.
|
|
316
|
-
if (!/^[a-z0-9-]+$/.test(key)) {
|
|
317
|
-
console.error(
|
|
318
|
-
`[bitboss-ui] Invalid locale key '${key}' — use lowercase letters, digits and dashes (it doubles as the dayjs locale name, e.g. 'nl', 'ja', 'zh-cn').`
|
|
319
|
-
);
|
|
320
|
-
process.exit(1);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const blueprintPath = join(PACKAGE_ROOT, 'dist', 'locale-blueprint.json');
|
|
324
|
-
if (!existsSync(blueprintPath)) {
|
|
325
|
-
console.error(
|
|
326
|
-
'[bitboss-ui] dist/locale-blueprint.json not found in the installed package — reinstall bitboss-ui (or run `npm run build` when working in the library repo).'
|
|
327
|
-
);
|
|
328
|
-
process.exit(1);
|
|
329
|
-
}
|
|
330
|
-
const { builtins, template } = JSON.parse(
|
|
331
|
-
readFileSync(blueprintPath, 'utf-8')
|
|
332
|
-
);
|
|
333
|
-
|
|
334
|
-
if (builtins.includes(key)) {
|
|
335
|
-
console.error(
|
|
336
|
-
`[bitboss-ui] '${key}' is a built-in locale — built-ins cannot be overridden; the \`additionalLocales\` option only adds new ones. Just set \`locale: '${key}'\`.`
|
|
337
|
-
);
|
|
338
|
-
process.exit(1);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
const outPath = join(projectRoot, `${key}.locale.ts`);
|
|
342
|
-
if (existsSync(outPath)) {
|
|
343
|
-
console.error(
|
|
344
|
-
`[bitboss-ui] ${key}.locale.ts already exists — delete it first if you want a fresh blueprint.`
|
|
345
|
-
);
|
|
346
|
-
process.exit(1);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Same check the vite plugin performs at build time — surface it here too,
|
|
350
|
-
// while the consumer is still choosing the key.
|
|
351
|
-
let dayjsHint = `Calendar (dayjs) locale '${key}' found — calendars will follow automatically.`;
|
|
352
|
-
try {
|
|
353
|
-
// Consumer's own resolution first; fall back to the installed package's
|
|
354
|
-
// (dayjs is a bitboss-ui dependency, so it's always reachable from here).
|
|
355
|
-
try {
|
|
356
|
-
createRequire(join(projectRoot, 'package.json')).resolve(
|
|
357
|
-
`dayjs/locale/${key}.js`
|
|
358
|
-
);
|
|
359
|
-
} catch {
|
|
360
|
-
createRequire(join(PACKAGE_ROOT, 'package.json')).resolve(
|
|
361
|
-
`dayjs/locale/${key}.js`
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
} catch {
|
|
365
|
-
dayjsHint = `⚠ dayjs ships no locale named '${key}' — calendars will fall back to English (the vite plugin repeats this warning at build time). If a nearby dayjs name exists (e.g. 'zh-cn', 'pt-br'), prefer it as your key: https://github.com/iamkun/dayjs/tree/dev/src/locale`;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
writeFileSync(
|
|
369
|
-
outPath,
|
|
370
|
-
`import type { LocaleOverrides } from 'bitboss-ui';
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* bitboss-ui locale blueprint for '${key}' — generated by \`npx bitboss-ui locale ${key}\`.
|
|
374
|
-
*
|
|
375
|
-
* Translate the English strings below ({0}/{1} placeholders are interpolated
|
|
376
|
-
* arguments — keep them). Keys you delete fall back per-key to the library's
|
|
377
|
-
* default locale. Register it in your vite config:
|
|
378
|
-
*
|
|
379
|
-
* import ${key.replace(/-/g, '_')} from './${key}.locale';
|
|
380
|
-
* bitbossUi({ iconDir: '...', locale: '${key}', additionalLocales: { '${key}': ${key.replace(/-/g, '_')} } })
|
|
381
|
-
*
|
|
382
|
-
* The plugin regenerates \`locale-registry.d.ts\` on build start, making
|
|
383
|
-
* '${key}' a valid \`locale\` value everywhere (run dev once after adding it).
|
|
384
|
-
*/
|
|
385
|
-
export default ${localeObjectLiteral(template)} satisfies LocaleOverrides;
|
|
386
|
-
`,
|
|
387
|
-
'utf-8'
|
|
388
|
-
);
|
|
389
|
-
|
|
390
|
-
console.log(`[bitboss-ui] Wrote ${key}.locale.ts (English blueprint).`);
|
|
391
|
-
console.log(` ${dayjsHint}`);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
286
|
// SNT-007: a bare-segment skip list of `node_modules`/`dist`/`.git` let a
|
|
395
287
|
// default (no-glob) `check` sweep straight through a Laravel-style consumer's
|
|
396
288
|
// `vendor/`, `storage/`, and `public/` trees — hundreds of vendored
|
|
@@ -724,9 +616,6 @@ Commands:
|
|
|
724
616
|
mcp Start a stdio MCP server exposing the dist/ai knowledge
|
|
725
617
|
base (search_components, get_component, list_recipes,
|
|
726
618
|
get_recipe, validate) to MCP-capable agent harnesses.
|
|
727
|
-
locale <key> Generate <key>.locale.ts at the project root — an English
|
|
728
|
-
blueprint dictionary to translate and pass to the plugin's
|
|
729
|
-
\`additionalLocales\` option (additions only; built-ins are refused).
|
|
730
619
|
help Show this help.
|
|
731
620
|
`);
|
|
732
621
|
}
|
|
@@ -804,18 +693,6 @@ switch (command) {
|
|
|
804
693
|
await main();
|
|
805
694
|
break;
|
|
806
695
|
}
|
|
807
|
-
case 'locale': {
|
|
808
|
-
const { positionals } = parseCommandArgs(
|
|
809
|
-
command,
|
|
810
|
-
commandArgs,
|
|
811
|
-
{},
|
|
812
|
-
{
|
|
813
|
-
allowPositionals: true,
|
|
814
|
-
}
|
|
815
|
-
);
|
|
816
|
-
localeBlueprint(positionals[0]);
|
|
817
|
-
break;
|
|
818
|
-
}
|
|
819
696
|
case 'help':
|
|
820
697
|
case '--help':
|
|
821
698
|
case '-h':
|
package/dist/ai/BbBaseRating.md
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
| Prop | Type | Default | Required | Description |
|
|
18
18
|
| --- | --- | --- | --- | --- |
|
|
19
19
|
| `ariaDescribedby` | `string \| undefined` | | | Id(s) of elements describing this rating input for assistive technologies. |
|
|
20
|
+
| `ariaLabelledby` | `string \| undefined` | | | Id(s) of the element(s) that NAME this rating group. Supplying one is what promotes the inner container to `role="radiogroup"` (Q4.5): an unnamed `radiogroup` announces as a bare "radio group" and is no better than the role-less `<span>` it… |
|
|
20
21
|
| `autofocus` | `Booleanish \| undefined` | | | Sets autofocus on page load. |
|
|
21
22
|
| `clearable` | `boolean \| undefined` | `false` | | Allows clearing the selected rating by clicking the current value. |
|
|
22
23
|
| `disabled` | `boolean \| undefined` | | | Disable all interactions with the rating. |
|
|
@@ -33,9 +33,13 @@ date (see _Time selection_). `label` is required.
|
|
|
33
33
|
|
|
34
34
|
The shared surface applies:
|
|
35
35
|
|
|
36
|
-
- **`label`** (required)
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
- **`label`** (required) names the field for display and accessibility only —
|
|
37
|
+
it has **no** effect on the native `name` attribute of the segment inputs.
|
|
38
|
+
Leave `name` unset and the rendered segments carry none at all, so a plain
|
|
39
|
+
form post silently drops the value; pass `name` explicitly whenever it's
|
|
40
|
+
submitted via a native form or read from `FormData`. **`hideLabel`** hides
|
|
41
|
+
it visually while keeping the accessible name; **`labelPosition`** aligns
|
|
42
|
+
it; the **`label` slot** replaces it with `{ text, hasErrors }`.
|
|
39
43
|
- **`labelMode`** — `outside` / `floating` / `inside`. When unset it falls back
|
|
40
44
|
to the project-wide `config.defaultInputLabelMode` (library default:
|
|
41
45
|
`outside`), the same resolution as `BbTextInput` and `BbNumberInput`.
|
package/dist/ai/BbIcon.md
CHANGED
|
@@ -135,7 +135,12 @@ The `icon` prop takes a name in one of three forms:
|
|
|
135
135
|
- **`local:name`** — an SVG in the configured `iconDir` (brand marks, custom
|
|
136
136
|
illustrations). Each `.svg` file becomes `local:<basename>`.
|
|
137
137
|
- **bare `name`** — an unprefixed name **normalizes to `local:`**; it never
|
|
138
|
-
searches provider sets.
|
|
138
|
+
searches provider sets. Prefer writing the prefix anyway: the Iconify editor
|
|
139
|
+
extension keys off `prefix:name`, so `local:user-circle` gets an inline
|
|
140
|
+
preview and name autocomplete in the template while a bare `user-circle`
|
|
141
|
+
reads as an ordinary string and gets neither. It also puts your own art in
|
|
142
|
+
the same shape as `mdi:home` / `lucide:check`, so the source of every icon is
|
|
143
|
+
legible without inferring it from a missing prefix.
|
|
139
144
|
|
|
140
145
|
Discovery-first: **only use names you have verified exist** — a missing icon
|
|
141
146
|
**throws at mount** (dev shows an actionable Vite overlay with the exact
|
package/dist/ai/BbNumberInput.md
CHANGED
|
@@ -36,8 +36,11 @@ and locale-separator quirks of native number inputs don't apply here.
|
|
|
36
36
|
|
|
37
37
|
### Label & label modes
|
|
38
38
|
|
|
39
|
-
`label` is required
|
|
40
|
-
|
|
39
|
+
`label` is required, but it names the field for display and accessibility
|
|
40
|
+
only — it has **no** effect on the native `name` attribute. Leave `name`
|
|
41
|
+
unset and the rendered `<input>` carries none at all, so a plain form post
|
|
42
|
+
silently drops the value; pass `name` explicitly whenever it's submitted via
|
|
43
|
+
a native form or read from `FormData`. The shared label controls apply:
|
|
41
44
|
|
|
42
45
|
- **`labelMode`** sets where the label sits: `outside` (default, above),
|
|
43
46
|
`floating` (rests inside like a placeholder, lifts on focus/fill) or `inside`
|
package/dist/ai/BbTextInput.md
CHANGED
|
@@ -29,9 +29,11 @@ Pick a sibling when the shape of the data is different:
|
|
|
29
29
|
|
|
30
30
|
### Label & label modes
|
|
31
31
|
|
|
32
|
-
`label` names the field and
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
`label` names the field for display and accessibility only — it has **no**
|
|
33
|
+
effect on the native `name` attribute. Leave `name` unset and the rendered
|
|
34
|
+
`<input>` carries none at all, so a plain form post silently drops the value.
|
|
35
|
+
Pass `name` explicitly whenever the value is submitted via a native form or
|
|
36
|
+
read from `FormData`.
|
|
35
37
|
|
|
36
38
|
- **`labelMode`** sets where the label sits: `outside` (above the field),
|
|
37
39
|
`floating` (rests inside like a placeholder at reduced opacity, lifts on
|
package/dist/ai/BbTextarea.md
CHANGED
|
@@ -30,9 +30,11 @@ Pick a sibling when the shape of the data is different:
|
|
|
30
30
|
|
|
31
31
|
### Label
|
|
32
32
|
|
|
33
|
-
`label` names the field and
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
`label` names the field for display and accessibility only — it has **no**
|
|
34
|
+
effect on the native `name` attribute. Leave `name` unset and the rendered
|
|
35
|
+
`<textarea>` carries none at all, so a plain form post silently drops the
|
|
36
|
+
value. Pass `name` explicitly whenever the value is submitted via a native
|
|
37
|
+
form or read from `FormData`.
|
|
36
38
|
|
|
37
39
|
- **`hideLabel`** keeps the label for screen readers but removes it visually.
|
|
38
40
|
- **`labelPosition`** aligns the label text `left` / `center` / `right`.
|
package/dist/ai/BbToast.md
CHANGED
|
@@ -165,7 +165,9 @@ Three things worth internalising:
|
|
|
165
165
|
- **Variants tint the icon and set announcement priority — nothing else.** A
|
|
166
166
|
variant toast without an `icon` looks identical to a default one, so pass a
|
|
167
167
|
matching icon (`lucide:circle-check` for success, `lucide:circle-x` for
|
|
168
|
-
destructive…) whenever the tone matters visually. No icon is ever implied
|
|
168
|
+
destructive…) whenever the tone matters visually. No icon is ever implied —
|
|
169
|
+
dev builds warn when a built-in variant is used without one, since the tone
|
|
170
|
+
is otherwise dropped with no trace.
|
|
169
171
|
- `toast(...)` returns the message `id`. Keep it to `update(...)` or
|
|
170
172
|
`dismiss(...)` that toast later; `dismiss()` with no argument clears the
|
|
171
173
|
whole stack.
|
package/dist/ai/changelog.json
CHANGED
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-
|
|
5
|
-
"generatedAt": "2026-08-
|
|
4
|
+
"version": "3.0.0-beta.0",
|
|
5
|
+
"generatedAt": "2026-08-24T15:06:25.249Z",
|
|
6
6
|
"composables": [
|
|
7
7
|
{
|
|
8
8
|
"name": "useBbConfig",
|
|
@@ -24,11 +24,6 @@
|
|
|
24
24
|
"description": "Read and drive a BbTabs/BbTabsRoot group from anywhere by id — writable current tab, goTo/select, no template refs.",
|
|
25
25
|
"doc": "ai/composables/useBbTabsContext.md"
|
|
26
26
|
},
|
|
27
|
-
{
|
|
28
|
-
"name": "useBroadcastChannelInstance",
|
|
29
|
-
"description": "Typed cross-tab messaging via the BroadcastChannel API with per-component subscriber lifecycle.",
|
|
30
|
-
"doc": "ai/composables/useBroadcastChannelInstance.md"
|
|
31
|
-
},
|
|
32
27
|
{
|
|
33
28
|
"name": "useConfirm",
|
|
34
29
|
"description": "Promise-based confirm dialogs — await the user's yes/no, with yes/no button configs, async onClick busy states, and portal content. Requires exactly one <BbConfirm /> host, mounted at the app root.",
|
|
@@ -243,6 +238,16 @@
|
|
|
243
238
|
"fix": {
|
|
244
239
|
"kind": "invert"
|
|
245
240
|
}
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"name": "theme",
|
|
244
|
+
"new": "variant",
|
|
245
|
+
"since": "3.0.0-unreleased",
|
|
246
|
+
"migration": "ai/guides/migration/components/bb-alert.md",
|
|
247
|
+
"silent": true,
|
|
248
|
+
"fix": {
|
|
249
|
+
"kind": "rename"
|
|
250
|
+
}
|
|
246
251
|
}
|
|
247
252
|
],
|
|
248
253
|
"renamed": [
|
|
@@ -254,6 +259,15 @@
|
|
|
254
259
|
"fix": {
|
|
255
260
|
"kind": "invert"
|
|
256
261
|
}
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"from": "theme",
|
|
265
|
+
"to": "variant",
|
|
266
|
+
"since": "3.0.0-unreleased",
|
|
267
|
+
"migration": "ai/guides/migration/components/bb-alert.md",
|
|
268
|
+
"fix": {
|
|
269
|
+
"kind": "rename"
|
|
270
|
+
}
|
|
257
271
|
}
|
|
258
272
|
]
|
|
259
273
|
},
|
|
@@ -3020,6 +3034,12 @@
|
|
|
3020
3034
|
"required": false,
|
|
3021
3035
|
"description": "Id(s) of elements describing this rating input for assistive technologies."
|
|
3022
3036
|
},
|
|
3037
|
+
{
|
|
3038
|
+
"name": "ariaLabelledby",
|
|
3039
|
+
"type": "string | undefined",
|
|
3040
|
+
"required": false,
|
|
3041
|
+
"description": "Id(s) of the element(s) that NAME this rating group. Supplying one is what\npromotes the inner container to `role=\"radiogroup\"` (Q4.5): an unnamed\n`radiogroup` announces as a bare \"radio group\" and is no better than the\nrole-less `<span>` it replaces, so the role is withheld until a name\nsource exists. `BbRating` wires this to its `<legend>`."
|
|
3042
|
+
},
|
|
3023
3043
|
{
|
|
3024
3044
|
"name": "autofocus",
|
|
3025
3045
|
"type": "Booleanish | undefined",
|
|
@@ -15246,6 +15266,36 @@
|
|
|
15246
15266
|
}
|
|
15247
15267
|
],
|
|
15248
15268
|
"removed": [
|
|
15269
|
+
{
|
|
15270
|
+
"name": "block",
|
|
15271
|
+
"new": null,
|
|
15272
|
+
"since": "3.0.0-unreleased",
|
|
15273
|
+
"migration": "ai/guides/migration/components/bb-tooltip.md",
|
|
15274
|
+
"silent": true,
|
|
15275
|
+
"fix": {
|
|
15276
|
+
"kind": "remove"
|
|
15277
|
+
}
|
|
15278
|
+
},
|
|
15279
|
+
{
|
|
15280
|
+
"name": "showClose",
|
|
15281
|
+
"new": null,
|
|
15282
|
+
"since": "3.0.0-unreleased",
|
|
15283
|
+
"migration": "ai/guides/migration/components/bb-tooltip.md",
|
|
15284
|
+
"silent": true,
|
|
15285
|
+
"fix": {
|
|
15286
|
+
"kind": "remove"
|
|
15287
|
+
}
|
|
15288
|
+
},
|
|
15289
|
+
{
|
|
15290
|
+
"name": "theme",
|
|
15291
|
+
"new": "variant",
|
|
15292
|
+
"since": "3.0.0-unreleased",
|
|
15293
|
+
"migration": "ai/guides/migration/components/bb-tooltip.md",
|
|
15294
|
+
"silent": true,
|
|
15295
|
+
"fix": {
|
|
15296
|
+
"kind": "rename"
|
|
15297
|
+
}
|
|
15298
|
+
},
|
|
15249
15299
|
{
|
|
15250
15300
|
"name": "timeout",
|
|
15251
15301
|
"new": "delay",
|
|
@@ -15258,6 +15308,15 @@
|
|
|
15258
15308
|
}
|
|
15259
15309
|
],
|
|
15260
15310
|
"renamed": [
|
|
15311
|
+
{
|
|
15312
|
+
"from": "theme",
|
|
15313
|
+
"to": "variant",
|
|
15314
|
+
"since": "3.0.0-unreleased",
|
|
15315
|
+
"migration": "ai/guides/migration/components/bb-tooltip.md",
|
|
15316
|
+
"fix": {
|
|
15317
|
+
"kind": "rename"
|
|
15318
|
+
}
|
|
15319
|
+
},
|
|
15261
15320
|
{
|
|
15262
15321
|
"from": "timeout",
|
|
15263
15322
|
"to": "delay",
|
|
@@ -234,11 +234,10 @@ twice.
|
|
|
234
234
|
Symptoms that mean stop: an `<img>` with an initials/icon fallback →
|
|
235
235
|
`BbAvatar` (**circle-only** — a rounded-square avatar really is yours to build);
|
|
236
236
|
a hand-written spin animation → `BbSpinner`; a tinted `<span>` pill standing for
|
|
237
|
-
a status → `BbBadge` with a registered `soft-*` variant
|
|
238
|
-
`new BroadcastChannel(…)` → `useBroadcastChannelInstance`. Full symptom index:
|
|
237
|
+
a status → `BbBadge` with a registered `soft-*` variant. Full symptom index:
|
|
239
238
|
[Component Picker](./component-picker.md) § Am I about to rebuild one of ours?
|
|
240
239
|
|
|
241
|
-
`npx bitboss-ui check` prints the avatar
|
|
240
|
+
`npx bitboss-ui check` prints the avatar and spinner shapes
|
|
242
241
|
as **advisory hints** — never a build failure, because a round `<img>` is
|
|
243
242
|
sometimes a logo — so that much backstops itself on files it scans. The badge
|
|
244
243
|
case is not decidable from markup and has no hint.
|
|
@@ -255,4 +254,4 @@ case is not decidable from markup and has no hint.
|
|
|
255
254
|
- [ ] Uses declarative coherence/dependencies before manual watchers.
|
|
256
255
|
- [ ] Mounts exactly one `<BbToast />` and one `<BbConfirm />` host, at the app root — never inside a page or component.
|
|
257
256
|
- [ ] Confirmed the plugin's `locale` is set explicitly if the app isn't Italian (default is `'it'`) — see Setup-First Rule.
|
|
258
|
-
- [ ] Ran the Rebuild Check over the hand-written markup — nothing reimplements `BbAvatar`, `BbSpinner
|
|
257
|
+
- [ ] Ran the Rebuild Check over the hand-written markup — nothing reimplements `BbAvatar`, `BbSpinner` or `BbBadge`.
|
|
@@ -22,12 +22,11 @@ this picker four times and hand-rolled an avatar twice while `BbAvatar` sat in
|
|
|
22
22
|
the Data Display table below. So this section is indexed by **symptom**: match it
|
|
23
23
|
against the markup you are about to write, not against a need.
|
|
24
24
|
|
|
25
|
-
| You are about to write | Stop — use
|
|
26
|
-
| ------------------------------------------------------------------------------------------- |
|
|
27
|
-
| An `<img>` with an initials/icon fallback branch, `border-radius: 50%`, `object-fit: cover` | [BbAvatar](../BbAvatar.md) — `src`/`alt`/size, initials slot, icon fallback, load-error handling
|
|
28
|
-
| `@keyframes spin` / `animation: … spin` on an element that means "waiting" | [BbSpinner](../BbSpinner.md) — sized off the control scale, honours `prefers-reduced-motion`
|
|
29
|
-
| A `<span>` pill with a tinted background standing for a status | [BbBadge](../BbBadge.md) with a registered `soft-*` variant (design-language § Getting soft semantic badges)
|
|
30
|
-
| `new BroadcastChannel('…')` for cross-tab sync | [useBroadcastChannelInstance](../composables/useBroadcastChannelInstance.md) — a typed wrapper: each call opens its own channel and removes its listeners on unmount |
|
|
25
|
+
| You are about to write | Stop — use |
|
|
26
|
+
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
27
|
+
| An `<img>` with an initials/icon fallback branch, `border-radius: 50%`, `object-fit: cover` | [BbAvatar](../BbAvatar.md) — `src`/`alt`/size, initials slot, icon fallback, load-error handling |
|
|
28
|
+
| `@keyframes spin` / `animation: … spin` on an element that means "waiting" | [BbSpinner](../BbSpinner.md) — sized off the control scale, honours `prefers-reduced-motion` |
|
|
29
|
+
| A `<span>` pill with a tinted background standing for a status | [BbBadge](../BbBadge.md) with a registered `soft-*` variant (design-language § Getting soft semantic badges) |
|
|
31
30
|
|
|
32
31
|
**`BbAvatar` is circle-only.** Its `border-radius: 50%` is in the component's own
|
|
33
32
|
CSS and no prop changes it, so a rounded-**square** avatar genuinely has no answer
|
|
@@ -35,7 +34,7 @@ here — build that one yourself. Everything else about it (fallbacks, load erro
|
|
|
35
34
|
sizing) still applies, so the honest options are "use it and accept a circle" or
|
|
36
35
|
"hand-roll the square one knowingly", not "hand-roll it because you never saw it".
|
|
37
36
|
|
|
38
|
-
`npx bitboss-ui check` prints the avatar
|
|
37
|
+
`npx bitboss-ui check` prints the avatar and spinner rows as
|
|
39
38
|
**advisory hints** — never a build failure, since a round `<img>` is sometimes a
|
|
40
39
|
logo — on every `.vue` file it scans. That is the backstop: it fires without
|
|
41
40
|
anyone thinking to ask. The badge case is not decidable from markup (a tinted
|
|
@@ -244,7 +243,7 @@ compose it or write it yourself.
|
|
|
244
243
|
| `BbTab` (singular) | The consumer API is [BbTabs](../BbTabs.md) / `BbTabsRoot`. `BbTab` appears only as the **v2 "before" side** of the migration diffs. |
|
|
245
244
|
| `BbCard` | Does not exist — a card is a `<div>` with tokens. See [design-language](./design-language.md). |
|
|
246
245
|
| `BbList` / `BbListItem` / `BbDescriptionList` | Do not exist — a list row is an `<li>` with tokens, and [BbBaseButton](../BbBaseButton.md) makes the whole row navigable. See the note under Data Display. |
|
|
247
|
-
| `useLiveFeed` / any polling or cross-tab feed helper | Does not exist
|
|
246
|
+
| `useLiveFeed` / any polling or cross-tab feed helper | Does not exist, and neither does a cross-tab helper — `useBroadcastChannelInstance` was removed (cross-tab messaging is not a UI concern). Use `useBroadcastChannel` from `@vueuse/core`; the polling and the merge are yours. |
|
|
248
247
|
| `BbStepper` / `BbWizard` | Does not exist as a component; the wizard-form recipe composes one. |
|
|
249
248
|
| `BbSkeleton` (standalone) | Only `BbTable` ships skeletons, via the column `skeleton` field. |
|
|
250
249
|
| `BbCommand` / command palette | Does not exist. Compose `BbDialog` + `BbSelectPopover`. |
|
|
@@ -295,6 +295,51 @@ Component tokens are still real affordances: a consumer can retune one
|
|
|
295
295
|
instance (`<BbTabs style="--list-h: 40px">`) or a whole page scope. They are
|
|
296
296
|
just not global namespace.
|
|
297
297
|
|
|
298
|
+
### Overriding one from a consumer app
|
|
299
|
+
|
|
300
|
+
Three rules, in order of how often they are broken.
|
|
301
|
+
|
|
302
|
+
**1. Override only what you actually render.** Several components expose a
|
|
303
|
+
per-size lookup table (`--icon-size-xs … --icon-size-2xl`, `--h-xs … --h-2xl`)
|
|
304
|
+
plus an _active_ token the size class re-points. Setting the whole family
|
|
305
|
+
because you want one value is not "thorough" — it silently opts you out of the
|
|
306
|
+
size scale for variants you may start using later, and it buries the one line
|
|
307
|
+
that mattered. Retune the sizes you use:
|
|
308
|
+
|
|
309
|
+
```css
|
|
310
|
+
/* we render sm and md buttons; leave the rest on the library's scale */
|
|
311
|
+
.bb-button {
|
|
312
|
+
--icon-size-sm: 12px;
|
|
313
|
+
--icon-size-md: 12px;
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**2. Override the per-size entry, not the active token.** The active token is
|
|
318
|
+
re-resolved by the size class, which is _more specific_ than the root class:
|
|
319
|
+
|
|
320
|
+
```css
|
|
321
|
+
.bb-button {
|
|
322
|
+
--icon-size: var(--icon-size-md);
|
|
323
|
+
} /* 0,1,0 */
|
|
324
|
+
.bb-button--sm {
|
|
325
|
+
--icon-size: var(--icon-size-sm);
|
|
326
|
+
} /* 0,2,0 — nested */
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
So `.bb-button { --icon-size: 12px }` appears to work on default buttons and
|
|
330
|
+
silently does nothing on every `size="sm"` one — the confusing half-failure that
|
|
331
|
+
sends people to the shotgun in rule 1. The per-size entry has no competing
|
|
332
|
+
declaration, so it always wins. (A scope selector of equal-or-greater
|
|
333
|
+
specificity also works, but you have to keep winning that race; overriding the
|
|
334
|
+
entry does not.)
|
|
335
|
+
|
|
336
|
+
**3. Scope it to the component, never `:root`.** Short names are deliberately
|
|
337
|
+
reused across components — `--icon-size` is read by `BbButton`, `BbBadge` and
|
|
338
|
+
`CloseIcon`; `--gap`, `--px`, `--h` are everywhere. Hoisting one to `:root`
|
|
339
|
+
retunes every component that happens to share the name, which is exactly what
|
|
340
|
+
tier-2's sealing rule exists to prevent. Put it on the component's class, a page
|
|
341
|
+
scope, or the instance's `style=`.
|
|
342
|
+
|
|
298
343
|
## The emphasis ladder
|
|
299
344
|
|
|
300
345
|
All translucency/tinting goes through **one ladder** of `color-mix()`
|
|
@@ -319,7 +319,7 @@ Default label rendering mode for input-like components; set globally instead of
|
|
|
319
319
|
|
|
320
320
|
### `requiredAsterisk?: boolean` (default: `false`)
|
|
321
321
|
|
|
322
|
-
Marks required fields with a red asterisk beside the label/legend. Presentational only — it keys off the standard `required` prop and changes neither validation nor native `required` semantics. The marker is applied by the [`bitboss-ui/validated`](./validated-forms.md) controls
|
|
322
|
+
Marks required fields with a red asterisk beside the label/legend. Presentational only — it keys off the standard `required` prop and changes neither validation nor native `required` semantics. The marker is applied by the [`bitboss-ui/validated`](./validated-forms.md) controls — a field that is `required`, or whose `rules` contain a `required` rule; other rules never raise it, because they only apply once a value exists. Core controls ignore the flag, so on a hand-wired form render the exported `BbAsterisk` in your own label content.
|
|
323
323
|
|
|
324
324
|
### `locale?: LocaleKey` (default: `'it'`)
|
|
325
325
|
|
|
@@ -350,70 +350,31 @@ bitbossUi({
|
|
|
350
350
|
```
|
|
351
351
|
|
|
352
352
|
Your `locale` and `'en'` are always auto-included, so the list never needs to
|
|
353
|
-
repeat them
|
|
354
|
-
belong here.
|
|
353
|
+
repeat them.
|
|
355
354
|
There is deliberately **no catch-all** ("all") value — it would hide the
|
|
356
355
|
bundle cost. Wanting every built-in means writing the list, so the cost is
|
|
357
356
|
visible in your config where reviewers can see it.
|
|
358
357
|
|
|
359
358
|
**Selecting a non-enabled locale is a compile error**, not a silent runtime
|
|
360
|
-
fallback: the generated `locale-registry.d.ts` registers only enabled
|
|
361
|
-
built-ins
|
|
362
|
-
|
|
359
|
+
fallback: the generated `locale-registry.d.ts` registers only the enabled
|
|
360
|
+
built-ins, so `setConfig({ locale: 'ja' })` fails to type-check until `'ja'` is
|
|
361
|
+
enabled. Run dev once after changing the list.
|
|
363
362
|
|
|
364
|
-
###
|
|
363
|
+
### Custom locales are not a supported surface
|
|
365
364
|
|
|
366
|
-
**
|
|
367
|
-
built-in locales cannot be overridden — a built-in key here is a type error,
|
|
368
|
-
and one smuggled past the compiler is ignored with a build-time warning.
|
|
365
|
+
The library ships **22 dictionaries** and that is the whole set:
|
|
369
366
|
|
|
370
|
-
The full flow for adding a locale (using Georgian, which the library doesn't
|
|
371
|
-
ship):
|
|
372
|
-
|
|
373
|
-
```bash
|
|
374
|
-
# 1. Generate a translation blueprint (English strings) at the project root
|
|
375
|
-
npx bitboss-ui locale ka
|
|
376
367
|
```
|
|
377
|
-
|
|
378
|
-
```ts
|
|
379
|
-
// 2. Translate ka.locale.ts, then register it
|
|
380
|
-
import ka from './ka.locale';
|
|
381
|
-
|
|
382
|
-
bitbossUi({
|
|
383
|
-
iconDir: './src/assets/icons',
|
|
384
|
-
locale: 'ka',
|
|
385
|
-
additionalLocales: { ka },
|
|
386
|
-
});
|
|
368
|
+
cs da de el en es fi fr hu it ja ko nb nl pl pt ro ru sv tr uk zh-cn
|
|
387
369
|
```
|
|
388
370
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
- **regenerates `locale-registry.d.ts`**, augmenting `LocaleRegistry` with
|
|
398
|
-
your keys (exactly like the variant registries), so `'ka'` is a valid
|
|
399
|
-
`locale` value everywhere — the plugin option and `setConfig({ locale })`
|
|
400
|
-
alike. Run dev once after adding a key so the file exists.
|
|
401
|
-
- **wires the matching dayjs locale** (`dayjs/locale/ka`) so calendars follow
|
|
402
|
-
your locale's month/day names and week start. Any dayjs-shipped name works.
|
|
403
|
-
If dayjs has no locale under your key, the plugin **warns at build time**
|
|
404
|
-
and calendars fall back to English (there is no runtime warning) — when a
|
|
405
|
-
nearby dayjs name exists (`zh-cn`, `pt-br`, …), prefer it as your key.
|
|
406
|
-
|
|
407
|
-
Keys you delete from the blueprint fall back per-key to the default locale
|
|
408
|
-
(your `locale` when it's a built-in, otherwise `en` — always bundled, always
|
|
409
|
-
complete) — and are reported by the completeness warning above, which is the
|
|
410
|
-
point: partial is allowed, silent-partial is not.
|
|
411
|
-
|
|
412
|
-
Locale dictionaries are **build-time only**: `setConfig` accepts `locale` but
|
|
413
|
-
deliberately not `additionalLocales` — a runtime path would bypass every check
|
|
414
|
-
the plugin performs (built-in collision, completeness verification, dayjs
|
|
415
|
-
wiring, registry typing). Only the active `locale` switches at runtime, among
|
|
416
|
-
what the build enabled.
|
|
371
|
+
There is no `additionalLocales` option and no `npx bitboss-ui locale` blueprint
|
|
372
|
+
generator — both were removed deliberately (owner ruling, 2026-08-08). If your
|
|
373
|
+
language is not on that list, the supported answer is to ask for it to be
|
|
374
|
+
added upstream rather than to author a dictionary in your app.
|
|
375
|
+
|
|
376
|
+
Locale selection is **build-time**: `enabledLocales` decides what ships, and
|
|
377
|
+
only the active `locale` switches at runtime, among what the build enabled.
|
|
417
378
|
|
|
418
379
|
### `toastPosition?: BbToastPosition` (default: `'bottom-right'`)
|
|
419
380
|
|
|
@@ -25,3 +25,29 @@ summary: The required prop is renamed type→icon, color is removed, and the xxl
|
|
|
25
25
|
Provider prefixes now require the matching `@iconify-json/<prefix>` dev
|
|
26
26
|
dependency, and names must be **literal strings** (the build scans statically;
|
|
27
27
|
dynamically assembled names won't be bundled).
|
|
28
|
+
|
|
29
|
+
## Prefix your own icons with `local:` while you are in there
|
|
30
|
+
|
|
31
|
+
A v2 `type` naming an icon from your own `iconDir` was bare — `type="user-circle"`.
|
|
32
|
+
Carry it over **with the prefix**:
|
|
33
|
+
|
|
34
|
+
```diff
|
|
35
|
+
- <BbIcon type="user-circle" />
|
|
36
|
+
+ <BbIcon icon="local:user-circle" />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This is not a functional change: `BbIcon` already resolves a name with no `:`
|
|
40
|
+
as `local:<name>`, so both spellings render the same icon. It is a **tooling**
|
|
41
|
+
change, and worth doing across the whole app in one pass:
|
|
42
|
+
|
|
43
|
+
- The Iconify editor extension keys off `prefix:name`. Spelled `local:user-circle`
|
|
44
|
+
it renders an inline preview and autocompletes the name in the template; spelled
|
|
45
|
+
`user-circle` it sees an ordinary string and shows nothing.
|
|
46
|
+
- It reads unambiguously next to `mdi:home` / `lucide:check` — same shape, and the
|
|
47
|
+
source of every icon is legible at a glance instead of inferred from absence.
|
|
48
|
+
|
|
49
|
+
Apply it wherever the name is written **literally in a template**. Leave names that
|
|
50
|
+
arrive through a variable, a map, or props alone — the prefix buys nothing there
|
|
51
|
+
(no extension preview to gain), and rewriting data is out of scope for a rename.
|
|
52
|
+
The same goes for any component prop that takes an icon (`prepend:icon`,
|
|
53
|
+
`append:icon`, `icon` on buttons, dropdown items, toasts…), not just `<BbIcon>`.
|