@weni/unnnic-system 3.32.0 → 3.32.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weni/unnnic-system",
3
- "version": "3.32.0",
3
+ "version": "3.32.1",
4
4
  "type": "commonjs",
5
5
  "files": [
6
6
  "dist",
@@ -18,59 +18,45 @@
18
18
  </div>
19
19
  </template>
20
20
 
21
- <script>
21
+ <script setup lang="ts">
22
+ import { computed } from 'vue';
22
23
  import UnnnicIcon from '../Icon.vue';
24
+ import type { SchemeColor } from '../Icon.vue';
25
+ import type { IconSize } from '../Icon/types';
23
26
 
24
- export default {
25
- components: {
26
- UnnnicIcon,
27
- },
27
+ defineOptions({
28
+ name: 'UnnnicAvatarIcon',
29
+ });
28
30
 
29
- props: {
30
- enabled: {
31
- type: Boolean,
32
- default: true,
33
- },
31
+ export type AvatarIconSize = 'nano' | 'xs' | 'sm' | 'lg' | 'xl';
34
32
 
35
- icon: {
36
- type: String,
37
- default: 'graph-stats-1',
38
- },
39
-
40
- size: {
41
- type: String,
42
- default: 'sm',
43
- validator(value) {
44
- return ['nano', 'xs', 'sm', 'lg', 'xl'].indexOf(value) !== -1;
45
- },
46
- },
33
+ export interface AvatarIconProps {
34
+ enabled?: boolean;
35
+ icon?: string;
36
+ size?: AvatarIconSize;
37
+ scheme?: SchemeColor;
38
+ filled?: boolean;
39
+ opacity?: boolean;
40
+ }
47
41
 
48
- scheme: {
49
- type: String,
50
- default: 'fg-info',
51
- },
52
- filled: {
53
- type: Boolean,
54
- default: false,
55
- },
56
- opacity: {
57
- type: Boolean,
58
- default: true,
59
- },
60
- },
42
+ const props = withDefaults(defineProps<AvatarIconProps>(), {
43
+ enabled: true,
44
+ icon: 'graph-stats-1',
45
+ size: 'sm',
46
+ scheme: 'fg-info',
47
+ filled: false,
48
+ opacity: true,
49
+ });
61
50
 
62
- computed: {
63
- iconSize() {
64
- return {
65
- nano: 'xs',
66
- xs: 'sm',
67
- sm: 'md',
68
- lg: 'lg',
69
- xl: 'xl',
70
- }[this.size];
71
- },
72
- },
73
- };
51
+ const iconSize = computed((): IconSize => {
52
+ return {
53
+ nano: 'xs',
54
+ xs: 'sm',
55
+ sm: 'md',
56
+ lg: 'lg',
57
+ xl: 'xl',
58
+ }[props.size] as IconSize;
59
+ });
74
60
  </script>
75
61
 
76
62
  <style lang="scss" scoped>
@@ -96,12 +82,12 @@ export default {
96
82
 
97
83
  .unnnic-avatar-icon {
98
84
  border-radius: $unnnic-border-radius-sm;
99
- padding: $unnnic-spacing-inset-nano;
85
+ padding: $unnnic-space-2;
100
86
  display: inline-flex;
101
87
 
102
88
  &.nano,
103
89
  &.xs {
104
- padding: $unnnic-spacing-stack-nano $unnnic-spacing-inline-nano;
90
+ padding: $unnnic-space-1;
105
91
  }
106
92
  }
107
93
  </style>
@@ -11,7 +11,7 @@
11
11
  index === crumbs.length - 1,
12
12
  }"
13
13
  :data-test="crumb.name"
14
- @click="$emit('crumb-click', crumb)"
14
+ @click="emit('crumb-click', crumb)"
15
15
  >
16
16
  {{ crumb.name }}
17
17
  </div>
@@ -29,22 +29,28 @@
29
29
  </div>
30
30
  </template>
31
31
 
32
- <script>
32
+ <script setup lang="ts">
33
33
  import UnnnicIcon from '../Icon.vue';
34
34
 
35
- export default {
35
+ defineOptions({
36
36
  name: 'UnnnicBreadcrumb',
37
- components: { UnnnicIcon },
38
- props: {
39
- crumbs: {
40
- type: Array,
41
- default: null,
42
- validator: (crumb) => crumb.every((c) => c.name !== null),
43
- },
44
- },
37
+ });
45
38
 
46
- emits: ['crumb-click'],
47
- };
39
+ export interface BreadcrumbItem {
40
+ name: string;
41
+ }
42
+
43
+ export interface BreadcrumbProps {
44
+ crumbs?: BreadcrumbItem[] | null;
45
+ }
46
+
47
+ withDefaults(defineProps<BreadcrumbProps>(), {
48
+ crumbs: null,
49
+ });
50
+
51
+ const emit = defineEmits<{
52
+ 'crumb-click': [crumb: BreadcrumbItem];
53
+ }>();
48
54
  </script>
49
55
 
50
56
  <style scoped lang="scss">
@@ -56,7 +62,7 @@ export default {
56
62
 
57
63
  &__container {
58
64
  &__divider {
59
- margin: 0 $unnnic-inline-xs;
65
+ margin: 0 $unnnic-space-2;
60
66
  }
61
67
 
62
68
  &__link {
@@ -40,68 +40,55 @@
40
40
  </section>
41
41
  </template>
42
42
 
43
- <script>
43
+ <script setup lang="ts">
44
+ import { computed, useAttrs } from 'vue';
44
45
  import { pick } from 'lodash';
45
46
 
46
- export default {
47
- model: {
48
- event: 'change',
49
- },
50
-
51
- props: {
52
- modelValue: {
53
- type: [Boolean, String],
54
- default: false,
55
- validator(value) {
56
- return [true, false, 'less'].includes(value);
57
- },
58
- },
59
-
60
- disabled: {
61
- type: Boolean,
62
- default: false,
63
- },
64
-
65
- label: {
66
- type: String,
67
- default: '',
68
- },
69
-
70
- helper: {
71
- type: String,
72
- default: '',
73
- },
74
-
75
- textRight: {
76
- type: String,
77
- default: '',
78
- },
79
- },
80
- emits: ['change', 'update:model-value'],
81
-
82
- computed: {
83
- valueName() {
84
- if (this.modelValue === true) {
85
- return 'checked';
86
- }
87
- if (this.modelValue === false) {
88
- return 'default';
89
- }
47
+ defineOptions({
48
+ name: 'UnnnicCheckbox',
49
+ });
50
+
51
+ export type CheckboxValue = boolean | 'less';
52
+
53
+ export interface CheckboxProps {
54
+ modelValue?: CheckboxValue;
55
+ disabled?: boolean;
56
+ label?: string;
57
+ helper?: string;
58
+ textRight?: string;
59
+ }
60
+
61
+ const props = withDefaults(defineProps<CheckboxProps>(), {
62
+ modelValue: false,
63
+ disabled: false,
64
+ label: '',
65
+ helper: '',
66
+ textRight: '',
67
+ });
90
68
 
91
- return 'less';
92
- },
93
- },
69
+ const emit = defineEmits<{
70
+ change: [value: boolean];
71
+ 'update:model-value': [value: boolean];
72
+ }>();
94
73
 
95
- methods: {
96
- pick,
74
+ const $attrs = useAttrs();
97
75
 
98
- click() {
99
- const isChecked = ['checked', 'less'].includes(this.valueName);
100
- this.$emit('change', !isChecked);
101
- this.$emit('update:model-value', !isChecked);
102
- },
103
- },
104
- };
76
+ const valueName = computed(() => {
77
+ if (props.modelValue === true) {
78
+ return 'checked';
79
+ }
80
+ if (props.modelValue === false) {
81
+ return 'default';
82
+ }
83
+
84
+ return 'less';
85
+ });
86
+
87
+ function click() {
88
+ const isChecked = ['checked', 'less'].includes(valueName.value);
89
+ emit('change', !isChecked);
90
+ emit('update:model-value', !isChecked);
91
+ }
105
92
  </script>
106
93
 
107
94
  <style lang="scss" scoped>
@@ -260,7 +260,8 @@ import {
260
260
  days as translationDays,
261
261
  periods as translationPeriods,
262
262
  buttons as translationButtons,
263
- } from './translations.js';
263
+ type PeriodOption,
264
+ } from './translations';
264
265
 
265
266
  import i18n from '@/utils/plugins/i18n';
266
267
 
@@ -270,9 +271,34 @@ defineOptions({
270
271
  name: 'UnnnicDatePicker',
271
272
  });
272
273
 
273
- type PeriodOption = {
274
- id: string;
275
- name: string;
274
+ export type { PeriodOption };
275
+
276
+ export type DateCellProperty =
277
+ | 'inside month'
278
+ | 'out of range'
279
+ | 'selected'
280
+ | 'left-highlighted'
281
+ | 'right-highlighted'
282
+ | 'highlighted'
283
+ | 'today'
284
+ | string;
285
+
286
+ export interface DateCell {
287
+ properties: DateCellProperty[];
288
+ date?: string | number;
289
+ toString: () => string;
290
+ }
291
+
292
+ export type DatePickerTranslations = Record<
293
+ string,
294
+ string | Record<string, string>
295
+ >;
296
+
297
+ type I18nPlugin = {
298
+ global: {
299
+ locale: string;
300
+ messages: Record<string, unknown>;
301
+ };
276
302
  };
277
303
 
278
304
  export interface DatePickerProps {
@@ -300,7 +326,7 @@ export interface DatePickerProps {
300
326
  hideOptions?: boolean;
301
327
 
302
328
  locale?: string;
303
- translations?: Record<string, unknown>;
329
+ translations?: DatePickerTranslations;
304
330
 
305
331
  variant?: 'card' | 'popover';
306
332
  }
@@ -403,19 +429,21 @@ const containerOptionsFlexDirection = computed(() => {
403
429
  return props.hideOptions ? 'column-reverse' : 'column';
404
430
  });
405
431
 
406
- const i18nFn = (...args: any[]): string | undefined => {
407
- const [key, defaults] = args;
432
+ const i18nPlugin = i18n as unknown as I18nPlugin;
433
+
434
+ type I18nFnArg = number | string | Record<string, string>;
408
435
 
409
- const validLocaleValues = Object.keys(
410
- ((i18n as any).global.messages as Record<string, unknown>) || {},
411
- );
436
+ const i18nFn = (key: string, ...args: I18nFnArg[]): string | undefined => {
437
+ const [defaults] = args;
412
438
 
413
- let locale = props.locale as string | undefined;
439
+ const validLocaleValues = Object.keys(i18nPlugin.global.messages || {});
440
+
441
+ let locale = props.locale;
414
442
 
415
443
  const treatedSelectedLocale =
416
- get(i18n, 'global.locale') === 'en-us'
444
+ get(i18nPlugin, 'global.locale') === 'en-us'
417
445
  ? 'en'
418
- : (get(i18n, 'global.locale') as string | undefined);
446
+ : (get(i18nPlugin, 'global.locale') as string | undefined);
419
447
 
420
448
  locale =
421
449
  locale && validLocaleValues.includes(locale)
@@ -432,14 +460,14 @@ const i18nFn = (...args: any[]): string | undefined => {
432
460
 
433
461
  if (!text) {
434
462
  text = get(
435
- defaultTranslations as Record<string, unknown>,
463
+ defaultTranslations,
436
464
  `${key}.${locale}`,
437
- get(defaultTranslations as Record<string, unknown>, key, defaults),
465
+ get(defaultTranslations, key, defaults),
438
466
  ) as string | undefined;
439
467
  }
440
468
 
441
- if (text?.includes('|') && typeof args[1] === 'number') {
442
- const count: number = args[1];
469
+ if (text?.includes('|') && typeof args[0] === 'number') {
470
+ const count: number = args[0];
443
471
  const pluralization = text.split('|');
444
472
 
445
473
  if (pluralization.length === 3) {
@@ -451,13 +479,11 @@ const i18nFn = (...args: any[]): string | undefined => {
451
479
 
452
480
  let vars: Record<string, string> = {};
453
481
 
454
- Object.values(args)
455
- .slice(1)
456
- .forEach((argument) => {
457
- if (!(argument instanceof Array) && argument instanceof Object) {
458
- vars = argument as Record<string, string>;
459
- }
460
- });
482
+ args.forEach((argument) => {
483
+ if (!(argument instanceof Array) && argument instanceof Object) {
484
+ vars = argument;
485
+ }
486
+ });
461
487
 
462
488
  Object.keys(vars).forEach((varName) => {
463
489
  text = text?.replaceAll(new RegExp(`{ *${varName} *}`, 'g'), vars[varName]);
@@ -589,7 +615,7 @@ function getDatesOfTheMonth(reference: string) {
589
615
 
590
616
  date.setDate(1 - date.getDay());
591
617
 
592
- const dates: { properties: string[]; toString: () => string }[] = [];
618
+ const dates: DateCell[] = [];
593
619
 
594
620
  for (let i = 0; i < 6 * 7; i += 1) {
595
621
  const dateString = dateToString(date);
@@ -668,11 +694,7 @@ function getMonthsOfTheYear(reference: string) {
668
694
 
669
695
  date.setMonth(0);
670
696
 
671
- const dates: {
672
- properties: string[];
673
- date: string;
674
- toString: () => string;
675
- }[] = [];
697
+ const dates: DateCell[] = [];
676
698
 
677
699
  for (let i = 0; i < 3 * 4; i += 1) {
678
700
  const dateString = dateToString(date);
@@ -732,11 +754,7 @@ function getYears(reference: string) {
732
754
 
733
755
  date.setMonth(0);
734
756
 
735
- const dates: {
736
- properties: string[];
737
- date: number;
738
- toString: () => string;
739
- }[] = [];
757
+ const dates: DateCell[] = [];
740
758
 
741
759
  for (let i = 0; i < 3 * 4; i += 1) {
742
760
  const dateString = dateToString(date);
@@ -1,3 +1,15 @@
1
+ export type DatePickerLocale = 'pt-br' | 'en' | 'en-us' | 'es';
2
+
3
+ export type PeriodOption = {
4
+ id: string;
5
+ name: string;
6
+ };
7
+
8
+ export type LocaleButtons = {
9
+ clear: string;
10
+ filter: string;
11
+ };
12
+
1
13
  const englishMonths = [
2
14
  'January',
3
15
  'February',
@@ -15,7 +27,7 @@ const englishMonths = [
15
27
 
16
28
  const englishDays = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
17
29
 
18
- const englishPeriods = [
30
+ const englishPeriods: PeriodOption[] = [
19
31
  { name: 'Last 7 days', id: 'last-7-days' },
20
32
  { name: 'Last 14 days', id: 'last-14-days' },
21
33
  { name: 'Last 30 days', id: 'last-30-days' },
@@ -25,7 +37,7 @@ const englishPeriods = [
25
37
  { name: 'Custom', id: 'custom' },
26
38
  ];
27
39
 
28
- export const months = {
40
+ export const months: Record<string, string[]> = {
29
41
  'pt-br': [
30
42
  'Janeiro',
31
43
  'Fevereiro',
@@ -58,14 +70,14 @@ export const months = {
58
70
  ],
59
71
  };
60
72
 
61
- export const days = {
73
+ export const days: Record<string, string[]> = {
62
74
  'pt-br': ['D', 'S', 'T', 'Q', 'Q', 'S', 'S'],
63
75
  en: englishDays,
64
76
  'en-us': englishDays,
65
77
  es: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
66
78
  };
67
79
 
68
- export const buttons = {
80
+ export const buttons: Record<string, LocaleButtons> = {
69
81
  'pt-br': {
70
82
  clear: 'Limpar',
71
83
  filter: 'Filtrar',
@@ -82,7 +94,7 @@ export const buttons = {
82
94
 
83
95
  buttons.en = buttons['en-us'];
84
96
 
85
- export const periods = {
97
+ export const periods: Record<string, PeriodOption[]> = {
86
98
  'pt-br': [
87
99
  {
88
100
  name: 'Últimos 7 dias',
@@ -14,90 +14,82 @@
14
14
  :value="fullySanitize(modelValue)"
15
15
  :class="[classes, { focus, 'use-focus-prop': useFocusProp }]"
16
16
  :type="nativeType"
17
- :maxlength="maxlength"
17
+ :maxlength="maxlength ?? undefined"
18
18
  :readonly="readonly"
19
19
  />
20
20
  </template>
21
21
 
22
- <script>
23
- import { mask } from 'vue-the-mask';
22
+ <script setup lang="ts">
23
+ import { computed, useAttrs } from 'vue';
24
+ import { mask as vMask } from 'vue-the-mask';
24
25
  import { fullySanitize } from '../../utils/sanitize';
25
26
 
26
- export default {
27
- directives: { mask },
28
- props: {
29
- type: {
30
- type: String,
31
- default: 'normal',
32
- validator(value) {
33
- return ['normal', 'error'].indexOf(value) !== -1;
34
- },
35
- },
36
- modelValue: {
37
- type: String,
38
- default: '',
39
- },
40
- nativeType: {
41
- type: String,
42
- default: 'text',
43
- },
44
- size: {
45
- type: String,
46
- default: 'md',
47
- },
48
- mask: {
49
- type: [String, Array],
50
- default: '',
51
- },
52
- hasIconLeft: Boolean,
53
- hasIconRight: Boolean,
54
- hasClearIcon: Boolean,
55
- maxlength: {
56
- type: Number,
57
- default: null,
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
- },
71
- },
72
- emits: ['update:modelValue'],
73
- computed: {
74
- attributes() {
75
- return {
76
- ...this.$attrs,
77
- ...this.$attrs['v-bind'],
78
- onInput: (event) => {
79
- this.$emit('update:modelValue', event.srcElement.value);
80
- },
81
- };
27
+ defineOptions({
28
+ name: 'UnnnicBaseInput',
29
+ });
30
+
31
+ export type InputVariant = 'normal' | 'error';
32
+ export type InputSize = 'md' | 'sm';
33
+
34
+ export interface BaseInputProps {
35
+ type?: InputVariant;
36
+ modelValue?: string;
37
+ nativeType?: string;
38
+ size?: InputSize | string;
39
+ mask?: string | string[];
40
+ hasIconLeft?: boolean;
41
+ hasIconRight?: boolean;
42
+ hasClearIcon?: boolean;
43
+ maxlength?: number | null;
44
+ readonly?: boolean;
45
+ useFocusProp?: boolean;
46
+ focus?: boolean;
47
+ }
48
+
49
+ const props = withDefaults(defineProps<BaseInputProps>(), {
50
+ type: 'normal',
51
+ modelValue: '',
52
+ nativeType: 'text',
53
+ size: 'md',
54
+ mask: '',
55
+ hasIconLeft: false,
56
+ hasIconRight: false,
57
+ hasClearIcon: false,
58
+ maxlength: null,
59
+ readonly: false,
60
+ useFocusProp: false,
61
+ focus: false,
62
+ });
63
+
64
+ const emit = defineEmits<{
65
+ 'update:modelValue': [value: string];
66
+ }>();
67
+
68
+ const attrs = useAttrs();
69
+
70
+ const attributes = computed(() => {
71
+ return {
72
+ ...attrs,
73
+ ...(attrs['v-bind'] as Record<string, unknown> | undefined),
74
+ onInput: (event: Event) => {
75
+ const target = event.target as HTMLInputElement | null;
76
+ emit('update:modelValue', target?.value ?? '');
82
77
  },
78
+ };
79
+ });
83
80
 
84
- classes() {
85
- return [
86
- 'input',
87
- `size-${this.size}`,
88
- this.type,
89
- {
90
- 'input--has-icon-left': this.hasIconLeft,
91
- 'input--has-icon-right': this.hasIconRight,
92
- 'input--has-clear-icon': this.hasClearIcon,
93
- },
94
- ];
81
+ const classes = computed(() => {
82
+ return [
83
+ 'input',
84
+ `size-${props.size}`,
85
+ props.type,
86
+ {
87
+ 'input--has-icon-left': props.hasIconLeft,
88
+ 'input--has-icon-right': props.hasIconRight,
89
+ 'input--has-clear-icon': props.hasClearIcon,
95
90
  },
96
- },
97
- methods: {
98
- fullySanitize,
99
- },
100
- };
91
+ ];
92
+ });
101
93
  </script>
102
94
 
103
95
  <style lang="scss" scoped>