reka-ui 2.0.2 → 2.1.1

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 (95) hide show
  1. package/dist/AlertDialog/AlertDialogRoot.cjs +2 -2
  2. package/dist/AlertDialog/AlertDialogRoot.cjs.map +1 -1
  3. package/dist/AlertDialog/AlertDialogRoot.js +3 -3
  4. package/dist/AlertDialog/AlertDialogRoot.js.map +1 -1
  5. package/dist/Calendar/CalendarCellTrigger.cjs +7 -5
  6. package/dist/Calendar/CalendarCellTrigger.cjs.map +1 -1
  7. package/dist/Calendar/CalendarCellTrigger.js +7 -5
  8. package/dist/Calendar/CalendarCellTrigger.js.map +1 -1
  9. package/dist/Combobox/ComboboxItem.cjs +0 -3
  10. package/dist/Combobox/ComboboxItem.cjs.map +1 -1
  11. package/dist/Combobox/ComboboxItem.js +1 -3
  12. package/dist/Combobox/ComboboxItem.js.map +1 -1
  13. package/dist/Combobox/ComboboxRoot.cjs +9 -1
  14. package/dist/Combobox/ComboboxRoot.cjs.map +1 -1
  15. package/dist/Combobox/ComboboxRoot.js +10 -2
  16. package/dist/Combobox/ComboboxRoot.js.map +1 -1
  17. package/dist/HoverCard/HoverCardRoot.cjs.map +1 -1
  18. package/dist/HoverCard/HoverCardRoot.js.map +1 -1
  19. package/dist/NavigationMenu/NavigationMenuSub.cjs +11 -1
  20. package/dist/NavigationMenu/NavigationMenuSub.cjs.map +1 -1
  21. package/dist/NavigationMenu/NavigationMenuSub.js +12 -2
  22. package/dist/NavigationMenu/NavigationMenuSub.js.map +1 -1
  23. package/dist/NavigationMenu/NavigationMenuViewport.cjs +2 -3
  24. package/dist/NavigationMenu/NavigationMenuViewport.cjs.map +1 -1
  25. package/dist/NavigationMenu/NavigationMenuViewport.js +2 -3
  26. package/dist/NavigationMenu/NavigationMenuViewport.js.map +1 -1
  27. package/dist/NumberField/NumberFieldInput.cjs +2 -0
  28. package/dist/NumberField/NumberFieldInput.cjs.map +1 -1
  29. package/dist/NumberField/NumberFieldInput.js +2 -0
  30. package/dist/NumberField/NumberFieldInput.js.map +1 -1
  31. package/dist/NumberField/NumberFieldRoot.cjs +5 -2
  32. package/dist/NumberField/NumberFieldRoot.cjs.map +1 -1
  33. package/dist/NumberField/NumberFieldRoot.js +5 -2
  34. package/dist/NumberField/NumberFieldRoot.js.map +1 -1
  35. package/dist/RangeCalendar/RangeCalendarCellTrigger.cjs +6 -4
  36. package/dist/RangeCalendar/RangeCalendarCellTrigger.cjs.map +1 -1
  37. package/dist/RangeCalendar/RangeCalendarCellTrigger.js +6 -4
  38. package/dist/RangeCalendar/RangeCalendarCellTrigger.js.map +1 -1
  39. package/dist/RangeCalendar/RangeCalendarRoot.cjs +3 -3
  40. package/dist/RangeCalendar/RangeCalendarRoot.cjs.map +1 -1
  41. package/dist/RangeCalendar/RangeCalendarRoot.js +3 -3
  42. package/dist/RangeCalendar/RangeCalendarRoot.js.map +1 -1
  43. package/dist/Select/SelectContentImpl.cjs +15 -5
  44. package/dist/Select/SelectContentImpl.cjs.map +1 -1
  45. package/dist/Select/SelectContentImpl.js +15 -5
  46. package/dist/Select/SelectContentImpl.js.map +1 -1
  47. package/dist/Slider/SliderHorizontal.cjs +19 -9
  48. package/dist/Slider/SliderHorizontal.cjs.map +1 -1
  49. package/dist/Slider/SliderHorizontal.js +20 -10
  50. package/dist/Slider/SliderHorizontal.js.map +1 -1
  51. package/dist/Slider/SliderRoot.cjs +5 -3
  52. package/dist/Slider/SliderRoot.cjs.map +1 -1
  53. package/dist/Slider/SliderRoot.js +5 -3
  54. package/dist/Slider/SliderRoot.js.map +1 -1
  55. package/dist/Slider/SliderThumb.cjs +2 -2
  56. package/dist/Slider/SliderThumb.cjs.map +1 -1
  57. package/dist/Slider/SliderThumb.js +2 -2
  58. package/dist/Slider/SliderThumb.js.map +1 -1
  59. package/dist/Slider/SliderThumbImpl.cjs +7 -1
  60. package/dist/Slider/SliderThumbImpl.cjs.map +1 -1
  61. package/dist/Slider/SliderThumbImpl.js +7 -1
  62. package/dist/Slider/SliderThumbImpl.js.map +1 -1
  63. package/dist/Slider/SliderVertical.cjs +19 -9
  64. package/dist/Slider/SliderVertical.cjs.map +1 -1
  65. package/dist/Slider/SliderVertical.js +20 -10
  66. package/dist/Slider/SliderVertical.js.map +1 -1
  67. package/dist/TagsInput/TagsInputItemDelete.cjs +2 -1
  68. package/dist/TagsInput/TagsInputItemDelete.cjs.map +1 -1
  69. package/dist/TagsInput/TagsInputItemDelete.js +2 -1
  70. package/dist/TagsInput/TagsInputItemDelete.js.map +1 -1
  71. package/dist/Toast/ToastClose.cjs +2 -2
  72. package/dist/Toast/ToastClose.cjs.map +1 -1
  73. package/dist/Toast/ToastClose.js +2 -2
  74. package/dist/Toast/ToastClose.js.map +1 -1
  75. package/dist/Toast/ToastRoot.cjs +3 -0
  76. package/dist/Toast/ToastRoot.cjs.map +1 -1
  77. package/dist/Toast/ToastRoot.js +3 -0
  78. package/dist/Toast/ToastRoot.js.map +1 -1
  79. package/dist/Toast/ToastRootImpl.cjs +6 -3
  80. package/dist/Toast/ToastRootImpl.cjs.map +1 -1
  81. package/dist/Toast/ToastRootImpl.js +6 -3
  82. package/dist/Toast/ToastRootImpl.js.map +1 -1
  83. package/dist/Toggle/Toggle.cjs +6 -1
  84. package/dist/Toggle/Toggle.cjs.map +1 -1
  85. package/dist/Toggle/Toggle.js +6 -1
  86. package/dist/Toggle/Toggle.js.map +1 -1
  87. package/dist/ToggleGroup/ToggleGroupItem.cjs +2 -2
  88. package/dist/ToggleGroup/ToggleGroupItem.cjs.map +1 -1
  89. package/dist/ToggleGroup/ToggleGroupItem.js +3 -3
  90. package/dist/ToggleGroup/ToggleGroupItem.js.map +1 -1
  91. package/dist/date.d.ts +2 -0
  92. package/dist/index.cjs +4 -4
  93. package/dist/index.d.ts +59 -16
  94. package/dist/index.js +2 -2
  95. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationMenuSub.cjs","sources":["../../src/NavigationMenu/NavigationMenuSub.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { Orientation } from './utils'\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useCollection } from '@/Collection'\n\nexport type NavigationMenuSubEmits = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: string]\n}\n\nexport interface NavigationMenuSubProps extends PrimitiveProps {\n /** The controlled value of the sub menu item to activate. Can be used as `v-model`. */\n modelValue?: string\n /**\n * The value of the menu item that should be active when initially rendered.\n *\n * Use when you do not need to control the value state.\n */\n defaultValue?: string\n /** The orientation of the menu. */\n orientation?: Orientation\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { useVModel } from '@vueuse/core'\nimport { injectNavigationMenuContext, provideNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nconst props = withDefaults(defineProps<NavigationMenuSubProps>(), {\n orientation: 'horizontal',\n})\nconst emits = defineEmits<NavigationMenuSubEmits>()\n\ndefineSlots<{\n default: (props: {\n /** Current input values */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue ?? '',\n passive: (props.modelValue === undefined) as false,\n}) as Ref<string>\nconst previousValue = ref('')\n\nconst menuContext = injectNavigationMenuContext()\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst indicatorTrack = ref<HTMLElement>()\nconst viewport = ref<HTMLElement>()\n\nconst { CollectionSlot } = useCollection({ key: 'NavigationMenu', isProvider: true })\n\nprovideNavigationMenuContext({\n ...menuContext,\n isRootMenu: false,\n modelValue,\n previousValue,\n orientation: props.orientation,\n rootNavigationMenu: currentElement,\n indicatorTrack,\n onIndicatorTrackChange: (val) => {\n indicatorTrack.value = val\n },\n viewport,\n onViewportChange: (val) => {\n viewport.value = val\n },\n\n onTriggerEnter: (val) => {\n modelValue.value = val\n },\n onTriggerLeave: () => {\n // do nothing for submenu\n },\n onContentEnter: () => {\n // do nothing for submenu\n },\n onContentLeave: () => {\n // do nothing for submenu\n },\n onItemSelect: (val) => {\n modelValue.value = val\n },\n onItemDismiss: () => {\n modelValue.value = ''\n },\n})\n</script>\n\n<template>\n <CollectionSlot>\n <Primitive\n :ref=\"forwardRef\"\n :data-orientation=\"orientation\"\n :as-child=\"props.asChild\"\n :as=\"as\"\n data-reka-navigation-menu\n >\n <slot :model-value=\"modelValue\" />\n </Primitive>\n </CollectionSlot>\n</template>\n"],"names":["useVModel","ref","injectNavigationMenuContext","useForwardExpose","useCollection","provideNavigationMenuContext"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkCA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAGd,IAAA,MAAM,KAAQ,GAAA,MAAA;AASd,IAAA,MAAM,UAAa,GAAAA,cAAA,CAAU,KAAO,EAAA,YAAA,EAAc,KAAO,EAAA;AAAA,MACvD,YAAA,EAAc,MAAM,YAAgB,IAAA,EAAA;AAAA,MACpC,OAAA,EAAU,MAAM,UAAe,KAAA;AAAA,KAChC,CAAA;AACD,IAAM,MAAA,aAAA,GAAgBC,QAAI,EAAE,CAAA;AAE5B,IAAA,MAAM,cAAcC,6DAA4B,EAAA;AAChD,IAAA,MAAM,EAAE,UAAA,EAAY,cAAe,EAAA,GAAIC,wCAAiB,EAAA;AAExD,IAAA,MAAM,iBAAiBF,OAAiB,EAAA;AACxC,IAAA,MAAM,WAAWA,OAAiB,EAAA;AAElC,IAAM,MAAA,EAAE,gBAAmB,GAAAG,mCAAA,CAAc,EAAE,GAAK,EAAA,gBAAA,EAAkB,UAAY,EAAA,IAAA,EAAM,CAAA;AAEpF,IAA6BC,8DAAA,CAAA;AAAA,MAC3B,GAAG,WAAA;AAAA,MACH,UAAY,EAAA,KAAA;AAAA,MACZ,UAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAa,KAAM,CAAA,WAAA;AAAA,MACnB,kBAAoB,EAAA,cAAA;AAAA,MACpB,cAAA;AAAA,MACA,sBAAA,EAAwB,CAAC,GAAQ,KAAA;AAC/B,QAAA,cAAA,CAAe,KAAQ,GAAA,GAAA;AAAA,OACzB;AAAA,MACA,QAAA;AAAA,MACA,gBAAA,EAAkB,CAAC,GAAQ,KAAA;AACzB,QAAA,QAAA,CAAS,KAAQ,GAAA,GAAA;AAAA,OACnB;AAAA,MAEA,cAAA,EAAgB,CAAC,GAAQ,KAAA;AACvB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,YAAA,EAAc,CAAC,GAAQ,KAAA;AACrB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,eAAe,MAAM;AACnB,QAAA,UAAA,CAAW,KAAQ,GAAA,EAAA;AAAA;AACrB,KACD,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NavigationMenuSub.cjs","sources":["../../src/NavigationMenu/NavigationMenuSub.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { Orientation } from './utils'\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useCollection } from '@/Collection'\n\nexport type NavigationMenuSubEmits = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: string]\n}\n\nexport interface NavigationMenuSubProps extends PrimitiveProps {\n /** The controlled value of the sub menu item to activate. Can be used as `v-model`. */\n modelValue?: string\n /**\n * The value of the menu item that should be active when initially rendered.\n *\n * Use when you do not need to control the value state.\n */\n defaultValue?: string\n /** The orientation of the menu. */\n orientation?: Orientation\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, watchEffect } from 'vue'\nimport { useVModel } from '@vueuse/core'\nimport { injectNavigationMenuContext, provideNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nconst props = withDefaults(defineProps<NavigationMenuSubProps>(), {\n orientation: 'horizontal',\n})\nconst emits = defineEmits<NavigationMenuSubEmits>()\n\ndefineSlots<{\n default: (props: {\n /** Current input values */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue ?? '',\n passive: (props.modelValue === undefined) as false,\n}) as Ref<string>\nconst previousValue = ref('')\n\nconst menuContext = injectNavigationMenuContext()\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst indicatorTrack = ref<HTMLElement>()\nconst viewport = ref<HTMLElement>()\nconst activeTrigger = ref<HTMLElement>()\n\nconst { getItems, CollectionSlot } = useCollection({ key: 'NavigationMenu', isProvider: true })\n\nwatchEffect(() => {\n if (!modelValue.value)\n return\n\n const items = getItems().map(i => i.ref)\n activeTrigger.value = items.find(item =>\n item.id.includes(modelValue.value),\n )\n})\n\nprovideNavigationMenuContext({\n ...menuContext,\n isRootMenu: false,\n modelValue,\n previousValue,\n activeTrigger,\n orientation: props.orientation,\n rootNavigationMenu: currentElement,\n indicatorTrack,\n onIndicatorTrackChange: (val) => {\n indicatorTrack.value = val\n },\n viewport,\n onViewportChange: (val) => {\n viewport.value = val\n },\n\n onTriggerEnter: (val) => {\n modelValue.value = val\n },\n onTriggerLeave: () => {\n // do nothing for submenu\n },\n onContentEnter: () => {\n // do nothing for submenu\n },\n onContentLeave: () => {\n // do nothing for submenu\n },\n onItemSelect: (val) => {\n modelValue.value = val\n },\n onItemDismiss: () => {\n modelValue.value = ''\n },\n})\n</script>\n\n<template>\n <CollectionSlot>\n <Primitive\n :ref=\"forwardRef\"\n :data-orientation=\"orientation\"\n :as-child=\"props.asChild\"\n :as=\"as\"\n data-reka-navigation-menu\n >\n <slot :model-value=\"modelValue\" />\n </Primitive>\n </CollectionSlot>\n</template>\n"],"names":["useVModel","ref","injectNavigationMenuContext","useForwardExpose","useCollection","watchEffect","provideNavigationMenuContext"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkCA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAGd,IAAA,MAAM,KAAQ,GAAA,MAAA;AASd,IAAA,MAAM,UAAa,GAAAA,cAAA,CAAU,KAAO,EAAA,YAAA,EAAc,KAAO,EAAA;AAAA,MACvD,YAAA,EAAc,MAAM,YAAgB,IAAA,EAAA;AAAA,MACpC,OAAA,EAAU,MAAM,UAAe,KAAA;AAAA,KAChC,CAAA;AACD,IAAM,MAAA,aAAA,GAAgBC,QAAI,EAAE,CAAA;AAE5B,IAAA,MAAM,cAAcC,6DAA4B,EAAA;AAChD,IAAA,MAAM,EAAE,UAAA,EAAY,cAAe,EAAA,GAAIC,wCAAiB,EAAA;AAExD,IAAA,MAAM,iBAAiBF,OAAiB,EAAA;AACxC,IAAA,MAAM,WAAWA,OAAiB,EAAA;AAClC,IAAA,MAAM,gBAAgBA,OAAiB,EAAA;AAEvC,IAAM,MAAA,EAAE,QAAU,EAAA,cAAA,EAAmB,GAAAG,mCAAA,CAAc,EAAE,GAAK,EAAA,gBAAA,EAAkB,UAAY,EAAA,IAAA,EAAM,CAAA;AAE9F,IAAAC,eAAA,CAAY,MAAM;AAChB,MAAA,IAAI,CAAC,UAAW,CAAA,KAAA;AACd,QAAA;AAEF,MAAA,MAAM,QAAQ,QAAS,EAAA,CAAE,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,GAAG,CAAA;AACvC,MAAA,aAAA,CAAc,QAAQ,KAAM,CAAA,IAAA;AAAA,QAAK,CAC/B,IAAA,KAAA,IAAA,CAAK,EAAG,CAAA,QAAA,CAAS,WAAW,KAAK;AAAA,OACnC;AAAA,KACD,CAAA;AAED,IAA6BC,8DAAA,CAAA;AAAA,MAC3B,GAAG,WAAA;AAAA,MACH,UAAY,EAAA,KAAA;AAAA,MACZ,UAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAa,KAAM,CAAA,WAAA;AAAA,MACnB,kBAAoB,EAAA,cAAA;AAAA,MACpB,cAAA;AAAA,MACA,sBAAA,EAAwB,CAAC,GAAQ,KAAA;AAC/B,QAAA,cAAA,CAAe,KAAQ,GAAA,GAAA;AAAA,OACzB;AAAA,MACA,QAAA;AAAA,MACA,gBAAA,EAAkB,CAAC,GAAQ,KAAA;AACzB,QAAA,QAAA,CAAS,KAAQ,GAAA,GAAA;AAAA,OACnB;AAAA,MAEA,cAAA,EAAgB,CAAC,GAAQ,KAAA;AACvB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,YAAA,EAAc,CAAC,GAAQ,KAAA;AACrB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,eAAe,MAAM;AACnB,QAAA,UAAA,CAAW,KAAQ,GAAA,EAAA;AAAA;AACrB,KACD,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { defineComponent, ref, openBlock, createBlock, unref, withCtx, createVNode, renderSlot } from 'vue';
1
+ import { defineComponent, ref, watchEffect, openBlock, createBlock, unref, withCtx, createVNode, renderSlot } from 'vue';
2
2
  import { useVModel } from '@vueuse/core';
3
3
  import { u as useCollection } from '../Collection/Collection.js';
4
4
  import { u as useForwardExpose } from '../shared/useForwardExpose.js';
@@ -27,12 +27,22 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
27
27
  const { forwardRef, currentElement } = useForwardExpose();
28
28
  const indicatorTrack = ref();
29
29
  const viewport = ref();
30
- const { CollectionSlot } = useCollection({ key: "NavigationMenu", isProvider: true });
30
+ const activeTrigger = ref();
31
+ const { getItems, CollectionSlot } = useCollection({ key: "NavigationMenu", isProvider: true });
32
+ watchEffect(() => {
33
+ if (!modelValue.value)
34
+ return;
35
+ const items = getItems().map((i) => i.ref);
36
+ activeTrigger.value = items.find(
37
+ (item) => item.id.includes(modelValue.value)
38
+ );
39
+ });
31
40
  provideNavigationMenuContext({
32
41
  ...menuContext,
33
42
  isRootMenu: false,
34
43
  modelValue,
35
44
  previousValue,
45
+ activeTrigger,
36
46
  orientation: props.orientation,
37
47
  rootNavigationMenu: currentElement,
38
48
  indicatorTrack,
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationMenuSub.js","sources":["../../src/NavigationMenu/NavigationMenuSub.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { Orientation } from './utils'\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useCollection } from '@/Collection'\n\nexport type NavigationMenuSubEmits = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: string]\n}\n\nexport interface NavigationMenuSubProps extends PrimitiveProps {\n /** The controlled value of the sub menu item to activate. Can be used as `v-model`. */\n modelValue?: string\n /**\n * The value of the menu item that should be active when initially rendered.\n *\n * Use when you do not need to control the value state.\n */\n defaultValue?: string\n /** The orientation of the menu. */\n orientation?: Orientation\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { useVModel } from '@vueuse/core'\nimport { injectNavigationMenuContext, provideNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nconst props = withDefaults(defineProps<NavigationMenuSubProps>(), {\n orientation: 'horizontal',\n})\nconst emits = defineEmits<NavigationMenuSubEmits>()\n\ndefineSlots<{\n default: (props: {\n /** Current input values */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue ?? '',\n passive: (props.modelValue === undefined) as false,\n}) as Ref<string>\nconst previousValue = ref('')\n\nconst menuContext = injectNavigationMenuContext()\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst indicatorTrack = ref<HTMLElement>()\nconst viewport = ref<HTMLElement>()\n\nconst { CollectionSlot } = useCollection({ key: 'NavigationMenu', isProvider: true })\n\nprovideNavigationMenuContext({\n ...menuContext,\n isRootMenu: false,\n modelValue,\n previousValue,\n orientation: props.orientation,\n rootNavigationMenu: currentElement,\n indicatorTrack,\n onIndicatorTrackChange: (val) => {\n indicatorTrack.value = val\n },\n viewport,\n onViewportChange: (val) => {\n viewport.value = val\n },\n\n onTriggerEnter: (val) => {\n modelValue.value = val\n },\n onTriggerLeave: () => {\n // do nothing for submenu\n },\n onContentEnter: () => {\n // do nothing for submenu\n },\n onContentLeave: () => {\n // do nothing for submenu\n },\n onItemSelect: (val) => {\n modelValue.value = val\n },\n onItemDismiss: () => {\n modelValue.value = ''\n },\n})\n</script>\n\n<template>\n <CollectionSlot>\n <Primitive\n :ref=\"forwardRef\"\n :data-orientation=\"orientation\"\n :as-child=\"props.asChild\"\n :as=\"as\"\n data-reka-navigation-menu\n >\n <slot :model-value=\"modelValue\" />\n </Primitive>\n </CollectionSlot>\n</template>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAkCA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAGd,IAAA,MAAM,KAAQ,GAAA,MAAA;AASd,IAAA,MAAM,UAAa,GAAA,SAAA,CAAU,KAAO,EAAA,YAAA,EAAc,KAAO,EAAA;AAAA,MACvD,YAAA,EAAc,MAAM,YAAgB,IAAA,EAAA;AAAA,MACpC,OAAA,EAAU,MAAM,UAAe,KAAA;AAAA,KAChC,CAAA;AACD,IAAM,MAAA,aAAA,GAAgB,IAAI,EAAE,CAAA;AAE5B,IAAA,MAAM,cAAc,2BAA4B,EAAA;AAChD,IAAA,MAAM,EAAE,UAAA,EAAY,cAAe,EAAA,GAAI,gBAAiB,EAAA;AAExD,IAAA,MAAM,iBAAiB,GAAiB,EAAA;AACxC,IAAA,MAAM,WAAW,GAAiB,EAAA;AAElC,IAAM,MAAA,EAAE,gBAAmB,GAAA,aAAA,CAAc,EAAE,GAAK,EAAA,gBAAA,EAAkB,UAAY,EAAA,IAAA,EAAM,CAAA;AAEpF,IAA6B,4BAAA,CAAA;AAAA,MAC3B,GAAG,WAAA;AAAA,MACH,UAAY,EAAA,KAAA;AAAA,MACZ,UAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAa,KAAM,CAAA,WAAA;AAAA,MACnB,kBAAoB,EAAA,cAAA;AAAA,MACpB,cAAA;AAAA,MACA,sBAAA,EAAwB,CAAC,GAAQ,KAAA;AAC/B,QAAA,cAAA,CAAe,KAAQ,GAAA,GAAA;AAAA,OACzB;AAAA,MACA,QAAA;AAAA,MACA,gBAAA,EAAkB,CAAC,GAAQ,KAAA;AACzB,QAAA,QAAA,CAAS,KAAQ,GAAA,GAAA;AAAA,OACnB;AAAA,MAEA,cAAA,EAAgB,CAAC,GAAQ,KAAA;AACvB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,YAAA,EAAc,CAAC,GAAQ,KAAA;AACrB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,eAAe,MAAM;AACnB,QAAA,UAAA,CAAW,KAAQ,GAAA,EAAA;AAAA;AACrB,KACD,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NavigationMenuSub.js","sources":["../../src/NavigationMenu/NavigationMenuSub.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { Orientation } from './utils'\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useCollection } from '@/Collection'\n\nexport type NavigationMenuSubEmits = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: string]\n}\n\nexport interface NavigationMenuSubProps extends PrimitiveProps {\n /** The controlled value of the sub menu item to activate. Can be used as `v-model`. */\n modelValue?: string\n /**\n * The value of the menu item that should be active when initially rendered.\n *\n * Use when you do not need to control the value state.\n */\n defaultValue?: string\n /** The orientation of the menu. */\n orientation?: Orientation\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, watchEffect } from 'vue'\nimport { useVModel } from '@vueuse/core'\nimport { injectNavigationMenuContext, provideNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nconst props = withDefaults(defineProps<NavigationMenuSubProps>(), {\n orientation: 'horizontal',\n})\nconst emits = defineEmits<NavigationMenuSubEmits>()\n\ndefineSlots<{\n default: (props: {\n /** Current input values */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue ?? '',\n passive: (props.modelValue === undefined) as false,\n}) as Ref<string>\nconst previousValue = ref('')\n\nconst menuContext = injectNavigationMenuContext()\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst indicatorTrack = ref<HTMLElement>()\nconst viewport = ref<HTMLElement>()\nconst activeTrigger = ref<HTMLElement>()\n\nconst { getItems, CollectionSlot } = useCollection({ key: 'NavigationMenu', isProvider: true })\n\nwatchEffect(() => {\n if (!modelValue.value)\n return\n\n const items = getItems().map(i => i.ref)\n activeTrigger.value = items.find(item =>\n item.id.includes(modelValue.value),\n )\n})\n\nprovideNavigationMenuContext({\n ...menuContext,\n isRootMenu: false,\n modelValue,\n previousValue,\n activeTrigger,\n orientation: props.orientation,\n rootNavigationMenu: currentElement,\n indicatorTrack,\n onIndicatorTrackChange: (val) => {\n indicatorTrack.value = val\n },\n viewport,\n onViewportChange: (val) => {\n viewport.value = val\n },\n\n onTriggerEnter: (val) => {\n modelValue.value = val\n },\n onTriggerLeave: () => {\n // do nothing for submenu\n },\n onContentEnter: () => {\n // do nothing for submenu\n },\n onContentLeave: () => {\n // do nothing for submenu\n },\n onItemSelect: (val) => {\n modelValue.value = val\n },\n onItemDismiss: () => {\n modelValue.value = ''\n },\n})\n</script>\n\n<template>\n <CollectionSlot>\n <Primitive\n :ref=\"forwardRef\"\n :data-orientation=\"orientation\"\n :as-child=\"props.asChild\"\n :as=\"as\"\n data-reka-navigation-menu\n >\n <slot :model-value=\"modelValue\" />\n </Primitive>\n </CollectionSlot>\n</template>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAkCA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAGd,IAAA,MAAM,KAAQ,GAAA,MAAA;AASd,IAAA,MAAM,UAAa,GAAA,SAAA,CAAU,KAAO,EAAA,YAAA,EAAc,KAAO,EAAA;AAAA,MACvD,YAAA,EAAc,MAAM,YAAgB,IAAA,EAAA;AAAA,MACpC,OAAA,EAAU,MAAM,UAAe,KAAA;AAAA,KAChC,CAAA;AACD,IAAM,MAAA,aAAA,GAAgB,IAAI,EAAE,CAAA;AAE5B,IAAA,MAAM,cAAc,2BAA4B,EAAA;AAChD,IAAA,MAAM,EAAE,UAAA,EAAY,cAAe,EAAA,GAAI,gBAAiB,EAAA;AAExD,IAAA,MAAM,iBAAiB,GAAiB,EAAA;AACxC,IAAA,MAAM,WAAW,GAAiB,EAAA;AAClC,IAAA,MAAM,gBAAgB,GAAiB,EAAA;AAEvC,IAAM,MAAA,EAAE,QAAU,EAAA,cAAA,EAAmB,GAAA,aAAA,CAAc,EAAE,GAAK,EAAA,gBAAA,EAAkB,UAAY,EAAA,IAAA,EAAM,CAAA;AAE9F,IAAA,WAAA,CAAY,MAAM;AAChB,MAAA,IAAI,CAAC,UAAW,CAAA,KAAA;AACd,QAAA;AAEF,MAAA,MAAM,QAAQ,QAAS,EAAA,CAAE,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,GAAG,CAAA;AACvC,MAAA,aAAA,CAAc,QAAQ,KAAM,CAAA,IAAA;AAAA,QAAK,CAC/B,IAAA,KAAA,IAAA,CAAK,EAAG,CAAA,QAAA,CAAS,WAAW,KAAK;AAAA,OACnC;AAAA,KACD,CAAA;AAED,IAA6B,4BAAA,CAAA;AAAA,MAC3B,GAAG,WAAA;AAAA,MACH,UAAY,EAAA,KAAA;AAAA,MACZ,UAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAa,KAAM,CAAA,WAAA;AAAA,MACnB,kBAAoB,EAAA,cAAA;AAAA,MACpB,cAAA;AAAA,MACA,sBAAA,EAAwB,CAAC,GAAQ,KAAA;AAC/B,QAAA,cAAA,CAAe,KAAQ,GAAA,GAAA;AAAA,OACzB;AAAA,MACA,QAAA;AAAA,MACA,gBAAA,EAAkB,CAAC,GAAQ,KAAA;AACzB,QAAA,QAAA,CAAS,KAAQ,GAAA,GAAA;AAAA,OACnB;AAAA,MAEA,cAAA,EAAgB,CAAC,GAAQ,KAAA;AACvB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,gBAAgB,MAAM;AAAA,OAEtB;AAAA,MACA,YAAA,EAAc,CAAC,GAAQ,KAAA;AACrB,QAAA,UAAA,CAAW,KAAQ,GAAA,GAAA;AAAA,OACrB;AAAA,MACA,eAAe,MAAM;AACnB,QAAA,UAAA,CAAW,KAAQ,GAAA,EAAA;AAAA;AACrB,KACD,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -28,15 +28,14 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
28
28
  const position = vue.ref();
29
29
  const open = vue.computed(() => !!menuContext.modelValue.value);
30
30
  vue.watch(currentElement, () => {
31
- if (currentElement.value)
32
- menuContext.onViewportChange(currentElement.value);
31
+ menuContext.onViewportChange(currentElement.value);
33
32
  });
34
33
  const content = vue.ref();
35
34
  vue.watch([modelValue, open], () => {
36
35
  if (!currentElement.value)
37
36
  return;
38
37
  requestAnimationFrame(() => {
39
- const el = currentElement.value?.querySelector("[data-state=open]")?.children?.[0];
38
+ const el = currentElement.value?.querySelector("[data-state=open]");
40
39
  content.value = el;
41
40
  });
42
41
  }, { immediate: true, flush: "post" });
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationMenuViewport.cjs","sources":["../../src/NavigationMenu/NavigationMenuViewport.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nexport interface NavigationMenuViewportProps extends PrimitiveProps {\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with Vue animation libraries.\n */\n forceMount?: boolean\n /**\n * Placement of the viewport for css variables `(--reka-navigation-menu-viewport-left, --reka-navigation-menu-viewport-top)`.\n * @defaultValue 'center'\n */\n align?: 'start' | 'center' | 'end'\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport { injectNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport { getOpenState, whenMouse } from './utils'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { Presence } from '@/Presence'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NavigationMenuViewportProps>(), {\n align: 'center',\n})\n\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst menuContext = injectNavigationMenuContext()\nconst { activeTrigger, rootNavigationMenu, modelValue } = menuContext\n\nconst size = ref<{ width: number, height: number }>()\nconst position = ref<{ left: number, top: number }>()\n\nconst open = computed(() => !!menuContext.modelValue.value)\n\nwatch(currentElement, () => {\n if (currentElement.value)\n menuContext.onViewportChange(currentElement.value)\n})\n\nconst content = ref<HTMLElement>()\n\nwatch([modelValue, open], () => {\n if (!currentElement.value)\n return\n\n requestAnimationFrame(() => {\n const el = (currentElement.value as HTMLElement)?.querySelector('[data-state=open]')?.children?.[0] as HTMLElement | undefined\n content.value = el\n })\n}, { immediate: true, flush: 'post' })\n\nfunction updatePosition() {\n if (content.value && activeTrigger.value && rootNavigationMenu.value) {\n const bodyWidth = document.documentElement.offsetWidth\n const bodyHeight = document.documentElement.offsetHeight\n const rootRect = rootNavigationMenu.value.getBoundingClientRect()\n const rect = activeTrigger.value.getBoundingClientRect()\n const { offsetWidth, offsetHeight } = content.value\n\n // Find the beginning of the position of the menu item\n const startPositionLeft = rect.left - rootRect.left\n const startPositionTop = rect.top - rootRect.top\n\n // Aligning to specified alignment\n let posLeft = null\n let posTop = null\n switch (props.align) {\n case 'start':\n posLeft = startPositionLeft\n posTop = startPositionTop\n break\n case 'end':\n posLeft = startPositionLeft - offsetWidth + rect.width\n posTop = startPositionTop - offsetHeight + rect.height\n break\n default:\n // center\n posLeft = startPositionLeft - offsetWidth / 2 + rect.width / 2\n posTop = startPositionTop - offsetHeight / 2 + rect.height / 2\n }\n\n const screenOffset = 10\n\n // Do not let go of the left side of the screen\n if (posLeft + rootRect.left < screenOffset) {\n posLeft = screenOffset - rootRect.left\n }\n\n // Now also check the right side of the screen\n const rightOffset = posLeft + rootRect.left + offsetWidth\n if (rightOffset > bodyWidth - screenOffset) {\n posLeft -= rightOffset - bodyWidth + screenOffset\n\n // Recheck the left side of the screen\n if (posLeft < screenOffset - rootRect.left) {\n // Just set the menu to the full width of the screen\n posLeft = screenOffset - rootRect.left\n }\n }\n\n // Do not let go of the top side of the screen\n if (posTop + rootRect.top < screenOffset) {\n posTop = screenOffset - rootRect.top\n }\n\n // Now also check the bottom side of the screen\n const bottomOffset = posTop + rootRect.top + offsetHeight\n if (bottomOffset > bodyHeight - screenOffset) {\n posTop -= bottomOffset - bodyHeight + screenOffset\n\n // Recheck the top side of the screen\n if (posTop < screenOffset - rootRect.top) {\n // Just set the menu to the full height of the screen\n posTop = screenOffset - rootRect.top\n }\n }\n\n // Possible blurring font with decimal values\n posLeft = Math.round(posLeft)\n posTop = Math.round(posTop)\n\n position.value = {\n left: posLeft,\n top: posTop,\n }\n }\n}\n\nuseResizeObserver(content, () => {\n if (content.value) {\n size.value = {\n width: content.value.offsetWidth,\n height: content.value.offsetHeight,\n }\n updatePosition()\n }\n})\n\nuseResizeObserver([globalThis.document?.body, rootNavigationMenu], () => {\n updatePosition()\n})\n</script>\n\n<template>\n <Presence\n v-slot=\"{ present }\"\n :present=\"forceMount || open\"\n :force-mount=\"!menuContext.unmountOnHide.value\"\n @after-leave=\"() => {\n size = undefined\n position = undefined\n }\"\n >\n <Primitive\n v-bind=\"$attrs\"\n :ref=\"forwardRef\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-state=\"getOpenState(open)\"\n :data-orientation=\"menuContext.orientation\"\n :style=\"{\n // Prevent interaction when animating out\n pointerEvents: !open && menuContext.isRootMenu ? 'none' : undefined,\n ['--reka-navigation-menu-viewport-width']: size ? `${size?.width}px` : undefined,\n ['--reka-navigation-menu-viewport-height']: size ? `${size?.height}px` : undefined,\n ['--reka-navigation-menu-viewport-left']: position ? `${position?.left}px` : undefined,\n ['--reka-navigation-menu-viewport-top']: position ? `${position?.top}px` : undefined,\n }\"\n :hidden=\"!present\"\n @pointerenter=\"menuContext.onContentEnter(menuContext.modelValue.value)\"\n @pointerleave=\"whenMouse(() => menuContext.onContentLeave())($event)\"\n >\n <slot />\n </Primitive>\n </Presence>\n</template>\n"],"names":["useForwardExpose","injectNavigationMenuContext","ref","computed","watch","useResizeObserver"],"mappings":"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"}
1
+ {"version":3,"file":"NavigationMenuViewport.cjs","sources":["../../src/NavigationMenu/NavigationMenuViewport.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nexport interface NavigationMenuViewportProps extends PrimitiveProps {\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with Vue animation libraries.\n */\n forceMount?: boolean\n /**\n * Placement of the viewport for css variables `(--reka-navigation-menu-viewport-left, --reka-navigation-menu-viewport-top)`.\n * @defaultValue 'center'\n */\n align?: 'start' | 'center' | 'end'\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport { injectNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport { getOpenState, whenMouse } from './utils'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { Presence } from '@/Presence'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NavigationMenuViewportProps>(), {\n align: 'center',\n})\n\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst menuContext = injectNavigationMenuContext()\nconst { activeTrigger, rootNavigationMenu, modelValue } = menuContext\n\nconst size = ref<{ width: number, height: number }>()\nconst position = ref<{ left: number, top: number }>()\n\nconst open = computed(() => !!menuContext.modelValue.value)\n\nwatch(currentElement, () => {\n menuContext.onViewportChange(currentElement.value)\n})\n\nconst content = ref<HTMLElement>()\n\nwatch([modelValue, open], () => {\n if (!currentElement.value)\n return\n\n requestAnimationFrame(() => {\n const el = (currentElement.value as HTMLElement)?.querySelector('[data-state=open]') as HTMLElement | undefined\n content.value = el\n })\n}, { immediate: true, flush: 'post' })\n\nfunction updatePosition() {\n if (content.value && activeTrigger.value && rootNavigationMenu.value) {\n const bodyWidth = document.documentElement.offsetWidth\n const bodyHeight = document.documentElement.offsetHeight\n const rootRect = rootNavigationMenu.value.getBoundingClientRect()\n const rect = activeTrigger.value.getBoundingClientRect()\n const { offsetWidth, offsetHeight } = content.value\n\n // Find the beginning of the position of the menu item\n const startPositionLeft = rect.left - rootRect.left\n const startPositionTop = rect.top - rootRect.top\n\n // Aligning to specified alignment\n let posLeft = null\n let posTop = null\n switch (props.align) {\n case 'start':\n posLeft = startPositionLeft\n posTop = startPositionTop\n break\n case 'end':\n posLeft = startPositionLeft - offsetWidth + rect.width\n posTop = startPositionTop - offsetHeight + rect.height\n break\n default:\n // center\n posLeft = startPositionLeft - offsetWidth / 2 + rect.width / 2\n posTop = startPositionTop - offsetHeight / 2 + rect.height / 2\n }\n\n const screenOffset = 10\n\n // Do not let go of the left side of the screen\n if (posLeft + rootRect.left < screenOffset) {\n posLeft = screenOffset - rootRect.left\n }\n\n // Now also check the right side of the screen\n const rightOffset = posLeft + rootRect.left + offsetWidth\n if (rightOffset > bodyWidth - screenOffset) {\n posLeft -= rightOffset - bodyWidth + screenOffset\n\n // Recheck the left side of the screen\n if (posLeft < screenOffset - rootRect.left) {\n // Just set the menu to the full width of the screen\n posLeft = screenOffset - rootRect.left\n }\n }\n\n // Do not let go of the top side of the screen\n if (posTop + rootRect.top < screenOffset) {\n posTop = screenOffset - rootRect.top\n }\n\n // Now also check the bottom side of the screen\n const bottomOffset = posTop + rootRect.top + offsetHeight\n if (bottomOffset > bodyHeight - screenOffset) {\n posTop -= bottomOffset - bodyHeight + screenOffset\n\n // Recheck the top side of the screen\n if (posTop < screenOffset - rootRect.top) {\n // Just set the menu to the full height of the screen\n posTop = screenOffset - rootRect.top\n }\n }\n\n // Possible blurring font with decimal values\n posLeft = Math.round(posLeft)\n posTop = Math.round(posTop)\n\n position.value = {\n left: posLeft,\n top: posTop,\n }\n }\n}\n\nuseResizeObserver(content, () => {\n if (content.value) {\n size.value = {\n width: content.value.offsetWidth,\n height: content.value.offsetHeight,\n }\n updatePosition()\n }\n})\n\nuseResizeObserver([globalThis.document?.body, rootNavigationMenu], () => {\n updatePosition()\n})\n</script>\n\n<template>\n <Presence\n v-slot=\"{ present }\"\n :present=\"forceMount || open\"\n :force-mount=\"!menuContext.unmountOnHide.value\"\n @after-leave=\"() => {\n size = undefined\n position = undefined\n }\"\n >\n <Primitive\n v-bind=\"$attrs\"\n :ref=\"forwardRef\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-state=\"getOpenState(open)\"\n :data-orientation=\"menuContext.orientation\"\n :style=\"{\n // Prevent interaction when animating out\n pointerEvents: !open && menuContext.isRootMenu ? 'none' : undefined,\n ['--reka-navigation-menu-viewport-width']: size ? `${size?.width}px` : undefined,\n ['--reka-navigation-menu-viewport-height']: size ? `${size?.height}px` : undefined,\n ['--reka-navigation-menu-viewport-left']: position ? `${position?.left}px` : undefined,\n ['--reka-navigation-menu-viewport-top']: position ? `${position?.top}px` : undefined,\n }\"\n :hidden=\"!present\"\n @pointerenter=\"menuContext.onContentEnter(menuContext.modelValue.value)\"\n @pointerleave=\"whenMouse(() => menuContext.onContentLeave())($event)\"\n >\n <slot />\n </Primitive>\n </Presence>\n</template>\n"],"names":["useForwardExpose","injectNavigationMenuContext","ref","computed","watch","useResizeObserver"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAId,IAAA,MAAM,EAAE,UAAA,EAAY,cAAe,EAAA,GAAIA,wCAAiB,EAAA;AAExD,IAAA,MAAM,cAAcC,6DAA4B,EAAA;AAChD,IAAA,MAAM,EAAE,aAAA,EAAe,kBAAoB,EAAA,UAAA,EAAe,GAAA,WAAA;AAE1D,IAAA,MAAM,OAAOC,OAAuC,EAAA;AACpD,IAAA,MAAM,WAAWA,OAAmC,EAAA;AAEpD,IAAA,MAAM,OAAOC,YAAS,CAAA,MAAM,CAAC,CAAC,WAAA,CAAY,WAAW,KAAK,CAAA;AAE1D,IAAAC,SAAA,CAAM,gBAAgB,MAAM;AAC1B,MAAY,WAAA,CAAA,gBAAA,CAAiB,eAAe,KAAK,CAAA;AAAA,KAClD,CAAA;AAED,IAAA,MAAM,UAAUF,OAAiB,EAAA;AAEjC,IAAAE,SAAA,CAAM,CAAC,UAAA,EAAY,IAAI,CAAA,EAAG,MAAM;AAC9B,MAAA,IAAI,CAAC,cAAe,CAAA,KAAA;AAClB,QAAA;AAEF,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAA,MAAM,EAAM,GAAA,cAAA,CAAe,KAAuB,EAAA,aAAA,CAAc,mBAAmB,CAAA;AACnF,QAAA,OAAA,CAAQ,KAAQ,GAAA,EAAA;AAAA,OACjB,CAAA;AAAA,OACA,EAAE,SAAA,EAAW,IAAM,EAAA,KAAA,EAAO,QAAQ,CAAA;AAErC,IAAA,SAAS,cAAiB,GAAA;AACxB,MAAA,IAAI,OAAQ,CAAA,KAAA,IAAS,aAAc,CAAA,KAAA,IAAS,mBAAmB,KAAO,EAAA;AACpE,QAAM,MAAA,SAAA,GAAY,SAAS,eAAgB,CAAA,WAAA;AAC3C,QAAM,MAAA,UAAA,GAAa,SAAS,eAAgB,CAAA,YAAA;AAC5C,QAAM,MAAA,QAAA,GAAW,kBAAmB,CAAA,KAAA,CAAM,qBAAsB,EAAA;AAChE,QAAM,MAAA,IAAA,GAAO,aAAc,CAAA,KAAA,CAAM,qBAAsB,EAAA;AACvD,QAAA,MAAM,EAAE,WAAA,EAAa,YAAa,EAAA,GAAI,OAAQ,CAAA,KAAA;AAG9C,QAAM,MAAA,iBAAA,GAAoB,IAAK,CAAA,IAAA,GAAO,QAAS,CAAA,IAAA;AAC/C,QAAM,MAAA,gBAAA,GAAmB,IAAK,CAAA,GAAA,GAAM,QAAS,CAAA,GAAA;AAG7C,QAAA,IAAI,OAAU,GAAA,IAAA;AACd,QAAA,IAAI,MAAS,GAAA,IAAA;AACb,QAAA,QAAQ,MAAM,KAAO;AAAA,UACnB,KAAK,OAAA;AACH,YAAU,OAAA,GAAA,iBAAA;AACV,YAAS,MAAA,GAAA,gBAAA;AACT,YAAA;AAAA,UACF,KAAK,KAAA;AACH,YAAU,OAAA,GAAA,iBAAA,GAAoB,cAAc,IAAK,CAAA,KAAA;AACjD,YAAS,MAAA,GAAA,gBAAA,GAAmB,eAAe,IAAK,CAAA,MAAA;AAChD,YAAA;AAAA,UACF;AAEE,YAAA,OAAA,GAAU,iBAAoB,GAAA,WAAA,GAAc,CAAI,GAAA,IAAA,CAAK,KAAQ,GAAA,CAAA;AAC7D,YAAA,MAAA,GAAS,gBAAmB,GAAA,YAAA,GAAe,CAAI,GAAA,IAAA,CAAK,MAAS,GAAA,CAAA;AAAA;AAGjE,QAAA,MAAM,YAAe,GAAA,EAAA;AAGrB,QAAI,IAAA,OAAA,GAAU,QAAS,CAAA,IAAA,GAAO,YAAc,EAAA;AAC1C,UAAA,OAAA,GAAU,eAAe,QAAS,CAAA,IAAA;AAAA;AAIpC,QAAM,MAAA,WAAA,GAAc,OAAU,GAAA,QAAA,CAAS,IAAO,GAAA,WAAA;AAC9C,QAAI,IAAA,WAAA,GAAc,YAAY,YAAc,EAAA;AAC1C,UAAA,OAAA,IAAW,cAAc,SAAY,GAAA,YAAA;AAGrC,UAAI,IAAA,OAAA,GAAU,YAAe,GAAA,QAAA,CAAS,IAAM,EAAA;AAE1C,YAAA,OAAA,GAAU,eAAe,QAAS,CAAA,IAAA;AAAA;AACpC;AAIF,QAAI,IAAA,MAAA,GAAS,QAAS,CAAA,GAAA,GAAM,YAAc,EAAA;AACxC,UAAA,MAAA,GAAS,eAAe,QAAS,CAAA,GAAA;AAAA;AAInC,QAAM,MAAA,YAAA,GAAe,MAAS,GAAA,QAAA,CAAS,GAAM,GAAA,YAAA;AAC7C,QAAI,IAAA,YAAA,GAAe,aAAa,YAAc,EAAA;AAC5C,UAAA,MAAA,IAAU,eAAe,UAAa,GAAA,YAAA;AAGtC,UAAI,IAAA,MAAA,GAAS,YAAe,GAAA,QAAA,CAAS,GAAK,EAAA;AAExC,YAAA,MAAA,GAAS,eAAe,QAAS,CAAA,GAAA;AAAA;AACnC;AAIF,QAAU,OAAA,GAAA,IAAA,CAAK,MAAM,OAAO,CAAA;AAC5B,QAAS,MAAA,GAAA,IAAA,CAAK,MAAM,MAAM,CAAA;AAE1B,QAAA,QAAA,CAAS,KAAQ,GAAA;AAAA,UACf,IAAM,EAAA,OAAA;AAAA,UACN,GAAK,EAAA;AAAA,SACP;AAAA;AACF;AAGF,IAAAC,sBAAA,CAAkB,SAAS,MAAM;AAC/B,MAAA,IAAI,QAAQ,KAAO,EAAA;AACjB,QAAA,IAAA,CAAK,KAAQ,GAAA;AAAA,UACX,KAAA,EAAO,QAAQ,KAAM,CAAA,WAAA;AAAA,UACrB,MAAA,EAAQ,QAAQ,KAAM,CAAA;AAAA,SACxB;AACA,QAAe,cAAA,EAAA;AAAA;AACjB,KACD,CAAA;AAED,IAAAA,sBAAA,CAAkB,CAAC,UAAW,CAAA,QAAA,EAAU,IAAM,EAAA,kBAAkB,GAAG,MAAM;AACvE,MAAe,cAAA,EAAA;AAAA,KAChB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -26,15 +26,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
26
26
  const position = ref();
27
27
  const open = computed(() => !!menuContext.modelValue.value);
28
28
  watch(currentElement, () => {
29
- if (currentElement.value)
30
- menuContext.onViewportChange(currentElement.value);
29
+ menuContext.onViewportChange(currentElement.value);
31
30
  });
32
31
  const content = ref();
33
32
  watch([modelValue, open], () => {
34
33
  if (!currentElement.value)
35
34
  return;
36
35
  requestAnimationFrame(() => {
37
- const el = currentElement.value?.querySelector("[data-state=open]")?.children?.[0];
36
+ const el = currentElement.value?.querySelector("[data-state=open]");
38
37
  content.value = el;
39
38
  });
40
39
  }, { immediate: true, flush: "post" });
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationMenuViewport.js","sources":["../../src/NavigationMenu/NavigationMenuViewport.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nexport interface NavigationMenuViewportProps extends PrimitiveProps {\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with Vue animation libraries.\n */\n forceMount?: boolean\n /**\n * Placement of the viewport for css variables `(--reka-navigation-menu-viewport-left, --reka-navigation-menu-viewport-top)`.\n * @defaultValue 'center'\n */\n align?: 'start' | 'center' | 'end'\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport { injectNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport { getOpenState, whenMouse } from './utils'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { Presence } from '@/Presence'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NavigationMenuViewportProps>(), {\n align: 'center',\n})\n\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst menuContext = injectNavigationMenuContext()\nconst { activeTrigger, rootNavigationMenu, modelValue } = menuContext\n\nconst size = ref<{ width: number, height: number }>()\nconst position = ref<{ left: number, top: number }>()\n\nconst open = computed(() => !!menuContext.modelValue.value)\n\nwatch(currentElement, () => {\n if (currentElement.value)\n menuContext.onViewportChange(currentElement.value)\n})\n\nconst content = ref<HTMLElement>()\n\nwatch([modelValue, open], () => {\n if (!currentElement.value)\n return\n\n requestAnimationFrame(() => {\n const el = (currentElement.value as HTMLElement)?.querySelector('[data-state=open]')?.children?.[0] as HTMLElement | undefined\n content.value = el\n })\n}, { immediate: true, flush: 'post' })\n\nfunction updatePosition() {\n if (content.value && activeTrigger.value && rootNavigationMenu.value) {\n const bodyWidth = document.documentElement.offsetWidth\n const bodyHeight = document.documentElement.offsetHeight\n const rootRect = rootNavigationMenu.value.getBoundingClientRect()\n const rect = activeTrigger.value.getBoundingClientRect()\n const { offsetWidth, offsetHeight } = content.value\n\n // Find the beginning of the position of the menu item\n const startPositionLeft = rect.left - rootRect.left\n const startPositionTop = rect.top - rootRect.top\n\n // Aligning to specified alignment\n let posLeft = null\n let posTop = null\n switch (props.align) {\n case 'start':\n posLeft = startPositionLeft\n posTop = startPositionTop\n break\n case 'end':\n posLeft = startPositionLeft - offsetWidth + rect.width\n posTop = startPositionTop - offsetHeight + rect.height\n break\n default:\n // center\n posLeft = startPositionLeft - offsetWidth / 2 + rect.width / 2\n posTop = startPositionTop - offsetHeight / 2 + rect.height / 2\n }\n\n const screenOffset = 10\n\n // Do not let go of the left side of the screen\n if (posLeft + rootRect.left < screenOffset) {\n posLeft = screenOffset - rootRect.left\n }\n\n // Now also check the right side of the screen\n const rightOffset = posLeft + rootRect.left + offsetWidth\n if (rightOffset > bodyWidth - screenOffset) {\n posLeft -= rightOffset - bodyWidth + screenOffset\n\n // Recheck the left side of the screen\n if (posLeft < screenOffset - rootRect.left) {\n // Just set the menu to the full width of the screen\n posLeft = screenOffset - rootRect.left\n }\n }\n\n // Do not let go of the top side of the screen\n if (posTop + rootRect.top < screenOffset) {\n posTop = screenOffset - rootRect.top\n }\n\n // Now also check the bottom side of the screen\n const bottomOffset = posTop + rootRect.top + offsetHeight\n if (bottomOffset > bodyHeight - screenOffset) {\n posTop -= bottomOffset - bodyHeight + screenOffset\n\n // Recheck the top side of the screen\n if (posTop < screenOffset - rootRect.top) {\n // Just set the menu to the full height of the screen\n posTop = screenOffset - rootRect.top\n }\n }\n\n // Possible blurring font with decimal values\n posLeft = Math.round(posLeft)\n posTop = Math.round(posTop)\n\n position.value = {\n left: posLeft,\n top: posTop,\n }\n }\n}\n\nuseResizeObserver(content, () => {\n if (content.value) {\n size.value = {\n width: content.value.offsetWidth,\n height: content.value.offsetHeight,\n }\n updatePosition()\n }\n})\n\nuseResizeObserver([globalThis.document?.body, rootNavigationMenu], () => {\n updatePosition()\n})\n</script>\n\n<template>\n <Presence\n v-slot=\"{ present }\"\n :present=\"forceMount || open\"\n :force-mount=\"!menuContext.unmountOnHide.value\"\n @after-leave=\"() => {\n size = undefined\n position = undefined\n }\"\n >\n <Primitive\n v-bind=\"$attrs\"\n :ref=\"forwardRef\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-state=\"getOpenState(open)\"\n :data-orientation=\"menuContext.orientation\"\n :style=\"{\n // Prevent interaction when animating out\n pointerEvents: !open && menuContext.isRootMenu ? 'none' : undefined,\n ['--reka-navigation-menu-viewport-width']: size ? `${size?.width}px` : undefined,\n ['--reka-navigation-menu-viewport-height']: size ? `${size?.height}px` : undefined,\n ['--reka-navigation-menu-viewport-left']: position ? `${position?.left}px` : undefined,\n ['--reka-navigation-menu-viewport-top']: position ? `${position?.top}px` : undefined,\n }\"\n :hidden=\"!present\"\n @pointerenter=\"menuContext.onContentEnter(menuContext.modelValue.value)\"\n @pointerleave=\"whenMouse(() => menuContext.onContentLeave())($event)\"\n >\n <slot />\n </Primitive>\n </Presence>\n</template>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NavigationMenuViewport.js","sources":["../../src/NavigationMenu/NavigationMenuViewport.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useForwardExpose } from '@/shared'\n\nexport interface NavigationMenuViewportProps extends PrimitiveProps {\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with Vue animation libraries.\n */\n forceMount?: boolean\n /**\n * Placement of the viewport for css variables `(--reka-navigation-menu-viewport-left, --reka-navigation-menu-viewport-top)`.\n * @defaultValue 'center'\n */\n align?: 'start' | 'center' | 'end'\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useResizeObserver } from '@vueuse/core'\nimport { injectNavigationMenuContext } from './NavigationMenuRoot.vue'\nimport { getOpenState, whenMouse } from './utils'\nimport {\n Primitive,\n} from '@/Primitive'\nimport { Presence } from '@/Presence'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NavigationMenuViewportProps>(), {\n align: 'center',\n})\n\nconst { forwardRef, currentElement } = useForwardExpose()\n\nconst menuContext = injectNavigationMenuContext()\nconst { activeTrigger, rootNavigationMenu, modelValue } = menuContext\n\nconst size = ref<{ width: number, height: number }>()\nconst position = ref<{ left: number, top: number }>()\n\nconst open = computed(() => !!menuContext.modelValue.value)\n\nwatch(currentElement, () => {\n menuContext.onViewportChange(currentElement.value)\n})\n\nconst content = ref<HTMLElement>()\n\nwatch([modelValue, open], () => {\n if (!currentElement.value)\n return\n\n requestAnimationFrame(() => {\n const el = (currentElement.value as HTMLElement)?.querySelector('[data-state=open]') as HTMLElement | undefined\n content.value = el\n })\n}, { immediate: true, flush: 'post' })\n\nfunction updatePosition() {\n if (content.value && activeTrigger.value && rootNavigationMenu.value) {\n const bodyWidth = document.documentElement.offsetWidth\n const bodyHeight = document.documentElement.offsetHeight\n const rootRect = rootNavigationMenu.value.getBoundingClientRect()\n const rect = activeTrigger.value.getBoundingClientRect()\n const { offsetWidth, offsetHeight } = content.value\n\n // Find the beginning of the position of the menu item\n const startPositionLeft = rect.left - rootRect.left\n const startPositionTop = rect.top - rootRect.top\n\n // Aligning to specified alignment\n let posLeft = null\n let posTop = null\n switch (props.align) {\n case 'start':\n posLeft = startPositionLeft\n posTop = startPositionTop\n break\n case 'end':\n posLeft = startPositionLeft - offsetWidth + rect.width\n posTop = startPositionTop - offsetHeight + rect.height\n break\n default:\n // center\n posLeft = startPositionLeft - offsetWidth / 2 + rect.width / 2\n posTop = startPositionTop - offsetHeight / 2 + rect.height / 2\n }\n\n const screenOffset = 10\n\n // Do not let go of the left side of the screen\n if (posLeft + rootRect.left < screenOffset) {\n posLeft = screenOffset - rootRect.left\n }\n\n // Now also check the right side of the screen\n const rightOffset = posLeft + rootRect.left + offsetWidth\n if (rightOffset > bodyWidth - screenOffset) {\n posLeft -= rightOffset - bodyWidth + screenOffset\n\n // Recheck the left side of the screen\n if (posLeft < screenOffset - rootRect.left) {\n // Just set the menu to the full width of the screen\n posLeft = screenOffset - rootRect.left\n }\n }\n\n // Do not let go of the top side of the screen\n if (posTop + rootRect.top < screenOffset) {\n posTop = screenOffset - rootRect.top\n }\n\n // Now also check the bottom side of the screen\n const bottomOffset = posTop + rootRect.top + offsetHeight\n if (bottomOffset > bodyHeight - screenOffset) {\n posTop -= bottomOffset - bodyHeight + screenOffset\n\n // Recheck the top side of the screen\n if (posTop < screenOffset - rootRect.top) {\n // Just set the menu to the full height of the screen\n posTop = screenOffset - rootRect.top\n }\n }\n\n // Possible blurring font with decimal values\n posLeft = Math.round(posLeft)\n posTop = Math.round(posTop)\n\n position.value = {\n left: posLeft,\n top: posTop,\n }\n }\n}\n\nuseResizeObserver(content, () => {\n if (content.value) {\n size.value = {\n width: content.value.offsetWidth,\n height: content.value.offsetHeight,\n }\n updatePosition()\n }\n})\n\nuseResizeObserver([globalThis.document?.body, rootNavigationMenu], () => {\n updatePosition()\n})\n</script>\n\n<template>\n <Presence\n v-slot=\"{ present }\"\n :present=\"forceMount || open\"\n :force-mount=\"!menuContext.unmountOnHide.value\"\n @after-leave=\"() => {\n size = undefined\n position = undefined\n }\"\n >\n <Primitive\n v-bind=\"$attrs\"\n :ref=\"forwardRef\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-state=\"getOpenState(open)\"\n :data-orientation=\"menuContext.orientation\"\n :style=\"{\n // Prevent interaction when animating out\n pointerEvents: !open && menuContext.isRootMenu ? 'none' : undefined,\n ['--reka-navigation-menu-viewport-width']: size ? `${size?.width}px` : undefined,\n ['--reka-navigation-menu-viewport-height']: size ? `${size?.height}px` : undefined,\n ['--reka-navigation-menu-viewport-left']: position ? `${position?.left}px` : undefined,\n ['--reka-navigation-menu-viewport-top']: position ? `${position?.top}px` : undefined,\n }\"\n :hidden=\"!present\"\n @pointerenter=\"menuContext.onContentEnter(menuContext.modelValue.value)\"\n @pointerleave=\"whenMouse(() => menuContext.onContentLeave())($event)\"\n >\n <slot />\n </Primitive>\n </Presence>\n</template>\n"],"names":[],"mappings":"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"}
@@ -17,6 +17,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
17
17
  const { primitiveElement, currentElement } = Primitive_usePrimitiveElement.usePrimitiveElement();
18
18
  const rootContext = NumberField_NumberFieldRoot.injectNumberFieldRootContext();
19
19
  function handleWheelEvent(event) {
20
+ if (rootContext.disableWheelChange.value)
21
+ return;
20
22
  if (event.target !== shared_getActiveElement.getActiveElement())
21
23
  return;
22
24
  if (Math.abs(event.deltaY) <= Math.abs(event.deltaX))
@@ -1 +1 @@
1
- {"version":3,"file":"NumberFieldInput.cjs","sources":["../../src/NumberField/NumberFieldInput.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { injectNumberFieldRootContext } from './NumberFieldRoot.vue'\nimport { onMounted, ref, watch } from 'vue'\nimport { getActiveElement } from '@/shared'\n\nexport interface NumberFieldInputProps extends PrimitiveProps {\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\n\nconst props = withDefaults(defineProps<NumberFieldInputProps>(), {\n as: 'input',\n})\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\nconst rootContext = injectNumberFieldRootContext()\n\nfunction handleWheelEvent(event: WheelEvent) {\n // only handle when in focus\n if (event.target !== getActiveElement())\n return\n\n // if on a trackpad, users can scroll in both X and Y at once, check the magnitude of the change\n // if it's mostly in the X direction, then just return, the user probably doesn't mean to inc/dec\n // this isn't perfect, events come in fast with small deltas and a part of the scroll may give a false indication\n // especially if the user is scrolling near 45deg\n if (Math.abs(event.deltaY) <= Math.abs(event.deltaX))\n return\n\n event.preventDefault()\n if (event.deltaY > 0)\n rootContext.handleIncrease()\n else if (event.deltaY < 0)\n rootContext.handleDecrease()\n}\n\nonMounted(() => {\n rootContext.onInputElement(currentElement.value as HTMLInputElement)\n})\n\nconst inputValue = ref(rootContext.textValue.value)\nwatch(() => rootContext.textValue.value, () => {\n inputValue.value = rootContext.textValue.value\n}, { immediate: true, deep: true })\n\nfunction handleChange() {\n requestAnimationFrame(() => {\n inputValue.value = rootContext.textValue.value\n })\n}\n</script>\n\n<template>\n <Primitive\n v-bind=\"props\"\n :id=\"rootContext.id.value\"\n ref=\"primitiveElement\"\n :value=\"inputValue\"\n role=\"spinbutton\"\n type=\"text\"\n tabindex=\"0\"\n :inputmode=\"rootContext.inputMode.value\"\n :disabled=\"rootContext.disabled.value ? '' : undefined\"\n :data-disabled=\"rootContext.disabled.value ? '' : undefined\"\n autocomplete=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n aria-roledescription=\"Number field\"\n :aria-valuenow=\"rootContext.modelValue.value\"\n :aria-valuemin=\"rootContext.min.value\"\n :aria-valuemax=\"rootContext.max.value\"\n @keydown.up.prevent=\"rootContext.handleIncrease()\"\n @keydown.down.prevent=\"rootContext.handleDecrease()\"\n @keydown.page-up.prevent=\"rootContext.handleIncrease(10)\"\n @keydown.page-down.prevent=\"rootContext.handleDecrease(10)\"\n @keydown.home.prevent=\"rootContext.handleMinMaxValue('min')\"\n @keydown.end.prevent=\"rootContext.handleMinMaxValue('max')\"\n @wheel=\"handleWheelEvent\"\n @beforeinput=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n let nextValue\n = target.value.slice(0, target.selectionStart ?? undefined)\n + (event.data ?? '')\n + target.value.slice(target.selectionEnd ?? undefined);\n\n // validate\n if (!rootContext.validate(nextValue))\n event.preventDefault()\n }\"\n @input=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n inputValue = target.value\n }\"\n @change=\"handleChange\"\n @keydown.enter=\"rootContext.applyInputValue($event.target?.value)\"\n @blur=\"rootContext.applyInputValue($event.target?.value)\"\n >\n <slot />\n </Primitive>\n</template>\n"],"names":["usePrimitiveElement","injectNumberFieldRootContext","getActiveElement","onMounted","ref","watch"],"mappings":";;;;;;;;;;;;;;;AAaA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAId,IAAA,MAAM,EAAE,gBAAA,EAAkB,cAAe,EAAA,GAAIA,iDAAoB,EAAA;AACjE,IAAA,MAAM,cAAcC,wDAA6B,EAAA;AAEjD,IAAA,SAAS,iBAAiB,KAAmB,EAAA;AAE3C,MAAI,IAAA,KAAA,CAAM,WAAWC,wCAAiB,EAAA;AACpC,QAAA;AAMF,MAAI,IAAA,IAAA,CAAK,IAAI,KAAM,CAAA,MAAM,KAAK,IAAK,CAAA,GAAA,CAAI,MAAM,MAAM,CAAA;AACjD,QAAA;AAEF,MAAA,KAAA,CAAM,cAAe,EAAA;AACrB,MAAA,IAAI,MAAM,MAAS,GAAA,CAAA;AACjB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA,WAAA,IACpB,MAAM,MAAS,GAAA,CAAA;AACtB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA;AAG/B,IAAAC,aAAA,CAAU,MAAM;AACd,MAAY,WAAA,CAAA,cAAA,CAAe,eAAe,KAAyB,CAAA;AAAA,KACpE,CAAA;AAED,IAAA,MAAM,UAAa,GAAAC,OAAA,CAAI,WAAY,CAAA,SAAA,CAAU,KAAK,CAAA;AAClD,IAAAC,SAAA,CAAM,MAAM,WAAA,CAAY,SAAU,CAAA,KAAA,EAAO,MAAM;AAC7C,MAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OACxC,EAAE,SAAA,EAAW,IAAM,EAAA,IAAA,EAAM,MAAM,CAAA;AAElC,IAAA,SAAS,YAAe,GAAA;AACtB,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OAC1C,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NumberFieldInput.cjs","sources":["../../src/NumberField/NumberFieldInput.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { injectNumberFieldRootContext } from './NumberFieldRoot.vue'\nimport { onMounted, ref, watch } from 'vue'\nimport { getActiveElement } from '@/shared'\n\nexport interface NumberFieldInputProps extends PrimitiveProps {\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\n\nconst props = withDefaults(defineProps<NumberFieldInputProps>(), {\n as: 'input',\n})\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\nconst rootContext = injectNumberFieldRootContext()\n\nfunction handleWheelEvent(event: WheelEvent) {\n if (rootContext.disableWheelChange.value)\n return\n\n // only handle when in focus\n if (event.target !== getActiveElement())\n return\n\n // if on a trackpad, users can scroll in both X and Y at once, check the magnitude of the change\n // if it's mostly in the X direction, then just return, the user probably doesn't mean to inc/dec\n // this isn't perfect, events come in fast with small deltas and a part of the scroll may give a false indication\n // especially if the user is scrolling near 45deg\n if (Math.abs(event.deltaY) <= Math.abs(event.deltaX))\n return\n\n event.preventDefault()\n if (event.deltaY > 0)\n rootContext.handleIncrease()\n else if (event.deltaY < 0)\n rootContext.handleDecrease()\n}\n\nonMounted(() => {\n rootContext.onInputElement(currentElement.value as HTMLInputElement)\n})\n\nconst inputValue = ref(rootContext.textValue.value)\nwatch(() => rootContext.textValue.value, () => {\n inputValue.value = rootContext.textValue.value\n}, { immediate: true, deep: true })\n\nfunction handleChange() {\n requestAnimationFrame(() => {\n inputValue.value = rootContext.textValue.value\n })\n}\n</script>\n\n<template>\n <Primitive\n v-bind=\"props\"\n :id=\"rootContext.id.value\"\n ref=\"primitiveElement\"\n :value=\"inputValue\"\n role=\"spinbutton\"\n type=\"text\"\n tabindex=\"0\"\n :inputmode=\"rootContext.inputMode.value\"\n :disabled=\"rootContext.disabled.value ? '' : undefined\"\n :data-disabled=\"rootContext.disabled.value ? '' : undefined\"\n autocomplete=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n aria-roledescription=\"Number field\"\n :aria-valuenow=\"rootContext.modelValue.value\"\n :aria-valuemin=\"rootContext.min.value\"\n :aria-valuemax=\"rootContext.max.value\"\n @keydown.up.prevent=\"rootContext.handleIncrease()\"\n @keydown.down.prevent=\"rootContext.handleDecrease()\"\n @keydown.page-up.prevent=\"rootContext.handleIncrease(10)\"\n @keydown.page-down.prevent=\"rootContext.handleDecrease(10)\"\n @keydown.home.prevent=\"rootContext.handleMinMaxValue('min')\"\n @keydown.end.prevent=\"rootContext.handleMinMaxValue('max')\"\n @wheel=\"handleWheelEvent\"\n @beforeinput=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n let nextValue\n = target.value.slice(0, target.selectionStart ?? undefined)\n + (event.data ?? '')\n + target.value.slice(target.selectionEnd ?? undefined);\n\n // validate\n if (!rootContext.validate(nextValue))\n event.preventDefault()\n }\"\n @input=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n inputValue = target.value\n }\"\n @change=\"handleChange\"\n @keydown.enter=\"rootContext.applyInputValue($event.target?.value)\"\n @blur=\"rootContext.applyInputValue($event.target?.value)\"\n >\n <slot />\n </Primitive>\n</template>\n"],"names":["usePrimitiveElement","injectNumberFieldRootContext","getActiveElement","onMounted","ref","watch"],"mappings":";;;;;;;;;;;;;;;AAaA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAId,IAAA,MAAM,EAAE,gBAAA,EAAkB,cAAe,EAAA,GAAIA,iDAAoB,EAAA;AACjE,IAAA,MAAM,cAAcC,wDAA6B,EAAA;AAEjD,IAAA,SAAS,iBAAiB,KAAmB,EAAA;AAC3C,MAAA,IAAI,YAAY,kBAAmB,CAAA,KAAA;AACjC,QAAA;AAGF,MAAI,IAAA,KAAA,CAAM,WAAWC,wCAAiB,EAAA;AACpC,QAAA;AAMF,MAAI,IAAA,IAAA,CAAK,IAAI,KAAM,CAAA,MAAM,KAAK,IAAK,CAAA,GAAA,CAAI,MAAM,MAAM,CAAA;AACjD,QAAA;AAEF,MAAA,KAAA,CAAM,cAAe,EAAA;AACrB,MAAA,IAAI,MAAM,MAAS,GAAA,CAAA;AACjB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA,WAAA,IACpB,MAAM,MAAS,GAAA,CAAA;AACtB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA;AAG/B,IAAAC,aAAA,CAAU,MAAM;AACd,MAAY,WAAA,CAAA,cAAA,CAAe,eAAe,KAAyB,CAAA;AAAA,KACpE,CAAA;AAED,IAAA,MAAM,UAAa,GAAAC,OAAA,CAAI,WAAY,CAAA,SAAA,CAAU,KAAK,CAAA;AAClD,IAAAC,SAAA,CAAM,MAAM,WAAA,CAAY,SAAU,CAAA,KAAA,EAAO,MAAM;AAC7C,MAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OACxC,EAAE,SAAA,EAAW,IAAM,EAAA,IAAA,EAAM,MAAM,CAAA;AAElC,IAAA,SAAS,YAAe,GAAA;AACtB,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OAC1C,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -15,6 +15,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
15
15
  const { primitiveElement, currentElement } = usePrimitiveElement();
16
16
  const rootContext = injectNumberFieldRootContext();
17
17
  function handleWheelEvent(event) {
18
+ if (rootContext.disableWheelChange.value)
19
+ return;
18
20
  if (event.target !== getActiveElement())
19
21
  return;
20
22
  if (Math.abs(event.deltaY) <= Math.abs(event.deltaX))
@@ -1 +1 @@
1
- {"version":3,"file":"NumberFieldInput.js","sources":["../../src/NumberField/NumberFieldInput.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { injectNumberFieldRootContext } from './NumberFieldRoot.vue'\nimport { onMounted, ref, watch } from 'vue'\nimport { getActiveElement } from '@/shared'\n\nexport interface NumberFieldInputProps extends PrimitiveProps {\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\n\nconst props = withDefaults(defineProps<NumberFieldInputProps>(), {\n as: 'input',\n})\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\nconst rootContext = injectNumberFieldRootContext()\n\nfunction handleWheelEvent(event: WheelEvent) {\n // only handle when in focus\n if (event.target !== getActiveElement())\n return\n\n // if on a trackpad, users can scroll in both X and Y at once, check the magnitude of the change\n // if it's mostly in the X direction, then just return, the user probably doesn't mean to inc/dec\n // this isn't perfect, events come in fast with small deltas and a part of the scroll may give a false indication\n // especially if the user is scrolling near 45deg\n if (Math.abs(event.deltaY) <= Math.abs(event.deltaX))\n return\n\n event.preventDefault()\n if (event.deltaY > 0)\n rootContext.handleIncrease()\n else if (event.deltaY < 0)\n rootContext.handleDecrease()\n}\n\nonMounted(() => {\n rootContext.onInputElement(currentElement.value as HTMLInputElement)\n})\n\nconst inputValue = ref(rootContext.textValue.value)\nwatch(() => rootContext.textValue.value, () => {\n inputValue.value = rootContext.textValue.value\n}, { immediate: true, deep: true })\n\nfunction handleChange() {\n requestAnimationFrame(() => {\n inputValue.value = rootContext.textValue.value\n })\n}\n</script>\n\n<template>\n <Primitive\n v-bind=\"props\"\n :id=\"rootContext.id.value\"\n ref=\"primitiveElement\"\n :value=\"inputValue\"\n role=\"spinbutton\"\n type=\"text\"\n tabindex=\"0\"\n :inputmode=\"rootContext.inputMode.value\"\n :disabled=\"rootContext.disabled.value ? '' : undefined\"\n :data-disabled=\"rootContext.disabled.value ? '' : undefined\"\n autocomplete=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n aria-roledescription=\"Number field\"\n :aria-valuenow=\"rootContext.modelValue.value\"\n :aria-valuemin=\"rootContext.min.value\"\n :aria-valuemax=\"rootContext.max.value\"\n @keydown.up.prevent=\"rootContext.handleIncrease()\"\n @keydown.down.prevent=\"rootContext.handleDecrease()\"\n @keydown.page-up.prevent=\"rootContext.handleIncrease(10)\"\n @keydown.page-down.prevent=\"rootContext.handleDecrease(10)\"\n @keydown.home.prevent=\"rootContext.handleMinMaxValue('min')\"\n @keydown.end.prevent=\"rootContext.handleMinMaxValue('max')\"\n @wheel=\"handleWheelEvent\"\n @beforeinput=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n let nextValue\n = target.value.slice(0, target.selectionStart ?? undefined)\n + (event.data ?? '')\n + target.value.slice(target.selectionEnd ?? undefined);\n\n // validate\n if (!rootContext.validate(nextValue))\n event.preventDefault()\n }\"\n @input=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n inputValue = target.value\n }\"\n @change=\"handleChange\"\n @keydown.enter=\"rootContext.applyInputValue($event.target?.value)\"\n @blur=\"rootContext.applyInputValue($event.target?.value)\"\n >\n <slot />\n </Primitive>\n</template>\n"],"names":[],"mappings":";;;;;;;;;;;;;AAaA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAId,IAAA,MAAM,EAAE,gBAAA,EAAkB,cAAe,EAAA,GAAI,mBAAoB,EAAA;AACjE,IAAA,MAAM,cAAc,4BAA6B,EAAA;AAEjD,IAAA,SAAS,iBAAiB,KAAmB,EAAA;AAE3C,MAAI,IAAA,KAAA,CAAM,WAAW,gBAAiB,EAAA;AACpC,QAAA;AAMF,MAAI,IAAA,IAAA,CAAK,IAAI,KAAM,CAAA,MAAM,KAAK,IAAK,CAAA,GAAA,CAAI,MAAM,MAAM,CAAA;AACjD,QAAA;AAEF,MAAA,KAAA,CAAM,cAAe,EAAA;AACrB,MAAA,IAAI,MAAM,MAAS,GAAA,CAAA;AACjB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA,WAAA,IACpB,MAAM,MAAS,GAAA,CAAA;AACtB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA;AAG/B,IAAA,SAAA,CAAU,MAAM;AACd,MAAY,WAAA,CAAA,cAAA,CAAe,eAAe,KAAyB,CAAA;AAAA,KACpE,CAAA;AAED,IAAA,MAAM,UAAa,GAAA,GAAA,CAAI,WAAY,CAAA,SAAA,CAAU,KAAK,CAAA;AAClD,IAAA,KAAA,CAAM,MAAM,WAAA,CAAY,SAAU,CAAA,KAAA,EAAO,MAAM;AAC7C,MAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OACxC,EAAE,SAAA,EAAW,IAAM,EAAA,IAAA,EAAM,MAAM,CAAA;AAElC,IAAA,SAAS,YAAe,GAAA;AACtB,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OAC1C,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NumberFieldInput.js","sources":["../../src/NumberField/NumberFieldInput.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { injectNumberFieldRootContext } from './NumberFieldRoot.vue'\nimport { onMounted, ref, watch } from 'vue'\nimport { getActiveElement } from '@/shared'\n\nexport interface NumberFieldInputProps extends PrimitiveProps {\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\n\nconst props = withDefaults(defineProps<NumberFieldInputProps>(), {\n as: 'input',\n})\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\nconst rootContext = injectNumberFieldRootContext()\n\nfunction handleWheelEvent(event: WheelEvent) {\n if (rootContext.disableWheelChange.value)\n return\n\n // only handle when in focus\n if (event.target !== getActiveElement())\n return\n\n // if on a trackpad, users can scroll in both X and Y at once, check the magnitude of the change\n // if it's mostly in the X direction, then just return, the user probably doesn't mean to inc/dec\n // this isn't perfect, events come in fast with small deltas and a part of the scroll may give a false indication\n // especially if the user is scrolling near 45deg\n if (Math.abs(event.deltaY) <= Math.abs(event.deltaX))\n return\n\n event.preventDefault()\n if (event.deltaY > 0)\n rootContext.handleIncrease()\n else if (event.deltaY < 0)\n rootContext.handleDecrease()\n}\n\nonMounted(() => {\n rootContext.onInputElement(currentElement.value as HTMLInputElement)\n})\n\nconst inputValue = ref(rootContext.textValue.value)\nwatch(() => rootContext.textValue.value, () => {\n inputValue.value = rootContext.textValue.value\n}, { immediate: true, deep: true })\n\nfunction handleChange() {\n requestAnimationFrame(() => {\n inputValue.value = rootContext.textValue.value\n })\n}\n</script>\n\n<template>\n <Primitive\n v-bind=\"props\"\n :id=\"rootContext.id.value\"\n ref=\"primitiveElement\"\n :value=\"inputValue\"\n role=\"spinbutton\"\n type=\"text\"\n tabindex=\"0\"\n :inputmode=\"rootContext.inputMode.value\"\n :disabled=\"rootContext.disabled.value ? '' : undefined\"\n :data-disabled=\"rootContext.disabled.value ? '' : undefined\"\n autocomplete=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n aria-roledescription=\"Number field\"\n :aria-valuenow=\"rootContext.modelValue.value\"\n :aria-valuemin=\"rootContext.min.value\"\n :aria-valuemax=\"rootContext.max.value\"\n @keydown.up.prevent=\"rootContext.handleIncrease()\"\n @keydown.down.prevent=\"rootContext.handleDecrease()\"\n @keydown.page-up.prevent=\"rootContext.handleIncrease(10)\"\n @keydown.page-down.prevent=\"rootContext.handleDecrease(10)\"\n @keydown.home.prevent=\"rootContext.handleMinMaxValue('min')\"\n @keydown.end.prevent=\"rootContext.handleMinMaxValue('max')\"\n @wheel=\"handleWheelEvent\"\n @beforeinput=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n let nextValue\n = target.value.slice(0, target.selectionStart ?? undefined)\n + (event.data ?? '')\n + target.value.slice(target.selectionEnd ?? undefined);\n\n // validate\n if (!rootContext.validate(nextValue))\n event.preventDefault()\n }\"\n @input=\"(event: InputEvent) => {\n const target = event.target as HTMLInputElement\n inputValue = target.value\n }\"\n @change=\"handleChange\"\n @keydown.enter=\"rootContext.applyInputValue($event.target?.value)\"\n @blur=\"rootContext.applyInputValue($event.target?.value)\"\n >\n <slot />\n </Primitive>\n</template>\n"],"names":[],"mappings":";;;;;;;;;;;;;AAaA,IAAA,MAAM,KAAQ,GAAA,OAAA;AAId,IAAA,MAAM,EAAE,gBAAA,EAAkB,cAAe,EAAA,GAAI,mBAAoB,EAAA;AACjE,IAAA,MAAM,cAAc,4BAA6B,EAAA;AAEjD,IAAA,SAAS,iBAAiB,KAAmB,EAAA;AAC3C,MAAA,IAAI,YAAY,kBAAmB,CAAA,KAAA;AACjC,QAAA;AAGF,MAAI,IAAA,KAAA,CAAM,WAAW,gBAAiB,EAAA;AACpC,QAAA;AAMF,MAAI,IAAA,IAAA,CAAK,IAAI,KAAM,CAAA,MAAM,KAAK,IAAK,CAAA,GAAA,CAAI,MAAM,MAAM,CAAA;AACjD,QAAA;AAEF,MAAA,KAAA,CAAM,cAAe,EAAA;AACrB,MAAA,IAAI,MAAM,MAAS,GAAA,CAAA;AACjB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA,WAAA,IACpB,MAAM,MAAS,GAAA,CAAA;AACtB,QAAA,WAAA,CAAY,cAAe,EAAA;AAAA;AAG/B,IAAA,SAAA,CAAU,MAAM;AACd,MAAY,WAAA,CAAA,cAAA,CAAe,eAAe,KAAyB,CAAA;AAAA,KACpE,CAAA;AAED,IAAA,MAAM,UAAa,GAAA,GAAA,CAAI,WAAY,CAAA,SAAA,CAAU,KAAK,CAAA;AAClD,IAAA,KAAA,CAAM,MAAM,WAAA,CAAY,SAAU,CAAA,KAAA,EAAO,MAAM;AAC7C,MAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OACxC,EAAE,SAAA,EAAW,IAAM,EAAA,IAAA,EAAM,MAAM,CAAA;AAElC,IAAA,SAAS,YAAe,GAAA;AACtB,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAW,UAAA,CAAA,KAAA,GAAQ,YAAY,SAAU,CAAA,KAAA;AAAA,OAC1C,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -23,9 +23,11 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
23
23
  min: {},
24
24
  max: {},
25
25
  step: { default: 1 },
26
+ stepSnapping: { type: Boolean, default: true },
26
27
  formatOptions: {},
27
28
  locale: {},
28
29
  disabled: { type: Boolean },
30
+ disableWheelChange: { type: Boolean },
29
31
  id: {},
30
32
  asChild: { type: Boolean },
31
33
  as: { default: "div" },
@@ -36,7 +38,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
36
38
  setup(__props, { emit: __emit }) {
37
39
  const props = __props;
38
40
  const emits = __emit;
39
- const { disabled, min, max, step, formatOptions, id, locale: propLocale } = vue.toRefs(props);
41
+ const { disabled, disableWheelChange, min, max, step, stepSnapping, formatOptions, id, locale: propLocale } = vue.toRefs(props);
40
42
  const modelValue = core.useVModel(props, "modelValue", emits, {
41
43
  defaultValue: props.defaultValue,
42
44
  passive: props.modelValue === undefined
@@ -94,7 +96,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
94
96
  }
95
97
  function clampInputValue(val) {
96
98
  let clampedValue;
97
- if (step.value === undefined || isNaN(step.value))
99
+ if (step.value === undefined || isNaN(step.value) || !stepSnapping.value)
98
100
  clampedValue = shared_clamp.clamp(val, min.value, max.value);
99
101
  else
100
102
  clampedValue = shared_clamp.snapValueToStep(val, min.value, max.value, step.value);
@@ -122,6 +124,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
122
124
  validate,
123
125
  applyInputValue,
124
126
  disabled,
127
+ disableWheelChange,
125
128
  max,
126
129
  min,
127
130
  isDecreaseDisabled,
@@ -1 +1 @@
1
- {"version":3,"file":"NumberFieldRoot.cjs","sources":["../../src/NumberField/NumberFieldRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useVModel } from '@vueuse/core'\nimport { clamp, createContext, snapValueToStep, useFormControl, useLocale } from '@/shared'\nimport { type HTMLAttributes, type Ref, computed, ref, toRefs } from 'vue'\nimport type { FormFieldProps } from '@/shared/types'\n\nexport interface NumberFieldRootProps extends PrimitiveProps, FormFieldProps {\n defaultValue?: number\n modelValue?: number | null\n /** The smallest value allowed for the input. */\n min?: number\n /** The largest value allowed for the input. */\n max?: number\n /** The amount that the input value changes with each increment or decrement \"tick\". */\n step?: number\n /** Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. */\n formatOptions?: Intl.NumberFormatOptions\n /** The locale to use for formatting dates */\n locale?: string\n /** When `true`, prevents the user from interacting with the Number Field. */\n disabled?: boolean\n /** Id of the element */\n id?: string\n}\n\nexport type NumberFieldRootEmits = {\n 'update:modelValue': [val: number]\n}\n\ninterface NumberFieldRootContext {\n modelValue: Ref<number>\n handleIncrease: (multiplier?: number) => void\n handleDecrease: (multiplier?: number) => void\n handleMinMaxValue: (type: 'min' | 'max') => void\n inputEl: Ref<HTMLInputElement | undefined>\n onInputElement: (el: HTMLInputElement) => void\n inputMode: Ref<HTMLAttributes['inputmode']>\n textValue: Ref<string>\n validate: (val: string) => boolean\n applyInputValue: (val: string) => void\n disabled: Ref<boolean>\n max: Ref<number | undefined>\n min: Ref<number | undefined>\n isDecreaseDisabled: Ref<boolean>\n isIncreaseDisabled: Ref<boolean>\n id: Ref<string | undefined>\n}\n\nexport const [injectNumberFieldRootContext, provideNumberFieldRootContext] = createContext<NumberFieldRootContext>('NumberFieldRoot')\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\nimport { handleDecimalOperation, useNumberFormatter, useNumberParser } from './utils'\nimport { VisuallyHiddenInput } from '@/VisuallyHidden'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NumberFieldRootProps>(), {\n as: 'div',\n defaultValue: undefined,\n step: 1,\n})\nconst emits = defineEmits<NumberFieldRootEmits>()\nconst { disabled, min, max, step, formatOptions, id, locale: propLocale } = toRefs(props)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue,\n passive: (props.modelValue === undefined) as false,\n}) as Ref<number>\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\n\nconst locale = useLocale(propLocale)\nconst isFormControl = useFormControl(currentElement)\nconst inputEl = ref<HTMLInputElement>()\n\nconst isDecreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === min.value\n || (min.value && !isNaN(modelValue.value) ? (handleDecimalOperation('-', modelValue.value, step.value) < min.value) : false)),\n)\nconst isIncreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === max.value\n || (max.value && !isNaN(modelValue.value) ? (handleDecimalOperation('+', modelValue.value, step.value) > max.value) : false)),\n)\n\nfunction handleChangingValue(type: 'increase' | 'decrease', multiplier = 1) {\n inputEl.value?.focus()\n const currentInputValue = numberParser.parse(inputEl.value?.value ?? '')\n if (props.disabled)\n return\n if (isNaN(currentInputValue)) {\n modelValue.value = min.value ?? 0\n }\n else {\n if (type === 'increase')\n modelValue.value = clampInputValue(currentInputValue + ((step.value ?? 1) * multiplier))\n else\n modelValue.value = clampInputValue(currentInputValue - ((step.value ?? 1) * multiplier))\n }\n}\n\nfunction handleIncrease(multiplier = 1) {\n handleChangingValue('increase', multiplier)\n}\nfunction handleDecrease(multiplier = 1) {\n handleChangingValue('decrease', multiplier)\n}\n\nfunction handleMinMaxValue(type: 'min' | 'max') {\n if (type === 'min' && min.value !== undefined)\n modelValue.value = clampInputValue(min.value)\n else if (type === 'max' && max.value !== undefined)\n modelValue.value = clampInputValue(max.value)\n}\n\n// Formatter\nconst numberFormatter = useNumberFormatter(locale, formatOptions)\nconst numberParser = useNumberParser(locale, formatOptions)\n\nconst inputMode = computed<HTMLAttributes['inputmode']>(() => {\n // The inputMode attribute influences the software keyboard that is shown on touch devices.\n // Browsers and operating systems are quite inconsistent about what keys are available, however.\n // We choose between numeric and decimal based on whether we allow negative and fractional numbers,\n // and based on testing on various devices to determine what keys are available in each inputMode.\n const hasDecimals = numberFormatter.resolvedOptions().maximumFractionDigits! > 0\n\n return hasDecimals ? 'decimal' : 'numeric'\n})\n// Replace negative textValue formatted using currencySign: 'accounting'\n// with a textValue that can be announced using a minus sign.\nconst textValueFormatter = useNumberFormatter(locale, formatOptions)\nconst textValue = computed(() => isNaN(modelValue.value) ? '' : textValueFormatter.format(modelValue.value))\n\nfunction validate(val: string) {\n return numberParser.isValidPartialNumber(val, min.value, max.value)\n}\n\nfunction setInputValue(val: string) {\n if (inputEl.value)\n inputEl.value.value = val\n}\n\nfunction clampInputValue(val: number) {\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number\n if (step.value === undefined || isNaN(step.value))\n clampedValue = clamp(val, min.value, max.value)\n else\n clampedValue = snapValueToStep(val, min.value, max.value, step.value)\n\n clampedValue = numberParser.parse(numberFormatter.format(clampedValue))\n return clampedValue\n}\n\nfunction applyInputValue(val: string) {\n const parsedValue = numberParser.parse(val)\n\n modelValue.value = clampInputValue(parsedValue)\n // Set to empty state if input value is empty\n if (!val.length)\n return setInputValue(val)\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsedValue))\n return setInputValue(textValue.value)\n\n return setInputValue(textValue.value)\n}\n\nprovideNumberFieldRootContext({\n modelValue,\n handleDecrease,\n handleIncrease,\n handleMinMaxValue,\n inputMode,\n inputEl,\n onInputElement: el => inputEl.value = el,\n textValue,\n validate,\n applyInputValue,\n disabled,\n max,\n min,\n isDecreaseDisabled,\n isIncreaseDisabled,\n id,\n})\n</script>\n\n<template>\n <Primitive\n v-bind=\"$attrs\"\n ref=\"primitiveElement\"\n role=\"group\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <slot\n :model-value=\"modelValue\"\n :text-value=\"textValue\"\n />\n\n <VisuallyHiddenInput\n v-if=\"isFormControl && name\"\n type=\"text\"\n :value=\"modelValue\"\n :name=\"name\"\n :disabled=\"disabled\"\n :required=\"required\"\n />\n </Primitive>\n</template>\n"],"names":["createContext","toRefs","useVModel","usePrimitiveElement","useLocale","useFormControl","ref","computed","handleDecimalOperation","useNumberFormatter","useNumberParser","clamp","snapValueToStep"],"mappings":"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"}
1
+ {"version":3,"file":"NumberFieldRoot.cjs","sources":["../../src/NumberField/NumberFieldRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useVModel } from '@vueuse/core'\nimport { clamp, createContext, snapValueToStep, useFormControl, useLocale } from '@/shared'\nimport { type HTMLAttributes, type Ref, computed, ref, toRefs } from 'vue'\nimport type { FormFieldProps } from '@/shared/types'\n\nexport interface NumberFieldRootProps extends PrimitiveProps, FormFieldProps {\n defaultValue?: number\n modelValue?: number | null\n /** The smallest value allowed for the input. */\n min?: number\n /** The largest value allowed for the input. */\n max?: number\n /** The amount that the input value changes with each increment or decrement \"tick\". */\n step?: number\n /** When `false`, prevents the value from snapping to the nearest increment of the step value */\n stepSnapping?: boolean\n /** Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. */\n formatOptions?: Intl.NumberFormatOptions\n /** The locale to use for formatting dates */\n locale?: string\n /** When `true`, prevents the user from interacting with the Number Field. */\n disabled?: boolean\n /** When `true`, prevents the value from changing on wheel scroll. */\n disableWheelChange?: boolean\n /** Id of the element */\n id?: string\n}\n\nexport type NumberFieldRootEmits = {\n 'update:modelValue': [val: number]\n}\n\ninterface NumberFieldRootContext {\n modelValue: Ref<number>\n handleIncrease: (multiplier?: number) => void\n handleDecrease: (multiplier?: number) => void\n handleMinMaxValue: (type: 'min' | 'max') => void\n inputEl: Ref<HTMLInputElement | undefined>\n onInputElement: (el: HTMLInputElement) => void\n inputMode: Ref<HTMLAttributes['inputmode']>\n textValue: Ref<string>\n validate: (val: string) => boolean\n applyInputValue: (val: string) => void\n disabled: Ref<boolean>\n disableWheelChange: Ref<boolean>\n max: Ref<number | undefined>\n min: Ref<number | undefined>\n isDecreaseDisabled: Ref<boolean>\n isIncreaseDisabled: Ref<boolean>\n id: Ref<string | undefined>\n}\n\nexport const [injectNumberFieldRootContext, provideNumberFieldRootContext] = createContext<NumberFieldRootContext>('NumberFieldRoot')\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\nimport { handleDecimalOperation, useNumberFormatter, useNumberParser } from './utils'\nimport { VisuallyHiddenInput } from '@/VisuallyHidden'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NumberFieldRootProps>(), {\n as: 'div',\n defaultValue: undefined,\n step: 1,\n stepSnapping: true,\n})\nconst emits = defineEmits<NumberFieldRootEmits>()\nconst { disabled, disableWheelChange, min, max, step, stepSnapping, formatOptions, id, locale: propLocale } = toRefs(props)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue,\n passive: (props.modelValue === undefined) as false,\n}) as Ref<number>\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\n\nconst locale = useLocale(propLocale)\nconst isFormControl = useFormControl(currentElement)\nconst inputEl = ref<HTMLInputElement>()\n\nconst isDecreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === min.value\n || (min.value && !isNaN(modelValue.value) ? (handleDecimalOperation('-', modelValue.value, step.value) < min.value) : false)),\n)\nconst isIncreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === max.value\n || (max.value && !isNaN(modelValue.value) ? (handleDecimalOperation('+', modelValue.value, step.value) > max.value) : false)),\n)\n\nfunction handleChangingValue(type: 'increase' | 'decrease', multiplier = 1) {\n inputEl.value?.focus()\n const currentInputValue = numberParser.parse(inputEl.value?.value ?? '')\n if (props.disabled)\n return\n if (isNaN(currentInputValue)) {\n modelValue.value = min.value ?? 0\n }\n else {\n if (type === 'increase')\n modelValue.value = clampInputValue(currentInputValue + ((step.value ?? 1) * multiplier))\n else\n modelValue.value = clampInputValue(currentInputValue - ((step.value ?? 1) * multiplier))\n }\n}\n\nfunction handleIncrease(multiplier = 1) {\n handleChangingValue('increase', multiplier)\n}\nfunction handleDecrease(multiplier = 1) {\n handleChangingValue('decrease', multiplier)\n}\n\nfunction handleMinMaxValue(type: 'min' | 'max') {\n if (type === 'min' && min.value !== undefined)\n modelValue.value = clampInputValue(min.value)\n else if (type === 'max' && max.value !== undefined)\n modelValue.value = clampInputValue(max.value)\n}\n\n// Formatter\nconst numberFormatter = useNumberFormatter(locale, formatOptions)\nconst numberParser = useNumberParser(locale, formatOptions)\n\nconst inputMode = computed<HTMLAttributes['inputmode']>(() => {\n // The inputMode attribute influences the software keyboard that is shown on touch devices.\n // Browsers and operating systems are quite inconsistent about what keys are available, however.\n // We choose between numeric and decimal based on whether we allow negative and fractional numbers,\n // and based on testing on various devices to determine what keys are available in each inputMode.\n const hasDecimals = numberFormatter.resolvedOptions().maximumFractionDigits! > 0\n\n return hasDecimals ? 'decimal' : 'numeric'\n})\n// Replace negative textValue formatted using currencySign: 'accounting'\n// with a textValue that can be announced using a minus sign.\nconst textValueFormatter = useNumberFormatter(locale, formatOptions)\nconst textValue = computed(() => isNaN(modelValue.value) ? '' : textValueFormatter.format(modelValue.value))\n\nfunction validate(val: string) {\n return numberParser.isValidPartialNumber(val, min.value, max.value)\n}\n\nfunction setInputValue(val: string) {\n if (inputEl.value)\n inputEl.value.value = val\n}\n\nfunction clampInputValue(val: number) {\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number\n if (step.value === undefined || isNaN(step.value) || !stepSnapping.value)\n clampedValue = clamp(val, min.value, max.value)\n else\n clampedValue = snapValueToStep(val, min.value, max.value, step.value)\n\n clampedValue = numberParser.parse(numberFormatter.format(clampedValue))\n return clampedValue\n}\n\nfunction applyInputValue(val: string) {\n const parsedValue = numberParser.parse(val)\n\n modelValue.value = clampInputValue(parsedValue)\n // Set to empty state if input value is empty\n if (!val.length)\n return setInputValue(val)\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsedValue))\n return setInputValue(textValue.value)\n\n return setInputValue(textValue.value)\n}\n\nprovideNumberFieldRootContext({\n modelValue,\n handleDecrease,\n handleIncrease,\n handleMinMaxValue,\n inputMode,\n inputEl,\n onInputElement: el => inputEl.value = el,\n textValue,\n validate,\n applyInputValue,\n disabled,\n disableWheelChange,\n max,\n min,\n isDecreaseDisabled,\n isIncreaseDisabled,\n id,\n})\n</script>\n\n<template>\n <Primitive\n v-bind=\"$attrs\"\n ref=\"primitiveElement\"\n role=\"group\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <slot\n :model-value=\"modelValue\"\n :text-value=\"textValue\"\n />\n\n <VisuallyHiddenInput\n v-if=\"isFormControl && name\"\n type=\"text\"\n :value=\"modelValue\"\n :name=\"name\"\n :disabled=\"disabled\"\n :required=\"required\"\n />\n </Primitive>\n</template>\n"],"names":["createContext","toRefs","useVModel","usePrimitiveElement","useLocale","useFormControl","ref","computed","handleDecimalOperation","useNumberFormatter","useNumberParser","clamp","snapValueToStep"],"mappings":"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"}
@@ -21,9 +21,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
21
21
  min: {},
22
22
  max: {},
23
23
  step: { default: 1 },
24
+ stepSnapping: { type: Boolean, default: true },
24
25
  formatOptions: {},
25
26
  locale: {},
26
27
  disabled: { type: Boolean },
28
+ disableWheelChange: { type: Boolean },
27
29
  id: {},
28
30
  asChild: { type: Boolean },
29
31
  as: { default: "div" },
@@ -34,7 +36,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
34
36
  setup(__props, { emit: __emit }) {
35
37
  const props = __props;
36
38
  const emits = __emit;
37
- const { disabled, min, max, step, formatOptions, id, locale: propLocale } = toRefs(props);
39
+ const { disabled, disableWheelChange, min, max, step, stepSnapping, formatOptions, id, locale: propLocale } = toRefs(props);
38
40
  const modelValue = useVModel(props, "modelValue", emits, {
39
41
  defaultValue: props.defaultValue,
40
42
  passive: props.modelValue === undefined
@@ -92,7 +94,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
92
94
  }
93
95
  function clampInputValue(val) {
94
96
  let clampedValue;
95
- if (step.value === undefined || isNaN(step.value))
97
+ if (step.value === undefined || isNaN(step.value) || !stepSnapping.value)
96
98
  clampedValue = clamp(val, min.value, max.value);
97
99
  else
98
100
  clampedValue = snapValueToStep(val, min.value, max.value, step.value);
@@ -120,6 +122,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
120
122
  validate,
121
123
  applyInputValue,
122
124
  disabled,
125
+ disableWheelChange,
123
126
  max,
124
127
  min,
125
128
  isDecreaseDisabled,
@@ -1 +1 @@
1
- {"version":3,"file":"NumberFieldRoot.js","sources":["../../src/NumberField/NumberFieldRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useVModel } from '@vueuse/core'\nimport { clamp, createContext, snapValueToStep, useFormControl, useLocale } from '@/shared'\nimport { type HTMLAttributes, type Ref, computed, ref, toRefs } from 'vue'\nimport type { FormFieldProps } from '@/shared/types'\n\nexport interface NumberFieldRootProps extends PrimitiveProps, FormFieldProps {\n defaultValue?: number\n modelValue?: number | null\n /** The smallest value allowed for the input. */\n min?: number\n /** The largest value allowed for the input. */\n max?: number\n /** The amount that the input value changes with each increment or decrement \"tick\". */\n step?: number\n /** Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. */\n formatOptions?: Intl.NumberFormatOptions\n /** The locale to use for formatting dates */\n locale?: string\n /** When `true`, prevents the user from interacting with the Number Field. */\n disabled?: boolean\n /** Id of the element */\n id?: string\n}\n\nexport type NumberFieldRootEmits = {\n 'update:modelValue': [val: number]\n}\n\ninterface NumberFieldRootContext {\n modelValue: Ref<number>\n handleIncrease: (multiplier?: number) => void\n handleDecrease: (multiplier?: number) => void\n handleMinMaxValue: (type: 'min' | 'max') => void\n inputEl: Ref<HTMLInputElement | undefined>\n onInputElement: (el: HTMLInputElement) => void\n inputMode: Ref<HTMLAttributes['inputmode']>\n textValue: Ref<string>\n validate: (val: string) => boolean\n applyInputValue: (val: string) => void\n disabled: Ref<boolean>\n max: Ref<number | undefined>\n min: Ref<number | undefined>\n isDecreaseDisabled: Ref<boolean>\n isIncreaseDisabled: Ref<boolean>\n id: Ref<string | undefined>\n}\n\nexport const [injectNumberFieldRootContext, provideNumberFieldRootContext] = createContext<NumberFieldRootContext>('NumberFieldRoot')\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\nimport { handleDecimalOperation, useNumberFormatter, useNumberParser } from './utils'\nimport { VisuallyHiddenInput } from '@/VisuallyHidden'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NumberFieldRootProps>(), {\n as: 'div',\n defaultValue: undefined,\n step: 1,\n})\nconst emits = defineEmits<NumberFieldRootEmits>()\nconst { disabled, min, max, step, formatOptions, id, locale: propLocale } = toRefs(props)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue,\n passive: (props.modelValue === undefined) as false,\n}) as Ref<number>\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\n\nconst locale = useLocale(propLocale)\nconst isFormControl = useFormControl(currentElement)\nconst inputEl = ref<HTMLInputElement>()\n\nconst isDecreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === min.value\n || (min.value && !isNaN(modelValue.value) ? (handleDecimalOperation('-', modelValue.value, step.value) < min.value) : false)),\n)\nconst isIncreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === max.value\n || (max.value && !isNaN(modelValue.value) ? (handleDecimalOperation('+', modelValue.value, step.value) > max.value) : false)),\n)\n\nfunction handleChangingValue(type: 'increase' | 'decrease', multiplier = 1) {\n inputEl.value?.focus()\n const currentInputValue = numberParser.parse(inputEl.value?.value ?? '')\n if (props.disabled)\n return\n if (isNaN(currentInputValue)) {\n modelValue.value = min.value ?? 0\n }\n else {\n if (type === 'increase')\n modelValue.value = clampInputValue(currentInputValue + ((step.value ?? 1) * multiplier))\n else\n modelValue.value = clampInputValue(currentInputValue - ((step.value ?? 1) * multiplier))\n }\n}\n\nfunction handleIncrease(multiplier = 1) {\n handleChangingValue('increase', multiplier)\n}\nfunction handleDecrease(multiplier = 1) {\n handleChangingValue('decrease', multiplier)\n}\n\nfunction handleMinMaxValue(type: 'min' | 'max') {\n if (type === 'min' && min.value !== undefined)\n modelValue.value = clampInputValue(min.value)\n else if (type === 'max' && max.value !== undefined)\n modelValue.value = clampInputValue(max.value)\n}\n\n// Formatter\nconst numberFormatter = useNumberFormatter(locale, formatOptions)\nconst numberParser = useNumberParser(locale, formatOptions)\n\nconst inputMode = computed<HTMLAttributes['inputmode']>(() => {\n // The inputMode attribute influences the software keyboard that is shown on touch devices.\n // Browsers and operating systems are quite inconsistent about what keys are available, however.\n // We choose between numeric and decimal based on whether we allow negative and fractional numbers,\n // and based on testing on various devices to determine what keys are available in each inputMode.\n const hasDecimals = numberFormatter.resolvedOptions().maximumFractionDigits! > 0\n\n return hasDecimals ? 'decimal' : 'numeric'\n})\n// Replace negative textValue formatted using currencySign: 'accounting'\n// with a textValue that can be announced using a minus sign.\nconst textValueFormatter = useNumberFormatter(locale, formatOptions)\nconst textValue = computed(() => isNaN(modelValue.value) ? '' : textValueFormatter.format(modelValue.value))\n\nfunction validate(val: string) {\n return numberParser.isValidPartialNumber(val, min.value, max.value)\n}\n\nfunction setInputValue(val: string) {\n if (inputEl.value)\n inputEl.value.value = val\n}\n\nfunction clampInputValue(val: number) {\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number\n if (step.value === undefined || isNaN(step.value))\n clampedValue = clamp(val, min.value, max.value)\n else\n clampedValue = snapValueToStep(val, min.value, max.value, step.value)\n\n clampedValue = numberParser.parse(numberFormatter.format(clampedValue))\n return clampedValue\n}\n\nfunction applyInputValue(val: string) {\n const parsedValue = numberParser.parse(val)\n\n modelValue.value = clampInputValue(parsedValue)\n // Set to empty state if input value is empty\n if (!val.length)\n return setInputValue(val)\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsedValue))\n return setInputValue(textValue.value)\n\n return setInputValue(textValue.value)\n}\n\nprovideNumberFieldRootContext({\n modelValue,\n handleDecrease,\n handleIncrease,\n handleMinMaxValue,\n inputMode,\n inputEl,\n onInputElement: el => inputEl.value = el,\n textValue,\n validate,\n applyInputValue,\n disabled,\n max,\n min,\n isDecreaseDisabled,\n isIncreaseDisabled,\n id,\n})\n</script>\n\n<template>\n <Primitive\n v-bind=\"$attrs\"\n ref=\"primitiveElement\"\n role=\"group\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <slot\n :model-value=\"modelValue\"\n :text-value=\"textValue\"\n />\n\n <VisuallyHiddenInput\n v-if=\"isFormControl && name\"\n type=\"text\"\n :value=\"modelValue\"\n :name=\"name\"\n :disabled=\"disabled\"\n :required=\"required\"\n />\n </Primitive>\n</template>\n"],"names":[],"mappings":";;;;;;;;;;;AAiDO,MAAM,CAAC,4BAAA,EAA8B,6BAA6B,CAAA,GAAI,cAAsC,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;AAYpI,IAAA,MAAM,KAAQ,GAAA,OAAA;AAKd,IAAA,MAAM,KAAQ,GAAA,MAAA;AACd,IAAM,MAAA,EAAE,QAAU,EAAA,GAAA,EAAK,GAAK,EAAA,IAAA,EAAM,aAAe,EAAA,EAAA,EAAI,MAAQ,EAAA,UAAA,EAAe,GAAA,MAAA,CAAO,KAAK,CAAA;AAExF,IAAA,MAAM,UAAa,GAAA,SAAA,CAAU,KAAO,EAAA,YAAA,EAAc,KAAO,EAAA;AAAA,MACvD,cAAc,KAAM,CAAA,YAAA;AAAA,MACpB,OAAA,EAAU,MAAM,UAAe,KAAA;AAAA,KAChC,CAAA;AAED,IAAA,MAAM,EAAE,gBAAA,EAAkB,cAAe,EAAA,GAAI,mBAAoB,EAAA;AAEjE,IAAM,MAAA,MAAA,GAAS,UAAU,UAAU,CAAA;AACnC,IAAM,MAAA,aAAA,GAAgB,eAAe,cAAc,CAAA;AACnD,IAAA,MAAM,UAAU,GAAsB,EAAA;AAEtC,IAAA,MAAM,kBAAqB,GAAA,QAAA;AAAA,MAAS,MAClC,gBAAgB,UAAW,CAAA,KAAK,MAAM,GAAI,CAAA,KAAA,KACtC,GAAI,CAAA,KAAA,IAAS,CAAC,KAAA,CAAM,WAAW,KAAK,CAAA,GAAK,uBAAuB,GAAK,EAAA,UAAA,CAAW,OAAO,IAAK,CAAA,KAAK,CAAI,GAAA,GAAA,CAAI,KAAS,GAAA,KAAA;AAAA,KACxH;AACA,IAAA,MAAM,kBAAqB,GAAA,QAAA;AAAA,MAAS,MAClC,gBAAgB,UAAW,CAAA,KAAK,MAAM,GAAI,CAAA,KAAA,KACtC,GAAI,CAAA,KAAA,IAAS,CAAC,KAAA,CAAM,WAAW,KAAK,CAAA,GAAK,uBAAuB,GAAK,EAAA,UAAA,CAAW,OAAO,IAAK,CAAA,KAAK,CAAI,GAAA,GAAA,CAAI,KAAS,GAAA,KAAA;AAAA,KACxH;AAEA,IAAS,SAAA,mBAAA,CAAoB,IAA+B,EAAA,UAAA,GAAa,CAAG,EAAA;AAC1E,MAAA,OAAA,CAAQ,OAAO,KAAM,EAAA;AACrB,MAAA,MAAM,oBAAoB,YAAa,CAAA,KAAA,CAAM,OAAQ,CAAA,KAAA,EAAO,SAAS,EAAE,CAAA;AACvE,MAAA,IAAI,KAAM,CAAA,QAAA;AACR,QAAA;AACF,MAAI,IAAA,KAAA,CAAM,iBAAiB,CAAG,EAAA;AAC5B,QAAW,UAAA,CAAA,KAAA,GAAQ,IAAI,KAAS,IAAA,CAAA;AAAA,OAE7B,MAAA;AACH,QAAA,IAAI,IAAS,KAAA,UAAA;AACX,UAAA,UAAA,CAAW,QAAQ,eAAgB,CAAA,iBAAA,GAAA,CAAsB,IAAK,CAAA,KAAA,IAAS,KAAK,UAAW,CAAA;AAAA;AAEvF,UAAA,UAAA,CAAW,QAAQ,eAAgB,CAAA,iBAAA,GAAA,CAAsB,IAAK,CAAA,KAAA,IAAS,KAAK,UAAW,CAAA;AAAA;AAC3F;AAGF,IAAS,SAAA,cAAA,CAAe,aAAa,CAAG,EAAA;AACtC,MAAA,mBAAA,CAAoB,YAAY,UAAU,CAAA;AAAA;AAE5C,IAAS,SAAA,cAAA,CAAe,aAAa,CAAG,EAAA;AACtC,MAAA,mBAAA,CAAoB,YAAY,UAAU,CAAA;AAAA;AAG5C,IAAA,SAAS,kBAAkB,IAAqB,EAAA;AAC9C,MAAI,IAAA,IAAA,KAAS,KAAS,IAAA,GAAA,CAAI,KAAU,KAAA,SAAA;AAClC,QAAW,UAAA,CAAA,KAAA,GAAQ,eAAgB,CAAA,GAAA,CAAI,KAAK,CAAA;AAAA,WACrC,IAAA,IAAA,KAAS,KAAS,IAAA,GAAA,CAAI,KAAU,KAAA,SAAA;AACvC,QAAW,UAAA,CAAA,KAAA,GAAQ,eAAgB,CAAA,GAAA,CAAI,KAAK,CAAA;AAAA;AAIhD,IAAM,MAAA,eAAA,GAAkB,kBAAmB,CAAA,MAAA,EAAQ,aAAa,CAAA;AAChE,IAAM,MAAA,YAAA,GAAe,eAAgB,CAAA,MAAA,EAAQ,aAAa,CAAA;AAE1D,IAAM,MAAA,SAAA,GAAY,SAAsC,MAAM;AAK5D,MAAA,MAAM,WAAc,GAAA,eAAA,CAAgB,eAAgB,EAAA,CAAE,qBAAyB,GAAA,CAAA;AAE/E,MAAA,OAAO,cAAc,SAAY,GAAA,SAAA;AAAA,KAClC,CAAA;AAGD,IAAM,MAAA,kBAAA,GAAqB,kBAAmB,CAAA,MAAA,EAAQ,aAAa,CAAA;AACnE,IAAA,MAAM,SAAY,GAAA,QAAA,CAAS,MAAM,KAAA,CAAM,UAAW,CAAA,KAAK,CAAI,GAAA,EAAA,GAAK,kBAAmB,CAAA,MAAA,CAAO,UAAW,CAAA,KAAK,CAAC,CAAA;AAE3G,IAAA,SAAS,SAAS,GAAa,EAAA;AAC7B,MAAA,OAAO,aAAa,oBAAqB,CAAA,GAAA,EAAK,GAAI,CAAA,KAAA,EAAO,IAAI,KAAK,CAAA;AAAA;AAGpE,IAAA,SAAS,cAAc,GAAa,EAAA;AAClC,MAAA,IAAI,OAAQ,CAAA,KAAA;AACV,QAAA,OAAA,CAAQ,MAAM,KAAQ,GAAA,GAAA;AAAA;AAG1B,IAAA,SAAS,gBAAgB,GAAa,EAAA;AAEpC,MAAI,IAAA,YAAA;AACJ,MAAA,IAAI,IAAK,CAAA,KAAA,KAAU,SAAa,IAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAC9C,QAAA,YAAA,GAAe,KAAM,CAAA,GAAA,EAAK,GAAI,CAAA,KAAA,EAAO,IAAI,KAAK,CAAA;AAAA;AAE9C,QAAA,YAAA,GAAe,gBAAgB,GAAK,EAAA,GAAA,CAAI,OAAO,GAAI,CAAA,KAAA,EAAO,KAAK,KAAK,CAAA;AAEtE,MAAA,YAAA,GAAe,YAAa,CAAA,KAAA,CAAM,eAAgB,CAAA,MAAA,CAAO,YAAY,CAAC,CAAA;AACtE,MAAO,OAAA,YAAA;AAAA;AAGT,IAAA,SAAS,gBAAgB,GAAa,EAAA;AACpC,MAAM,MAAA,WAAA,GAAc,YAAa,CAAA,KAAA,CAAM,GAAG,CAAA;AAE1C,MAAW,UAAA,CAAA,KAAA,GAAQ,gBAAgB,WAAW,CAAA;AAE9C,MAAA,IAAI,CAAC,GAAI,CAAA,MAAA;AACP,QAAA,OAAO,cAAc,GAAG,CAAA;AAG1B,MAAA,IAAI,MAAM,WAAW,CAAA;AACnB,QAAO,OAAA,aAAA,CAAc,UAAU,KAAK,CAAA;AAEtC,MAAO,OAAA,aAAA,CAAc,UAAU,KAAK,CAAA;AAAA;AAGtC,IAA8B,6BAAA,CAAA;AAAA,MAC5B,UAAA;AAAA,MACA,cAAA;AAAA,MACA,cAAA;AAAA,MACA,iBAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,cAAA,EAAgB,CAAM,EAAA,KAAA,OAAA,CAAQ,KAAQ,GAAA,EAAA;AAAA,MACtC,SAAA;AAAA,MACA,QAAA;AAAA,MACA,eAAA;AAAA,MACA,QAAA;AAAA,MACA,GAAA;AAAA,MACA,GAAA;AAAA,MACA,kBAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACD,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NumberFieldRoot.js","sources":["../../src/NumberField/NumberFieldRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { useVModel } from '@vueuse/core'\nimport { clamp, createContext, snapValueToStep, useFormControl, useLocale } from '@/shared'\nimport { type HTMLAttributes, type Ref, computed, ref, toRefs } from 'vue'\nimport type { FormFieldProps } from '@/shared/types'\n\nexport interface NumberFieldRootProps extends PrimitiveProps, FormFieldProps {\n defaultValue?: number\n modelValue?: number | null\n /** The smallest value allowed for the input. */\n min?: number\n /** The largest value allowed for the input. */\n max?: number\n /** The amount that the input value changes with each increment or decrement \"tick\". */\n step?: number\n /** When `false`, prevents the value from snapping to the nearest increment of the step value */\n stepSnapping?: boolean\n /** Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user. */\n formatOptions?: Intl.NumberFormatOptions\n /** The locale to use for formatting dates */\n locale?: string\n /** When `true`, prevents the user from interacting with the Number Field. */\n disabled?: boolean\n /** When `true`, prevents the value from changing on wheel scroll. */\n disableWheelChange?: boolean\n /** Id of the element */\n id?: string\n}\n\nexport type NumberFieldRootEmits = {\n 'update:modelValue': [val: number]\n}\n\ninterface NumberFieldRootContext {\n modelValue: Ref<number>\n handleIncrease: (multiplier?: number) => void\n handleDecrease: (multiplier?: number) => void\n handleMinMaxValue: (type: 'min' | 'max') => void\n inputEl: Ref<HTMLInputElement | undefined>\n onInputElement: (el: HTMLInputElement) => void\n inputMode: Ref<HTMLAttributes['inputmode']>\n textValue: Ref<string>\n validate: (val: string) => boolean\n applyInputValue: (val: string) => void\n disabled: Ref<boolean>\n disableWheelChange: Ref<boolean>\n max: Ref<number | undefined>\n min: Ref<number | undefined>\n isDecreaseDisabled: Ref<boolean>\n isIncreaseDisabled: Ref<boolean>\n id: Ref<string | undefined>\n}\n\nexport const [injectNumberFieldRootContext, provideNumberFieldRootContext] = createContext<NumberFieldRootContext>('NumberFieldRoot')\n</script>\n\n<script setup lang=\"ts\">\nimport { Primitive, usePrimitiveElement } from '@/Primitive'\nimport { handleDecimalOperation, useNumberFormatter, useNumberParser } from './utils'\nimport { VisuallyHiddenInput } from '@/VisuallyHidden'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<NumberFieldRootProps>(), {\n as: 'div',\n defaultValue: undefined,\n step: 1,\n stepSnapping: true,\n})\nconst emits = defineEmits<NumberFieldRootEmits>()\nconst { disabled, disableWheelChange, min, max, step, stepSnapping, formatOptions, id, locale: propLocale } = toRefs(props)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n defaultValue: props.defaultValue,\n passive: (props.modelValue === undefined) as false,\n}) as Ref<number>\n\nconst { primitiveElement, currentElement } = usePrimitiveElement()\n\nconst locale = useLocale(propLocale)\nconst isFormControl = useFormControl(currentElement)\nconst inputEl = ref<HTMLInputElement>()\n\nconst isDecreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === min.value\n || (min.value && !isNaN(modelValue.value) ? (handleDecimalOperation('-', modelValue.value, step.value) < min.value) : false)),\n)\nconst isIncreaseDisabled = computed(() => (\n clampInputValue(modelValue.value) === max.value\n || (max.value && !isNaN(modelValue.value) ? (handleDecimalOperation('+', modelValue.value, step.value) > max.value) : false)),\n)\n\nfunction handleChangingValue(type: 'increase' | 'decrease', multiplier = 1) {\n inputEl.value?.focus()\n const currentInputValue = numberParser.parse(inputEl.value?.value ?? '')\n if (props.disabled)\n return\n if (isNaN(currentInputValue)) {\n modelValue.value = min.value ?? 0\n }\n else {\n if (type === 'increase')\n modelValue.value = clampInputValue(currentInputValue + ((step.value ?? 1) * multiplier))\n else\n modelValue.value = clampInputValue(currentInputValue - ((step.value ?? 1) * multiplier))\n }\n}\n\nfunction handleIncrease(multiplier = 1) {\n handleChangingValue('increase', multiplier)\n}\nfunction handleDecrease(multiplier = 1) {\n handleChangingValue('decrease', multiplier)\n}\n\nfunction handleMinMaxValue(type: 'min' | 'max') {\n if (type === 'min' && min.value !== undefined)\n modelValue.value = clampInputValue(min.value)\n else if (type === 'max' && max.value !== undefined)\n modelValue.value = clampInputValue(max.value)\n}\n\n// Formatter\nconst numberFormatter = useNumberFormatter(locale, formatOptions)\nconst numberParser = useNumberParser(locale, formatOptions)\n\nconst inputMode = computed<HTMLAttributes['inputmode']>(() => {\n // The inputMode attribute influences the software keyboard that is shown on touch devices.\n // Browsers and operating systems are quite inconsistent about what keys are available, however.\n // We choose between numeric and decimal based on whether we allow negative and fractional numbers,\n // and based on testing on various devices to determine what keys are available in each inputMode.\n const hasDecimals = numberFormatter.resolvedOptions().maximumFractionDigits! > 0\n\n return hasDecimals ? 'decimal' : 'numeric'\n})\n// Replace negative textValue formatted using currencySign: 'accounting'\n// with a textValue that can be announced using a minus sign.\nconst textValueFormatter = useNumberFormatter(locale, formatOptions)\nconst textValue = computed(() => isNaN(modelValue.value) ? '' : textValueFormatter.format(modelValue.value))\n\nfunction validate(val: string) {\n return numberParser.isValidPartialNumber(val, min.value, max.value)\n}\n\nfunction setInputValue(val: string) {\n if (inputEl.value)\n inputEl.value.value = val\n}\n\nfunction clampInputValue(val: number) {\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number\n if (step.value === undefined || isNaN(step.value) || !stepSnapping.value)\n clampedValue = clamp(val, min.value, max.value)\n else\n clampedValue = snapValueToStep(val, min.value, max.value, step.value)\n\n clampedValue = numberParser.parse(numberFormatter.format(clampedValue))\n return clampedValue\n}\n\nfunction applyInputValue(val: string) {\n const parsedValue = numberParser.parse(val)\n\n modelValue.value = clampInputValue(parsedValue)\n // Set to empty state if input value is empty\n if (!val.length)\n return setInputValue(val)\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsedValue))\n return setInputValue(textValue.value)\n\n return setInputValue(textValue.value)\n}\n\nprovideNumberFieldRootContext({\n modelValue,\n handleDecrease,\n handleIncrease,\n handleMinMaxValue,\n inputMode,\n inputEl,\n onInputElement: el => inputEl.value = el,\n textValue,\n validate,\n applyInputValue,\n disabled,\n disableWheelChange,\n max,\n min,\n isDecreaseDisabled,\n isIncreaseDisabled,\n id,\n})\n</script>\n\n<template>\n <Primitive\n v-bind=\"$attrs\"\n ref=\"primitiveElement\"\n role=\"group\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <slot\n :model-value=\"modelValue\"\n :text-value=\"textValue\"\n />\n\n <VisuallyHiddenInput\n v-if=\"isFormControl && name\"\n type=\"text\"\n :value=\"modelValue\"\n :name=\"name\"\n :disabled=\"disabled\"\n :required=\"required\"\n />\n </Primitive>\n</template>\n"],"names":[],"mappings":"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"}
@@ -129,7 +129,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
129
129
  rootContext.prevPage();
130
130
  vue.nextTick(() => {
131
131
  const newCollectionItems = parentElement ? Array.from(parentElement.querySelectorAll(SELECTOR)) : [];
132
- if (!rootContext.pagedNavigation.value) {
132
+ if (!rootContext.pagedNavigation.value && rootContext.numberOfMonths.value > 1) {
133
133
  const numberOfDays = date_comparators.getDaysInMonth(rootContext.placeholder.value);
134
134
  newCollectionItems[numberOfDays - Math.abs(newIndex)].focus();
135
135
  return;
@@ -144,9 +144,11 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
144
144
  rootContext.nextPage();
145
145
  vue.nextTick(() => {
146
146
  const newCollectionItems = parentElement ? Array.from(parentElement.querySelectorAll(SELECTOR)) : [];
147
- if (!rootContext.pagedNavigation.value) {
148
- const numberOfDays = date_comparators.getDaysInMonth(rootContext.placeholder.value.add({ months: rootContext.numberOfMonths.value - 1 }));
149
- newCollectionItems[newCollectionItems.length - numberOfDays + newIndex - allCollectionItems.length].focus();
147
+ if (!rootContext.pagedNavigation.value && rootContext.numberOfMonths.value > 1) {
148
+ const numberOfDays = date_comparators.getDaysInMonth(
149
+ rootContext.placeholder.value.add({ months: rootContext.numberOfMonths.value - 1 })
150
+ );
151
+ newCollectionItems[newIndex - allCollectionItems.length + (newCollectionItems.length - numberOfDays)].focus();
150
152
  return;
151
153
  }
152
154
  newCollectionItems[newIndex - allCollectionItems.length].focus();