@scality/core-ui 0.121.0 → 0.123.0

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 (102) hide show
  1. package/.storybook/preview.js +29 -8
  2. package/dist/components/card/Card.component.d.ts.map +1 -1
  3. package/dist/components/card/Card.component.js +7 -5
  4. package/dist/components/checkbox/Checkbox.component.d.ts +7 -0
  5. package/dist/components/checkbox/Checkbox.component.d.ts.map +1 -1
  6. package/dist/components/checkbox/Checkbox.component.js +2 -0
  7. package/dist/components/constrainedtext/Constrainedtext.component.d.ts.map +1 -1
  8. package/dist/components/constrainedtext/Constrainedtext.component.js +1 -4
  9. package/dist/components/emptystate/Emptystate.component.d.ts +11 -1
  10. package/dist/components/emptystate/Emptystate.component.d.ts.map +1 -1
  11. package/dist/components/emptystate/Emptystate.component.js +9 -4
  12. package/dist/components/icon/Icon.component.d.ts +2 -2
  13. package/dist/components/icon/Icon.component.d.ts.map +1 -1
  14. package/dist/components/infomessage/InfoMessageUtils.d.ts +1 -1
  15. package/dist/components/infomessage/InfoMessageUtils.d.ts.map +1 -1
  16. package/dist/components/infomessage/InfoMessageUtils.js +5 -4
  17. package/dist/components/layout/v2/AppContainer.js +1 -1
  18. package/dist/components/linetemporalchart/LineTemporalChart.component.d.ts.map +1 -1
  19. package/dist/components/linetemporalchart/LineTemporalChart.component.js +1 -2
  20. package/dist/components/navbar/Navbar.component.d.ts.map +1 -1
  21. package/dist/components/navbar/Navbar.component.js +1 -0
  22. package/dist/components/searchinput/SearchInput.component.d.ts +2 -1
  23. package/dist/components/searchinput/SearchInput.component.d.ts.map +1 -1
  24. package/dist/components/selectv2/Selectv2.component.d.ts +1 -1
  25. package/dist/components/selectv2/Selectv2.component.d.ts.map +1 -1
  26. package/dist/components/selectv2/Selectv2.component.js +10 -7
  27. package/dist/components/sidebar/Sidebar.component.d.ts.map +1 -1
  28. package/dist/components/sidebar/Sidebar.component.js +2 -1
  29. package/dist/components/steppers/Steppers.component.d.ts.map +1 -1
  30. package/dist/components/steppers/Steppers.component.js +9 -3
  31. package/dist/components/tablev2/MultiSelectableContent.d.ts +1 -2
  32. package/dist/components/tablev2/MultiSelectableContent.d.ts.map +1 -1
  33. package/dist/components/tablev2/MultiSelectableContent.js +9 -24
  34. package/dist/components/tablev2/Search.d.ts +0 -6
  35. package/dist/components/tablev2/Search.d.ts.map +1 -1
  36. package/dist/components/tablev2/Search.js +3 -4
  37. package/dist/components/tablev2/SingleSelectableContent.d.ts +4 -5
  38. package/dist/components/tablev2/SingleSelectableContent.d.ts.map +1 -1
  39. package/dist/components/tablev2/SingleSelectableContent.js +9 -23
  40. package/dist/components/tablev2/TableCommon.d.ts +15 -3
  41. package/dist/components/tablev2/TableCommon.d.ts.map +1 -1
  42. package/dist/components/tablev2/TableCommon.js +37 -2
  43. package/dist/components/tablev2/TableUtils.d.ts +11 -0
  44. package/dist/components/tablev2/TableUtils.d.ts.map +1 -1
  45. package/dist/components/tablev2/TableUtils.js +23 -0
  46. package/dist/components/tablev2/Tablestyle.d.ts +6 -3
  47. package/dist/components/tablev2/Tablestyle.d.ts.map +1 -1
  48. package/dist/components/tablev2/Tablestyle.js +29 -36
  49. package/dist/components/tablev2/Tablev2.component.d.ts +24 -3
  50. package/dist/components/tablev2/Tablev2.component.d.ts.map +1 -1
  51. package/dist/components/tablev2/Tablev2.component.js +3 -1
  52. package/dist/components/tabsv2/StyledTabs.d.ts.map +1 -1
  53. package/dist/components/tabsv2/StyledTabs.js +14 -14
  54. package/dist/components/toast/Toast.component.d.ts.map +1 -1
  55. package/dist/components/toast/Toast.component.js +1 -1
  56. package/dist/components/toast/useMutationsHandler.d.ts +1 -1
  57. package/dist/components/toast/useMutationsHandler.d.ts.map +1 -1
  58. package/dist/components/toast/useMutationsHandler.js +8 -6
  59. package/dist/components/vegachartv2/VegaChartV2.component.js +1 -1
  60. package/dist/organisms/attachments/AttachmentConfirmationModal.d.ts.map +1 -1
  61. package/dist/organisms/attachments/AttachmentConfirmationModal.js +1 -1
  62. package/dist/organisms/attachments/AttachmentTable.d.ts.map +1 -1
  63. package/dist/organisms/attachments/AttachmentTable.js +15 -12
  64. package/package.json +5 -3
  65. package/src/lib/components/card/Card.component.tsx +7 -6
  66. package/src/lib/components/checkbox/Checkbox.component.tsx +3 -1
  67. package/src/lib/components/constrainedtext/Constrainedtext.component.tsx +1 -4
  68. package/src/lib/components/emptystate/Emptystate.component.tsx +34 -10
  69. package/src/lib/components/icon/Icon.component.tsx +2 -2
  70. package/src/lib/components/infomessage/InfoMessageUtils.ts +39 -33
  71. package/src/lib/components/layout/v2/AppContainer.tsx +1 -1
  72. package/src/lib/components/linetemporalchart/LineTemporalChart.component.tsx +1 -2
  73. package/src/lib/components/navbar/Navbar.component.tsx +1 -0
  74. package/src/lib/components/searchinput/SearchInput.component.tsx +1 -0
  75. package/src/lib/components/selectv2/Selectv2.component.tsx +12 -8
  76. package/src/lib/components/selectv2/selectv2.test.tsx +193 -5
  77. package/src/lib/components/sidebar/Sidebar.component.tsx +3 -2
  78. package/src/lib/components/steppers/Steppers.component.tsx +13 -3
  79. package/src/lib/components/tablev2/MultiSelectableContent.tsx +13 -63
  80. package/src/lib/components/tablev2/Search.tsx +13 -24
  81. package/src/lib/components/tablev2/SingleSelectableContent.tsx +18 -71
  82. package/src/lib/components/tablev2/TableCommon.tsx +100 -1
  83. package/src/lib/components/tablev2/TableUtils.ts +37 -0
  84. package/src/lib/components/tablev2/Tablestyle.tsx +30 -37
  85. package/src/lib/components/tablev2/Tablev2.component.tsx +14 -0
  86. package/src/lib/components/tablev2/Tablev2.test.tsx +0 -3
  87. package/src/lib/components/tabsv2/StyledTabs.ts +16 -14
  88. package/src/lib/components/toast/Toast.component.tsx +1 -0
  89. package/src/lib/components/toast/useMutationsHandler.ts +4 -2
  90. package/src/lib/components/vegachartv2/VegaChartV2.component.tsx +1 -1
  91. package/src/lib/organisms/attachments/AttachmentConfirmationModal.tsx +0 -1
  92. package/src/lib/organisms/attachments/AttachmentTable.tsx +25 -16
  93. package/stories/Checkbox/checkbox.guideline.mdx +55 -0
  94. package/stories/Checkbox/checkbox.stories.tsx +173 -0
  95. package/stories/Hooks/useMutationsHandler.mdx +121 -0
  96. package/stories/attachment.stories.tsx +78 -0
  97. package/stories/common.tsx +12 -6
  98. package/stories/emptystate.stories.tsx +1 -2
  99. package/stories/form.stories.tsx +1 -3
  100. package/stories/modal.stories.tsx +0 -2
  101. package/stories/tablev2.stories.tsx +131 -52
  102. package/stories/checkbox.stories.tsx +0 -63
@@ -1,4 +1,4 @@
1
- import { ComponentType, LegacyRef, useCallback, useState } from 'react';
1
+ import React, { ComponentType, LegacyRef, useCallback, useState } from 'react';
2
2
  import { Row } from 'react-table';
3
3
  import AutoSizer from 'react-virtualized-auto-sizer';
4
4
  import {
@@ -9,9 +9,18 @@ import {
9
9
  } from 'react-window';
10
10
  import {
11
11
  convertRemToPixels,
12
+ translatedMessages,
12
13
  TableHeightKeyType,
14
+ TableLocalType,
13
15
  tableRowHeight,
14
16
  } from './TableUtils';
17
+ import { useTableContext } from './Tablev2.component';
18
+ import { NoResult } from './Tablestyle';
19
+ import { Loader } from '../loader/Loader.component';
20
+ import { Text } from '../text/Text.component';
21
+ import { Icon } from '../icon/Icon.component';
22
+ import useSyncedScroll from './useSyncedScroll';
23
+ import { CSSProperties } from 'styled-components';
15
24
 
16
25
  type VirtualizedRowsType<
17
26
  DATA_ROW extends Record<string, unknown> = Record<string, unknown>,
@@ -100,3 +109,93 @@ export const useTableScrollbar = () => {
100
109
  handleScrollbarWidth,
101
110
  };
102
111
  };
112
+
113
+ export type RenderRowType = {
114
+ index: number;
115
+ style: CSSProperties;
116
+ };
117
+
118
+ type TableRowsProps<
119
+ DATA_ROW extends Record<string, unknown> = Record<string, unknown>,
120
+ > = {
121
+ locale?: TableLocalType;
122
+ children?: (children: JSX.Element) => JSX.Element;
123
+ customItemKey?: (index: number, data: DATA_ROW) => string;
124
+ RenderRow: React.MemoExoticComponent<
125
+ ({ index, style }: RenderRowType) => JSX.Element
126
+ >;
127
+ };
128
+ export function TableRows<
129
+ DATA_ROW extends Record<string, unknown> = Record<string, unknown>,
130
+ >({ locale, children, customItemKey, RenderRow }: TableRowsProps<DATA_ROW>) {
131
+ const { setHasScrollbar } = useTableScrollbar();
132
+ const { rows, status, entityName, rowHeight, onBottom, onBottomOffset } =
133
+ useTableContext();
134
+ const { bodyRef } = useSyncedScroll();
135
+
136
+ function itemKey(index, data) {
137
+ if (typeof customItemKey === 'function') {
138
+ return customItemKey(index, data);
139
+ }
140
+
141
+ return index;
142
+ }
143
+
144
+ if (status === 'idle' || status === 'loading') {
145
+ return (
146
+ <NoResult rowHeight={rowHeight}>
147
+ <Loader />
148
+ <Text color="textSecondary">
149
+ {translatedMessages('loading', entityName, locale)}
150
+ </Text>
151
+ </NoResult>
152
+ );
153
+ }
154
+ if (status === 'error') {
155
+ return (
156
+ <NoResult rowHeight={rowHeight}>
157
+ <Icon name="Exclamation-circle" color="statusWarning" />
158
+ <Text color="textSecondary">
159
+ {translatedMessages('error', entityName, locale)}
160
+ </Text>
161
+ </NoResult>
162
+ );
163
+ }
164
+ if (status === 'success' || status === undefined) {
165
+ if (typeof children === 'function') {
166
+ return children(
167
+ <VirtualizedRows
168
+ rows={rows}
169
+ listRef={bodyRef}
170
+ itemKey={itemKey}
171
+ rowHeight={rowHeight}
172
+ setHasScrollbar={setHasScrollbar}
173
+ onBottom={onBottom}
174
+ onBottomOffset={onBottomOffset}
175
+ RenderRow={RenderRow}
176
+ />,
177
+ );
178
+ } else if (rows.length) {
179
+ return (
180
+ <VirtualizedRows
181
+ rows={rows}
182
+ listRef={bodyRef}
183
+ setHasScrollbar={setHasScrollbar}
184
+ onBottom={onBottom}
185
+ onBottomOffset={onBottomOffset}
186
+ itemKey={itemKey}
187
+ rowHeight={rowHeight}
188
+ RenderRow={RenderRow}
189
+ />
190
+ );
191
+ } else {
192
+ return (
193
+ <NoResult rowHeight={rowHeight}>
194
+ {translatedMessages('noResult', entityName, locale)}
195
+ </NoResult>
196
+ );
197
+ }
198
+ }
199
+
200
+ return null;
201
+ }
@@ -58,3 +58,40 @@ export const tableRowHeight = {
58
58
  h48: '3.428', //2 line
59
59
  h64: '4.572', //3 line
60
60
  };
61
+
62
+ type TableMessagesType = 'error' | 'loading' | 'noResult';
63
+
64
+ export const translatedMessages = (
65
+ type: TableMessagesType,
66
+ entityName?: {
67
+ en: { singular: string; plural: string };
68
+ fr?: { singular: string; plural: string };
69
+ },
70
+ locale?: TableLocalType,
71
+ ) => {
72
+ if (type === 'error') {
73
+ if (locale === 'fr') {
74
+ return `Erreur lors du chargement des ${
75
+ entityName?.fr?.plural || 'données'
76
+ }, veuillez rafraîchir la page.`;
77
+ }
78
+ return `An error occurred while loading ${
79
+ entityName ? `the ${entityName.en.plural}` : 'data'
80
+ }, please refresh the
81
+ page.`;
82
+ }
83
+ if (type === 'loading') {
84
+ if (locale === 'fr') {
85
+ return `Chargement des ${entityName?.fr?.plural || 'données'}...`;
86
+ }
87
+ return `Loading ${entityName?.en.plural || 'data'}...`;
88
+ }
89
+ if (type === 'noResult') {
90
+ if (locale === 'fr') {
91
+ return `Aucun ${entityName?.fr?.singular || 'résultat'} trouvé`;
92
+ }
93
+ return `No ${entityName?.en.plural || 'results'} found`;
94
+ }
95
+
96
+ return '';
97
+ };
@@ -1,6 +1,4 @@
1
1
  import styled, { css } from 'styled-components';
2
-
3
- import { spacing } from '../../style/theme';
4
2
  import {
5
3
  TableHeightKeyType,
6
4
  tableRowHeight,
@@ -9,6 +7,8 @@ import {
9
7
  import { HeaderGroup } from 'react-table';
10
8
  import { Icon } from '../icon/Icon.component';
11
9
  import { FocusVisibleStyle } from '../buttonv2/Buttonv2.component';
10
+ import { spacing } from '../../spacing';
11
+ import { Box } from '../box/Box';
12
12
 
13
13
  const borderSize = '4px';
14
14
  export const SortIncentive = styled.span`
@@ -16,7 +16,7 @@ export const SortIncentive = styled.span`
16
16
  display: none;
17
17
  `;
18
18
  export const SortCaretWrapper = styled.span`
19
- padding-left: ${spacing.sp4};
19
+ padding-left: ${spacing.r4};
20
20
  position: absolute;
21
21
  `;
22
22
  export const TableHeader = styled.div<{
@@ -45,11 +45,14 @@ type HeadRowType = {
45
45
  hasScrollBar: boolean;
46
46
  scrollBarWidth: number;
47
47
  rowHeight: TableHeightKeyType;
48
+ separationLineVariant: TableVariantType;
48
49
  };
49
50
 
50
51
  export const HeadRow = styled.div<HeadRowType>`
52
+ box-sizing: border-box;
51
53
  display: flex;
52
54
  align-items: center;
55
+ gap: ${spacing.r16};
53
56
  height: 2.286rem;
54
57
  width: ${(props) =>
55
58
  props.hasScrollBar
@@ -60,23 +63,26 @@ export const HeadRow = styled.div<HeadRowType>`
60
63
  color: ${(props) => props.theme.textPrimary};
61
64
  font-weight: bold;
62
65
  overflow: hidden;
66
+ border-bottom: 1px solid
67
+ ${(props) => props.theme[props.separationLineVariant]};
68
+ padding-right: ${borderSize};
69
+ padding-left: ${spacing.r16};
63
70
  `;
64
71
 
65
72
  type TableRowType = {
66
73
  isSelected: boolean;
67
74
  selectedId?: string;
68
75
  separationLineVariant: TableVariantType;
69
- backgroundVariant: TableVariantType;
70
76
  };
71
77
  export const TableRow = styled.div<TableRowType>`
72
78
  color: ${(props) => props.theme.textPrimary};
73
- border-top: 1px solid ${(props) => props.theme[props.separationLineVariant]};
74
- :last-child {
75
- border-bottom: 1px solid
76
- ${(props) => props.theme[props.separationLineVariant]};
77
- }
79
+ gap: ${spacing.r16};
80
+ border-bottom: 1px solid
81
+ ${(props) => props.theme[props.separationLineVariant]};
78
82
  cursor: default;
79
83
  box-sizing: border-box;
84
+ padding-left: ${spacing.r16};
85
+ padding-right: ${borderSize};
80
86
 
81
87
  // single selectable case
82
88
  ${(props) => {
@@ -101,11 +107,6 @@ export const TableRow = styled.div<TableRowType>`
101
107
  background-color: ${props.theme.highlight};
102
108
  border-right: ${borderSize} solid ${props.theme.selectedActive};
103
109
  `;
104
- } else {
105
- const color = props.theme[props.backgroundVariant];
106
- return css`
107
- border-right: ${borderSize} solid ${color};
108
- `;
109
110
  }
110
111
  }}
111
112
  `;
@@ -113,41 +114,32 @@ export const TableRow = styled.div<TableRowType>`
113
114
  type TableRowMultiSelectableType = {
114
115
  isSelected: boolean;
115
116
  separationLineVariant: TableVariantType;
116
- backgroundVariant: TableVariantType;
117
117
  };
118
118
  export const TableRowMultiSelectable = styled.div<TableRowMultiSelectableType>`
119
119
  color: ${(props) => props.theme.textPrimary};
120
- border-top: 1px solid ${(props) => props.theme[props.separationLineVariant]};
121
- :last-child {
122
- border-bottom: 1px solid
123
- ${(props) => props.theme[props.separationLineVariant]};
124
- }
125
-
120
+ border-bottom: 1px solid
121
+ ${(props) => props.theme[props.separationLineVariant]};
126
122
  box-sizing: border-box;
127
-
128
- &:hover,
129
- &:focus {
130
- background-color: ${(props) => props.theme.highlight};
131
- outline: none;
132
- cursor: pointer;
133
- }
134
-
135
123
  ${(props) => {
136
124
  if (props.isSelected) {
137
125
  return css`
138
126
  background-color: ${(props) => props.theme.highlight};
139
127
  border-right: ${borderSize} solid ${props.theme.selectedActive};
140
128
  `;
141
- } else {
142
- const color = props.theme[props.backgroundVariant];
143
- return css`
144
- border-right: ${borderSize} solid ${color};
145
- `;
146
129
  }
147
130
  }}
131
+ padding-right: ${borderSize};
132
+ padding-left: ${spacing.r16};
133
+ &:hover,
134
+ &:focus {
135
+ background-color: ${(props) => props.theme.highlight};
136
+ outline: none;
137
+ cursor: pointer;
138
+ }
148
139
  `;
149
140
 
150
141
  export const TableBody = styled.div`
142
+ box-sizing: border-box;
151
143
  display: block;
152
144
  flex-grow: 1;
153
145
  height: 100%;
@@ -164,12 +156,13 @@ export const TooltipContent = styled.div`
164
156
  min-width: 60px;
165
157
  `;
166
158
 
167
- export const NoResult = styled.div`
159
+ export const NoResult = styled(Box)<{ rowHeight: TableHeightKeyType }>`
168
160
  display: flex;
169
161
  justify-content: center;
162
+ align-items: center;
170
163
  color: ${(props) => props.theme.textSecondary};
171
- padding-top: ${spacing.sp8};
172
- border-top: 1px solid ${(props) => props.theme.backgroundLevel3};
164
+ height: ${(props) => tableRowHeight[props.rowHeight]}rem;
165
+ gap: ${spacing.r8};
173
166
  `;
174
167
 
175
168
  export const SortCaret = <
@@ -67,6 +67,11 @@ export type TableProps<
67
67
  onBottom?: (rowLength: number) => void;
68
68
  onBottomOffset?: number;
69
69
  allFilters?: { id: string; value: string }[];
70
+ status?: 'idle' | 'loading' | 'error' | 'success';
71
+ entityName?: {
72
+ en: { singular: string; plural: string };
73
+ fr?: { singular: string; plural: string };
74
+ };
70
75
  initiallySelectedRowsIds?: Set<string | number>;
71
76
  //To call it from the Cell renderer to update the original data
72
77
  } & UpdateTableData<DATA_ROW>;
@@ -95,6 +100,11 @@ type TableContextType<
95
100
  setHiddenColumns: (param: string[] | setHiddenColumnFuncType) => void;
96
101
  isAllRowsSelected?: boolean;
97
102
  toggleAllRowsSelected: (value?: boolean) => void;
103
+ status?: 'idle' | 'loading' | 'error' | 'success';
104
+ entityName?: {
105
+ en: { singular: string; plural: string };
106
+ fr?: { singular: string; plural: string };
107
+ };
98
108
  };
99
109
  const TableContext = React.createContext<TableContextType | null>(null);
100
110
 
@@ -168,6 +178,8 @@ function Table<
168
178
  onBottomOffset = 10,
169
179
  initiallySelectedRowsIds,
170
180
  updateTableData,
181
+ status,
182
+ entityName,
171
183
  }: TableProps<DATA_ROW>) {
172
184
  sortTypes = {
173
185
  health: (row1, row2) => {
@@ -296,6 +308,8 @@ function Table<
296
308
  setHiddenColumns,
297
309
  isAllRowsSelected,
298
310
  toggleAllRowsSelected,
311
+ status,
312
+ entityName,
299
313
  };
300
314
  return (
301
315
  <TableContext.Provider
@@ -72,7 +72,6 @@ describe('TableV2', () => {
72
72
  <Table.SingleSelectableContent
73
73
  rowHeight="h40"
74
74
  separationLineVariant="backgroundLevel3"
75
- backgroundVariant="backgroundLevel1"
76
75
  />
77
76
  </Table>
78
77
  </div>
@@ -92,7 +91,6 @@ describe('TableV2', () => {
92
91
  <Table.SingleSelectableContent
93
92
  rowHeight="h40"
94
93
  separationLineVariant="backgroundLevel3"
95
- backgroundVariant="backgroundLevel1"
96
94
  />
97
95
  </Table>
98
96
  </div>
@@ -117,7 +115,6 @@ describe('TableV2', () => {
117
115
  <Table.SingleSelectableContent
118
116
  rowHeight="h40"
119
117
  separationLineVariant="backgroundLevel3"
120
- backgroundVariant="backgroundLevel1"
121
118
  />
122
119
  </Table>
123
120
  </div>
@@ -1,9 +1,11 @@
1
1
  import styled from 'styled-components';
2
- import { spacing } from '../../style/theme';
2
+
3
3
  import { getThemePropSelector } from '../../utils';
4
+ import { spacing } from '../../spacing';
5
+
4
6
  export const TabBar = styled.div`
5
7
  display: flex;
6
- height: ${spacing.sp40};
8
+ height: ${spacing.r40};
7
9
  `;
8
10
  export const TabItem = styled.div<{
9
11
  selected?: boolean;
@@ -14,15 +16,15 @@ export const TabItem = styled.div<{
14
16
  }>`
15
17
  display: flex;
16
18
  align-items: center;
17
- padding: 0 ${spacing.sp24} 0 ${spacing.sp24};
18
- border-radius: ${spacing.sp4} ${spacing.sp4} 0 0;
19
- border: ${spacing.sp1} solid transparent;
19
+ padding: 0 ${spacing.r24} 0 ${spacing.r24};
20
+ border-radius: ${spacing.r4} ${spacing.r4} 0 0;
21
+ border: ${spacing.r1} solid transparent;
20
22
  min-width: 5rem;
21
23
 
22
24
  &:focus-visible {
23
25
  outline: 0;
24
26
  position: relative;
25
- border: ${spacing.sp1} dashed ${getThemePropSelector('selectedActive')};
27
+ border: ${spacing.r1} dashed ${getThemePropSelector('selectedActive')};
26
28
  }
27
29
 
28
30
  &:focus-within {
@@ -39,19 +41,19 @@ export const TabItem = styled.div<{
39
41
  content: "";
40
42
  background: ${props.activeTabSeparator || selectedActive};
41
43
  position: absolute;
42
- border-radius: ${spacing.sp2} ${spacing.sp2} 0 0;
44
+ border-radius: ${spacing.r2} ${spacing.r2} 0 0;
43
45
  bottom: 0;
44
46
  right: 0;
45
- left: calc(50% - ${spacing.sp16});
46
- height: ${spacing.sp2};
47
- width: ${spacing.sp32};
47
+ left: calc(50% - ${spacing.r16});
48
+ height: ${spacing.r2};
49
+ width: ${spacing.r32};
48
50
  }
49
51
  `
50
52
  : `
51
53
  background-color: ${props.inactiveTabColor || backgroundLevel3};
52
54
  &:hover {
53
55
  cursor: pointer;
54
- border: ${spacing.sp1} solid ${props.tabHoverColor || highlight};
56
+ border: ${spacing.r1} solid ${props.tabHoverColor || highlight};
55
57
  }
56
58
  `;
57
59
  }}
@@ -73,16 +75,16 @@ export const TabsContainer = styled.div<{
73
75
  }
74
76
 
75
77
  & ${TabItem}::before {
76
- content: "";
78
+ content: '';
77
79
  background: ${(props) => props.separatorColor || props.theme.infoSecondary};
78
80
  position: absolute;
79
81
  bottom: 25%;
80
82
  right: 0;
81
- height: ${spacing.sp16};
83
+ height: ${spacing.r16};
82
84
  width: 1px;
83
85
  margin-right: -1px;
84
86
  }
85
- }`;
87
+ `;
86
88
  export const TabContent = styled.div<{ tabContentColor?: string }>`
87
89
  margin: 0;
88
90
  padding: 0;
@@ -165,6 +165,7 @@ function Toast({
165
165
  icon={<Icon name="Close" size="lg" color="textSecondary" />}
166
166
  onClick={params?.onClose}
167
167
  aria-label="Close"
168
+ tooltip={{ overlay: 'Close', placement: 'top' }}
168
169
  />
169
170
  </Box>
170
171
  </motion.div>
@@ -86,7 +86,7 @@ type Props<MainMutationType, T extends any[]> = {
86
86
  | { onAllMutationsSuccess?: () => void; onMainMutationSuccess?: never }
87
87
  );
88
88
 
89
- type MinimalMutationResult<TData, TError> = Pick<
89
+ export type MinimalMutationResult<TData, TError> = Pick<
90
90
  UseMutationResult<TData, TError, unknown, unknown>,
91
91
  'isError' | 'isIdle' | 'isSuccess' | 'isLoading' | 'error' | 'data'
92
92
  >;
@@ -122,7 +122,9 @@ export const useMutationsHandler = <
122
122
 
123
123
  const mainMutationDesc: GetDescriptionBuilder<MainMutationType> = {
124
124
  data: mainMutation.mutation?.data,
125
- status: DescriptionBuilderStatus.Success,
125
+ status: mainMutation.mutation?.isSuccess
126
+ ? DescriptionBuilderStatus.Success
127
+ : DescriptionBuilderStatus.Error,
126
128
  name: mainMutation.name,
127
129
  } as GetDescriptionBuilder<MainMutationType>;
128
130
  const descriptionBuilders = [
@@ -83,7 +83,7 @@ function VegaChartInternal(
83
83
  domainColor: 'transparent',
84
84
  },
85
85
  title: {
86
- color: currentTheme.buttonDelete,
86
+ color: currentTheme.textPrimary,
87
87
  font: 'Lato',
88
88
  },
89
89
  view: {
@@ -259,7 +259,6 @@ export function AttachmentConfirmationModal<ENTITY_TYPE, RESOURCE_TYPE>({
259
259
  <Table.SingleSelectableContent
260
260
  rowHeight="h32"
261
261
  separationLineVariant="backgroundLevel3"
262
- backgroundVariant="backgroundLevel1"
263
262
  children={(Rows) => {
264
263
  return <>{Rows}</>;
265
264
  }}
@@ -32,6 +32,7 @@ import {
32
32
  } from './AttachmentTypes';
33
33
  import { useQuery, UseQueryOptions } from 'react-query';
34
34
  import { EmptyCell } from '../../components/tablev2/Tablev2.component';
35
+ import { tableRowHeight } from '../../components/tablev2/TableUtils';
35
36
 
36
37
  type AttachableEntityWithPendingStatus<ENTITY_TYPE> = {
37
38
  isPending?: boolean;
@@ -104,11 +105,7 @@ const MenuContainer = styled.ul<{
104
105
  `;
105
106
 
106
107
  const SearchBoxContainer = styled.div`
107
- margin-bottom: ${spacing.r24};
108
- width: 78%;
109
- .sc-tooltip {
110
- width: 100%;
111
- }
108
+ padding: ${spacing.r16};
112
109
  `;
113
110
 
114
111
  const StyledSearchInput = styled(SearchInput)`
@@ -134,6 +131,7 @@ const StyledTable = styled.div`
134
131
  const CenterredSecondaryText = styled(SecondaryText)`
135
132
  display: block;
136
133
  text-align: center;
134
+ line-height: ${tableRowHeight[rowHeight]}rem;
137
135
  `;
138
136
 
139
137
  const PrivateAttachmentContext = createContext<{
@@ -477,8 +475,12 @@ export const AttachmentTable = <ENTITY_TYPE,>({
477
475
  <SearchBoxContainer
478
476
  {...{
479
477
  ref: (element) => {
480
- if (element) {
481
- setSearchWidth(element.getBoundingClientRect().width - 2 + 'px');
478
+ if (element?.firstElementChild) {
479
+ setSearchWidth(
480
+ element.firstElementChild.getBoundingClientRect().width -
481
+ 2 +
482
+ 'px',
483
+ );
482
484
  }
483
485
  },
484
486
  }}
@@ -489,7 +491,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
489
491
  <>We failed to load the entities, hence search is disabled</>
490
492
  }
491
493
  >
492
- <Box display="flex" alignItems="center" width="100%" gap={8}>
494
+ <Stack>
493
495
  <StyledSearchInput
494
496
  placeholder={searchEntityPlaceholder}
495
497
  {...getInputProps({
@@ -508,7 +510,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
508
510
  disabled={filteredEntities.status === 'error'}
509
511
  />
510
512
  <Loader />
511
- </Box>
513
+ </Stack>
512
514
  </Tooltip>
513
515
  ) : (
514
516
  <StyledSearchInput
@@ -595,7 +597,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
595
597
  <Table
596
598
  columns={[
597
599
  {
598
- Header: <Box flex={1.5}>Name</Box>,
600
+ Header: 'Name',
599
601
  accessor: 'name',
600
602
  cellStyle: {
601
603
  flex: 1.5,
@@ -639,7 +641,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
639
641
  },
640
642
  },
641
643
  {
642
- Header: <Box flex={0.5}>Attachment status</Box>,
644
+ Header: 'Attachment',
643
645
  accessor: 'isPending',
644
646
  cellStyle: {
645
647
  flex: 0.5,
@@ -690,7 +692,6 @@ export const AttachmentTable = <ENTITY_TYPE,>({
690
692
  defaultSortingKey="name"
691
693
  >
692
694
  <Table.SingleSelectableContent
693
- backgroundVariant="backgroundLevel4"
694
695
  rowHeight={rowHeight}
695
696
  separationLineVariant="backgroundLevel2"
696
697
  >
@@ -698,7 +699,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
698
699
  <>
699
700
  {initiallyAttachedEntitiesStatus === 'idle' ||
700
701
  initiallyAttachedEntitiesStatus === 'loading' ? (
701
- <Wrap>
702
+ <Wrap style={{ height: `${tableRowHeight[rowHeight]}rem` }}>
702
703
  <p></p>
703
704
  <Stack>
704
705
  <Loader />
@@ -707,9 +708,17 @@ export const AttachmentTable = <ENTITY_TYPE,>({
707
708
  <p></p>
708
709
  </Wrap>
709
710
  ) : initiallyAttachedEntitiesStatus === 'error' ? (
710
- <CenterredSecondaryText>
711
- Failed to load {entityName.plural}
712
- </CenterredSecondaryText>
711
+ <Stack
712
+ style={{
713
+ justifyContent: 'center',
714
+ height: `${tableRowHeight[rowHeight]}rem`,
715
+ }}
716
+ >
717
+ <Icon name="Exclamation-circle" color="statusWarning" />
718
+ <Text color="textSecondary">
719
+ Failed to load attached {entityName.plural}.
720
+ </Text>
721
+ </Stack>
713
722
  ) : (
714
723
  desiredAttachedEntities.length === 0 && (
715
724
  <CenterredSecondaryText>
@@ -0,0 +1,55 @@
1
+ import {
2
+ Meta,
3
+ Story,
4
+ Canvas,
5
+ Primary,
6
+ Controls,
7
+ Unstyled,
8
+ Source,
9
+ } from '@storybook/blocks';
10
+ import { Checkbox } from '../../src/lib/components/checkbox/Checkbox.component';
11
+
12
+ import * as CheckboxStories from './checkbox.stories';
13
+
14
+ <Meta of={CheckboxStories} name="Guideline" />
15
+
16
+ # Checkbox
17
+
18
+ Checkboxes are used to select one or more options in a list.
19
+
20
+ ## Usage
21
+
22
+ Unlike the radio element it is possible to select more than one option. \
23
+ A tick/check indicates that the element is selected. \
24
+
25
+ <Canvas of={CheckboxStories.ChoiceCheckbox} layout="fullscreen" />
26
+
27
+ It is possible to use the checkbox to enable or disable an option:
28
+
29
+ <Canvas of={CheckboxStories.OptionCheckbox} layout="fullscreen" />
30
+
31
+ ## State Variations
32
+
33
+ ### Indeterminate State
34
+
35
+ Apart from checked and unchecked, checkboxes can be in a third state : indeterminate. \
36
+ When a checkbox has sub-options checkboxes, this state indicates that some of the sub-options are checked. \
37
+ Clicking on the main checkbox select or unselect all the sub-options boxes.
38
+
39
+ <Canvas of={CheckboxStories.IndeterminateUseCase} layout="fullscreen" />
40
+
41
+ ### Disabled state
42
+
43
+ Checkboxes can be disabled, making it impossible to change the box state. \
44
+ A not-allowed cursor inform the user about the unavaibility of the action.
45
+
46
+ <Canvas
47
+ of={CheckboxStories.DisabledCheckboxes}
48
+
49
+ layout="fullscreen"
50
+ />
51
+
52
+ ### Playground
53
+
54
+ <Canvas of={CheckboxStories.Playground} layout="fullscreen" />
55
+ <Controls of={CheckboxStories.Playground} />