reka-ui 2.6.2 → 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.
- package/dist/Avatar/AvatarImage.cjs +4 -2
- package/dist/Avatar/AvatarImage.cjs.map +1 -1
- package/dist/Avatar/AvatarImage.js +4 -2
- package/dist/Avatar/AvatarImage.js.map +1 -1
- package/dist/Collection/Collection.cjs +6 -2
- package/dist/Collection/Collection.cjs.map +1 -1
- package/dist/Collection/Collection.js +6 -2
- package/dist/Collection/Collection.js.map +1 -1
- package/dist/Combobox/ComboboxContent.cjs +4 -0
- package/dist/Combobox/ComboboxContent.cjs.map +1 -1
- package/dist/Combobox/ComboboxContent.js +4 -0
- package/dist/Combobox/ComboboxContent.js.map +1 -1
- package/dist/Combobox/ComboboxContentImpl.cjs +46 -33
- package/dist/Combobox/ComboboxContentImpl.cjs.map +1 -1
- package/dist/Combobox/ComboboxContentImpl.js +47 -34
- package/dist/Combobox/ComboboxContentImpl.js.map +1 -1
- package/dist/ContextMenu/ContextMenuContent.cjs +4 -0
- package/dist/ContextMenu/ContextMenuContent.cjs.map +1 -1
- package/dist/ContextMenu/ContextMenuContent.js +4 -0
- package/dist/ContextMenu/ContextMenuContent.js.map +1 -1
- package/dist/ContextMenu/ContextMenuRadioGroup.cjs +1 -1
- package/dist/ContextMenu/ContextMenuRadioGroup.js +1 -1
- package/dist/ContextMenu/ContextMenuRadioItem.cjs +1 -1
- package/dist/ContextMenu/ContextMenuRadioItem.js +1 -1
- package/dist/ContextMenu/ContextMenuSubContent.cjs +4 -0
- package/dist/ContextMenu/ContextMenuSubContent.cjs.map +1 -1
- package/dist/ContextMenu/ContextMenuSubContent.js +4 -0
- package/dist/ContextMenu/ContextMenuSubContent.js.map +1 -1
- package/dist/DatePicker/DatePickerContent.cjs +4 -0
- package/dist/DatePicker/DatePickerContent.cjs.map +1 -1
- package/dist/DatePicker/DatePickerContent.js +4 -0
- package/dist/DatePicker/DatePickerContent.js.map +1 -1
- package/dist/DatePicker/DatePickerRoot.cjs +7 -6
- package/dist/DatePicker/DatePickerRoot.cjs.map +1 -1
- package/dist/DatePicker/DatePickerRoot.js +7 -6
- package/dist/DatePicker/DatePickerRoot.js.map +1 -1
- package/dist/DateRangePicker/DateRangePickerContent.cjs +4 -0
- package/dist/DateRangePicker/DateRangePickerContent.cjs.map +1 -1
- package/dist/DateRangePicker/DateRangePickerContent.js +4 -0
- package/dist/DateRangePicker/DateRangePickerContent.js.map +1 -1
- package/dist/DateRangePicker/DateRangePickerRoot.cjs +7 -6
- package/dist/DateRangePicker/DateRangePickerRoot.cjs.map +1 -1
- package/dist/DateRangePicker/DateRangePickerRoot.js +7 -6
- package/dist/DateRangePicker/DateRangePickerRoot.js.map +1 -1
- package/dist/DropdownMenu/DropdownMenuContent.cjs +4 -0
- package/dist/DropdownMenu/DropdownMenuContent.cjs.map +1 -1
- package/dist/DropdownMenu/DropdownMenuContent.js +4 -0
- package/dist/DropdownMenu/DropdownMenuContent.js.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.cjs +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.cjs +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +1 -1
- package/dist/DropdownMenu/DropdownMenuSubContent.cjs +4 -0
- package/dist/DropdownMenu/DropdownMenuSubContent.cjs.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubContent.js +4 -0
- package/dist/DropdownMenu/DropdownMenuSubContent.js.map +1 -1
- package/dist/Editable/EditableInput.cjs +1 -1
- package/dist/Editable/EditableInput.cjs.map +1 -1
- package/dist/Editable/EditableInput.js +1 -1
- package/dist/Editable/EditableInput.js.map +1 -1
- package/dist/FocusScope/FocusScope.cjs +1 -1
- package/dist/FocusScope/FocusScope.cjs.map +1 -1
- package/dist/FocusScope/FocusScope.js +2 -2
- package/dist/FocusScope/FocusScope.js.map +1 -1
- package/dist/FocusScope/stack.cjs +0 -9
- package/dist/FocusScope/stack.cjs.map +1 -1
- package/dist/FocusScope/stack.js +1 -4
- package/dist/FocusScope/stack.js.map +1 -1
- package/dist/HoverCard/HoverCardContent.cjs +4 -0
- package/dist/HoverCard/HoverCardContent.cjs.map +1 -1
- package/dist/HoverCard/HoverCardContent.js +4 -0
- package/dist/HoverCard/HoverCardContent.js.map +1 -1
- package/dist/HoverCard/HoverCardContentImpl.cjs +4 -0
- package/dist/HoverCard/HoverCardContentImpl.cjs.map +1 -1
- package/dist/HoverCard/HoverCardContentImpl.js +4 -0
- package/dist/HoverCard/HoverCardContentImpl.js.map +1 -1
- package/dist/Listbox/ListboxRoot.cjs.map +1 -1
- package/dist/Listbox/ListboxRoot.js.map +1 -1
- package/dist/Menu/MenuContent.cjs +4 -0
- package/dist/Menu/MenuContent.cjs.map +1 -1
- package/dist/Menu/MenuContent.js +4 -0
- package/dist/Menu/MenuContent.js.map +1 -1
- package/dist/Menu/MenuContentImpl.cjs +4 -0
- package/dist/Menu/MenuContentImpl.cjs.map +1 -1
- package/dist/Menu/MenuContentImpl.js +4 -0
- package/dist/Menu/MenuContentImpl.js.map +1 -1
- package/dist/Menu/MenuRadioGroup.cjs +1 -1
- package/dist/Menu/MenuRadioGroup.cjs.map +1 -1
- package/dist/Menu/MenuRadioGroup.js +1 -1
- package/dist/Menu/MenuRadioGroup.js.map +1 -1
- package/dist/Menu/MenuRadioItem.cjs +1 -1
- package/dist/Menu/MenuRadioItem.cjs.map +1 -1
- package/dist/Menu/MenuRadioItem.js +1 -1
- package/dist/Menu/MenuRadioItem.js.map +1 -1
- package/dist/Menu/MenuRootContentModal.cjs +4 -0
- package/dist/Menu/MenuRootContentModal.cjs.map +1 -1
- package/dist/Menu/MenuRootContentModal.js +4 -0
- package/dist/Menu/MenuRootContentModal.js.map +1 -1
- package/dist/Menu/MenuRootContentNonModal.cjs +4 -0
- package/dist/Menu/MenuRootContentNonModal.cjs.map +1 -1
- package/dist/Menu/MenuRootContentNonModal.js +4 -0
- package/dist/Menu/MenuRootContentNonModal.js.map +1 -1
- package/dist/Menu/MenuSubContent.cjs +4 -0
- package/dist/Menu/MenuSubContent.cjs.map +1 -1
- package/dist/Menu/MenuSubContent.js +4 -0
- package/dist/Menu/MenuSubContent.js.map +1 -1
- package/dist/Menubar/MenubarContent.cjs +4 -0
- package/dist/Menubar/MenubarContent.cjs.map +1 -1
- package/dist/Menubar/MenubarContent.js +4 -0
- package/dist/Menubar/MenubarContent.js.map +1 -1
- package/dist/Menubar/MenubarRadioGroup.cjs +1 -1
- package/dist/Menubar/MenubarRadioGroup.js +1 -1
- package/dist/Menubar/MenubarRadioItem.cjs +1 -1
- package/dist/Menubar/MenubarRadioItem.js +1 -1
- package/dist/Menubar/MenubarSubContent.cjs +4 -0
- package/dist/Menubar/MenubarSubContent.cjs.map +1 -1
- package/dist/Menubar/MenubarSubContent.js +4 -0
- package/dist/Menubar/MenubarSubContent.js.map +1 -1
- package/dist/NavigationMenu/NavigationMenuContent.cjs +1 -1
- package/dist/NavigationMenu/NavigationMenuContent.js +1 -1
- package/dist/NavigationMenu/NavigationMenuContentImpl.cjs +1 -1
- package/dist/NavigationMenu/NavigationMenuContentImpl.js +1 -1
- package/dist/NavigationMenu/NavigationMenuItem.cjs +1 -1
- package/dist/NavigationMenu/NavigationMenuItem.js +1 -1
- package/dist/NavigationMenu/NavigationMenuRoot.cjs +7 -5
- package/dist/NavigationMenu/NavigationMenuRoot.cjs.map +1 -1
- package/dist/NavigationMenu/NavigationMenuRoot.js +8 -6
- package/dist/NavigationMenu/NavigationMenuRoot.js.map +1 -1
- package/dist/NavigationMenu/NavigationMenuTrigger.cjs +1 -1
- package/dist/NavigationMenu/NavigationMenuTrigger.js +1 -1
- package/dist/NavigationMenu/NavigationMenuViewport.cjs +1 -1
- package/dist/NavigationMenu/NavigationMenuViewport.js +1 -1
- package/dist/NumberField/NumberFieldRoot.cjs +6 -1
- package/dist/NumberField/NumberFieldRoot.cjs.map +1 -1
- package/dist/NumberField/NumberFieldRoot.js +6 -1
- package/dist/NumberField/NumberFieldRoot.js.map +1 -1
- package/dist/PinInput/PinInputInput.cjs +15 -11
- package/dist/PinInput/PinInputInput.cjs.map +1 -1
- package/dist/PinInput/PinInputInput.js +15 -11
- package/dist/PinInput/PinInputInput.js.map +1 -1
- package/dist/Popover/PopoverContent.cjs +4 -0
- package/dist/Popover/PopoverContent.cjs.map +1 -1
- package/dist/Popover/PopoverContent.js +4 -0
- package/dist/Popover/PopoverContent.js.map +1 -1
- package/dist/Popover/PopoverContentImpl.cjs +4 -0
- package/dist/Popover/PopoverContentImpl.cjs.map +1 -1
- package/dist/Popover/PopoverContentImpl.js +4 -0
- package/dist/Popover/PopoverContentImpl.js.map +1 -1
- package/dist/Popover/PopoverContentModal.cjs +4 -0
- package/dist/Popover/PopoverContentModal.cjs.map +1 -1
- package/dist/Popover/PopoverContentModal.js +4 -0
- package/dist/Popover/PopoverContentModal.js.map +1 -1
- package/dist/Popover/PopoverContentNonModal.cjs +4 -0
- package/dist/Popover/PopoverContentNonModal.cjs.map +1 -1
- package/dist/Popover/PopoverContentNonModal.js +4 -0
- package/dist/Popover/PopoverContentNonModal.js.map +1 -1
- package/dist/Popper/PopperContent.cjs +10 -2
- package/dist/Popper/PopperContent.cjs.map +1 -1
- package/dist/Popper/PopperContent.js +10 -2
- package/dist/Popper/PopperContent.js.map +1 -1
- package/dist/ScrollArea/ScrollAreaRoot.cjs.map +1 -1
- package/dist/ScrollArea/ScrollAreaRoot.js.map +1 -1
- package/dist/ScrollArea/ScrollAreaScrollbar.cjs +9 -2
- package/dist/ScrollArea/ScrollAreaScrollbar.cjs.map +1 -1
- package/dist/ScrollArea/ScrollAreaScrollbar.js +9 -2
- package/dist/ScrollArea/ScrollAreaScrollbar.js.map +1 -1
- package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.cjs +132 -0
- package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.cjs.map +1 -0
- package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.js +126 -0
- package/dist/ScrollArea/ScrollAreaScrollbarGlimpse.js.map +1 -0
- package/dist/Select/SelectContent.cjs +4 -0
- package/dist/Select/SelectContent.cjs.map +1 -1
- package/dist/Select/SelectContent.js +4 -0
- package/dist/Select/SelectContent.js.map +1 -1
- package/dist/Select/SelectContentImpl.cjs +4 -0
- package/dist/Select/SelectContentImpl.cjs.map +1 -1
- package/dist/Select/SelectContentImpl.js +4 -0
- package/dist/Select/SelectContentImpl.js.map +1 -1
- package/dist/Select/SelectPopperPosition.cjs +4 -0
- package/dist/Select/SelectPopperPosition.cjs.map +1 -1
- package/dist/Select/SelectPopperPosition.js +4 -0
- package/dist/Select/SelectPopperPosition.js.map +1 -1
- package/dist/Tabs/TabsContent.cjs +4 -0
- package/dist/Tabs/TabsContent.cjs.map +1 -1
- package/dist/Tabs/TabsContent.js +5 -1
- package/dist/Tabs/TabsContent.js.map +1 -1
- package/dist/Tabs/TabsRoot.cjs +11 -1
- package/dist/Tabs/TabsRoot.cjs.map +1 -1
- package/dist/Tabs/TabsRoot.js +12 -2
- package/dist/Tabs/TabsRoot.js.map +1 -1
- package/dist/Tabs/TabsTrigger.cjs +1 -1
- package/dist/Tabs/TabsTrigger.cjs.map +1 -1
- package/dist/Tabs/TabsTrigger.js +1 -1
- package/dist/Tabs/TabsTrigger.js.map +1 -1
- package/dist/TimeField/TimeFieldInput.cjs +3 -1
- package/dist/TimeField/TimeFieldInput.cjs.map +1 -1
- package/dist/TimeField/TimeFieldInput.js +3 -1
- package/dist/TimeField/TimeFieldInput.js.map +1 -1
- package/dist/TimeField/TimeFieldRoot.cjs +24 -2
- package/dist/TimeField/TimeFieldRoot.cjs.map +1 -1
- package/dist/TimeField/TimeFieldRoot.js +24 -2
- package/dist/TimeField/TimeFieldRoot.js.map +1 -1
- package/dist/constant.d.cts.map +1 -1
- package/dist/date/comparators.cjs +14 -2
- package/dist/date/comparators.cjs.map +1 -1
- package/dist/date/comparators.js +14 -2
- package/dist/date/comparators.js.map +1 -1
- package/dist/date/parser.cjs +1 -0
- package/dist/date/parser.cjs.map +1 -1
- package/dist/date/parser.js +1 -0
- package/dist/date/parser.js.map +1 -1
- package/dist/date/useDateField.cjs +41 -20
- package/dist/date/useDateField.cjs.map +1 -1
- package/dist/date/useDateField.js +41 -20
- package/dist/date/useDateField.js.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +1089 -1052
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1079 -1042
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index2.d.cts.map +1 -1
- package/dist/index2.d.ts.map +1 -1
- package/dist/shared/useDateFormatter.cjs +1 -1
- package/dist/shared/useDateFormatter.cjs.map +1 -1
- package/dist/shared/useDateFormatter.js +1 -1
- package/dist/shared/useDateFormatter.js.map +1 -1
- package/dist/shared/useGraceArea.cjs +1 -1
- package/dist/shared/useGraceArea.cjs.map +1 -1
- package/dist/shared/useGraceArea.js +1 -1
- package/dist/shared/useGraceArea.js.map +1 -1
- package/package.json +5 -5
- package/src/Avatar/AvatarImage.vue +2 -1
- package/src/Collection/Collection.ts +3 -2
- package/src/Combobox/ComboboxContentImpl.vue +39 -32
- package/src/Combobox/ComboboxRoot.vue +1 -1
- package/src/DatePicker/DatePickerRoot.vue +6 -6
- package/src/DatePicker/index.ts +4 -4
- package/src/DateRangePicker/DateRangePickerRoot.vue +6 -6
- package/src/DateRangePicker/index.ts +4 -4
- package/src/Editable/EditableInput.vue +1 -1
- package/src/FocusScope/FocusScope.vue +2 -2
- package/src/Listbox/ListboxFilter.vue +1 -1
- package/src/Listbox/ListboxRoot.vue +2 -1
- package/src/Menu/MenuRadioGroup.vue +5 -4
- package/src/Menu/MenuRadioItem.vue +2 -1
- package/src/NavigationMenu/NavigationMenuRoot.vue +10 -6
- package/src/NumberField/NumberFieldRoot.vue +6 -1
- package/src/PinInput/PinInputInput.vue +25 -18
- package/src/Popper/PopperContent.vue +15 -5
- package/src/Rating/RatingItem.vue +52 -0
- package/src/Rating/RatingItemIndicator.vue +60 -0
- package/src/Rating/RatingRoot.vue +113 -0
- package/src/Rating/index.ts +3 -0
- package/src/ScrollArea/ScrollAreaRoot.vue +2 -1
- package/src/ScrollArea/ScrollAreaScrollbar.vue +9 -0
- package/src/ScrollArea/ScrollAreaScrollbarGlimpse.vue +145 -0
- package/src/ScrollArea/index.ts +4 -0
- package/src/ScrollArea/types.ts +1 -1
- package/src/Tabs/TabsContent.vue +6 -1
- package/src/Tabs/TabsRoot.vue +14 -1
- package/src/Tabs/TabsTrigger.vue +1 -1
- package/src/TimeField/TimeFieldInput.vue +6 -1
- package/src/TimeField/TimeFieldRoot.vue +25 -2
- package/src/Tree/TreeRoot.vue +2 -2
- package/src/date/comparators.ts +15 -2
- package/src/index.ts +1 -0
- package/src/shared/date/parser.ts +10 -0
- package/src/shared/date/useDateField.ts +70 -21
- package/src/shared/index.ts +1 -1
- package/src/shared/useDateFormatter.ts +2 -2
- 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
|
|
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
|
|
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<
|
|
8
|
-
onValueChange: (payload:
|
|
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?:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
|
54
|
-
const target = currentElement.value as HTMLInputElement
|
|
53
|
+
function updatePlaceholder() {
|
|
55
54
|
nextTick(() => {
|
|
56
|
-
|
|
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
|
-
|
|
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 "
|
|
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
|
|
350
|
-
|
|
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
|
|
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>
|
|
@@ -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>
|