reka-ui 2.9.7 → 2.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/Dialog/DialogOverlayImpl.cjs +2 -1
  2. package/dist/Dialog/DialogOverlayImpl.cjs.map +1 -1
  3. package/dist/Dialog/DialogOverlayImpl.js +3 -2
  4. package/dist/Dialog/DialogOverlayImpl.js.map +1 -1
  5. package/dist/FocusScope/FocusScope.cjs +2 -0
  6. package/dist/FocusScope/FocusScope.cjs.map +1 -1
  7. package/dist/FocusScope/FocusScope.js +2 -0
  8. package/dist/FocusScope/FocusScope.js.map +1 -1
  9. package/dist/Listbox/ListboxItem.cjs +7 -2
  10. package/dist/Listbox/ListboxItem.cjs.map +1 -1
  11. package/dist/Listbox/ListboxItem.js +7 -2
  12. package/dist/Listbox/ListboxItem.js.map +1 -1
  13. package/dist/Menu/MenuItemImpl.cjs +1 -1
  14. package/dist/Menu/MenuItemImpl.cjs.map +1 -1
  15. package/dist/Menu/MenuItemImpl.js +1 -1
  16. package/dist/Menu/MenuItemImpl.js.map +1 -1
  17. package/dist/NavigationMenu/NavigationMenuContentImpl.cjs +1 -0
  18. package/dist/NavigationMenu/NavigationMenuContentImpl.cjs.map +1 -1
  19. package/dist/NavigationMenu/NavigationMenuContentImpl.js +1 -0
  20. package/dist/NavigationMenu/NavigationMenuContentImpl.js.map +1 -1
  21. package/dist/Select/SelectContent.cjs +15 -2
  22. package/dist/Select/SelectContent.cjs.map +1 -1
  23. package/dist/Select/SelectContent.js +16 -3
  24. package/dist/Select/SelectContent.js.map +1 -1
  25. package/dist/constant.d.cts.map +1 -1
  26. package/dist/index2.d.ts.map +1 -1
  27. package/dist/index3.d.cts +15 -15
  28. package/dist/index4.d.cts +659 -659
  29. package/dist/index4.d.cts.map +1 -1
  30. package/dist/index4.d.ts +663 -663
  31. package/dist/index4.d.ts.map +1 -1
  32. package/dist/internal.d.cts +2 -2
  33. package/dist/internal.d.ts +2 -2
  34. package/dist/internal.d.ts.map +1 -1
  35. package/package.json +2 -2
  36. package/src/Calendar/CalendarRoot.vue +1 -1
  37. package/src/DateRangeField/DateRangeFieldRoot.vue +1 -1
  38. package/src/Dialog/DialogOverlayImpl.vue +1 -0
  39. package/src/FocusScope/FocusScope.vue +5 -0
  40. package/src/Listbox/ListboxItem.vue +2 -2
  41. package/src/Menu/MenuItemImpl.vue +1 -1
  42. package/src/MonthPicker/MonthPickerRoot.vue +1 -1
  43. package/src/NavigationMenu/NavigationMenuContentImpl.vue +3 -0
  44. package/src/NavigationMenu/__test__/NavigationMenuUnmountOnHideFalse.vue +45 -0
  45. package/src/Select/SelectContent.vue +19 -3
  46. package/src/Select/__test__/SelectUnmountCleanup.vue +43 -0
  47. package/src/YearPicker/YearPickerRoot.vue +1 -1
@@ -1,7 +1,7 @@
1
1
  import "./index2.cjs";
2
2
  import "./index3.cjs";
3
3
  import { MenuArrowProps, MenuCheckboxItemEmits, MenuCheckboxItemProps, MenuContentEmits, MenuContentProps, MenuEmits, MenuGroupProps, MenuItemEmits, MenuItemIndicatorProps, MenuItemProps, MenuLabelProps, MenuPortalProps, MenuProps, MenuRadioGroupEmits, MenuRadioGroupProps, MenuRadioItemEmits, MenuRadioItemProps, MenuSeparatorProps, MenuSubContentEmits, MenuSubContentProps, MenuSubEmits, MenuSubProps, MenuSubTriggerProps, PopperAnchorProps, _default$277 as _default$13, _default$278 as _default$8, _default$279 as _default, _default$280 as _default$6, _default$281 as _default$10, _default$282 as _default$3, _default$283 as _default$14, _default$284 as _default$12, _default$285 as _default$2, _default$286 as _default$1, _default$287 as _default$11, _default$288 as _default$7, _default$290 as _default$9, _default$291 as _default$4, _default$292 as _default$5, injectMenuContext, injectMenuRootContext } from "./index4.cjs";
4
- import * as vue785 from "vue";
4
+ import * as vue136 from "vue";
5
5
 
6
6
  //#region src/Menu/MenuAnchor.vue.d.ts
7
7
  interface MenuAnchorProps extends PopperAnchorProps {}
@@ -9,7 +9,7 @@ declare var __VLS_8: {};
9
9
  type __VLS_Slots = {} & {
10
10
  default?: (props: typeof __VLS_8) => any;
11
11
  };
12
- declare const __VLS_base: vue785.DefineComponent<MenuAnchorProps, {}, {}, {}, {}, vue785.ComponentOptionsMixin, vue785.ComponentOptionsMixin, {}, string, vue785.PublicProps, Readonly<MenuAnchorProps> & Readonly<{}>, {}, {}, {}, {}, string, vue785.ComponentProvideOptions, false, {}, any>;
12
+ declare const __VLS_base: vue136.DefineComponent<MenuAnchorProps, {}, {}, {}, {}, vue136.ComponentOptionsMixin, vue136.ComponentOptionsMixin, {}, string, vue136.PublicProps, Readonly<MenuAnchorProps> & Readonly<{}>, {}, {}, {}, {}, string, vue136.ComponentProvideOptions, false, {}, any>;
13
13
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
14
  declare const _default$15: typeof __VLS_export;
15
15
  type __VLS_WithSlots<T, S> = T & {
@@ -1,7 +1,7 @@
1
1
  import "./index2.js";
2
2
  import "./index3.js";
3
3
  import { MenuArrowProps, MenuCheckboxItemEmits, MenuCheckboxItemProps, MenuContentEmits, MenuContentProps, MenuEmits, MenuGroupProps, MenuItemEmits, MenuItemIndicatorProps, MenuItemProps, MenuLabelProps, MenuPortalProps, MenuProps, MenuRadioGroupEmits, MenuRadioGroupProps, MenuRadioItemEmits, MenuRadioItemProps, MenuSeparatorProps, MenuSubContentEmits, MenuSubContentProps, MenuSubEmits, MenuSubProps, MenuSubTriggerProps, PopperAnchorProps, _default$277 as _default$13, _default$278 as _default$8, _default$279 as _default, _default$280 as _default$6, _default$281 as _default$10, _default$282 as _default$3, _default$283 as _default$14, _default$284 as _default$12, _default$285 as _default$2, _default$286 as _default$1, _default$287 as _default$11, _default$288 as _default$7, _default$290 as _default$9, _default$291 as _default$4, _default$292 as _default$5, injectMenuContext, injectMenuRootContext } from "./index4.js";
4
- import * as vue1111 from "vue";
4
+ import * as vue50 from "vue";
5
5
 
6
6
  //#region src/Menu/MenuAnchor.vue.d.ts
7
7
  interface MenuAnchorProps extends PopperAnchorProps {}
@@ -9,7 +9,7 @@ declare var __VLS_8: {};
9
9
  type __VLS_Slots = {} & {
10
10
  default?: (props: typeof __VLS_8) => any;
11
11
  };
12
- declare const __VLS_base: vue1111.DefineComponent<MenuAnchorProps, {}, {}, {}, {}, vue1111.ComponentOptionsMixin, vue1111.ComponentOptionsMixin, {}, string, vue1111.PublicProps, Readonly<MenuAnchorProps> & Readonly<{}>, {}, {}, {}, {}, string, vue1111.ComponentProvideOptions, false, {}, any>;
12
+ declare const __VLS_base: vue50.DefineComponent<MenuAnchorProps, {}, {}, {}, {}, vue50.ComponentOptionsMixin, vue50.ComponentOptionsMixin, {}, string, vue50.PublicProps, Readonly<MenuAnchorProps> & Readonly<{}>, {}, {}, {}, {}, string, vue50.ComponentProvideOptions, false, {}, any>;
13
13
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
14
  declare const _default$15: typeof __VLS_export;
15
15
  type __VLS_WithSlots<T, S> = T & {
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","names":[],"sources":["../src/Menu/MenuAnchor.vue"],"sourcesContent":[],"mappings":";;;;;;UAoBU,eAAA,SAAwB;YAsC9B;KACC,WAAA;2BACwB;AA3CoB,CAAA;AAGE,cA2C7C,UALgB,EAKN,OAAA,CAAA,eALM,CAKN,eALM,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAKN,OAAA,CAAA,qBAAA,EAAA,OAAA,CAAA,qBAAA,EALM,CAAA,CAAA,EAAA,MAAA,EAKN,OAAA,CAAA,WAAA,EAAA,QALM,CAKN,eALM,CAAA,GAKN,QALM,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,MAAA,EAKN,OAAA,CAAA,uBAAA,EALM,KAAA,EAAA,CAAA,CAAA,EAAA,GAAA,CAAA;AAAA,cAQhB,YAPU,EAOW,eANS,CAAA,OAMc,UANd,EAM0B,WAN1B,CAAA;AAAA,cAMM,WADxC,EAAA,OAE0B,YAF1B;KAGG,eALW,CAAA,CAAA,EAAA,CAAA,CAAA,GAKa,CALb,GAAA;EAAA,MAAA,EAAA;IAAA,MAAA,EAON,CAPM;EAAA,CAAA;CAAA"}
1
+ {"version":3,"file":"internal.d.ts","names":[],"sources":["../src/Menu/MenuAnchor.vue"],"sourcesContent":[],"mappings":";;;;;;UAoBU,eAAA,SAAwB;YAsC9B;KACC,WAAA;2BACwB;AA3CoB,CAAA;AAGE,cA2C7C,UALgB,EAKN,KAAA,CAAA,eALM,CAKN,eALM,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAKN,KAAA,CAAA,qBAAA,EAAA,KAAA,CAAA,qBAAA,EALM,CAAA,CAAA,EAAA,MAAA,EAKN,KAAA,CAAA,WAAA,EAAA,QALM,CAKN,eALM,CAAA,GAKN,QALM,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,MAAA,EAKN,KAAA,CAAA,uBAAA,EALM,KAAA,EAAA,CAAA,CAAA,EAAA,GAAA,CAAA;AAAA,cAQhB,YAPU,EAOW,eANS,CAAA,OAMc,UANd,EAM0B,WAN1B,CAAA;AAAA,cAMM,WADxC,EAAA,OAE0B,YAF1B;KAGG,eALW,CAAA,CAAA,EAAA,CAAA,CAAA,GAKa,CALb,GAAA;EAAA,MAAA,EAAA;IAAA,MAAA,EAON,CAPM;EAAA,CAAA;CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reka-ui",
3
3
  "type": "module",
4
- "version": "2.9.7",
4
+ "version": "2.9.8",
5
5
  "description": "Vue port for Radix UI Primitives.",
6
6
  "author": "UnoVue Contributors (https://github.com/unovue)",
7
7
  "license": "MIT",
@@ -118,7 +118,7 @@
118
118
  "jsdom": "^26.1.0",
119
119
  "size-limit": "^12.0.1",
120
120
  "tsdown": "^0.12.9",
121
- "vite": "^8.0.10",
121
+ "vite": "^8.0.12",
122
122
  "vitest": "^3.2.4",
123
123
  "vitest-axe": "0.1.0",
124
124
  "vitest-canvas-mock": "^0.3.3",
@@ -98,7 +98,7 @@ export interface CalendarRootProps extends PrimitiveProps {
98
98
  /** A function that returns the previous page of the calendar. It receives the current placeholder as an argument inside the component. */
99
99
  prevPage?: (placeholder: DateValue) => DateValue
100
100
  /** The controlled selected date value of the calendar. Can be bound as `v-model`. */
101
- modelValue?: DateValue | DateValue[] | undefined
101
+ modelValue?: DateValue | DateValue[] | null
102
102
  /** Whether multiple dates can be selected */
103
103
  multiple?: boolean
104
104
  /** Whether or not to disable days outside the current view. */
@@ -84,7 +84,7 @@ export interface DateRangeFieldRootProps extends PrimitiveProps, FormFieldProps
84
84
 
85
85
  export type DateRangeFieldRootEmits = {
86
86
  /** Event handler called whenever the model value changes */
87
- 'update:modelValue': [DateRange]
87
+ 'update:modelValue': [date: DateRange]
88
88
  /** Event handler called whenever the placeholder value changes */
89
89
  'update:placeholder': [date: DateValue]
90
90
  }
@@ -23,6 +23,7 @@ useForwardExpose()
23
23
  :as-child="asChild"
24
24
  :data-state="rootContext.open.value ? 'open' : 'closed'"
25
25
  style="pointer-events: auto"
26
+ @pointerdown.left.prevent
26
27
  >
27
28
  <slot />
28
29
  </Primitive>
@@ -185,6 +185,10 @@ watchEffect(async (cleanupFn) => {
185
185
  container.addEventListener(AUTOFOCUS_ON_UNMOUNT, unmountEventHandler)
186
186
  container.dispatchEvent(unmountEvent)
187
187
 
188
+ // Signal that blur events fired below are system-initiated (focus trap
189
+ // cleanup), not user-initiated. Consumers can use this to skip validation.
190
+ container.setAttribute('data-focus-scope-unmounting', '')
191
+
188
192
  setTimeout(() => {
189
193
  if (!unmountEvent.defaultPrevented)
190
194
  focus(previouslyFocusedElement ?? document.body, { select: true })
@@ -193,6 +197,7 @@ watchEffect(async (cleanupFn) => {
193
197
  container.removeEventListener(AUTOFOCUS_ON_UNMOUNT, unmountEventHandler)
194
198
 
195
199
  focusScopesStack.remove(focusScope)
200
+ container.removeAttribute('data-focus-scope-unmounting')
196
201
  }, 0)
197
202
  })
198
203
  })
@@ -44,7 +44,7 @@ const { CollectionItem } = useCollection()
44
44
  const { forwardRef, currentElement } = useForwardExpose()
45
45
  const rootContext = injectListboxRootContext()
46
46
 
47
- const isHighlighted = computed(() => currentElement.value === rootContext.highlightedElement.value)
47
+ const isHighlighted = computed(() => currentElement.value != null && currentElement.value === rootContext.highlightedElement.value)
48
48
  const isSelected = computed(() => valueComparator(rootContext.modelValue.value, props.value, rootContext.by))
49
49
 
50
50
  const disabled = computed(() => rootContext.disabled.value || props.disabled)
@@ -76,7 +76,7 @@ provideListboxItemContext({
76
76
  :id="id"
77
77
  v-bind="$attrs"
78
78
  :ref="forwardRef"
79
- v-memo="[isHighlighted, isSelected]"
79
+ v-memo="[isHighlighted, isSelected, disabled, rootContext.focusable.value]"
80
80
  role="option"
81
81
  :tabindex="rootContext.focusable.value ? isHighlighted ? '0' : '-1' : -1"
82
82
  :aria-selected="isSelected"
@@ -33,7 +33,7 @@ const { forwardRef, currentElement } = useForwardExpose()
33
33
  const { CollectionItem } = useCollection()
34
34
 
35
35
  const isFocused = ref(false)
36
- const isHighlighted = computed(() => isFocused.value || (contentContext.highlightedElement.value === currentElement.value))
36
+ const isHighlighted = computed(() => isFocused.value || (currentElement.value != null && contentContext.highlightedElement.value === currentElement.value))
37
37
 
38
38
  async function handlePointerMove(event: PointerEvent) {
39
39
  if (event.defaultPrevented || !isMouseEvent(event))
@@ -74,7 +74,7 @@ export interface MonthPickerRootProps extends PrimitiveProps {
74
74
  /** A function that returns the previous page of the month picker. Receives the current placeholder as an argument. */
75
75
  prevPage?: (placeholder: DateValue) => DateValue
76
76
  /** The controlled selected month value of the month picker. Can be bound as `v-model`. */
77
- modelValue?: DateValue | DateValue[] | undefined
77
+ modelValue?: DateValue | DateValue[] | null
78
78
  /** Whether multiple months can be selected */
79
79
  multiple?: boolean
80
80
  }
@@ -180,6 +180,9 @@ function handleKeydown(ev: KeyboardEvent) {
180
180
  }
181
181
 
182
182
  function handleDismiss() {
183
+ if (menuContext.modelValue.value !== itemContext.value)
184
+ return
185
+
183
186
  const rootContentDismissEvent = new Event(EVENT_ROOT_CONTENT_DISMISS, {
184
187
  bubbles: true,
185
188
  cancelable: true,
@@ -0,0 +1,45 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import {
4
+ NavigationMenuContent,
5
+ NavigationMenuItem,
6
+ NavigationMenuList,
7
+ NavigationMenuRoot,
8
+ NavigationMenuTrigger,
9
+ } from '..'
10
+
11
+ const modelValue = ref('')
12
+ </script>
13
+
14
+ <template>
15
+ <NavigationMenuRoot
16
+ v-model="modelValue"
17
+ :unmount-on-hide="false"
18
+ :disable-hover-trigger="true"
19
+ >
20
+ <span data-testid="model-value">{{ modelValue }}</span>
21
+ <NavigationMenuList>
22
+ <NavigationMenuItem value="one">
23
+ <NavigationMenuTrigger data-testid="trigger-one">
24
+ One
25
+ </NavigationMenuTrigger>
26
+ <NavigationMenuContent data-testid="content-one">
27
+ <button data-testid="inside-one">
28
+ Inside one
29
+ </button>
30
+ </NavigationMenuContent>
31
+ </NavigationMenuItem>
32
+
33
+ <NavigationMenuItem value="two">
34
+ <NavigationMenuTrigger data-testid="trigger-two">
35
+ Two
36
+ </NavigationMenuTrigger>
37
+ <NavigationMenuContent data-testid="content-two">
38
+ <button data-testid="inside-two">
39
+ Inside two
40
+ </button>
41
+ </NavigationMenuContent>
42
+ </NavigationMenuItem>
43
+ </NavigationMenuList>
44
+ </NavigationMenuRoot>
45
+ </template>
@@ -3,7 +3,7 @@ import type {
3
3
  SelectContentImplEmits,
4
4
  SelectContentImplProps,
5
5
  } from './SelectContentImpl.vue'
6
- import { computed, onMounted, ref, watch } from 'vue'
6
+ import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
7
7
 
8
8
  export type SelectContentEmits = SelectContentImplEmits
9
9
 
@@ -44,15 +44,31 @@ const presenceRef = ref<InstanceType<typeof Presence>>()
44
44
  const present = computed(() => props.forceMount || rootContext.open.value)
45
45
  const renderPresence = ref(present.value)
46
46
 
47
- watch(present, () => {
47
+ let renderPresenceTimeout: ReturnType<typeof setTimeout> | undefined
48
+
49
+ function clearRenderPresenceTimeout() {
50
+ if (renderPresenceTimeout) {
51
+ clearTimeout(renderPresenceTimeout)
52
+ renderPresenceTimeout = undefined
53
+ }
54
+ }
55
+
56
+ watch(present, (_value, _oldValue, onCleanup) => {
48
57
  // Toggle render presence after a delay (nextTick is not enough)
49
58
  // to allow children to re-render with the latest state.
50
59
  // Otherwise, they would remain in the old state during the transition,
51
60
  // which would prevent the animation that depend on state (e.g., data-[state=closed])
52
61
  // from being applied accurately.
53
62
  // @see https://github.com/unovue/reka-ui/issues/1865
54
- setTimeout(() => renderPresence.value = present.value)
63
+ clearRenderPresenceTimeout()
64
+ renderPresenceTimeout = setTimeout(() => {
65
+ renderPresence.value = present.value
66
+ renderPresenceTimeout = undefined
67
+ })
68
+ onCleanup(clearRenderPresenceTimeout)
55
69
  })
70
+
71
+ onUnmounted(clearRenderPresenceTimeout)
56
72
  </script>
57
73
 
58
74
  <template>
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import {
4
+ SelectContent,
5
+ SelectItem,
6
+ SelectItemText,
7
+ SelectPortal,
8
+ SelectRoot,
9
+ SelectTrigger,
10
+ SelectValue,
11
+ SelectViewport,
12
+ } from '..'
13
+
14
+ const open = ref(true)
15
+ const mounted = ref(true)
16
+ </script>
17
+
18
+ <template>
19
+ <button @click="open = false">
20
+ Close
21
+ </button>
22
+ <button @click="mounted = false">
23
+ Unmount
24
+ </button>
25
+
26
+ <SelectRoot
27
+ v-if="mounted"
28
+ v-model:open="open"
29
+ >
30
+ <SelectTrigger aria-label="Fruit">
31
+ <SelectValue placeholder="Please select a fruit" />
32
+ </SelectTrigger>
33
+ <SelectPortal>
34
+ <SelectContent position="popper">
35
+ <SelectViewport>
36
+ <SelectItem value="apple">
37
+ <SelectItemText>Apple</SelectItemText>
38
+ </SelectItem>
39
+ </SelectViewport>
40
+ </SelectContent>
41
+ </SelectPortal>
42
+ </SelectRoot>
43
+ </template>
@@ -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[] | undefined
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 */