@spaced-out/ui-design-system 0.4.12 → 0.4.13

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.
@@ -221,6 +221,77 @@ const TABLE_DOCS = exports.TABLE_DOCS = {
221
221
  summary: true
222
222
  }
223
223
  }
224
+ },
225
+ rowsCount: {
226
+ name: 'virtualizationOptions.rowsCount',
227
+ description: 'Total number of virtual rows.',
228
+ control: {
229
+ type: 'number'
230
+ },
231
+ table: {
232
+ type: {
233
+ summary: 'number'
234
+ },
235
+ defaultValue: {
236
+ summary: 20
237
+ }
238
+ }
239
+ },
240
+ rowHeight: {
241
+ name: 'virtualizationOptions.rowHeight',
242
+ description: 'Row height in CSS units (e.g., "48px"). Should be provided correctly, otherwise it will not work as expected.',
243
+ control: {
244
+ type: 'text'
245
+ },
246
+ table: {
247
+ type: {
248
+ summary: 'string'
249
+ },
250
+ defaultValue: {
251
+ summary: '48px'
252
+ }
253
+ }
254
+ },
255
+ isEndLoading: {
256
+ name: 'virtualizationOptions.isEndLoading',
257
+ description: 'Whether to show loading spinner at the bottom.',
258
+ control: {
259
+ type: 'boolean'
260
+ },
261
+ table: {
262
+ type: {
263
+ summary: 'boolean'
264
+ },
265
+ defaultValue: {
266
+ summary: false
267
+ }
268
+ }
269
+ },
270
+ isAllDataFetched: {
271
+ name: 'virtualizationOptions.isAllDataFetched',
272
+ description: 'Whether all rows are fetched (disables infinite loading).',
273
+ control: {
274
+ type: 'boolean'
275
+ },
276
+ table: {
277
+ type: {
278
+ summary: 'boolean'
279
+ },
280
+ defaultValue: {
281
+ summary: false
282
+ }
283
+ }
284
+ },
285
+ // Note: onEndReached can't be controlled, but you can mock it
286
+ onEndReached: {
287
+ name: 'virtualizationOptions.onEndReached',
288
+ description: 'Callback triggered when end of list is reached.',
289
+ action: 'onEndReached',
290
+ table: {
291
+ type: {
292
+ summary: '() => void'
293
+ }
294
+ }
224
295
  }
225
296
  },
226
297
  parameters: {
@@ -285,6 +356,15 @@ just CSS Wrappers for Button and SimpleButtonDropdown components
285
356
  * Use ButtonCta component to add a button CTA in the \`TableActionBar\`
286
357
  * Use DropdownCta component to add a dropdown CTA button in the \`TableActionBar\` for screen width less than size1280(1280px)
287
358
 
359
+ ### Handling Sticky Headers with Virtualization
360
+ * When using **virtualization**, always assign a fixed \`min-width\` and \`max-width\` to sticky table headers with **same value**.
361
+ This ensures a strict, fixed width for header cells. Directly using \`width\` (non strict for table headers) alone is not sufficient, as
362
+ it can be overridden by content width due to table layout behavior, causing headers to shift.
363
+ * If the cell content may exceed the defined width, or if you're unsure of its maximum width, also use \`white-space: normal;\` and \`word-break: break-word;\`
364
+ to ensure the content wraps within the cell instead of overflowing or causing layout shifts.
365
+
366
+ This helps maintain consistent column alignment and improves readability across varying data lengths.
367
+
288
368
  \`\`\`jsx
289
369
  <Table
290
370
  headers={TABLE_HEADERS}
@@ -181,6 +181,52 @@ export const TABLE_DOCS = {
181
181
  defaultValue: {summary: true},
182
182
  },
183
183
  },
184
+ rowsCount: {
185
+ name: 'virtualizationOptions.rowsCount',
186
+ description: 'Total number of virtual rows.',
187
+ control: {type: 'number'},
188
+ table: {
189
+ type: {summary: 'number'},
190
+ defaultValue: {summary: 20},
191
+ },
192
+ },
193
+ rowHeight: {
194
+ name: 'virtualizationOptions.rowHeight',
195
+ description:
196
+ 'Row height in CSS units (e.g., "48px"). Should be provided correctly, otherwise it will not work as expected.',
197
+ control: {type: 'text'},
198
+ table: {
199
+ type: {summary: 'string'},
200
+ defaultValue: {summary: '48px'},
201
+ },
202
+ },
203
+ isEndLoading: {
204
+ name: 'virtualizationOptions.isEndLoading',
205
+ description: 'Whether to show loading spinner at the bottom.',
206
+ control: {type: 'boolean'},
207
+ table: {
208
+ type: {summary: 'boolean'},
209
+ defaultValue: {summary: false},
210
+ },
211
+ },
212
+ isAllDataFetched: {
213
+ name: 'virtualizationOptions.isAllDataFetched',
214
+ description: 'Whether all rows are fetched (disables infinite loading).',
215
+ control: {type: 'boolean'},
216
+ table: {
217
+ type: {summary: 'boolean'},
218
+ defaultValue: {summary: false},
219
+ },
220
+ },
221
+ // Note: onEndReached can't be controlled, but you can mock it
222
+ onEndReached: {
223
+ name: 'virtualizationOptions.onEndReached',
224
+ description: 'Callback triggered when end of list is reached.',
225
+ action: 'onEndReached',
226
+ table: {
227
+ type: {summary: '() => void'},
228
+ },
229
+ },
184
230
  },
185
231
  parameters: {
186
232
  docs: {
@@ -244,6 +290,15 @@ just CSS Wrappers for Button and SimpleButtonDropdown components
244
290
  * Use ButtonCta component to add a button CTA in the \`TableActionBar\`
245
291
  * Use DropdownCta component to add a dropdown CTA button in the \`TableActionBar\` for screen width less than size1280(1280px)
246
292
 
293
+ ### Handling Sticky Headers with Virtualization
294
+ * When using **virtualization**, always assign a fixed \`min-width\` and \`max-width\` to sticky table headers with **same value**.
295
+ This ensures a strict, fixed width for header cells. Directly using \`width\` (non strict for table headers) alone is not sufficient, as
296
+ it can be overridden by content width due to table layout behavior, causing headers to shift.
297
+ * If the cell content may exceed the defined width, or if you're unsure of its maximum width, also use \`white-space: normal;\` and \`word-break: break-word;\`
298
+ to ensure the content wraps within the cell instead of overflowing or causing layout shifts.
299
+
300
+ This helps maintain consistent column alignment and improves readability across varying data lengths.
301
+
247
302
  \`\`\`jsx
248
303
  <Table
249
304
  headers={TABLE_HEADERS}
@@ -50,7 +50,8 @@ function Table(props) {
50
50
  isLoading,
51
51
  idName = 'id',
52
52
  // eslint-disable-next-line unused-imports/no-unused-vars
53
- emptyText
53
+ emptyText,
54
+ virtualizationOptions
54
55
  } = props;
55
56
 
56
57
  /**
@@ -67,9 +68,14 @@ function Table(props) {
67
68
  onSort,
68
69
  enableInternalSorting
69
70
  });
70
- return /*#__PURE__*/React.createElement(_StaticTable.StaticTable, _extends({}, props, sortableProps, {
71
+ const virtualized = !!(virtualizationOptions && virtualizationOptions.rowsCount > 0);
72
+ return virtualized ? /*#__PURE__*/React.createElement(_StaticTable.StaticTableVirtualized, _extends({}, props, sortableProps, {
71
73
  sortable: sortable,
72
- entries: entries,
74
+ entries: sortedEntries,
75
+ rowKeys: sortedKeys
76
+ })) : /*#__PURE__*/React.createElement(_StaticTable.StaticTable, _extends({}, props, sortableProps, {
77
+ sortable: sortable,
78
+ entries: sortedEntries,
73
79
  rowKeys: sortedKeys
74
80
  }));
75
81
  }
@@ -6,7 +6,7 @@ import type {TableRow} from './DefaultRow';
6
6
  import type {GenericHeaderItems} from './DefaultTableHeader';
7
7
  import type {SortDirection} from './hooks';
8
8
  import {useSortableEntries} from './hooks';
9
- import {StaticTable} from './StaticTable';
9
+ import {StaticTable, StaticTableVirtualized} from './StaticTable';
10
10
 
11
11
  // type ClassNames = $ReadOnly<{wrapper?: string}>;
12
12
 
@@ -19,7 +19,7 @@ export type GenericObject = {
19
19
  +[key: string]: mixed,
20
20
  };
21
21
 
22
- type ClassNames = $ReadOnly<{
22
+ export type ClassNames = $ReadOnly<{
23
23
  wrapper?: string,
24
24
  table?: string,
25
25
  tableHeader?: string,
@@ -28,6 +28,14 @@ type ClassNames = $ReadOnly<{
28
28
  checkbox?: string,
29
29
  }>;
30
30
 
31
+ type VirtualizationOptions = {
32
+ rowsCount: number,
33
+ rowHeight?: string,
34
+ onEndReached?: () => void,
35
+ isEndLoading?: boolean,
36
+ isAllDataFetched?: boolean,
37
+ };
38
+
31
39
  export type TableProps<T, U> = {
32
40
  classNames?: ClassNames,
33
41
  className?: string,
@@ -58,6 +66,7 @@ export type TableProps<T, U> = {
58
66
 
59
67
  // For this to work the table wrapper should be scrollable
60
68
  stickyHeader?: boolean,
69
+ virtualizationOptions?: VirtualizationOptions,
61
70
  };
62
71
 
63
72
  /**
@@ -103,6 +112,7 @@ export function Table<Data: GenericObject, Extras: GenericObject>(
103
112
  idName = 'id',
104
113
  // eslint-disable-next-line unused-imports/no-unused-vars
105
114
  emptyText,
115
+ virtualizationOptions,
106
116
  } = props;
107
117
 
108
118
  /**
@@ -120,12 +130,24 @@ export function Table<Data: GenericObject, Extras: GenericObject>(
120
130
  },
121
131
  );
122
132
 
123
- return (
133
+ const virtualized = !!(
134
+ virtualizationOptions && virtualizationOptions.rowsCount > 0
135
+ );
136
+
137
+ return virtualized ? (
138
+ <StaticTableVirtualized
139
+ {...props}
140
+ {...sortableProps}
141
+ sortable={sortable}
142
+ entries={sortedEntries}
143
+ rowKeys={sortedKeys}
144
+ />
145
+ ) : (
124
146
  <StaticTable
125
147
  {...props}
126
148
  {...sortableProps}
127
149
  sortable={sortable}
128
- entries={entries}
150
+ entries={sortedEntries}
129
151
  rowKeys={sortedKeys}
130
152
  />
131
153
  );
@@ -10,11 +10,35 @@
10
10
  colorBackgroundTertiary,
11
11
  colorGrayLightest
12
12
  ) from '../../styles/variables/_color.css';
13
- @value (spaceNone, spaceXXSmall, spaceXSmall, spaceSmall, spaceMedium) from '../../styles/variables/_space.css';
14
- @value (sizeFluid, size2, size48, size60, size240, size300) from '../../styles/variables/_size.css';
15
- @value (borderWidthNone, borderWidthPrimary, borderRadiusNone, borderRadiusMedium, borderWidthSecondary) from '../../styles/variables/_border.css';
16
- @value (fontLineHeight170) from '../../styles/variables/_font.css';
17
- @value (elevationCard) from '../../styles/variables/_elevation.css';
13
+ @value (
14
+ spaceNone,
15
+ spaceXXSmall,
16
+ spaceXSmall,
17
+ spaceSmall,
18
+ spaceMedium
19
+ ) from '../../styles/variables/_space.css';
20
+ @value (
21
+ sizeFluid,
22
+ size2,
23
+ size8,
24
+ size48,
25
+ size60,
26
+ size240,
27
+ size300
28
+ ) from '../../styles/variables/_size.css';
29
+ @value (
30
+ borderWidthNone,
31
+ borderWidthPrimary,
32
+ borderRadiusNone,
33
+ borderRadiusMedium,
34
+ borderWidthSecondary
35
+ ) from '../../styles/variables/_border.css';
36
+ @value (
37
+ fontLineHeight170
38
+ ) from '../../styles/variables/_font.css';
39
+ @value (
40
+ elevationCard
41
+ ) from '../../styles/variables/_elevation.css';
18
42
 
19
43
  @value tableRowTotalPadding: calc(spaceMedium * 2);
20
44
 
@@ -287,3 +311,10 @@
287
311
  height: calc(size2 / 2);
288
312
  background: colorBorderPrimary;
289
313
  }
314
+
315
+ .fetchMoreLoaderContainer {
316
+ display: flex;
317
+ text-align: center;
318
+ justify-content: center;
319
+ padding: size8;
320
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.4.12",
3
+ "version": "0.4.13",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@floating-ui/react": "^0.24.0",
48
+ "@tanstack/react-virtual": "^3.13.12",
48
49
  "date-fns": "^2.29.3",
49
50
  "highcharts": "^11.4.1",
50
51
  "highcharts-react-official": "^3.2.1",