bitboss-ui 3.0.0-alpha.5 → 3.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -14
- package/bin/bitboss-ui-mcp.mjs +16 -2
- package/bin/bitboss-ui.mjs +93 -3
- package/dist/ai/BbAlert.md +9 -7
- package/dist/ai/BbAvatar.md +14 -7
- package/dist/ai/BbBadgeButton.md +13 -0
- package/dist/ai/BbBaseButton.md +19 -3
- package/dist/ai/BbButton.md +48 -4
- package/dist/ai/BbDropdownButton.md +0 -1
- package/dist/ai/BbDropzone.md +136 -31
- package/dist/ai/BbRadio.md +7 -5
- package/dist/ai/BbRadioGroup.md +3 -2
- package/dist/ai/BbSelect.md +1 -1
- package/dist/ai/BbSelectPopover.md +7 -1
- package/dist/ai/BbSwitchGroup.md +0 -3
- package/dist/ai/BbTable.md +17 -19
- package/dist/ai/BbTabs.md +26 -1
- package/dist/ai/changelog.json +284 -0
- package/dist/ai/components.json +301 -11
- package/dist/ai/composables/useBbTableContext.md +12 -12
- package/dist/ai/guides/agent-contract.md +33 -1
- package/dist/ai/guides/ai-router.md +5 -2
- package/dist/ai/guides/app-layout.md +43 -3
- package/dist/ai/guides/coherence-playbook.md +10 -10
- package/dist/ai/guides/component-picker.md +45 -8
- package/dist/ai/guides/design-tokens.md +19 -6
- package/dist/ai/guides/fetch-items-playbook.md +3 -1
- package/dist/ai/guides/inertia-helpers.md +91 -16
- package/dist/ai/guides/inline-edit-playbook.md +41 -0
- package/dist/ai/guides/installation-and-plugin-setup.md +60 -10
- package/dist/ai/guides/migration/components/bb-date-picker-input.md +38 -0
- package/dist/ai/guides/migration/components/bb-select-popover.md +2 -0
- package/dist/ai/guides/migration/components/bb-select.md +26 -0
- package/dist/ai/guides/migration/components/bb-spinner.md +18 -0
- package/dist/ai/guides/migration/components/bb-text-input.md +9 -0
- package/dist/ai/guides/migration/v2-to-v3.md +2 -1
- package/dist/ai/guides/options-items-playbook.md +1 -1
- package/dist/ai/guides/page-shell.md +57 -9
- package/dist/ai/guides/validated-forms.md +3 -1
- package/dist/ai/recipes/inertia/approvals-inbox.md +9 -3
- package/dist/ai/recipes/inertia/layout-scaffold.md +98 -2
- package/dist/ai/recipes/inertia/records-workspace.md +1 -1
- package/dist/ai/recipes/inertia/upload-center.md +1 -1
- package/dist/ai/recipes/nuxt/approvals-inbox.md +16 -10
- package/dist/ai/recipes/nuxt/layout-scaffold.md +98 -2
- package/dist/ai/recipes/vue/approvals-inbox.md +16 -10
- package/dist/ai/recipes/vue/layout-scaffold.md +98 -2
- package/dist/ai/source/BbAccordion.md +12 -0
- package/dist/ai/source/BbAlert.md +33 -3
- package/dist/ai/source/BbBadge.md +3 -3
- package/dist/ai/source/BbBadgeButton.md +3 -3
- package/dist/ai/source/BbBaseButton.md +132 -5
- package/dist/ai/source/BbBaseColorPalette.md +9 -1
- package/dist/ai/source/BbBaseDatePicker.md +19 -4
- package/dist/ai/source/BbBaseDatePickerInput.md +28 -17
- package/dist/ai/source/BbBaseInputContainer.md +6 -7
- package/dist/ai/source/BbBaseRadio.md +6 -2
- package/dist/ai/source/BbBaseRadioGroup.md +6 -0
- package/dist/ai/source/BbBaseRadioIcon.md +5 -5
- package/dist/ai/source/BbBaseSelect.md +15 -2
- package/dist/ai/source/BbBaseSlider.md +11 -2
- package/dist/ai/source/BbBaseTimePickerInput.md +32 -26
- package/dist/ai/source/BbButton.md +83 -0
- package/dist/ai/source/BbCollapsible.md +1 -1
- package/dist/ai/source/BbDatePickerInput.md +1 -1
- package/dist/ai/source/BbDialog.md +6 -2
- package/dist/ai/source/BbDropdown.md +47 -2
- package/dist/ai/source/BbDropdownButton.md +1 -1
- package/dist/ai/source/BbDropdownGroup.md +47 -2
- package/dist/ai/source/BbDropzone.md +5 -4
- package/dist/ai/source/BbOffCanvas.md +5 -3
- package/dist/ai/source/BbPagination.md +4 -4
- package/dist/ai/source/BbPopover.md +8 -0
- package/dist/ai/source/BbSelectPopover.md +43 -18
- package/dist/ai/source/BbSmoothHeight.md +1 -1
- package/dist/ai/source/BbSpinner.md +26 -11
- package/dist/ai/source/BbTable.md +14 -43
- package/dist/ai/source/BbTabs.md +11 -2
- package/dist/ai/source/BbTabsList.md +11 -2
- package/dist/ai/source/BbTabsPanes.md +11 -2
- package/dist/ai/source/BbTabsRoot.md +11 -2
- package/dist/ai/source/BbTimePickerInput.md +1 -1
- package/dist/ai/source/BbToast.md +7 -8
- package/dist/ai/source/BbToastPortal.md +7 -8
- package/dist/ai/source/BbTooltip.md +36 -12
- package/dist/ai/source/BbTree.md +10 -0
- package/dist/ai/source/FlatListBox.md +20 -7
- package/dist/ai/source/GroupedListBox.md +20 -7
- package/dist/assets/svgs/spinner.svg_raw.js +1 -1
- package/dist/badge-variants.d.ts +0 -6
- package/dist/button-variants.d.ts +0 -1
- package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbAlert/types.d.ts +10 -1
- package/dist/components/BbBadge/BbBadgeButton.vue_vue_type_script_setup_true_lang.js +22 -1
- package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +31 -1
- package/dist/components/BbBaseButton/types.d.ts +77 -0
- package/dist/components/BbBaseButton/types.js +13 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePicker.vue_vue_type_script_setup_true_lang.js +194 -194
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerMonthSelector.vue_vue_type_script_setup_true_lang.js +6 -3
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerYearSelector.vue_vue_type_script_setup_true_lang.js +45 -44
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue_vue_type_script_setup_true_lang.js +11 -11
- package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue_vue_type_script_setup_true_lang.js +0 -1
- package/dist/components/BbBaseRadio/BbBaseRadio.vue_vue_type_script_setup_true_lang.js +0 -1
- package/dist/components/BbBaseRadioGroup/BbBaseRadioGroup.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +62 -62
- package/dist/components/BbBaseSlider/BbBaseSlider.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/components/BbBaseTag/BbBaseTag.vue.d.ts +1 -1
- package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue_vue_type_script_setup_true_lang.js +41 -44
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +18 -1
- package/dist/components/BbButton/types.d.ts +77 -0
- package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbDropdown/types.d.ts +33 -2
- package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +1 -2
- package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +55 -55
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +9 -8
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +106 -103
- package/dist/components/BbTable/BbTable.vue.d.ts +1 -1
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +364 -371
- package/dist/components/BbTable/types.d.ts +3 -8
- package/dist/components/BbTabs/types.d.ts +11 -2
- package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +81 -78
- package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +18 -15
- package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +90 -87
- package/dist/composables/useBbTableContext.d.ts +2 -2
- package/dist/composables/useBbTabsContext.js +6 -4
- package/dist/composables/useListboxFocus.d.ts +2 -0
- package/dist/composables/useListboxFocus.js +30 -19
- package/dist/index.d.ts +2 -1
- package/dist/llms-full.txt +1155 -197
- package/dist/llms-medium.txt +143 -21
- package/dist/locale-registry.d.ts +21 -0
- package/dist/nuxt-module.d.ts +14 -0
- package/dist/styles.css +1 -1
- package/dist/validated/index.d.ts +14 -0
- package/dist/vite-plugin.d.ts +27 -0
- package/dist/vite.js +173 -145
- package/package.json +20 -9
- package/scripts/README.md +66 -0
- package/scripts/lib/eslint-plugin.d.ts +65 -0
- package/scripts/lib/eslint-plugin.mjs +3 -3
- package/scripts/lib/hand-roll-hints.mjs +173 -0
- package/scripts/lib/mcp-config.mjs +39 -1
- package/scripts/lib/validate-bb-markup.mjs +106 -0
package/README.md
CHANGED
|
@@ -6,11 +6,29 @@ Vue 3 component library used across BitBoss products. It ships typed building bl
|
|
|
6
6
|
|
|
7
7
|
## What’s in the package
|
|
8
8
|
|
|
9
|
-
Published artifacts are **`dist/`** (ESM JavaScript, `.d.ts`, and **`
|
|
9
|
+
Published artifacts are **`dist/`** (ESM JavaScript, `.d.ts`, the two stylesheets **`styles.css`** and **`reset.css`**, and the `dist/ai/` knowledge base), plus the **`bin/`** CLI, **`scripts/lib/`** (ESLint plugin and markup validator), the root **`llms.txt`**, and this **README**. The sections below match how the library is organised in code and in the [documentation](https://ui-components-docs.vercel.app/).
|
|
10
10
|
|
|
11
11
|
### Styles
|
|
12
12
|
|
|
13
13
|
- **Global stylesheet** — import `bitboss-ui/styles.css` once. It bundles design tokens, base rules, and styles for all exported components (built from the library’s PostCSS/Tailwind pipeline).
|
|
14
|
+
- **Optional reset** — `bitboss-ui/reset.css`, only if your app has no reset of its own. Import it _before_ `styles.css` (or let the build plugin inject it with `resetCss: true`).
|
|
15
|
+
|
|
16
|
+
### TypeScript: use `vue-tsc` 3
|
|
17
|
+
|
|
18
|
+
Use **`vue-tsc` 3 or newer**. Under `vue-tsc` 2 the template type-checker
|
|
19
|
+
silently checks **nothing** about the props of the nine components declared with
|
|
20
|
+
`generic="T"` — `BbSelect`, `BbSelectPopover`, `BbTable`, `BbTabs`,
|
|
21
|
+
`BbTabsRoot`, `BbTree`, `BbRadioGroup`, `BbCheckboxGroup`, `BbSwitchGroup` —
|
|
22
|
+
because they emit as generic functions rather than `DefineComponent<…>`, a shape
|
|
23
|
+
Vue Language Tools 2 cannot read props out of.
|
|
24
|
+
|
|
25
|
+
The trap is that the failure is partial and invisible: unknown-**component**
|
|
26
|
+
checking still fires and non-generic components still reject bad props, so the
|
|
27
|
+
gate looks like it is working. A real consumer shipped
|
|
28
|
+
`<BbRadioGroup label="…">` (the prop is `legend`) through six release slices on
|
|
29
|
+
`vue-tsc@^2.2.12` with a green `--noEmit`.
|
|
30
|
+
|
|
31
|
+
Full detail: `ai/guides/installation-and-plugin-setup.md`.
|
|
14
32
|
|
|
15
33
|
### TypeScript: icons
|
|
16
34
|
|
|
@@ -71,13 +89,14 @@ For most **Base\*** and **Bb\*** components, the package exports matching **prop
|
|
|
71
89
|
|
|
72
90
|
The same knowledge base the npm package ships is served publicly over a CDN, so
|
|
73
91
|
an agent can read it before anything is installed. `@alpha` tracks the latest
|
|
74
|
-
v3 prerelease; pin an exact version (`bitboss-ui@3.0.0-alpha.
|
|
75
|
-
links.
|
|
92
|
+
v3 prerelease; pin an exact version (`bitboss-ui@3.0.0-alpha.5`) for stable
|
|
93
|
+
links. Sizes grow with the catalogue — treat them as the current order of
|
|
94
|
+
magnitude, not a contract.
|
|
76
95
|
|
|
77
|
-
- [Core knowledge base](https://cdn.jsdelivr.net/npm/bitboss-ui@alpha/dist/llms-medium.txt) (~
|
|
78
|
-
- [Index](https://cdn.jsdelivr.net/npm/bitboss-ui@alpha/llms.txt) (~
|
|
96
|
+
- [Core knowledge base](https://cdn.jsdelivr.net/npm/bitboss-ui@alpha/dist/llms-medium.txt) (~110 KB) — **start here if you can only fetch one file.** Hard rules, setup, component picker, design language, and the full component catalogue.
|
|
97
|
+
- [Index](https://cdn.jsdelivr.net/npm/bitboss-ui@alpha/llms.txt) (~19 KB) — link index into every document.
|
|
79
98
|
- [components.json](https://cdn.jsdelivr.net/npm/bitboss-ui@alpha/dist/ai/components.json) — machine-readable API surface, for programmatic validation.
|
|
80
|
-
- [Complete knowledge base](https://cdn.jsdelivr.net/npm/bitboss-ui@alpha/dist/llms-full.txt) (~2
|
|
99
|
+
- [Complete knowledge base](https://cdn.jsdelivr.net/npm/bitboss-ui@alpha/dist/llms-full.txt) (~3.2 MB) — everything concatenated. Bulk ingestion only; too large to prompt with.
|
|
81
100
|
|
|
82
101
|
Already installed? Prefer the local copy under `node_modules/bitboss-ui/dist/ai/`,
|
|
83
102
|
run `npx bitboss-ui ai-init` to write agent pointers, and
|
|
@@ -204,9 +223,17 @@ can **query** the knowledge base (search components, read a contract, validate
|
|
|
204
223
|
markup) instead of reading files blind:
|
|
205
224
|
|
|
206
225
|
```bash
|
|
226
|
+
npm i -D @modelcontextprotocol/sdk zod
|
|
207
227
|
npx bitboss-ui ai-init --mcp
|
|
208
228
|
```
|
|
209
229
|
|
|
230
|
+
Those two are **optional peer dependencies**, not dependencies: together they
|
|
231
|
+
weigh ~12 MB — more than every runtime dependency of the component library
|
|
232
|
+
combined — and nothing but the MCP server loads them, so installing
|
|
233
|
+
`bitboss-ui` never drags them in. `ai-init --mcp` warns if they are missing,
|
|
234
|
+
and `bitboss-ui mcp` tells you what to install rather than dying on a module
|
|
235
|
+
resolution error.
|
|
236
|
+
|
|
210
237
|
The agent harness launches the server itself (`npx bitboss-ui@<installed version> mcp`,
|
|
211
238
|
pinned so npx can never fall back to fetching a different version from the registry) on demand —
|
|
212
239
|
you never run it by hand. `--mcp` merges the server entry into each harness's
|
|
@@ -333,13 +360,16 @@ A standard `llms.txt` discovery file is also published at:
|
|
|
333
360
|
|
|
334
361
|
### Package exports
|
|
335
362
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
import
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
363
|
+
These are **resolution paths, not importable modules** — they resolve to
|
|
364
|
+
Markdown and JSON, so a side-effect `import` of them neither type-checks nor
|
|
365
|
+
bundles. Use them with `import.meta.resolve` / `require.resolve`, or read the
|
|
366
|
+
files directly:
|
|
367
|
+
|
|
368
|
+
| Subpath | Resolves to |
|
|
369
|
+
| ----------------------------------- | ------------------------------ |
|
|
370
|
+
| `bitboss-ui/ai` | `dist/ai/index.md` (catalogue) |
|
|
371
|
+
| `bitboss-ui/ai/components.json` | `dist/ai/components.json` |
|
|
372
|
+
| `bitboss-ui/ai/guides/ai-router.md` | `dist/ai/guides/ai-router.md` |
|
|
343
373
|
|
|
344
374
|
Agents can also read paths under `node_modules/bitboss-ui/dist/ai/` directly.
|
|
345
375
|
|
|
@@ -376,7 +406,7 @@ MIT — see [`LICENSE`](LICENSE).
|
|
|
376
406
|
|
|
377
407
|
The source repository is private while v3 is in development, so there is no
|
|
378
408
|
public issue tracker yet. **Report bugs by email to
|
|
379
|
-
[
|
|
409
|
+
[hey@bitboss.it](mailto:hey@bitboss.it)** — that address is the `bugs` contact
|
|
380
410
|
in `package.json`, so `npm bugs bitboss-ui` opens it too.
|
|
381
411
|
|
|
382
412
|
To make a report actionable, include:
|
package/bin/bitboss-ui-mcp.mjs
CHANGED
|
@@ -7,8 +7,22 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Built on `@modelcontextprotocol/sdk` (McpServer over the stdio transport);
|
|
9
9
|
* the SDK owns JSON-RPC framing, capability handshake, and protocol-version
|
|
10
|
-
* negotiation. Tool input schemas are declared as zod shapes
|
|
11
|
-
*
|
|
10
|
+
* negotiation. Tool input schemas are declared as zod shapes; the SDK renders
|
|
11
|
+
* them to the JSON Schema advertised by tools/list.
|
|
12
|
+
*
|
|
13
|
+
* BOTH imports below are OPTIONAL PEERS, not dependencies — together ~12 MB,
|
|
14
|
+
* more than every runtime dependency of the component library combined, and
|
|
15
|
+
* loaded by nothing else. `bin/bitboss-ui.mjs` catches the resolution failure
|
|
16
|
+
* and names them; `missingMcpPeers()` warns at registration time.
|
|
17
|
+
*
|
|
18
|
+
* `zod`'s declared range is `^3.25 || ^4.0` — copied verbatim from the SDK's
|
|
19
|
+
* own dependency range, NOT invented. Do not "simplify" it to `>=` or to a
|
|
20
|
+
* single major: the schemas built here are validated by the SDK's OWN copy of
|
|
21
|
+
* zod, so a consumer hoisting a different MAJOR fails the SDK's brand checks
|
|
22
|
+
* while npm stays silent (both ranges are independently satisfied). Mirroring
|
|
23
|
+
* the range means it moves when the SDK's does. Everything used here
|
|
24
|
+
* (`z.string`, `z.enum`, `z.number`, `.describe`, `.int`, `.min`, `.optional`)
|
|
25
|
+
* is stable across zod 3 and 4, so the lower bound costs nothing.
|
|
12
26
|
*
|
|
13
27
|
* Run standalone: `npx bitboss-ui mcp` (delegated from bin/bitboss-ui.mjs).
|
|
14
28
|
* Register with an MCP-capable harness via `npx bitboss-ui ai-init --mcp`.
|
package/bin/bitboss-ui.mjs
CHANGED
|
@@ -35,11 +35,15 @@ import {
|
|
|
35
35
|
statSync,
|
|
36
36
|
writeFileSync,
|
|
37
37
|
} from 'node:fs';
|
|
38
|
+
import { findHandRollHints } from '../scripts/lib/hand-roll-hints.mjs';
|
|
38
39
|
import { createRequire } from 'node:module';
|
|
39
40
|
import { dirname, isAbsolute, join, relative } from 'node:path';
|
|
40
41
|
import { fileURLToPath } from 'node:url';
|
|
41
42
|
import { parseArgs } from 'node:util';
|
|
42
|
-
import {
|
|
43
|
+
import {
|
|
44
|
+
ensureMcpConfigs,
|
|
45
|
+
missingMcpPeers,
|
|
46
|
+
} from '../scripts/lib/mcp-config.mjs';
|
|
43
47
|
import {
|
|
44
48
|
loadManifest,
|
|
45
49
|
validateMarkdown,
|
|
@@ -238,6 +242,21 @@ function aiInit({ mcp = false } = {}) {
|
|
|
238
242
|
action: result.action,
|
|
239
243
|
});
|
|
240
244
|
}
|
|
245
|
+
|
|
246
|
+
// The harness launches the server on demand, long after this command
|
|
247
|
+
// ran — so a missing peer would surface inside an agent as a server
|
|
248
|
+
// that never starts. Say it here, where the person is still watching.
|
|
249
|
+
const missing = missingMcpPeers(projectRoot);
|
|
250
|
+
if (missing.length > 0) {
|
|
251
|
+
console.warn(
|
|
252
|
+
`[bitboss-ui] the MCP server needs ${missing.join(' and ')}, which ${
|
|
253
|
+
missing.length > 1 ? 'are' : 'is'
|
|
254
|
+
} not installed:\n` +
|
|
255
|
+
`\n npm i -D ${missing.join(' ')}\n\n` +
|
|
256
|
+
' Optional peers, not dependencies — ~12 MB that only the MCP\n' +
|
|
257
|
+
' server uses. The harness entries above are written either way.'
|
|
258
|
+
);
|
|
259
|
+
}
|
|
241
260
|
}
|
|
242
261
|
|
|
243
262
|
console.log(`[bitboss-ui] ai-init complete (library v${version})`);
|
|
@@ -550,9 +569,34 @@ function checkCommand(globs, jsonMode, allowEmpty = false) {
|
|
|
550
569
|
process.exit(1);
|
|
551
570
|
}
|
|
552
571
|
const manifest = loadManifest(manifestPath);
|
|
572
|
+
|
|
573
|
+
/*
|
|
574
|
+
* Every `--bb-*` the INSTALLED package declares, read from the stylesheet
|
|
575
|
+
* the consumer actually ships. Read from disk rather than hardcoded so this
|
|
576
|
+
* can never claim a token is invented when their version does declare it.
|
|
577
|
+
* Absent stylesheet → an empty set → the unknown-token hint stays silent,
|
|
578
|
+
* which is the right failure: no data, no accusation.
|
|
579
|
+
*/
|
|
580
|
+
const stylesPath = join(PACKAGE_ROOT, 'dist', 'styles.css');
|
|
581
|
+
const knownTokens = existsSync(stylesPath)
|
|
582
|
+
? new Set(
|
|
583
|
+
[
|
|
584
|
+
...readFileSync(stylesPath, 'utf-8').matchAll(
|
|
585
|
+
/(--bb-[a-z0-9-]+)\s*:/gi
|
|
586
|
+
),
|
|
587
|
+
].map((m) => m[1].toLowerCase())
|
|
588
|
+
)
|
|
589
|
+
: new Set();
|
|
553
590
|
const files = resolveCheckFiles(projectRoot, globs);
|
|
554
591
|
|
|
555
592
|
const findings = [];
|
|
593
|
+
/*
|
|
594
|
+
* Advisory only — see scripts/lib/hand-roll-hints.mjs. Hints never touch the
|
|
595
|
+
* exit code, so a guess can never fail a consumer's build. `--no-hints`
|
|
596
|
+
* silences them for anyone who finds them noisy.
|
|
597
|
+
*/
|
|
598
|
+
const hints = [];
|
|
599
|
+
const wantHints = !process.argv.includes('--no-hints');
|
|
556
600
|
for (const file of files) {
|
|
557
601
|
const relPath = relative(projectRoot, file);
|
|
558
602
|
const content = readFileSync(file, 'utf-8');
|
|
@@ -562,10 +606,34 @@ function checkCommand(globs, jsonMode, allowEmpty = false) {
|
|
|
562
606
|
for (const finding of fileFindings) {
|
|
563
607
|
findings.push({ file: relPath, ...finding });
|
|
564
608
|
}
|
|
609
|
+
// .md files are documentation ABOUT components; a round <img> in a doc
|
|
610
|
+
// example is illustrative, not a hand-roll.
|
|
611
|
+
if (wantHints && !file.endsWith('.md')) {
|
|
612
|
+
for (const hint of findHandRollHints(content, knownTokens)) {
|
|
613
|
+
hints.push({ file: relPath, ...hint });
|
|
614
|
+
}
|
|
615
|
+
}
|
|
565
616
|
}
|
|
566
617
|
|
|
618
|
+
/** Advisory block, printed on success and on failure alike. Never fatal. */
|
|
619
|
+
const printHints = () => {
|
|
620
|
+
if (hints.length === 0) return;
|
|
621
|
+
console.log(
|
|
622
|
+
`\n[bitboss-ui] ${hints.length} hint(s) — advisory, not errors:`
|
|
623
|
+
);
|
|
624
|
+
for (const hint of hints) {
|
|
625
|
+
console.log(` ${hint.file}:${hint.line}`);
|
|
626
|
+
console.log(` → ${hint.message}`);
|
|
627
|
+
}
|
|
628
|
+
console.log(
|
|
629
|
+
' Deliberate? Ignore these, record them in a HANDROLLED note, or pass --no-hints.'
|
|
630
|
+
);
|
|
631
|
+
};
|
|
632
|
+
|
|
567
633
|
if (jsonMode) {
|
|
568
|
-
console.log(
|
|
634
|
+
console.log(
|
|
635
|
+
JSON.stringify({ findings, hints, files: files.length }, null, 2)
|
|
636
|
+
);
|
|
569
637
|
if (findings.length > 0) process.exit(1);
|
|
570
638
|
if (files.length === 0 && globs.length > 0 && !allowEmpty) process.exit(1);
|
|
571
639
|
return;
|
|
@@ -595,6 +663,7 @@ function checkCommand(globs, jsonMode, allowEmpty = false) {
|
|
|
595
663
|
console.log(
|
|
596
664
|
`[bitboss-ui] check OK — ${summarizeFileCounts(files)} file(s), zero unknown Bb* props/v-models/slots/nav-attrs.`
|
|
597
665
|
);
|
|
666
|
+
printHints();
|
|
598
667
|
return;
|
|
599
668
|
}
|
|
600
669
|
|
|
@@ -620,6 +689,7 @@ function checkCommand(globs, jsonMode, allowEmpty = false) {
|
|
|
620
689
|
console.error(
|
|
621
690
|
'\nFix the markup (or the component API) so it stays copy-safe for agents.'
|
|
622
691
|
);
|
|
692
|
+
printHints();
|
|
623
693
|
process.exit(1);
|
|
624
694
|
}
|
|
625
695
|
|
|
@@ -710,7 +780,27 @@ switch (command) {
|
|
|
710
780
|
break;
|
|
711
781
|
}
|
|
712
782
|
case 'mcp': {
|
|
713
|
-
|
|
783
|
+
// `@modelcontextprotocol/sdk` + `zod` are OPTIONAL peers, not
|
|
784
|
+
// dependencies: together they weigh ~12 MB — more than every runtime
|
|
785
|
+
// dependency of the component library combined, and the SDK drags in a
|
|
786
|
+
// whole HTTP stack (express, hono, cors, jose). Only this subcommand
|
|
787
|
+
// needs them, so consumers who never run the MCP server do not pay for
|
|
788
|
+
// it. That makes the import failure a SUPPORTED path, and a bare
|
|
789
|
+
// ERR_MODULE_NOT_FOUND stack is not an answer — say what to install.
|
|
790
|
+
let main;
|
|
791
|
+
try {
|
|
792
|
+
({ main } = await import('./bitboss-ui-mcp.mjs'));
|
|
793
|
+
} catch (error) {
|
|
794
|
+
if (error?.code !== 'ERR_MODULE_NOT_FOUND') throw error;
|
|
795
|
+
console.error(
|
|
796
|
+
'bitboss-ui mcp needs two optional peer dependencies that are not installed:\n' +
|
|
797
|
+
'\n npm i -D @modelcontextprotocol/sdk zod\n\n' +
|
|
798
|
+
'They are optional because they are ~12 MB and only this subcommand uses them.\n' +
|
|
799
|
+
`Resolution failed with: ${error.message}`
|
|
800
|
+
);
|
|
801
|
+
process.exitCode = 1;
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
714
804
|
await main();
|
|
715
805
|
break;
|
|
716
806
|
}
|
package/dist/ai/BbAlert.md
CHANGED
|
@@ -207,9 +207,13 @@ click handler for something a link can do.
|
|
|
207
207
|
</div>
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
**The default slot is the text slot.** `<BbAlert>Something went wrong</BbAlert>`
|
|
211
|
+
is the shortest form and the one to reach for; `text` as a prop is for when a
|
|
212
|
+
string is all you have (an `:items` loop, a server message). When more than one
|
|
213
|
+
is present the most specific wins: `#text` > children > `text`.
|
|
214
|
+
|
|
215
|
+
There is no `actions` slot. A short inline link in the text (as above) is fine;
|
|
216
|
+
anything more interactive belongs outside the alert, or in a `BbDialog`.
|
|
213
217
|
|
|
214
218
|
#### Brand art via a raw SVG
|
|
215
219
|
|
|
@@ -353,9 +357,6 @@ const publish = () => {
|
|
|
353
357
|
|
|
354
358
|
### Gotchas & anti-patterns
|
|
355
359
|
|
|
356
|
-
- **There is no default slot.** `<BbAlert>some text</BbAlert>` renders
|
|
357
|
-
nothing — Vue drops an unconsumed default slot silently, with no warning.
|
|
358
|
-
Use `title`/`text` (or `#title`/`#text`, see above).
|
|
359
360
|
- **Omitting `v-model` does not make an alert permanent** — the close button
|
|
360
361
|
still dismisses it locally. Use `hide-close` for that.
|
|
361
362
|
- Don't rebuild dismissal with your own button + `v-if`; the built-in close
|
|
@@ -407,7 +408,8 @@ const publish = () => {
|
|
|
407
408
|
|
|
408
409
|
## Slots
|
|
409
410
|
|
|
410
|
-
- `
|
|
411
|
+
- `default` — scope: `any` — The alert body — the shortest form, and the one to reach for: `<BbAlert>Something went wrong</BbAlert>`. Same idiom as the rest of the `text`-prop family (BbButton, BbBaseButton, BbTooltip, BbIndicator). When more than one source is present…
|
|
412
|
+
- `text` — scope: `BbAlertTextSlotProps` — Replaces the default alert body text. Wins over children and `text`.
|
|
411
413
|
- `title` — scope: `BbAlertTitleSlotProps` — Replaces the default alert title text.
|
|
412
414
|
|
|
413
415
|
## See Also
|
package/dist/ai/BbAvatar.md
CHANGED
|
@@ -439,10 +439,12 @@ const feed: FeedEntry[] = [
|
|
|
439
439
|
Load failures are normally caught by the image's `error` event. As a safety
|
|
440
440
|
net — mainly for SSR/hydrated pages where the events fired before hydration —
|
|
441
441
|
the component also checks the image `timeout` ms after mount (default `400`)
|
|
442
|
-
and switches to the fallback if it hasn't loaded correctly by then.
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
442
|
+
and switches to the fallback if it hasn't loaded correctly by then. The
|
|
443
|
+
`<img>` stays mounted (visually hidden) through that switch, so the deadline
|
|
444
|
+
is **not** terminal: a slow image shows the fallback at `timeout` and swaps
|
|
445
|
+
itself back in the moment it finishes loading. Only a real `error` is
|
|
446
|
+
permanent until `src` changes. If your avatars come from a slow origin, raise
|
|
447
|
+
`timeout` rather than accepting a visible fallback-then-photo flip.
|
|
446
448
|
|
|
447
449
|
Platform notes: the component is SSR-safe (Nuxt/Inertia) with no client-only
|
|
448
450
|
markup; the only global config it reads is `iconDefaultSizes` for the size
|
|
@@ -461,15 +463,20 @@ keys.
|
|
|
461
463
|
|
|
462
464
|
### Gotchas & anti-patterns
|
|
463
465
|
|
|
464
|
-
- **There is no `color` prop.** The fallback is always
|
|
465
|
-
don't reach for per-avatar inline backgrounds.
|
|
466
|
-
`--bb-primary-fg`
|
|
466
|
+
- **There is no `color` prop, and no `variant` either.** The fallback is always
|
|
467
|
+
primary-token colored; don't reach for per-avatar inline backgrounds. If the
|
|
468
|
+
palette is wrong, retheme `--bb-primary` / `--bb-primary-fg` — theming here
|
|
469
|
+
happens through the tokens, not a prop.
|
|
467
470
|
- **Default `timeout` can false-fallback slow images** (see above) — tune it,
|
|
468
471
|
don't reimplement image loading around the component.
|
|
469
472
|
- Don't hand-position presence dots with absolute CSS — `BbIndicator dot`
|
|
470
473
|
exists for that.
|
|
471
474
|
- Don't wrap the avatar in a raw `<span @click>` for menus — put it inside
|
|
472
475
|
`BbBaseButton`/`BbDropdown` so focus and keyboard behavior come for free.
|
|
476
|
+
- **The shape is a circle, and it is not configurable.** `border-radius: 50%`
|
|
477
|
+
is baked in. A rounded-SQUARE avatar — common in dense tables, where a square
|
|
478
|
+
reads as "entity" and a circle as "person" — has no answer here; build that
|
|
479
|
+
one yourself rather than fighting the radius.
|
|
473
480
|
- Don't pre-crop sources to circles — the component center-crops; ship square
|
|
474
481
|
or larger originals.
|
|
475
482
|
- Don't leave `alt` empty for meaningful avatars: fallbacks lose their
|
package/dist/ai/BbBadgeButton.md
CHANGED
|
@@ -14,24 +14,36 @@
|
|
|
14
14
|
| --- | --- | --- | --- | --- |
|
|
15
15
|
| `activeClass` | `string \| undefined` | | | CSS class applied when the component renders as a link and the target of the link is the current route or the url matches partially. Ported for Inertia compatibility. |
|
|
16
16
|
| `ariaCurrentValue` | `"page" \| "step" \| "location" \| "date" \| "time" \| "true" \| "false" \| undefined` | | | Value forwarded to the `aria-current` attribute when the component renders as a router link and the target route is an exact match. Use to communicate the current location to assistive technologies. |
|
|
17
|
+
| `async` | `boolean \| undefined` | | | Inertia: runs the visit without blocking — the page stays interactive and several async visits can be in flight at once. |
|
|
18
|
+
| `cacheFor` | `string \| number \| (string \| number)[] \| undefined` | | | Inertia: how long a prefetched response stays fresh before it is re-fetched. A single duration, or `[staleAfter, expiresAfter]`. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue3` to be in… |
|
|
19
|
+
| `cacheTags` | `string \| string[] \| undefined` | | | Inertia: tags to file this visit's prefetch cache under, so a later request can invalidate the whole tagged group. |
|
|
20
|
+
| `component` | `string \| undefined` | | | Inertia: the page component this visit resolves to. Rarely set by hand — the server normally decides it. |
|
|
17
21
|
| `data` | `object \| undefined` | | | Request payload forwarded to Inertia when navigating via `href` in an Inertia-enabled app. Ignored when not using Inertia. |
|
|
18
22
|
| `disabled` | `boolean \| undefined` | | | Disables user interaction. - When rendering as a native button, sets the `disabled` attribute. - When rendering as a link (anchor/Inertia), removes `href`, adds `aria-disabled="true"`, and prevents navigation while keeping focusable semanti… |
|
|
19
23
|
| `download` | `string \| boolean \| undefined` | | | Marks an `href` link as a download. Renders a plain `<a download>` doing a native navigation — never an Inertia/router visit — so file downloads (including same-origin, `blob:` and `data:` URLs) work. Pass a string to set the suggested file… |
|
|
20
24
|
| `exactActiveClass` | `string \| undefined` | | | CSS class applied when the component renders as a link and the target of the link and the url matches exactly. Ported for Inertia compatibility. |
|
|
25
|
+
| `except` | `string[] \| undefined` | | | Inertia: the inverse of `only` — properties to EXCLUDE from a partial reload. Pass one or the other, not both. |
|
|
21
26
|
| `external` | `boolean \| undefined` | | | Forces an `href` link to render as a plain `<a>` (native navigation), bypassing Inertia/router interception — the same intent as Nuxt's `NuxtLink` `external`. Use for links outside the SPA. One of the native-anchor signals alongside `target… |
|
|
22
27
|
| `headers` | `object \| undefined` | | | Additional HTTP headers forwarded to Inertia when navigating via `href` in an Inertia-enabled app. |
|
|
23
28
|
| `href` | `string \| undefined` | | | Hyperlink reference used when rendering as an anchor (or as an Inertia link in Inertia-enabled apps). If provided and not disabled, the component renders as an anchor/Inertia link. |
|
|
29
|
+
| `instant` | `boolean \| undefined` | | | Inertia: navigate optimistically on click and reconcile when the response lands, instead of waiting for the round trip. |
|
|
24
30
|
| `method` | `"get" \| "post" \| "put" \| "patch" \| "delete" \| undefined` | | | HTTP method used for Inertia navigation when `href` is provided in an Inertia-enabled app. Ignored otherwise. |
|
|
25
31
|
| `onBefore` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia right before the request is sent. |
|
|
26
32
|
| `onCancel` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a request is cancelled. |
|
|
27
33
|
| `onCancelToken` | `((cancelToken: unknown) => void) \| undefined` | | | Receives the Inertia cancel token source when a request is initiated. Can be used to cancel the request. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue3` to be installed. |
|
|
34
|
+
| `onError` | `((errors: Record<string, string>) => void) \| undefined` | | | Lifecycle hook invoked by Inertia when the server responds with VALIDATION errors — the ordinary 422 path. This is the only failure callback Inertia's `Link` accepts. `onHttpException` (server answered 5xx) and `onNetworkError` (the request… |
|
|
28
35
|
| `onFinish` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia after the request has finished (regardless of success or error). |
|
|
29
36
|
| `only` | `string[] \| undefined` | | | Limits the properties that are preserved in Inertia partial reloads. |
|
|
37
|
+
| `onPrefetched` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a prefetch for this link has completed and is cached. |
|
|
38
|
+
| `onPrefetching` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a prefetch for this link starts. |
|
|
30
39
|
| `onProgress` | `((progress: { percentage: number \| undefined; }) => void) \| undefined` | | | Progress callback invoked by Inertia with the upload/download percentage when available. |
|
|
31
40
|
| `onStart` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a request starts. |
|
|
32
41
|
| `onSuccess` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a request succeeds. |
|
|
42
|
+
| `pageProps` | `Record<string, unknown> \| ((currentProps: Record<string, unknown>, sharedProps: Record<string, unknown>) => Record<string, unknown>) \| null \| undefined` | | | Inertia: props to merge into the next page optimistically, before the server responds. Either an object or a function of the current props. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue… |
|
|
43
|
+
| `prefetch` | `string \| boolean \| string[] \| undefined` | | | Inertia: fetch and cache this link's page ahead of the click. `true` uses the default trigger; a string or list of strings picks them (`'mount'`, `'hover'`, `'click'`). |
|
|
33
44
|
| `preserveScroll` | `boolean \| ((props: Record<string, unknown>) => boolean) \| undefined` | | | Controls whether Inertia should preserve the current scroll position after navigation. Can be a boolean or a predicate receiving the visit props. |
|
|
34
45
|
| `preserveState` | `boolean \| ((props: Record<string, unknown>) => boolean) \| null \| undefined` | | | Controls whether Inertia should preserve the current state after navigation. Can be a boolean or a predicate receiving the visit props. |
|
|
46
|
+
| `preserveUrl` | `boolean \| undefined` | | | Inertia: keep the current URL in the address bar even though the page content changes. |
|
|
35
47
|
| `queryStringArrayFormat` | `"brackets" \| "indices" \| undefined` | | | Format to use when serializing array values into the query string for Inertia requests. |
|
|
36
48
|
| `rel` | `string \| undefined` | | | Relationship between the current document and the linked resource. Useful for security when opening new tabs (e.g. `noopener noreferrer`). |
|
|
37
49
|
| `replace` | `boolean \| undefined` | | | Uses history replacement instead of push navigation. - With Vue Router (`to`), calls `router.replace`. - With Inertia (`href`), performs a replace visit. |
|
|
@@ -39,6 +51,7 @@
|
|
|
39
51
|
| `target` | `string \| undefined` | | | Target browsing context for anchor/Inertia links (e.g. `_self`, `_blank`). Ignored when rendering as a native button. |
|
|
40
52
|
| `to` | `string \| wt \| bt \| undefined` | | | Route location to navigate to. When provided (and not disabled), the component renders as a Vue Router link. |
|
|
41
53
|
| `type` | `"button" \| "submit" \| "reset" \| undefined` | | | Native `type` attribute used when rendering as a button (e.g. `button`, `submit`, `reset`). |
|
|
54
|
+
| `viewTransition` | `boolean \| undefined` | | | Inertia: run the page swap inside a View Transition, where the browser supports one. |
|
|
42
55
|
|
|
43
56
|
## Events
|
|
44
57
|
|
package/dist/ai/BbBaseButton.md
CHANGED
|
@@ -102,9 +102,12 @@ const pinged = ref(false);
|
|
|
102
102
|
### It ships no chrome — you style it
|
|
103
103
|
|
|
104
104
|
The only classes it applies are structural: `bb-base-button` (a focus-ring
|
|
105
|
-
scaffold, `cursor
|
|
106
|
-
|
|
107
|
-
variant appearance** — that is the whole point.
|
|
105
|
+
scaffold, `cursor` and transitions), `bb-base-button--block` and
|
|
106
|
+
`bb-base-button--disabled`. There is **no padding, background, border, or
|
|
107
|
+
variant appearance** — that is the whole point. It sets **no text color**, so a
|
|
108
|
+
`text-*` utility on the element just works with no specificity fight; the text
|
|
109
|
+
inherits from its container (in anchor mode, the browser's blue-and-underlined
|
|
110
|
+
link chrome is neutralized so it inherits too). Give it a class (your own, or
|
|
108
111
|
Tailwind utilities) and it looks like whatever you draw. This is what makes it
|
|
109
112
|
the right base for a clickable card or a bespoke nav item:
|
|
110
113
|
|
|
@@ -454,25 +457,37 @@ const sent = ref(false);
|
|
|
454
457
|
| --- | --- | --- | --- | --- |
|
|
455
458
|
| `activeClass` | `string \| undefined` | | | CSS class applied when the component renders as a link and the target of the link is the current route or the url matches partially. Ported for Inertia compatibility. |
|
|
456
459
|
| `ariaCurrentValue` | `"page" \| "step" \| "location" \| "date" \| "time" \| "true" \| "false" \| undefined` | | | Value forwarded to the `aria-current` attribute when the component renders as a router link and the target route is an exact match. Use to communicate the current location to assistive technologies. |
|
|
460
|
+
| `async` | `boolean \| undefined` | | | Inertia: runs the visit without blocking — the page stays interactive and several async visits can be in flight at once. |
|
|
457
461
|
| `block` | `boolean \| undefined` | | | Makes the component take the full available width (block-level layout). Adds the `bb-base-button--block` modifier class. |
|
|
462
|
+
| `cacheFor` | `string \| number \| (string \| number)[] \| undefined` | | | Inertia: how long a prefetched response stays fresh before it is re-fetched. A single duration, or `[staleAfter, expiresAfter]`. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue3` to be in… |
|
|
463
|
+
| `cacheTags` | `string \| string[] \| undefined` | | | Inertia: tags to file this visit's prefetch cache under, so a later request can invalidate the whole tagged group. |
|
|
464
|
+
| `component` | `string \| undefined` | | | Inertia: the page component this visit resolves to. Rarely set by hand — the server normally decides it. |
|
|
458
465
|
| `data` | `object \| undefined` | | | Request payload forwarded to Inertia when navigating via `href` in an Inertia-enabled app. Ignored when not using Inertia. |
|
|
459
466
|
| `disabled` | `boolean \| undefined` | | | Disables user interaction. - When rendering as a native button, sets the `disabled` attribute. - When rendering as a link (anchor/Inertia), removes `href`, adds `aria-disabled="true"`, and prevents navigation while keeping focusable semanti… |
|
|
460
467
|
| `download` | `string \| boolean \| undefined` | | | Marks an `href` link as a download. Renders a plain `<a download>` doing a native navigation — never an Inertia/router visit — so file downloads (including same-origin, `blob:` and `data:` URLs) work. Pass a string to set the suggested file… |
|
|
461
468
|
| `exactActiveClass` | `string \| undefined` | | | CSS class applied when the component renders as a link and the target of the link and the url matches exactly. Ported for Inertia compatibility. |
|
|
469
|
+
| `except` | `string[] \| undefined` | | | Inertia: the inverse of `only` — properties to EXCLUDE from a partial reload. Pass one or the other, not both. |
|
|
462
470
|
| `external` | `boolean \| undefined` | | | Forces an `href` link to render as a plain `<a>` (native navigation), bypassing Inertia/router interception — the same intent as Nuxt's `NuxtLink` `external`. Use for links outside the SPA. One of the native-anchor signals alongside `target… |
|
|
463
471
|
| `headers` | `object \| undefined` | | | Additional HTTP headers forwarded to Inertia when navigating via `href` in an Inertia-enabled app. |
|
|
464
472
|
| `href` | `string \| undefined` | | | Hyperlink reference used when rendering as an anchor (or as an Inertia link in Inertia-enabled apps). If provided and not disabled, the component renders as an anchor/Inertia link. |
|
|
473
|
+
| `instant` | `boolean \| undefined` | | | Inertia: navigate optimistically on click and reconcile when the response lands, instead of waiting for the round trip. |
|
|
465
474
|
| `method` | `"get" \| "post" \| "put" \| "patch" \| "delete" \| undefined` | | | HTTP method used for Inertia navigation when `href` is provided in an Inertia-enabled app. Ignored otherwise. |
|
|
466
475
|
| `onBefore` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia right before the request is sent. |
|
|
467
476
|
| `onCancel` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a request is cancelled. |
|
|
468
477
|
| `onCancelToken` | `((cancelToken: unknown) => void) \| undefined` | | | Receives the Inertia cancel token source when a request is initiated. Can be used to cancel the request. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue3` to be installed. |
|
|
478
|
+
| `onError` | `((errors: Record<string, string>) => void) \| undefined` | | | Lifecycle hook invoked by Inertia when the server responds with VALIDATION errors — the ordinary 422 path. This is the only failure callback Inertia's `Link` accepts. `onHttpException` (server answered 5xx) and `onNetworkError` (the request… |
|
|
469
479
|
| `onFinish` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia after the request has finished (regardless of success or error). |
|
|
470
480
|
| `only` | `string[] \| undefined` | | | Limits the properties that are preserved in Inertia partial reloads. |
|
|
481
|
+
| `onPrefetched` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a prefetch for this link has completed and is cached. |
|
|
482
|
+
| `onPrefetching` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a prefetch for this link starts. |
|
|
471
483
|
| `onProgress` | `((progress: { percentage: number \| undefined; }) => void) \| undefined` | | | Progress callback invoked by Inertia with the upload/download percentage when available. |
|
|
472
484
|
| `onStart` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a request starts. |
|
|
473
485
|
| `onSuccess` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a request succeeds. |
|
|
486
|
+
| `pageProps` | `Record<string, unknown> \| ((currentProps: Record<string, unknown>, sharedProps: Record<string, unknown>) => Record<string, unknown>) \| null \| undefined` | | | Inertia: props to merge into the next page optimistically, before the server responds. Either an object or a function of the current props. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue… |
|
|
487
|
+
| `prefetch` | `string \| boolean \| string[] \| undefined` | | | Inertia: fetch and cache this link's page ahead of the click. `true` uses the default trigger; a string or list of strings picks them (`'mount'`, `'hover'`, `'click'`). |
|
|
474
488
|
| `preserveScroll` | `boolean \| ((props: Record<string, unknown>) => boolean) \| undefined` | | | Controls whether Inertia should preserve the current scroll position after navigation. Can be a boolean or a predicate receiving the visit props. |
|
|
475
489
|
| `preserveState` | `boolean \| ((props: Record<string, unknown>) => boolean) \| null \| undefined` | | | Controls whether Inertia should preserve the current state after navigation. Can be a boolean or a predicate receiving the visit props. |
|
|
490
|
+
| `preserveUrl` | `boolean \| undefined` | | | Inertia: keep the current URL in the address bar even though the page content changes. |
|
|
476
491
|
| `queryStringArrayFormat` | `"brackets" \| "indices" \| undefined` | | | Format to use when serializing array values into the query string for Inertia requests. |
|
|
477
492
|
| `rel` | `string \| undefined` | | | Relationship between the current document and the linked resource. Useful for security when opening new tabs (e.g. `noopener noreferrer`). |
|
|
478
493
|
| `replace` | `boolean \| undefined` | | | Uses history replacement instead of push navigation. - With Vue Router (`to`), calls `router.replace`. - With Inertia (`href`), performs a replace visit. |
|
|
@@ -481,6 +496,7 @@ const sent = ref(false);
|
|
|
481
496
|
| `text` | `string \| undefined` | | | Fallback text content rendered when no default slot is provided. |
|
|
482
497
|
| `to` | `string \| wt \| bt \| undefined` | | | Route location to navigate to. When provided (and not disabled), the component renders as a Vue Router link. |
|
|
483
498
|
| `type` | `"button" \| "submit" \| "reset" \| undefined` | `"button"` | | Native `type` attribute used when rendering as a button (e.g. `button`, `submit`, `reset`). |
|
|
499
|
+
| `viewTransition` | `boolean \| undefined` | | | Inertia: run the page swap inside a View Transition, where the browser supports one. |
|
|
484
500
|
|
|
485
501
|
## Events
|
|
486
502
|
|
package/dist/ai/BbButton.md
CHANGED
|
@@ -642,12 +642,35 @@ Under Inertia, `href` accepts the full visit surface as props, grouped by
|
|
|
642
642
|
concern:
|
|
643
643
|
|
|
644
644
|
- **Request shape** — `method` (`get`…`delete`), `data`, `headers`, `only`
|
|
645
|
-
(partial reloads), `
|
|
645
|
+
(partial reloads), `except` (the inverse of `only` — pass one or the other),
|
|
646
|
+
`query-string-array-format`, `component`.
|
|
646
647
|
- **History & scroll** — `replace`, `preserve-scroll`, `preserve-state` (each
|
|
647
|
-
also accepts a callback form)
|
|
648
|
+
also accepts a callback form), `preserve-url` (change the page, keep the
|
|
649
|
+
address bar), `view-transition`.
|
|
650
|
+
- **Prefetching** — `prefetch` (`true`, or `'mount'`/`'hover'`/`'click'`),
|
|
651
|
+
`cache-for` (a duration, or `[staleAfter, expiresAfter]`), `cache-tags` for
|
|
652
|
+
group invalidation.
|
|
653
|
+
- **Speed** — `async` (don't block the page), `instant` (navigate optimistically
|
|
654
|
+
and reconcile on response), `page-props` (props to merge before the server
|
|
655
|
+
answers).
|
|
648
656
|
- **Lifecycle hooks** — `onBefore`, `onStart`, `onProgress`, `onSuccess`,
|
|
649
|
-
`onCancel`, `onFinish`, plus `onCancelToken` to capture a cancel
|
|
650
|
-
|
|
657
|
+
`onError`, `onCancel`, `onFinish`, plus `onCancelToken` to capture a cancel
|
|
658
|
+
handle and `onPrefetching`/`onPrefetched` for the prefetch pair. Bind them as
|
|
659
|
+
props (`:on-success="..."`), not `@` listeners.
|
|
660
|
+
|
|
661
|
+
**`onError` here means VALIDATION errors** — the ordinary 422 — and it is the
|
|
662
|
+
only failure callback `<Link>` accepts. Inertia's other two,
|
|
663
|
+
`onHttpException` (the server answered 5xx) and `onNetworkError` (the request
|
|
664
|
+
never arrived — offline, DNS, connection reset), are **`router.visit()` /
|
|
665
|
+
`useForm()` options, not Link props**; passing them to a link-shaped button
|
|
666
|
+
does nothing. Reach for a form or an explicit visit when you need to tell those
|
|
667
|
+
apart — see the Inertia helpers guide.
|
|
668
|
+
|
|
669
|
+
Every prop Inertia's own `<Link>` accepts is forwarded, and
|
|
670
|
+
`npm run check:inertia-props` fails the build both when Inertia adds one we
|
|
671
|
+
don't forward and when we declare a callback `<Link>` never accepted. The list
|
|
672
|
+
has to be hand-written, because `@inertiajs/vue3` is an optional peer the
|
|
673
|
+
library's public types are not allowed to import.
|
|
651
674
|
|
|
652
675
|
```vue
|
|
653
676
|
<!-- Inertia: href becomes a visit; the whole option set rides along -->
|
|
@@ -658,11 +681,19 @@ concern:
|
|
|
658
681
|
preserve-scroll
|
|
659
682
|
:only="['invoices']"
|
|
660
683
|
:on-success="() => drawer.close()"
|
|
684
|
+
:on-error="(errors) => (formErrors = errors)"
|
|
661
685
|
>
|
|
662
686
|
Create invoice
|
|
663
687
|
</BbButton>
|
|
664
688
|
```
|
|
665
689
|
|
|
690
|
+
```vue
|
|
691
|
+
<!-- Prefetch on hover so the detail page is already cached by the click -->
|
|
692
|
+
<BbButton href="/invoices/42" prefetch="hover" cache-for="30s" variant="link">
|
|
693
|
+
Invoice #42
|
|
694
|
+
</BbButton>
|
|
695
|
+
```
|
|
696
|
+
|
|
666
697
|
### Works well with
|
|
667
698
|
|
|
668
699
|
- `BbDropdownButton` — escalate to it when a primary action grows close
|
|
@@ -851,18 +882,24 @@ Anti-patterns:
|
|
|
851
882
|
| `activeClass` | `string \| undefined` | | | Class to apply when the link is active. |
|
|
852
883
|
| `append:icon` | `string \| undefined` | | | Icon to be added on the right of the text. |
|
|
853
884
|
| `ariaCurrentValue` | `"page" \| "step" \| "location" \| "date" \| "time" \| "true" \| "false" \| undefined` | | | Value passed to the attribute `aria-current` when the link is exact active. |
|
|
885
|
+
| `async` | `boolean \| undefined` | | | Inertia: runs the visit without blocking — the page stays interactive and several async visits can be in flight at once. |
|
|
854
886
|
| `block` | `boolean \| undefined` | | | Displays the component as full width. |
|
|
887
|
+
| `cacheFor` | `string \| number \| (string \| number)[] \| undefined` | | | Inertia: how long a prefetched response stays fresh before it is re-fetched. A single duration, or `[staleAfter, expiresAfter]`. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue3` to be in… |
|
|
888
|
+
| `cacheTags` | `string \| string[] \| undefined` | | | Inertia: tags to file this visit's prefetch cache under, so a later request can invalidate the whole tagged group. |
|
|
889
|
+
| `component` | `string \| undefined` | | | Inertia: the page component this visit resolves to. Rarely set by hand — the server normally decides it. |
|
|
855
890
|
| `data` | `object \| undefined` | | | |
|
|
856
891
|
| `disableAutoLoading` | `boolean \| undefined` | | | Disables the automatic loading state that tracks async click handlers (enabled by default). |
|
|
857
892
|
| `disabled` | `boolean \| undefined` | | | Disables the component. |
|
|
858
893
|
| `download` | `string \| boolean \| undefined` | | | Marks an `href` link as a download: renders a plain `<a download>` doing a native navigation (never an Inertia/router visit), so file downloads work. Pass a string for the suggested filename. A native-anchor signal alongside `target` and `e… |
|
|
859
894
|
| `exactActiveClass` | `string \| undefined` | | | Class to apply when the link is exact active. |
|
|
895
|
+
| `except` | `string[] \| undefined` | | | Inertia: the inverse of `only` — properties to EXCLUDE from a partial reload. Pass one or the other, not both. |
|
|
860
896
|
| `external` | `boolean \| undefined` | | | Forces an `href` link to render as a plain `<a>` (native navigation), bypassing Inertia/router interception — same intent as Nuxt's `external`. A native-anchor signal alongside `target` and `download`. |
|
|
861
897
|
| `falseValue` | `any` | `false` | | Value emitted when the toggle is deactivated. |
|
|
862
898
|
| `group` | `boolean \| undefined` | | | Identifies the button as part of a button group. |
|
|
863
899
|
| `headers` | `object \| undefined` | | | |
|
|
864
900
|
| `href` | `string \| undefined` | | | Returns the hyperlink's URL. Can be set, to change the URL. |
|
|
865
901
|
| `icon` | `string \| undefined` | | | Used when only an icon with no text should be displayed. |
|
|
902
|
+
| `instant` | `boolean \| undefined` | | | Inertia: navigate optimistically on click and reconcile when the response lands, instead of waiting for the round trip. |
|
|
866
903
|
| `interactiveWhileLoading` | `boolean \| undefined` | | | Keeps the button clickable while it is loading. Buttons are disabled while loading by default; this escape hatch exists for toggles that must stay interactive (e.g. the dropdown-button caret). |
|
|
867
904
|
| `loading` | `boolean \| undefined` | | | Triggers a loading indicator. |
|
|
868
905
|
| `method` | `"get" \| "post" \| "put" \| "patch" \| "delete" \| undefined` | | | |
|
|
@@ -870,14 +907,20 @@ Anti-patterns:
|
|
|
870
907
|
| `onBefore` | `(() => void) \| undefined` | | | |
|
|
871
908
|
| `onCancel` | `(() => void) \| undefined` | | | |
|
|
872
909
|
| `onCancelToken` | `((cancelToken: unknown) => void) \| undefined` | | | |
|
|
910
|
+
| `onError` | `((errors: Record<string, string>) => void) \| undefined` | | | Lifecycle hook invoked by Inertia when the server responds with VALIDATION errors — the ordinary 422 path. This is the only failure callback Inertia's `Link` accepts. `onHttpException` (server answered 5xx) and `onNetworkError` (the request… |
|
|
873
911
|
| `onFinish` | `(() => void) \| undefined` | | | |
|
|
874
912
|
| `only` | `string[] \| undefined` | | | |
|
|
913
|
+
| `onPrefetched` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a prefetch for this link has completed and is cached. |
|
|
914
|
+
| `onPrefetching` | `(() => void) \| undefined` | | | Lifecycle hook invoked by Inertia when a prefetch for this link starts. |
|
|
875
915
|
| `onProgress` | `((progress: { percentage: number \| undefined; }) => void) \| undefined` | | | |
|
|
876
916
|
| `onStart` | `(() => void) \| undefined` | | | |
|
|
877
917
|
| `onSuccess` | `(() => void) \| undefined` | | | |
|
|
918
|
+
| `pageProps` | `Record<string, unknown> \| ((currentProps: Record<string, unknown>, sharedProps: Record<string, unknown>) => Record<string, unknown>) \| null \| undefined` | | | Inertia: props to merge into the next page optimistically, before the server responds. Either an object or a function of the current props. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue… |
|
|
919
|
+
| `prefetch` | `string \| boolean \| string[] \| undefined` | | | Inertia: fetch and cache this link's page ahead of the click. `true` uses the default trigger; a string or list of strings picks them (`'mount'`, `'hover'`, `'click'`). |
|
|
878
920
|
| `prepend:icon` | `string \| undefined` | | | Icon to be added on the left of the text. |
|
|
879
921
|
| `preserveScroll` | `boolean \| ((props: Record<string, unknown>) => boolean) \| undefined` | | | |
|
|
880
922
|
| `preserveState` | `boolean \| ((props: Record<string, unknown>) => boolean) \| null \| undefined` | | | |
|
|
923
|
+
| `preserveUrl` | `boolean \| undefined` | | | Inertia: keep the current URL in the address bar even though the page content changes. |
|
|
881
924
|
| `queryStringArrayFormat` | `"brackets" \| "indices" \| undefined` | | | |
|
|
882
925
|
| `replace` | `boolean \| undefined` | | | Calls `router.replace` instead of `router.push`. |
|
|
883
926
|
| `size` | `Responsive<Sizes> \| undefined` | `"md"` | | Sets the size of the button. A single value applies at every breakpoint; a per-breakpoint map (e.g. `{ default: 'sm', lg: 'md' }`) switches responsively. Purely CSS-driven — no runtime breakpoint watching. |
|
|
@@ -888,6 +931,7 @@ Anti-patterns:
|
|
|
888
931
|
| `trueValue` | `any` | `true` | | Value emitted when the toggle is activated. |
|
|
889
932
|
| `type` | `"button" \| "submit" \| "reset" \| undefined` | | | Gets the classification and default behavior of the button. |
|
|
890
933
|
| `variant` | `ButtonVariantType \| undefined` | `"primary"` | | Visual variant of the button. Controls colors and surface style while keeping spacing and sizing unchanged. |
|
|
934
|
+
| `viewTransition` | `boolean \| undefined` | | | Inertia: run the page swap inside a View Transition, where the browser supports one. |
|
|
891
935
|
|
|
892
936
|
## Events
|
|
893
937
|
|