reka-ui 2.7.0 → 2.8.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 (272) hide show
  1. package/dist/Avatar/AvatarImage.cjs +4 -2
  2. package/dist/Avatar/AvatarImage.cjs.map +1 -1
  3. package/dist/Avatar/AvatarImage.js +4 -2
  4. package/dist/Avatar/AvatarImage.js.map +1 -1
  5. package/dist/Collection/Collection.cjs +6 -2
  6. package/dist/Collection/Collection.cjs.map +1 -1
  7. package/dist/Collection/Collection.js +6 -2
  8. package/dist/Collection/Collection.js.map +1 -1
  9. package/dist/Combobox/ComboboxContent.cjs +4 -0
  10. package/dist/Combobox/ComboboxContent.cjs.map +1 -1
  11. package/dist/Combobox/ComboboxContent.js +4 -0
  12. package/dist/Combobox/ComboboxContent.js.map +1 -1
  13. package/dist/Combobox/ComboboxContentImpl.cjs +46 -33
  14. package/dist/Combobox/ComboboxContentImpl.cjs.map +1 -1
  15. package/dist/Combobox/ComboboxContentImpl.js +47 -34
  16. package/dist/Combobox/ComboboxContentImpl.js.map +1 -1
  17. package/dist/ContextMenu/ContextMenuContent.cjs +4 -0
  18. package/dist/ContextMenu/ContextMenuContent.cjs.map +1 -1
  19. package/dist/ContextMenu/ContextMenuContent.js +4 -0
  20. package/dist/ContextMenu/ContextMenuContent.js.map +1 -1
  21. package/dist/ContextMenu/ContextMenuRadioGroup.cjs +1 -1
  22. package/dist/ContextMenu/ContextMenuRadioGroup.js +1 -1
  23. package/dist/ContextMenu/ContextMenuRadioItem.cjs +1 -1
  24. package/dist/ContextMenu/ContextMenuRadioItem.js +1 -1
  25. package/dist/ContextMenu/ContextMenuSubContent.cjs +4 -0
  26. package/dist/ContextMenu/ContextMenuSubContent.cjs.map +1 -1
  27. package/dist/ContextMenu/ContextMenuSubContent.js +4 -0
  28. package/dist/ContextMenu/ContextMenuSubContent.js.map +1 -1
  29. package/dist/DatePicker/DatePickerContent.cjs +4 -0
  30. package/dist/DatePicker/DatePickerContent.cjs.map +1 -1
  31. package/dist/DatePicker/DatePickerContent.js +4 -0
  32. package/dist/DatePicker/DatePickerContent.js.map +1 -1
  33. package/dist/DatePicker/DatePickerRoot.cjs +7 -6
  34. package/dist/DatePicker/DatePickerRoot.cjs.map +1 -1
  35. package/dist/DatePicker/DatePickerRoot.js +7 -6
  36. package/dist/DatePicker/DatePickerRoot.js.map +1 -1
  37. package/dist/DateRangePicker/DateRangePickerContent.cjs +4 -0
  38. package/dist/DateRangePicker/DateRangePickerContent.cjs.map +1 -1
  39. package/dist/DateRangePicker/DateRangePickerContent.js +4 -0
  40. package/dist/DateRangePicker/DateRangePickerContent.js.map +1 -1
  41. package/dist/DateRangePicker/DateRangePickerRoot.cjs +7 -6
  42. package/dist/DateRangePicker/DateRangePickerRoot.cjs.map +1 -1
  43. package/dist/DateRangePicker/DateRangePickerRoot.js +7 -6
  44. package/dist/DateRangePicker/DateRangePickerRoot.js.map +1 -1
  45. package/dist/DropdownMenu/DropdownMenuContent.cjs +4 -0
  46. package/dist/DropdownMenu/DropdownMenuContent.cjs.map +1 -1
  47. package/dist/DropdownMenu/DropdownMenuContent.js +4 -0
  48. package/dist/DropdownMenu/DropdownMenuContent.js.map +1 -1
  49. package/dist/DropdownMenu/DropdownMenuRadioGroup.cjs +1 -1
  50. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -1
  51. package/dist/DropdownMenu/DropdownMenuRadioItem.cjs +1 -1
  52. package/dist/DropdownMenu/DropdownMenuRadioItem.js +1 -1
  53. package/dist/DropdownMenu/DropdownMenuSubContent.cjs +4 -0
  54. package/dist/DropdownMenu/DropdownMenuSubContent.cjs.map +1 -1
  55. package/dist/DropdownMenu/DropdownMenuSubContent.js +4 -0
  56. package/dist/DropdownMenu/DropdownMenuSubContent.js.map +1 -1
  57. package/dist/Editable/EditableInput.cjs +1 -1
  58. package/dist/Editable/EditableInput.cjs.map +1 -1
  59. package/dist/Editable/EditableInput.js +1 -1
  60. package/dist/Editable/EditableInput.js.map +1 -1
  61. package/dist/FocusScope/FocusScope.cjs +1 -1
  62. package/dist/FocusScope/FocusScope.cjs.map +1 -1
  63. package/dist/FocusScope/FocusScope.js +2 -2
  64. package/dist/FocusScope/FocusScope.js.map +1 -1
  65. package/dist/FocusScope/stack.cjs +0 -9
  66. package/dist/FocusScope/stack.cjs.map +1 -1
  67. package/dist/FocusScope/stack.js +1 -4
  68. package/dist/FocusScope/stack.js.map +1 -1
  69. package/dist/HoverCard/HoverCardContent.cjs +4 -0
  70. package/dist/HoverCard/HoverCardContent.cjs.map +1 -1
  71. package/dist/HoverCard/HoverCardContent.js +4 -0
  72. package/dist/HoverCard/HoverCardContent.js.map +1 -1
  73. package/dist/HoverCard/HoverCardContentImpl.cjs +4 -0
  74. package/dist/HoverCard/HoverCardContentImpl.cjs.map +1 -1
  75. package/dist/HoverCard/HoverCardContentImpl.js +4 -0
  76. package/dist/HoverCard/HoverCardContentImpl.js.map +1 -1
  77. package/dist/Listbox/ListboxRoot.cjs.map +1 -1
  78. package/dist/Listbox/ListboxRoot.js.map +1 -1
  79. package/dist/Menu/MenuContent.cjs +4 -0
  80. package/dist/Menu/MenuContent.cjs.map +1 -1
  81. package/dist/Menu/MenuContent.js +4 -0
  82. package/dist/Menu/MenuContent.js.map +1 -1
  83. package/dist/Menu/MenuContentImpl.cjs +4 -0
  84. package/dist/Menu/MenuContentImpl.cjs.map +1 -1
  85. package/dist/Menu/MenuContentImpl.js +4 -0
  86. package/dist/Menu/MenuContentImpl.js.map +1 -1
  87. package/dist/Menu/MenuRadioGroup.cjs +1 -1
  88. package/dist/Menu/MenuRadioGroup.cjs.map +1 -1
  89. package/dist/Menu/MenuRadioGroup.js +1 -1
  90. package/dist/Menu/MenuRadioGroup.js.map +1 -1
  91. package/dist/Menu/MenuRadioItem.cjs +1 -1
  92. package/dist/Menu/MenuRadioItem.cjs.map +1 -1
  93. package/dist/Menu/MenuRadioItem.js +1 -1
  94. package/dist/Menu/MenuRadioItem.js.map +1 -1
  95. package/dist/Menu/MenuRootContentModal.cjs +4 -0
  96. package/dist/Menu/MenuRootContentModal.cjs.map +1 -1
  97. package/dist/Menu/MenuRootContentModal.js +4 -0
  98. package/dist/Menu/MenuRootContentModal.js.map +1 -1
  99. package/dist/Menu/MenuRootContentNonModal.cjs +4 -0
  100. package/dist/Menu/MenuRootContentNonModal.cjs.map +1 -1
  101. package/dist/Menu/MenuRootContentNonModal.js +4 -0
  102. package/dist/Menu/MenuRootContentNonModal.js.map +1 -1
  103. package/dist/Menu/MenuSubContent.cjs +4 -0
  104. package/dist/Menu/MenuSubContent.cjs.map +1 -1
  105. package/dist/Menu/MenuSubContent.js +4 -0
  106. package/dist/Menu/MenuSubContent.js.map +1 -1
  107. package/dist/Menubar/MenubarContent.cjs +4 -0
  108. package/dist/Menubar/MenubarContent.cjs.map +1 -1
  109. package/dist/Menubar/MenubarContent.js +4 -0
  110. package/dist/Menubar/MenubarContent.js.map +1 -1
  111. package/dist/Menubar/MenubarRadioGroup.cjs +1 -1
  112. package/dist/Menubar/MenubarRadioGroup.js +1 -1
  113. package/dist/Menubar/MenubarRadioItem.cjs +1 -1
  114. package/dist/Menubar/MenubarRadioItem.js +1 -1
  115. package/dist/Menubar/MenubarSubContent.cjs +4 -0
  116. package/dist/Menubar/MenubarSubContent.cjs.map +1 -1
  117. package/dist/Menubar/MenubarSubContent.js +4 -0
  118. package/dist/Menubar/MenubarSubContent.js.map +1 -1
  119. package/dist/NavigationMenu/NavigationMenuContent.cjs +1 -1
  120. package/dist/NavigationMenu/NavigationMenuContent.js +1 -1
  121. package/dist/NavigationMenu/NavigationMenuContentImpl.cjs +1 -1
  122. package/dist/NavigationMenu/NavigationMenuContentImpl.js +1 -1
  123. package/dist/NavigationMenu/NavigationMenuItem.cjs +1 -1
  124. package/dist/NavigationMenu/NavigationMenuItem.js +1 -1
  125. package/dist/NavigationMenu/NavigationMenuRoot.cjs +7 -5
  126. package/dist/NavigationMenu/NavigationMenuRoot.cjs.map +1 -1
  127. package/dist/NavigationMenu/NavigationMenuRoot.js +8 -6
  128. package/dist/NavigationMenu/NavigationMenuRoot.js.map +1 -1
  129. package/dist/NavigationMenu/NavigationMenuTrigger.cjs +1 -1
  130. package/dist/NavigationMenu/NavigationMenuTrigger.js +1 -1
  131. package/dist/NavigationMenu/NavigationMenuViewport.cjs +1 -1
  132. package/dist/NavigationMenu/NavigationMenuViewport.js +1 -1
  133. package/dist/NumberField/NumberFieldRoot.cjs +6 -1
  134. package/dist/NumberField/NumberFieldRoot.cjs.map +1 -1
  135. package/dist/NumberField/NumberFieldRoot.js +6 -1
  136. package/dist/NumberField/NumberFieldRoot.js.map +1 -1
  137. package/dist/PinInput/PinInputInput.cjs +15 -11
  138. package/dist/PinInput/PinInputInput.cjs.map +1 -1
  139. package/dist/PinInput/PinInputInput.js +15 -11
  140. package/dist/PinInput/PinInputInput.js.map +1 -1
  141. package/dist/Popover/PopoverContent.cjs +4 -0
  142. package/dist/Popover/PopoverContent.cjs.map +1 -1
  143. package/dist/Popover/PopoverContent.js +4 -0
  144. package/dist/Popover/PopoverContent.js.map +1 -1
  145. package/dist/Popover/PopoverContentImpl.cjs +4 -0
  146. package/dist/Popover/PopoverContentImpl.cjs.map +1 -1
  147. package/dist/Popover/PopoverContentImpl.js +4 -0
  148. package/dist/Popover/PopoverContentImpl.js.map +1 -1
  149. package/dist/Popover/PopoverContentModal.cjs +4 -0
  150. package/dist/Popover/PopoverContentModal.cjs.map +1 -1
  151. package/dist/Popover/PopoverContentModal.js +4 -0
  152. package/dist/Popover/PopoverContentModal.js.map +1 -1
  153. package/dist/Popover/PopoverContentNonModal.cjs +4 -0
  154. package/dist/Popover/PopoverContentNonModal.cjs.map +1 -1
  155. package/dist/Popover/PopoverContentNonModal.js +4 -0
  156. package/dist/Popover/PopoverContentNonModal.js.map +1 -1
  157. package/dist/Popper/PopperContent.cjs +10 -2
  158. package/dist/Popper/PopperContent.cjs.map +1 -1
  159. package/dist/Popper/PopperContent.js +10 -2
  160. package/dist/Popper/PopperContent.js.map +1 -1
  161. package/dist/ScrollArea/ScrollAreaRoot.cjs.map +1 -1
  162. package/dist/ScrollArea/ScrollAreaRoot.js.map +1 -1
  163. package/dist/ScrollArea/ScrollAreaScrollbar.cjs +9 -2
  164. package/dist/ScrollArea/ScrollAreaScrollbar.cjs.map +1 -1
  165. package/dist/ScrollArea/ScrollAreaScrollbar.js +9 -2
  166. package/dist/ScrollArea/ScrollAreaScrollbar.js.map +1 -1
  167. package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.cjs +132 -0
  168. package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.cjs.map +1 -0
  169. package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.js +126 -0
  170. package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.js.map +1 -0
  171. package/dist/Select/SelectContent.cjs +4 -0
  172. package/dist/Select/SelectContent.cjs.map +1 -1
  173. package/dist/Select/SelectContent.js +4 -0
  174. package/dist/Select/SelectContent.js.map +1 -1
  175. package/dist/Select/SelectContentImpl.cjs +4 -0
  176. package/dist/Select/SelectContentImpl.cjs.map +1 -1
  177. package/dist/Select/SelectContentImpl.js +4 -0
  178. package/dist/Select/SelectContentImpl.js.map +1 -1
  179. package/dist/Select/SelectPopperPosition.cjs +4 -0
  180. package/dist/Select/SelectPopperPosition.cjs.map +1 -1
  181. package/dist/Select/SelectPopperPosition.js +4 -0
  182. package/dist/Select/SelectPopperPosition.js.map +1 -1
  183. package/dist/Tabs/TabsContent.cjs +4 -0
  184. package/dist/Tabs/TabsContent.cjs.map +1 -1
  185. package/dist/Tabs/TabsContent.js +5 -1
  186. package/dist/Tabs/TabsContent.js.map +1 -1
  187. package/dist/Tabs/TabsRoot.cjs +11 -1
  188. package/dist/Tabs/TabsRoot.cjs.map +1 -1
  189. package/dist/Tabs/TabsRoot.js +12 -2
  190. package/dist/Tabs/TabsRoot.js.map +1 -1
  191. package/dist/Tabs/TabsTrigger.cjs +1 -1
  192. package/dist/Tabs/TabsTrigger.cjs.map +1 -1
  193. package/dist/Tabs/TabsTrigger.js +1 -1
  194. package/dist/Tabs/TabsTrigger.js.map +1 -1
  195. package/dist/TimeField/TimeFieldInput.cjs +3 -1
  196. package/dist/TimeField/TimeFieldInput.cjs.map +1 -1
  197. package/dist/TimeField/TimeFieldInput.js +3 -1
  198. package/dist/TimeField/TimeFieldInput.js.map +1 -1
  199. package/dist/TimeField/TimeFieldRoot.cjs +24 -2
  200. package/dist/TimeField/TimeFieldRoot.cjs.map +1 -1
  201. package/dist/TimeField/TimeFieldRoot.js +24 -2
  202. package/dist/TimeField/TimeFieldRoot.js.map +1 -1
  203. package/dist/constant.d.cts.map +1 -1
  204. package/dist/date/comparators.cjs +14 -2
  205. package/dist/date/comparators.cjs.map +1 -1
  206. package/dist/date/comparators.js +14 -2
  207. package/dist/date/comparators.js.map +1 -1
  208. package/dist/date/parser.cjs +1 -0
  209. package/dist/date/parser.cjs.map +1 -1
  210. package/dist/date/parser.js +1 -0
  211. package/dist/date/parser.js.map +1 -1
  212. package/dist/date/useDateField.cjs +41 -20
  213. package/dist/date/useDateField.cjs.map +1 -1
  214. package/dist/date/useDateField.js +41 -20
  215. package/dist/date/useDateField.js.map +1 -1
  216. package/dist/index.cjs +3 -1
  217. package/dist/index.d.cts +1122 -1085
  218. package/dist/index.d.cts.map +1 -1
  219. package/dist/index.d.ts +1115 -1078
  220. package/dist/index.d.ts.map +1 -1
  221. package/dist/index.js +3 -2
  222. package/dist/index2.d.cts.map +1 -1
  223. package/dist/index2.d.ts.map +1 -1
  224. package/dist/shared/useDateFormatter.cjs +1 -1
  225. package/dist/shared/useDateFormatter.cjs.map +1 -1
  226. package/dist/shared/useDateFormatter.js +1 -1
  227. package/dist/shared/useDateFormatter.js.map +1 -1
  228. package/dist/shared/useGraceArea.cjs +1 -1
  229. package/dist/shared/useGraceArea.cjs.map +1 -1
  230. package/dist/shared/useGraceArea.js +1 -1
  231. package/dist/shared/useGraceArea.js.map +1 -1
  232. package/package.json +5 -5
  233. package/src/Avatar/AvatarImage.vue +2 -1
  234. package/src/Collection/Collection.ts +3 -2
  235. package/src/Combobox/ComboboxContentImpl.vue +39 -32
  236. package/src/Combobox/ComboboxRoot.vue +1 -1
  237. package/src/DatePicker/DatePickerRoot.vue +6 -6
  238. package/src/DatePicker/index.ts +4 -4
  239. package/src/DateRangePicker/DateRangePickerRoot.vue +6 -6
  240. package/src/DateRangePicker/index.ts +4 -4
  241. package/src/Editable/EditableInput.vue +1 -1
  242. package/src/FocusScope/FocusScope.vue +2 -2
  243. package/src/Listbox/ListboxFilter.vue +1 -1
  244. package/src/Listbox/ListboxRoot.vue +2 -1
  245. package/src/Menu/MenuRadioGroup.vue +5 -4
  246. package/src/Menu/MenuRadioItem.vue +2 -1
  247. package/src/NavigationMenu/NavigationMenuRoot.vue +10 -6
  248. package/src/NumberField/NumberFieldRoot.vue +6 -1
  249. package/src/PinInput/PinInputInput.vue +25 -18
  250. package/src/Popper/PopperContent.vue +15 -5
  251. package/src/Rating/RatingItem.vue +52 -0
  252. package/src/Rating/RatingItemIndicator.vue +60 -0
  253. package/src/Rating/RatingRoot.vue +113 -0
  254. package/src/Rating/index.ts +3 -0
  255. package/src/ScrollArea/ScrollAreaRoot.vue +2 -1
  256. package/src/ScrollArea/ScrollAreaScrollbar.vue +9 -0
  257. package/src/ScrollArea/ScrollAreaScrollbarGlimpse.vue +145 -0
  258. package/src/ScrollArea/index.ts +4 -0
  259. package/src/ScrollArea/types.ts +1 -1
  260. package/src/Tabs/TabsContent.vue +6 -1
  261. package/src/Tabs/TabsRoot.vue +14 -1
  262. package/src/Tabs/TabsTrigger.vue +1 -1
  263. package/src/TimeField/TimeFieldInput.vue +6 -1
  264. package/src/TimeField/TimeFieldRoot.vue +25 -2
  265. package/src/Tree/TreeRoot.vue +2 -2
  266. package/src/date/comparators.ts +15 -2
  267. package/src/index.ts +1 -0
  268. package/src/shared/date/parser.ts +10 -0
  269. package/src/shared/date/useDateField.ts +70 -21
  270. package/src/shared/index.ts +1 -1
  271. package/src/shared/useDateFormatter.ts +2 -2
  272. package/src/shared/useGraceArea.ts +1 -1
@@ -7,7 +7,7 @@ import { Primitive } from '..'
7
7
  import { injectListboxRootContext } from './ListboxRoot.vue'
8
8
 
9
9
  export interface ListboxFilterProps extends PrimitiveProps {
10
- /** The controlled value of the filter. Can be binded with with v-model. */
10
+ /** The controlled value of the filter. Can be binded with v-model. */
11
11
  modelValue?: string
12
12
  /** Focus on element when mounted. */
13
13
  autoFocus?: boolean
@@ -40,7 +40,7 @@ export const [injectListboxRootContext, provideListboxRootContext]
40
40
  = createContext<ListboxRootContext<AcceptableValue>>('ListboxRoot')
41
41
 
42
42
  export interface ListboxRootProps<T = AcceptableValue> extends PrimitiveProps, FormFieldProps {
43
- /** The controlled value of the listbox. Can be binded with with `v-model`. */
43
+ /** The controlled value of the listbox. Can be binded with `v-model`. */
44
44
  modelValue?: T | Array<T>
45
45
  /** The value of the listbox when initially rendered. Use when you do not need to control the state of the Listbox */
46
46
  defaultValue?: T | Array<T>
@@ -173,6 +173,7 @@ function changeHighlight(el: HTMLElement, scrollIntoView = true) {
173
173
 
174
174
  function highlightItem(value: T) {
175
175
  if (isVirtual.value) {
176
+ // @ts-expect-error known type issue https://github.com/vueuse/vueuse/issues/4610
176
177
  virtualHighlightHook.trigger(value)
177
178
  }
178
179
  else {
@@ -1,21 +1,22 @@
1
1
  <script lang="ts">
2
2
  import type { Ref } from 'vue'
3
3
  import type { MenuGroupProps } from './MenuGroup.vue'
4
+ import type { AcceptableValue } from '@/shared/types'
4
5
  import { createContext, useForwardProps } from '@/shared'
5
6
 
6
7
  interface MenuRadioGroupContext {
7
- modelValue: Ref<string>
8
- onValueChange: (payload: string) => void
8
+ modelValue: Ref<AcceptableValue>
9
+ onValueChange: (payload: AcceptableValue) => void
9
10
  }
10
11
 
11
12
  export interface MenuRadioGroupProps extends MenuGroupProps {
12
13
  /** The value of the selected item in the group. */
13
- modelValue?: string
14
+ modelValue?: AcceptableValue
14
15
  }
15
16
 
16
17
  export type MenuRadioGroupEmits = {
17
18
  /** Event handler called when the value changes. */
18
- 'update:modelValue': [payload: string]
19
+ 'update:modelValue': [payload: AcceptableValue]
19
20
  }
20
21
 
21
22
  export const [injectMenuRadioGroupContext, provideMenuRadioGroupContext]
@@ -3,6 +3,7 @@ import type {
3
3
  MenuItemEmits,
4
4
  MenuItemProps,
5
5
  } from './MenuItem.vue'
6
+ import type { AcceptableValue } from '@/shared/types'
6
7
  import { reactiveOmit } from '@vueuse/shared'
7
8
  import { useForwardProps } from '@/shared'
8
9
 
@@ -10,7 +11,7 @@ export type MenuRadioItemEmits = MenuItemEmits
10
11
 
11
12
  export interface MenuRadioItemProps extends MenuItemProps {
12
13
  /** The unique value of the item. */
13
- value: string
14
+ value: AcceptableValue
14
15
  }
15
16
  </script>
16
17
 
@@ -5,6 +5,7 @@ import type { Direction, Orientation } from './utils'
5
5
  import type { PrimitiveProps } from '@/Primitive'
6
6
  import { useCollection } from '@/Collection'
7
7
  import { createContext, useDirection, useForwardExpose, useId } from '@/shared'
8
+ import { EVENT_ROOT_CONTENT_DISMISS } from './utils'
8
9
 
9
10
  export interface NavigationMenuRootProps extends PrimitiveProps {
10
11
  /** The controlled value of the menu item to activate. Can be used as `v-model`. */
@@ -91,7 +92,7 @@ export const [injectNavigationMenuContext, provideNavigationMenuContext]
91
92
  </script>
92
93
 
93
94
  <script setup lang="ts">
94
- import { refAutoReset, useDebounceFn, useVModel } from '@vueuse/core'
95
+ import { refAutoReset, useDebounceFn, useEventListener, useVModel } from '@vueuse/core'
95
96
  import {
96
97
  computed,
97
98
  ref,
@@ -164,6 +165,8 @@ watchEffect(() => {
164
165
  )
165
166
  })
166
167
 
168
+ useEventListener(rootNavigationMenu, EVENT_ROOT_CONTENT_DISMISS, onItemDismiss)
169
+
167
170
  provideNavigationMenuContext({
168
171
  isRootMenu: true,
169
172
  modelValue,
@@ -203,18 +206,19 @@ provideNavigationMenuContext({
203
206
  previousValue.value = modelValue.value
204
207
  modelValue.value = val
205
208
  },
206
- onItemDismiss: () => {
207
- previousValue.value = modelValue.value
208
- modelValue.value = ''
209
- },
209
+ onItemDismiss,
210
210
  })
211
+
212
+ function onItemDismiss() {
213
+ previousValue.value = modelValue.value
214
+ modelValue.value = ''
215
+ }
211
216
  </script>
212
217
 
213
218
  <template>
214
219
  <CollectionSlot>
215
220
  <Primitive
216
221
  :ref="forwardRef"
217
- aria-label="Main"
218
222
  :as="as"
219
223
  :as-child="asChild"
220
224
  :data-orientation="orientation"
@@ -17,6 +17,8 @@ export interface NumberFieldRootProps extends PrimitiveProps, FormFieldProps {
17
17
  step?: number
18
18
  /** When `false`, prevents the value from snapping to the nearest increment of the step value */
19
19
  stepSnapping?: boolean
20
+ /** When `true`, the input will be focused when the value changes. */
21
+ focusOnChange?: boolean
20
22
  /** Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. */
21
23
  formatOptions?: Intl.NumberFormatOptions
22
24
  /** The locale to use for formatting and currencies */
@@ -76,6 +78,7 @@ const props = withDefaults(defineProps<NumberFieldRootProps>(), {
76
78
  defaultValue: undefined,
77
79
  step: 1,
78
80
  stepSnapping: true,
81
+ focusOnChange: true,
79
82
  })
80
83
  const emits = defineEmits<NumberFieldRootEmits>()
81
84
  const { disabled, readonly, disableWheelChange, invertWheelChange, min, max, step, stepSnapping, formatOptions, id, locale: propLocale } = toRefs(props)
@@ -109,7 +112,9 @@ const isIncreaseDisabled = computed(() => (
109
112
  )
110
113
 
111
114
  function handleChangingValue(type: 'increase' | 'decrease', multiplier = 1) {
112
- inputEl.value?.focus()
115
+ if (props.focusOnChange) {
116
+ inputEl.value?.focus()
117
+ }
113
118
  if (props.disabled || props.readonly)
114
119
  return
115
120
  const currentInputValue = numberParser.parse(inputEl.value?.value ?? '')
@@ -50,11 +50,18 @@ function handleInput(event: InputEvent) {
50
50
  nextEl.focus()
51
51
  }
52
52
 
53
- function resetPlaceholder() {
54
- const target = currentElement.value as HTMLInputElement
53
+ function updatePlaceholder() {
55
54
  nextTick(() => {
56
- if (target && !target.value)
55
+ const target = currentElement.value as HTMLInputElement
56
+ if (!target) {
57
+ return
58
+ }
59
+ if (!target.value && target === getActiveElement()) {
60
+ target.placeholder = ''
61
+ }
62
+ else {
57
63
  target.placeholder = context.placeholder.value
64
+ }
58
65
  })
59
66
  }
60
67
 
@@ -93,21 +100,25 @@ function handleDelete(event: KeyboardEvent) {
93
100
  }
94
101
 
95
102
  function handleFocus(event: FocusEvent) {
103
+ // In OTP mode, inputs should be filled one by one without skipping middle inputs
104
+ if (context.otp.value) {
105
+ const firstEmptyInputIdx = inputElements.value.findIndex((_, idx) =>
106
+ context.currentModelValue.value[idx] === ''
107
+ || context.currentModelValue.value[idx] === undefined,
108
+ )
109
+ if (firstEmptyInputIdx !== -1 && firstEmptyInputIdx < props.index) {
110
+ inputElements.value[firstEmptyInputIdx].focus()
111
+ return
112
+ }
113
+ }
114
+
96
115
  const target = event.target as HTMLInputElement
97
116
  target.setSelectionRange(1, 1)
98
-
99
- if (!target.value)
100
- target.placeholder = ''
101
-
102
- // #2266, check again after DOM flushes
103
- setTimeout(() => {
104
- if (!target.value)
105
- target.placeholder = ''
106
- })
117
+ updatePlaceholder()
107
118
  }
108
119
 
109
120
  function handleBlur(event: FocusEvent) {
110
- resetPlaceholder()
121
+ updatePlaceholder()
111
122
  }
112
123
 
113
124
  function handlePaste(event: ClipboardEvent) {
@@ -168,11 +179,7 @@ function updateModelValueAt(index: number, value: string) {
168
179
  context.modelValue.value = removeTrailingEmptyStrings(tempModelValue)
169
180
  }
170
181
 
171
- watch(currentValue, () => {
172
- if (!currentValue.value) {
173
- resetPlaceholder()
174
- }
175
- })
182
+ watch(currentValue, updatePlaceholder)
176
183
 
177
184
  onMounted(() => {
178
185
  context.onInputElementChange(currentElement.value as HTMLInputElement)
@@ -20,6 +20,7 @@ export const PopperContentPropsDefaultValue = {
20
20
  alignOffset: 0,
21
21
  alignFlip: true,
22
22
  arrowPadding: 0,
23
+ hideShiftedArrow: true,
23
24
  avoidCollisions: true,
24
25
  collisionBoundary: () => [],
25
26
  collisionPadding: 0,
@@ -36,7 +37,7 @@ export interface PopperContentProps extends PrimitiveProps {
36
37
  * Will be reversed when collisions occur and avoidCollisions
37
38
  * is enabled.
38
39
  *
39
- * @defaultValue "top"
40
+ * @defaultValue "bottom"
40
41
  */
41
42
  side?: Side
42
43
 
@@ -112,6 +113,14 @@ export interface PopperContentProps extends PrimitiveProps {
112
113
  */
113
114
  arrowPadding?: number
114
115
 
116
+ /**
117
+ * When `true`, hides the arrow when it cannot be centered
118
+ * to the reference element.
119
+ *
120
+ * @defaultValue true
121
+ */
122
+ hideShiftedArrow?: boolean
123
+
115
124
  /**
116
125
  * The sticky behavior on the align axis. `partial` will keep the
117
126
  * content in the boundary as long as the trigger is at least partially
@@ -346,9 +355,10 @@ watchPostEffect(() => {
346
355
  emits('placed')
347
356
  })
348
357
 
349
- const cannotCenterArrow = computed(
350
- () => middlewareData.value.arrow?.centerOffset !== 0,
351
- )
358
+ const shouldHideArrow = computed(() => {
359
+ const cannotCenterArrow = middlewareData.value.arrow?.centerOffset !== 0
360
+ return props.hideShiftedArrow && cannotCenterArrow
361
+ })
352
362
 
353
363
  const contentZIndex = ref('')
354
364
  watchEffect(() => {
@@ -364,7 +374,7 @@ providePopperContentContext({
364
374
  onArrowChange: element => arrow.value = element,
365
375
  arrowX,
366
376
  arrowY,
367
- shouldHideArrow: cannotCenterArrow,
377
+ shouldHideArrow,
368
378
  })
369
379
  </script>
370
380
 
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import type { ComputedRef } from 'vue'
3
+ import type { PrimitiveProps } from '@/Primitive'
4
+ import { computed } from 'vue'
5
+ import { Primitive } from '@/Primitive'
6
+ import { createContext } from '@/shared'
7
+ import { injectRatingRootContext } from './RatingRoot.vue'
8
+
9
+ interface RatingItemContext {
10
+ steps: ComputedRef<number[]>
11
+ }
12
+
13
+ export interface RatingItemProps extends PrimitiveProps {
14
+ item: number
15
+ }
16
+
17
+ export const [injectRatingItemContext, provideRatingItemContext]
18
+ = createContext<RatingItemContext>('RatingItem')
19
+ </script>
20
+
21
+ <script setup lang="ts">
22
+ const props = withDefaults(defineProps<RatingItemProps>(), { as: 'label' })
23
+ defineSlots<{
24
+ default?: (props: {
25
+ steps: number[]
26
+ }) => any
27
+ }>()
28
+
29
+ const rootContext = injectRatingRootContext()
30
+
31
+ const steps = computed(() => {
32
+ const groupStartValue = (props.item - 1)
33
+ const groupEndValue = props.item
34
+ const stepSize = rootContext.step.value
35
+
36
+ const numberOfSteps = Math.ceil((groupEndValue - groupStartValue) / stepSize)
37
+
38
+ return Array.from({ length: numberOfSteps }, (_, index) =>
39
+ Number((groupStartValue + (index + 1) * stepSize).toFixed(2)))
40
+ })
41
+
42
+ provideRatingItemContext({ steps })
43
+ </script>
44
+
45
+ <template>
46
+ <Primitive
47
+ :as="as"
48
+ :as-child="asChild"
49
+ >
50
+ <slot :steps="steps" />
51
+ </Primitive>
52
+ </template>
@@ -0,0 +1,60 @@
1
+ <script lang="ts">
2
+ import type { PrimitiveProps } from '@/Primitive'
3
+ import { useActiveElement } from '@vueuse/core'
4
+ import { computed } from 'vue'
5
+ import { RadioGroupIndicator, RadioGroupItem } from '@/RadioGroup'
6
+ import { useForwardExpose } from '@/shared'
7
+ import { injectRatingItemContext } from './RatingItem.vue'
8
+ import { injectRatingRootContext } from './RatingRoot.vue'
9
+
10
+ export interface RatingItemProps extends PrimitiveProps {
11
+ step: number
12
+ }
13
+ </script>
14
+
15
+ <script setup lang="ts">
16
+ const props = defineProps<RatingItemProps>()
17
+
18
+ const rootContext = injectRatingRootContext()
19
+ const { currentElement, forwardRef } = useForwardExpose()
20
+ const activeElement = useActiveElement()
21
+ const itemContext = injectRatingItemContext()
22
+
23
+ const isActive = computed(() => {
24
+ return (rootContext.hoveredRating.value > 0 && props.step <= rootContext.hoveredRating.value) || (rootContext.hoveredRating.value === 0 && props.step <= rootContext.modelValue.value)
25
+ })
26
+
27
+ const isVisible = computed(() => {
28
+ return activeElement.value === currentElement.value || rootContext.step.value === 1 || props.step % 1 === 0 || props.step === rootContext.hoveredRating.value || props.step === rootContext.modelValue.value
29
+ })
30
+
31
+ function handleMouseEnter() {
32
+ rootContext.changeHoveredRating(props.step)
33
+ }
34
+ </script>
35
+
36
+ <template>
37
+ <RadioGroupItem
38
+ :ref="forwardRef"
39
+ :as="as"
40
+ :as-child="asChild"
41
+ :style="{
42
+ ['--reka-rating-item-step-width']: `${((step % 1 || 1) * 100)}%`,
43
+ ['--reka-rating-item-step-opacity']: isVisible ? 1 : 0,
44
+ ['--reka-rating-item-step-z-index']: itemContext.steps.value.length - itemContext.steps.value.indexOf(step),
45
+
46
+ }"
47
+ :value="step"
48
+ :data-state="isActive ? 'active' : undefined"
49
+ :disabled="rootContext.disabled.value"
50
+ @select="rootContext.changeModelValue(step)"
51
+ @mouseenter="handleMouseEnter"
52
+ >
53
+ <RadioGroupIndicator
54
+ force-mount
55
+ as-child
56
+ >
57
+ <slot />
58
+ </RadioGroupIndicator>
59
+ </RadioGroupItem>
60
+ </template>
@@ -0,0 +1,113 @@
1
+ <script lang="ts">
2
+ import type { RadioGroupRootProps } from '@/RadioGroup'
3
+ import { reactiveOmit, useVModel } from '@vueuse/core'
4
+ import { RadioGroupRoot } from '@/RadioGroup'
5
+ import { createContext, useForwardExpose } from '@/shared'
6
+
7
+ export interface RatingRootContext {
8
+ modelValue: Ref<number>
9
+ items: ComputedRef<number[]>
10
+ hoveredRating: Ref<number>
11
+ disabled: Ref<boolean>
12
+ step: Ref<number>
13
+ changeModelValue: (rating: number) => void
14
+ changeHoveredRating: (rating: number) => void
15
+ }
16
+
17
+ export interface RatingRootProps extends Omit<RadioGroupRootProps, 'modelValue' | 'defaultValue'> {
18
+ /**
19
+ * The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs
20
+ */
21
+ defaultValue?: number
22
+ /** The controlled value of the tab to activate. Can be bind as `v-model`. */
23
+ modelValue?: number
24
+ length?: number
25
+ clearable?: boolean
26
+ hoverable?: boolean
27
+ step?: 1 | 0.5 | 0.25 | 0.1
28
+
29
+ }
30
+ export type RatingRootEmits = {
31
+ /** Event handler called when the value changes */
32
+ 'update:modelValue': [payload: number]
33
+ }
34
+
35
+ export const [injectRatingRootContext, provideRatingRootContext]
36
+ = createContext<RatingRootContext>('RatingRoot')
37
+ </script>
38
+
39
+ <script setup lang="ts">
40
+ import type { ComputedRef, Ref } from 'vue'
41
+ import { computed, ref, toRefs } from 'vue'
42
+
43
+ const props = withDefaults(defineProps<RatingRootProps>(), {
44
+ orientation: 'horizontal',
45
+ length: 5,
46
+ step: 1,
47
+ })
48
+ const emits = defineEmits<RatingRootEmits>()
49
+
50
+ defineSlots<{
51
+ default?: (props: {
52
+ modelValue: number | undefined
53
+ items: number[]
54
+ }) => any
55
+ }>()
56
+
57
+ const { length, disabled, clearable, hoverable, step } = toRefs(props)
58
+
59
+ useForwardExpose()
60
+
61
+ const modelValue = useVModel<RatingRootProps, 'modelValue', 'update:modelValue'>(props, 'modelValue', emits, {
62
+ defaultValue: props.defaultValue,
63
+ passive: (props.modelValue === undefined) as false,
64
+ }) as Ref<number>
65
+
66
+ const items = computed(() => {
67
+ return Array.from({ length: length.value }, (_, i) => i + 1)
68
+ })
69
+
70
+ const hoveredRating = ref<number>(0)
71
+
72
+ function changeModelValue(rating: number) {
73
+ if (disabled.value)
74
+ return
75
+
76
+ if (clearable.value && modelValue.value === rating) {
77
+ hoveredRating.value = 0
78
+ modelValue.value = 0
79
+ }
80
+ else {
81
+ modelValue.value = rating
82
+ }
83
+ }
84
+
85
+ function changeHoveredRating(rating: number) {
86
+ if (disabled.value || !hoverable.value)
87
+ return
88
+
89
+ hoveredRating.value = rating
90
+ }
91
+
92
+ provideRatingRootContext({
93
+ modelValue,
94
+ items,
95
+ hoveredRating,
96
+ disabled,
97
+ step,
98
+ changeModelValue,
99
+ changeHoveredRating,
100
+ })
101
+ </script>
102
+
103
+ <template>
104
+ <RadioGroupRoot
105
+ v-bind="reactiveOmit(props, 'length', 'clearable', 'hoverable', 'step')"
106
+ :disabled="disabled"
107
+ >
108
+ <slot
109
+ :items="items"
110
+ :model-value="modelValue"
111
+ />
112
+ </RadioGroupRoot>
113
+ </template>
@@ -0,0 +1,3 @@
1
+ export { default as RatingItem, type RatingItemProps } from './RatingItem.vue'
2
+ export { default as RatingItemIndicator } from './RatingItemIndicator.vue'
3
+ export { default as RatingRoot, type RatingRootProps } from './RatingRoot.vue'
@@ -35,7 +35,8 @@ export interface ScrollAreaRootProps extends PrimitiveProps {
35
35
  * `auto` - means that scrollbars are visible when content is overflowing on the corresponding orientation. <br>
36
36
  * `always` - means that scrollbars are always visible regardless of whether the content is overflowing.<br>
37
37
  * `scroll` - means that scrollbars are visible when the user is scrolling along its corresponding orientation.<br>
38
- * `hover` - when the user is scrolling along its corresponding orientation and when the user is hovering over the scroll area.
38
+ * `hover` - when the user is scrolling along its corresponding orientation and when the user is hovering over the scroll area.<br>
39
+ * `glimpse` - a hybrid approach that briefly shows scrollbars when the user enters the scroll area, then hides them until further interaction.
39
40
  */
40
41
  type?: ScrollType
41
42
  /** The reading direction of the combobox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. */
@@ -34,6 +34,7 @@ import {
34
34
  } from 'vue'
35
35
  import { injectScrollAreaRootContext } from './ScrollAreaRoot.vue'
36
36
  import ScrollAreaScrollbarAuto from './ScrollAreaScrollbarAuto.vue'
37
+ import ScrollAreaScrollbarGlimpse from './ScrollAreaScrollbarGlimpse.vue'
37
38
  import ScrollAreaScrollbarHover from './ScrollAreaScrollbarHover.vue'
38
39
  import ScrollAreaScrollbarScroll from './ScrollAreaScrollbarScroll.vue'
39
40
  import ScrollAreaScrollbarVisible from './ScrollAreaScrollbarVisible.vue'
@@ -94,6 +95,14 @@ provideScrollAreaScrollbarContext({
94
95
  >
95
96
  <slot />
96
97
  </ScrollAreaScrollbarScroll>
98
+ <ScrollAreaScrollbarGlimpse
99
+ v-else-if="rootContext.type.value === 'glimpse'"
100
+ v-bind="$attrs"
101
+ :ref="forwardRef"
102
+ :force-mount="forceMount"
103
+ >
104
+ <slot />
105
+ </ScrollAreaScrollbarGlimpse>
97
106
  <ScrollAreaScrollbarAuto
98
107
  v-else-if="rootContext.type.value === 'auto'"
99
108
  v-bind="$attrs"
@@ -0,0 +1,145 @@
1
+ <script lang="ts">
2
+ import type { ScrollAreaScrollbarAutoProps } from './ScrollAreaScrollbarAuto.vue'
3
+
4
+ export interface ScrollAreaScrollbarGlimpseProps extends ScrollAreaScrollbarAutoProps {}
5
+ </script>
6
+
7
+ <script setup lang="ts">
8
+ import { useDebounceFn } from '@vueuse/core'
9
+ import { computed, onMounted, onUnmounted, watchEffect } from 'vue'
10
+ import { Presence } from '@/Presence'
11
+ import { useForwardExpose } from '@/shared'
12
+ import { useStateMachine } from '../shared/useStateMachine'
13
+ import { injectScrollAreaRootContext } from './ScrollAreaRoot.vue'
14
+ import { injectScrollAreaScrollbarContext } from './ScrollAreaScrollbar.vue'
15
+ import ScrollAreaScrollbarAuto from './ScrollAreaScrollbarAuto.vue'
16
+
17
+ defineOptions({
18
+ inheritAttrs: false,
19
+ })
20
+
21
+ defineProps<ScrollAreaScrollbarGlimpseProps>()
22
+
23
+ const rootContext = injectScrollAreaRootContext()
24
+ const scrollbarContext = injectScrollAreaScrollbarContext()
25
+
26
+ const { forwardRef } = useForwardExpose()
27
+
28
+ const { state, dispatch } = useStateMachine('hidden', {
29
+ hidden: {
30
+ POINTER_ENTER: 'glimpse',
31
+ SCROLL: 'scrolling',
32
+ },
33
+ glimpse: {
34
+ HIDE: 'hidden',
35
+ POINTER_LEAVE: 'hidden',
36
+ SCROLL: 'scrolling',
37
+ POINTER_ENTER: 'glimpse',
38
+ },
39
+ scrolling: {
40
+ SCROLL_END: 'idle',
41
+ POINTER_ENTER: 'interacting',
42
+ },
43
+ interacting: {
44
+ SCROLL: 'interacting',
45
+ POINTER_LEAVE: 'idle',
46
+ },
47
+ idle: {
48
+ HIDE: 'hidden',
49
+ SCROLL: 'scrolling',
50
+ POINTER_ENTER: 'interacting',
51
+ },
52
+ })
53
+
54
+ const visible = computed(() => state.value !== 'hidden')
55
+
56
+ function handlePointerEnter() {
57
+ dispatch('POINTER_ENTER')
58
+ }
59
+
60
+ function handlePointerLeave() {
61
+ dispatch('POINTER_LEAVE')
62
+ }
63
+
64
+ const debounceScrollEnd = useDebounceFn(() => dispatch('SCROLL_END'), 100)
65
+
66
+ watchEffect((onCleanup) => {
67
+ if (state.value === 'glimpse') {
68
+ const timeId = window.setTimeout(
69
+ () => dispatch('HIDE'),
70
+ rootContext.scrollHideDelay.value,
71
+ )
72
+
73
+ onCleanup(() => {
74
+ window.clearTimeout(timeId)
75
+ })
76
+ }
77
+ })
78
+
79
+ watchEffect((onCleanup) => {
80
+ if (state.value === 'idle') {
81
+ const timeId = window.setTimeout(
82
+ () => dispatch('HIDE'),
83
+ rootContext.scrollHideDelay.value,
84
+ )
85
+
86
+ onCleanup(() => {
87
+ window.clearTimeout(timeId)
88
+ })
89
+ }
90
+ })
91
+
92
+ watchEffect((onCleanup) => {
93
+ const viewport = rootContext.viewport.value
94
+ const scrollDirection = scrollbarContext.isHorizontal.value
95
+ ? 'scrollLeft'
96
+ : 'scrollTop'
97
+
98
+ if (viewport) {
99
+ let prevScrollPos = viewport[scrollDirection]
100
+ const handleScroll = () => {
101
+ const scrollPos = viewport[scrollDirection]
102
+ const hasScrollInDirectionChanged = prevScrollPos !== scrollPos
103
+ if (hasScrollInDirectionChanged) {
104
+ dispatch('SCROLL')
105
+ debounceScrollEnd()
106
+ }
107
+ prevScrollPos = scrollPos
108
+ }
109
+ viewport.addEventListener('scroll', handleScroll)
110
+
111
+ onCleanup(() => {
112
+ viewport.removeEventListener('scroll', handleScroll)
113
+ })
114
+ }
115
+ })
116
+
117
+ onMounted(() => {
118
+ const scrollArea = rootContext.scrollArea.value
119
+
120
+ if (scrollArea) {
121
+ scrollArea.addEventListener('pointerenter', handlePointerEnter)
122
+ scrollArea.addEventListener('pointerleave', handlePointerLeave)
123
+ }
124
+ })
125
+
126
+ onUnmounted(() => {
127
+ const scrollArea = rootContext.scrollArea.value
128
+ if (scrollArea) {
129
+ scrollArea.removeEventListener('pointerenter', handlePointerEnter)
130
+ scrollArea.removeEventListener('pointerleave', handlePointerLeave)
131
+ }
132
+ })
133
+ </script>
134
+
135
+ <template>
136
+ <Presence :present="forceMount || visible">
137
+ <ScrollAreaScrollbarAuto
138
+ v-bind="$attrs"
139
+ :ref="forwardRef"
140
+ :data-state="visible ? 'visible' : 'hidden'"
141
+ >
142
+ <slot />
143
+ </ScrollAreaScrollbarAuto>
144
+ </Presence>
145
+ </template>