@weni/unnnic-system 3.12.8 → 3.14.0-alpha-teleports.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +9 -1
  3. package/dist/{es-62c1e8d3.mjs → es-0d53b5b2.mjs} +1 -1
  4. package/dist/{index-ef197fd5.mjs → index-d7070de8.mjs} +99880 -96723
  5. package/dist/index.d.ts +5588 -1607
  6. package/dist/{pt-br-198b147b.mjs → pt-br-bf4e1f97.mjs} +1 -1
  7. package/dist/style.css +1 -1
  8. package/dist/unnnic.mjs +233 -203
  9. package/dist/unnnic.umd.js +48 -44
  10. package/package.json +3 -2
  11. package/src/assets/scss/tailwind.scss +8 -0
  12. package/src/components/Alert/__tests__/__snapshots__/Alert.spec.js.snap +1 -1
  13. package/src/components/ChartFunnel/DefaultFunnel/ChartDefaultFunnelBase.vue +2 -1
  14. package/src/components/ChartFunnel/SvgFunnel/ChartFunnelTwoRows.vue +61 -60
  15. package/src/components/Checkbox/Checkbox.vue +1 -1
  16. package/src/components/CheckboxGroup/CheckboxGroup.vue +5 -7
  17. package/src/components/Chip/Chip.vue +1 -1
  18. package/src/components/DatePicker/DatePicker.vue +10 -1
  19. package/src/components/Drawer/Drawer.vue +180 -270
  20. package/src/components/Drawer/__tests__/Drawer.spec.js +32 -43
  21. package/src/components/Drawer/__tests__/__snapshots__/Drawer.spec.js.snap +18 -19
  22. package/src/components/FormElement/FormElement.vue +87 -96
  23. package/src/components/Input/BaseInput.vue +25 -5
  24. package/src/components/Input/Input.scss +2 -1
  25. package/src/components/Input/Input.vue +24 -1
  26. package/src/components/Input/TextInput.vue +64 -25
  27. package/src/components/Input/__test__/TextInput.spec.js +1 -1
  28. package/src/components/Input/__test__/__snapshots__/Input.spec.js.snap +5 -1
  29. package/src/components/Input/__test__/__snapshots__/TextInput.spec.js.snap +7 -1
  30. package/src/components/InputDatePicker/InputDatePicker.vue +68 -73
  31. package/src/components/InputDatePicker/__test__/InputDatePicker.spec.js +31 -24
  32. package/src/components/ModalDialog/ModalDialog.vue +63 -154
  33. package/src/components/ModalDialog/__tests__/ModalDialog.spec.js +30 -210
  34. package/src/components/ModalDialog/__tests__/__snapshots__/ModalDialog.spec.js.snap +1 -22
  35. package/src/components/MultiSelect/MultSelectOption.vue +49 -0
  36. package/src/components/MultiSelect/__tests__/MultiSelect.spec.js +557 -0
  37. package/src/components/MultiSelect/__tests__/MultiSelectOption.spec.js +229 -0
  38. package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelect.spec.js.snap +87 -0
  39. package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelectOption.spec.js.snap +51 -0
  40. package/src/components/MultiSelect/index.vue +265 -0
  41. package/src/components/Radio/Radio.vue +6 -12
  42. package/src/components/Radio/__test__/Radio.spec.js +1 -3
  43. package/src/components/RadioGroup/RadioGroup.vue +10 -18
  44. package/src/components/Select/__tests__/Select.spec.js +422 -0
  45. package/src/components/Select/__tests__/SelectItem.spec.js +310 -0
  46. package/src/components/Select/__tests__/__snapshots__/Popover.spec.js.snap +8 -0
  47. package/src/components/Select/__tests__/__snapshots__/Select.spec.js.snap +71 -0
  48. package/src/components/Select/__tests__/__snapshots__/SelectItem.spec.js.snap +15 -0
  49. package/src/components/Select/__tests__/__snapshots__/SelectOption.spec.js.snap +25 -0
  50. package/src/components/Select/__tests__/__snapshots__/SelectPopover.spec.js.snap +8 -0
  51. package/src/components/Select/index.vue +308 -0
  52. package/src/components/Switch/Switch.vue +3 -10
  53. package/src/components/Tab/__test__/__snapshots__/Tab.spec.js.snap +3 -1
  54. package/src/components/TemplatePreview/TemplatePreview.vue +25 -28
  55. package/src/components/TemplatePreview/TemplatePreviewModal.vue +10 -10
  56. package/src/components/TemplatePreview/types.d.ts +3 -3
  57. package/src/components/Toast/Toast.vue +4 -1
  58. package/src/components/Toast/ToastManager.ts +4 -1
  59. package/src/components/Toast/__tests__/ToastManager.spec.js +10 -6
  60. package/src/components/ToolTip/ToolTip.vue +25 -177
  61. package/src/components/ToolTip/__tests__/ToolTip.spec.js +339 -61
  62. package/src/components/index.ts +62 -6
  63. package/src/components/ui/dialog/Dialog.vue +19 -0
  64. package/src/components/ui/dialog/DialogClose.vue +29 -0
  65. package/src/components/ui/dialog/DialogContent.vue +140 -0
  66. package/src/components/ui/dialog/DialogFooter.vue +50 -0
  67. package/src/components/ui/dialog/DialogHeader.vue +83 -0
  68. package/src/components/ui/dialog/DialogTitle.vue +38 -0
  69. package/src/components/ui/dialog/DialogTrigger.vue +16 -0
  70. package/src/components/ui/dialog/index.ts +7 -0
  71. package/src/components/ui/drawer/Drawer.vue +27 -0
  72. package/src/components/ui/drawer/DrawerClose.vue +31 -0
  73. package/src/components/ui/drawer/DrawerContent.vue +113 -0
  74. package/src/components/ui/drawer/DrawerDescription.vue +40 -0
  75. package/src/components/ui/drawer/DrawerFooter.vue +38 -0
  76. package/src/components/ui/drawer/DrawerHeader.vue +57 -0
  77. package/src/components/ui/drawer/DrawerOverlay.vue +33 -0
  78. package/src/components/ui/drawer/DrawerTitle.vue +37 -0
  79. package/src/components/ui/drawer/DrawerTrigger.vue +31 -0
  80. package/src/components/ui/drawer/index.ts +10 -0
  81. package/src/components/ui/popover/PopoverContent.vue +7 -4
  82. package/src/components/ui/popover/PopoverOption.vue +4 -0
  83. package/src/components/ui/popover/PopoverTrigger.vue +5 -1
  84. package/src/components/ui/tooltip/Tooltip.vue +21 -0
  85. package/src/components/ui/tooltip/TooltipContent.vue +77 -0
  86. package/src/components/ui/tooltip/TooltipTrigger.vue +24 -0
  87. package/src/components/ui/tooltip/index.ts +3 -0
  88. package/src/index.ts +9 -2
  89. package/src/lib/__tests__/teleport-target.spec.ts +73 -0
  90. package/src/lib/layer-manager.ts +64 -0
  91. package/src/lib/teleport-target.ts +46 -0
  92. package/src/locales/en.json +3 -1
  93. package/src/locales/es.json +3 -1
  94. package/src/locales/pt_br.json +3 -1
  95. package/src/stories/Dialog.stories.js +832 -0
  96. package/src/stories/Drawer.stories.js +1 -1
  97. package/src/stories/DrawerNext.stories.js +611 -0
  98. package/src/stories/Input.mdx +3 -0
  99. package/src/stories/LayerManager.docs.mdx +40 -0
  100. package/src/stories/LayerManager.stories.js +407 -0
  101. package/src/stories/ModalDialog.mdx +3 -0
  102. package/src/stories/ModalDialog.stories.js +96 -1
  103. package/src/stories/MultiSelect.stories.js +143 -45
  104. package/src/stories/Select.stories.js +161 -0
  105. package/src/stories/TemplatePreview.stories.js +27 -27
  106. package/src/stories/TemplatePreviewModal.stories.js +31 -31
  107. package/src/components/MultiSelect/MultiSelect.vue +0 -297
@@ -1,23 +1,22 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
3
  exports[`Drawer.vue > Component Rendering > Component Rendering > matches the snapshot 1`] = `
4
- "<aside data-v-196de012="" class="unnnic-drawer" data-testid="drawer">
5
- <section data-v-196de012="" class="unnnic-drawer__overlay" data-testid="overlay"></section>
6
- <transition-stub data-v-196de012="" name="drawer" appear="true" persisted="false" css="true">
7
- <section data-v-196de012="" data-testid="drawer-container" class="unnnic-drawer__container unnnic-drawer__container--md">
8
- <header data-v-196de012="" class="unnnic-drawer__header">
9
- <section data-v-196de012="" class="unnnic-drawer__title-container">
10
- <h1 data-v-196de012="" class="unnnic-drawer__title" data-testid="drawer-title">Test Title</h1>
11
- <p data-v-196de012="" class="unnnic-drawer__description" data-testid="drawer-description">Test Description</p>
12
- </section>
13
- <unnnic-icon-stub data-v-196de012="" filled="false" icon="arrow_back" clickable="true" size="avatar-nano" scheme="neutral-darkest" class="unnnic-drawer__close" data-testid="close-icon"></unnnic-icon-stub>
14
- </header>
15
- <section data-v-196de012="" class="unnnic-drawer__content"></section>
16
- <footer data-v-196de012="" class="unnnic-drawer__footer" data-testid="footer">
17
- <unnnic-button-stub data-v-196de012="" size="large" text="Secondary Action" type="tertiary" float="false" iconleft="" iconright="" iconcenter="" iconsfilled="false" disabled="false" loading="false" data-testid="secondary-button"></unnnic-button-stub>
18
- <unnnic-button-stub data-v-196de012="" size="large" text="Primary Action" type="primary" float="false" iconleft="" iconright="" iconcenter="" iconsfilled="false" disabled="false" loading="false" data-testid="primary-button"></unnnic-button-stub>
19
- </footer>
20
- </section>
21
- </transition-stub>
22
- </aside>"
4
+ "<div data-v-196de012="" class="unnnic-drawer" data-testid="drawer" open="true">
5
+ <div data-v-196de012="" showoverlay="true" data-testid="drawer-container" size="medium" class="unnnic-drawer__container unnnic-drawer__container--md">
6
+ <header data-v-39d0dfb8="" data-v-196de012="" class="unnnic-drawer__header unnnic-drawer__header">
7
+ <section data-v-196de012="" class="unnnic-drawer__title-container">
8
+ <div data-v-196de012="" class="unnnic-drawer__title" data-testid="drawer-title">Test Title</div>
9
+ <div data-v-196de012="" class="unnnic-drawer__description" data-testid="drawer-description">Test Description</div>
10
+ </section>
11
+ <div data-v-196de012="">
12
+ <unnnic-button-stub data-v-196de012="" size="small" text="" type="tertiary" float="false" iconleft="" iconright="" iconcenter="arrow_forward" iconsfilled="false" disabled="false" loading="false" class="unnnic-drawer__close-icon" data-testid="close-icon"></unnnic-button-stub>
13
+ </div>
14
+ </header>
15
+ <section data-v-196de012="" class="unnnic-drawer__content"></section>
16
+ <div data-v-196de012="" class="unnnic-drawer__footer" data-testid="footer">
17
+ <unnnic-button-stub data-v-196de012="" size="large" text="Secondary Action" type="tertiary" float="false" iconleft="" iconright="" iconcenter="" iconsfilled="false" disabled="false" loading="false" data-testid="secondary-button"></unnnic-button-stub>
18
+ <unnnic-button-stub data-v-196de012="" size="large" text="Primary Action" type="primary" float="false" iconleft="" iconright="" iconcenter="" iconsfilled="false" disabled="false" loading="false" data-testid="primary-button"></unnnic-button-stub>
19
+ </div>
20
+ </div>
21
+ </div>"
23
22
  `;
@@ -1,37 +1,28 @@
1
1
  <template>
2
- <section
3
- class="unnnic-form-element"
4
- :class="{ 'unnnic-form-element--disabled': disabled }"
5
- >
6
- <UnnnicLabel
7
- v-if="label"
8
- :label="label"
2
+ <section class="unnnic-form-element" :class="{ 'unnnic-form-element--disabled': disabled }">
3
+ <UnnnicLabel
4
+ v-if="label"
5
+ :label="label"
9
6
  :tooltip="tooltip"
10
7
  :class="[
11
8
  'unnnic-form-element__label',
12
9
  {
13
10
  'unnnic-form-element__label--fixed': fixedLabel,
14
11
  },
15
- ]"
12
+ ]"
16
13
  />
17
14
 
18
15
  <slot></slot>
19
16
 
20
- <section
17
+ <section
21
18
  class="unnnic-form-element__hints-container"
22
19
  v-if="message || error || !!$slots.rightMessage"
23
20
  >
24
21
  <section class="unnnic-form-element__message-container">
25
- <p
26
- v-if="message"
27
- class="unnnic-form-element__message"
28
- >
22
+ <p v-if="message" class="unnnic-form-element__message">
29
23
  {{ fullySanitize(message) }}
30
24
  </p>
31
- <p
32
- v-if="!!error?.length"
33
- class="unnnic-form-element__message error"
34
- >
25
+ <p v-if="!!error?.length" class="unnnic-form-element__message error">
35
26
  {{ Array.isArray(error) ? error.join(', ') : error }}
36
27
  </p>
37
28
  </section>
@@ -43,104 +34,104 @@
43
34
  </template>
44
35
 
45
36
  <script lang="js">
46
- import { fullySanitize } from '../../utils/sanitize';
47
- import UnnnicLabel from '../Label/Label.vue';
48
-
49
- export default {
50
- components: {
51
- UnnnicLabel,
52
- },
53
- props: {
54
- size: {
55
- type: String,
56
- default: 'md',
57
- validator: (size) => ['md', 'sm'].includes(size),
37
+ import { fullySanitize } from '../../utils/sanitize';
38
+ import UnnnicLabel from '../Label/Label.vue';
39
+
40
+ export default {
41
+ components: {
42
+ UnnnicLabel,
58
43
  },
44
+ props: {
45
+ size: {
46
+ type: String,
47
+ default: 'md',
48
+ validator: (size) => ['md', 'sm'].includes(size),
49
+ },
59
50
 
60
- label: { type: String, default: '' },
51
+ label: { type: String, default: '' },
61
52
 
62
- fixedLabel: { type: Boolean, default: false },
53
+ fixedLabel: { type: Boolean, default: false },
63
54
 
64
- error: {
65
- type: [Boolean, String],
66
- default: false,
67
- },
55
+ error: {
56
+ type: [Boolean, String],
57
+ default: false,
58
+ },
68
59
 
69
- message: { type: String, default: '' },
60
+ message: { type: String, default: '' },
70
61
 
71
- disabled: { type: Boolean, default: false },
62
+ disabled: { type: Boolean, default: false },
72
63
 
73
- tooltip: { type: String, default: '' },
74
- },
75
- methods: {
76
- fullySanitize,
77
- },
78
- };
64
+ tooltip: { type: String, default: '' },
65
+ },
66
+ methods: {
67
+ fullySanitize,
68
+ },
69
+ };
79
70
  </script>
80
71
 
81
72
  <style lang="scss" scoped>
82
- @use '@/assets/scss/unnnic' as *;
83
-
84
- * {
85
- margin: $unnnic-space-0;
86
- padding: $unnnic-space-0;
87
- box-sizing: border-box;
88
- }
89
-
90
- .unnnic-form-element {
91
- &__label {
92
- font: $unnnic-font-body;
93
- color: $unnnic-color-neutral-cloudy;
94
- margin-bottom: $unnnic-space-1;
95
- display: flex;
96
- align-items: center;
97
- gap: $unnnic-space-2;
98
-
99
- &--fixed {
100
- margin-top: -$unnnic-font-size-body-gt - $unnnic-space-2 + $unnnic-space-1;
101
- }
73
+ @use '@/assets/scss/unnnic' as *;
74
+
75
+ * {
76
+ margin: $unnnic-space-0;
77
+ padding: $unnnic-space-0;
78
+ box-sizing: border-box;
79
+ }
102
80
 
103
- &--fixed {
104
- margin-bottom: $unnnic-space-0;
105
- position: absolute;
106
- padding: $unnnic-space-0 $unnnic-space-1;
107
- margin-left: $unnnic-space-2;
81
+ .unnnic-form-element {
82
+ &__label {
83
+ font: $unnnic-font-body;
84
+ color: $unnnic-color-neutral-cloudy;
85
+ margin-bottom: $unnnic-space-1;
86
+ display: flex;
87
+ align-items: center;
88
+ gap: $unnnic-space-2;
89
+
90
+ &--fixed {
91
+ margin-top: -$unnnic-font-size-body-gt - $unnnic-space-2 + $unnnic-space-1;
92
+ }
108
93
 
109
- &:after {
110
- content: ' ';
94
+ &--fixed {
95
+ margin-bottom: $unnnic-space-0;
111
96
  position: absolute;
112
- left: $unnnic-space-0;
113
- bottom: $unnnic-space-1 - $unnnic-border-width-thinner;
114
- width: 100%;
115
- height: $unnnic-border-width-thinner;
116
- background-color: $unnnic-color-white;
97
+ padding: $unnnic-space-0 $unnnic-space-1;
98
+ margin-left: $unnnic-space-2;
99
+
100
+ &:after {
101
+ content: ' ';
102
+ position: absolute;
103
+ left: $unnnic-space-0;
104
+ bottom: $unnnic-space-1 - $unnnic-border-width-thinner;
105
+ width: 100%;
106
+ height: $unnnic-border-width-thinner;
107
+ background-color: $unnnic-color-white;
108
+ }
117
109
  }
118
110
  }
119
- }
120
111
 
121
- &__message {
122
- &.error {
123
- color: $unnnic-color-fg-critical;
112
+ &__message {
113
+ &.error {
114
+ color: $unnnic-color-fg-critical;
115
+ }
124
116
  }
125
- }
126
117
 
127
- &__hints-container {
128
- display: flex;
129
- justify-content: space-between;
130
- margin-top: $unnnic-space-1;
131
- font: $unnnic-font-caption-2;
132
- color: $unnnic-color-fg-base;
133
- }
118
+ &__hints-container {
119
+ display: flex;
120
+ justify-content: space-between;
121
+ margin-top: $unnnic-space-1;
122
+ font: $unnnic-font-caption-2;
123
+ color: $unnnic-color-fg-base;
124
+ }
134
125
 
135
- &__message-container {
136
- display: flex;
137
- flex-direction: column;
138
- gap: $unnnic-space-1;
139
- }
126
+ &__message-container {
127
+ display: flex;
128
+ flex-direction: column;
129
+ gap: $unnnic-space-1;
130
+ }
140
131
 
141
- &--disabled .unnnic-form-element__label,
142
- &--disabled .unnnic-form-element__message {
143
- user-select: none;
132
+ &--disabled .unnnic-form-element__label,
133
+ &--disabled .unnnic-form-element__message {
134
+ user-select: none;
135
+ }
144
136
  }
145
- }
146
137
  </style>
@@ -4,16 +4,18 @@
4
4
  v-mask="mask"
5
5
  v-bind="attributes"
6
6
  :value="fullySanitize(modelValue)"
7
- :class="classes"
7
+ :class="[classes, { focus, 'use-focus-prop': useFocusProp }]"
8
8
  :type="nativeType"
9
+ :readonly="readonly"
9
10
  />
10
11
  <input
11
12
  v-else
12
13
  v-bind="attributes"
13
14
  :value="fullySanitize(modelValue)"
14
- :class="classes"
15
+ :class="[classes, { focus, 'use-focus-prop': useFocusProp }]"
15
16
  :type="nativeType"
16
17
  :maxlength="maxlength"
18
+ :readonly="readonly"
17
19
  />
18
20
  </template>
19
21
 
@@ -49,15 +51,25 @@ export default {
49
51
  },
50
52
  hasIconLeft: Boolean,
51
53
  hasIconRight: Boolean,
54
+ hasClearIcon: Boolean,
52
55
  maxlength: {
53
56
  type: Number,
54
57
  default: null,
55
58
  },
59
+ readonly: {
60
+ type: Boolean,
61
+ default: false,
62
+ },
63
+ useFocusProp: {
64
+ type: Boolean,
65
+ default: false,
66
+ },
67
+ focus: {
68
+ type: Boolean,
69
+ default: false,
70
+ },
56
71
  },
57
72
  emits: ['update:modelValue'],
58
- data() {
59
- return {};
60
- },
61
73
  computed: {
62
74
  attributes() {
63
75
  return {
@@ -77,6 +89,7 @@ export default {
77
89
  {
78
90
  'input--has-icon-left': this.hasIconLeft,
79
91
  'input--has-icon-right': this.hasIconRight,
92
+ 'input--has-clear-icon': this.hasClearIcon,
80
93
  },
81
94
  ];
82
95
  },
@@ -117,6 +130,13 @@ export default {
117
130
 
118
131
  &.input--has-icon-right {
119
132
  padding-right: $unnnic-space-10;
133
+ &.input--has-clear-icon {
134
+ padding-right: $unnnic-space-10 + $unnnic-space-6;
135
+ }
136
+ }
137
+
138
+ &.input--has-clear-icon {
139
+ padding-right: $unnnic-space-10;
120
140
  }
121
141
 
122
142
  &.error {
@@ -11,7 +11,8 @@
11
11
 
12
12
  transition: border-color 0.1s ease-in-out;
13
13
 
14
- &:focus {
14
+ &:focus:not(.use-focus-prop),
15
+ &.focus {
15
16
  border-color: $unnnic-color-border-active;
16
17
  }
17
18
 
@@ -13,6 +13,8 @@
13
13
  v-bind="$attrs"
14
14
  v-model="val"
15
15
  class="unnnic-form-input"
16
+ :useFocusProp="useFocusProp"
17
+ :focus="focus"
16
18
  :placeholder="placeholder"
17
19
  :iconLeft="iconLeft"
18
20
  :iconRight="iconRight"
@@ -25,6 +27,9 @@
25
27
  :nativeType="nativeType"
26
28
  :maxlength="maxlength"
27
29
  :disabled="disabled"
30
+ :readonly="readonly"
31
+ :showClear="showClear"
32
+ @clear="$emit('clear')"
28
33
  />
29
34
 
30
35
  <template
@@ -127,8 +132,26 @@ export default {
127
132
  type: Boolean,
128
133
  default: false,
129
134
  },
135
+ readonly: {
136
+ type: Boolean,
137
+ default: false,
138
+ },
139
+ useFocusProp: {
140
+ type: Boolean,
141
+ default: false,
142
+ },
143
+ focus: {
144
+ type: Boolean,
145
+ default: false,
146
+ },
147
+ showClear: {
148
+ type: Boolean,
149
+ default: false,
150
+ },
130
151
  },
131
- emits: ['update:modelValue'],
152
+
153
+ emits: ['update:modelValue', 'clear'],
154
+
132
155
  data() {
133
156
  return {
134
157
  val: this.modelValue,
@@ -12,9 +12,11 @@
12
12
  class="input-itself"
13
13
  :hasIconLeft="!!iconLeft"
14
14
  :hasIconRight="!!iconRight || allowTogglePassword"
15
+ :hasClearIcon="showClear"
15
16
  :maxlength="maxlength"
16
- @focus="onFocus"
17
- @blur="onBlur"
17
+ :readonly="readonly"
18
+ :useFocusProp="useFocusProp"
19
+ :focus="focus"
18
20
  />
19
21
 
20
22
  <UnnnicIcon
@@ -27,18 +29,28 @@
27
29
  @click="onIconLeftClick"
28
30
  />
29
31
 
30
- <UnnnicIcon
31
- v-if="iconRightSvg"
32
- :scheme="iconScheme"
33
- :icon="iconRightSvg"
34
- size="ant"
35
- :clickable="iconRightClickable || allowTogglePassword"
36
- :class="[
37
- 'icon-right',
38
- { clickable: iconRightClickable || allowTogglePassword },
39
- ]"
40
- @click="onIconRightClick"
41
- />
32
+ <section class="icon-right-container">
33
+ <UnnnicIcon
34
+ v-if="showClear"
35
+ class="icon-clear"
36
+ :scheme="iconScheme"
37
+ icon="close"
38
+ size="ant"
39
+ clickable
40
+ @click.stop="onClearClick"
41
+ />
42
+
43
+ <UnnnicIcon
44
+ v-if="iconRightSvg"
45
+ :scheme="iconScheme"
46
+ :icon="iconRightSvg"
47
+ size="ant"
48
+ :clickable="iconRightClickable || allowTogglePassword"
49
+ class="icon-right"
50
+ :class="{ clickable: iconRightClickable || allowTogglePassword }"
51
+ @click="onIconRightClick"
52
+ />
53
+ </section>
42
54
  </div>
43
55
  </template>
44
56
 
@@ -103,8 +115,24 @@ export default {
103
115
  type: Boolean,
104
116
  default: false,
105
117
  },
118
+ readonly: {
119
+ type: Boolean,
120
+ default: false,
121
+ },
122
+ useFocusProp: {
123
+ type: Boolean,
124
+ default: false,
125
+ },
126
+ focus: {
127
+ type: Boolean,
128
+ default: false,
129
+ },
130
+ showClear: {
131
+ type: Boolean,
132
+ default: false,
133
+ },
106
134
  },
107
- emits: ['icon-left-click', 'icon-right-click'],
135
+ emits: ['icon-left-click', 'icon-right-click', 'clear'],
108
136
  data() {
109
137
  return {
110
138
  isFocused: false,
@@ -128,7 +156,6 @@ export default {
128
156
  if (this.isDisabled) {
129
157
  return 'fg-muted';
130
158
  }
131
-
132
159
  return 'fg-base';
133
160
  },
134
161
 
@@ -138,7 +165,7 @@ export default {
138
165
  },
139
166
 
140
167
  methods: {
141
- focus() {
168
+ focusInput() {
142
169
  this.$refs['base-input'].$el.focus();
143
170
  },
144
171
 
@@ -154,6 +181,10 @@ export default {
154
181
  if (this.iconLeftClickable) this.$emit('icon-left-click');
155
182
  },
156
183
 
184
+ onClearClick() {
185
+ this.$emit('clear');
186
+ },
187
+
157
188
  onIconRightClick() {
158
189
  if (this.attributes.disabled) return;
159
190
  if (this.allowTogglePassword) this.showPassword = !this.showPassword;
@@ -171,25 +202,33 @@ export default {
171
202
  }
172
203
 
173
204
  .icon {
174
- &-left,
175
- &-right {
176
- &:not(.clickable) {
177
- pointer-events: none;
178
- }
179
- }
180
-
181
205
  &-left {
182
206
  position: absolute;
183
207
  top: 50%;
184
208
  transform: translateY(-50%);
185
209
  left: $unnnic-space-4;
210
+
211
+ &:not(.clickable) {
212
+ pointer-events: none;
213
+ }
186
214
  }
187
215
 
188
- &-right {
216
+ &-right-container {
189
217
  position: absolute;
190
218
  top: 50%;
191
219
  transform: translateY(-50%);
192
220
  right: $unnnic-space-4;
221
+
222
+ display: flex;
223
+ align-items: center;
224
+ gap: $unnnic-space-2;
225
+
226
+ .icon-clear {
227
+ cursor: pointer;
228
+ }
229
+ .icon-right:not(.clickable) {
230
+ pointer-events: none;
231
+ }
193
232
  }
194
233
  }
195
234
  </style>
@@ -129,7 +129,7 @@ describe('TextInput.vue', () => {
129
129
 
130
130
  test('focus method calls focus on base input element', () => {
131
131
  const focusSpy = vi.spyOn(wrapper.vm.$refs['base-input'].$el, 'focus');
132
- wrapper.vm.focus();
132
+ wrapper.vm.focusInput();
133
133
 
134
134
  expect(focusSpy).toHaveBeenCalled();
135
135
  focusSpy.mockRestore();
@@ -6,7 +6,11 @@ exports[`Input.vue > matches the snapshot 1`] = `
6
6
  <p data-v-7f222291="" class="unnnic-label__label">Sample Label</p>
7
7
  <!--v-if-->
8
8
  </section>
9
- <div data-v-a0d36167="" data-v-d890ad85="" class="text-input size--md unnnic-form-input" hascloudycolor="false" mask="####-####"><input data-v-86533b41="" data-v-a0d36167="" class="unnnic-form-input input-itself input size-md normal input--has-icon-left input--has-icon-right unnnic-form-input input-itself" hascloudycolor="false" placeholder="Enter text" iconleft="search" iconright="clear" iconleftclickable="true" iconrightclickable="true" type="text" value=""><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-left clickable" data-testid="material-icon" translate="no">search</span><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-right clickable" data-testid="material-icon" translate="no">clear</span></div>
9
+ <div data-v-a0d36167="" data-v-d890ad85="" class="text-input size--md unnnic-form-input" hascloudycolor="false" mask="####-####"><input data-v-86533b41="" data-v-a0d36167="" class="unnnic-form-input input-itself input size-md normal input--has-icon-left input--has-icon-right unnnic-form-input input-itself" hascloudycolor="false" placeholder="Enter text" iconleft="search" iconright="clear" iconleftclickable="true" iconrightclickable="true" showclear="false" type="text" value=""><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-left clickable" data-testid="material-icon" translate="no">search</span>
10
+ <section data-v-a0d36167="" class="icon-right-container">
11
+ <!--v-if--><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-right clickable" data-testid="material-icon" translate="no">clear</span>
12
+ </section>
13
+ </div>
10
14
  <section data-v-9f8d6c86="" class="unnnic-form-element__hints-container">
11
15
  <section data-v-9f8d6c86="" class="unnnic-form-element__message-container">
12
16
  <p data-v-9f8d6c86="" class="unnnic-form-element__message">Error message</p>
@@ -1,3 +1,9 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`TextInput.vue > matches the snapshot 1`] = `"<div data-v-a0d36167="" class="text-input size--md"><input data-v-86533b41="" data-v-a0d36167="" placeholder="Enter text" iconleft="search" iconright="clear" iconleftclickable="true" iconrightclickable="true" allowtogglepassword="false" class="input-itself input size-md normal input--has-icon-left input--has-icon-right input-itself" type="text" value=""><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-left clickable" data-testid="material-icon" translate="no">search</span><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-right clickable" data-testid="material-icon" translate="no">clear</span></div>"`;
3
+ exports[`TextInput.vue > matches the snapshot 1`] = `
4
+ "<div data-v-a0d36167="" class="text-input size--md"><input data-v-86533b41="" data-v-a0d36167="" placeholder="Enter text" iconleft="search" iconright="clear" iconleftclickable="true" iconrightclickable="true" allowtogglepassword="false" showclear="false" class="input-itself input size-md normal input--has-icon-left input--has-icon-right input-itself" type="text" value=""><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-left clickable" data-testid="material-icon" translate="no">search</span>
5
+ <section data-v-a0d36167="" class="icon-right-container">
6
+ <!--v-if--><span data-v-26446d8e="" data-v-a0d36167="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic-icon__size--ant unnnic--clickable icon-right clickable" data-testid="material-icon" translate="no">clear</span>
7
+ </section>
8
+ </div>"
9
+ `;