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.
- 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 +1122 -1085
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1115 -1078
- 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
package/src/ScrollArea/index.ts
CHANGED
|
@@ -12,6 +12,10 @@ export {
|
|
|
12
12
|
default as ScrollAreaScrollbar,
|
|
13
13
|
type ScrollAreaScrollbarProps,
|
|
14
14
|
} from './ScrollAreaScrollbar.vue'
|
|
15
|
+
export {
|
|
16
|
+
default as ScrollAreaScrollbarGlimpse,
|
|
17
|
+
type ScrollAreaScrollbarGlimpseProps,
|
|
18
|
+
} from './ScrollAreaScrollbarGlimpse.vue'
|
|
15
19
|
export {
|
|
16
20
|
default as ScrollAreaThumb,
|
|
17
21
|
type ScrollAreaThumbProps,
|
package/src/ScrollArea/types.ts
CHANGED
package/src/Tabs/TabsContent.vue
CHANGED
|
@@ -15,7 +15,7 @@ export interface TabsContentProps extends PrimitiveProps {
|
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<script setup lang="ts">
|
|
18
|
-
import { computed, onMounted, ref } from 'vue'
|
|
18
|
+
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
19
19
|
import { Presence } from '@/Presence'
|
|
20
20
|
import { Primitive } from '@/Primitive'
|
|
21
21
|
import { injectTabsRootContext } from './TabsRoot.vue'
|
|
@@ -33,10 +33,15 @@ const isSelected = computed(() => props.value === rootContext.modelValue.value)
|
|
|
33
33
|
const isMountAnimationPreventedRef = ref(isSelected.value)
|
|
34
34
|
|
|
35
35
|
onMounted(() => {
|
|
36
|
+
rootContext.registerContent(props.value)
|
|
36
37
|
requestAnimationFrame(() => {
|
|
37
38
|
isMountAnimationPreventedRef.value = false
|
|
38
39
|
})
|
|
39
40
|
})
|
|
41
|
+
|
|
42
|
+
onBeforeUnmount(() => {
|
|
43
|
+
rootContext.unregisterContent(props.value)
|
|
44
|
+
})
|
|
40
45
|
</script>
|
|
41
46
|
|
|
42
47
|
<template>
|
package/src/Tabs/TabsRoot.vue
CHANGED
|
@@ -14,6 +14,9 @@ export interface TabsRootContext {
|
|
|
14
14
|
activationMode: 'automatic' | 'manual'
|
|
15
15
|
baseId: string
|
|
16
16
|
tabsList: Ref<HTMLElement | undefined>
|
|
17
|
+
contentIds: Ref<Set<StringOrNumber>>
|
|
18
|
+
registerContent: (value: StringOrNumber) => void
|
|
19
|
+
unregisterContent: (value: StringOrNumber) => void
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
export interface TabsRootProps<T extends StringOrNumber = StringOrNumber> extends PrimitiveProps {
|
|
@@ -55,7 +58,7 @@ export const [injectTabsRootContext, provideTabsRootContext]
|
|
|
55
58
|
</script>
|
|
56
59
|
|
|
57
60
|
<script setup lang="ts" generic="T extends StringOrNumber = StringOrNumber">
|
|
58
|
-
import { ref, toRefs } from 'vue'
|
|
61
|
+
import { ref, shallowRef, toRefs } from 'vue'
|
|
59
62
|
import { Primitive } from '@/Primitive'
|
|
60
63
|
|
|
61
64
|
const props = withDefaults(defineProps<TabsRootProps<T>>(), {
|
|
@@ -82,6 +85,7 @@ const modelValue = useVModel<TabsRootProps<T>, 'modelValue', 'update:modelValue'
|
|
|
82
85
|
})
|
|
83
86
|
|
|
84
87
|
const tabsList = ref<HTMLElement>()
|
|
88
|
+
const contentIds = shallowRef<Set<StringOrNumber>>(new Set())
|
|
85
89
|
|
|
86
90
|
provideTabsRootContext({
|
|
87
91
|
modelValue,
|
|
@@ -94,6 +98,15 @@ provideTabsRootContext({
|
|
|
94
98
|
activationMode: props.activationMode,
|
|
95
99
|
baseId: useId(undefined, 'reka-tabs'),
|
|
96
100
|
tabsList,
|
|
101
|
+
contentIds,
|
|
102
|
+
registerContent: (value: StringOrNumber) => {
|
|
103
|
+
contentIds.value = new Set([...contentIds.value, value])
|
|
104
|
+
},
|
|
105
|
+
unregisterContent: (value: StringOrNumber) => {
|
|
106
|
+
const newSet = new Set(contentIds.value)
|
|
107
|
+
newSet.delete(value)
|
|
108
|
+
contentIds.value = newSet
|
|
109
|
+
},
|
|
97
110
|
})
|
|
98
111
|
</script>
|
|
99
112
|
|
package/src/Tabs/TabsTrigger.vue
CHANGED
|
@@ -27,7 +27,7 @@ const { forwardRef } = useForwardExpose()
|
|
|
27
27
|
const rootContext = injectTabsRootContext()
|
|
28
28
|
|
|
29
29
|
const triggerId = computed(() => makeTriggerId(rootContext.baseId, props.value))
|
|
30
|
-
const contentId = computed(() => makeContentId(rootContext.baseId, props.value))
|
|
30
|
+
const contentId = computed(() => rootContext.contentIds.value.has(props.value) ? makeContentId(rootContext.baseId, props.value) : undefined)
|
|
31
31
|
|
|
32
32
|
const isSelected = computed(() => props.value === rootContext.modelValue.value)
|
|
33
33
|
</script>
|
|
@@ -23,6 +23,7 @@ const lastKeyZero = ref(false)
|
|
|
23
23
|
const {
|
|
24
24
|
handleSegmentClick,
|
|
25
25
|
handleSegmentKeydown,
|
|
26
|
+
handleSegmentFocusOut,
|
|
26
27
|
attributes,
|
|
27
28
|
} = useDateField({
|
|
28
29
|
hasLeftFocus,
|
|
@@ -30,6 +31,7 @@ const {
|
|
|
30
31
|
placeholder: rootContext.placeholder,
|
|
31
32
|
hourCycle: rootContext.hourCycle,
|
|
32
33
|
step: rootContext.step,
|
|
34
|
+
stepSnapping: rootContext.stepSnapping,
|
|
33
35
|
segmentValues: rootContext.segmentValues,
|
|
34
36
|
formatter: rootContext.formatter,
|
|
35
37
|
part: props.part,
|
|
@@ -59,7 +61,10 @@ const isInvalid = computed(() => rootContext.isInvalid.value)
|
|
|
59
61
|
v-on="part !== 'literal' ? {
|
|
60
62
|
mousedown: handleSegmentClick,
|
|
61
63
|
keydown: handleSegmentKeydown,
|
|
62
|
-
focusout: () => {
|
|
64
|
+
focusout: () => {
|
|
65
|
+
hasLeftFocus = true
|
|
66
|
+
handleSegmentFocusOut()
|
|
67
|
+
},
|
|
63
68
|
focusin: (e: FocusEvent) => {
|
|
64
69
|
rootContext.setFocusedElement(e.target as HTMLElement)
|
|
65
70
|
},
|
|
@@ -32,6 +32,7 @@ type TimeFieldRootContext = {
|
|
|
32
32
|
formatter: Formatter
|
|
33
33
|
hourCycle: HourCycle
|
|
34
34
|
step: Ref<DateStep>
|
|
35
|
+
stepSnapping: Ref<boolean>
|
|
35
36
|
segmentValues: Ref<SegmentValueObj>
|
|
36
37
|
segmentContents: Ref<{ part: SegmentPart, value: string }[]>
|
|
37
38
|
elements: Ref<Set<HTMLElement>>
|
|
@@ -52,6 +53,8 @@ export interface TimeFieldRootProps extends PrimitiveProps, FormFieldProps {
|
|
|
52
53
|
hourCycle?: HourCycle
|
|
53
54
|
/** The stepping interval for the time fields. Defaults to `1`. */
|
|
54
55
|
step?: DateStep
|
|
56
|
+
/** Whether to enforce snapping the value to the nearest step increment after input. Defaults to `false`. */
|
|
57
|
+
stepSnapping?: boolean
|
|
55
58
|
/** The granularity to use for formatting times. Defaults to minute if a Time is provided, otherwise defaults to minute. The field will render segments for each part of the date up to and including the specified granularity */
|
|
56
59
|
granularity?: 'hour' | 'minute' | 'second'
|
|
57
60
|
/** Whether or not to hide the time zone segment of the field */
|
|
@@ -107,6 +110,7 @@ const props = withDefaults(defineProps<TimeFieldRootProps>(), {
|
|
|
107
110
|
readonly: false,
|
|
108
111
|
placeholder: undefined,
|
|
109
112
|
isDateUnavailable: undefined,
|
|
113
|
+
stepSnapping: false,
|
|
110
114
|
})
|
|
111
115
|
const emits = defineEmits<TimeFieldRootEmits>()
|
|
112
116
|
defineSlots<{
|
|
@@ -120,7 +124,7 @@ defineSlots<{
|
|
|
120
124
|
}) => any
|
|
121
125
|
}>()
|
|
122
126
|
|
|
123
|
-
const { disabled, readonly, granularity, defaultValue, minValue, maxValue, dir: propDir, locale: propLocale } = toRefs(props)
|
|
127
|
+
const { disabled, readonly, granularity, defaultValue, minValue, maxValue, stepSnapping, dir: propDir, locale: propLocale } = toRefs(props)
|
|
124
128
|
const locale = useLocale(propLocale)
|
|
125
129
|
const dir = useDirection(propDir)
|
|
126
130
|
|
|
@@ -218,7 +222,25 @@ const allSegmentContent = computed(() => createContent({
|
|
|
218
222
|
isTimeValue: true,
|
|
219
223
|
}))
|
|
220
224
|
|
|
221
|
-
const segmentContents = computed(() =>
|
|
225
|
+
const segmentContents = computed(() => {
|
|
226
|
+
const contents = allSegmentContent.value.arr
|
|
227
|
+
|
|
228
|
+
// Convert hour values for 12-hour display
|
|
229
|
+
if (props.hourCycle === 12) {
|
|
230
|
+
return contents.map((segment) => {
|
|
231
|
+
if (segment.part === 'hour' && 'hour' in segmentValues.value) {
|
|
232
|
+
const hour = segmentValues.value.hour
|
|
233
|
+
if (hour !== null) {
|
|
234
|
+
const displayHour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour
|
|
235
|
+
return { ...segment, value: displayHour.toString() }
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return segment
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return contents
|
|
243
|
+
})
|
|
222
244
|
|
|
223
245
|
const editableSegmentContents = computed(() => segmentContents.value.filter(({ part }) => part !== 'literal'))
|
|
224
246
|
|
|
@@ -298,6 +320,7 @@ provideTimeFieldRootContext({
|
|
|
298
320
|
formatter,
|
|
299
321
|
hourCycle: props.hourCycle,
|
|
300
322
|
step,
|
|
323
|
+
stepSnapping,
|
|
301
324
|
readonly,
|
|
302
325
|
segmentValues,
|
|
303
326
|
isInvalid,
|
package/src/Tree/TreeRoot.vue
CHANGED
|
@@ -4,13 +4,13 @@ import { createContext, getActiveElement, useDirection, useSelectionBehavior, us
|
|
|
4
4
|
import { flatten } from './utils'
|
|
5
5
|
|
|
6
6
|
export interface TreeRootProps<T = Record<string, any>, U extends Record<string, any> = Record<string, any>, M extends boolean = false> extends PrimitiveProps {
|
|
7
|
-
/** The controlled value of the tree. Can be binded with
|
|
7
|
+
/** The controlled value of the tree. Can be binded with `v-model`. */
|
|
8
8
|
modelValue?: M extends true ? U[] : U
|
|
9
9
|
/** The value of the tree when initially rendered. Use when you do not need to control the state of the tree */
|
|
10
10
|
defaultValue?: M extends true ? U[] : U
|
|
11
11
|
/** List of items */
|
|
12
12
|
items?: T[]
|
|
13
|
-
/** The controlled value of the expanded item. Can be binded with
|
|
13
|
+
/** The controlled value of the expanded item. Can be binded with `v-model`. */
|
|
14
14
|
expanded?: string[]
|
|
15
15
|
/** The value of the expanded tree when initially rendered. Use when you do not need to control the state of the expanded tree */
|
|
16
16
|
defaultExpanded?: string[]
|
package/src/date/comparators.ts
CHANGED
|
@@ -143,7 +143,13 @@ export function getLastFirstDayOfWeek<T extends DateValue = DateValue>(
|
|
|
143
143
|
firstDayOfWeek: number,
|
|
144
144
|
locale: string,
|
|
145
145
|
): T {
|
|
146
|
-
|
|
146
|
+
/**
|
|
147
|
+
* "firstDayOfWeek" is fixed to 0(Sunday) to avoid confusion regarding locales.
|
|
148
|
+
* This also aligns with other date libraries, e.g., date-fns.
|
|
149
|
+
*
|
|
150
|
+
* #see https://github.com/unovue/reka-ui/issues/2157
|
|
151
|
+
*/
|
|
152
|
+
const day = getDayOfWeek(date, locale, 'sun')
|
|
147
153
|
|
|
148
154
|
if (firstDayOfWeek > day)
|
|
149
155
|
return date.subtract({ days: day + 7 - firstDayOfWeek }) as T
|
|
@@ -159,7 +165,14 @@ export function getNextLastDayOfWeek<T extends DateValue = DateValue>(
|
|
|
159
165
|
firstDayOfWeek: number,
|
|
160
166
|
locale: string,
|
|
161
167
|
): T {
|
|
162
|
-
|
|
168
|
+
/**
|
|
169
|
+
* "firstDayOfWeek" is fixed to 0(Sunday) to avoid confusion regarding locales.
|
|
170
|
+
* This also aligns with other date libraries, e.g., date-fns.
|
|
171
|
+
*
|
|
172
|
+
* #see https://github.com/unovue/reka-ui/issues/2157
|
|
173
|
+
*/
|
|
174
|
+
const day = getDayOfWeek(date, locale, 'sun')
|
|
175
|
+
|
|
163
176
|
const lastDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1
|
|
164
177
|
|
|
165
178
|
if (day === lastDayOfWeek)
|
package/src/index.ts
CHANGED
|
@@ -197,6 +197,16 @@ function createContentArr(props: CreateContentArrProps) {
|
|
|
197
197
|
if (segment.part === 'timeZoneName' && (!isZonedDateTime(props.dateRef) || hideTimeZone))
|
|
198
198
|
return false
|
|
199
199
|
|
|
200
|
+
// In some locales (e.g., zh-TW), the time zone is represented with square brackets.
|
|
201
|
+
// We also filter out these literals that are just brackets.
|
|
202
|
+
// @see https://github.com/unovue/reka-ui/issues/1670
|
|
203
|
+
if (
|
|
204
|
+
(!isZonedDateTime(props.dateRef) || hideTimeZone)
|
|
205
|
+
&& segment.part === 'literal' && ['[', ']'].includes(segment.value.trim())
|
|
206
|
+
) {
|
|
207
|
+
return false
|
|
208
|
+
}
|
|
209
|
+
|
|
200
210
|
return true
|
|
201
211
|
})
|
|
202
212
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type { CalendarDateTime,
|
|
1
|
+
import type { CalendarDateTime, DateFields, DateValue, TimeFields } from '@internationalized/date'
|
|
2
2
|
import type { Ref } from 'vue'
|
|
3
3
|
import type { AnyExceptLiteral, DateStep, HourCycle, SegmentPart, SegmentValueObj } from './types'
|
|
4
4
|
import type { Formatter } from '@/shared'
|
|
5
|
+
import {
|
|
6
|
+
DateFormatter,
|
|
7
|
+
} from '@internationalized/date'
|
|
5
8
|
import { computed } from 'vue'
|
|
6
9
|
import { getDaysInMonth, toDate } from '@/date'
|
|
7
|
-
import { useKbd } from '@/shared'
|
|
10
|
+
import { snapValueToStep, useKbd } from '@/shared'
|
|
8
11
|
import { isAcceptableSegmentKey, isNumberString, isSegmentNavigationKey } from './segment'
|
|
9
12
|
|
|
10
13
|
type MinuteSecondIncrementProps = {
|
|
@@ -19,7 +22,6 @@ type DateTimeValueIncrementation = {
|
|
|
19
22
|
part: keyof Omit<DateFields, 'era'> | keyof TimeFields
|
|
20
23
|
dateRef: DateValue
|
|
21
24
|
prevValue: number | null
|
|
22
|
-
hourCycle?: HourCycle
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
type SegmentAttrProps = {
|
|
@@ -282,6 +284,7 @@ export type UseDateFieldProps = {
|
|
|
282
284
|
placeholder: Ref<DateValue>
|
|
283
285
|
hourCycle: HourCycle
|
|
284
286
|
step: Ref<DateStep>
|
|
287
|
+
stepSnapping?: Ref<boolean>
|
|
285
288
|
formatter: Formatter
|
|
286
289
|
segmentValues: Ref<SegmentValueObj>
|
|
287
290
|
disabled: Ref<boolean>
|
|
@@ -320,7 +323,7 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
320
323
|
|
|
321
324
|
return Number.parseInt(str.slice(0, -1))
|
|
322
325
|
}
|
|
323
|
-
function dateTimeValueIncrementation({ e, part, dateRef, prevValue
|
|
326
|
+
function dateTimeValueIncrementation({ e, part, dateRef, prevValue }: DateTimeValueIncrementation): number {
|
|
324
327
|
const step = props.step.value[part] ?? 1
|
|
325
328
|
const sign = e.key === kbd.ARROW_UP ? step : -step
|
|
326
329
|
|
|
@@ -328,7 +331,9 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
328
331
|
return dateRef[part as keyof Omit<DateFields, 'era'>]
|
|
329
332
|
|
|
330
333
|
if (part === 'hour' && 'hour' in dateRef) {
|
|
331
|
-
|
|
334
|
+
// Don't pass hourCycle to cycle - internal representation is always 24-hour
|
|
335
|
+
// The hourCycle prop only affects display, not internal cycling
|
|
336
|
+
const cycleArgs: [keyof DateFields | keyof TimeFields, number] = [part, sign]
|
|
332
337
|
return dateRef.set({ [part as keyof DateValue]: prevValue }).cycle(...cycleArgs)[part]
|
|
333
338
|
}
|
|
334
339
|
|
|
@@ -507,8 +512,7 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
507
512
|
return { value: total, moveToNext }
|
|
508
513
|
}
|
|
509
514
|
|
|
510
|
-
function updateHour(num: number, prev: number | null) {
|
|
511
|
-
const max = 24
|
|
515
|
+
function updateHour(max: number, num: number, prev: number | null) {
|
|
512
516
|
let moveToNext = false
|
|
513
517
|
const maxStart = Math.floor(max / 10)
|
|
514
518
|
|
|
@@ -714,6 +718,11 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
714
718
|
}
|
|
715
719
|
}
|
|
716
720
|
|
|
721
|
+
function uses12HourFormat(locale: string): boolean {
|
|
722
|
+
const hourCycle = new DateFormatter(locale, { hour: 'numeric' }).resolvedOptions().hourCycle
|
|
723
|
+
return hourCycle === 'h11' || hourCycle === 'h12'
|
|
724
|
+
}
|
|
725
|
+
|
|
717
726
|
function handleHourSegmentKeydown(e: KeyboardEvent) {
|
|
718
727
|
const dateRef = props.placeholder.value
|
|
719
728
|
if (!isAcceptableSegmentKey(e.key) || isSegmentNavigationKey(e.key) || !('hour' in dateRef) || !('hour' in props.segmentValues.value))
|
|
@@ -721,16 +730,14 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
721
730
|
|
|
722
731
|
const prevValue = props.segmentValues.value.hour
|
|
723
732
|
|
|
724
|
-
const hourCycle = props.hourCycle
|
|
725
|
-
|
|
726
733
|
if (e.key === kbd.ARROW_UP || e.key === kbd.ARROW_DOWN) {
|
|
727
|
-
|
|
734
|
+
const newHour = dateTimeValueIncrementation({ e, part: 'hour', dateRef: props.placeholder.value, prevValue })
|
|
735
|
+
props.segmentValues.value.hour = newHour
|
|
728
736
|
|
|
729
|
-
if ('dayPeriod' in props.segmentValues.value) {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
props.segmentValues.value.dayPeriod = 'PM'
|
|
737
|
+
if ('dayPeriod' in props.segmentValues.value && newHour !== null) {
|
|
738
|
+
// Determine AM/PM based on internal 24-hour value
|
|
739
|
+
// Hour 0-11 = AM, Hour 12-23 = PM
|
|
740
|
+
props.segmentValues.value.dayPeriod = newHour >= 12 ? 'PM' : 'AM'
|
|
734
741
|
}
|
|
735
742
|
|
|
736
743
|
return
|
|
@@ -738,14 +745,29 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
738
745
|
|
|
739
746
|
if (isNumberString(e.key)) {
|
|
740
747
|
const num = Number.parseInt(e.key)
|
|
741
|
-
const
|
|
748
|
+
const is12Hour = uses12HourFormat(props.formatter.getLocale())
|
|
749
|
+
const max = is12Hour ? 12 : 24
|
|
742
750
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
751
|
+
let displayPrev = prevValue
|
|
752
|
+
if (is12Hour && prevValue !== null) {
|
|
753
|
+
displayPrev = prevValue === 0 ? 12 : (prevValue > 12 ? prevValue - 12 : prevValue)
|
|
754
|
+
}
|
|
747
755
|
|
|
748
|
-
|
|
756
|
+
const { value, moveToNext } = updateHour(max, num, displayPrev)
|
|
757
|
+
|
|
758
|
+
// Convert display hour back to internal 24-hour format
|
|
759
|
+
let internalValue = value
|
|
760
|
+
if (is12Hour && value !== null) {
|
|
761
|
+
const period = props.segmentValues.value.dayPeriod || 'AM'
|
|
762
|
+
if (value === 12) {
|
|
763
|
+
internalValue = period === 'AM' ? 0 : 12
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
internalValue = period === 'PM' ? value + 12 : value
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
props.segmentValues.value.hour = internalValue
|
|
749
771
|
|
|
750
772
|
if (moveToNext)
|
|
751
773
|
props.focusNext()
|
|
@@ -881,9 +903,36 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
881
903
|
}
|
|
882
904
|
}
|
|
883
905
|
|
|
906
|
+
function handleSegmentFocusOut() {
|
|
907
|
+
if (!props.stepSnapping?.value)
|
|
908
|
+
return
|
|
909
|
+
|
|
910
|
+
if (props.part === 'hour' && 'hour' in props.segmentValues.value && props.segmentValues.value.hour !== null && props.step.value.hour && props.step.value.hour > 1) {
|
|
911
|
+
props.segmentValues.value.hour = snapValueToStep(props.segmentValues.value.hour, 0, 23, props.step.value.hour)
|
|
912
|
+
if ('dayPeriod' in props.segmentValues.value) {
|
|
913
|
+
if (props.segmentValues.value.hour < 12)
|
|
914
|
+
props.segmentValues.value.dayPeriod = 'AM'
|
|
915
|
+
else if (props.segmentValues.value.hour)
|
|
916
|
+
props.segmentValues.value.dayPeriod = 'PM'
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
else if (props.part === 'minute' && 'minute' in props.segmentValues.value && props.segmentValues.value.minute !== null && props.step.value.minute && props.step.value.minute > 1) {
|
|
920
|
+
props.segmentValues.value.minute = snapValueToStep(props.segmentValues.value.minute, 0, 59, props.step.value.minute)
|
|
921
|
+
}
|
|
922
|
+
else if (props.part === 'second' && 'second' in props.segmentValues.value && props.segmentValues.value.second !== null && props.step.value.second && props.step.value.second > 1) {
|
|
923
|
+
props.segmentValues.value.second = snapValueToStep(props.segmentValues.value.second, 0, 59, props.step.value.second)
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (Object.values(props.segmentValues.value).every(item => item !== null)) {
|
|
927
|
+
const dateRef = props.placeholder.value.set({ ...props.segmentValues.value as Record<AnyExceptLiteral, number> })
|
|
928
|
+
props.modelValue.value = dateRef.copy()
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
|
|
884
932
|
return {
|
|
885
933
|
handleSegmentClick,
|
|
886
934
|
handleSegmentKeydown,
|
|
935
|
+
handleSegmentFocusOut,
|
|
887
936
|
attributes,
|
|
888
937
|
}
|
|
889
938
|
}
|
package/src/shared/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from './arrays'
|
|
|
2
2
|
export * from './browser'
|
|
3
3
|
export * from './clamp'
|
|
4
4
|
export { createContext } from './createContext'
|
|
5
|
-
export { type DateRange, type DateStep, type DateValue, type SegmentPart } from './date'
|
|
5
|
+
export { type DateRange, type DateStep, type DateValue, type SegmentPart, type TimeValue } from './date'
|
|
6
6
|
export { getActiveElement } from './getActiveElement'
|
|
7
7
|
export { handleAndDispatchCustomEvent } from './handleAndDispatchCustomEvent'
|
|
8
8
|
export { isValidVNodeElement } from './isValidVNodeElement'
|
|
@@ -105,8 +105,8 @@ export function useDateFormatter(initialLocale: string, opts: DateFormatterOptio
|
|
|
105
105
|
minute: 'numeric',
|
|
106
106
|
}).formatToParts(date)
|
|
107
107
|
const value = parts.find(p => p.type === 'dayPeriod')?.value
|
|
108
|
-
// Day period can be "AM"/"PM" or "a.m."/"p.m." in some locales
|
|
109
|
-
if (value === 'PM' || value === 'p.m.')
|
|
108
|
+
// Day period can be "AM"/"PM" or "am"/"pm" or "a.m."/"p.m." in some locales
|
|
109
|
+
if (value === 'PM' || value === 'pm' || value === 'p.m.')
|
|
110
110
|
return 'PM'
|
|
111
111
|
|
|
112
112
|
return 'AM'
|
|
@@ -25,7 +25,7 @@ export function useGraceArea(triggerElement: Ref<HTMLElement | undefined>, conta
|
|
|
25
25
|
const currentTarget = event.currentTarget as HTMLElement
|
|
26
26
|
const exitPoint = { x: event.clientX, y: event.clientY }
|
|
27
27
|
const exitSide = getExitSideFromRect(exitPoint, currentTarget.getBoundingClientRect())
|
|
28
|
-
const paddedExitPoints = getPaddedExitPoints(exitPoint, exitSide)
|
|
28
|
+
const paddedExitPoints = getPaddedExitPoints(exitPoint, exitSide, 1)
|
|
29
29
|
const hoverTargetPoints = getPointsFromRect(hoverTarget.getBoundingClientRect())
|
|
30
30
|
const graceArea = getHull([...paddedExitPoints, ...hoverTargetPoints])
|
|
31
31
|
pointerGraceArea.value = graceArea
|