@leaflink/stash 50.0.4 → 50.0.6

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/dist/Field.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as f } from "./Field.vue_vue_type_script_setup_true_lang-DjxUvSRF.js";
1
+ import { _ as f } from "./Field.vue_vue_type_script_setup_true_lang--tBfZB2K.js";
2
2
  export {
3
3
  f as default
4
4
  };
@@ -71,6 +71,8 @@ showOptionalInLabel: boolean;
71
71
  fieldErrorId: string;
72
72
  hasError: boolean;
73
73
  isRequired: boolean;
74
+ isReadOnly: boolean;
75
+ disabled: boolean;
74
76
  labelId: string;
75
77
  showOptionalInLabel: boolean;
76
78
  }): any;
@@ -0,0 +1,85 @@
1
+ import { defineComponent as I, useAttrs as B, useSlots as T, computed as t, openBlock as a, createBlock as c, resolveDynamicComponent as O, mergeProps as R, unref as d, withCtx as m, createTextVNode as k, toDisplayString as o, createCommentVNode as w, renderSlot as b, createElementBlock as r } from "vue";
2
+ import i from "lodash-es/uniqueId";
3
+ import { _ as q } from "./Label.vue_vue_type_script_setup_true_lang-C4JKdqvC.js";
4
+ const E = ["id"], S = {
5
+ key: 2,
6
+ class: "stash-field-hint tw-mt-1 tw-block tw-whitespace-pre-line tw-text-xs",
7
+ "data-test": "stash-field-hint"
8
+ }, g = {
9
+ key: 3,
10
+ class: "stash-field-hint tw-mt-1 tw-whitespace-pre-line tw-text-xs",
11
+ "data-test": "stash-field-hint"
12
+ }, $ = /* @__PURE__ */ I({
13
+ inheritAttrs: !1,
14
+ __name: "Field",
15
+ props: {
16
+ addBottomSpace: { type: Boolean, default: !1 },
17
+ errorText: { default: void 0 },
18
+ hintText: { default: void 0 },
19
+ id: { default: void 0 },
20
+ errorId: { default: void 0 },
21
+ isReadOnly: { type: Boolean },
22
+ isRequired: { type: Boolean, default: !1 },
23
+ label: { default: void 0 },
24
+ showOptionalInLabel: { type: Boolean, default: !1 },
25
+ fieldset: { type: Boolean, default: !1 },
26
+ disabled: { type: Boolean, default: !1 }
27
+ },
28
+ setup(y) {
29
+ const e = y, v = B(), l = T(), n = t(() => e.id || i("stash-field-")), f = t(() => e.errorId || i("stash-field-error-")), h = t(() => i("stash-field-label-")), p = t(() => !!e.errorText), x = t(() => e.fieldset ? "fieldset" : "div"), _ = t(() => {
30
+ const { placeholder: s, ...u } = v;
31
+ return u;
32
+ });
33
+ return (s, u) => (a(), c(O(x.value), R({
34
+ "data-test": "stash-field",
35
+ class: ["stash-field", [
36
+ { "tw-p-0": e.fieldset },
37
+ { "tw-mb-9": e.addBottomSpace && !e.errorText && !e.hintText && !d(l).hint },
38
+ { "tw-mb-4": e.addBottomSpace && (e.errorText || e.hintText || d(l).hint) },
39
+ { "stash-field--disabled": e.disabled },
40
+ { "stash-field--is-read-only": e.isReadOnly }
41
+ ]]
42
+ }, _.value), {
43
+ default: m(() => [
44
+ e.label ? (a(), c(q, {
45
+ key: 0,
46
+ id: h.value,
47
+ for: n.value,
48
+ "has-error": p.value,
49
+ "is-required": s.isRequired,
50
+ "show-optional": e.showOptionalInLabel,
51
+ legend: e.fieldset,
52
+ disabled: e.disabled
53
+ }, {
54
+ default: m(() => [
55
+ k(o(e.label), 1)
56
+ ]),
57
+ _: 1
58
+ }, 8, ["id", "for", "has-error", "is-required", "show-optional", "legend", "disabled"])) : w("", !0),
59
+ b(s.$slots, "default", {
60
+ fieldId: n.value,
61
+ fieldErrorId: f.value,
62
+ hasError: p.value,
63
+ isRequired: s.isRequired,
64
+ isReadOnly: e.isReadOnly,
65
+ disabled: e.disabled,
66
+ labelId: h.value,
67
+ showOptionalInLabel: e.showOptionalInLabel
68
+ }),
69
+ e.errorText ? (a(), r("span", {
70
+ key: 1,
71
+ id: f.value,
72
+ class: "stash-field-error tw-mt-1 tw-block tw-whitespace-pre-line tw-text-xs tw-text-red-500",
73
+ "data-test": "stash-field-error"
74
+ }, o(e.errorText), 9, E)) : e.hintText && !e.isReadOnly ? (a(), r("span", S, o(e.hintText), 1)) : d(l).hint && !e.isReadOnly ? (a(), r("div", g, [
75
+ b(s.$slots, "hint")
76
+ ])) : w("", !0)
77
+ ]),
78
+ _: 3
79
+ }, 16, ["class"]));
80
+ }
81
+ });
82
+ export {
83
+ $ as _
84
+ };
85
+ //# sourceMappingURL=Field.vue_vue_type_script_setup_true_lang--tBfZB2K.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Field.vue_vue_type_script_setup_true_lang-DjxUvSRF.js","sources":["../src/components/Field/Field.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, useAttrs, useSlots } from 'vue';\n\n import Label from '../Label/Label.vue';\n\n defineOptions({\n inheritAttrs: false,\n });\n\n export interface FieldProps {\n /**\n * Adds spacing under the field that is consistent whether hint/error text is displayed.\n */\n addBottomSpace?: boolean;\n\n /**\n * Error text to display. Replaces `hintText` (if provided) & adds error styling.\n */\n errorText?: string;\n\n /**\n * Displays text below the input; hidden when the isReadOnly prop is truthy.\n */\n hintText?: string;\n\n /**\n * ID for the Label and Input; must be unique\n */\n id?: string;\n\n /**\n * ID for the error text element; useful for aria-errormessage\n */\n errorId?: string;\n\n /**\n * Whether it's a readonly field.\n */\n isReadOnly?: boolean;\n\n /**\n * Whether the field is required.\n */\n isRequired?: boolean;\n\n /**\n * Label to render above the input.\n */\n label?: string;\n\n /**\n * Show \"(optional)\" to the right of the label text\n */\n showOptionalInLabel?: boolean;\n\n /**\n * Indicates wheter the field is a fieldset or not\n */\n fieldset?: boolean;\n\n /**\n * Indicates whether the field is disabled.\n */\n disabled?: boolean;\n }\n\n const props = withDefaults(defineProps<FieldProps>(), {\n addBottomSpace: false,\n errorText: undefined,\n hintText: undefined,\n id: undefined,\n errorId: undefined,\n isRequired: false,\n label: undefined,\n showOptionalInLabel: false,\n fieldset: false,\n disabled: false,\n });\n const attrs = useAttrs();\n const slots = useSlots();\n const fieldId = computed(() => props.id || uniqueId('stash-field-'));\n const fieldErrorId = computed(() => props.errorId || uniqueId('stash-field-error-'));\n const labelId = computed(() => uniqueId('stash-field-label-'));\n const hasError = computed(() => !!props.errorText);\n const wrapperElement = computed(() => (props.fieldset ? 'fieldset' : 'div'));\n\n // Any attributes that are unique to form elements, you want to exclude from\n // being bound from the root element.\n const rootAttrs = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { placeholder, ...otherAttrs } = attrs;\n\n return otherAttrs;\n });\n</script>\n\n<template>\n <component\n :is=\"wrapperElement\"\n data-test=\"stash-field\"\n class=\"stash-field\"\n :class=\"[\n { 'tw-p-0': props.fieldset },\n { 'tw-mb-9': props.addBottomSpace && !props.errorText && !props.hintText && !slots.hint },\n { 'tw-mb-4': props.addBottomSpace && (props.errorText || props.hintText || slots.hint) },\n { 'stash-field--disabled': props.disabled },\n ]\"\n v-bind=\"rootAttrs\"\n >\n <Label\n v-if=\"props.label\"\n :id=\"labelId\"\n :for=\"fieldId\"\n :has-error=\"hasError\"\n :is-required=\"isRequired\"\n :show-optional=\"props.showOptionalInLabel\"\n :legend=\"props.fieldset\"\n :disabled=\"props.disabled\"\n >\n {{ props.label }}\n </Label>\n\n <!-- @slot for the form field; the Label can also be rendered here instead of using the label prop -->\n <template v-if=\"props.isReadOnly\">\n <div :aria-labelledby=\"labelId\">\n <slot\n :field-id=\"fieldId\"\n :field-error-id=\"fieldErrorId\"\n :has-error=\"hasError\"\n :is-required=\"isRequired\"\n :label-id=\"labelId\"\n :show-optional-in-label=\"props.showOptionalInLabel\"\n ></slot>\n </div>\n </template>\n <template v-else>\n <slot\n :field-id=\"fieldId\"\n :field-error-id=\"fieldErrorId\"\n :has-error=\"hasError\"\n :is-required=\"isRequired\"\n :label-id=\"labelId\"\n :show-optional-in-label=\"props.showOptionalInLabel\"\n ></slot>\n </template>\n\n <span\n v-if=\"props.errorText\"\n :id=\"fieldErrorId\"\n class=\"stash-field-error tw-mt-1 tw-block tw-whitespace-pre-line tw-text-xs tw-text-red-500\"\n data-test=\"stash-field-error\"\n >\n {{ props.errorText }}\n </span>\n\n <span\n v-else-if=\"props.hintText && !props.isReadOnly\"\n class=\"stash-field-hint tw-mt-1 tw-block tw-whitespace-pre-line tw-text-xs\"\n data-test=\"stash-field-hint\"\n >\n {{ props.hintText }}\n </span>\n\n <div\n v-else-if=\"slots.hint && !props.isReadOnly\"\n class=\"stash-field-hint tw-mt-1 tw-whitespace-pre-line tw-text-xs\"\n data-test=\"stash-field-hint\"\n >\n <!-- @slot for displaying hint text below the field -->\n <slot name=\"hint\"></slot>\n </div>\n </component>\n</template>\n"],"names":["props","__props","attrs","useAttrs","slots","useSlots","fieldId","computed","uniqueId","fieldErrorId","labelId","hasError","wrapperElement","rootAttrs","placeholder","otherAttrs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEE,UAAMA,IAAQC,GAYRC,IAAQC,KACRC,IAAQC,KACRC,IAAUC,EAAS,MAAMP,EAAM,MAAMQ,EAAS,cAAc,CAAC,GAC7DC,IAAeF,EAAS,MAAMP,EAAM,WAAWQ,EAAS,oBAAoB,CAAC,GAC7EE,IAAUH,EAAS,MAAMC,EAAS,oBAAoB,CAAC,GACvDG,IAAWJ,EAAS,MAAM,CAAC,CAACP,EAAM,SAAS,GAC3CY,IAAiBL,EAAS,MAAOP,EAAM,WAAW,aAAa,KAAM,GAIrEa,IAAYN,EAAS,MAAM;AAE/B,YAAM,EAAE,aAAAO,GAAa,GAAGC,EAAA,IAAeb;AAEhC,aAAAa;AAAA,IAAA,CACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Field.vue_vue_type_script_setup_true_lang--tBfZB2K.js","sources":["../src/components/Field/Field.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, useAttrs, useSlots } from 'vue';\n\n import Label from '../Label/Label.vue';\n\n defineOptions({\n inheritAttrs: false,\n });\n\n export interface FieldProps {\n /**\n * Adds spacing under the field that is consistent whether hint/error text is displayed.\n */\n addBottomSpace?: boolean;\n\n /**\n * Error text to display. Replaces `hintText` (if provided) & adds error styling.\n */\n errorText?: string;\n\n /**\n * Displays text below the input; hidden when the isReadOnly prop is truthy.\n */\n hintText?: string;\n\n /**\n * ID for the Label and Input; must be unique\n */\n id?: string;\n\n /**\n * ID for the error text element; useful for aria-errormessage\n */\n errorId?: string;\n\n /**\n * Whether it's a readonly field.\n */\n isReadOnly?: boolean;\n\n /**\n * Whether the field is required.\n */\n isRequired?: boolean;\n\n /**\n * Label to render above the input.\n */\n label?: string;\n\n /**\n * Show \"(optional)\" to the right of the label text\n */\n showOptionalInLabel?: boolean;\n\n /**\n * Indicates wheter the field is a fieldset or not\n */\n fieldset?: boolean;\n\n /**\n * Indicates whether the field is disabled.\n */\n disabled?: boolean;\n }\n\n const props = withDefaults(defineProps<FieldProps>(), {\n addBottomSpace: false,\n errorText: undefined,\n hintText: undefined,\n id: undefined,\n errorId: undefined,\n isRequired: false,\n label: undefined,\n showOptionalInLabel: false,\n fieldset: false,\n disabled: false,\n });\n const attrs = useAttrs();\n const slots = useSlots();\n const fieldId = computed(() => props.id || uniqueId('stash-field-'));\n const fieldErrorId = computed(() => props.errorId || uniqueId('stash-field-error-'));\n const labelId = computed(() => uniqueId('stash-field-label-'));\n const hasError = computed(() => !!props.errorText);\n const wrapperElement = computed(() => (props.fieldset ? 'fieldset' : 'div'));\n\n // Any attributes that are unique to form elements, you want to exclude from\n // being bound from the root element.\n const rootAttrs = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { placeholder, ...otherAttrs } = attrs;\n\n return otherAttrs;\n });\n</script>\n\n<template>\n <component\n :is=\"wrapperElement\"\n data-test=\"stash-field\"\n class=\"stash-field\"\n :class=\"[\n { 'tw-p-0': props.fieldset },\n { 'tw-mb-9': props.addBottomSpace && !props.errorText && !props.hintText && !slots.hint },\n { 'tw-mb-4': props.addBottomSpace && (props.errorText || props.hintText || slots.hint) },\n { 'stash-field--disabled': props.disabled },\n { 'stash-field--is-read-only': props.isReadOnly },\n ]\"\n v-bind=\"rootAttrs\"\n >\n <Label\n v-if=\"props.label\"\n :id=\"labelId\"\n :for=\"fieldId\"\n :has-error=\"hasError\"\n :is-required=\"isRequired\"\n :show-optional=\"props.showOptionalInLabel\"\n :legend=\"props.fieldset\"\n :disabled=\"props.disabled\"\n >\n {{ props.label }}\n </Label>\n\n <!-- @slot for the form field; the Label can also be rendered here instead of using the label prop -->\n <slot\n :field-id=\"fieldId\"\n :field-error-id=\"fieldErrorId\"\n :has-error=\"hasError\"\n :is-required=\"isRequired\"\n :is-read-only=\"props.isReadOnly\"\n :disabled=\"props.disabled\"\n :label-id=\"labelId\"\n :show-optional-in-label=\"props.showOptionalInLabel\"\n ></slot>\n\n <span\n v-if=\"props.errorText\"\n :id=\"fieldErrorId\"\n class=\"stash-field-error tw-mt-1 tw-block tw-whitespace-pre-line tw-text-xs tw-text-red-500\"\n data-test=\"stash-field-error\"\n >\n {{ props.errorText }}\n </span>\n\n <span\n v-else-if=\"props.hintText && !props.isReadOnly\"\n class=\"stash-field-hint tw-mt-1 tw-block tw-whitespace-pre-line tw-text-xs\"\n data-test=\"stash-field-hint\"\n >\n {{ props.hintText }}\n </span>\n\n <div\n v-else-if=\"slots.hint && !props.isReadOnly\"\n class=\"stash-field-hint tw-mt-1 tw-whitespace-pre-line tw-text-xs\"\n data-test=\"stash-field-hint\"\n >\n <!-- @slot for displaying hint text below the field -->\n <slot name=\"hint\"></slot>\n </div>\n </component>\n</template>\n"],"names":["props","__props","attrs","useAttrs","slots","useSlots","fieldId","computed","uniqueId","fieldErrorId","labelId","hasError","wrapperElement","rootAttrs","placeholder","otherAttrs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEE,UAAMA,IAAQC,GAYRC,IAAQC,KACRC,IAAQC,KACRC,IAAUC,EAAS,MAAMP,EAAM,MAAMQ,EAAS,cAAc,CAAC,GAC7DC,IAAeF,EAAS,MAAMP,EAAM,WAAWQ,EAAS,oBAAoB,CAAC,GAC7EE,IAAUH,EAAS,MAAMC,EAAS,oBAAoB,CAAC,GACvDG,IAAWJ,EAAS,MAAM,CAAC,CAACP,EAAM,SAAS,GAC3CY,IAAiBL,EAAS,MAAOP,EAAM,WAAW,aAAa,KAAM,GAIrEa,IAAYN,EAAS,MAAM;AAE/B,YAAM,EAAE,aAAAO,GAAa,GAAGC,EAAA,IAAeb;AAEhC,aAAAa;AAAA,IAAA,CACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as $, computed as p, openBlock as u, createBlock as C, withCtx as i, createElementVNode as s, createElementBlock as d, withDirectives as f, vModelCheckbox as v, createVNode as _, withKeys as h, createTextVNode as b, toDisplayString as x, unref as A, createCommentVNode as B, Fragment as E, renderList as K } from "vue";
2
2
  import { t as N } from "./locale.js";
3
- import { _ as F } from "./Field.vue_vue_type_script_setup_true_lang-DjxUvSRF.js";
3
+ import { _ as F } from "./Field.vue_vue_type_script_setup_true_lang--tBfZB2K.js";
4
4
  import y from "./FilterChip.js";
5
5
  const D = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, O = ["id"], U = ["for"], I = ["id", "value"], L = ["for"], z = /* @__PURE__ */ $({
6
6
  __name: "FilterSelect",
@@ -515,6 +515,10 @@ hintText: {
515
515
  type: PropType<string>;
516
516
  default: undefined;
517
517
  };
518
+ isReadOnly: {
519
+ type: PropType<boolean>;
520
+ default: boolean;
521
+ };
518
522
  showOptionalInLabel: {
519
523
  type: PropType<boolean>;
520
524
  };
@@ -553,6 +557,7 @@ label: string;
553
557
  id: string;
554
558
  errorText: string;
555
559
  hintText: string;
560
+ isReadOnly: boolean;
556
561
  placeholder: string;
557
562
  modelValue: string | number;
558
563
  value: string | number | null;
@@ -592,6 +597,10 @@ hintText: {
592
597
  type: PropType<string>;
593
598
  default: undefined;
594
599
  };
600
+ isReadOnly: {
601
+ type: PropType<boolean>;
602
+ default: boolean;
603
+ };
595
604
  showOptionalInLabel: {
596
605
  type: PropType<boolean>;
597
606
  };
@@ -625,6 +634,7 @@ label: string;
625
634
  id: string;
626
635
  errorText: string;
627
636
  hintText: string;
637
+ isReadOnly: boolean;
628
638
  placeholder: string;
629
639
  modelValue: string | number;
630
640
  value: string | number | null;
@@ -661,6 +671,10 @@ hintText: {
661
671
  type: PropType<string>;
662
672
  default: undefined;
663
673
  };
674
+ isReadOnly: {
675
+ type: PropType<boolean>;
676
+ default: boolean;
677
+ };
664
678
  showOptionalInLabel: {
665
679
  type: PropType<boolean>;
666
680
  };
@@ -699,6 +713,7 @@ label: string;
699
713
  id: string;
700
714
  errorText: string;
701
715
  hintText: string;
716
+ isReadOnly: boolean;
702
717
  placeholder: string;
703
718
  modelValue: string | number;
704
719
  value: string | number | null;
@@ -732,6 +747,10 @@ hintText: {
732
747
  type: PropType<string>;
733
748
  default: undefined;
734
749
  };
750
+ isReadOnly: {
751
+ type: PropType<boolean>;
752
+ default: boolean;
753
+ };
735
754
  placeholder: {
736
755
  type: PropType<string>;
737
756
  default: undefined;
@@ -786,6 +805,7 @@ disabled: boolean;
786
805
  label: string;
787
806
  errorText: string;
788
807
  hintText: string;
808
+ isReadOnly: boolean;
789
809
  placeholder: string;
790
810
  options: any[];
791
811
  modelValue: {
@@ -821,6 +841,10 @@ hintText: {
821
841
  type: PropType<string>;
822
842
  default: undefined;
823
843
  };
844
+ isReadOnly: {
845
+ type: PropType<boolean>;
846
+ default: boolean;
847
+ };
824
848
  placeholder: {
825
849
  type: PropType<string>;
826
850
  default: undefined;
@@ -862,6 +886,7 @@ disabled: boolean;
862
886
  label: string;
863
887
  errorText: string;
864
888
  hintText: string;
889
+ isReadOnly: boolean;
865
890
  placeholder: string;
866
891
  options: any[];
867
892
  modelValue: {
@@ -894,6 +919,10 @@ hintText: {
894
919
  type: PropType<string>;
895
920
  default: undefined;
896
921
  };
922
+ isReadOnly: {
923
+ type: PropType<boolean>;
924
+ default: boolean;
925
+ };
897
926
  placeholder: {
898
927
  type: PropType<string>;
899
928
  default: undefined;
@@ -948,6 +977,7 @@ disabled: boolean;
948
977
  label: string;
949
978
  errorText: string;
950
979
  hintText: string;
980
+ isReadOnly: boolean;
951
981
  placeholder: string;
952
982
  options: any[];
953
983
  modelValue: {
@@ -1059,6 +1089,9 @@ hintText: {
1059
1089
  type: PropType<string>;
1060
1090
  default: string;
1061
1091
  };
1092
+ isReadOnly: {
1093
+ type: PropType<boolean>;
1094
+ };
1062
1095
  showOptionalInLabel: {
1063
1096
  type: PropType<boolean>;
1064
1097
  default: boolean;
@@ -1267,6 +1300,9 @@ hintText: {
1267
1300
  type: PropType<string>;
1268
1301
  default: string;
1269
1302
  };
1303
+ isReadOnly: {
1304
+ type: PropType<boolean>;
1305
+ };
1270
1306
  showOptionalInLabel: {
1271
1307
  type: PropType<boolean>;
1272
1308
  default: boolean;
@@ -1465,6 +1501,9 @@ hintText: {
1465
1501
  type: PropType<string>;
1466
1502
  default: string;
1467
1503
  };
1504
+ isReadOnly: {
1505
+ type: PropType<boolean>;
1506
+ };
1468
1507
  showOptionalInLabel: {
1469
1508
  type: PropType<boolean>;
1470
1509
  default: boolean;
package/dist/Input.js CHANGED
@@ -1,10 +1,10 @@
1
- import { defineComponent as U, useSlots as G, useCssModule as L, useAttrs as O, ref as f, computed as v, watchEffect as W, onMounted as j, openBlock as m, createBlock as V, mergeProps as k, unref as l, createSlots as q, withCtx as N, createElementVNode as x, withDirectives as H, vModelDynamic as J, createElementBlock as B, normalizeClass as y, renderSlot as h, createCommentVNode as C } from "vue";
2
- import I from "lodash-es/isNil";
3
- import { convertDecimal as $, sanitizeDecimal as K, decimalSeparator as b } from "./utils/i18n.js";
4
- import { _ as Q } from "./Field.vue_vue_type_script_setup_true_lang-DjxUvSRF.js";
5
- import R from "./Icon.js";
6
- import { _ as X } from "./_plugin-vue_export-helper-CHgC5LLL.js";
7
- const Y = { class: "tw-relative" }, Z = ["id", "aria-errormessage", "aria-invalid", "autocomplete", "placeholder", "type", "disabled"], ee = /* @__PURE__ */ U({
1
+ import { defineComponent as P, useSlots as U, useCssModule as G, useAttrs as L, ref as v, computed as c, watchEffect as W, onMounted as j, openBlock as f, createBlock as k, mergeProps as N, unref as l, createSlots as q, withCtx as x, createElementVNode as B, withDirectives as H, vModelDynamic as J, createElementBlock as C, normalizeClass as y, renderSlot as h, createCommentVNode as I } from "vue";
2
+ import $ from "lodash-es/isNil";
3
+ import { convertDecimal as E, sanitizeDecimal as K, decimalSeparator as b } from "./utils/i18n.js";
4
+ import { _ as Q } from "./Field.vue_vue_type_script_setup_true_lang--tBfZB2K.js";
5
+ import X from "./Icon.js";
6
+ import { _ as Y } from "./_plugin-vue_export-helper-CHgC5LLL.js";
7
+ const Z = { class: "tw-relative" }, ee = ["id", "aria-errormessage", "aria-invalid", "autocomplete", "placeholder", "type", "disabled", "readonly"], te = /* @__PURE__ */ P({
8
8
  name: "ll-input",
9
9
  inheritAttrs: !1,
10
10
  __name: "Input",
@@ -20,128 +20,131 @@ const Y = { class: "tw-relative" }, Z = ["id", "aria-errormessage", "aria-invali
20
20
  value: { default: null },
21
21
  type: { default: "text" },
22
22
  placeholder: { default: void 0 },
23
- disabled: { type: Boolean, default: !1 }
23
+ disabled: { type: Boolean, default: !1 },
24
+ isReadOnly: { type: Boolean, default: !1 }
24
25
  },
25
26
  emits: ["update:model-value", "change", "focus", "blur"],
26
- setup(E, { expose: S, emit: D }) {
27
- const t = E, i = D, r = G(), s = L(), c = O(), _ = f();
28
- S({ inputEl: _ });
29
- const n = f(t.modelValue);
30
- t.type === "number" && (t.modelValue || t.modelValue === 0) && (n.value = $(t.modelValue, b));
31
- const p = f(!1), d = v(() => t.type === "number"), M = v(() => {
32
- const o = { ...c };
27
+ setup(S, { expose: D, emit: M }) {
28
+ const e = S, m = M, r = U(), n = G(), p = L(), _ = v();
29
+ D({ inputEl: _ });
30
+ const s = v(e.modelValue);
31
+ e.type === "number" && (e.modelValue || e.modelValue === 0) && (s.value = E(e.modelValue, b));
32
+ const d = v(!1), g = c(() => e.isReadOnly || "readonly" in p && p.readonly !== !1), i = c(() => e.type === "number"), A = c(() => {
33
+ const o = { ...p };
33
34
  return delete o.class, o;
34
- }), A = v(() => d.value || t.type === "password" && p.value ? "text" : t.type);
35
+ }), F = c(() => i.value || e.type === "password" && d.value ? "text" : e.type);
35
36
  W(() => {
36
- n.value = g(t.modelValue);
37
+ s.value = V(e.modelValue);
37
38
  });
38
39
  function w(o = "", a = !1) {
39
- if (!d.value)
40
+ if (!i.value)
40
41
  return o;
41
- let e = o;
42
- if (I(e) || `${e}`.length === 0) return "";
43
- if (b !== "." && (e = $(e, ".")), a && (e === "." && (e = "0."), e.toString().startsWith("0.")))
44
- return e;
45
- if (!I(e) && `${e}`.length)
46
- e = Intl.NumberFormat("en-US", {
42
+ let t = o;
43
+ if ($(t) || `${t}`.length === 0) return "";
44
+ if (b !== "." && (t = E(t, ".")), a && (t === "." && (t = "0."), t.toString().startsWith("0.")))
45
+ return t;
46
+ if (!$(t) && `${t}`.length)
47
+ t = Intl.NumberFormat("en-US", {
47
48
  style: "decimal",
48
49
  maximumFractionDigits: 7,
49
50
  useGrouping: !1
50
- }).format(Number(e));
51
+ }).format(Number(t));
51
52
  else
52
53
  return "";
53
- return isNaN(Number(e)) ? "" : parseFloat(e);
54
+ return isNaN(Number(t)) ? "" : parseFloat(t);
54
55
  }
55
- function g(o) {
56
- return d.value ? K(o, b) : o;
56
+ function V(o) {
57
+ return i.value ? K(o, b) : o;
57
58
  }
58
- function F() {
59
- const o = d.value ? w(n.value) : n.value;
60
- i("change", o);
59
+ function O() {
60
+ const o = i.value ? w(s.value) : s.value;
61
+ m("change", o);
61
62
  }
62
63
  function T(o) {
63
64
  const a = o.target.value;
64
- n.value = g(a);
65
- const e = d.value ? w(n.value, !0) : a;
66
- i("update:model-value", e);
65
+ s.value = V(a);
66
+ const t = i.value ? w(s.value, !0) : a;
67
+ m("update:model-value", t);
67
68
  }
68
69
  return j(() => {
69
- if (t.value !== null)
70
+ if (e.value !== null)
70
71
  throw new Error("ll-input: use :model-value or v-model instead of :value.");
71
- if (c.onInput)
72
+ if (p.onInput)
72
73
  throw new Error("ll-input: use the @update:model-value event instead of @input");
73
- }), (o, a) => (m(), V(Q, k(t, {
74
- class: ["stash-input", [l(s).root, l(c).class]],
74
+ }), (o, a) => (f(), k(Q, N(e, {
75
+ "is-read-only": g.value,
76
+ class: ["stash-input", [l(n).root, l(p).class]],
75
77
  "data-test": "ll-input"
76
78
  }), q({
77
- default: N(({ fieldId: e, fieldErrorId: z, hasError: P }) => [
78
- x("div", Y, [
79
- H(x("input", k(M.value, {
80
- id: e,
79
+ default: x(({ fieldId: t, fieldErrorId: R, hasError: z }) => [
80
+ B("div", Z, [
81
+ H(B("input", N(A.value, {
82
+ id: t,
81
83
  ref_key: "inputEl",
82
84
  ref: _,
83
- "onUpdate:modelValue": a[0] || (a[0] = (u) => n.value = u),
84
- "aria-errormessage": z,
85
- "aria-invalid": P,
85
+ "onUpdate:modelValue": a[0] || (a[0] = (u) => s.value = u),
86
+ "aria-errormessage": R,
87
+ "aria-invalid": z,
86
88
  autocomplete: o.autocomplete,
87
- placeholder: t.placeholder,
89
+ placeholder: e.placeholder,
88
90
  class: [
89
- { [l(s)["input-prepended"]]: !!l(r).prepend },
90
- { [l(s)["input-appended"]]: !!l(r).append || t.type === "password" },
91
- { [l(s)["has-error"]]: !!t.errorText }
91
+ { [l(n)["input-prepended"]]: !!l(r).prepend },
92
+ { [l(n)["input-appended"]]: !!l(r).append || e.type === "password" },
93
+ { [l(n)["has-error"]]: !!e.errorText }
92
94
  ],
93
- type: A.value,
94
- disabled: t.disabled,
95
- onChange: F,
95
+ type: F.value,
96
+ disabled: e.disabled,
97
+ readonly: g.value,
98
+ onChange: O,
96
99
  onInput: T,
97
- onBlur: a[1] || (a[1] = (u) => i("blur", u)),
98
- onFocus: a[2] || (a[2] = (u) => i("focus", u))
99
- }), null, 16, Z), [
100
- [J, n.value]
100
+ onBlur: a[1] || (a[1] = (u) => m("blur", u)),
101
+ onFocus: a[2] || (a[2] = (u) => m("focus", u))
102
+ }), null, 16, ee), [
103
+ [J, s.value]
101
104
  ]),
102
- l(r).prepend ? (m(), B("div", {
105
+ l(r).prepend ? (f(), C("div", {
103
106
  key: 0,
104
- class: y(["stash-input-prepend font-semibold", [l(s).symbol, l(s)["symbol--prepend"]]])
107
+ class: y(["stash-input-prepend font-semibold", [l(n).symbol, l(n)["symbol--prepend"]]])
105
108
  }, [
106
109
  h(o.$slots, "prepend")
107
- ], 2)) : C("", !0),
108
- l(r).append || t.type === "password" ? (m(), B("div", {
110
+ ], 2)) : I("", !0),
111
+ l(r).append || e.type === "password" ? (f(), C("div", {
109
112
  key: 1,
110
- class: y(["stash-input-append font-semibold", [l(s).symbol, l(s)["symbol--append"]]])
113
+ class: y(["stash-input-append font-semibold", [l(n).symbol, l(n)["symbol--append"]]])
111
114
  }, [
112
- l(r).append ? h(o.$slots, "append", { key: 0 }) : (m(), V(R, {
115
+ l(r).append ? h(o.$slots, "append", { key: 0 }) : (f(), k(X, {
113
116
  key: 1,
114
- name: p.value ? "hide" : "show",
115
- class: y(["tw-cursor-pointer", { "tw-text-ice-500": t.disabled }]),
116
- "data-test": p.value ? "hide-password-icon" : "show-password-icon",
117
- onClick: a[3] || (a[3] = (u) => p.value = !p.value)
117
+ name: d.value ? "hide" : "show",
118
+ class: y(["tw-cursor-pointer", { "tw-text-ice-500": e.disabled }]),
119
+ "data-test": d.value ? "hide-password-icon" : "show-password-icon",
120
+ onClick: a[3] || (a[3] = (u) => d.value = !d.value)
118
121
  }, null, 8, ["name", "class", "data-test"]))
119
- ], 2)) : C("", !0)
122
+ ], 2)) : I("", !0)
120
123
  ])
121
124
  ]),
122
125
  _: 2
123
126
  }, [
124
127
  l(r).hint ? {
125
128
  name: "hint",
126
- fn: N(() => [
129
+ fn: x(() => [
127
130
  h(o.$slots, "hint")
128
131
  ]),
129
132
  key: "0"
130
133
  } : void 0
131
- ]), 1040, ["class"]));
134
+ ]), 1040, ["is-read-only", "class"]));
132
135
  }
133
- }), te = "_root_12641_2", oe = "_symbol_12641_46", le = {
134
- root: te,
135
- "has-error": "_has-error_12641_34",
136
- "input-prepended": "_input-prepended_12641_38",
137
- "input-appended": "_input-appended_12641_42",
138
- symbol: oe,
139
- "symbol--prepend": "_symbol--prepend_12641_57",
140
- "symbol--append": "_symbol--append_12641_63"
141
- }, ae = {
142
- $style: le
143
- }, ie = /* @__PURE__ */ X(ee, [["__cssModules", ae]]);
136
+ }), oe = "_root_1tgop_2", le = "_symbol_1tgop_46", ae = {
137
+ root: oe,
138
+ "has-error": "_has-error_1tgop_34",
139
+ "input-prepended": "_input-prepended_1tgop_38",
140
+ "input-appended": "_input-appended_1tgop_42",
141
+ symbol: le,
142
+ "symbol--prepend": "_symbol--prepend_1tgop_57",
143
+ "symbol--append": "_symbol--append_1tgop_63"
144
+ }, ne = {
145
+ $style: ae
146
+ }, me = /* @__PURE__ */ Y(te, [["__cssModules", ne]]);
144
147
  export {
145
- ie as default
148
+ me as default
146
149
  };
147
150
  //# sourceMappingURL=Input.js.map
package/dist/Input.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../src/components/Input/Input.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import isNil from 'lodash-es/isNil';\n import { computed, onMounted, ref, useAttrs, useCssModule, useSlots, watchEffect } from 'vue';\n\n import { convertDecimal, decimalSeparator, sanitizeDecimal } from '../../utils/i18n';\n import Field from '../Field/Field.vue';\n import Icon from '../Icon/Icon.vue';\n\n export type InputValue = string | number | undefined;\n\n export interface InputProps {\n /**\n * Adds spacing under the field that is consistent whether or not hint/error text is displayed.\n */\n addBottomSpace?: boolean;\n\n /**\n * Error text to display. Replaces `hintText` (if provided) & adds error styling.\n */\n errorText?: string;\n\n /**\n * Displays text below the input; hidden when the isReadOnly prop is truthy.\n */\n hintText?: string;\n\n /**\n * ID for the Label and Input; must be unique\n */\n id?: string;\n\n /**\n * Label to render above the input.\n */\n label?: string;\n\n /**\n * Show \"(optional)\" to the right of the label text\n */\n showOptionalInLabel?: boolean;\n\n /**\n * Autocomplete takes in a string of off or on\n */\n autocomplete?: string;\n\n /**\n * Value for the input element.\n */\n modelValue?: string | number;\n\n /**\n * @deprecated Use :model-value or v-model instead of :value.\n */\n value?: string | number | null;\n\n /**\n * Input type. Excludes certain types that have a dedicated component.\n *\n * Note: For distinguishing between text & number internally, passing `number`\n * will still render an input with a type of `text` (for localization).\n */\n type?: string extends 'button' | 'checkbox' | 'radio' | 'submit' ? never : string;\n\n /**\n * Placeholder text for the input.\n * **Note:** placeholders should be used to display examples; they should not be used as labels because they are not accessible as labels. If a real label cannot be used, use the `aria-label` attribute.\n */\n placeholder?: string;\n\n /**\n * Indicates whether the input is disabled.\n */\n disabled?: boolean;\n }\n\n defineOptions({\n name: 'll-input',\n inheritAttrs: false,\n });\n\n const props = withDefaults(defineProps<InputProps>(), {\n autocomplete: 'off',\n type: 'text',\n modelValue: '',\n value: null,\n errorText: undefined,\n hintText: undefined,\n label: undefined,\n id: undefined,\n placeholder: undefined,\n disabled: false,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the input value changes.\n */\n (e: 'update:model-value', v: string | number): void;\n /**\n * Emitted when the input value changes.\n */\n (e: 'change', v: string | number): void;\n /**\n * Emitted when the input is focused\n */\n (e: 'focus', evt: Event): void;\n /**\n * Emitted when the input is blurred\n */\n (e: 'blur', evt: Event): void;\n }>();\n\n const slots = useSlots();\n const classes = useCssModule();\n const attrs = useAttrs();\n\n // declare a ref to hold the element reference\n // the name must match template ref value\n const inputEl = ref<HTMLInputElement>();\n\n // this exposes the input ref to any parent that renders the `Input` component\n // and gives it a template ref, giving parent components access to the DOM element.\n defineExpose({ inputEl });\n\n const internalValue = ref<string | number>(props.modelValue);\n\n if (props.type === 'number' && (props.modelValue || props.modelValue === 0)) {\n internalValue.value = convertDecimal(props.modelValue, decimalSeparator);\n }\n\n const showPassword = ref(false);\n\n const isNumber = computed(() => props.type === 'number');\n\n const inputAttrs = computed(() => {\n const tempAttrs = { ...attrs };\n\n delete tempAttrs.class;\n\n return tempAttrs;\n });\n\n const inputType = computed(() => {\n // type 'number' is a special use case and requires\n // that the type be 'text' to support internationalization\n if (isNumber.value) {\n return 'text';\n }\n\n if (props.type === 'password' && showPassword.value) {\n return 'text';\n }\n\n return props.type;\n });\n\n watchEffect(() => {\n internalValue.value = format(props.modelValue);\n });\n\n /**\n * Converts the localized number to a valid number (to emit). i.e. 12,50 > 12.50\n *\n * @param {string|number} value - Number you want to parse.\n * @returns {number|string} number or empty string (for empty input)\n */\n function parseNumber(value: string | number = '', isUserTyping = false): string | number {\n // If this isn't a number input, we shouldn't be calling this function\n if (!isNumber.value) {\n return value;\n }\n\n let tempValue = value;\n\n // If blank, just stop\n if (isNil(tempValue) || `${tempValue}`.length === 0) return '';\n\n // clean out different locale decimals\n if (decimalSeparator !== '.') {\n tempValue = convertDecimal(tempValue, '.');\n }\n\n // If the user is in the middle of an input, let them finish the number\n if (isUserTyping) {\n // Prefix values with a 0 if the user starts with a decimal point\n if (tempValue === '.') tempValue = '0.';\n\n // This is to prevent the parsing from correcting 0. to 0 and causing the value to be reset\n if (tempValue.toString().startsWith('0.')) return tempValue;\n }\n\n // Empty or null values convert to 0 with NumberFormat, so return '';\n if (!isNil(tempValue) && `${tempValue}`.length) {\n tempValue = Intl.NumberFormat('en-US', {\n style: 'decimal',\n maximumFractionDigits: 7,\n useGrouping: false,\n }).format(Number(tempValue));\n } else {\n return '';\n }\n\n // Ensure valid number, otherwise clear value\n return isNaN(Number(tempValue)) ? '' : parseFloat(tempValue);\n }\n\n /**\n * Formats the input based on conditions\n *\n * @param {number|string} value - The value to format.\n */\n function format(value: string | number) {\n if (isNumber.value) {\n return sanitizeDecimal(value, decimalSeparator);\n }\n\n return value;\n }\n\n /**\n * Fire after focusing out of input, if value has changed.\n */\n function handleChange() {\n // Parse the final value on blur\n const parsedValue = isNumber.value ? parseNumber(internalValue.value) : internalValue.value;\n emit('change', parsedValue);\n }\n\n /**\n * Fired when typing on input.\n */\n function handleInput(e: Event) {\n const value = (e.target as HTMLInputElement).value;\n\n // Update the internal value with a sanitized version\n internalValue.value = format(value);\n\n const parsedValue = isNumber.value ? parseNumber(internalValue.value, true) : value;\n\n emit('update:model-value', parsedValue);\n }\n\n onMounted(() => {\n if (props.value !== null) {\n throw new Error('ll-input: use :model-value or v-model instead of :value.');\n }\n\n if (attrs.onInput) {\n throw new Error('ll-input: use the @update:model-value event instead of @input');\n }\n });\n</script>\n\n<template>\n <Field v-bind=\"props\" class=\"stash-input\" :class=\"[classes.root, attrs.class]\" data-test=\"ll-input\">\n <template #default=\"{ fieldId, fieldErrorId, hasError }\">\n <div class=\"tw-relative\">\n <input\n v-bind=\"inputAttrs\"\n :id=\"fieldId\"\n ref=\"inputEl\"\n v-model=\"internalValue\"\n :aria-errormessage=\"fieldErrorId\"\n :aria-invalid=\"hasError\"\n :autocomplete=\"autocomplete\"\n :placeholder=\"props.placeholder\"\n :class=\"[\n { [classes['input-prepended']]: !!slots.prepend },\n { [classes['input-appended']]: !!slots.append || props.type === 'password' },\n { [classes['has-error']]: !!props.errorText },\n ]\"\n :type=\"inputType\"\n :disabled=\"props.disabled\"\n @change=\"handleChange\"\n @input=\"handleInput\"\n @blur=\"(evt) => emit('blur', evt)\"\n @focus=\"(evt) => emit('focus', evt)\"\n />\n\n <div\n v-if=\"slots.prepend\"\n class=\"stash-input-prepend font-semibold\"\n :class=\"[classes.symbol, classes['symbol--prepend']]\"\n >\n <!-- @slot renders content on the left side of the input -->\n <slot name=\"prepend\"> </slot>\n </div>\n\n <div\n v-if=\"slots.append || props.type === 'password'\"\n class=\"stash-input-append font-semibold\"\n :class=\"[classes.symbol, classes['symbol--append']]\"\n >\n <!-- @slot renders content on the right side of the input -->\n <slot v-if=\"slots.append\" name=\"append\"></slot>\n <Icon\n v-else\n :name=\"showPassword ? 'hide' : 'show'\"\n class=\"tw-cursor-pointer\"\n :class=\"{ 'tw-text-ice-500': props.disabled }\"\n :data-test=\"showPassword ? 'hide-password-icon' : 'show-password-icon'\"\n @click=\"showPassword = !showPassword\"\n />\n </div>\n </div>\n </template>\n <template v-if=\"slots.hint\" #hint>\n <slot name=\"hint\"></slot>\n </template>\n </Field>\n</template>\n\n<style module>\n .root {\n position: relative;\n }\n\n .root input {\n background: var(--color-white);\n border: 1px solid var(--color-ice-500);\n border-radius: theme('borderRadius.DEFAULT');\n color: var(--color-ice-700);\n display: block;\n height: theme('height.input');\n font-size: theme('fontSize.sm');\n font-weight: theme('fontWeight.normal');\n outline: none;\n padding: 0 theme('spacing.3');\n width: 100%;\n }\n\n .root input:hover {\n border-color: var(--color-ice-500);\n }\n\n .root input:active,\n .root input:focus {\n border-color: var(--color-blue-500);\n }\n\n .root input::placeholder {\n color: var(--color-ice-500);\n opacity: 1;\n }\n\n .root input.has-error:not(:focus) {\n border-color: var(--color-red-500);\n }\n\n .root input.input-prepended {\n padding-left: 36px;\n }\n\n .root input.input-appended {\n padding-right: 36px;\n }\n\n .symbol {\n align-items: center;\n display: flex;\n height: theme('height.input');\n justify-content: center;\n overflow: hidden;\n position: absolute;\n top: 0;\n width: theme('height.input');\n }\n\n .symbol--prepend {\n border-bottom-left-radius: theme('borderRadius.DEFAULT');\n border-top-left-radius: theme('borderRadius.DEFAULT');\n left: 0;\n }\n\n .symbol--append {\n border-bottom-right-radius: theme('borderRadius.DEFAULT');\n border-top-right-radius: theme('borderRadius.DEFAULT');\n right: 0;\n }\n\n .root input[disabled],\n .root input[readonly] {\n background-color: var(--color-ice-100) !important;\n border-color: var(--color-ice-500) !important;\n color: var(--color-ice-500) !important;\n pointer-events: none;\n outline-color: var(--color-ice-500) !important;\n\n & + .symbol--prepend,\n & + .symbol--append {\n color: var(--color-ice-500);\n }\n }\n\n .root input[disabled]:active,\n .root input[readonly]:active,\n .root input[disabled]:focus,\n .root input[readonly]:focus {\n box-shadow: none !important;\n }\n\n .root input[disabled]::placeholder,\n .root input[readonly]::placeholder {\n text-transform: none;\n }\n</style>\n"],"names":["props","__props","emit","__emit","slots","useSlots","classes","useCssModule","attrs","useAttrs","inputEl","ref","__expose","internalValue","convertDecimal","decimalSeparator","showPassword","isNumber","computed","inputAttrs","tempAttrs","inputType","watchEffect","format","parseNumber","value","isUserTyping","tempValue","isNil","sanitizeDecimal","handleChange","parsedValue","handleInput","e","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAiFE,UAAMA,IAAQC,GAaRC,IAAOC,GAmBPC,IAAQC,KACRC,IAAUC,KACVC,IAAQC,KAIRC,IAAUC;AAIH,IAAAC,EAAA,EAAE,SAAAF,GAAS;AAElB,UAAAG,IAAgBF,EAAqBX,EAAM,UAAU;AAE3D,IAAIA,EAAM,SAAS,aAAaA,EAAM,cAAcA,EAAM,eAAe,OACvEa,EAAc,QAAQC,EAAed,EAAM,YAAYe,CAAgB;AAGnE,UAAAC,IAAeL,EAAI,EAAK,GAExBM,IAAWC,EAAS,MAAMlB,EAAM,SAAS,QAAQ,GAEjDmB,IAAaD,EAAS,MAAM;AAC1B,YAAAE,IAAY,EAAE,GAAGZ;AAEvB,oBAAOY,EAAU,OAEVA;AAAA,IAAA,CACR,GAEKC,IAAYH,EAAS,MAGrBD,EAAS,SAITjB,EAAM,SAAS,cAAcgB,EAAa,QACrC,SAGFhB,EAAM,IACd;AAED,IAAAsB,EAAY,MAAM;AACF,MAAAT,EAAA,QAAQU,EAAOvB,EAAM,UAAU;AAAA,IAAA,CAC9C;AAQD,aAASwB,EAAYC,IAAyB,IAAIC,IAAe,IAAwB;AAEnF,UAAA,CAACT,EAAS;AACL,eAAAQ;AAGT,UAAIE,IAAYF;AAGZ,UAAAG,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG,WAAW,EAAU,QAAA;AAQ5D,UALIZ,MAAqB,QACXY,IAAAb,EAAea,GAAW,GAAG,IAIvCD,MAEEC,MAAc,QAAiBA,IAAA,OAG/BA,EAAU,SAAS,EAAE,WAAW,IAAI;AAAU,eAAAA;AAIpD,UAAI,CAACC,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG;AAC1B,QAAAA,IAAA,KAAK,aAAa,SAAS;AAAA,UACrC,OAAO;AAAA,UACP,uBAAuB;AAAA,UACvB,aAAa;AAAA,QACd,CAAA,EAAE,OAAO,OAAOA,CAAS,CAAC;AAAA;AAEpB,eAAA;AAIT,aAAO,MAAM,OAAOA,CAAS,CAAC,IAAI,KAAK,WAAWA,CAAS;AAAA,IAC7D;AAOA,aAASJ,EAAOE,GAAwB;AACtC,aAAIR,EAAS,QACJY,EAAgBJ,GAAOV,CAAgB,IAGzCU;AAAA,IACT;AAKA,aAASK,IAAe;AAEtB,YAAMC,IAAcd,EAAS,QAAQO,EAAYX,EAAc,KAAK,IAAIA,EAAc;AACtF,MAAAX,EAAK,UAAU6B,CAAW;AAAA,IAC5B;AAKA,aAASC,EAAYC,GAAU;AACvB,YAAAR,IAASQ,EAAE,OAA4B;AAG/B,MAAApB,EAAA,QAAQU,EAAOE,CAAK;AAElC,YAAMM,IAAcd,EAAS,QAAQO,EAAYX,EAAc,OAAO,EAAI,IAAIY;AAE9E,MAAAvB,EAAK,sBAAsB6B,CAAW;AAAA,IACxC;AAEA,WAAAG,EAAU,MAAM;AACV,UAAAlC,EAAM,UAAU;AACZ,cAAA,IAAI,MAAM,0DAA0D;AAG5E,UAAIQ,EAAM;AACF,cAAA,IAAI,MAAM,+DAA+D;AAAA,IACjF,CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Input.js","sources":["../src/components/Input/Input.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import isNil from 'lodash-es/isNil';\n import { computed, onMounted, ref, useAttrs, useCssModule, useSlots, watchEffect } from 'vue';\n\n import { convertDecimal, decimalSeparator, sanitizeDecimal } from '../../utils/i18n';\n import Field from '../Field/Field.vue';\n import Icon from '../Icon/Icon.vue';\n\n export type InputValue = string | number | undefined;\n\n export interface InputProps {\n /**\n * Adds spacing under the field that is consistent whether or not hint/error text is displayed.\n */\n addBottomSpace?: boolean;\n\n /**\n * Error text to display. Replaces `hintText` (if provided) & adds error styling.\n */\n errorText?: string;\n\n /**\n * Displays text below the input; hidden when the isReadOnly prop is truthy.\n */\n hintText?: string;\n\n /**\n * ID for the Label and Input; must be unique\n */\n id?: string;\n\n /**\n * Label to render above the input.\n */\n label?: string;\n\n /**\n * Show \"(optional)\" to the right of the label text\n */\n showOptionalInLabel?: boolean;\n\n /**\n * Autocomplete takes in a string of off or on\n */\n autocomplete?: string;\n\n /**\n * Value for the input element.\n */\n modelValue?: string | number;\n\n /**\n * @deprecated Use :model-value or v-model instead of :value.\n */\n value?: string | number | null;\n\n /**\n * Input type. Excludes certain types that have a dedicated component.\n *\n * Note: For distinguishing between text & number internally, passing `number`\n * will still render an input with a type of `text` (for localization).\n */\n type?: string extends 'button' | 'checkbox' | 'radio' | 'submit' ? never : string;\n\n /**\n * Placeholder text for the input.\n * **Note:** placeholders should be used to display examples; they should not be used as labels because they are not accessible as labels. If a real label cannot be used, use the `aria-label` attribute.\n */\n placeholder?: string;\n\n /**\n * Indicates whether the input is disabled.\n */\n disabled?: boolean;\n\n /**\n * Indicates whether the input is read-only.\n */\n isReadOnly?: boolean;\n }\n\n defineOptions({\n name: 'll-input',\n inheritAttrs: false,\n });\n\n const props = withDefaults(defineProps<InputProps>(), {\n autocomplete: 'off',\n type: 'text',\n modelValue: '',\n value: null,\n errorText: undefined,\n hintText: undefined,\n label: undefined,\n id: undefined,\n placeholder: undefined,\n disabled: false,\n isReadOnly: false,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the input value changes.\n */\n (e: 'update:model-value', v: string | number): void;\n /**\n * Emitted when the input value changes.\n */\n (e: 'change', v: string | number): void;\n /**\n * Emitted when the input is focused\n */\n (e: 'focus', evt: Event): void;\n /**\n * Emitted when the input is blurred\n */\n (e: 'blur', evt: Event): void;\n }>();\n\n const slots = useSlots();\n const classes = useCssModule();\n const attrs = useAttrs();\n\n // declare a ref to hold the element reference\n // the name must match template ref value\n const inputEl = ref<HTMLInputElement>();\n\n // this exposes the input ref to any parent that renders the `Input` component\n // and gives it a template ref, giving parent components access to the DOM element.\n defineExpose({ inputEl });\n\n const internalValue = ref<string | number>(props.modelValue);\n\n if (props.type === 'number' && (props.modelValue || props.modelValue === 0)) {\n internalValue.value = convertDecimal(props.modelValue, decimalSeparator);\n }\n\n const showPassword = ref(false);\n\n const isReadOnly = computed(() => props.isReadOnly || ('readonly' in attrs && attrs.readonly !== false));\n const isNumber = computed(() => props.type === 'number');\n\n const inputAttrs = computed(() => {\n const tempAttrs = { ...attrs };\n\n delete tempAttrs.class;\n\n return tempAttrs;\n });\n\n const inputType = computed(() => {\n // type 'number' is a special use case and requires\n // that the type be 'text' to support internationalization\n if (isNumber.value) {\n return 'text';\n }\n\n if (props.type === 'password' && showPassword.value) {\n return 'text';\n }\n\n return props.type;\n });\n\n watchEffect(() => {\n internalValue.value = format(props.modelValue);\n });\n\n /**\n * Converts the localized number to a valid number (to emit). i.e. 12,50 > 12.50\n *\n * @param {string|number} value - Number you want to parse.\n * @returns {number|string} number or empty string (for empty input)\n */\n function parseNumber(value: string | number = '', isUserTyping = false): string | number {\n // If this isn't a number input, we shouldn't be calling this function\n if (!isNumber.value) {\n return value;\n }\n\n let tempValue = value;\n\n // If blank, just stop\n if (isNil(tempValue) || `${tempValue}`.length === 0) return '';\n\n // clean out different locale decimals\n if (decimalSeparator !== '.') {\n tempValue = convertDecimal(tempValue, '.');\n }\n\n // If the user is in the middle of an input, let them finish the number\n if (isUserTyping) {\n // Prefix values with a 0 if the user starts with a decimal point\n if (tempValue === '.') tempValue = '0.';\n\n // This is to prevent the parsing from correcting 0. to 0 and causing the value to be reset\n if (tempValue.toString().startsWith('0.')) return tempValue;\n }\n\n // Empty or null values convert to 0 with NumberFormat, so return '';\n if (!isNil(tempValue) && `${tempValue}`.length) {\n tempValue = Intl.NumberFormat('en-US', {\n style: 'decimal',\n maximumFractionDigits: 7,\n useGrouping: false,\n }).format(Number(tempValue));\n } else {\n return '';\n }\n\n // Ensure valid number, otherwise clear value\n return isNaN(Number(tempValue)) ? '' : parseFloat(tempValue);\n }\n\n /**\n * Formats the input based on conditions\n *\n * @param {number|string} value - The value to format.\n */\n function format(value: string | number) {\n if (isNumber.value) {\n return sanitizeDecimal(value, decimalSeparator);\n }\n\n return value;\n }\n\n /**\n * Fire after focusing out of input, if value has changed.\n */\n function handleChange() {\n // Parse the final value on blur\n const parsedValue = isNumber.value ? parseNumber(internalValue.value) : internalValue.value;\n emit('change', parsedValue);\n }\n\n /**\n * Fired when typing on input.\n */\n function handleInput(e: Event) {\n const value = (e.target as HTMLInputElement).value;\n\n // Update the internal value with a sanitized version\n internalValue.value = format(value);\n\n const parsedValue = isNumber.value ? parseNumber(internalValue.value, true) : value;\n\n emit('update:model-value', parsedValue);\n }\n\n onMounted(() => {\n if (props.value !== null) {\n throw new Error('ll-input: use :model-value or v-model instead of :value.');\n }\n\n if (attrs.onInput) {\n throw new Error('ll-input: use the @update:model-value event instead of @input');\n }\n });\n</script>\n\n<template>\n <Field\n v-bind=\"props\"\n :is-read-only=\"isReadOnly\"\n class=\"stash-input\"\n :class=\"[classes.root, attrs.class]\"\n data-test=\"ll-input\"\n >\n <template #default=\"{ fieldId, fieldErrorId, hasError }\">\n <div class=\"tw-relative\">\n <input\n v-bind=\"inputAttrs\"\n :id=\"fieldId\"\n ref=\"inputEl\"\n v-model=\"internalValue\"\n :aria-errormessage=\"fieldErrorId\"\n :aria-invalid=\"hasError\"\n :autocomplete=\"autocomplete\"\n :placeholder=\"props.placeholder\"\n :class=\"[\n { [classes['input-prepended']]: !!slots.prepend },\n { [classes['input-appended']]: !!slots.append || props.type === 'password' },\n { [classes['has-error']]: !!props.errorText },\n ]\"\n :type=\"inputType\"\n :disabled=\"props.disabled\"\n :readonly=\"isReadOnly\"\n @change=\"handleChange\"\n @input=\"handleInput\"\n @blur=\"(evt) => emit('blur', evt)\"\n @focus=\"(evt) => emit('focus', evt)\"\n />\n\n <div\n v-if=\"slots.prepend\"\n class=\"stash-input-prepend font-semibold\"\n :class=\"[classes.symbol, classes['symbol--prepend']]\"\n >\n <!-- @slot renders content on the left side of the input -->\n <slot name=\"prepend\"> </slot>\n </div>\n\n <div\n v-if=\"slots.append || props.type === 'password'\"\n class=\"stash-input-append font-semibold\"\n :class=\"[classes.symbol, classes['symbol--append']]\"\n >\n <!-- @slot renders content on the right side of the input -->\n <slot v-if=\"slots.append\" name=\"append\"></slot>\n <Icon\n v-else\n :name=\"showPassword ? 'hide' : 'show'\"\n class=\"tw-cursor-pointer\"\n :class=\"{ 'tw-text-ice-500': props.disabled }\"\n :data-test=\"showPassword ? 'hide-password-icon' : 'show-password-icon'\"\n @click=\"showPassword = !showPassword\"\n />\n </div>\n </div>\n </template>\n <template v-if=\"slots.hint\" #hint>\n <slot name=\"hint\"></slot>\n </template>\n </Field>\n</template>\n\n<style module>\n .root {\n position: relative;\n }\n\n .root input {\n background: var(--color-white);\n border: 1px solid var(--color-ice-500);\n border-radius: theme('borderRadius.DEFAULT');\n color: var(--color-ice-700);\n display: block;\n height: theme('height.input');\n font-size: theme('fontSize.sm');\n font-weight: theme('fontWeight.normal');\n outline: none;\n padding: 0 theme('spacing.3');\n width: 100%;\n }\n\n .root input:hover {\n border-color: var(--color-ice-500);\n }\n\n .root input:active,\n .root input:focus {\n border-color: var(--color-blue-500);\n }\n\n .root input::placeholder {\n color: var(--color-ice-500);\n opacity: 1;\n }\n\n .root input.has-error:not(:focus) {\n border-color: var(--color-red-500);\n }\n\n .root input.input-prepended {\n padding-left: 36px;\n }\n\n .root input.input-appended {\n padding-right: 36px;\n }\n\n .symbol {\n align-items: center;\n display: flex;\n height: theme('height.input');\n justify-content: center;\n overflow: hidden;\n position: absolute;\n top: 0;\n width: theme('height.input');\n }\n\n .symbol--prepend {\n border-bottom-left-radius: theme('borderRadius.DEFAULT');\n border-top-left-radius: theme('borderRadius.DEFAULT');\n left: 0;\n }\n\n .symbol--append {\n border-bottom-right-radius: theme('borderRadius.DEFAULT');\n border-top-right-radius: theme('borderRadius.DEFAULT');\n right: 0;\n }\n\n .root input[disabled] {\n background-color: var(--color-ice-100) !important;\n border-color: var(--color-ice-500) !important;\n color: var(--color-ice-500) !important;\n pointer-events: none;\n outline-color: var(--color-ice-500) !important;\n\n & + .symbol--prepend,\n & + .symbol--append {\n color: var(--color-ice-500);\n }\n }\n\n .root input[readonly] {\n border-color: transparent;\n background-color: transparent;\n padding-left: 0;\n padding-right: 0;\n }\n\n .root input[disabled]:active,\n .root input[readonly]:active,\n .root input[disabled]:focus,\n .root input[readonly]:focus {\n box-shadow: none !important;\n }\n\n .root input[disabled]::placeholder {\n text-transform: none;\n }\n</style>\n"],"names":["props","__props","emit","__emit","slots","useSlots","classes","useCssModule","attrs","useAttrs","inputEl","ref","__expose","internalValue","convertDecimal","decimalSeparator","showPassword","isReadOnly","computed","isNumber","inputAttrs","tempAttrs","inputType","watchEffect","format","parseNumber","value","isUserTyping","tempValue","isNil","sanitizeDecimal","handleChange","parsedValue","handleInput","e","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFE,UAAMA,IAAQC,GAcRC,IAAOC,GAmBPC,IAAQC,KACRC,IAAUC,KACVC,IAAQC,KAIRC,IAAUC;AAIH,IAAAC,EAAA,EAAE,SAAAF,GAAS;AAElB,UAAAG,IAAgBF,EAAqBX,EAAM,UAAU;AAE3D,IAAIA,EAAM,SAAS,aAAaA,EAAM,cAAcA,EAAM,eAAe,OACvEa,EAAc,QAAQC,EAAed,EAAM,YAAYe,CAAgB;AAGnE,UAAAC,IAAeL,EAAI,EAAK,GAExBM,IAAaC,EAAS,MAAMlB,EAAM,cAAe,cAAcQ,KAASA,EAAM,aAAa,EAAM,GACjGW,IAAWD,EAAS,MAAMlB,EAAM,SAAS,QAAQ,GAEjDoB,IAAaF,EAAS,MAAM;AAC1B,YAAAG,IAAY,EAAE,GAAGb;AAEvB,oBAAOa,EAAU,OAEVA;AAAA,IAAA,CACR,GAEKC,IAAYJ,EAAS,MAGrBC,EAAS,SAITnB,EAAM,SAAS,cAAcgB,EAAa,QACrC,SAGFhB,EAAM,IACd;AAED,IAAAuB,EAAY,MAAM;AACF,MAAAV,EAAA,QAAQW,EAAOxB,EAAM,UAAU;AAAA,IAAA,CAC9C;AAQD,aAASyB,EAAYC,IAAyB,IAAIC,IAAe,IAAwB;AAEnF,UAAA,CAACR,EAAS;AACL,eAAAO;AAGT,UAAIE,IAAYF;AAGZ,UAAAG,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG,WAAW,EAAU,QAAA;AAQ5D,UALIb,MAAqB,QACXa,IAAAd,EAAec,GAAW,GAAG,IAIvCD,MAEEC,MAAc,QAAiBA,IAAA,OAG/BA,EAAU,SAAS,EAAE,WAAW,IAAI;AAAU,eAAAA;AAIpD,UAAI,CAACC,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG;AAC1B,QAAAA,IAAA,KAAK,aAAa,SAAS;AAAA,UACrC,OAAO;AAAA,UACP,uBAAuB;AAAA,UACvB,aAAa;AAAA,QACd,CAAA,EAAE,OAAO,OAAOA,CAAS,CAAC;AAAA;AAEpB,eAAA;AAIT,aAAO,MAAM,OAAOA,CAAS,CAAC,IAAI,KAAK,WAAWA,CAAS;AAAA,IAC7D;AAOA,aAASJ,EAAOE,GAAwB;AACtC,aAAIP,EAAS,QACJW,EAAgBJ,GAAOX,CAAgB,IAGzCW;AAAA,IACT;AAKA,aAASK,IAAe;AAEtB,YAAMC,IAAcb,EAAS,QAAQM,EAAYZ,EAAc,KAAK,IAAIA,EAAc;AACtF,MAAAX,EAAK,UAAU8B,CAAW;AAAA,IAC5B;AAKA,aAASC,EAAYC,GAAU;AACvB,YAAAR,IAASQ,EAAE,OAA4B;AAG/B,MAAArB,EAAA,QAAQW,EAAOE,CAAK;AAElC,YAAMM,IAAcb,EAAS,QAAQM,EAAYZ,EAAc,OAAO,EAAI,IAAIa;AAE9E,MAAAxB,EAAK,sBAAsB8B,CAAW;AAAA,IACxC;AAEA,WAAAG,EAAU,MAAM;AACV,UAAAnC,EAAM,UAAU;AACZ,cAAA,IAAI,MAAM,0DAA0D;AAG5E,UAAIQ,EAAM;AACF,cAAA,IAAI,MAAM,+DAA+D;AAAA,IACjF,CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -44,6 +44,7 @@ label: undefined;
44
44
  id: undefined;
45
45
  placeholder: undefined;
46
46
  disabled: boolean;
47
+ isReadOnly: boolean;
47
48
  }>>, {
48
49
  inputEl: Ref<HTMLInputElement | undefined, HTMLInputElement | undefined>;
49
50
  }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
@@ -62,6 +63,7 @@ label: undefined;
62
63
  id: undefined;
63
64
  placeholder: undefined;
64
65
  disabled: boolean;
66
+ isReadOnly: boolean;
65
67
  }>>> & Readonly<{
66
68
  onBlur?: ((evt: Event) => any) | undefined;
67
69
  onChange?: ((v: string | number) => any) | undefined;
@@ -74,6 +76,7 @@ label: string;
74
76
  id: string;
75
77
  errorText: string;
76
78
  hintText: string;
79
+ isReadOnly: boolean;
77
80
  placeholder: string;
78
81
  modelValue: string | number;
79
82
  value: string | number | null;
@@ -138,6 +141,10 @@ export declare interface InputProps {
138
141
  * Indicates whether the input is disabled.
139
142
  */
140
143
  disabled?: boolean;
144
+ /**
145
+ * Indicates whether the input is read-only.
146
+ */
147
+ isReadOnly?: boolean;
141
148
  }
142
149
 
143
150
  export declare type InputValue = string | number | undefined;