@onewelcome/react-lib-components 0.1.8-alpha → 0.1.11-alpha

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 (37) hide show
  1. package/README.md +13 -11
  2. package/dist/DataGrid/DataGrid.d.ts +2 -0
  3. package/dist/DataGrid/DataGridBody/DataGridBody.d.ts +1 -0
  4. package/dist/DataGrid/DataGridBody/DataGridCell.d.ts +5 -1
  5. package/dist/DataGrid/DataGridBody/DataGridRow.d.ts +3 -1
  6. package/dist/DataGrid/DataGridHeader/DataGridHeader.d.ts +2 -1
  7. package/dist/Skeleton/Skeleton.d.ts +7 -0
  8. package/dist/_BaseStyling_/BaseStyling.d.ts +0 -2
  9. package/dist/hooks/useSpacing.d.ts +1 -1
  10. package/dist/hooks/useWrapper.d.ts +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/react-lib-components.cjs.development.js +233 -107
  13. package/dist/react-lib-components.cjs.development.js.map +1 -1
  14. package/dist/react-lib-components.cjs.production.min.js +1 -1
  15. package/dist/react-lib-components.cjs.production.min.js.map +1 -1
  16. package/dist/react-lib-components.esm.js +233 -108
  17. package/dist/react-lib-components.esm.js.map +1 -1
  18. package/dist/util/helper.d.ts +1 -1
  19. package/package.json +10 -12
  20. package/src/ContextMenu/ContextMenu.module.scss +2 -5
  21. package/src/ContextMenu/ContextMenu.tsx +1 -1
  22. package/src/DataGrid/DataGrid.module.scss +4 -0
  23. package/src/DataGrid/DataGrid.test.tsx +145 -0
  24. package/src/DataGrid/DataGrid.tsx +58 -2
  25. package/src/DataGrid/DataGridBody/DataGridBody.tsx +18 -2
  26. package/src/DataGrid/DataGridBody/DataGridCell.tsx +35 -2
  27. package/src/DataGrid/DataGridBody/DataGridRow.tsx +19 -4
  28. package/src/DataGrid/DataGridHeader/DataGridHeader.tsx +26 -3
  29. package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +1 -0
  30. package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.module.scss +1 -1
  31. package/src/Pagination/Pagination.module.scss +5 -1
  32. package/src/Pagination/Pagination.tsx +23 -9
  33. package/src/Skeleton/Skeleton.module.scss +20 -0
  34. package/src/Skeleton/Skeleton.test.tsx +96 -0
  35. package/src/Skeleton/Skeleton.tsx +29 -0
  36. package/src/_BaseStyling_/BaseStyling.tsx +0 -4
  37. package/src/index.ts +1 -0
@@ -1,6 +1,6 @@
1
1
  declare type KeyValuePair = {
2
2
  [key: string]: unknown;
3
3
  };
4
- export declare const generateID: (length?: number, stringToWeaveIn?: string | undefined) => string;
4
+ export declare const generateID: (length?: number, stringToWeaveIn?: string) => string;
5
5
  export declare const filterProps: (props: any, regexPattern: RegExp, returnFiltered?: boolean) => KeyValuePair;
6
6
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onewelcome/react-lib-components",
3
- "version": "0.1.8-alpha",
3
+ "version": "0.1.11-alpha",
4
4
  "license": "Apache-2.0",
5
5
  "author": "OneWelcome B.V.",
6
6
  "main": "dist/index.js",
@@ -49,16 +49,16 @@
49
49
  "devDependencies": {
50
50
  "@babel/core": "^7.18.0",
51
51
  "@size-limit/preset-small-lib": "^7.0.8",
52
- "@storybook/addon-a11y": "^6.5.8",
53
- "@storybook/addon-docs": "^6.5.8",
54
- "@storybook/addon-essentials": "^6.5.8",
55
- "@storybook/addon-links": "^6.5.8",
56
- "@storybook/addons": "^6.5.8",
57
- "@storybook/builder-webpack5": "^6.5.8",
58
- "@storybook/manager-webpack5": "^6.5.8",
52
+ "@storybook/addon-a11y": "^6.5.9",
53
+ "@storybook/addon-docs": "^6.5.9",
54
+ "@storybook/addon-essentials": "^6.5.9",
55
+ "@storybook/addon-links": "^6.5.9",
56
+ "@storybook/addons": "^6.5.9",
57
+ "@storybook/builder-webpack5": "^6.5.9",
58
+ "@storybook/manager-webpack5": "^6.5.9",
59
59
  "@storybook/preset-scss": "^1.0.3",
60
- "@storybook/react": "^6.5.8",
61
- "@storybook/theming": "^6.5.8",
60
+ "@storybook/react": "^6.5.9",
61
+ "@storybook/theming": "^6.5.9",
62
62
  "@testing-library/dom": "^8.13.0",
63
63
  "@testing-library/jest-dom": "^5.16.4",
64
64
  "@testing-library/react": "^12.1.5",
@@ -70,8 +70,6 @@
70
70
  "@types/mdx": "^2.0.2",
71
71
  "@types/react": "^17.0.45",
72
72
  "@types/react-dom": "^17.0.17",
73
- "@types/react-router": "^5.1.18",
74
- "@types/react-router-dom": "^5.3.3",
75
73
  "babel-loader": "^8.2.5",
76
74
  "dts-cli": "^1.5.1",
77
75
  "html-webpack-plugin": "^5.5.0",
@@ -2,14 +2,11 @@
2
2
  position: relative;
3
3
  display: inline-block;
4
4
  box-sizing: border-box;
5
-
6
- ul {
7
- white-space: nowrap;
8
- margin: 1rem 0;
9
- }
10
5
  }
11
6
 
12
7
  .menu {
8
+ white-space: nowrap;
9
+ margin: 1rem 0;
13
10
  list-style: none;
14
11
  padding: 0;
15
12
  min-width: 200px;
@@ -177,7 +177,7 @@ export const ContextMenu = React.forwardRef<HTMLDivElement, Props>(
177
177
  anchorEl={anchorEl}
178
178
  show={showContextMenu}
179
179
  >
180
- <ul className={classes.menu} id={`${id}-menu`} aria-describedby={id} role="menu">
180
+ <ul className={classes['menu']} id={`${id}-menu`} aria-describedby={id} role="menu">
181
181
  {renderChildren()}
182
182
  </ul>
183
183
  </Popover>,
@@ -1,3 +1,7 @@
1
+ .grid-wrapper {
2
+ padding: 1rem 0;
3
+ }
4
+
1
5
  .table-wrapper {
2
6
  overflow-x: auto;
3
7
  }
@@ -274,3 +274,148 @@ describe('ref should work', () => {
274
274
  render(<ExampleComponent propagateRef={refCheck} />);
275
275
  });
276
276
  });
277
+
278
+ describe('spacing should work correctly', () => {
279
+ it('gives the proper paddings to the right elements', () => {
280
+ const { dataGrid } = createDataGrid((defaultParams) => ({
281
+ ...defaultParams,
282
+ spacing: { padding: 4 },
283
+ paginationProps: {
284
+ totalElements: 105,
285
+ pageSize: 10,
286
+ currentPage: 2,
287
+ onPageChange: jest.fn(),
288
+ onPageSizeChange: jest.fn(),
289
+ },
290
+ }));
291
+
292
+ const firstHeaderCell = dataGrid.querySelector('.table .thead .row .header-cell');
293
+ const lastHeaderCell = dataGrid.querySelector('.table .thead .row td');
294
+ const firstBodyCell = dataGrid.querySelector('.table tbody .row .cell');
295
+ const lastBodyCell = dataGrid.querySelector('.table tbody .row td:last-of-type');
296
+ const pagination = dataGrid.querySelector('.pagination-wrapper');
297
+
298
+ expect(dataGrid).toHaveStyle({ 'padding-top': '1rem', 'padding-bottom': '1rem' });
299
+ expect(firstHeaderCell).toHaveStyle({ 'padding-left': '1rem' });
300
+ expect(lastHeaderCell).toHaveStyle({ 'padding-right': '1rem' });
301
+ expect(firstBodyCell).toHaveStyle({ 'padding-left': '1rem' });
302
+ expect(lastBodyCell).toHaveStyle({ 'padding-right': '1rem' });
303
+ expect(pagination).toHaveStyle({ 'padding-left': '1rem', 'padding-right': '1rem' });
304
+ });
305
+
306
+ it('gives the proper paddings to the right elements', () => {
307
+ const { dataGrid } = createDataGrid((defaultParams) => ({
308
+ ...defaultParams,
309
+ spacing: { padding: '4 5' },
310
+ paginationProps: {
311
+ totalElements: 105,
312
+ pageSize: 10,
313
+ currentPage: 2,
314
+ onPageChange: jest.fn(),
315
+ onPageSizeChange: jest.fn(),
316
+ },
317
+ }));
318
+
319
+ const firstHeaderCell = dataGrid.querySelector('.table .thead .row .header-cell');
320
+ const lastHeaderCell = dataGrid.querySelector('.table .thead .row td');
321
+ const firstBodyCell = dataGrid.querySelector('.table tbody .row .cell');
322
+ const lastBodyCell = dataGrid.querySelector('.table tbody .row td:last-of-type');
323
+ const pagination = dataGrid.querySelector('.pagination-wrapper');
324
+
325
+ expect(dataGrid).toHaveStyle({ 'padding-top': '1rem', 'padding-bottom': '1rem' });
326
+ expect(firstHeaderCell).toHaveStyle({ 'padding-left': '1.25rem' });
327
+ expect(lastHeaderCell).toHaveStyle({ 'padding-right': '1.25rem' });
328
+ expect(firstBodyCell).toHaveStyle({ 'padding-left': '1.25rem' });
329
+ expect(lastBodyCell).toHaveStyle({ 'padding-right': '1.25rem' });
330
+ expect(pagination).toHaveStyle({ 'padding-left': '1.25rem', 'padding-right': '1.25rem' });
331
+ });
332
+
333
+ it('gives the proper paddings to the right elements', () => {
334
+ const { dataGrid } = createDataGrid((defaultParams) => ({
335
+ ...defaultParams,
336
+ spacing: { padding: '4 5 8' },
337
+ paginationProps: {
338
+ totalElements: 105,
339
+ pageSize: 10,
340
+ currentPage: 2,
341
+ onPageChange: jest.fn(),
342
+ onPageSizeChange: jest.fn(),
343
+ },
344
+ }));
345
+
346
+ const firstHeaderCell = dataGrid.querySelector('.table .thead .row .header-cell');
347
+ const lastHeaderCell = dataGrid.querySelector('.table .thead .row td');
348
+ const firstBodyCell = dataGrid.querySelector('.table tbody .row .cell');
349
+ const lastBodyCell = dataGrid.querySelector('.table tbody .row td:last-of-type');
350
+ const pagination = dataGrid.querySelector('.pagination-wrapper');
351
+
352
+ expect(dataGrid).toHaveStyle({ 'padding-top': '1rem', 'padding-bottom': '2rem' });
353
+ expect(firstHeaderCell).toHaveStyle({ 'padding-left': '1.25rem' });
354
+ expect(lastHeaderCell).toHaveStyle({ 'padding-right': '1.25rem' });
355
+ expect(firstBodyCell).toHaveStyle({ 'padding-left': '1.25rem' });
356
+ expect(lastBodyCell).toHaveStyle({ 'padding-right': '1.25rem' });
357
+ expect(pagination).toHaveStyle({ 'padding-left': '1.25rem', 'padding-right': '1.25rem' });
358
+ });
359
+
360
+ it('gives the proper paddings to the right elements', () => {
361
+ const { dataGrid } = createDataGrid((defaultParams) => ({
362
+ ...defaultParams,
363
+ spacing: { padding: '6 4 8 8' },
364
+ paginationProps: {
365
+ totalElements: 105,
366
+ pageSize: 10,
367
+ currentPage: 2,
368
+ onPageChange: jest.fn(),
369
+ onPageSizeChange: jest.fn(),
370
+ },
371
+ }));
372
+
373
+ const firstHeaderCell = dataGrid.querySelector('.table .thead .row .header-cell');
374
+ const lastHeaderCell = dataGrid.querySelector('.table .thead .row td');
375
+ const firstBodyCell = dataGrid.querySelector('.table tbody .row .cell');
376
+ const lastBodyCell = dataGrid.querySelector('.table tbody .row td:last-of-type');
377
+ const pagination = dataGrid.querySelector('.pagination-wrapper');
378
+
379
+ expect(dataGrid).toHaveStyle({ 'padding-top': '1.5rem', 'padding-bottom': '2rem' });
380
+ expect(firstHeaderCell).toHaveStyle({ 'padding-left': '2rem' });
381
+ expect(lastHeaderCell).toHaveStyle({ 'padding-right': '1rem' });
382
+ expect(firstBodyCell).toHaveStyle({ 'padding-left': '2rem' });
383
+ expect(lastBodyCell).toHaveStyle({ 'padding-right': '1rem' });
384
+ expect(pagination).toHaveStyle({ 'padding-left': '2rem', 'padding-right': '1rem' });
385
+ });
386
+
387
+ it('gives the proper paddings to the right elements, also with contextmenu disabled', () => {
388
+ const { dataGrid } = createDataGrid((defaultParams) => ({
389
+ ...defaultParams,
390
+ spacing: { padding: '6 4 8 8' },
391
+ disableContextMenuColumn: true,
392
+ paginationProps: {
393
+ totalElements: 105,
394
+ pageSize: 10,
395
+ currentPage: 2,
396
+ onPageChange: jest.fn(),
397
+ onPageSizeChange: jest.fn(),
398
+ },
399
+ children: ({ item }) => (
400
+ <DataGridRow key={item.firstName}>
401
+ <DataGridCell>{item.firstName}</DataGridCell>
402
+ <DataGridCell>{item.lastName}</DataGridCell>
403
+ <DataGridCell>{item.date}</DataGridCell>
404
+ </DataGridRow>
405
+ ),
406
+ }));
407
+
408
+ const firstHeaderCell = dataGrid.querySelector('.table .thead .row .header-cell');
409
+ const lastHeaderCell = dataGrid.querySelector('.table .thead .row th:last-of-type');
410
+ const firstBodyCell = dataGrid.querySelector('.table tbody .row .cell');
411
+ const lastBodyCell = dataGrid.querySelector('.table tbody .row td:last-of-type');
412
+ const pagination = dataGrid.querySelector('.pagination-wrapper');
413
+
414
+ expect(dataGrid).toHaveStyle({ 'padding-top': '1.5rem', 'padding-bottom': '2rem' });
415
+ expect(firstHeaderCell).toHaveStyle({ 'padding-left': '2rem' });
416
+ expect(lastHeaderCell).toHaveStyle({ 'padding-right': '1rem' });
417
+ expect(firstBodyCell).toHaveStyle({ 'padding-left': '2rem' });
418
+ expect(lastBodyCell).toHaveStyle({ 'padding-right': '1rem' });
419
+ expect(pagination).toHaveStyle({ 'padding-left': '2rem', 'padding-right': '1rem' });
420
+ });
421
+ });
@@ -6,6 +6,7 @@ import { DataGridActions } from './DataGridActions/DataGridActions';
6
6
  import { DataGridBody } from './DataGridBody/DataGridBody';
7
7
  import { ColumnName, HeaderCell, OnSortFunction, Sort } from './datagrid.interfaces';
8
8
  import { Pagination, Props as PaginationProps } from '../Pagination/Pagination';
9
+ import { Spacing, useSpacing } from '../hooks/useSpacing';
9
10
 
10
11
  export interface Props<T> extends ComponentPropsWithRef<'div'> {
11
12
  children: ({ item, index }: { item: T; index: number }) => ReactElement;
@@ -26,6 +27,7 @@ export interface Props<T> extends ComponentPropsWithRef<'div'> {
26
27
  disableContextMenuColumn?: boolean;
27
28
  isLoading?: boolean;
28
29
  enableMultiSorting?: boolean;
30
+ spacing?: Spacing;
29
31
  }
30
32
 
31
33
  const DataGridInner = <T extends {}>(
@@ -41,6 +43,8 @@ const DataGridInner = <T extends {}>(
41
43
  isLoading,
42
44
  enableMultiSorting,
43
45
  emptyLabel,
46
+ spacing,
47
+ style,
44
48
  ...rest
45
49
  }: Props<T>,
46
50
  ref: Ref<HTMLDivElement>
@@ -53,6 +57,7 @@ const DataGridInner = <T extends {}>(
53
57
  }
54
58
 
55
59
  const [internalHeaders, setInternalHeaders] = useState(headers);
60
+ const styleWithSpacing = useSpacing(spacing, style);
56
61
 
57
62
  useEffect(() => setInternalHeaders(headers), [headers]);
58
63
 
@@ -64,9 +69,53 @@ const DataGridInner = <T extends {}>(
64
69
  );
65
70
  };
66
71
 
72
+ if (styleWithSpacing?.padding) {
73
+ const splitPaddings = styleWithSpacing.padding.toString().split(' ');
74
+
75
+ let paddingLeftIndex: number = 0;
76
+
77
+ if (splitPaddings.length >= 2) {
78
+ paddingLeftIndex = 1;
79
+ }
80
+ if (splitPaddings.length === 4) {
81
+ paddingLeftIndex = 3;
82
+ }
83
+
84
+ Object.defineProperties(styleWithSpacing, {
85
+ paddingTop: {
86
+ value: splitPaddings[0],
87
+ },
88
+ paddingRight: {
89
+ value: splitPaddings[splitPaddings.length - 1 > 0 ? 1 : 0],
90
+ },
91
+ paddingBottom: {
92
+ value: splitPaddings[splitPaddings.length / 3 >= 1 ? 2 : 0],
93
+ },
94
+ paddingLeft: {
95
+ value: splitPaddings[paddingLeftIndex],
96
+ },
97
+ });
98
+ }
99
+
67
100
  return (
68
- <div {...rest} ref={ref}>
69
- <DataGridActions {...actions} headers={internalHeaders} onColumnToggled={onColumnToggled} />
101
+ <div
102
+ {...rest}
103
+ className={classes['grid-wrapper']}
104
+ ref={ref}
105
+ style={{
106
+ paddingTop: styleWithSpacing?.paddingTop,
107
+ paddingBottom: styleWithSpacing?.paddingBottom,
108
+ }}
109
+ >
110
+ <DataGridActions
111
+ {...actions}
112
+ style={{
113
+ paddingLeft: styleWithSpacing?.paddingLeft,
114
+ paddingRight: styleWithSpacing?.paddingRight,
115
+ }}
116
+ headers={internalHeaders}
117
+ onColumnToggled={onColumnToggled}
118
+ />
70
119
  <div className={classes['table-wrapper']}>
71
120
  <table className={classes['table']}>
72
121
  <DataGridHeader
@@ -75,6 +124,7 @@ const DataGridInner = <T extends {}>(
75
124
  onSort={onSort}
76
125
  disableContextMenuColumn={disableContextMenuColumn}
77
126
  enableMultiSorting={enableMultiSorting}
127
+ spacing={styleWithSpacing}
78
128
  />
79
129
  <DataGridBody
80
130
  children={children}
@@ -83,12 +133,18 @@ const DataGridInner = <T extends {}>(
83
133
  isLoading={isLoading}
84
134
  disableContextMenuColumn={disableContextMenuColumn}
85
135
  emptyLabel={emptyLabel}
136
+ spacing={styleWithSpacing}
86
137
  />
87
138
  </table>
88
139
  </div>
89
140
  {paginationProps && !isLoading && (
90
141
  <Pagination
91
142
  {...paginationProps}
143
+ style={{
144
+ ...paginationProps.style,
145
+ paddingLeft: styleWithSpacing?.paddingLeft,
146
+ paddingRight: styleWithSpacing?.paddingRight,
147
+ }}
92
148
  className={`${classes['pagination']} ${paginationProps.className ?? ''}`}
93
149
  />
94
150
  )}
@@ -12,12 +12,22 @@ export interface Props<T> extends ComponentPropsWithRef<'tbody'> {
12
12
  isLoading?: boolean;
13
13
  disableContextMenuColumn?: boolean;
14
14
  emptyLabel?: string;
15
+ spacing?: React.CSSProperties;
15
16
  }
16
17
 
17
18
  const skeletonLoadingRows = 9;
18
19
 
19
20
  const DataGridBodyInner = <T extends {}>(
20
- { children, data, headers, isLoading, disableContextMenuColumn, emptyLabel, ...rest }: Props<T>,
21
+ {
22
+ children,
23
+ data,
24
+ headers,
25
+ isLoading,
26
+ disableContextMenuColumn,
27
+ emptyLabel,
28
+ spacing,
29
+ ...rest
30
+ }: Props<T>,
21
31
  ref: Ref<HTMLTableSectionElement>
22
32
  ) => {
23
33
  const renderContent = () => {
@@ -49,7 +59,13 @@ const DataGridBodyInner = <T extends {}>(
49
59
  );
50
60
  }
51
61
 
52
- return data?.map((item, index) => React.cloneElement(children({ item, index }), { headers }));
62
+ return data?.map((item, index) => {
63
+ return React.cloneElement(children({ item, index }), {
64
+ headers,
65
+ spacing,
66
+ disableContextMenuColumn,
67
+ });
68
+ });
53
69
  };
54
70
 
55
71
  return (
@@ -5,12 +5,45 @@ import classes from './DataGridCell.module.scss';
5
5
  export interface Props extends ComponentPropsWithRef<'td'> {
6
6
  children?: ReactChild;
7
7
  isLoading?: boolean;
8
+ spacing?: React.CSSProperties;
9
+ cellIndex?: number;
10
+ columnLength?: number;
11
+ disableContextMenuColumn?: boolean;
8
12
  }
9
13
 
10
14
  export const DataGridCell = React.forwardRef<HTMLTableCellElement, Props>(
11
- ({ children, className, isLoading, ...rest }: Props, ref) => {
15
+ (
16
+ {
17
+ children,
18
+ className,
19
+ isLoading,
20
+ spacing,
21
+ cellIndex,
22
+ columnLength,
23
+ disableContextMenuColumn,
24
+ ...rest
25
+ }: Props,
26
+ ref
27
+ ) => {
28
+ let cellStyle: React.CSSProperties = {};
29
+
30
+ if (cellIndex === 0) {
31
+ cellStyle.paddingLeft = spacing?.paddingLeft;
32
+ }
33
+ if (
34
+ (cellIndex === columnLength && !disableContextMenuColumn) ||
35
+ (columnLength && cellIndex === columnLength - 1 && disableContextMenuColumn)
36
+ ) {
37
+ cellStyle.paddingRight = spacing?.paddingRight;
38
+ }
39
+
12
40
  return (
13
- <td {...rest} ref={ref} className={`${classes['cell']} ${className ?? ''}`}>
41
+ <td
42
+ {...rest}
43
+ ref={ref}
44
+ style={{ ...rest.style, ...cellStyle }}
45
+ className={`${classes['cell']} ${className ?? ''}`}
46
+ >
14
47
  {isLoading && (
15
48
  <div className={classes['loading']} aria-busy="true" aria-live="polite"></div>
16
49
  )}
@@ -5,13 +5,28 @@ import classes from './DataGridRow.module.scss';
5
5
  export interface Props extends ComponentPropsWithRef<'tr'> {
6
6
  headers?: HeaderCell[];
7
7
  isLoading?: boolean;
8
+ spacing?: React.CSSProperties;
9
+ disableContextMenuColumn?: boolean;
8
10
  }
9
11
 
10
12
  export const DataGridRow = React.forwardRef<HTMLTableRowElement, Props>(
11
- ({ children, className, headers, isLoading, ...rest }: Props, ref) => {
12
- const visibleCells = React.Children.map(children, (child, index) => {
13
- const visible = headers?.length! > index ? !headers![index].hidden : true;
14
- return visible && child;
13
+ (
14
+ { children, className, headers, isLoading, spacing, disableContextMenuColumn, ...rest }: Props,
15
+ ref
16
+ ) => {
17
+ const visibleCells = React.Children.map(children as React.ReactElement[], (child, index) => {
18
+ if (child) {
19
+ const cellWithSpacing = React.cloneElement(child, {
20
+ spacing: spacing,
21
+ cellIndex: index,
22
+ columnLength: headers?.length,
23
+ disableContextMenuColumn,
24
+ });
25
+
26
+ const visible = headers?.length! > index ? !headers![index].hidden : true;
27
+ return visible && cellWithSpacing;
28
+ }
29
+ return null;
15
30
  });
16
31
 
17
32
  const classNames = [classes['row']];
@@ -9,13 +9,22 @@ export interface Props extends ComponentPropsWithRef<'thead'> {
9
9
  onSort?: OnSortFunction;
10
10
  disableContextMenuColumn?: boolean;
11
11
  enableMultiSorting?: boolean;
12
+ spacing?: React.CSSProperties;
12
13
  }
13
14
 
14
15
  const sortingStates = [undefined, 'ASC', 'DESC'] as (Direction | undefined)[];
15
16
 
16
17
  export const DataGridHeader = React.forwardRef<HTMLTableSectionElement, Props>(
17
18
  (
18
- { initialSort, onSort, headers, disableContextMenuColumn, enableMultiSorting, ...rest }: Props,
19
+ {
20
+ initialSort,
21
+ onSort,
22
+ headers,
23
+ disableContextMenuColumn,
24
+ enableMultiSorting,
25
+ spacing,
26
+ ...rest
27
+ }: Props,
19
28
  ref
20
29
  ) => {
21
30
  const [sortList, setSortList] = useState(initialSort || []);
@@ -48,11 +57,20 @@ export const DataGridHeader = React.forwardRef<HTMLTableSectionElement, Props>(
48
57
  setSortList(newSort);
49
58
  };
50
59
 
51
- const headerCells = headers.map((header) => {
60
+ const headerCells = headers.map((header, index) => {
52
61
  if (header.hidden) {
53
62
  return null;
54
63
  }
55
64
 
65
+ let headerStyle: React.CSSProperties = {};
66
+
67
+ if (index === 0) {
68
+ headerStyle.paddingLeft = spacing?.paddingLeft;
69
+ }
70
+ if (index === headers.length - 1 && disableContextMenuColumn) {
71
+ headerStyle.paddingRight = spacing?.paddingRight;
72
+ }
73
+
56
74
  const sort = sortList.find((item) => item.name === header.name);
57
75
  return (
58
76
  <DataGridHeaderCell
@@ -62,6 +80,7 @@ export const DataGridHeader = React.forwardRef<HTMLTableSectionElement, Props>(
62
80
  disableSorting={header.disableSorting || !onSort}
63
81
  onSort={wrapOnSort}
64
82
  activeSortDirection={sort?.direction}
83
+ style={headerStyle}
65
84
  />
66
85
  );
67
86
  });
@@ -71,7 +90,11 @@ export const DataGridHeader = React.forwardRef<HTMLTableSectionElement, Props>(
71
90
  <tr className={classes['row']}>
72
91
  {headerCells}
73
92
  {!disableContextMenuColumn && (
74
- <td aria-label="context menu" className={classes['context-menu']}></td>
93
+ <td
94
+ style={{ paddingRight: spacing?.paddingRight }}
95
+ aria-label="context menu"
96
+ className={classes['context-menu']}
97
+ ></td>
75
98
  )}
76
99
  </tr>
77
100
  </thead>
@@ -3,6 +3,7 @@
3
3
  }
4
4
 
5
5
  .floating-label {
6
+ font-family: var(--font-family);
6
7
  font-size: 1rem;
7
8
  position: absolute;
8
9
  z-index: 1;
@@ -4,6 +4,6 @@
4
4
  justify-content: flex-end;
5
5
 
6
6
  & * + * {
7
- margin-left: 1.25rem;
7
+ margin-left: 2rem;
8
8
  }
9
9
  }
@@ -5,6 +5,10 @@
5
5
  display: flex;
6
6
  flex-direction: column;
7
7
 
8
+ label {
9
+ margin-bottom: 0;
10
+ }
11
+
8
12
  .form-element {
9
13
  height: 2.5rem;
10
14
 
@@ -106,7 +110,7 @@
106
110
  .previous,
107
111
  .next {
108
112
  button {
109
- margin: 0.5rem;
113
+ margin: 0 0.5rem;
110
114
  }
111
115
  }
112
116
  }
@@ -53,7 +53,15 @@ export const Pagination = React.forwardRef<HTMLDivElement, Props>(
53
53
  ) => {
54
54
  /** We use an internal state variable, because we don't want to fire onCurrentPageChange whenever onChange fires on the input. Rather, only when the Enter key is pressed. */
55
55
  const [internalCurrentPage, setInternalCurrentPage] = useState(currentPage?.toString() || '1');
56
- const calculateAmountOfPages = () => (totalElements ? Math.ceil(totalElements / pageSize) : 0);
56
+ const calculateAmountOfPages = () => {
57
+ if (!totalElements) return 1;
58
+
59
+ if (Math.ceil(totalElements / pageSize) < 1) {
60
+ return 1;
61
+ }
62
+
63
+ return Math.ceil(totalElements / pageSize);
64
+ };
57
65
 
58
66
  const onEnterListener = (event: React.KeyboardEvent<HTMLInputElement>) => {
59
67
  if (event.code === 'Enter') {
@@ -74,7 +82,7 @@ export const Pagination = React.forwardRef<HTMLDivElement, Props>(
74
82
  <Label
75
83
  id="current-value-input-label"
76
84
  htmlFor="current-value-input"
77
- className={readyclasses['sr-only']}
85
+ className={`${readyclasses['sr-only']} ${classes['current-value-input-label']}`}
78
86
  >
79
87
  {translate.currentPageLabel}
80
88
  </Label>
@@ -102,7 +110,11 @@ export const Pagination = React.forwardRef<HTMLDivElement, Props>(
102
110
  }
103
111
 
104
112
  if (string.includes('%2')) {
105
- return <div key={string}>{string.replace('%2', amountOfPages.toString())}&nbsp;</div>;
113
+ return (
114
+ <div key={string}>
115
+ <strong>{string.replace('%2', amountOfPages.toString())}</strong>&nbsp;
116
+ </div>
117
+ );
106
118
  }
107
119
 
108
120
  return <div key={string}>{string}&nbsp;</div>;
@@ -135,7 +147,7 @@ export const Pagination = React.forwardRef<HTMLDivElement, Props>(
135
147
  </div>
136
148
  )}
137
149
  <div className={classes['pagination']}>
138
- {totalElements && pageSize && (
150
+ {pageSize && (
139
151
  <div className={classes['per-page']}>
140
152
  <Label id="page-size-select-label">{translate.itemsPerPage}</Label>
141
153
  <Select
@@ -151,7 +163,7 @@ export const Pagination = React.forwardRef<HTMLDivElement, Props>(
151
163
  </div>
152
164
  )}
153
165
  <Fragment>
154
- {((currentPage && currentPage > 2) || (currentPage && currentPage > 1)) && (
166
+ {!!((currentPage && currentPage > 2) || (currentPage && currentPage > 1)) && (
155
167
  <div className={classes['previous']}>
156
168
  {currentPage > 2 && (
157
169
  <IconButton
@@ -173,12 +185,14 @@ export const Pagination = React.forwardRef<HTMLDivElement, Props>(
173
185
  )}
174
186
  </div>
175
187
  )}
176
- {totalElements && (
188
+ {totalElements && calculateAmountOfPages() && (
177
189
  <div className={classes['page']}>{renderCurrentPageTranslation()}</div>
178
190
  )}
179
191
  <div className={classes['next']}>
180
- {((currentPage && currentPage < calculateAmountOfPages()) ||
181
- (currentPage && !totalElements)) && (
192
+ {!!(
193
+ (currentPage !== undefined && currentPage < calculateAmountOfPages()!) ||
194
+ (currentPage !== undefined && !totalElements)
195
+ ) && (
182
196
  <IconButton
183
197
  title="next"
184
198
  onClick={() => onPageChangeHandler(currentPage + 1)}
@@ -187,7 +201,7 @@ export const Pagination = React.forwardRef<HTMLDivElement, Props>(
187
201
  <Icon icon={Icons.ChevronRight} />
188
202
  </IconButton>
189
203
  )}
190
- {currentPage && totalElements && currentPage < calculateAmountOfPages()! - 1 && (
204
+ {!!(currentPage && totalElements && currentPage < calculateAmountOfPages()! - 1) && (
191
205
  <IconButton
192
206
  title="last"
193
207
  onClick={() => onPageChangeHandler(totalElements / pageSize)}