{"version":3,"file":"numberBox.obs.js","sources":["../../../Framework/Controls/numberBox.obs"],"sourcesContent":["<!-- Copyright by the Spark Development Network; Licensed under the Rock Community License -->\r\n<template>\r\n <RockFormField\r\n :modelValue=\"internalValue\"\r\n formGroupClasses=\"rock-number-box\"\r\n name=\"numberbox\"\r\n :rules=\"computedRules\">\r\n <template #default=\"{ uniqueId, field }\">\r\n <div class=\"control-wrapper\">\r\n <slot name=\"prepend\" />\r\n <div :class=\"controlContainerClass\">\r\n <slot name=\"inputGroupPrepend\" :isInputGroupSupported=\"true\" />\r\n <input\r\n :value=\"internalValue\"\r\n :id=\"uniqueId\"\r\n type=\"number\"\r\n class=\"form-control\"\r\n :class=\"inputClasses\"\r\n v-bind=\"field\"\r\n inputmode=\"decimal\"\r\n :placeholder=\"placeholder\"\r\n :step=\"internalStep\"\r\n :min=\"minimumValue\"\r\n :max=\"maximumValue\"\r\n @input=\"onInput\"\r\n @change=\"onChange\"\r\n @blur=\"formatInternalValue\" />\r\n <slot name=\"inputGroupAppend\" :isInputGroupSupported=\"true\" />\r\n </div>\r\n <slot name=\"append\" />\r\n </div>\r\n </template>\r\n </RockFormField>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed, PropType, ref, useSlots, watch } from \"vue\";\r\n import { normalizeRules, rulesPropType, ValidationRule } from \"@Obsidian/ValidationRules\";\r\n import { asFormattedString, toNumberOrNull } from \"@Obsidian/Utility/numberUtils\";\r\n import RockFormField from \"./rockFormField.obs\";\r\n\r\n const props = defineProps({\r\n modelValue: {\r\n type: Number as PropType<number | null>,\r\n default: null\r\n },\r\n /** Internal use to track what modifier flags were applied to modelValue. */\r\n modelModifiers: {\r\n type: Object as PropType<Record<string, boolean>>,\r\n default: () => ({})\r\n },\r\n placeholder: {\r\n type: String as PropType<string>,\r\n default: \"\"\r\n },\r\n /** The minimum allowed value to be entered. */\r\n minimumValue: {\r\n type: Number as PropType<number | null>\r\n },\r\n maximumValue: {\r\n type: Number as PropType<number | null>\r\n },\r\n /** The number of decimal places allowed. */\r\n decimalCount: {\r\n type: Number as PropType<number | null>,\r\n default: null\r\n },\r\n inputClasses: {\r\n type: String as PropType<string>,\r\n default: \"\"\r\n },\r\n inputGroupClasses: {\r\n type: String as PropType<string>,\r\n default: \"\"\r\n },\r\n rules: rulesPropType\r\n });\r\n\r\n const emit = defineEmits<{\r\n (e: \"update:modelValue\", value: number | null): void;\r\n }>();\r\n\r\n const slots = useSlots();\r\n const internalValue = ref(formatNumber(props.modelValue));\r\n\r\n const internalNumberValue = computed((): number | null => {\r\n return toNumberOrNull(internalValue.value);\r\n });\r\n\r\n const internalStep = computed((): string => {\r\n return props.decimalCount === null ? \"any\" : (1 / Math.pow(10, props.decimalCount)).toString();\r\n });\r\n\r\n const isInputGroup = computed((): boolean => {\r\n return !!slots.inputGroupPrepend || !!slots.inputGroupAppend;\r\n });\r\n\r\n const controlContainerClass = computed((): string => {\r\n return isInputGroup.value ? `input-group ${props.inputGroupClasses}` : \"\";\r\n });\r\n\r\n const computedRules = computed((): ValidationRule[] => {\r\n const rules = normalizeRules(props.rules);\r\n\r\n if (props.maximumValue != null) {\r\n rules.push(`lte:${props.maximumValue}`);\r\n }\r\n\r\n if (props.minimumValue != null) {\r\n rules.push(`gte:${props.minimumValue}`);\r\n }\r\n\r\n return rules;\r\n });\r\n\r\n function formatNumber(num: number | null): string {\r\n return asFormattedString(num, props.decimalCount ?? undefined, { useGrouping: false });\r\n }\r\n\r\n function formatInternalValue(): void {\r\n internalValue.value = formatNumber(internalNumberValue.value);\r\n }\r\n\r\n /**\r\n * Event handler for the input field having any modification to the value\r\n * happen. This is basically called on every key press.\r\n *\r\n * @param e The object that describes the event.\r\n */\r\n function onInput(e: Event): void {\r\n if (e.target instanceof HTMLInputElement) {\r\n internalValue.value = e.target.value;\r\n }\r\n\r\n // Lazy models do not get every single key press.\r\n if (!props.modelModifiers.lazy) {\r\n emit(\"update:modelValue\", internalNumberValue.value);\r\n }\r\n }\r\n\r\n /**\r\n * Event handler for the input field when the changed value is \"committed\".\r\n * This is basically called when the focus leaves the input field.\r\n *\r\n * @param e The object that describes the event.\r\n */\r\n function onChange(e: Event): void {\r\n if (e.target instanceof HTMLInputElement) {\r\n internalValue.value = e.target.value;\r\n }\r\n\r\n formatInternalValue();\r\n\r\n // Only send the update if we didn't send it in the onInput handler.\r\n if (props.modelModifiers.lazy) {\r\n emit(\"update:modelValue\", internalNumberValue.value);\r\n }\r\n }\r\n\r\n watch(() => props.modelValue, () => {\r\n if (props.modelValue !== internalNumberValue.value) {\r\n internalValue.value = formatNumber(props.modelValue);\r\n }\r\n });\r\n\r\n watch(() => props.decimalCount, () => {\r\n formatInternalValue();\r\n });\r\n</script>\r\n"],"names":["slots","useSlots","internalValue","ref","formatNumber","props","modelValue","internalNumberValue","computed","toNumberOrNull","value","internalStep","decimalCount","Math","pow","toString","isInputGroup","inputGroupPrepend","inputGroupAppend","controlContainerClass","concat","inputGroupClasses","computedRules","rules","normalizeRules","maximumValue","push","minimumValue","num","_props$decimalCount","asFormattedString","undefined","useGrouping","formatInternalValue","onInput","e","target","HTMLInputElement","modelModifiers","lazy","emit","onChange","watch"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAkFI,IAAMA,KAAK,GAAGC,QAAQ,EAAE,CAAA;UACxB,IAAMC,aAAa,GAAGC,GAAG,CAACC,YAAY,CAACC,KAAK,CAACC,UAAU,CAAC,CAAC,CAAA;MAEzD,IAAA,IAAMC,mBAAmB,GAAGC,QAAQ,CAAC,MAAqB;MACtD,MAAA,OAAOC,cAAc,CAACP,aAAa,CAACQ,KAAK,CAAC,CAAA;MAC9C,KAAC,CAAC,CAAA;MAEF,IAAA,IAAMC,YAAY,GAAGH,QAAQ,CAAC,MAAc;YACxC,OAAOH,KAAK,CAACO,YAAY,KAAK,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,GAAGC,IAAI,CAACC,GAAG,CAAC,EAAE,EAAET,KAAK,CAACO,YAAY,CAAC,EAAEG,QAAQ,EAAE,CAAA;MAClG,KAAC,CAAC,CAAA;MAEF,IAAA,IAAMC,YAAY,GAAGR,QAAQ,CAAC,MAAe;YACzC,OAAO,CAAC,CAACR,KAAK,CAACiB,iBAAiB,IAAI,CAAC,CAACjB,KAAK,CAACkB,gBAAgB,CAAA;MAChE,KAAC,CAAC,CAAA;MAEF,IAAA,IAAMC,qBAAqB,GAAGX,QAAQ,CAAC,MAAc;YACjD,OAAOQ,YAAY,CAACN,KAAK,GAAAU,cAAAA,CAAAA,MAAA,CAAkBf,KAAK,CAACgB,iBAAiB,CAAA,GAAK,EAAE,CAAA;MAC7E,KAAC,CAAC,CAAA;MAEF,IAAA,IAAMC,aAAa,GAAGd,QAAQ,CAAC,MAAwB;MACnD,MAAA,IAAMe,KAAK,GAAGC,cAAc,CAACnB,KAAK,CAACkB,KAAK,CAAC,CAAA;MAEzC,MAAA,IAAIlB,KAAK,CAACoB,YAAY,IAAI,IAAI,EAAE;cAC5BF,KAAK,CAACG,IAAI,CAAAN,MAAAA,CAAAA,MAAA,CAAQf,KAAK,CAACoB,YAAY,CAAG,CAAA,CAAA;MAC3C,OAAA;MAEA,MAAA,IAAIpB,KAAK,CAACsB,YAAY,IAAI,IAAI,EAAE;cAC5BJ,KAAK,CAACG,IAAI,CAAAN,MAAAA,CAAAA,MAAA,CAAQf,KAAK,CAACsB,YAAY,CAAG,CAAA,CAAA;MAC3C,OAAA;MAEA,MAAA,OAAOJ,KAAK,CAAA;MAChB,KAAC,CAAC,CAAA;UAEF,SAASnB,YAAYA,CAACwB,GAAkB,EAAU;MAAA,MAAA,IAAAC,mBAAA,CAAA;MAC9C,MAAA,OAAOC,iBAAiB,CAACF,GAAG,EAAA,CAAAC,mBAAA,GAAExB,KAAK,CAACO,YAAY,cAAAiB,mBAAA,KAAA,KAAA,CAAA,GAAAA,mBAAA,GAAIE,SAAS,EAAE;MAAEC,QAAAA,WAAW,EAAE,KAAA;MAAM,OAAC,CAAC,CAAA;MAC1F,KAAA;UAEA,SAASC,mBAAmBA,GAAS;YACjC/B,aAAa,CAACQ,KAAK,GAAGN,YAAY,CAACG,mBAAmB,CAACG,KAAK,CAAC,CAAA;MACjE,KAAA;UAQC,SAASwB,OAAOA,CAACC,CAAQ,EAAQ;MAC9B,MAAA,IAAIA,CAAC,CAACC,MAAM,YAAYC,gBAAgB,EAAE;MACtCnC,QAAAA,aAAa,CAACQ,KAAK,GAAGyB,CAAC,CAACC,MAAM,CAAC1B,KAAK,CAAA;MACxC,OAAA;MAGA,MAAA,IAAI,CAACL,KAAK,CAACiC,cAAc,CAACC,IAAI,EAAE;MAC5BC,QAAAA,IAAI,CAAC,mBAAmB,EAAEjC,mBAAmB,CAACG,KAAK,CAAC,CAAA;MACxD,OAAA;MACJ,KAAA;UAQC,SAAS+B,QAAQA,CAACN,CAAQ,EAAQ;MAC/B,MAAA,IAAIA,CAAC,CAACC,MAAM,YAAYC,gBAAgB,EAAE;MACtCnC,QAAAA,aAAa,CAACQ,KAAK,GAAGyB,CAAC,CAACC,MAAM,CAAC1B,KAAK,CAAA;MACxC,OAAA;MAEAuB,MAAAA,mBAAmB,EAAE,CAAA;MAGrB,MAAA,IAAI5B,KAAK,CAACiC,cAAc,CAACC,IAAI,EAAE;MAC3BC,QAAAA,IAAI,CAAC,mBAAmB,EAAEjC,mBAAmB,CAACG,KAAK,CAAC,CAAA;MACxD,OAAA;MACJ,KAAA;MAEAgC,IAAAA,KAAK,CAAC,MAAMrC,KAAK,CAACC,UAAU,EAAE,MAAM;MAChC,MAAA,IAAID,KAAK,CAACC,UAAU,KAAKC,mBAAmB,CAACG,KAAK,EAAE;cAChDR,aAAa,CAACQ,KAAK,GAAGN,YAAY,CAACC,KAAK,CAACC,UAAU,CAAC,CAAA;MACxD,OAAA;MACJ,KAAC,CAAC,CAAA;MAEFoC,IAAAA,KAAK,CAAC,MAAMrC,KAAK,CAACO,YAAY,EAAE,MAAM;MAClCqB,MAAAA,mBAAmB,EAAE,CAAA;MACzB,KAAC,CAAC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}