@milaboratories/uikit 2.14.25 → 2.15.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.
Files changed (40) hide show
  1. package/.turbo/turbo-build.log +21 -21
  2. package/.turbo/turbo-formatter$colon$check.log +2 -2
  3. package/.turbo/turbo-linter$colon$check.log +2 -2
  4. package/.turbo/turbo-types$colon$check.log +1 -1
  5. package/CHANGELOG.md +16 -0
  6. package/dist/components/PlAlert/pl-alert.css +1 -1
  7. package/dist/components/PlDropdown/PlDropdown.js.map +1 -1
  8. package/dist/components/PlDropdown/PlDropdown.vue.d.ts +5 -0
  9. package/dist/components/PlDropdown/PlDropdown.vue.d.ts.map +1 -1
  10. package/dist/components/PlDropdown/PlDropdown.vue2.js +66 -62
  11. package/dist/components/PlDropdown/PlDropdown.vue2.js.map +1 -1
  12. package/dist/components/PlDropdown/pl-dropdown.css +1 -1
  13. package/dist/components/PlDropdownMulti/PlDropdownMulti.js.map +1 -1
  14. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.d.ts +5 -0
  15. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.d.ts.map +1 -1
  16. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue2.js +75 -58
  17. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue2.js.map +1 -1
  18. package/dist/components/PlDropdownMulti/pl-dropdown-multi.css +1 -1
  19. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.js.map +1 -1
  20. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue.d.ts +6 -0
  21. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue.d.ts.map +1 -1
  22. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue2.js +1 -0
  23. package/dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue2.js.map +1 -1
  24. package/dist/components/PlDropdownRef/PlDropdownRef.js.map +1 -1
  25. package/dist/components/PlDropdownRef/PlDropdownRef.vue.d.ts +5 -0
  26. package/dist/components/PlDropdownRef/PlDropdownRef.vue.d.ts.map +1 -1
  27. package/dist/components/PlDropdownRef/PlDropdownRef.vue2.js +1 -0
  28. package/dist/components/PlDropdownRef/PlDropdownRef.vue2.js.map +1 -1
  29. package/package.json +2 -2
  30. package/src/components/PlAlert/pl-alert.scss +3 -1
  31. package/src/components/PlDropdown/PlDropdown.vue +25 -14
  32. package/src/components/PlDropdown/__tests__/PlDropdown.spec.ts +119 -0
  33. package/src/components/PlDropdown/pl-dropdown.scss +9 -0
  34. package/src/components/PlDropdownMulti/PlDropdownMulti.vue +32 -4
  35. package/src/components/PlDropdownMulti/__tests__/PlDropdownMulti.spec.ts +135 -0
  36. package/src/components/PlDropdownMulti/pl-dropdown-multi.scss +11 -0
  37. package/src/components/PlDropdownMultiRef/PlDropdownMultiRef.vue +6 -0
  38. package/src/components/PlDropdownMultiRef/__tests__/PlDropdownMultiRef.spec.ts +42 -0
  39. package/src/components/PlDropdownRef/PlDropdownRef.vue +6 -0
  40. package/src/components/PlDropdownRef/__tests__/PlDropdownRef.spec.ts +53 -0
@@ -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.14.25 build /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.15.1 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...
@@ -24,7 +24,7 @@ Using custom config: ./build.browser-lib.config.js
24
24
  rendering chunks...
25
25
 
26
26
  [vite:dts] Start generate declaration files...
27
- [vite:dts] Declaration files built in 8852ms.
27
+ [vite:dts] Declaration files built in 6690ms.
28
28
 
29
29
  computing gzip size...
30
30
  dist/components/PlClipboard/PlClipboard.vue?vue&type=style&index=0&lang.css 0.04 kB │ gzip: 0.06 kB
@@ -91,11 +91,11 @@ dist/components/PlTooltip/PlTooltip.vue?vue&type=style&index=0&lang.css
91
91
  dist/components/PlDropdownLine/pl-dropdown-line.css 4.55 kB │ gzip: 1.24 kB
92
92
  dist/components/PlFileInput/pl-file-input.css 4.67 kB │ gzip: 1.24 kB
93
93
  dist/components/PlSidebar/PlSidebarGroup.vue?vue&type=style&index=0&lang.css 4.78 kB │ gzip: 1.30 kB
94
- dist/components/PlDropdown/pl-dropdown.css 4.88 kB │ gzip: 1.31 kB
95
94
  dist/components/PlSidebar/PlSidebarItem.vue?vue&type=style&index=0&lang.css 4.89 kB │ gzip: 1.36 kB
95
+ dist/components/PlDropdown/pl-dropdown.css 5.00 kB │ gzip: 1.33 kB
96
96
  dist/components/PlCheckbox/pl-checkbox-base.css 5.69 kB │ gzip: 0.75 kB
97
97
  dist/components/PlAutocomplete/pl-autocomplete.css 6.28 kB │ gzip: 1.70 kB
98
- dist/components/PlDropdownMulti/pl-dropdown-multi.css 7.35 kB │ gzip: 1.93 kB
98
+ dist/components/PlDropdownMulti/pl-dropdown-multi.css 7.54 kB │ gzip: 1.96 kB
99
99
  dist/components/PlAutocompleteMulti/pl-autocomplete-multi.css 7.55 kB │ gzip: 1.94 kB
100
100
  dist/components/DataTable/assets/data-table-style.css 8.17 kB │ gzip: 2.12 kB
101
101
  dist/components/PlFileDialog/pl-file-dialog.css 46.28 kB │ gzip: 16.05 kB
@@ -203,7 +203,7 @@ dist/components/PlBtnGroup/PlBtnGroup.js
203
203
  dist/components/PlBtnSplit/PlBtnSplit.js 0.20 kB │ gzip: 0.16 kB │ map: 5.82 kB
204
204
  dist/components/PlCheckbox/PlCheckbox.js 0.20 kB │ gzip: 0.16 kB │ map: 1.37 kB
205
205
  dist/components/PlDropdown/OptionList.js 0.20 kB │ gzip: 0.17 kB │ map: 2.40 kB
206
- dist/components/PlDropdown/PlDropdown.js 0.20 kB │ gzip: 0.16 kB │ map: 11.84 kB
206
+ dist/components/PlDropdown/PlDropdown.js 0.20 kB │ gzip: 0.16 kB │ map: 12.33 kB
207
207
  dist/components/PlTextArea/PlTextArea.js 0.20 kB │ gzip: 0.16 kB │ map: 4.74 kB
208
208
  dist/layout/PlContainer/PlContainer.js 0.20 kB │ gzip: 0.16 kB │ map: 0.94 kB
209
209
  dist/components/PlSlideModal/props.js 0.20 kB │ gzip: 0.18 kB │ map: 0.75 kB
@@ -225,7 +225,7 @@ dist/components/SliderRangeTriple.js
225
225
  dist/components/DataTable/TableComponent.js 0.21 kB │ gzip: 0.16 kB │ map: 3.77 kB
226
226
  dist/components/PlCheckbox/PlCheckboxBase.js 0.22 kB │ gzip: 0.17 kB │ map: 0.73 kB
227
227
  dist/components/PlDialogModal/PlDialogModal.js 0.22 kB │ gzip: 0.16 kB │ map: 4.61 kB
228
- dist/components/PlDropdownRef/PlDropdownRef.js 0.22 kB │ gzip: 0.16 kB │ map: 3.02 kB
228
+ dist/components/PlDropdownRef/PlDropdownRef.js 0.22 kB │ gzip: 0.16 kB │ map: 3.27 kB
229
229
  dist/components/PlNumberField/PlNumberField.js 0.22 kB │ gzip: 0.16 kB │ map: 10.17 kB
230
230
  dist/components/PlProgressBar/PlProgressBar.js 0.22 kB │ gzip: 0.16 kB │ map: 0.93 kB
231
231
  dist/components/DataTable/RowsCommandMenu.js 0.22 kB │ gzip: 0.17 kB │ map: 1.05 kB
@@ -239,7 +239,7 @@ dist/components/PlToggleSwitch/PlToggleSwitch.js
239
239
  dist/components/TransitionSlidePanel.js 0.22 kB │ gzip: 0.16 kB │ map: 0.51 kB
240
240
  dist/components/DataTable/BaseCellComponent.js 0.22 kB │ gzip: 0.17 kB │ map: 1.67 kB
241
241
  dist/components/PlCheckboxGroup/PlCheckboxGroup.js 0.22 kB │ gzip: 0.17 kB │ map: 2.26 kB
242
- dist/components/PlDropdownMulti/PlDropdownMulti.js 0.22 kB │ gzip: 0.16 kB │ map: 10.24 kB
242
+ dist/components/PlDropdownMulti/PlDropdownMulti.js 0.22 kB │ gzip: 0.16 kB │ map: 11.48 kB
243
243
  dist/components/PlEditableTitle/PlEditableTitle.js 0.22 kB │ gzip: 0.16 kB │ map: 3.01 kB
244
244
  dist/components/PlErrorBoundary/PlErrorBoundary.js 0.22 kB │ gzip: 0.17 kB │ map: 1.73 kB
245
245
  dist/components/PlSlideModal/PlPureSlideModal.js 0.22 kB │ gzip: 0.17 kB │ map: 1.91 kB
@@ -250,7 +250,7 @@ dist/components/PlEditableTitle/pl-editable-title.module.js
250
250
  dist/components/PlLoaderCircular/PlLoaderCircular.js 0.23 kB │ gzip: 0.16 kB │ map: 1.02 kB
251
251
  dist/layout/PlBlockPage/PlBlockPageTitleTeleportTarget.js 0.23 kB │ gzip: 0.16 kB │ map: 0.31 kB
252
252
  dist/helpers/index.js 0.23 kB │ gzip: 0.19 kB │ map: 0.58 kB
253
- dist/components/PlDropdownMultiRef/PlDropdownMultiRef.js 0.24 kB │ gzip: 0.17 kB │ map: 2.17 kB
253
+ dist/components/PlDropdownMultiRef/PlDropdownMultiRef.js 0.24 kB │ gzip: 0.17 kB │ map: 2.42 kB
254
254
  dist/components/PlLoaderLogo.vue_vue_type_style_index_0_lang.module.js 0.24 kB │ gzip: 0.19 kB │ map: 0.45 kB
255
255
  dist/components/PlAutocompleteMulti/PlAutocompleteMulti.js 0.24 kB │ gzip: 0.17 kB │ map: 13.35 kB
256
256
  dist/components/PlNotificationAlert/PlNotificationAlert.js 0.24 kB │ gzip: 0.17 kB │ map: 1.31 kB
@@ -534,6 +534,14 @@ dist/composition/useQuery.js
534
534
  dist/assets/icons/icon-assets-min/16_settings.js 0.64 kB │ gzip: 0.37 kB │ map: 0.71 kB
535
535
  dist/assets/icons/icon-assets-min/24_table-upload.js 0.64 kB │ gzip: 0.38 kB │ map: 0.73 kB
536
536
  dist/assets/icons/icon-assets-min/16_data-dimentions.js 0.64 kB │ gzip: 0.42 kB │ map: 0.74 kB
537
+ [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
538
+ - vite:asset (36%)
539
+ - sourcemaps (14%)
540
+ - vite:css-post (11%)
541
+ - vite:dts (10%)
542
+ - vite:vue (9%)
543
+ See https://rolldown.rs/options/checks#plugintimings for more details.
544
+ 
537
545
  dist/assets/icons/icon-assets-min/16_clipboard.js 0.64 kB │ gzip: 0.38 kB │ map: 0.72 kB
538
546
  dist/components/PlFileDialog/utils.js 0.64 kB │ gzip: 0.43 kB │ map: 2.18 kB
539
547
  dist/assets/icons/icon-assets-min/24_frame-type-none.js 0.65 kB │ gzip: 0.30 kB │ map: 0.72 kB
@@ -589,14 +597,6 @@ dist/assets/icons/icon-assets-min/24_folder-parent.js
589
597
  dist/assets/icons/icon-assets-min/24_file-doc-add.js 0.74 kB │ gzip: 0.43 kB │ map: 0.83 kB
590
598
  dist/assets/icons/icon-assets-min/24_filter.js 0.74 kB │ gzip: 0.44 kB │ map: 0.83 kB
591
599
  dist/assets/icons/icon-assets-min/24_cpu.js 0.74 kB │ gzip: 0.42 kB │ map: 0.82 kB
592
- [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
593
- - vite:asset (42%)
594
- - vite:dts (11%)
595
- - vite:css-post (11%)
596
- - vite:css (8%)
597
- - vite:vue (8%)
598
- See https://rolldown.rs/options/checks#plugintimings for more details.
599
- 
600
600
  dist/components/PlChartHistogram/createGridlines.js 0.75 kB │ gzip: 0.42 kB │ map: 2.52 kB
601
601
  dist/assets/icons/icon-assets-min/24_cloud-online.js 0.76 kB │ gzip: 0.47 kB │ map: 0.84 kB
602
602
  dist/generated/icons-16.js 0.76 kB │ gzip: 0.44 kB │ map: 1.35 kB
@@ -692,10 +692,10 @@ dist/helpers/dom.js
692
692
  dist/assets/icons/icon-assets-min/24_dna-add.js 1.23 kB │ gzip: 0.71 kB │ map: 1.32 kB
693
693
  dist/assets/icons/icon-assets-min/24_line-binned.js 1.23 kB │ gzip: 0.60 kB │ map: 1.33 kB
694
694
  dist/assets/icons/icon-assets-min/24_cluster.js 1.24 kB │ gzip: 0.52 kB │ map: 1.32 kB
695
- dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue_vue_type_script_setup_true_lang.js 1.26 kB │ gzip: 0.64 kB │ map: 2.53 kB
696
695
  dist/components/DataTable/RowsCommandMenu.vue_vue_type_script_setup_true_lang.js 1.26 kB │ gzip: 0.71 kB │ map: 1.72 kB
697
696
  dist/components/DataTable/ColumnsCommandMenu.vue_vue_type_script_setup_true_lang.js 1.27 kB │ gzip: 0.70 kB │ map: 1.71 kB
698
697
  dist/components/DataTable/TScroll.vue_vue_type_script_setup_true_lang.js 1.30 kB │ gzip: 0.69 kB │ map: 2.11 kB
698
+ dist/components/PlDropdownMultiRef/PlDropdownMultiRef.vue_vue_type_script_setup_true_lang.js 1.32 kB │ gzip: 0.67 kB │ map: 2.77 kB
699
699
  dist/assets/icons/icon-assets-min/24_annotate.js 1.33 kB │ gzip: 0.73 kB │ map: 1.44 kB
700
700
  dist/components/PlDropdownLine/ResizableInput.vue_vue_type_script_setup_true_lang.js 1.34 kB │ gzip: 0.72 kB │ map: 3.31 kB
701
701
  dist/components/PlErrorAlert/PlErrorAlert.vue_vue_type_script_setup_true_lang.js 1.37 kB │ gzip: 0.66 kB │ map: 3.02 kB
@@ -712,9 +712,9 @@ dist/components/DataTable/composition/useResize.js
712
712
  dist/components/PlErrorBoundary/PlErrorBoundary.vue_vue_type_script_setup_true_lang.js 1.47 kB │ gzip: 0.78 kB │ map: 2.45 kB
713
713
  dist/components/HScroll.vue_vue_type_script_setup_true_lang.js 1.48 kB │ gzip: 0.78 kB │ map: 2.40 kB
714
714
  dist/components/VScroll.vue_vue_type_script_setup_true_lang.js 1.48 kB │ gzip: 0.78 kB │ map: 2.40 kB
715
- dist/components/PlDropdownRef/PlDropdownRef.vue_vue_type_script_setup_true_lang.js 1.49 kB │ gzip: 0.72 kB │ map: 3.47 kB
716
715
  dist/components/PlSlideModal/PlSlideModal.vue_vue_type_script_setup_true_lang.js 1.50 kB │ gzip: 0.74 kB │ map: 3.99 kB
717
716
  dist/components/PlTabs/PlTabs.vue_vue_type_script_setup_true_lang.js 1.52 kB │ gzip: 0.81 kB │ map: 2.73 kB
717
+ dist/components/PlDropdownRef/PlDropdownRef.vue_vue_type_script_setup_true_lang.js 1.55 kB │ gzip: 0.75 kB │ map: 3.72 kB
718
718
  dist/assets/icons/icon-assets-min/24_social-youtube.js 1.58 kB │ gzip: 0.81 kB │ map: 1.67 kB
719
719
  dist/layout/PlPlaceholder/PlPlaceholder.vue_vue_type_script_setup_true_lang.js 1.59 kB │ gzip: 0.81 kB │ map: 4.80 kB
720
720
  dist/components/PlChip/PlChip.vue_vue_type_script_setup_true_lang.js 1.59 kB │ gzip: 0.84 kB │ map: 4.46 kB
@@ -785,9 +785,9 @@ dist/components/PlNumberField/PlNumberField.vue_vue_type_script_setup_true_lang.
785
785
  dist/components/PlDropdownLine/PlDropdownLine.vue_vue_type_script_setup_true_lang.js 7.23 kB │ gzip: 2.55 kB │ map: 21.04 kB
786
786
  dist/components/PlFileDialog/Remote.vue_vue_type_script_setup_true_lang.js 7.32 kB │ gzip: 2.76 kB │ map: 15.24 kB
787
787
  dist/components/SliderRangeTriple.vue_vue_type_script_setup_true_lang.js 7.35 kB │ gzip: 2.43 kB │ map: 15.58 kB
788
- dist/components/PlDropdownMulti/PlDropdownMulti.vue_vue_type_script_setup_true_lang.js 7.54 kB │ gzip: 2.76 kB │ map: 22.56 kB
789
788
  dist/components/PlDropdownLegacy/PlDropdownLegacy.vue_vue_type_script_setup_true_lang.js 7.78 kB │ gzip: 2.80 kB │ map: 15.70 kB
790
- dist/components/PlDropdown/PlDropdown.vue_vue_type_script_setup_true_lang.js 7.79 kB │ gzip: 2.77 kB │ map: 22.70 kB
789
+ dist/components/PlDropdown/PlDropdown.vue_vue_type_script_setup_true_lang.js 7.95 kB │ gzip: 2.80 kB │ map: 23.31 kB
790
+ dist/components/PlDropdownMulti/PlDropdownMulti.vue_vue_type_script_setup_true_lang.js 7.96 kB │ gzip: 2.87 kB │ map: 23.66 kB
791
791
  dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue_vue_type_script_setup_true_lang.js 8.35 kB │ gzip: 3.04 kB │ map: 24.74 kB
792
792
  dist/components/PlAutocomplete/PlAutocomplete.vue_vue_type_script_setup_true_lang.js 8.79 kB │ gzip: 3.11 kB │ map: 26.05 kB
793
793
  dist/components/PlElementList/PlElementList.vue_vue_type_script_setup_true_lang.js 9.01 kB │ gzip: 2.39 kB │ map: 20.07 kB
@@ -796,5 +796,5 @@ dist/composition/filters/metadata.js
796
796
  dist/index.js 12.53 kB │ gzip: 2.96 kB │ map: 21.32 kB
797
797
  dist/components/PlSvg/PlSvg.vue_vue_type_script_setup_true_lang.js 39.41 kB │ gzip: 3.40 kB │ map: 8.66 kB
798
798
 
799
- ✓ built in 11.48s
799
+ ✓ built in 8.78s
800
800
  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.14.25 formatter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.15.1 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 6116ms on 381 files using 8 threads.
11
+ Finished in 7565ms on 381 files using 8 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.14.25 linter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.15.1 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 31ms on 308 files with 108 rules using 8 threads.
9
+ Finished in 36ms on 308 files with 108 rules using 8 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.14.25 types:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.15.1 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.js --noEmit --project ./tsconfig.json --customConditions ,
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @milaboratories/uikit
2
2
 
3
+ ## 2.15.1
4
+
5
+ ### Patch Changes
6
+
7
+ - @platforma-sdk/model@1.78.12
8
+
9
+ ## 2.15.0
10
+
11
+ ### Minor Changes
12
+
13
+ - a6de7cb: Fix `PlDropdown`, `PlDropdownMulti`, `PlDropdownRef`, and `PlDropdownMultiRef`: selected values missing from the options list — typically `PlRef`s whose upstream block was deleted — now render an italic "Value not available" / "Upstream value removed" label instead of leaking the raw value. Multi variants surface missing entries as closeable chips instead of dropping them. All four components accept a `missingValueLabel` prop for custom text.
14
+
15
+ ### Patch Changes
16
+
17
+ - 09a2985: `PlAlert`: center the `closeable` close button on the first line of text. The X was pinned ~6px too low on single-line alerts; it now aligns with the text on both single-line and multi-line alerts.
18
+
3
19
  ## 2.14.25
4
20
 
5
21
  ### Patch Changes
@@ -1 +1 @@
1
- .pl-alert{--text-font-family:var(--font-family-base);--text-white-space:normal;--indent:24px;border:1px solid var(--border-color-default);color:var(--txt-01);border-radius:6px;flex-wrap:nowrap;gap:12px;padding:12px;display:flex;position:relative}.pl-alert.monospace{--text-font-family:var(--font-family-monospace)}.pl-alert.whiteSpacePre{--text-white-space:pre}.pl-alert__error{background:var(--notification-error)}.pl-alert__warn{background:var(--notification-warning)}.pl-alert__success{background:var(--notification-success)}.pl-alert__info{background:var(--notification-neutral)}.pl-alert__icon{width:24px}.pl-alert__main{flex-direction:column;flex:1;gap:6px;width:100%;min-height:24px;display:flex;overflow:hidden}.pl-alert__main label{letter-spacing:-.2px;font-size:20px;font-weight:500;line-height:24px}.pl-alert__main__text{font-size:14px;font-weight:500;line-height:20px;font-family:var(--text-font-family);white-space:var(--text-white-space);--thumb-color:var(--ic-02);flex:1;max-width:100%;overflow-y:auto}.pl-alert__main__text::-webkit-scrollbar{width:var(--scrollbar-width,6px);background-color:#0000;height:5px;display:block}.pl-alert__main__text::-webkit-scrollbar-thumb{background:var(--thumb-color);border-radius:5px}.pl-alert__main__text::-webkit-scrollbar-thumb:hover{--thumb-color:var(--border-color-focus)}.pl-alert__close-btn{position:absolute;top:10px;right:12px}
1
+ .pl-alert{--text-font-family:var(--font-family-base);--text-white-space:normal;--indent:24px;border:1px solid var(--border-color-default);color:var(--txt-01);border-radius:6px;flex-wrap:nowrap;gap:12px;padding:12px;display:flex;position:relative}.pl-alert.monospace{--text-font-family:var(--font-family-monospace)}.pl-alert.whiteSpacePre{--text-white-space:pre}.pl-alert__error{background:var(--notification-error)}.pl-alert__warn{background:var(--notification-warning)}.pl-alert__success{background:var(--notification-success)}.pl-alert__info{background:var(--notification-neutral)}.pl-alert__icon{width:24px}.pl-alert__main{flex-direction:column;flex:1;gap:6px;width:100%;min-height:24px;display:flex;overflow:hidden}.pl-alert__main label{letter-spacing:-.2px;font-size:20px;font-weight:500;line-height:24px}.pl-alert__main__text{font-size:14px;font-weight:500;line-height:20px;font-family:var(--text-font-family);white-space:var(--text-white-space);--thumb-color:var(--ic-02);flex:1;max-width:100%;overflow-y:auto}.pl-alert__main__text::-webkit-scrollbar{width:var(--scrollbar-width,6px);background-color:#0000;height:5px;display:block}.pl-alert__main__text::-webkit-scrollbar-thumb{background:var(--thumb-color);border-radius:5px}.pl-alert__main__text::-webkit-scrollbar-thumb:hover{--thumb-color:var(--border-color-focus)}.pl-alert__close-btn{position:absolute;top:4px;right:12px}
@@ -1 +1 @@
1
- {"version":3,"file":"PlDropdown.js","names":[],"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 { 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 * 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 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 computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue !== undefined && selectedIndex.value === -1) {\n return \"The selected value is not one of the options\";\n }\n\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 textValue = computed(() => {\n const options = unref(optionsRef);\n\n const item: ListOption | undefined = options.find((o) => deepEqual(o.value, props.modelValue));\n\n return item?.label || props.modelValue; // @todo show inner value?\n});\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && props.modelValue !== undefined) {\n return \"\";\n }\n\n return props.modelValue ? String(textValue.value) : props.placeholder;\n});\n\nconst hasValue = computed(() => {\n return props.modelValue !== undefined && props.modelValue !== null;\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\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-dropdown\"\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\">\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 @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\">\n <LongText> {{ textValue }} </LongText>\n </div>\n\n <div class=\"pl-dropdown__controls\">\n <PlIcon24 v-if=\"showLoadingSpinner\" 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-dropdown__arrow-wrapper\" @click.stop=\"toggleOpen\">\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\">\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 <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\">{{ computedError }}</div>\n <div v-else-if=\"showLoadingSpinner && loadingOptionsHelper\" class=\"pl-dropdown__helper\">\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-dropdown__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"PlDropdown.js","names":[],"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 { 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 textValue = computed(() => {\n const options = unref(optionsRef);\n const item: ListOption | undefined = options.find((o) => deepEqual(o.value, props.modelValue));\n return item?.label;\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\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-dropdown\"\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\">\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 @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\">\n <LongText v-if=\"isMissing\" class=\"input-value--missing\">\n {{ missingValueLabel }}\n </LongText>\n <LongText v-else-if=\"textValue !== undefined\">\n {{ textValue }}\n </LongText>\n </div>\n\n <div class=\"pl-dropdown__controls\">\n <PlIcon24 v-if=\"showLoadingSpinner\" 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-dropdown__arrow-wrapper\" @click.stop=\"toggleOpen\">\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\">\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 <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\">{{ computedError }}</div>\n <div v-else-if=\"showLoadingSpinner && loadingOptionsHelper\" class=\"pl-dropdown__helper\">\n {{ loadingOptionsHelper }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-dropdown__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":""}
@@ -38,6 +38,11 @@ declare const _default: <M = unknown>(__VLS_props: NonNullable<Awaited<typeof __
38
38
  * Placeholder text shown when no value is selected.
39
39
  */
40
40
  placeholder?: string;
41
+ /**
42
+ * 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
+ */
45
+ missingValueLabel?: string;
41
46
  /**
42
47
  * Enables a button to clear the selected value (default: false)
43
48
  */
@@ -1 +1 @@
1
- {"version":3,"file":"PlDropdown.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"names":[],"mappings":"AAsaA,OAAO,KAAK,EAAE,UAAU,EAAwB,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AASpG,OAAO,oBAAoB,CAAC;AAK5B;;GAEG;yBACc,CAAC,GAAG,OAAO,EAC3B,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,eAAe,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EACjE;WAqnBO,mBAAmB,CAAC;;;QA3mBxB;;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;;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;mBAuiB8E,CAAC,4BAA2B;oBACzG,OAAO,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,IAAI;WAClD,GAAG;;wBA/DkB,GAAG;yBACF,GAAG;;cApjB3B,mBAAmB,SAAS,CAAC,GAAG,SAAS,KAAG,IAAI;EAsnBlD,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAA;CAAE;AAhoBzE,wBAgoB4E;AAG5E,KAAK,mBAAmB,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"PlDropdown.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"names":[],"mappings":"AAibA,OAAO,KAAK,EAAE,UAAU,EAAwB,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AASpG,OAAO,oBAAoB,CAAC;AAK5B;;GAEG;yBACc,CAAC,GAAG,OAAO,EAC3B,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,eAAe,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EACjE;WA6oBO,mBAAmB,CAAC;;;QAnoBxB;;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;;;WAGG;4BACiB,MAAM;QAC1B;;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;mBA0jB8E,CAAC,4BAA2B;oBACzG,OAAO,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,IAAI;WAClD,GAAG;;wBAhEkB,GAAG;yBACF,GAAG;;cA3kB3B,mBAAmB,SAAS,CAAC,GAAG,SAAS,KAAG,IAAI;EA8oBlD,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAA;CAAE;AAxpBzE,wBAwpB4E;AAG5E,KAAK,mBAAmB,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC"}
@@ -22,16 +22,16 @@ import { computed as f, createBlock as p, createCommentVNode as m, createElement
22
22
  var ae = ["tabindex"], oe = { class: "pl-dropdown__container" }, se = { class: "pl-dropdown__field" }, ce = ["disabled", "placeholder"], le = {
23
23
  key: 0,
24
24
  class: "input-value"
25
- }, ue = { class: "pl-dropdown__controls" }, j = { key: 0 }, M = {
25
+ }, ue = { class: "pl-dropdown__controls" }, de = { key: 0 }, j = {
26
26
  key: 0,
27
27
  class: "pl-dropdown__error"
28
- }, N = {
28
+ }, M = {
29
29
  key: 1,
30
30
  class: "pl-dropdown__helper"
31
- }, P = {
31
+ }, N = {
32
32
  key: 2,
33
33
  class: "pl-dropdown__helper"
34
- }, F = /* @__PURE__ */ y({
34
+ }, P = /* @__PURE__ */ y({
35
35
  name: "PlDropdown",
36
36
  props: {
37
37
  modelValue: {},
@@ -42,6 +42,7 @@ var ae = ["tabindex"], oe = { class: "pl-dropdown__container" }, se = { class: "
42
42
  error: { default: void 0 },
43
43
  errorStatus: { type: Boolean },
44
44
  placeholder: { default: "..." },
45
+ missingValueLabel: { default: "Value not available" },
45
46
  clearable: {
46
47
  type: Boolean,
47
48
  default: !1
@@ -60,38 +61,35 @@ var ae = ["tabindex"], oe = { class: "pl-dropdown__container" }, se = { class: "
60
61
  groupPosition: { default: void 0 }
61
62
  },
62
63
  emits: ["update:modelValue"],
63
- setup(y, { emit: F }) {
64
- let I = F, L = y, R = S(), z = S(), B = E("optionListRef"), V = x({
64
+ setup(y, { emit: P }) {
65
+ let F = P, I = y, L = S(), R = S(), z = E("optionListRef"), B = x({
65
66
  search: "",
66
67
  activeIndex: -1,
67
68
  open: !1,
68
69
  optionsHeight: 0
69
- }), H = () => e(Z.value.findIndex((e) => l(e.value, L.modelValue)), (e) => e < 0 ? 0 : e), U = () => V.activeIndex = H(), W = f(() => L.options === void 0), G = f(() => !L.disabled && W.value), K = f(() => W.value ? !0 : L.disabled), q = f(() => (L.options ?? []).findIndex((e) => l(e.value, L.modelValue))), J = f(() => {
70
- if (!W.value) {
71
- if (L.error) return r(L.error);
72
- if (L.modelValue !== void 0 && q.value === -1) return "The selected value is not one of the options";
73
- }
74
- }), Y = f(() => t(L.options ?? []).map((e, t) => ({
70
+ }), V = () => e(Z.value.findIndex((e) => l(e.value, I.modelValue)), (e) => e < 0 ? 0 : e), H = () => B.activeIndex = V(), U = f(() => I.options === void 0), W = f(() => !I.disabled && U.value), G = f(() => U.value ? !0 : I.disabled), K = f(() => (I.options ?? []).findIndex((e) => l(e.value, I.modelValue))), q = f(() => I.modelValue !== void 0 && I.modelValue !== null), fe = f(() => q.value && K.value === -1 && !U.value), J = f(() => {
71
+ if (!U.value && I.error) return r(I.error);
72
+ }), Y = f(() => t(I.options ?? []).map((e, t) => ({
75
73
  ...e,
76
74
  index: t,
77
- isSelected: t === q.value,
78
- isActive: t === V.activeIndex
79
- }))), X = f(() => T(Y).find((e) => l(e.value, L.modelValue))?.label || L.modelValue), de = f(() => !V.open && L.modelValue !== void 0 ? "" : L.modelValue ? String(X.value) : L.placeholder), fe = f(() => L.modelValue !== void 0 && L.modelValue !== null), { orderedRef: Z, groupsRef: pe, restRef: me } = d(f(() => {
75
+ isSelected: t === K.value,
76
+ isActive: t === B.activeIndex
77
+ }))), X = f(() => T(Y).find((e) => l(e.value, I.modelValue))?.label), pe = f(() => !B.open && q.value ? "" : X.value ? String(X.value) : I.placeholder), { orderedRef: Z, groupsRef: me, restRef: he } = d(f(() => {
80
78
  let e = Y.value;
81
- return V.search ? e.filter((e) => {
82
- let t = V.search.toLowerCase();
83
- 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 === V.search;
79
+ return B.search ? e.filter((e) => {
80
+ let t = B.search.toLowerCase();
81
+ 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 === B.search;
84
82
  }) : e;
85
- }), "group"), Q = f(() => K.value ? void 0 : "0"), $ = (e) => {
86
- I("update:modelValue", e), V.search = "", V.open = !1, R?.value?.focus();
87
- }, he = (e) => {
88
- $(e);
89
- }, ge = () => I("update:modelValue", void 0), _e = () => z.value?.focus(), ve = () => {
90
- V.open = !V.open, V.open || (V.search = "");
91
- }, ye = () => V.open = !0, be = (e) => {
83
+ }), "group"), ge = f(() => G.value ? void 0 : "0"), Q = (e) => {
84
+ F("update:modelValue", e), B.search = "", B.open = !1, L?.value?.focus();
85
+ }, $ = (e) => {
86
+ Q(e);
87
+ }, _e = () => F("update:modelValue", void 0), ve = () => R.value?.focus(), ye = () => {
88
+ B.open = !B.open, B.open || (B.search = "");
89
+ }, be = () => B.open = !0, xe = (e) => {
92
90
  let t = e.relatedTarget;
93
- !R.value?.contains(t) && !B.value?.listRef?.contains(t) && (V.search = "", V.open = !1);
94
- }, xe = (e) => {
91
+ !L.value?.contains(t) && !z.value?.listRef?.contains(t) && (B.search = "", B.open = !1);
92
+ }, Se = (e) => {
95
93
  if ([
96
94
  "ArrowDown",
97
95
  "ArrowUp",
@@ -99,67 +97,73 @@ var ae = ["tabindex"], oe = { class: "pl-dropdown__container" }, se = { class: "
99
97
  "Escape"
100
98
  ].includes(e.code)) e.preventDefault();
101
99
  else return;
102
- let { open: t, activeIndex: n } = V;
100
+ let { open: t, activeIndex: n } = B;
103
101
  if (!t) {
104
- e.code === "Enter" && (V.open = !0);
102
+ e.code === "Enter" && (B.open = !0);
105
103
  return;
106
104
  }
107
- e.code === "Escape" && (V.open = !1, R.value?.focus());
105
+ e.code === "Escape" && (B.open = !1, L.value?.focus());
108
106
  let r = Z.value, { length: i } = r;
109
107
  if (!i) return;
110
- e.code === "Enter" && $(r.find((e) => e.index === n)?.value);
108
+ e.code === "Enter" && Q(r.find((e) => e.index === n)?.value);
111
109
  let a = r.findIndex((e) => e.index === n) ?? -1, o = e.code === "ArrowDown" ? 1 : e.code === "ArrowUp" ? -1 : 0;
112
- V.activeIndex = r[Math.abs(a + o + i) % i].index ?? -1;
110
+ B.activeIndex = r[Math.abs(a + o + i) % i].index ?? -1;
113
111
  };
114
- return c(R), O(() => L.modelValue, U, { immediate: !0 }), O(() => V.open, (e) => e ? z.value?.focus() : ""), re(() => {
115
- V.search, V.activeIndex >= 0 && V.open && B.value?.scrollIntoActive();
112
+ return c(L), O(() => I.modelValue, H, { immediate: !0 }), O(() => B.open, (e) => e ? R.value?.focus() : ""), re(() => {
113
+ B.search, B.activeIndex >= 0 && B.open && z.value?.scrollIntoActive();
116
114
  }), (e, t) => (b(), h("div", {
117
115
  class: "pl-dropdown__envelope",
118
- onClick: _e
116
+ onClick: ve
119
117
  }, [g("div", {
120
118
  ref_key: "rootRef",
121
- ref: R,
122
- tabindex: Q.value,
119
+ ref: L,
120
+ tabindex: ge.value,
123
121
  class: ne(["pl-dropdown", {
124
- open: V.open,
122
+ open: B.open,
125
123
  error: y.error || y.errorStatus,
126
- disabled: K.value
124
+ disabled: G.value
127
125
  }]),
128
- onKeydown: xe,
129
- onFocusout: be
126
+ onKeydown: Se,
127
+ onFocusout: xe
130
128
  }, [g("div", oe, [
131
129
  g("div", se, [
132
130
  ie(g("input", {
133
131
  ref_key: "input",
134
- ref: z,
135
- "onUpdate:modelValue": t[0] ||= (e) => V.search = e,
132
+ ref: R,
133
+ "onUpdate:modelValue": t[0] ||= (e) => B.search = e,
136
134
  type: "text",
137
135
  tabindex: "-1",
138
- disabled: K.value,
139
- placeholder: de.value,
136
+ disabled: G.value,
137
+ placeholder: pe.value,
140
138
  spellcheck: "false",
141
139
  autocomplete: "chrome-off",
142
- onFocus: ye
143
- }, null, 40, ce), [[D, V.search]]),
144
- V.open ? m("", !0) : (b(), h("div", le, [v(i, null, {
140
+ onFocus: be
141
+ }, null, 40, ce), [[D, B.search]]),
142
+ B.open ? m("", !0) : (b(), h("div", le, [fe.value ? (b(), p(i, {
143
+ key: 0,
144
+ class: "input-value--missing"
145
+ }, {
146
+ default: k(() => [_(w(y.missingValueLabel), 1)]),
147
+ _: 1
148
+ })) : X.value === void 0 ? m("", !0) : (b(), p(i, { key: 1 }, {
145
149
  default: k(() => [_(w(X.value), 1)]),
146
150
  _: 1
147
- })])),
151
+ }))])),
148
152
  g("div", ue, [
149
- G.value ? (b(), p(T(o), {
153
+ W.value ? (b(), p(T(o), {
150
154
  key: 0,
151
155
  name: "loading"
152
156
  })) : m("", !0),
153
- y.clearable && fe.value ? (b(), p(T(s), {
157
+ y.clearable && q.value ? (b(), p(T(s), {
154
158
  key: 1,
155
159
  class: "clear",
156
160
  name: "delete-clear",
157
- onClick: A(ge, ["stop"])
161
+ onClick: A(_e, ["stop"])
158
162
  })) : m("", !0),
159
163
  C(e.$slots, "append"),
160
164
  g("div", {
161
165
  class: "pl-dropdown__arrow-wrapper",
162
- onClick: A(ve, ["stop"])
166
+ onClick: A(ye, ["stop"])
163
167
  }, [y.arrowIconLarge ? (b(), p(T(o), {
164
168
  key: 0,
165
169
  name: y.arrowIconLarge,
@@ -175,7 +179,7 @@ var ae = ["tabindex"], oe = { class: "pl-dropdown__container" }, se = { class: "
175
179
  }))])
176
180
  ])
177
181
  ]),
178
- y.label ? (b(), h("label", j, [
182
+ y.label ? (b(), h("label", de, [
179
183
  y.required ? (b(), p(T(a), {
180
184
  key: 0,
181
185
  uri: T(te)
@@ -190,15 +194,15 @@ var ae = ["tabindex"], oe = { class: "pl-dropdown__container" }, se = { class: "
190
194
  _: 3
191
195
  })) : m("", !0)
192
196
  ])) : m("", !0),
193
- V.open ? (b(), p(u, {
197
+ B.open ? (b(), p(u, {
194
198
  key: 1,
195
199
  ref_key: "optionListRef",
196
- ref: B,
197
- "root-ref": R.value,
198
- groups: T(pe),
199
- rest: T(me),
200
+ ref: z,
201
+ "root-ref": L.value,
202
+ groups: T(me),
203
+ rest: T(he),
200
204
  "option-size": y.optionSize,
201
- "select-option": he
205
+ "select-option": $
202
206
  }, null, 8, [
203
207
  "root-ref",
204
208
  "groups",
@@ -209,10 +213,10 @@ var ae = ["tabindex"], oe = { class: "pl-dropdown__container" }, se = { class: "
209
213
  class: "pl-dropdown__contour",
210
214
  "group-position": y.groupPosition
211
215
  }, null, 8, ["group-position"])
212
- ])], 42, ae), J.value ? (b(), h("div", M, w(J.value), 1)) : G.value && y.loadingOptionsHelper ? (b(), h("div", N, w(y.loadingOptionsHelper), 1)) : y.helper ? (b(), h("div", P, w(y.helper), 1)) : m("", !0)]));
216
+ ])], 42, ae), J.value ? (b(), h("div", j, w(J.value), 1)) : W.value && y.loadingOptionsHelper ? (b(), h("div", M, w(y.loadingOptionsHelper), 1)) : y.helper ? (b(), h("div", N, w(y.helper), 1)) : m("", !0)]));
213
217
  }
214
218
  });
215
219
  //#endregion
216
- export { F as default };
220
+ export { P as default };
217
221
 
218
222
  //# sourceMappingURL=PlDropdown.vue2.js.map