@weni/unnnic-system 3.12.6-alpha-teleports.0 → 3.12.8-alpha.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 (78) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/CHANGELOG.md +1080 -0
  3. package/README.md +1 -9
  4. package/dist/{es-ebc7770b.mjs → es-52edeb71.mjs} +1 -1
  5. package/dist/{index-f117a889.mjs → index-756fe685.mjs} +9070 -8660
  6. package/dist/index.d.ts +1013 -311
  7. package/dist/{pt-br-b1a08da0.mjs → pt-br-24583c8c.mjs} +1 -1
  8. package/dist/style.css +1 -1
  9. package/dist/unnnic.mjs +181 -177
  10. package/dist/unnnic.umd.js +33 -33
  11. package/package.json +1 -1
  12. package/src/assets/scss/scheme-colors.scss +223 -223
  13. package/src/components/Alert/__tests__/__snapshots__/Alert.spec.js.snap +1 -1
  14. package/src/components/ChartFunnel/DefaultFunnel/ChartDefaultFunnelBase.vue +1 -2
  15. package/src/components/ChartFunnel/SvgFunnel/ChartFunnelTwoRows.vue +60 -61
  16. package/src/components/Checkbox/Checkbox.vue +9 -3
  17. package/src/components/CheckboxGroup/CheckboxGroup.vue +7 -5
  18. package/src/components/Chip/Chip.vue +1 -1
  19. package/src/components/Drawer/Drawer.vue +20 -9
  20. package/src/components/Drawer/__tests__/Drawer.spec.js +11 -9
  21. package/src/components/Drawer/__tests__/__snapshots__/Drawer.spec.js.snap +9 -9
  22. package/src/components/FormElement/FormElement.vue +97 -88
  23. package/src/components/Input/BaseInput.vue +25 -5
  24. package/src/components/Input/Input.scss +2 -3
  25. package/src/components/Input/Input.vue +26 -3
  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/ModalDialog/ModalDialog.vue +11 -4
  31. package/src/components/MultiSelect/MultSelectOption.vue +49 -0
  32. package/src/components/MultiSelect/__tests__/MultiSelect.spec.js +557 -0
  33. package/src/components/MultiSelect/__tests__/MultiSelectOption.spec.js +229 -0
  34. package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelect.spec.js.snap +87 -0
  35. package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelectOption.spec.js.snap +51 -0
  36. package/src/components/MultiSelect/index.vue +265 -0
  37. package/src/components/Radio/Radio.vue +13 -7
  38. package/src/components/Radio/__test__/Radio.spec.js +3 -1
  39. package/src/components/RadioGroup/RadioGroup.vue +18 -10
  40. package/src/components/Select/__tests__/Select.spec.js +422 -0
  41. package/src/components/Select/__tests__/SelectItem.spec.js +330 -0
  42. package/src/components/Select/__tests__/__snapshots__/Popover.spec.js.snap +8 -0
  43. package/src/components/Select/__tests__/__snapshots__/Select.spec.js.snap +71 -0
  44. package/src/components/Select/__tests__/__snapshots__/SelectItem.spec.js.snap +15 -0
  45. package/src/components/Select/__tests__/__snapshots__/SelectOption.spec.js.snap +25 -0
  46. package/src/components/Select/__tests__/__snapshots__/SelectPopover.spec.js.snap +8 -0
  47. package/src/components/Select/index.vue +308 -0
  48. package/src/components/Switch/Switch.vue +11 -4
  49. package/src/components/TemplatePreview/TemplatePreview.vue +30 -27
  50. package/src/components/TemplatePreview/TemplatePreviewModal.vue +11 -11
  51. package/src/components/TemplatePreview/types.d.ts +3 -3
  52. package/src/components/Toast/Toast.vue +13 -9
  53. package/src/components/Toast/ToastManager.ts +1 -4
  54. package/src/components/Toast/__tests__/ToastManager.spec.js +6 -10
  55. package/src/components/ToolTip/ToolTip.vue +1 -1
  56. package/src/components/index.ts +10 -6
  57. package/src/components/ui/dialog/DialogContent.vue +5 -5
  58. package/src/components/ui/drawer/DrawerContent.vue +2 -4
  59. package/src/components/ui/popover/PopoverContent.vue +29 -13
  60. package/src/components/ui/popover/PopoverOption.vue +5 -1
  61. package/src/components/ui/tooltip/TooltipContent.vue +2 -5
  62. package/src/components/ui/tooltip/TooltipTrigger.vue +4 -2
  63. package/src/index.ts +2 -9
  64. package/src/lib/layer-manager.ts +52 -24
  65. package/src/locales/en.json +3 -1
  66. package/src/locales/es.json +3 -1
  67. package/src/locales/pt_br.json +3 -1
  68. package/src/stories/Input.mdx +3 -0
  69. package/src/stories/LayerManager.docs.mdx +9 -9
  70. package/src/stories/LayerManager.stories.js +11 -54
  71. package/src/stories/MultiSelect.stories.js +143 -45
  72. package/src/stories/Popover.stories.js +5 -0
  73. package/src/stories/Select.stories.js +161 -0
  74. package/src/stories/TemplatePreview.stories.js +27 -27
  75. package/src/stories/TemplatePreviewModal.stories.js +31 -31
  76. package/src/components/MultiSelect/MultiSelect.vue +0 -297
  77. package/src/lib/__tests__/teleport-target.spec.ts +0 -73
  78. package/src/lib/teleport-target.ts +0 -46
@@ -1,7 +1,12 @@
1
1
  <!-- eslint-disable vue/multi-word-component-names -->
2
2
  <template>
3
3
  <section class="unnnic-checkbox">
4
- <label :class="['unnnic-checkbox__input-wrapper', {'unnnic-checkbox__input-wrapper--disabled': disabled}]">
4
+ <label
5
+ :class="[
6
+ 'unnnic-checkbox__input-wrapper',
7
+ { 'unnnic-checkbox__input-wrapper--disabled': disabled },
8
+ ]"
9
+ >
5
10
  <input
6
11
  :class="[
7
12
  'unnnic-checkbox__input',
@@ -10,8 +15,8 @@
10
15
  type="checkbox"
11
16
  :disabled="disabled"
12
17
  :checked="modelValue === 'less' || modelValue"
13
- @change="click"
14
18
  v-bind="pick($attrs, ['id', 'name'])"
19
+ @change="click"
15
20
  />
16
21
 
17
22
  <p
@@ -150,7 +155,8 @@ $checkbox-size: 21px;
150
155
  }
151
156
  }
152
157
 
153
- &:disabled, &:disabled:checked {
158
+ &:disabled,
159
+ &:disabled:checked {
154
160
  background-color: $unnnic-color-bg-muted;
155
161
  border: 1px solid $unnnic-color-border-muted;
156
162
 
@@ -1,8 +1,10 @@
1
1
  <template>
2
- <section :class="[
3
- 'unnnic-checkbox-group__container',
4
- `unnnic-checkbox-group--state-${state}`,
5
- ]">
2
+ <section
3
+ :class="[
4
+ 'unnnic-checkbox-group__container',
5
+ `unnnic-checkbox-group--state-${state}`,
6
+ ]"
7
+ >
6
8
  <UnnnicLabel
7
9
  v-if="label"
8
10
  :label="label"
@@ -52,7 +54,7 @@ const props = defineProps({
52
54
  },
53
55
  });
54
56
  </script>
55
-
57
+
56
58
  <style lang="scss" scoped>
57
59
  @use '@/assets/scss/unnnic' as *;
58
60
 
@@ -80,7 +80,7 @@ const chipClass = computed(() => {
80
80
  border-radius: 600px;
81
81
  background-color: $unnnic-color-bg-base;
82
82
  border: 1px solid transparent;
83
-
83
+
84
84
  &:hover {
85
85
  background-color: $unnnic-color-bg-soft;
86
86
  }
@@ -10,11 +10,15 @@
10
10
  :showOverlay="!withoutOverlay"
11
11
  data-testid="drawer-container"
12
12
  :size="mappedSize"
13
- :class="[
14
- 'unnnic-drawer__container',
15
- `unnnic-drawer__container--${size}`,
16
- props.class,
17
- ].filter(Boolean).join(' ')"
13
+ :class="
14
+ [
15
+ 'unnnic-drawer__container',
16
+ `unnnic-drawer__container--${size}`,
17
+ props.class,
18
+ ]
19
+ .filter(Boolean)
20
+ .join(' ')
21
+ "
18
22
  >
19
23
  <DrawerHeader class="unnnic-drawer__header">
20
24
  <section class="unnnic-drawer__title-container">
@@ -91,7 +95,7 @@
91
95
  import { computed } from 'vue';
92
96
 
93
97
  import UnnnicButton from '../Button/Button.vue';
94
- import {
98
+ import {
95
99
  Drawer,
96
100
  DrawerContent,
97
101
  DrawerHeader,
@@ -172,15 +176,22 @@ const props = defineProps({
172
176
  },
173
177
  });
174
178
 
175
- const emit = defineEmits(['primaryButtonClick', 'secondaryButtonClick', 'close', 'back']);
176
- const showFooter = computed(() => !!(props.primaryButtonText || props.secondaryButtonText));
179
+ const emit = defineEmits([
180
+ 'primaryButtonClick',
181
+ 'secondaryButtonClick',
182
+ 'close',
183
+ 'back',
184
+ ]);
185
+ const showFooter = computed(
186
+ () => !!(props.primaryButtonText || props.secondaryButtonText),
187
+ );
177
188
  const mappedSize = computed(() => {
178
189
  const sizes = {
179
190
  md: 'medium',
180
191
  lg: 'large',
181
192
  xl: 'extra-large',
182
193
  gt: 'giant',
183
- }
194
+ };
184
195
  return sizes[props.size] || 'medium';
185
196
  });
186
197
 
@@ -35,7 +35,7 @@ describe('Drawer.vue', () => {
35
35
 
36
36
  const element = (id) => wrapper.find(`[data-testid="${id}"]`);
37
37
  const component = (id) => wrapper.findComponent(`[data-testid="${id}"]`);
38
- const drawer = () => element('drawer');
38
+ const drawerRoot = () => wrapper.findComponent({ name: 'UnnnicDrawerNext' });
39
39
  const title = () => element('drawer-title');
40
40
  const description = () => element('drawer-description');
41
41
  const primaryButton = () => component('primary-button');
@@ -43,6 +43,8 @@ describe('Drawer.vue', () => {
43
43
  const footer = () => element('footer');
44
44
  const closeIcon = () => component('close-icon');
45
45
  const drawerContainer = () => element('drawer-container');
46
+ const drawerContentComponent = () =>
47
+ wrapper.findComponent({ name: 'UnnnicDrawerContent' });
46
48
 
47
49
  describe('Component Rendering', () => {
48
50
  describe('Component Rendering', () => {
@@ -51,23 +53,21 @@ describe('Drawer.vue', () => {
51
53
  });
52
54
 
53
55
  it('should render the drawer when modelValue is true', () => {
54
- expect(drawer().attributes('open')).toBe('true');
56
+ expect(drawerRoot().props('open')).toBe(true);
55
57
  });
56
58
 
57
59
  it('should not render the drawer when modelValue is false', async () => {
58
60
  await wrapper.setProps({ modelValue: false });
59
- expect(drawer().attributes('open')).toBe('false');
61
+ expect(drawerRoot().props('open')).toBe(false);
60
62
  });
61
63
 
62
64
  it('should render the overlay when withoutOverlay is false', () => {
63
- console.log('wrapper.html()', wrapper.html());
64
-
65
- expect(drawerContainer().attributes('showoverlay')).toBe('true');
65
+ expect(drawerContentComponent().props('showOverlay')).toBe(true);
66
66
  });
67
67
 
68
68
  it('should not render the overlay when withoutOverlay is true', async () => {
69
69
  await wrapper.setProps({ withoutOverlay: true });
70
- expect(drawerContainer().attributes('showoverlay')).toBe('false');
70
+ expect(drawerContentComponent().props('showOverlay')).toBe(false);
71
71
  });
72
72
 
73
73
  it('should display the title and description correctly', () => {
@@ -217,14 +217,16 @@ describe('Drawer.vue', () => {
217
217
  describe('Props and Computed Properties', () => {
218
218
  it('should render the correct size class based on size prop', async () => {
219
219
  await wrapper.setProps({ size: 'lg' });
220
- expect(drawerContainer().classes()).toContain(
220
+ expect(drawerContentComponent().props('class')).toContain(
221
221
  'unnnic-drawer__container--lg',
222
222
  );
223
+ expect(drawerContentComponent().props('size')).toBe('large');
223
224
 
224
225
  await wrapper.setProps({ size: 'xl' });
225
- expect(drawerContainer().classes()).toContain(
226
+ expect(drawerContentComponent().props('class')).toContain(
226
227
  'unnnic-drawer__container--xl',
227
228
  );
229
+ expect(drawerContentComponent().props('size')).toBe('extra-large');
228
230
  });
229
231
 
230
232
  it('should display footer if either primaryButtonText or secondaryButtonText is provided', async () => {
@@ -1,22 +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
- "<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">
4
+ "<div data-v-e761d31f="" data-v-196de012="" disabled="false" defer="false" forcemount="false" data-testid="drawer-container">
5
+ <div data-v-7f241b30="" data-v-e761d31f="" data-state="open" style="pointer-events: auto;" data-vaul-overlay="" data-vaul-snap-points="false" data-vaul-snap-points-overlay="true" class="unnnic-drawer__overlay"></div>
6
+ <div data-v-e761d31f="" data-dismissable-layer="" style="--snap-point-height: 0; --initial-transform: calc(100% + 8px); pointer-events: auto;" tabindex="-1" data-vaul-drawer="" data-vaul-drawer-direction="right" data-vaul-delayed-snap-points="false" data-vaul-snap-points="false" size="medium" showoverlay="true" class="unnnic-drawer__content unnnic-drawer__content--medium unnnic-drawer__container unnnic-drawer__container--md" id="" role="dialog" aria-describedby="reka-dialog-description-v-1" aria-labelledby="reka-dialog-title-v-0" data-state="open">
6
7
  <header data-v-39d0dfb8="" data-v-196de012="" class="unnnic-drawer__header unnnic-drawer__header">
7
8
  <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="">
9
+ <h2 data-v-97709962="" data-v-196de012="" id="reka-dialog-title-v-0" class="unnnic-drawer__title unnnic-drawer__title" data-testid="drawer-title">Test Title</h2>
10
+ <p data-v-750ea255="" data-v-196de012="" id="reka-dialog-description-v-1" class="unnnic-drawer__description unnnic-drawer__description" data-testid="drawer-description">Test Description</p>
11
+ </section><button data-v-4a771f40="" data-v-196de012="" type="button" class="unnnic-drawer__close">
12
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>
13
+ </button>
14
14
  </header>
15
15
  <section data-v-196de012="" class="unnnic-drawer__content"></section>
16
- <div data-v-196de012="" class="unnnic-drawer__footer" data-testid="footer">
16
+ <footer data-v-02ebc5b4="" data-v-196de012="" class="unnnic-drawer__footer unnnic-drawer__footer" data-testid="footer">
17
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
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>
19
+ </footer>
20
20
  </div>
21
21
  </div>"
22
22
  `;
@@ -1,28 +1,37 @@
1
1
  <template>
2
- <section class="unnnic-form-element" :class="{ 'unnnic-form-element--disabled': disabled }">
3
- <UnnnicLabel
4
- v-if="label"
5
- :label="label"
2
+ <section
3
+ class="unnnic-form-element"
4
+ :class="{ 'unnnic-form-element--disabled': disabled }"
5
+ >
6
+ <UnnnicLabel
7
+ v-if="label"
8
+ :label="label"
6
9
  :tooltip="tooltip"
7
10
  :class="[
8
11
  'unnnic-form-element__label',
9
12
  {
10
13
  'unnnic-form-element__label--fixed': fixedLabel,
11
14
  },
12
- ]"
15
+ ]"
13
16
  />
14
17
 
15
18
  <slot></slot>
16
19
 
17
- <section
18
- class="unnnic-form-element__hints-container"
20
+ <section
19
21
  v-if="message || error || !!$slots.rightMessage"
22
+ class="unnnic-form-element__hints-container"
20
23
  >
21
24
  <section class="unnnic-form-element__message-container">
22
- <p v-if="message" class="unnnic-form-element__message">
25
+ <p
26
+ v-if="message"
27
+ class="unnnic-form-element__message"
28
+ >
23
29
  {{ fullySanitize(message) }}
24
30
  </p>
25
- <p v-if="!!error?.length" class="unnnic-form-element__message error">
31
+ <p
32
+ v-if="!!error?.length"
33
+ class="unnnic-form-element__message error"
34
+ >
26
35
  {{ Array.isArray(error) ? error.join(', ') : error }}
27
36
  </p>
28
37
  </section>
@@ -34,104 +43,104 @@
34
43
  </template>
35
44
 
36
45
  <script lang="js">
37
- import { fullySanitize } from '../../utils/sanitize';
38
- import UnnnicLabel from '../Label/Label.vue';
39
-
40
- export default {
41
- components: {
42
- UnnnicLabel,
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),
43
58
  },
44
- props: {
45
- size: {
46
- type: String,
47
- default: 'md',
48
- validator: (size) => ['md', 'sm'].includes(size),
49
- },
50
59
 
51
- label: { type: String, default: '' },
60
+ label: { type: String, default: '' },
52
61
 
53
- fixedLabel: { type: Boolean, default: false },
62
+ fixedLabel: { type: Boolean, default: false },
54
63
 
55
- error: {
56
- type: [Boolean, String],
57
- default: false,
58
- },
64
+ error: {
65
+ type: [Boolean, String],
66
+ default: false,
67
+ },
59
68
 
60
- message: { type: String, default: '' },
69
+ message: { type: String, default: '' },
61
70
 
62
- disabled: { type: Boolean, default: false },
71
+ disabled: { type: Boolean, default: false },
63
72
 
64
- tooltip: { type: String, default: '' },
65
- },
66
- methods: {
67
- fullySanitize,
68
- },
69
- };
73
+ tooltip: { type: String, default: '' },
74
+ },
75
+ methods: {
76
+ fullySanitize,
77
+ },
78
+ };
70
79
  </script>
71
80
 
72
81
  <style lang="scss" scoped>
73
- @use '@/assets/scss/unnnic' as *;
74
-
75
- * {
76
- margin: $unnnic-space-0;
77
- padding: $unnnic-space-0;
78
- box-sizing: border-box;
79
- }
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
+ }
80
102
 
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
- }
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;
93
108
 
94
- &--fixed {
95
- margin-bottom: $unnnic-space-0;
109
+ &:after {
110
+ content: ' ';
96
111
  position: absolute;
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
- }
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;
109
117
  }
110
118
  }
119
+ }
111
120
 
112
- &__message {
113
- &.error {
114
- color: $unnnic-color-fg-critical;
115
- }
121
+ &__message {
122
+ &.error {
123
+ color: $unnnic-color-fg-critical;
116
124
  }
125
+ }
117
126
 
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
- }
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
+ }
125
134
 
126
- &__message-container {
127
- display: flex;
128
- flex-direction: column;
129
- gap: $unnnic-space-1;
130
- }
135
+ &__message-container {
136
+ display: flex;
137
+ flex-direction: column;
138
+ gap: $unnnic-space-1;
139
+ }
131
140
 
132
- &--disabled .unnnic-form-element__label,
133
- &--disabled .unnnic-form-element__message {
134
- user-select: none;
135
- }
141
+ &--disabled .unnnic-form-element__label,
142
+ &--disabled .unnnic-form-element__message {
143
+ user-select: none;
136
144
  }
145
+ }
137
146
  </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 {
@@ -9,9 +9,8 @@
9
9
  caret-color: $unnnic-color-fg-muted;
10
10
  font: $unnnic-font-body;
11
11
 
12
- transition: border-color 0.1s ease-in-out;
13
-
14
- &:focus {
12
+ &:focus:not(.use-focus-prop),
13
+ &.focus {
15
14
  border-color: $unnnic-color-border-active;
16
15
  }
17
16
 
@@ -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
@@ -43,8 +48,8 @@ import UnnnicFormElement from '../FormElement/FormElement.vue';
43
48
 
44
49
  export default {
45
50
  name: 'UnnnicInput',
46
- components: {
47
- TextInput,
51
+ components: {
52
+ TextInput,
48
53
  UnnnicFormElement,
49
54
  },
50
55
  props: {
@@ -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,