@axinom/mosaic-ui 0.34.0-rc.6 → 0.34.0-rc.7
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/dist/components/Explorer/Explorer.d.ts.map +1 -1
- package/dist/components/List/List.d.ts.map +1 -1
- package/dist/components/List/List.model.d.ts +2 -0
- package/dist/components/List/List.model.d.ts.map +1 -1
- package/dist/components/List/ListHeader/ListHeader.d.ts +7 -1
- package/dist/components/List/ListHeader/ListHeader.d.ts.map +1 -1
- package/dist/components/List/ListHeader/useResize.d.ts +18 -0
- package/dist/components/List/ListHeader/useResize.d.ts.map +1 -0
- package/dist/components/List/ListRow/ListRow.d.ts.map +1 -1
- package/dist/components/List/ListRow/ListRowLoader.d.ts +2 -2
- package/dist/components/List/ListRow/ListRowLoader.d.ts.map +1 -1
- package/dist/components/List/ListRow/Renderers/BooleanDotRenderer/BooleanDotRenderer.d.ts.map +1 -1
- package/dist/components/List/useColumnsSize.d.ts +21 -0
- package/dist/components/List/useColumnsSize.d.ts.map +1 -0
- package/dist/index.es.js +3 -3
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/Explorer/Explorer.stories.tsx +16 -0
- package/src/components/Explorer/Explorer.tsx +33 -31
- package/src/components/FormElements/FormElementContainer/FormElementContainer.scss +2 -0
- package/src/components/List/List.model.ts +3 -0
- package/src/components/List/List.scss +0 -2
- package/src/components/List/List.stories.tsx +1 -1
- package/src/components/List/List.tsx +17 -55
- package/src/components/List/ListHeader/ListHeader.scss +23 -10
- package/src/components/List/ListHeader/ListHeader.spec.tsx +56 -0
- package/src/components/List/ListHeader/ListHeader.tsx +43 -9
- package/src/components/List/ListHeader/useResize.ts +108 -0
- package/src/components/List/ListRow/ListRow.scss +8 -12
- package/src/components/List/ListRow/ListRow.spec.tsx +5 -21
- package/src/components/List/ListRow/ListRow.tsx +16 -31
- package/src/components/List/ListRow/ListRowLoader.tsx +14 -4
- package/src/components/List/ListRow/Renderers/BooleanDotRenderer/BooleanDotRenderer.scss +10 -8
- package/src/components/List/ListRow/Renderers/BooleanDotRenderer/BooleanDotRenderer.tsx +3 -1
- package/src/components/List/useColumnsSize.ts +120 -0
|
@@ -51,7 +51,7 @@ describe('ListRow', () => {
|
|
|
51
51
|
<ListRow {...mockProps} columns={expectedColumns} />,
|
|
52
52
|
);
|
|
53
53
|
|
|
54
|
-
const actualColumns = wrapper.find('.
|
|
54
|
+
const actualColumns = wrapper.find('.cellWrapper');
|
|
55
55
|
|
|
56
56
|
// Check amount of rendered columns
|
|
57
57
|
expect(actualColumns).toHaveLength(expectedColumns.length);
|
|
@@ -87,7 +87,7 @@ describe('ListRow', () => {
|
|
|
87
87
|
/>,
|
|
88
88
|
);
|
|
89
89
|
|
|
90
|
-
const actualColumns = wrapper.find('.
|
|
90
|
+
const actualColumns = wrapper.find('.cellWrapper');
|
|
91
91
|
// Check amount of rendered columns
|
|
92
92
|
expect(actualColumns).toHaveLength(2);
|
|
93
93
|
|
|
@@ -119,21 +119,21 @@ describe('ListRow', () => {
|
|
|
119
119
|
// @ts-expect-error Typings to not match up
|
|
120
120
|
<ListRow {...mockProps} data={rowData} columns={expectedColumns} />,
|
|
121
121
|
);
|
|
122
|
-
const actualColumns = wrapper.find('.
|
|
122
|
+
const actualColumns = wrapper.find('.cellWrapper');
|
|
123
123
|
expect(actualColumns.at(0).text()).toBe('Changed: something');
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
it('shows empty field if a value required in a column is not present on the data object', () => {
|
|
127
127
|
const expectedColumns: Column<TestExplorerData>[] = [
|
|
128
128
|
// @ts-expect-error intentional bad property
|
|
129
|
-
{ propertyName: '
|
|
129
|
+
{ propertyName: "doesn't exist", size: '1fr', label: 'desc' },
|
|
130
130
|
];
|
|
131
131
|
|
|
132
132
|
const wrapper = shallow(
|
|
133
133
|
<ListRow {...mockProps} columns={expectedColumns} />,
|
|
134
134
|
);
|
|
135
135
|
|
|
136
|
-
const actualColumns = wrapper.find('.
|
|
136
|
+
const actualColumns = wrapper.find('.cellWrapper');
|
|
137
137
|
|
|
138
138
|
// Check amount of rendered columns
|
|
139
139
|
expect(actualColumns).toHaveLength(1);
|
|
@@ -514,22 +514,6 @@ describe('ListRow', () => {
|
|
|
514
514
|
|
|
515
515
|
expect(link.exists()).toBe(false);
|
|
516
516
|
});
|
|
517
|
-
|
|
518
|
-
it('receives list row height', () => {
|
|
519
|
-
const height = '55px';
|
|
520
|
-
const wrapper = shallow(
|
|
521
|
-
<ListRow
|
|
522
|
-
{...mockProps}
|
|
523
|
-
onItemClicked="http://this.is.a.test.url"
|
|
524
|
-
selectionMode={ListSelectMode.None}
|
|
525
|
-
rowHeight={height}
|
|
526
|
-
/>,
|
|
527
|
-
);
|
|
528
|
-
|
|
529
|
-
const link = wrapper.find(Link);
|
|
530
|
-
|
|
531
|
-
expect(link.prop('style')?.gridTemplateRows).toBe(height);
|
|
532
|
-
});
|
|
533
517
|
});
|
|
534
518
|
|
|
535
519
|
describe('tooltip', () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { LocationDescriptor } from 'history';
|
|
3
3
|
import React, { PropsWithChildren, useCallback, useRef } from 'react';
|
|
4
|
-
import { Link
|
|
4
|
+
import { Link } from 'react-router-dom';
|
|
5
5
|
import { noop } from '../../../helpers/utils';
|
|
6
6
|
import { Data } from '../../../types/data';
|
|
7
7
|
import { getTooltipText } from '../../../utils/ToolTipHelpers';
|
|
@@ -140,14 +140,13 @@ export const ListRow = <T extends Data>({
|
|
|
140
140
|
isRowDisabled = false,
|
|
141
141
|
inlineMenuActions,
|
|
142
142
|
}: PropsWithChildren<ListRowProps<T>>): JSX.Element => {
|
|
143
|
-
const
|
|
143
|
+
const customRootStyles = {
|
|
144
144
|
gridAutoRows: rowHeight,
|
|
145
|
-
gridTemplateColumns: columnSizes,
|
|
146
145
|
gridColumnGap: columnGap,
|
|
147
146
|
justifyItems: horizontalTextAlign,
|
|
148
147
|
alignItems: verticalTextAlign,
|
|
148
|
+
gridTemplateColumns: columnSizes,
|
|
149
149
|
} as React.CSSProperties;
|
|
150
|
-
const history = useHistory();
|
|
151
150
|
|
|
152
151
|
// Trigger based on: https://www.youtube.com/watch?v=NZKUirTtxcg
|
|
153
152
|
const onTriggeredHandler = useCallback(() => {
|
|
@@ -196,14 +195,6 @@ export const ListRow = <T extends Data>({
|
|
|
196
195
|
const isLinkable: boolean =
|
|
197
196
|
selectionMode === ListSelectMode.None &&
|
|
198
197
|
typeof onItemClicked !== 'function';
|
|
199
|
-
const allColumns: string[] = columnSizes.split(' ');
|
|
200
|
-
const columnsWithoutActions: string[] = allColumns.slice(0, -1);
|
|
201
|
-
const cssStyles: React.CSSProperties = {
|
|
202
|
-
...customStyles,
|
|
203
|
-
gridTemplateColumns: isLinkable
|
|
204
|
-
? `1fr ${allColumns.slice(-1)}`
|
|
205
|
-
: columnSizes,
|
|
206
|
-
};
|
|
207
198
|
|
|
208
199
|
const generateCells: JSX.Element[] = columns.map((column: Column<T>) => {
|
|
209
200
|
const columnData: React.ReactNode = renderData<T>(
|
|
@@ -213,16 +204,17 @@ export const ListRow = <T extends Data>({
|
|
|
213
204
|
);
|
|
214
205
|
|
|
215
206
|
return (
|
|
216
|
-
<div
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
207
|
+
<div key={column.propertyName as string} className={classes.cellWrapper}>
|
|
208
|
+
<div
|
|
209
|
+
className={classes.cell}
|
|
210
|
+
title={
|
|
211
|
+
column.tooltip !== false ? getTooltipText(columnData) : undefined
|
|
212
|
+
}
|
|
213
|
+
data-test-id={`list-entry-property:${column.propertyName as string}`}
|
|
214
|
+
style={{ justifySelf: column.horizontalColumnAlign }}
|
|
215
|
+
>
|
|
216
|
+
{columnData}
|
|
217
|
+
</div>
|
|
226
218
|
</div>
|
|
227
219
|
);
|
|
228
220
|
});
|
|
@@ -237,7 +229,7 @@ export const ListRow = <T extends Data>({
|
|
|
237
229
|
[classes.selected]: itemSelected && showItemCheckbox,
|
|
238
230
|
[classes.disabled]: isRowDisabled,
|
|
239
231
|
})}
|
|
240
|
-
style={
|
|
232
|
+
style={customRootStyles}
|
|
241
233
|
onClick={() => {
|
|
242
234
|
onItemClickedHandler(data);
|
|
243
235
|
}}
|
|
@@ -246,14 +238,7 @@ export const ListRow = <T extends Data>({
|
|
|
246
238
|
>
|
|
247
239
|
{/* Items */}
|
|
248
240
|
{isLinkable ? (
|
|
249
|
-
<Link
|
|
250
|
-
to={onItemClicked as string}
|
|
251
|
-
className={classes.link}
|
|
252
|
-
style={{
|
|
253
|
-
gridTemplateColumns: columnsWithoutActions.join(' '),
|
|
254
|
-
gridTemplateRows: rowHeight,
|
|
255
|
-
}}
|
|
256
|
-
>
|
|
241
|
+
<Link to={onItemClicked as string} className={classes.link}>
|
|
257
242
|
{generateCells}
|
|
258
243
|
</Link>
|
|
259
244
|
) : (
|
|
@@ -5,9 +5,9 @@ import { Loader } from '../../Loaders/Loader/Loader';
|
|
|
5
5
|
import classes from './ListRow.scss';
|
|
6
6
|
|
|
7
7
|
export interface ListRowLoaderProps<T extends Data> {
|
|
8
|
-
/** Spacing
|
|
8
|
+
/** Spacing of columns */
|
|
9
9
|
columnSizes: string;
|
|
10
|
-
/**
|
|
10
|
+
/** Space between columns */
|
|
11
11
|
columnGap: string;
|
|
12
12
|
/** List row height */
|
|
13
13
|
rowHeight: string;
|
|
@@ -36,13 +36,23 @@ export const ListRowLoader = <T extends Data>({
|
|
|
36
36
|
className={classes.columnsRoot}
|
|
37
37
|
style={{
|
|
38
38
|
...customRowStyles,
|
|
39
|
-
opacity: (rows - i) / rows,
|
|
39
|
+
//opacity: (rows - i) / rows,
|
|
40
40
|
}}
|
|
41
41
|
>
|
|
42
42
|
{columns.map((column) => {
|
|
43
43
|
const loaderWidth = getSize(column.size);
|
|
44
44
|
return (
|
|
45
|
-
<div
|
|
45
|
+
<div
|
|
46
|
+
key={column.propertyName as string}
|
|
47
|
+
className={classes.cell}
|
|
48
|
+
style={{
|
|
49
|
+
opacity:
|
|
50
|
+
(rows -
|
|
51
|
+
i -
|
|
52
|
+
0.5) /* - 0.5 to make the loaders slightly more faint */ /
|
|
53
|
+
rows,
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
46
56
|
<Loader
|
|
47
57
|
showLoader={true}
|
|
48
58
|
height={textLoaderHeight}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
@import '../../../../../styles/common.scss';
|
|
2
2
|
|
|
3
|
-
.
|
|
4
|
-
background-color: var(--boolean-dot-true-color, $boolean-dot-true-color);
|
|
3
|
+
.circle {
|
|
5
4
|
height: var(--boolean-dot-size, $boolean-dot-size);
|
|
6
5
|
width: var(--boolean-dot-size, $boolean-dot-size);
|
|
6
|
+
min-width: var(--boolean-dot-size, $boolean-dot-size);
|
|
7
|
+
min-height: var(--boolean-dot-size, $boolean-dot-size);
|
|
7
8
|
border-radius: 100%;
|
|
8
|
-
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
&.green {
|
|
11
|
+
background-color: var(--boolean-dot-true-color, $boolean-dot-true-color);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&.red {
|
|
15
|
+
background-color: var(--boolean-dot-false-color, $boolean-dot-false-color);
|
|
16
|
+
}
|
|
15
17
|
}
|
|
@@ -16,5 +16,7 @@ import classes from './BooleanDotRenderer.scss';
|
|
|
16
16
|
*
|
|
17
17
|
*/
|
|
18
18
|
export const BooleanDotRenderer = (val: unknown): JSX.Element => (
|
|
19
|
-
<div
|
|
19
|
+
<div
|
|
20
|
+
className={clsx(classes.circle, val ? [classes.green] : [classes.red])}
|
|
21
|
+
></div>
|
|
20
22
|
);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { Data } from '../../types';
|
|
3
|
+
import { Column, ListSelectMode } from './List.model';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generates a combined string of all columns.columnSize values, to be used as CSS value
|
|
7
|
+
* @param columns The list of columns that should be used
|
|
8
|
+
* @returns a string of all column sizes of the array, combined
|
|
9
|
+
*/
|
|
10
|
+
const getColumnsSizeDefinition = function <T extends Data>(
|
|
11
|
+
columns: Column<T>[],
|
|
12
|
+
showActionButton: boolean,
|
|
13
|
+
selectMode: ListSelectMode,
|
|
14
|
+
showInlineMenu: boolean,
|
|
15
|
+
): string {
|
|
16
|
+
const columnSizeDefinition = columns.map((column) => column.size ?? '1fr');
|
|
17
|
+
|
|
18
|
+
const hasActionsColumn = hasActionColumn(
|
|
19
|
+
selectMode,
|
|
20
|
+
showActionButton,
|
|
21
|
+
showInlineMenu,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (hasActionsColumn) {
|
|
25
|
+
columnSizeDefinition.push(
|
|
26
|
+
getActionsColumnSizePx(showInlineMenu, showActionButton),
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return columnSizeDefinition.join(' ');
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getActionsColumnSizePx = (...enableActions: boolean[]): string => {
|
|
34
|
+
const enabledActionsCount = enableActions.filter(
|
|
35
|
+
(actionEnabled) => actionEnabled,
|
|
36
|
+
).length;
|
|
37
|
+
|
|
38
|
+
const defaultActionSizePx = 50;
|
|
39
|
+
const defaultActionsRawGapPx = 8;
|
|
40
|
+
const calculateMultiActionsColumnSizePx = (actionsCount: number): number => {
|
|
41
|
+
return (
|
|
42
|
+
defaultActionSizePx * actionsCount +
|
|
43
|
+
defaultActionsRawGapPx * (actionsCount - 1)
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const sizePx =
|
|
48
|
+
enabledActionsCount > 1
|
|
49
|
+
? calculateMultiActionsColumnSizePx(enabledActionsCount)
|
|
50
|
+
: defaultActionSizePx;
|
|
51
|
+
|
|
52
|
+
return `${sizePx}px`;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Covers the concern of managing the column sizes for the list component
|
|
57
|
+
* @param columns input definition of columns
|
|
58
|
+
* @param showActionButton whether the action button is shown
|
|
59
|
+
* @param selectMode current select mode
|
|
60
|
+
* @param showInlineMenu whether the inline menu is shown
|
|
61
|
+
* @returns an object containing the columnSizes (CSS grid-template-columns),
|
|
62
|
+
* a reset function (to reset to the initial column sizes)
|
|
63
|
+
* and a setter function (to update the column sizes)
|
|
64
|
+
*/
|
|
65
|
+
export const useColumnsSize = <T extends Data>(
|
|
66
|
+
columns: Column<T>[],
|
|
67
|
+
showActionButton: boolean,
|
|
68
|
+
selectMode: ListSelectMode,
|
|
69
|
+
showInlineMenu: boolean,
|
|
70
|
+
): {
|
|
71
|
+
columnSizes: string;
|
|
72
|
+
resetColumnSizes: () => void;
|
|
73
|
+
setColumnSizes: React.Dispatch<React.SetStateAction<string>>;
|
|
74
|
+
hasActionColumn: boolean;
|
|
75
|
+
} => {
|
|
76
|
+
const [orgColumnSizes, setOrgColumnSizes] = useState<string>(
|
|
77
|
+
getColumnsSizeDefinition(
|
|
78
|
+
columns,
|
|
79
|
+
showActionButton,
|
|
80
|
+
selectMode,
|
|
81
|
+
showInlineMenu,
|
|
82
|
+
),
|
|
83
|
+
);
|
|
84
|
+
const [columnSizes, setColumnSizes] = useState<string>(orgColumnSizes);
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
setOrgColumnSizes(
|
|
88
|
+
getColumnsSizeDefinition(
|
|
89
|
+
columns,
|
|
90
|
+
showActionButton,
|
|
91
|
+
selectMode,
|
|
92
|
+
showInlineMenu,
|
|
93
|
+
),
|
|
94
|
+
);
|
|
95
|
+
}, [columns, selectMode, showActionButton, showInlineMenu]);
|
|
96
|
+
|
|
97
|
+
const resetColumnSizes = (): void => {
|
|
98
|
+
setColumnSizes(orgColumnSizes);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
columnSizes,
|
|
103
|
+
resetColumnSizes,
|
|
104
|
+
setColumnSizes,
|
|
105
|
+
hasActionColumn: hasActionColumn(
|
|
106
|
+
selectMode,
|
|
107
|
+
showActionButton,
|
|
108
|
+
showInlineMenu,
|
|
109
|
+
),
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
function hasActionColumn(
|
|
113
|
+
selectMode: ListSelectMode,
|
|
114
|
+
showActionButton: boolean,
|
|
115
|
+
showInlineMenu: boolean,
|
|
116
|
+
): boolean {
|
|
117
|
+
return (
|
|
118
|
+
selectMode !== ListSelectMode.None || showActionButton || showInlineMenu
|
|
119
|
+
);
|
|
120
|
+
}
|