bitboss-ui 3.0.0-beta.21 → 3.0.0-beta.23
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 +55 -3
- package/bin/bitboss-ui-mcp.mjs +419 -9
- package/bin/bitboss-ui.mjs +293 -22
- package/dist/ai/BbAccordion.md +21 -23
- package/dist/ai/BbAlert.md +6 -12
- package/dist/ai/BbAvatar.md +60 -24
- package/dist/ai/BbBadge.md +12 -20
- package/dist/ai/BbBaseButton.md +14 -16
- package/dist/ai/BbBaseCheckboxIcon.md +6 -10
- package/dist/ai/BbBaseColorInput.md +1 -0
- package/dist/ai/BbBaseDatePickerInput.md +1 -0
- package/dist/ai/BbBaseNumberInput.md +1 -0
- package/dist/ai/BbBaseRadioIcon.md +6 -10
- package/dist/ai/BbBaseSelect.md +1 -0
- package/dist/ai/BbBaseSwitchIcon.md +5 -9
- package/dist/ai/BbBaseTag.md +1 -0
- package/dist/ai/BbBaseTextInput.md +2 -1
- package/dist/ai/BbBaseTextarea.md +1 -0
- package/dist/ai/BbBaseTimePickerInput.md +1 -0
- package/dist/ai/BbBreadcrumbs.md +23 -34
- package/dist/ai/BbButton.md +35 -47
- package/dist/ai/BbCheckbox.md +21 -37
- package/dist/ai/BbCheckboxGroup.md +13 -13
- package/dist/ai/BbCollapsible.md +14 -26
- package/dist/ai/BbColorInput.md +27 -23
- package/dist/ai/BbColorPalette.md +23 -35
- package/dist/ai/BbConfirm.md +17 -32
- package/dist/ai/BbDatePickerInput.md +29 -21
- package/dist/ai/BbDialog.md +159 -62
- package/dist/ai/BbDropdown.md +21 -25
- package/dist/ai/BbDropdownButton.md +13 -30
- package/dist/ai/BbDropzone.md +9 -11
- package/dist/ai/BbIcon.md +44 -33
- package/dist/ai/BbIndicator.md +2 -2
- package/dist/ai/BbNumberInput.md +32 -20
- package/dist/ai/BbOffCanvas.md +42 -42
- package/dist/ai/BbPagination.md +21 -23
- package/dist/ai/BbPopover.md +15 -17
- package/dist/ai/BbProgress.md +40 -51
- package/dist/ai/BbRadio.md +9 -9
- package/dist/ai/BbRadioGroup.md +7 -11
- package/dist/ai/BbRating.md +8 -12
- package/dist/ai/BbSelect.md +46 -36
- package/dist/ai/BbSelectPopover.md +19 -31
- package/dist/ai/BbSlider.md +15 -19
- package/dist/ai/BbSmoothHeight.md +16 -31
- package/dist/ai/BbSpinner.md +118 -74
- package/dist/ai/BbSwitch.md +25 -18
- package/dist/ai/BbSwitchGroup.md +9 -14
- package/dist/ai/BbTable.md +102 -55
- package/dist/ai/BbTabs.md +59 -82
- package/dist/ai/BbTag.md +26 -23
- package/dist/ai/BbTextInput.md +63 -27
- package/dist/ai/BbTextarea.md +42 -34
- package/dist/ai/BbTimePickerInput.md +14 -0
- package/dist/ai/BbToast.md +14 -34
- package/dist/ai/BbTooltip.md +22 -20
- package/dist/ai/BbTree.md +46 -72
- package/dist/ai/CommonInputWrapper.md +1 -0
- package/dist/ai/changelog.json +170 -62
- package/dist/ai/components.json +1678 -11
- package/dist/ai/composables/useConfirm.md +5 -2
- package/dist/ai/composables/useToast.md +4 -2
- package/dist/ai/guides/agent-contract.md +7 -4
- package/dist/ai/guides/ai-router.md +37 -22
- package/dist/ai/guides/component-picker.md +23 -18
- package/dist/ai/guides/design-language.md +151 -21
- package/dist/ai/guides/design-tokens.md +29 -4
- package/dist/ai/guides/icons-policy.md +46 -21
- package/dist/ai/guides/installation-and-plugin-setup.md +286 -17
- package/dist/ai/guides/migration/components/bb-rating.md +26 -1
- package/dist/ai/guides/migration/components/bb-tooltip.md +18 -0
- package/dist/ai/guides/migration/v2-to-v3.md +50 -23
- package/dist/ai/index.md +1 -1
- package/dist/ai/recipes/inertia/approvals-inbox.md +3 -3
- package/dist/ai/recipes/inertia/inline-edit-workspace.md +2 -2
- package/dist/ai/recipes/inertia/onboarding.md +2 -2
- package/dist/ai/recipes/inertia/ownership-atlas.md +6 -6
- package/dist/ai/recipes/inertia/record-form.md +5 -5
- package/dist/ai/recipes/inertia/records-workspace.md +4 -4
- package/dist/ai/recipes/inertia/upload-center.md +6 -6
- package/dist/ai/recipes/inertia/wizard-form.md +5 -5
- package/dist/ai/recipes/nuxt/approvals-inbox.md +3 -3
- package/dist/ai/recipes/nuxt/inline-edit-workspace.md +2 -2
- package/dist/ai/recipes/nuxt/onboarding.md +2 -2
- package/dist/ai/recipes/nuxt/record-form.md +5 -5
- package/dist/ai/recipes/nuxt/records-workspace.md +4 -4
- package/dist/ai/recipes/nuxt/upload-center.md +6 -6
- package/dist/ai/recipes/nuxt/wizard-form.md +5 -5
- package/dist/ai/recipes/vue/approvals-inbox.md +3 -3
- package/dist/ai/recipes/vue/inline-edit-workspace.md +2 -2
- package/dist/ai/recipes/vue/onboarding.md +2 -2
- package/dist/ai/recipes/vue/record-form.md +10 -10
- package/dist/ai/recipes/vue/records-workspace.md +4 -4
- package/dist/ai/recipes/vue/upload-center.md +6 -6
- package/dist/ai/recipes/vue/wizard-form.md +5 -5
- package/dist/ai/source/BbBadge.md +1 -1
- package/dist/ai/source/BbBaseCheckbox.md +1 -1
- package/dist/ai/source/BbBaseColorInput.md +7 -0
- package/dist/ai/source/BbBaseDatePicker.md +5 -5
- package/dist/ai/source/BbBaseDatePickerInput.md +9 -2
- package/dist/ai/source/BbBaseNumberInput.md +7 -0
- package/dist/ai/source/BbBaseRadio.md +1 -1
- package/dist/ai/source/BbBaseRating.md +5 -5
- package/dist/ai/source/BbBaseSelect.md +8 -1
- package/dist/ai/source/BbBaseSlider.md +5 -5
- package/dist/ai/source/BbBaseSwitch.md +1 -1
- package/dist/ai/source/BbBaseTag.md +7 -0
- package/dist/ai/source/BbBaseTextInput.md +7 -0
- package/dist/ai/source/BbBaseTextarea.md +7 -0
- package/dist/ai/source/BbBaseTimePickerInput.md +8 -1
- package/dist/ai/source/BbBreadcrumbs.md +20 -1
- package/dist/ai/source/BbButton.md +2 -2
- package/dist/ai/source/BbColorInput.md +14 -0
- package/dist/ai/source/BbDatePickerInput.md +14 -0
- package/dist/ai/source/BbDialog.md +39 -8
- package/dist/ai/source/BbDropdown.md +1 -1
- package/dist/ai/source/BbDropzone.md +5 -5
- package/dist/ai/source/BbIcon.md +23 -10
- package/dist/ai/source/BbNumberInput.md +14 -0
- package/dist/ai/source/BbOffCanvas.md +50 -28
- package/dist/ai/source/BbPagination.md +2 -2
- package/dist/ai/source/BbPopover.md +12 -1
- package/dist/ai/source/BbSelect.md +14 -0
- package/dist/ai/source/BbSelectPopover.md +45 -7
- package/dist/ai/source/BbSpinner.md +2 -2
- package/dist/ai/source/BbTable.md +11 -11
- package/dist/ai/source/BbTag.md +14 -0
- package/dist/ai/source/BbTextInput.md +14 -0
- package/dist/ai/source/BbTextarea.md +14 -0
- package/dist/ai/source/BbTimePickerInput.md +14 -0
- package/dist/ai/source/BbTooltip.md +57 -10
- package/dist/ai/source/ChipsBox.md +1 -1
- package/dist/ai/source/CommaBox.md +1 -1
- package/dist/ai/source/CommonInputWrapper.md +128 -33
- package/dist/ai/source/GuidesComponent.md +14 -7
- package/dist/ai/source/OptionsContainer.md +1 -1
- package/dist/components/BbBadge/BadgeBodyContent.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbBaseCheckbox/BbBaseCheckbox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbBaseColorInput/BbBaseColorInput.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/BbBaseColorInput/types.d.ts +5 -0
- package/dist/components/BbBaseDatePicker/BbBaseDatePicker.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/components/BbBaseDatePickerInput/types.d.ts +5 -0
- package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue.d.ts +1 -1
- package/dist/components/BbBaseNumberInput/BbBaseNumberInput.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/BbBaseNumberInput/types.d.ts +5 -0
- package/dist/components/BbBaseRadio/BbBaseRadio.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbBaseRating/BbBaseRating.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/BbBaseSelect/types.d.ts +5 -0
- package/dist/components/BbBaseSlider/BbBaseSlider.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/BbBaseSwitch/BbBaseSwitch.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbBaseTag/BbBaseTag.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/BbBaseTag/types.d.ts +5 -0
- package/dist/components/BbBaseTextInput/BbBaseTextInput.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/BbBaseTextInput/types.d.ts +5 -0
- package/dist/components/BbBaseTextarea/BbBaseTextarea.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/BbBaseTextarea/types.d.ts +5 -0
- package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/components/BbBaseTimePickerInput/types.d.ts +5 -0
- package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +71 -71
- package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/components/BbColorInput/types.d.ts +12 -0
- package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/BbDatePickerInput/types.d.ts +12 -0
- package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +102 -97
- package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +58 -58
- package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/BbIcon/BbIcon.vue_vue_type_script_setup_true_lang.js +33 -35
- package/dist/components/BbIcon/iconCache.d.ts +30 -0
- package/dist/components/BbIcon/iconCache.js +21 -3
- package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/components/BbNumberInput/types.d.ts +12 -0
- package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +57 -56
- package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +138 -138
- package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/BbSelect/types.d.ts +12 -0
- package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +43 -43
- package/dist/components/BbSpinner/BbSpinner.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/BbSpinner/types.d.ts +1 -1
- package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/BbTable/BbTableDataRow.js +2 -2
- package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/components/BbTag/types.d.ts +12 -0
- package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/components/BbTextInput/types.d.ts +12 -0
- package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/components/BbTextarea/types.d.ts +12 -0
- package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/BbTimePickerInput/types.d.ts +12 -0
- package/dist/components/BbToast/BbToastRegion.vue_vue_type_script_setup_true_lang.js +62 -62
- package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +81 -78
- package/dist/components/BbTooltip/types.d.ts +8 -1
- package/dist/components/ChipsBox/ChipsBox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/CommaBox/CommaBox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/CommonInputWrapper/CommonInputWrapper.vue.d.ts +1 -0
- package/dist/components/CommonInputWrapper/CommonInputWrapper.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/CommonInputWrapper/types.d.ts +10 -0
- package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/composables/useConfirm.d.ts +22 -0
- package/dist/composables/useConfirm.js +43 -40
- package/dist/composables/useSafeAreaInternal.js +1 -1
- package/dist/composables/useToast.d.ts +16 -0
- package/dist/composables/useToast.js +20 -16
- package/dist/composables/useViewportWidth.d.ts +20 -6
- package/dist/composables/useViewportWidth.js +8 -7
- package/dist/icon-scan.d.ts +276 -0
- package/dist/icon-scan.js +485 -0
- package/dist/icons-whitelist.d.ts +5 -4
- package/dist/index.d.ts +2 -0
- package/dist/input-variants.d.ts +18 -0
- package/dist/llms-full.txt +2173 -1537
- package/dist/llms-medium.txt +504 -82
- package/dist/llms.txt +1 -1
- package/dist/nuxt-module.d.ts +1 -0
- package/dist/nuxt.js +10 -7
- package/dist/plugin.js +1 -0
- package/dist/runtime/nuxt-plugin.js +2 -1
- package/dist/styles.css +1 -1
- package/dist/types/Config.d.ts +18 -0
- package/dist/types/InputVariant.d.ts +22 -0
- package/dist/utils/cssLayers.d.ts +91 -0
- package/dist/utils/cssLayers.js +43 -0
- package/dist/utils/injectLibraryStyles.d.ts +3 -1
- package/dist/utils/injectLibraryStyles.js +24 -23
- package/dist/validated/BbColorInput.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/BbNumberInput.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/BbSelect.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/BbTag.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/BbTextInput.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/BbTextarea.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/validated/index.d.ts +1 -0
- package/dist/vite-plugin.d.ts +89 -12
- package/dist/vite.js +331 -281
- package/llms.txt +1 -1
- package/package.json +7 -5
- package/scripts/lib/ensure-manifest.mjs +28 -5
- package/scripts/lib/eslint-plugin.d.ts +35 -0
- package/scripts/lib/eslint-plugin.mjs +299 -3
- package/scripts/lib/hand-roll-hints.mjs +50 -6
- package/scripts/lib/html-attributes.mjs +42 -0
- package/scripts/lib/mcp-config.mjs +38 -34
- package/scripts/lib/public-type-exports.mjs +246 -0
- package/scripts/lib/validate-bb-markup.mjs +205 -12
package/bin/bitboss-ui.mjs
CHANGED
|
@@ -22,15 +22,23 @@
|
|
|
22
22
|
* `bitboss-ui.allowComponents`) exempts an app-owned component
|
|
23
23
|
* whose name happens to start with `Bb`.
|
|
24
24
|
*
|
|
25
|
+
* `--manifest <path>` judges against ANOTHER version's
|
|
26
|
+
* components.json instead of the installed one — answers "what
|
|
27
|
+
* breaks if I upgrade" BEFORE upgrading. A path, not a version:
|
|
28
|
+
* no network call inside a CI validator.
|
|
29
|
+
*
|
|
25
30
|
* SCOPE: `check` knows the INSTALLED v3 API and nothing about v2.
|
|
26
31
|
* "was removed from X" is a recorded v2→v3 break; "is not in X's
|
|
27
32
|
* API" only says the prop is not a v3 prop of that component —
|
|
28
33
|
* it may never have been one anywhere. `printFindingLegend` says
|
|
29
34
|
* so in the output, because two migrating fleets each spent real
|
|
30
35
|
* time discovering it the hard way.
|
|
36
|
+
* changelog Breaking changes between two releases — `--since <version>`
|
|
37
|
+
* answers "what breaks if I bump", without MCP. Reads the
|
|
38
|
+
* installed `dist/ai/changelog.json`.
|
|
31
39
|
* mcp Start a stdio MCP server exposing the dist/ai knowledge base
|
|
32
|
-
* (search_components, get_component,
|
|
33
|
-
* validate) to MCP-capable agent harnesses.
|
|
40
|
+
* (search_components, get_component, list_changes, list_recipes,
|
|
41
|
+
* get_recipe, validate) to MCP-capable agent harnesses.
|
|
34
42
|
*
|
|
35
43
|
* Plain ESM JavaScript on purpose: shipped as-is in the package, no build.
|
|
36
44
|
*/
|
|
@@ -44,13 +52,18 @@ import {
|
|
|
44
52
|
statSync,
|
|
45
53
|
writeFileSync,
|
|
46
54
|
} from 'node:fs';
|
|
47
|
-
import {
|
|
48
|
-
|
|
55
|
+
import {
|
|
56
|
+
findHandRollHints,
|
|
57
|
+
loadKnownTokens,
|
|
58
|
+
} from '../scripts/lib/hand-roll-hints.mjs';
|
|
59
|
+
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
49
60
|
import { fileURLToPath } from 'node:url';
|
|
50
61
|
import { parseArgs } from 'node:util';
|
|
51
62
|
import {
|
|
52
63
|
ensureMcpConfigs,
|
|
53
64
|
missingMcpPeers,
|
|
65
|
+
MCP_BIN_PATH,
|
|
66
|
+
MCP_PEERS,
|
|
54
67
|
} from '../scripts/lib/mcp-config.mjs';
|
|
55
68
|
import {
|
|
56
69
|
loadManifest,
|
|
@@ -88,7 +101,7 @@ function coreRules(version) {
|
|
|
88
101
|
5. **Icons**: discover names first; never invent them (\`${KNOWLEDGE_BASE}/guides/icons-policy.md\`).
|
|
89
102
|
6. **Item-driven components**: declarative \`items\` / \`item-text\` / \`item-value\`, \`dependencies\`, \`enforce-coherence\` — no manual watchers for coherence.
|
|
90
103
|
7. **Whole pages**: one recipe under \`${KNOWLEDGE_BASE}/recipes/{vue|nuxt|inertia}/\` (see the router table).
|
|
91
|
-
8. **CSS near components**: \`${KNOWLEDGE_BASE}/guides/design-language.md
|
|
104
|
+
8. **CSS near components**: \`${KNOWLEDGE_BASE}/guides/design-language.md\`. Two token tiers, and reaching for the wrong one is why apps end up re-skinning by class: \`--bb-*\` is the small GLOBAL theme tier (brand knobs, ~90 names, no numeric ramp — there is no \`--bb-primary-800\`), while each component declares its own **unprefixed** \`--*\` tokens for its look (\`.bb-table { --cell-h: 32px }\`). A missing \`--bb-*\` name is not a gap in the library — it means the knob you want is a component token. Set it on the element that DECLARES it (grep \`${KNOWLEDGE_BASE}/source/<ComponentName>.md\`); a value set further out is masked, not inherited. Never override \`.bb-*__*\` internals, and never target \`.bb-base-*\` / \`.bb-common-*\` at all. **A Tailwind utility on a \`Bb*\` component that does nothing** is not a library bug: Tailwind v4 emits layered CSS and unlayered CSS outranks it, whatever the specificity. The fix is in the BUILD plugin, not in CSS — \`cssLayers: TAILWIND_V4_LAYERS\` (imported from \`bitboss-ui/vite\`) in \`vite.config.*\` / \`nuxt.config.*\`; see \`${KNOWLEDGE_BASE}/guides/installation-and-plugin-setup.md\` § Cascade layers. One primary action per view region.
|
|
92
105
|
9. **Variants are yours to add**: the shipped \`variant\` names are a floor, not a ceiling. When the design needs a colour the library doesn't ship (soft status badges, a brand button tone), **register the name** in the build plugin's \`badgeVariants\`/\`buttonVariants\`/\`alertVariants\`/… and **style \`.bb-badge--<name>\`** (etc.) in a project stylesheet loaded after \`bitboss-ui/styles.css\`. Do both halves — a registered name with no CSS ships an unstyled pill, and CSS with no registration fails \`vue-tsc\`. Never write an unregistered name, and never downgrade the design to a neutral shipped variant to avoid registering. Canonical palette + snippet: \`${KNOWLEDGE_BASE}/guides/design-language.md\` § Getting soft semantic badges.
|
|
93
106
|
10. **After writing bitboss-ui markup**, run \`npx bitboss-ui check\` — validates \`Bb*\` usage against the installed \`components.json\` and catches invented/removed props before review.
|
|
94
107
|
|
|
@@ -519,6 +532,29 @@ function printFindingLegend(findings) {
|
|
|
519
532
|
' "restoring" anything: the second case needs deleting,\n' +
|
|
520
533
|
' not porting.'
|
|
521
534
|
);
|
|
535
|
+
// A type written as a tag is its own category: the name IS ours, so neither
|
|
536
|
+
// "check the spelling" nor the allowlist applies, and a reader who skims the
|
|
537
|
+
// message alone would reach for one of them.
|
|
538
|
+
if (
|
|
539
|
+
findings.some((f) => / is a type export, not a component$/.test(f.message))
|
|
540
|
+
)
|
|
541
|
+
rows.push(
|
|
542
|
+
' "is a type export" a real export, but a TYPE — it types a prop, it does not\n' +
|
|
543
|
+
' render. Import it (`import type { … }`) and pass the\n' +
|
|
544
|
+
' value; never allowlist it, which would only silence\n' +
|
|
545
|
+
' every other check on that tag.'
|
|
546
|
+
);
|
|
547
|
+
if (findings.some((f) => f.fallthrough))
|
|
548
|
+
rows.push(
|
|
549
|
+
' ⚠ (vs ✗) markup that is not a typo and may work today: an\n' +
|
|
550
|
+
' undeclared listener Vue binds to the root ELEMENT,\n' +
|
|
551
|
+
' so whether it fires depends on what that root is —\n' +
|
|
552
|
+
" an internal detail, on the component's schedule or\n" +
|
|
553
|
+
" the element's. `<BbDialog @close>` runs (that root is\n" +
|
|
554
|
+
' a native <dialog>); `<BbAlert @close>` does not.\n' +
|
|
555
|
+
' Still reported, because neither is the contract. In\n' +
|
|
556
|
+
' ESLint this is `no-unknown-event`, a warning.'
|
|
557
|
+
);
|
|
522
558
|
if (rows.length === 0) return;
|
|
523
559
|
console.error('\nReading these findings:');
|
|
524
560
|
for (const row of rows) console.error(row);
|
|
@@ -532,13 +568,156 @@ function printFindingLegend(findings) {
|
|
|
532
568
|
* v-models, and `<template #slot>` names) in `.vue` and `.md` files against
|
|
533
569
|
* the installed components.json manifest.
|
|
534
570
|
*/
|
|
535
|
-
|
|
571
|
+
/**
|
|
572
|
+
* The version a components.json describes. `loadManifest` returns the indexed
|
|
573
|
+
* component map, not the envelope, so read the field straight off the file.
|
|
574
|
+
*/
|
|
575
|
+
/**
|
|
576
|
+
* `changelog [--since <v>] [--until <v>] [--json]` — what breaks between two
|
|
577
|
+
* releases, for anyone not driving the MCP server (a human at a terminal, CI,
|
|
578
|
+
* or an agent whose harness has no MCP). Same data and same range rules as the
|
|
579
|
+
* `list_changes` tool; this is the transport-free path to it.
|
|
580
|
+
*/
|
|
581
|
+
function changelogCommand({ since, until, json: jsonMode }) {
|
|
582
|
+
const path = join(PACKAGE_ROOT, 'dist', 'ai', 'changelog.json');
|
|
583
|
+
if (!existsSync(path)) {
|
|
584
|
+
console.error(
|
|
585
|
+
`[bitboss-ui] changelog: not found at ${path} — reinstall bitboss-ui (or run \`npm run build\` when working in the library repo).`
|
|
586
|
+
);
|
|
587
|
+
process.exit(1);
|
|
588
|
+
}
|
|
589
|
+
const doc = JSON.parse(readFileSync(path, 'utf-8'));
|
|
590
|
+
const releases = doc.releases ?? [];
|
|
591
|
+
|
|
592
|
+
for (const [label, value] of [
|
|
593
|
+
['--since', since],
|
|
594
|
+
['--until', until],
|
|
595
|
+
]) {
|
|
596
|
+
if (value != null && !releases.includes(value)) {
|
|
597
|
+
console.error(
|
|
598
|
+
`[bitboss-ui] changelog: unknown ${label} version '${value}'.\n` +
|
|
599
|
+
`Known releases: ${releases.join(', ')}`
|
|
600
|
+
);
|
|
601
|
+
process.exit(1);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const ranged = since != null || until != null;
|
|
606
|
+
const rows = (doc.breaking ?? []).filter((entry) => {
|
|
607
|
+
if (!ranged) return true;
|
|
608
|
+
const at = entry.firstReleasedIn;
|
|
609
|
+
if (at == null) return until == null;
|
|
610
|
+
if (since != null && compareReleaseVersions(at, since) <= 0) return false;
|
|
611
|
+
if (until != null && compareReleaseVersions(at, until) > 0) return false;
|
|
612
|
+
return true;
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
if (jsonMode) {
|
|
616
|
+
console.log(
|
|
617
|
+
JSON.stringify(
|
|
618
|
+
{
|
|
619
|
+
version: doc.version,
|
|
620
|
+
since: since ?? null,
|
|
621
|
+
until: until ?? doc.version,
|
|
622
|
+
count: rows.length,
|
|
623
|
+
breaking: rows,
|
|
624
|
+
guide: doc.guide,
|
|
625
|
+
},
|
|
626
|
+
null,
|
|
627
|
+
2
|
|
628
|
+
)
|
|
629
|
+
);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
const range = ranged
|
|
634
|
+
? `${since ?? 'the start of v3'} → ${until ?? doc.version}`
|
|
635
|
+
: `the whole v2 → v3 upgrade`;
|
|
636
|
+
if (rows.length === 0) {
|
|
637
|
+
// "Nothing breaks" and "I could not tell you" must not look alike.
|
|
638
|
+
console.log(
|
|
639
|
+
`[bitboss-ui] changelog: no BREAKING changes in ${range}.\n` +
|
|
640
|
+
' Features and fixes are deliberately not tracked here, so this\n' +
|
|
641
|
+
' means nothing breaks — not that nothing changed.'
|
|
642
|
+
);
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
console.log(
|
|
646
|
+
`[bitboss-ui] changelog: ${rows.length} breaking change(s), ${range}\n`
|
|
647
|
+
);
|
|
648
|
+
for (const entry of rows) {
|
|
649
|
+
const at = entry.firstReleasedIn ?? 'unreleased';
|
|
650
|
+
if (entry.kind === 'rename') {
|
|
651
|
+
console.log(
|
|
652
|
+
` [${at}] ${entry.components.join(', ')}: \`${entry.from}\` → \`${entry.to}\``
|
|
653
|
+
);
|
|
654
|
+
} else {
|
|
655
|
+
console.log(` [${at}] ${entry.description}`);
|
|
656
|
+
}
|
|
657
|
+
if (entry.guide) console.log(` ${entry.guide}`);
|
|
658
|
+
}
|
|
659
|
+
console.log(`\nFull migration guide: ${doc.guide}`);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/** Numeric, prerelease-aware ordering; the twin of the MCP server's copy. */
|
|
663
|
+
function compareReleaseVersions(a, b) {
|
|
664
|
+
const parse = (v) => {
|
|
665
|
+
const [core, pre = ''] = String(v).split('-');
|
|
666
|
+
const nums = core.split('.').map((n) => Number.parseInt(n, 10) || 0);
|
|
667
|
+
const [tag = '', n = ''] = pre.split('.');
|
|
668
|
+
return { nums, tag, n: Number.parseInt(n, 10) || 0 };
|
|
669
|
+
};
|
|
670
|
+
const x = parse(a);
|
|
671
|
+
const y = parse(b);
|
|
672
|
+
for (let i = 0; i < 3; i += 1) {
|
|
673
|
+
if ((x.nums[i] ?? 0) !== (y.nums[i] ?? 0))
|
|
674
|
+
return (x.nums[i] ?? 0) - (y.nums[i] ?? 0);
|
|
675
|
+
}
|
|
676
|
+
if (!x.tag && y.tag) return 1;
|
|
677
|
+
if (x.tag && !y.tag) return -1;
|
|
678
|
+
if (x.tag !== y.tag) return x.tag < y.tag ? -1 : 1;
|
|
679
|
+
return x.n - y.n;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
function manifestVersionOf(manifestPath) {
|
|
683
|
+
try {
|
|
684
|
+
return JSON.parse(readFileSync(manifestPath, 'utf-8')).version ?? 'unknown';
|
|
685
|
+
} catch {
|
|
686
|
+
return 'unknown';
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
function checkCommand(
|
|
691
|
+
globs,
|
|
692
|
+
{ json: jsonMode, allowEmpty, allowComponents, manifest: manifestOverride }
|
|
693
|
+
) {
|
|
536
694
|
const projectRoot = process.cwd();
|
|
537
695
|
|
|
538
|
-
|
|
696
|
+
/*
|
|
697
|
+
* `--manifest` answers the question `check` could not: "which of my files
|
|
698
|
+
* break in the version I am about to move to?" (reported 2026-09-09). By
|
|
699
|
+
* default the manifest is the INSTALLED one, so the only way to see an
|
|
700
|
+
* upgrade's damage was to perform the upgrade first — exactly backwards for
|
|
701
|
+
* the one moment the answer is worth having.
|
|
702
|
+
*
|
|
703
|
+
* Deliberately a PATH, not a version: fetching a version would put a network
|
|
704
|
+
* call inside a validator that consumers run in CI, with a registry outage
|
|
705
|
+
* as a new failure mode. Getting the file is one documented command
|
|
706
|
+
* (`npm pack bitboss-ui@<version>`, or the public CDN copy), and pointing at
|
|
707
|
+
* it keeps this offline and reproducible.
|
|
708
|
+
*/
|
|
709
|
+
const installedManifest = join(PACKAGE_ROOT, 'dist', 'ai', 'components.json');
|
|
710
|
+
const manifestPath = manifestOverride
|
|
711
|
+
? resolve(projectRoot, manifestOverride)
|
|
712
|
+
: installedManifest;
|
|
539
713
|
if (!existsSync(manifestPath)) {
|
|
540
714
|
console.error(
|
|
541
|
-
|
|
715
|
+
manifestOverride
|
|
716
|
+
? `[bitboss-ui] --manifest: no file at ${manifestPath}.\n` +
|
|
717
|
+
'Point it at a components.json from the version you are moving to:\n' +
|
|
718
|
+
' npm pack bitboss-ui@<version> && tar -xzf bitboss-ui-<version>.tgz\n' +
|
|
719
|
+
' npx bitboss-ui check --manifest package/dist/ai/components.json'
|
|
720
|
+
: `[bitboss-ui] Manifest not found at ${manifestPath} — reinstall bitboss-ui (or run \`npm run build\` when working in the library repo).`
|
|
542
721
|
);
|
|
543
722
|
process.exit(1);
|
|
544
723
|
}
|
|
@@ -551,16 +730,14 @@ function checkCommand(globs, { json: jsonMode, allowEmpty, allowComponents }) {
|
|
|
551
730
|
* Absent stylesheet → an empty set → the unknown-token hint stays silent,
|
|
552
731
|
* which is the right failure: no data, no accusation.
|
|
553
732
|
*/
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
)
|
|
563
|
-
: new Set();
|
|
733
|
+
// Under `--manifest`, take the sheet from beside THAT manifest
|
|
734
|
+
// (`<pkg>/dist/ai/components.json` → `<pkg>/dist/styles.css`). Reading the
|
|
735
|
+
// installed sheet while judging props against another version would mix two
|
|
736
|
+
// releases in one verdict — the exact confusion this flag exists to end.
|
|
737
|
+
const stylesPath = manifestOverride
|
|
738
|
+
? join(dirname(dirname(manifestPath)), 'styles.css')
|
|
739
|
+
: join(PACKAGE_ROOT, 'dist', 'styles.css');
|
|
740
|
+
const knownTokens = loadKnownTokens(stylesPath);
|
|
564
741
|
const files = resolveCheckFiles(projectRoot, globs);
|
|
565
742
|
|
|
566
743
|
// CHK-ALLOWCOMPONENTS: `Bb` is a naming convention, not proof of ownership.
|
|
@@ -613,9 +790,37 @@ function checkCommand(globs, { json: jsonMode, allowEmpty, allowComponents }) {
|
|
|
613
790
|
);
|
|
614
791
|
};
|
|
615
792
|
|
|
793
|
+
/*
|
|
794
|
+
* Which API the verdict is against. Silent when it is the installed one —
|
|
795
|
+
* that is the assumption, and a banner on every run trains people to skip
|
|
796
|
+
* it. Loud under `--manifest`, because "12 findings" means something
|
|
797
|
+
* completely different when it describes a version you have not installed
|
|
798
|
+
* yet, and a scrollback with no marker is indistinguishable from a normal
|
|
799
|
+
* run.
|
|
800
|
+
*/
|
|
801
|
+
const judgedAgainst = manifestOverride
|
|
802
|
+
? manifestVersionOf(manifestPath)
|
|
803
|
+
: packageVersion();
|
|
804
|
+
if (manifestOverride && !jsonMode) {
|
|
805
|
+
console.log(
|
|
806
|
+
`[bitboss-ui] check: judging against bitboss-ui ${judgedAgainst} (--manifest), NOT the installed ${packageVersion()}.\n` +
|
|
807
|
+
' Findings describe the version you are moving TO.'
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
|
|
616
811
|
if (jsonMode) {
|
|
617
812
|
console.log(
|
|
618
|
-
JSON.stringify(
|
|
813
|
+
JSON.stringify(
|
|
814
|
+
{
|
|
815
|
+
findings,
|
|
816
|
+
hints,
|
|
817
|
+
files: files.length,
|
|
818
|
+
manifestVersion: judgedAgainst,
|
|
819
|
+
installedVersion: packageVersion(),
|
|
820
|
+
},
|
|
821
|
+
null,
|
|
822
|
+
2
|
|
823
|
+
)
|
|
619
824
|
);
|
|
620
825
|
if (findings.length > 0) process.exit(1);
|
|
621
826
|
if (files.length === 0 && globs.length > 0 && !allowEmpty) process.exit(1);
|
|
@@ -668,8 +873,13 @@ function checkCommand(globs, { json: jsonMode, allowEmpty, allowComponents }) {
|
|
|
668
873
|
// were indistinguishable, so every automated fix had to re-parse the
|
|
669
874
|
// file to place them. The line comes straight off the template AST.
|
|
670
875
|
const at = finding.line != null ? `line ${finding.line}: ` : '';
|
|
876
|
+
// A `fallthrough` finding is not a typo and may be doing something
|
|
877
|
+
// today — a native listener reaching the root element. It still counts,
|
|
878
|
+
// but marking it `✗` alongside a genuinely broken prop is what let one
|
|
879
|
+
// migration report read a live `<BbDialog @close>` as dead code.
|
|
880
|
+
const mark = finding.fallthrough ? '⚠' : '✗';
|
|
671
881
|
console.error(
|
|
672
|
-
`
|
|
882
|
+
` ${mark} ${at}${where ? `[${where.trim()}] ` : ''}${finding.message}`
|
|
673
883
|
);
|
|
674
884
|
if (finding.hint) console.error(` hint: ${finding.hint}`);
|
|
675
885
|
}
|
|
@@ -697,7 +907,7 @@ Commands:
|
|
|
697
907
|
VS Code/Copilot (.vscode/mcp.json), and Windsurf (~/.codeium
|
|
698
908
|
global) — merges, never overwrites other servers.
|
|
699
909
|
check [glob…] [--json] [--allow-empty] [--allow-component <Name>]
|
|
700
|
-
[--no-hints]
|
|
910
|
+
[--no-hints] [--manifest <path>]
|
|
701
911
|
Validate \`Bb*\` markup in .vue/.md files against the
|
|
702
912
|
installed components.json manifest (unknown/removed props,
|
|
703
913
|
bad v-models, unknown \`<template #slot>\` names,
|
|
@@ -710,6 +920,17 @@ Commands:
|
|
|
710
920
|
nothing (a typo'd CI path validates zero files silently) —
|
|
711
921
|
pass \`--allow-empty\` when an empty match is expected.
|
|
712
922
|
|
|
923
|
+
\`--manifest <path>\` judges against another version's
|
|
924
|
+
components.json instead of the installed one — the answer
|
|
925
|
+
to "which of my files break if I upgrade", BEFORE you
|
|
926
|
+
upgrade. The banner names both versions so a findings list
|
|
927
|
+
is never mistaken for one about your current install.
|
|
928
|
+
npm pack bitboss-ui@3.0.0-beta.21
|
|
929
|
+
tar -xzf bitboss-ui-3.0.0-beta.21.tgz
|
|
930
|
+
npx bitboss-ui check --manifest package/dist/ai/components.json
|
|
931
|
+
A path, not a version, on purpose: fetching one would put
|
|
932
|
+
a registry call inside a validator people run in CI.
|
|
933
|
+
|
|
713
934
|
\`--allow-component <Name>\` (repeatable) exempts a
|
|
714
935
|
component your APP owns whose name starts with \`Bb\` —
|
|
715
936
|
the prefix is a convention, not proof of provenance.
|
|
@@ -730,6 +951,16 @@ Commands:
|
|
|
730
951
|
\`no-default-slot\`, \`inert-nav-attr\`,
|
|
731
952
|
\`missing-partner-prop\`, \`partner-prop\`,
|
|
732
953
|
\`validated-only-prop\`.
|
|
954
|
+
changelog [--since <version>] [--until <version>] [--json]
|
|
955
|
+
Breaking changes between two releases — "what breaks if I
|
|
956
|
+
bump". \`--since\` is the version you are ON, and is
|
|
957
|
+
exclusive. With no range, every break in the v2 → v3
|
|
958
|
+
upgrade. Only BREAKING changes are tracked, so an empty
|
|
959
|
+
result means nothing breaks, not that nothing changed.
|
|
960
|
+
npx bitboss-ui changelog --since 3.0.0-beta.20
|
|
961
|
+
Pair it with \`check --manifest\` to turn the list into the
|
|
962
|
+
files in YOUR app that break.
|
|
963
|
+
|
|
733
964
|
mcp Start a stdio MCP server exposing the dist/ai knowledge
|
|
734
965
|
base (search_components, get_component, list_recipes,
|
|
735
966
|
get_recipe, validate) to MCP-capable agent harnesses.
|
|
@@ -776,6 +1007,7 @@ switch (command) {
|
|
|
776
1007
|
json: { type: 'boolean' },
|
|
777
1008
|
'allow-empty': { type: 'boolean' },
|
|
778
1009
|
'allow-component': { type: 'string', multiple: true },
|
|
1010
|
+
manifest: { type: 'string' },
|
|
779
1011
|
// Accepted and ignored here — read straight off argv inside
|
|
780
1012
|
// checkCommand, but parseArgs is strict, so it must be declared.
|
|
781
1013
|
'no-hints': { type: 'boolean' },
|
|
@@ -786,6 +1018,20 @@ switch (command) {
|
|
|
786
1018
|
json: values.json ?? false,
|
|
787
1019
|
allowEmpty: values['allow-empty'] ?? false,
|
|
788
1020
|
allowComponents: values['allow-component'] ?? [],
|
|
1021
|
+
manifest: values.manifest,
|
|
1022
|
+
});
|
|
1023
|
+
break;
|
|
1024
|
+
}
|
|
1025
|
+
case 'changelog': {
|
|
1026
|
+
const { values } = parseCommandArgs(command, commandArgs, {
|
|
1027
|
+
since: { type: 'string' },
|
|
1028
|
+
until: { type: 'string' },
|
|
1029
|
+
json: { type: 'boolean' },
|
|
1030
|
+
});
|
|
1031
|
+
changelogCommand({
|
|
1032
|
+
since: values.since,
|
|
1033
|
+
until: values.until,
|
|
1034
|
+
json: values.json ?? false,
|
|
789
1035
|
});
|
|
790
1036
|
break;
|
|
791
1037
|
}
|
|
@@ -802,9 +1048,34 @@ switch (command) {
|
|
|
802
1048
|
({ main } = await import('./bitboss-ui-mcp.mjs'));
|
|
803
1049
|
} catch (error) {
|
|
804
1050
|
if (error?.code !== 'ERR_MODULE_NOT_FOUND') throw error;
|
|
1051
|
+
// Running from an npx cache is a DIFFERENT failure wearing the same
|
|
1052
|
+
// error: the peers resolve relative to the package we were launched
|
|
1053
|
+
// from, so a cached copy can never see the project's node_modules no
|
|
1054
|
+
// matter what is installed there. Telling that user to install peers
|
|
1055
|
+
// they already have is what sent a consumer down a dead end
|
|
1056
|
+
// (2026-09-09). `ai-init --mcp` now writes the local binary instead
|
|
1057
|
+
// of `npx`, so the fix is to rewrite the config.
|
|
1058
|
+
const fromNpxCache = /[/\\]_npx[/\\]/.test(
|
|
1059
|
+
fileURLToPath(import.meta.url)
|
|
1060
|
+
);
|
|
1061
|
+
const projectHasPeers = missingMcpPeers(process.cwd()).length === 0;
|
|
1062
|
+
if (fromNpxCache && projectHasPeers) {
|
|
1063
|
+
console.error(
|
|
1064
|
+
'bitboss-ui mcp was launched through `npx`, which runs it from the npx cache —\n' +
|
|
1065
|
+
'its optional peers resolve there, not in your project, so the server cannot start\n' +
|
|
1066
|
+
`even though this project has them installed (${MCP_PEERS.join(', ')}).\n\n` +
|
|
1067
|
+
'Fix the harness config to invoke the installed binary:\n\n' +
|
|
1068
|
+
' npx bitboss-ui ai-init --mcp\n\n' +
|
|
1069
|
+
`which writes \`node ${MCP_BIN_PATH} mcp\`. To run it right now:\n\n` +
|
|
1070
|
+
` node ${MCP_BIN_PATH} mcp\n\n` +
|
|
1071
|
+
`Resolution failed with: ${error.message}`
|
|
1072
|
+
);
|
|
1073
|
+
process.exitCode = 1;
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
805
1076
|
console.error(
|
|
806
1077
|
'bitboss-ui mcp needs two optional peer dependencies that are not installed:\n' +
|
|
807
|
-
|
|
1078
|
+
`\n npm i -D ${MCP_PEERS.join(' ')}\n\n` +
|
|
808
1079
|
'They are optional because they are ~12 MB and only this subcommand uses them.\n' +
|
|
809
1080
|
`Resolution failed with: ${error.message}`
|
|
810
1081
|
);
|
package/dist/ai/BbAccordion.md
CHANGED
|
@@ -47,13 +47,13 @@ collapsed state and strips padding/borders you put on the panel itself.
|
|
|
47
47
|
```vue
|
|
48
48
|
<template>
|
|
49
49
|
<div
|
|
50
|
-
class="max-w-md overflow-hidden rounded-
|
|
50
|
+
class="max-w-md overflow-hidden rounded-(--bb-radius) border border-(--bb-border)"
|
|
51
51
|
>
|
|
52
52
|
<BbAccordion
|
|
53
53
|
v-for="(faq, index) in faqs"
|
|
54
54
|
:key="faq.question"
|
|
55
55
|
v-model="faq.open"
|
|
56
|
-
:class="index ? 'border-t border-
|
|
56
|
+
:class="index ? 'border-t border-(--bb-border)' : ''"
|
|
57
57
|
>
|
|
58
58
|
<template #header="{ value }">
|
|
59
59
|
<div
|
|
@@ -61,7 +61,7 @@ collapsed state and strips padding/borders you put on the panel itself.
|
|
|
61
61
|
>
|
|
62
62
|
<span>{{ faq.question }}</span>
|
|
63
63
|
<span
|
|
64
|
-
class="shrink-0 text-
|
|
64
|
+
class="shrink-0 text-(--bb-text-muted) transition-transform duration-200"
|
|
65
65
|
:class="value ? 'rotate-180' : ''"
|
|
66
66
|
>
|
|
67
67
|
<BbIcon icon="lucide:chevron-down" size="sm" />
|
|
@@ -69,7 +69,7 @@ collapsed state and strips padding/borders you put on the panel itself.
|
|
|
69
69
|
</div>
|
|
70
70
|
</template>
|
|
71
71
|
|
|
72
|
-
<p class="px-3 pb-2.5 text-sm text-
|
|
72
|
+
<p class="px-3 pb-2.5 text-sm text-(--bb-text-muted)">
|
|
73
73
|
{{ faq.answer }}
|
|
74
74
|
</p>
|
|
75
75
|
</BbAccordion>
|
|
@@ -121,13 +121,13 @@ on the row, badge included, toggles the panel.
|
|
|
121
121
|
```vue
|
|
122
122
|
<template>
|
|
123
123
|
<div
|
|
124
|
-
class="max-w-md overflow-hidden rounded-
|
|
124
|
+
class="max-w-md overflow-hidden rounded-(--bb-radius) border border-(--bb-border)"
|
|
125
125
|
>
|
|
126
126
|
<BbAccordion
|
|
127
127
|
v-for="(endpoint, index) in endpoints"
|
|
128
128
|
:key="`${endpoint.method}:${endpoint.path}`"
|
|
129
129
|
v-model="endpoint.open"
|
|
130
|
-
:class="index ? 'border-t border-
|
|
130
|
+
:class="index ? 'border-t border-(--bb-border)' : ''"
|
|
131
131
|
>
|
|
132
132
|
<template #header="{ value }">
|
|
133
133
|
<div class="flex w-full items-center gap-2 px-3 py-2 text-left">
|
|
@@ -136,7 +136,7 @@ on the row, badge included, toggles the panel.
|
|
|
136
136
|
}}</BbBadge>
|
|
137
137
|
<code class="truncate font-mono text-xs">{{ endpoint.path }}</code>
|
|
138
138
|
<span
|
|
139
|
-
class="ml-auto shrink-0 text-
|
|
139
|
+
class="ml-auto shrink-0 text-(--bb-text-muted) transition-transform duration-200"
|
|
140
140
|
:class="value ? 'rotate-180' : ''"
|
|
141
141
|
>
|
|
142
142
|
<BbIcon icon="lucide:chevron-down" size="sm" />
|
|
@@ -145,7 +145,7 @@ on the row, badge included, toggles the panel.
|
|
|
145
145
|
</template>
|
|
146
146
|
|
|
147
147
|
<div class="flex flex-col gap-1.5 px-3 pb-2.5">
|
|
148
|
-
<p class="text-xs text-
|
|
148
|
+
<p class="text-xs text-(--bb-text-muted)">
|
|
149
149
|
{{ endpoint.summary }}
|
|
150
150
|
</p>
|
|
151
151
|
<dl class="flex flex-col gap-1 text-xs">
|
|
@@ -155,7 +155,7 @@ on the row, badge included, toggles the panel.
|
|
|
155
155
|
class="flex items-baseline gap-2"
|
|
156
156
|
>
|
|
157
157
|
<dt class="shrink-0 font-mono">{{ param.name }}</dt>
|
|
158
|
-
<dd class="text-
|
|
158
|
+
<dd class="text-(--bb-text-muted)">
|
|
159
159
|
{{ param.type }} · {{ param.description }}
|
|
160
160
|
</dd>
|
|
161
161
|
</div>
|
|
@@ -263,7 +263,7 @@ Both slots — `header` and the default (body) slot — receive the same scope,
|
|
|
263
263
|
```vue
|
|
264
264
|
<template>
|
|
265
265
|
<div
|
|
266
|
-
class="max-w-md overflow-hidden rounded-
|
|
266
|
+
class="max-w-md overflow-hidden rounded-(--bb-radius) border border-(--bb-border)"
|
|
267
267
|
>
|
|
268
268
|
<BbAccordion v-model="notes">
|
|
269
269
|
<template #header="{ value }">
|
|
@@ -272,7 +272,7 @@ Both slots — `header` and the default (body) slot — receive the same scope,
|
|
|
272
272
|
>
|
|
273
273
|
<span>Release notes</span>
|
|
274
274
|
<span
|
|
275
|
-
class="shrink-0 text-
|
|
275
|
+
class="shrink-0 text-(--bb-text-muted) transition-transform duration-200"
|
|
276
276
|
:class="value ? 'rotate-180' : ''"
|
|
277
277
|
>
|
|
278
278
|
<BbIcon icon="lucide:chevron-down" size="sm" />
|
|
@@ -281,7 +281,7 @@ Both slots — `header` and the default (body) slot — receive the same scope,
|
|
|
281
281
|
</template>
|
|
282
282
|
<template #default="{ toggle }">
|
|
283
283
|
<div class="flex flex-col items-start gap-1.5 px-3 pb-2.5">
|
|
284
|
-
<p class="text-sm text-
|
|
284
|
+
<p class="text-sm text-(--bb-text-muted)">
|
|
285
285
|
Dropdown keyboard navigation, smoother select popovers, and a new
|
|
286
286
|
color picker.
|
|
287
287
|
</p>
|
|
@@ -317,12 +317,12 @@ to `null`). Prefer a stable key over an index when the list can reorder.
|
|
|
317
317
|
```vue
|
|
318
318
|
<template>
|
|
319
319
|
<div
|
|
320
|
-
class="max-w-md overflow-hidden rounded-
|
|
320
|
+
class="max-w-md overflow-hidden rounded-(--bb-radius) border border-(--bb-border)"
|
|
321
321
|
>
|
|
322
322
|
<BbAccordion
|
|
323
323
|
v-for="(plan, index) in plans"
|
|
324
324
|
:key="plan.name"
|
|
325
|
-
:class="index ? 'border-t border-
|
|
325
|
+
:class="index ? 'border-t border-(--bb-border)' : ''"
|
|
326
326
|
:model-value="openIndex === index"
|
|
327
327
|
@update:model-value="openIndex = $event ? index : null"
|
|
328
328
|
>
|
|
@@ -331,9 +331,7 @@ to `null`). Prefer a stable key over an index when the list can reorder.
|
|
|
331
331
|
class="flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-sm"
|
|
332
332
|
>
|
|
333
333
|
<span class="font-medium">{{ plan.name }}</span>
|
|
334
|
-
<span
|
|
335
|
-
class="flex items-center gap-1.5 text-[color:var(--bb-text-muted)]"
|
|
336
|
-
>
|
|
334
|
+
<span class="flex items-center gap-1.5 text-(--bb-text-muted)">
|
|
337
335
|
{{ plan.price }}
|
|
338
336
|
<span
|
|
339
337
|
class="shrink-0 transition-transform duration-200"
|
|
@@ -346,7 +344,7 @@ to `null`). Prefer a stable key over an index when the list can reorder.
|
|
|
346
344
|
</template>
|
|
347
345
|
|
|
348
346
|
<ul
|
|
349
|
-
class="flex flex-col gap-1 px-3 pb-2.5 text-sm text-
|
|
347
|
+
class="flex flex-col gap-1 px-3 pb-2.5 text-sm text-(--bb-text-muted)"
|
|
350
348
|
>
|
|
351
349
|
<li v-for="feature in plan.features" :key="feature">{{ feature }}</li>
|
|
352
350
|
</ul>
|
|
@@ -394,7 +392,7 @@ padding on the nested body content.
|
|
|
394
392
|
```vue
|
|
395
393
|
<template>
|
|
396
394
|
<div
|
|
397
|
-
class="max-w-md overflow-hidden rounded-
|
|
395
|
+
class="max-w-md overflow-hidden rounded-(--bb-radius) border border-(--bb-border)"
|
|
398
396
|
>
|
|
399
397
|
<BbAccordion v-model="notifications">
|
|
400
398
|
<template #header="{ value }">
|
|
@@ -403,7 +401,7 @@ padding on the nested body content.
|
|
|
403
401
|
>
|
|
404
402
|
<span>Notifications</span>
|
|
405
403
|
<span
|
|
406
|
-
class="shrink-0 text-
|
|
404
|
+
class="shrink-0 text-(--bb-text-muted) transition-transform duration-200"
|
|
407
405
|
:class="value ? 'rotate-180' : ''"
|
|
408
406
|
>
|
|
409
407
|
<BbIcon icon="lucide:chevron-down" size="sm" />
|
|
@@ -416,7 +414,7 @@ padding on the nested body content.
|
|
|
416
414
|
<BbAccordion v-model="advanced">
|
|
417
415
|
<template #header="{ value }">
|
|
418
416
|
<div
|
|
419
|
-
class="flex w-full items-center justify-between gap-2 py-1 text-left text-sm text-
|
|
417
|
+
class="flex w-full items-center justify-between gap-2 py-1 text-left text-sm text-(--bb-text-muted)"
|
|
420
418
|
>
|
|
421
419
|
<span>Advanced</span>
|
|
422
420
|
<span
|
|
@@ -427,7 +425,7 @@ padding on the nested body content.
|
|
|
427
425
|
</span>
|
|
428
426
|
</div>
|
|
429
427
|
</template>
|
|
430
|
-
<div class="
|
|
428
|
+
<div class="pt-1 pb-1">
|
|
431
429
|
<BbCheckbox v-model="quiet" label="Quiet hours (22:00–08:00)" />
|
|
432
430
|
</div>
|
|
433
431
|
</BbAccordion>
|
|
@@ -470,7 +468,7 @@ get a near-instant transition automatically.
|
|
|
470
468
|
<template #header>
|
|
471
469
|
<span class="px-3 py-2 text-sm font-medium">Shipping details</span>
|
|
472
470
|
</template>
|
|
473
|
-
<p class="px-3 pb-3 text-sm text-
|
|
471
|
+
<p class="px-3 pb-3 text-sm text-(--bb-text-muted)">
|
|
474
472
|
Rendered up front so its text is present even while collapsed.
|
|
475
473
|
</p>
|
|
476
474
|
</BbAccordion>
|
package/dist/ai/BbAlert.md
CHANGED
|
@@ -129,12 +129,10 @@ Bind `v-model` when the visibility matters to you:
|
|
|
129
129
|
|
|
130
130
|
```vue
|
|
131
131
|
<template>
|
|
132
|
-
<div
|
|
133
|
-
class="flex max-w-md flex-col gap-3 rounded-[var(--bb-radius)] border p-3"
|
|
134
|
-
>
|
|
132
|
+
<div class="flex max-w-md flex-col gap-3 rounded-(--bb-radius) border p-3">
|
|
135
133
|
<div class="flex flex-col gap-0.5">
|
|
136
134
|
<p class="text-sm font-medium">Account</p>
|
|
137
|
-
<p class="text-xs text-
|
|
135
|
+
<p class="text-xs text-(--bb-text-muted)">
|
|
138
136
|
Confirm your email to invite teammates and manage billing.
|
|
139
137
|
</p>
|
|
140
138
|
</div>
|
|
@@ -233,12 +231,10 @@ genuine brand art; everything semantic stays a provider icon.
|
|
|
233
231
|
|
|
234
232
|
```vue
|
|
235
233
|
<template>
|
|
236
|
-
<div
|
|
237
|
-
class="flex max-w-md flex-col gap-3 rounded-[var(--bb-radius)] border p-3"
|
|
238
|
-
>
|
|
234
|
+
<div class="flex max-w-md flex-col gap-3 rounded-(--bb-radius) border p-3">
|
|
239
235
|
<div class="flex flex-col gap-0.5">
|
|
240
236
|
<p class="text-sm font-medium">Integrations</p>
|
|
241
|
-
<p class="text-xs text-
|
|
237
|
+
<p class="text-xs text-(--bb-text-muted)">
|
|
242
238
|
Connected payment providers for Northwind Billing.
|
|
243
239
|
</p>
|
|
244
240
|
</div>
|
|
@@ -279,12 +275,10 @@ list of problems changes.
|
|
|
279
275
|
|
|
280
276
|
```vue
|
|
281
277
|
<template>
|
|
282
|
-
<div
|
|
283
|
-
class="flex max-w-md flex-col gap-3 rounded-[var(--bb-radius)] border p-3"
|
|
284
|
-
>
|
|
278
|
+
<div class="flex max-w-md flex-col gap-3 rounded-(--bb-radius) border p-3">
|
|
285
279
|
<div class="flex flex-col gap-0.5">
|
|
286
280
|
<p class="text-sm font-medium">Publish checklist</p>
|
|
287
|
-
<p class="text-xs text-
|
|
281
|
+
<p class="text-xs text-(--bb-text-muted)">
|
|
288
282
|
Northwind Q3 release notes — blocked until both items are done.
|
|
289
283
|
</p>
|
|
290
284
|
</div>
|