@stonecrop/aform 0.18.0 → 0.20.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/aform.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"aform.js","sources":["../src/utils/deserialize.ts","../src/components/form/ACheckbox.vue","../src/components/form/AFormLink.vue","../src/components/form/ACurrencyInput.vue","../src/components/form/ADatePicker.vue","../src/components/form/ADateTime.vue","../src/components/form/ADateSelection.vue","../src/components/form/ADate.vue","../src/components/form/ADropdown.vue","../src/components/form/ADuration.vue","../src/components/form/ADateRange.vue","../src/components/AForm.vue","../src/components/base/CollapseButton.vue","../src/components/form/AFieldset.vue","../src/components/form/AFileAttach.vue","../src/components/form/ANumericInput.vue","../src/components/form/AQuantityInput.vue","../src/directives/mask.ts","../src/components/form/ATextInput.vue","../src/components/form/ATextboxInput.vue","../src/components/utilities/Login.vue","../src/components/AFormLoading.vue","../src/index.ts"],"sourcesContent":["/**\n * Deserializes a stringified function expression into a typed callable.\n *\n * Throws if the string cannot be parsed as a function (SyntaxError) or if the\n * resulting expression is not callable (TypeError), or if the expression references\n * an undefined variable (ReferenceError). Callers are responsible for try/catch.\n *\n * @example\n * ```ts\n * const fn = deserializeFunction<(x: number) => number>('(x) => x * 2')\n * fn(5) // 10\n * ```\n * @public\n */\n// T is intentionally a caller-supplied return type — this utility is unsafe by design (Function constructor).\n// oxlint-disable-next-line typescript/no-unnecessary-type-parameters\nexport function deserializeFunction<T extends (...args: any[]) => any>(source: string): T {\n\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion, typescript/no-implied-eval\n\treturn Function(`\"use strict\"; return (${source})`)() as T\n}\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t\t<span class=\"aform_display-value\">{{ checkbox ? '✓' : '✗' }}</span>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t<span class=\"aform_checkbox-container aform_input-field\">\n\t\t\t\t<input\n\t\t\t\t\t:id=\"uuid\"\n\t\t\t\t\tv-model=\"checkbox\"\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tclass=\"aform_checkbox\"\n\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t:required=\"required\" />\n\t\t\t</span>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, InputHTMLAttributes } from 'vue'\n\nimport { ComponentProps } from '../../types'\n\nconst { label, required, mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst checkbox = defineModel<InputHTMLAttributes['checked']>()\n</script>\n\n<style scoped>\n.aform_checkbox {\n\tcursor: pointer;\n\twidth: auto;\n\tmargin-top: 0;\n\tdisplay: block;\n}\n\n.aform_checkbox:checked {\n\taccent-color: var(--sc-primary-color);\n\tborder: 1px solid black;\n}\n\n.aform_checkbox-container {\n\twidth: 100%;\n\tdisplay: inline-block;\n\ttext-align: left;\n}\n\n.aform_checkbox-container input {\n\twidth: auto;\n}\n\n.aform_checkbox-container:hover + .aform_field-label {\n\tcolor: var(--sc-input-active-label-color);\n}\n</style>\n","<template>\n\t<div :class=\"['aform_form-element', { 'aform_form-element--embedded': embedded }]\">\n\t\t<span v-if=\"mode === 'display'\" class=\"aform_display-value\">{{ displayedText }}</span>\n\t\t<template v-else>\n\t\t\t<div v-on-click-outside=\"onClickOutside\" class=\"aform_form-link-wrapper\">\n\t\t\t\t<div class=\"input-group\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"searchText\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\t:class=\"['aform_input-field', { 'aform_input-field--embedded': embedded }]\"\n\t\t\t\t\t\t:placeholder=\"placeholder\"\n\t\t\t\t\t\t:aria-label=\"ariaLabel\"\n\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t:aria-expanded=\"dropdownOpen\"\n\t\t\t\t\t\t:aria-controls=\"dropdownOpen ? listboxId : undefined\"\n\t\t\t\t\t\t:aria-activedescendant=\"activeIndex === null ? undefined : `${listboxId}-opt-${activeIndex}`\"\n\t\t\t\t\t\t:disabled=\"disabled || mode === 'read'\"\n\t\t\t\t\t\t@input=\"onInput\"\n\t\t\t\t\t\t@focus=\"onFocus\"\n\t\t\t\t\t\t@keydown.down.prevent=\"selectNext\"\n\t\t\t\t\t\t@keydown.up.prevent=\"selectPrev\"\n\t\t\t\t\t\t@keydown.enter.prevent=\"selectCurrent\"\n\t\t\t\t\t\t@keydown.esc=\"closeDropdown\"\n\t\t\t\t\t\t@keydown.tab=\"closeDropdown\" />\n\t\t\t\t\t<button\n\t\t\t\t\t\tv-if=\"hasValidId && !disabled && !embedded\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"aform_form-btn\"\n\t\t\t\t\t\t@click=\"handleNavigate\"\n\t\t\t\t\t\t@keydown.enter.prevent=\"handleNavigate\">\n\t\t\t\t\t\t<span>{{ icon === 'chevron-right' ? '›' : '→' }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<ul v-if=\"dropdownOpen\" :id=\"listboxId\" class=\"autocomplete-results\" role=\"listbox\" :aria-label=\"ariaLabel\">\n\t\t\t\t\t<li v-if=\"loading\" class=\"autocomplete-result loading\">Loading…</li>\n\t\t\t\t\t<li\n\t\t\t\t\t\tv-for=\"(option, i) in dropdownResults\"\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:id=\"`${listboxId}-opt-${i}`\"\n\t\t\t\t\t\t:key=\"String(option.id)\"\n\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t:aria-selected=\"i === activeIndex\"\n\t\t\t\t\t\tclass=\"autocomplete-result\"\n\t\t\t\t\t\t:class=\"{ 'is-active': i === activeIndex }\"\n\t\t\t\t\t\t@mousedown.prevent=\"selectOption(option)\">\n\t\t\t\t\t\t<slot name=\"option\" :option=\"option\">{{ option.displayText ?? String(option.id) }}</slot>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t\t<label v-if=\"label && !embedded\" class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { vOnClickOutside } from '@vueuse/components'\nimport { computed, inject, ref, useId, watch } from 'vue'\n\nimport type { AFormLinkNavigator, AFormLinkValue, ComponentProps } from '../../types'\nimport { deserializeFunction } from '../../utils/deserialize'\n\nconst {\n\tlabel,\n\tmode,\n\tuuid,\n\trequired,\n\tdoctype = undefined,\n\tformatter = undefined,\n\ticon = 'arrow-right',\n\tdisabled = false,\n\tfilterFunction = undefined,\n\tisAsync = false,\n\tembedded = false,\n\tplaceholder = undefined,\n\tariaLabel = undefined,\n} = defineProps<\n\tComponentProps & {\n\t\tdoctype?: string\n\t\tformatter?: (value: AFormLinkValue) => string\n\t\ticon?: 'arrow-right' | 'chevron-right'\n\t\tdisabled?: boolean\n\t\tfilterFunction?: string | ((search: string) => AFormLinkValue[] | Promise<AFormLinkValue[]>)\n\t\tisAsync?: boolean\n\t\t// Bare rendering for compositing into another component's own bordered container\n\t\t// (e.g. ACurrencyInput's merged amount+currency group): suppresses this component's\n\t\t// own outline/border and floating label so the parent supplies both exactly once.\n\t\tembedded?: boolean\n\t\tplaceholder?: string\n\t\t// Accessible name for the search input. Needed in `embedded` mode, where the visible\n\t\t// <label> is suppressed and a placeholder is not a dependable accessible name — it is\n\t\t// not exposed consistently across screen readers and vanishes once a value is picked.\n\t\tariaLabel?: string\n\t}\n>()\n\n// Ties the input to its listbox and to the active option (aria-controls / aria-activedescendant).\n// `uuid` is per-field when AForm supplies it; the fallback keeps the ids unique for a standalone\n// mount so two pickers on one page can't cross-wire their ARIA relationships.\nconst listboxId = `${uuid ?? `aform-link-${useId()}`}-listbox`\n\nconst modelValue = defineModel<AFormLinkValue>({ default: () => ({ id: '', displayText: '' }) })\n\nconst hasValidId = computed(() => {\n\tconst id = modelValue.value?.id\n\treturn id !== null && id !== undefined && id !== ''\n})\n\nconst displayedText = computed(() => {\n\tif (!hasValidId.value) return '—'\n\tif (formatter) return formatter(modelValue.value)\n\treturn modelValue.value.displayText ?? String(modelValue.value.id)\n})\n\nconst searchText = ref(hasValidId.value ? displayedText.value : '')\nconst dropdownOpen = ref(false)\nconst loading = ref(false)\nconst dropdownResults = ref<AFormLinkValue[]>([])\nconst activeIndex = ref<number | null>(null)\n\nconst navigator = inject<AFormLinkNavigator | null>('aformLinkNavigator', null)\n\ntype FilterFn = (search: string) => AFormLinkValue[] | Promise<AFormLinkValue[]>\ntype ResolverFn = (doctype: string, id: string) => string | undefined | Promise<string | undefined>\nconst resolver = inject<ResolverFn | null>('aformLinkResolver', null)\n\n// Records loaded from the DB arrive as scalar UUID strings; normalize to AFormLinkValue\n// so the resolution watch below can pick up the id correctly.\nwatch(\n\t() => modelValue.value,\n\tvalue => {\n\t\tif (value !== null && value !== undefined && (typeof value === 'string' || typeof value === 'number')) {\n\t\t\tmodelValue.value = { id: value }\n\t\t}\n\t},\n\t{ immediate: true }\n)\n\n// When the id changes (including on first render), resolve its display text.\n// Tries filterFunction first (returns a list of candidates to search); falls back to the\n// injected resolver (a direct doctype+id lookup). Skips if displayText is already set.\nwatch(\n\t() => modelValue.value?.id,\n\tasync id => {\n\t\tif (!id || modelValue.value.displayText) return\n\t\ttry {\n\t\t\tlet match: AFormLinkValue | undefined\n\t\t\tlet displayText: string | undefined\n\t\t\tif (filterFunction) {\n\t\t\t\tconst fn: FilterFn =\n\t\t\t\t\ttypeof filterFunction === 'string' ? deserializeFunction<FilterFn>(filterFunction) : filterFunction\n\t\t\t\tconst results = await fn(String(id))\n\t\t\t\tmatch = results.find(r => String(r.id) === String(id))\n\t\t\t\tdisplayText = match?.displayText\n\t\t\t\tif (displayText === undefined) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[AFormLink] filterFunction returned no matching result for id \"${id}\". ` +\n\t\t\t\t\t\t\t`The function must return an item whose \\`id\\` exactly matches the search string.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else if (resolver && doctype) {\n\t\t\t\tdisplayText = (await resolver(doctype, id.toString())) ?? undefined\n\t\t\t}\n\t\t\tif (displayText) {\n\t\t\t\t// Merge the whole matched record, not just its display text — the extra properties\n\t\t\t\t// an AFormLinkValue carries are part of the value (ACurrencyInput's `symbol`, which\n\t\t\t\t// its formatter renders, is one). `id` is pinned to the value we already hold so a\n\t\t\t\t// loosely-typed match (1 vs '1') can't change the FK's type underneath the record.\n\t\t\t\tconst resolved: AFormLinkValue = { ...modelValue.value, ...match, id: modelValue.value.id, displayText }\n\t\t\t\t// Format for the same reason selectOption does: the input shows `formatter`'s output\n\t\t\t\t// everywhere else (initial render, blur), so assigning the raw displayText here would\n\t\t\t\t// make a value that arrived as a bare id render differently from the identical value\n\t\t\t\t// picked by hand — e.g. \"Euro\" instead of \"€\".\n\t\t\t\tsearchText.value = formatter ? formatter(resolved) : displayText\n\t\t\t\tmodelValue.value = resolved\n\t\t\t}\n\t\t} catch {\n\t\t\t// silent — fall back to showing the raw id\n\t\t}\n\t},\n\t{ immediate: true }\n)\n\nconst handleNavigate = () => {\n\tif (navigator && doctype) {\n\t\tnavigator.navigate(doctype, modelValue.value.id)\n\t} else if (navigator && !doctype) {\n\t\tconsole.warn(\n\t\t\t`[AFormLink] Navigation requested but \\`doctype\\` prop is missing. ` +\n\t\t\t\t`Add \\`options\\` (or \\`doctype\\`) to the Link field definition to enable navigation.`\n\t\t)\n\t}\n}\n\nconst openDropdown = async (text: string) => {\n\tif (!filterFunction || mode === 'read') return\n\tactiveIndex.value = null\n\tdropdownOpen.value = true\n\tif (isAsync) loading.value = true\n\ttry {\n\t\tconst fn: FilterFn =\n\t\t\ttypeof filterFunction === 'string' ? deserializeFunction<FilterFn>(filterFunction) : filterFunction\n\t\tdropdownResults.value = (await fn(text)) ?? []\n\t} catch {\n\t\tdropdownResults.value = []\n\t} finally {\n\t\tloading.value = false\n\t}\n}\n\nconst closeDropdown = () => {\n\tdropdownOpen.value = false\n\tactiveIndex.value = null\n\tsearchText.value = hasValidId.value ? displayedText.value : ''\n}\n\nconst onClickOutside = () => {\n\tif (dropdownOpen.value) closeDropdown()\n}\n\nconst onFocus = () => openDropdown(searchText.value)\n\nconst onInput = () => openDropdown(searchText.value)\n\nconst selectOption = (option: AFormLinkValue) => {\n\tmodelValue.value = option\n\t// Format `option` directly rather than reading back displayedText/modelValue: under a real\n\t// two-way v-model (e.g. ACurrencyInput binding to a computed with a side-effecting setter),\n\t// modelValue.value still reflects the *prop* until the parent's update round-trips back,\n\t// so reading it synchronously here would show stale (pre-selection) text for a tick.\n\tsearchText.value = formatter ? formatter(option) : (option.displayText ?? String(option.id))\n\tdropdownOpen.value = false\n\tactiveIndex.value = null\n}\n\nconst selectNext = () => {\n\tconst len = dropdownResults.value.length\n\tif (!len) return\n\tactiveIndex.value = activeIndex.value === null ? 0 : (activeIndex.value + 1) % len\n}\n\nconst selectPrev = () => {\n\tconst len = dropdownResults.value.length\n\tif (!len) return\n\tif (activeIndex.value === null || activeIndex.value === 0) {\n\t\tactiveIndex.value = null\n\t} else {\n\t\tactiveIndex.value -= 1\n\t}\n}\n\nconst selectCurrent = () => {\n\tif (activeIndex.value !== null && dropdownResults.value[activeIndex.value]) {\n\t\tselectOption(dropdownResults.value[activeIndex.value])\n\t}\n}\n</script>\n\n<style scoped>\n.aform_form-link-wrapper {\n\tposition: relative;\n}\n\n.input-group {\n\tdisplay: flex;\n\talign-items: stretch;\n}\n\n.aform_input-field {\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.aform_form-element--embedded {\n\tmin-width: 0;\n\tflex-grow: 0;\n}\n\n/* Embedded mode: the host component's own container supplies the border, so this input\n goes borderless and inherits the host's padding scale instead of the standalone default. */\n.aform_input-field--embedded {\n\toutline: none;\n\tbackground: transparent;\n\tpadding: 0.5ch 1ch;\n}\n\n/* Only in embedded mode is the trigger deliberately narrower than its options (e.g. a currency\n symbol box): let the dropdown grow past it rather than truncate. Standalone pickers keep the\n dropdown flush with the input, so a long display text can't overhang a narrow form column. */\n.aform_form-element--embedded .autocomplete-results {\n\tmin-width: 100%;\n\twidth: max-content;\n}\n\n/* Give the button the same outline as the input, then slide it 2px left so the outlines\n overlap exactly at the join: input right outline sits at (input_right - 1px),\n button left outline also sits at (button_left + 1px) = (input_right - 2px + 1px) = same pixel. */\n.aform_form-btn {\n\tappearance: none;\n\tborder: none;\n\toutline: 1px solid var(--sc-input-border-color);\n\toutline-offset: -1px;\n\tmargin-left: -2px;\n\tbackground: var(--sc-input-field-background, white);\n\tpadding: 0 0.75rem;\n\tcursor: pointer;\n}\n\n.aform_form-btn:focus,\n.input-group:focus-within .aform_form-btn {\n\toutline-color: var(--sc-input-active-border-color);\n}\n\n.autocomplete-results {\n\tposition: absolute;\n\twidth: 100%;\n\tz-index: 100;\n\tpadding: 0;\n\tmargin: 0;\n\tlist-style: none;\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-top: none;\n\tborder-radius: 0 0 0.25rem 0.25rem;\n\tbackground: #fff;\n}\n\n.autocomplete-result {\n\tpadding: 4px 6px;\n\tcursor: pointer;\n\tborder-bottom: 0.5px solid lightgray;\n}\n\n.autocomplete-result.is-active,\n.autocomplete-result:hover {\n\tbackground-color: var(--sc-row-color-zebra-light);\n\tcolor: var(--sc-input-active-border-color);\n}\n</style>\n","<template>\n\t<div class=\"aform_form-element acurrency\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayText }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<div class=\"acurrency__row\">\n\t\t\t\t<div class=\"acurrency__field acurrency__field--amount\">\n\t\t\t\t\t<div class=\"acurrency__group\">\n\t\t\t\t\t\t<div class=\"acurrency__currency\">\n\t\t\t\t\t\t\t<AFormLink\n\t\t\t\t\t\t\t\tv-model=\"currency\"\n\t\t\t\t\t\t\t\t:mode=\"mode\"\n\t\t\t\t\t\t\t\tembedded\n\t\t\t\t\t\t\t\t:placeholder=\"currencyLabel\"\n\t\t\t\t\t\t\t\t:aria-label=\"currencyLabel\"\n\t\t\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t\t\t:formatter=\"currencySymbol\"\n\t\t\t\t\t\t\t\t:doctype=\"options.doctype\"\n\t\t\t\t\t\t\t\t:filter-function=\"options.filterFunction\"\n\t\t\t\t\t\t\t\t:is-async=\"options.isAsync\">\n\t\t\t\t\t\t\t\t<template #option=\"{ option }\"\n\t\t\t\t\t\t\t\t\t>{{ option.symbol ? `${option.symbol} — ` : '' }}{{ option.displayText ?? option.id }}</template\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t</AFormLink>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"acurrency__amount-wrap\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t:id=\"uuid\"\n\t\t\t\t\t\t\t\tv-model.number=\"amount\"\n\t\t\t\t\t\t\t\tclass=\"acurrency__amount\"\n\t\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t\t\t@keydown=\"onAmountKeydown\"\n\t\t\t\t\t\t\t\t@paste=\"onAmountPaste\" />\n\t\t\t\t\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"acurrency__row acurrency__row--base\">\n\t\t\t\t<div class=\"acurrency__field acurrency__field--base-currency\">\n\t\t\t\t\t<input :value=\"baseCurrencyText\" class=\"aform_input-field acurrency__base-field\" type=\"text\" disabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ baseCurrencyLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"acurrency__field acurrency__field--base-amount\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:value=\"modelValue.baseAmount\"\n\t\t\t\t\t\tclass=\"aform_input-field acurrency__base-field\"\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tdisabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ baseAmountLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"acurrency__field acurrency__field--exchange-rate\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:value=\"modelValue.exchangeRate\"\n\t\t\t\t\t\tclass=\"aform_input-field acurrency__base-field\"\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tdisabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ exchangeRateLabel }}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<p v-show=\"validation.errorMessage\" class=\"aform_error\" v-html=\"validation.errorMessage\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, ref, watch } from 'vue'\n\nimport type { AFormLinkValue, ComponentProps, CurrencyOptions, CurrencyValue } from '../../types'\nimport AFormLink from './AFormLink.vue'\n\nconst {\n\tlabel,\n\trequired,\n\tmode,\n\tuuid,\n\tvalidation = { errorMessage: '&nbsp;' },\n\toptions = {},\n\tcurrencyLabel = 'Currency',\n\tbaseCurrencyLabel = 'Base Currency',\n\tbaseAmountLabel = 'Base Amount',\n\texchangeRateLabel = 'Exchange Rate',\n} = defineProps<\n\tComponentProps & {\n\t\toptions?: CurrencyOptions\n\t\tcurrencyLabel?: string\n\t\tbaseCurrencyLabel?: string\n\t\tbaseAmountLabel?: string\n\t\texchangeRateLabel?: string\n\t}\n>()\n\n// The merged currency prefix is compact by design, so it shows the symbol rather than the\n// full currency name once a value is picked — falls back gracefully when a currency record\n// (or the story/app data behind it) doesn't carry a `symbol`.\nconst currencySymbol = (value: AFormLinkValue): string => value.symbol ?? value.displayText ?? String(value.id)\n\nconst modelValue = defineModel<CurrencyValue>({\n\tdefault: () => ({\n\t\tamount: 0,\n\t\tcurrency: { id: '' },\n\t\tbaseAmount: 0,\n\t\tbaseCurrency: { id: '' },\n\t\texchangeRate: 1,\n\t}),\n})\n\n// The base currency is fixed configuration, not user-editable. It may be supplied as a bare id\n// (resolved to displayText below via the same `aformLinkResolver` injection AFormLink uses) or\n// as a full AFormLinkValue that already carries displayText.\nconst normalizedBaseCurrency = computed<AFormLinkValue>(() => {\n\tconst base = options.baseCurrency ?? modelValue.value?.baseCurrency\n\tif (!base) return { id: '' }\n\treturn typeof base === 'string' ? { id: base } : base\n})\n\ntype ResolverFn = (doctype: string, id: string) => string | undefined | Promise<string | undefined>\nconst resolver = inject<ResolverFn | null>('aformLinkResolver', null)\n\nconst resolvedBaseCurrency = ref<AFormLinkValue>(normalizedBaseCurrency.value)\n\nwatch(\n\tnormalizedBaseCurrency,\n\tasync base => {\n\t\tif (!base.id || base.displayText || !resolver || !options.doctype) {\n\t\t\tresolvedBaseCurrency.value = base\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst displayText = await resolver(options.doctype, String(base.id))\n\t\t\tresolvedBaseCurrency.value = displayText ? { ...base, displayText } : base\n\t\t} catch {\n\t\t\tresolvedBaseCurrency.value = base\n\t\t}\n\t},\n\t{ immediate: true }\n)\n\nconst baseCurrencyText = computed(() => {\n\tconst base = resolvedBaseCurrency.value\n\tif (!base?.id) return ''\n\treturn base.displayText ?? String(base.id)\n})\n\nconst resolveExchangeRate = (currencyId: string | number | undefined): number => {\n\tconst baseId = resolvedBaseCurrency.value.id\n\tif (!currencyId || String(currencyId) === String(baseId)) return 1\n\t// The rate the value was booked at wins for as long as the currency is unchanged. Rates are\n\t// time-varying in a way conversion factors are not (see AQuantityInput), so `exchangeRates`\n\t// carries *today's* rates: preferring it here would silently re-rate a stored line to the\n\t// current rate on any touch — including the write-back AFormLink does when it resolves the\n\t// currency's display text, i.e. on mere render.\n\tif (String(currencyId) === String(modelValue.value?.currency?.id)) {\n\t\treturn modelValue.value?.exchangeRate ?? options.exchangeRates?.[String(currencyId)] ?? 1\n\t}\n\t// Switching to a currency absent from the rate map resets to 1 rather than silently reusing\n\t// the outgoing currency's rate.\n\treturn options.exchangeRates?.[String(currencyId)] ?? 1\n}\n\n// Enough decimal places to shed floating-point noise from the multiplication (e.g. 4 * 1.1 → 4.4\n// rather than 4.4000000000000004) without discarding a digit the rate actually produced. Matches\n// AQuantityInput's roundQty.\nconst FLOAT_NOISE_DECIMALS = 6\n\n// How far to round the base amount is the *base currency's* business, and only the app knows what\n// that is — so it says so via `precision` (JPY carries 0 decimals, most currencies 2, KWD 3).\n// Unset stays deliberately loose rather than defaulting to 2: hard-rounding every currency to\n// cents destroys value outright, e.g. 50 IDR at 0.000063 rounds to a base amount of 0. A garbage\n// precision (non-integer, negative, or past toFixed's 100 ceiling) falls back rather than throwing\n// inside the setter and breaking the field.\nconst baseDecimals = computed(() => {\n\tconst { precision } = options\n\tif (precision === undefined) return FLOAT_NOISE_DECIMALS\n\treturn Number.isInteger(precision) && precision >= 0 && precision <= 100 ? precision : FLOAT_NOISE_DECIMALS\n})\n\nconst roundAmount = (value: number): number => Number(value.toFixed(baseDecimals.value))\n\nconst recompute = (amount: number, currencyValue: AFormLinkValue) => {\n\tconst exchangeRate = resolveExchangeRate(currencyValue.id)\n\tmodelValue.value = {\n\t\tamount,\n\t\tcurrency: currencyValue,\n\t\texchangeRate,\n\t\tbaseCurrency: resolvedBaseCurrency.value,\n\t\tbaseAmount: roundAmount(amount * exchangeRate),\n\t}\n}\n\nconst amount = computed({\n\tget: () => modelValue.value?.amount ?? 0,\n\tset: (value: number) => recompute(value, modelValue.value?.currency ?? { id: '' }),\n})\n\nconst currency = computed<AFormLinkValue>({\n\tget: () => modelValue.value?.currency ?? { id: '' },\n\tset: (value: AFormLinkValue) => recompute(modelValue.value?.amount ?? 0, value),\n})\n\nconst amountNavigationKeys = new Set([\n\t'Backspace',\n\t'Delete',\n\t'Tab',\n\t'Escape',\n\t'Enter',\n\t'ArrowLeft',\n\t'ArrowRight',\n\t'ArrowUp',\n\t'ArrowDown',\n\t'Home',\n\t'End',\n])\n\nconst onAmountKeydown = (event: KeyboardEvent) => {\n\tif (event.ctrlKey || event.metaKey || event.altKey) return\n\tif (amountNavigationKeys.has(event.key)) return\n\tif (/^[0-9]$/.test(event.key)) return\n\t// A currency amount is signed — credit notes, refunds and adjustments are negative.\n\t//\n\t// Both dedup checks below are best-effort: a `type=\"number\"` input reports `value` as `''`\n\t// whenever its content isn't a valid number, so mid-entry states like \"1.\" or \"-\" read as\n\t// empty and a second separator can slip through. The browser rejects the resulting value\n\t// anyway; this guard exists to stop the obviously-wrong keys (letters, 'e', '+'), not to be\n\t// the sole arbiter of well-formedness.\n\tconst input = event.target as HTMLInputElement\n\tif (event.key === '.' && !input.value.includes('.')) return\n\tif (event.key === '-' && !input.value.includes('-')) return\n\tevent.preventDefault()\n}\n\nconst onAmountPaste = (event: ClipboardEvent) => {\n\tconst pasted = event.clipboardData?.getData('text') ?? ''\n\tif (!/^-?\\d*\\.?\\d*$/.test(pasted)) event.preventDefault()\n}\n\nconst showBase = computed(() => {\n\tconst v = modelValue.value\n\treturn !!v?.baseCurrency?.id && (v.currency?.id !== v.baseCurrency?.id || v.amount !== v.baseAmount)\n})\n\nconst displayText = computed(() => {\n\tconst v = modelValue.value\n\tif (!v || !v.currency?.id) return '—'\n\tconst currencyText = v.currency.displayText ?? String(v.currency.id)\n\tconst base = `${v.amount} ${currencyText}`\n\tif (!showBase.value) return base\n\tconst baseText = v.baseCurrency.displayText ?? String(v.baseCurrency.id)\n\treturn `${base} (${v.baseAmount} ${baseText})`\n})\n</script>\n\n<style scoped>\n.acurrency__row {\n\tdisplay: flex;\n\tgap: 1ch;\n}\n\n.acurrency__row--base {\n\tmargin-top: 1.5rem;\n}\n\n.acurrency__field {\n\tposition: relative;\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.acurrency__group {\n\tdisplay: flex;\n\talign-items: stretch;\n\twidth: 100%;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n}\n\n.acurrency__group:focus-within {\n\tborder-color: var(--sc-input-active-border-color);\n}\n\n/* Wraps just the amount input so its floating label (`left: 10px` of the nearest\n `position: relative` ancestor, per .aform_field-label) anchors above the amount box\n specifically, not the group's outer left edge — which is now the currency prefix. */\n.acurrency__amount-wrap {\n\tposition: relative;\n\tflex: 1;\n\tmin-width: 0;\n}\n\n/* The amount label (\"Total\") is the primary label for the whole merged group — bumped up\n slightly from the shared .aform_field-label size so it reads as the group's main label. */\n.acurrency__amount-wrap .aform_field-label {\n\tfont-size: 0.85rem;\n}\n\n.acurrency__amount {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tborder: none;\n\toutline: none;\n\tpadding: 0.5ch 1ch;\n\tbackground: transparent;\n\tborder-radius: 0 0.25rem 0.25rem 0;\n\ttext-align: right;\n\tappearance: textfield;\n\t-moz-appearance: textfield;\n}\n\n.acurrency__amount::-webkit-outer-spin-button,\n.acurrency__amount::-webkit-inner-spin-button {\n\tappearance: none;\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n\n/* The currency picker reads as a simple prefix addon (like Bootstrap's \"$\" prepend) rather\n than an equal partner to the amount box: compact width (it shows a symbol once a value is\n picked, not the full name), tinted background, left-rounded to match the group's own\n corner so the tint doesn't overhang the border. The dropdown itself isn't bound by this\n width — see AFormLink's .autocomplete-results — so search results still show full names. */\n.acurrency__currency {\n\tposition: relative;\n\tflex: 0 0 auto;\n\tmin-width: 4.5rem;\n\tbackground: var(--sc-gray-5);\n\tborder-right: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem 0 0 0.25rem;\n}\n\n.acurrency__base-field {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tfont-size: 1rem;\n\tpadding: 0.5ch 1ch;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n\toutline: none;\n\tappearance: textfield;\n\t-moz-appearance: textfield;\n}\n\n.acurrency__base-field:disabled {\n\tcolor: var(--sc-gray-50, #888);\n}\n\n/* Base Amount and Exchange Rate are read-only — the number spinner offers nothing here. */\n.acurrency__base-field::-webkit-outer-spin-button,\n.acurrency__base-field::-webkit-inner-spin-button {\n\tappearance: none;\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n</style>\n","<template>\n\t<template v-if=\"mode === 'display' || mode === 'read'\">\n\t\t<span class=\"aform_display-value\">{{ date ? new Date(date).toLocaleDateString() : '' }}</span>\n\t\t<label v-if=\"label\">{{ label }}</label>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</template>\n\t<template v-else>\n\t\t<div ref=\"datepicker\" class=\"adatepicker\" tabindex=\"0\">\n\t\t\t<table>\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td id=\"previous-month-btn\" :tabindex=\"-1\" @click=\"previousMonth\">&lt;</td>\n\t\t\t\t\t\t<th colspan=\"5\" :tabindex=\"-1\">{{ monthAndYear }}</th>\n\t\t\t\t\t\t<td id=\"next-month-btn\" :tabindex=\"-1\" @click=\"nextMonth\">&gt;</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr v-if=\"selectRange\">\n\t\t\t\t\t\t<td colspan=\"7\">\n\t\t\t\t\t\t\t<div class=\"date-input\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\tref=\"start-date-input\"\n\t\t\t\t\t\t\t\t\t:value=\"getStartDate\"\n\t\t\t\t\t\t\t\t\tclass=\"date-input-start aform_input-field\"\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tplaceholder=\"start date\"\n\t\t\t\t\t\t\t\t\t@blur=\"enterInputDate()\"\n\t\t\t\t\t\t\t\t\t@keydown=\"enterDate\" />\n\t\t\t\t\t\t\t\t<div>-</div>\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\tref=\"end-date-input\"\n\t\t\t\t\t\t\t\t\t:value=\"getEndDate\"\n\t\t\t\t\t\t\t\t\tclass=\"date-input-end aform_input-field\"\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tplaceholder=\"end date\"\n\t\t\t\t\t\t\t\t\t@blur=\"enterInputDate()\"\n\t\t\t\t\t\t\t\t\t@keydown=\"enterDate\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<!-- {{ formattedDateRange }} -->\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr class=\"days-header\">\n\t\t\t\t\t\t<td>M</td>\n\t\t\t\t\t\t<td>T</td>\n\t\t\t\t\t\t<td>W</td>\n\t\t\t\t\t\t<td>T</td>\n\t\t\t\t\t\t<td>F</td>\n\t\t\t\t\t\t<td>S</td>\n\t\t\t\t\t\t<td>S</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr v-for=\"rowNo in numberOfRows\" :key=\"rowNo\">\n\t\t\t\t\t\t<!-- the 'ref' key is currently only used for test references -->\n\t\t\t\t\t\t<td\n\t\t\t\t\t\t\tv-for=\"colNo in numberOfColumns\"\n\t\t\t\t\t\t\tref=\"celldate\"\n\t\t\t\t\t\t\t:key=\"getCurrentCell(rowNo, colNo)\"\n\t\t\t\t\t\t\tclass=\"date-cell\"\n\t\t\t\t\t\t\t:contenteditable=\"false\"\n\t\t\t\t\t\t\t:spellcheck=\"false\"\n\t\t\t\t\t\t\t:tabindex=\"0\"\n\t\t\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t\t\ttodaysDate: isTodaysDate(getCurrentDate(rowNo, colNo)),\n\t\t\t\t\t\t\t\tselectedDate: isSelectedDate(getCurrentDate(rowNo, colNo)),\n\t\t\t\t\t\t\t\twithinRange: selectRange ? isInDateRange(getCurrentDate(rowNo, colNo)) : false,\n\t\t\t\t\t\t\t\tstartDate: selectRange ? isStartDate(getCurrentDate(rowNo, colNo)) : false,\n\t\t\t\t\t\t\t\tendDate: selectRange ? isEndDate(getCurrentDate(rowNo, colNo)) : false,\n\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t@click.prevent.stop=\"selectDate(getCurrentCell(rowNo, colNo))\"\n\t\t\t\t\t\t\t@keydown.enter=\"selectDate(getCurrentCell(rowNo, colNo))\"\n\t\t\t\t\t\t\t@mouseover=\"hoverDate(getCurrentCell(rowNo, colNo))\">\n\t\t\t\t\t\t\t{{ new Date(getCurrentDate(rowNo, colNo)).getDate() }}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</template>\n</template>\n\n<script setup lang=\"ts\">\n/* removed keyboard nav temportarily since it interfered with user experience navigating input fields */\n// import { defaultKeypressHandlers, useKeyboardNav } from '@stonecrop/utilities'\nimport { computed, nextTick, onMounted, ref, useTemplateRef, watch } from 'vue'\n\nimport type { ComponentProps } from '../../types'\n\nconst numberOfRows = 6\nconst numberOfColumns = 7\n\nconst { mode, label, selectRange = false, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst date = defineModel<number | Date>({ default: () => new Date() })\nconst selectedDate = ref(new Date(date.value))\nconst currentMonth = ref<number>(selectedDate.value.getMonth())\nconst currentYear = ref<number>(selectedDate.value.getFullYear())\nconst currentDates = ref<number[]>([])\n\n/* needed for keyboard navigation. uncomment if implementing */\n// const datepickerRef = useTemplateRef<HTMLDivElement>('datepicker')\n\nconst hoveredDate = ref(new Date(date.value))\nconst start_date = ref<Date | null>(null)\nconst end_date = ref<Date | null>(null)\nconst startDateInput = useTemplateRef<HTMLInputElement>('start-date-input')\nconst endDateInput = useTemplateRef<HTMLInputElement>('end-date-input')\n\n/*******************\nEmits\n*******************/\n\nconst emit = defineEmits<{\n\t'get-date': [{ start: Date | null; end: Date | null; selected: Date }]\n}>()\n\n/*******************\nComputed\n*******************/\n\nconst monthAndYear = computed(() => {\n\treturn new Date(currentYear.value, currentMonth.value, 1).toLocaleDateString(undefined, {\n\t\tyear: 'numeric',\n\t\tmonth: 'long',\n\t})\n})\n\nconst getStartDate = computed(() => {\n\treturn start_date.value != null ? parseDateToString(start_date.value) : ''\n})\n\nconst getEndDate = computed(() => {\n\treturn end_date.value != null ? parseDateToString(end_date.value) : ''\n})\n\n/*******************\nFunctions\n*******************/\n\nconst parseDateToString = (dateValue: Date | null) => {\n\tif (!validateDate(dateValue)) return ''\n\treturn dateValue.getMonth() + 1 + '/' + dateValue.getDate() + '/' + dateValue.getFullYear()\n}\n\nconst isTodaysDate = (day: string | number | Date): boolean => {\n\tconst todaysDate = new Date()\n\tif (currentMonth.value !== todaysDate.getMonth()) return false\n\treturn todaysDate.toDateString() === new Date(day).toDateString()\n}\n\nconst isSelectedDate = (day: string | number | Date) => {\n\treturn new Date(day).toDateString() === new Date(selectedDate.value).toDateString()\n}\n\nconst isStartDate = (day: string | number | Date) => {\n\tconst start = start_date.value\n\tif (!validateDate(start)) return false\n\treturn new Date(day).toDateString() === start.toDateString()\n}\n\nconst isEndDate = (day: string | number | Date) => {\n\tconst end = end_date.value\n\tif (!validateDate(end)) return false\n\treturn new Date(day).toDateString() === end.toDateString()\n}\n\nconst getCurrentCell = (rowNo: number, colNo: number) => {\n\treturn (rowNo - 1) * numberOfColumns + colNo\n}\n\nconst isInDateRange = (day: string | number | Date) => {\n\tconst start = start_date.value\n\tif (!validateDate(start)) return false\n\tconst this_date = new Date(day)\n\n\t//the end is either the selected end date or wherever the user is hovering\n\tconst end = end_date.value\n\tconst temp_end_date = validateDate(end) ? end : new Date(hoveredDate.value)\n\n\treturn this_date.getTime() > start.getTime() && this_date.getTime() < temp_end_date.getTime()\n}\n\nconst getCurrentDate = (rowNo: number, colNo: number) => {\n\treturn currentDates.value[getCurrentCell(rowNo, colNo)]\n}\n\nconst hoverDate = (currentIndex: number) => {\n\thoveredDate.value = new Date(currentDates.value[currentIndex])\n}\n\nconst populateMonth = () => {\n\tcurrentDates.value = []\n\tconst firstOfMonth = new Date(currentYear.value, currentMonth.value, 1)\n\tconst monthStartWeekday = firstOfMonth.getDay()\n\tconst calendarStartDay = firstOfMonth.setDate(firstOfMonth.getDate() - monthStartWeekday)\n\n\t// assume midnight for all dates while building the calendar\n\tfor (const dayIndex of Array(43).keys()) {\n\t\tcurrentDates.value.push(calendarStartDay + dayIndex * 86400000)\n\t}\n}\nconst previousYear = () => (currentYear.value -= 1)\nconst nextYear = () => (currentYear.value += 1)\n\nconst previousMonth = () => {\n\tif (currentMonth.value == 0) {\n\t\tcurrentMonth.value = 11\n\t\tpreviousYear()\n\t} else {\n\t\tcurrentMonth.value -= 1\n\t}\n}\n\nconst nextMonth = () => {\n\tif (currentMonth.value == 11) {\n\t\tcurrentMonth.value = 0\n\t\tnextYear()\n\t} else {\n\t\tcurrentMonth.value += 1\n\t}\n}\n\nconst enterDate = (event: KeyboardEvent) => {\n\tif (event.key === 'Enter') enterInputDate()\n}\n\n// useKeyboardNav([\n// \t{\n// \t\tparent: datepickerRef,\n// \t\tselectors: 'td',\n// \t\thandlers: {\n// \t\t\t...defaultKeypressHandlers,\n// \t\t\t...{\n// \t\t\t\t'keydown.pageup': previousMonth,\n// \t\t\t\t'keydown.shift.pageup': previousYear,\n// \t\t\t\t'keydown.pagedown': nextMonth,\n// \t\t\t\t'keydown.shift.pagedown': nextYear,\n// \t\t\t\t// TODO: this is a hack to override the stonecrop enter handler;\n// \t\t\t\t// store context inside the component so that handlers can be setup consistently\n// \t\t\t\t// eslint-disable-next-line @typescript-eslint/no-empty-function\n// \t\t\t\t'keydown.enter': () => {}, // select this date\n// \t\t\t},\n// \t\t},\n// \t},\n// ])\n\nconst selectDate = (currentIndex: number) => {\n\tdate.value = selectedDate.value = new Date(currentDates.value[currentIndex])\n\n\tif (selectRange) {\n\t\tconst start = start_date.value\n\t\tif (start == null || end_date.value != null) {\n\t\t\tstart_date.value = date.value\n\t\t\tend_date.value = null\n\t\t} else if (validateDate(start) && selectedDate.value.getTime() < start.getTime()) {\n\t\t\tend_date.value = null\n\t\t\tstart_date.value = date.value\n\t\t} else {\n\t\t\tend_date.value = date.value\n\t\t}\n\t\tif (startDateInput.value) startDateInput.value.value = parseDateToString(start_date.value) ?? ''\n\t\tif (endDateInput.value) endDateInput.value.value = parseDateToString(end_date.value) ?? ''\n\t}\n\temitData()\n}\n\nconst testDateOrder = () => {\n\tconst start = start_date.value\n\tconst end = end_date.value\n\tif (validateDate(end) && validateDate(start) && end.getTime() < start.getTime())\n\t\t[start_date.value, end_date.value] = [end, start]\n}\n\nconst validateDate = (dateValue: unknown): dateValue is Date => {\n\treturn dateValue instanceof Date && !isNaN(dateValue.getTime())\n}\n\nconst enterInputDate = () => {\n\tif (startDateInput.value?.value == '') {\n\t\tstart_date.value = null\n\t} else if (startDateInput.value) {\n\t\tconst start = new Date(startDateInput.value.value)\n\t\tstart_date.value = validateDate(start) ? start : null\n\t}\n\n\tif (endDateInput.value?.value == '') {\n\t\tend_date.value = null\n\t} else if (endDateInput.value) {\n\t\tconst end = new Date(endDateInput.value.value)\n\t\tend_date.value = validateDate(end) ? end : null\n\t}\n\n\tif (validateDate(start_date.value)) {\n\t\tif (validateDate(end_date.value)) testDateOrder()\n\t\tselectedDate.value = start_date.value\n\t}\n\n\temitData()\n}\n\nconst emitData = () => {\n\temit('get-date', {\n\t\tstart: selectRange ? start_date.value : null,\n\t\tend: selectRange ? end_date.value : null,\n\t\tselected: selectedDate.value,\n\t})\n}\n\n/*******************\nHooks\n*******************/\n\nonMounted(async () => {\n\tpopulateMonth()\n\t// required to allow the elements to be focused in the next step\n\tawait nextTick()\n\tconst $selectedDate = document.getElementsByClassName('selectedDate')\n\tif ($selectedDate.length > 0) {\n\t\t;($selectedDate[0] as HTMLElement).focus()\n\t} else {\n\t\tconst $todaysDate = document.getElementsByClassName('todaysDate')\n\t\tif ($todaysDate.length > 0) {\n\t\t\t;($todaysDate[0] as HTMLElement).focus()\n\t\t}\n\t}\n})\n\n// setup keyboard navigation\n// useKeyboardNav([\n// \t{\n// \t\tparent: datepickerRef,\n// \t\tselectors: 'td',\n// \t\thandlers: {\n// \t\t\t...defaultKeypressHandlers,\n// \t\t\t'keydown.pageup': previousMonth,\n// \t\t\t'keydown.shift.pageup': previousYear,\n// \t\t\t'keydown.pagedown': nextMonth,\n// \t\t\t'keydown.shift.pagedown': nextYear,\n// \t\t\t// TODO: this is a hack to override the stonecrop enter handler;\n// \t\t\t// store context inside the component so that handlers can be setup consistently\n\n// \t\t\t'keydown.enter': () => {}, // select this date\n// \t\t},\n// \t},\n// ])\n\n/*******************\nWatchers\n*******************/\n\nwatch([currentMonth, currentYear], populateMonth)\n\n/*******************\nExpose\n*******************/\n\ndefineExpose({ currentMonth, currentYear, selectedDate })\n</script>\n\n<style scoped>\n.adatepicker {\n\tfont-size: var(--sc-table-font-size);\n\tdisplay: inline-table;\n\tcolor: var(--sc-cell-text-color);\n\toutline: none;\n\tborder-collapse: collapse;\n\tmargin-bottom: 10px;\n\t/* width: calc(100% - 4px); */\n}\n\n.adatepicker tr {\n\theight: 1.15rem;\n\theight: 1.15rem;\n\ttext-align: center;\n\tvertical-align: middle;\n}\n\n.adatepicker td {\n\tborder: 2px solid transparent;\n\toutline: 2px solid transparent;\n\tmin-width: 3ch;\n\tmax-width: 3ch;\n\tcursor: pointer;\n}\n.adatepicker td.date-cell:hover {\n\tbackground: var(--sc-gray-10);\n}\n\n.adatepicker td:focus,\n.adatepicker td:focus-within {\n\t/* outline: 1px dashed black; */\n\tbox-shadow: none;\n\toverflow: hidden;\n\tmin-height: 1.15em;\n\tmax-height: 1.15em;\n\toverflow: hidden;\n}\n.adatepicker .selectedDate,\n.adatepicker .startDate,\n.adatepicker .endDate {\n\t/* outline: 1px solid black; */\n\tbackground: var(--sc-gray-20);\n\tfont-weight: bolder;\n}\n.adatepicker .startDate {\n\t/* border-radius: 5px 0px 0px 5px; */\n\tborder-left: 1px solid var(--sc-gray-50);\n\tbackground: var(--sc-gray-20) !important;\n}\n.adatepicker .endDate {\n\tborder-right: 1px solid var(--sc-gray-50);\n\t/* border-radius: 0px 5px 5px 0px; */\n\tbackground: var(--sc-gray-20) !important;\n}\n.adatepicker .withinRange {\n\tbackground: var(--sc-gray-5);\n}\n\n.adatepicker .todaysDate {\n\tfont-weight: bolder;\n\t/* text-decoration: underline; */\n\tcolor: black;\n}\n.days-header > td {\n\tfont-weight: bold;\n}\n.prev-date {\n\tcolor: var(--sc-gray-20);\n}\n\n.adatepicker .date-input {\n\tdisplay: flex;\n\twidth: 100%;\n\tgap: 5px;\n\talign-items: center;\n}\n.adatepicker .date-input > input {\n\twidth: 50%;\n\tpadding: 2px;\n}\n\n/* Keep the field error in-flow below the calendar. The shared .aform_error is absolutely\n positioned against a .aform_form-element anchor, which this grid component does not use. */\np.aform_error {\n\tposition: static;\n\tdisplay: block;\n\tcolor: var(--sc-brand-danger, red);\n\tfont-size: 0.7rem;\n\tmargin: 0.25rem 0 0;\n}\n</style>\n","<template>\n\t<div class=\"adate_time\">\n\t\t<div class=\"adate_time_fields\">\n\t\t\t<input\n\t\t\t\tv-model=\"timeData.hours\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tinputmode=\"numeric\"\n\t\t\t\t@paste=\"pasteInput($event, true)\"\n\t\t\t\t@focus=\"focusInput\"\n\t\t\t\t@blur=\"confirmTime\"\n\t\t\t\t@keydown.enter.prevent=\"confirmTime\"\n\t\t\t\t@keydown.up.prevent=\"tick('hours')\"\n\t\t\t\t@keydown.down.prevent=\"tick('hours', -1)\" />\n\t\t\t<span class=\"colon\">:</span>\n\t\t\t<input\n\t\t\t\tv-model=\"timeData.minutes\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tinputmode=\"numeric\"\n\t\t\t\t@paste=\"pasteInput\"\n\t\t\t\t@focus=\"focusInput\"\n\t\t\t\t@blur=\"confirmTime\"\n\t\t\t\t@keydown.enter.prevent=\"confirmTime\"\n\t\t\t\t@keydown.up.prevent=\"tick('minutes')\"\n\t\t\t\t@keydown.down.prevent=\"tick('minutes', -1)\" />\n\t\t\t<span v-if=\"useSeconds\" class=\"colon\">:</span>\n\t\t\t<input\n\t\t\t\tv-if=\"useSeconds\"\n\t\t\t\tv-model=\"timeData.seconds\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tinputmode=\"numeric\"\n\t\t\t\t@paste=\"pasteInput\"\n\t\t\t\t@focus=\"focusInput\"\n\t\t\t\t@blur=\"confirmTime\"\n\t\t\t\t@keydown.enter.prevent=\"confirmTime\"\n\t\t\t\t@keydown.up.prevent=\"tick('seconds')\"\n\t\t\t\t@keydown.down.prevent=\"tick('seconds', -1)\" />\n\t\t\t<select\n\t\t\t\tv-if=\"!allowMilitaryTime\"\n\t\t\t\tref=\"meridiem-selector\"\n\t\t\t\tv-model=\"meridiem\"\n\t\t\t\tclass=\"aform-select meridiem-selector\"\n\t\t\t\t@change=\"confirmTime\">\n\t\t\t\t<option value=\"AM\">AM</option>\n\t\t\t\t<option value=\"PM\">PM</option>\n\t\t\t</select>\n\t\t</div>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, useTemplateRef, watch, onMounted } from 'vue'\n\nconst {\n\tallowMilitaryTime = false,\n\tdefaultHours = 12,\n\tdefaultMinutes = 0,\n\tdefaultSeconds = 0,\n\tdefaultMeridiem = 'AM',\n\tuseSeconds = true,\n} = defineProps<{\n\tallowMilitaryTime?: boolean\n\tdefaultHours?: number\n\tdefaultMinutes?: number\n\tdefaultSeconds?: number\n\tdefaultMeridiem?: string\n\tuseSeconds?: boolean\n}>()\n\nconst emit = defineEmits<{\n\t'get-time': [{ hours: number; minutes: number; seconds: number; meridiem: string; militaryTime: number }]\n}>()\n\nconst meridiemSelector = useTemplateRef<HTMLSelectElement>('meridiem-selector')\n\nconst timeData = reactive({\n\thours: String(defaultHours).padStart(2, '0'),\n\tminutes: String(defaultMinutes).padStart(2, '0'),\n\tseconds: String(defaultSeconds).padStart(2, '0'),\n})\n\nconst meridiem = ref(defaultMeridiem == 'AM' ? 'AM' : 'PM')\n\nonMounted(() => {\n\temitTime()\n})\n\nconst confirmTime = () => {\n\tconst maxHours = allowMilitaryTime ? 23 : 12\n\tconst minHours = allowMilitaryTime ? 0 : 1\n\tlet hours = Number(timeData.hours)\n\tlet minutes = Number(timeData.minutes)\n\tlet seconds = Number(timeData.seconds)\n\n\tif (isNaN(hours) || timeData.hours === '' || hours > maxHours) hours = maxHours\n\tif (!allowMilitaryTime && hours < minHours) hours = minHours\n\tif (isNaN(minutes) || timeData.minutes === '' || minutes > 59) minutes = 59\n\tif (isNaN(seconds) || timeData.seconds === '' || seconds > 59) seconds = 59\n\n\ttimeData.hours = String(hours).padStart(2, '0')\n\ttimeData.minutes = String(minutes).padStart(2, '0')\n\ttimeData.seconds = String(seconds).padStart(2, '0')\n\n\temitTime()\n}\n\nconst emitTime = () => {\n\tconst hours = Number(timeData.hours)\n\tconst minutes = Number(timeData.minutes)\n\tconst seconds = Number(timeData.seconds)\n\temit('get-time', {\n\t\thours,\n\t\tminutes,\n\t\tseconds,\n\t\tmeridiem: meridiem.value,\n\t\tmilitaryTime: allowMilitaryTime ? hours : meridiem.value === 'PM' ? (hours === 12 ? 12 : hours + 12) : hours % 12,\n\t})\n}\n\nconst focusInput = (event: FocusEvent) => {\n\tconst target = event.target\n\tif (target instanceof HTMLInputElement) {\n\t\ttarget.select()\n\t}\n}\n\nconst tick = (target: 'hours' | 'minutes' | 'seconds', amount = 1) => {\n\tconst maxHours = allowMilitaryTime ? 23 : 12\n\tconst minHours = allowMilitaryTime ? 0 : 1\n\n\tif (target == 'hours') {\n\t\tconst oldHours = Number(timeData.hours)\n\t\ttimeData.hours = String(oldHours + amount)\n\t\tif ((oldHours == 11 && Number(timeData.hours) == 12) || (oldHours == 12 && Number(timeData.hours) == 11)) {\n\t\t\tchangeMeridiem()\n\t\t}\n\t} else if (target == 'minutes') {\n\t\ttimeData.minutes = String(Number(timeData.minutes) + amount)\n\t} else if (target == 'seconds') {\n\t\ttimeData.seconds = String(Number(timeData.seconds) + amount)\n\t}\n\n\tconst prevHours = Number(timeData.hours)\n\n\tif (Number(timeData.seconds) < 0) timeData.minutes = String(Number(timeData.minutes) - 1)\n\telse if (Number(timeData.seconds) > 59) timeData.minutes = String(Number(timeData.minutes) + 1)\n\n\tif (Number(timeData.minutes) < 0) timeData.hours = String(prevHours - 1)\n\telse if (Number(timeData.minutes) > 59) timeData.hours = String(prevHours + 1)\n\n\tconst newRawHours = Number(timeData.hours)\n\tif (!allowMilitaryTime && newRawHours !== prevHours) {\n\t\tif ((prevHours === 11 && newRawHours === 12) || (prevHours === 12 && newRawHours === 11)) {\n\t\t\tchangeMeridiem()\n\t\t}\n\t}\n\n\ttimeData.hours = String(formatTime(Number(timeData.hours), minHours, maxHours)).padStart(2, '0')\n\ttimeData.minutes = String(formatTime(Number(timeData.minutes), 0, 59)).padStart(2, '0')\n\ttimeData.seconds = String(formatTime(Number(timeData.seconds), 0, 59)).padStart(2, '0')\n}\n\nwatch(\n\t() => timeData.hours,\n\t(newVal, oldVal) => {\n\t\ttimeData.hours = Number(newVal) > 99 ? oldVal : newVal\n\t}\n)\nwatch(\n\t() => timeData.minutes,\n\t(newVal, oldVal) => {\n\t\ttimeData.minutes = Number(newVal) > 99 ? oldVal : newVal\n\t}\n)\nwatch(\n\t() => timeData.seconds,\n\t(newVal, oldVal) => {\n\t\ttimeData.seconds = Number(newVal) > 99 ? oldVal : newVal\n\t}\n)\n\nconst formatTime = (target: number, min: number, max: number): number => {\n\tif (target > max) return min\n\telse if (target < min) return max\n\treturn target\n}\n\nconst changeMeridiem = () => {\n\tmeridiem.value = meridiem.value == 'PM' ? 'AM' : 'PM'\n\temitTime()\n}\n\nconst pasteInput = (event: ClipboardEvent, pasteAllFields = false) => {\n\tevent.stopPropagation()\n\tevent.preventDefault()\n\n\tconst clipboardData = event.clipboardData\n\tif (!clipboardData) return\n\tlet pastedData: string = clipboardData.getData('Text')\n\n\tpastedData = pastedData.replace(/[^0-9]/g, '')\n\n\tif (pasteAllFields) {\n\t\tif (pastedData.length % 2 != 0) pastedData = '0' + pastedData\n\t\tif (pastedData.length < 3) pastedData += '00'\n\t\tif (pastedData.length < 5) pastedData += '00'\n\n\t\tconst timeUnits = pastedData.match(/(..?)/g)\n\t\tif (!timeUnits || timeUnits.length < 3) return\n\n\t\ttimeData.seconds = timeUnits[2]\n\t\ttimeData.minutes = timeUnits[1]\n\t\ttimeData.hours = timeUnits[0]\n\t\tconfirmTime()\n\t\tif (!allowMilitaryTime) meridiemSelector.value?.focus()\n\t} else {\n\t\tif (pastedData.length > 2) pastedData = pastedData.slice(0, 2)\n\t\tconst target = event.target\n\t\tif (target instanceof HTMLInputElement) {\n\t\t\ttarget.value = pastedData\n\t\t\ttarget.dispatchEvent(new Event('input'))\n\t\t}\n\t}\n}\n</script>\n\n<style scoped>\n.adate_time {\n\twidth: auto;\n\tpadding: 10px;\n\tbox-sizing: border-box;\n\tfont-size: 1rem;\n\tbackground: var(--sc-gray-10);\n}\n.adate_time_fields {\n\tdisplay: flex;\n\talign-items: stretch;\n\tgap: 5px;\n\tjustify-content: flex-start;\n}\n.adate_time_fields > input {\n\tmin-width: 30px;\n\tpadding: 2px;\n\ttext-align: center;\n\tdisplay: inline-block;\n\tflex-basis: 0;\n}\n.meridiem-selector {\n\tcursor: pointer;\n\tdisplay: inline-block;\n\tflex-basis: 0;\n\tpadding: 5px;\n\tuser-select: none;\n}\n.meridiem-selector:focus {\n\toutline: 2px solid black;\n\toutline-offset: -2px;\n}\n.adate_time_segment {\n\tdisplay: flex;\n\tflex-direction: column;\n\twidth: 40px;\n}\n.colon {\n\tdisplay: flex;\n\talign-items: normal;\n}\n.aform_form-btn {\n\tcursor: pointer;\n}\n.aform-select {\n\tborder-radius: 0px;\n\tborder: 1px solid rgb(118, 118, 118);\n\tfont-size: 1rem;\n\tpadding: 0rem;\n\tmargin: 0;\n\tborder-radius: 0;\n\tbox-sizing: border-box;\n\tmin-height: auto;\n\tposition: relative;\n\tcolor: var(--sc-cell-text-color);\n}\n.meridiem-selector {\n\tmargin-left: 6px;\n}\n</style>\n","<!-- This serves as a wrapper component for ADatePicker and ADateTime in one component -->\n\n<template>\n\t<div class=\"adate-selection\">\n\t\t<ADatePicker v-if=\"showDate\" :select-range=\"selectRange\" @get-date=\"handleDate\" />\n\n\t\t<ADateTime\n\t\t\tv-if=\"showTime\"\n\t\t\t:allow-military-time=\"allowMilitaryTime\"\n\t\t\t:default-hours=\"defaultHours\"\n\t\t\t:default-minutes=\"defaultMinutes\"\n\t\t\t:default-seconds=\"defaultSeconds\"\n\t\t\t:default-meridiem=\"defaultMeridiem\"\n\t\t\t:use-seconds=\"useSeconds\"\n\t\t\t@get-time=\"handleStartTime\" />\n\n\t\t<template v-if=\"selectRange && showTime && showEndTime\">\n\t\t\t<div class=\"adate-selection__end-label\">End time</div>\n\t\t\t<ADateTime\n\t\t\t\t:allow-military-time=\"allowMilitaryTime\"\n\t\t\t\t:default-hours=\"defaultHours\"\n\t\t\t\t:default-minutes=\"defaultMinutes\"\n\t\t\t\t:default-seconds=\"defaultSeconds\"\n\t\t\t\t:default-meridiem=\"defaultMeridiem\"\n\t\t\t\t:use-seconds=\"useSeconds\"\n\t\t\t\t@get-time=\"handleEndTime\" />\n\t\t</template>\n\n\t\t<p v-if=\"!showTime && !showDate\" class=\"empty\">empty</p>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { provide, ref } from 'vue'\nimport ADatePicker from './ADatePicker.vue'\nimport ADateTime from './ADateTime.vue'\n\nconst {\n\tshowDate = true,\n\tshowTime = true,\n\tselectRange = true,\n\tshowEndTime = false,\n\tallowMilitaryTime = false,\n\tdefaultHours = 12,\n\tdefaultMinutes = 0,\n\tdefaultSeconds = 0,\n\tdefaultMeridiem = 'AM',\n\tuseSeconds = true,\n} = defineProps<{\n\tshowDate?: boolean\n\tshowTime?: boolean\n\tselectRange?: boolean\n\tshowEndTime?: boolean\n\tallowMilitaryTime?: boolean\n\tdefaultHours?: number\n\tdefaultMinutes?: number\n\tdefaultSeconds?: number\n\tdefaultMeridiem?: string\n\tuseSeconds?: boolean\n}>()\n\nconst emit = defineEmits<{\n\t'get-date': [{ selected: Date; start?: Date | null; end?: Date | null }]\n\t'get-time': [{ hours: number; minutes: number; seconds: number; meridiem: string }]\n\t'get-range': [{ start: Date; end: Date }]\n}>()\n\nprovide('select-range', selectRange)\n\nconst today = new Date()\nconst pickerStart = ref<Date>(today)\nconst pickerEnd = ref<Date>(today)\nconst startTimeMs = ref<number>(0)\nconst endTimeMs = ref<number>(0)\n\nconst mergeDateTime = (date: Date, timeMs: number): Date => {\n\tconst d = new Date(date)\n\td.setHours(0, 0, 0, 0)\n\treturn new Date(d.getTime() + timeMs)\n}\n\nconst timePayloadToMs = (payload: {\n\thours: number\n\tminutes: number\n\tseconds: number\n\tmeridiem: string\n\tmilitaryTime?: number\n}): number => {\n\tlet h: number\n\tif (payload.militaryTime !== undefined) {\n\t\th = payload.militaryTime\n\t} else {\n\t\tconst hrs = payload.hours % 12\n\t\th = payload.meridiem === 'PM' ? hrs + 12 : hrs\n\t}\n\treturn (h * 3600 + payload.minutes * 60 + (payload.seconds ?? 0)) * 1000\n}\n\nconst tryEmitRange = () => {\n\tif (!selectRange || !showTime || !showEndTime) return\n\temit('get-range', {\n\t\tstart: mergeDateTime(pickerStart.value, startTimeMs.value),\n\t\tend: mergeDateTime(pickerEnd.value, endTimeMs.value),\n\t})\n}\n\nconst handleDate = (data: { start: Date | null; end: Date | null; selected: Date }) => {\n\temit('get-date', data)\n\tif (selectRange) {\n\t\tpickerStart.value = data.start ?? data.selected\n\t\tpickerEnd.value = data.end ?? data.selected\n\t\ttryEmitRange()\n\t}\n}\n\nconst handleStartTime = (data: {\n\thours: number\n\tminutes: number\n\tseconds: number\n\tmeridiem: string\n\tmilitaryTime?: number\n}) => {\n\tstartTimeMs.value = timePayloadToMs(data)\n\tif (showEndTime) {\n\t\ttryEmitRange()\n\t} else {\n\t\temit('get-time', data)\n\t}\n}\n\nconst handleEndTime = (data: {\n\thours: number\n\tminutes: number\n\tseconds: number\n\tmeridiem: string\n\tmilitaryTime?: number\n}) => {\n\tendTimeMs.value = timePayloadToMs(data)\n\ttryEmitRange()\n}\n</script>\n\n<style scoped>\n.adate-selection {\n\tdisplay: inline-block;\n\tborder: 1px solid var(--sc-gray-80);\n\tpadding: 10px;\n\tbackground: var(--sc-form-background);\n}\n\n.adate-selection__end-label {\n\tfont-size: 0.8em;\n\tfont-weight: bold;\n\tcolor: var(--sc-input-active-label-color, #555);\n\tmargin-top: 8px;\n\tmargin-bottom: 2px;\n\tpadding-left: 2px;\n}\n\n.empty {\n\tcolor: #ccc;\n\tpadding: 10px;\n\ttext-align: center;\n\tborder: 1px solid #ccc;\n}\n</style>\n","<template>\n\t<div>\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ modelValue ? new Date(inputDate).toLocaleDateString() : '' }}</span>\n\t\t\t<label>{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tref=\"date\"\n\t\t\t\tv-model=\"inputDate\"\n\t\t\t\tclass=\"adate-input\"\n\t\t\t\t:value=\"inputDate\"\n\t\t\t\ttype=\"date\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:required=\"required\"\n\t\t\t\t@click.prevent=\"\n\t\t\t\t\t() => {\n\t\t\t\t\t\tshowPicker = !showPicker\n\t\t\t\t\t}\n\t\t\t\t\" />\n\t\t\t<label :for=\"uuid\">{{ label }}</label>\n\t\t\t<p v-show=\"errorText\" v-html=\"errorText\"></p>\n\t\t\t<ADateSelection\n\t\t\t\tv-if=\"showPicker\"\n\t\t\t\tref=\"picker\"\n\t\t\t\tclass=\"picker\"\n\t\t\t\t:select-range=\"false\"\n\t\t\t\t:show-time=\"false\"\n\t\t\t\t@get-date=\"handleDate\" />\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useTemplateRef, ref, computed, watch } from 'vue'\nimport { onClickOutside } from '@vueuse/core'\n\nimport ADateSelection from './ADateSelection.vue'\nimport type { ComponentProps } from '../../types'\n\nconst {\n\tlabel = 'Date',\n\trequired,\n\tmode,\n\tuuid,\n\terrors,\n\tvalidation = { errorMessage: '' },\n} = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst modelValue = defineModel<string | Date>()\n\nconst currentDate = ref(modelValue.value ? new Date(modelValue.value) : new Date())\nconst inputDate = computed({\n\tget: () => currentDate.value.toISOString().split('T')[0],\n\tset: (value: string) => {\n\t\tcurrentDate.value = new Date(value)\n\t\tmodelValue.value = value\n\t},\n})\n\nconst pickerRef = useTemplateRef<HTMLDivElement>('picker')\nconst showPicker = ref(false)\n\nonClickOutside(pickerRef, () => (showPicker.value = false))\n\nwatch(\n\t() => modelValue.value,\n\tnewValue => {\n\t\tif (newValue) {\n\t\t\tcurrentDate.value = new Date(newValue)\n\t\t}\n\t}\n)\n\nconst handleDate = (data: { selected: Date }) => {\n\tcurrentDate.value = data.selected\n\tmodelValue.value = inputDate.value\n}\n</script>\n\n<style scoped>\n.adate-input {\n\toverflow: auto;\n}\ndiv {\n\tmin-width: 40ch;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tborder: 1px solid transparent;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tmargin-right: 1ch;\n}\n\ninput {\n\twidth: calc(100% - 1ch);\n\tbox-sizing: border-box;\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tpadding: 1ch 0.5ch 0.5ch 1ch;\n\tmargin: calc(1.15rem / 2) 0 0 0;\n\tmin-height: 1.15rem;\n\tborder-radius: 0.25rem;\n}\n\np,\nlabel {\n\tcolor: var(--sc-input-label-color);\n\tdisplay: block;\n\tmin-height: 1.15rem;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tborder: 1px solid transparent;\n\tmargin-bottom: 0.25rem;\n\tbox-sizing: border-box;\n}\n\np {\n\twidth: 100%;\n\tcolor: red;\n\tfont-size: 85%;\n\tbox-sizing: border-box;\n}\n\nlabel {\n\tz-index: 0;\n\tfont-size: 80%;\n\tposition: absolute;\n\tbackground: white;\n\tmargin: calc(-1.5rem - calc(2.15rem / 2)) 0 0 1ch;\n\tpadding: 0 0.25ch 0 0.25ch;\n\tbox-sizing: border-box;\n}\n\ninput:focus {\n\tborder: 1px solid var(--sc-input-active-border-color);\n}\n\ninput:focus + label {\n\tcolor: var(--sc-input-active-label-color);\n}\n.picker {\n\tposition: absolute;\n\ttop: 50px;\n}\n</style>\n","<template>\n\t<div v-if=\"mode === 'display'\" class=\"input-wrapper\">\n\t\t<span class=\"aform_display-value\">{{ search ?? '' }}</span>\n\t\t<label>{{ label }}</label>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</div>\n\t<div v-else v-on-click-outside=\"onClickOutside\" class=\"autocomplete\" :class=\"{ isOpen: dropdown.open }\">\n\t\t<div class=\"input-wrapper\">\n\t\t\t<input\n\t\t\t\tv-model=\"search\"\n\t\t\t\ttype=\"text\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t@input=\"filter\"\n\t\t\t\t@focus=\"openDropdown\"\n\t\t\t\t@keydown.down=\"selectNextResult\"\n\t\t\t\t@keydown.up=\"selectPrevResult\"\n\t\t\t\t@keydown.enter=\"setCurrentResult\"\n\t\t\t\t@keydown.esc=\"onClickOutside\"\n\t\t\t\t@keydown.tab=\"onClickOutside\" />\n\n\t\t\t<ul v-show=\"dropdown.open\" id=\"autocomplete-results\" class=\"autocomplete-results\">\n\t\t\t\t<li v-if=\"dropdown.loading\" class=\"loading autocomplete-result\">Loading results...</li>\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"(result, i) in dropdown.results\"\n\t\t\t\t\tv-else\n\t\t\t\t\t:key=\"result\"\n\t\t\t\t\tclass=\"autocomplete-result\"\n\t\t\t\t\t:class=\"{ 'is-active': i === dropdown.activeItemIndex }\"\n\t\t\t\t\t@click.stop=\"setResult(result)\">\n\t\t\t\t\t{{ result }}\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t\t<label>{{ label }}</label>\n\t\t</div>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { vOnClickOutside } from '@vueuse/components'\nimport { computed, reactive, ref } from 'vue'\n\nimport type { ComponentProps } from '../../types'\n\nconst {\n\tlabel,\n\toptions = [],\n\tisAsync = false,\n\tfilterFunction = undefined,\n\tmode,\n\terrors,\n\tvalidation = { errorMessage: '' },\n} = defineProps<\n\tComponentProps & {\n\t\toptions?: string[]\n\t\tisAsync?: boolean\n\t\tfilterFunction?: (search: string) => string[] | Promise<string[]>\n\t}\n>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\nconst search = defineModel<string>()\n\n// tracks the last explicitly-committed value so outside-click reverts instead of clears\nconst committedValue = ref(search.value ?? '')\n\nconst dropdown = reactive({\n\tactiveItemIndex: null as number | null,\n\topen: false,\n\tloading: false,\n\tresults: options,\n})\n\nconst onClickOutside = () => closeDropdown()\n\nconst filter = async () => {\n\tdropdown.open = true\n\tdropdown.activeItemIndex = null\n\tif (filterFunction) {\n\t\tif (isAsync) dropdown.loading = true\n\t\ttry {\n\t\t\tconst filteredResults = await filterFunction(search.value || '')\n\t\t\tdropdown.results = filteredResults || []\n\t\t} catch {\n\t\t\tdropdown.results = []\n\t\t} finally {\n\t\t\tif (isAsync) dropdown.loading = false\n\t\t}\n\t} else {\n\t\tfilterResults()\n\t}\n}\n\nconst setResult = (result: string) => {\n\tsearch.value = result\n\tcommittedValue.value = result\n\tcloseDropdown(result)\n}\n\nconst openDropdown = () => {\n\tconst idx = options?.indexOf(search.value ?? '') ?? -1\n\tdropdown.activeItemIndex = isAsync ? null : idx >= 0 ? idx : null\n\tdropdown.open = true\n\t// TODO: this should probably call the async function if it's async\n\tdropdown.results = isAsync ? [] : options\n}\n\nconst closeDropdown = (result?: string) => {\n\tdropdown.activeItemIndex = null\n\tdropdown.open = false\n\tif (!options?.includes(result || search.value || '')) {\n\t\tsearch.value = committedValue.value\n\t}\n}\n\nconst filterResults = () => {\n\tif (!search.value) {\n\t\tdropdown.results = options\n\t} else {\n\t\tdropdown.results = options?.filter(item => item.toLowerCase().includes((search.value ?? '').toLowerCase()))\n\t}\n}\n\nconst selectNextResult = () => {\n\tconst resultsLength = dropdown.results?.length || 0\n\tif (dropdown.activeItemIndex != null) {\n\t\tconst currentIndex = isNaN(dropdown.activeItemIndex) ? 0 : dropdown.activeItemIndex\n\t\tdropdown.activeItemIndex = (currentIndex + 1) % resultsLength\n\t} else {\n\t\tdropdown.activeItemIndex = 0\n\t}\n}\n\nconst selectPrevResult = () => {\n\tconst resultsLength = dropdown.results?.length || 0\n\tif (dropdown.activeItemIndex != null) {\n\t\tconst currentIndex = isNaN(dropdown.activeItemIndex) ? 0 : dropdown.activeItemIndex\n\t\tif (currentIndex === 0) {\n\t\t\tdropdown.activeItemIndex = null\n\t\t} else {\n\t\t\tdropdown.activeItemIndex = currentIndex - 1\n\t\t}\n\t} else {\n\t\tdropdown.activeItemIndex = resultsLength - 1\n\t}\n}\n\nconst setCurrentResult = () => {\n\tif (dropdown.results) {\n\t\tconst currentIndex = dropdown.activeItemIndex || 0\n\t\tconst result = dropdown.results[currentIndex]\n\t\tsetResult(result)\n\t}\n\tdropdown.activeItemIndex = 0\n}\n</script>\n\n<style scoped>\n/* variables taken from here: https://github.com/frappe/frappe/blob/version-13/frappe/public/scss/common/awesomeplete.scss */\n.autocomplete {\n\tposition: relative;\n}\n\n.input-wrapper {\n\tborder: 1px solid transparent;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tmargin-right: 1ch;\n}\n\ninput {\n\twidth: calc(100% - 1ch);\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tpadding: 1ch 0.5ch 0.5ch 1ch;\n\tmargin: calc(1.15rem / 2) 0 0 0;\n\tmin-height: 1.15rem;\n\tborder-radius: 0.25rem;\n\tfont-family: var(--sc-font-family);\n}\n\ninput:focus {\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-radius: 0.25rem 0.25rem 0 0;\n\tborder-bottom: none;\n}\n\nlabel {\n\tdisplay: block;\n\tmin-height: 1.15rem;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tborder: 1px solid transparent;\n\tmargin-bottom: 0.25rem;\n\tz-index: 0;\n\tfont-size: 80%;\n\tposition: absolute;\n\tbackground: white;\n\tmargin: calc(-1.5rem - calc(2.15rem / 2)) 0 0 1ch;\n\tpadding: 0 0.25ch 0 0.25ch;\n}\n\n.autocomplete-results {\n\tposition: absolute;\n\twidth: calc(100% - 1ch + 1.5px);\n\tz-index: 100;\n\tpadding: 0;\n\tmargin: 0;\n\tcolor: var(--sc-input-active-border-color);\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-radius: 0 0 0.25rem 0.25rem;\n\tborder-top: none;\n\tbackground-color: #fff;\n}\n\n.autocomplete-result {\n\tlist-style: none;\n\ttext-align: left;\n\tpadding: 4px 6px;\n\tcursor: pointer;\n\tborder-bottom: 0.5px solid lightgray;\n}\n\n.autocomplete-result.is-active,\n.autocomplete-result:hover {\n\tbackground-color: var(--sc-row-color-zebra-light);\n\tcolor: var(--sc-input-active-border-color);\n}\n\n/* Keep the field error in-flow below the control. The shared .aform_error is absolutely\n positioned against a .aform_form-element anchor, which this component does not use. */\np.aform_error {\n\tposition: static;\n\tdisplay: block;\n\tcolor: var(--sc-brand-danger, red);\n\tfont-size: 0.7rem;\n\tmargin: 0.25rem 0 0;\n}\n</style>\n","<template>\n\t<div class=\"aduration\">\n\t\t<template v-if=\"mode === 'display' || mode === 'read'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayValue }}</span>\n\t\t\t<label>{{ label }}</label>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<ADateSelection\n\t\t\t\tref=\"selectionRef\"\n\t\t\t\t:select-range=\"true\"\n\t\t\t\t:show-time=\"true\"\n\t\t\t\t:show-end-time=\"true\"\n\t\t\t\t:allow-military-time=\"allowMilitaryTime\"\n\t\t\t\t:use-seconds=\"useSeconds\"\n\t\t\t\t@get-range=\"handleRange\" />\n\t\t\t<div class=\"aduration__footer\">\n\t\t\t\t<label>{{ label }}</label>\n\t\t\t\t<div v-if=\"startDatetime && endDatetime\" class=\"aduration__summary\">\n\t\t\t\t\t<span class=\"aduration__label\">Duration:</span>\n\t\t\t\t\t<span class=\"aduration__value\">{{ humanDuration }}</span>\n\t\t\t\t\t<span class=\"aduration__ms\">({{ modelValue ?? 0 }} ms)</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue'\nimport ADateSelection from './ADateSelection.vue'\n\nconst {\n\tlabel = 'Duration',\n\tmode = 'edit',\n\tallowMilitaryTime = false,\n\tuseSeconds = false,\n} = defineProps<{\n\tlabel?: string\n\tmode?: string\n\tallowMilitaryTime?: boolean\n\tuseSeconds?: boolean\n}>()\n\nconst modelValue = defineModel<number>()\n\nconst startDatetime = ref<Date | null>(null)\nconst endDatetime = ref<Date | null>(null)\n\nconst duration = computed<number>(() => {\n\tif (!startDatetime.value || !endDatetime.value) return 0\n\tconst ms = endDatetime.value.getTime() - startDatetime.value.getTime()\n\treturn ms > 0 ? ms : 0\n})\n\nwatch(duration, newMs => {\n\tmodelValue.value = newMs\n})\n\nconst handleRange = (data: { start: Date; end: Date }) => {\n\tstartDatetime.value = data.start\n\tendDatetime.value = data.end\n\tmodelValue.value = duration.value\n}\n\nconst humanDuration = computed(() => {\n\tconst ms = duration.value\n\tif (ms === 0) return '0s'\n\tconst s = Math.floor(ms / 1000) % 60\n\tconst m = Math.floor(ms / 60000) % 60\n\tconst h = Math.floor(ms / 3600000) % 24\n\tconst d = Math.floor(ms / 86400000)\n\treturn [d && `${d}d`, h && `${h}h`, m && `${m}m`, s && `${s}s`].filter(Boolean).join(' ') || '0s'\n})\n\nconst displayValue = computed(() => {\n\tconst ms = modelValue.value\n\tif (!ms) return '—'\n\tconst s = Math.floor(ms / 1000) % 60\n\tconst m = Math.floor(ms / 60000) % 60\n\tconst h = Math.floor(ms / 3600000) % 24\n\tconst d = Math.floor(ms / 86400000)\n\treturn [d && `${d}d`, h && `${h}h`, m && `${m}m`, s && `${s}s`].filter(Boolean).join(' ') || '0s'\n})\n</script>\n\n<style scoped>\n.aduration {\n\tposition: relative;\n\tmin-width: 40ch;\n\twidth: 100%;\n}\n\n.aduration__summary {\n\tdisplay: flex;\n\tgap: 6px;\n\talign-items: baseline;\n\tmargin-top: 6px;\n\tfont-size: 0.9em;\n}\n\n.aduration__label {\n\tfont-weight: bold;\n\tcolor: var(--sc-input-active-label-color, #555);\n}\n\n.aduration__value {\n\tcolor: var(--sc-cell-text-color, #000);\n}\n\n.aduration__ms {\n\tcolor: var(--sc-gray-50, #888);\n\tfont-size: 0.85em;\n}\n\n.aduration__footer {\n\tmargin-top: 8px;\n}\n</style>\n","<template>\n\t<div class=\"adaterange\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayValue }}</span>\n\t\t\t<label>{{ label }}</label>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tclass=\"adate-input aform_input-field\"\n\t\t\t\ttype=\"text\"\n\t\t\t\t:value=\"rangeDisplay\"\n\t\t\t\tplaceholder=\"Select date range\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\treadonly\n\t\t\t\t@click=\"openPicker\" />\n\t\t\t<label :for=\"uuid\">{{ label }}</label>\n\n\t\t\t<p v-show=\"errorText\" v-html=\"errorText\"></p>\n\n\t\t\t<ADateSelection\n\t\t\t\tv-if=\"showPicker\"\n\t\t\t\tref=\"pickerRef\"\n\t\t\t\tclass=\"picker\"\n\t\t\t\t:select-range=\"true\"\n\t\t\t\t:show-time=\"false\"\n\t\t\t\t@get-date=\"handlePickerDate\" />\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue'\nimport { onClickOutside } from '@vueuse/core'\nimport ADateSelection from './ADateSelection.vue'\nimport type { ComponentProps } from '../../types'\n\nconst fmt = (d: string) => new Date(d).toLocaleDateString()\n\nconst { label = 'Date Range', mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nexport interface DateRangeValue {\n\tstart_date: string | null\n\tend_date: string | null\n}\n\nconst modelValue = defineModel<DateRangeValue>({\n\tdefault: () => ({ start_date: null, end_date: null }),\n})\n\nconst startDate = ref<Date | null>(modelValue.value.start_date ? new Date(modelValue.value.start_date) : null)\nconst endDate = ref<Date | null>(modelValue.value.end_date ? new Date(modelValue.value.end_date) : null)\n\nconst showPicker = ref(false)\nconst pickerRef = ref(null)\nonClickOutside(pickerRef, () => (showPicker.value = false))\n\nconst openPicker = () => {\n\tif (mode !== 'read') showPicker.value = true\n}\n\nconst formatDate = (d: Date | null): string => {\n\tif (!d) return ''\n\treturn `${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()}`\n}\n\nconst rangeDisplay = computed(() => {\n\tconst s = formatDate(startDate.value)\n\tconst e = formatDate(endDate.value)\n\tif (s && e) return `${s} — ${e}`\n\tif (s) return `${s} — ...`\n\treturn ''\n})\n\nconst displayValue = computed(() => {\n\tconst s = modelValue.value.start_date\n\tconst e = modelValue.value.end_date\n\tif (!s && !e) return ''\n\tif (s && e) return `${fmt(s)} — ${fmt(e)}`\n\tif (s) return `From ${fmt(s)}`\n\treturn `Until ${fmt(e!)}`\n})\n\nconst ensureOrder = () => {\n\tconst s = startDate.value\n\tconst e = endDate.value\n\tif (s && e && e.getTime() < s.getTime()) {\n\t\t;[startDate.value, endDate.value] = [e, s]\n\t}\n}\n\nconst toISODate = (d: Date | null): string | null => (d ? d.toISOString().split('T')[0] : null)\n\nconst emitModel = () => {\n\tmodelValue.value = {\n\t\tstart_date: toISODate(startDate.value),\n\t\tend_date: toISODate(endDate.value),\n\t}\n}\n\nconst handlePickerDate = (data: { selected: Date; start?: Date | null; end?: Date | null }) => {\n\tif (data.start) startDate.value = data.start\n\tif (data.end) {\n\t\tendDate.value = data.end\n\t\tensureOrder()\n\t\tshowPicker.value = false\n\t}\n\temitModel()\n}\n\nwatch(\n\t() => modelValue.value,\n\tnewVal => {\n\t\tstartDate.value = newVal.start_date ? new Date(newVal.start_date) : null\n\t\tendDate.value = newVal.end_date ? new Date(newVal.end_date) : null\n\t},\n\t{ deep: true }\n)\n</script>\n\n<style scoped>\n.adaterange {\n\tmin-width: 40ch;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tborder: 1px solid transparent;\n\tpadding: 0;\n\tmargin: 0;\n\tmargin-right: 1ch;\n\tposition: relative;\n\toverflow: visible;\n}\n\n.adate-input {\n\twidth: calc(100% - 1ch);\n\tbox-sizing: border-box;\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tpadding: 1ch 0.5ch 0.5ch 1ch;\n\tmargin: calc(1.15rem / 2) 0 0 0;\n\tmin-height: 1.15rem;\n\tborder-radius: 0.25rem;\n\tcursor: pointer;\n\tbackground: white;\n\tfont-size: 1rem;\n}\n\n.adate-input:focus {\n\tborder: 1px solid var(--sc-input-active-border-color);\n}\n\n.adate-input:focus + label {\n\tcolor: var(--sc-input-active-label-color);\n}\n\np,\nlabel {\n\tcolor: var(--sc-input-label-color);\n\tdisplay: block;\n\tmin-height: 1.15rem;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 1px solid transparent;\n\tmargin-bottom: 0.25rem;\n\tbox-sizing: border-box;\n}\n\np {\n\twidth: 100%;\n\tcolor: red;\n\tfont-size: 85%;\n}\n\nlabel {\n\tz-index: 0;\n\tfont-size: 80%;\n\tposition: absolute;\n\tbackground: white;\n\tmargin: calc(-1.5rem - calc(2.15rem / 2)) 0 0 1ch;\n\tpadding: 0 0.25ch 0 0.25ch;\n\tbox-sizing: border-box;\n}\n\n.picker {\n\tposition: absolute;\n\ttop: 50px;\n\tleft: 0;\n\tz-index: 1000;\n}\n</style>\n","<template>\n\t<form class=\"aform\">\n\t\t<template v-for=\"(componentObj, key) in schema\" :key=\"key\">\n\t\t\t<!-- Nested schema field (Doctype or any field with resolved schema) -->\n\t\t\t<div v-if=\"isNestedSection(componentObj)\" class=\"aform-nested-section\">\n\t\t\t\t<!-- Suppress h4 for fieldsets — they render their own legend inside AFieldset -->\n\t\t\t\t<h4 v-if=\"componentObj.label && componentObj.kind !== 'fieldset'\" class=\"aform-nested-label\">\n\t\t\t\t\t{{ componentObj.label }}\n\t\t\t\t</h4>\n\t\t\t\t<component\n\t\t\t\t\t:is=\"componentObj.component ?? 'AForm'\"\n\t\t\t\t\t:data=\"nestedData[componentObj.fieldname]\"\n\t\t\t\t\t:mode=\"resolvedMode(componentObj)\"\n\t\t\t\t\t:schema=\"componentObj.schema\"\n\t\t\t\t\t:label=\"componentObj.label\"\n\t\t\t\t\t:collapsible=\"componentObj.kind === 'fieldset' ? componentObj.collapsible : undefined\"\n\t\t\t\t\t:errors=\"errors\"\n\t\t\t\t\t@update:data=\"(val: any) => updateNestedData(componentObj.fieldname, val)\" />\n\t\t\t</div>\n\n\t\t\t<!-- Regular field -->\n\t\t\t<component\n\t\t\t\t:is=\"componentObj.component\"\n\t\t\t\tv-else-if=\"!componentObj.hidden\"\n\t\t\t\tv-model=\"childModels[key].value\"\n\t\t\t\t:style=\"fieldStyle(componentObj)\"\n\t\t\t\t:schema=\"componentObj\"\n\t\t\t\t:data=\"dataModel[componentObj.fieldname]\"\n\t\t\t\t:mode=\"resolvedMode(componentObj)\"\n\t\t\t\t:errors=\"errors?.[componentObj.fieldname]\"\n\t\t\t\tv-bind=\"componentProps(componentObj)\">\n\t\t\t</component>\n\t\t</template>\n\t</form>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, watchEffect, watch, ref } from 'vue'\n\nimport type { ResolvedField, ResolvedLink, ResolvedFieldset } from '../types'\nimport type { InteractionMode } from '@stonecrop/schema'\n\nconst emit = defineEmits(['update:schema', 'update:data'])\nconst dataModel = defineModel<Record<string, any>>('data', { required: true })\nconst {\n\tschema,\n\tmode = 'edit',\n\terrors,\n} = defineProps<{\n\tschema: ResolvedField[]\n\tmode?: InteractionMode\n\t/** Inline validation errors keyed by fieldname. Fed by the host; the form stays store-agnostic. */\n\terrors?: Record<string, string[]>\n}>()\n\nconst isNestedSection = (componentObj: ResolvedField): componentObj is ResolvedLink | ResolvedFieldset =>\n\t(componentObj.kind === 'link' || componentObj.kind === 'fieldset') &&\n\t'schema' in componentObj &&\n\tArray.isArray(componentObj.schema) &&\n\tcomponentObj.schema.length > 0\n\n// Reactive nested data refs for two-way binding with nested AForm instances\nconst nestedData = ref<Record<string, any>>({})\n\n// Sync external dataModel changes into nestedData (one-way, no emit back).\n// Uses a shallow watch so only top-level object replacement (e.g. parent reset)\n// triggers a sync — property mutations from within are handled by updateNestedData.\nwatch(\n\t() => dataModel.value,\n\tnewData => {\n\t\tif (!schema || !newData) return\n\t\tschema.forEach(field => {\n\t\t\tif (isNestedSection(field)) {\n\t\t\t\tnestedData.value[field.fieldname] = newData[field.fieldname] ?? {}\n\t\t\t}\n\t\t})\n\t},\n\t{ immediate: true }\n)\n\n// Called by the nested <AForm>'s @update:data handler.\n// Updates nestedData locally and propagates upward in one step,\n// avoiding the watchEffect feedback loop that occurred with v-model.\nconst updateNestedData = (fieldname: string, val: any) => {\n\tnestedData.value[fieldname] = val\n\tif (dataModel.value) {\n\t\tdataModel.value[fieldname] = val\n\t\temit('update:data', { ...dataModel.value })\n\t}\n}\n\nconst componentProps = (componentObj: ResolvedField) => {\n\tconst propsToPass: Record<string, any> = {}\n\tfor (const [key, value] of Object.entries(componentObj)) {\n\t\t// 'mode' is excluded here because it is handled by resolvedMode()\n\t\t// and passed explicitly via :mode to avoid conflicting with the form-level defaults.\n\t\tif (!['component', 'primaryKey', 'computed', 'language', 'hidden', 'mode', 'width'].includes(key)) {\n\t\t\tpropsToPass[key] = value\n\t\t}\n\t}\n\n\t// A table sources its rows from the data model, never from the schema. `kind` is the only\n\t// check: every path into AForm sets it (Zod's injectKind, Doctype.fromObject's\n\t// normalizeFieldKind, and the registry), and hand-built ResolvedTable literals declare it.\n\tif (componentObj.kind === 'table') {\n\t\tpropsToPass['rows'] = dataModel.value[componentObj.fieldname] || []\n\t}\n\n\treturn propsToPass\n}\n\nconst fieldStyle = (componentObj: ResolvedField): Record<string, string> => {\n\tif (componentObj.kind !== 'field') return {}\n\tconst width = componentObj.width\n\tif (!width) return {}\n\treturn { flexBasis: width, width }\n}\n\nconst effectiveFormMode = computed(() => mode ?? 'edit')\n\n// Resolve the effective mode for a schema field, allowing per-field overrides\nfunction resolvedMode(componentObj: ResolvedField): InteractionMode {\n\tconst fieldMode = componentObj.mode\n\tif (fieldMode) return fieldMode\n\treturn effectiveFormMode.value\n}\n\n// Create stable computed refs array to avoid recreation on every access\nconst childModelsCache = ref<ReturnType<typeof computed>[]>([])\n\n// Watch for schema changes and update cache (avoiding side effects in computed)\nwatchEffect(() => {\n\tif (!schema) return\n\n\t// Recreate cache only if length changed\n\tif (childModelsCache.value.length !== schema.length) {\n\t\tchildModelsCache.value = schema.map((_val, i) => {\n\t\t\treturn computed({\n\t\t\t\tget() {\n\t\t\t\t\treturn dataModel.value?.[schema[i].fieldname]\n\t\t\t\t},\n\t\t\t\tset: newValue => {\n\t\t\t\t\tconst fieldname = schema[i].fieldname\n\t\t\t\t\tif (fieldname && dataModel.value) {\n\t\t\t\t\t\tdataModel.value[fieldname] = newValue\n\t\t\t\t\t\temit('update:data', { ...dataModel.value })\n\t\t\t\t\t}\n\t\t\t\t\temit('update:schema', schema)\n\t\t\t\t},\n\t\t\t})\n\t\t})\n\t}\n})\n\n// Computed just returns the cached models (no side effects)\nconst childModels = computed(() => childModelsCache.value)\n</script>\n\n<style>\n/* global styles for aform */\n.aform input {\n\tfont-family: var(--sc-font-family);\n\tborder: none;\n}\n.aform_form-element {\n\tpadding: 0;\n\tmargin: 0;\n\tposition: relative;\n\tbox-sizing: border-box;\n\tflex-grow: 1;\n\tmin-width: 20ch;\n\t/* margin-bottom: 1rem; */\n}\n.aform__grid--full {\n\tflex-basis: 100%;\n\twidth: 100%;\n}\n.aform_input-field {\n\toutline: 1px solid var(--sc-input-border-color);\n\toutline-offset: -1px;\n\tfont-size: 1rem;\n\tpadding: 0.5rem;\n\tmargin: 0 0 0 0;\n\tborder-radius: 0;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tmin-height: auto;\n\tposition: relative;\n\tcolor: var(--sc-cell-text-color);\n\tbackground: var(--sc-input-field-background);\n\tfont-family: var(--sc-font-family);\n}\n.aform_input-field:focus {\n\toutline: 1px solid var(--sc-input-active-border-color);\n}\n\n.aform_display-value {\n\tdisplay: block;\n\tpadding: 0.5rem;\n\tmin-height: 2rem;\n\tcolor: var(--sc-cell-text-color);\n\tword-break: break-word;\n}\n\n.aform_input-field:focus + .aform_field-label {\n\tcolor: var(--sc-input-active-label-color);\n}\n\n.aform_field-label {\n\tcolor: var(--sc-input-label-color);\n\tdisplay: inline-block;\n\tposition: absolute;\n\tpadding: 0 0.25rem;\n\tmargin: 0rem;\n\tz-index: 1;\n\tfont-size: 0.7rem;\n\tfont-weight: 300;\n\tletter-spacing: 0.05rem;\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-background) 50%);\n\twidth: auto;\n\tbox-sizing: border-box;\n\tbackground: white;\n\tmargin: 0;\n\tgrid-row: 1;\n\ttop: 0;\n\tleft: 10px;\n\tborder: none;\n\tline-height: 0;\n\ttransform: translateY(-50%);\n}\n.aform_input-field:disabled,\n.aform_checkbox-container:has(.aform_checkbox:disabled) {\n\tbackground: var(--sc-input-field-disabled-background);\n}\n.aform_input-field:disabled + .aform_field-label,\n.aform_checkbox-container:has(.aform_checkbox:disabled) + .aform_field-label {\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-disabled-background) 50%);\n}\n.aform_input-field:disabled ~ p.aform_error,\n.aform_checkbox-container:has(.aform_checkbox:disabled) ~ p.aform_error {\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-disabled-background) 50%);\n}\n.aform_field-label::after {\n\tmargin: 0;\n\tpadding: 0;\n\tbox-sizing: border-box;\n\tcontent: '';\n\tline-height: normal;\n}\np.aform_error {\n\t/* v-show toggles visibility per field; base display must be visible (was stuck at `none`,\n\t which overrode v-show and left every field error dormant). */\n\tdisplay: inline-block;\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-background) 50%);\n\tpadding: 0 0.25rem;\n\tmargin: 0rem;\n\twidth: auto;\n\tcolor: var(--sc-brand-danger);\n\tfont-size: 0.7rem;\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\tline-height: 0;\n\tbackground: white;\n\tpadding: 0.25rem;\n\ttransform: translate(-1rem, -50%);\n\tmargin: 0;\n}\n</style>\n\n<style scoped>\n.aform {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 1rem;\n\tpadding: 1rem;\n\tborder: 1px solid var(--sc-form-border);\n\tborder-left: 4px solid var(--sc-form-border);\n\tmargin-bottom: 1rem;\n\tmax-width: 100%;\n}\n@media screen and (max-width: 400px) {\n\t.aform {\n\t\tflex-direction: column;\n\t}\n}\n\n/* Nested form section */\n.aform-nested-section {\n\twidth: 100%;\n\tpadding: 0.5rem 0;\n}\n\n.aform-nested-label {\n\tfont-size: 0.9rem;\n\tfont-weight: 600;\n\tmargin: 0 0 0.5rem 0;\n\tcolor: var(--sc-input-label-color, #666);\n}\n\n.aform-nested-section .aform {\n\tborder-left-width: 2px;\n\tmargin-left: 0.5rem;\n}\n</style>\n","<template>\n\t<button class=\"collapse-button\" :class=\"collapsed ? 'rotated' : 'unrotated'\">×</button>\n</template>\n\n<script setup lang=\"ts\">\ndefineProps<{ collapsed: boolean }>()\n</script>\n\n<style scoped>\n.collapse-button {\n\twidth: 2ch;\n\tmin-width: calc(66px - 4ch);\n\tbackground-color: transparent;\n\tfont-size: 150%;\n\ttext-align: center;\n\tborder: none;\n\tmargin-top: -0.5rem;\n}\n.rotated {\n\ttransform: rotate(45deg);\n\t-webkit-transform: rotate(45deg);\n\t-moz-transform: rotate(45deg);\n\t-ms-transform: rotate(45deg);\n\t-o-transform: rotate(45deg);\n\ttransition: transform 250ms;\n\ttransform-origin: center center;\n}\n.unrotated {\n\ttransform: rotate(0deg);\n\t-webkit-transform: rotate(0deg);\n\t-moz-transform: rotate(0deg);\n\t-ms-transform: rotate(0deg);\n\t-o-transform: rotate(0deg);\n\ttransition: transform 250ms;\n}\n</style>\n","<template>\n\t<fieldset>\n\t\t<legend v-if=\"label || collapsible\" @click=\"toggleCollapse\" @submit=\"toggleCollapse\">\n\t\t\t{{ label }}\n\t\t\t<CollapseButton v-if=\"collapsible\" :collapsed=\"collapsed\" />\n\t\t</legend>\n\t\t<slot :collapsed=\"collapsed\">\n\t\t\t<AForm v-show=\"!collapsed\" v-model:data=\"formData\" :schema=\"formSchema\" :mode=\"mode\" />\n\t\t</slot>\n\t</fieldset>\n</template>\n\n<script setup lang=\"ts\">\nimport type { InteractionMode } from '@stonecrop/schema'\nimport { ref } from 'vue'\n\nimport AForm from '../AForm.vue'\nimport CollapseButton from '../base/CollapseButton.vue'\nimport type { ResolvedField } from '../../types'\n\nconst {\n\tschema,\n\tlabel = undefined,\n\tcollapsible,\n\tdata = {},\n\tmode = 'edit',\n} = defineProps<{\n\tschema: ResolvedField[]\n\tlabel?: string\n\tcollapsible?: boolean\n\tdata?: Record<string, any>\n\t/** Rendering mode forwarded to the inner AForm */\n\tmode?: InteractionMode\n}>()\n\nconst collapsed = ref(false)\nconst formData = ref(data || [])\nconst formSchema = ref(schema)\n\nconst toggleCollapse = (event: Event) => {\n\tevent.preventDefault()\n\tif (collapsible) {\n\t\tcollapsed.value = !collapsed.value\n\t}\n}\n\ndefineExpose({ collapsed })\n</script>\n\n<style scoped>\nfieldset {\n\tmax-width: 100%;\n\twidth: 100%;\n\tmargin-right: 2ch;\n\tborder: 1px solid transparent;\n\tborder-bottom: 1px solid var(--sc-gray-50);\n}\n\nlegend {\n\twidth: 100%;\n\theight: 1.15rem;\n\tborder: 1px solid transparent;\n\tpadding-bottom: 0.5rem;\n\tfont-size: 110%;\n\tfont-weight: 600;\n\tuser-select: none;\n}\n\n.collapse-button {\n\tfloat: right;\n}\n</style>\n","<template>\n\t<div class=\"aform_form-element aform_file-attach aform__grid--full\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<template v-if=\"files\">\n\t\t\t\t<div class=\"aform_file-attach-feedback\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<b>{{ fileLengthText }}</b>\n\t\t\t\t\t</p>\n\t\t\t\t\t<li v-for=\"file of files\" :key=\"file.name\">{{ file.name }}</li>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t\t<span v-else class=\"aform_display-value\">No file selected</span>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<template v-if=\"files\">\n\t\t\t\t<div class=\"aform_file-attach-feedback\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\tYou have selected: <b>{{ fileLengthText }}</b>\n\t\t\t\t\t</p>\n\t\t\t\t\t<li v-for=\"file of files\" :key=\"file.name\">\n\t\t\t\t\t\t{{ file.name }}\n\t\t\t\t\t</li>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t\t<button type=\"button\" class=\"aform_form-btn\" :disabled=\"mode === 'read'\" @click=\"open()\">\n\t\t\t\t{{ label }}\n\t\t\t</button>\n\t\t\t<button type=\"button\" :disabled=\"!files || mode === 'read'\" class=\"aform_form-btn\" @click=\"reset()\">Reset</button>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useFileDialog } from '@vueuse/core'\nimport { computed } from 'vue'\n\nimport type { ComponentProps } from '../../types'\n\nconst { label, mode } = defineProps<ComponentProps>()\nconst { files, open, reset, onChange } = useFileDialog()\n\nconst fileLengthText = computed(() => {\n\tconst count = files.value?.length ?? 0\n\treturn `${count} ${count === 1 ? 'file' : 'files'}`\n})\n\nonChange(changedFiles => changedFiles)\n</script>\n\n<style scoped>\n.aform_file-attach {\n\tpadding: 1rem;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 1rem;\n\tflex-direction: row;\n\tjustify-content: center;\n\talign-items: center;\n\tborder: 1px dashed var(--sc-input-border-color);\n\twidth: 100%;\n}\n\n@media screen and (max-width: 400px) {\n\t.aform_file-attach > .aform_form-btn {\n\t\twidth: 100%;\n\t}\n}\n\n.aform_file-attach-feedback {\n\tcolor: var(--sc-input-label-color);\n\twidth: 100%;\n\tpadding: 0.5rem;\n\ttext-align: center;\n\talign-self: center;\n\n\t& > li {\n\t\tlist-style: none;\n\t\tfont-style: italic;\n\t}\n\t& > p {\n\t\tmargin-top: 0;\n\t}\n}\n\n.aform_form-btn {\n\tpadding: 0.5rem 2rem;\n\twidth: auto;\n\tborder: 1px solid var(--sc-input-border-color);\n\tcolor: var(--sc-input-label-color);\n\tcursor: pointer;\n\tbackground-color: white;\n}\n\n.aform_form-btn:disabled {\n\tbackground-color: var(--sc-gray-5);\n}\n</style>\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ inputNumber ?? '' }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tv-model=\"inputNumber\"\n\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\ttype=\"number\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:required=\"required\" />\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { ComponentProps } from '../../types'\n\nconst { label, required, mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst inputNumber = defineModel<number>()\n</script>\n","<template>\n\t<div class=\"aform_form-element aquantity\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayText }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<div class=\"aquantity__row\">\n\t\t\t\t<div class=\"aquantity__field aquantity__field--qty\">\n\t\t\t\t\t<div class=\"aquantity__group\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t:id=\"uuid\"\n\t\t\t\t\t\t\tv-model.number=\"qty\"\n\t\t\t\t\t\t\tclass=\"aquantity__qty\"\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t\t@keydown=\"onQtyKeydown\"\n\t\t\t\t\t\t\t@paste=\"onQtyPaste\" />\n\t\t\t\t\t\t<div v-on-click-outside=\"closeDropdown\" class=\"aquantity__uom\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t:id=\"`${uuid}-uom`\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"aquantity__uom-toggle\"\n\t\t\t\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\t\t\t\t:aria-expanded=\"dropdown.open\"\n\t\t\t\t\t\t\t\t:aria-activedescendant=\"\n\t\t\t\t\t\t\t\t\tdropdown.open && dropdown.activeIndex >= 0 ? `${uuid}-uom-opt-${dropdown.activeIndex}` : undefined\n\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t@click=\"toggleDropdown\"\n\t\t\t\t\t\t\t\t@keydown.down.prevent=\"moveActive(1)\"\n\t\t\t\t\t\t\t\t@keydown.up.prevent=\"moveActive(-1)\"\n\t\t\t\t\t\t\t\t@keydown.enter.prevent=\"selectActive\"\n\t\t\t\t\t\t\t\t@keydown.esc=\"closeDropdown\">\n\t\t\t\t\t\t\t\t<span class=\"aquantity__uom-value\">{{ uom || uomLabel }}</span>\n\t\t\t\t\t\t\t\t<span class=\"aquantity__caret\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<ul v-show=\"dropdown.open\" class=\"aquantity__uom-menu\" role=\"listbox\" :aria-label=\"uomLabel\">\n\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\tv-for=\"(option, i) in uoms\"\n\t\t\t\t\t\t\t\t\t:id=\"`${uuid}-uom-opt-${i}`\"\n\t\t\t\t\t\t\t\t\t:key=\"option\"\n\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\t:aria-selected=\"option === uom\"\n\t\t\t\t\t\t\t\t\tclass=\"aquantity__uom-option\"\n\t\t\t\t\t\t\t\t\t:class=\"{ 'is-active': i === dropdown.activeIndex }\"\n\t\t\t\t\t\t\t\t\t@mouseenter=\"dropdown.activeIndex = i\"\n\t\t\t\t\t\t\t\t\t@click=\"selectUom(option)\">\n\t\t\t\t\t\t\t\t\t{{ option }}\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"aquantity__row aquantity__row--stock\">\n\t\t\t\t<div class=\"aquantity__field aquantity__field--stock-uom\">\n\t\t\t\t\t<input :value=\"modelValue.stockUom\" class=\"aform_input-field aquantity__stock-field\" type=\"text\" disabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ stockUomLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"aquantity__field aquantity__field--stock-qty\">\n\t\t\t\t\t<input :value=\"modelValue.stockQty\" class=\"aform_input-field aquantity__stock-field\" type=\"number\" disabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ stockQtyLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"aquantity__field aquantity__field--conversion\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:value=\"modelValue.conversionFactor\"\n\t\t\t\t\t\tclass=\"aform_input-field aquantity__stock-field\"\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tdisabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ conversionFactorLabel }}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<p v-show=\"validation.errorMessage\" class=\"aform_error\" v-html=\"validation.errorMessage\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { vOnClickOutside } from '@vueuse/components'\nimport { computed, reactive } from 'vue'\n\nimport type { ComponentProps, QuantityOptions, QuantityValue } from '../../types'\n\nconst {\n\tlabel,\n\trequired,\n\tmode,\n\tuuid,\n\tvalidation = { errorMessage: '&nbsp;' },\n\toptions = {},\n\tuomLabel = 'UOM',\n\tstockUomLabel = 'Stock UOM',\n\tstockQtyLabel = 'Stock Qty',\n\tconversionFactorLabel = 'Conversion Factor',\n} = defineProps<\n\tComponentProps & {\n\t\toptions?: QuantityOptions\n\t\tuomLabel?: string\n\t\tstockUomLabel?: string\n\t\tstockQtyLabel?: string\n\t\tconversionFactorLabel?: string\n\t}\n>()\n\nconst modelValue = defineModel<QuantityValue>({\n\tdefault: () => ({ qty: 0, uom: '', stockQty: 0, stockUom: '', conversionFactor: 1 }),\n})\n\nconst uoms = computed(() => options.uoms ?? [])\n\n// Round to shed binary floating-point noise (e.g. 0.1 * 3 → 0.30000000000000004) while\n// preserving any legitimate decimal places.\nconst roundQty = (value: number): number => Number(value.toFixed(6))\n\nconst resolveConversionFactor = (uom: string): number => {\n\tconst stockUom = options.stockUom ?? modelValue.value.stockUom\n\tif (!uom || uom === stockUom) return 1\n\tconst mapped = options.conversionFactors?.[uom]\n\tif (mapped !== undefined) return mapped\n\t// UOM absent from the conversion map: keep the stored factor only when the unit is\n\t// unchanged (e.g. editing qty on a loaded value, so the factor round-trips). Switching\n\t// to a new, unmapped unit resets to 1 rather than silently reusing the previous factor.\n\tif (uom === modelValue.value.uom) return modelValue.value.conversionFactor ?? 1\n\treturn 1\n}\n\nconst recompute = (qty: number, uom: string) => {\n\tconst conversionFactor = resolveConversionFactor(uom)\n\tmodelValue.value = {\n\t\tqty,\n\t\tuom,\n\t\tconversionFactor,\n\t\tstockUom: options.stockUom ?? modelValue.value.stockUom,\n\t\tstockQty: roundQty(qty * conversionFactor),\n\t}\n}\n\nconst qty = computed({\n\tget: () => modelValue.value?.qty ?? 0,\n\tset: (value: number) => recompute(value, modelValue.value?.uom ?? ''),\n})\n\nconst uom = computed({\n\tget: () => modelValue.value?.uom ?? '',\n\tset: (value: string) => recompute(modelValue.value?.qty ?? 0, value),\n})\n\nconst qtyNavigationKeys = new Set([\n\t'Backspace',\n\t'Delete',\n\t'Tab',\n\t'Escape',\n\t'Enter',\n\t'ArrowLeft',\n\t'ArrowRight',\n\t'ArrowUp',\n\t'ArrowDown',\n\t'Home',\n\t'End',\n])\n\nconst onQtyKeydown = (event: KeyboardEvent) => {\n\tif (event.ctrlKey || event.metaKey || event.altKey) return\n\tif (qtyNavigationKeys.has(event.key)) return\n\tif (/^[0-9]$/.test(event.key)) return\n\tconst input = event.target as HTMLInputElement\n\tif (event.key === '.' && !input.value.includes('.')) return\n\tevent.preventDefault()\n}\n\nconst onQtyPaste = (event: ClipboardEvent) => {\n\tconst pasted = event.clipboardData?.getData('text') ?? ''\n\tif (!/^\\d*\\.?\\d*$/.test(pasted)) event.preventDefault()\n}\n\nconst dropdown = reactive({ open: false, activeIndex: -1 })\n\nconst openDropdown = () => {\n\tdropdown.activeIndex = Math.max(uoms.value.indexOf(uom.value), 0)\n\tdropdown.open = true\n}\n\nconst closeDropdown = () => {\n\tdropdown.open = false\n}\n\nconst toggleDropdown = () => {\n\tif (dropdown.open) closeDropdown()\n\telse openDropdown()\n}\n\nconst selectUom = (value: string) => {\n\tuom.value = value\n\tcloseDropdown()\n}\n\nconst moveActive = (delta: number) => {\n\tif (!dropdown.open) {\n\t\topenDropdown()\n\t\treturn\n\t}\n\tconst length = uoms.value.length\n\tif (!length) return\n\tdropdown.activeIndex = (dropdown.activeIndex + delta + length) % length\n}\n\nconst selectActive = () => {\n\tif (!dropdown.open) {\n\t\topenDropdown()\n\t\treturn\n\t}\n\tconst option = uoms.value[dropdown.activeIndex]\n\tif (option !== undefined) selectUom(option)\n}\n\nconst showStock = computed(() => {\n\tconst v = modelValue.value\n\treturn !!v?.stockUom && (v.uom !== v.stockUom || v.qty !== v.stockQty)\n})\n\nconst displayText = computed(() => {\n\tconst v = modelValue.value\n\tif (!v || !v.uom) return '—'\n\tconst base = `${v.qty} ${v.uom}`\n\treturn showStock.value ? `${base} (${v.stockQty} ${v.stockUom})` : base\n})\n</script>\n\n<style scoped>\n.aquantity__row {\n\tdisplay: flex;\n\tgap: 1ch;\n}\n\n.aquantity__row--stock {\n\tmargin-top: 1.5rem;\n}\n\n.aquantity__field {\n\tposition: relative;\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.aquantity__group {\n\tdisplay: flex;\n\talign-items: stretch;\n\twidth: 100%;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n}\n\n.aquantity__group:focus-within {\n\tborder-color: var(--sc-input-active-border-color);\n}\n\n.aquantity__qty {\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tpadding: 0.5ch 1ch;\n\tbackground: transparent;\n\tborder-radius: 0.25rem 0 0 0.25rem;\n\tappearance: textfield;\n\t-moz-appearance: textfield;\n}\n\n.aquantity__qty::-webkit-outer-spin-button,\n.aquantity__qty::-webkit-inner-spin-button {\n\tappearance: none;\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n\n.aquantity__uom {\n\tposition: relative;\n\tflex: 0 0 auto;\n\tborder-left: 1px solid var(--sc-input-border-color);\n}\n\n.aquantity__uom-toggle {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 0.75ch;\n\theight: 100%;\n\tpadding: 0.5ch 1ch;\n\tbackground: var(--sc-gray-5);\n\tborder: none;\n\tborder-radius: 0 0.25rem 0.25rem 0;\n\twhite-space: nowrap;\n\tcursor: pointer;\n}\n\n.aquantity__uom-toggle:disabled {\n\tcursor: not-allowed;\n\tcolor: var(--sc-gray-50, #888);\n}\n\n.aquantity__caret {\n\tdisplay: inline-block;\n\twidth: 0;\n\theight: 0;\n\tborder-left: 0.3em solid transparent;\n\tborder-right: 0.3em solid transparent;\n\tborder-top: 0.3em solid currentColor;\n}\n\n.aquantity__uom-menu {\n\tposition: absolute;\n\ttop: 100%;\n\tright: 0;\n\tz-index: 100;\n\tmin-width: 100%;\n\tmargin: 0.15rem 0 0 0;\n\tpadding: 0.25rem 0;\n\tlist-style: none;\n\tbackground: var(--sc-input-field-background, #fff);\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-radius: 0.25rem;\n}\n\n.aquantity__uom-option {\n\tpadding: 0.4ch 1ch;\n\twhite-space: nowrap;\n\tcursor: pointer;\n}\n\n.aquantity__uom-option.is-active,\n.aquantity__uom-option:hover {\n\tbackground-color: var(--sc-row-color-zebra-light);\n}\n\n.aquantity__stock-field {\n\twidth: 100%;\n\tfont-size: 1rem;\n\tpadding: 0.5ch 1ch;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n\toutline: none;\n}\n\n.aquantity__stock-field:disabled {\n\tcolor: var(--sc-gray-50, #888);\n}\n</style>\n","import type { DirectiveBinding } from 'vue'\n\nimport { deserializeFunction } from '../utils/deserialize'\n\n/**\n * Extracts a mask function from a stringified function\n * @param mask - Mask string\n * @returns Mask function, or undefined if the string is not a valid function expression\n */\nfunction extractMaskFn(mask: string): ((locale: any) => string) | undefined {\n\ttry {\n\t\treturn deserializeFunction<(locale: any) => string>(mask)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\n/**\n * Gets the mask for a given directive binding\n * @param binding - Binding object from directive hook\n * @returns Mask string\n */\nfunction getMask(binding: DirectiveBinding<string>) {\n\tconst mask = binding.value\n\tif (!mask) return undefined\n\n\tconst maskFn = extractMaskFn(mask)\n\tif (maskFn) {\n\t\t// TODO: (state) replace with state management;\n\t\t// pass the entire form/table data to the function\n\t\t// Vue directive reads arbitrary fields off host component instance; type is unknown at this layer.\n\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion\n\t\tconst instance = binding.instance as Record<string, unknown> | null | undefined\n\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion\n\t\tconst locale = instance?.['locale'] as string | undefined\n\t\treturn maskFn(locale)\n\t}\n\n\treturn mask\n}\n\n/**\n * Unmasks the input string\n * @param input - Input string\n * @param maskToken - Mask token character\n * @returns Unmasked input string\n */\nfunction unmaskInput(input: string, maskToken?: string) {\n\tif (!maskToken) {\n\t\tmaskToken = '#'\n\t}\n\n\tlet unmaskedInput = input\n\tconst maskChars = [maskToken, '/', '-', '(', ')', ' ']\n\n\tfor (const char of maskChars) {\n\t\tunmaskedInput = unmaskedInput.replaceAll(char, '')\n\t}\n\n\treturn unmaskedInput\n}\n\n/**\n * Fills the mask with the input string\n * @param input - Input string\n * @param mask - Mask string\n * @param maskToken - Mask token character\n * @returns Masked input string\n */\nfunction fillMask(input: string, mask: string, maskToken?: string) {\n\tif (!maskToken) {\n\t\tmaskToken = '#'\n\t}\n\n\tlet replacement = mask\n\tfor (const inputChar of input) {\n\t\tconst replaceIndex = replacement.indexOf(maskToken)\n\t\tif (replaceIndex !== -1) {\n\t\t\tconst prefix = replacement.substring(0, replaceIndex)\n\t\t\tconst suffix = replacement.substring(replaceIndex + 1)\n\t\t\treplacement = prefix + inputChar + suffix\n\t\t}\n\t}\n\n\treturn replacement.slice(0, mask.length)\n}\n\n/**\n * Applies a mask to an input element\n * @param el - Input element\n * @param binding - Binding object from directive hook\n * @returns void\n * @public\n */\nexport function useStringMask(el: HTMLInputElement, binding: DirectiveBinding<string>) {\n\tconst mask = getMask(binding)\n\tif (!mask) return\n\n\tconst maskToken = '#'\n\tconst inputText = el.value\n\n\t// process input value with mask\n\tconst unmaskedInput = unmaskInput(inputText, maskToken)\n\tif (unmaskedInput) {\n\t\tconst replacement = fillMask(unmaskedInput, mask, maskToken)\n\n\t\t// TODO: (state) this is very opinionated;\n\t\t// most likely fixed with state management;\n\t\t// a better way could be to emit back to instance;\n\n\t\t// Vue directive reads/writes arbitrary fields on host component instance.\n\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion\n\t\tconst instance = binding.instance as Record<string, unknown> | null | undefined\n\t\tif (instance?.['maskFilled']) {\n\t\t\tinstance['maskFilled'] = !replacement.includes(maskToken)\n\t\t}\n\n\t\tel.value = replacement\n\t} else {\n\t\tel.value = mask\n\t}\n}\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ inputText ?? '' }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tv-model=\"inputText\"\n\t\t\t\tv-mask=\"mask\"\n\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:maxlength=\"mask ? (maskFilled ? mask.length : undefined) : undefined\"\n\t\t\t\t:required=\"required\" />\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }} </label>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { /* inject, */ computed, ref } from 'vue'\n\nimport { useStringMask as vMask } from '../../directives/mask'\nimport { ComponentProps } from '../../types'\n\nconst { label, mask, required, mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\n// TODO: setup maskFilled as a computed property\nconst maskFilled = ref(true)\n\n// TODO: (state) replace with state management\n// const locale = inject<string>('locale', '')\n\nconst inputText = defineModel<number | string>()\n</script>\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value aform_textbox-display\">{{ inputText ?? '' }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<textarea\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tv-model=\"inputText\"\n\t\t\t\tclass=\"aform_input-field aform_textbox\"\n\t\t\t\t:placeholder=\"placeholder\"\n\t\t\t\t:rows=\"rows\"\n\t\t\t\t:maxlength=\"maxlength\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:required=\"required\"></textarea>\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { ComponentProps } from '../../types'\n\nconst {\n\tlabel,\n\trequired,\n\tmode,\n\tuuid,\n\terrors,\n\tplaceholder = '',\n\trows = 4,\n\tmaxlength,\n\tvalidation = { errorMessage: '' },\n} = defineProps<\n\tComponentProps & {\n\t\t/** Placeholder shown when the field is empty */\n\t\tplaceholder?: string\n\t\t/** Visible number of text lines (maps to the textarea `rows` attribute) */\n\t\trows?: number\n\t\t/** Maximum number of characters the field will accept */\n\t\tmaxlength?: number\n\t}\n>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst inputText = defineModel<string | null>()\n</script>\n\n<style scoped>\n.aform_textbox {\n\tresize: vertical;\n\tline-height: 1.5;\n\tmin-height: 4rem;\n\tfont-family: inherit;\n}\n\n.aform_textbox-display {\n\twhite-space: pre-wrap;\n}\n</style>\n","<template>\n\t<div class=\"login-container\">\n\t\t<div>\n\t\t\t<div class=\"account-container\">\n\t\t\t\t<div class=\"account-header\">\n\t\t\t\t\t<h1 id=\"account-title\">{{ headerTitle }}</h1>\n\t\t\t\t\t<p id=\"account-subtitle\">{{ headerSubtitle }}</p>\n\t\t\t\t</div>\n\n\t\t\t\t<form @submit=\"onSubmit\">\n\t\t\t\t\t<div class=\"login-form-container\">\n\t\t\t\t\t\t<div class=\"login-form-email aform_form-element\">\n\t\t\t\t\t\t\t<label id=\"login-email\" for=\"email\" class=\"aform_field-label\">Email</label>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tid=\"email\"\n\t\t\t\t\t\t\t\tv-model=\"email\"\n\t\t\t\t\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\t\t\t\t\tname=\"email\"\n\t\t\t\t\t\t\t\tplaceholder=\"name@example.com\"\n\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\tauto-capitalize=\"none\"\n\t\t\t\t\t\t\t\tauto-complete=\"email\"\n\t\t\t\t\t\t\t\tauto-correct=\"off\"\n\t\t\t\t\t\t\t\t:disabled=\"isLoading\" />\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"login-form-password aform_form-element\">\n\t\t\t\t\t\t\t<label id=\"login-password\" for=\"password\" class=\"aform_field-label\">Password</label>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tid=\"password\"\n\t\t\t\t\t\t\t\tv-model=\"password\"\n\t\t\t\t\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t:disabled=\"isLoading\" />\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button class=\"btn\" :disabled=\"isLoading || !email || !password\" @click=\"onSubmit\">\n\t\t\t\t\t\t\t<span v-if=\"isLoading\" class=\"material-symbols-outlined loading-icon\">progress_activity</span>\n\t\t\t\t\t\t\t<span id=\"login-form-button\">Login</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\n\t\t\t\t<button class=\"btn\">\n\t\t\t\t\t<span id=\"forgot-password-button\">Forgot password?</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\n\nconst { headerTitle = 'Login', headerSubtitle = 'Enter your email and password to login' } = defineProps<{\n\theaderTitle?: string\n\theaderSubtitle?: string\n}>()\n\nconst emit = defineEmits(['loginFailed', 'loginSuccess'])\n\nconst email = ref('')\nconst password = ref('')\n\nconst isLoading = ref(false)\nconst loginFailed = ref(false)\n\nfunction onSubmit(event: Event) {\n\tevent.preventDefault()\n\tisLoading.value = true\n\n\t// TODO: handle submit logic, handle failure\n\n\tif (loginFailed.value) {\n\t\tisLoading.value = false\n\t\temit('loginFailed')\n\t\treturn\n\t}\n\n\tisLoading.value = false\n\temit('loginSuccess')\n}\n</script>\n\n<style scoped>\n.login-container {\n\twidth: 100%;\n\tposition: relative;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-family: var(--sc-font-family);\n}\n\n.account-container {\n\twidth: 100%;\n\tmargin-left: auto;\n\tmargin-top: 0.5rem;\n\tmargin-right: auto;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n.account-header {\n\tdisplay: flex;\n\tflex-direction: column;\n\ttext-align: center;\n\tmargin-top: 0.5rem;\n}\n\n#account-title {\n\tfont-size: 1.5rem;\n\tline-height: 2rem;\n\tfont-weight: 600;\n\tletter-spacing: -0.025em;\n\tmargin: 0;\n}\n\n#account-subtitle {\n\tfont-size: 0.875rem;\n\tline-height: 1.25rem;\n\tmargin: 1rem;\n}\n\n.login-form-container {\n\tdisplay: grid;\n\tgap: 0.5rem;\n}\n\n.login-form-element {\n\tdisplay: grid;\n\tmargin: 0.5rem 0;\n\tposition: relative;\n}\n.login-field {\n\tpadding: 0.5rem 0.25rem 0.25rem 0.5rem;\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n\n\t&:focus {\n\t\tborder: 1px solid black;\n\t}\n}\n\n.btn {\n\tbackground-color: var(--sc-btn-color);\n\tcolor: var(--sc-btn-label-color);\n\tborder: 1px solid var(--sc-btn-border);\n\tmargin: 0.5rem 0;\n\tpadding: 0.25rem;\n\tposition: relative;\n\tcursor: pointer;\n\n\t&:hover {\n\t\tbackground-color: var(--sc-btn-hover);\n\t}\n\n\t&:disabled {\n\t\tbackground-color: var(--sc-input-field-disabled-background);\n\t}\n}\n.disabled {\n\topacity: 0.5;\n}\n.loading-icon {\n\tanimation: spin 1s linear infinite forwards;\n\tdisplay: inline-block;\n\tmargin-right: 0.2rem;\n\tline-height: 0;\n\tfont-size: 1rem;\n\tposition: relative;\n\ttop: 0.2rem;\n}\n\n/* ANIMATION */\n@keyframes spin {\n\tfrom {\n\t\ttransform: rotate(0deg);\n\t}\n\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n</style>\n","<template>\n\t<div class=\"aform-loading\">\n\t\t<div class=\"aform-loading__label\">\n\t\t\t<slot></slot>\n\t\t</div>\n\t\t<div class=\"aform-loading__bar\"></div>\n\t</div>\n</template>\n\n<style scoped>\n.aform-loading {\n\twidth: 100%;\n\tborder: 1px solid var(--sc-form-border);\n\tborder-left: 4px solid var(--sc-form-border);\n\tpadding: 1rem;\n\tmargin-bottom: 1rem;\n\tbox-sizing: border-box;\n\tposition: relative;\n\toverflow: hidden;\n\tbackground: var(--sc-input-field-background, #fff);\n}\n\n.aform-loading__label {\n\tfont-size: 0.9rem;\n\tcolor: var(--sc-cell-text-color);\n\tz-index: 1;\n\tposition: relative;\n}\n\n.aform-loading__label:not(:empty)::after {\n\tcontent: '...';\n\tanimation: ellipsis 2s infinite;\n}\n\n.aform-loading__bar {\n\twidth: 100%;\n\theight: 100%;\n\tposition: absolute;\n\tleft: -100%;\n\ttop: 0;\n\tbackground: linear-gradient(\n\t\t90deg,\n\t\trgba(var(--sc-table-loading-color), 0) 0%,\n\t\trgba(var(--sc-table-loading-color), 1) 50%,\n\t\trgba(var(--sc-table-loading-color), 0) 100%\n\t);\n\tanimation: bar-sweep 2s infinite;\n\tz-index: 0;\n}\n\n@keyframes bar-sweep {\n\t0% {\n\t\tleft: -100%;\n\t}\n\t100% {\n\t\tleft: 100%;\n\t}\n}\n\n@keyframes ellipsis {\n\t0%,\n\t20% {\n\t\tcontent: '';\n\t}\n\t40% {\n\t\tcontent: '.';\n\t}\n\t60% {\n\t\tcontent: '..';\n\t}\n\t80%,\n\t100% {\n\t\tcontent: '...';\n\t}\n}\n</style>\n","export type * from '@stonecrop/atable/types'\nexport { deserializeFunction } from './utils/deserialize'\nimport { install as installATable } from '@stonecrop/atable'\nimport type { App } from 'vue'\n\nimport ACheckbox from './components/form/ACheckbox.vue'\nimport ACurrencyInput from './components/form/ACurrencyInput.vue'\nimport ADate from './components/form/ADate.vue'\nimport ADropdown from './components/form/ADropdown.vue'\nimport ADatePicker from './components/form/ADatePicker.vue'\nimport ADateTime from './components/form/ADateTime.vue'\nimport ADateSelection from './components/form/ADateSelection.vue'\nimport ADuration from './components/form/ADuration.vue'\nimport ADateRange from './components/form/ADateRange.vue'\nimport AFieldset from './components/form/AFieldset.vue'\nimport AFileAttach from './components/form/AFileAttach.vue'\nimport AForm from './components/AForm.vue'\nimport AFormLink from './components/form/AFormLink.vue'\nimport ANumericInput from './components/form/ANumericInput.vue'\nimport AQuantityInput from './components/form/AQuantityInput.vue'\nimport ATextInput from './components/form/ATextInput.vue'\nimport ATextboxInput from './components/form/ATextboxInput.vue'\nimport Login from './components/utilities/Login.vue'\nimport AFormLoading from './components/AFormLoading.vue'\n\nexport type * from './types'\n\n/**\n * Install all AForm components\n * @param app - Vue app instance\n * @public\n */\nfunction install(app: App /* options */) {\n\tapp.use(installATable) // Install ATable components for use within AForm\n\n\tapp.component('ACheckbox', ACheckbox)\n\tapp.component('ACurrencyInput', ACurrencyInput)\n\tapp.component('ADate', ADate)\n\tapp.component('ADropdown', ADropdown)\n\tapp.component('ADatePicker', ADatePicker)\n\tapp.component('ADateTime', ADateTime)\n\tapp.component('ADateRange', ADateRange)\n\tapp.component('ADateSelection', ADateSelection)\n\tapp.component('AFieldset', AFieldset)\n\tapp.component('AFileAttach', AFileAttach)\n\tapp.component('AForm', AForm)\n\tapp.component('AFormLink', AFormLink)\n\tapp.component('ANumericInput', ANumericInput)\n\tapp.component('AQuantityInput', AQuantityInput)\n\tapp.component('ATextInput', ATextInput)\n\tapp.component('ATextboxInput', ATextboxInput)\n\tapp.component('ADuration', ADuration)\n\tapp.component('AFormLoading', AFormLoading)\n}\n\nexport {\n\tACheckbox,\n\tACurrencyInput,\n\tADate,\n\tADropdown,\n\tADatePicker,\n\tADateRange,\n\tADateSelection,\n\tADuration,\n\tADateTime,\n\tAFieldset,\n\tAFileAttach,\n\tAForm,\n\tAFormLink,\n\tANumericInput,\n\tAQuantityInput,\n\tATextInput,\n\tATextboxInput,\n\tLogin,\n\tAFormLoading,\n\tinstall,\n}\n"],"names":["deserializeFunction","source","errorText","computed","__props","checkbox","_useModel","_openBlock","_createElementBlock","_hoisted_1","_Fragment","_createElementVNode","_hoisted_2","_toDisplayString","_hoisted_3","_hoisted_4","_hoisted_5","$event","listboxId","useId","modelValue","hasValidId","id","displayedText","searchText","ref","dropdownOpen","loading","dropdownResults","activeIndex","navigator","inject","resolver","watch","value","match","displayText","r","resolved","handleNavigate","openDropdown","text","fn","closeDropdown","onClickOutside","onFocus","onInput","selectOption","option","selectNext","len","selectPrev","selectCurrent","_withDirectives","_hoisted_7","_renderList","i","_normalizeClass","_withModifiers","_renderSlot","_ctx","_createTextVNode","_hoisted_9","FLOAT_NOISE_DECIMALS","currencySymbol","normalizedBaseCurrency","base","resolvedBaseCurrency","baseCurrencyText","resolveExchangeRate","currencyId","baseId","baseDecimals","precision","roundAmount","recompute","amount","currencyValue","exchangeRate","currency","amountNavigationKeys","onAmountKeydown","event","input","onAmountPaste","pasted","showBase","v","currencyText","baseText","_hoisted_6","_createVNode","AFormLink","_withCtx","_hoisted_8","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_14","_hoisted_15","_hoisted_17","_hoisted_18","_hoisted_20","_vShow","numberOfRows","numberOfColumns","date","selectedDate","currentMonth","currentYear","currentDates","hoveredDate","start_date","end_date","startDateInput","useTemplateRef","endDateInput","emit","__emit","monthAndYear","getStartDate","parseDateToString","getEndDate","dateValue","validateDate","isTodaysDate","day","todaysDate","isSelectedDate","isStartDate","start","isEndDate","end","getCurrentCell","rowNo","colNo","isInDateRange","this_date","temp_end_date","getCurrentDate","hoverDate","currentIndex","populateMonth","firstOfMonth","monthStartWeekday","calendarStartDay","dayIndex","previousYear","nextYear","previousMonth","nextMonth","enterDate","enterInputDate","selectDate","emitData","testDateOrder","onMounted","nextTick","$selectedDate","$todaysDate","__expose","_cache","meridiemSelector","timeData","reactive","meridiem","emitTime","confirmTime","maxHours","minHours","hours","minutes","seconds","focusInput","target","tick","oldHours","changeMeridiem","prevHours","newRawHours","formatTime","newVal","oldVal","min","max","pasteInput","pasteAllFields","clipboardData","pastedData","timeUnits","_vModelText","provide","today","pickerStart","pickerEnd","startTimeMs","endTimeMs","mergeDateTime","timeMs","d","timePayloadToMs","payload","h","hrs","tryEmitRange","handleDate","data","handleStartTime","handleEndTime","_createBlock","ADatePicker","ADateTime","currentDate","inputDate","pickerRef","showPicker","newValue","ADateSelection","search","committedValue","dropdown","filter","filteredResults","filterResults","setResult","result","idx","item","selectNextResult","resultsLength","selectPrevResult","setCurrentResult","startDatetime","endDatetime","duration","ms","newMs","handleRange","humanDuration","s","m","displayValue","fmt","startDate","endDate","openPicker","formatDate","rangeDisplay","e","ensureOrder","toISODate","emitModel","handlePickerDate","dataModel","isNestedSection","componentObj","nestedData","newData","field","updateNestedData","fieldname","val","componentProps","propsToPass","key","fieldStyle","width","effectiveFormMode","resolvedMode","fieldMode","childModelsCache","watchEffect","_val","childModels","_resolveDynamicComponent","_mergeProps","collapsed","formData","formSchema","toggleCollapse","CollapseButton","AForm","files","open","reset","onChange","useFileDialog","fileLengthText","count","changedFiles","_unref","file","inputNumber","uoms","roundQty","resolveConversionFactor","uom","stockUom","mapped","qty","conversionFactor","qtyNavigationKeys","onQtyKeydown","onQtyPaste","toggleDropdown","selectUom","moveActive","delta","length","selectActive","showStock","_hoisted_13","_hoisted_21","_hoisted_23","extractMaskFn","mask","getMask","binding","maskFn","locale","unmaskInput","maskToken","unmaskedInput","maskChars","char","fillMask","replacement","inputChar","replaceIndex","prefix","suffix","useStringMask","el","inputText","instance","maskFilled","email","password","isLoading","loginFailed","onSubmit","install","app","installATable","ACheckbox","ACurrencyInput","ADate","ADropdown","ADateRange","AFieldset","AFileAttach","ANumericInput","AQuantityInput","ATextInput","ATextboxInput","ADuration","AFormLoading"],"mappings":"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"}
1
+ {"version":3,"file":"aform.js","sources":["../src/utils/deserialize.ts","../src/components/form/ACheckbox.vue","../src/components/form/AFormLink.vue","../src/components/form/ACurrencyInput.vue","../src/components/form/ADatePicker.vue","../src/components/form/ADateTime.vue","../src/components/form/ADateSelection.vue","../src/components/form/ADate.vue","../src/components/form/ADropdown.vue","../src/components/form/ADuration.vue","../src/components/form/ADateRange.vue","../src/components/AForm.vue","../src/components/base/CollapseButton.vue","../src/components/form/AFieldset.vue","../src/components/form/AFileAttach.vue","../src/components/form/ANumericInput.vue","../src/components/form/AQuantityInput.vue","../src/directives/mask.ts","../src/components/form/ATextInput.vue","../src/components/form/ATextboxInput.vue","../src/components/utilities/Login.vue","../src/components/AFormLoading.vue","../src/index.ts"],"sourcesContent":["/**\n * Deserializes a stringified function expression into a typed callable.\n *\n * Throws if the string cannot be parsed as a function (SyntaxError) or if the\n * resulting expression is not callable (TypeError), or if the expression references\n * an undefined variable (ReferenceError). Callers are responsible for try/catch.\n *\n * @example\n * ```ts\n * const fn = deserializeFunction<(x: number) => number>('(x) => x * 2')\n * fn(5) // 10\n * ```\n * @public\n */\n// T is intentionally a caller-supplied return type — this utility is unsafe by design (Function constructor).\n// oxlint-disable-next-line typescript/no-unnecessary-type-parameters\nexport function deserializeFunction<T extends (...args: any[]) => any>(source: string): T {\n\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion, typescript/no-implied-eval\n\treturn Function(`\"use strict\"; return (${source})`)() as T\n}\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t\t<span class=\"aform_display-value\">{{ checkbox ? '✓' : '✗' }}</span>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t<span class=\"aform_checkbox-container aform_input-field\">\n\t\t\t\t<input\n\t\t\t\t\t:id=\"uuid\"\n\t\t\t\t\tv-model=\"checkbox\"\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tclass=\"aform_checkbox\"\n\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t:required=\"required\" />\n\t\t\t</span>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, InputHTMLAttributes } from 'vue'\n\nimport { ComponentProps } from '../../types'\n\nconst { label, required, mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst checkbox = defineModel<InputHTMLAttributes['checked']>()\n</script>\n\n<style scoped>\n.aform_checkbox {\n\tcursor: pointer;\n\twidth: auto;\n\tmargin-top: 0;\n\tdisplay: block;\n}\n\n.aform_checkbox:checked {\n\taccent-color: var(--sc-primary-color);\n\tborder: 1px solid black;\n}\n\n.aform_checkbox-container {\n\twidth: 100%;\n\tdisplay: inline-block;\n\ttext-align: left;\n}\n\n.aform_checkbox-container input {\n\twidth: auto;\n}\n\n.aform_checkbox-container:hover + .aform_field-label {\n\tcolor: var(--sc-input-active-label-color);\n}\n</style>\n","<template>\n\t<div :class=\"['aform_form-element', { 'aform_form-element--embedded': embedded }]\">\n\t\t<span v-if=\"mode === 'display'\" class=\"aform_display-value\">{{ displayedText }}</span>\n\t\t<template v-else>\n\t\t\t<div v-on-click-outside=\"onClickOutside\" class=\"aform_form-link-wrapper\">\n\t\t\t\t<div class=\"input-group\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"searchText\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\t:class=\"['aform_input-field', { 'aform_input-field--embedded': embedded }]\"\n\t\t\t\t\t\t:placeholder=\"placeholder\"\n\t\t\t\t\t\t:aria-label=\"ariaLabel\"\n\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t:aria-expanded=\"dropdownOpen\"\n\t\t\t\t\t\t:aria-controls=\"dropdownOpen ? listboxId : undefined\"\n\t\t\t\t\t\t:aria-activedescendant=\"activeIndex === null ? undefined : `${listboxId}-opt-${activeIndex}`\"\n\t\t\t\t\t\t:disabled=\"disabled || mode === 'read'\"\n\t\t\t\t\t\t@input=\"onInput\"\n\t\t\t\t\t\t@focus=\"onFocus\"\n\t\t\t\t\t\t@keydown.down.prevent=\"selectNext\"\n\t\t\t\t\t\t@keydown.up.prevent=\"selectPrev\"\n\t\t\t\t\t\t@keydown.enter.prevent=\"selectCurrent\"\n\t\t\t\t\t\t@keydown.esc=\"closeDropdown\"\n\t\t\t\t\t\t@keydown.tab=\"closeDropdown\" />\n\t\t\t\t\t<button\n\t\t\t\t\t\tv-if=\"hasValidId && !disabled && !embedded\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"aform_form-btn\"\n\t\t\t\t\t\t@click=\"handleNavigate\"\n\t\t\t\t\t\t@keydown.enter.prevent=\"handleNavigate\">\n\t\t\t\t\t\t<span>{{ icon === 'chevron-right' ? '›' : '→' }}</span>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<ul v-if=\"dropdownOpen\" :id=\"listboxId\" class=\"autocomplete-results\" role=\"listbox\" :aria-label=\"ariaLabel\">\n\t\t\t\t\t<li v-if=\"loading\" class=\"autocomplete-result loading\">Loading…</li>\n\t\t\t\t\t<li\n\t\t\t\t\t\tv-for=\"(option, i) in dropdownResults\"\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:id=\"`${listboxId}-opt-${i}`\"\n\t\t\t\t\t\t:key=\"String(option.id)\"\n\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t:aria-selected=\"i === activeIndex\"\n\t\t\t\t\t\tclass=\"autocomplete-result\"\n\t\t\t\t\t\t:class=\"{ 'is-active': i === activeIndex }\"\n\t\t\t\t\t\t@mousedown.prevent=\"selectOption(option)\">\n\t\t\t\t\t\t<slot name=\"option\" :option=\"option\">{{ option.displayText ?? String(option.id) }}</slot>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t\t<label v-if=\"label && !embedded\" class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { vOnClickOutside } from '@vueuse/components'\nimport { computed, inject, ref, useId, watch } from 'vue'\n\nimport type { AFormLinkModelValue, AFormLinkNavigator, AFormLinkValue, ComponentProps } from '../../types'\nimport { deserializeFunction } from '../../utils/deserialize'\n\nconst {\n\tlabel,\n\tmode,\n\tuuid,\n\trequired,\n\tdoctype = undefined,\n\tformatter = undefined,\n\ticon = 'arrow-right',\n\tdisabled = false,\n\tfilterFunction = undefined,\n\tisAsync = false,\n\tembedded = false,\n\tplaceholder = undefined,\n\tariaLabel = undefined,\n} = defineProps<\n\tComponentProps & {\n\t\tdoctype?: string\n\t\tformatter?: (value: AFormLinkValue) => string\n\t\ticon?: 'arrow-right' | 'chevron-right'\n\t\tdisabled?: boolean\n\t\tfilterFunction?: string | ((search: string) => AFormLinkValue[] | Promise<AFormLinkValue[]>)\n\t\tisAsync?: boolean\n\t\t// Bare rendering for compositing into another component's own bordered container\n\t\t// (e.g. ACurrencyInput's merged amount+currency group): suppresses this component's\n\t\t// own outline/border and floating label so the parent supplies both exactly once.\n\t\tembedded?: boolean\n\t\tplaceholder?: string\n\t\t// Accessible name for the search input. Needed in `embedded` mode, where the visible\n\t\t// <label> is suppressed and a placeholder is not a dependable accessible name — it is\n\t\t// not exposed consistently across screen readers and vanishes once a value is picked.\n\t\tariaLabel?: string\n\t}\n>()\n\n// Ties the input to its listbox and to the active option (aria-controls / aria-activedescendant).\n// `uuid` is per-field when AForm supplies it; the fallback keeps the ids unique for a standalone\n// mount so two pickers on one page can't cross-wire their ARIA relationships.\nconst listboxId = `${uuid ?? `aform-link-${useId()}`}-listbox`\n\nconst modelValue = defineModel<AFormLinkModelValue>({ default: () => ({ id: '', displayText: '' }) })\n\nconst hasValidId = computed(() => linkId(modelValue.value) !== undefined)\n\nconst displayedText = computed(() => {\n\tconst id = linkId(modelValue.value)\n\tif (id === undefined) return '—'\n\tif (formatter) return formatter(asLinkValue(modelValue.value))\n\treturn linkDisplayText(modelValue.value) ?? id\n})\n\nconst searchText = ref(hasValidId.value ? displayedText.value : '')\nconst dropdownOpen = ref(false)\nconst loading = ref(false)\nconst dropdownResults = ref<AFormLinkValue[]>([])\nconst activeIndex = ref<number | null>(null)\n\nconst navigator = inject<AFormLinkNavigator | null>('aformLinkNavigator', null)\n\ntype FilterFn = (search: string) => AFormLinkValue[] | Promise<AFormLinkValue[]>\ntype ResolverFn = (doctype: string, id: string) => string | undefined | Promise<string | undefined>\nconst resolver = inject<ResolverFn | null>('aformLinkResolver', null)\n\n// A link's value arrives as a bare scalar as often as it does as an AFormLinkValue: a record\n// loaded from the DB carries the raw FK column, and a parent bound to that column coerces every\n// update it receives back to a scalar. So read the value through these three helpers rather than\n// reaching into `modelValue.value` directly.\n//\n// Rejected: normalizing on write — an immediate watch that replaced a scalar model with `{ id }`.\n// It survives only until the parent writes its scalar back, so it fixed a scalar passed once at\n// mount and nothing else, and it emitted an `update:modelValue` the user never made on every\n// mount of a scalar-valued link field.\nfunction linkId(value: AFormLinkModelValue | null | undefined): string | undefined {\n\tif (value == null) return undefined\n\tif (typeof value === 'string') return value === '' ? undefined : value\n\tif (typeof value === 'number') return String(value)\n\tconst id = value.id\n\tif (id === null || id === undefined || id === '') return undefined\n\treturn String(id)\n}\n\nfunction linkDisplayText(value: AFormLinkModelValue | null | undefined): string | undefined {\n\tif (value == null || typeof value !== 'object') return undefined\n\tconst text = value.displayText\n\treturn typeof text === 'string' || typeof text === 'number' ? String(text) : undefined\n}\n\nfunction asLinkValue(value: AFormLinkModelValue | null | undefined): AFormLinkValue {\n\tif (value != null && typeof value === 'object') return value\n\tconst id = linkId(value)\n\treturn id !== undefined ? { id } : { id: '' }\n}\n\n// When the id changes (including on first render), resolve its display text.\n// Tries filterFunction first (returns a list of candidates to search); falls back to the\n// injected resolver (a direct doctype+id lookup). Skips if displayText is already set.\nwatch(\n\t() => linkId(modelValue.value),\n\tasync id => {\n\t\tif (!id || linkDisplayText(modelValue.value)) return\n\t\ttry {\n\t\t\tlet match: AFormLinkValue | undefined\n\t\t\tlet displayText: string | undefined\n\t\t\tif (filterFunction) {\n\t\t\t\tconst fn: FilterFn =\n\t\t\t\t\ttypeof filterFunction === 'string' ? deserializeFunction<FilterFn>(filterFunction) : filterFunction\n\t\t\t\tconst results = await fn(String(id))\n\t\t\t\tmatch = results.find(r => String(r.id) === String(id))\n\t\t\t\tdisplayText = match?.displayText\n\t\t\t\tif (displayText === undefined) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[AFormLink] filterFunction returned no matching result for id \"${id}\". ` +\n\t\t\t\t\t\t\t`The function must return an item whose \\`id\\` exactly matches the search string.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else if (resolver && doctype) {\n\t\t\t\tdisplayText = (await resolver(doctype, id.toString())) ?? undefined\n\t\t\t}\n\t\t\tif (displayText) {\n\t\t\t\t// Merge the whole matched record, not just its display text — the extra properties\n\t\t\t\t// an AFormLinkValue carries are part of the value (ACurrencyInput's `symbol`, which\n\t\t\t\t// its formatter renders, is one). `id` is pinned to the value we already hold so a\n\t\t\t\t// loosely-typed match (1 vs '1') can't change the FK's type underneath the record.\n\t\t\t\tconst resolved: AFormLinkValue = { ...asLinkValue(modelValue.value), ...match, id, displayText }\n\t\t\t\t// Format for the same reason selectOption does: the input shows `formatter`'s output\n\t\t\t\t// everywhere else (initial render, blur), so assigning the raw displayText here would\n\t\t\t\t// make a value that arrived as a bare id render differently from the identical value\n\t\t\t\t// picked by hand — e.g. \"Euro\" instead of \"€\".\n\t\t\t\tsearchText.value = formatter ? formatter(resolved) : displayText\n\t\t\t\tmodelValue.value = resolved\n\t\t\t}\n\t\t} catch {\n\t\t\t// silent — fall back to showing the raw id\n\t\t}\n\t},\n\t{ immediate: true }\n)\n\nconst handleNavigate = () => {\n\tconst id = linkId(modelValue.value)\n\tif (navigator && doctype && id !== undefined) {\n\t\tnavigator.navigate(doctype, id)\n\t} else if (navigator && !doctype) {\n\t\tconsole.warn(\n\t\t\t`[AFormLink] Navigation requested but \\`doctype\\` prop is missing. ` +\n\t\t\t\t`Add \\`options\\` (or \\`doctype\\`) to the Link field definition to enable navigation.`\n\t\t)\n\t}\n}\n\nconst openDropdown = async (text: string) => {\n\tif (!filterFunction || mode === 'read') return\n\tactiveIndex.value = null\n\tdropdownOpen.value = true\n\tif (isAsync) loading.value = true\n\ttry {\n\t\tconst fn: FilterFn =\n\t\t\ttypeof filterFunction === 'string' ? deserializeFunction<FilterFn>(filterFunction) : filterFunction\n\t\tdropdownResults.value = (await fn(text)) ?? []\n\t} catch {\n\t\tdropdownResults.value = []\n\t} finally {\n\t\tloading.value = false\n\t}\n}\n\nconst closeDropdown = () => {\n\tdropdownOpen.value = false\n\tactiveIndex.value = null\n\tsearchText.value = hasValidId.value ? displayedText.value : ''\n}\n\nconst onClickOutside = () => {\n\tif (dropdownOpen.value) closeDropdown()\n}\n\nconst onFocus = () => openDropdown(searchText.value)\n\nconst onInput = () => openDropdown(searchText.value)\n\nconst selectOption = (option: AFormLinkValue) => {\n\tmodelValue.value = option\n\t// Format `option` directly rather than reading back displayedText/modelValue: under a real\n\t// two-way v-model (e.g. ACurrencyInput binding to a computed with a side-effecting setter),\n\t// modelValue.value still reflects the *prop* until the parent's update round-trips back,\n\t// so reading it synchronously here would show stale (pre-selection) text for a tick.\n\tsearchText.value = formatter ? formatter(option) : (option.displayText ?? String(option.id))\n\tdropdownOpen.value = false\n\tactiveIndex.value = null\n}\n\nconst selectNext = () => {\n\tconst len = dropdownResults.value.length\n\tif (!len) return\n\tactiveIndex.value = activeIndex.value === null ? 0 : (activeIndex.value + 1) % len\n}\n\nconst selectPrev = () => {\n\tconst len = dropdownResults.value.length\n\tif (!len) return\n\tif (activeIndex.value === null || activeIndex.value === 0) {\n\t\tactiveIndex.value = null\n\t} else {\n\t\tactiveIndex.value -= 1\n\t}\n}\n\nconst selectCurrent = () => {\n\tif (activeIndex.value !== null && dropdownResults.value[activeIndex.value]) {\n\t\tselectOption(dropdownResults.value[activeIndex.value])\n\t}\n}\n</script>\n\n<style scoped>\n.aform_form-link-wrapper {\n\tposition: relative;\n}\n\n.input-group {\n\tdisplay: flex;\n\talign-items: stretch;\n}\n\n.aform_input-field {\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.aform_form-element--embedded {\n\tmin-width: 0;\n\tflex-grow: 0;\n}\n\n/* Embedded mode: the host component's own container supplies the border, so this input\n goes borderless and inherits the host's padding scale instead of the standalone default. */\n.aform_input-field--embedded {\n\toutline: none;\n\tbackground: transparent;\n\tpadding: 0.5ch 1ch;\n}\n\n/* Only in embedded mode is the trigger deliberately narrower than its options (e.g. a currency\n symbol box): let the dropdown grow past it rather than truncate. Standalone pickers keep the\n dropdown flush with the input, so a long display text can't overhang a narrow form column. */\n.aform_form-element--embedded .autocomplete-results {\n\tmin-width: 100%;\n\twidth: max-content;\n}\n\n/* Give the button the same outline as the input, then slide it 2px left so the outlines\n overlap exactly at the join: input right outline sits at (input_right - 1px),\n button left outline also sits at (button_left + 1px) = (input_right - 2px + 1px) = same pixel. */\n.aform_form-btn {\n\tappearance: none;\n\tborder: none;\n\toutline: 1px solid var(--sc-input-border-color);\n\toutline-offset: -1px;\n\tmargin-left: -2px;\n\tbackground: var(--sc-input-field-background, white);\n\tpadding: 0 0.75rem;\n\tcursor: pointer;\n}\n\n.aform_form-btn:focus,\n.input-group:focus-within .aform_form-btn {\n\toutline-color: var(--sc-input-active-border-color);\n}\n\n.autocomplete-results {\n\tposition: absolute;\n\twidth: 100%;\n\tz-index: 100;\n\tpadding: 0;\n\tmargin: 0;\n\tlist-style: none;\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-top: none;\n\tborder-radius: 0 0 0.25rem 0.25rem;\n\tbackground: #fff;\n}\n\n.autocomplete-result {\n\tpadding: 4px 6px;\n\tcursor: pointer;\n\tborder-bottom: 0.5px solid lightgray;\n}\n\n.autocomplete-result.is-active,\n.autocomplete-result:hover {\n\tbackground-color: var(--sc-row-color-zebra-light);\n\tcolor: var(--sc-input-active-border-color);\n}\n</style>\n","<template>\n\t<div class=\"aform_form-element acurrency\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayText }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<div class=\"acurrency__row\">\n\t\t\t\t<div class=\"acurrency__field acurrency__field--amount\">\n\t\t\t\t\t<div class=\"acurrency__group\">\n\t\t\t\t\t\t<div class=\"acurrency__currency\">\n\t\t\t\t\t\t\t<AFormLink\n\t\t\t\t\t\t\t\tv-model=\"currency\"\n\t\t\t\t\t\t\t\t:mode=\"mode\"\n\t\t\t\t\t\t\t\tembedded\n\t\t\t\t\t\t\t\t:placeholder=\"currencyLabel\"\n\t\t\t\t\t\t\t\t:aria-label=\"currencyLabel\"\n\t\t\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t\t\t:formatter=\"currencySymbol\"\n\t\t\t\t\t\t\t\t:doctype=\"options.doctype\"\n\t\t\t\t\t\t\t\t:filter-function=\"options.filterFunction\"\n\t\t\t\t\t\t\t\t:is-async=\"options.isAsync\">\n\t\t\t\t\t\t\t\t<template #option=\"{ option }\"\n\t\t\t\t\t\t\t\t\t>{{ option.symbol ? `${option.symbol} — ` : '' }}{{ option.displayText ?? option.id }}</template\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t</AFormLink>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"acurrency__amount-wrap\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t:id=\"uuid\"\n\t\t\t\t\t\t\t\tv-model.number=\"amount\"\n\t\t\t\t\t\t\t\tclass=\"acurrency__amount\"\n\t\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t\t\t@keydown=\"onAmountKeydown\"\n\t\t\t\t\t\t\t\t@paste=\"onAmountPaste\" />\n\t\t\t\t\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"acurrency__row acurrency__row--base\">\n\t\t\t\t<div class=\"acurrency__field acurrency__field--base-currency\">\n\t\t\t\t\t<input :value=\"baseCurrencyText\" class=\"aform_input-field acurrency__base-field\" type=\"text\" disabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ baseCurrencyLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"acurrency__field acurrency__field--base-amount\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:value=\"modelValue.baseAmount\"\n\t\t\t\t\t\tclass=\"aform_input-field acurrency__base-field\"\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tdisabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ baseAmountLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"acurrency__field acurrency__field--exchange-rate\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:value=\"modelValue.exchangeRate\"\n\t\t\t\t\t\tclass=\"aform_input-field acurrency__base-field\"\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tdisabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ exchangeRateLabel }}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<p v-show=\"validation.errorMessage\" class=\"aform_error\" v-html=\"validation.errorMessage\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, inject, ref, watch } from 'vue'\n\nimport type { AFormLinkValue, ComponentProps, CurrencyOptions, CurrencyValue } from '../../types'\nimport AFormLink from './AFormLink.vue'\n\nconst {\n\tlabel,\n\trequired,\n\tmode,\n\tuuid,\n\tvalidation = { errorMessage: '&nbsp;' },\n\toptions = {},\n\tcurrencyLabel = 'Currency',\n\tbaseCurrencyLabel = 'Base Currency',\n\tbaseAmountLabel = 'Base Amount',\n\texchangeRateLabel = 'Exchange Rate',\n} = defineProps<\n\tComponentProps & {\n\t\toptions?: CurrencyOptions\n\t\tcurrencyLabel?: string\n\t\tbaseCurrencyLabel?: string\n\t\tbaseAmountLabel?: string\n\t\texchangeRateLabel?: string\n\t}\n>()\n\n// The merged currency prefix is compact by design, so it shows the symbol rather than the\n// full currency name once a value is picked — falls back gracefully when a currency record\n// (or the story/app data behind it) doesn't carry a `symbol`.\nconst currencySymbol = (value: AFormLinkValue): string => value.symbol ?? value.displayText ?? String(value.id)\n\nconst modelValue = defineModel<CurrencyValue>({\n\tdefault: () => ({\n\t\tamount: 0,\n\t\tcurrency: { id: '' },\n\t\tbaseAmount: 0,\n\t\tbaseCurrency: { id: '' },\n\t\texchangeRate: 1,\n\t}),\n})\n\n// The base currency is fixed configuration, not user-editable. It may be supplied as a bare id\n// (resolved to displayText below via the same `aformLinkResolver` injection AFormLink uses) or\n// as a full AFormLinkValue that already carries displayText.\nconst normalizedBaseCurrency = computed<AFormLinkValue>(() => {\n\tconst base = options.baseCurrency ?? modelValue.value?.baseCurrency\n\tif (!base) return { id: '' }\n\treturn typeof base === 'string' ? { id: base } : base\n})\n\ntype ResolverFn = (doctype: string, id: string) => string | undefined | Promise<string | undefined>\nconst resolver = inject<ResolverFn | null>('aformLinkResolver', null)\n\nconst resolvedBaseCurrency = ref<AFormLinkValue>(normalizedBaseCurrency.value)\n\nwatch(\n\tnormalizedBaseCurrency,\n\tasync base => {\n\t\tif (!base.id || base.displayText || !resolver || !options.doctype) {\n\t\t\tresolvedBaseCurrency.value = base\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst displayText = await resolver(options.doctype, String(base.id))\n\t\t\tresolvedBaseCurrency.value = displayText ? { ...base, displayText } : base\n\t\t} catch {\n\t\t\tresolvedBaseCurrency.value = base\n\t\t}\n\t},\n\t{ immediate: true }\n)\n\nconst baseCurrencyText = computed(() => {\n\tconst base = resolvedBaseCurrency.value\n\tif (!base?.id) return ''\n\treturn base.displayText ?? String(base.id)\n})\n\nconst resolveExchangeRate = (currencyId: string | number | undefined): number => {\n\tconst baseId = resolvedBaseCurrency.value.id\n\tif (!currencyId || String(currencyId) === String(baseId)) return 1\n\t// The rate the value was booked at wins for as long as the currency is unchanged. Rates are\n\t// time-varying in a way conversion factors are not (see AQuantityInput), so `exchangeRates`\n\t// carries *today's* rates: preferring it here would silently re-rate a stored line to the\n\t// current rate on any touch — including the write-back AFormLink does when it resolves the\n\t// currency's display text, i.e. on mere render.\n\tif (String(currencyId) === String(modelValue.value?.currency?.id)) {\n\t\treturn modelValue.value?.exchangeRate ?? options.exchangeRates?.[String(currencyId)] ?? 1\n\t}\n\t// Switching to a currency absent from the rate map resets to 1 rather than silently reusing\n\t// the outgoing currency's rate.\n\treturn options.exchangeRates?.[String(currencyId)] ?? 1\n}\n\n// Enough decimal places to shed floating-point noise from the multiplication (e.g. 4 * 1.1 → 4.4\n// rather than 4.4000000000000004) without discarding a digit the rate actually produced. Matches\n// AQuantityInput's roundQty.\nconst FLOAT_NOISE_DECIMALS = 6\n\n// How far to round the base amount is the *base currency's* business, and only the app knows what\n// that is — so it says so via `precision` (JPY carries 0 decimals, most currencies 2, KWD 3).\n// Unset stays deliberately loose rather than defaulting to 2: hard-rounding every currency to\n// cents destroys value outright, e.g. 50 IDR at 0.000063 rounds to a base amount of 0. A garbage\n// precision (non-integer, negative, or past toFixed's 100 ceiling) falls back rather than throwing\n// inside the setter and breaking the field.\nconst baseDecimals = computed(() => {\n\tconst { precision } = options\n\tif (precision === undefined) return FLOAT_NOISE_DECIMALS\n\treturn Number.isInteger(precision) && precision >= 0 && precision <= 100 ? precision : FLOAT_NOISE_DECIMALS\n})\n\nconst roundAmount = (value: number): number => Number(value.toFixed(baseDecimals.value))\n\nconst recompute = (amount: number, currencyValue: AFormLinkValue) => {\n\tconst exchangeRate = resolveExchangeRate(currencyValue.id)\n\tmodelValue.value = {\n\t\tamount,\n\t\tcurrency: currencyValue,\n\t\texchangeRate,\n\t\tbaseCurrency: resolvedBaseCurrency.value,\n\t\tbaseAmount: roundAmount(amount * exchangeRate),\n\t}\n}\n\nconst amount = computed({\n\tget: () => modelValue.value?.amount ?? 0,\n\tset: (value: number) => recompute(value, modelValue.value?.currency ?? { id: '' }),\n})\n\nconst currency = computed<AFormLinkValue>({\n\tget: () => modelValue.value?.currency ?? { id: '' },\n\tset: (value: AFormLinkValue) => recompute(modelValue.value?.amount ?? 0, value),\n})\n\nconst amountNavigationKeys = new Set([\n\t'Backspace',\n\t'Delete',\n\t'Tab',\n\t'Escape',\n\t'Enter',\n\t'ArrowLeft',\n\t'ArrowRight',\n\t'ArrowUp',\n\t'ArrowDown',\n\t'Home',\n\t'End',\n])\n\nconst onAmountKeydown = (event: KeyboardEvent) => {\n\tif (event.ctrlKey || event.metaKey || event.altKey) return\n\tif (amountNavigationKeys.has(event.key)) return\n\tif (/^[0-9]$/.test(event.key)) return\n\t// A currency amount is signed — credit notes, refunds and adjustments are negative.\n\t//\n\t// Both dedup checks below are best-effort: a `type=\"number\"` input reports `value` as `''`\n\t// whenever its content isn't a valid number, so mid-entry states like \"1.\" or \"-\" read as\n\t// empty and a second separator can slip through. The browser rejects the resulting value\n\t// anyway; this guard exists to stop the obviously-wrong keys (letters, 'e', '+'), not to be\n\t// the sole arbiter of well-formedness.\n\tconst input = event.target as HTMLInputElement\n\tif (event.key === '.' && !input.value.includes('.')) return\n\tif (event.key === '-' && !input.value.includes('-')) return\n\tevent.preventDefault()\n}\n\nconst onAmountPaste = (event: ClipboardEvent) => {\n\tconst pasted = event.clipboardData?.getData('text') ?? ''\n\tif (!/^-?\\d*\\.?\\d*$/.test(pasted)) event.preventDefault()\n}\n\nconst showBase = computed(() => {\n\tconst v = modelValue.value\n\treturn !!v?.baseCurrency?.id && (v.currency?.id !== v.baseCurrency?.id || v.amount !== v.baseAmount)\n})\n\nconst displayText = computed(() => {\n\tconst v = modelValue.value\n\tif (!v || !v.currency?.id) return '—'\n\tconst currencyText = v.currency.displayText ?? String(v.currency.id)\n\tconst base = `${v.amount} ${currencyText}`\n\tif (!showBase.value) return base\n\tconst baseText = v.baseCurrency.displayText ?? String(v.baseCurrency.id)\n\treturn `${base} (${v.baseAmount} ${baseText})`\n})\n</script>\n\n<style scoped>\n.acurrency__row {\n\tdisplay: flex;\n\tgap: 1ch;\n}\n\n.acurrency__row--base {\n\tmargin-top: 1.5rem;\n}\n\n.acurrency__field {\n\tposition: relative;\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.acurrency__group {\n\tdisplay: flex;\n\talign-items: stretch;\n\twidth: 100%;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n}\n\n.acurrency__group:focus-within {\n\tborder-color: var(--sc-input-active-border-color);\n}\n\n/* Wraps just the amount input so its floating label (`left: 10px` of the nearest\n `position: relative` ancestor, per .aform_field-label) anchors above the amount box\n specifically, not the group's outer left edge — which is now the currency prefix. */\n.acurrency__amount-wrap {\n\tposition: relative;\n\tflex: 1;\n\tmin-width: 0;\n}\n\n/* The amount label (\"Total\") is the primary label for the whole merged group — bumped up\n slightly from the shared .aform_field-label size so it reads as the group's main label. */\n.acurrency__amount-wrap .aform_field-label {\n\tfont-size: 0.85rem;\n}\n\n.acurrency__amount {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tborder: none;\n\toutline: none;\n\tpadding: 0.5ch 1ch;\n\tbackground: transparent;\n\tborder-radius: 0 0.25rem 0.25rem 0;\n\ttext-align: right;\n\tappearance: textfield;\n\t-moz-appearance: textfield;\n}\n\n.acurrency__amount::-webkit-outer-spin-button,\n.acurrency__amount::-webkit-inner-spin-button {\n\tappearance: none;\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n\n/* The currency picker reads as a simple prefix addon (like Bootstrap's \"$\" prepend) rather\n than an equal partner to the amount box: compact width (it shows a symbol once a value is\n picked, not the full name), tinted background, left-rounded to match the group's own\n corner so the tint doesn't overhang the border. The dropdown itself isn't bound by this\n width — see AFormLink's .autocomplete-results — so search results still show full names. */\n.acurrency__currency {\n\tposition: relative;\n\tflex: 0 0 auto;\n\tmin-width: 4.5rem;\n\tbackground: var(--sc-gray-5);\n\tborder-right: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem 0 0 0.25rem;\n}\n\n.acurrency__base-field {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tfont-size: 1rem;\n\tpadding: 0.5ch 1ch;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n\toutline: none;\n\tappearance: textfield;\n\t-moz-appearance: textfield;\n}\n\n.acurrency__base-field:disabled {\n\tcolor: var(--sc-gray-50, #888);\n}\n\n/* Base Amount and Exchange Rate are read-only — the number spinner offers nothing here. */\n.acurrency__base-field::-webkit-outer-spin-button,\n.acurrency__base-field::-webkit-inner-spin-button {\n\tappearance: none;\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n</style>\n","<template>\n\t<template v-if=\"mode === 'display' || mode === 'read'\">\n\t\t<span class=\"aform_display-value\">{{ date ? new Date(date).toLocaleDateString() : '' }}</span>\n\t\t<label v-if=\"label\">{{ label }}</label>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</template>\n\t<template v-else>\n\t\t<div ref=\"datepicker\" class=\"adatepicker\" tabindex=\"0\">\n\t\t\t<table @mousedown=\"preventCellSelection\">\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td id=\"previous-month-btn\" :tabindex=\"-1\" @click=\"previousMonth\">&lt;</td>\n\t\t\t\t\t\t<th colspan=\"5\" :tabindex=\"-1\">{{ monthAndYear }}</th>\n\t\t\t\t\t\t<td id=\"next-month-btn\" :tabindex=\"-1\" @click=\"nextMonth\">&gt;</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr v-if=\"selectRange\">\n\t\t\t\t\t\t<td colspan=\"7\">\n\t\t\t\t\t\t\t<div class=\"date-input\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\tref=\"start-date-input\"\n\t\t\t\t\t\t\t\t\t:value=\"getStartDate\"\n\t\t\t\t\t\t\t\t\tclass=\"date-input-start aform_input-field\"\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tplaceholder=\"start date\"\n\t\t\t\t\t\t\t\t\t@blur=\"enterInputDate()\"\n\t\t\t\t\t\t\t\t\t@keydown=\"enterDate\" />\n\t\t\t\t\t\t\t\t<div>-</div>\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\tref=\"end-date-input\"\n\t\t\t\t\t\t\t\t\t:value=\"getEndDate\"\n\t\t\t\t\t\t\t\t\tclass=\"date-input-end aform_input-field\"\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tplaceholder=\"end date\"\n\t\t\t\t\t\t\t\t\t@blur=\"enterInputDate()\"\n\t\t\t\t\t\t\t\t\t@keydown=\"enterDate\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<!-- {{ formattedDateRange }} -->\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr class=\"days-header\">\n\t\t\t\t\t\t<td>M</td>\n\t\t\t\t\t\t<td>T</td>\n\t\t\t\t\t\t<td>W</td>\n\t\t\t\t\t\t<td>T</td>\n\t\t\t\t\t\t<td>F</td>\n\t\t\t\t\t\t<td>S</td>\n\t\t\t\t\t\t<td>S</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr v-for=\"rowNo in numberOfRows\" :key=\"rowNo\">\n\t\t\t\t\t\t<!-- the 'ref' key is currently only used for test references -->\n\t\t\t\t\t\t<td\n\t\t\t\t\t\t\tv-for=\"colNo in numberOfColumns\"\n\t\t\t\t\t\t\tref=\"celldate\"\n\t\t\t\t\t\t\t:key=\"getCurrentCell(rowNo, colNo)\"\n\t\t\t\t\t\t\tclass=\"date-cell\"\n\t\t\t\t\t\t\t:contenteditable=\"false\"\n\t\t\t\t\t\t\t:spellcheck=\"false\"\n\t\t\t\t\t\t\t:tabindex=\"0\"\n\t\t\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t\t\ttodaysDate: isTodaysDate(getCurrentDate(rowNo, colNo)),\n\t\t\t\t\t\t\t\tselectedDate: isSelectedDate(getCurrentDate(rowNo, colNo)),\n\t\t\t\t\t\t\t\twithinRange: selectRange ? isInDateRange(getCurrentDate(rowNo, colNo)) : false,\n\t\t\t\t\t\t\t\tstartDate: selectRange ? isStartDate(getCurrentDate(rowNo, colNo)) : false,\n\t\t\t\t\t\t\t\tendDate: selectRange ? isEndDate(getCurrentDate(rowNo, colNo)) : false,\n\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t@click.prevent.stop=\"selectDate(getCurrentCell(rowNo, colNo))\"\n\t\t\t\t\t\t\t@keydown.enter=\"selectDate(getCurrentCell(rowNo, colNo))\"\n\t\t\t\t\t\t\t@mouseover=\"hoverDate(getCurrentCell(rowNo, colNo))\">\n\t\t\t\t\t\t\t{{ new Date(getCurrentDate(rowNo, colNo)).getDate() }}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</template>\n</template>\n\n<script setup lang=\"ts\">\n/* removed keyboard nav temportarily since it interfered with user experience navigating input fields */\n// import { defaultKeypressHandlers, useKeyboardNav } from '@stonecrop/utilities'\nimport { computed, nextTick, onMounted, ref, useTemplateRef, watch } from 'vue'\n\nimport type { ComponentProps } from '../../types'\n\nconst numberOfRows = 6\nconst numberOfColumns = 7\n\nconst { mode, label, selectRange = false, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst date = defineModel<number | Date>({ default: () => new Date() })\nconst selectedDate = ref(new Date(date.value))\nconst currentMonth = ref<number>(selectedDate.value.getMonth())\nconst currentYear = ref<number>(selectedDate.value.getFullYear())\nconst currentDates = ref<number[]>([])\n\n/* needed for keyboard navigation. uncomment if implementing */\n// const datepickerRef = useTemplateRef<HTMLDivElement>('datepicker')\n\nconst hoveredDate = ref(new Date(date.value))\nconst start_date = ref<Date | null>(null)\nconst end_date = ref<Date | null>(null)\nconst startDateInput = useTemplateRef<HTMLInputElement>('start-date-input')\nconst endDateInput = useTemplateRef<HTMLInputElement>('end-date-input')\n\n/*******************\nEmits\n*******************/\n\nconst emit = defineEmits<{\n\t'get-date': [{ start: Date | null; end: Date | null; selected: Date }]\n}>()\n\n/*******************\nComputed\n*******************/\n\nconst monthAndYear = computed(() => {\n\treturn new Date(currentYear.value, currentMonth.value, 1).toLocaleDateString(undefined, {\n\t\tyear: 'numeric',\n\t\tmonth: 'long',\n\t})\n})\n\nconst getStartDate = computed(() => {\n\treturn start_date.value != null ? parseDateToString(start_date.value) : ''\n})\n\nconst getEndDate = computed(() => {\n\treturn end_date.value != null ? parseDateToString(end_date.value) : ''\n})\n\n/*******************\nFunctions\n*******************/\n\nconst parseDateToString = (dateValue: Date | null) => {\n\tif (!validateDate(dateValue)) return ''\n\treturn dateValue.getMonth() + 1 + '/' + dateValue.getDate() + '/' + dateValue.getFullYear()\n}\n\nconst isTodaysDate = (day: string | number | Date): boolean => {\n\tconst todaysDate = new Date()\n\tif (currentMonth.value !== todaysDate.getMonth()) return false\n\treturn todaysDate.toDateString() === new Date(day).toDateString()\n}\n\nconst isSelectedDate = (day: string | number | Date) => {\n\treturn new Date(day).toDateString() === new Date(selectedDate.value).toDateString()\n}\n\nconst isStartDate = (day: string | number | Date) => {\n\tconst start = start_date.value\n\tif (!validateDate(start)) return false\n\treturn new Date(day).toDateString() === start.toDateString()\n}\n\nconst isEndDate = (day: string | number | Date) => {\n\tconst end = end_date.value\n\tif (!validateDate(end)) return false\n\treturn new Date(day).toDateString() === end.toDateString()\n}\n\nconst getCurrentCell = (rowNo: number, colNo: number) => {\n\treturn (rowNo - 1) * numberOfColumns + colNo\n}\n\nconst isInDateRange = (day: string | number | Date) => {\n\tconst start = start_date.value\n\tif (!validateDate(start)) return false\n\tconst this_date = new Date(day)\n\n\t//the end is either the selected end date or wherever the user is hovering\n\tconst end = end_date.value\n\tconst temp_end_date = validateDate(end) ? end : new Date(hoveredDate.value)\n\n\treturn this_date.getTime() > start.getTime() && this_date.getTime() < temp_end_date.getTime()\n}\n\nconst getCurrentDate = (rowNo: number, colNo: number) => {\n\treturn currentDates.value[getCurrentCell(rowNo, colNo)]\n}\n\nconst hoverDate = (currentIndex: number) => {\n\thoveredDate.value = new Date(currentDates.value[currentIndex])\n}\n\n// browsers (notably Firefox) allow drag-selecting text across table cells even with\n// `user-select: none` on the cells; blocking mousedown is the reliable cross-browser fix.\n// the start/end-date inputs must keep native mousedown behavior so they stay focusable/typable.\nconst preventCellSelection = (event: MouseEvent) => {\n\tif ((event.target as HTMLElement)?.tagName !== 'INPUT') {\n\t\tevent.preventDefault()\n\t}\n}\n\nconst populateMonth = () => {\n\tcurrentDates.value = []\n\tconst firstOfMonth = new Date(currentYear.value, currentMonth.value, 1)\n\tconst monthStartWeekday = firstOfMonth.getDay()\n\tconst calendarStartDay = firstOfMonth.setDate(firstOfMonth.getDate() - monthStartWeekday)\n\n\t// assume midnight for all dates while building the calendar\n\tfor (const dayIndex of Array(43).keys()) {\n\t\tcurrentDates.value.push(calendarStartDay + dayIndex * 86400000)\n\t}\n}\nconst previousYear = () => (currentYear.value -= 1)\nconst nextYear = () => (currentYear.value += 1)\n\nconst previousMonth = () => {\n\tif (currentMonth.value == 0) {\n\t\tcurrentMonth.value = 11\n\t\tpreviousYear()\n\t} else {\n\t\tcurrentMonth.value -= 1\n\t}\n}\n\nconst nextMonth = () => {\n\tif (currentMonth.value == 11) {\n\t\tcurrentMonth.value = 0\n\t\tnextYear()\n\t} else {\n\t\tcurrentMonth.value += 1\n\t}\n}\n\nconst enterDate = (event: KeyboardEvent) => {\n\tif (event.key === 'Enter') enterInputDate()\n}\n\n// useKeyboardNav([\n// \t{\n// \t\tparent: datepickerRef,\n// \t\tselectors: 'td',\n// \t\thandlers: {\n// \t\t\t...defaultKeypressHandlers,\n// \t\t\t...{\n// \t\t\t\t'keydown.pageup': previousMonth,\n// \t\t\t\t'keydown.shift.pageup': previousYear,\n// \t\t\t\t'keydown.pagedown': nextMonth,\n// \t\t\t\t'keydown.shift.pagedown': nextYear,\n// \t\t\t\t// TODO: this is a hack to override the stonecrop enter handler;\n// \t\t\t\t// store context inside the component so that handlers can be setup consistently\n// \t\t\t\t// eslint-disable-next-line @typescript-eslint/no-empty-function\n// \t\t\t\t'keydown.enter': () => {}, // select this date\n// \t\t\t},\n// \t\t},\n// \t},\n// ])\n\nconst selectDate = (currentIndex: number) => {\n\tdate.value = selectedDate.value = new Date(currentDates.value[currentIndex])\n\n\tif (selectRange) {\n\t\tconst start = start_date.value\n\t\tif (start == null || end_date.value != null) {\n\t\t\tstart_date.value = date.value\n\t\t\tend_date.value = null\n\t\t} else if (validateDate(start) && selectedDate.value.getTime() < start.getTime()) {\n\t\t\tend_date.value = null\n\t\t\tstart_date.value = date.value\n\t\t} else {\n\t\t\tend_date.value = date.value\n\t\t}\n\t\tif (startDateInput.value) startDateInput.value.value = parseDateToString(start_date.value) ?? ''\n\t\tif (endDateInput.value) endDateInput.value.value = parseDateToString(end_date.value) ?? ''\n\t}\n\temitData()\n}\n\nconst testDateOrder = () => {\n\tconst start = start_date.value\n\tconst end = end_date.value\n\tif (validateDate(end) && validateDate(start) && end.getTime() < start.getTime())\n\t\t[start_date.value, end_date.value] = [end, start]\n}\n\nconst validateDate = (dateValue: unknown): dateValue is Date => {\n\treturn dateValue instanceof Date && !isNaN(dateValue.getTime())\n}\n\nconst enterInputDate = () => {\n\tif (startDateInput.value?.value == '') {\n\t\tstart_date.value = null\n\t} else if (startDateInput.value) {\n\t\tconst start = new Date(startDateInput.value.value)\n\t\tstart_date.value = validateDate(start) ? start : null\n\t}\n\n\tif (endDateInput.value?.value == '') {\n\t\tend_date.value = null\n\t} else if (endDateInput.value) {\n\t\tconst end = new Date(endDateInput.value.value)\n\t\tend_date.value = validateDate(end) ? end : null\n\t}\n\n\tif (validateDate(start_date.value)) {\n\t\tif (validateDate(end_date.value)) testDateOrder()\n\t\tselectedDate.value = start_date.value\n\t}\n\n\temitData()\n}\n\nconst emitData = () => {\n\temit('get-date', {\n\t\tstart: selectRange ? start_date.value : null,\n\t\tend: selectRange ? end_date.value : null,\n\t\tselected: selectedDate.value,\n\t})\n}\n\n/*******************\nHooks\n*******************/\n\nonMounted(async () => {\n\tpopulateMonth()\n\t// required to allow the elements to be focused in the next step\n\tawait nextTick()\n\tconst $selectedDate = document.getElementsByClassName('selectedDate')\n\tif ($selectedDate.length > 0) {\n\t\t;($selectedDate[0] as HTMLElement).focus()\n\t} else {\n\t\tconst $todaysDate = document.getElementsByClassName('todaysDate')\n\t\tif ($todaysDate.length > 0) {\n\t\t\t;($todaysDate[0] as HTMLElement).focus()\n\t\t}\n\t}\n})\n\n// setup keyboard navigation\n// useKeyboardNav([\n// \t{\n// \t\tparent: datepickerRef,\n// \t\tselectors: 'td',\n// \t\thandlers: {\n// \t\t\t...defaultKeypressHandlers,\n// \t\t\t'keydown.pageup': previousMonth,\n// \t\t\t'keydown.shift.pageup': previousYear,\n// \t\t\t'keydown.pagedown': nextMonth,\n// \t\t\t'keydown.shift.pagedown': nextYear,\n// \t\t\t// TODO: this is a hack to override the stonecrop enter handler;\n// \t\t\t// store context inside the component so that handlers can be setup consistently\n\n// \t\t\t'keydown.enter': () => {}, // select this date\n// \t\t},\n// \t},\n// ])\n\n/*******************\nWatchers\n*******************/\n\nwatch([currentMonth, currentYear], populateMonth)\n\n/*******************\nExpose\n*******************/\n\ndefineExpose({ currentMonth, currentYear, selectedDate })\n</script>\n\n<style scoped>\n.adatepicker,\n.adatepicker table,\n.adatepicker tr,\n.adatepicker td,\n.adatepicker th {\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\tuser-select: none;\n}\n\n.adatepicker {\n\tfont-size: var(--sc-table-font-size);\n\tdisplay: inline-table;\n\tcolor: var(--sc-cell-text-color);\n\toutline: none;\n\tborder-collapse: collapse;\n\tmargin-bottom: 10px;\n\t/* width: calc(100% - 4px); */\n}\n\n.adatepicker tr {\n\theight: 1.15rem;\n\theight: 1.15rem;\n\ttext-align: center;\n\tvertical-align: middle;\n}\n\n.adatepicker td {\n\tborder: 2px solid transparent;\n\toutline: 2px solid transparent;\n\tmin-width: 3ch;\n\tmax-width: 3ch;\n\tcursor: pointer;\n}\n.adatepicker td.date-cell:hover {\n\tbackground: var(--sc-gray-10);\n}\n\n.adatepicker td:focus,\n.adatepicker td:focus-within {\n\t/* outline: 1px dashed black; */\n\tbox-shadow: none;\n\toverflow: hidden;\n\tmin-height: 1.15em;\n\tmax-height: 1.15em;\n\toverflow: hidden;\n}\n.adatepicker .selectedDate,\n.adatepicker .startDate,\n.adatepicker .endDate {\n\t/* outline: 1px solid black; */\n\tbackground: var(--sc-gray-20);\n\tfont-weight: bolder;\n}\n.adatepicker .startDate {\n\t/* border-radius: 5px 0px 0px 5px; */\n\tborder-left: 1px solid var(--sc-gray-50);\n\tbackground: var(--sc-gray-20) !important;\n}\n.adatepicker .endDate {\n\tborder-right: 1px solid var(--sc-gray-50);\n\t/* border-radius: 0px 5px 5px 0px; */\n\tbackground: var(--sc-gray-20) !important;\n}\n.adatepicker .withinRange {\n\tbackground: var(--sc-gray-5);\n}\n\n.adatepicker .todaysDate {\n\tfont-weight: bolder;\n\t/* text-decoration: underline; */\n\tcolor: black;\n}\n.days-header > td {\n\tfont-weight: bold;\n}\n.prev-date {\n\tcolor: var(--sc-gray-20);\n}\n\n.adatepicker .date-input {\n\tdisplay: flex;\n\twidth: 100%;\n\tgap: 5px;\n\talign-items: center;\n}\n.adatepicker .date-input > input {\n\twidth: 50%;\n\tpadding: 2px;\n}\n\n/* Keep the field error in-flow below the calendar. The shared .aform_error is absolutely\n positioned against a .aform_form-element anchor, which this grid component does not use. */\np.aform_error {\n\tposition: static;\n\tdisplay: block;\n\tcolor: var(--sc-brand-danger, red);\n\tfont-size: 0.7rem;\n\tmargin: 0.25rem 0 0;\n}\n</style>\n","<template>\n\t<div class=\"adate_time\">\n\t\t<div class=\"adate_time_fields\">\n\t\t\t<input\n\t\t\t\tv-model=\"timeData.hours\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tinputmode=\"numeric\"\n\t\t\t\t@paste=\"pasteInput($event, true)\"\n\t\t\t\t@focus=\"focusInput\"\n\t\t\t\t@blur=\"confirmTime\"\n\t\t\t\t@keydown.enter.prevent=\"confirmTime\"\n\t\t\t\t@keydown.up.prevent=\"tick('hours')\"\n\t\t\t\t@keydown.down.prevent=\"tick('hours', -1)\" />\n\t\t\t<span class=\"colon\">:</span>\n\t\t\t<input\n\t\t\t\tv-model=\"timeData.minutes\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tinputmode=\"numeric\"\n\t\t\t\t@paste=\"pasteInput\"\n\t\t\t\t@focus=\"focusInput\"\n\t\t\t\t@blur=\"confirmTime\"\n\t\t\t\t@keydown.enter.prevent=\"confirmTime\"\n\t\t\t\t@keydown.up.prevent=\"tick('minutes')\"\n\t\t\t\t@keydown.down.prevent=\"tick('minutes', -1)\" />\n\t\t\t<span v-if=\"useSeconds\" class=\"colon\">:</span>\n\t\t\t<input\n\t\t\t\tv-if=\"useSeconds\"\n\t\t\t\tv-model=\"timeData.seconds\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tinputmode=\"numeric\"\n\t\t\t\t@paste=\"pasteInput\"\n\t\t\t\t@focus=\"focusInput\"\n\t\t\t\t@blur=\"confirmTime\"\n\t\t\t\t@keydown.enter.prevent=\"confirmTime\"\n\t\t\t\t@keydown.up.prevent=\"tick('seconds')\"\n\t\t\t\t@keydown.down.prevent=\"tick('seconds', -1)\" />\n\t\t\t<select\n\t\t\t\tv-if=\"!allowMilitaryTime\"\n\t\t\t\tref=\"meridiem-selector\"\n\t\t\t\tv-model=\"meridiem\"\n\t\t\t\tclass=\"aform-select meridiem-selector\"\n\t\t\t\t@change=\"confirmTime\">\n\t\t\t\t<option value=\"AM\">AM</option>\n\t\t\t\t<option value=\"PM\">PM</option>\n\t\t\t</select>\n\t\t</div>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, useTemplateRef, watch, onMounted } from 'vue'\n\nconst {\n\tallowMilitaryTime = false,\n\tdefaultHours = 12,\n\tdefaultMinutes = 0,\n\tdefaultSeconds = 0,\n\tdefaultMeridiem = 'AM',\n\tuseSeconds = true,\n} = defineProps<{\n\tallowMilitaryTime?: boolean\n\tdefaultHours?: number\n\tdefaultMinutes?: number\n\tdefaultSeconds?: number\n\tdefaultMeridiem?: string\n\tuseSeconds?: boolean\n}>()\n\nconst emit = defineEmits<{\n\t'get-time': [{ hours: number; minutes: number; seconds: number; meridiem: string; militaryTime: number }]\n}>()\n\nconst meridiemSelector = useTemplateRef<HTMLSelectElement>('meridiem-selector')\n\nconst timeData = reactive({\n\thours: String(defaultHours).padStart(2, '0'),\n\tminutes: String(defaultMinutes).padStart(2, '0'),\n\tseconds: String(defaultSeconds).padStart(2, '0'),\n})\n\nconst meridiem = ref(defaultMeridiem == 'AM' ? 'AM' : 'PM')\n\nonMounted(() => {\n\temitTime()\n})\n\nconst confirmTime = () => {\n\tconst maxHours = allowMilitaryTime ? 23 : 12\n\tconst minHours = allowMilitaryTime ? 0 : 1\n\tlet hours = Number(timeData.hours)\n\tlet minutes = Number(timeData.minutes)\n\tlet seconds = Number(timeData.seconds)\n\n\tif (isNaN(hours) || timeData.hours === '' || hours > maxHours) hours = maxHours\n\tif (!allowMilitaryTime && hours < minHours) hours = minHours\n\tif (isNaN(minutes) || timeData.minutes === '' || minutes > 59) minutes = 59\n\tif (isNaN(seconds) || timeData.seconds === '' || seconds > 59) seconds = 59\n\n\ttimeData.hours = String(hours).padStart(2, '0')\n\ttimeData.minutes = String(minutes).padStart(2, '0')\n\ttimeData.seconds = String(seconds).padStart(2, '0')\n\n\temitTime()\n}\n\nconst emitTime = () => {\n\tconst hours = Number(timeData.hours)\n\tconst minutes = Number(timeData.minutes)\n\tconst seconds = Number(timeData.seconds)\n\temit('get-time', {\n\t\thours,\n\t\tminutes,\n\t\tseconds,\n\t\tmeridiem: meridiem.value,\n\t\tmilitaryTime: allowMilitaryTime ? hours : meridiem.value === 'PM' ? (hours === 12 ? 12 : hours + 12) : hours % 12,\n\t})\n}\n\nconst focusInput = (event: FocusEvent) => {\n\tconst target = event.target\n\tif (target instanceof HTMLInputElement) {\n\t\ttarget.select()\n\t}\n}\n\nconst tick = (target: 'hours' | 'minutes' | 'seconds', amount = 1) => {\n\tconst maxHours = allowMilitaryTime ? 23 : 12\n\tconst minHours = allowMilitaryTime ? 0 : 1\n\n\tif (target == 'hours') {\n\t\tconst oldHours = Number(timeData.hours)\n\t\ttimeData.hours = String(oldHours + amount)\n\t\tif ((oldHours == 11 && Number(timeData.hours) == 12) || (oldHours == 12 && Number(timeData.hours) == 11)) {\n\t\t\tchangeMeridiem()\n\t\t}\n\t} else if (target == 'minutes') {\n\t\ttimeData.minutes = String(Number(timeData.minutes) + amount)\n\t} else if (target == 'seconds') {\n\t\ttimeData.seconds = String(Number(timeData.seconds) + amount)\n\t}\n\n\tconst prevHours = Number(timeData.hours)\n\n\tif (Number(timeData.seconds) < 0) timeData.minutes = String(Number(timeData.minutes) - 1)\n\telse if (Number(timeData.seconds) > 59) timeData.minutes = String(Number(timeData.minutes) + 1)\n\n\tif (Number(timeData.minutes) < 0) timeData.hours = String(prevHours - 1)\n\telse if (Number(timeData.minutes) > 59) timeData.hours = String(prevHours + 1)\n\n\tconst newRawHours = Number(timeData.hours)\n\tif (!allowMilitaryTime && newRawHours !== prevHours) {\n\t\tif ((prevHours === 11 && newRawHours === 12) || (prevHours === 12 && newRawHours === 11)) {\n\t\t\tchangeMeridiem()\n\t\t}\n\t}\n\n\ttimeData.hours = String(formatTime(Number(timeData.hours), minHours, maxHours)).padStart(2, '0')\n\ttimeData.minutes = String(formatTime(Number(timeData.minutes), 0, 59)).padStart(2, '0')\n\ttimeData.seconds = String(formatTime(Number(timeData.seconds), 0, 59)).padStart(2, '0')\n}\n\nwatch(\n\t() => timeData.hours,\n\t(newVal, oldVal) => {\n\t\ttimeData.hours = Number(newVal) > 99 ? oldVal : newVal\n\t}\n)\nwatch(\n\t() => timeData.minutes,\n\t(newVal, oldVal) => {\n\t\ttimeData.minutes = Number(newVal) > 99 ? oldVal : newVal\n\t}\n)\nwatch(\n\t() => timeData.seconds,\n\t(newVal, oldVal) => {\n\t\ttimeData.seconds = Number(newVal) > 99 ? oldVal : newVal\n\t}\n)\n\nconst formatTime = (target: number, min: number, max: number): number => {\n\tif (target > max) return min\n\telse if (target < min) return max\n\treturn target\n}\n\nconst changeMeridiem = () => {\n\tmeridiem.value = meridiem.value == 'PM' ? 'AM' : 'PM'\n\temitTime()\n}\n\nconst pasteInput = (event: ClipboardEvent, pasteAllFields = false) => {\n\tevent.stopPropagation()\n\tevent.preventDefault()\n\n\tconst clipboardData = event.clipboardData\n\tif (!clipboardData) return\n\tlet pastedData: string = clipboardData.getData('Text')\n\n\tpastedData = pastedData.replace(/[^0-9]/g, '')\n\n\tif (pasteAllFields) {\n\t\tif (pastedData.length % 2 != 0) pastedData = '0' + pastedData\n\t\tif (pastedData.length < 3) pastedData += '00'\n\t\tif (pastedData.length < 5) pastedData += '00'\n\n\t\tconst timeUnits = pastedData.match(/(..?)/g)\n\t\tif (!timeUnits || timeUnits.length < 3) return\n\n\t\ttimeData.seconds = timeUnits[2]\n\t\ttimeData.minutes = timeUnits[1]\n\t\ttimeData.hours = timeUnits[0]\n\t\tconfirmTime()\n\t\tif (!allowMilitaryTime) meridiemSelector.value?.focus()\n\t} else {\n\t\tif (pastedData.length > 2) pastedData = pastedData.slice(0, 2)\n\t\tconst target = event.target\n\t\tif (target instanceof HTMLInputElement) {\n\t\t\ttarget.value = pastedData\n\t\t\ttarget.dispatchEvent(new Event('input'))\n\t\t}\n\t}\n}\n</script>\n\n<style scoped>\n.adate_time {\n\twidth: auto;\n\tpadding: 10px;\n\tbox-sizing: border-box;\n\tfont-size: 1rem;\n\tbackground: var(--sc-gray-10);\n}\n.adate_time_fields {\n\tdisplay: flex;\n\talign-items: stretch;\n\tgap: 5px;\n\tjustify-content: flex-start;\n}\n.adate_time_fields > input {\n\tmin-width: 30px;\n\tpadding: 2px;\n\ttext-align: center;\n\tdisplay: inline-block;\n\tflex-basis: 0;\n}\n.meridiem-selector {\n\tcursor: pointer;\n\tdisplay: inline-block;\n\tflex-basis: 0;\n\tpadding: 5px;\n\tuser-select: none;\n}\n.meridiem-selector:focus {\n\toutline: 2px solid black;\n\toutline-offset: -2px;\n}\n.adate_time_segment {\n\tdisplay: flex;\n\tflex-direction: column;\n\twidth: 40px;\n}\n.colon {\n\tdisplay: flex;\n\talign-items: normal;\n}\n.aform_form-btn {\n\tcursor: pointer;\n}\n.aform-select {\n\tborder-radius: 0px;\n\tborder: 1px solid rgb(118, 118, 118);\n\tfont-size: 1rem;\n\tpadding: 0rem;\n\tmargin: 0;\n\tborder-radius: 0;\n\tbox-sizing: border-box;\n\tmin-height: auto;\n\tposition: relative;\n\tcolor: var(--sc-cell-text-color);\n}\n.meridiem-selector {\n\tmargin-left: 6px;\n}\n</style>\n","<!-- This serves as a wrapper component for ADatePicker and ADateTime in one component -->\n\n<template>\n\t<div class=\"adate-selection\">\n\t\t<ADatePicker v-if=\"showDate\" :select-range=\"selectRange\" @get-date=\"handleDate\" />\n\n\t\t<ADateTime\n\t\t\tv-if=\"showTime\"\n\t\t\t:allow-military-time=\"allowMilitaryTime\"\n\t\t\t:default-hours=\"defaultHours\"\n\t\t\t:default-minutes=\"defaultMinutes\"\n\t\t\t:default-seconds=\"defaultSeconds\"\n\t\t\t:default-meridiem=\"defaultMeridiem\"\n\t\t\t:use-seconds=\"useSeconds\"\n\t\t\t@get-time=\"handleStartTime\" />\n\n\t\t<template v-if=\"selectRange && showTime && showEndTime\">\n\t\t\t<div class=\"adate-selection__end-label\">End time</div>\n\t\t\t<ADateTime\n\t\t\t\t:allow-military-time=\"allowMilitaryTime\"\n\t\t\t\t:default-hours=\"defaultHours\"\n\t\t\t\t:default-minutes=\"defaultMinutes\"\n\t\t\t\t:default-seconds=\"defaultSeconds\"\n\t\t\t\t:default-meridiem=\"defaultMeridiem\"\n\t\t\t\t:use-seconds=\"useSeconds\"\n\t\t\t\t@get-time=\"handleEndTime\" />\n\t\t</template>\n\n\t\t<p v-if=\"!showTime && !showDate\" class=\"empty\">empty</p>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { provide, ref } from 'vue'\nimport ADatePicker from './ADatePicker.vue'\nimport ADateTime from './ADateTime.vue'\n\nconst {\n\tshowDate = true,\n\tshowTime = true,\n\tselectRange = true,\n\tshowEndTime = false,\n\tallowMilitaryTime = false,\n\tdefaultHours = 12,\n\tdefaultMinutes = 0,\n\tdefaultSeconds = 0,\n\tdefaultMeridiem = 'AM',\n\tuseSeconds = true,\n} = defineProps<{\n\tshowDate?: boolean\n\tshowTime?: boolean\n\tselectRange?: boolean\n\tshowEndTime?: boolean\n\tallowMilitaryTime?: boolean\n\tdefaultHours?: number\n\tdefaultMinutes?: number\n\tdefaultSeconds?: number\n\tdefaultMeridiem?: string\n\tuseSeconds?: boolean\n}>()\n\nconst emit = defineEmits<{\n\t'get-date': [{ selected: Date; start?: Date | null; end?: Date | null }]\n\t'get-time': [{ hours: number; minutes: number; seconds: number; meridiem: string }]\n\t'get-range': [{ start: Date; end: Date }]\n}>()\n\nprovide('select-range', selectRange)\n\nconst today = new Date()\nconst pickerStart = ref<Date>(today)\nconst pickerEnd = ref<Date>(today)\nconst startTimeMs = ref<number>(0)\nconst endTimeMs = ref<number>(0)\n\nconst mergeDateTime = (date: Date, timeMs: number): Date => {\n\tconst d = new Date(date)\n\td.setHours(0, 0, 0, 0)\n\treturn new Date(d.getTime() + timeMs)\n}\n\nconst timePayloadToMs = (payload: {\n\thours: number\n\tminutes: number\n\tseconds: number\n\tmeridiem: string\n\tmilitaryTime?: number\n}): number => {\n\tlet h: number\n\tif (payload.militaryTime !== undefined) {\n\t\th = payload.militaryTime\n\t} else {\n\t\tconst hrs = payload.hours % 12\n\t\th = payload.meridiem === 'PM' ? hrs + 12 : hrs\n\t}\n\treturn (h * 3600 + payload.minutes * 60 + (payload.seconds ?? 0)) * 1000\n}\n\nconst tryEmitRange = () => {\n\tif (!selectRange || !showTime || !showEndTime) return\n\temit('get-range', {\n\t\tstart: mergeDateTime(pickerStart.value, startTimeMs.value),\n\t\tend: mergeDateTime(pickerEnd.value, endTimeMs.value),\n\t})\n}\n\nconst handleDate = (data: { start: Date | null; end: Date | null; selected: Date }) => {\n\temit('get-date', data)\n\tif (selectRange) {\n\t\tpickerStart.value = data.start ?? data.selected\n\t\tpickerEnd.value = data.end ?? data.selected\n\t\ttryEmitRange()\n\t}\n}\n\nconst handleStartTime = (data: {\n\thours: number\n\tminutes: number\n\tseconds: number\n\tmeridiem: string\n\tmilitaryTime?: number\n}) => {\n\tstartTimeMs.value = timePayloadToMs(data)\n\tif (showEndTime) {\n\t\ttryEmitRange()\n\t} else {\n\t\temit('get-time', data)\n\t}\n}\n\nconst handleEndTime = (data: {\n\thours: number\n\tminutes: number\n\tseconds: number\n\tmeridiem: string\n\tmilitaryTime?: number\n}) => {\n\tendTimeMs.value = timePayloadToMs(data)\n\ttryEmitRange()\n}\n</script>\n\n<style scoped>\n.adate-selection {\n\tdisplay: inline-block;\n\tborder: 1px solid var(--sc-gray-80);\n\tpadding: 10px;\n\tbackground: var(--sc-form-background);\n}\n\n.adate-selection__end-label {\n\tfont-size: 0.8em;\n\tfont-weight: bold;\n\tcolor: var(--sc-input-active-label-color, #555);\n\tmargin-top: 8px;\n\tmargin-bottom: 2px;\n\tpadding-left: 2px;\n}\n\n.empty {\n\tcolor: #ccc;\n\tpadding: 10px;\n\ttext-align: center;\n\tborder: 1px solid #ccc;\n}\n</style>\n","<template>\n\t<div>\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ modelValue ? new Date(inputDate).toLocaleDateString() : '' }}</span>\n\t\t\t<label>{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tref=\"date\"\n\t\t\t\tv-model=\"inputDate\"\n\t\t\t\tclass=\"adate-input\"\n\t\t\t\t:value=\"inputDate\"\n\t\t\t\ttype=\"date\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:required=\"required\"\n\t\t\t\t@click.prevent=\"\n\t\t\t\t\t() => {\n\t\t\t\t\t\tshowPicker = !showPicker\n\t\t\t\t\t}\n\t\t\t\t\" />\n\t\t\t<label :for=\"uuid\">{{ label }}</label>\n\t\t\t<p v-show=\"errorText\" v-html=\"errorText\"></p>\n\t\t\t<ADateSelection\n\t\t\t\tv-if=\"showPicker\"\n\t\t\t\tref=\"picker\"\n\t\t\t\tclass=\"picker\"\n\t\t\t\t:select-range=\"false\"\n\t\t\t\t:show-time=\"false\"\n\t\t\t\t@get-date=\"handleDate\" />\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useTemplateRef, ref, computed, watch } from 'vue'\nimport { onClickOutside } from '@vueuse/core'\n\nimport ADateSelection from './ADateSelection.vue'\nimport type { ComponentProps } from '../../types'\n\nconst {\n\tlabel = 'Date',\n\trequired,\n\tmode,\n\tuuid,\n\terrors,\n\tvalidation = { errorMessage: '' },\n} = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst modelValue = defineModel<string | Date>()\n\nconst currentDate = ref(modelValue.value ? new Date(modelValue.value) : new Date())\nconst inputDate = computed({\n\tget: () => currentDate.value.toISOString().split('T')[0],\n\tset: (value: string) => {\n\t\tcurrentDate.value = new Date(value)\n\t\tmodelValue.value = value\n\t},\n})\n\nconst pickerRef = useTemplateRef<HTMLDivElement>('picker')\nconst showPicker = ref(false)\n\nonClickOutside(pickerRef, () => (showPicker.value = false))\n\nwatch(\n\t() => modelValue.value,\n\tnewValue => {\n\t\tif (newValue) {\n\t\t\tcurrentDate.value = new Date(newValue)\n\t\t}\n\t}\n)\n\nconst handleDate = (data: { selected: Date }) => {\n\tcurrentDate.value = data.selected\n\tmodelValue.value = inputDate.value\n}\n</script>\n\n<style scoped>\n.adate-input {\n\toverflow: auto;\n}\ndiv {\n\tmin-width: 40ch;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tborder: 1px solid transparent;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tmargin-right: 1ch;\n}\n\ninput {\n\twidth: calc(100% - 1ch);\n\tbox-sizing: border-box;\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tpadding: 1ch 0.5ch 0.5ch 1ch;\n\tmargin: calc(1.15rem / 2) 0 0 0;\n\tmin-height: 1.15rem;\n\tborder-radius: 0.25rem;\n}\n\np,\nlabel {\n\tcolor: var(--sc-input-label-color);\n\tdisplay: block;\n\tmin-height: 1.15rem;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tborder: 1px solid transparent;\n\tmargin-bottom: 0.25rem;\n\tbox-sizing: border-box;\n}\n\np {\n\twidth: 100%;\n\tcolor: red;\n\tfont-size: 85%;\n\tbox-sizing: border-box;\n}\n\nlabel {\n\tz-index: 0;\n\tfont-size: 80%;\n\tposition: absolute;\n\tbackground: white;\n\tmargin: calc(-1.5rem - calc(2.15rem / 2)) 0 0 1ch;\n\tpadding: 0 0.25ch 0 0.25ch;\n\tbox-sizing: border-box;\n}\n\ninput:focus {\n\tborder: 1px solid var(--sc-input-active-border-color);\n}\n\ninput:focus + label {\n\tcolor: var(--sc-input-active-label-color);\n}\n.picker {\n\tposition: absolute;\n\ttop: 50px;\n}\n</style>\n","<template>\n\t<div v-if=\"mode === 'display'\" class=\"input-wrapper\">\n\t\t<span class=\"aform_display-value\">{{ search ?? '' }}</span>\n\t\t<label>{{ label }}</label>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</div>\n\t<div v-else v-on-click-outside=\"onClickOutside\" class=\"autocomplete\" :class=\"{ isOpen: dropdown.open }\">\n\t\t<div class=\"input-wrapper\">\n\t\t\t<input\n\t\t\t\tv-model=\"search\"\n\t\t\t\ttype=\"text\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t@input=\"filter\"\n\t\t\t\t@focus=\"openDropdown\"\n\t\t\t\t@keydown.down=\"selectNextResult\"\n\t\t\t\t@keydown.up=\"selectPrevResult\"\n\t\t\t\t@keydown.enter=\"setCurrentResult\"\n\t\t\t\t@keydown.esc=\"onClickOutside\"\n\t\t\t\t@keydown.tab=\"onClickOutside\" />\n\n\t\t\t<ul v-show=\"dropdown.open\" id=\"autocomplete-results\" class=\"autocomplete-results\">\n\t\t\t\t<li v-if=\"dropdown.loading\" class=\"loading autocomplete-result\">Loading results...</li>\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"(result, i) in dropdown.results\"\n\t\t\t\t\tv-else\n\t\t\t\t\t:key=\"result\"\n\t\t\t\t\tclass=\"autocomplete-result\"\n\t\t\t\t\t:class=\"{ 'is-active': i === dropdown.activeItemIndex }\"\n\t\t\t\t\t@click.stop=\"setResult(result)\">\n\t\t\t\t\t{{ result }}\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t\t<label>{{ label }}</label>\n\t\t</div>\n\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { vOnClickOutside } from '@vueuse/components'\nimport { computed, reactive, ref } from 'vue'\n\nimport type { ComponentProps } from '../../types'\n\nconst {\n\tlabel,\n\toptions = [],\n\tisAsync = false,\n\tfilterFunction = undefined,\n\tmode,\n\terrors,\n\tvalidation = { errorMessage: '' },\n} = defineProps<\n\tComponentProps & {\n\t\toptions?: string[]\n\t\tisAsync?: boolean\n\t\tfilterFunction?: (search: string) => string[] | Promise<string[]>\n\t}\n>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\nconst search = defineModel<string>()\n\n// tracks the last explicitly-committed value so outside-click reverts instead of clears\nconst committedValue = ref(search.value ?? '')\n\nconst dropdown = reactive({\n\tactiveItemIndex: null as number | null,\n\topen: false,\n\tloading: false,\n\tresults: options,\n})\n\nconst onClickOutside = () => closeDropdown()\n\nconst filter = async () => {\n\tdropdown.open = true\n\tdropdown.activeItemIndex = null\n\tif (filterFunction) {\n\t\tif (isAsync) dropdown.loading = true\n\t\ttry {\n\t\t\tconst filteredResults = await filterFunction(search.value || '')\n\t\t\tdropdown.results = filteredResults || []\n\t\t} catch {\n\t\t\tdropdown.results = []\n\t\t} finally {\n\t\t\tif (isAsync) dropdown.loading = false\n\t\t}\n\t} else {\n\t\tfilterResults()\n\t}\n}\n\nconst setResult = (result: string) => {\n\tsearch.value = result\n\tcommittedValue.value = result\n\tcloseDropdown(result)\n}\n\nconst openDropdown = () => {\n\tconst idx = options?.indexOf(search.value ?? '') ?? -1\n\tdropdown.activeItemIndex = isAsync ? null : idx >= 0 ? idx : null\n\tdropdown.open = true\n\t// TODO: this should probably call the async function if it's async\n\tdropdown.results = isAsync ? [] : options\n}\n\nconst closeDropdown = (result?: string) => {\n\tdropdown.activeItemIndex = null\n\tdropdown.open = false\n\tif (!options?.includes(result || search.value || '')) {\n\t\tsearch.value = committedValue.value\n\t}\n}\n\nconst filterResults = () => {\n\tif (!search.value) {\n\t\tdropdown.results = options\n\t} else {\n\t\tdropdown.results = options?.filter(item => item.toLowerCase().includes((search.value ?? '').toLowerCase()))\n\t}\n}\n\nconst selectNextResult = () => {\n\tconst resultsLength = dropdown.results?.length || 0\n\tif (dropdown.activeItemIndex != null) {\n\t\tconst currentIndex = isNaN(dropdown.activeItemIndex) ? 0 : dropdown.activeItemIndex\n\t\tdropdown.activeItemIndex = (currentIndex + 1) % resultsLength\n\t} else {\n\t\tdropdown.activeItemIndex = 0\n\t}\n}\n\nconst selectPrevResult = () => {\n\tconst resultsLength = dropdown.results?.length || 0\n\tif (dropdown.activeItemIndex != null) {\n\t\tconst currentIndex = isNaN(dropdown.activeItemIndex) ? 0 : dropdown.activeItemIndex\n\t\tif (currentIndex === 0) {\n\t\t\tdropdown.activeItemIndex = null\n\t\t} else {\n\t\t\tdropdown.activeItemIndex = currentIndex - 1\n\t\t}\n\t} else {\n\t\tdropdown.activeItemIndex = resultsLength - 1\n\t}\n}\n\nconst setCurrentResult = () => {\n\tif (dropdown.results) {\n\t\tconst currentIndex = dropdown.activeItemIndex || 0\n\t\tconst result = dropdown.results[currentIndex]\n\t\tsetResult(result)\n\t}\n\tdropdown.activeItemIndex = 0\n}\n</script>\n\n<style scoped>\n/* variables taken from here: https://github.com/frappe/frappe/blob/version-13/frappe/public/scss/common/awesomeplete.scss */\n.autocomplete {\n\tposition: relative;\n}\n\n.input-wrapper {\n\tborder: 1px solid transparent;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tmargin-right: 1ch;\n}\n\ninput {\n\twidth: calc(100% - 1ch);\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tpadding: 1ch 0.5ch 0.5ch 1ch;\n\tmargin: calc(1.15rem / 2) 0 0 0;\n\tmin-height: 1.15rem;\n\tborder-radius: 0.25rem;\n\tfont-family: var(--sc-font-family);\n}\n\ninput:focus {\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-radius: 0.25rem 0.25rem 0 0;\n\tborder-bottom: none;\n}\n\nlabel {\n\tdisplay: block;\n\tmin-height: 1.15rem;\n\tpadding: 0rem;\n\tmargin: 0rem;\n\tborder: 1px solid transparent;\n\tmargin-bottom: 0.25rem;\n\tz-index: 0;\n\tfont-size: 80%;\n\tposition: absolute;\n\tbackground: white;\n\tmargin: calc(-1.5rem - calc(2.15rem / 2)) 0 0 1ch;\n\tpadding: 0 0.25ch 0 0.25ch;\n}\n\n.autocomplete-results {\n\tposition: absolute;\n\twidth: calc(100% - 1ch + 1.5px);\n\tz-index: 100;\n\tpadding: 0;\n\tmargin: 0;\n\tcolor: var(--sc-input-active-border-color);\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-radius: 0 0 0.25rem 0.25rem;\n\tborder-top: none;\n\tbackground-color: #fff;\n}\n\n.autocomplete-result {\n\tlist-style: none;\n\ttext-align: left;\n\tpadding: 4px 6px;\n\tcursor: pointer;\n\tborder-bottom: 0.5px solid lightgray;\n}\n\n.autocomplete-result.is-active,\n.autocomplete-result:hover {\n\tbackground-color: var(--sc-row-color-zebra-light);\n\tcolor: var(--sc-input-active-border-color);\n}\n\n/* Keep the field error in-flow below the control. The shared .aform_error is absolutely\n positioned against a .aform_form-element anchor, which this component does not use. */\np.aform_error {\n\tposition: static;\n\tdisplay: block;\n\tcolor: var(--sc-brand-danger, red);\n\tfont-size: 0.7rem;\n\tmargin: 0.25rem 0 0;\n}\n</style>\n","<template>\n\t<div class=\"aduration\">\n\t\t<template v-if=\"mode === 'display' || mode === 'read'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayValue }}</span>\n\t\t\t<label>{{ label }}</label>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<ADateSelection\n\t\t\t\tref=\"selectionRef\"\n\t\t\t\t:select-range=\"true\"\n\t\t\t\t:show-time=\"true\"\n\t\t\t\t:show-end-time=\"true\"\n\t\t\t\t:allow-military-time=\"allowMilitaryTime\"\n\t\t\t\t:use-seconds=\"useSeconds\"\n\t\t\t\t@get-range=\"handleRange\" />\n\t\t\t<div class=\"aduration__footer\">\n\t\t\t\t<label>{{ label }}</label>\n\t\t\t\t<div v-if=\"startDatetime && endDatetime\" class=\"aduration__summary\">\n\t\t\t\t\t<span class=\"aduration__label\">Duration:</span>\n\t\t\t\t\t<span class=\"aduration__value\">{{ humanDuration }}</span>\n\t\t\t\t\t<span class=\"aduration__ms\">({{ modelValue ?? 0 }} ms)</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue'\nimport ADateSelection from './ADateSelection.vue'\n\nconst {\n\tlabel = 'Duration',\n\tmode = 'edit',\n\tallowMilitaryTime = false,\n\tuseSeconds = false,\n} = defineProps<{\n\tlabel?: string\n\tmode?: string\n\tallowMilitaryTime?: boolean\n\tuseSeconds?: boolean\n}>()\n\nconst modelValue = defineModel<number>()\n\nconst startDatetime = ref<Date | null>(null)\nconst endDatetime = ref<Date | null>(null)\n\nconst duration = computed<number>(() => {\n\tif (!startDatetime.value || !endDatetime.value) return 0\n\tconst ms = endDatetime.value.getTime() - startDatetime.value.getTime()\n\treturn ms > 0 ? ms : 0\n})\n\nwatch(duration, newMs => {\n\tmodelValue.value = newMs\n})\n\nconst handleRange = (data: { start: Date; end: Date }) => {\n\tstartDatetime.value = data.start\n\tendDatetime.value = data.end\n\tmodelValue.value = duration.value\n}\n\nconst humanDuration = computed(() => {\n\tconst ms = duration.value\n\tif (ms === 0) return '0s'\n\tconst s = Math.floor(ms / 1000) % 60\n\tconst m = Math.floor(ms / 60000) % 60\n\tconst h = Math.floor(ms / 3600000) % 24\n\tconst d = Math.floor(ms / 86400000)\n\treturn [d && `${d}d`, h && `${h}h`, m && `${m}m`, s && `${s}s`].filter(Boolean).join(' ') || '0s'\n})\n\nconst displayValue = computed(() => {\n\tconst ms = modelValue.value\n\tif (!ms) return '—'\n\tconst s = Math.floor(ms / 1000) % 60\n\tconst m = Math.floor(ms / 60000) % 60\n\tconst h = Math.floor(ms / 3600000) % 24\n\tconst d = Math.floor(ms / 86400000)\n\treturn [d && `${d}d`, h && `${h}h`, m && `${m}m`, s && `${s}s`].filter(Boolean).join(' ') || '0s'\n})\n</script>\n\n<style scoped>\n.aduration {\n\tposition: relative;\n\tmin-width: 40ch;\n\twidth: 100%;\n}\n\n.aduration__summary {\n\tdisplay: flex;\n\tgap: 6px;\n\talign-items: baseline;\n\tmargin-top: 6px;\n\tfont-size: 0.9em;\n}\n\n.aduration__label {\n\tfont-weight: bold;\n\tcolor: var(--sc-input-active-label-color, #555);\n}\n\n.aduration__value {\n\tcolor: var(--sc-cell-text-color, #000);\n}\n\n.aduration__ms {\n\tcolor: var(--sc-gray-50, #888);\n\tfont-size: 0.85em;\n}\n\n.aduration__footer {\n\tmargin-top: 8px;\n}\n</style>\n","<template>\n\t<div class=\"adaterange\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayValue }}</span>\n\t\t\t<label>{{ label }}</label>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tclass=\"adate-input aform_input-field\"\n\t\t\t\ttype=\"text\"\n\t\t\t\t:value=\"rangeDisplay\"\n\t\t\t\tplaceholder=\"Select date range\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\treadonly\n\t\t\t\t@click=\"openPicker\" />\n\t\t\t<label :for=\"uuid\">{{ label }}</label>\n\n\t\t\t<p v-show=\"errorText\" v-html=\"errorText\"></p>\n\n\t\t\t<ADateSelection\n\t\t\t\tv-if=\"showPicker\"\n\t\t\t\tref=\"pickerRef\"\n\t\t\t\tclass=\"picker\"\n\t\t\t\t:select-range=\"true\"\n\t\t\t\t:show-time=\"false\"\n\t\t\t\t@get-date=\"handlePickerDate\" />\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue'\nimport { onClickOutside } from '@vueuse/core'\nimport ADateSelection from './ADateSelection.vue'\nimport type { ComponentProps } from '../../types'\n\nconst fmt = (d: string) => new Date(d).toLocaleDateString()\n\nconst { label = 'Date Range', mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nexport interface DateRangeValue {\n\tstart_date: string | null\n\tend_date: string | null\n}\n\nconst modelValue = defineModel<DateRangeValue>({\n\tdefault: () => ({ start_date: null, end_date: null }),\n})\n\nconst startDate = ref<Date | null>(modelValue.value.start_date ? new Date(modelValue.value.start_date) : null)\nconst endDate = ref<Date | null>(modelValue.value.end_date ? new Date(modelValue.value.end_date) : null)\n\nconst showPicker = ref(false)\nconst pickerRef = ref(null)\nonClickOutside(pickerRef, () => (showPicker.value = false))\n\nconst openPicker = () => {\n\tif (mode !== 'read') showPicker.value = true\n}\n\nconst formatDate = (d: Date | null): string => {\n\tif (!d) return ''\n\treturn `${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()}`\n}\n\nconst rangeDisplay = computed(() => {\n\tconst s = formatDate(startDate.value)\n\tconst e = formatDate(endDate.value)\n\tif (s && e) return `${s} — ${e}`\n\tif (s) return `${s} — ...`\n\treturn ''\n})\n\nconst displayValue = computed(() => {\n\tconst s = modelValue.value.start_date\n\tconst e = modelValue.value.end_date\n\tif (!s && !e) return ''\n\tif (s && e) return `${fmt(s)} — ${fmt(e)}`\n\tif (s) return `From ${fmt(s)}`\n\treturn `Until ${fmt(e!)}`\n})\n\nconst ensureOrder = () => {\n\tconst s = startDate.value\n\tconst e = endDate.value\n\tif (s && e && e.getTime() < s.getTime()) {\n\t\t;[startDate.value, endDate.value] = [e, s]\n\t}\n}\n\nconst toISODate = (d: Date | null): string | null => (d ? d.toISOString().split('T')[0] : null)\n\nconst emitModel = () => {\n\tmodelValue.value = {\n\t\tstart_date: toISODate(startDate.value),\n\t\tend_date: toISODate(endDate.value),\n\t}\n}\n\nconst handlePickerDate = (data: { selected: Date; start?: Date | null; end?: Date | null }) => {\n\tif (data.start) startDate.value = data.start\n\tif (data.end) {\n\t\tendDate.value = data.end\n\t\tensureOrder()\n\t\tshowPicker.value = false\n\t}\n\temitModel()\n}\n\nwatch(\n\t() => modelValue.value,\n\tnewVal => {\n\t\tstartDate.value = newVal.start_date ? new Date(newVal.start_date) : null\n\t\tendDate.value = newVal.end_date ? new Date(newVal.end_date) : null\n\t},\n\t{ deep: true }\n)\n</script>\n\n<style scoped>\n.adaterange {\n\tmin-width: 40ch;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tborder: 1px solid transparent;\n\tpadding: 0;\n\tmargin: 0;\n\tmargin-right: 1ch;\n\tposition: relative;\n\toverflow: visible;\n}\n\n.adate-input {\n\twidth: calc(100% - 1ch);\n\tbox-sizing: border-box;\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tpadding: 1ch 0.5ch 0.5ch 1ch;\n\tmargin: calc(1.15rem / 2) 0 0 0;\n\tmin-height: 1.15rem;\n\tborder-radius: 0.25rem;\n\tcursor: pointer;\n\tbackground: white;\n\tfont-size: 1rem;\n}\n\n.adate-input:focus {\n\tborder: 1px solid var(--sc-input-active-border-color);\n}\n\n.adate-input:focus + label {\n\tcolor: var(--sc-input-active-label-color);\n}\n\np,\nlabel {\n\tcolor: var(--sc-input-label-color);\n\tdisplay: block;\n\tmin-height: 1.15rem;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 1px solid transparent;\n\tmargin-bottom: 0.25rem;\n\tbox-sizing: border-box;\n}\n\np {\n\twidth: 100%;\n\tcolor: red;\n\tfont-size: 85%;\n}\n\nlabel {\n\tz-index: 0;\n\tfont-size: 80%;\n\tposition: absolute;\n\tbackground: white;\n\tmargin: calc(-1.5rem - calc(2.15rem / 2)) 0 0 1ch;\n\tpadding: 0 0.25ch 0 0.25ch;\n\tbox-sizing: border-box;\n}\n\n.picker {\n\tposition: absolute;\n\ttop: 50px;\n\tleft: 0;\n\tz-index: 1000;\n}\n</style>\n","<template>\n\t<form class=\"aform\">\n\t\t<template v-for=\"(componentObj, key) in schema\" :key=\"key\">\n\t\t\t<!-- Nested schema field (Doctype or any field with resolved schema) -->\n\t\t\t<div v-if=\"isNestedSection(componentObj)\" class=\"aform-nested-section\">\n\t\t\t\t<!-- Suppress h4 for fieldsets — they render their own legend inside AFieldset -->\n\t\t\t\t<h4 v-if=\"componentObj.label && componentObj.kind !== 'fieldset'\" class=\"aform-nested-label\">\n\t\t\t\t\t{{ componentObj.label }}\n\t\t\t\t</h4>\n\t\t\t\t<component\n\t\t\t\t\t:is=\"componentObj.component ?? 'AForm'\"\n\t\t\t\t\t:data=\"nestedData[componentObj.fieldname]\"\n\t\t\t\t\t:mode=\"resolvedMode(componentObj)\"\n\t\t\t\t\t:schema=\"componentObj.schema\"\n\t\t\t\t\t:label=\"componentObj.label\"\n\t\t\t\t\t:collapsible=\"componentObj.kind === 'fieldset' ? componentObj.collapsible : undefined\"\n\t\t\t\t\t:errors=\"errors\"\n\t\t\t\t\t@update:data=\"(val: any) => updateNestedData(componentObj.fieldname, val)\" />\n\t\t\t</div>\n\n\t\t\t<!-- Regular field -->\n\t\t\t<component\n\t\t\t\t:is=\"componentObj.component\"\n\t\t\t\tv-else-if=\"!componentObj.hidden\"\n\t\t\t\tv-model=\"childModels[key].value\"\n\t\t\t\t:style=\"fieldStyle(componentObj)\"\n\t\t\t\t:schema=\"componentObj\"\n\t\t\t\t:data=\"dataModel[componentObj.fieldname]\"\n\t\t\t\t:mode=\"resolvedMode(componentObj)\"\n\t\t\t\t:errors=\"errors?.[componentObj.fieldname]\"\n\t\t\t\tv-bind=\"componentProps(componentObj)\">\n\t\t\t</component>\n\t\t</template>\n\t</form>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, watchEffect, watch, ref } from 'vue'\n\nimport type { ResolvedField, ResolvedLink, ResolvedFieldset } from '../types'\nimport type { InteractionMode } from '@stonecrop/schema'\n\nconst emit = defineEmits(['update:schema', 'update:data'])\nconst dataModel = defineModel<Record<string, any>>('data', { required: true })\nconst {\n\tschema,\n\tmode = 'edit',\n\terrors,\n} = defineProps<{\n\tschema: ResolvedField[]\n\tmode?: InteractionMode\n\t/** Inline validation errors keyed by fieldname. Fed by the host; the form stays store-agnostic. */\n\terrors?: Record<string, string[]>\n}>()\n\nconst isNestedSection = (componentObj: ResolvedField): componentObj is ResolvedLink | ResolvedFieldset =>\n\t(componentObj.kind === 'link' || componentObj.kind === 'fieldset') &&\n\t'schema' in componentObj &&\n\tArray.isArray(componentObj.schema) &&\n\tcomponentObj.schema.length > 0\n\n// Reactive nested data refs for two-way binding with nested AForm instances\nconst nestedData = ref<Record<string, any>>({})\n\n// Sync external dataModel changes into nestedData (one-way, no emit back).\n// Uses a shallow watch so only top-level object replacement (e.g. parent reset)\n// triggers a sync — property mutations from within are handled by updateNestedData.\nwatch(\n\t() => dataModel.value,\n\tnewData => {\n\t\tif (!schema || !newData) return\n\t\tschema.forEach(field => {\n\t\t\tif (isNestedSection(field)) {\n\t\t\t\tnestedData.value[field.fieldname] = newData[field.fieldname] ?? {}\n\t\t\t}\n\t\t})\n\t},\n\t{ immediate: true }\n)\n\n// Called by the nested <AForm>'s @update:data handler.\n// Updates nestedData locally and propagates upward in one step,\n// avoiding the watchEffect feedback loop that occurred with v-model.\nconst updateNestedData = (fieldname: string, val: any) => {\n\tnestedData.value[fieldname] = val\n\tif (dataModel.value) {\n\t\tdataModel.value[fieldname] = val\n\t\temit('update:data', { ...dataModel.value })\n\t}\n}\n\nconst componentProps = (componentObj: ResolvedField) => {\n\tconst propsToPass: Record<string, any> = {}\n\tfor (const [key, value] of Object.entries(componentObj)) {\n\t\t// 'mode' is excluded here because it is handled by resolvedMode()\n\t\t// and passed explicitly via :mode to avoid conflicting with the form-level defaults.\n\t\tif (!['component', 'primaryKey', 'computed', 'language', 'hidden', 'mode', 'width'].includes(key)) {\n\t\t\tpropsToPass[key] = value\n\t\t}\n\t}\n\n\t// A table sources its rows from the data model, never from the schema. `kind` is the only\n\t// check: every path into AForm sets it (Zod's injectKind, Doctype.fromObject's\n\t// normalizeFieldKind, and the registry), and hand-built ResolvedTable literals declare it.\n\tif (componentObj.kind === 'table') {\n\t\tpropsToPass['rows'] = dataModel.value[componentObj.fieldname] || []\n\t}\n\n\treturn propsToPass\n}\n\nconst fieldStyle = (componentObj: ResolvedField): Record<string, string> => {\n\tif (componentObj.kind !== 'field') return {}\n\tconst width = componentObj.width\n\tif (!width) return {}\n\treturn { flexBasis: width, width }\n}\n\nconst effectiveFormMode = computed(() => mode ?? 'edit')\n\n// Resolve the effective mode for a schema field, allowing per-field overrides\nfunction resolvedMode(componentObj: ResolvedField): InteractionMode {\n\tconst fieldMode = componentObj.mode\n\tif (fieldMode) return fieldMode\n\treturn effectiveFormMode.value\n}\n\n// Create stable computed refs array to avoid recreation on every access\nconst childModelsCache = ref<ReturnType<typeof computed>[]>([])\n\n// Watch for schema changes and update cache (avoiding side effects in computed)\nwatchEffect(() => {\n\tif (!schema) return\n\n\t// Recreate cache only if length changed\n\tif (childModelsCache.value.length !== schema.length) {\n\t\tchildModelsCache.value = schema.map((_val, i) => {\n\t\t\treturn computed({\n\t\t\t\tget() {\n\t\t\t\t\treturn dataModel.value?.[schema[i].fieldname]\n\t\t\t\t},\n\t\t\t\tset: newValue => {\n\t\t\t\t\tconst fieldname = schema[i].fieldname\n\t\t\t\t\tif (fieldname && dataModel.value) {\n\t\t\t\t\t\tdataModel.value[fieldname] = newValue\n\t\t\t\t\t\temit('update:data', { ...dataModel.value })\n\t\t\t\t\t}\n\t\t\t\t\temit('update:schema', schema)\n\t\t\t\t},\n\t\t\t})\n\t\t})\n\t}\n})\n\n// Computed just returns the cached models (no side effects)\nconst childModels = computed(() => childModelsCache.value)\n</script>\n\n<style>\n/* global styles for aform */\n.aform input {\n\tfont-family: var(--sc-font-family);\n\tborder: none;\n}\n.aform_form-element {\n\tpadding: 0;\n\tmargin: 0;\n\tposition: relative;\n\tbox-sizing: border-box;\n\tflex-grow: 1;\n\tmin-width: 20ch;\n\t/* margin-bottom: 1rem; */\n}\n.aform__grid--full {\n\tflex-basis: 100%;\n\twidth: 100%;\n}\n.aform_input-field {\n\toutline: 1px solid var(--sc-input-border-color);\n\toutline-offset: -1px;\n\tfont-size: 1rem;\n\tpadding: 0.5rem;\n\tmargin: 0 0 0 0;\n\tborder-radius: 0;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tmin-height: auto;\n\tposition: relative;\n\tcolor: var(--sc-cell-text-color);\n\tbackground: var(--sc-input-field-background);\n\tfont-family: var(--sc-font-family);\n}\n.aform_input-field:focus {\n\toutline: 1px solid var(--sc-input-active-border-color);\n}\n\n.aform_display-value {\n\tdisplay: block;\n\tpadding: 0.5rem;\n\tmin-height: 2rem;\n\tcolor: var(--sc-cell-text-color);\n\tword-break: break-word;\n}\n\n.aform_input-field:focus + .aform_field-label {\n\tcolor: var(--sc-input-active-label-color);\n}\n\n.aform_field-label {\n\tcolor: var(--sc-input-label-color);\n\tdisplay: inline-block;\n\tposition: absolute;\n\tpadding: 0 0.25rem;\n\tmargin: 0rem;\n\tz-index: 1;\n\tfont-size: 0.7rem;\n\tfont-weight: 300;\n\tletter-spacing: 0.05rem;\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-background) 50%);\n\twidth: auto;\n\tbox-sizing: border-box;\n\tbackground: white;\n\tmargin: 0;\n\tgrid-row: 1;\n\ttop: 0;\n\tleft: 10px;\n\tborder: none;\n\tline-height: 0;\n\ttransform: translateY(-50%);\n}\n.aform_input-field:disabled,\n.aform_checkbox-container:has(.aform_checkbox:disabled) {\n\tbackground: var(--sc-input-field-disabled-background);\n}\n.aform_input-field:disabled + .aform_field-label,\n.aform_checkbox-container:has(.aform_checkbox:disabled) + .aform_field-label {\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-disabled-background) 50%);\n}\n.aform_input-field:disabled ~ p.aform_error,\n.aform_checkbox-container:has(.aform_checkbox:disabled) ~ p.aform_error {\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-disabled-background) 50%);\n}\n.aform_field-label::after {\n\tmargin: 0;\n\tpadding: 0;\n\tbox-sizing: border-box;\n\tcontent: '';\n\tline-height: normal;\n}\np.aform_error {\n\t/* v-show toggles visibility per field; base display must be visible (was stuck at `none`,\n\t which overrode v-show and left every field error dormant). */\n\tdisplay: inline-block;\n\tbackground: linear-gradient(var(--sc-form-background) 50%, var(--sc-input-field-background) 50%);\n\tpadding: 0 0.25rem;\n\tmargin: 0rem;\n\twidth: auto;\n\tcolor: var(--sc-brand-danger);\n\tfont-size: 0.7rem;\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\tline-height: 0;\n\tbackground: white;\n\tpadding: 0.25rem;\n\ttransform: translate(-1rem, -50%);\n\tmargin: 0;\n}\n</style>\n\n<style scoped>\n.aform {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 1rem;\n\tpadding: 1rem;\n\tborder: 1px solid var(--sc-form-border);\n\tborder-left: 4px solid var(--sc-form-border);\n\tmargin-bottom: 1rem;\n\tmax-width: 100%;\n}\n@media screen and (max-width: 400px) {\n\t.aform {\n\t\tflex-direction: column;\n\t}\n}\n\n/* Nested form section */\n.aform-nested-section {\n\twidth: 100%;\n\tpadding: 0.5rem 0;\n}\n\n.aform-nested-label {\n\tfont-size: 0.9rem;\n\tfont-weight: 600;\n\tmargin: 0 0 0.5rem 0;\n\tcolor: var(--sc-input-label-color, #666);\n}\n\n.aform-nested-section .aform {\n\tborder-left-width: 2px;\n\tmargin-left: 0.5rem;\n}\n</style>\n","<template>\n\t<button class=\"collapse-button\" :class=\"collapsed ? 'rotated' : 'unrotated'\">×</button>\n</template>\n\n<script setup lang=\"ts\">\ndefineProps<{ collapsed: boolean }>()\n</script>\n\n<style scoped>\n.collapse-button {\n\twidth: 2ch;\n\tmin-width: calc(66px - 4ch);\n\tbackground-color: transparent;\n\tfont-size: 150%;\n\ttext-align: center;\n\tborder: none;\n\tmargin-top: -0.5rem;\n}\n.rotated {\n\ttransform: rotate(45deg);\n\t-webkit-transform: rotate(45deg);\n\t-moz-transform: rotate(45deg);\n\t-ms-transform: rotate(45deg);\n\t-o-transform: rotate(45deg);\n\ttransition: transform 250ms;\n\ttransform-origin: center center;\n}\n.unrotated {\n\ttransform: rotate(0deg);\n\t-webkit-transform: rotate(0deg);\n\t-moz-transform: rotate(0deg);\n\t-ms-transform: rotate(0deg);\n\t-o-transform: rotate(0deg);\n\ttransition: transform 250ms;\n}\n</style>\n","<template>\n\t<fieldset>\n\t\t<legend v-if=\"label || collapsible\" @click=\"toggleCollapse\" @submit=\"toggleCollapse\">\n\t\t\t{{ label }}\n\t\t\t<CollapseButton v-if=\"collapsible\" :collapsed=\"collapsed\" />\n\t\t</legend>\n\t\t<slot :collapsed=\"collapsed\">\n\t\t\t<AForm v-show=\"!collapsed\" v-model:data=\"formData\" :schema=\"formSchema\" :mode=\"mode\" />\n\t\t</slot>\n\t</fieldset>\n</template>\n\n<script setup lang=\"ts\">\nimport type { InteractionMode } from '@stonecrop/schema'\nimport { ref } from 'vue'\n\nimport AForm from '../AForm.vue'\nimport CollapseButton from '../base/CollapseButton.vue'\nimport type { ResolvedField } from '../../types'\n\nconst {\n\tschema,\n\tlabel = undefined,\n\tcollapsible,\n\tdata = {},\n\tmode = 'edit',\n} = defineProps<{\n\tschema: ResolvedField[]\n\tlabel?: string\n\tcollapsible?: boolean\n\tdata?: Record<string, any>\n\t/** Rendering mode forwarded to the inner AForm */\n\tmode?: InteractionMode\n}>()\n\nconst collapsed = ref(false)\nconst formData = ref(data || [])\nconst formSchema = ref(schema)\n\nconst toggleCollapse = (event: Event) => {\n\tevent.preventDefault()\n\tif (collapsible) {\n\t\tcollapsed.value = !collapsed.value\n\t}\n}\n\ndefineExpose({ collapsed })\n</script>\n\n<style scoped>\nfieldset {\n\tmax-width: 100%;\n\twidth: 100%;\n\tmargin-right: 2ch;\n\tborder: 1px solid transparent;\n\tborder-bottom: 1px solid var(--sc-gray-50);\n}\n\nlegend {\n\twidth: 100%;\n\theight: 1.15rem;\n\tborder: 1px solid transparent;\n\tpadding-bottom: 0.5rem;\n\tfont-size: 110%;\n\tfont-weight: 600;\n\tuser-select: none;\n}\n\n.collapse-button {\n\tfloat: right;\n}\n</style>\n","<template>\n\t<div class=\"aform_form-element aform_file-attach aform__grid--full\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<template v-if=\"files\">\n\t\t\t\t<div class=\"aform_file-attach-feedback\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<b>{{ fileLengthText }}</b>\n\t\t\t\t\t</p>\n\t\t\t\t\t<li v-for=\"file of files\" :key=\"file.name\">{{ file.name }}</li>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t\t<span v-else class=\"aform_display-value\">No file selected</span>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<template v-if=\"files\">\n\t\t\t\t<div class=\"aform_file-attach-feedback\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\tYou have selected: <b>{{ fileLengthText }}</b>\n\t\t\t\t\t</p>\n\t\t\t\t\t<li v-for=\"file of files\" :key=\"file.name\">\n\t\t\t\t\t\t{{ file.name }}\n\t\t\t\t\t</li>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t\t<button type=\"button\" class=\"aform_form-btn\" :disabled=\"mode === 'read'\" @click=\"open()\">\n\t\t\t\t{{ label }}\n\t\t\t</button>\n\t\t\t<button type=\"button\" :disabled=\"!files || mode === 'read'\" class=\"aform_form-btn\" @click=\"reset()\">Reset</button>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useFileDialog } from '@vueuse/core'\nimport { computed } from 'vue'\n\nimport type { ComponentProps } from '../../types'\n\nconst { label, mode } = defineProps<ComponentProps>()\nconst { files, open, reset, onChange } = useFileDialog()\n\nconst fileLengthText = computed(() => {\n\tconst count = files.value?.length ?? 0\n\treturn `${count} ${count === 1 ? 'file' : 'files'}`\n})\n\nonChange(changedFiles => changedFiles)\n</script>\n\n<style scoped>\n.aform_file-attach {\n\tpadding: 1rem;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 1rem;\n\tflex-direction: row;\n\tjustify-content: center;\n\talign-items: center;\n\tborder: 1px dashed var(--sc-input-border-color);\n\twidth: 100%;\n}\n\n@media screen and (max-width: 400px) {\n\t.aform_file-attach > .aform_form-btn {\n\t\twidth: 100%;\n\t}\n}\n\n.aform_file-attach-feedback {\n\tcolor: var(--sc-input-label-color);\n\twidth: 100%;\n\tpadding: 0.5rem;\n\ttext-align: center;\n\talign-self: center;\n\n\t& > li {\n\t\tlist-style: none;\n\t\tfont-style: italic;\n\t}\n\t& > p {\n\t\tmargin-top: 0;\n\t}\n}\n\n.aform_form-btn {\n\tpadding: 0.5rem 2rem;\n\twidth: auto;\n\tborder: 1px solid var(--sc-input-border-color);\n\tcolor: var(--sc-input-label-color);\n\tcursor: pointer;\n\tbackground-color: white;\n}\n\n.aform_form-btn:disabled {\n\tbackground-color: var(--sc-gray-5);\n}\n</style>\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ inputNumber ?? '' }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tv-model=\"inputNumber\"\n\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\ttype=\"number\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:required=\"required\" />\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { ComponentProps } from '../../types'\n\nconst { label, required, mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst inputNumber = defineModel<number>()\n</script>\n","<template>\n\t<div class=\"aform_form-element aquantity\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ displayText }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<div class=\"aquantity__row\">\n\t\t\t\t<div class=\"aquantity__field aquantity__field--qty\">\n\t\t\t\t\t<div class=\"aquantity__group\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t:id=\"uuid\"\n\t\t\t\t\t\t\tv-model.number=\"qty\"\n\t\t\t\t\t\t\tclass=\"aquantity__qty\"\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t\t\t:required=\"required\"\n\t\t\t\t\t\t\t@keydown=\"onQtyKeydown\"\n\t\t\t\t\t\t\t@paste=\"onQtyPaste\" />\n\t\t\t\t\t\t<div v-on-click-outside=\"closeDropdown\" class=\"aquantity__uom\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t:id=\"`${uuid}-uom`\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"aquantity__uom-toggle\"\n\t\t\t\t\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\t\t\t\t:aria-expanded=\"dropdown.open\"\n\t\t\t\t\t\t\t\t:aria-activedescendant=\"\n\t\t\t\t\t\t\t\t\tdropdown.open && dropdown.activeIndex >= 0 ? `${uuid}-uom-opt-${dropdown.activeIndex}` : undefined\n\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\t@click=\"toggleDropdown\"\n\t\t\t\t\t\t\t\t@keydown.down.prevent=\"moveActive(1)\"\n\t\t\t\t\t\t\t\t@keydown.up.prevent=\"moveActive(-1)\"\n\t\t\t\t\t\t\t\t@keydown.enter.prevent=\"selectActive\"\n\t\t\t\t\t\t\t\t@keydown.esc=\"closeDropdown\">\n\t\t\t\t\t\t\t\t<span class=\"aquantity__uom-value\">{{ uom || uomLabel }}</span>\n\t\t\t\t\t\t\t\t<span class=\"aquantity__caret\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<ul v-show=\"dropdown.open\" class=\"aquantity__uom-menu\" role=\"listbox\" :aria-label=\"uomLabel\">\n\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\tv-for=\"(option, i) in uoms\"\n\t\t\t\t\t\t\t\t\t:id=\"`${uuid}-uom-opt-${i}`\"\n\t\t\t\t\t\t\t\t\t:key=\"option\"\n\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\t:aria-selected=\"option === uom\"\n\t\t\t\t\t\t\t\t\tclass=\"aquantity__uom-option\"\n\t\t\t\t\t\t\t\t\t:class=\"{ 'is-active': i === dropdown.activeIndex }\"\n\t\t\t\t\t\t\t\t\t@mouseenter=\"dropdown.activeIndex = i\"\n\t\t\t\t\t\t\t\t\t@click=\"selectUom(option)\">\n\t\t\t\t\t\t\t\t\t{{ option }}\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"aquantity__row aquantity__row--stock\">\n\t\t\t\t<div class=\"aquantity__field aquantity__field--stock-uom\">\n\t\t\t\t\t<input :value=\"modelValue.stockUom\" class=\"aform_input-field aquantity__stock-field\" type=\"text\" disabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ stockUomLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"aquantity__field aquantity__field--stock-qty\">\n\t\t\t\t\t<input :value=\"modelValue.stockQty\" class=\"aform_input-field aquantity__stock-field\" type=\"number\" disabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ stockQtyLabel }}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"aquantity__field aquantity__field--conversion\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:value=\"modelValue.conversionFactor\"\n\t\t\t\t\t\tclass=\"aform_input-field aquantity__stock-field\"\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tdisabled />\n\t\t\t\t\t<label class=\"aform_field-label\">{{ conversionFactorLabel }}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<p v-show=\"validation.errorMessage\" class=\"aform_error\" v-html=\"validation.errorMessage\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { vOnClickOutside } from '@vueuse/components'\nimport { computed, reactive } from 'vue'\n\nimport type { ComponentProps, QuantityOptions, QuantityValue } from '../../types'\n\nconst {\n\tlabel,\n\trequired,\n\tmode,\n\tuuid,\n\tvalidation = { errorMessage: '&nbsp;' },\n\toptions = {},\n\tuomLabel = 'UOM',\n\tstockUomLabel = 'Stock UOM',\n\tstockQtyLabel = 'Stock Qty',\n\tconversionFactorLabel = 'Conversion Factor',\n} = defineProps<\n\tComponentProps & {\n\t\toptions?: QuantityOptions\n\t\tuomLabel?: string\n\t\tstockUomLabel?: string\n\t\tstockQtyLabel?: string\n\t\tconversionFactorLabel?: string\n\t}\n>()\n\nconst modelValue = defineModel<QuantityValue>({\n\tdefault: () => ({ qty: 0, uom: '', stockQty: 0, stockUom: '', conversionFactor: 1 }),\n})\n\nconst uoms = computed(() => options.uoms ?? [])\n\n// Round to shed binary floating-point noise (e.g. 0.1 * 3 → 0.30000000000000004) while\n// preserving any legitimate decimal places.\nconst roundQty = (value: number): number => Number(value.toFixed(6))\n\nconst resolveConversionFactor = (uom: string): number => {\n\tconst stockUom = options.stockUom ?? modelValue.value.stockUom\n\tif (!uom || uom === stockUom) return 1\n\tconst mapped = options.conversionFactors?.[uom]\n\tif (mapped !== undefined) return mapped\n\t// UOM absent from the conversion map: keep the stored factor only when the unit is\n\t// unchanged (e.g. editing qty on a loaded value, so the factor round-trips). Switching\n\t// to a new, unmapped unit resets to 1 rather than silently reusing the previous factor.\n\tif (uom === modelValue.value.uom) return modelValue.value.conversionFactor ?? 1\n\treturn 1\n}\n\nconst recompute = (qty: number, uom: string) => {\n\tconst conversionFactor = resolveConversionFactor(uom)\n\tmodelValue.value = {\n\t\tqty,\n\t\tuom,\n\t\tconversionFactor,\n\t\tstockUom: options.stockUom ?? modelValue.value.stockUom,\n\t\tstockQty: roundQty(qty * conversionFactor),\n\t}\n}\n\nconst qty = computed({\n\tget: () => modelValue.value?.qty ?? 0,\n\tset: (value: number) => recompute(value, modelValue.value?.uom ?? ''),\n})\n\nconst uom = computed({\n\tget: () => modelValue.value?.uom ?? '',\n\tset: (value: string) => recompute(modelValue.value?.qty ?? 0, value),\n})\n\nconst qtyNavigationKeys = new Set([\n\t'Backspace',\n\t'Delete',\n\t'Tab',\n\t'Escape',\n\t'Enter',\n\t'ArrowLeft',\n\t'ArrowRight',\n\t'ArrowUp',\n\t'ArrowDown',\n\t'Home',\n\t'End',\n])\n\nconst onQtyKeydown = (event: KeyboardEvent) => {\n\tif (event.ctrlKey || event.metaKey || event.altKey) return\n\tif (qtyNavigationKeys.has(event.key)) return\n\tif (/^[0-9]$/.test(event.key)) return\n\tconst input = event.target as HTMLInputElement\n\tif (event.key === '.' && !input.value.includes('.')) return\n\tevent.preventDefault()\n}\n\nconst onQtyPaste = (event: ClipboardEvent) => {\n\tconst pasted = event.clipboardData?.getData('text') ?? ''\n\tif (!/^\\d*\\.?\\d*$/.test(pasted)) event.preventDefault()\n}\n\nconst dropdown = reactive({ open: false, activeIndex: -1 })\n\nconst openDropdown = () => {\n\tdropdown.activeIndex = Math.max(uoms.value.indexOf(uom.value), 0)\n\tdropdown.open = true\n}\n\nconst closeDropdown = () => {\n\tdropdown.open = false\n}\n\nconst toggleDropdown = () => {\n\tif (dropdown.open) closeDropdown()\n\telse openDropdown()\n}\n\nconst selectUom = (value: string) => {\n\tuom.value = value\n\tcloseDropdown()\n}\n\nconst moveActive = (delta: number) => {\n\tif (!dropdown.open) {\n\t\topenDropdown()\n\t\treturn\n\t}\n\tconst length = uoms.value.length\n\tif (!length) return\n\tdropdown.activeIndex = (dropdown.activeIndex + delta + length) % length\n}\n\nconst selectActive = () => {\n\tif (!dropdown.open) {\n\t\topenDropdown()\n\t\treturn\n\t}\n\tconst option = uoms.value[dropdown.activeIndex]\n\tif (option !== undefined) selectUom(option)\n}\n\nconst showStock = computed(() => {\n\tconst v = modelValue.value\n\treturn !!v?.stockUom && (v.uom !== v.stockUom || v.qty !== v.stockQty)\n})\n\nconst displayText = computed(() => {\n\tconst v = modelValue.value\n\tif (!v || !v.uom) return '—'\n\tconst base = `${v.qty} ${v.uom}`\n\treturn showStock.value ? `${base} (${v.stockQty} ${v.stockUom})` : base\n})\n</script>\n\n<style scoped>\n.aquantity__row {\n\tdisplay: flex;\n\tgap: 1ch;\n}\n\n.aquantity__row--stock {\n\tmargin-top: 1.5rem;\n}\n\n.aquantity__field {\n\tposition: relative;\n\tflex: 1;\n\tmin-width: 0;\n}\n\n.aquantity__group {\n\tdisplay: flex;\n\talign-items: stretch;\n\twidth: 100%;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n}\n\n.aquantity__group:focus-within {\n\tborder-color: var(--sc-input-active-border-color);\n}\n\n.aquantity__qty {\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tpadding: 0.5ch 1ch;\n\tbackground: transparent;\n\tborder-radius: 0.25rem 0 0 0.25rem;\n\tappearance: textfield;\n\t-moz-appearance: textfield;\n}\n\n.aquantity__qty::-webkit-outer-spin-button,\n.aquantity__qty::-webkit-inner-spin-button {\n\tappearance: none;\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n\n.aquantity__uom {\n\tposition: relative;\n\tflex: 0 0 auto;\n\tborder-left: 1px solid var(--sc-input-border-color);\n}\n\n.aquantity__uom-toggle {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 0.75ch;\n\theight: 100%;\n\tpadding: 0.5ch 1ch;\n\tbackground: var(--sc-gray-5);\n\tborder: none;\n\tborder-radius: 0 0.25rem 0.25rem 0;\n\twhite-space: nowrap;\n\tcursor: pointer;\n}\n\n.aquantity__uom-toggle:disabled {\n\tcursor: not-allowed;\n\tcolor: var(--sc-gray-50, #888);\n}\n\n.aquantity__caret {\n\tdisplay: inline-block;\n\twidth: 0;\n\theight: 0;\n\tborder-left: 0.3em solid transparent;\n\tborder-right: 0.3em solid transparent;\n\tborder-top: 0.3em solid currentColor;\n}\n\n.aquantity__uom-menu {\n\tposition: absolute;\n\ttop: 100%;\n\tright: 0;\n\tz-index: 100;\n\tmin-width: 100%;\n\tmargin: 0.15rem 0 0 0;\n\tpadding: 0.25rem 0;\n\tlist-style: none;\n\tbackground: var(--sc-input-field-background, #fff);\n\tborder: 1px solid var(--sc-input-active-border-color);\n\tborder-radius: 0.25rem;\n}\n\n.aquantity__uom-option {\n\tpadding: 0.4ch 1ch;\n\twhite-space: nowrap;\n\tcursor: pointer;\n}\n\n.aquantity__uom-option.is-active,\n.aquantity__uom-option:hover {\n\tbackground-color: var(--sc-row-color-zebra-light);\n}\n\n.aquantity__stock-field {\n\twidth: 100%;\n\tfont-size: 1rem;\n\tpadding: 0.5ch 1ch;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n\toutline: none;\n}\n\n.aquantity__stock-field:disabled {\n\tcolor: var(--sc-gray-50, #888);\n}\n</style>\n","import type { DirectiveBinding } from 'vue'\n\nimport { deserializeFunction } from '../utils/deserialize'\n\n/**\n * Extracts a mask function from a stringified function\n * @param mask - Mask string\n * @returns Mask function, or undefined if the string is not a valid function expression\n */\nfunction extractMaskFn(mask: string): ((locale: any) => string) | undefined {\n\ttry {\n\t\treturn deserializeFunction<(locale: any) => string>(mask)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\n/**\n * Gets the mask for a given directive binding\n * @param binding - Binding object from directive hook\n * @returns Mask string\n */\nfunction getMask(binding: DirectiveBinding<string>) {\n\tconst mask = binding.value\n\tif (!mask) return undefined\n\n\tconst maskFn = extractMaskFn(mask)\n\tif (maskFn) {\n\t\t// TODO: (state) replace with state management;\n\t\t// pass the entire form/table data to the function\n\t\t// Vue directive reads arbitrary fields off host component instance; type is unknown at this layer.\n\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion\n\t\tconst instance = binding.instance as Record<string, unknown> | null | undefined\n\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion\n\t\tconst locale = instance?.['locale'] as string | undefined\n\t\treturn maskFn(locale)\n\t}\n\n\treturn mask\n}\n\n/**\n * Unmasks the input string\n * @param input - Input string\n * @param maskToken - Mask token character\n * @returns Unmasked input string\n */\nfunction unmaskInput(input: string, maskToken?: string) {\n\tif (!maskToken) {\n\t\tmaskToken = '#'\n\t}\n\n\tlet unmaskedInput = input\n\tconst maskChars = [maskToken, '/', '-', '(', ')', ' ']\n\n\tfor (const char of maskChars) {\n\t\tunmaskedInput = unmaskedInput.replaceAll(char, '')\n\t}\n\n\treturn unmaskedInput\n}\n\n/**\n * Fills the mask with the input string\n * @param input - Input string\n * @param mask - Mask string\n * @param maskToken - Mask token character\n * @returns Masked input string\n */\nfunction fillMask(input: string, mask: string, maskToken?: string) {\n\tif (!maskToken) {\n\t\tmaskToken = '#'\n\t}\n\n\tlet replacement = mask\n\tfor (const inputChar of input) {\n\t\tconst replaceIndex = replacement.indexOf(maskToken)\n\t\tif (replaceIndex !== -1) {\n\t\t\tconst prefix = replacement.substring(0, replaceIndex)\n\t\t\tconst suffix = replacement.substring(replaceIndex + 1)\n\t\t\treplacement = prefix + inputChar + suffix\n\t\t}\n\t}\n\n\treturn replacement.slice(0, mask.length)\n}\n\n/**\n * Applies a mask to an input element\n * @param el - Input element\n * @param binding - Binding object from directive hook\n * @returns void\n * @public\n */\nexport function useStringMask(el: HTMLInputElement, binding: DirectiveBinding<string>) {\n\tconst mask = getMask(binding)\n\tif (!mask) return\n\n\tconst maskToken = '#'\n\tconst inputText = el.value\n\n\t// process input value with mask\n\tconst unmaskedInput = unmaskInput(inputText, maskToken)\n\tif (unmaskedInput) {\n\t\tconst replacement = fillMask(unmaskedInput, mask, maskToken)\n\n\t\t// TODO: (state) this is very opinionated;\n\t\t// most likely fixed with state management;\n\t\t// a better way could be to emit back to instance;\n\n\t\t// Vue directive reads/writes arbitrary fields on host component instance.\n\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion\n\t\tconst instance = binding.instance as Record<string, unknown> | null | undefined\n\t\tif (instance?.['maskFilled']) {\n\t\t\tinstance['maskFilled'] = !replacement.includes(maskToken)\n\t\t}\n\n\t\tel.value = replacement\n\t} else {\n\t\tel.value = mask\n\t}\n}\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value\">{{ inputText ?? '' }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<input\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tv-model=\"inputText\"\n\t\t\t\tv-mask=\"mask\"\n\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:maxlength=\"mask ? (maskFilled ? mask.length : undefined) : undefined\"\n\t\t\t\t:required=\"required\" />\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }} </label>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { /* inject, */ computed, ref } from 'vue'\n\nimport { useStringMask as vMask } from '../../directives/mask'\nimport { ComponentProps } from '../../types'\n\nconst { label, mask, required, mode, uuid, errors, validation = { errorMessage: '' } } = defineProps<ComponentProps>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\n// TODO: setup maskFilled as a computed property\nconst maskFilled = ref(true)\n\n// TODO: (state) replace with state management\n// const locale = inject<string>('locale', '')\n\nconst inputText = defineModel<number | string>()\n</script>\n","<template>\n\t<div class=\"aform_form-element\">\n\t\t<template v-if=\"mode === 'display'\">\n\t\t\t<span class=\"aform_display-value aform_textbox-display\">{{ inputText ?? '' }}</span>\n\t\t\t<label class=\"aform_field-label\">{{ label }}</label>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<textarea\n\t\t\t\t:id=\"uuid\"\n\t\t\t\tv-model=\"inputText\"\n\t\t\t\tclass=\"aform_input-field aform_textbox\"\n\t\t\t\t:placeholder=\"placeholder\"\n\t\t\t\t:rows=\"rows\"\n\t\t\t\t:maxlength=\"maxlength\"\n\t\t\t\t:disabled=\"mode === 'read'\"\n\t\t\t\t:required=\"required\"></textarea>\n\t\t\t<label class=\"aform_field-label\" :for=\"uuid\">{{ label }}</label>\n\t\t\t<p v-show=\"errorText\" class=\"aform_error\" v-html=\"errorText\"></p>\n\t\t</template>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { ComponentProps } from '../../types'\n\nconst {\n\tlabel,\n\trequired,\n\tmode,\n\tuuid,\n\terrors,\n\tplaceholder = '',\n\trows = 4,\n\tmaxlength,\n\tvalidation = { errorMessage: '' },\n} = defineProps<\n\tComponentProps & {\n\t\t/** Placeholder shown when the field is empty */\n\t\tplaceholder?: string\n\t\t/** Visible number of text lines (maps to the textarea `rows` attribute) */\n\t\trows?: number\n\t\t/** Maximum number of characters the field will accept */\n\t\tmaxlength?: number\n\t}\n>()\n\n// Dynamic trigger errors take precedence over a static schema errorMessage; empty means the slot hides.\nconst errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))\n\nconst inputText = defineModel<string | null>()\n</script>\n\n<style scoped>\n.aform_textbox {\n\tresize: vertical;\n\tline-height: 1.5;\n\tmin-height: 4rem;\n\tfont-family: inherit;\n}\n\n.aform_textbox-display {\n\twhite-space: pre-wrap;\n}\n</style>\n","<template>\n\t<div class=\"login-container\">\n\t\t<div>\n\t\t\t<div class=\"account-container\">\n\t\t\t\t<div class=\"account-header\">\n\t\t\t\t\t<h1 id=\"account-title\">{{ headerTitle }}</h1>\n\t\t\t\t\t<p id=\"account-subtitle\">{{ headerSubtitle }}</p>\n\t\t\t\t</div>\n\n\t\t\t\t<form @submit=\"onSubmit\">\n\t\t\t\t\t<div class=\"login-form-container\">\n\t\t\t\t\t\t<div class=\"login-form-email aform_form-element\">\n\t\t\t\t\t\t\t<label id=\"login-email\" for=\"email\" class=\"aform_field-label\">Email</label>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tid=\"email\"\n\t\t\t\t\t\t\t\tv-model=\"email\"\n\t\t\t\t\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\t\t\t\t\tname=\"email\"\n\t\t\t\t\t\t\t\tplaceholder=\"name@example.com\"\n\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\tauto-capitalize=\"none\"\n\t\t\t\t\t\t\t\tauto-complete=\"email\"\n\t\t\t\t\t\t\t\tauto-correct=\"off\"\n\t\t\t\t\t\t\t\t:disabled=\"isLoading\" />\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"login-form-password aform_form-element\">\n\t\t\t\t\t\t\t<label id=\"login-password\" for=\"password\" class=\"aform_field-label\">Password</label>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tid=\"password\"\n\t\t\t\t\t\t\t\tv-model=\"password\"\n\t\t\t\t\t\t\t\tclass=\"aform_input-field\"\n\t\t\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t:disabled=\"isLoading\" />\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button class=\"btn\" :disabled=\"isLoading || !email || !password\" @click=\"onSubmit\">\n\t\t\t\t\t\t\t<span v-if=\"isLoading\" class=\"material-symbols-outlined loading-icon\">progress_activity</span>\n\t\t\t\t\t\t\t<span id=\"login-form-button\">Login</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\n\t\t\t\t<button class=\"btn\">\n\t\t\t\t\t<span id=\"forgot-password-button\">Forgot password?</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\n\nconst { headerTitle = 'Login', headerSubtitle = 'Enter your email and password to login' } = defineProps<{\n\theaderTitle?: string\n\theaderSubtitle?: string\n}>()\n\nconst emit = defineEmits(['loginFailed', 'loginSuccess'])\n\nconst email = ref('')\nconst password = ref('')\n\nconst isLoading = ref(false)\nconst loginFailed = ref(false)\n\nfunction onSubmit(event: Event) {\n\tevent.preventDefault()\n\tisLoading.value = true\n\n\t// TODO: handle submit logic, handle failure\n\n\tif (loginFailed.value) {\n\t\tisLoading.value = false\n\t\temit('loginFailed')\n\t\treturn\n\t}\n\n\tisLoading.value = false\n\temit('loginSuccess')\n}\n</script>\n\n<style scoped>\n.login-container {\n\twidth: 100%;\n\tposition: relative;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-family: var(--sc-font-family);\n}\n\n.account-container {\n\twidth: 100%;\n\tmargin-left: auto;\n\tmargin-top: 0.5rem;\n\tmargin-right: auto;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: center;\n}\n\n.account-header {\n\tdisplay: flex;\n\tflex-direction: column;\n\ttext-align: center;\n\tmargin-top: 0.5rem;\n}\n\n#account-title {\n\tfont-size: 1.5rem;\n\tline-height: 2rem;\n\tfont-weight: 600;\n\tletter-spacing: -0.025em;\n\tmargin: 0;\n}\n\n#account-subtitle {\n\tfont-size: 0.875rem;\n\tline-height: 1.25rem;\n\tmargin: 1rem;\n}\n\n.login-form-container {\n\tdisplay: grid;\n\tgap: 0.5rem;\n}\n\n.login-form-element {\n\tdisplay: grid;\n\tmargin: 0.5rem 0;\n\tposition: relative;\n}\n.login-field {\n\tpadding: 0.5rem 0.25rem 0.25rem 0.5rem;\n\toutline: 1px solid transparent;\n\tborder: 1px solid var(--sc-input-border-color);\n\tborder-radius: 0.25rem;\n\n\t&:focus {\n\t\tborder: 1px solid black;\n\t}\n}\n\n.btn {\n\tbackground-color: var(--sc-btn-color);\n\tcolor: var(--sc-btn-label-color);\n\tborder: 1px solid var(--sc-btn-border);\n\tmargin: 0.5rem 0;\n\tpadding: 0.25rem;\n\tposition: relative;\n\tcursor: pointer;\n\n\t&:hover {\n\t\tbackground-color: var(--sc-btn-hover);\n\t}\n\n\t&:disabled {\n\t\tbackground-color: var(--sc-input-field-disabled-background);\n\t}\n}\n.disabled {\n\topacity: 0.5;\n}\n.loading-icon {\n\tanimation: spin 1s linear infinite forwards;\n\tdisplay: inline-block;\n\tmargin-right: 0.2rem;\n\tline-height: 0;\n\tfont-size: 1rem;\n\tposition: relative;\n\ttop: 0.2rem;\n}\n\n/* ANIMATION */\n@keyframes spin {\n\tfrom {\n\t\ttransform: rotate(0deg);\n\t}\n\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n</style>\n","<template>\n\t<div class=\"aform-loading\">\n\t\t<div class=\"aform-loading__label\">\n\t\t\t<slot></slot>\n\t\t</div>\n\t\t<div class=\"aform-loading__bar\"></div>\n\t</div>\n</template>\n\n<style scoped>\n.aform-loading {\n\twidth: 100%;\n\tborder: 1px solid var(--sc-form-border);\n\tborder-left: 4px solid var(--sc-form-border);\n\tpadding: 1rem;\n\tmargin-bottom: 1rem;\n\tbox-sizing: border-box;\n\tposition: relative;\n\toverflow: hidden;\n\tbackground: var(--sc-input-field-background, #fff);\n}\n\n.aform-loading__label {\n\tfont-size: 0.9rem;\n\tcolor: var(--sc-cell-text-color);\n\tz-index: 1;\n\tposition: relative;\n}\n\n.aform-loading__label:not(:empty)::after {\n\tcontent: '...';\n\tanimation: ellipsis 2s infinite;\n}\n\n.aform-loading__bar {\n\twidth: 100%;\n\theight: 100%;\n\tposition: absolute;\n\tleft: -100%;\n\ttop: 0;\n\tbackground: linear-gradient(\n\t\t90deg,\n\t\trgba(var(--sc-table-loading-color), 0) 0%,\n\t\trgba(var(--sc-table-loading-color), 1) 50%,\n\t\trgba(var(--sc-table-loading-color), 0) 100%\n\t);\n\tanimation: bar-sweep 2s infinite;\n\tz-index: 0;\n}\n\n@keyframes bar-sweep {\n\t0% {\n\t\tleft: -100%;\n\t}\n\t100% {\n\t\tleft: 100%;\n\t}\n}\n\n@keyframes ellipsis {\n\t0%,\n\t20% {\n\t\tcontent: '';\n\t}\n\t40% {\n\t\tcontent: '.';\n\t}\n\t60% {\n\t\tcontent: '..';\n\t}\n\t80%,\n\t100% {\n\t\tcontent: '...';\n\t}\n}\n</style>\n","export type * from '@stonecrop/atable/types'\nexport { deserializeFunction } from './utils/deserialize'\nimport { install as installATable } from '@stonecrop/atable'\nimport type { App } from 'vue'\n\nimport ACheckbox from './components/form/ACheckbox.vue'\nimport ACurrencyInput from './components/form/ACurrencyInput.vue'\nimport ADate from './components/form/ADate.vue'\nimport ADropdown from './components/form/ADropdown.vue'\nimport ADatePicker from './components/form/ADatePicker.vue'\nimport ADateTime from './components/form/ADateTime.vue'\nimport ADateSelection from './components/form/ADateSelection.vue'\nimport ADuration from './components/form/ADuration.vue'\nimport ADateRange from './components/form/ADateRange.vue'\nimport AFieldset from './components/form/AFieldset.vue'\nimport AFileAttach from './components/form/AFileAttach.vue'\nimport AForm from './components/AForm.vue'\nimport AFormLink from './components/form/AFormLink.vue'\nimport ANumericInput from './components/form/ANumericInput.vue'\nimport AQuantityInput from './components/form/AQuantityInput.vue'\nimport ATextInput from './components/form/ATextInput.vue'\nimport ATextboxInput from './components/form/ATextboxInput.vue'\nimport Login from './components/utilities/Login.vue'\nimport AFormLoading from './components/AFormLoading.vue'\n\nexport type * from './types'\n\n/**\n * Install all AForm components\n * @param app - Vue app instance\n * @public\n */\nfunction install(app: App /* options */) {\n\tapp.use(installATable) // Install ATable components for use within AForm\n\n\tapp.component('ACheckbox', ACheckbox)\n\tapp.component('ACurrencyInput', ACurrencyInput)\n\tapp.component('ADate', ADate)\n\tapp.component('ADropdown', ADropdown)\n\tapp.component('ADatePicker', ADatePicker)\n\tapp.component('ADateTime', ADateTime)\n\tapp.component('ADateRange', ADateRange)\n\tapp.component('ADateSelection', ADateSelection)\n\tapp.component('AFieldset', AFieldset)\n\tapp.component('AFileAttach', AFileAttach)\n\tapp.component('AForm', AForm)\n\tapp.component('AFormLink', AFormLink)\n\tapp.component('ANumericInput', ANumericInput)\n\tapp.component('AQuantityInput', AQuantityInput)\n\tapp.component('ATextInput', ATextInput)\n\tapp.component('ATextboxInput', ATextboxInput)\n\tapp.component('ADuration', ADuration)\n\tapp.component('AFormLoading', AFormLoading)\n}\n\nexport {\n\tACheckbox,\n\tACurrencyInput,\n\tADate,\n\tADropdown,\n\tADatePicker,\n\tADateRange,\n\tADateSelection,\n\tADuration,\n\tADateTime,\n\tAFieldset,\n\tAFileAttach,\n\tAForm,\n\tAFormLink,\n\tANumericInput,\n\tAQuantityInput,\n\tATextInput,\n\tATextboxInput,\n\tLogin,\n\tAFormLoading,\n\tinstall,\n}\n"],"names":["deserializeFunction","source","errorText","computed","__props","checkbox","_useModel","_openBlock","_createElementBlock","_hoisted_1","_Fragment","_createElementVNode","_hoisted_2","_toDisplayString","_hoisted_3","_hoisted_4","_hoisted_5","$event","listboxId","useId","modelValue","hasValidId","linkId","displayedText","id","asLinkValue","linkDisplayText","searchText","ref","dropdownOpen","loading","dropdownResults","activeIndex","navigator","inject","resolver","value","text","watch","match","displayText","r","resolved","handleNavigate","openDropdown","fn","closeDropdown","onClickOutside","onFocus","onInput","selectOption","option","selectNext","len","selectPrev","selectCurrent","_withDirectives","_hoisted_7","_renderList","i","_normalizeClass","_withModifiers","_renderSlot","_ctx","_createTextVNode","_hoisted_9","FLOAT_NOISE_DECIMALS","currencySymbol","normalizedBaseCurrency","base","resolvedBaseCurrency","baseCurrencyText","resolveExchangeRate","currencyId","baseId","baseDecimals","precision","roundAmount","recompute","amount","currencyValue","exchangeRate","currency","amountNavigationKeys","onAmountKeydown","event","input","onAmountPaste","pasted","showBase","v","currencyText","baseText","_hoisted_6","_createVNode","AFormLink","_withCtx","_hoisted_8","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_14","_hoisted_15","_hoisted_17","_hoisted_18","_hoisted_20","_vShow","numberOfRows","numberOfColumns","date","selectedDate","currentMonth","currentYear","currentDates","hoveredDate","start_date","end_date","startDateInput","useTemplateRef","endDateInput","emit","__emit","monthAndYear","getStartDate","parseDateToString","getEndDate","dateValue","validateDate","isTodaysDate","day","todaysDate","isSelectedDate","isStartDate","start","isEndDate","end","getCurrentCell","rowNo","colNo","isInDateRange","this_date","temp_end_date","getCurrentDate","hoverDate","currentIndex","preventCellSelection","populateMonth","firstOfMonth","monthStartWeekday","calendarStartDay","dayIndex","previousYear","nextYear","previousMonth","nextMonth","enterDate","enterInputDate","selectDate","emitData","testDateOrder","onMounted","nextTick","$selectedDate","$todaysDate","__expose","_cache","meridiemSelector","timeData","reactive","meridiem","emitTime","confirmTime","maxHours","minHours","hours","minutes","seconds","focusInput","target","tick","oldHours","changeMeridiem","prevHours","newRawHours","formatTime","newVal","oldVal","min","max","pasteInput","pasteAllFields","clipboardData","pastedData","timeUnits","_vModelText","provide","today","pickerStart","pickerEnd","startTimeMs","endTimeMs","mergeDateTime","timeMs","d","timePayloadToMs","payload","h","hrs","tryEmitRange","handleDate","data","handleStartTime","handleEndTime","_createBlock","ADatePicker","ADateTime","currentDate","inputDate","pickerRef","showPicker","newValue","ADateSelection","search","committedValue","dropdown","filter","filteredResults","filterResults","setResult","result","idx","item","selectNextResult","resultsLength","selectPrevResult","setCurrentResult","startDatetime","endDatetime","duration","ms","newMs","handleRange","humanDuration","s","m","displayValue","fmt","startDate","endDate","openPicker","formatDate","rangeDisplay","e","ensureOrder","toISODate","emitModel","handlePickerDate","dataModel","isNestedSection","componentObj","nestedData","newData","field","updateNestedData","fieldname","val","componentProps","propsToPass","key","fieldStyle","width","effectiveFormMode","resolvedMode","fieldMode","childModelsCache","watchEffect","_val","childModels","_resolveDynamicComponent","_mergeProps","collapsed","formData","formSchema","toggleCollapse","CollapseButton","AForm","files","open","reset","onChange","useFileDialog","fileLengthText","count","changedFiles","_unref","file","inputNumber","uoms","roundQty","resolveConversionFactor","uom","stockUom","mapped","qty","conversionFactor","qtyNavigationKeys","onQtyKeydown","onQtyPaste","toggleDropdown","selectUom","moveActive","delta","length","selectActive","showStock","_hoisted_13","_hoisted_21","_hoisted_23","extractMaskFn","mask","getMask","binding","maskFn","locale","unmaskInput","maskToken","unmaskedInput","maskChars","char","fillMask","replacement","inputChar","replaceIndex","prefix","suffix","useStringMask","el","inputText","instance","maskFilled","email","password","isLoading","loginFailed","onSubmit","install","app","installATable","ACheckbox","ACurrencyInput","ADate","ADropdown","ADateRange","AFieldset","AFileAttach","ANumericInput","AQuantityInput","ATextInput","ATextboxInput","ADuration","AFormLoading"],"mappings":"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"}