reka-ui 2.9.7 → 2.9.9
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/Autocomplete/AutocompleteInput.cjs +12 -16
- package/dist/Autocomplete/AutocompleteInput.cjs.map +1 -1
- package/dist/Autocomplete/AutocompleteInput.js +13 -17
- package/dist/Autocomplete/AutocompleteInput.js.map +1 -1
- package/dist/ColorField/ColorFieldInput.cjs +10 -2
- package/dist/ColorField/ColorFieldInput.cjs.map +1 -1
- package/dist/ColorField/ColorFieldInput.js +10 -2
- package/dist/ColorField/ColorFieldInput.js.map +1 -1
- package/dist/Combobox/ComboboxInput.cjs +27 -9
- package/dist/Combobox/ComboboxInput.cjs.map +1 -1
- package/dist/Combobox/ComboboxInput.js +28 -10
- package/dist/Combobox/ComboboxInput.js.map +1 -1
- package/dist/DateField/DateFieldInput.cjs +4 -1
- package/dist/DateField/DateFieldInput.cjs.map +1 -1
- package/dist/DateField/DateFieldInput.js +4 -1
- package/dist/DateField/DateFieldInput.js.map +1 -1
- package/dist/DateField/DateFieldRoot.cjs +1 -0
- package/dist/DateField/DateFieldRoot.cjs.map +1 -1
- package/dist/DateField/DateFieldRoot.js +1 -0
- package/dist/DateField/DateFieldRoot.js.map +1 -1
- package/dist/DatePicker/DatePickerRoot.cjs +15 -1
- package/dist/DatePicker/DatePickerRoot.cjs.map +1 -1
- package/dist/DatePicker/DatePickerRoot.js +15 -1
- package/dist/DatePicker/DatePickerRoot.js.map +1 -1
- package/dist/DateRangeField/DateRangeFieldInput.cjs +4 -1
- package/dist/DateRangeField/DateRangeFieldInput.cjs.map +1 -1
- package/dist/DateRangeField/DateRangeFieldInput.js +4 -1
- package/dist/DateRangeField/DateRangeFieldInput.js.map +1 -1
- package/dist/DateRangeField/DateRangeFieldRoot.cjs +1 -0
- package/dist/DateRangeField/DateRangeFieldRoot.cjs.map +1 -1
- package/dist/DateRangeField/DateRangeFieldRoot.js +1 -0
- package/dist/DateRangeField/DateRangeFieldRoot.js.map +1 -1
- package/dist/Dialog/DialogOverlayImpl.cjs +6 -1
- package/dist/Dialog/DialogOverlayImpl.cjs.map +1 -1
- package/dist/Dialog/DialogOverlayImpl.js +7 -2
- package/dist/Dialog/DialogOverlayImpl.js.map +1 -1
- package/dist/DropdownMenu/DropdownMenuFilter.cjs +19 -2
- package/dist/DropdownMenu/DropdownMenuFilter.cjs.map +1 -1
- package/dist/DropdownMenu/DropdownMenuFilter.js +19 -2
- package/dist/DropdownMenu/DropdownMenuFilter.js.map +1 -1
- package/dist/FocusScope/FocusScope.cjs +2 -0
- package/dist/FocusScope/FocusScope.cjs.map +1 -1
- package/dist/FocusScope/FocusScope.js +2 -0
- package/dist/FocusScope/FocusScope.js.map +1 -1
- package/dist/Listbox/ListboxFilter.cjs +29 -10
- package/dist/Listbox/ListboxFilter.cjs.map +1 -1
- package/dist/Listbox/ListboxFilter.js +30 -11
- package/dist/Listbox/ListboxFilter.js.map +1 -1
- package/dist/Listbox/ListboxItem.cjs +7 -2
- package/dist/Listbox/ListboxItem.cjs.map +1 -1
- package/dist/Listbox/ListboxItem.js +7 -2
- package/dist/Listbox/ListboxItem.js.map +1 -1
- package/dist/Listbox/ListboxRoot.cjs +12 -6
- package/dist/Listbox/ListboxRoot.cjs.map +1 -1
- package/dist/Listbox/ListboxRoot.js +12 -6
- package/dist/Listbox/ListboxRoot.js.map +1 -1
- package/dist/Menu/MenuItemImpl.cjs +1 -1
- package/dist/Menu/MenuItemImpl.cjs.map +1 -1
- package/dist/Menu/MenuItemImpl.js +1 -1
- package/dist/Menu/MenuItemImpl.js.map +1 -1
- package/dist/NavigationMenu/NavigationMenuContentImpl.cjs +1 -0
- package/dist/NavigationMenu/NavigationMenuContentImpl.cjs.map +1 -1
- package/dist/NavigationMenu/NavigationMenuContentImpl.js +1 -0
- package/dist/NavigationMenu/NavigationMenuContentImpl.js.map +1 -1
- package/dist/NavigationMenu/NavigationMenuRoot.cjs +16 -3
- package/dist/NavigationMenu/NavigationMenuRoot.cjs.map +1 -1
- package/dist/NavigationMenu/NavigationMenuRoot.js +16 -3
- package/dist/NavigationMenu/NavigationMenuRoot.js.map +1 -1
- package/dist/NumberField/NumberFieldInput.cjs +46 -13
- package/dist/NumberField/NumberFieldInput.cjs.map +1 -1
- package/dist/NumberField/NumberFieldInput.js +47 -14
- package/dist/NumberField/NumberFieldInput.js.map +1 -1
- package/dist/PinInput/PinInputInput.cjs +37 -2
- package/dist/PinInput/PinInputInput.cjs.map +1 -1
- package/dist/PinInput/PinInputInput.js +37 -2
- package/dist/PinInput/PinInputInput.js.map +1 -1
- package/dist/ScrollArea/ScrollAreaScrollbarX.cjs +3 -0
- package/dist/ScrollArea/ScrollAreaScrollbarX.cjs.map +1 -1
- package/dist/ScrollArea/ScrollAreaScrollbarX.js +4 -1
- package/dist/ScrollArea/ScrollAreaScrollbarX.js.map +1 -1
- package/dist/ScrollArea/ScrollAreaScrollbarY.cjs +3 -0
- package/dist/ScrollArea/ScrollAreaScrollbarY.cjs.map +1 -1
- package/dist/ScrollArea/ScrollAreaScrollbarY.js +4 -1
- package/dist/ScrollArea/ScrollAreaScrollbarY.js.map +1 -1
- package/dist/Select/SelectContent.cjs +15 -2
- package/dist/Select/SelectContent.cjs.map +1 -1
- package/dist/Select/SelectContent.js +16 -3
- package/dist/Select/SelectContent.js.map +1 -1
- package/dist/TagsInput/TagsInputInput.cjs +12 -13
- package/dist/TagsInput/TagsInputInput.cjs.map +1 -1
- package/dist/TagsInput/TagsInputInput.js +13 -14
- package/dist/TagsInput/TagsInputInput.js.map +1 -1
- package/dist/TagsInput/TagsInputRoot.cjs +1 -0
- package/dist/TagsInput/TagsInputRoot.cjs.map +1 -1
- package/dist/TagsInput/TagsInputRoot.js +1 -0
- package/dist/TagsInput/TagsInputRoot.js.map +1 -1
- package/dist/TimeField/TimeFieldInput.cjs +4 -1
- package/dist/TimeField/TimeFieldInput.cjs.map +1 -1
- package/dist/TimeField/TimeFieldInput.js +4 -1
- package/dist/TimeField/TimeFieldInput.js.map +1 -1
- package/dist/TimeField/TimeFieldRoot.cjs +1 -0
- package/dist/TimeField/TimeFieldRoot.cjs.map +1 -1
- package/dist/TimeField/TimeFieldRoot.js +1 -0
- package/dist/TimeField/TimeFieldRoot.js.map +1 -1
- package/dist/TimeRangeField/TimeRangeFieldInput.cjs +4 -1
- package/dist/TimeRangeField/TimeRangeFieldInput.cjs.map +1 -1
- package/dist/TimeRangeField/TimeRangeFieldInput.js +4 -1
- package/dist/TimeRangeField/TimeRangeFieldInput.js.map +1 -1
- package/dist/TimeRangeField/TimeRangeFieldRoot.cjs +1 -0
- package/dist/TimeRangeField/TimeRangeFieldRoot.cjs.map +1 -1
- package/dist/TimeRangeField/TimeRangeFieldRoot.js +1 -0
- package/dist/TimeRangeField/TimeRangeFieldRoot.js.map +1 -1
- package/dist/date/useDateField.cjs +38 -0
- package/dist/date/useDateField.cjs.map +1 -1
- package/dist/date/useDateField.js +38 -0
- package/dist/date/useDateField.js.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.js +1 -0
- package/dist/index2.d.ts.map +1 -1
- package/dist/index3.d.cts +24 -16
- package/dist/index3.d.cts.map +1 -1
- package/dist/index3.d.ts +13 -5
- package/dist/index3.d.ts.map +1 -1
- package/dist/index4.d.cts +655 -655
- package/dist/index4.d.cts.map +1 -1
- package/dist/index4.d.ts +684 -684
- package/dist/index4.d.ts.map +1 -1
- package/dist/internal.cjs +1 -0
- package/dist/internal.d.cts +2 -2
- package/dist/internal.d.cts.map +1 -1
- package/dist/internal.d.ts +2 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/shared/useComposing.cjs +30 -0
- package/dist/shared/useComposing.cjs.map +1 -0
- package/dist/shared/useComposing.js +24 -0
- package/dist/shared/useComposing.js.map +1 -0
- package/dist/shared.cjs +2 -0
- package/dist/shared.d.cts +2 -2
- package/dist/shared.d.ts +2 -2
- package/dist/shared.js +2 -1
- package/package.json +4 -4
- package/src/Autocomplete/AutocompleteInput.vue +13 -17
- package/src/Calendar/CalendarRoot.vue +1 -1
- package/src/ColorField/ColorFieldInput.vue +11 -0
- package/src/Combobox/ComboboxInput.vue +37 -7
- package/src/DateField/DateFieldInput.vue +6 -0
- package/src/DateField/DateFieldRoot.vue +3 -0
- package/src/DatePicker/DatePickerRoot.vue +18 -2
- package/src/DateRangeField/DateRangeFieldInput.vue +6 -0
- package/src/DateRangeField/DateRangeFieldRoot.vue +4 -1
- package/src/Dialog/DialogOverlayImpl.vue +1 -0
- package/src/DropdownMenu/DropdownMenuFilter.vue +20 -1
- package/src/FocusScope/FocusScope.vue +5 -0
- package/src/Listbox/ListboxFilter.vue +39 -8
- package/src/Listbox/ListboxItem.vue +2 -2
- package/src/Listbox/ListboxRoot.vue +17 -4
- package/src/Menu/MenuItemImpl.vue +1 -1
- package/src/MonthPicker/MonthPickerRoot.vue +1 -1
- package/src/NavigationMenu/NavigationMenuContentImpl.vue +3 -0
- package/src/NavigationMenu/NavigationMenuRoot.vue +19 -3
- package/src/NavigationMenu/__test__/NavigationMenuUnmountOnHideFalse.vue +45 -0
- package/src/NumberField/NumberFieldInput.vue +45 -8
- package/src/PinInput/PinInputInput.vue +44 -1
- package/src/ScrollArea/ScrollAreaScrollbarX.vue +6 -1
- package/src/ScrollArea/ScrollAreaScrollbarY.vue +6 -1
- package/src/Select/SelectContent.vue +19 -3
- package/src/Select/__test__/SelectUnmountCleanup.vue +43 -0
- package/src/TagsInput/TagsInputInput.vue +16 -14
- package/src/TagsInput/TagsInputRoot.vue +3 -0
- package/src/TimeField/TimeFieldInput.vue +6 -0
- package/src/TimeField/TimeFieldRoot.vue +3 -0
- package/src/TimeRangeField/TimeRangeFieldInput.vue +6 -0
- package/src/TimeRangeField/TimeRangeFieldRoot.vue +3 -0
- package/src/YearPicker/YearPickerRoot.vue +1 -1
- package/src/shared/date/useDateField.ts +75 -1
- package/src/shared/index.ts +1 -0
- package/src/shared/useComposing.ts +18 -0
|
@@ -402,6 +402,9 @@ const prevFocusableSegment = computed(() => {
|
|
|
402
402
|
const kbd = useKbd()
|
|
403
403
|
|
|
404
404
|
function handleKeydown(e: KeyboardEvent) {
|
|
405
|
+
// Don't navigate between segments mid-composition, arrow keys are used for IME candidate navigation
|
|
406
|
+
if (e.isComposing)
|
|
407
|
+
return
|
|
405
408
|
if (!isSegmentNavigationKey(e.key))
|
|
406
409
|
return
|
|
407
410
|
if (e.key === kbd.ARROW_LEFT)
|
|
@@ -75,7 +75,7 @@ export interface YearPickerRootProps extends PrimitiveProps {
|
|
|
75
75
|
/** A function that returns the previous page of the year picker. Receives the current placeholder as an argument. */
|
|
76
76
|
prevPage?: (placeholder: DateValue) => DateValue
|
|
77
77
|
/** The controlled selected year value of the year picker. Can be bound as `v-model`. */
|
|
78
|
-
modelValue?: DateValue | DateValue[] |
|
|
78
|
+
modelValue?: DateValue | DateValue[] | null
|
|
79
79
|
/** Whether multiple years can be selected */
|
|
80
80
|
multiple?: boolean
|
|
81
81
|
/** Number of years to display per page */
|
|
@@ -7,9 +7,11 @@ import {
|
|
|
7
7
|
} from '@internationalized/date'
|
|
8
8
|
import { computed } from 'vue'
|
|
9
9
|
import { getDaysInMonth, toDate } from '@/date'
|
|
10
|
-
import { snapValueToStep, useKbd } from '@/shared'
|
|
10
|
+
import { getActiveElement, snapValueToStep, useKbd } from '@/shared'
|
|
11
11
|
import { isAcceptableSegmentKey, isNumberString, isSegmentNavigationKey } from './segment'
|
|
12
12
|
|
|
13
|
+
const DIGIT_REG = /^\d$/
|
|
14
|
+
|
|
13
15
|
type MinuteSecondIncrementProps = {
|
|
14
16
|
e: KeyboardEvent
|
|
15
17
|
part: keyof TimeFields
|
|
@@ -877,6 +879,13 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
877
879
|
}
|
|
878
880
|
|
|
879
881
|
function handleSegmentKeydown(e: KeyboardEvent) {
|
|
882
|
+
// A genuine composition keydown sets `isComposing` or reports `key === 'Process'`.
|
|
883
|
+
// Don't use `keyCode === 229` alone: a CJK IME (e.g. Pinyin) keeps that flag set
|
|
884
|
+
// while passing a directly-typed key through, so a real digit (`key === '1'`)
|
|
885
|
+
// would be dropped and leak into the contenteditable as raw text.
|
|
886
|
+
if (e.isComposing || e.key === 'Process')
|
|
887
|
+
return
|
|
888
|
+
|
|
880
889
|
const disabled = props.disabled.value
|
|
881
890
|
const readonly = props.readonly.value
|
|
882
891
|
if (disabled || readonly)
|
|
@@ -935,9 +944,74 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
935
944
|
}
|
|
936
945
|
}
|
|
937
946
|
|
|
947
|
+
// Snapshot of the segment's child nodes (and their text) before the IME mutates
|
|
948
|
+
// the contenteditable. Vue renders the value into one text node but may keep
|
|
949
|
+
// empty sibling text nodes around it, so we must preserve EVERY node it owns and
|
|
950
|
+
// restore them verbatim on `compositionend`. Recreating nodes (textContent) would
|
|
951
|
+
// detach Vue's binding and freeze the segment; recreating the element isn't an
|
|
952
|
+
// option either, since the root captures segment elements once via
|
|
953
|
+
// `getSegmentElements` and a fresh node would break navigation.
|
|
954
|
+
let preCompositionNodes: { node: ChildNode, value: string | null }[] | null = null
|
|
955
|
+
|
|
956
|
+
function handleSegmentBeforeInput(e: InputEvent) {
|
|
957
|
+
// The segment's text is driven programmatically (keydown -> segmentValues ->
|
|
958
|
+
// Vue render), so the contenteditable must never be edited directly. Safari
|
|
959
|
+
// dispatches `beforeinput`/`input` BEFORE `keydown` while an IME is active,
|
|
960
|
+
// so a passed-through key (e.g. a digit typed while Pinyin is selected) would
|
|
961
|
+
// leak into the DOM as raw text before `handleSegmentKeydown` can prevent it.
|
|
962
|
+
// Composition input keeps `isComposing` true, so let it through and reconcile
|
|
963
|
+
// on `compositionend`.
|
|
964
|
+
if (!e.isComposing)
|
|
965
|
+
e.preventDefault()
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
function handleSegmentCompositionStart(e: CompositionEvent) {
|
|
969
|
+
const el = e.target as HTMLElement
|
|
970
|
+
preCompositionNodes = Array.from(el.childNodes, node => ({ node, value: node.nodeValue }))
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
function handleSegmentCompositionEnd(e: CompositionEvent) {
|
|
974
|
+
const el = e.target as HTMLElement
|
|
975
|
+
const original = preCompositionNodes
|
|
976
|
+
preCompositionNodes = null
|
|
977
|
+
|
|
978
|
+
// Restore Vue's original nodes (with their text) and drop anything the IME
|
|
979
|
+
// inserted, keeping Vue's bindings intact so later renders still patch the DOM.
|
|
980
|
+
// When no composition was tracked (e.g. synthetic events in tests) leave it be.
|
|
981
|
+
if (original) {
|
|
982
|
+
for (const { node, value } of original)
|
|
983
|
+
node.nodeValue = value
|
|
984
|
+
el.replaceChildren(...original.map(o => o.node))
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
const data = e.data
|
|
988
|
+
if (!data)
|
|
989
|
+
return
|
|
990
|
+
|
|
991
|
+
for (const char of data) {
|
|
992
|
+
if (!DIGIT_REG.test(char))
|
|
993
|
+
continue
|
|
994
|
+
|
|
995
|
+
// Dispatch to the focused segment so subsequent digits follow focus
|
|
996
|
+
// after `focusNext()` advances to the next segment (e.g. "34" → 3 in day, 4 in month).
|
|
997
|
+
const target = getActiveElement()
|
|
998
|
+
if (!(target instanceof HTMLElement))
|
|
999
|
+
break
|
|
1000
|
+
|
|
1001
|
+
target.dispatchEvent(new KeyboardEvent('keydown', {
|
|
1002
|
+
key: char,
|
|
1003
|
+
bubbles: true,
|
|
1004
|
+
cancelable: true,
|
|
1005
|
+
}))
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
938
1009
|
return {
|
|
939
1010
|
handleSegmentClick,
|
|
940
1011
|
handleSegmentKeydown,
|
|
1012
|
+
handleSegmentBeforeInput,
|
|
1013
|
+
handleSegmentCompositionStart,
|
|
1014
|
+
handleSegmentCompositionEnd,
|
|
941
1015
|
handleSegmentFocusOut,
|
|
942
1016
|
attributes,
|
|
943
1017
|
}
|
package/src/shared/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { renderSlotFragments } from './renderSlotFragments'
|
|
|
14
14
|
export { trapFocus } from './trap-focus'
|
|
15
15
|
export { useArrowNavigation } from './useArrowNavigation'
|
|
16
16
|
export { useBodyScrollLock } from './useBodyScrollLock'
|
|
17
|
+
export { useComposing } from './useComposing'
|
|
17
18
|
export { type Formatter, useDateFormatter } from './useDateFormatter'
|
|
18
19
|
export { useDirection } from './useDirection'
|
|
19
20
|
export { useEmitAsProps } from './useEmitAsProps'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { nextTick, ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export function useComposing(onEnd?: (event: CompositionEvent) => void) {
|
|
4
|
+
const isComposing = ref(false)
|
|
5
|
+
|
|
6
|
+
function handleCompositionStart() {
|
|
7
|
+
isComposing.value = true
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function handleCompositionEnd(event: CompositionEvent) {
|
|
11
|
+
nextTick(() => {
|
|
12
|
+
isComposing.value = false
|
|
13
|
+
onEnd?.(event)
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return { isComposing, handleCompositionStart, handleCompositionEnd }
|
|
18
|
+
}
|