@scality/core-ui 0.134.0 → 0.136.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 (53) hide show
  1. package/dist/components/constrainedtext/Constrainedtext.component.d.ts.map +1 -1
  2. package/dist/components/constrainedtext/Constrainedtext.component.js +4 -1
  3. package/dist/components/icon/Icon.component.d.ts.map +1 -1
  4. package/dist/components/icon/Icon.component.js +9 -3
  5. package/dist/components/searchinput/SearchInput.component.d.ts +0 -1
  6. package/dist/components/searchinput/SearchInput.component.d.ts.map +1 -1
  7. package/dist/components/searchinput/SearchInput.component.js +1 -1
  8. package/dist/components/selectv2/Selectv2.component.d.ts +1 -1
  9. package/dist/components/selectv2/Selectv2.component.d.ts.map +1 -1
  10. package/dist/components/selectv2/Selectv2.component.js +5 -9
  11. package/dist/components/tablev2/Search.d.ts +1 -1
  12. package/dist/components/tablev2/Search.d.ts.map +1 -1
  13. package/dist/components/tablev2/Search.js +1 -1
  14. package/dist/components/tablev2/TableCommon.d.ts +1 -1
  15. package/dist/components/tablev2/TableCommon.js +3 -3
  16. package/dist/components/tablev2/Tablestyle.d.ts +1 -1
  17. package/dist/components/tablev2/Tablestyle.d.ts.map +1 -1
  18. package/dist/components/tablev2/Tablev2.component.d.ts +5 -1
  19. package/dist/components/tablev2/Tablev2.component.d.ts.map +1 -1
  20. package/dist/components/tablev2/Tablev2.component.js +6 -0
  21. package/dist/components/tablev2/useSyncedScroll.d.ts +2 -1
  22. package/dist/components/tablev2/useSyncedScroll.d.ts.map +1 -1
  23. package/dist/components/tablev2/useSyncedScroll.js +17 -19
  24. package/dist/components/tabsv2/StyledTabs.d.ts +1 -1
  25. package/dist/components/tabsv2/StyledTabs.d.ts.map +1 -1
  26. package/dist/components/tabsv2/Tabsv2.component.js +5 -1
  27. package/dist/components/toggle/Toggle.component.d.ts +1 -1
  28. package/dist/components/toggle/Toggle.component.d.ts.map +1 -1
  29. package/dist/components/toggle/Toggle.component.js +8 -11
  30. package/dist/organisms/attachments/AttachmentTable.d.ts.map +1 -1
  31. package/dist/organisms/attachments/AttachmentTable.js +2 -2
  32. package/package.json +2 -2
  33. package/src/lib/components/constrainedtext/Constrainedtext.component.tsx +4 -1
  34. package/src/lib/components/icon/Icon.component.tsx +12 -5
  35. package/src/lib/components/searchinput/SearchInput.component.tsx +0 -2
  36. package/src/lib/components/searchinput/SearchInput.test.tsx +88 -0
  37. package/src/lib/components/selectv2/Selectv2.component.tsx +7 -11
  38. package/src/lib/components/selectv2/selectv2.test.tsx +190 -200
  39. package/src/lib/components/tablev2/Search.tsx +1 -2
  40. package/src/lib/components/tablev2/TableCommon.tsx +5 -5
  41. package/src/lib/components/tablev2/Tablestyle.tsx +1 -1
  42. package/src/lib/components/tablev2/Tablev2.component.tsx +14 -0
  43. package/src/lib/components/tablev2/useSyncedScroll.ts +22 -24
  44. package/src/lib/components/tabsv2/StyledTabs.ts +1 -1
  45. package/src/lib/components/tabsv2/Tabsv2.component.tsx +1 -1
  46. package/src/lib/components/toggle/Toggle.component.tsx +9 -12
  47. package/src/lib/components/toggle/Toggle.test.tsx +56 -0
  48. package/src/lib/organisms/attachments/AttachmentTable.tsx +0 -2
  49. package/stories/SearchInput/searchinput.guideline.mdx +20 -0
  50. package/stories/{searchinput.stories.tsx → SearchInput/searchinput.stories.tsx} +13 -20
  51. package/stories/Select/selectv2.stories.tsx +23 -5
  52. package/stories/Toggle/toggle.guideline.mdx +20 -0
  53. package/stories/{toggle.stories.tsx → Toggle/toggle.stories.tsx} +17 -10
@@ -5,7 +5,7 @@ import React, {
5
5
  useEffect,
6
6
  useState,
7
7
  } from 'react';
8
- import styled, { css } from 'styled-components';
8
+ import styled, { css, useTheme } from 'styled-components';
9
9
  import { CoreUITheme } from '../../style/theme';
10
10
 
11
11
  import { Loader } from '../loader/Loader.component';
@@ -137,6 +137,13 @@ export const iconTable = {
137
137
  News: 'fas faBullhorn',
138
138
  };
139
139
 
140
+ const getColor = (color: string | undefined): string => {
141
+ const theme = useTheme();
142
+ if (!color) return 'currentColor';
143
+
144
+ return theme[color] || color;
145
+ };
146
+
140
147
  export const customIcons = {
141
148
  'Remote-user': ({ ariaLabel, color, size }) => (
142
149
  <svg
@@ -148,11 +155,11 @@ export const customIcons = {
148
155
  >
149
156
  <path
150
157
  d="M16.5902 0.5C17.4071 0.5 18.0984 1.1875 18.0984 2V12C18.0984 12.8438 17.4071 13.5 16.5902 13.5H10.5574L11.0601 15H13.3224C13.7309 15 14.0765 15.3438 14.0765 15.75C14.0765 16.1875 13.7309 16.5 13.3224 16.5H4.77596C4.33607 16.5 4.02186 16.1875 4.02186 15.75C4.02186 15.3438 4.33607 15 4.77596 15H7.03825L7.54098 13.5H1.5082C0.659836 13.5 0 12.8438 0 12V2C0 1.1875 0.659836 0.5 1.5082 0.5H16.5902ZM16.0874 11.5V2.5H2.01093V11.5H16.0874Z"
151
- fill={color || 'currentcolor'}
158
+ fill={getColor(color)}
152
159
  />
153
160
  <path
154
161
  d="M9.18043 7.97631C8.0165 7.97631 7.08207 7.01268 7.08207 5.81237C7.08207 4.62897 8.0165 3.64844 9.18043 3.64844C10.328 3.64844 11.2788 4.62897 11.2788 5.81237C11.2788 7.01268 10.328 7.97631 9.18043 7.97631ZM10.6394 8.51729C11.8526 8.51729 12.8526 9.54854 12.8526 10.7996V11.4927C12.8526 11.9492 12.4919 12.3042 12.0657 12.3042H6.29519C5.85256 12.3042 5.5083 11.9492 5.5083 11.4927V10.7996C5.5083 9.54854 6.49191 8.51729 7.70502 8.51729H7.98371C8.34437 8.70325 8.7542 8.78778 9.18043 8.78778C9.60666 8.78778 10.0001 8.70325 10.3608 8.51729H10.6394Z"
155
- fill={color || 'currentcolor'}
162
+ fill={getColor(color)}
156
163
  />
157
164
  </svg>
158
165
  ),
@@ -166,11 +173,11 @@ export const customIcons = {
166
173
  >
167
174
  <path
168
175
  d="M16.5902 0.5C17.4071 0.5 18.0984 1.1875 18.0984 2V12C18.0984 12.8438 17.4071 13.5 16.5902 13.5H10.5574L11.0601 15H13.3224C13.7309 15 14.0765 15.3438 14.0765 15.75C14.0765 16.1875 13.7309 16.5 13.3224 16.5H4.77596C4.33607 16.5 4.02186 16.1875 4.02186 15.75C4.02186 15.3438 4.33607 15 4.77596 15H7.03825L7.54098 13.5H1.5082C0.659836 13.5 0 12.8438 0 12V2C0 1.1875 0.659836 0.5 1.5082 0.5H16.5902ZM16.0874 11.5V2.5H2.01093V11.5H16.0874Z"
169
- fill={color || 'currentcolor'}
176
+ fill={getColor(color)}
170
177
  />
171
178
  <path
172
179
  d="M4.8 7.85714C4.125 7.85714 3.6 7.29464 3.6 6.57143C3.6 5.8683 4.125 5.28571 4.8 5.28571C5.45625 5.28571 6 5.8683 6 6.57143C6 7.29464 5.45625 7.85714 4.8 7.85714ZM13.2 7.85714C12.525 7.85714 12 7.29464 12 6.57143C12 5.8683 12.525 5.28571 13.2 5.28571C13.8563 5.28571 14.4 5.8683 14.4 6.57143C14.4 7.29464 13.8563 7.85714 13.2 7.85714ZM13.8 8.5C14.4563 8.5 15 9.08259 15 9.78571V10.4286C15 10.7902 14.7188 11.0714 14.4 11.0714H13.1625C13.0313 10.1272 12.5063 9.32366 11.7375 8.8817C11.9625 8.66071 12.2625 8.5 12.6 8.5H13.8ZM9 8.5C7.8375 8.5 6.9 7.49554 6.9 6.25C6.9 5.02455 7.8375 4 9 4C10.1438 4 11.1 5.02455 11.1 6.25C11.1 7.49554 10.1438 8.5 9 8.5ZM10.425 9.14286C11.625 9.14286 12.6 10.1875 12.6 11.4732V12.0357C12.6 12.5781 12.1875 13 11.7 13H6.3C5.79375 13 5.4 12.5781 5.4 12.0357V11.4732C5.4 10.1875 6.35625 9.14286 7.55625 9.14286H7.70625C8.1 9.34375 8.53125 9.46429 9 9.46429C9.45 9.46429 9.88125 9.34375 10.275 9.14286H10.425ZM6.24375 8.8817C5.475 9.32366 4.95 10.1272 4.81875 11.0714H3.6C3.2625 11.0714 3 10.7902 3 10.4286V9.78571C3 9.08259 3.525 8.5 4.2 8.5H5.4C5.71875 8.5 6.01875 8.66071 6.24375 8.8817Z"
173
- fill={color || 'currentcolor'}
180
+ fill={getColor(color)}
174
181
  />
175
182
  </svg>
176
183
  ),
@@ -10,7 +10,6 @@ export type Props = {
10
10
  value: string;
11
11
  onChange: (e: ChangeEvent<HTMLInputElement>) => void;
12
12
  onReset?: () => void;
13
- disableToggle: boolean;
14
13
  disabled?: boolean;
15
14
  id?: string;
16
15
  size?: InputSize;
@@ -57,7 +56,6 @@ const ClearButton = styled.div`
57
56
  const SearchInput = forwardRef(
58
57
  (
59
58
  {
60
- disableToggle,
61
59
  placeholder,
62
60
  value,
63
61
  onChange,
@@ -0,0 +1,88 @@
1
+ import React from 'react';
2
+ import { render, screen, waitFor } from '@testing-library/react';
3
+ import { SearchInput, Props } from './SearchInput.component';
4
+ import { QueryClient, QueryClientProvider } from 'react-query';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ const queryClient = new QueryClient();
8
+
9
+ const SearchInputRender = (props: Props) => {
10
+ return (
11
+ <QueryClientProvider client={queryClient}>
12
+ <SearchInput {...props} />
13
+ </QueryClientProvider>
14
+ );
15
+ };
16
+
17
+ describe('SearchInput', () => {
18
+ const selectors = {
19
+ searchInput: () => screen.getByRole('searchbox'),
20
+ clearButton: () => screen.queryByRole('button'),
21
+ };
22
+ it('should render the SearchInput component', () => {
23
+ render(<SearchInputRender value="" onChange={() => {}} />);
24
+
25
+ const searchInput = selectors.searchInput();
26
+ expect(searchInput).toBeInTheDocument();
27
+ });
28
+
29
+ it('should render the SearchInput component with placeholder', () => {
30
+ render(
31
+ <SearchInputRender value="" onChange={() => {}} placeholder="Search" />,
32
+ );
33
+
34
+ const searchInput = screen.queryByPlaceholderText('Example: Search');
35
+ expect(searchInput).toBeInTheDocument();
36
+ });
37
+
38
+ it('should render the SearchInput component with disabled prop', () => {
39
+ render(<SearchInputRender value="" onChange={() => {}} disabled />);
40
+
41
+ const searchInput = selectors.searchInput();
42
+ expect(searchInput).toBeInTheDocument();
43
+ expect(searchInput).toBeDisabled();
44
+ });
45
+
46
+ it('should change value instantly but call the onChange function with a 300ms delay after the end of typing', async () => {
47
+ const onChange = jest.fn();
48
+ render(<SearchInputRender value="" onChange={onChange} />);
49
+ const searchInput = selectors.searchInput();
50
+ userEvent.type(searchInput, 'test');
51
+ expect(searchInput).toHaveValue('test');
52
+ expect(onChange).not.toHaveBeenCalled();
53
+ await waitFor(
54
+ () => {
55
+ expect(onChange).toHaveBeenCalled();
56
+ },
57
+ { timeout: 350 },
58
+ );
59
+ });
60
+
61
+ it('should have a clear button when the input is not empty', () => {
62
+ render(<SearchInputRender value="" onChange={() => {}} />);
63
+
64
+ // clear button should not be rendered as value is empty
65
+ let clearButton = selectors.clearButton();
66
+ expect(clearButton).not.toBeInTheDocument();
67
+
68
+ const searchInput = selectors.searchInput();
69
+ userEvent.type(searchInput, 'test');
70
+
71
+ // clear button should now be rendered
72
+ clearButton = selectors.clearButton();
73
+ expect(clearButton).toBeInTheDocument();
74
+ });
75
+
76
+ it('should call the onReset function when the clear button is clicked and clear the input value', async () => {
77
+ const onReset = jest.fn();
78
+ render(
79
+ <SearchInputRender value="test" onChange={() => {}} onReset={onReset} />,
80
+ );
81
+ const searchInput = selectors.searchInput();
82
+ const clearButton = selectors.clearButton();
83
+ expect(clearButton).toBeInTheDocument();
84
+ clearButton && userEvent.click(clearButton);
85
+ expect(onReset).toHaveBeenCalled();
86
+ expect(searchInput).toHaveValue('');
87
+ });
88
+ });
@@ -135,7 +135,11 @@ const InternalOption = (width, isDefaultVariant) => (props) => {
135
135
  ? 'sc-highlighted-matching-text'
136
136
  : '';
137
137
  return (
138
- <span key={i} className={highlightStyle}>
138
+ <span
139
+ role={highlightStyle ? 'mark' : undefined}
140
+ key={i}
141
+ className={highlightStyle}
142
+ >
139
143
  {part}
140
144
  </span>
141
145
  );
@@ -238,7 +242,6 @@ const MenuList = (props) => {
238
242
  selectedIndex * optionHeight - (ITEMS_PER_SCROLL_WINDOW - 1) * optionHeight;
239
243
  useEffect(() => {
240
244
  if (listRef && listRef.current) {
241
- // @ts-ignore
242
245
  listRef.current.scrollTo(
243
246
  getScrollOffset(
244
247
  listRef.current,
@@ -282,6 +285,7 @@ const ValueContainer = ({ children, ...props }) => {
282
285
  const icon = selectedOption ? selectedOption.icon : null;
283
286
  const ariaProps = {
284
287
  innerProps: {
288
+ disabled: true,
285
289
  role: props.selectProps.isSearchable ? 'combobox' : 'listbox',
286
290
  'aria-expanded': props.selectProps.menuIsOpen,
287
291
  'aria-autocomplete': 'list',
@@ -302,7 +306,6 @@ export type SelectProps = {
302
306
  placeholder?: string;
303
307
  disabled?: boolean;
304
308
  children?: React.ReactNode;
305
- defaultValue?: string;
306
309
  value?: string;
307
310
  onFocus?: (event: FocusEvent) => void;
308
311
  onBlur?: (event: FocusEvent) => void;
@@ -310,6 +313,7 @@ export type SelectProps = {
310
313
  variant?: 'default' | 'rounded';
311
314
  size?: '1' | '2/3' | '1/2' | '1/3';
312
315
  className?: string;
316
+ /** use menuPositon='fixed' inside modal to avoid display issue */
313
317
  menuPosition?: 'fixed' | 'absolute';
314
318
  };
315
319
  type SelectOptionProps = {
@@ -357,7 +361,6 @@ function SelectWithOptionContext(props: SelectProps) {
357
361
  function SelectBox({
358
362
  placeholder = 'Select...',
359
363
  disabled = false,
360
- defaultValue,
361
364
  value,
362
365
  onChange,
363
366
  variant = 'default',
@@ -366,11 +369,6 @@ function SelectBox({
366
369
  id,
367
370
  ...rest
368
371
  }: SelectProps) {
369
- if (defaultValue && value) {
370
- console.error(
371
- 'The `defaultValue` will be overridden by the `value` if they are set at the same time.',
372
- );
373
- }
374
372
  const [keyboardFocusEnabled, setKeyboardFocusEnabled] = useState(false);
375
373
  const [searchSelection, setSearchSelection] = useState('');
376
374
  const [searchValue, setSearchValue] = useState('');
@@ -414,7 +412,6 @@ function SelectBox({
414
412
  // Force to reset the value
415
413
  useEffect(() => {
416
414
  if (
417
- !defaultValue &&
418
415
  !isEmptyStringInOptions &&
419
416
  value === '' &&
420
417
  selectRef.current &&
@@ -436,7 +433,6 @@ function SelectBox({
436
433
  value={
437
434
  searchSelection || options.find((opt) => opt.value === value)
438
435
  }
439
- defaultValue={defaultValue}
440
436
  inputValue={options.length > NOPT_SEARCH ? searchValue : undefined}
441
437
  selectedOption={options.find((opt) => opt.value === value)}
442
438
  keyboardFocusEnabled={keyboardFocusEnabled}