@nuxt/ui 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/.nuxt/ui/accordion.ts +25 -4
  2. package/.nuxt/ui/alert.ts +52 -31
  3. package/.nuxt/ui/avatar-group.ts +24 -3
  4. package/.nuxt/ui/avatar.ts +26 -5
  5. package/.nuxt/ui/badge.ts +56 -35
  6. package/.nuxt/ui/breadcrumb.ts +28 -7
  7. package/.nuxt/ui/button-group.ts +23 -2
  8. package/.nuxt/ui/button.ts +66 -45
  9. package/.nuxt/ui/calendar.ts +39 -18
  10. package/.nuxt/ui/card.ts +28 -7
  11. package/.nuxt/ui/carousel.ts +29 -8
  12. package/.nuxt/ui/checkbox-group.ts +82 -0
  13. package/.nuxt/ui/checkbox.ts +163 -29
  14. package/.nuxt/ui/chip.ts +31 -10
  15. package/.nuxt/ui/collapsible.ts +23 -2
  16. package/.nuxt/ui/color-picker.ts +26 -5
  17. package/.nuxt/ui/command-palette.ts +37 -16
  18. package/.nuxt/ui/container.ts +23 -2
  19. package/.nuxt/ui/context-menu.ts +56 -35
  20. package/.nuxt/ui/drawer.ts +33 -12
  21. package/.nuxt/ui/dropdown-menu.ts +57 -36
  22. package/.nuxt/ui/form-field.ts +29 -8
  23. package/.nuxt/ui/form.ts +23 -2
  24. package/.nuxt/ui/index.ts +1 -0
  25. package/.nuxt/ui/input-menu.ts +65 -44
  26. package/.nuxt/ui/input-number.ts +43 -22
  27. package/.nuxt/ui/input.ts +46 -25
  28. package/.nuxt/ui/kbd.ts +27 -6
  29. package/.nuxt/ui/link.ts +26 -5
  30. package/.nuxt/ui/modal.ts +28 -7
  31. package/.nuxt/ui/navigation-menu.ts +102 -83
  32. package/.nuxt/ui/pagination.ts +23 -2
  33. package/.nuxt/ui/pin-input.ts +43 -22
  34. package/.nuxt/ui/popover.ts +25 -4
  35. package/.nuxt/ui/progress.ts +40 -19
  36. package/.nuxt/ui/radio-group.ts +273 -37
  37. package/.nuxt/ui/select-menu.ts +59 -35
  38. package/.nuxt/ui/select.ts +55 -34
  39. package/.nuxt/ui/separator.ts +31 -10
  40. package/.nuxt/ui/skeleton.ts +24 -3
  41. package/.nuxt/ui/slideover.ts +27 -6
  42. package/.nuxt/ui/slider.ts +39 -18
  43. package/.nuxt/ui/stepper.ts +41 -20
  44. package/.nuxt/ui/switch.ts +43 -22
  45. package/.nuxt/ui/table.ts +38 -17
  46. package/.nuxt/ui/tabs.ts +55 -34
  47. package/.nuxt/ui/textarea.ts +63 -37
  48. package/.nuxt/ui/toast.ts +47 -26
  49. package/.nuxt/ui/toaster.ts +23 -2
  50. package/.nuxt/ui/tooltip.ts +25 -4
  51. package/.nuxt/ui/tree.ts +41 -20
  52. package/.nuxt/ui.css +56 -12
  53. package/README.md +11 -0
  54. package/cli/templates.mjs +18 -17
  55. package/dist/module.json +5 -5
  56. package/dist/module.mjs +11 -7
  57. package/dist/runtime/components/Accordion.vue +36 -93
  58. package/dist/runtime/components/Accordion.vue.d.ts +91 -0
  59. package/dist/runtime/components/Alert.vue +37 -100
  60. package/dist/runtime/components/Alert.vue.d.ts +96 -0
  61. package/dist/runtime/components/App.vue +28 -34
  62. package/dist/runtime/components/App.vue.d.ts +24 -0
  63. package/dist/runtime/components/Avatar.vue +42 -75
  64. package/dist/runtime/components/Avatar.vue.d.ts +60 -0
  65. package/dist/runtime/components/AvatarGroup.vue +40 -77
  66. package/dist/runtime/components/AvatarGroup.vue.d.ts +40 -0
  67. package/dist/runtime/components/Badge.vue +33 -62
  68. package/dist/runtime/components/Badge.vue.d.ts +62 -0
  69. package/dist/runtime/components/Breadcrumb.vue +37 -90
  70. package/dist/runtime/components/Breadcrumb.vue.d.ts +82 -0
  71. package/dist/runtime/components/Button.vue +95 -104
  72. package/dist/runtime/components/Button.vue.d.ts +73 -0
  73. package/dist/runtime/components/ButtonGroup.vue +20 -46
  74. package/dist/runtime/components/ButtonGroup.vue.d.ts +55 -0
  75. package/dist/runtime/components/Calendar.vue +67 -150
  76. package/dist/runtime/components/Calendar.vue.d.ts +107 -0
  77. package/dist/runtime/components/Card.vue +18 -40
  78. package/dist/runtime/components/Card.vue.d.ts +38 -0
  79. package/dist/runtime/components/Carousel.vue +112 -234
  80. package/dist/runtime/components/Carousel.vue.d.ts +120 -0
  81. package/dist/runtime/components/Checkbox.vue +52 -93
  82. package/dist/runtime/components/Checkbox.vue.d.ts +76 -0
  83. package/dist/runtime/components/CheckboxGroup.vue +121 -0
  84. package/dist/runtime/components/CheckboxGroup.vue.d.ts +75 -0
  85. package/dist/runtime/components/Chip.vue +26 -69
  86. package/dist/runtime/components/Chip.vue.d.ts +71 -0
  87. package/dist/runtime/components/Collapsible.vue +22 -41
  88. package/dist/runtime/components/Collapsible.vue.d.ts +50 -0
  89. package/dist/runtime/components/ColorPicker.vue +111 -197
  90. package/dist/runtime/components/ColorPicker.vue.d.ts +63 -0
  91. package/dist/runtime/components/CommandPalette.vue +96 -237
  92. package/dist/runtime/components/CommandPalette.vue.d.ts +173 -0
  93. package/dist/runtime/components/Container.vue +15 -28
  94. package/dist/runtime/components/Container.vue.d.ts +27 -0
  95. package/dist/runtime/components/ContextMenu.vue +34 -133
  96. package/dist/runtime/components/ContextMenu.vue.d.ts +127 -0
  97. package/dist/runtime/components/ContextMenuContent.vue +73 -81
  98. package/dist/runtime/components/ContextMenuContent.vue.d.ts +105 -0
  99. package/dist/runtime/components/Drawer.vue +49 -83
  100. package/dist/runtime/components/Drawer.vue.d.ts +88 -0
  101. package/dist/runtime/components/DropdownMenu.vue +39 -142
  102. package/dist/runtime/components/DropdownMenu.vue.d.ts +141 -0
  103. package/dist/runtime/components/DropdownMenuContent.vue +78 -88
  104. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +55 -0
  105. package/dist/runtime/components/Form.vue +135 -220
  106. package/dist/runtime/components/Form.vue.d.ts +66 -0
  107. package/dist/runtime/components/FormField.vue +35 -77
  108. package/dist/runtime/components/FormField.vue.d.ts +70 -0
  109. package/dist/runtime/components/Icon.vue +12 -19
  110. package/dist/runtime/components/Icon.vue.d.ts +17 -0
  111. package/dist/runtime/components/Input.vue +82 -140
  112. package/dist/runtime/components/Input.vue.d.ts +91 -0
  113. package/dist/runtime/components/InputMenu.vue +185 -332
  114. package/dist/runtime/components/InputMenu.vue.d.ts +312 -0
  115. package/dist/runtime/components/InputNumber.vue +71 -133
  116. package/dist/runtime/components/InputNumber.vue.d.ts +193 -0
  117. package/dist/runtime/components/Kbd.vue +20 -46
  118. package/dist/runtime/components/Kbd.vue.d.ts +55 -0
  119. package/dist/runtime/components/Link.vue +98 -176
  120. package/dist/runtime/components/Link.vue.d.ts +124 -0
  121. package/dist/runtime/components/LinkBase.vue +33 -42
  122. package/dist/runtime/components/LinkBase.vue.d.ts +48 -0
  123. package/dist/runtime/components/Modal.vue +53 -116
  124. package/dist/runtime/components/Modal.vue.d.ts +109 -0
  125. package/dist/runtime/components/NavigationMenu.vue +77 -209
  126. package/dist/runtime/components/NavigationMenu.vue.d.ts +159 -0
  127. package/dist/runtime/components/OverlayProvider.vue +14 -18
  128. package/dist/runtime/components/OverlayProvider.vue.d.ts +2 -0
  129. package/dist/runtime/components/Pagination.vue +46 -140
  130. package/dist/runtime/components/Pagination.vue.d.ts +143 -0
  131. package/dist/runtime/components/PinInput.vue +61 -78
  132. package/dist/runtime/components/PinInput.vue.d.ts +68 -0
  133. package/dist/runtime/components/Popover.vue +47 -84
  134. package/dist/runtime/components/Popover.vue.d.ts +80 -0
  135. package/dist/runtime/components/Progress.vue +70 -131
  136. package/dist/runtime/components/Progress.vue.d.ts +97 -0
  137. package/dist/runtime/components/RadioGroup.vue +70 -132
  138. package/dist/runtime/components/RadioGroup.vue.d.ts +88 -0
  139. package/dist/runtime/components/Select.vue +110 -224
  140. package/dist/runtime/components/Select.vue.d.ts +139 -0
  141. package/dist/runtime/components/SelectMenu.vue +161 -310
  142. package/dist/runtime/components/SelectMenu.vue.d.ts +184 -0
  143. package/dist/runtime/components/Separator.vue +29 -71
  144. package/dist/runtime/components/Separator.vue.d.ts +75 -0
  145. package/dist/runtime/components/Skeleton.vue +21 -23
  146. package/dist/runtime/components/Skeleton.vue.d.ts +26 -0
  147. package/dist/runtime/components/Slideover.vue +53 -120
  148. package/dist/runtime/components/Slideover.vue.d.ts +111 -0
  149. package/dist/runtime/components/Slider.vue +46 -84
  150. package/dist/runtime/components/Slider.vue.d.ts +71 -0
  151. package/dist/runtime/components/Stepper.vue +45 -115
  152. package/dist/runtime/components/Stepper.vue.d.ts +89 -0
  153. package/dist/runtime/components/Switch.vue +45 -93
  154. package/dist/runtime/components/Switch.vue.d.ts +73 -0
  155. package/dist/runtime/components/Table.vue +163 -267
  156. package/dist/runtime/components/Table.vue.d.ts +183 -0
  157. package/dist/runtime/components/Tabs.vue +41 -107
  158. package/dist/runtime/components/Tabs.vue.d.ts +104 -0
  159. package/dist/runtime/components/Textarea.vue +113 -158
  160. package/dist/runtime/components/Textarea.vue.d.ts +95 -0
  161. package/dist/runtime/components/Toast.vue +49 -110
  162. package/dist/runtime/components/Toast.vue.d.ts +95 -0
  163. package/dist/runtime/components/Toaster.vue +70 -107
  164. package/dist/runtime/components/Toaster.vue.d.ts +63 -0
  165. package/dist/runtime/components/Tooltip.vue +38 -65
  166. package/dist/runtime/components/Tooltip.vue.d.ts +65 -0
  167. package/dist/runtime/components/Tree.vue +59 -166
  168. package/dist/runtime/components/Tree.vue.d.ts +128 -0
  169. package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
  170. package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
  171. package/dist/runtime/composables/useButtonGroup.d.ts +2 -2
  172. package/dist/runtime/composables/useFormField.d.ts +2 -2
  173. package/dist/runtime/composables/useOverlay.d.ts +14 -7
  174. package/dist/runtime/composables/useOverlay.js +14 -6
  175. package/dist/runtime/composables/usePortal.d.ts +6 -0
  176. package/dist/runtime/composables/usePortal.js +17 -0
  177. package/dist/runtime/index.css +1 -1
  178. package/dist/runtime/inertia/components/Link.vue +146 -0
  179. package/dist/runtime/inertia/components/Link.vue.d.ts +92 -0
  180. package/dist/runtime/inertia/stubs.d.ts +43 -0
  181. package/dist/runtime/inertia/stubs.js +82 -0
  182. package/dist/runtime/locale/bg.d.ts +3 -0
  183. package/dist/runtime/locale/bg.js +54 -0
  184. package/dist/runtime/locale/index.d.ts +5 -1
  185. package/dist/runtime/locale/index.js +5 -1
  186. package/dist/runtime/locale/kk.d.ts +3 -0
  187. package/dist/runtime/locale/kk.js +54 -0
  188. package/dist/runtime/locale/tj.d.ts +3 -0
  189. package/dist/runtime/locale/tj.js +54 -0
  190. package/dist/runtime/locale/ug_cn.d.ts +3 -0
  191. package/dist/runtime/locale/ug_cn.js +55 -0
  192. package/dist/runtime/types/form.d.ts +4 -1
  193. package/dist/runtime/types/index.d.ts +1 -0
  194. package/dist/runtime/types/index.js +1 -0
  195. package/dist/runtime/types/utils.d.ts +47 -7
  196. package/dist/runtime/utils/link.d.ts +3 -3
  197. package/dist/runtime/utils/link.js +1 -0
  198. package/dist/runtime/utils/tv.js +2 -2
  199. package/dist/runtime/vue/components/Icon.vue +7 -8
  200. package/dist/runtime/vue/components/Icon.vue.d.ts +14 -0
  201. package/dist/runtime/vue/components/Link.vue +118 -202
  202. package/dist/runtime/vue/components/Link.vue.d.ts +124 -0
  203. package/dist/runtime/vue/stubs.d.ts +2 -2
  204. package/dist/shared/{ui.BkNUP964.mjs → ui.D7lOOabO.mjs} +621 -362
  205. package/dist/types.d.mts +3 -5
  206. package/dist/unplugin.d.mts +4 -0
  207. package/dist/unplugin.mjs +25 -4
  208. package/dist/vite.mjs +1 -1
  209. package/package.json +94 -53
  210. package/dist/module.cjs +0 -62
  211. package/dist/module.d.cts +0 -45
  212. package/dist/module.d.ts +0 -45
  213. package/dist/shared/ui.BL-XB3u1.cjs +0 -3555
  214. package/dist/types.d.ts +0 -7
  215. package/dist/unplugin.cjs +0 -232
  216. package/dist/unplugin.d.cts +0 -62
  217. package/dist/unplugin.d.ts +0 -62
  218. package/dist/vite.cjs +0 -23
  219. package/dist/vite.d.cts +0 -15
  220. package/dist/vite.d.ts +0 -15
@@ -1,190 +1,132 @@
1
- <script lang="ts">
2
- import type { VariantProps } from 'tailwind-variants'
3
- import type { AppConfig } from '@nuxt/schema'
4
- import _appConfig from '#build/app.config'
5
- import theme from '#build/ui/textarea'
6
- import { tv } from '../utils/tv'
7
- import type { PartialString } from '../types/utils'
8
-
9
- const appConfigTextarea = _appConfig as AppConfig & { ui: { textarea: Partial<typeof theme> } }
10
-
11
- const textarea = tv({ extend: tv(theme), ...(appConfigTextarea.ui?.textarea || {}) })
12
-
13
- type TextareaVariants = VariantProps<typeof textarea>
14
-
15
- export interface TextareaProps {
16
- /**
17
- * The element or component this component should render as.
18
- * @defaultValue 'div'
19
- */
20
- as?: any
21
- id?: string
22
- name?: string
23
- /** The placeholder text when the textarea is empty. */
24
- placeholder?: string
25
- /**
26
- * @defaultValue 'primary'
27
- */
28
- color?: TextareaVariants['color']
29
- /**
30
- * @defaultValue 'outline'
31
- */
32
- variant?: TextareaVariants['variant']
33
- /**
34
- * @defaultValue 'md'
35
- */
36
- size?: TextareaVariants['size']
37
- required?: boolean
38
- autofocus?: boolean
39
- autofocusDelay?: number
40
- disabled?: boolean
41
- class?: any
42
- rows?: number
43
- maxrows?: number
44
- autoresize?: boolean
45
- /** Highlight the ring color like a focus state. */
46
- highlight?: boolean
47
- ui?: PartialString<typeof textarea.slots>
48
- }
49
-
50
- export interface TextareaEmits {
51
- (e: 'update:modelValue', payload: string | number): void
52
- (e: 'blur', event: FocusEvent): void
53
- (e: 'change', event: Event): void
54
- }
55
-
56
- export interface TextareaSlots {
57
- default(props?: {}): any
58
- }
1
+ <script>
2
+ import theme from "#build/ui/textarea";
59
3
  </script>
60
4
 
61
- <script setup lang="ts">
62
- import { ref, computed, onMounted, nextTick, watch } from 'vue'
63
- import { Primitive } from 'reka-ui'
64
- import { useFormField } from '../composables/useFormField'
65
- import { looseToNumber } from '../utils'
66
-
67
- defineOptions({ inheritAttrs: false })
68
-
69
- const props = withDefaults(defineProps<TextareaProps>(), {
70
- rows: 3,
71
- maxrows: 0,
72
- autofocusDelay: 0
73
- })
74
- defineSlots<TextareaSlots>()
75
- const emits = defineEmits<TextareaEmits>()
76
-
77
- const [modelValue, modelModifiers] = defineModel<string | number | null>()
78
-
79
- const { emitFormFocus, emitFormBlur, emitFormInput, emitFormChange, size, color, id, name, highlight, disabled, ariaAttrs } = useFormField<TextareaProps>(props, { deferInputValidation: true })
80
-
81
- const ui = computed(() => textarea({
5
+ <script setup>
6
+ import { ref, computed, onMounted, nextTick, watch } from "vue";
7
+ import { Primitive } from "reka-ui";
8
+ import { useAppConfig } from "#imports";
9
+ import { useComponentIcons } from "../composables/useComponentIcons";
10
+ import { useFormField } from "../composables/useFormField";
11
+ import { looseToNumber } from "../utils";
12
+ import { tv } from "../utils/tv";
13
+ defineOptions({ inheritAttrs: false });
14
+ const props = defineProps({
15
+ as: { type: null, required: false },
16
+ id: { type: String, required: false },
17
+ name: { type: String, required: false },
18
+ placeholder: { type: String, required: false },
19
+ color: { type: null, required: false },
20
+ variant: { type: null, required: false },
21
+ size: { type: null, required: false },
22
+ required: { type: Boolean, required: false },
23
+ autofocus: { type: Boolean, required: false },
24
+ autofocusDelay: { type: Number, required: false, default: 0 },
25
+ autoresize: { type: Boolean, required: false },
26
+ autoresizeDelay: { type: Number, required: false, default: 0 },
27
+ disabled: { type: Boolean, required: false },
28
+ class: { type: null, required: false },
29
+ rows: { type: Number, required: false, default: 3 },
30
+ maxrows: { type: Number, required: false, default: 0 },
31
+ highlight: { type: Boolean, required: false },
32
+ ui: { type: null, required: false },
33
+ icon: { type: String, required: false },
34
+ avatar: { type: Object, required: false },
35
+ leading: { type: Boolean, required: false },
36
+ leadingIcon: { type: String, required: false },
37
+ trailing: { type: Boolean, required: false },
38
+ trailingIcon: { type: String, required: false },
39
+ loading: { type: Boolean, required: false },
40
+ loadingIcon: { type: String, required: false }
41
+ });
42
+ const slots = defineSlots();
43
+ const emits = defineEmits(["update:modelValue", "blur", "change"]);
44
+ const [modelValue, modelModifiers] = defineModel({ type: [String, Number, null] });
45
+ const appConfig = useAppConfig();
46
+ const { emitFormFocus, emitFormBlur, emitFormInput, emitFormChange, size, color, id, name, highlight, disabled, ariaAttrs } = useFormField(props, { deferInputValidation: true });
47
+ const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props);
48
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.textarea || {} })({
82
49
  color: color.value,
83
50
  variant: props.variant,
84
51
  size: size?.value,
85
- highlight: highlight.value
86
- }))
87
-
88
- const textareaRef = ref<HTMLTextAreaElement | null>(null)
89
-
90
- function autoFocus() {
91
- if (props.autofocus) {
92
- textareaRef.value?.focus()
93
- }
94
- }
95
-
96
- // Custom function to handle the v-model properties
97
- function updateInput(value: string | null) {
52
+ loading: props.loading,
53
+ highlight: highlight.value,
54
+ autoresize: props.autoresize,
55
+ leading: isLeading.value || !!props.avatar || !!slots.leading,
56
+ trailing: isTrailing.value || !!slots.trailing
57
+ }));
58
+ const textareaRef = ref(null);
59
+ function updateInput(value) {
98
60
  if (modelModifiers.trim) {
99
- value = value?.trim() ?? null
61
+ value = value?.trim() ?? null;
100
62
  }
101
-
102
63
  if (modelModifiers.number) {
103
- value = looseToNumber(value)
64
+ value = looseToNumber(value);
104
65
  }
105
-
106
66
  if (modelModifiers.nullify) {
107
- value ||= null
67
+ value ||= null;
108
68
  }
109
-
110
- modelValue.value = value
111
- emitFormInput()
69
+ modelValue.value = value;
70
+ emitFormInput();
112
71
  }
113
-
114
- function onInput(event: Event) {
115
- autoResize()
116
-
72
+ function onInput(event) {
73
+ autoResize();
117
74
  if (!modelModifiers.lazy) {
118
- updateInput((event.target as HTMLInputElement).value)
75
+ updateInput(event.target.value);
119
76
  }
120
77
  }
121
-
122
- function onChange(event: Event) {
123
- const value = (event.target as HTMLInputElement).value
124
-
78
+ function onChange(event) {
79
+ const value = event.target.value;
125
80
  if (modelModifiers.lazy) {
126
- updateInput(value)
81
+ updateInput(value);
127
82
  }
128
-
129
- // Update trimmed textarea so that it has same behavior as native textarea https://github.com/vuejs/core/blob/5ea8a8a4fab4e19a71e123e4d27d051f5e927172/packages/runtime-dom/src/directives/vModel.ts#L63
130
83
  if (modelModifiers.trim) {
131
- (event.target as HTMLInputElement).value = value.trim()
84
+ event.target.value = value.trim();
132
85
  }
133
-
134
- emitFormChange()
135
- emits('change', event)
86
+ emitFormChange();
87
+ emits("change", event);
136
88
  }
137
-
138
- function onBlur(event: FocusEvent) {
139
- emitFormBlur()
140
- emits('blur', event)
89
+ function onBlur(event) {
90
+ emitFormBlur();
91
+ emits("blur", event);
92
+ }
93
+ function autoFocus() {
94
+ if (props.autofocus) {
95
+ textareaRef.value?.focus();
96
+ }
141
97
  }
142
-
143
- onMounted(() => {
144
- setTimeout(() => {
145
- autoFocus()
146
- }, props.autofocusDelay)
147
- })
148
-
149
98
  function autoResize() {
150
- if (props.autoresize) {
151
- if (!textareaRef.value) {
152
- return
153
- }
154
-
155
- textareaRef.value.rows = props.rows
156
- const overflow = textareaRef.value.style.overflow
157
- textareaRef.value.style.overflow = 'hidden'
158
-
159
- const styles = window.getComputedStyle(textareaRef.value)
160
- const paddingTop = Number.parseInt(styles.paddingTop)
161
- const paddingBottom = Number.parseInt(styles.paddingBottom)
162
- const padding = paddingTop + paddingBottom
163
- const lineHeight = Number.parseInt(styles.lineHeight)
164
- const { scrollHeight } = textareaRef.value
165
- const newRows = (scrollHeight - padding) / lineHeight
166
-
99
+ if (props.autoresize && textareaRef.value) {
100
+ textareaRef.value.rows = props.rows;
101
+ const overflow = textareaRef.value.style.overflow;
102
+ textareaRef.value.style.overflow = "hidden";
103
+ const styles = window.getComputedStyle(textareaRef.value);
104
+ const paddingTop = Number.parseInt(styles.paddingTop);
105
+ const paddingBottom = Number.parseInt(styles.paddingBottom);
106
+ const padding = paddingTop + paddingBottom;
107
+ const lineHeight = Number.parseInt(styles.lineHeight);
108
+ const { scrollHeight } = textareaRef.value;
109
+ const newRows = (scrollHeight - padding) / lineHeight;
167
110
  if (newRows > props.rows) {
168
- textareaRef.value.rows = props.maxrows ? Math.min(newRows, props.maxrows) : newRows
111
+ textareaRef.value.rows = props.maxrows ? Math.min(newRows, props.maxrows) : newRows;
169
112
  }
170
-
171
- textareaRef.value.style.overflow = overflow
113
+ textareaRef.value.style.overflow = overflow;
172
114
  }
173
115
  }
174
-
175
116
  watch(modelValue, () => {
176
- nextTick(autoResize)
177
- })
178
-
179
- defineExpose({
180
- textareaRef
181
- })
182
-
117
+ nextTick(autoResize);
118
+ });
183
119
  onMounted(() => {
184
120
  setTimeout(() => {
185
- autoResize()
186
- }, 100)
187
- })
121
+ autoFocus();
122
+ }, props.autofocusDelay);
123
+ setTimeout(() => {
124
+ autoResize();
125
+ }, props.autoresizeDelay);
126
+ });
127
+ defineExpose({
128
+ textareaRef
129
+ });
188
130
  </script>
189
131
 
190
132
  <template>
@@ -207,5 +149,18 @@ onMounted(() => {
207
149
  />
208
150
 
209
151
  <slot />
152
+
153
+ <span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
154
+ <slot name="leading">
155
+ <UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
156
+ <UAvatar v-else-if="!!avatar" :size="props.ui?.leadingAvatarSize || ui.leadingAvatarSize()" v-bind="avatar" :class="ui.leadingAvatar({ class: props.ui?.leadingAvatar })" />
157
+ </slot>
158
+ </span>
159
+
160
+ <span v-if="isTrailing || !!slots.trailing" :class="ui.trailing({ class: props.ui?.trailing })">
161
+ <slot name="trailing">
162
+ <UIcon v-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" />
163
+ </slot>
164
+ </span>
210
165
  </Primitive>
211
166
  </template>
@@ -0,0 +1,95 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import theme from '#build/ui/textarea';
3
+ import type { UseComponentIconsProps } from '../composables/useComponentIcons';
4
+ import type { ComponentConfig } from '../types/utils';
5
+ type Textarea = ComponentConfig<typeof theme, AppConfig, 'textarea'>;
6
+ export interface TextareaProps extends UseComponentIconsProps {
7
+ /**
8
+ * The element or component this component should render as.
9
+ * @defaultValue 'div'
10
+ */
11
+ as?: any;
12
+ id?: string;
13
+ name?: string;
14
+ /** The placeholder text when the textarea is empty. */
15
+ placeholder?: string;
16
+ /**
17
+ * @defaultValue 'primary'
18
+ */
19
+ color?: Textarea['variants']['color'];
20
+ /**
21
+ * @defaultValue 'outline'
22
+ */
23
+ variant?: Textarea['variants']['variant'];
24
+ /**
25
+ * @defaultValue 'md'
26
+ */
27
+ size?: Textarea['variants']['size'];
28
+ required?: boolean;
29
+ autofocus?: boolean;
30
+ autofocusDelay?: number;
31
+ autoresize?: boolean;
32
+ autoresizeDelay?: number;
33
+ disabled?: boolean;
34
+ class?: any;
35
+ rows?: number;
36
+ maxrows?: number;
37
+ /** Highlight the ring color like a focus state. */
38
+ highlight?: boolean;
39
+ ui?: Textarea['slots'];
40
+ }
41
+ export interface TextareaEmits {
42
+ (e: 'update:modelValue', payload: string | number): void;
43
+ (e: 'blur', event: FocusEvent): void;
44
+ (e: 'change', event: Event): void;
45
+ }
46
+ export interface TextareaSlots {
47
+ leading(props?: {}): any;
48
+ default(props?: {}): any;
49
+ trailing(props?: {}): any;
50
+ }
51
+ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<{
52
+ modelValue?: string | number | null;
53
+ } & TextareaProps>, {
54
+ rows: number;
55
+ maxrows: number;
56
+ autofocusDelay: number;
57
+ autoresizeDelay: number;
58
+ }>>, {
59
+ textareaRef: import("vue").Ref<HTMLTextAreaElement | null, HTMLTextAreaElement | null>;
60
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<{
61
+ modelValue?: string | number | null;
62
+ } & TextareaProps>, {
63
+ rows: number;
64
+ maxrows: number;
65
+ autofocusDelay: number;
66
+ autoresizeDelay: number;
67
+ }>>> & Readonly<{}>, {
68
+ autofocusDelay: number;
69
+ autoresizeDelay: number;
70
+ rows: number;
71
+ maxrows: number;
72
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>, Readonly<TextareaSlots> & TextareaSlots>;
73
+ export default _default;
74
+ type __VLS_WithDefaults<P, D> = {
75
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
76
+ default: D[K];
77
+ }> : P[K];
78
+ };
79
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
80
+ type __VLS_TypePropsToOption<T> = {
81
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
82
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
83
+ } : {
84
+ type: import('vue').PropType<T[K]>;
85
+ required: true;
86
+ };
87
+ };
88
+ type __VLS_WithTemplateSlots<T, S> = T & {
89
+ new (): {
90
+ $slots: S;
91
+ };
92
+ };
93
+ type __VLS_PrettifyLocal<T> = {
94
+ [K in keyof T]: T[K];
95
+ } & {};
@@ -1,119 +1,58 @@
1
- <script lang="ts">
2
- import type { VariantProps } from 'tailwind-variants'
3
- import type { ToastRootProps, ToastRootEmits } from 'reka-ui'
4
- import type { AppConfig } from '@nuxt/schema'
5
- import _appConfig from '#build/app.config'
6
- import theme from '#build/ui/toast'
7
- import { tv } from '../utils/tv'
8
- import type { AvatarProps, ButtonProps } from '../types'
9
- import type { StringOrVNode } from '../types/utils'
10
-
11
- const appConfigToast = _appConfig as AppConfig & { ui: { toast: Partial<typeof theme> } }
12
-
13
- const toast = tv({ extend: tv(theme), ...(appConfigToast.ui?.toast || {}) })
14
-
15
- type ToastVariants = VariantProps<typeof toast>
16
-
17
- export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open' | 'type' | 'duration'> {
18
- /**
19
- * The element or component this component should render as.
20
- * @defaultValue 'li'
21
- */
22
- as?: any
23
- title?: StringOrVNode
24
- description?: StringOrVNode
25
- /**
26
- * @IconifyIcon
27
- */
28
- icon?: string
29
- avatar?: AvatarProps
30
- /**
31
- * @defaultValue 'primary'
32
- */
33
- color?: ToastVariants['color']
34
- /**
35
- * The orientation between the content and the actions.
36
- * @defaultValue 'vertical'
37
- */
38
- orientation?: ToastVariants['orientation']
39
- /**
40
- * Display a list of actions:
41
- * - under the title and description when orientation is `vertical`
42
- * - next to the close button when orientation is `horizontal`
43
- * `{ size: 'xs' }`{lang="ts-type"}
44
- */
45
- actions?: ButtonProps[]
46
- /**
47
- * Display a close button to dismiss the toast.
48
- * `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
49
- * @defaultValue true
50
- */
51
- close?: boolean | Partial<ButtonProps>
52
- /**
53
- * The icon displayed in the close button.
54
- * @defaultValue appConfig.ui.icons.close
55
- * @IconifyIcon
56
- */
57
- closeIcon?: string
58
- class?: any
59
- ui?: Partial<typeof toast.slots>
60
- }
61
-
62
- export interface ToastEmits extends ToastRootEmits {}
63
-
64
- export interface ToastSlots {
65
- leading(props?: {}): any
66
- title(props?: {}): any
67
- description(props?: {}): any
68
- actions(props?: {}): any
69
- close(props: { ui: ReturnType<typeof toast> }): any
70
- }
1
+ <script>
2
+ import theme from "#build/ui/toast";
71
3
  </script>
72
4
 
73
- <script setup lang="ts">
74
- import { ref, computed, onMounted } from 'vue'
75
- import { ToastRoot, ToastTitle, ToastDescription, ToastAction, ToastClose, useForwardPropsEmits } from 'reka-ui'
76
- import { reactivePick } from '@vueuse/core'
77
- import { useAppConfig } from '#imports'
78
- import { useLocale } from '../composables/useLocale'
79
- import UIcon from './Icon.vue'
80
- import UAvatar from './Avatar.vue'
81
- import UButton from './Button.vue'
82
-
83
- const props = withDefaults(defineProps<ToastProps>(), {
84
- close: true,
85
- orientation: 'vertical'
86
- })
87
- const emits = defineEmits<ToastEmits>()
88
- const slots = defineSlots<ToastSlots>()
89
-
90
- const { t } = useLocale()
91
- const appConfig = useAppConfig()
92
-
93
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen', 'open', 'duration', 'type'), emits)
94
-
95
- const ui = computed(() => toast({
5
+ <script setup>
6
+ import { ref, computed, onMounted } from "vue";
7
+ import { ToastRoot, ToastTitle, ToastDescription, ToastAction, ToastClose, useForwardPropsEmits } from "reka-ui";
8
+ import { reactivePick } from "@vueuse/core";
9
+ import { useAppConfig } from "#imports";
10
+ import { useLocale } from "../composables/useLocale";
11
+ import { tv } from "../utils/tv";
12
+ import UIcon from "./Icon.vue";
13
+ import UAvatar from "./Avatar.vue";
14
+ import UButton from "./Button.vue";
15
+ const props = defineProps({
16
+ as: { type: null, required: false },
17
+ title: { type: [String, Object, Function], required: false },
18
+ description: { type: [String, Object, Function], required: false },
19
+ icon: { type: String, required: false },
20
+ avatar: { type: Object, required: false },
21
+ color: { type: null, required: false },
22
+ orientation: { type: null, required: false, default: "vertical" },
23
+ actions: { type: Array, required: false },
24
+ close: { type: [Boolean, Object], required: false, default: true },
25
+ closeIcon: { type: String, required: false },
26
+ class: { type: null, required: false },
27
+ ui: { type: null, required: false },
28
+ defaultOpen: { type: Boolean, required: false },
29
+ open: { type: Boolean, required: false },
30
+ type: { type: String, required: false },
31
+ duration: { type: Number, required: false }
32
+ });
33
+ const emits = defineEmits(["escapeKeyDown", "pause", "resume", "swipeStart", "swipeMove", "swipeCancel", "swipeEnd", "update:open"]);
34
+ const slots = defineSlots();
35
+ const { t } = useLocale();
36
+ const appConfig = useAppConfig();
37
+ const rootProps = useForwardPropsEmits(reactivePick(props, "as", "defaultOpen", "open", "duration", "type"), emits);
38
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.toast || {} })({
96
39
  color: props.color,
97
40
  orientation: props.orientation,
98
41
  title: !!props.title || !!slots.title
99
- }))
100
-
101
- const el = ref()
102
- const height = ref(0)
103
-
42
+ }));
43
+ const el = ref();
44
+ const height = ref(0);
104
45
  onMounted(() => {
105
46
  if (!el.value) {
106
- return
47
+ return;
107
48
  }
108
-
109
49
  setTimeout(() => {
110
- height.value = el.value.$el.getBoundingClientRect()?.height
111
- }, 0)
112
- })
113
-
50
+ height.value = el.value.$el.getBoundingClientRect()?.height;
51
+ }, 0);
52
+ });
114
53
  defineExpose({
115
54
  height
116
- })
55
+ });
117
56
  </script>
118
57
 
119
58
  <template>
@@ -126,7 +65,7 @@ defineExpose({
126
65
  :style="{ '--height': height }"
127
66
  >
128
67
  <slot name="leading">
129
- <UAvatar v-if="avatar" :size="((props.ui?.avatarSize || ui.avatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="ui.avatar({ class: props.ui?.avatar })" />
68
+ <UAvatar v-if="avatar" :size="props.ui?.avatarSize || ui.avatarSize()" v-bind="avatar" :class="ui.avatar({ class: props.ui?.avatar })" />
130
69
  <UIcon v-else-if="icon" :name="icon" :class="ui.icon({ class: props.ui?.icon })" />
131
70
  </slot>
132
71
 
@@ -150,7 +89,7 @@ defineExpose({
150
89
  </slot>
151
90
  </ToastDescription>
152
91
 
153
- <div v-if="orientation === 'vertical' && actions?.length" :class="ui.actions({ class: props.ui?.actions })">
92
+ <div v-if="orientation === 'vertical' && (actions?.length || !!slots.actions)" :class="ui.actions({ class: props.ui?.actions })">
154
93
  <slot name="actions">
155
94
  <ToastAction v-for="(action, index) in actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
156
95
  <UButton size="xs" :color="color" v-bind="action" />
@@ -159,8 +98,8 @@ defineExpose({
159
98
  </div>
160
99
  </div>
161
100
 
162
- <div v-if="(orientation === 'horizontal' && actions?.length) || close" :class="ui.actions({ class: props.ui?.actions, orientation: 'horizontal' })">
163
- <template v-if="orientation === 'horizontal' && actions?.length">
101
+ <div v-if="orientation === 'horizontal' && (actions?.length || !!slots.actions) || close" :class="ui.actions({ class: props.ui?.actions, orientation: 'horizontal' })">
102
+ <template v-if="orientation === 'horizontal' && (actions?.length || !!slots.actions)">
164
103
  <slot name="actions">
165
104
  <ToastAction v-for="(action, index) in actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
166
105
  <UButton size="xs" :color="color" v-bind="action" />
@@ -177,7 +116,7 @@ defineExpose({
177
116
  color="neutral"
178
117
  variant="link"
179
118
  :aria-label="t('toast.close')"
180
- v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
119
+ v-bind="typeof close === 'object' ? close : {}"
181
120
  :class="ui.close({ class: props.ui?.close })"
182
121
  @click.stop
183
122
  />