spoko-design-system 1.3.1 → 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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ ## [1.3.2](https://github.com/polo-blue/sds/compare/v1.3.1...v1.3.2) (2025-10-07)
2
+
1
3
  ## [1.3.1](https://github.com/polo-blue/sds/compare/v1.3.0...v1.3.1) (2025-10-05)
2
4
 
3
5
  ## [1.3.0](https://github.com/polo-blue/sds/compare/v1.2.2...v1.3.0) (2025-10-05)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spoko-design-system",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "private": false,
5
5
  "main": "./index.ts",
6
6
  "module": "./index.ts",
@@ -2,30 +2,18 @@
2
2
  import { PropType, computed } from 'vue';
3
3
  import ProductDetailName from './ProductDetailName.vue';
4
4
 
5
- interface ColorCode {
6
- code: string;
7
- name: string;
5
+ interface Link {
6
+ type: string;
7
+ url: string;
8
+ anchor: string;
8
9
  }
9
10
 
10
11
  interface TableItem {
11
12
  id: string;
12
- name: string;
13
- value: unknown; // Może być string, number, boolean, array (ColorCode[] lub string[])
14
- translated?: boolean;
15
- icon?: boolean;
16
- isArrayValue?: boolean;
17
- isColorArray?: boolean; // dla product.colors (color_ids)
18
- isPaintMarks?: boolean; // dla product.paint_marks_text
19
- isGenericArray?: boolean; // dla ogólnych tablic stringów (np. position)
20
- isForExteriorColour?: boolean; // Ta flaga będzie ustawiana przez getProductDetails na true, jeśli 'value' jest tablicą
21
- }
22
-
23
- interface GroupedLink {
24
- id: string;
25
- links: {
26
- name: string;
27
- value: string;
28
- }[];
13
+ label: string; // Display name from API
14
+ value: unknown; // Can be string, number, boolean, string array, or Link array
15
+ type?: string; // 'links' for link arrays
16
+ isGenericArray?: boolean; // for generic string arrays (e.g., position)
29
17
  }
30
18
 
31
19
  const props = defineProps({
@@ -33,21 +21,9 @@ const props = defineProps({
33
21
  caption: { type: String, default: null },
34
22
  });
35
23
 
36
- // Function to check if a value is a link
37
- const isLink = (id: string) => {
38
- return ['blog', 'youtube', 'vimeo'].includes(id);
39
- };
40
-
41
- // Function to check if it's a color array (for 'color_ids' field from product.colors)
42
- // This will still apply to the 'color' detail if its value is an array of ColorCode objects
43
- const isColorArray = (item: TableItem) => {
44
- const colorIds = ['color', 'thread-color']; // lista ID które są kolorami
45
- return (item.isColorArray || colorIds.includes(item.id)) && Array.isArray(item.value);
46
- };
47
-
48
- // Function to check if it's paint marks (value is now a string from API)
49
- const isPaintMarks = (item: TableItem) => {
50
- return item.isPaintMarks && typeof item.value === 'string';
24
+ // Function to check if it's a links array from new API
25
+ const isLinksArray = (item: TableItem) => {
26
+ return item.type === 'links' && Array.isArray(item.value);
51
27
  };
52
28
 
53
29
  // Function to check if it's a generic array (e.g., for position)
@@ -55,33 +31,23 @@ const isGenericArray = (item: TableItem) => {
55
31
  return item.isGenericArray && Array.isArray(item.value);
56
32
  };
57
33
 
58
- // ✅ Zaktualizowana funkcja: Sprawdzamy ID i czy value jest faktycznie tablicą ColorCode[]
59
- const isForExteriorColour = (item: TableItem) => {
60
- return item.id === 'for-exterior-colour' && Array.isArray(item.value);
61
- };
62
-
63
34
  // Function to check if value is HTML string (fallback)
64
35
  const isHtmlValue = (value: unknown): boolean => {
65
36
  return typeof value === 'string' && (value.includes('<span') || value.includes('<br>'));
66
37
  };
67
38
 
68
39
  // Function for specifying header text
69
- const getHeaderText = (row: TableItem | GroupedLink) => {
70
- if (row.id === 'blog') {
71
- return row.id.charAt(0).toUpperCase() + row.id.slice(1);
72
- }
73
- // Użyj `name` z obiektu `TableItem`, jeśli istnieje, w przeciwnym razie sformatuj `id`.
74
- return 'name' in row
75
- ? row.name
76
- : row.id
77
- .split('-')
78
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
79
- .join(' ');
40
+ const getHeaderText = (row: TableItem) => {
41
+ return row.label || row.id
42
+ .split('-')
43
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
44
+ .join(' ');
80
45
  };
81
46
 
82
47
  // Function to determine the icon class for a link type
83
- const getLinkIconClass = (linkId: string) => {
84
- switch (linkId) {
48
+ const getLinkIconClass = (linkType: string) => {
49
+ const type = linkType.toLowerCase();
50
+ switch (type) {
85
51
  case 'blog':
86
52
  return 'i-lucide-book-text';
87
53
  case 'youtube':
@@ -93,46 +59,13 @@ const getLinkIconClass = (linkId: string) => {
93
59
  }
94
60
  };
95
61
 
96
- // Grouping of elements by id
97
- const groupedItems = computed(() => {
98
- // ✅ Add validation to ensure props.items is an array
62
+ // Validate items
63
+ const validatedItems = computed(() => {
99
64
  if (!Array.isArray(props.items)) {
100
65
  console.warn('ProductDetailsList: items prop is not an array:', props.items);
101
66
  return [];
102
67
  }
103
-
104
- const result: (TableItem | GroupedLink)[] = [];
105
- const linkGroups = new Map<string, GroupedLink>();
106
-
107
- // Process all elements
108
- for (const item of props.items) {
109
- // If it's a link (blog, youtube, vimeo)
110
- if (isLink(item.id)) {
111
- // Add a link to the relevant group
112
- if (!linkGroups.has(item.id)) {
113
- linkGroups.set(item.id, {
114
- id: item.id,
115
- links: [],
116
- });
117
- }
118
-
119
- // Add link to the relevant group
120
- linkGroups.get(item.id)?.links.push({
121
- name: item.name,
122
- value: item.value as string,
123
- });
124
- } else {
125
- // If it's not a link, add it normally to the results
126
- result.push(item);
127
- }
128
- }
129
-
130
- // Add all link groups at the end
131
- for (const group of linkGroups.values()) {
132
- result.push(group);
133
- }
134
-
135
- return result;
68
+ return props.items;
136
69
  });
137
70
  </script>
138
71
 
@@ -149,7 +82,7 @@ const groupedItems = computed(() => {
149
82
  </colgroup>
150
83
  <tbody>
151
84
  <tr
152
- v-for="(row, index) in groupedItems"
85
+ v-for="(row, index) in validatedItems"
153
86
  :key="index"
154
87
  class="details-table-row"
155
88
  >
@@ -160,84 +93,35 @@ const groupedItems = computed(() => {
160
93
  />
161
94
 
162
95
  <td
163
- v-if="'links' in row"
96
+ v-if="isLinksArray(row)"
164
97
  class="details-table-cell"
165
98
  >
166
99
  <ul class="list-none p-0 m-0">
167
100
  <li
168
- v-for="(link, linkIndex) in row.links"
101
+ v-for="(link, linkIndex) in row.value as Link[]"
169
102
  :key="linkIndex"
170
103
  class="mb-2 last:mb-0 flex items-center"
171
104
  >
172
105
  <span
173
106
  :class="[
174
- getLinkIconClass(row.id),
107
+ getLinkIconClass(link.type),
175
108
  'leading-none inline-block mr-2 w-4 min-w-4 h-4 text-gray-400',
176
109
  ]"
177
110
  />
178
111
  <a
179
- :href="link.value"
112
+ :href="link.url"
180
113
  target="_blank"
181
114
  rel="noopener noreferrer"
182
115
  class="link-primary"
183
116
  >
184
- {{ link.name }}
117
+ {{ link.anchor }}
185
118
  </a>
186
119
  </li>
187
120
  </ul>
188
121
  </td>
189
122
 
190
123
  <td
191
- v-else-if="'id' in row && isColorArray(row)"
192
- class="details-table-cell"
193
- >
194
- <ul class="list-none p-0 m-0">
195
- <li
196
- v-for="(colorItem, colorIndex) in row.value as ColorCode[]"
197
- :key="colorIndex"
198
- class="flex items-center gap-1 mb-1 last:mb-0"
199
- >
200
- <template v-if="colorItem.code">
201
- <code class="font-mono text-sm">
202
- {{ colorItem.code }}
203
- </code>
204
- <span class="text-gray-400">-</span>
205
- </template>
206
- <span class="text-gray-700 dark:text-gray-300">{{ colorItem.name }}</span>
207
- </li>
208
- </ul>
209
- </td>
210
-
211
- <td
212
- v-else-if="'id' in row && isPaintMarks(row)"
213
- class="details-table-cell"
214
- >
215
- <span class="text-gray-700 dark:text-gray-300">{{ row.value }}</span>
216
- </td>
217
-
218
- <td
219
- v-else-if="'id' in row && isForExteriorColour(row)"
220
- class="details-table-cell"
221
- >
222
- <ul class="list-none p-0 m-0">
223
- <li
224
- v-for="(colorEntry, colourIndex) in row.value as ColorCode[]"
225
- :key="colourIndex"
226
- class="flex items-center gap-1 mb-1 last:mb-0"
227
- >
228
- <template v-if="colorEntry.code">
229
- <code class="font-mono text-sm">
230
- {{ colorEntry.code }}
231
- </code>
232
- <span class="text-gray-400">-</span>
233
- </template>
234
- <span class="text-gray-700 dark:text-gray-300">{{ colorEntry.name }}</span>
235
- </li>
236
- </ul>
237
- </td>
238
-
239
- <td
240
- v-else-if="'id' in row && isGenericArray(row)"
124
+ v-else-if="isGenericArray(row)"
241
125
  class="details-table-cell"
242
126
  >
243
127
  <ul class="list-none p-0 m-0">
@@ -253,13 +137,12 @@ const groupedItems = computed(() => {
253
137
  </td>
254
138
 
255
139
  <td
256
- v-else-if="'id' in row && isHtmlValue(row.value)"
140
+ v-else-if="isHtmlValue(row.value)"
257
141
  class="details-table-cell"
258
142
  v-html="row.value"
259
143
  />
260
144
 
261
145
  <slot
262
- v-else-if="'id' in row"
263
146
  :name="row.id"
264
147
  >
265
148
  <td class="details-table-cell">