@milaboratories/uikit 2.11.9 → 2.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +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 +17 -0
- package/dist/components/LongText.js.map +1 -1
- package/dist/components/LongText.style.css +1 -1
- package/dist/components/LongText.vue.d.ts.map +1 -1
- package/dist/components/LongText.vue2.js +1 -1
- package/dist/components/LongText.vue2.js.map +1 -1
- package/dist/components/PlElementList/PlElementList.js.map +1 -1
- package/dist/components/PlElementList/PlElementList.style.js.map +1 -1
- package/dist/components/PlElementList/PlElementList.vue.d.ts.map +1 -1
- package/dist/components/PlElementList/PlElementList.vue2.js +95 -95
- package/dist/components/PlElementList/PlElementList.vue2.js.map +1 -1
- package/dist/components/PlElementList/utils.d.ts +1 -1
- package/dist/components/PlElementList/utils.d.ts.map +1 -1
- package/dist/components/PlElementList/utils.js +6 -5
- package/dist/components/PlElementList/utils.js.map +1 -1
- package/dist/composition/filters/metadata.js +16 -16
- package/dist/composition/filters/metadata.js.map +1 -1
- package/package.json +4 -4
- package/src/components/LongText.vue +6 -8
- package/src/components/PlElementList/PlElementList.vue +51 -42
- package/src/components/PlElementList/utils.ts +7 -6
- package/src/composition/filters/metadata.ts +16 -16
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.
|
|
3
|
+
> @milaboratories/uikit@2.12.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
|
|
27
|
+
[vite:dts] Declaration files built in 6998ms.
|
|
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
|
|
@@ -47,8 +47,8 @@ dist/utils/TextLabel.vue?vue&type=style&index=0&lang.css
|
|
|
47
47
|
dist/components/PlLoaderLogo.vue?vue&type=style&index=0&lang.css 0.44 kB │ gzip: 0.24 kB
|
|
48
48
|
dist/components/PlChartStackedBar/Legends.vue?vue&type=style&index=0&lang.css 0.44 kB │ gzip: 0.27 kB
|
|
49
49
|
dist/components/PlChartHistogram/PlChartHistogram.vue?vue&type=style&index=0&lang.css 0.44 kB │ gzip: 0.30 kB
|
|
50
|
+
dist/components/LongText.vue_vue_type_style_index_0_lang.css 0.48 kB │ gzip: 0.28 kB
|
|
50
51
|
dist/components/PlChartStackedBar/StackedRowCompact.vue?vue&type=style&index=0&lang.css 0.54 kB │ gzip: 0.27 kB
|
|
51
|
-
dist/components/LongText.vue_vue_type_style_index_0_lang.css 0.54 kB │ gzip: 0.30 kB
|
|
52
52
|
dist/components/PlCheckboxGroup/pl-checkbox-group.css 0.58 kB │ gzip: 0.27 kB
|
|
53
53
|
dist/components/PlDropdownLine/resizable-input.css 0.60 kB │ gzip: 0.28 kB
|
|
54
54
|
dist/utils/PlCloseModalBtn.vue?vue&type=style&index=0&lang.css 0.68 kB │ gzip: 0.40 kB
|
|
@@ -296,7 +296,6 @@ dist/components/PlRadio/PlRadio.js
|
|
|
296
296
|
dist/assets/icons/icon-assets-min/16_minus.js 0.33 kB │ gzip: 0.26 kB │ map: 0.41 kB
|
|
297
297
|
dist/components/PlIcon16/PlIcon16.js 0.33 kB │ gzip: 0.24 kB │ map: 1.28 kB
|
|
298
298
|
dist/components/PlIcon24/PlIcon24.js 0.33 kB │ gzip: 0.24 kB │ map: 1.99 kB
|
|
299
|
-
dist/components/PlElementList/utils.js 0.34 kB │ gzip: 0.26 kB │ map: 0.70 kB
|
|
300
299
|
dist/components/PlFileDialog/Shortcuts.js 0.34 kB │ gzip: 0.24 kB │ map: 2.27 kB
|
|
301
300
|
dist/components/PlTooltip/PlTooltip.js 0.34 kB │ gzip: 0.24 kB │ map: 9.08 kB
|
|
302
301
|
dist/components/PlChartStackedBar/StackedRow.js 0.34 kB │ gzip: 0.24 kB │ map: 2.73 kB
|
|
@@ -311,7 +310,7 @@ dist/components/PlSlideModal/PlSlideModal.js
|
|
|
311
310
|
dist/assets/icons/icon-assets-min/16_add.js 0.35 kB │ gzip: 0.26 kB │ map: 0.42 kB
|
|
312
311
|
dist/assets/icons/icon-assets-min/24_arrow-left.js 0.35 kB │ gzip: 0.27 kB │ map: 0.42 kB
|
|
313
312
|
dist/assets/icons/icon-assets-min/24_color-stroke.js 0.35 kB │ gzip: 0.25 kB │ map: 0.44 kB
|
|
314
|
-
dist/components/PlElementList/PlElementList.js 0.35 kB │ gzip: 0.24 kB │ map: 14.
|
|
313
|
+
dist/components/PlElementList/PlElementList.js 0.35 kB │ gzip: 0.24 kB │ map: 14.55 kB
|
|
315
314
|
dist/components/PlSearchField/PlSearchField.js 0.35 kB │ gzip: 0.24 kB │ map: 2.95 kB
|
|
316
315
|
dist/components/PlSidebar/PlSidebarItem.js 0.35 kB │ gzip: 0.24 kB │ map: 1.43 kB
|
|
317
316
|
dist/layout/PlPlaceholder/PlPlaceholder.js 0.35 kB │ gzip: 0.24 kB │ map: 3.74 kB
|
|
@@ -319,6 +318,7 @@ dist/assets/icons/icon-assets-min/24_arrow-down.js
|
|
|
319
318
|
dist/assets/icons/icon-assets-min/24_arrow-right.js 0.35 kB │ gzip: 0.27 kB │ map: 0.42 kB
|
|
320
319
|
dist/components/PlAccordion/ExpandTransition.js 0.35 kB │ gzip: 0.21 kB │ map: 0.74 kB
|
|
321
320
|
dist/components/PlSidebar/PlSidebarGroup.js 0.35 kB │ gzip: 0.24 kB │ map: 0.84 kB
|
|
321
|
+
dist/components/PlElementList/utils.js 0.35 kB │ gzip: 0.27 kB │ map: 0.78 kB
|
|
322
322
|
dist/helpers/functions.js 0.35 kB │ gzip: 0.23 kB │ map: 1.06 kB
|
|
323
323
|
dist/assets/icons/icon-assets-min/16_chevron-first.js 0.36 kB │ gzip: 0.27 kB │ map: 0.42 kB
|
|
324
324
|
dist/components/PlChartHistogram/PlChartHistogram.js 0.36 kB │ gzip: 0.24 kB │ map: 2.52 kB
|
|
@@ -534,14 +534,6 @@ 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
|
-
[33m[33m[PLUGIN_TIMINGS] Warning:[0m Your build spent significant time in plugins. Here is a breakdown:
|
|
538
|
-
- vite:asset (39%)
|
|
539
|
-
- vite:css-post (12%)
|
|
540
|
-
- vite:dts (11%)
|
|
541
|
-
- vite:vue (10%)
|
|
542
|
-
- sourcemaps (8%)
|
|
543
|
-
See https://rolldown.rs/options/checks#plugintimings for more details.
|
|
544
|
-
[39m
|
|
545
537
|
dist/assets/icons/icon-assets-min/16_clipboard.js 0.64 kB │ gzip: 0.38 kB │ map: 0.72 kB
|
|
546
538
|
dist/components/PlFileDialog/utils.js 0.64 kB │ gzip: 0.43 kB │ map: 2.18 kB
|
|
547
539
|
dist/assets/icons/icon-assets-min/24_frame-type-none.js 0.65 kB │ gzip: 0.30 kB │ map: 0.72 kB
|
|
@@ -679,7 +671,7 @@ dist/assets/icons/icon-assets-min/24_fire-tips.js
|
|
|
679
671
|
dist/components/PlSplash/PlSplash.vue_vue_type_script_setup_true_lang.js 1.17 kB │ gzip: 0.61 kB │ map: 1.73 kB
|
|
680
672
|
dist/assets/icons/icon-assets-min/24_line-jitter.js 1.18 kB │ gzip: 0.54 kB │ map: 1.26 kB
|
|
681
673
|
dist/assets/icons/icon-assets-min/24_wetlab.js 1.18 kB │ gzip: 0.61 kB │ map: 1.28 kB
|
|
682
|
-
dist/components/LongText.vue_vue_type_script_setup_true_lang.js 1.18 kB │ gzip: 0.69 kB │ map: 2.
|
|
674
|
+
dist/components/LongText.vue_vue_type_script_setup_true_lang.js 1.18 kB │ gzip: 0.69 kB │ map: 2.59 kB
|
|
683
675
|
dist/assets/icons/icon-assets-min/24_rotation-90.js 1.18 kB │ gzip: 0.63 kB │ map: 1.25 kB
|
|
684
676
|
dist/assets/icons/icon-assets-min/24_progress.js 1.19 kB │ gzip: 0.69 kB │ map: 1.27 kB
|
|
685
677
|
dist/components/PlChartStackedBar/PlChartStackedBar.vue_vue_type_script_setup_true_lang.js 1.20 kB │ gzip: 0.64 kB │ map: 1.90 kB
|
|
@@ -790,11 +782,19 @@ dist/components/PlDropdownLegacy/PlDropdownLegacy.vue_vue_type_script_setup_true
|
|
|
790
782
|
dist/components/PlDropdown/PlDropdown.vue_vue_type_script_setup_true_lang.js 7.79 kB │ gzip: 2.77 kB │ map: 22.70 kB
|
|
791
783
|
dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue_vue_type_script_setup_true_lang.js 8.35 kB │ gzip: 3.04 kB │ map: 24.74 kB
|
|
792
784
|
dist/components/PlAutocomplete/PlAutocomplete.vue_vue_type_script_setup_true_lang.js 8.72 kB │ gzip: 3.07 kB │ map: 25.90 kB
|
|
793
|
-
dist/components/PlElementList/PlElementList.vue_vue_type_script_setup_true_lang.js
|
|
785
|
+
dist/components/PlElementList/PlElementList.vue_vue_type_script_setup_true_lang.js 9.01 kB │ gzip: 2.39 kB │ map: 20.07 kB
|
|
794
786
|
dist/demo-site-data/all-css-variables.js 9.68 kB │ gzip: 1.75 kB │ map: 17.53 kB
|
|
795
|
-
dist/composition/filters/metadata.js 11.
|
|
787
|
+
dist/composition/filters/metadata.js 11.37 kB │ gzip: 1.20 kB │ map: 22.01 kB
|
|
796
788
|
dist/index.js 12.53 kB │ gzip: 2.96 kB │ map: 21.32 kB
|
|
797
789
|
dist/components/PlSvg/PlSvg.vue_vue_type_script_setup_true_lang.js 39.41 kB │ gzip: 3.40 kB │ map: 8.66 kB
|
|
798
790
|
|
|
799
|
-
[
|
|
791
|
+
[33m[33m[PLUGIN_TIMINGS] Warning:[0m Your build spent significant time in plugins. Here is a breakdown:
|
|
792
|
+
- vite:asset (36%)
|
|
793
|
+
- sourcemaps (13%)
|
|
794
|
+
- vite:css-post (11%)
|
|
795
|
+
- vite:dts (10%)
|
|
796
|
+
- vite:vue (9%)
|
|
797
|
+
See https://rolldown.rs/options/checks#plugintimings for more details.
|
|
798
|
+
[39m
|
|
799
|
+
[32m✓ built in 9.54s[39m
|
|
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.
|
|
3
|
+
> @milaboratories/uikit@2.12.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
|
|
11
|
+
Finished in 2197ms 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.
|
|
3
|
+
> @milaboratories/uikit@2.12.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
|
|
9
|
+
Finished in 25ms on 308 files with 98 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.
|
|
3
|
+
> @milaboratories/uikit@2.12.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,22 @@
|
|
|
1
1
|
# @milaboratories/uikit
|
|
2
2
|
|
|
3
|
+
## 2.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @platforma-sdk/model@1.65.3
|
|
8
|
+
|
|
9
|
+
## 2.12.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 92ef20f: Default filters available from UI
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [92ef20f]
|
|
18
|
+
- @platforma-sdk/model@1.65.0
|
|
19
|
+
|
|
3
20
|
## 2.11.9
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LongText.js","names":[],"sources":["../../src/components/LongText.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\nimport { debounce, notEmpty } from \"@milaboratories/helpers\";\n\nconst hasElementEllipsis = ref(false);\n\nconst span = ref<HTMLElement>();\n\nconst isHovered = ref(false);\n\nconst classes = computed(() =>\n isHovered.value && hasElementEllipsis.value ? \"ui-lt-animate\" : \"\",\n);\n\nconst updateStatus = debounce((val: boolean) => (isHovered.value = val), 500);\n\nconst animationTime = computed(() => {\n return span.value ? `${span.value?.innerHTML.length * 0.4}s` : \"5s\";\n});\n\nfunction isEllipsisEnabled() {\n const el = notEmpty(span.value, \"span cannot be empty\");\n hasElementEllipsis.value = el.clientWidth < el.scrollWidth;\n}\n\nfunction mouseoverHandler() {\n isEllipsisEnabled();\n updateStatus(true);\n}\n\nfunction mouseoutHandler() {\n updateStatus(false);\n}\n</script>\n\n<template>\n <div v-bind=\"$attrs\" class=\"ui-lt-container\">\n <span @mouseover=\"mouseoverHandler\" @mouseleave=\"mouseoutHandler\">\n <span ref=\"span\" :class=\"classes\"><slot /></span>\n </span>\n </div>\n</template>\n\n<style lang=\"scss\">\n.ui-lt-container {\n
|
|
1
|
+
{"version":3,"file":"LongText.js","names":[],"sources":["../../src/components/LongText.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\nimport { debounce, notEmpty } from \"@milaboratories/helpers\";\n\nconst hasElementEllipsis = ref(false);\n\nconst span = ref<HTMLElement>();\n\nconst isHovered = ref(false);\n\nconst classes = computed(() =>\n isHovered.value && hasElementEllipsis.value ? \"ui-lt-animate\" : \"\",\n);\n\nconst updateStatus = debounce((val: boolean) => (isHovered.value = val), 500);\n\nconst animationTime = computed(() => {\n return span.value ? `${span.value?.innerHTML.length * 0.4}s` : \"5s\";\n});\n\nfunction isEllipsisEnabled() {\n const el = notEmpty(span.value, \"span cannot be empty\");\n hasElementEllipsis.value = el.clientWidth < el.scrollWidth;\n}\n\nfunction mouseoverHandler() {\n isEllipsisEnabled();\n updateStatus(true);\n}\n\nfunction mouseoutHandler() {\n updateStatus(false);\n}\n</script>\n\n<template>\n <div v-bind=\"$attrs\" class=\"ui-lt-container\">\n <span @mouseover=\"mouseoverHandler\" @mouseleave=\"mouseoutHandler\">\n <span ref=\"span\" :class=\"classes\"><slot /></span>\n </span>\n </div>\n</template>\n\n<style lang=\"scss\">\n.ui-lt-container {\n position: relative;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n border-radius: 5px;\n\n span {\n display: inline-block;\n width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n vertical-align: bottom;\n }\n\n .ui-lt-animate {\n position: relative;\n width: fit-content;\n overflow: unset;\n text-overflow: unset;\n animation: left-to-right v-bind(animationTime) infinite alternate linear;\n }\n}\n\n@keyframes left-to-right {\n 0% {\n transform: translateX(0%);\n left: 0%;\n }\n\n 100% {\n transform: translateX(-101%);\n left: 101%;\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.ui-lt-container{white-space:nowrap;border-radius:5px;min-width:0;position:relative;overflow:hidden}.ui-lt-container span{text-overflow:ellipsis;vertical-align:bottom;width:100%;display:inline-block;overflow:hidden
|
|
1
|
+
.ui-lt-container{white-space:nowrap;border-radius:5px;min-width:0;position:relative;overflow:hidden}.ui-lt-container span{text-overflow:ellipsis;vertical-align:bottom;width:100%;display:inline-block;overflow:hidden}.ui-lt-container .ui-lt-animate{width:fit-content;overflow:unset;text-overflow:unset;animation:left-to-right var(--v0036837f) infinite alternate linear;position:relative}@keyframes left-to-right{0%{left:0%;transform:translate(0%)}to{left:101%;transform:translate(-101%)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LongText.vue.d.ts","sourceRoot":"","sources":["../../src/components/LongText.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LongText.vue.d.ts","sourceRoot":"","sources":["../../src/components/LongText.vue"],"names":[],"mappings":"AAqHA,iBAAS,cAAc;WAuCT,OAAO,IAA6B;;yBAZrB,GAAG;;;;;;EAiB/B;AAYD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;kBAOnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAEpG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { debounce as u, notEmpty as d } from "@milaboratories/helpers";
|
|
|
4
4
|
var f = /* @__PURE__ */ r({
|
|
5
5
|
__name: "LongText",
|
|
6
6
|
setup(r) {
|
|
7
|
-
l((e) => ({
|
|
7
|
+
l((e) => ({ v0036837f: _.value }));
|
|
8
8
|
let f = s(!1), p = s(), m = s(!1), h = e(() => m.value && f.value ? "ui-lt-animate" : ""), g = u((e) => m.value = e, 500), _ = e(() => p.value ? `${p.value?.innerHTML.length * .4}s` : "5s");
|
|
9
9
|
function v() {
|
|
10
10
|
let e = d(p.value, "span cannot be empty");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LongText.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../src/components/LongText.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\nimport { debounce, notEmpty } from \"@milaboratories/helpers\";\n\nconst hasElementEllipsis = ref(false);\n\nconst span = ref<HTMLElement>();\n\nconst isHovered = ref(false);\n\nconst classes = computed(() =>\n isHovered.value && hasElementEllipsis.value ? \"ui-lt-animate\" : \"\",\n);\n\nconst updateStatus = debounce((val: boolean) => (isHovered.value = val), 500);\n\nconst animationTime = computed(() => {\n return span.value ? `${span.value?.innerHTML.length * 0.4}s` : \"5s\";\n});\n\nfunction isEllipsisEnabled() {\n const el = notEmpty(span.value, \"span cannot be empty\");\n hasElementEllipsis.value = el.clientWidth < el.scrollWidth;\n}\n\nfunction mouseoverHandler() {\n isEllipsisEnabled();\n updateStatus(true);\n}\n\nfunction mouseoutHandler() {\n updateStatus(false);\n}\n</script>\n\n<template>\n <div v-bind=\"$attrs\" class=\"ui-lt-container\">\n <span @mouseover=\"mouseoverHandler\" @mouseleave=\"mouseoutHandler\">\n <span ref=\"span\" :class=\"classes\"><slot /></span>\n </span>\n </div>\n</template>\n\n<style lang=\"scss\">\n.ui-lt-container {\n
|
|
1
|
+
{"version":3,"file":"LongText.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../src/components/LongText.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\nimport { debounce, notEmpty } from \"@milaboratories/helpers\";\n\nconst hasElementEllipsis = ref(false);\n\nconst span = ref<HTMLElement>();\n\nconst isHovered = ref(false);\n\nconst classes = computed(() =>\n isHovered.value && hasElementEllipsis.value ? \"ui-lt-animate\" : \"\",\n);\n\nconst updateStatus = debounce((val: boolean) => (isHovered.value = val), 500);\n\nconst animationTime = computed(() => {\n return span.value ? `${span.value?.innerHTML.length * 0.4}s` : \"5s\";\n});\n\nfunction isEllipsisEnabled() {\n const el = notEmpty(span.value, \"span cannot be empty\");\n hasElementEllipsis.value = el.clientWidth < el.scrollWidth;\n}\n\nfunction mouseoverHandler() {\n isEllipsisEnabled();\n updateStatus(true);\n}\n\nfunction mouseoutHandler() {\n updateStatus(false);\n}\n</script>\n\n<template>\n <div v-bind=\"$attrs\" class=\"ui-lt-container\">\n <span @mouseover=\"mouseoverHandler\" @mouseleave=\"mouseoutHandler\">\n <span ref=\"span\" :class=\"classes\"><slot /></span>\n </span>\n </div>\n</template>\n\n<style lang=\"scss\">\n.ui-lt-container {\n position: relative;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n border-radius: 5px;\n\n span {\n display: inline-block;\n width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n vertical-align: bottom;\n }\n\n .ui-lt-animate {\n position: relative;\n width: fit-content;\n overflow: unset;\n text-overflow: unset;\n animation: left-to-right v-bind(animationTime) infinite alternate linear;\n }\n}\n\n@keyframes left-to-right {\n 0% {\n transform: translateX(0%);\n left: 0%;\n }\n\n 100% {\n transform: translateX(-101%);\n left: 101%;\n }\n}\n</style>\n"],"mappings":";;;;;;;EAIA,IAAM,IAAqB,EAAI,GAAM,EAE/B,IAAO,GAAkB,EAEzB,IAAY,EAAI,GAAM,EAEtB,IAAU,QACd,EAAU,SAAS,EAAmB,QAAQ,kBAAkB,GACjE,EAEK,IAAe,GAAU,MAAkB,EAAU,QAAQ,GAAM,IAAI,EAEvE,IAAgB,QACb,EAAK,QAAQ,GAAG,EAAK,OAAO,UAAU,SAAS,GAAI,KAAK,KAC/D;EAEF,SAAS,IAAoB;GAC3B,IAAM,IAAK,EAAS,EAAK,OAAO,uBAAuB;AACvD,KAAmB,QAAQ,EAAG,cAAc,EAAG;;EAGjD,SAAS,IAAmB;AAE1B,GADA,GAAmB,EACnB,EAAa,GAAK;;EAGpB,SAAS,IAAkB;AACzB,KAAa,GAAM;;yBAKnB,EAIM,OAJN,EAAaA,EAIP,QAJa,EAAE,OAAM,mBAAiB,CAAA,EAAA,CAC1C,EAEO,QAAA;GAFA,aAAW;GAAmB,cAAY;MAC/C,EAAiD,QAAA;YAAvC;GAAJ,KAAI;GAAQ,OAAK,EAAE,EAAA,MAAO;MAAE,EAAQ,EAAA,QAAA,UAAA,CAAA,EAAA,EAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlElementList.js","names":[],"sources":["../../../src/components/PlElementList/PlElementList.vue"],"sourcesContent":["<script\n generic=\"T extends unknown = unknown, K extends number | string = number | string\"\n lang=\"ts\"\n setup\n>\nimport { isFunction, shallowHash } from \"@milaboratories/helpers\";\nimport { useSortable } from \"@vueuse/integrations/useSortable\";\nimport { type SortableEvent } from \"sortablejs\";\nimport type { ShallowRef } from \"vue\";\nimport { computed, shallowRef, watch } from \"vue\";\nimport PlElementListItem from \"./PlElementListItem.vue\";\nimport { moveElements } from \"./utils.ts\";\n\nconst itemsRef = defineModel<T[]>(\"items\", { required: true });\n\nconst props = withDefaults(\n defineProps<{\n getItemKey?: (item: T, index: number) => K;\n\n itemClass?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassTitle?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassBefore?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassAfter?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassContent?: string | string[] | ((item: T, index: number) => string | string[]);\n isActive?: (item: T, index: number) => boolean;\n\n disableDragging?: boolean;\n isDraggable?: (item: T, index: number) => boolean;\n onDragEnd?: (oldIndex: number, newIndex: number) => void | boolean;\n onSort?: (oldIndex: number, newIndex: number) => void | boolean;\n\n disableRemoving?: boolean;\n isRemovable?: (item: T, index: number) => boolean;\n onRemove?: (item: T, index: number) => void | boolean;\n\n disableExpanding?: boolean;\n isExpandable?: (item: T, index: number) => boolean;\n isExpanded?: (item: T, index: number) => boolean;\n onExpand?: (item: T, index: number) => unknown;\n\n disableToggling?: boolean;\n isToggable?: (item: T, index: number) => boolean;\n isToggled?: (item: T, index: number) => boolean;\n onToggle?: (item: T, index: number) => unknown;\n\n disablePinning?: boolean;\n isPinnable?: (item: T, index: number) => boolean;\n isPinned?: (item: T, index: number) => boolean;\n onPin?: (item: T, index: number) => void | boolean;\n }>(),\n {\n getItemKey: (item: T) => JSON.stringify(item) as K,\n\n itemClass: undefined,\n itemClassTitle: undefined,\n itemClassContent: undefined,\n itemClassBefore: undefined,\n itemClassAfter: undefined,\n isActive: undefined,\n\n disableDragging: undefined,\n isDraggable: undefined,\n onDragEnd: undefined,\n onSort: undefined,\n\n disableRemoving: undefined,\n isRemovable: undefined,\n onRemove: undefined,\n\n disableExpanding: undefined,\n isExpandable: undefined,\n isExpanded: undefined,\n onExpand: undefined,\n\n disableToggling: undefined,\n isToggable: undefined,\n isToggled: undefined,\n onToggle: undefined,\n\n disablePinning: undefined,\n isPinnable: undefined,\n isPinned: undefined,\n onPin: undefined,\n },\n);\n\nconst emits = defineEmits<{\n (e: \"itemClick\", item: T): void;\n}>();\n\nconst slots = defineSlots<{\n [\"item-title\"]: (props: { item: T; index: number }) => unknown;\n [\"item-content\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-before\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-after\"]?: (props: { item: T; index: number }) => unknown;\n}>();\n\nconst dndSortingEnabled = computed((): boolean => {\n return props.disableDragging !== true;\n});\n\nconst pinnedItemsRef = computed(() => itemsRef.value.filter(isPinnedItem));\nconst hasPinnedItems = computed(() => pinnedItemsRef.value.length > 0);\n\nconst unpinnedItemsRef = computed(() =>\n itemsRef.value.filter((item, index) => !isPinnedItem(item, index)),\n);\nconst hasUnpinnedItems = computed(() => unpinnedItemsRef.value.length > 0);\n\nconst domProjectionItemsRef = shallowRef<undefined | T[]>();\nconst pinnedContainerRef = shallowRef<HTMLElement>();\nconst unpinnedContainerRef = shallowRef<HTMLElement>();\n\n// version fix problem with sync between data and rendered values\nconst getKey = (item: T, index: number) => {\n return `${versionRef.value}-${props.getItemKey(item, index)}`;\n};\nconst pinnedKeysRef = computed(() => pinnedItemsRef.value.map(getKey));\nconst unpinnedKeysRef = computed(() => unpinnedItemsRef.value.map(getKey));\n\n// version fix problem with sync between data and rendered values when items have been changed\nconst versionRef = computed<number>((oldVersion) => {\n const currentKeys = itemsRef.value.map(props.getItemKey);\n\n if (domProjectionItemsRef.value === undefined) return oldVersion ?? shallowHash(...currentKeys);\n if (currentKeys.length !== domProjectionItemsRef.value.length) return shallowHash(...currentKeys);\n\n const domProjectionKeys = domProjectionItemsRef.value.map(props.getItemKey);\n const domProjectionKeysSet = new Set(domProjectionKeys);\n\n for (let i = 0; i < currentKeys.length; i++) {\n const hasInconsistentPosition =\n domProjectionKeysSet.has(currentKeys[i]) && domProjectionKeys[i] !== currentKeys[i];\n\n if (hasInconsistentPosition) {\n return shallowHash(...currentKeys);\n }\n }\n\n return oldVersion ?? shallowHash(...currentKeys);\n});\n\ncreateSortable(hasPinnedItems, pinnedContainerRef, pinnedItemsRef, () => 0);\ncreateSortable(\n hasUnpinnedItems,\n unpinnedContainerRef,\n unpinnedItemsRef,\n () => pinnedItemsRef.value.length,\n);\n\nfunction createSortable(\n toggler: ShallowRef<boolean>,\n elRef: ShallowRef<undefined | HTMLElement>,\n itemsRef: ShallowRef<T[]>,\n getOffset: () => number,\n) {\n const sortable = useSortable(elRef, itemsRef, {\n handle: `[data-draggable=\"true\"]`,\n animation: 150,\n forceFallback: true,\n fallbackOnBody: true,\n scrollSensitivity: 80,\n forceAutoScrollFallback: true,\n onUpdate: (evt: SortableEvent) => {\n if (evt.oldIndex == null || evt.newIndex == null) {\n throw new Error(\"Sortable event has no index\");\n }\n if (props.onDragEnd?.(evt.oldIndex, evt.newIndex) !== false) {\n moveItems(getOffset() + evt.oldIndex, getOffset() + evt.newIndex, true);\n }\n },\n });\n watch(\n [elRef, () => props.disableDragging, toggler],\n ([elRef, disabled, on]) => {\n if (!elRef || disabled || !on) {\n sortable.stop();\n } else {\n sortable.start();\n }\n },\n { immediate: true },\n );\n\n return sortable;\n}\n\nfunction moveItems(oldIndex: number, newIndex: number, afterUpdateDom: boolean) {\n if (oldIndex === newIndex) return;\n\n if (afterUpdateDom) {\n domProjectionItemsRef.value = moveElements(itemsRef.value.slice(), oldIndex, newIndex);\n }\n\n const preventDefault = props.onSort?.(oldIndex, newIndex) === false;\n\n if (!preventDefault) {\n moveElements(itemsRef.value, oldIndex, newIndex);\n }\n}\n\nfunction isActiveItem(item: T, index: number): boolean {\n return props.isActive?.(item, index) ?? false;\n}\n\nfunction isDraggableItem(item: T, index: number): boolean {\n if (props.disableDragging === true) return false;\n return props.isDraggable?.(item, index) ?? true;\n}\n\nfunction isRemovableItem(item: T, index: number): boolean {\n if (props.disableRemoving === true) return false;\n return props.isRemovable?.(item, index) ?? true;\n}\n\nfunction isToggableItem(item: T, index: number): boolean {\n if (props.disableToggling === true) return false;\n return (\n props.isToggable?.(item, index) ?? (isFunction(props.isToggled) || isFunction(props.onToggle))\n );\n}\n\nfunction isToggledItem(item: T, index: number): boolean {\n return props.isToggled?.(item, index) ?? false;\n}\n\nfunction isPinnableItem(item: T, index: number): boolean {\n if (props.disablePinning === true) return false;\n return props.isPinnable?.(item, index) ?? (isFunction(props.isPinned) || isFunction(props.onPin));\n}\n\nfunction isPinnedItem(item: T, index: number): boolean {\n return props.isPinned?.(item, index) ?? false;\n}\n\nfunction isExpandableItem(item: T, index: number): boolean {\n if (props.disableExpanding === true) return false;\n return (\n props.isExpandable?.(item, index) ??\n (isFunction(props.isExpanded) || isFunction(props.onExpand))\n );\n}\n\nfunction isExpandedItem(item: T, index: number): boolean {\n return props.isExpanded?.(item, index) ?? false;\n}\n\nfunction handleExpand(item: T, index: number) {\n props.onExpand?.(item, index);\n}\n\nfunction handleToggle(item: T, index: number) {\n props.onToggle?.(item, index);\n}\n\nfunction handlePin(item: T, index: number) {\n if (index === -1) {\n throw new Error(\"Pinnable item not found\");\n }\n\n const alreadyPinned = pinnedItemsRef.value.includes(item);\n\n if (props.onPin?.(item, index) === false) return;\n\n moveItems(index, pinnedItemsRef.value.length + (alreadyPinned ? 0 : -1), false);\n}\n\nfunction handleRemove(item: T, index: number) {\n if (props.onRemove?.(item, index) === false) return;\n itemsRef.value.splice(index, 1);\n}\n\nfunction getClassFunction(\n propsItemClass: string | string[] | ((item: T, index: number) => string | string[]) | undefined,\n): (item: T, index: number) => null | string | string[] {\n return (item: T, index: number): null | string | string[] => {\n if (typeof propsItemClass === \"function\") {\n return propsItemClass(item, index);\n }\n return propsItemClass ?? null;\n };\n}\nconst getItemClass = getClassFunction(props.itemClass);\nconst getItemClassTitle = getClassFunction(props.itemClassTitle);\nconst getItemClassContent = getClassFunction(props.itemClassContent);\nconst getItemClassBefore = getClassFunction(props.itemClassBefore);\nconst getItemClassAfter = getClassFunction(props.itemClassAfter);\n</script>\n\n<template>\n <div :class=\"$style.root\">\n <div ref=\"pinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"(pinnedItem, pinnedIndex) in pinnedItemsRef\"\n :key=\"pinnedKeysRef[pinnedIndex]\"\n :class=\"[$style.item, getItemClass(pinnedItem, pinnedIndex)]\"\n :titleClass=\"getItemClassTitle(pinnedItem, pinnedIndex)\"\n :contentClass=\"getItemClassContent(pinnedItem, pinnedIndex)\"\n :beforeClass=\"getItemClassBefore(pinnedItem, pinnedIndex)\"\n :afterClass=\"getItemClassAfter(pinnedItem, pinnedIndex)\"\n :index=\"pinnedIndex\"\n :item=\"pinnedItem\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(pinnedItem, pinnedIndex)\"\n :isDraggable=\"isDraggableItem(pinnedItem, pinnedIndex)\"\n :isRemovable=\"isRemovableItem(pinnedItem, pinnedIndex)\"\n :isToggable=\"isToggableItem(pinnedItem, pinnedIndex)\"\n :isToggled=\"isToggledItem(pinnedItem, pinnedIndex)\"\n :isPinnable=\"isPinnableItem(pinnedItem, pinnedIndex)\"\n :isPinned=\"true\"\n :isExpandable=\"isExpandableItem(pinnedItem, pinnedIndex)\"\n :isExpanded=\"isExpandedItem(pinnedItem, pinnedIndex)\"\n @click=\"emits('itemClick', pinnedItem)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template v-if=\"slots['item-before']\" #before=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-before\" />\n </template>\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n <div v-if=\"hasUnpinnedItems\" ref=\"unpinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"(unpinnedItem, unpinnedIndex) in unpinnedItemsRef\"\n :key=\"unpinnedKeysRef[unpinnedIndex]\"\n :class=\"[$style.item, getItemClass(unpinnedItem, unpinnedIndex)]\"\n :titleClass=\"getItemClassTitle(unpinnedItem, unpinnedIndex)\"\n :contentClass=\"getItemClassContent(unpinnedItem, unpinnedIndex)\"\n :beforeClass=\"getItemClassBefore(unpinnedItem, unpinnedIndex)\"\n :afterClass=\"getItemClassAfter(unpinnedItem, unpinnedIndex)\"\n :index=\"unpinnedIndex + (pinnedItemsRef?.length ?? 0)\"\n :item=\"unpinnedItem\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(unpinnedItem, unpinnedIndex)\"\n :isDraggable=\"isDraggableItem(unpinnedItem, unpinnedIndex)\"\n :isRemovable=\"isRemovableItem(unpinnedItem, unpinnedIndex)\"\n :isToggable=\"isToggableItem(unpinnedItem, unpinnedIndex)\"\n :isToggled=\"isToggledItem(unpinnedItem, unpinnedIndex)\"\n :isPinnable=\"isPinnableItem(unpinnedItem, unpinnedIndex)\"\n :isPinned=\"false\"\n :isExpandable=\"isExpandableItem(unpinnedItem, unpinnedIndex)\"\n :isExpanded=\"isExpandedItem(unpinnedItem, unpinnedIndex)\"\n @click=\"emits('itemClick', unpinnedItem)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n </div>\n</template>\n\n<style module>\n.root,\n.list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 180px;\n}\n\n.item {\n width: 100%;\n}\n\n:global(.sortable-ghost) {\n visibility: hidden;\n}\n:global(.sortable-drag) {\n opacity: 1;\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"PlElementList.js","names":[],"sources":["../../../src/components/PlElementList/PlElementList.vue"],"sourcesContent":["<script\n generic=\"T extends unknown = unknown, K extends number | string = number | string\"\n lang=\"ts\"\n setup\n>\nimport { isFunction, shallowHash } from \"@milaboratories/helpers\";\nimport { useSortable } from \"@vueuse/integrations/useSortable\";\nimport { type SortableEvent } from \"sortablejs\";\nimport type { ShallowRef } from \"vue\";\nimport { computed, shallowRef, watch } from \"vue\";\nimport PlElementListItem from \"./PlElementListItem.vue\";\nimport { moveElements } from \"./utils.ts\";\n\ntype ItemEntry = [idx: number, item: T];\n\nconst itemsRef = defineModel<T[]>(\"items\", { required: true });\n\nconst props = withDefaults(\n defineProps<{\n getItemKey?: (item: T, index: number) => K;\n\n itemClass?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassTitle?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassBefore?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassAfter?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassContent?: string | string[] | ((item: T, index: number) => string | string[]);\n isActive?: (item: T, index: number) => boolean;\n\n disableDragging?: boolean;\n isDraggable?: (item: T, index: number) => boolean;\n onDragEnd?: (oldIndex: number, newIndex: number) => void | boolean;\n onSort?: (oldIndex: number, newIndex: number) => void | boolean;\n\n disableRemoving?: boolean;\n isRemovable?: (item: T, index: number) => boolean;\n onRemove?: (item: T, index: number) => void | boolean;\n\n disableExpanding?: boolean;\n isExpandable?: (item: T, index: number) => boolean;\n isExpanded?: (item: T, index: number) => boolean;\n onExpand?: (item: T, index: number) => unknown;\n\n disableToggling?: boolean;\n isToggable?: (item: T, index: number) => boolean;\n isToggled?: (item: T, index: number) => boolean;\n onToggle?: (item: T, index: number) => unknown;\n\n disablePinning?: boolean;\n isPinnable?: (item: T, index: number) => boolean;\n isPinned?: (item: T, index: number) => boolean;\n onPin?: (item: T, index: number) => void | boolean;\n }>(),\n {\n getItemKey: (item: T) => JSON.stringify(item) as K,\n\n itemClass: undefined,\n itemClassTitle: undefined,\n itemClassContent: undefined,\n itemClassBefore: undefined,\n itemClassAfter: undefined,\n isActive: undefined,\n\n disableDragging: undefined,\n isDraggable: undefined,\n onDragEnd: undefined,\n onSort: undefined,\n\n disableRemoving: undefined,\n isRemovable: undefined,\n onRemove: undefined,\n\n disableExpanding: undefined,\n isExpandable: undefined,\n isExpanded: undefined,\n onExpand: undefined,\n\n disableToggling: undefined,\n isToggable: undefined,\n isToggled: undefined,\n onToggle: undefined,\n\n disablePinning: undefined,\n isPinnable: undefined,\n isPinned: undefined,\n onPin: undefined,\n },\n);\n\nconst emits = defineEmits<{\n (e: \"itemClick\", item: T): void;\n}>();\n\nconst slots = defineSlots<{\n [\"item-title\"]: (props: { item: T; index: number }) => unknown;\n [\"item-content\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-before\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-after\"]?: (props: { item: T; index: number }) => unknown;\n}>();\n\nconst dndSortingEnabled = computed((): boolean => {\n return props.disableDragging !== true;\n});\n\nconst pinnedItemsRef = computed(() =>\n itemsRef.value\n .map((item, index) => [index, item] as ItemEntry)\n .filter(([index, item]) => isPinnedItem(item, index)),\n);\nconst hasPinnedItems = computed(() => pinnedItemsRef.value.length > 0);\n\nconst unpinnedItemsRef = computed(() =>\n itemsRef.value\n .map((item, index) => [index, item] as ItemEntry)\n .filter(([index, item]) => !isPinnedItem(item, index)),\n);\nconst hasUnpinnedItems = computed(() => unpinnedItemsRef.value.length > 0);\n\nconst domProjectionItemsRef = shallowRef<undefined | T[]>();\nconst pinnedContainerRef = shallowRef<HTMLElement>();\nconst unpinnedContainerRef = shallowRef<HTMLElement>();\n\n// version fix problem with sync between data and rendered values\nconst getKey = (entry: ItemEntry) => {\n return `${versionRef.value}-${props.getItemKey(entry[1], entry[0])}`;\n};\nconst pinnedKeysRef = computed(() => pinnedItemsRef.value.map(getKey));\nconst unpinnedKeysRef = computed(() => unpinnedItemsRef.value.map(getKey));\n\n// version fix problem with sync between data and rendered values when items have been changed\nconst versionRef = computed<number>((oldVersion) => {\n const currentKeys = itemsRef.value.map(props.getItemKey);\n\n if (domProjectionItemsRef.value === undefined) return oldVersion ?? shallowHash(...currentKeys);\n if (currentKeys.length !== domProjectionItemsRef.value.length) return shallowHash(...currentKeys);\n\n const domProjectionKeys = domProjectionItemsRef.value.map(props.getItemKey);\n const domProjectionKeysSet = new Set(domProjectionKeys);\n\n for (let i = 0; i < currentKeys.length; i++) {\n const hasInconsistentPosition =\n domProjectionKeysSet.has(currentKeys[i]) && domProjectionKeys[i] !== currentKeys[i];\n\n if (hasInconsistentPosition) {\n return shallowHash(...currentKeys);\n }\n }\n\n return oldVersion ?? shallowHash(...currentKeys);\n});\n\ncreateSortable(hasPinnedItems, pinnedContainerRef, pinnedItemsRef, () => 0);\ncreateSortable(\n hasUnpinnedItems,\n unpinnedContainerRef,\n unpinnedItemsRef,\n () => pinnedItemsRef.value.length,\n);\n\nfunction createSortable(\n toggler: ShallowRef<boolean>,\n elRef: ShallowRef<undefined | HTMLElement>,\n itemsRef: ShallowRef<ItemEntry[]>,\n getOffset: () => number,\n) {\n const sortable = useSortable(elRef, itemsRef, {\n handle: `[data-draggable=\"true\"]`,\n animation: 150,\n forceFallback: true,\n fallbackOnBody: true,\n scrollSensitivity: 80,\n forceAutoScrollFallback: true,\n onUpdate: (evt: SortableEvent) => {\n if (evt.oldIndex == null || evt.newIndex == null) {\n throw new Error(\"Sortable event has no index\");\n }\n if (props.onDragEnd?.(evt.oldIndex, evt.newIndex) !== false) {\n moveItems(getOffset() + evt.oldIndex, getOffset() + evt.newIndex, true);\n }\n },\n });\n watch(\n [elRef, () => props.disableDragging, toggler],\n ([elRef, disabled, on]) => {\n if (!elRef || disabled || !on) {\n sortable.stop();\n } else {\n sortable.start();\n }\n },\n { immediate: true },\n );\n\n return sortable;\n}\n\nfunction moveItems(oldIndex: number, newIndex: number, afterUpdateDom: boolean) {\n if (oldIndex === newIndex) return;\n\n if (afterUpdateDom) {\n domProjectionItemsRef.value = moveElements(itemsRef.value.slice(), oldIndex, newIndex);\n }\n\n const preventDefault = props.onSort?.(oldIndex, newIndex) === false;\n\n if (!preventDefault) {\n itemsRef.value = moveElements(itemsRef.value, oldIndex, newIndex);\n }\n}\n\nfunction isActiveItem(item: T, index: number): boolean {\n return props.isActive?.(item, index) ?? false;\n}\n\nfunction isDraggableItem(item: T, index: number): boolean {\n if (props.disableDragging === true) return false;\n return props.isDraggable?.(item, index) ?? true;\n}\n\nfunction isRemovableItem(item: T, index: number): boolean {\n if (props.disableRemoving === true) return false;\n return props.isRemovable?.(item, index) ?? true;\n}\n\nfunction isToggableItem(item: T, index: number): boolean {\n if (props.disableToggling === true) return false;\n return (\n props.isToggable?.(item, index) ?? (isFunction(props.isToggled) || isFunction(props.onToggle))\n );\n}\n\nfunction isToggledItem(item: T, index: number): boolean {\n return props.isToggled?.(item, index) ?? false;\n}\n\nfunction isPinnableItem(item: T, index: number): boolean {\n if (props.disablePinning === true) return false;\n return props.isPinnable?.(item, index) ?? (isFunction(props.isPinned) || isFunction(props.onPin));\n}\n\nfunction isPinnedItem(item: T, index: number): boolean {\n return props.isPinned?.(item, index) ?? false;\n}\n\nfunction isExpandableItem(item: T, index: number): boolean {\n if (props.disableExpanding === true) return false;\n return (\n props.isExpandable?.(item, index) ??\n (isFunction(props.isExpanded) || isFunction(props.onExpand))\n );\n}\n\nfunction isExpandedItem(item: T, index: number): boolean {\n return props.isExpanded?.(item, index) ?? false;\n}\n\nfunction handleExpand(item: T, index: number) {\n props.onExpand?.(item, index);\n}\n\nfunction handleToggle(item: T, index: number) {\n props.onToggle?.(item, index);\n}\n\nfunction handlePin(item: T, index: number) {\n if (index === -1) {\n throw new Error(\"Pinnable item not found\");\n }\n\n const alreadyPinned =\n pinnedItemsRef.value.findIndex(([originalIndex]) => originalIndex === index) !== -1;\n\n if (props.onPin?.(item, index) === false) return;\n\n moveItems(index, pinnedItemsRef.value.length + (alreadyPinned ? 0 : -1), false);\n}\n\nfunction handleRemove(item: T, index: number) {\n if (props.onRemove?.(item, index) === false) return;\n itemsRef.value = [...itemsRef.value.slice(0, index), ...itemsRef.value.slice(index + 1)];\n}\n\nfunction getClassFunction(\n propsItemClass: string | string[] | ((item: T, index: number) => string | string[]) | undefined,\n): (item: T, index: number) => null | string | string[] {\n return (item: T, index: number): null | string | string[] => {\n if (typeof propsItemClass === \"function\") {\n return propsItemClass(item, index);\n }\n return propsItemClass ?? null;\n };\n}\nconst getItemClass = getClassFunction(props.itemClass);\nconst getItemClassTitle = getClassFunction(props.itemClassTitle);\nconst getItemClassContent = getClassFunction(props.itemClassContent);\nconst getItemClassBefore = getClassFunction(props.itemClassBefore);\nconst getItemClassAfter = getClassFunction(props.itemClassAfter);\n</script>\n\n<template>\n <div :class=\"$style.root\">\n <div ref=\"pinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"([originalIndex, item], pinnedIndex) in pinnedItemsRef\"\n :key=\"pinnedKeysRef[pinnedIndex]\"\n :class=\"[$style.item, getItemClass(item, originalIndex)]\"\n :titleClass=\"getItemClassTitle(item, originalIndex)\"\n :contentClass=\"getItemClassContent(item, originalIndex)\"\n :beforeClass=\"getItemClassBefore(item, originalIndex)\"\n :afterClass=\"getItemClassAfter(item, originalIndex)\"\n :index=\"originalIndex\"\n :item=\"item\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(item, originalIndex)\"\n :isDraggable=\"isDraggableItem(item, originalIndex)\"\n :isRemovable=\"isRemovableItem(item, originalIndex)\"\n :isToggable=\"isToggableItem(item, originalIndex)\"\n :isToggled=\"isToggledItem(item, originalIndex)\"\n :isPinnable=\"isPinnableItem(item, originalIndex)\"\n :isPinned=\"true\"\n :isExpandable=\"isExpandableItem(item, originalIndex)\"\n :isExpanded=\"isExpandedItem(item, originalIndex)\"\n @click=\"emits('itemClick', item)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template v-if=\"slots['item-before']\" #before=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-before\" />\n </template>\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n <div v-if=\"hasUnpinnedItems\" ref=\"unpinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"([originalIndex, item], unpinnedIndex) in unpinnedItemsRef\"\n :key=\"unpinnedKeysRef[unpinnedIndex]\"\n :class=\"[$style.item, getItemClass(item, originalIndex)]\"\n :titleClass=\"getItemClassTitle(item, originalIndex)\"\n :contentClass=\"getItemClassContent(item, originalIndex)\"\n :beforeClass=\"getItemClassBefore(item, originalIndex)\"\n :afterClass=\"getItemClassAfter(item, originalIndex)\"\n :index=\"originalIndex\"\n :item=\"item\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(item, originalIndex)\"\n :isDraggable=\"isDraggableItem(item, originalIndex)\"\n :isRemovable=\"isRemovableItem(item, originalIndex)\"\n :isToggable=\"isToggableItem(item, originalIndex)\"\n :isToggled=\"isToggledItem(item, originalIndex)\"\n :isPinnable=\"isPinnableItem(item, originalIndex)\"\n :isPinned=\"false\"\n :isExpandable=\"isExpandableItem(item, originalIndex)\"\n :isExpanded=\"isExpandedItem(item, originalIndex)\"\n @click=\"emits('itemClick', item)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n </div>\n</template>\n\n<style module>\n.root,\n.list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 180px;\n}\n\n.item {\n width: 100%;\n}\n\n:global(.sortable-ghost) {\n visibility: hidden;\n}\n:global(.sortable-drag) {\n opacity: 1;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlElementList.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../src/components/PlElementList/PlElementList.vue"],"sourcesContent":["<script\n generic=\"T extends unknown = unknown, K extends number | string = number | string\"\n lang=\"ts\"\n setup\n>\nimport { isFunction, shallowHash } from \"@milaboratories/helpers\";\nimport { useSortable } from \"@vueuse/integrations/useSortable\";\nimport { type SortableEvent } from \"sortablejs\";\nimport type { ShallowRef } from \"vue\";\nimport { computed, shallowRef, watch } from \"vue\";\nimport PlElementListItem from \"./PlElementListItem.vue\";\nimport { moveElements } from \"./utils.ts\";\n\nconst itemsRef = defineModel<T[]>(\"items\", { required: true });\n\nconst props = withDefaults(\n defineProps<{\n getItemKey?: (item: T, index: number) => K;\n\n itemClass?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassTitle?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassBefore?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassAfter?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassContent?: string | string[] | ((item: T, index: number) => string | string[]);\n isActive?: (item: T, index: number) => boolean;\n\n disableDragging?: boolean;\n isDraggable?: (item: T, index: number) => boolean;\n onDragEnd?: (oldIndex: number, newIndex: number) => void | boolean;\n onSort?: (oldIndex: number, newIndex: number) => void | boolean;\n\n disableRemoving?: boolean;\n isRemovable?: (item: T, index: number) => boolean;\n onRemove?: (item: T, index: number) => void | boolean;\n\n disableExpanding?: boolean;\n isExpandable?: (item: T, index: number) => boolean;\n isExpanded?: (item: T, index: number) => boolean;\n onExpand?: (item: T, index: number) => unknown;\n\n disableToggling?: boolean;\n isToggable?: (item: T, index: number) => boolean;\n isToggled?: (item: T, index: number) => boolean;\n onToggle?: (item: T, index: number) => unknown;\n\n disablePinning?: boolean;\n isPinnable?: (item: T, index: number) => boolean;\n isPinned?: (item: T, index: number) => boolean;\n onPin?: (item: T, index: number) => void | boolean;\n }>(),\n {\n getItemKey: (item: T) => JSON.stringify(item) as K,\n\n itemClass: undefined,\n itemClassTitle: undefined,\n itemClassContent: undefined,\n itemClassBefore: undefined,\n itemClassAfter: undefined,\n isActive: undefined,\n\n disableDragging: undefined,\n isDraggable: undefined,\n onDragEnd: undefined,\n onSort: undefined,\n\n disableRemoving: undefined,\n isRemovable: undefined,\n onRemove: undefined,\n\n disableExpanding: undefined,\n isExpandable: undefined,\n isExpanded: undefined,\n onExpand: undefined,\n\n disableToggling: undefined,\n isToggable: undefined,\n isToggled: undefined,\n onToggle: undefined,\n\n disablePinning: undefined,\n isPinnable: undefined,\n isPinned: undefined,\n onPin: undefined,\n },\n);\n\nconst emits = defineEmits<{\n (e: \"itemClick\", item: T): void;\n}>();\n\nconst slots = defineSlots<{\n [\"item-title\"]: (props: { item: T; index: number }) => unknown;\n [\"item-content\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-before\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-after\"]?: (props: { item: T; index: number }) => unknown;\n}>();\n\nconst dndSortingEnabled = computed((): boolean => {\n return props.disableDragging !== true;\n});\n\nconst pinnedItemsRef = computed(() => itemsRef.value.filter(isPinnedItem));\nconst hasPinnedItems = computed(() => pinnedItemsRef.value.length > 0);\n\nconst unpinnedItemsRef = computed(() =>\n itemsRef.value.filter((item, index) => !isPinnedItem(item, index)),\n);\nconst hasUnpinnedItems = computed(() => unpinnedItemsRef.value.length > 0);\n\nconst domProjectionItemsRef = shallowRef<undefined | T[]>();\nconst pinnedContainerRef = shallowRef<HTMLElement>();\nconst unpinnedContainerRef = shallowRef<HTMLElement>();\n\n// version fix problem with sync between data and rendered values\nconst getKey = (item: T, index: number) => {\n return `${versionRef.value}-${props.getItemKey(item, index)}`;\n};\nconst pinnedKeysRef = computed(() => pinnedItemsRef.value.map(getKey));\nconst unpinnedKeysRef = computed(() => unpinnedItemsRef.value.map(getKey));\n\n// version fix problem with sync between data and rendered values when items have been changed\nconst versionRef = computed<number>((oldVersion) => {\n const currentKeys = itemsRef.value.map(props.getItemKey);\n\n if (domProjectionItemsRef.value === undefined) return oldVersion ?? shallowHash(...currentKeys);\n if (currentKeys.length !== domProjectionItemsRef.value.length) return shallowHash(...currentKeys);\n\n const domProjectionKeys = domProjectionItemsRef.value.map(props.getItemKey);\n const domProjectionKeysSet = new Set(domProjectionKeys);\n\n for (let i = 0; i < currentKeys.length; i++) {\n const hasInconsistentPosition =\n domProjectionKeysSet.has(currentKeys[i]) && domProjectionKeys[i] !== currentKeys[i];\n\n if (hasInconsistentPosition) {\n return shallowHash(...currentKeys);\n }\n }\n\n return oldVersion ?? shallowHash(...currentKeys);\n});\n\ncreateSortable(hasPinnedItems, pinnedContainerRef, pinnedItemsRef, () => 0);\ncreateSortable(\n hasUnpinnedItems,\n unpinnedContainerRef,\n unpinnedItemsRef,\n () => pinnedItemsRef.value.length,\n);\n\nfunction createSortable(\n toggler: ShallowRef<boolean>,\n elRef: ShallowRef<undefined | HTMLElement>,\n itemsRef: ShallowRef<T[]>,\n getOffset: () => number,\n) {\n const sortable = useSortable(elRef, itemsRef, {\n handle: `[data-draggable=\"true\"]`,\n animation: 150,\n forceFallback: true,\n fallbackOnBody: true,\n scrollSensitivity: 80,\n forceAutoScrollFallback: true,\n onUpdate: (evt: SortableEvent) => {\n if (evt.oldIndex == null || evt.newIndex == null) {\n throw new Error(\"Sortable event has no index\");\n }\n if (props.onDragEnd?.(evt.oldIndex, evt.newIndex) !== false) {\n moveItems(getOffset() + evt.oldIndex, getOffset() + evt.newIndex, true);\n }\n },\n });\n watch(\n [elRef, () => props.disableDragging, toggler],\n ([elRef, disabled, on]) => {\n if (!elRef || disabled || !on) {\n sortable.stop();\n } else {\n sortable.start();\n }\n },\n { immediate: true },\n );\n\n return sortable;\n}\n\nfunction moveItems(oldIndex: number, newIndex: number, afterUpdateDom: boolean) {\n if (oldIndex === newIndex) return;\n\n if (afterUpdateDom) {\n domProjectionItemsRef.value = moveElements(itemsRef.value.slice(), oldIndex, newIndex);\n }\n\n const preventDefault = props.onSort?.(oldIndex, newIndex) === false;\n\n if (!preventDefault) {\n moveElements(itemsRef.value, oldIndex, newIndex);\n }\n}\n\nfunction isActiveItem(item: T, index: number): boolean {\n return props.isActive?.(item, index) ?? false;\n}\n\nfunction isDraggableItem(item: T, index: number): boolean {\n if (props.disableDragging === true) return false;\n return props.isDraggable?.(item, index) ?? true;\n}\n\nfunction isRemovableItem(item: T, index: number): boolean {\n if (props.disableRemoving === true) return false;\n return props.isRemovable?.(item, index) ?? true;\n}\n\nfunction isToggableItem(item: T, index: number): boolean {\n if (props.disableToggling === true) return false;\n return (\n props.isToggable?.(item, index) ?? (isFunction(props.isToggled) || isFunction(props.onToggle))\n );\n}\n\nfunction isToggledItem(item: T, index: number): boolean {\n return props.isToggled?.(item, index) ?? false;\n}\n\nfunction isPinnableItem(item: T, index: number): boolean {\n if (props.disablePinning === true) return false;\n return props.isPinnable?.(item, index) ?? (isFunction(props.isPinned) || isFunction(props.onPin));\n}\n\nfunction isPinnedItem(item: T, index: number): boolean {\n return props.isPinned?.(item, index) ?? false;\n}\n\nfunction isExpandableItem(item: T, index: number): boolean {\n if (props.disableExpanding === true) return false;\n return (\n props.isExpandable?.(item, index) ??\n (isFunction(props.isExpanded) || isFunction(props.onExpand))\n );\n}\n\nfunction isExpandedItem(item: T, index: number): boolean {\n return props.isExpanded?.(item, index) ?? false;\n}\n\nfunction handleExpand(item: T, index: number) {\n props.onExpand?.(item, index);\n}\n\nfunction handleToggle(item: T, index: number) {\n props.onToggle?.(item, index);\n}\n\nfunction handlePin(item: T, index: number) {\n if (index === -1) {\n throw new Error(\"Pinnable item not found\");\n }\n\n const alreadyPinned = pinnedItemsRef.value.includes(item);\n\n if (props.onPin?.(item, index) === false) return;\n\n moveItems(index, pinnedItemsRef.value.length + (alreadyPinned ? 0 : -1), false);\n}\n\nfunction handleRemove(item: T, index: number) {\n if (props.onRemove?.(item, index) === false) return;\n itemsRef.value.splice(index, 1);\n}\n\nfunction getClassFunction(\n propsItemClass: string | string[] | ((item: T, index: number) => string | string[]) | undefined,\n): (item: T, index: number) => null | string | string[] {\n return (item: T, index: number): null | string | string[] => {\n if (typeof propsItemClass === \"function\") {\n return propsItemClass(item, index);\n }\n return propsItemClass ?? null;\n };\n}\nconst getItemClass = getClassFunction(props.itemClass);\nconst getItemClassTitle = getClassFunction(props.itemClassTitle);\nconst getItemClassContent = getClassFunction(props.itemClassContent);\nconst getItemClassBefore = getClassFunction(props.itemClassBefore);\nconst getItemClassAfter = getClassFunction(props.itemClassAfter);\n</script>\n\n<template>\n <div :class=\"$style.root\">\n <div ref=\"pinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"(pinnedItem, pinnedIndex) in pinnedItemsRef\"\n :key=\"pinnedKeysRef[pinnedIndex]\"\n :class=\"[$style.item, getItemClass(pinnedItem, pinnedIndex)]\"\n :titleClass=\"getItemClassTitle(pinnedItem, pinnedIndex)\"\n :contentClass=\"getItemClassContent(pinnedItem, pinnedIndex)\"\n :beforeClass=\"getItemClassBefore(pinnedItem, pinnedIndex)\"\n :afterClass=\"getItemClassAfter(pinnedItem, pinnedIndex)\"\n :index=\"pinnedIndex\"\n :item=\"pinnedItem\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(pinnedItem, pinnedIndex)\"\n :isDraggable=\"isDraggableItem(pinnedItem, pinnedIndex)\"\n :isRemovable=\"isRemovableItem(pinnedItem, pinnedIndex)\"\n :isToggable=\"isToggableItem(pinnedItem, pinnedIndex)\"\n :isToggled=\"isToggledItem(pinnedItem, pinnedIndex)\"\n :isPinnable=\"isPinnableItem(pinnedItem, pinnedIndex)\"\n :isPinned=\"true\"\n :isExpandable=\"isExpandableItem(pinnedItem, pinnedIndex)\"\n :isExpanded=\"isExpandedItem(pinnedItem, pinnedIndex)\"\n @click=\"emits('itemClick', pinnedItem)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template v-if=\"slots['item-before']\" #before=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-before\" />\n </template>\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n <div v-if=\"hasUnpinnedItems\" ref=\"unpinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"(unpinnedItem, unpinnedIndex) in unpinnedItemsRef\"\n :key=\"unpinnedKeysRef[unpinnedIndex]\"\n :class=\"[$style.item, getItemClass(unpinnedItem, unpinnedIndex)]\"\n :titleClass=\"getItemClassTitle(unpinnedItem, unpinnedIndex)\"\n :contentClass=\"getItemClassContent(unpinnedItem, unpinnedIndex)\"\n :beforeClass=\"getItemClassBefore(unpinnedItem, unpinnedIndex)\"\n :afterClass=\"getItemClassAfter(unpinnedItem, unpinnedIndex)\"\n :index=\"unpinnedIndex + (pinnedItemsRef?.length ?? 0)\"\n :item=\"unpinnedItem\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(unpinnedItem, unpinnedIndex)\"\n :isDraggable=\"isDraggableItem(unpinnedItem, unpinnedIndex)\"\n :isRemovable=\"isRemovableItem(unpinnedItem, unpinnedIndex)\"\n :isToggable=\"isToggableItem(unpinnedItem, unpinnedIndex)\"\n :isToggled=\"isToggledItem(unpinnedItem, unpinnedIndex)\"\n :isPinnable=\"isPinnableItem(unpinnedItem, unpinnedIndex)\"\n :isPinned=\"false\"\n :isExpandable=\"isExpandableItem(unpinnedItem, unpinnedIndex)\"\n :isExpanded=\"isExpandedItem(unpinnedItem, unpinnedIndex)\"\n @click=\"emits('itemClick', unpinnedItem)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n </div>\n</template>\n\n<style module>\n.root,\n.list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 180px;\n}\n\n.item {\n width: 100%;\n}\n\n:global(.sortable-ghost) {\n visibility: hidden;\n}\n:global(.sortable-drag) {\n opacity: 1;\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"PlElementList.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../src/components/PlElementList/PlElementList.vue"],"sourcesContent":["<script\n generic=\"T extends unknown = unknown, K extends number | string = number | string\"\n lang=\"ts\"\n setup\n>\nimport { isFunction, shallowHash } from \"@milaboratories/helpers\";\nimport { useSortable } from \"@vueuse/integrations/useSortable\";\nimport { type SortableEvent } from \"sortablejs\";\nimport type { ShallowRef } from \"vue\";\nimport { computed, shallowRef, watch } from \"vue\";\nimport PlElementListItem from \"./PlElementListItem.vue\";\nimport { moveElements } from \"./utils.ts\";\n\ntype ItemEntry = [idx: number, item: T];\n\nconst itemsRef = defineModel<T[]>(\"items\", { required: true });\n\nconst props = withDefaults(\n defineProps<{\n getItemKey?: (item: T, index: number) => K;\n\n itemClass?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassTitle?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassBefore?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassAfter?: string | string[] | ((item: T, index: number) => string | string[]);\n itemClassContent?: string | string[] | ((item: T, index: number) => string | string[]);\n isActive?: (item: T, index: number) => boolean;\n\n disableDragging?: boolean;\n isDraggable?: (item: T, index: number) => boolean;\n onDragEnd?: (oldIndex: number, newIndex: number) => void | boolean;\n onSort?: (oldIndex: number, newIndex: number) => void | boolean;\n\n disableRemoving?: boolean;\n isRemovable?: (item: T, index: number) => boolean;\n onRemove?: (item: T, index: number) => void | boolean;\n\n disableExpanding?: boolean;\n isExpandable?: (item: T, index: number) => boolean;\n isExpanded?: (item: T, index: number) => boolean;\n onExpand?: (item: T, index: number) => unknown;\n\n disableToggling?: boolean;\n isToggable?: (item: T, index: number) => boolean;\n isToggled?: (item: T, index: number) => boolean;\n onToggle?: (item: T, index: number) => unknown;\n\n disablePinning?: boolean;\n isPinnable?: (item: T, index: number) => boolean;\n isPinned?: (item: T, index: number) => boolean;\n onPin?: (item: T, index: number) => void | boolean;\n }>(),\n {\n getItemKey: (item: T) => JSON.stringify(item) as K,\n\n itemClass: undefined,\n itemClassTitle: undefined,\n itemClassContent: undefined,\n itemClassBefore: undefined,\n itemClassAfter: undefined,\n isActive: undefined,\n\n disableDragging: undefined,\n isDraggable: undefined,\n onDragEnd: undefined,\n onSort: undefined,\n\n disableRemoving: undefined,\n isRemovable: undefined,\n onRemove: undefined,\n\n disableExpanding: undefined,\n isExpandable: undefined,\n isExpanded: undefined,\n onExpand: undefined,\n\n disableToggling: undefined,\n isToggable: undefined,\n isToggled: undefined,\n onToggle: undefined,\n\n disablePinning: undefined,\n isPinnable: undefined,\n isPinned: undefined,\n onPin: undefined,\n },\n);\n\nconst emits = defineEmits<{\n (e: \"itemClick\", item: T): void;\n}>();\n\nconst slots = defineSlots<{\n [\"item-title\"]: (props: { item: T; index: number }) => unknown;\n [\"item-content\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-before\"]?: (props: { item: T; index: number }) => unknown;\n [\"item-after\"]?: (props: { item: T; index: number }) => unknown;\n}>();\n\nconst dndSortingEnabled = computed((): boolean => {\n return props.disableDragging !== true;\n});\n\nconst pinnedItemsRef = computed(() =>\n itemsRef.value\n .map((item, index) => [index, item] as ItemEntry)\n .filter(([index, item]) => isPinnedItem(item, index)),\n);\nconst hasPinnedItems = computed(() => pinnedItemsRef.value.length > 0);\n\nconst unpinnedItemsRef = computed(() =>\n itemsRef.value\n .map((item, index) => [index, item] as ItemEntry)\n .filter(([index, item]) => !isPinnedItem(item, index)),\n);\nconst hasUnpinnedItems = computed(() => unpinnedItemsRef.value.length > 0);\n\nconst domProjectionItemsRef = shallowRef<undefined | T[]>();\nconst pinnedContainerRef = shallowRef<HTMLElement>();\nconst unpinnedContainerRef = shallowRef<HTMLElement>();\n\n// version fix problem with sync between data and rendered values\nconst getKey = (entry: ItemEntry) => {\n return `${versionRef.value}-${props.getItemKey(entry[1], entry[0])}`;\n};\nconst pinnedKeysRef = computed(() => pinnedItemsRef.value.map(getKey));\nconst unpinnedKeysRef = computed(() => unpinnedItemsRef.value.map(getKey));\n\n// version fix problem with sync between data and rendered values when items have been changed\nconst versionRef = computed<number>((oldVersion) => {\n const currentKeys = itemsRef.value.map(props.getItemKey);\n\n if (domProjectionItemsRef.value === undefined) return oldVersion ?? shallowHash(...currentKeys);\n if (currentKeys.length !== domProjectionItemsRef.value.length) return shallowHash(...currentKeys);\n\n const domProjectionKeys = domProjectionItemsRef.value.map(props.getItemKey);\n const domProjectionKeysSet = new Set(domProjectionKeys);\n\n for (let i = 0; i < currentKeys.length; i++) {\n const hasInconsistentPosition =\n domProjectionKeysSet.has(currentKeys[i]) && domProjectionKeys[i] !== currentKeys[i];\n\n if (hasInconsistentPosition) {\n return shallowHash(...currentKeys);\n }\n }\n\n return oldVersion ?? shallowHash(...currentKeys);\n});\n\ncreateSortable(hasPinnedItems, pinnedContainerRef, pinnedItemsRef, () => 0);\ncreateSortable(\n hasUnpinnedItems,\n unpinnedContainerRef,\n unpinnedItemsRef,\n () => pinnedItemsRef.value.length,\n);\n\nfunction createSortable(\n toggler: ShallowRef<boolean>,\n elRef: ShallowRef<undefined | HTMLElement>,\n itemsRef: ShallowRef<ItemEntry[]>,\n getOffset: () => number,\n) {\n const sortable = useSortable(elRef, itemsRef, {\n handle: `[data-draggable=\"true\"]`,\n animation: 150,\n forceFallback: true,\n fallbackOnBody: true,\n scrollSensitivity: 80,\n forceAutoScrollFallback: true,\n onUpdate: (evt: SortableEvent) => {\n if (evt.oldIndex == null || evt.newIndex == null) {\n throw new Error(\"Sortable event has no index\");\n }\n if (props.onDragEnd?.(evt.oldIndex, evt.newIndex) !== false) {\n moveItems(getOffset() + evt.oldIndex, getOffset() + evt.newIndex, true);\n }\n },\n });\n watch(\n [elRef, () => props.disableDragging, toggler],\n ([elRef, disabled, on]) => {\n if (!elRef || disabled || !on) {\n sortable.stop();\n } else {\n sortable.start();\n }\n },\n { immediate: true },\n );\n\n return sortable;\n}\n\nfunction moveItems(oldIndex: number, newIndex: number, afterUpdateDom: boolean) {\n if (oldIndex === newIndex) return;\n\n if (afterUpdateDom) {\n domProjectionItemsRef.value = moveElements(itemsRef.value.slice(), oldIndex, newIndex);\n }\n\n const preventDefault = props.onSort?.(oldIndex, newIndex) === false;\n\n if (!preventDefault) {\n itemsRef.value = moveElements(itemsRef.value, oldIndex, newIndex);\n }\n}\n\nfunction isActiveItem(item: T, index: number): boolean {\n return props.isActive?.(item, index) ?? false;\n}\n\nfunction isDraggableItem(item: T, index: number): boolean {\n if (props.disableDragging === true) return false;\n return props.isDraggable?.(item, index) ?? true;\n}\n\nfunction isRemovableItem(item: T, index: number): boolean {\n if (props.disableRemoving === true) return false;\n return props.isRemovable?.(item, index) ?? true;\n}\n\nfunction isToggableItem(item: T, index: number): boolean {\n if (props.disableToggling === true) return false;\n return (\n props.isToggable?.(item, index) ?? (isFunction(props.isToggled) || isFunction(props.onToggle))\n );\n}\n\nfunction isToggledItem(item: T, index: number): boolean {\n return props.isToggled?.(item, index) ?? false;\n}\n\nfunction isPinnableItem(item: T, index: number): boolean {\n if (props.disablePinning === true) return false;\n return props.isPinnable?.(item, index) ?? (isFunction(props.isPinned) || isFunction(props.onPin));\n}\n\nfunction isPinnedItem(item: T, index: number): boolean {\n return props.isPinned?.(item, index) ?? false;\n}\n\nfunction isExpandableItem(item: T, index: number): boolean {\n if (props.disableExpanding === true) return false;\n return (\n props.isExpandable?.(item, index) ??\n (isFunction(props.isExpanded) || isFunction(props.onExpand))\n );\n}\n\nfunction isExpandedItem(item: T, index: number): boolean {\n return props.isExpanded?.(item, index) ?? false;\n}\n\nfunction handleExpand(item: T, index: number) {\n props.onExpand?.(item, index);\n}\n\nfunction handleToggle(item: T, index: number) {\n props.onToggle?.(item, index);\n}\n\nfunction handlePin(item: T, index: number) {\n if (index === -1) {\n throw new Error(\"Pinnable item not found\");\n }\n\n const alreadyPinned =\n pinnedItemsRef.value.findIndex(([originalIndex]) => originalIndex === index) !== -1;\n\n if (props.onPin?.(item, index) === false) return;\n\n moveItems(index, pinnedItemsRef.value.length + (alreadyPinned ? 0 : -1), false);\n}\n\nfunction handleRemove(item: T, index: number) {\n if (props.onRemove?.(item, index) === false) return;\n itemsRef.value = [...itemsRef.value.slice(0, index), ...itemsRef.value.slice(index + 1)];\n}\n\nfunction getClassFunction(\n propsItemClass: string | string[] | ((item: T, index: number) => string | string[]) | undefined,\n): (item: T, index: number) => null | string | string[] {\n return (item: T, index: number): null | string | string[] => {\n if (typeof propsItemClass === \"function\") {\n return propsItemClass(item, index);\n }\n return propsItemClass ?? null;\n };\n}\nconst getItemClass = getClassFunction(props.itemClass);\nconst getItemClassTitle = getClassFunction(props.itemClassTitle);\nconst getItemClassContent = getClassFunction(props.itemClassContent);\nconst getItemClassBefore = getClassFunction(props.itemClassBefore);\nconst getItemClassAfter = getClassFunction(props.itemClassAfter);\n</script>\n\n<template>\n <div :class=\"$style.root\">\n <div ref=\"pinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"([originalIndex, item], pinnedIndex) in pinnedItemsRef\"\n :key=\"pinnedKeysRef[pinnedIndex]\"\n :class=\"[$style.item, getItemClass(item, originalIndex)]\"\n :titleClass=\"getItemClassTitle(item, originalIndex)\"\n :contentClass=\"getItemClassContent(item, originalIndex)\"\n :beforeClass=\"getItemClassBefore(item, originalIndex)\"\n :afterClass=\"getItemClassAfter(item, originalIndex)\"\n :index=\"originalIndex\"\n :item=\"item\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(item, originalIndex)\"\n :isDraggable=\"isDraggableItem(item, originalIndex)\"\n :isRemovable=\"isRemovableItem(item, originalIndex)\"\n :isToggable=\"isToggableItem(item, originalIndex)\"\n :isToggled=\"isToggledItem(item, originalIndex)\"\n :isPinnable=\"isPinnableItem(item, originalIndex)\"\n :isPinned=\"true\"\n :isExpandable=\"isExpandableItem(item, originalIndex)\"\n :isExpanded=\"isExpandedItem(item, originalIndex)\"\n @click=\"emits('itemClick', item)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template v-if=\"slots['item-before']\" #before=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-before\" />\n </template>\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n <div v-if=\"hasUnpinnedItems\" ref=\"unpinnedContainerRef\" :class=\"$style.list\">\n <PlElementListItem\n v-for=\"([originalIndex, item], unpinnedIndex) in unpinnedItemsRef\"\n :key=\"unpinnedKeysRef[unpinnedIndex]\"\n :class=\"[$style.item, getItemClass(item, originalIndex)]\"\n :titleClass=\"getItemClassTitle(item, originalIndex)\"\n :contentClass=\"getItemClassContent(item, originalIndex)\"\n :beforeClass=\"getItemClassBefore(item, originalIndex)\"\n :afterClass=\"getItemClassAfter(item, originalIndex)\"\n :index=\"originalIndex\"\n :item=\"item\"\n :showDragHandle=\"dndSortingEnabled\"\n :isActive=\"isActiveItem(item, originalIndex)\"\n :isDraggable=\"isDraggableItem(item, originalIndex)\"\n :isRemovable=\"isRemovableItem(item, originalIndex)\"\n :isToggable=\"isToggableItem(item, originalIndex)\"\n :isToggled=\"isToggledItem(item, originalIndex)\"\n :isPinnable=\"isPinnableItem(item, originalIndex)\"\n :isPinned=\"false\"\n :isExpandable=\"isExpandableItem(item, originalIndex)\"\n :isExpanded=\"isExpandedItem(item, originalIndex)\"\n @click=\"emits('itemClick', item)\"\n @remove=\"handleRemove\"\n @toggle=\"handleToggle\"\n @pin=\"handlePin\"\n @expand=\"handleExpand\"\n >\n <template #title=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-title\" />\n </template>\n <template v-if=\"slots['item-content']\" #content=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-content\" />\n </template>\n <template v-if=\"slots['item-after']\" #after=\"{ item, index }\">\n <slot :index=\"index\" :item=\"item\" name=\"item-after\" />\n </template>\n </PlElementListItem>\n </div>\n </div>\n</template>\n\n<style module>\n.root,\n.list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 180px;\n}\n\n.item {\n width: 100%;\n}\n\n:global(.sortable-ghost) {\n visibility: hidden;\n}\n:global(.sortable-drag) {\n opacity: 1;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlElementList.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlElementList/PlElementList.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlElementList.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlElementList/PlElementList.vue"],"names":[],"mappings":"yBA4ZiB,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EACxF,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;WAkoBO,mBAAmB,CAAC;;;;eAxTnB,CAAC,EAAE;;qBApUK,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;oBAE9B,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,EAAE,CAAC;yBAC9D,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,EAAE,CAAC;0BAClE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,EAAE,CAAC;yBACpE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,EAAE,CAAC;2BACjE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,EAAE,CAAC;mBAC3E,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;0BAE5B,OAAO;sBACX,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;oBACrC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;iBACzD,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;0BAE7C,OAAO;sBACX,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;mBACtC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;2BAElC,OAAO;uBACX,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;qBACrC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;mBACrC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;0BAE5B,OAAO;qBACZ,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;oBACpC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;mBACpC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;yBAE7B,OAAO;qBACX,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;mBACrC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO;gBACtC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;oBA6lBwC,CAAC,4BAA2B;oBACzG,OAAO,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,IAAI;WAClD,GAAG;;sBAjjBO,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;yBAC3C,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;wBAC/C,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;uBAC/C,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;;sBAH/C,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;yBAC3C,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;wBAC/C,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;uBAC/C,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,CAAC,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO;;UAgjB1D,KAxjBD,WAAW,QAAQ,CAAC,KAAG,IAAI,+CAwjBW;EAExC,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAA;CAAE;AA7oBzE,wBA6oB4E;AAS5E,KAAK,mBAAmB,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC"}
|