@milaboratories/uikit 2.10.41 → 2.10.43

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.
@@ -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.10.41 build /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.10.43 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,13 +24,13 @@ 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 7289ms.
27
+ [vite:dts] Declaration files built in 11516ms.
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
31
31
  dist/components/PlSlideModal/PlSlideModal.vue?vue&type=style&index=0&lang.css 0.05 kB │ gzip: 0.06 kB
32
- dist/components/PlChartStackedBar/PlChartStackedBarCompact.vue?vue&type=style&index=0&lang.css 0.06 kB │ gzip: 0.08 kB
33
32
  dist/layout/PlContainer/pl-container.css 0.06 kB │ gzip: 0.08 kB
33
+ dist/components/PlChartStackedBar/PlChartStackedBarCompact.vue?vue&type=style&index=0&lang.css 0.06 kB │ gzip: 0.08 kB
34
34
  dist/layout/PlGrid/pl-grid.css 0.06 kB │ gzip: 0.07 kB
35
35
  dist/layout/PlRow/pl-row.css 0.14 kB │ gzip: 0.12 kB
36
36
  dist/components/PlChartStackedBar/PlChartStackedBar.vue?vue&type=style&index=0&lang.css 0.17 kB │ gzip: 0.15 kB
@@ -203,7 +203,7 @@ dist/components/PlBtnAccent/PlBtnAccent.js
203
203
  dist/components/PlBtnDanger/PlBtnDanger.js 0.14 kB │ gzip: 0.14 kB │ map: 1.11 kB
204
204
  dist/components/PlFileInput/PlFileInput.js 0.14 kB │ gzip: 0.14 kB │ map: 6.62 kB
205
205
  dist/components/PlStatusTag/PlStatusTag.js 0.14 kB │ gzip: 0.14 kB │ map: 0.80 kB
206
- dist/components/PlTextField/PlTextField.js 0.14 kB │ gzip: 0.14 kB │ map: 7.34 kB
206
+ dist/components/PlTextField/PlTextField.js 0.14 kB │ gzip: 0.14 kB │ map: 5.75 kB
207
207
  dist/components/SliderRange.js 0.14 kB │ gzip: 0.14 kB │ map: 8.18 kB
208
208
  dist/composition/utils.js 0.14 kB │ gzip: 0.14 kB │ map: 0.32 kB
209
209
  dist/layout/PlContainer/PlContainer.js 0.14 kB │ gzip: 0.14 kB │ map: 0.94 kB
@@ -534,6 +534,14 @@ dist/composition/useConfirm.js
534
534
  dist/assets/icons/icon-assets-min/16_clipboard-copied.js 0.57 kB │ gzip: 0.36 kB │ map: 0.73 kB
535
535
  dist/assets/icons/icon-assets-min/16_clipboard.js 0.57 kB │ gzip: 0.34 kB │ map: 0.72 kB
536
536
  dist/components/DataTable/ColumnCaret.vue_vue_type_script_setup_true_lang.js 0.57 kB │ gzip: 0.39 kB │ map: 0.85 kB
537
+ [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
538
+ - vite:asset (33%)
539
+ - vite:css-post (15%)
540
+ - vite:dts (11%)
541
+ - vite:build-import-analysis (9%)
542
+ - sourcemaps (9%)
543
+ See https://rolldown.rs/options/checks#plugintimings for more details.
544
+ 
537
545
  dist/components/PlChartStackedBar/PlChartStackedBarCompact.vue_vue_type_script_setup_true_lang.js 0.57 kB │ gzip: 0.39 kB │ map: 1.02 kB
538
546
  dist/assets/icons/icon-assets-min/24_file-doc-import.js 0.57 kB │ gzip: 0.37 kB │ map: 0.74 kB
539
547
  dist/composition/useRipple.js 0.57 kB │ gzip: 0.37 kB │ map: 1.50 kB
@@ -764,12 +772,12 @@ dist/components/PlTooltip/PlTooltip.vue_vue_type_script_setup_true_lang.js
764
772
  dist/layout/PlPlaceholder/paint-worklet.js 3.40 kB │ gzip: 0.68 kB │ map: 3.65 kB
765
773
  dist/components/DataTable/TableComponent.vue_vue_type_script_setup_true_lang.js 3.51 kB │ gzip: 1.49 kB │ map: 10.60 kB
766
774
  dist/components/PlLogView/PlLogView.vue_vue_type_script_setup_true_lang.js 3.59 kB │ gzip: 1.53 kB │ map: 10.52 kB
775
+ dist/components/PlTextField/PlTextField.vue_vue_type_script_setup_true_lang.js 4.07 kB │ gzip: 1.66 kB │ map: 11.86 kB
767
776
  dist/components/PlElementList/PlElementListItem.vue_vue_type_script_setup_true_lang.js 4.08 kB │ gzip: 1.30 kB │ map: 10.07 kB
768
777
  dist/composition/useSortable2.js 4.37 kB │ gzip: 1.64 kB │ map: 11.54 kB
769
778
  dist/assets/icons/icon-assets-min/24_heatmap.js 4.42 kB │ gzip: 0.99 kB │ map: 4.65 kB
770
779
  dist/components/PlBtnSplit/PlBtnSplit.vue_vue_type_script_setup_true_lang.js 4.52 kB │ gzip: 1.94 kB │ map: 13.35 kB
771
780
  dist/components/Slider.vue_vue_type_script_setup_true_lang.js 4.59 kB │ gzip: 1.83 kB │ map: 8.92 kB
772
- dist/components/PlTextField/PlTextField.vue_vue_type_script_setup_true_lang.js 4.75 kB │ gzip: 1.89 kB │ map: 13.94 kB
773
781
  dist/components/PlFileInput/PlFileInput.vue_vue_type_script_setup_true_lang.js 5.17 kB │ gzip: 2.02 kB │ map: 14.66 kB
774
782
  dist/components/SliderRange.vue_vue_type_script_setup_true_lang.js 5.83 kB │ gzip: 2.09 kB │ map: 12.27 kB
775
783
  dist/components/PlNumberField/PlNumberField.vue_vue_type_script_setup_true_lang.js 6.12 kB │ gzip: 2.23 kB │ map: 17.47 kB
@@ -788,13 +796,5 @@ dist/composition/filters/metadata.js
788
796
  dist/index.js 12.50 kB │ gzip: 2.94 kB │ map: 21.27 kB
789
797
  dist/components/PlSvg/PlSvg.vue_vue_type_script_setup_true_lang.js 39.32 kB │ gzip: 3.34 kB │ map: 8.66 kB
790
798
 
791
- [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
792
- - vite:asset (38%)
793
- - vite:css-post (13%)
794
- - vite:dts (11%)
795
- - vite:build-import-analysis (8%)
796
- - vite:css (8%)
797
- See https://rolldown.rs/options/checks#plugintimings for more details.
798
- 
799
- ✓ built in 10.08s
799
+ ✓ built in 13.79s
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.10.41 formatter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.10.43 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 2820ms on 380 files using 8 threads.
11
+ Finished in 5599ms on 380 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.10.41 linter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.10.43 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 34ms on 307 files with 98 rules using 8 threads.
9
+ Finished in 31ms on 307 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.10.41 types:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.10.43 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.10.43
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [15959f8]
8
+ - @platforma-sdk/model@1.58.22
9
+
10
+ ## 2.10.42
11
+
12
+ ### Patch Changes
13
+
14
+ - a93de45: Fix table filters bugs
15
+ - Updated dependencies [a93de45]
16
+ - @milaboratories/helpers@1.13.7
17
+ - @platforma-sdk/model@1.58.19
18
+
3
19
  ## 2.10.41
4
20
 
5
21
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"PlTextField.js","names":[],"sources":["../../../src/components/PlTextField/PlTextField.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Component for one-line string data manipulation\n */\nexport default {\n name: \"PlTextField\",\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M, E = string, C = E\">\nimport type { Equal } from \"@milaboratories/helpers\";\nimport { computed, reactive, ref, useSlots } from \"vue\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport { useValidation } from \"../../utils/useValidation\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlIcon24 } from \"../PlIcon24\";\nimport { PlSvg } from \"../PlSvg\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport \"./pl-text-field.scss\";\n\nconst slots = useSlots();\n\ntype Model = Equal<M, E | C> extends true ? M : never; // basically in === out\n\n/**\n * The current value of the input field.\n */\nconst model = defineModel<Model>({\n required: true,\n});\n\nconst props = defineProps<{\n /**\n * The label to display above the input field.\n */\n label?: string;\n /**\n * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).\n * Or you can pass a callback that returns a custom \"empty\" value (null | undefined | string)\n */\n clearable?: boolean | (() => C);\n /**\n * An optional callback to parse and/or cast the value, the return type overrides the model type.\n * The callback must throw an exception if the value is invalid\n */\n parse?: (v: string) => E;\n /**\n * If `true`, the input field is marked as required.\n */\n required?: boolean;\n /**\n * An error message to display below the input field.\n */\n error?: unknown;\n /**\n * A helper text to display below the input field when there are no errors.\n */\n helper?: string;\n /**\n * A placeholder text to display inside the input field when it is empty.\n */\n placeholder?: string;\n /**\n * If `true`, the input field is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * If `true`, the input field has a dashed border.\n */\n dashed?: boolean;\n /**\n * A prefix text to display inside the input field before the value.\n */\n prefix?: string;\n /**\n * An array of validation rules to apply to the input field. Each rule is a function that takes the current value and returns `true` if valid or an error message if invalid.\n */\n rules?: ((v: string) => boolean | string)[];\n /**\n * The string specifies whether the field should be a password or not, value could be \"password\" or undefined.\n */\n type?: \"password\";\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\nconst rootRef = ref<HTMLInputElement | undefined>(undefined);\n\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst showPassword = ref(false);\n\nconst data = reactive({\n cached: undefined as { error: string; value: string } | undefined,\n});\n\nconst valueRef = computed<string>({\n get() {\n if (data.cached) {\n return data.cached.value;\n }\n return model.value === undefined || model.value === null ? \"\" : String(model.value);\n },\n set(value) {\n data.cached = undefined;\n\n if (props.parse) {\n try {\n model.value = props.parse(value) as Model;\n } catch (err) {\n data.cached = {\n error: err instanceof Error ? err.message : String(err),\n value,\n };\n }\n } else {\n model.value = value as Model;\n }\n },\n});\n\nconst fieldType = computed(() => {\n if (props.type && props.type === \"password\") {\n return showPassword.value ? \"text\" : props.type;\n } else {\n return \"text\";\n }\n});\n\nconst passwordIcon = computed(() => (showPassword.value ? \"view-show\" : \"view-hide\"));\n\nconst clear = () => {\n if (props.clearable) {\n data.cached = undefined;\n model.value = props.clearable === true ? (\"\" as Model) : (props.clearable() as Model);\n }\n};\n\nconst validationData = useValidation(valueRef, props.rules || []);\n\nconst isEmpty = computed(() => {\n if (props.clearable) {\n return props.clearable === true ? model.value === \"\" : model.value === props.clearable();\n }\n\n return model.value === \"\";\n});\n\nconst nonEmpty = computed(() => !isEmpty.value);\n\nconst displayErrors = computed(() => {\n const errors: string[] = [];\n const propsError = getErrorMessage(props.error);\n if (propsError) {\n errors.push(propsError);\n }\n if (data.cached) {\n errors.push(data.cached.error);\n }\n if (!validationData.value.isValid) {\n errors.push(...validationData.value.errors);\n }\n return errors;\n});\n\nconst hasErrors = computed(() => displayErrors.value.length > 0);\n\nconst canShowClearable = computed(\n () => props.clearable && nonEmpty.value && props.type !== \"password\" && !props.disabled,\n);\n\nconst togglePasswordVisibility = () => (showPassword.value = !showPassword.value);\n\nconst onFocusOut = () => {\n data.cached = undefined;\n};\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nuseLabelNotch(rootRef);\n</script>\n\n<template>\n <div class=\"pl-text-field__envelope\">\n <div\n ref=\"rootRef\"\n class=\"pl-text-field\"\n :class=\"{\n error: hasErrors,\n disabled,\n dashed,\n nonEmpty,\n }\"\n >\n <label v-if=\"label\" ref=\"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 <div v-if=\"prefix\" class=\"pl-text-field__prefix\">\n {{ prefix }}\n </div>\n <input\n ref=\"inputRef\"\n v-model=\"valueRef\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder || '...'\"\n :type=\"fieldType\"\n spellcheck=\"false\"\n @focusout=\"onFocusOut\"\n />\n <div class=\"pl-text-field__append\" @click=\"setFocusOnInput\">\n <PlIcon16\n v-if=\"canShowClearable\"\n class=\"pl-text-field__clearable\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <PlIcon24\n v-if=\"type === 'password'\"\n :name=\"passwordIcon\"\n style=\"cursor: pointer\"\n @click.stop=\"togglePasswordVisibility\"\n />\n <slot name=\"append\" />\n </div>\n <DoubleContour class=\"pl-text-field__contour\" :group-position=\"groupPosition\" />\n </div>\n <div v-if=\"hasErrors\" class=\"pl-text-field__error\">\n {{ displayErrors.join(\" \") }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-text-field__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"PlTextField.js","names":[],"sources":["../../../src/components/PlTextField/PlTextField.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Component for one-line string data manipulation\n */\nexport default {\n name: \"PlTextField\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport { computed, ref, useSlots } from \"vue\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport { useValidation } from \"../../utils/useValidation\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlIcon24 } from \"../PlIcon24\";\nimport { PlSvg } from \"../PlSvg\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport \"./pl-text-field.scss\";\n\nconst slots = useSlots();\n\n/**\n * The current value of the input field.\n */\nconst model = defineModel<string>({\n default: \"\",\n});\n\nconst props = defineProps<{\n /**\n * The label to display above the input field.\n */\n label?: string;\n /**\n * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).\n */\n clearable?: boolean;\n /**\n * If `true`, the input field is marked as required.\n */\n required?: boolean;\n /**\n * An error message to display below the input field.\n */\n error?: unknown;\n /**\n * A helper text to display below the input field when there are no errors.\n */\n helper?: string;\n /**\n * A placeholder text to display inside the input field when it is empty.\n */\n placeholder?: string;\n /**\n * If `true`, the input field is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * If `true`, the input field has a dashed border.\n */\n dashed?: boolean;\n /**\n * A prefix text to display inside the input field before the value.\n */\n prefix?: string;\n /**\n * An array of validation rules to apply to the input field. Each rule is a function that takes the current value and returns `true` if valid or an error message if invalid.\n */\n rules?: ((v: string) => boolean | string)[];\n /**\n * The string specifies whether the field should be a password or not, value could be \"password\" or undefined.\n */\n type?: \"password\";\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\nconst rootRef = ref<HTMLInputElement | undefined>(undefined);\n\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst showPassword = ref(false);\n\nconst fieldType = computed(() => {\n if (props.type && props.type === \"password\") {\n return showPassword.value ? \"text\" : props.type;\n } else {\n return \"text\";\n }\n});\n\nconst passwordIcon = computed(() => (showPassword.value ? \"view-show\" : \"view-hide\"));\n\nconst clear = () => {\n if (props.clearable) {\n model.value = \"\";\n }\n};\n\nconst validationData = useValidation(model, props.rules || []);\n\nconst isEmpty = computed(() => model.value === \"\");\n\nconst nonEmpty = computed(() => !isEmpty.value);\n\nconst displayErrors = computed(() => {\n const errors: string[] = [];\n const propsError = getErrorMessage(props.error);\n if (propsError) {\n errors.push(propsError);\n }\n if (!validationData.value.isValid) {\n errors.push(...validationData.value.errors);\n }\n return errors;\n});\n\nconst hasErrors = computed(() => displayErrors.value.length > 0);\n\nconst canShowClearable = computed(\n () => props.clearable && nonEmpty.value && props.type !== \"password\" && !props.disabled,\n);\n\nconst togglePasswordVisibility = () => (showPassword.value = !showPassword.value);\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nuseLabelNotch(rootRef);\n</script>\n\n<template>\n <div class=\"pl-text-field__envelope\">\n <div\n ref=\"rootRef\"\n class=\"pl-text-field\"\n :class=\"{\n error: hasErrors,\n disabled,\n dashed,\n nonEmpty,\n }\"\n >\n <label v-if=\"label\" ref=\"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 <div v-if=\"prefix\" class=\"pl-text-field__prefix\">\n {{ prefix }}\n </div>\n <input\n ref=\"inputRef\"\n v-model=\"model\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder || '...'\"\n :type=\"fieldType\"\n spellcheck=\"false\"\n />\n <div class=\"pl-text-field__append\" @click=\"setFocusOnInput\">\n <PlIcon16\n v-if=\"canShowClearable\"\n class=\"pl-text-field__clearable\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <PlIcon24\n v-if=\"type === 'password'\"\n :name=\"passwordIcon\"\n style=\"cursor: pointer\"\n @click.stop=\"togglePasswordVisibility\"\n />\n <slot name=\"append\" />\n </div>\n <DoubleContour class=\"pl-text-field__contour\" :group-position=\"groupPosition\" />\n </div>\n <div v-if=\"hasErrors\" class=\"pl-text-field__error\">\n {{ displayErrors.join(\" \") }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-text-field__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":""}
@@ -1,80 +1,124 @@
1
- import { Equal } from '@milaboratories/helpers';
2
1
  /**
3
2
  * Component for one-line string data manipulation
4
3
  */
5
- declare const _default: <M, E = string, C = E>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
6
- props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
7
- readonly "onUpdate:modelValue"?: ((value: Equal<M, E | C> extends true ? M : never) => any) | undefined;
8
- } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onUpdate:modelValue"> & ({
9
- modelValue: Equal<M, E | C> extends true ? M : never;
10
- } & {
11
- /**
12
- * The label to display above the input field.
13
- */
14
- label?: string;
15
- /**
16
- * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).
17
- * Or you can pass a callback that returns a custom "empty" value (null | undefined | string)
18
- */
19
- clearable?: boolean | (() => C);
20
- /**
21
- * An optional callback to parse and/or cast the value, the return type overrides the model type.
22
- * The callback must throw an exception if the value is invalid
23
- */
24
- parse?: (v: string) => E;
25
- /**
26
- * If `true`, the input field is marked as required.
27
- */
28
- required?: boolean;
29
- /**
30
- * An error message to display below the input field.
31
- */
32
- error?: unknown;
33
- /**
34
- * A helper text to display below the input field when there are no errors.
35
- */
36
- helper?: string;
37
- /**
38
- * A placeholder text to display inside the input field when it is empty.
39
- */
40
- placeholder?: string;
41
- /**
42
- * If `true`, the input field is disabled and cannot be interacted with.
43
- */
44
- disabled?: boolean;
45
- /**
46
- * If `true`, the input field has a dashed border.
47
- */
48
- dashed?: boolean;
49
- /**
50
- * A prefix text to display inside the input field before the value.
51
- */
52
- prefix?: string;
53
- /**
54
- * An array of validation rules to apply to the input field. Each rule is a function that takes the current value and returns `true` if valid or an error message if invalid.
55
- */
56
- rules?: ((v: string) => boolean | string)[];
57
- /**
58
- * The string specifies whether the field should be a password or not, value could be "password" or undefined.
59
- */
60
- type?: "password";
61
- /**
62
- * Makes some of corners not rounded
63
- * */
64
- groupPosition?: "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "middle";
65
- }) & Partial<{}>> & import('vue').PublicProps;
66
- expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
67
- attrs: any;
68
- slots: {
69
- tooltip?(_: {}): any;
70
- append?(_: {}): any;
4
+ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
5
+ modelValue?: string;
6
+ } & {
7
+ /**
8
+ * The label to display above the input field.
9
+ */
10
+ label?: string;
11
+ /**
12
+ * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).
13
+ */
14
+ clearable?: boolean;
15
+ /**
16
+ * If `true`, the input field is marked as required.
17
+ */
18
+ required?: boolean;
19
+ /**
20
+ * An error message to display below the input field.
21
+ */
22
+ error?: unknown;
23
+ /**
24
+ * A helper text to display below the input field when there are no errors.
25
+ */
26
+ helper?: string;
27
+ /**
28
+ * A placeholder text to display inside the input field when it is empty.
29
+ */
30
+ placeholder?: string;
31
+ /**
32
+ * If `true`, the input field is disabled and cannot be interacted with.
33
+ */
34
+ disabled?: boolean;
35
+ /**
36
+ * If `true`, the input field has a dashed border.
37
+ */
38
+ dashed?: boolean;
39
+ /**
40
+ * A prefix text to display inside the input field before the value.
41
+ */
42
+ prefix?: string;
43
+ /**
44
+ * An array of validation rules to apply to the input field. Each rule is a function that takes the current value and returns `true` if valid or an error message if invalid.
45
+ */
46
+ rules?: ((v: string) => boolean | string)[];
47
+ /**
48
+ * The string specifies whether the field should be a password or not, value could be "password" or undefined.
49
+ */
50
+ type?: "password";
51
+ /**
52
+ * Makes some of corners not rounded
53
+ * */
54
+ groupPosition?: "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "middle";
55
+ }, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
56
+ "update:modelValue": (value: string) => any;
57
+ }, string, import('vue').PublicProps, Readonly<{
58
+ modelValue?: string;
59
+ } & {
60
+ /**
61
+ * The label to display above the input field.
62
+ */
63
+ label?: string;
64
+ /**
65
+ * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).
66
+ */
67
+ clearable?: boolean;
68
+ /**
69
+ * If `true`, the input field is marked as required.
70
+ */
71
+ required?: boolean;
72
+ /**
73
+ * An error message to display below the input field.
74
+ */
75
+ error?: unknown;
76
+ /**
77
+ * A helper text to display below the input field when there are no errors.
78
+ */
79
+ helper?: string;
80
+ /**
81
+ * A placeholder text to display inside the input field when it is empty.
82
+ */
83
+ placeholder?: string;
84
+ /**
85
+ * If `true`, the input field is disabled and cannot be interacted with.
86
+ */
87
+ disabled?: boolean;
88
+ /**
89
+ * If `true`, the input field has a dashed border.
90
+ */
91
+ dashed?: boolean;
92
+ /**
93
+ * A prefix text to display inside the input field before the value.
94
+ */
95
+ prefix?: string;
96
+ /**
97
+ * An array of validation rules to apply to the input field. Each rule is a function that takes the current value and returns `true` if valid or an error message if invalid.
98
+ */
99
+ rules?: ((v: string) => boolean | string)[];
100
+ /**
101
+ * The string specifies whether the field should be a password or not, value could be "password" or undefined.
102
+ */
103
+ type?: "password";
104
+ /**
105
+ * Makes some of corners not rounded
106
+ * */
107
+ groupPosition?: "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "middle";
108
+ }> & Readonly<{
109
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
110
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
111
+ rootRef: HTMLDivElement;
112
+ label: HTMLLabelElement;
113
+ inputRef: HTMLInputElement;
114
+ }, HTMLDivElement>, {
115
+ tooltip?(_: {}): any;
116
+ append?(_: {}): any;
117
+ }>;
118
+ export default _default;
119
+ type __VLS_WithTemplateSlots<T, S> = T & {
120
+ new (): {
121
+ $slots: S;
71
122
  };
72
- emit: (evt: "update:modelValue", value: Equal<M, E | C> extends true ? M : never) => void;
73
- }>) => import('vue').VNode & {
74
- __ctx?: Awaited<typeof __VLS_setup>;
75
123
  };
76
- export default _default;
77
- type __VLS_PrettifyLocal<T> = {
78
- [K in keyof T]: T[K];
79
- } & {};
80
124
  //# sourceMappingURL=PlTextField.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlTextField.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlTextField/PlTextField.vue"],"names":[],"mappings":"AA8PA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAWrD,OAAO,sBAAsB,CAAC;AAG9B;;GAEG;yBACc,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,EACpC,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;WA2YO,mBAAmB,CAAC;;;;;QA9X1B;;WAEG;gBACK,MAAM;QACd;;;WAGG;oBACS,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B;;;WAGG;gBACK,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC;QACxB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;gBACK,OAAO;QACf;;WAEG;iBACM,MAAM;QACf;;WAEG;sBACW,MAAM;QACpB;;WAEG;mBACQ,OAAO;QAClB;;WAEG;iBACM,OAAO;QAChB;;WAEG;iBACM,MAAM;QACf;;WAEG;gBACK,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC,EAAE;QAC3C;;WAEG;eACI,UAAU;QACjB;;aAEK;wBAED,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,QAAQ;oBAgUgF,CAAC,4BAA2B;oBACzG,OAAO,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,IAAI;WAClD,GAAG;;yBAtDmB,GAAG;wBACJ,GAAG;;;EAyD5B,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAA;CAAE;AAtZzE,wBAsZ4E;AAG5E,KAAK,mBAAmB,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"PlTextField.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlTextField/PlTextField.vue"],"names":[],"mappings":"AAmNA,OAAO,sBAAsB,CAAC;AAG9B;;GAEG;;iBAiIU,MAAM;;IArHjB;;OAEG;YACK,MAAM;IACd;;OAEG;gBACS,OAAO;IACnB;;OAEG;eACQ,OAAO;IAClB;;OAEG;YACK,OAAO;IACf;;OAEG;aACM,MAAM;IACf;;OAEG;kBACW,MAAM;IACpB;;OAEG;eACQ,OAAO;IAClB;;OAEG;aACM,OAAO;IAChB;;OAEG;aACM,MAAM;IACf;;OAEG;YACK,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC,EAAE;IAC3C;;OAEG;WACI,UAAU;IACjB;;SAEK;oBAED,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,QAAQ;;;;iBA6DD,MAAM;;IArHjB;;OAEG;YACK,MAAM;IACd;;OAEG;gBACS,OAAO;IACnB;;OAEG;eACQ,OAAO;IAClB;;OAEG;YACK,OAAO;IACf;;OAEG;aACM,MAAM;IACf;;OAEG;kBACW,MAAM;IACpB;;OAEG;eACQ,OAAO;IAClB;;OAEG;aACM,OAAO;IAChB;;OAEG;aACM,MAAM;IACf;;OAEG;YACK,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC,EAAE;IAC3C;;OAEG;WACI,UAAU;IACjB;;SAEK;oBAED,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,GACd,QAAQ;;;;;;;;qBA4NgB,GAAG;oBACJ,GAAG;;AAhShC,wBA8VK;AASL,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
@@ -12,29 +12,28 @@ import "../PlIcon16/index.js";
12
12
  import s from "../../assets/images/required.js";
13
13
  import { useValidation as c } from "../../utils/useValidation.js";
14
14
  import './pl-text-field.css';/* empty css */
15
- import { computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createVNode as m, defineComponent as h, mergeModels as g, normalizeClass as _, openBlock as v, reactive as y, ref as b, renderSlot as x, toDisplayString as S, unref as C, useModel as w, useSlots as T, vModelDynamic as E, withCtx as D, withDirectives as O, withModifiers as k } from "vue";
16
- var A = { class: "pl-text-field__envelope" }, j = {
15
+ import { computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createVNode as m, defineComponent as h, mergeModels as g, normalizeClass as _, openBlock as v, ref as y, renderSlot as b, toDisplayString as x, unref as S, useModel as C, useSlots as w, vModelDynamic as T, withCtx as E, withDirectives as D, withModifiers as O } from "vue";
16
+ var k = { class: "pl-text-field__envelope" }, A = {
17
17
  key: 0,
18
18
  ref: "label"
19
- }, M = {
19
+ }, j = {
20
20
  key: 1,
21
21
  class: "pl-text-field__prefix"
22
- }, N = [
22
+ }, M = [
23
23
  "disabled",
24
24
  "placeholder",
25
25
  "type"
26
- ], P = {
26
+ ], N = {
27
27
  key: 0,
28
28
  class: "pl-text-field__error"
29
- }, F = {
29
+ }, P = {
30
30
  key: 1,
31
31
  class: "pl-text-field__helper"
32
- }, I = /* @__PURE__ */ h({
32
+ }, F = /* @__PURE__ */ h({
33
33
  name: "PlTextField",
34
34
  props: /* @__PURE__ */ g({
35
35
  label: {},
36
- clearable: { type: [Boolean, Function] },
37
- parse: { type: Function },
36
+ clearable: { type: Boolean },
38
37
  required: { type: Boolean },
39
38
  error: {},
40
39
  helper: {},
@@ -46,95 +45,77 @@ var A = { class: "pl-text-field__envelope" }, j = {
46
45
  type: {},
47
46
  groupPosition: {}
48
47
  }, {
49
- modelValue: { required: !0 },
48
+ modelValue: { default: "" },
50
49
  modelModifiers: {}
51
50
  }),
52
51
  emits: ["update:modelValue"],
53
52
  setup(h) {
54
- let g = T(), I = w(h, "modelValue"), L = h, R = b(void 0), z = b(), B = b(!1), V = y({ cached: void 0 }), H = l({
55
- get() {
56
- return V.cached ? V.cached.value : I.value === void 0 || I.value === null ? "" : String(I.value);
57
- },
58
- set(e) {
59
- if (V.cached = void 0, L.parse) try {
60
- I.value = L.parse(e);
61
- } catch (t) {
62
- V.cached = {
63
- error: t instanceof Error ? t.message : String(t),
64
- value: e
65
- };
66
- }
67
- else I.value = e;
68
- }
69
- }), U = l(() => L.type && L.type === "password" ? B.value ? "text" : L.type : "text"), W = l(() => B.value ? "view-show" : "view-hide"), G = () => {
70
- L.clearable && (V.cached = void 0, I.value = L.clearable === !0 ? "" : L.clearable());
71
- }, K = c(H, L.rules || []), q = l(() => L.clearable ? L.clearable === !0 ? I.value === "" : I.value === L.clearable() : I.value === ""), J = l(() => !q.value), Y = l(() => {
72
- let e = [], n = t(L.error);
73
- return n && e.push(n), V.cached && e.push(V.cached.error), K.value.isValid || e.push(...K.value.errors), e;
74
- }), X = l(() => Y.value.length > 0), Z = l(() => L.clearable && J.value && L.type !== "password" && !L.disabled), Q = () => B.value = !B.value, $ = () => {
75
- V.cached = void 0;
76
- }, ee = () => z.value?.focus();
77
- return o(R), (t, o) => (v(), f("div", A, [p("div", {
53
+ let g = w(), F = C(h, "modelValue"), I = h, L = y(void 0), R = y(), z = y(!1), B = l(() => I.type && I.type === "password" ? z.value ? "text" : I.type : "text"), V = l(() => z.value ? "view-show" : "view-hide"), H = () => {
54
+ I.clearable && (F.value = "");
55
+ }, U = c(F, I.rules || []), W = l(() => F.value === ""), G = l(() => !W.value), K = l(() => {
56
+ let e = [], n = t(I.error);
57
+ return n && e.push(n), U.value.isValid || e.push(...U.value.errors), e;
58
+ }), q = l(() => K.value.length > 0), J = l(() => I.clearable && G.value && I.type !== "password" && !I.disabled), Y = () => z.value = !z.value, X = () => R.value?.focus();
59
+ return o(L), (t, o) => (v(), f("div", k, [p("div", {
78
60
  ref_key: "rootRef",
79
- ref: R,
61
+ ref: L,
80
62
  class: _(["pl-text-field", {
81
- error: X.value,
63
+ error: q.value,
82
64
  disabled: h.disabled,
83
65
  dashed: h.dashed,
84
- nonEmpty: J.value
66
+ nonEmpty: G.value
85
67
  }])
86
68
  }, [
87
- h.label ? (v(), f("label", j, [
88
- h.required ? (v(), u(C(n), {
69
+ h.label ? (v(), f("label", A, [
70
+ h.required ? (v(), u(S(n), {
89
71
  key: 0,
90
- uri: C(s)
72
+ uri: S(s)
91
73
  }, null, 8, ["uri"])) : d("", !0),
92
- p("span", null, S(h.label), 1),
93
- C(g).tooltip ? (v(), u(C(e), {
74
+ p("span", null, x(h.label), 1),
75
+ S(g).tooltip ? (v(), u(S(e), {
94
76
  key: 1,
95
77
  class: "info",
96
78
  position: "top"
97
79
  }, {
98
- tooltip: D(() => [x(t.$slots, "tooltip")]),
80
+ tooltip: E(() => [b(t.$slots, "tooltip")]),
99
81
  _: 3
100
82
  })) : d("", !0)
101
83
  ], 512)) : d("", !0),
102
- h.prefix ? (v(), f("div", M, S(h.prefix), 1)) : d("", !0),
103
- O(p("input", {
84
+ h.prefix ? (v(), f("div", j, x(h.prefix), 1)) : d("", !0),
85
+ D(p("input", {
104
86
  ref_key: "inputRef",
105
- ref: z,
106
- "onUpdate:modelValue": o[0] ||= (e) => H.value = e,
87
+ ref: R,
88
+ "onUpdate:modelValue": o[0] ||= (e) => F.value = e,
107
89
  disabled: h.disabled,
108
90
  placeholder: h.placeholder || "...",
109
- type: U.value,
110
- spellcheck: "false",
111
- onFocusout: $
112
- }, null, 40, N), [[E, H.value]]),
91
+ type: B.value,
92
+ spellcheck: "false"
93
+ }, null, 8, M), [[T, F.value]]),
113
94
  p("div", {
114
95
  class: "pl-text-field__append",
115
- onClick: ee
96
+ onClick: X
116
97
  }, [
117
- Z.value ? (v(), u(C(i), {
98
+ J.value ? (v(), u(S(i), {
118
99
  key: 0,
119
100
  class: "pl-text-field__clearable",
120
101
  name: "delete-clear",
121
- onClick: k(G, ["stop"])
102
+ onClick: O(H, ["stop"])
122
103
  })) : d("", !0),
123
- h.type === "password" ? (v(), u(C(r), {
104
+ h.type === "password" ? (v(), u(S(r), {
124
105
  key: 1,
125
- name: W.value,
106
+ name: V.value,
126
107
  style: { cursor: "pointer" },
127
- onClick: k(Q, ["stop"])
108
+ onClick: O(Y, ["stop"])
128
109
  }, null, 8, ["name"])) : d("", !0),
129
- x(t.$slots, "append")
110
+ b(t.$slots, "append")
130
111
  ]),
131
112
  m(a, {
132
113
  class: "pl-text-field__contour",
133
114
  "group-position": h.groupPosition
134
115
  }, null, 8, ["group-position"])
135
- ], 2), X.value ? (v(), f("div", P, S(Y.value.join(" ")), 1)) : h.helper ? (v(), f("div", F, S(h.helper), 1)) : d("", !0)]));
116
+ ], 2), q.value ? (v(), f("div", N, x(K.value.join(" ")), 1)) : h.helper ? (v(), f("div", P, x(h.helper), 1)) : d("", !0)]));
136
117
  }
137
118
  });
138
- export { I as default };
119
+ export { F as default };
139
120
 
140
121
  //# sourceMappingURL=PlTextField.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlTextField.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlTextField/PlTextField.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Component for one-line string data manipulation\n */\nexport default {\n name: \"PlTextField\",\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M, E = string, C = E\">\nimport type { Equal } from \"@milaboratories/helpers\";\nimport { computed, reactive, ref, useSlots } from \"vue\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport { useValidation } from \"../../utils/useValidation\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlIcon24 } from \"../PlIcon24\";\nimport { PlSvg } from \"../PlSvg\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport \"./pl-text-field.scss\";\n\nconst slots = useSlots();\n\ntype Model = Equal<M, E | C> extends true ? M : never; // basically in === out\n\n/**\n * The current value of the input field.\n */\nconst model = defineModel<Model>({\n required: true,\n});\n\nconst props = defineProps<{\n /**\n * The label to display above the input field.\n */\n label?: string;\n /**\n * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).\n * Or you can pass a callback that returns a custom \"empty\" value (null | undefined | string)\n */\n clearable?: boolean | (() => C);\n /**\n * An optional callback to parse and/or cast the value, the return type overrides the model type.\n * The callback must throw an exception if the value is invalid\n */\n parse?: (v: string) => E;\n /**\n * If `true`, the input field is marked as required.\n */\n required?: boolean;\n /**\n * An error message to display below the input field.\n */\n error?: unknown;\n /**\n * A helper text to display below the input field when there are no errors.\n */\n helper?: string;\n /**\n * A placeholder text to display inside the input field when it is empty.\n */\n placeholder?: string;\n /**\n * If `true`, the input field is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * If `true`, the input field has a dashed border.\n */\n dashed?: boolean;\n /**\n * A prefix text to display inside the input field before the value.\n */\n prefix?: string;\n /**\n * An array of validation rules to apply to the input field. Each rule is a function that takes the current value and returns `true` if valid or an error message if invalid.\n */\n rules?: ((v: string) => boolean | string)[];\n /**\n * The string specifies whether the field should be a password or not, value could be \"password\" or undefined.\n */\n type?: \"password\";\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\nconst rootRef = ref<HTMLInputElement | undefined>(undefined);\n\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst showPassword = ref(false);\n\nconst data = reactive({\n cached: undefined as { error: string; value: string } | undefined,\n});\n\nconst valueRef = computed<string>({\n get() {\n if (data.cached) {\n return data.cached.value;\n }\n return model.value === undefined || model.value === null ? \"\" : String(model.value);\n },\n set(value) {\n data.cached = undefined;\n\n if (props.parse) {\n try {\n model.value = props.parse(value) as Model;\n } catch (err) {\n data.cached = {\n error: err instanceof Error ? err.message : String(err),\n value,\n };\n }\n } else {\n model.value = value as Model;\n }\n },\n});\n\nconst fieldType = computed(() => {\n if (props.type && props.type === \"password\") {\n return showPassword.value ? \"text\" : props.type;\n } else {\n return \"text\";\n }\n});\n\nconst passwordIcon = computed(() => (showPassword.value ? \"view-show\" : \"view-hide\"));\n\nconst clear = () => {\n if (props.clearable) {\n data.cached = undefined;\n model.value = props.clearable === true ? (\"\" as Model) : (props.clearable() as Model);\n }\n};\n\nconst validationData = useValidation(valueRef, props.rules || []);\n\nconst isEmpty = computed(() => {\n if (props.clearable) {\n return props.clearable === true ? model.value === \"\" : model.value === props.clearable();\n }\n\n return model.value === \"\";\n});\n\nconst nonEmpty = computed(() => !isEmpty.value);\n\nconst displayErrors = computed(() => {\n const errors: string[] = [];\n const propsError = getErrorMessage(props.error);\n if (propsError) {\n errors.push(propsError);\n }\n if (data.cached) {\n errors.push(data.cached.error);\n }\n if (!validationData.value.isValid) {\n errors.push(...validationData.value.errors);\n }\n return errors;\n});\n\nconst hasErrors = computed(() => displayErrors.value.length > 0);\n\nconst canShowClearable = computed(\n () => props.clearable && nonEmpty.value && props.type !== \"password\" && !props.disabled,\n);\n\nconst togglePasswordVisibility = () => (showPassword.value = !showPassword.value);\n\nconst onFocusOut = () => {\n data.cached = undefined;\n};\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nuseLabelNotch(rootRef);\n</script>\n\n<template>\n <div class=\"pl-text-field__envelope\">\n <div\n ref=\"rootRef\"\n class=\"pl-text-field\"\n :class=\"{\n error: hasErrors,\n disabled,\n dashed,\n nonEmpty,\n }\"\n >\n <label v-if=\"label\" ref=\"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 <div v-if=\"prefix\" class=\"pl-text-field__prefix\">\n {{ prefix }}\n </div>\n <input\n ref=\"inputRef\"\n v-model=\"valueRef\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder || '...'\"\n :type=\"fieldType\"\n spellcheck=\"false\"\n @focusout=\"onFocusOut\"\n />\n <div class=\"pl-text-field__append\" @click=\"setFocusOnInput\">\n <PlIcon16\n v-if=\"canShowClearable\"\n class=\"pl-text-field__clearable\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <PlIcon24\n v-if=\"type === 'password'\"\n :name=\"passwordIcon\"\n style=\"cursor: pointer\"\n @click.stop=\"togglePasswordVisibility\"\n />\n <slot name=\"append\" />\n </div>\n <DoubleContour class=\"pl-text-field__contour\" :group-position=\"groupPosition\" />\n </div>\n <div v-if=\"hasErrors\" class=\"pl-text-field__error\">\n {{ displayErrors.join(\" \") }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-text-field__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PlTextField.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlTextField/PlTextField.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Component for one-line string data manipulation\n */\nexport default {\n name: \"PlTextField\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport { computed, ref, useSlots } from \"vue\";\nimport SvgRequired from \"../../assets/images/required.svg?raw\";\nimport { getErrorMessage } from \"../../helpers/error.ts\";\nimport DoubleContour from \"../../utils/DoubleContour.vue\";\nimport { useLabelNotch } from \"../../utils/useLabelNotch\";\nimport { useValidation } from \"../../utils/useValidation\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport { PlIcon24 } from \"../PlIcon24\";\nimport { PlSvg } from \"../PlSvg\";\nimport { PlTooltip } from \"../PlTooltip\";\nimport \"./pl-text-field.scss\";\n\nconst slots = useSlots();\n\n/**\n * The current value of the input field.\n */\nconst model = defineModel<string>({\n default: \"\",\n});\n\nconst props = defineProps<{\n /**\n * The label to display above the input field.\n */\n label?: string;\n /**\n * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).\n */\n clearable?: boolean;\n /**\n * If `true`, the input field is marked as required.\n */\n required?: boolean;\n /**\n * An error message to display below the input field.\n */\n error?: unknown;\n /**\n * A helper text to display below the input field when there are no errors.\n */\n helper?: string;\n /**\n * A placeholder text to display inside the input field when it is empty.\n */\n placeholder?: string;\n /**\n * If `true`, the input field is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * If `true`, the input field has a dashed border.\n */\n dashed?: boolean;\n /**\n * A prefix text to display inside the input field before the value.\n */\n prefix?: string;\n /**\n * An array of validation rules to apply to the input field. Each rule is a function that takes the current value and returns `true` if valid or an error message if invalid.\n */\n rules?: ((v: string) => boolean | string)[];\n /**\n * The string specifies whether the field should be a password or not, value could be \"password\" or undefined.\n */\n type?: \"password\";\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\nconst rootRef = ref<HTMLInputElement | undefined>(undefined);\n\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst showPassword = ref(false);\n\nconst fieldType = computed(() => {\n if (props.type && props.type === \"password\") {\n return showPassword.value ? \"text\" : props.type;\n } else {\n return \"text\";\n }\n});\n\nconst passwordIcon = computed(() => (showPassword.value ? \"view-show\" : \"view-hide\"));\n\nconst clear = () => {\n if (props.clearable) {\n model.value = \"\";\n }\n};\n\nconst validationData = useValidation(model, props.rules || []);\n\nconst isEmpty = computed(() => model.value === \"\");\n\nconst nonEmpty = computed(() => !isEmpty.value);\n\nconst displayErrors = computed(() => {\n const errors: string[] = [];\n const propsError = getErrorMessage(props.error);\n if (propsError) {\n errors.push(propsError);\n }\n if (!validationData.value.isValid) {\n errors.push(...validationData.value.errors);\n }\n return errors;\n});\n\nconst hasErrors = computed(() => displayErrors.value.length > 0);\n\nconst canShowClearable = computed(\n () => props.clearable && nonEmpty.value && props.type !== \"password\" && !props.disabled,\n);\n\nconst togglePasswordVisibility = () => (showPassword.value = !showPassword.value);\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nuseLabelNotch(rootRef);\n</script>\n\n<template>\n <div class=\"pl-text-field__envelope\">\n <div\n ref=\"rootRef\"\n class=\"pl-text-field\"\n :class=\"{\n error: hasErrors,\n disabled,\n dashed,\n nonEmpty,\n }\"\n >\n <label v-if=\"label\" ref=\"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 <div v-if=\"prefix\" class=\"pl-text-field__prefix\">\n {{ prefix }}\n </div>\n <input\n ref=\"inputRef\"\n v-model=\"model\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder || '...'\"\n :type=\"fieldType\"\n spellcheck=\"false\"\n />\n <div class=\"pl-text-field__append\" @click=\"setFocusOnInput\">\n <PlIcon16\n v-if=\"canShowClearable\"\n class=\"pl-text-field__clearable\"\n name=\"delete-clear\"\n @click.stop=\"clear\"\n />\n <PlIcon24\n v-if=\"type === 'password'\"\n :name=\"passwordIcon\"\n style=\"cursor: pointer\"\n @click.stop=\"togglePasswordVisibility\"\n />\n <slot name=\"append\" />\n </div>\n <DoubleContour class=\"pl-text-field__contour\" :group-position=\"groupPosition\" />\n </div>\n <div v-if=\"hasErrors\" class=\"pl-text-field__error\">\n {{ displayErrors.join(\" \") }}\n </div>\n <div v-else-if=\"helper\" class=\"pl-text-field__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKE,MAAM;;;;;;;;;;;;;;;;;;;;EAiBR,IAAM,IAAQ,GAAU,EAKlB,IAAQ,EAAmB,GAAA,aAE/B,EAEI,IAAQ,GA4DR,IAAU,EAAkC,KAAA,EAAU,EAEtD,IAAW,GAAmC,EAE9C,IAAe,EAAI,GAAM,EAEzB,IAAY,QACZ,EAAM,QAAQ,EAAM,SAAS,aACxB,EAAa,QAAQ,SAAS,EAAM,OAEpC,OAET,EAEI,IAAe,QAAgB,EAAa,QAAQ,cAAc,YAAa,EAE/E,UAAc;AAClB,GAAI,EAAM,cACR,EAAM,QAAQ;KAIZ,IAAiB,EAAc,GAAO,EAAM,SAAS,EAAE,CAAC,EAExD,IAAU,QAAe,EAAM,UAAU,GAAG,EAE5C,IAAW,QAAe,CAAC,EAAQ,MAAM,EAEzC,IAAgB,QAAe;GACnC,IAAM,IAAmB,EAAE,EACrB,IAAa,EAAgB,EAAM,MAAM;AAO/C,UANI,KACF,EAAO,KAAK,EAAW,EAEpB,EAAe,MAAM,WACxB,EAAO,KAAK,GAAG,EAAe,MAAM,OAAO,EAEtC;IACP,EAEI,IAAY,QAAe,EAAc,MAAM,SAAS,EAAE,EAE1D,IAAmB,QACjB,EAAM,aAAa,EAAS,SAAS,EAAM,SAAS,cAAc,CAAC,EAAM,SAChF,EAEK,UAAkC,EAAa,QAAQ,CAAC,EAAa,OAErE,UAAwB,EAAS,OAAO,OAAO;SAErD,EAAc,EAAQ,kBAIpB,EAoDM,OApDN,GAoDM,CAnDJ,EA8CM,OAAA;YA7CA;GAAJ,KAAI;GACJ,OAAK,EAAA,CAAC,iBAAe;WACI,EAAA;cAAmB,EAAA;YAAkB,EAAA;cAAgB,EAAA;;;GAOjE,EAAA,SAAA,GAAA,EAAb,EAQQ,SARR,GAQQ;IAPO,EAAA,YAAA,GAAA,EAAb,EAA4C,EAAA,EAAA,EAAA;;KAApB,KAAK,EAAA,EAAW;;IACxC,EAAwB,QAAA,MAAA,EAAf,EAAA,MAAK,EAAA,EAAA;IACG,EAAA,EAAK,CAAC,WAAA,GAAA,EAAvB,EAIY,EAAA,EAAA,EAAA;;KAJoB,OAAM;KAAO,UAAS;;KACzC,SAAO,QACO,CAAvB,EAAuB,EAAA,QAAA,UAAA,CAAA,CAAA;;;;GAIlB,EAAA,UAAA,GAAA,EAAX,EAEM,OAFN,GAEM,EADD,EAAA,OAAM,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA;KAEX,EAOE,SAAA;aANI;IAAJ,KAAI;6CACU,QAAA;IACb,UAAU,EAAA;IACV,aAAa,EAAA,eAAW;IACxB,MAAM,EAAA;IACP,YAAW;wBAJF,EAAA,MAAK,CAAA,CAAA;GAMhB,EAcM,OAAA;IAdD,OAAM;IAAyB,SAAO;;IAEjC,EAAA,SAAA,GAAA,EADR,EAKE,EAAA,EAAA,EAAA;;KAHA,OAAM;KACN,MAAK;KACJ,SAAK,EAAO,GAAK,CAAA,OAAA,CAAA;;IAGZ,EAAA,SAAI,cAAA,GAAA,EADZ,EAKE,EAAA,EAAA,EAAA;;KAHC,MAAM,EAAA;KACP,OAAA,EAAA,QAAA,WAAuB;KACtB,SAAK,EAAO,GAAwB,CAAA,OAAA,CAAA;;IAEvC,EAAsB,EAAA,QAAA,SAAA;;GAExB,EAAgF,GAAA;IAAjE,OAAM;IAA0B,kBAAgB,EAAA;;SAEtD,EAAA,SAAA,GAAA,EAAX,EAEM,OAFN,GAEM,EADD,EAAA,MAAc,KAAI,IAAA,CAAA,EAAA,EAAA,IAEP,EAAA,UAAA,GAAA,EAAhB,EAAwE,OAAxE,GAAwE,EAAf,EAAA,OAAM,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA,CAAA,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/uikit",
3
- "version": "2.10.41",
3
+ "version": "2.10.43",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -31,8 +31,8 @@
31
31
  "resize-observer-polyfill": "^1.5.1",
32
32
  "sortablejs": "^1.15.6",
33
33
  "vue": "^3.5.24",
34
- "@platforma-sdk/model": "1.58.11",
35
- "@milaboratories/helpers": "1.13.6"
34
+ "@milaboratories/helpers": "1.13.7",
35
+ "@platforma-sdk/model": "1.58.22"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@vitest/coverage-istanbul": "^4.0.18",
@@ -7,9 +7,8 @@ export default {
7
7
  };
8
8
  </script>
9
9
 
10
- <script lang="ts" setup generic="M, E = string, C = E">
11
- import type { Equal } from "@milaboratories/helpers";
12
- import { computed, reactive, ref, useSlots } from "vue";
10
+ <script lang="ts" setup>
11
+ import { computed, ref, useSlots } from "vue";
13
12
  import SvgRequired from "../../assets/images/required.svg?raw";
14
13
  import { getErrorMessage } from "../../helpers/error.ts";
15
14
  import DoubleContour from "../../utils/DoubleContour.vue";
@@ -23,13 +22,11 @@ import "./pl-text-field.scss";
23
22
 
24
23
  const slots = useSlots();
25
24
 
26
- type Model = Equal<M, E | C> extends true ? M : never; // basically in === out
27
-
28
25
  /**
29
26
  * The current value of the input field.
30
27
  */
31
- const model = defineModel<Model>({
32
- required: true,
28
+ const model = defineModel<string>({
29
+ default: "",
33
30
  });
34
31
 
35
32
  const props = defineProps<{
@@ -39,14 +36,8 @@ const props = defineProps<{
39
36
  label?: string;
40
37
  /**
41
38
  * If `true`, a clear icon will appear in the input field to clear the value (set it to empty string).
42
- * Or you can pass a callback that returns a custom "empty" value (null | undefined | string)
43
- */
44
- clearable?: boolean | (() => C);
45
- /**
46
- * An optional callback to parse and/or cast the value, the return type overrides the model type.
47
- * The callback must throw an exception if the value is invalid
48
39
  */
49
- parse?: (v: string) => E;
40
+ clearable?: boolean;
50
41
  /**
51
42
  * If `true`, the input field is marked as required.
52
43
  */
@@ -104,35 +95,6 @@ const inputRef = ref<HTMLInputElement | undefined>();
104
95
 
105
96
  const showPassword = ref(false);
106
97
 
107
- const data = reactive({
108
- cached: undefined as { error: string; value: string } | undefined,
109
- });
110
-
111
- const valueRef = computed<string>({
112
- get() {
113
- if (data.cached) {
114
- return data.cached.value;
115
- }
116
- return model.value === undefined || model.value === null ? "" : String(model.value);
117
- },
118
- set(value) {
119
- data.cached = undefined;
120
-
121
- if (props.parse) {
122
- try {
123
- model.value = props.parse(value) as Model;
124
- } catch (err) {
125
- data.cached = {
126
- error: err instanceof Error ? err.message : String(err),
127
- value,
128
- };
129
- }
130
- } else {
131
- model.value = value as Model;
132
- }
133
- },
134
- });
135
-
136
98
  const fieldType = computed(() => {
137
99
  if (props.type && props.type === "password") {
138
100
  return showPassword.value ? "text" : props.type;
@@ -145,20 +107,13 @@ const passwordIcon = computed(() => (showPassword.value ? "view-show" : "view-hi
145
107
 
146
108
  const clear = () => {
147
109
  if (props.clearable) {
148
- data.cached = undefined;
149
- model.value = props.clearable === true ? ("" as Model) : (props.clearable() as Model);
110
+ model.value = "";
150
111
  }
151
112
  };
152
113
 
153
- const validationData = useValidation(valueRef, props.rules || []);
114
+ const validationData = useValidation(model, props.rules || []);
154
115
 
155
- const isEmpty = computed(() => {
156
- if (props.clearable) {
157
- return props.clearable === true ? model.value === "" : model.value === props.clearable();
158
- }
159
-
160
- return model.value === "";
161
- });
116
+ const isEmpty = computed(() => model.value === "");
162
117
 
163
118
  const nonEmpty = computed(() => !isEmpty.value);
164
119
 
@@ -168,9 +123,6 @@ const displayErrors = computed(() => {
168
123
  if (propsError) {
169
124
  errors.push(propsError);
170
125
  }
171
- if (data.cached) {
172
- errors.push(data.cached.error);
173
- }
174
126
  if (!validationData.value.isValid) {
175
127
  errors.push(...validationData.value.errors);
176
128
  }
@@ -185,10 +137,6 @@ const canShowClearable = computed(
185
137
 
186
138
  const togglePasswordVisibility = () => (showPassword.value = !showPassword.value);
187
139
 
188
- const onFocusOut = () => {
189
- data.cached = undefined;
190
- };
191
-
192
140
  const setFocusOnInput = () => inputRef.value?.focus();
193
141
 
194
142
  useLabelNotch(rootRef);
@@ -220,12 +168,11 @@ useLabelNotch(rootRef);
220
168
  </div>
221
169
  <input
222
170
  ref="inputRef"
223
- v-model="valueRef"
171
+ v-model="model"
224
172
  :disabled="disabled"
225
173
  :placeholder="placeholder || '...'"
226
174
  :type="fieldType"
227
175
  spellcheck="false"
228
- @focusout="onFocusOut"
229
176
  />
230
177
  <div class="pl-text-field__append" @click="setFocusOnInput">
231
178
  <PlIcon16
@@ -15,7 +15,7 @@ describe("TextField", () => {
15
15
  });
16
16
 
17
17
  it("modelValue:string", async () => {
18
- const wrapper = mount(PlTextField<string>, {
18
+ const wrapper = mount(PlTextField, {
19
19
  props: {
20
20
  modelValue: "initialText",
21
21
  "onUpdate:modelValue": (e: string) => wrapper.setProps({ modelValue: e }),
@@ -30,8 +30,8 @@ describe("TextField", () => {
30
30
  const wrapper = mount(PlTextField, {
31
31
  props: {
32
32
  modelValue: "initialText" as string | undefined,
33
- clearable: () => undefined,
34
- "onUpdate:modelValue": (e: unknown) => wrapper.setProps({ modelValue: e }),
33
+ clearable: true,
34
+ "onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
35
35
  },
36
36
  });
37
37