reka-ui 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlertDialog/AlertDialogRoot.cjs +2 -2
- package/dist/AlertDialog/AlertDialogRoot.cjs.map +1 -1
- package/dist/AlertDialog/AlertDialogRoot.js +3 -3
- package/dist/AlertDialog/AlertDialogRoot.js.map +1 -1
- package/dist/Combobox/ComboboxRoot.cjs +9 -1
- package/dist/Combobox/ComboboxRoot.cjs.map +1 -1
- package/dist/Combobox/ComboboxRoot.js +10 -2
- package/dist/Combobox/ComboboxRoot.js.map +1 -1
- package/dist/NavigationMenu/NavigationMenuViewport.cjs +1 -2
- package/dist/NavigationMenu/NavigationMenuViewport.cjs.map +1 -1
- package/dist/NavigationMenu/NavigationMenuViewport.js +1 -2
- package/dist/NavigationMenu/NavigationMenuViewport.js.map +1 -1
- package/dist/NumberField/NumberFieldInput.cjs +2 -0
- package/dist/NumberField/NumberFieldInput.cjs.map +1 -1
- package/dist/NumberField/NumberFieldInput.js +2 -0
- package/dist/NumberField/NumberFieldInput.js.map +1 -1
- package/dist/NumberField/NumberFieldRoot.cjs +5 -2
- package/dist/NumberField/NumberFieldRoot.cjs.map +1 -1
- package/dist/NumberField/NumberFieldRoot.js +5 -2
- package/dist/NumberField/NumberFieldRoot.js.map +1 -1
- package/dist/Slider/SliderHorizontal.cjs +19 -9
- package/dist/Slider/SliderHorizontal.cjs.map +1 -1
- package/dist/Slider/SliderHorizontal.js +20 -10
- package/dist/Slider/SliderHorizontal.js.map +1 -1
- package/dist/Slider/SliderRoot.cjs +4 -2
- package/dist/Slider/SliderRoot.cjs.map +1 -1
- package/dist/Slider/SliderRoot.js +4 -2
- package/dist/Slider/SliderRoot.js.map +1 -1
- package/dist/Slider/SliderThumb.cjs +1 -1
- package/dist/Slider/SliderThumb.cjs.map +1 -1
- package/dist/Slider/SliderThumb.js +1 -1
- package/dist/Slider/SliderThumb.js.map +1 -1
- package/dist/Slider/SliderThumbImpl.cjs +7 -1
- package/dist/Slider/SliderThumbImpl.cjs.map +1 -1
- package/dist/Slider/SliderThumbImpl.js +7 -1
- package/dist/Slider/SliderThumbImpl.js.map +1 -1
- package/dist/Slider/SliderVertical.cjs +19 -9
- package/dist/Slider/SliderVertical.cjs.map +1 -1
- package/dist/Slider/SliderVertical.js +20 -10
- package/dist/Slider/SliderVertical.js.map +1 -1
- package/dist/Toggle/Toggle.cjs +6 -1
- package/dist/Toggle/Toggle.cjs.map +1 -1
- package/dist/Toggle/Toggle.js +6 -1
- package/dist/Toggle/Toggle.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupItem.cjs +2 -2
- package/dist/ToggleGroup/ToggleGroupItem.cjs.map +1 -1
- package/dist/ToggleGroup/ToggleGroupItem.js +3 -3
- package/dist/ToggleGroup/ToggleGroupItem.js.map +1 -1
- package/dist/date.d.ts +2 -0
- package/dist/index.d.ts +50 -6
- package/package.json +1 -1
|
@@ -19,8 +19,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
19
19
|
shared_useForwardExpose.useForwardExpose();
|
|
20
20
|
return (_ctx, _cache) => {
|
|
21
21
|
return vue.openBlock(), vue.createBlock(vue.unref(Dialog_DialogRoot._sfc_main), vue.mergeProps(vue.unref(forwarded), { modal: true }), {
|
|
22
|
-
default: vue.withCtx(() => [
|
|
23
|
-
vue.renderSlot(_ctx.$slots, "default")
|
|
22
|
+
default: vue.withCtx((slotProps) => [
|
|
23
|
+
vue.renderSlot(_ctx.$slots, "default", vue.normalizeProps(vue.guardReactiveProps(slotProps)))
|
|
24
24
|
]),
|
|
25
25
|
_: 3
|
|
26
26
|
}, 16);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertDialogRoot.cjs","sources":["../../src/AlertDialog/AlertDialogRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type {\n DialogRootEmits,\n DialogRootProps,\n} from '@/Dialog'\n\nexport type AlertDialogEmits = DialogRootEmits\nexport interface AlertDialogProps extends Omit<DialogRootProps, 'modal'> {}\n</script>\n\n<script setup lang=\"ts\">\nimport { DialogRoot } from '@/Dialog'\nimport { useForwardExpose, useForwardPropsEmits } from '@/shared'\n\nconst props = defineProps<AlertDialogProps>()\nconst emits = defineEmits<AlertDialogEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\nuseForwardExpose()\n</script>\n\n<template>\n <DialogRoot\n v-bind=\"forwarded\"\n :modal=\"true\"\n >\n <slot />\n </DialogRoot>\n</template>\n"],"names":["useForwardPropsEmits","useForwardExpose"],"mappings":";;;;;;;;;;;;;;;AAcA,IAAA,MAAM,KAAQ,GAAA,OAAA;AACd,IAAA,MAAM,KAAQ,GAAA,MAAA;AAEd,IAAM,MAAA,SAAA,GAAYA,gDAAqB,CAAA,KAAA,EAAO,KAAK,CAAA;AACnD,IAAiBC,wCAAA,EAAA;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"AlertDialogRoot.cjs","sources":["../../src/AlertDialog/AlertDialogRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type {\n DialogRootEmits,\n DialogRootProps,\n} from '@/Dialog'\n\nexport type AlertDialogEmits = DialogRootEmits\nexport interface AlertDialogProps extends Omit<DialogRootProps, 'modal'> {}\n</script>\n\n<script setup lang=\"ts\">\nimport { DialogRoot } from '@/Dialog'\nimport { useForwardExpose, useForwardPropsEmits } from '@/shared'\n\nconst props = defineProps<AlertDialogProps>()\nconst emits = defineEmits<AlertDialogEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\nuseForwardExpose()\n</script>\n\n<template>\n <DialogRoot\n v-slot=\"slotProps\"\n v-bind=\"forwarded\"\n :modal=\"true\"\n >\n <slot v-bind=\"slotProps\" />\n </DialogRoot>\n</template>\n"],"names":["useForwardPropsEmits","useForwardExpose"],"mappings":";;;;;;;;;;;;;;;AAcA,IAAA,MAAM,KAAQ,GAAA,OAAA;AACd,IAAA,MAAM,KAAQ,GAAA,MAAA;AAEd,IAAM,MAAA,SAAA,GAAYA,gDAAqB,CAAA,KAAA,EAAO,KAAK,CAAA;AACnD,IAAiBC,wCAAA,EAAA;;;;;;;;;;;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, openBlock, createBlock, unref, mergeProps, withCtx, renderSlot } from 'vue';
|
|
1
|
+
import { defineComponent, openBlock, createBlock, unref, mergeProps, withCtx, renderSlot, normalizeProps, guardReactiveProps } from 'vue';
|
|
2
2
|
import { u as useForwardPropsEmits } from '../shared/useForwardPropsEmits.js';
|
|
3
3
|
import { u as useForwardExpose } from '../shared/useForwardExpose.js';
|
|
4
4
|
import { _ as _sfc_main$1 } from '../Dialog/DialogRoot.js';
|
|
@@ -17,8 +17,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
17
17
|
useForwardExpose();
|
|
18
18
|
return (_ctx, _cache) => {
|
|
19
19
|
return openBlock(), createBlock(unref(_sfc_main$1), mergeProps(unref(forwarded), { modal: true }), {
|
|
20
|
-
default: withCtx(() => [
|
|
21
|
-
renderSlot(_ctx.$slots, "default")
|
|
20
|
+
default: withCtx((slotProps) => [
|
|
21
|
+
renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps)))
|
|
22
22
|
]),
|
|
23
23
|
_: 3
|
|
24
24
|
}, 16);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertDialogRoot.js","sources":["../../src/AlertDialog/AlertDialogRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type {\n DialogRootEmits,\n DialogRootProps,\n} from '@/Dialog'\n\nexport type AlertDialogEmits = DialogRootEmits\nexport interface AlertDialogProps extends Omit<DialogRootProps, 'modal'> {}\n</script>\n\n<script setup lang=\"ts\">\nimport { DialogRoot } from '@/Dialog'\nimport { useForwardExpose, useForwardPropsEmits } from '@/shared'\n\nconst props = defineProps<AlertDialogProps>()\nconst emits = defineEmits<AlertDialogEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\nuseForwardExpose()\n</script>\n\n<template>\n <DialogRoot\n v-bind=\"forwarded\"\n :modal=\"true\"\n >\n <slot />\n </DialogRoot>\n</template>\n"],"names":[],"mappings":";;;;;;;;;;;;;AAcA,IAAA,MAAM,KAAQ,GAAA,OAAA;AACd,IAAA,MAAM,KAAQ,GAAA,MAAA;AAEd,IAAM,MAAA,SAAA,GAAY,oBAAqB,CAAA,KAAA,EAAO,KAAK,CAAA;AACnD,IAAiB,gBAAA,EAAA;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"AlertDialogRoot.js","sources":["../../src/AlertDialog/AlertDialogRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type {\n DialogRootEmits,\n DialogRootProps,\n} from '@/Dialog'\n\nexport type AlertDialogEmits = DialogRootEmits\nexport interface AlertDialogProps extends Omit<DialogRootProps, 'modal'> {}\n</script>\n\n<script setup lang=\"ts\">\nimport { DialogRoot } from '@/Dialog'\nimport { useForwardExpose, useForwardPropsEmits } from '@/shared'\n\nconst props = defineProps<AlertDialogProps>()\nconst emits = defineEmits<AlertDialogEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\nuseForwardExpose()\n</script>\n\n<template>\n <DialogRoot\n v-slot=\"slotProps\"\n v-bind=\"forwarded\"\n :modal=\"true\"\n >\n <slot v-bind=\"slotProps\" />\n </DialogRoot>\n</template>\n"],"names":[],"mappings":";;;;;;;;;;;;;AAcA,IAAA,MAAM,KAAQ,GAAA,OAAA;AACd,IAAA,MAAM,KAAQ,GAAA,MAAA;AAEd,IAAM,MAAA,SAAA,GAAY,oBAAqB,CAAA,KAAA,EAAO,KAAK,CAAA;AACnD,IAAiB,gBAAA,EAAA;;;;;;;;;;;;;;"}
|
|
@@ -39,7 +39,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
39
39
|
const dir = shared_useDirection.useDirection(propDir);
|
|
40
40
|
const modelValue = core.useVModel(props, "modelValue", emits, {
|
|
41
41
|
// @ts-expect-error ignore the type error here
|
|
42
|
-
defaultValue: props.defaultValue ?? multiple.value ? [] : undefined,
|
|
42
|
+
defaultValue: props.defaultValue ?? (multiple.value ? [] : undefined),
|
|
43
43
|
passive: props.modelValue === undefined,
|
|
44
44
|
deep: true
|
|
45
45
|
});
|
|
@@ -115,6 +115,14 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
115
115
|
filterItems();
|
|
116
116
|
});
|
|
117
117
|
}, { flush: "post" });
|
|
118
|
+
const inst = vue.getCurrentInstance();
|
|
119
|
+
vue.onMounted(() => {
|
|
120
|
+
if (inst?.exposed) {
|
|
121
|
+
inst.exposed.highlightItem = primitiveElement.value?.highlightItem;
|
|
122
|
+
inst.exposed.highlightFirstItem = primitiveElement.value?.highlightFirstItem;
|
|
123
|
+
inst.exposed.highlightSelected = primitiveElement.value?.highlightSelected;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
118
126
|
__expose({
|
|
119
127
|
filtered: vue.computed(() => filterState.filtered),
|
|
120
128
|
highlightedElement,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxRoot.cjs","sources":["../../src/Combobox/ComboboxRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { ListboxRootProps } from '@/Listbox'\nimport { createContext, useDirection, useFilter } from '@/shared'\nimport { usePrimitiveElement } from '@/Primitive'\nimport type { AcceptableValue, GenericComponentInstance } from '@/shared/types'\n\ntype ComboboxRootContext<T> = {\n modelValue: Ref<T | Array<T>>\n multiple: Ref<boolean>\n disabled: Ref<boolean>\n open: Ref<boolean>\n onOpenChange: (value: boolean) => void\n isUserInputted: Ref<boolean>\n isVirtual: Ref<boolean>\n contentId: string\n inputElement: Ref<HTMLInputElement | undefined>\n onInputElementChange: (el: HTMLInputElement) => void\n triggerElement: Ref<HTMLElement | undefined>\n onTriggerElementChange: (el: HTMLElement) => void\n highlightedElement: Ref<HTMLElement | undefined>\n parentElement: Ref<HTMLElement | undefined>\n resetSearchTermOnSelect: Ref<boolean>\n onResetSearchTerm: EventHookOn\n allItems: Ref<Map<string, string>>\n allGroups: Ref<Map<string, Set<string>>>\n filterState: {\n search: string\n filtered: { count: number, items: Map<string, number>, groups: Set<string> }\n }\n ignoreFilter: Ref<boolean>\n}\n\nexport const [injectComboboxRootContext, provideComboboxRootContext]\n = createContext<ComboboxRootContext<AcceptableValue>>('ComboboxRoot')\n\nexport type ComboboxRootEmits<T = AcceptableValue> = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: T]\n /** Event handler when highlighted element changes. */\n 'highlight': [payload: { ref: HTMLElement, value: T } | undefined]\n /** Event handler called when the open state of the combobox changes. */\n 'update:open': [value: boolean]\n}\n\nexport interface ComboboxRootProps<T = AcceptableValue> extends Omit<ListboxRootProps<T>, 'orientation' | 'selectionBehavior' > {\n /** The controlled open state of the Combobox. Can be binded with with `v-model:open`. */\n open?: boolean\n /** The open state of the combobox when it is initially rendered. <br> Use when you do not need to control its open state. */\n defaultOpen?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox input blurred\n * @defaultValue `true`\n */\n resetSearchTermOnBlur?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox value is selected\n * @defaultValue `true`\n */\n resetSearchTermOnSelect?: boolean\n /**\n * When `true`, disable the default filters\n */\n ignoreFilter?: boolean\n}\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends AcceptableValue = AcceptableValue\">\nimport { computed, nextTick, reactive, ref, toRefs, watch } from 'vue'\nimport { PopperRoot } from '@/Popper'\nimport { type EventHookOn, createEventHook, useVModel } from '@vueuse/core'\nimport { ListboxRoot } from '@/Listbox'\n\nconst props = withDefaults(defineProps<ComboboxRootProps<T>>(), {\n open: undefined,\n resetSearchTermOnBlur: true,\n resetSearchTermOnSelect: true,\n})\nconst emits = defineEmits<ComboboxRootEmits<T>>()\n\ndefineSlots<{\n default: (props: {\n /** Current open state */\n open: typeof open.value\n /** Current active value */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst { primitiveElement, currentElement: parentElement } = usePrimitiveElement<GenericComponentInstance<typeof ListboxRoot>>()\nconst { multiple, disabled, ignoreFilter, resetSearchTermOnSelect, dir: propDir } = toRefs(props)\n\nconst dir = useDirection(propDir)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n // @ts-expect-error ignore the type error here\n defaultValue: props.defaultValue ?? multiple.value ? [] : undefined,\n passive: (props.modelValue === undefined) as false,\n deep: true,\n}) as Ref<T | T[]>\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nasync function onOpenChange(val: boolean) {\n open.value = val\n filterState.search = ''\n\n if (val) {\n // make sure dom is ready then only highlight the selected\n await nextTick()\n primitiveElement.value?.highlightSelected()\n isUserInputted.value = true\n }\n else {\n isUserInputted.value = false\n }\n\n inputElement.value?.focus()\n setTimeout(() => {\n if (!val && props.resetSearchTermOnBlur)\n resetSearchTerm.trigger()\n }, 1)\n}\n\nconst resetSearchTerm = createEventHook()\nconst isUserInputted = ref(false)\nconst isVirtual = ref(false)\nconst inputElement = ref<HTMLInputElement>()\nconst triggerElement = ref<HTMLElement>()\n\nconst highlightedElement = computed(() => primitiveElement.value?.highlightedElement ?? undefined)\n\nconst allItems = ref<Map<string, string>>(new Map())\nconst allGroups = ref<Map<string, Set<string>>>(new Map())\n\nconst { contains } = useFilter({ sensitivity: 'base' })\nconst filterState = reactive({\n search: '',\n filtered: {\n /** The count of all visible items. */\n count: 0,\n /** Map from visible item id to its search score. */\n items: new Map() as Map<string, number>,\n /** Set of groups with at least one visible item. */\n groups: new Set() as Set<string>,\n },\n})\n\nfunction filterItems() {\n if (!filterState.search || props.ignoreFilter || isVirtual.value) {\n filterState.filtered.count = allItems.value.size\n // Do nothing, each item will know to show itself because search is empty\n return\n }\n\n // Reset the groups\n filterState.filtered.groups = new Set()\n let itemCount = 0\n\n // Check which items should be included\n for (const [id, value] of allItems.value) {\n const score = contains(value, filterState.search)\n filterState.filtered.items.set(id, score ? 1 : 0)\n if (score)\n itemCount++\n }\n\n // Check which groups have at least 1 item shown\n for (const [groupId, group] of allGroups.value) {\n for (const itemId of group) {\n if (filterState.filtered.items.get(itemId)! > 0) {\n filterState.filtered.groups.add(groupId)\n break\n }\n }\n }\n\n filterState.filtered.count = itemCount\n}\n\nwatch([() => filterState.search, () => allItems.value.size], () => {\n filterItems()\n}, { immediate: true })\n\nwatch(() => open.value, () => {\n // nextTick to allow multiple items to be mounted first\n nextTick(() => {\n if (open.value)\n filterItems()\n })\n}, { flush: 'post' })\n\ndefineExpose({\n filtered: computed(() => filterState.filtered),\n highlightedElement,\n highlightItem: primitiveElement.value?.highlightItem,\n highlightFirstItem: primitiveElement.value?.highlightFirstItem,\n highlightSelected: primitiveElement.value?.highlightSelected,\n})\n\nprovideComboboxRootContext({\n modelValue,\n multiple,\n disabled,\n open,\n onOpenChange,\n contentId: '',\n isUserInputted,\n isVirtual,\n inputElement,\n highlightedElement,\n onInputElementChange: val => inputElement.value = val,\n triggerElement,\n onTriggerElementChange: val => triggerElement.value = val,\n parentElement,\n resetSearchTermOnSelect,\n onResetSearchTerm: resetSearchTerm.on,\n allItems,\n allGroups,\n filterState,\n ignoreFilter,\n})\n</script>\n\n<template>\n <PopperRoot>\n <ListboxRoot\n ref=\"primitiveElement\"\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :style=\"{\n pointerEvents: open ? 'auto' : undefined,\n }\"\n :as=\"as\"\n :as-child=\"asChild\"\n :dir=\"dir\"\n :multiple=\"multiple\"\n :name=\"name\"\n :required=\"required\"\n :disabled=\"disabled\"\n :highlight-on-hover=\"true\"\n :by=\"props.by as any\"\n @highlight=\"emits('highlight', $event as any)\"\n >\n <slot\n :open=\"open\"\n :model-value=\"modelValue\"\n />\n </ListboxRoot>\n </PopperRoot>\n</template>\n"],"names":["createContext","usePrimitiveElement","toRefs","useDirection","useVModel","nextTick","createEventHook","ref","computed","useFilter","reactive","watch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ComboboxRoot.cjs","sources":["../../src/Combobox/ComboboxRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { ListboxRootProps } from '@/Listbox'\nimport { createContext, useDirection, useFilter } from '@/shared'\nimport { usePrimitiveElement } from '@/Primitive'\nimport type { AcceptableValue, GenericComponentInstance } from '@/shared/types'\n\ntype ComboboxRootContext<T> = {\n modelValue: Ref<T | Array<T>>\n multiple: Ref<boolean>\n disabled: Ref<boolean>\n open: Ref<boolean>\n onOpenChange: (value: boolean) => void\n isUserInputted: Ref<boolean>\n isVirtual: Ref<boolean>\n contentId: string\n inputElement: Ref<HTMLInputElement | undefined>\n onInputElementChange: (el: HTMLInputElement) => void\n triggerElement: Ref<HTMLElement | undefined>\n onTriggerElementChange: (el: HTMLElement) => void\n highlightedElement: Ref<HTMLElement | undefined>\n parentElement: Ref<HTMLElement | undefined>\n resetSearchTermOnSelect: Ref<boolean>\n onResetSearchTerm: EventHookOn\n allItems: Ref<Map<string, string>>\n allGroups: Ref<Map<string, Set<string>>>\n filterState: {\n search: string\n filtered: { count: number, items: Map<string, number>, groups: Set<string> }\n }\n ignoreFilter: Ref<boolean>\n}\n\nexport const [injectComboboxRootContext, provideComboboxRootContext]\n = createContext<ComboboxRootContext<AcceptableValue>>('ComboboxRoot')\n\nexport type ComboboxRootEmits<T = AcceptableValue> = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: T]\n /** Event handler when highlighted element changes. */\n 'highlight': [payload: { ref: HTMLElement, value: T } | undefined]\n /** Event handler called when the open state of the combobox changes. */\n 'update:open': [value: boolean]\n}\n\nexport interface ComboboxRootProps<T = AcceptableValue> extends Omit<ListboxRootProps<T>, 'orientation' | 'selectionBehavior' > {\n /** The controlled open state of the Combobox. Can be binded with with `v-model:open`. */\n open?: boolean\n /** The open state of the combobox when it is initially rendered. <br> Use when you do not need to control its open state. */\n defaultOpen?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox input blurred\n * @defaultValue `true`\n */\n resetSearchTermOnBlur?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox value is selected\n * @defaultValue `true`\n */\n resetSearchTermOnSelect?: boolean\n /**\n * When `true`, disable the default filters\n */\n ignoreFilter?: boolean\n}\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends AcceptableValue = AcceptableValue\">\nimport { computed, getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs, watch } from 'vue'\nimport { PopperRoot } from '@/Popper'\nimport { type EventHookOn, createEventHook, useVModel } from '@vueuse/core'\nimport { ListboxRoot } from '@/Listbox'\n\nconst props = withDefaults(defineProps<ComboboxRootProps<T>>(), {\n open: undefined,\n resetSearchTermOnBlur: true,\n resetSearchTermOnSelect: true,\n})\nconst emits = defineEmits<ComboboxRootEmits<T>>()\n\ndefineSlots<{\n default: (props: {\n /** Current open state */\n open: typeof open.value\n /** Current active value */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst { primitiveElement, currentElement: parentElement } = usePrimitiveElement<GenericComponentInstance<typeof ListboxRoot>>()\nconst { multiple, disabled, ignoreFilter, resetSearchTermOnSelect, dir: propDir } = toRefs(props)\n\nconst dir = useDirection(propDir)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n // @ts-expect-error ignore the type error here\n defaultValue: props.defaultValue ?? (multiple.value ? [] : undefined),\n passive: (props.modelValue === undefined) as false,\n deep: true,\n}) as Ref<T | T[]>\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nasync function onOpenChange(val: boolean) {\n open.value = val\n filterState.search = ''\n\n if (val) {\n // make sure dom is ready then only highlight the selected\n await nextTick()\n primitiveElement.value?.highlightSelected()\n isUserInputted.value = true\n }\n else {\n isUserInputted.value = false\n }\n\n inputElement.value?.focus()\n setTimeout(() => {\n if (!val && props.resetSearchTermOnBlur)\n resetSearchTerm.trigger()\n }, 1)\n}\n\nconst resetSearchTerm = createEventHook()\nconst isUserInputted = ref(false)\nconst isVirtual = ref(false)\nconst inputElement = ref<HTMLInputElement>()\nconst triggerElement = ref<HTMLElement>()\n\nconst highlightedElement = computed(() => primitiveElement.value?.highlightedElement ?? undefined)\n\nconst allItems = ref<Map<string, string>>(new Map())\nconst allGroups = ref<Map<string, Set<string>>>(new Map())\n\nconst { contains } = useFilter({ sensitivity: 'base' })\nconst filterState = reactive({\n search: '',\n filtered: {\n /** The count of all visible items. */\n count: 0,\n /** Map from visible item id to its search score. */\n items: new Map() as Map<string, number>,\n /** Set of groups with at least one visible item. */\n groups: new Set() as Set<string>,\n },\n})\n\nfunction filterItems() {\n if (!filterState.search || props.ignoreFilter || isVirtual.value) {\n filterState.filtered.count = allItems.value.size\n // Do nothing, each item will know to show itself because search is empty\n return\n }\n\n // Reset the groups\n filterState.filtered.groups = new Set()\n let itemCount = 0\n\n // Check which items should be included\n for (const [id, value] of allItems.value) {\n const score = contains(value, filterState.search)\n filterState.filtered.items.set(id, score ? 1 : 0)\n if (score)\n itemCount++\n }\n\n // Check which groups have at least 1 item shown\n for (const [groupId, group] of allGroups.value) {\n for (const itemId of group) {\n if (filterState.filtered.items.get(itemId)! > 0) {\n filterState.filtered.groups.add(groupId)\n break\n }\n }\n }\n\n filterState.filtered.count = itemCount\n}\n\nwatch([() => filterState.search, () => allItems.value.size], () => {\n filterItems()\n}, { immediate: true })\n\nwatch(() => open.value, () => {\n // nextTick to allow multiple items to be mounted first\n nextTick(() => {\n if (open.value)\n filterItems()\n })\n}, { flush: 'post' })\n\nconst inst = getCurrentInstance()\nonMounted(() => {\n if (inst?.exposed) {\n inst.exposed.highlightItem = primitiveElement.value?.highlightItem\n inst.exposed.highlightFirstItem = primitiveElement.value?.highlightFirstItem\n inst.exposed.highlightSelected = primitiveElement.value?.highlightSelected\n }\n})\n\ndefineExpose({\n filtered: computed(() => filterState.filtered),\n highlightedElement,\n highlightItem: primitiveElement.value?.highlightItem,\n highlightFirstItem: primitiveElement.value?.highlightFirstItem,\n highlightSelected: primitiveElement.value?.highlightSelected,\n})\n\nprovideComboboxRootContext({\n modelValue,\n multiple,\n disabled,\n open,\n onOpenChange,\n contentId: '',\n isUserInputted,\n isVirtual,\n inputElement,\n highlightedElement,\n onInputElementChange: val => inputElement.value = val,\n triggerElement,\n onTriggerElementChange: val => triggerElement.value = val,\n parentElement,\n resetSearchTermOnSelect,\n onResetSearchTerm: resetSearchTerm.on,\n allItems,\n allGroups,\n filterState,\n ignoreFilter,\n})\n</script>\n\n<template>\n <PopperRoot>\n <ListboxRoot\n ref=\"primitiveElement\"\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :style=\"{\n pointerEvents: open ? 'auto' : undefined,\n }\"\n :as=\"as\"\n :as-child=\"asChild\"\n :dir=\"dir\"\n :multiple=\"multiple\"\n :name=\"name\"\n :required=\"required\"\n :disabled=\"disabled\"\n :highlight-on-hover=\"true\"\n :by=\"props.by as any\"\n @highlight=\"emits('highlight', $event as any)\"\n >\n <slot\n :open=\"open\"\n :model-value=\"modelValue\"\n />\n </ListboxRoot>\n </PopperRoot>\n</template>\n"],"names":["createContext","usePrimitiveElement","toRefs","useDirection","useVModel","nextTick","createEventHook","ref","computed","useFilter","reactive","watch","getCurrentInstance","onMounted"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, toRefs, ref, computed, reactive, watch, nextTick, openBlock, createBlock, unref, withCtx, createVNode, mergeProps, isRef, renderSlot } from 'vue';
|
|
1
|
+
import { defineComponent, toRefs, ref, computed, reactive, watch, nextTick, getCurrentInstance, onMounted, openBlock, createBlock, unref, withCtx, createVNode, mergeProps, isRef, renderSlot } from 'vue';
|
|
2
2
|
import { _ as _sfc_main$1 } from '../Popper/PopperRoot.js';
|
|
3
3
|
import { useVModel, createEventHook } from '@vueuse/core';
|
|
4
4
|
import { u as usePrimitiveElement } from '../Primitive/usePrimitiveElement.js';
|
|
@@ -37,7 +37,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
37
37
|
const dir = useDirection(propDir);
|
|
38
38
|
const modelValue = useVModel(props, "modelValue", emits, {
|
|
39
39
|
// @ts-expect-error ignore the type error here
|
|
40
|
-
defaultValue: props.defaultValue ?? multiple.value ? [] : undefined,
|
|
40
|
+
defaultValue: props.defaultValue ?? (multiple.value ? [] : undefined),
|
|
41
41
|
passive: props.modelValue === undefined,
|
|
42
42
|
deep: true
|
|
43
43
|
});
|
|
@@ -113,6 +113,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
113
113
|
filterItems();
|
|
114
114
|
});
|
|
115
115
|
}, { flush: "post" });
|
|
116
|
+
const inst = getCurrentInstance();
|
|
117
|
+
onMounted(() => {
|
|
118
|
+
if (inst?.exposed) {
|
|
119
|
+
inst.exposed.highlightItem = primitiveElement.value?.highlightItem;
|
|
120
|
+
inst.exposed.highlightFirstItem = primitiveElement.value?.highlightFirstItem;
|
|
121
|
+
inst.exposed.highlightSelected = primitiveElement.value?.highlightSelected;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
116
124
|
__expose({
|
|
117
125
|
filtered: computed(() => filterState.filtered),
|
|
118
126
|
highlightedElement,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxRoot.js","sources":["../../src/Combobox/ComboboxRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { ListboxRootProps } from '@/Listbox'\nimport { createContext, useDirection, useFilter } from '@/shared'\nimport { usePrimitiveElement } from '@/Primitive'\nimport type { AcceptableValue, GenericComponentInstance } from '@/shared/types'\n\ntype ComboboxRootContext<T> = {\n modelValue: Ref<T | Array<T>>\n multiple: Ref<boolean>\n disabled: Ref<boolean>\n open: Ref<boolean>\n onOpenChange: (value: boolean) => void\n isUserInputted: Ref<boolean>\n isVirtual: Ref<boolean>\n contentId: string\n inputElement: Ref<HTMLInputElement | undefined>\n onInputElementChange: (el: HTMLInputElement) => void\n triggerElement: Ref<HTMLElement | undefined>\n onTriggerElementChange: (el: HTMLElement) => void\n highlightedElement: Ref<HTMLElement | undefined>\n parentElement: Ref<HTMLElement | undefined>\n resetSearchTermOnSelect: Ref<boolean>\n onResetSearchTerm: EventHookOn\n allItems: Ref<Map<string, string>>\n allGroups: Ref<Map<string, Set<string>>>\n filterState: {\n search: string\n filtered: { count: number, items: Map<string, number>, groups: Set<string> }\n }\n ignoreFilter: Ref<boolean>\n}\n\nexport const [injectComboboxRootContext, provideComboboxRootContext]\n = createContext<ComboboxRootContext<AcceptableValue>>('ComboboxRoot')\n\nexport type ComboboxRootEmits<T = AcceptableValue> = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: T]\n /** Event handler when highlighted element changes. */\n 'highlight': [payload: { ref: HTMLElement, value: T } | undefined]\n /** Event handler called when the open state of the combobox changes. */\n 'update:open': [value: boolean]\n}\n\nexport interface ComboboxRootProps<T = AcceptableValue> extends Omit<ListboxRootProps<T>, 'orientation' | 'selectionBehavior' > {\n /** The controlled open state of the Combobox. Can be binded with with `v-model:open`. */\n open?: boolean\n /** The open state of the combobox when it is initially rendered. <br> Use when you do not need to control its open state. */\n defaultOpen?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox input blurred\n * @defaultValue `true`\n */\n resetSearchTermOnBlur?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox value is selected\n * @defaultValue `true`\n */\n resetSearchTermOnSelect?: boolean\n /**\n * When `true`, disable the default filters\n */\n ignoreFilter?: boolean\n}\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends AcceptableValue = AcceptableValue\">\nimport { computed, nextTick, reactive, ref, toRefs, watch } from 'vue'\nimport { PopperRoot } from '@/Popper'\nimport { type EventHookOn, createEventHook, useVModel } from '@vueuse/core'\nimport { ListboxRoot } from '@/Listbox'\n\nconst props = withDefaults(defineProps<ComboboxRootProps<T>>(), {\n open: undefined,\n resetSearchTermOnBlur: true,\n resetSearchTermOnSelect: true,\n})\nconst emits = defineEmits<ComboboxRootEmits<T>>()\n\ndefineSlots<{\n default: (props: {\n /** Current open state */\n open: typeof open.value\n /** Current active value */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst { primitiveElement, currentElement: parentElement } = usePrimitiveElement<GenericComponentInstance<typeof ListboxRoot>>()\nconst { multiple, disabled, ignoreFilter, resetSearchTermOnSelect, dir: propDir } = toRefs(props)\n\nconst dir = useDirection(propDir)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n // @ts-expect-error ignore the type error here\n defaultValue: props.defaultValue ?? multiple.value ? [] : undefined,\n passive: (props.modelValue === undefined) as false,\n deep: true,\n}) as Ref<T | T[]>\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nasync function onOpenChange(val: boolean) {\n open.value = val\n filterState.search = ''\n\n if (val) {\n // make sure dom is ready then only highlight the selected\n await nextTick()\n primitiveElement.value?.highlightSelected()\n isUserInputted.value = true\n }\n else {\n isUserInputted.value = false\n }\n\n inputElement.value?.focus()\n setTimeout(() => {\n if (!val && props.resetSearchTermOnBlur)\n resetSearchTerm.trigger()\n }, 1)\n}\n\nconst resetSearchTerm = createEventHook()\nconst isUserInputted = ref(false)\nconst isVirtual = ref(false)\nconst inputElement = ref<HTMLInputElement>()\nconst triggerElement = ref<HTMLElement>()\n\nconst highlightedElement = computed(() => primitiveElement.value?.highlightedElement ?? undefined)\n\nconst allItems = ref<Map<string, string>>(new Map())\nconst allGroups = ref<Map<string, Set<string>>>(new Map())\n\nconst { contains } = useFilter({ sensitivity: 'base' })\nconst filterState = reactive({\n search: '',\n filtered: {\n /** The count of all visible items. */\n count: 0,\n /** Map from visible item id to its search score. */\n items: new Map() as Map<string, number>,\n /** Set of groups with at least one visible item. */\n groups: new Set() as Set<string>,\n },\n})\n\nfunction filterItems() {\n if (!filterState.search || props.ignoreFilter || isVirtual.value) {\n filterState.filtered.count = allItems.value.size\n // Do nothing, each item will know to show itself because search is empty\n return\n }\n\n // Reset the groups\n filterState.filtered.groups = new Set()\n let itemCount = 0\n\n // Check which items should be included\n for (const [id, value] of allItems.value) {\n const score = contains(value, filterState.search)\n filterState.filtered.items.set(id, score ? 1 : 0)\n if (score)\n itemCount++\n }\n\n // Check which groups have at least 1 item shown\n for (const [groupId, group] of allGroups.value) {\n for (const itemId of group) {\n if (filterState.filtered.items.get(itemId)! > 0) {\n filterState.filtered.groups.add(groupId)\n break\n }\n }\n }\n\n filterState.filtered.count = itemCount\n}\n\nwatch([() => filterState.search, () => allItems.value.size], () => {\n filterItems()\n}, { immediate: true })\n\nwatch(() => open.value, () => {\n // nextTick to allow multiple items to be mounted first\n nextTick(() => {\n if (open.value)\n filterItems()\n })\n}, { flush: 'post' })\n\ndefineExpose({\n filtered: computed(() => filterState.filtered),\n highlightedElement,\n highlightItem: primitiveElement.value?.highlightItem,\n highlightFirstItem: primitiveElement.value?.highlightFirstItem,\n highlightSelected: primitiveElement.value?.highlightSelected,\n})\n\nprovideComboboxRootContext({\n modelValue,\n multiple,\n disabled,\n open,\n onOpenChange,\n contentId: '',\n isUserInputted,\n isVirtual,\n inputElement,\n highlightedElement,\n onInputElementChange: val => inputElement.value = val,\n triggerElement,\n onTriggerElementChange: val => triggerElement.value = val,\n parentElement,\n resetSearchTermOnSelect,\n onResetSearchTerm: resetSearchTerm.on,\n allItems,\n allGroups,\n filterState,\n ignoreFilter,\n})\n</script>\n\n<template>\n <PopperRoot>\n <ListboxRoot\n ref=\"primitiveElement\"\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :style=\"{\n pointerEvents: open ? 'auto' : undefined,\n }\"\n :as=\"as\"\n :as-child=\"asChild\"\n :dir=\"dir\"\n :multiple=\"multiple\"\n :name=\"name\"\n :required=\"required\"\n :disabled=\"disabled\"\n :highlight-on-hover=\"true\"\n :by=\"props.by as any\"\n @highlight=\"emits('highlight', $event as any)\"\n >\n <slot\n :open=\"open\"\n :model-value=\"modelValue\"\n />\n </ListboxRoot>\n </PopperRoot>\n</template>\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ComboboxRoot.js","sources":["../../src/Combobox/ComboboxRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { ListboxRootProps } from '@/Listbox'\nimport { createContext, useDirection, useFilter } from '@/shared'\nimport { usePrimitiveElement } from '@/Primitive'\nimport type { AcceptableValue, GenericComponentInstance } from '@/shared/types'\n\ntype ComboboxRootContext<T> = {\n modelValue: Ref<T | Array<T>>\n multiple: Ref<boolean>\n disabled: Ref<boolean>\n open: Ref<boolean>\n onOpenChange: (value: boolean) => void\n isUserInputted: Ref<boolean>\n isVirtual: Ref<boolean>\n contentId: string\n inputElement: Ref<HTMLInputElement | undefined>\n onInputElementChange: (el: HTMLInputElement) => void\n triggerElement: Ref<HTMLElement | undefined>\n onTriggerElementChange: (el: HTMLElement) => void\n highlightedElement: Ref<HTMLElement | undefined>\n parentElement: Ref<HTMLElement | undefined>\n resetSearchTermOnSelect: Ref<boolean>\n onResetSearchTerm: EventHookOn\n allItems: Ref<Map<string, string>>\n allGroups: Ref<Map<string, Set<string>>>\n filterState: {\n search: string\n filtered: { count: number, items: Map<string, number>, groups: Set<string> }\n }\n ignoreFilter: Ref<boolean>\n}\n\nexport const [injectComboboxRootContext, provideComboboxRootContext]\n = createContext<ComboboxRootContext<AcceptableValue>>('ComboboxRoot')\n\nexport type ComboboxRootEmits<T = AcceptableValue> = {\n /** Event handler called when the value changes. */\n 'update:modelValue': [value: T]\n /** Event handler when highlighted element changes. */\n 'highlight': [payload: { ref: HTMLElement, value: T } | undefined]\n /** Event handler called when the open state of the combobox changes. */\n 'update:open': [value: boolean]\n}\n\nexport interface ComboboxRootProps<T = AcceptableValue> extends Omit<ListboxRootProps<T>, 'orientation' | 'selectionBehavior' > {\n /** The controlled open state of the Combobox. Can be binded with with `v-model:open`. */\n open?: boolean\n /** The open state of the combobox when it is initially rendered. <br> Use when you do not need to control its open state. */\n defaultOpen?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox input blurred\n * @defaultValue `true`\n */\n resetSearchTermOnBlur?: boolean\n /**\n * Whether to reset the searchTerm when the Combobox value is selected\n * @defaultValue `true`\n */\n resetSearchTermOnSelect?: boolean\n /**\n * When `true`, disable the default filters\n */\n ignoreFilter?: boolean\n}\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends AcceptableValue = AcceptableValue\">\nimport { computed, getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs, watch } from 'vue'\nimport { PopperRoot } from '@/Popper'\nimport { type EventHookOn, createEventHook, useVModel } from '@vueuse/core'\nimport { ListboxRoot } from '@/Listbox'\n\nconst props = withDefaults(defineProps<ComboboxRootProps<T>>(), {\n open: undefined,\n resetSearchTermOnBlur: true,\n resetSearchTermOnSelect: true,\n})\nconst emits = defineEmits<ComboboxRootEmits<T>>()\n\ndefineSlots<{\n default: (props: {\n /** Current open state */\n open: typeof open.value\n /** Current active value */\n modelValue: typeof modelValue.value\n }) => any\n}>()\n\nconst { primitiveElement, currentElement: parentElement } = usePrimitiveElement<GenericComponentInstance<typeof ListboxRoot>>()\nconst { multiple, disabled, ignoreFilter, resetSearchTermOnSelect, dir: propDir } = toRefs(props)\n\nconst dir = useDirection(propDir)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n // @ts-expect-error ignore the type error here\n defaultValue: props.defaultValue ?? (multiple.value ? [] : undefined),\n passive: (props.modelValue === undefined) as false,\n deep: true,\n}) as Ref<T | T[]>\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nasync function onOpenChange(val: boolean) {\n open.value = val\n filterState.search = ''\n\n if (val) {\n // make sure dom is ready then only highlight the selected\n await nextTick()\n primitiveElement.value?.highlightSelected()\n isUserInputted.value = true\n }\n else {\n isUserInputted.value = false\n }\n\n inputElement.value?.focus()\n setTimeout(() => {\n if (!val && props.resetSearchTermOnBlur)\n resetSearchTerm.trigger()\n }, 1)\n}\n\nconst resetSearchTerm = createEventHook()\nconst isUserInputted = ref(false)\nconst isVirtual = ref(false)\nconst inputElement = ref<HTMLInputElement>()\nconst triggerElement = ref<HTMLElement>()\n\nconst highlightedElement = computed(() => primitiveElement.value?.highlightedElement ?? undefined)\n\nconst allItems = ref<Map<string, string>>(new Map())\nconst allGroups = ref<Map<string, Set<string>>>(new Map())\n\nconst { contains } = useFilter({ sensitivity: 'base' })\nconst filterState = reactive({\n search: '',\n filtered: {\n /** The count of all visible items. */\n count: 0,\n /** Map from visible item id to its search score. */\n items: new Map() as Map<string, number>,\n /** Set of groups with at least one visible item. */\n groups: new Set() as Set<string>,\n },\n})\n\nfunction filterItems() {\n if (!filterState.search || props.ignoreFilter || isVirtual.value) {\n filterState.filtered.count = allItems.value.size\n // Do nothing, each item will know to show itself because search is empty\n return\n }\n\n // Reset the groups\n filterState.filtered.groups = new Set()\n let itemCount = 0\n\n // Check which items should be included\n for (const [id, value] of allItems.value) {\n const score = contains(value, filterState.search)\n filterState.filtered.items.set(id, score ? 1 : 0)\n if (score)\n itemCount++\n }\n\n // Check which groups have at least 1 item shown\n for (const [groupId, group] of allGroups.value) {\n for (const itemId of group) {\n if (filterState.filtered.items.get(itemId)! > 0) {\n filterState.filtered.groups.add(groupId)\n break\n }\n }\n }\n\n filterState.filtered.count = itemCount\n}\n\nwatch([() => filterState.search, () => allItems.value.size], () => {\n filterItems()\n}, { immediate: true })\n\nwatch(() => open.value, () => {\n // nextTick to allow multiple items to be mounted first\n nextTick(() => {\n if (open.value)\n filterItems()\n })\n}, { flush: 'post' })\n\nconst inst = getCurrentInstance()\nonMounted(() => {\n if (inst?.exposed) {\n inst.exposed.highlightItem = primitiveElement.value?.highlightItem\n inst.exposed.highlightFirstItem = primitiveElement.value?.highlightFirstItem\n inst.exposed.highlightSelected = primitiveElement.value?.highlightSelected\n }\n})\n\ndefineExpose({\n filtered: computed(() => filterState.filtered),\n highlightedElement,\n highlightItem: primitiveElement.value?.highlightItem,\n highlightFirstItem: primitiveElement.value?.highlightFirstItem,\n highlightSelected: primitiveElement.value?.highlightSelected,\n})\n\nprovideComboboxRootContext({\n modelValue,\n multiple,\n disabled,\n open,\n onOpenChange,\n contentId: '',\n isUserInputted,\n isVirtual,\n inputElement,\n highlightedElement,\n onInputElementChange: val => inputElement.value = val,\n triggerElement,\n onTriggerElementChange: val => triggerElement.value = val,\n parentElement,\n resetSearchTermOnSelect,\n onResetSearchTerm: resetSearchTerm.on,\n allItems,\n allGroups,\n filterState,\n ignoreFilter,\n})\n</script>\n\n<template>\n <PopperRoot>\n <ListboxRoot\n ref=\"primitiveElement\"\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :style=\"{\n pointerEvents: open ? 'auto' : undefined,\n }\"\n :as=\"as\"\n :as-child=\"asChild\"\n :dir=\"dir\"\n :multiple=\"multiple\"\n :name=\"name\"\n :required=\"required\"\n :disabled=\"disabled\"\n :highlight-on-hover=\"true\"\n :by=\"props.by as any\"\n @highlight=\"emits('highlight', $event as any)\"\n >\n <slot\n :open=\"open\"\n :model-value=\"modelValue\"\n />\n </ListboxRoot>\n </PopperRoot>\n</template>\n"],"names":[],"mappings":"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"}
|
|
@@ -28,8 +28,7 @@ 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
|
-
|
|
32
|
-
menuContext.onViewportChange(currentElement.value);
|
|
31
|
+
menuContext.onViewportChange(currentElement.value);
|
|
33
32
|
});
|
|
34
33
|
const content = vue.ref();
|
|
35
34
|
vue.watch([modelValue, open], () => {
|
|
@@ -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
|
|
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]')?.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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"}
|
|
@@ -26,8 +26,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
26
26
|
const position = ref();
|
|
27
27
|
const open = computed(() => !!menuContext.modelValue.value);
|
|
28
28
|
watch(currentElement, () => {
|
|
29
|
-
|
|
30
|
-
menuContext.onViewportChange(currentElement.value);
|
|
29
|
+
menuContext.onViewportChange(currentElement.value);
|
|
31
30
|
});
|
|
32
31
|
const content = ref();
|
|
33
32
|
watch([modelValue, open], () => {
|
|
@@ -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
|
|
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]')?.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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"}
|
|
@@ -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;
|
|
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;
|
|
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":";;;;;;;;;;;;;AAiDO,MAAM,CAAC,4BAAA,EAA8B,6BAA6B,CAAA,GAAIA,mCAAsC,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,GAAAC,UAAA,CAAO,KAAK,CAAA;AAExF,IAAA,MAAM,UAAa,GAAAC,cAAA,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,GAAIC,iDAAoB,EAAA;AAEjE,IAAM,MAAA,MAAA,GAASC,2BAAU,UAAU,CAAA;AACnC,IAAM,MAAA,aAAA,GAAgBC,qCAAe,cAAc,CAAA;AACnD,IAAA,MAAM,UAAUC,OAAsB,EAAA;AAEtC,IAAA,MAAM,kBAAqB,GAAAC,YAAA;AAAA,MAAS,MAClC,gBAAgB,UAAW,CAAA,KAAK,MAAM,GAAI,CAAA,KAAA,KACtC,GAAI,CAAA,KAAA,IAAS,CAAC,KAAA,CAAM,WAAW,KAAK,CAAA,GAAKC,yCAAuB,GAAK,EAAA,UAAA,CAAW,OAAO,IAAK,CAAA,KAAK,CAAI,GAAA,GAAA,CAAI,KAAS,GAAA,KAAA;AAAA,KACxH;AACA,IAAA,MAAM,kBAAqB,GAAAD,YAAA;AAAA,MAAS,MAClC,gBAAgB,UAAW,CAAA,KAAK,MAAM,GAAI,CAAA,KAAA,KACtC,GAAI,CAAA,KAAA,IAAS,CAAC,KAAA,CAAM,WAAW,KAAK,CAAA,GAAKC,yCAAuB,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,GAAkBC,oCAAmB,CAAA,MAAA,EAAQ,aAAa,CAAA;AAChE,IAAM,MAAA,YAAA,GAAeC,iCAAgB,CAAA,MAAA,EAAQ,aAAa,CAAA;AAE1D,IAAM,MAAA,SAAA,GAAYH,aAAsC,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,GAAqBE,oCAAmB,CAAA,MAAA,EAAQ,aAAa,CAAA;AACnE,IAAA,MAAM,SAAY,GAAAF,YAAA,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,GAAeI,kBAAM,CAAA,GAAA,EAAK,GAAI,CAAA,KAAA,EAAO,IAAI,KAAK,CAAA;AAAA;AAE9C,QAAA,YAAA,GAAeC,6BAAgB,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.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,
|