design-system-next 1.2.25 → 1.3.2

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 (45) hide show
  1. package/dist/design-system-next.js +2937 -2937
  2. package/dist/design-system-next.js.gz +0 -0
  3. package/dist/main.css +1 -1
  4. package/dist/main.css.gz +0 -0
  5. package/dist/main.d.ts +1 -6
  6. package/package.json +1 -1
  7. package/src/App.vue +8 -8
  8. package/src/assets/styles/tailwind.css +366 -367
  9. package/src/components/avatar/avatar.vue +1 -1
  10. package/src/components/avatar/use-avatar.ts +40 -34
  11. package/src/components/badge/badge.vue +2 -2
  12. package/src/components/badge/use-badge.ts +16 -16
  13. package/src/components/button/use-button.ts +39 -34
  14. package/src/components/checkbox/checkbox.vue +2 -2
  15. package/src/components/checkbox/use-checkbox.ts +23 -20
  16. package/src/components/dropdown/dropdown.vue +6 -6
  17. package/src/components/dropdown/use-dropdown.ts +6 -5
  18. package/src/components/empty-state/empty-state.vue +6 -5
  19. package/src/components/empty-state/use-empty-state.ts +8 -6
  20. package/src/components/input/input.ts +6 -1
  21. package/src/components/input/input.vue +7 -4
  22. package/src/components/input/use-input.ts +49 -47
  23. package/src/components/lozenge/lozenge.vue +7 -5
  24. package/src/components/lozenge/use-lozenge.ts +23 -15
  25. package/src/components/modal/modal.vue +8 -8
  26. package/src/components/modal/use-modal.ts +8 -8
  27. package/src/components/radio/radio.vue +1 -1
  28. package/src/components/radio/use-radio.ts +15 -13
  29. package/src/components/sidenav/sidenav.vue +158 -138
  30. package/src/components/sidepanel/sidepanel.vue +29 -21
  31. package/src/components/sidepanel/use-sidepanel.ts +17 -15
  32. package/src/components/snackbar/snack/snack.vue +13 -40
  33. package/src/components/snackbar/snack/use-snack.ts +12 -11
  34. package/src/components/snackbar/snackbar.vue +11 -13
  35. package/src/components/switch/switch.vue +14 -8
  36. package/src/components/switch/use-switch.ts +16 -15
  37. package/src/components/table/table.ts +5 -0
  38. package/src/components/table/table.vue +51 -24
  39. package/src/components/table/use-table.ts +1 -0
  40. package/src/components/tabs/tabs.vue +23 -19
  41. package/src/components/tabs/use-tabs.ts +5 -4
  42. package/src/components/timePicker/timePicker.vue +10 -9
  43. package/src/components/timePicker/use-timePicker.ts +31 -45
  44. package/src/components/tooltip/tooltip.vue +1 -1
  45. package/src/main.ts +3 -0
@@ -2,7 +2,7 @@
2
2
  <div :class="avatarClassses">
3
3
  <template v-if="!initial">
4
4
  <img v-if="!$slots.default && src" :src="src" :alt="alt" :class="avatarImageClassses" />
5
- <div v-else :class="[avatarImageClassses, 'avatar__slot border-color-weak border border-solid']">
5
+ <div v-else :class="[avatarImageClassses, 'avatar__slot spr-border-color-weak spr-border spr-border-solid']">
6
6
  <slot />
7
7
  </div>
8
8
  </template>
@@ -1,61 +1,67 @@
1
1
  import { computed, toRefs } from 'vue';
2
- import type { AvatarPropTypes } from './avatar';
3
2
 
4
3
  import classNames from 'classnames';
4
+
5
+ import type { AvatarPropTypes } from './avatar';
6
+
5
7
  export const useAvatar = (props: AvatarPropTypes) => {
6
8
  const { size, color } = toRefs(props);
9
+
7
10
  const avatarClassses = computed(() => {
8
- return classNames(' relative inline-block rounded-full', {
9
- 'background-color-surface': color.value === 'primary',
10
- 'background-color': color.value === 'secondary',
11
+ return classNames('spr-relative spr-inline-block spr-rounded-full', {
12
+ 'spr-background-color-surface': color.value === 'primary',
13
+ 'spr-background-color': color.value === 'secondary',
11
14
  });
12
15
  });
13
16
 
14
17
  const avatarImageClassses = computed(() => {
15
- return classNames('rounded-full object-cover flex items-center justify-center overflow-hidden', {
16
- 'h-20 min-w-20 text-[36px]': size.value === '2xl',
17
- 'h-14 min-w-14 font-size-600': size.value === 'xl',
18
- 'h-10 min-w-10 font-size-400': size.value === 'lg',
19
- 'h-9 min-w-9 font-size-300': size.value === 'md',
20
- 'h-6 min-w-6 font-size-200': size.value === 'sm',
21
- 'h-5 min-w-5 text-[10px]': size.value === 'xs',
22
- 'h-4 min-w-4 text-[10px]': size.value === '2xs',
23
- });
18
+ return classNames(
19
+ 'spr-rounded-full spr-object-cover spr-flex spr-items-center spr-justify-center spr-overflow-hidden',
20
+ {
21
+ 'spr-h-20 spr-min-w-20 spr-text-[36px]': size.value === '2xl',
22
+ 'spr-h-14 spr-min-w-14 spr-font-size-600': size.value === 'xl',
23
+ 'spr-h-10 spr-min-w-10 spr-font-size-400': size.value === 'lg',
24
+ 'spr-h-9 spr-min-w-9 spr-font-size-300': size.value === 'md',
25
+ 'spr-h-6 spr-min-w-6 spr-font-size-200': size.value === 'sm',
26
+ 'spr-h-5 spr-min-w-5 spr-text-[10px]': size.value === 'xs',
27
+ 'spr-h-4 spr-min-w-4 spr-text-[10px]': size.value === '2xs',
28
+ },
29
+ );
24
30
  });
25
31
 
26
32
  const initialClassses = computed(() => {
27
33
  return classNames(
28
- ' rounded-full border-color-weak border border-solid items-center flex justify-center heading-xs text-color-strong',
34
+ 'spr-rounded-full spr-border-color-weak spr-border spr-border-solid spr-items-center spr-flex spr-justify-center spr-heading-xs spr-text-color-strong',
29
35
  {
30
- ' h-20 min-w-20': size.value === '2xl',
31
- ' h-14 min-w-14 body-lg-regular-medium': size.value === 'xl',
32
- ' h-10 min-w-10 body-sm-regular-medium': size.value === 'lg',
33
- ' h-9 min-w-9 body-sm-regular-medium': size.value === 'md',
34
- ' h-6 min-w-6 body-xs-regular-medium': size.value === 'sm',
35
- ' h-5 min-w-5 !text-[10px]': size.value === 'xs',
36
- ' h-4 min-w-4 !text-[10px]': size.value === '2xs',
36
+ 'spr-h-20 spr-min-w-20': size.value === '2xl',
37
+ 'spr-h-14 spr-min-w-14 spr-body-lg-regular-medium': size.value === 'xl',
38
+ 'spr-h-10 spr-min-w-10 spr-body-sm-regular-medium': size.value === 'lg',
39
+ 'spr-h-9 spr-min-w-9 spr-body-sm-regular-medium': size.value === 'md',
40
+ 'spr-h-6 spr-min-w-6 spr-body-xs-regular-medium': size.value === 'sm',
41
+ 'spr-h-5 spr-min-w-5 !spr-text-[10px]': size.value === 'xs',
42
+ 'spr-h-4 spr-min-w-4 !spr-text-[10px]': size.value === '2xs',
37
43
  },
38
44
  );
39
45
  });
40
46
 
41
47
  const avatarNotificationClassses = computed(() => {
42
- return classNames(' absolute right-0 top-0', {
43
- ' right-[-5px] top-[-6.3px]': size.value === 'xl',
44
- ' right-[-7px] top-[-8px]': size.value === 'lg',
45
- ' right-[-5px] top-[-6px]': size.value === 'md',
46
- ' right-[-7px] top-[-7px]': size.value === 'sm',
47
- ' right-[-5px] top-[-4px]': size.value === 'xs',
48
- ' right-[-4px] top-[-4px]': size.value === '2xs',
48
+ return classNames('spr-absolute spr-right-0 spr-top-0', {
49
+ 'spr-right-[-5px] spr-top-[-6.3px]': size.value === 'xl',
50
+ 'spr-right-[-7px] spr-top-[-8px]': size.value === 'lg',
51
+ 'spr-right-[-5px] spr-top-[-6px]': size.value === 'md',
52
+ 'spr-right-[-7px] spr-top-[-7px]': size.value === 'sm',
53
+ 'spr-right-[-5px] spr-top-[-4px]': size.value === 'xs',
54
+ 'spr-right-[-4px] spr-top-[-4px]': size.value === '2xs',
49
55
  });
50
56
  });
51
57
 
52
58
  const onlineNotificationClassses = computed(() => {
53
- return classNames(' absolute bottom-0 right-0', {
54
- ' bottom-0 right-0': size.value === 'xl' || size.value === 'lg' || size.value === 'md',
55
- ' bottom-[1px] right-[1px]': size.value === 'xl',
56
- ' bottom-[-3px] right-[-4px]': size.value === 'sm',
57
- ' bottom-[-4px] right-[-3px]': size.value === 'xs',
58
- ' bottom-[-2px] right-[-4px]': size.value === '2xs',
59
+ return classNames('spr-absolute spr-bottom-0 spr-right-0', {
60
+ 'spr-bottom-0 spr-right-0': size.value === 'xl' || size.value === 'lg' || size.value === 'md',
61
+ 'spr-bottom-[1px] spr-right-[1px]': size.value === 'xl',
62
+ 'spr-bottom-[-3px] spr-right-[-4px]': size.value === 'sm',
63
+ 'spr-bottom-[-4px] spr-right-[-3px]': size.value === 'xs',
64
+ 'spr-bottom-[-2px] spr-right-[-4px]': size.value === '2xs',
59
65
  });
60
66
  });
61
67
 
@@ -1,9 +1,9 @@
1
1
  <template>
2
- <div class="flex gap-2">
2
+ <div class="spr-flex spr-gap-2">
3
3
  <slot />
4
4
  <div :class="[badgeElementWrapper]">
5
5
  <section :class="[badgePositionClasses]">
6
- <div :class="[badgeClasses, 'flex items-center justify-center']">
6
+ <div :class="[badgeClasses, 'spr-flex spr-items-center spr-justify-center']">
7
7
  {{ props.size === 'tiny' ? '' : text }}
8
8
  </div>
9
9
  </section>
@@ -1,24 +1,24 @@
1
1
  import { computed, toRefs } from 'vue';
2
+ import classNames from 'classnames';
2
3
  import type { BadgePropTypes } from './badge';
3
4
 
4
- import classNames from 'classnames';
5
5
  export const useBadge = (props: BadgePropTypes) => {
6
6
  const { position, size, variant } = toRefs(props);
7
7
 
8
8
  const badgeClasses = computed(() => {
9
9
  const variantClasses = classNames({
10
- 'background-color-danger-base text-color-inverted-strong': variant.value === 'danger',
11
- 'background-color-disabled text-color-on-fill-disabled ': variant.value === 'disabled',
12
- 'background-color-information-base text-color-inverted-strong': variant.value === 'information',
13
- 'background-color-brand-base text-color-inverted-strong': variant.value === 'brand',
10
+ 'spr-background-color-danger-base spr-text-color-inverted-strong': variant.value === 'danger',
11
+ 'spr-background-color-disabled spr-text-color-on-fill-disabled': variant.value === 'disabled',
12
+ 'spr-background-color-information-base spr-text-color-inverted-strong': variant.value === 'information',
13
+ 'spr-background-color-brand-base spr-text-color-inverted-strong': variant.value === 'brand',
14
14
  });
15
15
 
16
16
  const sizeClasses = classNames({
17
- 'label-sm-medium !leading-[0] !tracking-normal h-[20px] min-w-[20px] rounded-[32px] py-size-spacing-3xs px-size-spacing-5xs':
17
+ 'spr-label-sm-medium !spr-leading-[0] !spr-tracking-normal spr-h-[20px] spr-min-w-[20px] spr-rounded-[32px] spr-py-size-spacing-3xs spr-px-size-spacing-5xs':
18
18
  size.value === 'big',
19
- 'label-xs-medium !leading-[0] !tracking-normal h-[16px] min-w-[16px] rounded-[32px] py-size-spacing-6xs px-size-spacing-5xs':
19
+ 'spr-label-xs-medium !spr-leading-[0] !spr-tracking-normal spr-h-[16px] spr-min-w-[16px] spr-rounded-[32px] spr-py-size-spacing-6xs spr-px-size-spacing-5xs':
20
20
  size.value === 'small',
21
- 'h-[10px] min-w-[10px] rounded-full': size.value === 'tiny',
21
+ 'spr-h-[10px] spr-min-w-[10px] spr-rounded-full': size.value === 'tiny',
22
22
  });
23
23
 
24
24
  return classNames(variantClasses, sizeClasses);
@@ -26,19 +26,19 @@ export const useBadge = (props: BadgePropTypes) => {
26
26
 
27
27
  const badgePositionClasses = computed(() => {
28
28
  return classNames({
29
- 'absolute -top-1 right-1': position.value === 'top' && size.value === 'tiny',
30
- ' absolute -bottom-1 right-1': position.value === 'bottom' && size.value === 'tiny',
31
- 'absolute -top-2 -right-1': position.value === 'top' && size.value === 'small',
32
- ' absolute -bottom-2 -right-1': position.value === 'bottom' && size.value === 'small',
33
- 'absolute -top-3 -right-2': position.value === 'top' && size.value === 'big',
34
- ' absolute -bottom-3 -right-2': position.value === 'bottom' && size.value === 'big',
29
+ 'spr-absolute -spr-top-1 spr-right-1': position.value === 'top' && size.value === 'tiny',
30
+ 'spr-absolute -spr-bottom-1 spr-right-1': position.value === 'bottom' && size.value === 'tiny',
31
+ 'spr-absolute -spr-top-2 -spr-right-1': position.value === 'top' && size.value === 'small',
32
+ 'spr-absolute -spr-bottom-2 -spr-right-1': position.value === 'bottom' && size.value === 'small',
33
+ 'spr-absolute -spr-top-3 -spr-right-2': position.value === 'top' && size.value === 'big',
34
+ 'spr-absolute -spr-bottom-3 -spr-right-2': position.value === 'bottom' && size.value === 'big',
35
35
  });
36
36
  });
37
37
 
38
38
  const badgeElementWrapper = computed(() => {
39
39
  return classNames({
40
- 'flex items-center gap-2 ': position.value === 'default',
41
- relative: position.value === 'top' || position.value === 'bottom',
40
+ 'spr-flex spr-items-center spr-gap-2': position.value === 'default',
41
+ 'spr-relative': position.value === 'top' || position.value === 'bottom',
42
42
  });
43
43
  });
44
44
 
@@ -24,37 +24,42 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
24
24
 
25
25
  const buttonDefaultCssClass: ComputedRef<string> = computed(() =>
26
26
  classNames([
27
- 'background-color flex items-center gap-1.5 w-fit min-w-[24px] items-center justify-center rounded-md outline-2 outline-offset-4',
27
+ 'spr-background-color spr-flex spr-items-center spr-gap-1.5 spr-w-fit spr-min-w-[24px] spr-items-center spr-justify-center spr-rounded-md spr-outline-2 spr-outline-offset-4',
28
28
  ]),
29
29
  );
30
30
 
31
31
  const buttonTransitionCssClass: ComputedRef<string> = computed(() =>
32
- classNames(['transition duration-150 ease-in-out', 'hover:shadow-button-hover', 'active:scale-95']),
32
+ classNames([
33
+ 'spr-transition spr-duration-150 spr-ease-in-out',
34
+ 'hover:spr-shadow-button-hover',
35
+ 'active:spr-scale-95',
36
+ ]),
33
37
  );
34
38
 
35
39
  const buttonSizeCssClass: ComputedRef<string> = computed(() =>
36
40
  classNames({
37
- 'min-w-6 p-size-spacing-4xs font-medium font-size-100 leading-100': size.value === 'small',
38
- 'min-w-7 p-2 font-medium font-size-100 leading-100': size.value === 'medium',
39
- '!min-w-9 px-2 py-3 font-medium font-size-200 leading-300 max-h-9': size.value === 'large',
40
- 'font-size-400': hasIcon.value && size.value === 'large',
41
- 'font-size-300': hasIcon.value && size.value === 'medium',
42
- 'font-size-200': hasIcon.value && size.value === 'small',
41
+ 'spr-min-w-6 spr-p-size-spacing-4xs spr-font-medium spr-font-size-100 spr-leading-100': size.value === 'small',
42
+ 'spr-min-w-7 spr-p-2 spr-font-medium spr-font-size-100 spr-leading-100': size.value === 'medium',
43
+ '!spr-min-w-9 spr-px-2 spr-py-3 spr-font-medium spr-font-size-200 spr-leading-300 spr-max-h-9':
44
+ size.value === 'large',
45
+ 'spr-font-size-400': hasIcon.value && size.value === 'large',
46
+ 'spr-font-size-300': hasIcon.value && size.value === 'medium',
47
+ 'spr-font-size-200': hasIcon.value && size.value === 'small',
43
48
  }),
44
49
  );
45
50
 
46
51
  const buttonTextCssClass: ComputedRef<string> = computed(() => {
47
52
  if (variant.value === 'secondary' || variant.value === 'tertiary') {
48
53
  return classNames({
49
- 'text-color-strong': tone.value === 'neutral',
50
- 'text-color-brand-base': tone.value === 'success',
51
- 'text-color-danger-base': tone.value === 'danger',
54
+ 'spr-text-color-strong': tone.value === 'neutral',
55
+ 'spr-text-color-brand-base': tone.value === 'success',
56
+ 'spr-text-color-danger-base': tone.value === 'danger',
52
57
  });
53
58
  }
54
59
 
55
60
  return classNames({
56
- 'text-color-strong': tone.value === 'neutral',
57
- 'text-color-inverted-strong': tone.value === 'success' || tone.value === 'danger',
61
+ 'spr-text-color-strong': tone.value === 'neutral',
62
+ 'spr-text-color-inverted-strong': tone.value === 'success' || tone.value === 'danger',
58
63
  });
59
64
  });
60
65
 
@@ -62,10 +67,10 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
62
67
  const buttonBackgroundCssClass: ComputedRef<string> = computed(() => {
63
68
  if (variant.value === 'secondary') {
64
69
  if (pressed.value) {
65
- return 'background-color-pressed !shadow-button';
70
+ return 'spr-background-color-pressed !spr-shadow-button';
66
71
  }
67
72
 
68
- return isHovered.value ? 'background-color-hover' : 'background-color ';
73
+ return isHovered.value ? 'spr-background-color-hover' : 'spr-background-color ';
69
74
  }
70
75
 
71
76
  if (variant.value === 'tertiary') {
@@ -77,11 +82,11 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
77
82
 
78
83
  function getTertiaryBackground(): string {
79
84
  if (pressed.value) {
80
- return 'background-color-pressed !shadow-button';
85
+ return 'spr-background-color-pressed !spr-shadow-button';
81
86
  }
82
87
 
83
88
  return classNames('!border-none', {
84
- 'background-color-hover': isHovered.value,
89
+ 'spr-background-color-hover': isHovered.value,
85
90
  });
86
91
  }
87
92
 
@@ -99,9 +104,9 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
99
104
 
100
105
  function getPressedBackground(): string {
101
106
  const backgrounds: Record<string, string> = {
102
- neutral: 'background-color-pressed !shadow-button',
103
- success: 'background-color-brand-pressed !shadow-button',
104
- danger: 'background-color-danger-pressed !shadow-button',
107
+ neutral: 'spr-background-color-pressed !spr-shadow-button',
108
+ success: 'spr-background-color-brand-pressed !spr-shadow-button',
109
+ danger: 'spr-background-color-danger-pressed !spr-shadow-button',
105
110
  };
106
111
 
107
112
  return backgrounds[tone.value] || '';
@@ -109,9 +114,9 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
109
114
 
110
115
  function getHoveredBackground(): string {
111
116
  const backgrounds: Record<string, string> = {
112
- neutral: 'background-color-hover',
113
- success: 'background-color-success-pressed',
114
- danger: 'background-color-danger-hover',
117
+ neutral: 'spr-background-color-hover',
118
+ success: 'spr-background-color-success-pressed',
119
+ danger: 'spr-background-color-danger-hover',
115
120
  };
116
121
 
117
122
  return backgrounds[tone.value] || '';
@@ -119,9 +124,9 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
119
124
 
120
125
  function getDefaultBackground(): string {
121
126
  const backgrounds: Record<string, string> = {
122
- neutral: 'background-color-base',
123
- success: 'background-color-brand-base',
124
- danger: 'background-color-danger-base',
127
+ neutral: 'spr-background-color-base',
128
+ success: 'spr-background-color-brand-base',
129
+ danger: 'spr-background-color-danger-base',
125
130
  };
126
131
 
127
132
  return backgrounds[tone.value] || '';
@@ -131,16 +136,16 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
131
136
  const buttonBorderCssClass: ComputedRef<string> = computed(() => {
132
137
  if (variant.value === 'primary' || variant.value === 'tertiary') {
133
138
  if (focused.value) {
134
- return 'border-solid !border !border-white-50';
139
+ return 'spr-border-solid !spr-border !spr-border-white-50';
135
140
  }
136
141
 
137
- return 'border-solid !border !border-transparent';
142
+ return 'spr-border-solid !spr-border !spr-border-transparent';
138
143
  }
139
144
 
140
145
  return classNames({
141
- 'border-solid !border !border-color-base': tone.value === 'neutral',
142
- 'border-solid !border !border-color-brand-base': tone.value === 'success',
143
- 'border-solid !border !border-color-danger-base': tone.value === 'danger',
146
+ 'spr-border-solid !spr-border !spr-border-color-base': tone.value === 'neutral',
147
+ 'spr-border-solid !spr-border !spr-border-color-brand-base': tone.value === 'success',
148
+ 'spr-border-solid !spr-border !spr-border-color-danger-base': tone.value === 'danger',
144
149
  });
145
150
  });
146
151
 
@@ -154,21 +159,21 @@ export const useButton = (props: ButtonPropTypes, emit: SetupContext<ButtonEmitT
154
159
  return classNames(
155
160
  buttonDefaultCssClass.value,
156
161
  buttonSizeCssClass.value,
157
- 'text-color-disabled background-color-disabled !border-0 !shadow-none !cursor-not-allowed',
162
+ 'spr-text-color-disabled spr-background-color-disabled !spr-border-0 !spr-shadow-none !spr-cursor-not-allowed',
158
163
  );
159
164
 
160
165
  if (variant.value === 'secondary')
161
166
  return classNames(
162
167
  buttonDefaultCssClass.value,
163
168
  buttonSizeCssClass.value,
164
- 'text-color-disabled border-solid !border !border-color-disabled !shadow-none !cursor-not-allowed',
169
+ 'spr-text-color-disabled spr-border-solid !spr-border !spr-border-color-disabled !spr-shadow-none !spr-cursor-not-allowed',
165
170
  );
166
171
 
167
172
  if (variant.value === 'tertiary')
168
173
  return classNames(
169
174
  buttonDefaultCssClass.value,
170
175
  buttonSizeCssClass.value,
171
- 'text-color-disabled !border-0 !shadow-none !cursor-not-allowed',
176
+ 'spr-text-color-disabled !spr-border-0 !spr-shadow-none !spr-cursor-not-allowed',
172
177
  );
173
178
  }
174
179
 
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <label :class="wrapperClasses">
3
- <div class="relative flex items-center">
3
+ <div class="spr-relative spr-flex spr-items-center">
4
4
  <input
5
5
  type="checkbox"
6
6
  :checked="props.modelValue"
@@ -12,7 +12,7 @@
12
12
  <Icon icon="ph:check-bold" />
13
13
  </span>
14
14
  </div>
15
- <div v-if="props.label || props.description" class="grid gap-0.5">
15
+ <div v-if="props.label || props.description" class="spr-grid spr-gap-0.5">
16
16
  <span v-if="props.label" :class="labelClasses">
17
17
  {{ props.label }}
18
18
  </span>
@@ -1,7 +1,8 @@
1
1
  import { computed } from 'vue';
2
+
2
3
  import classNames from 'classnames';
3
- import type { SetupContext } from 'vue';
4
4
 
5
+ import type { SetupContext } from 'vue';
5
6
  import type { CheckboxPropTypes, CheckboxEmitTypes } from './checkbox';
6
7
 
7
8
  interface CheckboxEvent extends Event {
@@ -10,16 +11,18 @@ interface CheckboxEvent extends Event {
10
11
 
11
12
  export const useCheckbox = (props: CheckboxPropTypes, emit: SetupContext<CheckboxEmitTypes>['emit']) => {
12
13
  const wrapperClasses = computed(() => {
13
- const baseClasses = 'flex w-fit select-none items-center gap-1.5 transition duration-150 ease-in-out';
14
+ const baseClasses =
15
+ 'spr-flex spr-w-fit spr-select-none spr-items-center spr-gap-1.5 spr-transition spr-duration-150 spr-ease-in-out';
14
16
 
15
17
  const conditionalClasses = {
16
- 'border-color-weak hover:background-color-hover rounded-lg border border-solid px-3 py-2': props.bordered,
17
- 'active:scale-95': props.bordered && !props.disabled,
18
- 'cursor-not-allowed': props.disabled,
19
- 'cursor-pointer': !props.disabled,
20
- 'background-color-brand-weak hover:background-color-brand-weak border-color-success-base':
18
+ 'spr-border-color-weak hover:spr-background-color-hover spr-rounded-lg spr-border spr-border-solid spr-px-3 spr-py-2':
19
+ props.bordered,
20
+ 'active:spr-scale-95': props.bordered && !props.disabled,
21
+ 'spr-cursor-not-allowed': props.disabled,
22
+ 'spr-cursor-pointer': !props.disabled,
23
+ 'spr-background-color-brand-weak hover:spr-background-color-brand-weak spr-border-color-success-base':
21
24
  props.bordered && props.modelValue,
22
- 'background-color-disabled': props.bordered && props.disabled,
25
+ 'spr-background-color-disabled': props.bordered && props.disabled,
23
26
  };
24
27
 
25
28
  return classNames(baseClasses, conditionalClasses);
@@ -27,12 +30,12 @@ export const useCheckbox = (props: CheckboxPropTypes, emit: SetupContext<Checkbo
27
30
 
28
31
  const inputCheckboxClasses = computed(() => {
29
32
  const baseClasses =
30
- 'h-5 w-5 appearance-none rounded-[2.5px] border-color-supporting border-[1.25px] border-solid transition duration-150 ease-in-out';
33
+ 'spr-h-5 spr-w-5 spr-appearance-none spr-rounded-[2.5px] spr-border-color-supporting spr-border-[1.25px] spr-border-solid spr-transition spr-duration-150 spr-ease-in-out';
31
34
 
32
35
  const conditionalClasses = {
33
- 'background-color-brand-base border-color-brand-base': props.modelValue,
34
- 'border-color-disabled background-color-base cursor-not-allowed': props.disabled,
35
- 'cursor-pointer': !props.disabled,
36
+ 'spr-background-color-brand-base spr-border-color-brand-base': props.modelValue,
37
+ 'spr-border-color-disabled spr-background-color-base spr-cursor-not-allowed': props.disabled,
38
+ 'spr-cursor-pointer': !props.disabled,
36
39
  };
37
40
 
38
41
  return classNames(baseClasses, conditionalClasses);
@@ -40,32 +43,32 @@ export const useCheckbox = (props: CheckboxPropTypes, emit: SetupContext<Checkbo
40
43
 
41
44
  const inputCheckboxCheckIconClasses = computed(() => {
42
45
  const baseClasses =
43
- 'flex items-center justify-center pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform font-bold opacity-0';
46
+ 'spr-flex spr-items-center spr-justify-center spr-pointer-events-none spr-absolute spr-left-1/2 spr-top-1/2 -spr-translate-x-1/2 -spr-translate-y-1/2 spr-transform spr-font-bold spr-opacity-0';
44
47
 
45
48
  const conditionalClasses = {
46
- 'opacity-100': props.modelValue,
47
- 'text-color-inverted-strong': !props.disabled,
48
- 'text-color-on-fill-disabled': props.disabled,
49
+ 'spr-opacity-100': props.modelValue,
50
+ 'spr-text-color-inverted-strong': !props.disabled,
51
+ 'spr-text-color-on-fill-disabled': props.disabled,
49
52
  };
50
53
 
51
54
  return classNames(baseClasses, conditionalClasses);
52
55
  });
53
56
 
54
57
  const labelClasses = computed(() => {
55
- const baseClasses = 'label-xs-regular block';
58
+ const baseClasses = 'spr-label-xs-regular spr-block';
56
59
 
57
60
  const conditionalClasses = {
58
- 'text-color-on-fill-disabled': props.disabled,
61
+ 'spr-text-color-on-fill-disabled': props.disabled,
59
62
  };
60
63
 
61
64
  return classNames(baseClasses, conditionalClasses);
62
65
  });
63
66
 
64
67
  const descriptionClasses = computed(() => {
65
- const baseClasses = 'body-xs-regular block';
68
+ const baseClasses = 'spr-body-xs-regular spr-block';
66
69
 
67
70
  const conditionalClasses = {
68
- 'text-color-on-fill-disabled': props.disabled,
71
+ 'spr-text-color-on-fill-disabled': props.disabled,
69
72
  };
70
73
 
71
74
  return classNames(baseClasses, conditionalClasses);
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <Menu
3
3
  v-model:shown="menuOpened"
4
- class="w-fit"
4
+ class="spr-w-fit"
5
5
  aria-id="dropdown-wrapper"
6
6
  distance="4"
7
7
  :placement="props.placement"
@@ -13,25 +13,25 @@
13
13
  </div>
14
14
 
15
15
  <template #popper>
16
- <div class="grid gap-0.5">
16
+ <div class="spr-grid spr-gap-0.5">
17
17
  <div
18
18
  v-for="(item, index) in props.menu"
19
19
  :key="index"
20
20
  :class="[
21
21
  dropdownItemBaseClasses,
22
22
  {
23
- 'background-color-single-active': isItemSelected(item),
23
+ 'spr-background-color-single-active': isItemSelected(item),
24
24
  },
25
25
  ]"
26
26
  @click="handleSelectedItem(item)"
27
27
  >
28
28
  <spr-checkbox v-if="props.dropdownType === 'multi-select'" v-model="checkboxModels[item.text]" />
29
- <div class="flex w-full items-center">
30
- <span class="text-xs">{{ item.text }}</span>
29
+ <div class="spr-flex spr-w-full spr-items-center">
30
+ <span class="spr-text-xs">{{ item.text }}</span>
31
31
  </div>
32
32
  <Icon
33
33
  v-if="props.dropdownType === 'single-select' && isItemSelected(item)"
34
- class="text-color-brand-base w-[1.39em]"
34
+ class="spr-text-color-brand-base spr-w-[1.39em]"
35
35
  icon="ph:check"
36
36
  />
37
37
  </div>
@@ -1,7 +1,8 @@
1
1
  import { ref, onMounted, watch, computed } from 'vue';
2
- import type { SetupContext } from 'vue';
2
+
3
3
  import classNames from 'classnames';
4
4
 
5
+ import type { SetupContext } from 'vue';
5
6
  import type { DropdownPropTypes, DropdownEmitTypes } from './dropdown';
6
7
 
7
8
  interface SelectedItem {
@@ -12,10 +13,10 @@ interface SelectedItem {
12
13
  export const useDropdown = (props: DropdownPropTypes, emit: SetupContext<DropdownEmitTypes>['emit']) => {
13
14
  const dropdownItemBaseClasses = computed(() => {
14
15
  return classNames(
15
- 'flex cursor-pointer items-center justify-between gap-1.5 rounded-lg p-2',
16
- 'transition duration-150 ease-in-out',
17
- 'hover:background-color-hover',
18
- 'active:background-color-single-active active:scale-95',
16
+ 'spr-flex spr-cursor-pointer spr-items-center spr-justify-between spr-gap-1.5 spr-rounded-lg spr-p-2',
17
+ 'spr-transition spr-duration-150 spr-ease-in-out',
18
+ 'hover:spr-background-color-hover',
19
+ 'active:spr-background-color-single-active active:spr-scale-95',
19
20
  );
20
21
  });
21
22
 
@@ -3,13 +3,13 @@
3
3
  <slot :class="imageSizeClasses" />
4
4
 
5
5
  <div v-if="!$slots.default" :class="imageSizeClasses">
6
- <img :src="getImageUrl" alt="empty-image" class="h-full w-full object-cover" />
6
+ <img :src="getImageUrl" alt="empty-image" class="spr-h-full spr-w-full spr-object-cover" />
7
7
  </div>
8
8
 
9
- <section class="flex flex-col items-center justify-center gap-size-spacing-md">
10
- <div class="text-color-strong body-md body-md-regular-medium flex flex-col">
11
- {{ description }}
12
- <div class="text-color-base body-sm-regular">
9
+ <section class="spr-flex spr-flex-col spr-items-center spr-justify-center spr-gap-size-spacing-md">
10
+ <div class="spr-text-color-strong spr-body-md spr-body-md-regular-medium spr-flex spr-flex-col">
11
+ <span>{{ description }}</span>
12
+ <div class="spr-text-color-base spr-body-sm-regular">
13
13
  {{ subDescription }}
14
14
  </div>
15
15
  </div>
@@ -18,6 +18,7 @@
18
18
  </section>
19
19
  </div>
20
20
  </template>
21
+
21
22
  <script setup lang="ts">
22
23
  import { emptyStatePropTypes } from './empty-state';
23
24
  import { useEmptyState } from './use-empty-state';
@@ -1,24 +1,26 @@
1
1
  import { computed, toRefs } from 'vue';
2
- import type { EmptyStatePropTypes } from './empty-state';
3
2
 
4
3
  import classNames from 'classnames';
4
+
5
+ import type { EmptyStatePropTypes } from './empty-state';
6
+
5
7
  export const useEmptyState = (props: EmptyStatePropTypes) => {
6
8
  const { size, image } = toRefs(props);
7
9
 
8
10
  const emptyStateWrapperClasses = computed(() => {
9
11
  return classNames(
10
- 'background-color flex h-full w-full flex-col items-center justify-center gap-size-spacing-2xs px-size-spacing-2xl py-size-spacing-3xl text-center min-h-[240px]',
12
+ 'spr-background-color spr-flex spr-h-full spr-w-full spr-flex-col spr-items-center spr-justify-center spr-gap-size-spacing-2xs spr-px-size-spacing-2xl spr-py-size-spacing-3xl spr-text-center spr-min-h-[240px]',
11
13
  {
12
- 'px-size-spacing-sm py-size-spacing-md min-h-[240px]': size.value === 'small',
13
- 'px-size-spacing-sm py-size-spacing-2xl min-h-[360px]': size.value === 'large',
14
+ 'spr-px-size-spacing-sm spr-py-size-spacing-md spr-min-h-[240px]': size.value === 'small',
15
+ 'spr-px-size-spacing-sm spr-py-size-spacing-2xl spr-min-h-[360px]': size.value === 'large',
14
16
  },
15
17
  );
16
18
  });
17
19
 
18
20
  const imageSizeClasses = computed(() => {
19
21
  return classNames({
20
- 'h-[200px] w-[200px]': size.value === 'large',
21
- 'h-[120px] w-[120px]': size.value === 'small',
22
+ 'spr-h-[200px] spr-w-[200px]': size.value === 'large',
23
+ 'spr-h-[120px] spr-w-[120px]': size.value === 'small',
22
24
  });
23
25
  });
24
26
 
@@ -4,6 +4,10 @@ export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<
4
4
 
5
5
  const TRAILING_SIZES = ['xs', 'sm', 'md'] as const;
6
6
 
7
+ export const INPUT_TYPES = ['default','search'] as const;
8
+
9
+ export const TYPE_HAS_TRAILING_ICONS = ['search'] as const;
10
+
7
11
  export const inputPropTypes = {
8
12
  id: {
9
13
  type: String,
@@ -19,7 +23,8 @@ export const inputPropTypes = {
19
23
  },
20
24
  type: {
21
25
  type: String,
22
- default: 'text',
26
+ validator: (value: (typeof INPUT_TYPES)[number]) => INPUT_TYPES.includes(value),
27
+ default: 'default',
23
28
  },
24
29
  placeholder: {
25
30
  type: String,