@bridge-ui/vue 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/ai/AGENTS.md +31 -0
  2. package/ai/README.md +35 -0
  3. package/ai/guidelines/core.md +44 -0
  4. package/ai/llms.txt +38 -0
  5. package/ai/skills/bridge-ui-components/SKILL.md +37 -0
  6. package/ai/skills/bridge-ui-forms/SKILL.md +38 -0
  7. package/ai/skills/bridge-ui-overlays/SKILL.md +37 -0
  8. package/ai/skills/bridge-ui-setup/SKILL.md +38 -0
  9. package/bin/__tests__/ai.test.ts +319 -0
  10. package/bin/ai.mjs +469 -0
  11. package/dist/Adapters/I18n/useI18nAdapter.d.ts +1 -1
  12. package/dist/Adapters/Icon/useIconAdapter.d.ts +1 -1
  13. package/dist/Components/Autocomplete/Autocomplete.vue.d.ts +5 -5
  14. package/dist/Components/Autocomplete/composables/useAutocomplete.d.ts +3 -2
  15. package/dist/Components/Autocomplete/composables/useAutocomplete.js +6 -2
  16. package/dist/Components/Avatar/composables/useAvatar.d.ts +1 -1
  17. package/dist/Components/BaseField/BaseField.js +5 -0
  18. package/dist/Components/BaseField/BaseField.vue.d.ts +15 -0
  19. package/dist/Components/BaseField/BaseField.vue_vue_type_script_setup_true_lang.js +41 -0
  20. package/dist/Components/BaseField/BaseFieldLabel.js +5 -0
  21. package/dist/Components/{OtpField/OtpFieldLabel.vue.d.ts → BaseField/BaseFieldLabel.vue.d.ts} +2 -2
  22. package/dist/Components/{OtpField/OtpFieldLabel.vue_vue_type_script_setup_true_lang.js → BaseField/BaseFieldLabel.vue_vue_type_script_setup_true_lang.js} +2 -2
  23. package/dist/Components/BaseField/baseField.types.d.ts +222 -0
  24. package/dist/Components/BaseField/composables/useBaseField.d.ts +55 -0
  25. package/dist/Components/BaseField/composables/useBaseField.js +131 -0
  26. package/dist/Components/BaseField/index.d.ts +4 -0
  27. package/dist/Components/BaseField/index.js +3 -0
  28. package/dist/Components/Button/composables/useButton.d.ts +1 -1
  29. package/dist/Components/Checkbox/composables/useCheckbox.d.ts +1 -1
  30. package/dist/Components/Checkbox/composables/useCheckbox.js +1 -1
  31. package/dist/Components/Chip/Chip.vue.d.ts +1 -1
  32. package/dist/Components/Chip/composables/useChip.d.ts +1 -1
  33. package/dist/Components/Drawer/Drawer.vue.d.ts +2 -2
  34. package/dist/Components/Drawer/composables/useDrawer.d.ts +1 -1
  35. package/dist/Components/FormControl/composables/useFormControl.d.ts +11 -2
  36. package/dist/Components/FormControl/composables/useFormControl.js +57 -53
  37. package/dist/Components/FormControl/index.d.ts +1 -1
  38. package/dist/Components/FormField/composables/useFormField.d.ts +5 -1
  39. package/dist/Components/FormField/composables/useFormField.js +1 -1
  40. package/dist/Components/ListItem/ListItem.vue.d.ts +1 -1
  41. package/dist/Components/ListItem/composables/useListItem.d.ts +1 -1
  42. package/dist/Components/Listbox/Listbox.vue.d.ts +3 -3
  43. package/dist/Components/Listbox/Listbox.vue_vue_type_script_setup_true_lang.js +2 -1
  44. package/dist/Components/Listbox/composables/useListbox.d.ts +10 -1
  45. package/dist/Components/Listbox/composables/useListbox.js +20 -20
  46. package/dist/Components/Listbox/index.d.ts +1 -0
  47. package/dist/Components/Listbox/listbox.types.d.ts +6 -0
  48. package/dist/Components/Menu/Menu.vue.d.ts +2 -2
  49. package/dist/Components/Modal/Modal.vue.d.ts +2 -2
  50. package/dist/Components/Modal/composables/useModal.d.ts +1 -1
  51. package/dist/Components/NumberField/NumberField.vue.d.ts +2 -2
  52. package/dist/Components/NumberField/composables/useNumberField.d.ts +2 -2
  53. package/dist/Components/NumberField/composables/useNumberField.js +4 -1
  54. package/dist/Components/OtpField/OtpField.vue.d.ts +3 -3
  55. package/dist/Components/OtpField/OtpField.vue_vue_type_script_setup_true_lang.js +34 -52
  56. package/dist/Components/OtpField/composables/useOtpField.d.ts +40 -213
  57. package/dist/Components/OtpField/composables/useOtpField.js +92 -150
  58. package/dist/Components/OtpField/otpField.types.d.ts +10 -180
  59. package/dist/Components/PasswordField/composables/usePasswordField.d.ts +2 -2
  60. package/dist/Components/PasswordField/composables/usePasswordField.js +4 -1
  61. package/dist/Components/Radio/composables/useRadio.d.ts +1 -1
  62. package/dist/Components/Radio/composables/useRadio.js +1 -1
  63. package/dist/Components/Select/Select.vue.d.ts +4 -4
  64. package/dist/Components/Select/composables/useSelect.d.ts +3 -2
  65. package/dist/Components/Select/composables/useSelect.js +6 -2
  66. package/dist/Components/Slider/Slider.js +5 -0
  67. package/dist/Components/Slider/Slider.vue.d.ts +25 -0
  68. package/dist/Components/Slider/Slider.vue_vue_type_script_setup_true_lang.js +113 -0
  69. package/dist/Components/Slider/composables/useSlider.d.ts +482 -0
  70. package/dist/Components/Slider/composables/useSlider.js +287 -0
  71. package/dist/Components/Slider/index.d.ts +4 -0
  72. package/dist/Components/Slider/index.js +3 -0
  73. package/dist/Components/Slider/slider.types.d.ts +169 -0
  74. package/dist/Components/Snackbar/Snackbar.vue.d.ts +2 -2
  75. package/dist/Components/Switch/composables/useSwitch.d.ts +1 -1
  76. package/dist/Components/Switch/composables/useSwitch.js +1 -1
  77. package/dist/Components/Tabs/Tabs.vue.d.ts +2 -2
  78. package/dist/Components/TextField/composables/useTextField.d.ts +2 -2
  79. package/dist/Components/TextField/composables/useTextField.js +1 -1
  80. package/dist/Components/Textarea/composables/useTextarea.d.ts +2 -2
  81. package/dist/Components/Textarea/composables/useTextarea.js +1 -0
  82. package/dist/Utils/index.d.ts +3 -3
  83. package/dist/Utils/index.js +5 -2
  84. package/dist/augments.d.ts +29 -17
  85. package/dist/index.d.ts +5 -1
  86. package/dist/index.js +59 -55
  87. package/docs/README.md +56 -0
  88. package/docs/components/Alert.md +96 -0
  89. package/docs/components/Autocomplete.md +198 -0
  90. package/docs/components/Avatar.md +60 -0
  91. package/docs/components/Badge.md +47 -0
  92. package/docs/components/BaseField.md +126 -0
  93. package/docs/components/BridgeUIProvider.md +151 -0
  94. package/docs/components/Button.md +93 -0
  95. package/docs/components/Card.md +287 -0
  96. package/docs/components/Checkbox.md +87 -0
  97. package/docs/components/Divider.md +56 -0
  98. package/docs/components/Drawer.md +137 -0
  99. package/docs/components/FormControl.md +66 -0
  100. package/docs/components/FormField.md +71 -0
  101. package/docs/components/I18n.md +125 -0
  102. package/docs/components/Icon.md +88 -0
  103. package/docs/components/Label.md +31 -0
  104. package/docs/components/Link.md +71 -0
  105. package/docs/components/List.md +167 -0
  106. package/docs/components/Menu.md +97 -0
  107. package/docs/components/Modal.md +154 -0
  108. package/docs/components/NumberField.md +80 -0
  109. package/docs/components/OtpField.md +133 -0
  110. package/docs/components/PasswordField.md +82 -0
  111. package/docs/components/Progress.md +68 -0
  112. package/docs/components/Radio.md +91 -0
  113. package/docs/components/Select.md +181 -0
  114. package/docs/components/Skeleton.md +38 -0
  115. package/docs/components/Slider.md +140 -0
  116. package/docs/components/Snackbar.md +99 -0
  117. package/docs/components/Spinner.md +61 -0
  118. package/docs/components/Switch.md +72 -0
  119. package/docs/components/Tabs.md +207 -0
  120. package/docs/components/TextField.md +72 -0
  121. package/docs/components/Textarea.md +80 -0
  122. package/docs/components/Tooltip.md +125 -0
  123. package/docs/components/useBreakpoint.md +100 -0
  124. package/docs/components/useDialogAction.md +97 -0
  125. package/docs/components/useDrawerAction.md +75 -0
  126. package/docs/components/useModalAction.md +75 -0
  127. package/docs/components/useSnackbarAction.md +85 -0
  128. package/docs/examples/i18n-dictionary.ts +48 -0
  129. package/docs/examples/i18n-vue-i18n.ts +34 -0
  130. package/docs/examples/icon-fontawesome.ts +112 -0
  131. package/docs/examples/icon-heroicons.ts +57 -0
  132. package/docs/examples/icon-lucide.ts +57 -0
  133. package/docs/examples/icon-phosphor.ts +57 -0
  134. package/docs/examples/icon-tabler.ts +57 -0
  135. package/package.json +12 -5
  136. package/dist/Components/OtpField/OtpFieldLabel.js +0 -5
@@ -0,0 +1,60 @@
1
+ # Avatar
2
+
3
+ Displays a user image, initials fallback, or icon.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { Avatar } from "@bridge-ui/vue/Components/Avatar";
9
+ ```
10
+
11
+ ## Examples
12
+
13
+ ### Usage
14
+
15
+ ```vue
16
+ <Avatar fallback="JD" />
17
+
18
+ <Avatar :icon="User" color="primary" />
19
+
20
+ <Avatar alt="Jane Doe" :src="avatarSrc" />
21
+ ```
22
+
23
+ ### Classes
24
+
25
+ ```vue
26
+ <Avatar
27
+ fallback="JP"
28
+ :classes="{
29
+ root: 'ring-2 ring-info-500',
30
+ fallback: 'font-bold tracking-widest',
31
+ }"
32
+ />
33
+ ```
34
+
35
+ ### Fallback slot
36
+
37
+ ```vue
38
+ <Avatar>
39
+ <template #fallback>
40
+ <span class="text-xs font-semibold">Slot</span>
41
+ </template>
42
+ </Avatar>
43
+ ```
44
+
45
+ ## Props
46
+
47
+ | Prop | Type | Default | Description |
48
+ | ---------- | --------------- | --------- | -------------------------------------------------------- |
49
+ | `alt` | `string` | — | The alt text for the avatar image. |
50
+ | `classes` | `AvatarClasses` | — | The classes to apply to the avatar. |
51
+ | `color` | `AvatarColor` | "primary" | The color to apply to the avatar fallback. |
52
+ | `fallback` | `string` | — | The fallback text to display when no image is available. |
53
+ | `icon` | `LucideIcon` | — | The icon to display as fallback. |
54
+ | `rounded` | `AvatarRounded` | "full" | The roundedness of the avatar. |
55
+ | `size` | `AvatarSize` | "md" | The size of the avatar. |
56
+ | `src` | `string` | — | The source URL for the avatar image. |
57
+
58
+ ## Related components
59
+
60
+ Badge
@@ -0,0 +1,47 @@
1
+ # Badge
2
+
3
+ Small label for counts, status, or tags.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { Badge } from "@bridge-ui/vue/Components/Badge";
9
+ ```
10
+
11
+ ## Examples
12
+
13
+ ### Usage
14
+
15
+ ```vue
16
+ <Badge>New</Badge>
17
+
18
+ <Badge density="mini">3</Badge>
19
+
20
+ <Badge variant="flat" color="success">
21
+ Active
22
+ </Badge>
23
+ ```
24
+
25
+ ### Custom classes
26
+
27
+ ```vue
28
+ <Badge color="primary" class="tracking-widest uppercase shadow-md">
29
+ Styled
30
+ </Badge>
31
+ ```
32
+
33
+ ## Props
34
+
35
+ | Prop | Type | Default | Description |
36
+ | --------- | -------------- | --------- | ---------------------------------- |
37
+ | `classes` | `BadgeClasses` | — | The classes to apply to the badge. |
38
+ | `color` | `BadgeColor` | "primary" | The color to apply to the badge. |
39
+ | `density` | `BadgeDensity` | "default" | The density of the badge. |
40
+ | `full` | `boolean` | `false` | Whether the badge is full width. |
41
+ | `rounded` | `BadgeRounded` | "md" | The roundedness of the badge. |
42
+ | `size` | `BadgeSize` | "sm" | The size of the badge. |
43
+ | `variant` | `BadgeVariant` | "flat" | The variant of the badge. |
44
+
45
+ ## Related components
46
+
47
+ Button
@@ -0,0 +1,126 @@
1
+ # BaseField
2
+
3
+ > Building block for composite field chrome. Prefer `OtpField` / `Slider` in apps; BaseField remains exported for advanced composition. Not a registry key — theme chrome via `tokens.baseField` on the public parent (e.g. `components.Slider.tokens.baseField`).
4
+
5
+ Shared vertical field chrome (label, corner, start/end slots, description,
6
+ error message) for OtpField, Slider, and similar controls.
7
+
8
+ Control tokens stay on the parent (`tokens.size`, `tokens.invalidated`, …).
9
+
10
+ ## Import
11
+
12
+ ```ts
13
+ import { BaseField, useBaseField } from "@bridge-ui/vue";
14
+ ```
15
+
16
+ ## Examples
17
+
18
+ ### Usage
19
+
20
+ Compose with `useBaseField` and pass the returned API as `:field`:
21
+
22
+ ```vue
23
+ <script setup lang="ts">
24
+ import { BaseField, useBaseField } from "@bridge-ui/vue";
25
+
26
+ const field = useBaseField(() => ({
27
+ label: "Verification code",
28
+ description: "Enter the code from your email.",
29
+ }));
30
+ </script>
31
+
32
+ <template>
33
+ <BaseField :field="field">
34
+ <input type="text" aria-label="Code" />
35
+ </BaseField>
36
+ </template>
37
+ ```
38
+
39
+ ### Label and corner
40
+
41
+ ```vue
42
+ <BaseField
43
+ :field="
44
+ useBaseField(() => ({
45
+ label: 'Amount',
46
+ corner: 'Optional',
47
+ }))
48
+ "
49
+ >
50
+ <input type="number" aria-label="Amount" />
51
+ </BaseField>
52
+ ```
53
+
54
+ ### Adornment slots
55
+
56
+ ```vue
57
+ <BaseField :field="useBaseField(() => ({ label: 'Code' }))">
58
+ <template #start>
59
+ <Lock aria-hidden="true" />
60
+ </template>
61
+
62
+ <input type="text" aria-label="Code" />
63
+
64
+ <template #end>
65
+ <button type="button">Resend</button>
66
+ </template>
67
+ </BaseField>
68
+ ```
69
+
70
+ ### Error state
71
+
72
+ ```vue
73
+ <BaseField
74
+ :field="
75
+ useBaseField(() => ({
76
+ error: true,
77
+ label: 'Email',
78
+ errorMessage: 'Invalid email address.',
79
+ }))
80
+ "
81
+ >
82
+ <input type="email" aria-label="Email" />
83
+ </BaseField>
84
+ ```
85
+
86
+ ### customProps
87
+
88
+ ```vue
89
+ <BaseField
90
+ :field="
91
+ useBaseField(() => ({
92
+ label: 'Email',
93
+ description: 'We never share your email.',
94
+ customProps: {
95
+ group: { 'data-testid': 'email-group' },
96
+ },
97
+ }))
98
+ "
99
+ >
100
+ <input type="email" aria-label="Email" />
101
+ </BaseField>
102
+ ```
103
+
104
+ ## Props
105
+
106
+ | Prop | Type | Default | Description |
107
+ | ------------------ | ---------------------- | ------- | -------------------------------------------------------------------------------------------- |
108
+ | `classes` | `BaseFieldClasses` | — | Classes for the field chrome and control group layout. |
109
+ | `controlId` | `string` | auto | Id for the control group and related labels. |
110
+ | `corner` | `string` | — | Secondary header text at the inline end. |
111
+ | `customProps` | `BaseFieldCustomProps` | — | Extra props for internal parts (`root`, `group`, `label`, …). |
112
+ | `description` | `string` | — | Helper text below the control group (hidden when invalid). |
113
+ | `disabled` | `boolean` | `false` | Disables the field control group. |
114
+ | `error` | `boolean` | `false` | Invalid styling on the label and control group. |
115
+ | `errorMessage` | `string` | — | Error message below the control group. |
116
+ | `field` | `UseBaseFieldReturn` | — | Pre-composed field chrome API from `useBaseField`. Used by `<BaseField :field="…" />`. |
117
+ | `hideErrorMessage` | `boolean` | `false` | Hides the error message row and reserved space. |
118
+ | `label` | `string` | — | Primary label above the control group. |
119
+ | `readonly` | `boolean` | `false` | Read-only field control group. |
120
+ | `required` | `boolean` | `false` | Shows a required asterisk on the label. |
121
+ | `size` | `BaseFieldSize` | `"md"` | Label typography and control group gap scale. |
122
+ | `slots` | `BaseFieldSlots` | — | `#label`, `#corner`, `#description`, `#errorMessage`, `#start`, `#end`, and default control. |
123
+
124
+ ## Related components
125
+
126
+ OtpField, Slider, Label
@@ -0,0 +1,151 @@
1
+ # BridgeUIProvider
2
+
3
+ Root provider for theme, locale, direction, breakpoints, icon/i18n adapters, and component registry defaults.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { BridgeUIProvider, useBridgeUI } from "@bridge-ui/vue";
9
+ ```
10
+
11
+ ## Examples
12
+
13
+ ### Usage
14
+
15
+ ```vue
16
+ <BridgeUIProvider
17
+ :global="{
18
+ theme: 'light',
19
+ locale: 'en-US',
20
+ breakpoints: {},
21
+ direction: 'ltr',
22
+ mobileBreakpoint: 'sm',
23
+ }"
24
+ >
25
+ <App />
26
+ </BridgeUIProvider>
27
+ ```
28
+
29
+ ### Icon adapter
30
+
31
+ Provide `global.icons` when using semantic icon names (`"clear"`, `"check"`, …). Optional `normalize` converts library-native values (e.g. Font Awesome definitions) so `<Icon :icon="faCoffee" />` works. Ready samples in `packages/vue/docs/examples/` (Lucide, Heroicons, Tabler, Phosphor, Font Awesome).
32
+
33
+ ```ts
34
+ import { createBridgeUI } from "@bridge-ui/vue";
35
+ import { createLucideIconAdapter } from "@examples/icon-lucide";
36
+
37
+ const icons = createLucideIconAdapter();
38
+
39
+ app.use(
40
+ createBridgeUI({
41
+ global: { icons },
42
+ }),
43
+ );
44
+ ```
45
+
46
+ ### i18n adapter
47
+
48
+ Provide `global.i18n` to translate Bridge chrome strings (`"Close"`, `"Hide password"`, …). Lookup is gettext-style (source English text is the key). Without an adapter, the source string is used. `setLocale` updates Bridge `locale` and calls optional `i18n.setLocale` (vue-i18n / i18next / dictionary). Persistence (localStorage, backend) stays in the app. Ready samples in `packages/vue/docs/examples/` (dictionary, vue-i18n). See [I18n](./I18n.md).
49
+
50
+ ```ts
51
+ import { createBridgeUI } from "@bridge-ui/vue";
52
+ import { createDictionaryI18nAdapter } from "@examples/i18n-dictionary";
53
+
54
+ const i18n = createDictionaryI18nAdapter();
55
+
56
+ app.use(
57
+ createBridgeUI({
58
+ global: { i18n },
59
+ }),
60
+ );
61
+ ```
62
+
63
+ ### Form density defaults
64
+
65
+ Set `global.formDefaults` to apply shared `size` / `rounded` to form controls (TextField, Select, Checkbox, Slider, OtpField, …). Does not affect Button, Progress, Modal, etc.
66
+
67
+ Merge order: instance props → `components.{Name}.defaultProps` → `formDefaults` → library defaults.
68
+
69
+ Radio and Switch receive `size` only — their `rounded` stays shape-driven (`full`) unless overridden per component.
70
+
71
+ ```ts
72
+ import { createBridgeUI } from "@bridge-ui/vue";
73
+
74
+ app.use(
75
+ createBridgeUI({
76
+ global: {
77
+ formDefaults: { size: "lg", rounded: "md" },
78
+ },
79
+ }),
80
+ );
81
+ ```
82
+
83
+ ### Nested chrome tokens
84
+
85
+ Building blocks (`FormField`, `FormControl`, `BaseField`, `Listbox`) are not registry keys. Theme chrome under the public parent:
86
+
87
+ ```ts
88
+ app.use(
89
+ createBridgeUI({
90
+ components: {
91
+ Slider: {
92
+ tokens: {
93
+ baseField: {
94
+ size: { md: { text: "text-base", group: "gap-3" } },
95
+ },
96
+ },
97
+ },
98
+ Checkbox: {
99
+ tokens: {
100
+ formControl: {
101
+ invalidated: {
102
+ errorMessage: "text-error-700 dark:text-error-300",
103
+ },
104
+ },
105
+ },
106
+ },
107
+ Select: {
108
+ tokens: {
109
+ listbox: {
110
+ size: {
111
+ md: {
112
+ option: "px-3 py-2 text-sm",
113
+ check: "size-4",
114
+ message: "text-xs",
115
+ primary: "font-medium",
116
+ secondary: "text-xs opacity-70",
117
+ },
118
+ },
119
+ },
120
+ },
121
+ },
122
+ },
123
+ }),
124
+ );
125
+ ```
126
+
127
+ ### Runtime updates
128
+
129
+ ```ts
130
+ const { setLocale, setTheme, setDirection, setGlobal } = useBridgeUI()!;
131
+
132
+ setTheme("dark");
133
+ setLocale("pt-BR"); // also calls global.i18n.setLocale when present
134
+ setDirection("rtl");
135
+ setGlobal({ mobileBreakpoint: "md" });
136
+ ```
137
+
138
+ ## Props
139
+
140
+ | Prop | Type | Default | Description |
141
+ | ------------ | -------------------------- | ------- | -------------------------------------------------------------------------------------------------- |
142
+ | `components` | `BridgeUIComponentsConfig` | — | Per-component defaults |
143
+ | `global` | `Partial<BridgeUIGlobal>` | — | `theme`, `locale`, `direction`, `mobileBreakpoint`, `breakpoints`, `icons`, `i18n`, `formDefaults` |
144
+
145
+ App content is passed via the **default slot** (see Usage above).
146
+
147
+ **useBridgeUI():** `global`, `components`, `setGlobal`, `setComponents`, `setLocale`, `setTheme`, `setDirection`
148
+
149
+ ## Related components
150
+
151
+ All components
@@ -0,0 +1,93 @@
1
+ # Button
2
+
3
+ Primary action control. Renders as `button`, `a`, or `span` via the `as` prop.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { Button } from "@bridge-ui/vue/Components/Button";
9
+ ```
10
+
11
+ ## Examples
12
+
13
+ ### Usage
14
+
15
+ ```vue
16
+ <Button color="primary">Click me</Button>
17
+
18
+ <Button variant="outline" :start-icon="Plus">
19
+ With icon
20
+ </Button>
21
+
22
+ <Button as="a" href="https://example.com">
23
+ External link
24
+ </Button>
25
+ ```
26
+
27
+ ### Density
28
+
29
+ ```vue
30
+ <Button density="mini" :icon="Settings" aria-label="Settings" />
31
+ ```
32
+
33
+ ### States
34
+
35
+ ```vue
36
+ <Button loading>Loading</Button>
37
+ <Button disabled>Disabled</Button>
38
+ ```
39
+
40
+ ### Slots
41
+
42
+ ```vue
43
+ <Button>
44
+ <template #start>
45
+ <span class="text-xs opacity-80">◀</span>
46
+ </template>
47
+
48
+ With slots
49
+
50
+ <template #end>
51
+ <span class="text-xs opacity-80">▶</span>
52
+ </template>
53
+ </Button>
54
+ ```
55
+
56
+ ### customProps
57
+
58
+ ```vue
59
+ <Button
60
+ :icon="Plus"
61
+ :custom-props="{
62
+ startIcon: { 'aria-hidden': true },
63
+ root: { id: 'add-btn', type: 'button' },
64
+ }"
65
+ >
66
+ Add item
67
+ </Button>
68
+ ```
69
+
70
+ ## Props
71
+
72
+ | Prop | Type | Default | Description |
73
+ | ------------- | --------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------- |
74
+ | `as` | `"a" \| "span" \| "button"` | "button" | The element to render as. |
75
+ | `classes` | `ButtonClasses` | — | The classes to apply to the button. |
76
+ | `color` | `ButtonColor` | "primary" | The color to apply to the button. |
77
+ | `customProps` | `ButtonCustomProps` | — | Extra props for internal parts (`startIcon`, `endIcon`, slot wrappers, etc.). Root HTML attributes stay on the component top level. |
78
+ | `density` | `ButtonDensity` | "default" | The density of the button. |
79
+ | `disabled` | `boolean` | `false` | Whether the button is disabled. |
80
+ | `endIcon` | `LucideIcon` | — | Icon at the **inline end** (physical right in `ltr`, physical left in `rtl`). |
81
+ | `full` | `boolean` | `false` | Whether the button is full width. |
82
+ | `href` | `string` | — | The href to apply to the button. |
83
+ | `icon` | `LucideIcon` | — | Icon for mini density (replaces label and start/end icons). |
84
+ | `loading` | `boolean` | `false` | Whether the button is loading. |
85
+ | `rounded` | `ButtonRounded` | "md" | The roundedness of the button. |
86
+ | `size` | `ButtonSize` | "md" | The size of the button. |
87
+ | `startIcon` | `LucideIcon` | — | Icon at the **inline start** (physical left in `ltr`, physical right in `rtl`). |
88
+ | `text` | `string` | — | Label text when the default slot is not used. |
89
+ | `variant` | `ButtonVariant` | "solid" | The variant of the button. |
90
+
91
+ ## Related components
92
+
93
+ Link, Icon