design-system-next 2.8.3 → 2.9.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.
@@ -1,12 +1,16 @@
1
1
  import { computed, SetupContext, toRefs, ref, watch } from 'vue';
2
2
  import dayjs from 'dayjs';
3
+ import isBetween from 'dayjs/plugin/isBetween';
3
4
  import classNames from 'classnames';
5
+ import { useInfiniteScroll } from '@vueuse/core';
4
6
  import { useVModel } from '@vueuse/core';
5
7
 
8
+ dayjs.extend(isBetween);
9
+
6
10
  import type { CalendarPropTypes, CalendarEmitTypes, SelectedShift } from './calendar';
7
11
 
8
12
  export const useCalendar = (props: CalendarPropTypes, emit: SetupContext<CalendarEmitTypes>['emit']) => {
9
- const { initialDate, companyOptions, departmentOptions, branchOptions } = toRefs(props);
13
+ const { initialDate, hideAddButton } = toRefs(props);
10
14
 
11
15
  const state = {
12
16
  dateFormat: ref('YYYY-MM-DD'),
@@ -21,13 +25,20 @@ export const useCalendar = (props: CalendarPropTypes, emit: SetupContext<Calenda
21
25
  isHover: ref<boolean>(false),
22
26
  hoveredCell: ref<number>(),
23
27
  employeeId: ref<number>(),
28
+ sort: ref<string>(''),
29
+ tableBodyRef: ref<HTMLElement | null>(null),
24
30
  };
25
31
 
26
32
  const searchEmployee = useVModel(props, 'search', emit);
27
33
  const selectedCell = useVModel(props, 'selectedCell', emit);
28
- const selectedCompany = useVModel(props, 'selectedCompany', emit);
29
- const selectedDepartment = useVModel(props, 'selectedDepartment', emit);
30
- const selectedBranch = useVModel(props, 'selectedBranch', emit);
34
+
35
+ const getSortIcon = computed(() => {
36
+ if (!state.sort.value) {
37
+ return 'ph:caret-up-down-light';
38
+ }
39
+
40
+ return state.sort.value === 'asc' ? 'ph:arrow-up' : 'ph:arrow-down';
41
+ });
31
42
 
32
43
  const startDate = computed(() => state.currentDate.value.startOf('week'));
33
44
 
@@ -63,64 +74,81 @@ export const useCalendar = (props: CalendarPropTypes, emit: SetupContext<Calenda
63
74
  state.currentDate.value = state.currentDate.value.add(1, 'week');
64
75
  };
65
76
 
77
+ const getFirstAndLastDayOfWeek = () => {
78
+ if (!state.currentDate.value) return;
79
+
80
+ const firstDayOfWeek = state.currentDate.value.startOf('week');
81
+ const lastDayOfWeek = state.currentDate.value.endOf('week');
82
+
83
+ emit('update:firstLastDayOfWeek', {
84
+ firstDay: firstDayOfWeek.format(state.dateFormat.value),
85
+ lastDay: lastDayOfWeek.format(state.dateFormat.value),
86
+ });
87
+ };
88
+
66
89
  const goToToday = () => {
67
- state.currentDate.value = dayjs();
90
+ const today = dayjs();
91
+ const currentWeekStart = state.currentDate.value.startOf('week');
92
+ const currentWeekEnd = state.currentDate.value.endOf('week');
93
+
94
+ // Only update if today is not within the current week
95
+ if (!today.isBetween(currentWeekStart, currentWeekEnd, 'day', '[]')) {
96
+ state.currentDate.value = today;
97
+ }
68
98
  };
69
99
 
70
- const onShiftClick = (selected: SelectedShift) => {
100
+ const onCellClick = (selected: SelectedShift) => {
71
101
  selectedCell.value = selected;
102
+ emit('onCellClick', selected);
72
103
  };
73
104
 
74
105
  const handleHover = (isHover: boolean, index: number, employeeId: number) => {
75
106
  state.isHover.value = isHover;
76
- state.hoveredCell.value = isHover ? index : null;
107
+ state.hoveredCell.value = isHover ? index : undefined;
77
108
  state.employeeId.value = employeeId;
78
109
  };
79
110
 
80
111
  const showAddShift = (index: number, employeeId: number) => {
81
- return state.hoveredCell.value === index && state.isHover.value && state.employeeId.value === employeeId;
112
+ return (
113
+ state.hoveredCell.value === index &&
114
+ state.isHover.value &&
115
+ state.employeeId.value === employeeId &&
116
+ !hideAddButton.value
117
+ );
82
118
  };
83
119
 
84
- const handleFilter = (filter: string, selected: string) => {
85
- if (filter === 'company') {
86
- const foundCompany = companyOptions.value.find((item) => item.value === selected);
87
- state.selectedCompany.value = foundCompany?.text ?? '';
88
- selectedCompany.value = selected;
89
- }
90
-
91
- if (filter === 'department') {
92
- const foundCompany = departmentOptions.value.find((item) => item.value === selected);
93
- state.selectedDepartment.value = foundCompany?.text ?? '';
94
- selectedDepartment.value = selected;
95
- }
96
-
97
- if (filter === 'branch') {
98
- const foundCompany = branchOptions.value.find((item) => item.value === selected);
99
- state.selectedBranch.value = foundCompany?.text ?? '';
100
- selectedBranch.value = selected;
101
- }
120
+ const handleSorting = () => {
121
+ state.sort.value = state.sort.value === 'desc' ? 'asc' : 'desc';
122
+ emit('update:sort', state.sort.value);
102
123
  };
103
124
 
104
- watch(state.searchTerm, (value, oldValue) => {
105
- if (value === oldValue) return; // Prevent unnecessary updates
106
- searchEmployee.value = value;
107
- });
125
+ useInfiniteScroll(
126
+ state.tableBodyRef,
127
+ () => {
128
+ emit('loadMore');
129
+ },
130
+ {
131
+ distance: 50,
132
+ direction: 'bottom',
133
+ },
134
+ );
108
135
 
109
136
  const getCalendarClasses = computed(() => {
110
137
  const borderClasses = classNames(' spr-border spr-border-color-weak spr-border-solid');
111
138
  const headerWrapper = classNames(
112
- 'spr-bg-color-weak spr-flex spr-w-full spr-items-center spr-justify-between spr-border-x-0 spr-border-b spr-border-t-0 spr-p-size-spacing-sm',
139
+ 'spr-bg-color-weak spr-flex spr-w-full spr-items-center spr-justify-between spr-p-size-spacing-sm',
113
140
  );
114
141
 
115
142
  const contentWrapper = classNames('spr-divide-color-weak spr-divide-x-0 spr-divide-y spr-divide-solid');
116
- const calendarFilter = classNames('spr-grid spr-grid-cols-4 spr-gap-size-spacing-2xs spr-p-size-spacing-xs');
117
143
  const calendarTable = classNames(
118
- 'spr-table spr-w-full spr-table-fixed spr-border-collapse spr-border-spacing-0 spr-overflow-hidden spr-rounded-border',
144
+ ' spr-overflow-y-auto spr-h-full spr-table spr-w-full spr-table-fixed spr-border-collapse spr-border-spacing-0 spr-rounded-border',
119
145
  );
120
146
  const tableHeaderEmployeeName = classNames(
121
- 'spr-body-xs-regular-medium spr-border-x spr-border-y spr-p-size-spacing-xs spr-text-left first:spr-border-l-0 spr-overflow-hidden',
147
+ 'spr-sticky spr-left-0 spr-z-20 spr-background-color spr-body-xs-regular-medium spr-p-size-spacing-xs spr-text-left spr-overflow-hidden spr-h-full',
148
+ );
149
+ const tableHeader = classNames(
150
+ 'spr-background-color spr-border-x-0 spr-border-y-0 spr-border-l spr-p-size-spacing-sm spr-text-center',
122
151
  );
123
- const tableHeader = classNames('spr-border-x-0 spr-border-y spr-border-l spr-p-size-spacing-sm spr-text-center');
124
152
  const headerContent = classNames(
125
153
  'spr-flex spr-flex-row spr-w-full spr-items-center spr-gap-size-spacing-3xs lg:spr-flex-col spr-overflow-hidden',
126
154
  );
@@ -128,11 +156,16 @@ export const useCalendar = (props: CalendarPropTypes, emit: SetupContext<Calenda
128
156
  'spr-font-size-400 spr-line-height-500 spr-letter-spacing-dense spr-flex spr-h-size-spacing-md spr-w-size-spacing-md spr-items-center spr-justify-center spr-rounded-full spr-font-main spr-font-normal',
129
157
  );
130
158
 
159
+ getFirstAndLastDayOfWeek();
160
+
161
+ watch(state.searchTerm, (value, oldValue) => {
162
+ if (value === oldValue) return; // Prevent unnecessary updates
163
+ searchEmployee.value = value;
164
+ });
131
165
  return {
132
166
  borderClasses,
133
167
  headerWrapper,
134
168
  contentWrapper,
135
- calendarFilter,
136
169
  calendarTable,
137
170
  tableHeaderEmployeeName,
138
171
  tableHeader,
@@ -145,16 +178,17 @@ export const useCalendar = (props: CalendarPropTypes, emit: SetupContext<Calenda
145
178
  weekDates,
146
179
  weekRangeDisplay,
147
180
  getCalendarClasses,
181
+ getSortIcon,
148
182
 
149
183
  formatDate,
150
184
  isToday,
151
185
  prevWeek,
152
186
  nextWeek,
153
187
  goToToday,
154
- onShiftClick,
188
+ onCellClick,
155
189
  handleHover,
156
190
  showAddShift,
157
- handleFilter,
191
+ handleSorting,
158
192
 
159
193
  ...state,
160
194
  };
@@ -110,7 +110,6 @@ export const useCalendarCell = (props: CalendarCellPropTypes, emit: SetupContext
110
110
 
111
111
  return;
112
112
  }
113
-
114
113
  emit('onClick', evt);
115
114
  };
116
115
 
@@ -358,13 +358,17 @@ export const useList = (props: ListPropTypes, emit: SetupContext<ListEmitTypes>[
358
358
  };
359
359
  // #endregion - Helper Methods
360
360
 
361
- watch(menuList, () => {
362
- localizedMenuList.value = [];
363
- groupedMenuList.value = [];
361
+ watch(
362
+ menuList,
363
+ () => {
364
+ localizedMenuList.value = [];
365
+ groupedMenuList.value = [];
364
366
 
365
- setMenuList();
366
- setPreSelectedItems();
367
- });
367
+ setMenuList();
368
+ setPreSelectedItems();
369
+ },
370
+ { deep: true },
371
+ );
368
372
 
369
373
  onMounted(() => {
370
374
  setMenuList();
@@ -1,164 +1,164 @@
1
- import { ref, toRefs, computed, watch } from 'vue';
2
- import { useVModel, useDebounceFn, onClickOutside } from '@vueuse/core';
3
-
4
- import type { SelectLadderizedPropTypes } from './select-ladderized';
5
-
6
- import type { MenuListType } from '@/components/list/list';
7
-
8
- export const useSelectLadderized = (
9
- props: SelectLadderizedPropTypes,
10
- emit: (event: string, ...args: unknown[]) => void,
11
- ) => {
12
- const { options, disabled } = toRefs(props);
13
-
14
- const ladderizedClasses = computed(() => ({
15
- baseClasses: 'spr-flex spr-flex-col spr-gap-size-spacing-4xs',
16
- labelClasses: 'spr-body-sm-regular spr-text-color-strong spr-block',
17
- }));
18
-
19
- // Popper Variables
20
- const ladderizedSelectPopperState = ref(false);
21
- const ladderizedSelectRef = ref(null);
22
- const isLadderizedSelectPopperDisabled = computed(() => disabled.value);
23
-
24
- // Ladderized Select Model
25
- const ladderizedSelectModel = useVModel(props, 'modelValue', emit);
26
- const ladderizedSelectOptions = computed(() => options.value);
27
-
28
- // Input Variables
29
- const inputText = ref<string>('');
30
- const isSearching = ref(false);
31
- const wasCleared = ref(false);
32
-
33
- const isLeafNode = (item: MenuListType): boolean => {
34
- return !item.sublevel || item.sublevel.length === 0;
35
- };
36
-
37
- // Helper to find the path to a selected value in the menu tree
38
- const findPathToValue = (items: MenuListType[], value: string | number, path: string[] = []): string[] | null => {
39
- for (const item of items) {
40
- const newPath = [...path, item.text];
41
-
42
- if (item.value === value) {
43
- return newPath;
44
- }
45
-
46
- if (item.sublevel) {
47
- const result = findPathToValue(item.sublevel, value, newPath);
48
-
49
- if (result) return result;
50
- }
51
- }
52
-
53
- return null;
54
- };
55
-
56
- const handleSelectedLadderizedItem = (selectedItems: string[], selectedItem?: MenuListType) => {
57
- wasCleared.value = false;
58
- ladderizedSelectModel.value = selectedItems;
59
-
60
- let itemToCheck = selectedItem;
61
-
62
- // Fallback: if selectedItem is not provided, try to find it from the value
63
- if (!itemToCheck && selectedItems.length > 0) {
64
- const findItemByValue = (items: MenuListType[], value: string | number): MenuListType | undefined => {
65
- for (const item of items) {
66
- if (item.value === value) return item;
67
-
68
- if (item.sublevel) {
69
- const found = findItemByValue(item.sublevel, value);
70
-
71
- if (found) return found;
72
- }
73
- }
74
-
75
- return undefined;
76
- };
77
-
78
- itemToCheck = findItemByValue(ladderizedSelectOptions.value, selectedItems[selectedItems.length - 1]);
79
- }
80
-
81
- if (itemToCheck) {
82
- const path = findPathToValue(ladderizedSelectOptions.value, itemToCheck.value);
83
-
84
- inputText.value = path ? path.join(' > ') : itemToCheck.text || '';
85
-
86
- if (isLeafNode(itemToCheck)) {
87
- ladderizedSelectPopperState.value = false;
88
- }
89
- } else if (selectedItems.length === 0 && !wasCleared.value) {
90
- inputText.value = '';
91
- }
92
- };
93
-
94
- const handleSearch = () => {
95
- isSearching.value = true;
96
-
97
- debouncedEmitSearch();
98
- };
99
-
100
- const debouncedEmitSearch = useDebounceFn(() => {
101
- // Optionally emit search event here if needed
102
- }, 300);
103
-
104
- const handleClear = () => {
105
- wasCleared.value = true;
106
-
107
- inputText.value = '';
108
-
109
- emit('update:modelValue', []);
110
- };
111
-
112
- const handleOptionsToggle = () => {
113
- ladderizedSelectPopperState.value = true;
114
-
115
- isSearching.value = false;
116
- };
117
-
118
- // Watch for changes in modelValue to update inputText
119
- watch(
120
- () => ladderizedSelectModel.value,
121
- (newVal) => {
122
- if (wasCleared.value) {
123
- inputText.value = '';
124
- wasCleared.value = false;
125
- return;
126
- }
127
-
128
- if (Array.isArray(newVal) && newVal.length > 0) {
129
- // Treat the array as a single path for ladderized select
130
- let currentLevel = ladderizedSelectOptions.value;
131
-
132
- const pathTexts: string[] = [];
133
-
134
- for (const value of newVal) {
135
- const found = currentLevel.find((item) => item.value === value);
136
- if (!found) break;
137
- pathTexts.push(found.text);
138
- currentLevel = found.sublevel || [];
139
- }
140
-
141
- inputText.value = pathTexts.join(' > ');
142
- }
143
- },
144
- { immediate: true },
145
- );
146
-
147
- onClickOutside(ladderizedSelectRef, () => {
148
- ladderizedSelectPopperState.value = false;
149
- });
150
-
151
- return {
152
- ladderizedClasses,
153
- ladderizedSelectPopperState,
154
- ladderizedSelectRef,
155
- ladderizedSelectOptions,
156
- isLadderizedSelectPopperDisabled,
157
- ladderizedSelectModel,
158
- inputText,
159
- handleSelectedLadderizedItem,
160
- handleSearch,
161
- handleClear,
162
- handleOptionsToggle,
163
- };
164
- };
1
+ import { ref, toRefs, computed, watch } from 'vue';
2
+ import { useVModel, useDebounceFn, onClickOutside } from '@vueuse/core';
3
+
4
+ import type { SelectLadderizedPropTypes } from './select-ladderized';
5
+
6
+ import type { MenuListType } from '@/components/list/list';
7
+
8
+ export const useSelectLadderized = (
9
+ props: SelectLadderizedPropTypes,
10
+ emit: (event: string, ...args: unknown[]) => void,
11
+ ) => {
12
+ const { options, disabled } = toRefs(props);
13
+
14
+ const ladderizedClasses = computed(() => ({
15
+ baseClasses: 'spr-flex spr-flex-col spr-gap-size-spacing-4xs',
16
+ labelClasses: 'spr-body-sm-regular spr-text-color-strong spr-block',
17
+ }));
18
+
19
+ // Popper Variables
20
+ const ladderizedSelectPopperState = ref(false);
21
+ const ladderizedSelectRef = ref(null);
22
+ const isLadderizedSelectPopperDisabled = computed(() => disabled.value);
23
+
24
+ // Ladderized Select Model
25
+ const ladderizedSelectModel = useVModel(props, 'modelValue', emit);
26
+ const ladderizedSelectOptions = computed(() => options.value);
27
+
28
+ // Input Variables
29
+ const inputText = ref<string>('');
30
+ const isSearching = ref(false);
31
+ const wasCleared = ref(false);
32
+
33
+ const isLeafNode = (item: MenuListType): boolean => {
34
+ return !item.sublevel || item.sublevel.length === 0;
35
+ };
36
+
37
+ // Helper to find the path to a selected value in the menu tree
38
+ const findPathToValue = (items: MenuListType[], value: string | number, path: string[] = []): string[] | null => {
39
+ for (const item of items) {
40
+ const newPath = [...path, item.text];
41
+
42
+ if (item.value === value) {
43
+ return newPath;
44
+ }
45
+
46
+ if (item.sublevel) {
47
+ const result = findPathToValue(item.sublevel, value, newPath);
48
+
49
+ if (result) return result;
50
+ }
51
+ }
52
+
53
+ return null;
54
+ };
55
+
56
+ const handleSelectedLadderizedItem = (selectedItems: string[], selectedItem?: MenuListType) => {
57
+ wasCleared.value = false;
58
+ ladderizedSelectModel.value = selectedItems;
59
+
60
+ let itemToCheck = selectedItem;
61
+
62
+ // Fallback: if selectedItem is not provided, try to find it from the value
63
+ if (!itemToCheck && selectedItems.length > 0) {
64
+ const findItemByValue = (items: MenuListType[], value: string | number): MenuListType | undefined => {
65
+ for (const item of items) {
66
+ if (item.value === value) return item;
67
+
68
+ if (item.sublevel) {
69
+ const found = findItemByValue(item.sublevel, value);
70
+
71
+ if (found) return found;
72
+ }
73
+ }
74
+
75
+ return undefined;
76
+ };
77
+
78
+ itemToCheck = findItemByValue(ladderizedSelectOptions.value, selectedItems[selectedItems.length - 1]);
79
+ }
80
+
81
+ if (itemToCheck) {
82
+ const path = findPathToValue(ladderizedSelectOptions.value, itemToCheck.value);
83
+
84
+ inputText.value = path ? path.join(' > ') : itemToCheck.text || '';
85
+
86
+ if (isLeafNode(itemToCheck)) {
87
+ ladderizedSelectPopperState.value = false;
88
+ }
89
+ } else if (selectedItems.length === 0 && !wasCleared.value) {
90
+ inputText.value = '';
91
+ }
92
+ };
93
+
94
+ const handleSearch = () => {
95
+ isSearching.value = true;
96
+
97
+ debouncedEmitSearch();
98
+ };
99
+
100
+ const debouncedEmitSearch = useDebounceFn(() => {
101
+ // Optionally emit search event here if needed
102
+ }, 300);
103
+
104
+ const handleClear = () => {
105
+ wasCleared.value = true;
106
+
107
+ inputText.value = '';
108
+
109
+ emit('update:modelValue', []);
110
+ };
111
+
112
+ const handleOptionsToggle = () => {
113
+ ladderizedSelectPopperState.value = true;
114
+
115
+ isSearching.value = false;
116
+ };
117
+
118
+ // Watch for changes in modelValue to update inputText
119
+ watch(
120
+ () => ladderizedSelectModel.value,
121
+ (newVal) => {
122
+ if (wasCleared.value) {
123
+ inputText.value = '';
124
+ wasCleared.value = false;
125
+ return;
126
+ }
127
+
128
+ if (Array.isArray(newVal) && newVal.length > 0) {
129
+ // Treat the array as a single path for ladderized select
130
+ let currentLevel = ladderizedSelectOptions.value;
131
+
132
+ const pathTexts: string[] = [];
133
+
134
+ for (const value of newVal) {
135
+ const found = currentLevel.find((item) => item.value === value);
136
+ if (!found) break;
137
+ pathTexts.push(found.text);
138
+ currentLevel = found.sublevel || [];
139
+ }
140
+
141
+ inputText.value = pathTexts.join(' > ');
142
+ }
143
+ },
144
+ { immediate: true },
145
+ );
146
+
147
+ onClickOutside(ladderizedSelectRef, () => {
148
+ ladderizedSelectPopperState.value = false;
149
+ });
150
+
151
+ return {
152
+ ladderizedClasses,
153
+ ladderizedSelectPopperState,
154
+ ladderizedSelectRef,
155
+ ladderizedSelectOptions,
156
+ isLadderizedSelectPopperDisabled,
157
+ ladderizedSelectModel,
158
+ inputText,
159
+ handleSelectedLadderizedItem,
160
+ handleSearch,
161
+ handleClear,
162
+ handleOptionsToggle,
163
+ };
164
+ };
@@ -147,9 +147,13 @@ export const useSelect = (props: SelectPropTypes, emit: SetupContext<SelectEmitT
147
147
  return selectOptions.value.filter((item) => item.text?.toString().toLowerCase().includes(query));
148
148
  });
149
149
 
150
- watch(options, () => {
151
- processOptions();
152
- });
150
+ watch(
151
+ options,
152
+ () => {
153
+ processOptions();
154
+ },
155
+ { deep: true },
156
+ );
153
157
 
154
158
  // Search handler: always emit search-string, but only filter locally if local search is enabled
155
159
  const handleSearch = () => {
@@ -1,4 +1,5 @@
1
1
  import type { ExtractPropTypes, PropType } from 'vue';
2
+ import { STEPPER_TYPE } from '../stepper';
2
3
 
3
4
  export const STEP_STATES = ['pending', 'active', 'completed'] as const;
4
5
 
@@ -29,6 +30,13 @@ export const stepPropTypes = {
29
30
  validator: (value: (typeof STEP_STATES)[number]) => STEP_STATES.includes(value),
30
31
  default: 'pending',
31
32
  },
33
+ /**
34
+ * @description Display type of stepper if displayed as compact (no solid bg color) or solid
35
+ */
36
+ type: {
37
+ type: String as PropType<(typeof STEPPER_TYPE)[number]>,
38
+ validator: (value: (typeof STEPPER_TYPE)[number]) => STEPPER_TYPE.includes(value),
39
+ }
32
40
  };
33
41
 
34
42
  export const stepEmitTypes = {
@@ -2,7 +2,8 @@
2
2
  <div :class="stepClasses.baseClass">
3
3
  <!-- STEP NUMBER -->
4
4
  <div :class="stepClasses.badgeClass">
5
- <span :class="stepClasses.numberClass">
5
+ <icon v-if="props.status === 'completed' && props.type === 'solid'" icon="ph:check-bold" width="14px" height="14px" class="spr-text-color-inverted-strong"/>
6
+ <span v-else :class="stepClasses.numberClass">
6
7
  {{ props.number }}
7
8
  </span>
8
9
  </div>
@@ -23,6 +24,7 @@
23
24
  <script setup lang="ts">
24
25
  import { stepEmitTypes, stepPropTypes } from '@/components/stepper/step/step';
25
26
  import { useStep } from '@/components/stepper/step/use-step';
27
+ import { Icon } from '@iconify/vue';
26
28
 
27
29
  const props = defineProps(stepPropTypes);
28
30
  const emit = defineEmits(stepEmitTypes);
@@ -16,19 +16,29 @@ interface StepClasses {
16
16
  export const useStep = (props: StepPropTypes, emit: SetupContext<StepEmitTypes>['emit']) => {
17
17
 
18
18
  const stepClasses: ComputedRef<StepClasses> = computed(() => {
19
- const baseClass = classNames('spr-flex spr-gap-2 spr-items-center');
19
+ const baseClass = classNames(
20
+ 'spr-flex spr-gap-2 spr-items-top',
21
+ {
22
+ 'spr-p-size-spacing-3xs spr-rounded-border-radius-lg': props.type === 'solid',
23
+ 'spr-background-color-brand-weak': props.status === 'active' && props.type === 'solid',
24
+ 'spr-opacity-60': props.status === 'completed' && props.type === 'solid'
25
+ }
26
+ );
20
27
 
21
28
  // Usage of prop.status ensures reactivity instead of destructuring props
22
29
  const badgeClass = classNames(
23
- 'spr-flex spr-items-center spr-justify-center spr-rounded-border-radius-full spr-h-6 spr-w-6 spr-border spr-border-solid spr-border-2',
30
+ 'spr-flex spr-items-center spr-justify-center spr-rounded-border-radius-full spr-h-6 spr-w-6 spr-border spr-border-solid',
24
31
  {
25
- 'spr-bg-kangkong-700 spr-border-kangkong-700': props.status === 'active',
32
+ 'spr-border-2': props.type !== 'solid',
33
+ 'spr-border-1': props.type === 'solid',
34
+ 'spr-background-color-brand-base spr-border-color-brand-base': props.status === 'active',
26
35
  'spr-border-mushroom-300': props.status === 'pending',
27
36
  'spr-border-kangkong-700': props.status === 'completed',
37
+ 'spr-background-color-brand-base': props.status === 'completed' && props.type === 'solid'
28
38
  }
29
39
  );
30
40
 
31
- const numberClass = classNames('spr-text-sm spr-font-medium',
41
+ const numberClass = classNames('spr-body-md-regular-medium',
32
42
  {
33
43
  'spr-text-white-50': props.status === 'active',
34
44
  'spr-text-mushroom-600': props.status === 'pending',
@@ -36,18 +46,20 @@ export const useStep = (props: StepPropTypes, emit: SetupContext<StepEmitTypes>[
36
46
  }
37
47
  );
38
48
 
39
- const textContainerClass = classNames('spr-flex spr-flex-col spr-relative');
49
+ const textContainerClass = classNames('spr-flex spr-flex-col spr-mt-[2px]');
40
50
 
41
- const labelClass = classNames('spr-text-sm spr-whitespace-nowrap',
51
+ const labelClass = classNames('spr-body-md-regular spr-whitespace-nowrap',
42
52
  {
43
- 'spr-text-kangkong-700 spr-font-semibold': props.status === 'active',
44
- 'spr-text-mushroom-600': props.status === 'pending',
45
- 'spr-text-mushroom-950': props.status === 'completed',
53
+ 'spr-text-kangkong-700 !spr-body-md-regular-medium': props.status === 'active' && props.type === 'compact',
54
+ 'spr-text-mushroom-600': props.status === 'pending',
55
+ 'spr-text-mushroom-950': props.status === 'completed',
46
56
  }
47
57
  );
48
58
 
49
59
  // Absolute since the sample in the figma is a hanging text for description
50
- const descriptionClass = classNames('spr-text-xs spr-text-mushroom-400 spr-absolute spr-mt-size-spacing-sm spr-whitespace-nowrap');
60
+ const descriptionClass = classNames(
61
+ 'spr-body-sm-regular spr-text-color-supporting spr-whitespace-nowrap',
62
+ );
51
63
 
52
64
  return {
53
65
  baseClass,