@milaboratories/uikit 2.16.3 → 2.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +31 -23
- package/.turbo/turbo-formatter$colon$check.log +1 -1
- package/.turbo/turbo-linter$colon$check.log +1 -1
- package/CHANGELOG.md +32 -0
- package/dist/components/PlAlert/PlAlert.js.map +1 -1
- package/dist/components/PlAlert/PlAlert.vue.d.ts +4 -1
- package/dist/components/PlAlert/PlAlert.vue.d.ts.map +1 -1
- package/dist/components/PlAlert/PlAlert.vue2.js +27 -24
- package/dist/components/PlAlert/PlAlert.vue2.js.map +1 -1
- package/dist/components/PlAlert/pl-alert.css +1 -1
- package/dist/components/PlDropdown/PlDropdown.js +5 -4
- package/dist/components/PlDropdown/PlDropdown.js.map +1 -1
- package/dist/components/PlDropdown/PlDropdown.style.css +1 -0
- package/dist/components/PlDropdown/PlDropdown.style.js +5 -0
- package/dist/components/PlDropdown/PlDropdown.style.js.map +1 -0
- package/dist/components/PlDropdown/PlDropdown.vue.d.ts +10 -2
- package/dist/components/PlDropdown/PlDropdown.vue.d.ts.map +1 -1
- package/dist/components/PlDropdown/PlDropdown.vue2.js +136 -110
- package/dist/components/PlDropdown/PlDropdown.vue2.js.map +1 -1
- package/dist/components/PlDropdownMulti/PlDropdownMulti.js.map +1 -1
- package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.d.ts +10 -2
- package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.d.ts.map +1 -1
- package/dist/components/PlDropdownMulti/PlDropdownMulti.vue2.js +123 -84
- package/dist/components/PlDropdownMulti/PlDropdownMulti.vue2.js.map +1 -1
- package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.js.map +1 -1
- package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue.d.ts +12 -5
- package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue.d.ts.map +1 -1
- package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue2.js +8 -1
- package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue2.js.map +1 -1
- package/dist/components/PlDropdownRef/PlDropdownRef.js.map +1 -1
- package/dist/components/PlDropdownRef/PlDropdownRef.vue.d.ts +8 -2
- package/dist/components/PlDropdownRef/PlDropdownRef.vue.d.ts.map +1 -1
- package/dist/components/PlDropdownRef/PlDropdownRef.vue2.js +8 -1
- package/dist/components/PlDropdownRef/PlDropdownRef.vue2.js.map +1 -1
- package/dist/components/PlTooltip/PlTooltip.js.map +1 -1
- package/dist/components/PlTooltip/PlTooltip.style.css +1 -1
- package/dist/components/PlTooltip/PlTooltip.style.js +1 -1
- package/dist/components/PlTooltip/PlTooltip.style.js.map +1 -1
- package/dist/components/PlTooltip/PlTooltip.vue.d.ts.map +1 -1
- package/dist/components/PlTooltip/PlTooltip.vue2.js +1 -1
- package/dist/components/PlTooltip/PlTooltip.vue2.js.map +1 -1
- package/dist/components/PlValueLabel/PlValueLabel.js +7 -0
- package/dist/components/PlValueLabel/PlValueLabel.js.map +1 -0
- package/dist/components/PlValueLabel/PlValueLabel.style.css +1 -0
- package/dist/components/PlValueLabel/PlValueLabel.style.js +5 -0
- package/dist/components/PlValueLabel/PlValueLabel.style.js.map +1 -0
- package/dist/components/PlValueLabel/PlValueLabel.vue.d.ts +45 -0
- package/dist/components/PlValueLabel/PlValueLabel.vue.d.ts.map +1 -0
- package/dist/components/PlValueLabel/PlValueLabel.vue2.js +37 -0
- package/dist/components/PlValueLabel/PlValueLabel.vue2.js.map +1 -0
- package/dist/components/PlValueLabel/__tests__/PlValueLabel.spec.d.ts +2 -0
- package/dist/components/PlValueLabel/__tests__/PlValueLabel.spec.d.ts.map +1 -0
- package/dist/components/PlValueLabel/index.d.ts +2 -0
- package/dist/components/PlValueLabel/index.d.ts.map +1 -0
- package/dist/components/PlValueLabel/index.js +1 -0
- package/dist/helpers/columnValue.d.ts +25 -0
- package/dist/helpers/columnValue.d.ts.map +1 -0
- package/dist/helpers/columnValue.js +17 -0
- package/dist/helpers/columnValue.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -30
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
- package/src/__tests__/setup.ts +10 -2
- package/src/components/PlAlert/PlAlert.vue +23 -5
- package/src/components/PlAlert/pl-alert.scss +6 -0
- package/src/components/PlDropdown/PlDropdown.vue +49 -8
- package/src/components/PlDropdown/__tests__/PlDropdown.spec.ts +95 -0
- package/src/components/PlDropdownMulti/PlDropdownMulti.vue +50 -9
- package/src/components/PlDropdownMulti/__tests__/PlDropdownMulti.spec.ts +47 -0
- package/src/components/PlDropdownMultiRef/PlDropdownMultiRef.vue +10 -3
- package/src/components/PlDropdownMultiRef/__tests__/PlDropdownMultiRef.spec.ts +2 -2
- package/src/components/PlDropdownRef/PlDropdownRef.vue +10 -3
- package/src/components/PlDropdownRef/__tests__/PlDropdownRef.spec.ts +2 -2
- package/src/components/PlTooltip/PlTooltip.vue +1 -0
- package/src/components/PlValueLabel/PlValueLabel.vue +80 -0
- package/src/components/PlValueLabel/__tests__/PlValueLabel.spec.ts +64 -0
- package/src/components/PlValueLabel/index.ts +1 -0
- package/src/helpers/columnValue.ts +43 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlDropdown.vue_vue_type_style_index_0_lang.module.js","names":["hint","PlDropdown_vue_vue_type_style_index_0_lang_module_default"],"sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a list of options\n */\nexport default {\n name: \"PlDropdown\",\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M = unknown\">\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from \"vue\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { missingValueText, missingValueTooltip, pickedValueText } from \"../../helpers/columnValue\";\nimport type { MissingValueLabel, MissingValueTooltip } from \"../../helpers/columnValue\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport { tap } from \"../../helpers/functions\";\nimport { deepEqual } from \"../../helpers/objects\";\nimport { normalizeListOptions } from \"../../helpers/utils\";\nimport type { ListOption, ListOptionNormalized, MaskIconName16, MaskIconName24 } from \"../../types\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport LongText from \"../LongText.vue\";\nimport { PlColumnLabel } from \"../PlColumnLabel\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlIcon24 } from \"../PlIcon24\";\nimport { PlSvg } from \"../PlSvg\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport OptionList from \"./OptionList.vue\";\nimport \"./pl-dropdown.scss\";\nimport type { LOption } from \"./types\";\nimport { useGroupBy } from \"./useGroupBy\";\n\nconst emit = defineEmits<{\n /**\n * Emitted when the model value is updated.\n */\n (e: \"update:modelValue\", value: M | undefined): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected value of the dropdown.\n */\n modelValue: M;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * List of available options for the dropdown\n */\n options?: Readonly<ListOption<M>[]>;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * A helper text displayed below the dropdown when there are no options yet or options is undefined (optional).\n */\n loadingOptionsHelper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Shows red border even without an error message\n */\n errorStatus?: boolean;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * Text shown in the field when `modelValue` has no matching option — e.g. its\n * upstream block was deleted. Rendered italic in error color. One text for every such value,\n * or a function giving it per value. By default, the value a column value id picks, marked\n * as not available, or \"Value not available\".\n */\n missingValueLabel?: MissingValueLabel;\n /**\n * Explains a selected value missing from the options in a tooltip over it: one text for every\n * such value, or a function giving the content per value.\n */\n missingValueTooltip?: MissingValueTooltip;\n /**\n * Enables a button to clear the selected value (default: false)\n */\n clearable?: boolean;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Custom icon (16px) class for the dropdown arrow (optional)\n */\n arrowIcon?: MaskIconName16;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: MaskIconName24;\n /**\n * Option list item size\n */\n optionSize?: \"small\" | \"medium\";\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n label: \"\",\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n showErrorMessage: true,\n placeholder: \"...\",\n missingValueLabel: undefined,\n missingValueTooltip: undefined,\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: \"small\",\n options: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst optionListRef = useTemplateRef<InstanceType<typeof OptionList>>(\"optionListRef\");\n\nconst data = reactive({\n search: \"\",\n activeIndex: -1,\n open: false,\n optionsHeight: 0,\n});\n\nconst findActiveIndex = () =>\n tap(\n orderedRef.value.findIndex((o) => deepEqual(o.value, props.modelValue)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst isLoadingOptions = computed(() => {\n return props.options === undefined;\n});\n\n/**\n * Loading spinner should not be shown when the dropdown is explicitly disabled,\n * even if options are undefined. The disabled state takes precedence.\n */\nconst showLoadingSpinner = computed(() => {\n return !props.disabled && isLoadingOptions.value;\n});\n\nconst isDisabled = computed(() => {\n if (isLoadingOptions.value) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return (props.options ?? []).findIndex((o) => deepEqual(o.value, props.modelValue));\n});\n\nconst hasValue = computed(() => {\n return props.modelValue !== undefined && props.modelValue !== null;\n});\n\nconst isMissing = computed(() => {\n return hasValue.value && selectedIndex.value === -1 && !isLoadingOptions.value;\n});\n\nconst computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n // The field renders the missing state via `missingValueLabel`; no need to\n // duplicate it as a helper error.\n return undefined;\n});\n\nconst optionsRef = computed<LOption<M>[]>(() =>\n normalizeListOptions(props.options ?? []).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })),\n);\n\nconst selectedOption = computed(() =>\n unref(optionsRef).find((o) => deepEqual(o.value, props.modelValue)),\n);\n\nconst textValue = computed(() => {\n const option = selectedOption.value;\n if (option !== undefined) return option.label;\n // A picked column value is shown by its own label while the options load.\n return isLoadingOptions.value ? pickedValueText(props.modelValue) : undefined;\n});\n\nconst missingText = computed(() => missingValueText(props.modelValue, props.missingValueLabel));\n\nconst missingHint = computed(() =>\n isMissing.value ? missingValueTooltip(props.modelValue, props.missingValueTooltip) : undefined,\n);\n\n// Native tooltip with the full selected value and its link hint. The `.input-value` layer has\n// `pointer-events: none`, so the title must sit on the field wrapper, which is\n// what actually receives the hover. A missing value with a hint has its own tooltip.\nconst fieldTitle = computed(() => {\n if (data.open) return undefined;\n if (isMissing.value) return missingHint.value === undefined ? missingText.value : undefined;\n if (textValue.value === undefined) return undefined;\n const hint = selectedOption.value?.linkHint;\n return hint ? `${textValue.value}\\n${hint}` : String(textValue.value);\n});\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && hasValue.value) {\n return \"\";\n }\n\n return textValue.value ? String(textValue.value) : props.placeholder;\n});\n\nconst filteredRef = computed(() => {\n const options = optionsRef.value;\n\n if (data.search) {\n return options.filter((o: ListOptionNormalized) => {\n const search = data.search.toLowerCase();\n\n if (o.label.toLowerCase().includes(search)) {\n return true;\n }\n\n if (o.description && o.description.toLowerCase().includes(search)) {\n return true;\n }\n\n if (typeof o.value === \"string\") {\n return o.value.toLowerCase().includes(search);\n }\n\n return o.value === data.search;\n });\n }\n\n return options;\n});\n\nconst { orderedRef, groupsRef, restRef } = useGroupBy(filteredRef, \"group\");\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst selectOption = (v: M | undefined) => {\n emit(\"update:modelValue\", v);\n data.search = \"\";\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst selectOptionWrapper = (v: unknown) => {\n selectOption(v as M | undefined);\n};\n\nconst clear = () => emit(\"update:modelValue\", undefined);\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n if (!data.open) {\n data.search = \"\";\n }\n};\n\nconst onInputFocus = () => (data.open = true);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (\n !rootRef.value?.contains(relatedTarget) &&\n !optionListRef.value?.listRef?.contains(relatedTarget)\n ) {\n data.search = \"\";\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n if (![\"ArrowDown\", \"ArrowUp\", \"Enter\", \"Escape\"].includes(e.code)) {\n return;\n } else {\n e.preventDefault();\n }\n\n const { open, activeIndex } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n rootRef.value?.focus();\n }\n\n const ordered = orderedRef.value;\n\n const { length } = ordered;\n\n if (!length) {\n return;\n }\n\n if (e.code === \"Enter\") {\n selectOption(ordered.find((it) => it.index === activeIndex)?.value);\n }\n\n const localIndex = ordered.findIndex((it) => it.index === activeIndex) ?? -1;\n\n const delta = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n const newIndex = Math.abs(localIndex + delta + length) % length;\n\n data.activeIndex = ordered[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => props.modelValue, updateActive, { immediate: true });\n\nwatch(\n () => data.open,\n (open) => (open ? input.value?.focus() : \"\"),\n);\n\nwatchPostEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n data.search; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n optionListRef.value?.scrollIntoActive();\n }\n});\n</script>\n\n<template>\n <div class=\"pl-dropdown__envelope\" @click=\"setFocusOnInput\" data-testid=\"pl-dropdown\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-dropdown\"\n data-testid=\"pl-dropdown-control\"\n :class=\"{ open: data.open, error: error || errorStatus, disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-dropdown__container\">\n <div class=\"pl-dropdown__field\" :title=\"fieldTitle\">\n <input\n ref=\"input\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n data-testid=\"pl-dropdown-input\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\" data-testid=\"pl-dropdown-value\">\n <PlTooltip\n v-if=\"isMissing && missingHint !== undefined\"\n :class=\"$style.hint\"\n position=\"top\"\n data-testid=\"pl-dropdown-value-hint\"\n >\n <LongText class=\"input-value--missing\" data-testid=\"pl-dropdown-value-missing\">\n {{ missingText }}\n </LongText>\n <template #tooltip>\n <component :is=\"missingHint\" />\n </template>\n </PlTooltip>\n <LongText\n v-else-if=\"isMissing\"\n class=\"input-value--missing\"\n data-testid=\"pl-dropdown-value-missing\"\n >\n {{ missingText }}\n </LongText>\n <PlColumnLabel v-else-if=\"textValue !== undefined\" :option=\"selectedOption\">\n <LongText>{{ textValue }}</LongText>\n </PlColumnLabel>\n </div>\n\n <div class=\"pl-dropdown__controls\">\n <PlIcon24 v-if=\"showLoadingSpinner\" name=\"loading\" data-testid=\"pl-dropdown-loading\" />\n <PlIcon16\n v-if=\"clearable && hasValue\"\n class=\"clear\"\n data-testid=\"pl-dropdown-clear\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <slot name=\"append\" />\n <div\n class=\"pl-dropdown__arrow-wrapper\"\n data-testid=\"pl-dropdown-arrow\"\n @click.stop=\"toggleOpen\"\n >\n <PlIcon24 v-if=\"arrowIconLarge\" :name=\"arrowIconLarge\" class=\"arrow-icon\" />\n <PlIcon16 v-else-if=\"arrowIcon\" :name=\"arrowIcon\" class=\"arrow-icon\" />\n <PlIcon16 v-else name=\"chevron-down\" class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\" data-testid=\"pl-dropdown-label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" data-testid=\"pl-dropdown-required\" />\n <span>{{ label }}</span>\n <PlTooltip\n v-if=\"$slots.tooltip\"\n class=\"info\"\n position=\"top\"\n data-testid=\"pl-dropdown-tooltip\"\n >\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <OptionList\n v-if=\"data.open\"\n ref=\"optionListRef\"\n :root-ref=\"rootRef!\"\n :groups=\"groupsRef\"\n :rest=\"restRef\"\n :option-size=\"optionSize\"\n :select-option=\"selectOptionWrapper\"\n />\n <DoubleContour class=\"pl-dropdown__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-dropdown__error\" data-testid=\"pl-dropdown-error\">\n {{ computedError }}\n </div>\n <div\n v-else-if=\"showLoadingSpinner && loadingOptionsHelper\"\n class=\"pl-dropdown__helper\"\n data-testid=\"pl-dropdown-helper\"\n >\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-dropdown__helper\" data-testid=\"pl-dropdown-helper\">\n {{ helper }}\n </div>\n </div>\n</template>\n\n<style module>\n.hint {\n min-width: 0;\n pointer-events: auto;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MissingValueLabel, MissingValueTooltip } from '../../helpers/columnValue';
|
|
1
2
|
import { ListOption, MaskIconName16, MaskIconName24 } from '../../types';
|
|
2
3
|
/**
|
|
3
4
|
* A component for selecting one value from a list of options
|
|
@@ -40,9 +41,16 @@ declare const __VLS_export: <M = unknown>(__VLS_props: NonNullable<Awaited<typeo
|
|
|
40
41
|
placeholder?: string;
|
|
41
42
|
/**
|
|
42
43
|
* Text shown in the field when `modelValue` has no matching option — e.g. its
|
|
43
|
-
* upstream block was deleted. Rendered italic in error color.
|
|
44
|
+
* upstream block was deleted. Rendered italic in error color. One text for every such value,
|
|
45
|
+
* or a function giving it per value. By default, the value a column value id picks, marked
|
|
46
|
+
* as not available, or "Value not available".
|
|
44
47
|
*/
|
|
45
|
-
missingValueLabel?:
|
|
48
|
+
missingValueLabel?: MissingValueLabel;
|
|
49
|
+
/**
|
|
50
|
+
* Explains a selected value missing from the options in a tooltip over it: one text for every
|
|
51
|
+
* such value, or a function giving the content per value.
|
|
52
|
+
*/
|
|
53
|
+
missingValueTooltip?: MissingValueTooltip;
|
|
46
54
|
/**
|
|
47
55
|
* Enables a button to clear the selected value (default: false)
|
|
48
56
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDropdown.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlDropdown.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"names":[],"mappings":"AA4fA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAKxF,OAAO,KAAK,EAAE,UAAU,EAAwB,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAUpG,OAAO,oBAAoB,CAAC;AAK5B;;GAEG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY,GAAK,CAAC,GAAG,OAAO,EACjC,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WA2wBO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QAjwBpD;;WAEG;oBACS,CAAC;QACb;;WAEG;gBACK,MAAM;QACd;;WAEG;kBACO,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC;;WAEG;iBACM,MAAM;QACf;;WAEG;+BACoB,MAAM;QAC7B;;WAEG;gBACK,OAAO;QACf;;WAEG;sBACW,OAAO;QACrB;;WAEG;sBACW,MAAM;QACpB;;;;;WAKG;4BACiB,iBAAiB;QACrC;;;WAGG;8BACmB,mBAAmB;QACzC;;WAEG;oBACS,OAAO;QACnB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;oBACS,cAAc;QAC1B;;WAEG;yBACc,cAAc;QAC/B;;WAEG;qBACU,OAAO,GAAG,QAAQ;QAC/B;;aAEK;wBAED,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,QAAQ;;;KAirB2E,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI;WACtB,GAAG;;iBAbE,CAAC,KAAK,IAAiB,KAAK,GAAG;;kBAC9B,CAAC,KAAK,IAAiB,KAAK,GAAG;;cA5vBvC,mBAAmB,SAAS,CAAC,GAAG,SAAS,KAAG,IAAI;EA4wBlD,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;AACzF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
|
|
@@ -13,34 +13,35 @@ import s from "../LongText.js";
|
|
|
13
13
|
import c from "../PlIcon24/PlIcon24.js";
|
|
14
14
|
import "../PlIcon24/index.js";
|
|
15
15
|
import l from "../../utils/DoubleContour.js";
|
|
16
|
-
import { useLabelNotch as
|
|
17
|
-
import { deepEqual as
|
|
18
|
-
import
|
|
19
|
-
import
|
|
16
|
+
import { useLabelNotch as ee } from "../../utils/useLabelNotch.js";
|
|
17
|
+
import { deepEqual as u } from "../../helpers/objects.js";
|
|
18
|
+
import d from "../../assets/images/required.js";
|
|
19
|
+
import { missingValueText as f, missingValueTooltip as te, pickedValueText as ne } from "../../helpers/columnValue.js";
|
|
20
|
+
import re from "./OptionList.js";
|
|
20
21
|
import './pl-dropdown.css';/* empty css */
|
|
21
|
-
import { useGroupBy as
|
|
22
|
-
import { computed as
|
|
22
|
+
import { useGroupBy as ie } from "./useGroupBy.js";
|
|
23
|
+
import { computed as p, createBlock as m, createCommentVNode as h, createElementBlock as g, createElementVNode as _, createTextVNode as v, createVNode as y, defineComponent as b, normalizeClass as x, openBlock as S, reactive as C, ref as w, renderSlot as T, resolveDynamicComponent as ae, toDisplayString as E, unref as D, useTemplateRef as oe, vModelText as se, watch as O, watchPostEffect as ce, withCtx as k, withDirectives as le, withModifiers as A } from "vue";
|
|
23
24
|
// src/components/PlDropdown/PlDropdown.vue?vue&type=script&setup=true&lang.ts
|
|
24
|
-
var
|
|
25
|
+
var ue = ["tabindex"], de = { class: "pl-dropdown__container" }, fe = ["title"], pe = ["disabled", "placeholder"], me = {
|
|
25
26
|
key: 0,
|
|
26
27
|
class: "input-value",
|
|
27
28
|
"data-testid": "pl-dropdown-value"
|
|
28
|
-
},
|
|
29
|
+
}, he = { class: "pl-dropdown__controls" }, ge = {
|
|
29
30
|
key: 0,
|
|
30
31
|
"data-testid": "pl-dropdown-label"
|
|
31
|
-
},
|
|
32
|
+
}, _e = {
|
|
32
33
|
key: 0,
|
|
33
34
|
class: "pl-dropdown__error",
|
|
34
35
|
"data-testid": "pl-dropdown-error"
|
|
35
|
-
},
|
|
36
|
+
}, ve = {
|
|
36
37
|
key: 1,
|
|
37
38
|
class: "pl-dropdown__helper",
|
|
38
39
|
"data-testid": "pl-dropdown-helper"
|
|
39
|
-
},
|
|
40
|
+
}, j = {
|
|
40
41
|
key: 2,
|
|
41
42
|
class: "pl-dropdown__helper",
|
|
42
43
|
"data-testid": "pl-dropdown-helper"
|
|
43
|
-
},
|
|
44
|
+
}, M = /*@__PURE__*/ b({
|
|
44
45
|
name: "PlDropdown",
|
|
45
46
|
props: {
|
|
46
47
|
modelValue: {},
|
|
@@ -51,7 +52,14 @@ var ie = ["tabindex"], ae = { class: "pl-dropdown__container" }, oe = ["title"],
|
|
|
51
52
|
error: { default: void 0 },
|
|
52
53
|
errorStatus: { type: Boolean },
|
|
53
54
|
placeholder: { default: "..." },
|
|
54
|
-
missingValueLabel: {
|
|
55
|
+
missingValueLabel: {
|
|
56
|
+
type: [String, Function],
|
|
57
|
+
default: void 0
|
|
58
|
+
},
|
|
59
|
+
missingValueTooltip: {
|
|
60
|
+
type: [String, Function],
|
|
61
|
+
default: void 0
|
|
62
|
+
},
|
|
55
63
|
clearable: {
|
|
56
64
|
type: Boolean,
|
|
57
65
|
default: !1
|
|
@@ -70,41 +78,44 @@ var ie = ["tabindex"], ae = { class: "pl-dropdown__container" }, oe = ["title"],
|
|
|
70
78
|
groupPosition: { default: void 0 }
|
|
71
79
|
},
|
|
72
80
|
emits: ["update:modelValue"],
|
|
73
|
-
setup(
|
|
74
|
-
let
|
|
81
|
+
setup(b, { emit: M }) {
|
|
82
|
+
let N = M, P = b, F = w(), I = w(), L = oe("optionListRef"), R = C({
|
|
75
83
|
search: "",
|
|
76
84
|
activeIndex: -1,
|
|
77
85
|
open: !1,
|
|
78
86
|
optionsHeight: 0
|
|
79
|
-
}),
|
|
80
|
-
if (!
|
|
81
|
-
}),
|
|
87
|
+
}), ye = () => r(Z.value.findIndex((e) => u(e.value, P.modelValue)), (e) => e < 0 ? 0 : e), be = () => R.activeIndex = ye(), z = p(() => P.options === void 0), B = p(() => !P.disabled && z.value), V = p(() => z.value ? !0 : P.disabled), H = p(() => (P.options ?? []).findIndex((e) => u(e.value, P.modelValue))), U = p(() => P.modelValue !== void 0 && P.modelValue !== null), W = p(() => U.value && H.value === -1 && !z.value), G = p(() => {
|
|
88
|
+
if (!z.value && P.error) return o(P.error);
|
|
89
|
+
}), K = p(() => n(P.options ?? []).map((e, t) => ({
|
|
82
90
|
...e,
|
|
83
91
|
index: t,
|
|
84
|
-
isSelected: t ===
|
|
85
|
-
isActive: t ===
|
|
86
|
-
}))),
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return
|
|
92
|
-
|
|
93
|
-
let e =
|
|
94
|
-
return
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
isSelected: t === H.value,
|
|
93
|
+
isActive: t === R.activeIndex
|
|
94
|
+
}))), q = p(() => D(K).find((e) => u(e.value, P.modelValue))), J = p(() => {
|
|
95
|
+
let e = q.value;
|
|
96
|
+
return e === void 0 ? z.value ? ne(P.modelValue) : void 0 : e.label;
|
|
97
|
+
}), Y = p(() => f(P.modelValue, P.missingValueLabel)), X = p(() => W.value ? te(P.modelValue, P.missingValueTooltip) : void 0), xe = p(() => {
|
|
98
|
+
if (R.open) return;
|
|
99
|
+
if (W.value) return X.value === void 0 ? Y.value : void 0;
|
|
100
|
+
if (J.value === void 0) return;
|
|
101
|
+
let e = q.value?.linkHint;
|
|
102
|
+
return e ? `${J.value}\n${e}` : String(J.value);
|
|
103
|
+
}), Se = p(() => !R.open && U.value ? "" : J.value ? String(J.value) : P.placeholder), Ce = p(() => {
|
|
104
|
+
let e = K.value;
|
|
105
|
+
return R.search ? e.filter((e) => {
|
|
106
|
+
let t = R.search.toLowerCase();
|
|
107
|
+
return e.label.toLowerCase().includes(t) || e.description && e.description.toLowerCase().includes(t) ? !0 : typeof e.value == "string" ? e.value.toLowerCase().includes(t) : e.value === R.search;
|
|
97
108
|
}) : e;
|
|
98
|
-
}), { orderedRef: Z, groupsRef:
|
|
99
|
-
|
|
100
|
-
}, $ = (e) => {
|
|
101
|
-
Q(e);
|
|
102
|
-
}, xe = () => P("update:modelValue", void 0), Se = () => L.value?.focus(), Ce = () => {
|
|
103
|
-
z.open = !z.open, z.open || (z.search = "");
|
|
104
|
-
}, we = () => z.open = !0, Te = (e) => {
|
|
105
|
-
let t = e.relatedTarget;
|
|
106
|
-
!I.value?.contains(t) && !R.value?.listRef?.contains(t) && (z.search = "", z.open = !1);
|
|
109
|
+
}), { orderedRef: Z, groupsRef: we, restRef: Q } = ie(Ce, "group"), Te = p(() => V.value ? void 0 : "0"), $ = (e) => {
|
|
110
|
+
N("update:modelValue", e), R.search = "", R.open = !1, F?.value?.focus();
|
|
107
111
|
}, Ee = (e) => {
|
|
112
|
+
$(e);
|
|
113
|
+
}, De = () => N("update:modelValue", void 0), Oe = () => I.value?.focus(), ke = () => {
|
|
114
|
+
R.open = !R.open, R.open || (R.search = "");
|
|
115
|
+
}, Ae = () => R.open = !0, je = (e) => {
|
|
116
|
+
let t = e.relatedTarget;
|
|
117
|
+
!F.value?.contains(t) && !L.value?.listRef?.contains(t) && (R.search = "", R.open = !1);
|
|
118
|
+
}, Me = (e) => {
|
|
108
119
|
if ([
|
|
109
120
|
"ArrowDown",
|
|
110
121
|
"ArrowUp",
|
|
@@ -112,143 +123,158 @@ var ie = ["tabindex"], ae = { class: "pl-dropdown__container" }, oe = ["title"],
|
|
|
112
123
|
"Escape"
|
|
113
124
|
].includes(e.code)) e.preventDefault();
|
|
114
125
|
else return;
|
|
115
|
-
let { open: t, activeIndex: n } =
|
|
126
|
+
let { open: t, activeIndex: n } = R;
|
|
116
127
|
if (!t) {
|
|
117
|
-
e.code === "Enter" && (
|
|
128
|
+
e.code === "Enter" && (R.open = !0);
|
|
118
129
|
return;
|
|
119
130
|
}
|
|
120
|
-
e.code === "Escape" && (
|
|
131
|
+
e.code === "Escape" && (R.open = !1, F.value?.focus());
|
|
121
132
|
let r = Z.value, { length: i } = r;
|
|
122
133
|
if (!i) return;
|
|
123
|
-
e.code === "Enter" &&
|
|
134
|
+
e.code === "Enter" && $(r.find((e) => e.index === n)?.value);
|
|
124
135
|
let a = r.findIndex((e) => e.index === n) ?? -1, o = e.code === "ArrowDown" ? 1 : e.code === "ArrowUp" ? -1 : 0, s = Math.abs(a + o + i) % i;
|
|
125
|
-
|
|
136
|
+
R.activeIndex = r[s].index ?? -1;
|
|
126
137
|
};
|
|
127
|
-
return
|
|
128
|
-
|
|
129
|
-
}), (n, r) => (
|
|
138
|
+
return ee(F), O(() => P.modelValue, be, { immediate: !0 }), O(() => R.open, (e) => e ? I.value?.focus() : ""), ce(() => {
|
|
139
|
+
R.search, R.activeIndex >= 0 && R.open && L.value?.scrollIntoActive();
|
|
140
|
+
}), (n, r) => (S(), g("div", {
|
|
130
141
|
class: "pl-dropdown__envelope",
|
|
131
|
-
onClick:
|
|
142
|
+
onClick: Oe,
|
|
132
143
|
"data-testid": "pl-dropdown"
|
|
133
|
-
}, [
|
|
144
|
+
}, [_("div", {
|
|
134
145
|
ref_key: "rootRef",
|
|
135
|
-
ref:
|
|
136
|
-
tabindex:
|
|
137
|
-
class:
|
|
138
|
-
open:
|
|
139
|
-
error:
|
|
140
|
-
disabled:
|
|
146
|
+
ref: F,
|
|
147
|
+
tabindex: Te.value,
|
|
148
|
+
class: x(["pl-dropdown", {
|
|
149
|
+
open: R.open,
|
|
150
|
+
error: b.error || b.errorStatus,
|
|
151
|
+
disabled: V.value
|
|
141
152
|
}]),
|
|
142
153
|
"data-testid": "pl-dropdown-control",
|
|
143
|
-
onKeydown:
|
|
144
|
-
onFocusout:
|
|
145
|
-
}, [
|
|
146
|
-
|
|
154
|
+
onKeydown: Me,
|
|
155
|
+
onFocusout: je
|
|
156
|
+
}, [_("div", de, [
|
|
157
|
+
_("div", {
|
|
147
158
|
class: "pl-dropdown__field",
|
|
148
|
-
title:
|
|
159
|
+
title: xe.value
|
|
149
160
|
}, [
|
|
150
|
-
|
|
161
|
+
le(_("input", {
|
|
151
162
|
ref_key: "input",
|
|
152
|
-
ref:
|
|
153
|
-
"onUpdate:modelValue": r[0] ||= (e) =>
|
|
163
|
+
ref: I,
|
|
164
|
+
"onUpdate:modelValue": r[0] ||= (e) => R.search = e,
|
|
154
165
|
type: "text",
|
|
155
166
|
tabindex: "-1",
|
|
156
|
-
disabled:
|
|
157
|
-
placeholder:
|
|
167
|
+
disabled: V.value,
|
|
168
|
+
placeholder: Se.value,
|
|
158
169
|
spellcheck: "false",
|
|
159
170
|
autocomplete: "chrome-off",
|
|
160
171
|
"data-testid": "pl-dropdown-input",
|
|
161
|
-
onFocus:
|
|
162
|
-
}, null, 40,
|
|
163
|
-
|
|
172
|
+
onFocus: Ae
|
|
173
|
+
}, null, 40, pe), [[se, R.search]]),
|
|
174
|
+
R.open ? h("", !0) : (S(), g("div", me, [W.value && X.value !== void 0 ? (S(), m(D(i), {
|
|
164
175
|
key: 0,
|
|
176
|
+
class: x(n.$style.hint),
|
|
177
|
+
position: "top",
|
|
178
|
+
"data-testid": "pl-dropdown-value-hint"
|
|
179
|
+
}, {
|
|
180
|
+
tooltip: k(() => [(S(), m(ae(X.value)))]),
|
|
181
|
+
default: k(() => [y(s, {
|
|
182
|
+
class: "input-value--missing",
|
|
183
|
+
"data-testid": "pl-dropdown-value-missing"
|
|
184
|
+
}, {
|
|
185
|
+
default: k(() => [v(E(Y.value), 1)]),
|
|
186
|
+
_: 1
|
|
187
|
+
})]),
|
|
188
|
+
_: 1
|
|
189
|
+
}, 8, ["class"])) : W.value ? (S(), m(s, {
|
|
190
|
+
key: 1,
|
|
165
191
|
class: "input-value--missing",
|
|
166
192
|
"data-testid": "pl-dropdown-value-missing"
|
|
167
193
|
}, {
|
|
168
|
-
default:
|
|
194
|
+
default: k(() => [v(E(Y.value), 1)]),
|
|
169
195
|
_: 1
|
|
170
|
-
})) :
|
|
171
|
-
key:
|
|
172
|
-
option:
|
|
196
|
+
})) : J.value === void 0 ? h("", !0) : (S(), m(D(a), {
|
|
197
|
+
key: 2,
|
|
198
|
+
option: q.value
|
|
173
199
|
}, {
|
|
174
|
-
default:
|
|
175
|
-
default:
|
|
200
|
+
default: k(() => [y(s, null, {
|
|
201
|
+
default: k(() => [v(E(J.value), 1)]),
|
|
176
202
|
_: 1
|
|
177
203
|
})]),
|
|
178
204
|
_: 1
|
|
179
205
|
}, 8, ["option"]))])),
|
|
180
|
-
|
|
181
|
-
|
|
206
|
+
_("div", he, [
|
|
207
|
+
B.value ? (S(), m(D(c), {
|
|
182
208
|
key: 0,
|
|
183
209
|
name: "loading",
|
|
184
210
|
"data-testid": "pl-dropdown-loading"
|
|
185
|
-
})) :
|
|
186
|
-
|
|
211
|
+
})) : h("", !0),
|
|
212
|
+
b.clearable && U.value ? (S(), m(D(t), {
|
|
187
213
|
key: 1,
|
|
188
214
|
class: "clear",
|
|
189
215
|
"data-testid": "pl-dropdown-clear",
|
|
190
216
|
name: "delete-clear",
|
|
191
|
-
onClick:
|
|
192
|
-
})) :
|
|
217
|
+
onClick: A(De, ["stop"])
|
|
218
|
+
})) : h("", !0),
|
|
193
219
|
T(n.$slots, "append"),
|
|
194
|
-
|
|
220
|
+
_("div", {
|
|
195
221
|
class: "pl-dropdown__arrow-wrapper",
|
|
196
222
|
"data-testid": "pl-dropdown-arrow",
|
|
197
|
-
onClick:
|
|
198
|
-
}, [
|
|
223
|
+
onClick: A(ke, ["stop"])
|
|
224
|
+
}, [b.arrowIconLarge ? (S(), m(D(c), {
|
|
199
225
|
key: 0,
|
|
200
|
-
name:
|
|
226
|
+
name: b.arrowIconLarge,
|
|
201
227
|
class: "arrow-icon"
|
|
202
|
-
}, null, 8, ["name"])) :
|
|
228
|
+
}, null, 8, ["name"])) : b.arrowIcon ? (S(), m(D(t), {
|
|
203
229
|
key: 1,
|
|
204
|
-
name:
|
|
230
|
+
name: b.arrowIcon,
|
|
205
231
|
class: "arrow-icon"
|
|
206
|
-
}, null, 8, ["name"])) : (
|
|
232
|
+
}, null, 8, ["name"])) : (S(), m(D(t), {
|
|
207
233
|
key: 2,
|
|
208
234
|
name: "chevron-down",
|
|
209
235
|
class: "arrow-icon arrow-icon-default"
|
|
210
236
|
}))])
|
|
211
237
|
])
|
|
212
|
-
], 8,
|
|
213
|
-
|
|
214
|
-
|
|
238
|
+
], 8, fe),
|
|
239
|
+
b.label ? (S(), g("label", ge, [
|
|
240
|
+
b.required ? (S(), m(D(e), {
|
|
215
241
|
key: 0,
|
|
216
|
-
uri: D(
|
|
242
|
+
uri: D(d),
|
|
217
243
|
"data-testid": "pl-dropdown-required"
|
|
218
|
-
}, null, 8, ["uri"])) :
|
|
219
|
-
|
|
220
|
-
n.$slots.tooltip ? (
|
|
244
|
+
}, null, 8, ["uri"])) : h("", !0),
|
|
245
|
+
_("span", null, E(b.label), 1),
|
|
246
|
+
n.$slots.tooltip ? (S(), m(D(i), {
|
|
221
247
|
key: 1,
|
|
222
248
|
class: "info",
|
|
223
249
|
position: "top",
|
|
224
250
|
"data-testid": "pl-dropdown-tooltip"
|
|
225
251
|
}, {
|
|
226
|
-
tooltip:
|
|
252
|
+
tooltip: k(() => [T(n.$slots, "tooltip")]),
|
|
227
253
|
_: 3
|
|
228
|
-
})) :
|
|
229
|
-
])) :
|
|
230
|
-
|
|
254
|
+
})) : h("", !0)
|
|
255
|
+
])) : h("", !0),
|
|
256
|
+
R.open ? (S(), m(re, {
|
|
231
257
|
key: 1,
|
|
232
258
|
ref_key: "optionListRef",
|
|
233
|
-
ref:
|
|
234
|
-
"root-ref":
|
|
235
|
-
groups: D(
|
|
236
|
-
rest: D(
|
|
237
|
-
"option-size":
|
|
238
|
-
"select-option":
|
|
259
|
+
ref: L,
|
|
260
|
+
"root-ref": F.value,
|
|
261
|
+
groups: D(we),
|
|
262
|
+
rest: D(Q),
|
|
263
|
+
"option-size": b.optionSize,
|
|
264
|
+
"select-option": Ee
|
|
239
265
|
}, null, 8, [
|
|
240
266
|
"root-ref",
|
|
241
267
|
"groups",
|
|
242
268
|
"rest",
|
|
243
269
|
"option-size"
|
|
244
|
-
])) :
|
|
245
|
-
|
|
270
|
+
])) : h("", !0),
|
|
271
|
+
y(l, {
|
|
246
272
|
class: "pl-dropdown__contour",
|
|
247
|
-
"group-position":
|
|
273
|
+
"group-position": b.groupPosition
|
|
248
274
|
}, null, 8, ["group-position"])
|
|
249
|
-
])], 42,
|
|
275
|
+
])], 42, ue), G.value ? (S(), g("div", _e, E(G.value), 1)) : B.value && b.loadingOptionsHelper ? (S(), g("div", ve, E(b.loadingOptionsHelper), 1)) : b.helper ? (S(), g("div", j, E(b.helper), 1)) : h("", !0)]));
|
|
250
276
|
}
|
|
251
277
|
});
|
|
252
|
-
export {
|
|
278
|
+
export { M as default };
|
|
253
279
|
|
|
254
280
|
//# sourceMappingURL=PlDropdown.vue2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDropdown.vue_vue_type_script_setup_true_lang.js","names":["$slots","_openBlock","_createElementBlock","_createElementVNode","_normalizeClass","_withDirectives","_vModelText","_createBlock","LongText","_withCtx","_createTextVNode","_toDisplayString","_unref","PlColumnLabel","_createVNode","_createCommentVNode","PlIcon24","PlIcon16","_withModifiers","_renderSlot","PlSvg","SvgRequired","PlTooltip","OptionList","DoubleContour","PlSvg_default","PlIcon16_default","PlTooltip_default","PlColumnLabel_default","LongText_default","PlIcon24_default","DoubleContour_default","required_default","OptionList_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","PlDropdown_vue_vue_type_script_setup_true_lang_default","__emit","emit","props","__props","rootRef","ref","input","optionListRef","useTemplateRef","data","reactive","findActiveIndex","tap","orderedRef","deepEqual","o","v","updateActive","isLoadingOptions","computed","showLoadingSpinner","isDisabled","selectedIndex","hasValue","isMissing","computedError","getErrorMessage","optionsRef","normalizeListOptions","opt","index","selectedOption","unref","textValue","fieldTitle","hint","computedPlaceholder","filteredRef","options","search","useGroupBy","tabindex","selectOption","selectOptionWrapper","clear","setFocusOnInput","toggleOpen","onInputFocus","onFocusOut","relatedTarget","event","handleKeydown","open","ordered","length","it","activeIndex","localIndex","delta","newIndex","useLabelNotch","watch","watchPostEffect","openBlock","createElementBlock","createElementVNode","normalizeClass","withDirectives","_cache","$event","vModelText","createCommentVNode","createBlock","withCtx","createTextVNode","toDisplayString","createVNode","withModifiers","renderSlot","_ctx","groupsRef","restRef"],"sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a list of options\n */\nexport default {\n name: \"PlDropdown\",\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M = unknown\">\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from \"vue\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport { tap } from \"../../helpers/functions\";\nimport { deepEqual } from \"../../helpers/objects\";\nimport { normalizeListOptions } from \"../../helpers/utils\";\nimport type { ListOption, ListOptionNormalized, MaskIconName16, MaskIconName24 } from \"../../types\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport LongText from \"../LongText.vue\";\nimport { PlColumnLabel } from \"../PlColumnLabel\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlIcon24 } from \"../PlIcon24\";\nimport { PlSvg } from \"../PlSvg\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport OptionList from \"./OptionList.vue\";\nimport \"./pl-dropdown.scss\";\nimport type { LOption } from \"./types\";\nimport { useGroupBy } from \"./useGroupBy\";\n\nconst emit = defineEmits<{\n /**\n * Emitted when the model value is updated.\n */\n (e: \"update:modelValue\", value: M | undefined): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected value of the dropdown.\n */\n modelValue: M;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * List of available options for the dropdown\n */\n options?: Readonly<ListOption<M>[]>;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * A helper text displayed below the dropdown when there are no options yet or options is undefined (optional).\n */\n loadingOptionsHelper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Shows red border even without an error message\n */\n errorStatus?: boolean;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * Text shown in the field when `modelValue` has no matching option — e.g. its\n * upstream block was deleted. Rendered italic in error color.\n */\n missingValueLabel?: string;\n /**\n * Enables a button to clear the selected value (default: false)\n */\n clearable?: boolean;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Custom icon (16px) class for the dropdown arrow (optional)\n */\n arrowIcon?: MaskIconName16;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: MaskIconName24;\n /**\n * Option list item size\n */\n optionSize?: \"small\" | \"medium\";\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n label: \"\",\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n showErrorMessage: true,\n placeholder: \"...\",\n missingValueLabel: \"Value not available\",\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: \"small\",\n options: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst optionListRef = useTemplateRef<InstanceType<typeof OptionList>>(\"optionListRef\");\n\nconst data = reactive({\n search: \"\",\n activeIndex: -1,\n open: false,\n optionsHeight: 0,\n});\n\nconst findActiveIndex = () =>\n tap(\n orderedRef.value.findIndex((o) => deepEqual(o.value, props.modelValue)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst isLoadingOptions = computed(() => {\n return props.options === undefined;\n});\n\n/**\n * Loading spinner should not be shown when the dropdown is explicitly disabled,\n * even if options are undefined. The disabled state takes precedence.\n */\nconst showLoadingSpinner = computed(() => {\n return !props.disabled && isLoadingOptions.value;\n});\n\nconst isDisabled = computed(() => {\n if (isLoadingOptions.value) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return (props.options ?? []).findIndex((o) => deepEqual(o.value, props.modelValue));\n});\n\nconst hasValue = computed(() => {\n return props.modelValue !== undefined && props.modelValue !== null;\n});\n\nconst isMissing = computed(() => {\n return hasValue.value && selectedIndex.value === -1 && !isLoadingOptions.value;\n});\n\nconst computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n // The field renders the missing state via `missingValueLabel`; no need to\n // duplicate it as a helper error.\n return undefined;\n});\n\nconst optionsRef = computed<LOption<M>[]>(() =>\n normalizeListOptions(props.options ?? []).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })),\n);\n\nconst selectedOption = computed(() =>\n unref(optionsRef).find((o) => deepEqual(o.value, props.modelValue)),\n);\n\nconst textValue = computed(() => selectedOption.value?.label);\n\n// Native tooltip with the full selected value and its link hint. The `.input-value` layer has\n// `pointer-events: none`, so the title must sit on the field wrapper, which is\n// what actually receives the hover.\nconst fieldTitle = computed(() => {\n if (data.open) return undefined;\n if (isMissing.value) return props.missingValueLabel;\n if (textValue.value === undefined) return undefined;\n const hint = selectedOption.value?.linkHint;\n return hint ? `${textValue.value}\\n${hint}` : String(textValue.value);\n});\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && hasValue.value) {\n return \"\";\n }\n\n return textValue.value ? String(textValue.value) : props.placeholder;\n});\n\nconst filteredRef = computed(() => {\n const options = optionsRef.value;\n\n if (data.search) {\n return options.filter((o: ListOptionNormalized) => {\n const search = data.search.toLowerCase();\n\n if (o.label.toLowerCase().includes(search)) {\n return true;\n }\n\n if (o.description && o.description.toLowerCase().includes(search)) {\n return true;\n }\n\n if (typeof o.value === \"string\") {\n return o.value.toLowerCase().includes(search);\n }\n\n return o.value === data.search;\n });\n }\n\n return options;\n});\n\nconst { orderedRef, groupsRef, restRef } = useGroupBy(filteredRef, \"group\");\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst selectOption = (v: M | undefined) => {\n emit(\"update:modelValue\", v);\n data.search = \"\";\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst selectOptionWrapper = (v: unknown) => {\n selectOption(v as M | undefined);\n};\n\nconst clear = () => emit(\"update:modelValue\", undefined);\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n if (!data.open) {\n data.search = \"\";\n }\n};\n\nconst onInputFocus = () => (data.open = true);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (\n !rootRef.value?.contains(relatedTarget) &&\n !optionListRef.value?.listRef?.contains(relatedTarget)\n ) {\n data.search = \"\";\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n if (![\"ArrowDown\", \"ArrowUp\", \"Enter\", \"Escape\"].includes(e.code)) {\n return;\n } else {\n e.preventDefault();\n }\n\n const { open, activeIndex } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n rootRef.value?.focus();\n }\n\n const ordered = orderedRef.value;\n\n const { length } = ordered;\n\n if (!length) {\n return;\n }\n\n if (e.code === \"Enter\") {\n selectOption(ordered.find((it) => it.index === activeIndex)?.value);\n }\n\n const localIndex = ordered.findIndex((it) => it.index === activeIndex) ?? -1;\n\n const delta = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n const newIndex = Math.abs(localIndex + delta + length) % length;\n\n data.activeIndex = ordered[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => props.modelValue, updateActive, { immediate: true });\n\nwatch(\n () => data.open,\n (open) => (open ? input.value?.focus() : \"\"),\n);\n\nwatchPostEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n data.search; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n optionListRef.value?.scrollIntoActive();\n }\n});\n</script>\n\n<template>\n <div class=\"pl-dropdown__envelope\" @click=\"setFocusOnInput\" data-testid=\"pl-dropdown\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-dropdown\"\n data-testid=\"pl-dropdown-control\"\n :class=\"{ open: data.open, error: error || errorStatus, disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-dropdown__container\">\n <div class=\"pl-dropdown__field\" :title=\"fieldTitle\">\n <input\n ref=\"input\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n data-testid=\"pl-dropdown-input\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\" data-testid=\"pl-dropdown-value\">\n <LongText\n v-if=\"isMissing\"\n class=\"input-value--missing\"\n data-testid=\"pl-dropdown-value-missing\"\n >\n {{ missingValueLabel }}\n </LongText>\n <PlColumnLabel v-else-if=\"textValue !== undefined\" :option=\"selectedOption\">\n <LongText>{{ textValue }}</LongText>\n </PlColumnLabel>\n </div>\n\n <div class=\"pl-dropdown__controls\">\n <PlIcon24 v-if=\"showLoadingSpinner\" name=\"loading\" data-testid=\"pl-dropdown-loading\" />\n <PlIcon16\n v-if=\"clearable && hasValue\"\n class=\"clear\"\n data-testid=\"pl-dropdown-clear\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <slot name=\"append\" />\n <div\n class=\"pl-dropdown__arrow-wrapper\"\n data-testid=\"pl-dropdown-arrow\"\n @click.stop=\"toggleOpen\"\n >\n <PlIcon24 v-if=\"arrowIconLarge\" :name=\"arrowIconLarge\" class=\"arrow-icon\" />\n <PlIcon16 v-else-if=\"arrowIcon\" :name=\"arrowIcon\" class=\"arrow-icon\" />\n <PlIcon16 v-else name=\"chevron-down\" class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\" data-testid=\"pl-dropdown-label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" data-testid=\"pl-dropdown-required\" />\n <span>{{ label }}</span>\n <PlTooltip\n v-if=\"$slots.tooltip\"\n class=\"info\"\n position=\"top\"\n data-testid=\"pl-dropdown-tooltip\"\n >\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <OptionList\n v-if=\"data.open\"\n ref=\"optionListRef\"\n :root-ref=\"rootRef!\"\n :groups=\"groupsRef\"\n :rest=\"restRef\"\n :option-size=\"optionSize\"\n :select-option=\"selectOptionWrapper\"\n />\n <DoubleContour class=\"pl-dropdown__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-dropdown__error\" data-testid=\"pl-dropdown-error\">\n {{ computedError }}\n </div>\n <div\n v-else-if=\"showLoadingSpinner && loadingOptionsHelper\"\n class=\"pl-dropdown__helper\"\n data-testid=\"pl-dropdown-helper\"\n >\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-dropdown__helper\" data-testid=\"pl-dropdown-helper\">\n {{ helper }}\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlDropdown.vue_vue_type_script_setup_true_lang.js","names":["$style","$slots","_openBlock","_createElementBlock","_createElementVNode","_normalizeClass","_withDirectives","_vModelText","_createBlock","_unref","PlTooltip","_withCtx","_resolveDynamicComponent","_createVNode","LongText","_createTextVNode","_toDisplayString","PlColumnLabel","_createCommentVNode","PlIcon24","PlIcon16","_withModifiers","_renderSlot","PlSvg","SvgRequired","OptionList","DoubleContour","PlSvg_default","PlIcon16_default","PlTooltip_default","PlColumnLabel_default","LongText_default","PlIcon24_default","DoubleContour_default","required_default","OptionList_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","PlDropdown_vue_vue_type_script_setup_true_lang_default","__emit","emit","props","__props","rootRef","ref","input","optionListRef","useTemplateRef","data","reactive","findActiveIndex","tap","orderedRef","deepEqual","o","v","updateActive","isLoadingOptions","computed","showLoadingSpinner","isDisabled","selectedIndex","hasValue","isMissing","computedError","getErrorMessage","optionsRef","normalizeListOptions","opt","index","selectedOption","unref","textValue","option","pickedValueText","missingText","missingValueText","missingHint","missingValueTooltip","fieldTitle","hint","computedPlaceholder","filteredRef","options","search","useGroupBy","tabindex","selectOption","selectOptionWrapper","clear","setFocusOnInput","toggleOpen","onInputFocus","onFocusOut","relatedTarget","event","handleKeydown","open","ordered","length","it","activeIndex","localIndex","delta","newIndex","useLabelNotch","watch","watchPostEffect","openBlock","createElementBlock","createElementVNode","normalizeClass","withDirectives","_cache","$event","vModelText","createCommentVNode","createBlock","_ctx","withCtx","resolveDynamicComponent","createVNode","createTextVNode","toDisplayString","withModifiers","renderSlot","groupsRef","restRef"],"sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a list of options\n */\nexport default {\n name: \"PlDropdown\",\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M = unknown\">\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from \"vue\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { missingValueText, missingValueTooltip, pickedValueText } from \"../../helpers/columnValue\";\nimport type { MissingValueLabel, MissingValueTooltip } from \"../../helpers/columnValue\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport { tap } from \"../../helpers/functions\";\nimport { deepEqual } from \"../../helpers/objects\";\nimport { normalizeListOptions } from \"../../helpers/utils\";\nimport type { ListOption, ListOptionNormalized, MaskIconName16, MaskIconName24 } from \"../../types\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport LongText from \"../LongText.vue\";\nimport { PlColumnLabel } from \"../PlColumnLabel\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlIcon24 } from \"../PlIcon24\";\nimport { PlSvg } from \"../PlSvg\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport OptionList from \"./OptionList.vue\";\nimport \"./pl-dropdown.scss\";\nimport type { LOption } from \"./types\";\nimport { useGroupBy } from \"./useGroupBy\";\n\nconst emit = defineEmits<{\n /**\n * Emitted when the model value is updated.\n */\n (e: \"update:modelValue\", value: M | undefined): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected value of the dropdown.\n */\n modelValue: M;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * List of available options for the dropdown\n */\n options?: Readonly<ListOption<M>[]>;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * A helper text displayed below the dropdown when there are no options yet or options is undefined (optional).\n */\n loadingOptionsHelper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Shows red border even without an error message\n */\n errorStatus?: boolean;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * Text shown in the field when `modelValue` has no matching option — e.g. its\n * upstream block was deleted. Rendered italic in error color. One text for every such value,\n * or a function giving it per value. By default, the value a column value id picks, marked\n * as not available, or \"Value not available\".\n */\n missingValueLabel?: MissingValueLabel;\n /**\n * Explains a selected value missing from the options in a tooltip over it: one text for every\n * such value, or a function giving the content per value.\n */\n missingValueTooltip?: MissingValueTooltip;\n /**\n * Enables a button to clear the selected value (default: false)\n */\n clearable?: boolean;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Custom icon (16px) class for the dropdown arrow (optional)\n */\n arrowIcon?: MaskIconName16;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: MaskIconName24;\n /**\n * Option list item size\n */\n optionSize?: \"small\" | \"medium\";\n /**\n * Makes some of corners not rounded\n * */\n groupPosition?:\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\"\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"middle\";\n }>(),\n {\n label: \"\",\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n showErrorMessage: true,\n placeholder: \"...\",\n missingValueLabel: undefined,\n missingValueTooltip: undefined,\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: \"small\",\n options: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst optionListRef = useTemplateRef<InstanceType<typeof OptionList>>(\"optionListRef\");\n\nconst data = reactive({\n search: \"\",\n activeIndex: -1,\n open: false,\n optionsHeight: 0,\n});\n\nconst findActiveIndex = () =>\n tap(\n orderedRef.value.findIndex((o) => deepEqual(o.value, props.modelValue)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst isLoadingOptions = computed(() => {\n return props.options === undefined;\n});\n\n/**\n * Loading spinner should not be shown when the dropdown is explicitly disabled,\n * even if options are undefined. The disabled state takes precedence.\n */\nconst showLoadingSpinner = computed(() => {\n return !props.disabled && isLoadingOptions.value;\n});\n\nconst isDisabled = computed(() => {\n if (isLoadingOptions.value) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return (props.options ?? []).findIndex((o) => deepEqual(o.value, props.modelValue));\n});\n\nconst hasValue = computed(() => {\n return props.modelValue !== undefined && props.modelValue !== null;\n});\n\nconst isMissing = computed(() => {\n return hasValue.value && selectedIndex.value === -1 && !isLoadingOptions.value;\n});\n\nconst computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n // The field renders the missing state via `missingValueLabel`; no need to\n // duplicate it as a helper error.\n return undefined;\n});\n\nconst optionsRef = computed<LOption<M>[]>(() =>\n normalizeListOptions(props.options ?? []).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })),\n);\n\nconst selectedOption = computed(() =>\n unref(optionsRef).find((o) => deepEqual(o.value, props.modelValue)),\n);\n\nconst textValue = computed(() => {\n const option = selectedOption.value;\n if (option !== undefined) return option.label;\n // A picked column value is shown by its own label while the options load.\n return isLoadingOptions.value ? pickedValueText(props.modelValue) : undefined;\n});\n\nconst missingText = computed(() => missingValueText(props.modelValue, props.missingValueLabel));\n\nconst missingHint = computed(() =>\n isMissing.value ? missingValueTooltip(props.modelValue, props.missingValueTooltip) : undefined,\n);\n\n// Native tooltip with the full selected value and its link hint. The `.input-value` layer has\n// `pointer-events: none`, so the title must sit on the field wrapper, which is\n// what actually receives the hover. A missing value with a hint has its own tooltip.\nconst fieldTitle = computed(() => {\n if (data.open) return undefined;\n if (isMissing.value) return missingHint.value === undefined ? missingText.value : undefined;\n if (textValue.value === undefined) return undefined;\n const hint = selectedOption.value?.linkHint;\n return hint ? `${textValue.value}\\n${hint}` : String(textValue.value);\n});\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && hasValue.value) {\n return \"\";\n }\n\n return textValue.value ? String(textValue.value) : props.placeholder;\n});\n\nconst filteredRef = computed(() => {\n const options = optionsRef.value;\n\n if (data.search) {\n return options.filter((o: ListOptionNormalized) => {\n const search = data.search.toLowerCase();\n\n if (o.label.toLowerCase().includes(search)) {\n return true;\n }\n\n if (o.description && o.description.toLowerCase().includes(search)) {\n return true;\n }\n\n if (typeof o.value === \"string\") {\n return o.value.toLowerCase().includes(search);\n }\n\n return o.value === data.search;\n });\n }\n\n return options;\n});\n\nconst { orderedRef, groupsRef, restRef } = useGroupBy(filteredRef, \"group\");\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst selectOption = (v: M | undefined) => {\n emit(\"update:modelValue\", v);\n data.search = \"\";\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst selectOptionWrapper = (v: unknown) => {\n selectOption(v as M | undefined);\n};\n\nconst clear = () => emit(\"update:modelValue\", undefined);\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n if (!data.open) {\n data.search = \"\";\n }\n};\n\nconst onInputFocus = () => (data.open = true);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (\n !rootRef.value?.contains(relatedTarget) &&\n !optionListRef.value?.listRef?.contains(relatedTarget)\n ) {\n data.search = \"\";\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n if (![\"ArrowDown\", \"ArrowUp\", \"Enter\", \"Escape\"].includes(e.code)) {\n return;\n } else {\n e.preventDefault();\n }\n\n const { open, activeIndex } = data;\n\n if (!open) {\n if (e.code === \"Enter\") {\n data.open = true;\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n rootRef.value?.focus();\n }\n\n const ordered = orderedRef.value;\n\n const { length } = ordered;\n\n if (!length) {\n return;\n }\n\n if (e.code === \"Enter\") {\n selectOption(ordered.find((it) => it.index === activeIndex)?.value);\n }\n\n const localIndex = ordered.findIndex((it) => it.index === activeIndex) ?? -1;\n\n const delta = e.code === \"ArrowDown\" ? 1 : e.code === \"ArrowUp\" ? -1 : 0;\n\n const newIndex = Math.abs(localIndex + delta + length) % length;\n\n data.activeIndex = ordered[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => props.modelValue, updateActive, { immediate: true });\n\nwatch(\n () => data.open,\n (open) => (open ? input.value?.focus() : \"\"),\n);\n\nwatchPostEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n data.search; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n optionListRef.value?.scrollIntoActive();\n }\n});\n</script>\n\n<template>\n <div class=\"pl-dropdown__envelope\" @click=\"setFocusOnInput\" data-testid=\"pl-dropdown\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-dropdown\"\n data-testid=\"pl-dropdown-control\"\n :class=\"{ open: data.open, error: error || errorStatus, disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-dropdown__container\">\n <div class=\"pl-dropdown__field\" :title=\"fieldTitle\">\n <input\n ref=\"input\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n data-testid=\"pl-dropdown-input\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\" data-testid=\"pl-dropdown-value\">\n <PlTooltip\n v-if=\"isMissing && missingHint !== undefined\"\n :class=\"$style.hint\"\n position=\"top\"\n data-testid=\"pl-dropdown-value-hint\"\n >\n <LongText class=\"input-value--missing\" data-testid=\"pl-dropdown-value-missing\">\n {{ missingText }}\n </LongText>\n <template #tooltip>\n <component :is=\"missingHint\" />\n </template>\n </PlTooltip>\n <LongText\n v-else-if=\"isMissing\"\n class=\"input-value--missing\"\n data-testid=\"pl-dropdown-value-missing\"\n >\n {{ missingText }}\n </LongText>\n <PlColumnLabel v-else-if=\"textValue !== undefined\" :option=\"selectedOption\">\n <LongText>{{ textValue }}</LongText>\n </PlColumnLabel>\n </div>\n\n <div class=\"pl-dropdown__controls\">\n <PlIcon24 v-if=\"showLoadingSpinner\" name=\"loading\" data-testid=\"pl-dropdown-loading\" />\n <PlIcon16\n v-if=\"clearable && hasValue\"\n class=\"clear\"\n data-testid=\"pl-dropdown-clear\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <slot name=\"append\" />\n <div\n class=\"pl-dropdown__arrow-wrapper\"\n data-testid=\"pl-dropdown-arrow\"\n @click.stop=\"toggleOpen\"\n >\n <PlIcon24 v-if=\"arrowIconLarge\" :name=\"arrowIconLarge\" class=\"arrow-icon\" />\n <PlIcon16 v-else-if=\"arrowIcon\" :name=\"arrowIcon\" class=\"arrow-icon\" />\n <PlIcon16 v-else name=\"chevron-down\" class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\" data-testid=\"pl-dropdown-label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" data-testid=\"pl-dropdown-required\" />\n <span>{{ label }}</span>\n <PlTooltip\n v-if=\"$slots.tooltip\"\n class=\"info\"\n position=\"top\"\n data-testid=\"pl-dropdown-tooltip\"\n >\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <OptionList\n v-if=\"data.open\"\n ref=\"optionListRef\"\n :root-ref=\"rootRef!\"\n :groups=\"groupsRef\"\n :rest=\"restRef\"\n :option-size=\"optionSize\"\n :select-option=\"selectOptionWrapper\"\n />\n <DoubleContour class=\"pl-dropdown__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-dropdown__error\" data-testid=\"pl-dropdown-error\">\n {{ computedError }}\n </div>\n <div\n v-else-if=\"showLoadingSpinner && loadingOptionsHelper\"\n class=\"pl-dropdown__helper\"\n data-testid=\"pl-dropdown-helper\"\n >\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-dropdown__helper\" data-testid=\"pl-dropdown-helper\">\n {{ helper }}\n </div>\n </div>\n</template>\n\n<style module>\n.hint {\n min-width: 0;\n pointer-events: auto;\n}\n</style>\n"],"mappings":"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"}
|