@milaboratories/uikit 2.15.28 → 2.15.30
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 +17 -17
- package/.turbo/turbo-formatter$colon$check.log +2 -2
- package/.turbo/turbo-linter$colon$check.log +2 -2
- package/.turbo/turbo-types$colon$check.log +1 -1
- package/CHANGELOG.md +12 -0
- package/dist/components/PlAutocomplete/PlAutocomplete.js.map +1 -1
- package/dist/components/PlAutocomplete/PlAutocomplete.vue.d.ts.map +1 -1
- package/dist/components/PlAutocomplete/PlAutocomplete.vue2.js +90 -87
- package/dist/components/PlAutocomplete/PlAutocomplete.vue2.js.map +1 -1
- package/dist/components/PlDropdown/PlDropdown.js.map +1 -1
- package/dist/components/PlDropdown/PlDropdown.vue.d.ts.map +1 -1
- package/dist/components/PlDropdown/PlDropdown.vue2.js +76 -71
- package/dist/components/PlDropdown/PlDropdown.vue2.js.map +1 -1
- package/dist/components/PlDropdownLegacy/PlDropdownLegacy.js.map +1 -1
- package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.d.ts.map +1 -1
- package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue2.js +69 -62
- package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue2.js.map +1 -1
- package/package.json +5 -5
- package/src/components/PlAutocomplete/PlAutocomplete.vue +5 -1
- package/src/components/PlDropdown/PlDropdown.vue +10 -1
- package/src/components/PlDropdownLegacy/PlDropdownLegacy.vue +9 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @milaboratories/uikit@2.15.
|
|
3
|
+
> @milaboratories/uikit@2.15.30 build /home/runner/_work/platforma/platforma/lib/ui/uikit
|
|
4
4
|
> ts-builder build --target browser-lib --build-config ./build.browser-lib.config.js
|
|
5
5
|
|
|
6
6
|
Building browser-lib project...
|
|
@@ -18,7 +18,7 @@ Using custom config: ./build.browser-lib.config.js
|
|
|
18
18
|
rendering chunks...
|
|
19
19
|
|
|
20
20
|
[unplugin:dts] Start generate declaration files...
|
|
21
|
-
[unplugin:dts] Declaration files built in
|
|
21
|
+
[unplugin:dts] Declaration files built in 6504ms.
|
|
22
22
|
|
|
23
23
|
computing gzip size...
|
|
24
24
|
dist/components/PlClipboard/PlClipboard.vue?vue&type=style&index=0&lang.css 0.04 kB │ gzip: 0.06 kB
|
|
@@ -197,7 +197,7 @@ dist/components/PlBtnGroup/PlBtnGroup.js
|
|
|
197
197
|
dist/components/PlBtnSplit/PlBtnSplit.js 0.20 kB │ gzip: 0.16 kB │ map: 5.82 kB
|
|
198
198
|
dist/components/PlCheckbox/PlCheckbox.js 0.20 kB │ gzip: 0.16 kB │ map: 1.37 kB
|
|
199
199
|
dist/components/PlDropdown/OptionList.js 0.20 kB │ gzip: 0.17 kB │ map: 2.40 kB
|
|
200
|
-
dist/components/PlDropdown/PlDropdown.js 0.20 kB │ gzip: 0.16 kB │ map: 12.
|
|
200
|
+
dist/components/PlDropdown/PlDropdown.js 0.20 kB │ gzip: 0.16 kB │ map: 12.76 kB
|
|
201
201
|
dist/components/PlTextArea/PlTextArea.js 0.20 kB │ gzip: 0.16 kB │ map: 4.74 kB
|
|
202
202
|
dist/layout/PlContainer/PlContainer.js 0.20 kB │ gzip: 0.16 kB │ map: 0.94 kB
|
|
203
203
|
dist/components/PlSlideModal/props.js 0.20 kB │ gzip: 0.18 kB │ map: 0.75 kB
|
|
@@ -224,7 +224,7 @@ dist/components/PlNumberField/PlNumberField.js
|
|
|
224
224
|
dist/components/PlProgressBar/PlProgressBar.js 0.22 kB │ gzip: 0.16 kB │ map: 0.93 kB
|
|
225
225
|
dist/components/DataTable/RowsCommandMenu.js 0.22 kB │ gzip: 0.17 kB │ map: 1.05 kB
|
|
226
226
|
dist/utils/DropdownOverlay/DropdownOverlay.js 0.22 kB │ gzip: 0.16 kB │ map: 2.40 kB
|
|
227
|
-
dist/components/PlAutocomplete/PlAutocomplete.js 0.22 kB │ gzip: 0.16 kB │ map: 13.
|
|
227
|
+
dist/components/PlAutocomplete/PlAutocomplete.js 0.22 kB │ gzip: 0.16 kB │ map: 13.58 kB
|
|
228
228
|
dist/components/PlBtnSecondary/PlBtnSecondary.js 0.22 kB │ gzip: 0.16 kB │ map: 1.13 kB
|
|
229
229
|
dist/components/PlDropdownLine/PlDropdownLine.js 0.22 kB │ gzip: 0.16 kB │ map: 9.47 kB
|
|
230
230
|
dist/components/PlDropdownLine/ResizableInput.js 0.22 kB │ gzip: 0.17 kB │ map: 1.33 kB
|
|
@@ -239,7 +239,7 @@ dist/components/PlErrorBoundary/PlErrorBoundary.js
|
|
|
239
239
|
dist/components/PlSlideModal/PlPureSlideModal.js 0.22 kB │ gzip: 0.17 kB │ map: 1.91 kB
|
|
240
240
|
dist/utils/PlCloseModalBtn.vue_vue_type_style_index_0_lang.module.js 0.22 kB │ gzip: 0.18 kB │ map: 0.42 kB
|
|
241
241
|
dist/components/DataTable/ColumnsCommandMenu.js 0.23 kB │ gzip: 0.17 kB │ map: 1.06 kB
|
|
242
|
-
dist/components/PlDropdownLegacy/PlDropdownLegacy.js 0.23 kB │ gzip: 0.17 kB │ map: 11.
|
|
242
|
+
dist/components/PlDropdownLegacy/PlDropdownLegacy.js 0.23 kB │ gzip: 0.17 kB │ map: 11.53 kB
|
|
243
243
|
dist/components/PlEditableTitle/pl-editable-title.module.js 0.23 kB │ gzip: 0.18 kB │ map: 0.45 kB
|
|
244
244
|
dist/components/PlLoaderCircular/PlLoaderCircular.js 0.23 kB │ gzip: 0.16 kB │ map: 1.02 kB
|
|
245
245
|
dist/layout/PlBlockPage/PlBlockPageTitleTeleportTarget.js 0.23 kB │ gzip: 0.16 kB │ map: 0.31 kB
|
|
@@ -474,14 +474,6 @@ dist/assets/icons/icon-assets-min/24_success.js
|
|
|
474
474
|
dist/composition/useFormState.js 0.54 kB │ gzip: 0.34 kB │ map: 1.44 kB
|
|
475
475
|
dist/assets/icons/icon-assets-min/24_table-add.js 0.55 kB │ gzip: 0.37 kB │ map: 0.62 kB
|
|
476
476
|
dist/assets/icons/icon-assets-min/16_time.js 0.55 kB │ gzip: 0.36 kB │ map: 0.64 kB
|
|
477
|
-
[33m[33m[PLUGIN_TIMINGS] Warning:[0m Your build spent significant time in plugins. Here is a breakdown:
|
|
478
|
-
- vite:asset (37%)
|
|
479
|
-
- vite:css-post (15%)
|
|
480
|
-
- sourcemaps (10%)
|
|
481
|
-
- unplugin-dts (9%)
|
|
482
|
-
- vite:vue (8%)
|
|
483
|
-
See https://rolldown.rs/options/checks#plugintimings for more details.
|
|
484
|
-
[39m
|
|
485
477
|
dist/assets/icons/icon-assets-min/24_frame-type-left-bottom.js 0.55 kB │ gzip: 0.33 kB │ map: 0.63 kB
|
|
486
478
|
dist/assets/icons/icon-assets-min/16_lock.js 0.56 kB │ gzip: 0.37 kB │ map: 0.63 kB
|
|
487
479
|
dist/assets/icons/icon-assets-min/24_table-import.js 0.56 kB │ gzip: 0.37 kB │ map: 0.63 kB
|
|
@@ -536,6 +528,14 @@ dist/composition/useQuery.js
|
|
|
536
528
|
dist/assets/icons/icon-assets-min/16_settings.js 0.64 kB │ gzip: 0.37 kB │ map: 0.71 kB
|
|
537
529
|
dist/assets/icons/icon-assets-min/24_table-upload.js 0.64 kB │ gzip: 0.38 kB │ map: 0.73 kB
|
|
538
530
|
dist/assets/icons/icon-assets-min/16_data-dimentions.js 0.64 kB │ gzip: 0.42 kB │ map: 0.74 kB
|
|
531
|
+
[33m[33m[PLUGIN_TIMINGS] Warning:[0m Your build spent significant time in plugins. Here is a breakdown:
|
|
532
|
+
- vite:asset (37%)
|
|
533
|
+
- sourcemaps (15%)
|
|
534
|
+
- unplugin-dts (10%)
|
|
535
|
+
- vite:vue (10%)
|
|
536
|
+
- vite:css-post (9%)
|
|
537
|
+
See https://rolldown.rs/options/checks#plugintimings for more details.
|
|
538
|
+
[39m
|
|
539
539
|
dist/assets/icons/icon-assets-min/16_clipboard.js 0.64 kB │ gzip: 0.38 kB │ map: 0.72 kB
|
|
540
540
|
dist/components/PlFileDialog/utils.js 0.64 kB │ gzip: 0.43 kB │ map: 2.18 kB
|
|
541
541
|
dist/assets/icons/icon-assets-min/24_frame-type-none.js 0.65 kB │ gzip: 0.30 kB │ map: 0.72 kB
|
|
@@ -779,16 +779,16 @@ dist/components/PlNumberField/PlNumberField.vue_vue_type_script_setup_true_lang.
|
|
|
779
779
|
dist/components/PlDropdownLine/PlDropdownLine.vue_vue_type_script_setup_true_lang.js 7.15 kB │ gzip: 2.53 kB │ map: 20.82 kB
|
|
780
780
|
dist/components/PlFileDialog/Remote.vue_vue_type_script_setup_true_lang.js 7.32 kB │ gzip: 2.76 kB │ map: 15.24 kB
|
|
781
781
|
dist/components/SliderRangeTriple.vue_vue_type_script_setup_true_lang.js 7.35 kB │ gzip: 2.43 kB │ map: 15.58 kB
|
|
782
|
-
dist/components/PlDropdownLegacy/PlDropdownLegacy.vue_vue_type_script_setup_true_lang.js 7.
|
|
783
|
-
dist/components/PlDropdown/PlDropdown.vue_vue_type_script_setup_true_lang.js 7.95 kB │ gzip: 2.80 kB │ map: 23.31 kB
|
|
782
|
+
dist/components/PlDropdownLegacy/PlDropdownLegacy.vue_vue_type_script_setup_true_lang.js 7.94 kB │ gzip: 2.84 kB │ map: 16.19 kB
|
|
784
783
|
dist/components/PlDropdownMulti/PlDropdownMulti.vue_vue_type_script_setup_true_lang.js 7.96 kB │ gzip: 2.87 kB │ map: 23.66 kB
|
|
784
|
+
dist/components/PlDropdown/PlDropdown.vue_vue_type_script_setup_true_lang.js 8.12 kB │ gzip: 2.84 kB │ map: 23.81 kB
|
|
785
785
|
dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue_vue_type_script_setup_true_lang.js 8.35 kB │ gzip: 3.04 kB │ map: 24.74 kB
|
|
786
|
-
dist/components/PlAutocomplete/PlAutocomplete.vue_vue_type_script_setup_true_lang.js 8.
|
|
786
|
+
dist/components/PlAutocomplete/PlAutocomplete.vue_vue_type_script_setup_true_lang.js 8.89 kB │ gzip: 3.14 kB │ map: 26.37 kB
|
|
787
787
|
dist/components/PlElementList/PlElementList.vue_vue_type_script_setup_true_lang.js 9.01 kB │ gzip: 2.39 kB │ map: 20.07 kB
|
|
788
788
|
dist/demo-site-data/all-css-variables.js 9.68 kB │ gzip: 1.75 kB │ map: 17.53 kB
|
|
789
789
|
dist/composition/filters/metadata.js 11.37 kB │ gzip: 1.20 kB │ map: 22.01 kB
|
|
790
790
|
dist/index.js 12.53 kB │ gzip: 2.96 kB │ map: 21.32 kB
|
|
791
791
|
dist/components/PlSvg/PlSvg.vue_vue_type_script_setup_true_lang.js 39.41 kB │ gzip: 3.40 kB │ map: 8.66 kB
|
|
792
792
|
|
|
793
|
-
[32m✓ built in
|
|
793
|
+
[32m✓ built in 8.81s[39m
|
|
794
794
|
Build completed successfully
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @milaboratories/uikit@2.15.
|
|
3
|
+
> @milaboratories/uikit@2.15.30 formatter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
|
|
4
4
|
> ts-builder formatter --check
|
|
5
5
|
|
|
6
6
|
Checking formatting...
|
|
@@ -8,5 +8,5 @@ Checking formatting...
|
|
|
8
8
|
Checking formatting...
|
|
9
9
|
|
|
10
10
|
All matched files use the correct format.
|
|
11
|
-
Finished in
|
|
11
|
+
Finished in 3124ms on 383 files using 16 threads.
|
|
12
12
|
Format check completed successfully
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @milaboratories/uikit@2.15.
|
|
3
|
+
> @milaboratories/uikit@2.15.30 linter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
|
|
4
4
|
> ts-builder linter --check
|
|
5
5
|
|
|
6
6
|
Linting project...
|
|
7
7
|
↳ oxlint --config /home/runner/_work/platforma/platforma/lib/ui/uikit/.oxlintrc.json --deny-warnings
|
|
8
8
|
Found 0 warnings and 0 errors.
|
|
9
|
-
Finished in
|
|
9
|
+
Finished in 34ms on 310 files with 108 rules using 16 threads.
|
|
10
10
|
Linting completed successfully
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @milaboratories/uikit@2.15.
|
|
3
|
+
> @milaboratories/uikit@2.15.30 types:check /home/runner/_work/platforma/platforma/lib/ui/uikit
|
|
4
4
|
> ts-builder type-check --target browser-lib
|
|
5
5
|
|
|
6
6
|
↳ vue-tsc-ts6.cjs --noEmit --project ./tsconfig.json --customConditions default
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @milaboratories/uikit
|
|
2
2
|
|
|
3
|
+
## 2.15.30
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @platforma-sdk/model@1.83.17
|
|
8
|
+
|
|
9
|
+
## 2.15.29
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- b659a5d: PlDropdown, PlDropdownLegacy, PlAutocomplete: show the full selected value as a native tooltip on hover when it is truncated with an ellipsis
|
|
14
|
+
|
|
3
15
|
## 2.15.28
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAutocomplete.js","names":[],"sources":["../../../src/components/PlAutocomplete/PlAutocomplete.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a big list of options using string search request\n */\nexport default {\n name: \"PlAutocomplete\",\n};\n</script>\n\n<script\n lang=\"ts\"\n setup\n generic=\"M extends null | undefined | string | number = null | undefined | string\"\n>\nimport \"./pl-autocomplete.scss\";\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from \"vue\";\nimport { tap } from \"../../helpers/functions\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport type { ListOption, ListOptionNormalized } from \"../../types\";\nimport { deepEqual } from \"../../helpers/objects\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport LongText from \"../LongText.vue\";\nimport { normalizeListOptions } from \"../../helpers/utils\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { DropdownOverlay } from \"../../utils/DropdownOverlay\";\nimport { refDebounced } from \"@vueuse/core\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport { PlSvg } from \"../PlSvg\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { isNil } from \"@milaboratories/helpers\";\n\n/**\n * The current selected value.\n */\nconst model = defineModel<M>({ required: true });\n\nconst props = withDefaults(\n defineProps<{\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: (string: string, type: \"value\" | \"label\") => Promise<ListOption<M>[]>;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\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 * Placeholder text shown when no value is selected.\n */\n placeholder?: 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?: string;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: string;\n /**\n * Option list item size\n */\n optionSize?: \"small\" | \"medium\";\n /**\n * Formatter for the selected value if its label is absent\n */\n formatValue?: (value: M) => string;\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 modelSearch: undefined,\n label: \"\",\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: \"small\",\n formatValue: (v: M) => String(v),\n groupPosition: undefined,\n },\n);\n\nconst slots = defineSlots<{\n [key: string]: unknown;\n}>();\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst overlayRef = useTemplateRef(\"overlay\");\n\nconst search = ref<string | null>(null);\nconst data = reactive({\n activeIndex: -1,\n open: false,\n});\n\nconst findActiveIndex = () =>\n tap(\n renderedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.value)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst loadedOptionsRef = ref<ListOption<M>[]>([]);\nconst modelOptionRef = ref<ListOptionNormalized<M> | undefined>(); // list of 1 option that is selected or empty, to keep selected label\n\nconst renderedOptionsRef = computed(() => {\n return normalizeListOptions(loadedOptionsRef.value).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })) as (ListOptionBase<M> & { index: number; isSelected: boolean; isActive: boolean })[];\n});\nconst isLoadingOptions = ref<boolean>(true);\nconst isLoadingError = ref<boolean>(false);\n\nconst isDisabled = computed(() => {\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return loadedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.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 if (isLoadingError.value) {\n return \"Data loading error\";\n }\n\n return undefined;\n});\n\nconst textValue = computed(() => {\n const modelOption = unref(modelOptionRef);\n const options = unref(renderedOptionsRef);\n\n const item: ListOptionNormalized | undefined =\n modelOption ??\n options.find((o) => deepEqual(o.value, model.value)) ??\n options.find((o) => deepEqual(o.value, model.value));\n\n return item?.label || (model.value ? props.formatValue(model.value) : \"\");\n});\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && model.value) {\n return \"\";\n }\n\n return model.value ? String(textValue.value) : props.placeholder;\n});\n\nconst hasValue = computed(() => {\n return model.value !== undefined && model.value !== null;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst selectOption = (v: (ListOptionBase<M> & { index: number }) | undefined) => {\n model.value = v?.value as M;\n modelOptionRef.value = v;\n search.value = null;\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst clear = () => {\n model.value = undefined as M;\n modelOptionRef.value = undefined;\n};\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n};\n\nwatch(\n () => data.open,\n (v) => {\n search.value = v ? \"\" : null;\n },\n);\n\nconst onInputFocus = () => {\n data.open = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (\n !rootRef.value?.contains(relatedTarget) &&\n !overlayRef.value?.listRef?.contains(relatedTarget)\n ) {\n search.value = null;\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 search.value = \"\";\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n search.value = null;\n rootRef.value?.focus();\n }\n\n const options = unref(renderedOptionsRef);\n\n const { length } = options;\n\n if (!length) {\n return;\n }\n\n if (e.code === \"Enter\") {\n selectOption(options.find((it) => it.index === activeIndex));\n }\n\n const localIndex = options.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 = renderedOptionsRef.value[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => model.value, 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 search.value; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n overlayRef.value?.scrollIntoActive();\n }\n});\n\nconst searchDebounced = refDebounced(search, 300, { maxWait: 1000 });\n\nconst optionsRequest = useWatchFetch(\n () => searchDebounced.value,\n async (v) => (isNil(v) ? undefined : props.optionsSearch(v, \"label\")),\n);\n\nconst modelOptionRequest = useWatchFetch(\n () => model.value,\n async (v) => {\n if (isNil(v) || deepEqual(modelOptionRef.value?.value, v)) {\n return modelOptionRef.value;\n }\n\n const options = await props.optionsSearch(String(v), \"value\");\n return options.find((o) => String(o.value) === String(v));\n },\n);\n\nwatch(\n () => optionsRequest.value,\n (result) => {\n if (result) {\n loadedOptionsRef.value = result;\n if (search.value !== null) {\n isLoadingError.value = false;\n }\n }\n },\n);\n\nwatch(\n () => modelOptionRequest.value,\n (result) => {\n if (result) {\n modelOptionRef.value = normalizeListOptions([result])[0];\n }\n },\n);\n\nwatch(\n () => optionsRequest.error,\n (err) => {\n if (err) {\n isLoadingError.value = Boolean(err);\n }\n },\n);\n\nwatch(\n () => optionsRequest.loading || modelOptionRequest.loading,\n (loading) => {\n isLoadingOptions.value = loading;\n },\n);\n</script>\n\n<template>\n <div class=\"pl-autocomplete__envelope\" @click.stop=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete__container\">\n <div class=\"pl-autocomplete__field\">\n <input\n ref=\"input\"\n v-model=\"search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\">\n <LongText> {{ textValue }} </LongText>\n </div>\n\n <div class=\"pl-autocomplete__controls\">\n <PlMaskIcon24 v-if=\"isLoadingOptions\" name=\"loading\" />\n <PlIcon16\n v-if=\"clearable && hasValue\"\n class=\"clear\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <slot name=\"append\" />\n <div class=\"pl-autocomplete__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <div\n v-if=\"arrowIconLarge\"\n class=\"arrow-icon\"\n :class=\"[`icon-24 ${arrowIconLarge}`]\"\n />\n <div v-else-if=\"arrowIcon\" class=\"arrow-icon\" :class=\"[`icon-16 ${arrowIcon}`]\" />\n <div v-else class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" />\n <span>{{ label }}</span>\n <PlTooltip v-if=\"slots.tooltip\" class=\"info\" position=\"top\">\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete__options\"\n tabindex=\"-1\"\n :gap=\"3\"\n >\n <DropdownListItem\n v-for=\"(item, index) in renderedOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :is-selected=\"item.isSelected\"\n :is-hovered=\"item.isActive\"\n :size=\"optionSize\"\n @click.stop=\"selectOption(item)\"\n />\n <div v-if=\"!renderedOptionsRef.length\" class=\"nothing-found\">Nothing found</div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete__error\">{{ computedError }}</div>\n <div v-else-if=\"isLoadingOptions && loadingOptionsHelper\" class=\"pl-autocomplete__helper\">\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"PlAutocomplete.js","names":[],"sources":["../../../src/components/PlAutocomplete/PlAutocomplete.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a big list of options using string search request\n */\nexport default {\n name: \"PlAutocomplete\",\n};\n</script>\n\n<script\n lang=\"ts\"\n setup\n generic=\"M extends null | undefined | string | number = null | undefined | string\"\n>\nimport \"./pl-autocomplete.scss\";\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from \"vue\";\nimport { tap } from \"../../helpers/functions\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport type { ListOption, ListOptionNormalized } from \"../../types\";\nimport { deepEqual } from \"../../helpers/objects\";\nimport DropdownListItem from \"../DropdownListItem.vue\";\nimport LongText from \"../LongText.vue\";\nimport { normalizeListOptions } from \"../../helpers/utils\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlMaskIcon24 } from \"../PlMaskIcon24\";\nimport { DropdownOverlay } from \"../../utils/DropdownOverlay\";\nimport { refDebounced } from \"@vueuse/core\";\nimport { useWatchFetch } from \"../../composition/useWatchFetch.ts\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport type { ListOptionBase } from \"@platforma-sdk/model\";\nimport { PlSvg } from \"../PlSvg\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { isNil } from \"@milaboratories/helpers\";\n\n/**\n * The current selected value.\n */\nconst model = defineModel<M>({ required: true });\n\nconst props = withDefaults(\n defineProps<{\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: (string: string, type: \"value\" | \"label\") => Promise<ListOption<M>[]>;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\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 * Placeholder text shown when no value is selected.\n */\n placeholder?: 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?: string;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: string;\n /**\n * Option list item size\n */\n optionSize?: \"small\" | \"medium\";\n /**\n * Formatter for the selected value if its label is absent\n */\n formatValue?: (value: M) => string;\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 modelSearch: undefined,\n label: \"\",\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: \"small\",\n formatValue: (v: M) => String(v),\n groupPosition: undefined,\n },\n);\n\nconst slots = defineSlots<{\n [key: string]: unknown;\n}>();\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst overlayRef = useTemplateRef(\"overlay\");\n\nconst search = ref<string | null>(null);\nconst data = reactive({\n activeIndex: -1,\n open: false,\n});\n\nconst findActiveIndex = () =>\n tap(\n renderedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.value)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst loadedOptionsRef = ref<ListOption<M>[]>([]);\nconst modelOptionRef = ref<ListOptionNormalized<M> | undefined>(); // list of 1 option that is selected or empty, to keep selected label\n\nconst renderedOptionsRef = computed(() => {\n return normalizeListOptions(loadedOptionsRef.value).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })) as (ListOptionBase<M> & { index: number; isSelected: boolean; isActive: boolean })[];\n});\nconst isLoadingOptions = ref<boolean>(true);\nconst isLoadingError = ref<boolean>(false);\n\nconst isDisabled = computed(() => {\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return loadedOptionsRef.value.findIndex((o) => deepEqual(o.value, model.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 if (isLoadingError.value) {\n return \"Data loading error\";\n }\n\n return undefined;\n});\n\nconst textValue = computed(() => {\n const modelOption = unref(modelOptionRef);\n const options = unref(renderedOptionsRef);\n\n const item: ListOptionNormalized | undefined =\n modelOption ??\n options.find((o) => deepEqual(o.value, model.value)) ??\n options.find((o) => deepEqual(o.value, model.value));\n\n return item?.label || (model.value ? props.formatValue(model.value) : \"\");\n});\n\n// Native tooltip with the full selected value; the value layer itself has\n// `pointer-events: none`, so the title goes on the field wrapper.\nconst fieldTitle = computed(() => (!data.open && textValue.value ? textValue.value : undefined));\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && model.value) {\n return \"\";\n }\n\n return model.value ? String(textValue.value) : props.placeholder;\n});\n\nconst hasValue = computed(() => {\n return model.value !== undefined && model.value !== null;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : \"0\"));\n\nconst selectOption = (v: (ListOptionBase<M> & { index: number }) | undefined) => {\n model.value = v?.value as M;\n modelOptionRef.value = v;\n search.value = null;\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst clear = () => {\n model.value = undefined as M;\n modelOptionRef.value = undefined;\n};\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n};\n\nwatch(\n () => data.open,\n (v) => {\n search.value = v ? \"\" : null;\n },\n);\n\nconst onInputFocus = () => {\n data.open = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (\n !rootRef.value?.contains(relatedTarget) &&\n !overlayRef.value?.listRef?.contains(relatedTarget)\n ) {\n search.value = null;\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 search.value = \"\";\n }\n return;\n }\n\n if (e.code === \"Escape\") {\n data.open = false;\n search.value = null;\n rootRef.value?.focus();\n }\n\n const options = unref(renderedOptionsRef);\n\n const { length } = options;\n\n if (!length) {\n return;\n }\n\n if (e.code === \"Enter\") {\n selectOption(options.find((it) => it.index === activeIndex));\n }\n\n const localIndex = options.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 = renderedOptionsRef.value[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => model.value, 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 search.value; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n overlayRef.value?.scrollIntoActive();\n }\n});\n\nconst searchDebounced = refDebounced(search, 300, { maxWait: 1000 });\n\nconst optionsRequest = useWatchFetch(\n () => searchDebounced.value,\n async (v) => (isNil(v) ? undefined : props.optionsSearch(v, \"label\")),\n);\n\nconst modelOptionRequest = useWatchFetch(\n () => model.value,\n async (v) => {\n if (isNil(v) || deepEqual(modelOptionRef.value?.value, v)) {\n return modelOptionRef.value;\n }\n\n const options = await props.optionsSearch(String(v), \"value\");\n return options.find((o) => String(o.value) === String(v));\n },\n);\n\nwatch(\n () => optionsRequest.value,\n (result) => {\n if (result) {\n loadedOptionsRef.value = result;\n if (search.value !== null) {\n isLoadingError.value = false;\n }\n }\n },\n);\n\nwatch(\n () => modelOptionRequest.value,\n (result) => {\n if (result) {\n modelOptionRef.value = normalizeListOptions([result])[0];\n }\n },\n);\n\nwatch(\n () => optionsRequest.error,\n (err) => {\n if (err) {\n isLoadingError.value = Boolean(err);\n }\n },\n);\n\nwatch(\n () => optionsRequest.loading || modelOptionRequest.loading,\n (loading) => {\n isLoadingOptions.value = loading;\n },\n);\n</script>\n\n<template>\n <div class=\"pl-autocomplete__envelope\" @click.stop=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete__container\">\n <div class=\"pl-autocomplete__field\" :title=\"fieldTitle\">\n <input\n ref=\"input\"\n v-model=\"search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\">\n <LongText> {{ textValue }} </LongText>\n </div>\n\n <div class=\"pl-autocomplete__controls\">\n <PlMaskIcon24 v-if=\"isLoadingOptions\" name=\"loading\" />\n <PlIcon16\n v-if=\"clearable && hasValue\"\n class=\"clear\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <slot name=\"append\" />\n <div class=\"pl-autocomplete__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <div\n v-if=\"arrowIconLarge\"\n class=\"arrow-icon\"\n :class=\"[`icon-24 ${arrowIconLarge}`]\"\n />\n <div v-else-if=\"arrowIcon\" class=\"arrow-icon\" :class=\"[`icon-16 ${arrowIcon}`]\" />\n <div v-else class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" />\n <span>{{ label }}</span>\n <PlTooltip v-if=\"slots.tooltip\" class=\"info\" position=\"top\">\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete__options\"\n tabindex=\"-1\"\n :gap=\"3\"\n >\n <DropdownListItem\n v-for=\"(item, index) in renderedOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :is-selected=\"item.isSelected\"\n :is-hovered=\"item.isActive\"\n :size=\"optionSize\"\n @click.stop=\"selectOption(item)\"\n />\n <div v-if=\"!renderedOptionsRef.length\" class=\"nothing-found\">Nothing found</div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete__error\">{{ computedError }}</div>\n <div v-else-if=\"isLoadingOptions && loadingOptionsHelper\" class=\"pl-autocomplete__helper\">\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAutocomplete.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlAutocomplete/PlAutocomplete.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlAutocomplete.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlAutocomplete/PlAutocomplete.vue"],"names":[],"mappings":"AAodA,OAAO,wBAAwB,CAAC;AAMhC,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,aAAa,CAAC;AAiBpE;;GAEG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAC9F,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;WAkrBO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;QA3qBpD;;WAEG;uBACY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF;;WAEG;gBACK,MAAM;QACd;;WAEG;iBACM,MAAM;QACf;;WAEG;+BACoB,MAAM;QAC7B;;WAEG;gBACK,OAAO;QACf;;WAEG;sBACW,MAAM;QACpB;;WAEG;oBACS,OAAO;QACnB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;oBACS,MAAM;QAClB;;WAEG;yBACc,MAAM;QACvB;;WAEG;qBACU,OAAO,GAAG,QAAQ;QAC/B;;WAEG;sBACW,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM;QAClC;;aAEK;wBAED,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,QAAQ;;QAoRhB;;WAEG;oBACS,CAAC;;;KAoV8E,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;;;;;EAIP,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"}
|
|
@@ -19,29 +19,29 @@ import re from "../../utils/DropdownOverlay/DropdownOverlay.js";
|
|
|
19
19
|
import "../../utils/DropdownOverlay/index.js";
|
|
20
20
|
import { useWatchFetch as l } from "../../composition/useWatchFetch.js";
|
|
21
21
|
import ie from "../../assets/images/required.js";
|
|
22
|
-
import { Fragment as ae, computed as u, createBlock as d, createCommentVNode as f, createElementBlock as p, createElementVNode as m, createTextVNode as oe, createVNode as h, defineComponent as g, mergeModels as _, normalizeClass as v, openBlock as y, reactive as se, ref as b, renderList as ce, renderSlot as x, toDisplayString as S, unref as C, useModel as
|
|
23
|
-
import { isNil as
|
|
24
|
-
import { refDebounced as
|
|
22
|
+
import { Fragment as ae, computed as u, createBlock as d, createCommentVNode as f, createElementBlock as p, createElementVNode as m, createTextVNode as oe, createVNode as h, defineComponent as g, mergeModels as _, normalizeClass as v, openBlock as y, reactive as se, ref as b, renderList as ce, renderSlot as x, toDisplayString as S, unref as C, useModel as le, useSlots as ue, useTemplateRef as de, vModelText as fe, watch as w, watchPostEffect as pe, withCtx as T, withDirectives as me, withModifiers as E } from "vue";
|
|
23
|
+
import { isNil as D } from "@milaboratories/helpers";
|
|
24
|
+
import { refDebounced as he } from "@vueuse/core";
|
|
25
25
|
//#region src/components/PlAutocomplete/PlAutocomplete.vue?vue&type=script&setup=true&lang.ts
|
|
26
|
-
var
|
|
26
|
+
var ge = ["tabindex"], _e = { class: "pl-autocomplete__container" }, ve = ["title"], O = ["disabled", "placeholder"], k = {
|
|
27
27
|
key: 0,
|
|
28
28
|
class: "input-value"
|
|
29
|
-
},
|
|
29
|
+
}, A = { class: "pl-autocomplete__controls" }, j = {
|
|
30
30
|
key: 2,
|
|
31
31
|
class: "arrow-icon arrow-icon-default"
|
|
32
|
-
},
|
|
32
|
+
}, M = { key: 0 }, N = {
|
|
33
33
|
key: 0,
|
|
34
34
|
class: "nothing-found"
|
|
35
|
-
},
|
|
35
|
+
}, P = {
|
|
36
36
|
key: 0,
|
|
37
37
|
class: "pl-autocomplete__error"
|
|
38
|
-
},
|
|
38
|
+
}, F = {
|
|
39
39
|
key: 1,
|
|
40
40
|
class: "pl-autocomplete__helper"
|
|
41
|
-
},
|
|
41
|
+
}, ye = {
|
|
42
42
|
key: 2,
|
|
43
43
|
class: "pl-autocomplete__helper"
|
|
44
|
-
},
|
|
44
|
+
}, I = /* @__PURE__ */ g({
|
|
45
45
|
name: "PlAutocomplete",
|
|
46
46
|
props: /* @__PURE__ */ _({
|
|
47
47
|
optionsSearch: {},
|
|
@@ -76,38 +76,38 @@ var he = ["tabindex"], ge = { class: "pl-autocomplete__container" }, _e = { clas
|
|
|
76
76
|
}),
|
|
77
77
|
emits: ["update:modelValue"],
|
|
78
78
|
setup(g) {
|
|
79
|
-
let _ =
|
|
79
|
+
let _ = le(g, "modelValue"), I = g, be = ue(), L = b(), R = b(), z = de("overlay"), B = b(null), V = se({
|
|
80
80
|
activeIndex: -1,
|
|
81
81
|
open: !1
|
|
82
|
-
}),
|
|
82
|
+
}), xe = () => t(W.value.findIndex((e) => c(e.value, _.value)), (e) => e < 0 ? 0 : e), Se = () => V.activeIndex = xe(), H = b([]), U = b(), W = u(() => n(H.value).map((e, t) => ({
|
|
83
83
|
...e,
|
|
84
84
|
index: t,
|
|
85
|
-
isSelected: t ===
|
|
86
|
-
isActive: t ===
|
|
87
|
-
}))),
|
|
88
|
-
if (!
|
|
89
|
-
if (
|
|
90
|
-
if (
|
|
85
|
+
isSelected: t === Ce.value,
|
|
86
|
+
isActive: t === V.activeIndex
|
|
87
|
+
}))), G = b(!0), K = b(!1), q = u(() => I.disabled), Ce = u(() => H.value.findIndex((e) => c(e.value, _.value))), J = u(() => {
|
|
88
|
+
if (!G.value) {
|
|
89
|
+
if (I.error) return i(I.error);
|
|
90
|
+
if (K.value) return "Data loading error";
|
|
91
91
|
}
|
|
92
|
-
}),
|
|
93
|
-
let e = C(
|
|
94
|
-
return (e ?? t.find((e) => c(e.value, _.value)) ?? t.find((e) => c(e.value, _.value)))?.label || (_.value ?
|
|
95
|
-
}),
|
|
96
|
-
_.value = e?.value,
|
|
97
|
-
},
|
|
98
|
-
_.value = void 0,
|
|
99
|
-
},
|
|
100
|
-
|
|
92
|
+
}), Y = u(() => {
|
|
93
|
+
let e = C(U), t = C(W);
|
|
94
|
+
return (e ?? t.find((e) => c(e.value, _.value)) ?? t.find((e) => c(e.value, _.value)))?.label || (_.value ? I.formatValue(_.value) : "");
|
|
95
|
+
}), we = u(() => !V.open && Y.value ? Y.value : void 0), Te = u(() => !V.open && _.value ? "" : _.value ? String(Y.value) : I.placeholder), Ee = u(() => _.value !== void 0 && _.value !== null), De = u(() => q.value ? void 0 : "0"), X = (e) => {
|
|
96
|
+
_.value = e?.value, U.value = e, B.value = null, V.open = !1, L?.value?.focus();
|
|
97
|
+
}, Oe = () => {
|
|
98
|
+
_.value = void 0, U.value = void 0;
|
|
99
|
+
}, ke = () => R.value?.focus(), Z = () => {
|
|
100
|
+
V.open = !V.open;
|
|
101
101
|
};
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
w(() => V.open, (e) => {
|
|
103
|
+
B.value = e ? "" : null;
|
|
104
104
|
});
|
|
105
|
-
let
|
|
106
|
-
|
|
107
|
-
}, Ae = (e) => {
|
|
108
|
-
let t = e.relatedTarget;
|
|
109
|
-
!R.value?.contains(t) && !B.value?.listRef?.contains(t) && (V.value = null, H.open = !1);
|
|
105
|
+
let Ae = () => {
|
|
106
|
+
V.open = !0;
|
|
110
107
|
}, je = (e) => {
|
|
108
|
+
let t = e.relatedTarget;
|
|
109
|
+
!L.value?.contains(t) && !z.value?.listRef?.contains(t) && (B.value = null, V.open = !1);
|
|
110
|
+
}, Me = (e) => {
|
|
111
111
|
if ([
|
|
112
112
|
"ArrowDown",
|
|
113
113
|
"ArrowUp",
|
|
@@ -115,133 +115,136 @@ var he = ["tabindex"], ge = { class: "pl-autocomplete__container" }, _e = { clas
|
|
|
115
115
|
"Escape"
|
|
116
116
|
].includes(e.code)) e.preventDefault();
|
|
117
117
|
else return;
|
|
118
|
-
let { open: t, activeIndex: n } =
|
|
118
|
+
let { open: t, activeIndex: n } = V;
|
|
119
119
|
if (!t) {
|
|
120
|
-
e.code === "Enter" && (
|
|
120
|
+
e.code === "Enter" && (V.open = !0, B.value = "");
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
|
-
e.code === "Escape" && (
|
|
124
|
-
let r = C(
|
|
123
|
+
e.code === "Escape" && (V.open = !1, B.value = null, L.value?.focus());
|
|
124
|
+
let r = C(W), { length: i } = r;
|
|
125
125
|
if (!i) return;
|
|
126
|
-
e.code === "Enter" &&
|
|
126
|
+
e.code === "Enter" && X(r.find((e) => e.index === n));
|
|
127
127
|
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;
|
|
128
|
-
|
|
128
|
+
V.activeIndex = W.value[s].index ?? -1;
|
|
129
129
|
};
|
|
130
|
-
ne(
|
|
131
|
-
|
|
130
|
+
ne(L), w(() => _.value, Se, { immediate: !0 }), w(() => V.open, (e) => e ? R.value?.focus() : ""), pe(() => {
|
|
131
|
+
B.value, V.activeIndex >= 0 && V.open && z.value?.scrollIntoActive();
|
|
132
132
|
});
|
|
133
|
-
let
|
|
134
|
-
return
|
|
135
|
-
e && (
|
|
136
|
-
}),
|
|
137
|
-
e && (
|
|
138
|
-
}),
|
|
139
|
-
e && (
|
|
140
|
-
}),
|
|
141
|
-
|
|
133
|
+
let Ne = he(B, 300, { maxWait: 1e3 }), Q = l(() => Ne.value, async (e) => D(e) ? void 0 : I.optionsSearch(e, "label")), $ = l(() => _.value, async (e) => D(e) || c(U.value?.value, e) ? U.value : (await I.optionsSearch(String(e), "value")).find((t) => String(t.value) === String(e)));
|
|
134
|
+
return w(() => Q.value, (e) => {
|
|
135
|
+
e && (H.value = e, B.value !== null && (K.value = !1));
|
|
136
|
+
}), w(() => $.value, (e) => {
|
|
137
|
+
e && (U.value = n([e])[0]);
|
|
138
|
+
}), w(() => Q.error, (e) => {
|
|
139
|
+
e && (K.value = !!e);
|
|
140
|
+
}), w(() => Q.loading || $.loading, (e) => {
|
|
141
|
+
G.value = e;
|
|
142
142
|
}), (t, n) => (y(), p("div", {
|
|
143
143
|
class: "pl-autocomplete__envelope",
|
|
144
|
-
onClick:
|
|
144
|
+
onClick: E(ke, ["stop"])
|
|
145
145
|
}, [m("div", {
|
|
146
146
|
ref_key: "rootRef",
|
|
147
|
-
ref:
|
|
148
|
-
tabindex:
|
|
147
|
+
ref: L,
|
|
148
|
+
tabindex: De.value,
|
|
149
149
|
class: v(["pl-autocomplete", {
|
|
150
|
-
open:
|
|
151
|
-
error: !!
|
|
152
|
-
disabled:
|
|
150
|
+
open: V.open,
|
|
151
|
+
error: !!J.value,
|
|
152
|
+
disabled: q.value
|
|
153
153
|
}]),
|
|
154
|
-
onKeydown:
|
|
155
|
-
onFocusout:
|
|
156
|
-
}, [m("div",
|
|
157
|
-
m("div",
|
|
158
|
-
|
|
154
|
+
onKeydown: Me,
|
|
155
|
+
onFocusout: je
|
|
156
|
+
}, [m("div", _e, [
|
|
157
|
+
m("div", {
|
|
158
|
+
class: "pl-autocomplete__field",
|
|
159
|
+
title: we.value
|
|
160
|
+
}, [
|
|
161
|
+
me(m("input", {
|
|
159
162
|
ref_key: "input",
|
|
160
|
-
ref:
|
|
161
|
-
"onUpdate:modelValue": n[0] ||= (e) =>
|
|
163
|
+
ref: R,
|
|
164
|
+
"onUpdate:modelValue": n[0] ||= (e) => B.value = e,
|
|
162
165
|
type: "text",
|
|
163
166
|
tabindex: "-1",
|
|
164
|
-
disabled:
|
|
165
|
-
placeholder:
|
|
167
|
+
disabled: q.value,
|
|
168
|
+
placeholder: Te.value,
|
|
166
169
|
spellcheck: "false",
|
|
167
170
|
autocomplete: "chrome-off",
|
|
168
|
-
onFocus:
|
|
169
|
-
}, null, 40,
|
|
170
|
-
|
|
171
|
-
default:
|
|
171
|
+
onFocus: Ae
|
|
172
|
+
}, null, 40, O), [[fe, B.value]]),
|
|
173
|
+
V.open ? f("", !0) : (y(), p("div", k, [h(a, null, {
|
|
174
|
+
default: T(() => [oe(S(Y.value), 1)]),
|
|
172
175
|
_: 1
|
|
173
176
|
})])),
|
|
174
|
-
m("div",
|
|
175
|
-
|
|
177
|
+
m("div", A, [
|
|
178
|
+
G.value ? (y(), d(C(s), {
|
|
176
179
|
key: 0,
|
|
177
180
|
name: "loading"
|
|
178
181
|
})) : f("", !0),
|
|
179
|
-
g.clearable &&
|
|
182
|
+
g.clearable && Ee.value ? (y(), d(C(ee), {
|
|
180
183
|
key: 1,
|
|
181
184
|
class: "clear",
|
|
182
185
|
name: "delete-clear",
|
|
183
|
-
onClick:
|
|
186
|
+
onClick: E(Oe, ["stop"])
|
|
184
187
|
})) : f("", !0),
|
|
185
188
|
x(t.$slots, "append"),
|
|
186
189
|
m("div", {
|
|
187
190
|
class: "pl-autocomplete__arrow-wrapper",
|
|
188
|
-
onClick:
|
|
191
|
+
onClick: E(Z, ["stop"])
|
|
189
192
|
}, [g.arrowIconLarge ? (y(), p("div", {
|
|
190
193
|
key: 0,
|
|
191
194
|
class: v(["arrow-icon", [`icon-24 ${g.arrowIconLarge}`]])
|
|
192
195
|
}, null, 2)) : g.arrowIcon ? (y(), p("div", {
|
|
193
196
|
key: 1,
|
|
194
197
|
class: v(["arrow-icon", [`icon-16 ${g.arrowIcon}`]])
|
|
195
|
-
}, null, 2)) : (y(), p("div",
|
|
198
|
+
}, null, 2)) : (y(), p("div", j))])
|
|
196
199
|
])
|
|
197
|
-
]),
|
|
198
|
-
g.label ? (y(), p("label",
|
|
200
|
+
], 8, ve),
|
|
201
|
+
g.label ? (y(), p("label", M, [
|
|
199
202
|
g.required ? (y(), d(C(o), {
|
|
200
203
|
key: 0,
|
|
201
204
|
uri: C(ie)
|
|
202
205
|
}, null, 8, ["uri"])) : f("", !0),
|
|
203
206
|
m("span", null, S(g.label), 1),
|
|
204
|
-
|
|
207
|
+
be.tooltip ? (y(), d(C(r), {
|
|
205
208
|
key: 1,
|
|
206
209
|
class: "info",
|
|
207
210
|
position: "top"
|
|
208
211
|
}, {
|
|
209
|
-
tooltip:
|
|
212
|
+
tooltip: T(() => [x(t.$slots, "tooltip")]),
|
|
210
213
|
_: 3
|
|
211
214
|
})) : f("", !0)
|
|
212
215
|
])) : f("", !0),
|
|
213
|
-
|
|
216
|
+
V.open ? (y(), d(C(re), {
|
|
214
217
|
key: 1,
|
|
215
218
|
ref: "overlay",
|
|
216
|
-
root:
|
|
219
|
+
root: L.value,
|
|
217
220
|
class: "pl-autocomplete__options",
|
|
218
221
|
tabindex: "-1",
|
|
219
222
|
gap: 3
|
|
220
223
|
}, {
|
|
221
|
-
default:
|
|
224
|
+
default: T(() => [(y(!0), p(ae, null, ce(W.value, (t, n) => (y(), d(e, {
|
|
222
225
|
key: n,
|
|
223
226
|
option: t,
|
|
224
227
|
"is-selected": t.isSelected,
|
|
225
228
|
"is-hovered": t.isActive,
|
|
226
229
|
size: g.optionSize,
|
|
227
|
-
onClick:
|
|
230
|
+
onClick: E((e) => X(t), ["stop"])
|
|
228
231
|
}, null, 8, [
|
|
229
232
|
"option",
|
|
230
233
|
"is-selected",
|
|
231
234
|
"is-hovered",
|
|
232
235
|
"size",
|
|
233
236
|
"onClick"
|
|
234
|
-
]))), 128)),
|
|
237
|
+
]))), 128)), W.value.length ? f("", !0) : (y(), p("div", N, "Nothing found"))]),
|
|
235
238
|
_: 1
|
|
236
239
|
}, 8, ["root"])) : f("", !0),
|
|
237
240
|
h(te, {
|
|
238
241
|
class: "pl-autocomplete__contour",
|
|
239
242
|
"group-position": g.groupPosition
|
|
240
243
|
}, null, 8, ["group-position"])
|
|
241
|
-
])], 42,
|
|
244
|
+
])], 42, ge), J.value ? (y(), p("div", P, S(J.value), 1)) : G.value && g.loadingOptionsHelper ? (y(), p("div", F, S(g.loadingOptionsHelper), 1)) : g.helper ? (y(), p("div", ye, S(g.helper), 1)) : f("", !0)]));
|
|
242
245
|
}
|
|
243
246
|
});
|
|
244
247
|
//#endregion
|
|
245
|
-
export {
|
|
248
|
+
export { I as default };
|
|
246
249
|
|
|
247
250
|
//# sourceMappingURL=PlAutocomplete.vue2.js.map
|