@axinom/mosaic-ui 0.49.0-rc.10 → 0.49.0-rc.11

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 (28) hide show
  1. package/dist/components/DynamicDataList/DynamicDataList.d.ts +3 -1
  2. package/dist/components/DynamicDataList/DynamicDataList.d.ts.map +1 -1
  3. package/dist/components/DynamicDataList/DynamicListRow/DynamicListRow.d.ts +3 -1
  4. package/dist/components/DynamicDataList/DynamicListRow/DynamicListRow.d.ts.map +1 -1
  5. package/dist/components/Explorer/Explorer.d.ts +2 -0
  6. package/dist/components/Explorer/Explorer.d.ts.map +1 -1
  7. package/dist/components/List/List.d.ts +2 -0
  8. package/dist/components/List/List.d.ts.map +1 -1
  9. package/dist/components/List/ListRow/ListRow.d.ts +4 -2
  10. package/dist/components/List/ListRow/ListRow.d.ts.map +1 -1
  11. package/dist/components/List/ListRow/ListRowLoader.d.ts +1 -1
  12. package/dist/components/List/ListRow/ListRowLoader.d.ts.map +1 -1
  13. package/dist/index.es.js +5 -4
  14. package/dist/index.es.js.map +1 -1
  15. package/dist/index.js +5 -4
  16. package/dist/index.js.map +1 -1
  17. package/package.json +3 -3
  18. package/src/components/DynamicDataList/DynamicDataList.stories.tsx +2 -1
  19. package/src/components/DynamicDataList/DynamicDataList.tsx +4 -0
  20. package/src/components/DynamicDataList/DynamicListRow/DynamicListRow.scss +11 -5
  21. package/src/components/DynamicDataList/DynamicListRow/DynamicListRow.tsx +19 -14
  22. package/src/components/Explorer/Explorer.stories.tsx +1 -0
  23. package/src/components/Explorer/Explorer.tsx +5 -0
  24. package/src/components/List/List.stories.tsx +2 -1
  25. package/src/components/List/List.tsx +5 -1
  26. package/src/components/List/ListRow/ListRow.scss +11 -3
  27. package/src/components/List/ListRow/ListRow.tsx +39 -16
  28. package/src/components/List/ListRow/ListRowLoader.tsx +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.49.0-rc.10",
3
+ "version": "0.49.0-rc.11",
4
4
  "description": "UI components for building Axinom Mosaic applications",
5
5
  "author": "Axinom",
6
6
  "license": "PROPRIETARY",
@@ -32,7 +32,7 @@
32
32
  "build-storybook": "storybook build"
33
33
  },
34
34
  "dependencies": {
35
- "@axinom/mosaic-core": "^0.4.22-rc.10",
35
+ "@axinom/mosaic-core": "^0.4.22-rc.11",
36
36
  "@faker-js/faker": "^7.4.0",
37
37
  "@popperjs/core": "^2.11.8",
38
38
  "clsx": "^1.1.0",
@@ -105,5 +105,5 @@
105
105
  "publishConfig": {
106
106
  "access": "public"
107
107
  },
108
- "gitHead": "130dddd0b1efabb2f50d5cf5455e4f48f7309b34"
108
+ "gitHead": "9af527f2f2a4e4442b81530d50f4787ea5b9e4db"
109
109
  }
@@ -44,7 +44,7 @@ const generateData = (amount: number): DynamicListStoryData[] =>
44
44
  position: amount - index, // Position and ID is jumbled for demonstration purposes
45
45
  id: index,
46
46
  desc: `Description ${index}: ${faker.lorem.words(
47
- faker.datatype.number({ min: 10, max: 20 }),
47
+ faker.datatype.number({ min: 10, max: 50 }),
48
48
  )}`,
49
49
  title: `Item ${index}: ${faker.random.words(
50
50
  faker.datatype.number({ min: 1, max: 3 }),
@@ -87,6 +87,7 @@ const groups = createGroups({
87
87
  'headerRowActionSize',
88
88
  'horizontalTextAlign',
89
89
  'verticalTextAlign',
90
+ 'textWrap',
90
91
  'rowClassNameProvider',
91
92
  ],
92
93
  });
@@ -53,6 +53,8 @@ export interface DynamicDataListProps<T extends Data> {
53
53
  horizontalTextAlign?: 'left' | 'right' | 'center';
54
54
  /** Vertical alignment of text */
55
55
  verticalTextAlign?: 'start' | 'center' | 'end';
56
+ /** If set to true, column text overflow will be wrapped to a new line. Otherwise, it will be truncated with an ellipsis (default: false) */
57
+ textWrap?: boolean;
56
58
  /** Property that contains the value used in reordering the list (default: undefined) */
57
59
  positionPropertyName?: keyof T;
58
60
  /** If sets, sets the label for the position column (default: 'Position') */
@@ -127,6 +129,7 @@ export const DynamicDataList = <T extends Data>({
127
129
  stickyHeader = true,
128
130
  disabled = false,
129
131
  className = '',
132
+ textWrap = false,
130
133
  onChange = noop,
131
134
  onAddTransformData = (data) => data as T,
132
135
  rowClassNameProvider,
@@ -233,6 +236,7 @@ export const DynamicDataList = <T extends Data>({
233
236
  actionSize={listRowActionSize}
234
237
  horizontalTextAlign={horizontalTextAlign}
235
238
  verticalTextAlign={verticalTextAlign}
239
+ textWrap={textWrap}
236
240
  allowRemove={allowNewData}
237
241
  positionKey={positionPropertyName}
238
242
  allowDragging={allowRowDragging}
@@ -9,7 +9,6 @@
9
9
 
10
10
  display: grid;
11
11
  padding: 1px 0px 1px 0px;
12
- grid-auto-rows: var(--dynamic-list-row-height, $dynamic-list-row-height);
13
12
  column-gap: var(--dynamic-list-column-gap, $dynamic-list-column-gap);
14
13
 
15
14
  border-bottom: var(--dynamic-list-row-border, $dynamic-list-row-border);
@@ -26,7 +25,7 @@
26
25
  align-items: center;
27
26
 
28
27
  .wrapper {
29
- min-height: 50px;
28
+ min-height: var(--dynamic-list-row-height, $dynamic-list-row-height);
30
29
  min-width: 100%;
31
30
  display: grid;
32
31
  align-items: center;
@@ -41,9 +40,16 @@
41
40
  max-width: 100%;
42
41
  max-height: 100%;
43
42
 
44
- white-space: nowrap;
45
- text-overflow: ellipsis;
46
- overflow: hidden;
43
+ span {
44
+ padding: 5px 0;
45
+ display: grid;
46
+ }
47
+
48
+ &.nowrap {
49
+ white-space: nowrap;
50
+ text-overflow: ellipsis;
51
+ overflow: hidden;
52
+ }
47
53
  }
48
54
 
49
55
  .position,
@@ -28,6 +28,8 @@ export interface DynamicListRowProps<T extends Data> {
28
28
  horizontalTextAlign?: 'left' | 'right' | 'center';
29
29
  /** Vertical alignment of text */
30
30
  verticalTextAlign?: 'start' | 'center' | 'end';
31
+ /** If set to true, column text overflow will be wrapped to a new line. Otherwise, it will be truncated with an ellipsis (default: false) */
32
+ textWrap?: boolean;
31
33
  /** If set to true, the remove action button will be rendered (default: undefined) */
32
34
  allowRemove?: boolean;
33
35
  /** If set to true, editable fields will be highlighted and row click events will be fired (default: false) */
@@ -85,6 +87,7 @@ export const DynamicListRow = <T extends Data>({
85
87
  showPositionColumn = false,
86
88
  showActionColumn = false,
87
89
  allowEditing = false,
90
+ textWrap = false,
88
91
  }: PropsWithChildren<DynamicListRowProps<T>>): JSX.Element => {
89
92
  const customStyles = {
90
93
  gridAutoRows: `minmax(50px, ${rowHeight})`,
@@ -170,7 +173,7 @@ export const DynamicListRow = <T extends Data>({
170
173
  </div>
171
174
  )}
172
175
  {columns.map((column: DynamicListColumn<T>) => {
173
- const columnData: React.ReactNode = renderData<T>(column, data);
176
+ const { columnData, tooltip } = renderData<T>(column, data);
174
177
 
175
178
  return (
176
179
  <div
@@ -185,12 +188,10 @@ export const DynamicListRow = <T extends Data>({
185
188
  }}
186
189
  >
187
190
  <div
188
- className={classes.column}
189
- title={
190
- column.tooltip !== false
191
- ? getTooltipText(columnData)
192
- : undefined
193
- }
191
+ className={clsx(classes.column, {
192
+ [classes.nowrap]: !textWrap,
193
+ })}
194
+ title={tooltip}
194
195
  data-test-id={`dynamic-list-property:${
195
196
  column.propertyName as string
196
197
  }`}
@@ -230,22 +231,26 @@ export const DynamicListRow = <T extends Data>({
230
231
  </div>
231
232
  );
232
233
  };
233
-
234
- const renderData = function <T extends Data>(
234
+ const renderData = <T extends Data>(
235
235
  column: DynamicListColumn<T>,
236
236
  data: T,
237
- ): React.ReactNode {
237
+ ): { columnData: React.ReactNode; tooltip: string | undefined } => {
238
+ const getTooltip = (value: unknown): string | undefined =>
239
+ column.tooltip !== false ? getTooltipText(value) : undefined;
240
+
238
241
  if (!column.propertyName) {
239
- return column.render!(undefined, data);
242
+ const columnData = column.render?.(undefined, data);
243
+ return { columnData, tooltip: getTooltip(columnData) };
240
244
  }
241
245
  const value: unknown = data[column.propertyName];
242
246
  if (column.render) {
243
- return column.render(value, data);
247
+ const columnData = column.render(value, data);
248
+ return { columnData, tooltip: getTooltip(columnData) };
244
249
  }
245
250
 
246
251
  if (value === null || value === undefined) {
247
- return '';
252
+ return { columnData: <span />, tooltip: undefined };
248
253
  }
249
254
 
250
- return String(value);
255
+ return { columnData: String(value), tooltip: getTooltip(String(value)) };
251
256
  };
@@ -65,6 +65,7 @@ const groups = createGroups({
65
65
  'rowGap',
66
66
  'verticalTextAlign',
67
67
  'horizontalTextAlign',
68
+ 'textWrap',
68
69
  'headerRowActionSize',
69
70
  'listRowActionSize',
70
71
  ],
@@ -92,6 +92,9 @@ export interface ExplorerProps<T extends Data> {
92
92
  /** Vertical alignment of text */
93
93
  verticalTextAlign?: 'start' | 'center' | 'end';
94
94
 
95
+ /** If set to true, column text overflow will be wrapped to a new line. Otherwise, it will be truncated with an ellipsis (default: true) */
96
+ textWrap?: boolean;
97
+
95
98
  /** Defines when the loading of the next page is triggered. The number represents the number of row left, before a load is triggered. (default: 10) */
96
99
  loadingTriggerOffset?: number;
97
100
 
@@ -183,6 +186,7 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
183
186
  headerRowActionSize,
184
187
  horizontalTextAlign,
185
188
  verticalTextAlign,
189
+ textWrap,
186
190
 
187
191
  columns,
188
192
  filterOptions,
@@ -479,6 +483,7 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
479
483
  headerRowActionSize={headerRowActionSize}
480
484
  horizontalTextAlign={horizontalTextAlign}
481
485
  verticalTextAlign={verticalTextAlign}
486
+ textWrap={textWrap}
482
487
  keyProperty={keyProperty}
483
488
  showActionButton={Boolean(generateItemLink) || Boolean(onItemClicked)} // or hard code to `true`?
484
489
  selectionMode={mode}
@@ -54,7 +54,7 @@ const generateData = (amount: number): ListStoryData[] =>
54
54
  generateItemArray(amount, (index) => ({
55
55
  id: index + 1,
56
56
  desc: `Description ${index + 1}: ${faker.lorem.words(
57
- faker.datatype.number({ min: 10, max: 20 }),
57
+ faker.datatype.number({ min: 10, max: 50 }),
58
58
  )}`,
59
59
  title: `Item ${index + 1}: ${faker.random.words(
60
60
  faker.datatype.number({ min: 1, max: 3 }),
@@ -92,6 +92,7 @@ const groups = createGroups({
92
92
  Styling: [
93
93
  'horizontalTextAlign',
94
94
  'verticalTextAlign',
95
+ 'textWrap',
95
96
  'minimumWidth',
96
97
  'columnGap',
97
98
  'rowGap',
@@ -65,6 +65,8 @@ export interface ListProps<T extends Data> {
65
65
  horizontalTextAlign?: 'left' | 'right' | 'center';
66
66
  /** Vertical alignment of text */
67
67
  verticalTextAlign?: 'start' | 'center' | 'end';
68
+ /** If set to true, column text overflow will be wrapped to a new line. Otherwise, it will be truncated with an ellipsis (default: false) */
69
+ textWrap?: boolean;
68
70
  /**
69
71
  * Determines which select mode the list is in. (default: ListSelectMode.None)
70
72
  * If 'Single' is selected, a check mark will be rendered for each row of data
@@ -122,7 +124,7 @@ const ListRenderer = <T extends Data>(
122
124
  columnGap = '5px',
123
125
  rowGap = '0px',
124
126
  headerRowHeight = '44px',
125
- listRowHeight = '50px',
127
+ listRowHeight,
126
128
  listRowActionSize = '50px',
127
129
  headerRowActionSize = '28px',
128
130
  horizontalTextAlign = 'left',
@@ -134,6 +136,7 @@ const ListRenderer = <T extends Data>(
134
136
  selectionMode = ListSelectMode.None,
135
137
  enableSelectAll = true,
136
138
  enableSelectAllDeselect = false,
139
+ textWrap,
137
140
  onItemClicked = noop,
138
141
  onItemSelected = noop,
139
142
  onRequestMoreData = noop,
@@ -300,6 +303,7 @@ const ListRenderer = <T extends Data>(
300
303
  actionSize={listRowActionSize}
301
304
  horizontalTextAlign={horizontalTextAlign}
302
305
  verticalTextAlign={verticalTextAlign}
306
+ textWrap={textWrap}
303
307
  selectionMode={selectionMode}
304
308
  showActionButton={
305
309
  selectionMode === ListSelectMode.None &&
@@ -34,11 +34,19 @@
34
34
  }
35
35
 
36
36
  .cell {
37
- white-space: nowrap;
38
- text-overflow: ellipsis;
39
- overflow: hidden;
40
37
  max-width: 100%;
41
38
  max-height: 100%;
39
+
40
+ span {
41
+ padding: 5px 0;
42
+ display: grid;
43
+ }
44
+
45
+ &.nowrap {
46
+ white-space: nowrap;
47
+ text-overflow: ellipsis;
48
+ overflow: hidden;
49
+ }
42
50
  }
43
51
 
44
52
  .actions {
@@ -19,13 +19,15 @@ export interface ListRowProps<T extends Data> {
19
19
  /** Header row height */
20
20
  columnGap: string;
21
21
  /** List row height */
22
- rowHeight: string;
22
+ rowHeight?: string;
23
23
  /** Size of action button and checkbox */
24
24
  actionSize: string;
25
25
  /** Horizontal alignment of text */
26
26
  horizontalTextAlign: 'left' | 'right' | 'center';
27
27
  /** Vertical alignment of text */
28
28
  verticalTextAlign: 'start' | 'center' | 'end';
29
+ /** If set to true, column text overflow will be wrapped to a new line. Otherwise, it will be truncated with an ellipsis (default: false) */
30
+ textWrap?: boolean;
29
31
  /** List data */
30
32
  data: T;
31
33
  /** The column definition */
@@ -81,32 +83,54 @@ export const setLocale = (locale: string): void => {
81
83
 
82
84
  setLocale(navigator.language);
83
85
 
84
- function renderData<T extends Data>(
86
+ const renderData = <T extends Data>(
85
87
  column: Column<T>,
86
88
  rowData: T,
87
- ): React.ReactNode {
89
+ ): { columnData: React.ReactNode; tooltip: string | undefined } => {
90
+ const getTooltip = (value: unknown): string | undefined =>
91
+ column.tooltip !== false ? getTooltipText(value) : undefined;
92
+
88
93
  if (!column.propertyName) {
89
- return column.render!(undefined, rowData);
94
+ const columnData = column.render?.(undefined, rowData);
95
+ return {
96
+ columnData,
97
+ tooltip: getTooltip(columnData),
98
+ };
90
99
  }
91
100
  const value: unknown = rowData[column.propertyName];
92
101
  if (column.render) {
93
- return column.render(value, rowData);
102
+ const columnData = column.render(value, rowData);
103
+ return {
104
+ columnData,
105
+ tooltip: getTooltip(columnData),
106
+ };
94
107
  }
95
108
 
96
109
  if (value === null || value === undefined) {
97
- return '';
110
+ return { columnData: <span />, tooltip: undefined };
98
111
  }
99
112
 
100
113
  if (typeof value === 'number') {
101
- return numberFormatter.format(value);
114
+ const columnData = numberFormatter.format(value);
115
+ return {
116
+ columnData: <span>{columnData}</span>,
117
+ tooltip: getTooltip(columnData),
118
+ };
102
119
  }
103
120
 
104
121
  if (value instanceof Date) {
105
- return dateFormatter.format(value);
122
+ const columnData = dateFormatter.format(value);
123
+ return {
124
+ columnData: <span>{columnData}</span>,
125
+ tooltip: getTooltip(columnData),
126
+ };
106
127
  }
107
128
 
108
- return String(value);
109
- }
129
+ return {
130
+ columnData: <span>{String(value)}</span>,
131
+ tooltip: getTooltip(String(value)),
132
+ };
133
+ };
110
134
 
111
135
  /**
112
136
  * Renders the rows for the list component
@@ -128,6 +152,7 @@ export const ListRow = <T extends Data>({
128
152
  actionSize,
129
153
  horizontalTextAlign,
130
154
  verticalTextAlign,
155
+ textWrap = false,
131
156
  data,
132
157
  itemSelected = false,
133
158
  isTrigger = false,
@@ -143,7 +168,7 @@ export const ListRow = <T extends Data>({
143
168
  inlineMenuActions,
144
169
  }: PropsWithChildren<ListRowProps<T>>): JSX.Element => {
145
170
  const customRootStyles = {
146
- gridAutoRows: rowHeight,
171
+ gridAutoRows: `minmax(50px, ${rowHeight})`,
147
172
  gridColumnGap: columnGap,
148
173
  justifyItems: horizontalTextAlign,
149
174
  alignItems: verticalTextAlign,
@@ -199,7 +224,7 @@ export const ListRow = <T extends Data>({
199
224
  typeof onItemClicked !== 'function';
200
225
 
201
226
  const generateCells: JSX.Element[] = columns.map((column: Column<T>) => {
202
- const columnData: React.ReactNode = renderData<T>(column, data);
227
+ const { columnData, tooltip } = renderData<T>(column, data);
203
228
 
204
229
  return (
205
230
  <div
@@ -207,10 +232,8 @@ export const ListRow = <T extends Data>({
207
232
  className={classes.cellWrapper}
208
233
  >
209
234
  <div
210
- className={classes.cell}
211
- title={
212
- column.tooltip !== false ? getTooltipText(columnData) : undefined
213
- }
235
+ className={clsx(classes.cell, { [classes.nowrap]: !textWrap })}
236
+ title={tooltip}
214
237
  data-test-id={`list-entry-property:${column.propertyName as string}`}
215
238
  style={{
216
239
  justifySelf: column.horizontalColumnAlign, // Horizontal alignment based on column config
@@ -10,7 +10,7 @@ export interface ListRowLoaderProps<T extends Data> {
10
10
  /** Space between columns */
11
11
  columnGap: string;
12
12
  /** List row height */
13
- rowHeight: string;
13
+ rowHeight?: string;
14
14
  /** The column definition */
15
15
  columns: Column<T>[];
16
16
  }
@@ -25,7 +25,7 @@ export const ListRowLoader = <T extends Data>({
25
25
  const rows = 5;
26
26
 
27
27
  const customRowStyles = {
28
- gridAutoRows: rowHeight,
28
+ gridAutoRows: `minmax(50px, ${rowHeight})`,
29
29
  gridTemplateColumns: columnSizes,
30
30
  gridColumnGap: columnGap,
31
31
  } as React.CSSProperties;