@weni/unnnic-system 3.0.4 → 3.0.5-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 (40) hide show
  1. package/dist/components/DataTable/index.vue.d.ts +156 -0
  2. package/dist/components/DataTable/index.vue.d.ts.map +1 -0
  3. package/dist/components/DatePicker/DatePicker.vue.d.ts +2 -2
  4. package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts +3 -3
  5. package/dist/components/ModalDialog/ModalDialog.vue.d.ts +1 -1
  6. package/dist/components/ModalDialog/ModalDialog.vue.d.ts.map +1 -1
  7. package/dist/components/SelectSmart/SelectSmart.vue.d.ts +18 -0
  8. package/dist/components/SelectSmart/SelectSmart.vue.d.ts.map +1 -1
  9. package/dist/components/SelectSmart/SelectSmartOption.vue.d.ts +9 -0
  10. package/dist/components/SelectSmart/SelectSmartOption.vue.d.ts.map +1 -1
  11. package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts +9 -0
  12. package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts.map +1 -0
  13. package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts +15 -0
  14. package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts.map +1 -0
  15. package/dist/components/index.d.ts +263 -6
  16. package/dist/components/index.d.ts.map +1 -1
  17. package/dist/{es-91798705.mjs → es-e4780f92.mjs} +1 -1
  18. package/dist/{index-8110960e.mjs → index-c20c8a10.mjs} +9470 -9119
  19. package/dist/{pt-br-ca5eccc1.mjs → pt-br-9e604702.mjs} +1 -1
  20. package/dist/style.css +1 -1
  21. package/dist/unnnic.mjs +61 -58
  22. package/dist/unnnic.umd.js +44 -43
  23. package/package.json +2 -2
  24. package/src/assets/img/previews/doc-preview.png +0 -0
  25. package/src/assets/img/previews/image-preview.png +0 -0
  26. package/src/assets/img/previews/video-preview.png +0 -0
  27. package/src/components/DataTable/index.vue +493 -0
  28. package/src/components/ModalDialog/ModalDialog.vue +27 -29
  29. package/src/components/ModalDialog/__tests__/__snapshots__/ModalDialog.spec.js.snap +1 -1
  30. package/src/components/SelectSmart/SelectSmart.vue +22 -1
  31. package/src/components/SelectSmart/SelectSmartMultipleHeader.vue +1 -1
  32. package/src/components/SelectSmart/SelectSmartOption.vue +5 -0
  33. package/src/components/TemplatePreview/TemplatePreview.vue +249 -0
  34. package/src/components/TemplatePreview/TemplatePreviewModal.vue +51 -0
  35. package/src/components/TemplatePreview/types.d.ts +16 -0
  36. package/src/components/index.ts +9 -0
  37. package/src/stories/DataTable.stories.js +332 -0
  38. package/src/stories/SelectSmart.stories.js +1 -1
  39. package/src/stories/TemplatePreview.stories.js +94 -0
  40. package/src/stories/TemplatePreviewModal.stories.js +110 -0
@@ -86,6 +86,7 @@
86
86
  :active="
87
87
  option.value === modelValue || optionIsSelected(option)
88
88
  "
89
+ :disabled="optionIsSelected(option) && option.disableRemove"
89
90
  :focused="focusedOption && focusedOption.value === option.value"
90
91
  :allowCheckbox="!!multiple"
91
92
  :activeColor="type === 'secondary' ? 'secondary' : 'primary'"
@@ -142,6 +143,10 @@ export default {
142
143
  value: 'option1',
143
144
  label: 'Option1',
144
145
  },
146
+ {
147
+ value: 'option2',
148
+ label: 'Option2',
149
+ },
145
150
  ],
146
151
  },
147
152
  modelValue: {
@@ -203,6 +208,10 @@ export default {
203
208
  type: Boolean,
204
209
  default: false,
205
210
  },
211
+ multipleLimit: {
212
+ type: [Number, null],
213
+ default: null,
214
+ },
206
215
  },
207
216
 
208
217
  emits: ['update:searchValue', 'onChange', 'update:modelValue'],
@@ -363,11 +372,23 @@ export default {
363
372
 
364
373
  handleSelect(option) {
365
374
  if (option) {
366
- if (this.multiple && this.optionIsSelected(option)) {
375
+ if (
376
+ this.multiple &&
377
+ this.optionIsSelected(option) &&
378
+ !option.disableRemove
379
+ ) {
367
380
  this.unselectOption(option);
368
381
  return;
369
382
  }
370
383
 
384
+ if(this.multiple && option.disableRemove && this.optionIsSelected(option)) {
385
+ return;
386
+ }
387
+
388
+ if (this.multipleLimit && this.modelValue.length >= this.multipleLimit) {
389
+ return;
390
+ }
391
+
371
392
  this.selectOption(option);
372
393
  }
373
394
  },
@@ -10,7 +10,7 @@
10
10
  :key="option.value"
11
11
  class="unnnic-select-smart__options__multiple__selecteds__option"
12
12
  :text="option.label"
13
- hasCloseIcon
13
+ :hasCloseIcon="!option.disableRemove"
14
14
  @close="unselectOption(option)"
15
15
  />
16
16
  <p
@@ -19,6 +19,7 @@
19
19
  data-testid="checkbox"
20
20
  :modelValue="active"
21
21
  :size="size"
22
+ :disabled="disabled"
22
23
  />
23
24
  <div>
24
25
  <span
@@ -77,6 +78,10 @@ export default {
77
78
  type: Boolean,
78
79
  default: null,
79
80
  },
81
+ disabled: {
82
+ type: Boolean,
83
+ default: false,
84
+ },
80
85
  allowCheckbox: {
81
86
  type: Boolean,
82
87
  default: false,
@@ -0,0 +1,249 @@
1
+ <template>
2
+ <section class="unnnic-template-preview">
3
+ <section
4
+ :class="[
5
+ 'unnnic-template-preview__content',
6
+ { 'unnnic-template-preview__content--has-media': hasHeaderMedia },
7
+ ]"
8
+ >
9
+ <header
10
+ v-if="hasHeader"
11
+ :class="`unnnic-template-preview__header__${
12
+ template?.header.type === 'TEXT' ? 'text' : 'media'
13
+ }`"
14
+ >
15
+ <img
16
+ class="unnnic-template-preview__header__media__preview"
17
+ v-if="
18
+ template?.header.type === 'MEDIA' &&
19
+ template?.header.mediaType === 'IMAGE'
20
+ "
21
+ :src="template.header.src || imagePreview"
22
+ />
23
+ <template
24
+ v-else-if="
25
+ template?.header.type === 'MEDIA' &&
26
+ template?.header.mediaType === 'VIDEO'
27
+ "
28
+ >
29
+ <video
30
+ v-if="template.header.src"
31
+ class="unnnic-template-preview__header__media__preview"
32
+ :src="template.header.src"
33
+ controls
34
+ />
35
+ <img
36
+ v-else
37
+ class="unnnic-template-preview__header__media__preview"
38
+ :src="videoPreview"
39
+ />
40
+ </template>
41
+ <template
42
+ v-else-if="
43
+ template?.header.type === 'MEDIA' &&
44
+ template?.header.mediaType === 'DOCUMENT'
45
+ "
46
+ >
47
+ <img
48
+ class="unnnic-template-preview__header__media__preview"
49
+ :src="documentPreview"
50
+ />
51
+ </template>
52
+ <h1
53
+ class="unnnic-template-preview__header__text__preview"
54
+ v-else-if="template?.header.type === 'TEXT'"
55
+ >
56
+ {{ template.header.text }}
57
+ </h1>
58
+ </header>
59
+ <section
60
+ v-if="hasBody"
61
+ :class="[
62
+ 'unnnic-template-preview__body',
63
+ { 'unnnic-template-preview__body--has-media': hasHeaderMedia },
64
+ ]"
65
+ >
66
+ <section v-html="parsedBody"></section>
67
+ </section>
68
+ <footer
69
+ v-if="hasFooter"
70
+ :class="[
71
+ 'unnnic-template-preview__footer',
72
+ { 'unnnic-template-preview__footer--has-media': hasHeaderMedia },
73
+ ]"
74
+ >
75
+ {{ template?.footer }}
76
+ </footer>
77
+ </section>
78
+ <footer v-if="hasButtons" class="unnnic-template-preview__buttons">
79
+ <section
80
+ v-for="(button, index) in template?.buttons"
81
+ :key="`button-${index}`"
82
+ class="unnnic-template-preview__buttons__button"
83
+ >
84
+ <UnnnicIcon
85
+ class="unnnic-template-preview__buttons__button__icon"
86
+ :icon="getButtonIcon(button.type)"
87
+ scheme="aux-blue-500"
88
+ size="ant"
89
+ />
90
+ <p class="unnnic-template-preview__buttons__button__text">
91
+ {{ button.text }}
92
+ </p>
93
+ </section>
94
+ </footer>
95
+ </section>
96
+ </template>
97
+
98
+ <script lang="ts" setup>
99
+ import { computed } from "vue";
100
+
101
+ import type { Template } from "./types";
102
+
103
+ import imagePreview from "../../assets/img/previews/image-preview.png";
104
+ import documentPreview from "../../assets/img/previews/doc-preview.png";
105
+ import videoPreview from "../../assets/img/previews/video-preview.png";
106
+
107
+ import UnnnicIcon from "../Icon.vue";
108
+
109
+ interface Props {
110
+ template?: Template | null;
111
+ }
112
+
113
+ const props = withDefaults(defineProps<Props>(), {
114
+ template: null,
115
+ });
116
+
117
+ const hasHeader = computed(
118
+ () => props.template?.header && props.template.header.type
119
+ );
120
+ const hasHeaderMedia = computed(
121
+ () => !!props.template?.header && props.template.header.type === "MEDIA"
122
+ );
123
+ const hasBody = computed(
124
+ () => !!props.template?.body && props.template.body.length > 0
125
+ );
126
+ const hasFooter = computed(
127
+ () => !!props.template?.footer && props.template.footer.length > 0
128
+ );
129
+ const hasButtons = computed(
130
+ () => !!props.template?.buttons && props.template.buttons.length > 0
131
+ );
132
+ const parsedBody = computed(() => {
133
+ if (!hasBody.value) return "";
134
+
135
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
136
+ const result = props
137
+ .template!.body!.replaceAll("\n", "<br/>")
138
+ .replaceAll(/(?:\*)([^*<\n]+)(?:\*)/g, "<strong>$1</strong>")
139
+ .replaceAll(/(?:_)([^_<\n]+)(?:_)/g, "<i>$1</i>")
140
+ .replaceAll(/(?:~)([^~<\n]+)(?:~)/g, "<s>$1</s>")
141
+ .replaceAll(/(?:```)([^```<\n]+)(?:```)/g, "<tt>$1</tt>")
142
+ .replaceAll(/{{.*?}}/g, (match) => `<strong>${match}</strong>`);
143
+
144
+ return result;
145
+ });
146
+
147
+ const getButtonIcon = (buttonType) => {
148
+ const buttonMapper = {
149
+ PHONE_NUMBER: "phone",
150
+ URL: "open_in_new",
151
+ COPY_CODE: "content_copy",
152
+ FLOW: "",
153
+ QUICK_REPLY: "reply",
154
+ };
155
+
156
+ return buttonMapper[buttonType] || "";
157
+ };
158
+ </script>
159
+
160
+ <style lang="scss" scoped>
161
+ @use "@/assets/scss/unnnic" as *;
162
+
163
+ .unnnic-template-preview {
164
+ display: flex;
165
+ flex-direction: column;
166
+ box-shadow: $unnnic-shadow-level-near;
167
+ background-color: $unnnic-color-background-white;
168
+ width: 368px;
169
+ border-radius: $unnnic-border-radius-md;
170
+
171
+ &__content {
172
+ display: flex;
173
+ flex-direction: column;
174
+ gap: $unnnic-space-3;
175
+ padding: $unnnic-space-4 $unnnic-space-3;
176
+
177
+ &--has-media {
178
+ padding: $unnnic-space-1;
179
+ }
180
+ }
181
+
182
+ &__header {
183
+ &__text {
184
+ &__preview {
185
+ font-family: $unnnic-font-family-secondary;
186
+ font-weight: $unnnic-font-weight-bold;
187
+ font-size: $unnnic-font-size-body-gt;
188
+ line-height: $unnnic-font-size-body-gt + $unnnic-line-height-medium;
189
+ color: $unnnic-color-neutral-dark;
190
+
191
+ margin: $unnnic-space-0;
192
+ }
193
+ }
194
+
195
+ &__media {
196
+ &__preview {
197
+ width: 100%;
198
+ object-fit: cover;
199
+ }
200
+ }
201
+ }
202
+
203
+ &__body {
204
+ font-family: $unnnic-font-family-secondary;
205
+ font-weight: $unnnic-font-weight-regular;
206
+ font-size: $unnnic-font-size-body-gt;
207
+ line-height: $unnnic-font-size-body-gt + $unnnic-line-height-medium;
208
+ color: $unnnic-color-neutral-cloudy;
209
+
210
+ &--has-media {
211
+ padding: $unnnic-space-0 $unnnic-space-2;
212
+ }
213
+ }
214
+
215
+ &__footer {
216
+ font-family: $unnnic-font-family-secondary;
217
+ font-weight: $unnnic-font-weight-regular;
218
+ font-size: $unnnic-font-size-body-md;
219
+ line-height: $unnnic-font-size-body-md + $unnnic-line-height-medium;
220
+ color: $unnnic-color-neutral-clean;
221
+
222
+ &--has-media {
223
+ padding: $unnnic-space-0 $unnnic-space-3 $unnnic-space-2;
224
+ }
225
+ }
226
+
227
+ &__buttons {
228
+ font-family: $unnnic-font-family-secondary;
229
+ font-weight: $unnnic-font-weight-bold;
230
+ font-size: $unnnic-font-size-body-gt;
231
+ line-height: $unnnic-font-size-body-gt + $unnnic-line-height-medium;
232
+
233
+ &__button {
234
+ margin: 0;
235
+ display: flex;
236
+ align-items: center;
237
+ justify-content: center;
238
+ gap: $unnnic-space-2;
239
+ padding: $unnnic-space-3;
240
+ border-top: 1px solid $unnnic-color-neutral-light;
241
+
242
+ &__text {
243
+ color: $unnnic-color-aux-blue-500;
244
+ margin: $unnnic-space-0;
245
+ }
246
+ }
247
+ }
248
+ }
249
+ </style>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <UnnnicModalDialog
3
+ :model-value="modelValue"
4
+ @update:modelValue="$event === false && $emit('close')"
5
+ :title="defaultTranslations.title[props.locale]"
6
+ :show-close-icon="true"
7
+ class="unnnic-template-preview-modal"
8
+ >
9
+ <UnnnicTemplatePreview :template="template" />
10
+ </UnnnicModalDialog>
11
+ </template>
12
+
13
+ <script lang="ts" setup>
14
+ import UnnnicTemplatePreview from "./TemplatePreview.vue";
15
+ import UnnnicModalDialog from "../ModalDialog/ModalDialog.vue";
16
+
17
+ import type { Template } from "./types";
18
+
19
+ const defaultTranslations = {
20
+ title: {
21
+ "pt-br": "Visualizar modelo",
22
+ en: "Template preview",
23
+ es: "Vista previa de plantilla",
24
+ },
25
+ };
26
+
27
+ interface Props {
28
+ locale?: string;
29
+ template: Template;
30
+ modelValue: boolean;
31
+ }
32
+
33
+ const props = withDefaults(defineProps<Props>(), {
34
+ locale: "en",
35
+ });
36
+
37
+ defineEmits<{
38
+ close: void;
39
+ }>();
40
+ </script>
41
+
42
+ <style lang="scss" scoped>
43
+ @use "@/assets/scss/unnnic" as *;
44
+
45
+ :deep(.unnnic-modal-dialog__container__content) {
46
+ display: flex;
47
+ align-items: center;
48
+ justify-content: center;
49
+ background-color: $unnnic-color-neutral-lightest;
50
+ }
51
+ </style>
@@ -0,0 +1,16 @@
1
+ export interface Template {
2
+ header: {
3
+ type: "TEXT" | "MEDIA";
4
+ mediaType?: "IMAGE" | "VIDEO" | "DOCUMENT";
5
+ text?: string | null;
6
+ src?: string | null;
7
+ };
8
+ body?: string;
9
+ footer?: string;
10
+ buttons?: Array<{
11
+ type: "QUICK_REPLY" | "PHONE_NUMBER";
12
+ text: string;
13
+ countryCode?: string;
14
+ phoneNumber?: string;
15
+ }>;
16
+ }
@@ -88,6 +88,9 @@ import ModalDialog from "./ModalDialog/ModalDialog.vue";
88
88
  import Tour from "./Tour/Tour.vue";
89
89
  import Navigator from "./Navigator/index.vue";
90
90
  import SelectTime from "./SelectTime/index.vue";
91
+ import TemplatePreview from "./TemplatePreview/TemplatePreview.vue";
92
+ import TemplatePreviewModal from "./TemplatePreview/TemplatePreviewModal.vue";
93
+ import DataTable from './DataTable/index.vue';
91
94
 
92
95
  type VueComponent = Component;
93
96
 
@@ -186,6 +189,9 @@ export const components: ComponentsMap = {
186
189
  unnnicTour: Tour,
187
190
  unnnicNavigator: Navigator,
188
191
  unnnicSelectTime: SelectTime,
192
+ unnnicTemplatePreview: TemplatePreview,
193
+ unnnicTemplatePreviewModal: TemplatePreviewModal,
194
+ unnnicDataTable: DataTable,
189
195
  };
190
196
 
191
197
  export const unnnicFontSize = fontSize;
@@ -279,3 +285,6 @@ export const unnnicTableNext = TableNext;
279
285
  export const unnnicTour = Tour;
280
286
  export const unnnicNavigator = Navigator;
281
287
  export const unnnicSelectTime = SelectTime as VueComponent;
288
+ export const unnnicTemplatePreview = TemplatePreview as VueComponent;
289
+ export const unnnicTemplatePreviewModal = TemplatePreviewModal as VueComponent;
290
+ export const unnnicDataTable = DataTable;