@axinom/mosaic-ui 0.66.0-rc.2 → 0.66.0-rc.21

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 (122) hide show
  1. package/dist/components/DynamicDataList/DynamicListHeader/DynamicListHeader.d.ts.map +1 -1
  2. package/dist/components/Explorer/BulkEdit/FormFieldsConfigConverter.d.ts.map +1 -1
  3. package/dist/components/FieldSelection/FieldSelection.d.ts.map +1 -1
  4. package/dist/components/Filters/Filter/Filter.d.ts.map +1 -1
  5. package/dist/components/Filters/Filters.model.d.ts +5 -0
  6. package/dist/components/Filters/Filters.model.d.ts.map +1 -1
  7. package/dist/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.d.ts +2 -0
  8. package/dist/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.d.ts.map +1 -1
  9. package/dist/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.d.ts +2 -0
  10. package/dist/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.d.ts.map +1 -1
  11. package/dist/components/Filters/SelectionTypes/MultiOptionFilter/MultiOptionFilter.d.ts +2 -0
  12. package/dist/components/Filters/SelectionTypes/MultiOptionFilter/MultiOptionFilter.d.ts.map +1 -1
  13. package/dist/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.d.ts +2 -0
  14. package/dist/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.d.ts.map +1 -1
  15. package/dist/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.d.ts +2 -0
  16. package/dist/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.d.ts.map +1 -1
  17. package/dist/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.d.ts +2 -0
  18. package/dist/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.d.ts.map +1 -1
  19. package/dist/components/FormElements/Radio/Radio.d.ts.map +1 -1
  20. package/dist/components/FormElements/ToggleButton/ToggleButton.d.ts.map +1 -1
  21. package/dist/components/Hub/Tile/Tile.d.ts.map +1 -1
  22. package/dist/components/Icons/Icons.d.ts +4 -9
  23. package/dist/components/Icons/Icons.d.ts.map +1 -1
  24. package/dist/components/LandingPageTiles/TileLarge/TileLarge.d.ts.map +1 -1
  25. package/dist/components/LandingPageTiles/TileSmall/TileSmall.d.ts.map +1 -1
  26. package/dist/components/List/ListCheckBox/ListCheckBox.d.ts.map +1 -1
  27. package/dist/components/List/ListHeader/ColumnLabel/ColumnLabel.d.ts.map +1 -1
  28. package/dist/components/List/ListHeader/ListHeader.d.ts.map +1 -1
  29. package/dist/components/List/ListRow/ListRow.d.ts.map +1 -1
  30. package/dist/components/List/ListRow/ListRowCell/ListRowCell.d.ts +15 -0
  31. package/dist/components/List/ListRow/ListRowCell/ListRowCell.d.ts.map +1 -0
  32. package/dist/components/List/ListRow/ListRowCell/renderData.d.ts +9 -0
  33. package/dist/components/List/ListRow/ListRowCell/renderData.d.ts.map +1 -0
  34. package/dist/components/List/ListRow/Renderers/TagsRenderer/TagsRenderer.d.ts.map +1 -1
  35. package/dist/components/Loaders/ImageLoader/ImageLoader.d.ts.map +1 -1
  36. package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts.map +1 -1
  37. package/dist/components/VisualElements/ImgElement.d.ts +50 -0
  38. package/dist/components/VisualElements/ImgElement.d.ts.map +1 -0
  39. package/dist/components/VisualElements/SvgElement.d.ts +14 -0
  40. package/dist/components/VisualElements/SvgElement.d.ts.map +1 -0
  41. package/dist/components/VisualElements/index.d.ts +3 -0
  42. package/dist/components/VisualElements/index.d.ts.map +1 -0
  43. package/dist/components/index.d.ts +1 -0
  44. package/dist/components/index.d.ts.map +1 -1
  45. package/dist/helpers/idleCallbackHelpers.d.ts +42 -0
  46. package/dist/helpers/idleCallbackHelpers.d.ts.map +1 -0
  47. package/dist/helpers/index.d.ts +1 -0
  48. package/dist/helpers/index.d.ts.map +1 -1
  49. package/dist/hooks/useResize/ResizeIndicator.d.ts +8 -0
  50. package/dist/hooks/useResize/ResizeIndicator.d.ts.map +1 -0
  51. package/dist/hooks/useResize/useResize.d.ts +5 -2
  52. package/dist/hooks/useResize/useResize.d.ts.map +1 -1
  53. package/dist/index.es.js +4 -4
  54. package/dist/index.es.js.map +1 -1
  55. package/dist/index.js +4 -4
  56. package/dist/index.js.map +1 -1
  57. package/package.json +2 -2
  58. package/src/components/DynamicDataList/DynamicListHeader/DynamicListHeader.spec.tsx +2 -0
  59. package/src/components/DynamicDataList/DynamicListHeader/DynamicListHeader.tsx +62 -50
  60. package/src/components/Explorer/BulkEdit/FormFieldsConfigConverter.tsx +5 -21
  61. package/src/components/Explorer/Explorer.stories.tsx +17 -0
  62. package/src/components/FieldSelection/FieldSelection.scss +4 -0
  63. package/src/components/FieldSelection/FieldSelection.tsx +1 -0
  64. package/src/components/Filters/Filter/Filter.scss +34 -15
  65. package/src/components/Filters/Filter/Filter.spec.tsx +1 -1
  66. package/src/components/Filters/Filter/Filter.tsx +46 -34
  67. package/src/components/Filters/Filters.model.ts +6 -0
  68. package/src/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.tsx +6 -1
  69. package/src/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.tsx +4 -0
  70. package/src/components/Filters/SelectionTypes/MultiOptionFilter/MultiOptionFilter.tsx +9 -1
  71. package/src/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.tsx +5 -0
  72. package/src/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.scss +6 -10
  73. package/src/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.tsx +8 -0
  74. package/src/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.tsx +6 -1
  75. package/src/components/FormElements/Radio/Radio.tsx +3 -2
  76. package/src/components/FormElements/Select/Select.scss +11 -6
  77. package/src/components/FormElements/ToggleButton/ToggleButton.tsx +32 -27
  78. package/src/components/Hub/Hub.stories.tsx +3 -2
  79. package/src/components/Hub/Tile/Tile.spec.tsx +7 -2
  80. package/src/components/Hub/Tile/Tile.tsx +2 -1
  81. package/src/components/Icons/Icons.scss +1 -0
  82. package/src/components/Icons/Icons.spec.tsx +90 -41
  83. package/src/components/Icons/Icons.tsx +357 -765
  84. package/src/components/InfoTooltip/InfoTooltip.scss +1 -1
  85. package/src/components/InlineMenu/InlineMenu.scss +1 -1
  86. package/src/components/LandingPageTiles/LandingPageTiles.stories.tsx +3 -2
  87. package/src/components/LandingPageTiles/TileLarge/TileLarge.spec.tsx +5 -1
  88. package/src/components/LandingPageTiles/TileLarge/TileLarge.tsx +2 -1
  89. package/src/components/LandingPageTiles/TileSmall/TileSmall.spec.tsx +7 -2
  90. package/src/components/LandingPageTiles/TileSmall/TileSmall.tsx +2 -1
  91. package/src/components/List/ListCheckBox/ListCheckBox.tsx +1 -0
  92. package/src/components/List/ListHeader/ColumnLabel/ColumnLabel.spec.tsx +6 -6
  93. package/src/components/List/ListHeader/ColumnLabel/ColumnLabel.tsx +10 -13
  94. package/src/components/List/ListHeader/ListHeader.scss +0 -1
  95. package/src/components/List/ListHeader/ListHeader.spec.tsx +2 -0
  96. package/src/components/List/ListHeader/ListHeader.tsx +57 -51
  97. package/src/components/List/ListRow/ListRow.scss +0 -27
  98. package/src/components/List/ListRow/ListRow.spec.tsx +10 -8
  99. package/src/components/List/ListRow/ListRow.tsx +20 -152
  100. package/src/components/List/ListRow/ListRowCell/ListRowCell.scss +26 -0
  101. package/src/components/List/ListRow/ListRowCell/ListRowCell.spec.tsx +491 -0
  102. package/src/components/List/ListRow/ListRowCell/ListRowCell.tsx +57 -0
  103. package/src/components/List/ListRow/ListRowCell/renderData.tsx +124 -0
  104. package/src/components/List/ListRow/Renderers/TagsRenderer/TagsRenderer.scss +2 -1
  105. package/src/components/List/ListRow/Renderers/TagsRenderer/TagsRenderer.spec.tsx +187 -104
  106. package/src/components/List/ListRow/Renderers/TagsRenderer/TagsRenderer.tsx +134 -80
  107. package/src/components/Loaders/ImageLoader/ImageLoader.spec.tsx +13 -14
  108. package/src/components/Loaders/ImageLoader/ImageLoader.tsx +5 -3
  109. package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.tsx +13 -2
  110. package/src/components/Utils/Postgraphile/CreateConnectionRenderer.spec.ts +22 -75
  111. package/src/components/VisualElements/ImgElement.spec.tsx +92 -0
  112. package/src/components/VisualElements/ImgElement.tsx +72 -0
  113. package/src/components/VisualElements/SvgElement.spec.tsx +160 -0
  114. package/src/components/VisualElements/SvgElement.tsx +40 -0
  115. package/src/components/VisualElements/index.ts +7 -0
  116. package/src/components/index.ts +1 -0
  117. package/src/helpers/idleCallbackHelpers.ts +66 -0
  118. package/src/helpers/index.ts +5 -0
  119. package/src/hooks/useResize/ResizeIndicator.scss +7 -0
  120. package/src/hooks/useResize/ResizeIndicator.tsx +39 -0
  121. package/src/hooks/useResize/{useResize.ts → useResize.tsx} +38 -6
  122. package/src/styles/variables.scss +7 -6
@@ -4,11 +4,7 @@
4
4
  @include boxSizing;
5
5
 
6
6
  display: grid;
7
- grid-auto-rows: 50px;
8
- background-color: var(
9
- --filter-controller-background-color,
10
- $filter-controller-background-color
11
- );
7
+ grid-auto-rows: 40px;
12
8
  gap: 1px;
13
9
  border-top: unset;
14
10
 
@@ -18,7 +14,7 @@
18
14
 
19
15
  span {
20
16
  font-size: var(--filter-font-size, $filter-font-size);
21
- color: var(--filter-title-color, $filter-title-color);
17
+ color: var(--popper-text-color, $popper-text-color);
22
18
  display: grid;
23
19
  place-items: center left;
24
20
  padding: 0 20px;
@@ -27,15 +23,15 @@
27
23
 
28
24
  &:hover {
29
25
  background-color: var(
30
- --filter-background-selected-color,
31
- $filter-background-selected-color
26
+ --popper-item-hover-color,
27
+ $popper-item-hover-color
32
28
  );
33
29
  }
34
30
 
35
31
  &.selected {
36
32
  background-color: var(
37
- --filter-background-selected-color,
38
- $filter-background-selected-color
33
+ --popper-background-selected-color,
34
+ $popper-background-selected-color
39
35
  );
40
36
  }
41
37
  }
@@ -14,6 +14,9 @@ export interface OptionFilterProps {
14
14
 
15
15
  /** CSS Class name for additional styles */
16
16
  className?: string;
17
+
18
+ /** Optional id for the label element */
19
+ labelId?: string;
17
20
  }
18
21
 
19
22
  export const OptionsFilter: React.FC<OptionFilterProps> = ({
@@ -21,9 +24,12 @@ export const OptionsFilter: React.FC<OptionFilterProps> = ({
21
24
  options,
22
25
  onSelect,
23
26
  className = '',
27
+ labelId,
24
28
  }) => {
25
29
  return (
26
30
  <div
31
+ role="radiogroup"
32
+ aria-labelledby={labelId}
27
33
  className={clsx(classes.container, 'options-filter-container', className)}
28
34
  >
29
35
  {options?.map((option: Option) => (
@@ -32,6 +38,8 @@ export const OptionsFilter: React.FC<OptionFilterProps> = ({
32
38
  onClick={() => onSelect(option.value)}
33
39
  key={option.label}
34
40
  data-test-value={option.value as string}
41
+ role="radio"
42
+ aria-checked={value === option.value}
35
43
  >
36
44
  <span
37
45
  className={clsx(value === option.value && classes.selected)}
@@ -14,6 +14,9 @@ interface SearcheableOptionFilterProps
14
14
  searchInputPlaceholder?: string;
15
15
  maxItems?: number;
16
16
  onSelect: (value: string, stringValue?: string) => void;
17
+
18
+ /** Optional id for the input field */
19
+ inputId?: string;
17
20
  }
18
21
 
19
22
  export const SearcheableOptionsFilter: React.FC<
@@ -24,6 +27,7 @@ export const SearcheableOptionsFilter: React.FC<
24
27
  maxItems = 10,
25
28
  onSelect,
26
29
  className,
30
+ inputId,
27
31
  ...rest
28
32
  }) => {
29
33
  const [options, setOptions] = useState<Option[]>([]);
@@ -56,9 +60,10 @@ export const SearcheableOptionsFilter: React.FC<
56
60
  )}
57
61
  >
58
62
  <input
63
+ id={inputId}
59
64
  autoFocus
60
65
  onChange={debounce(onChangeHandler, 500)}
61
- className={clsx(classes.inputValue, '' && classes.hasError)}
66
+ className={classes.inputValue}
62
67
  placeholder={searchInputPlaceholder}
63
68
  />
64
69
  </div>
@@ -5,6 +5,7 @@ import {
5
5
  ConfirmationConfig,
6
6
  ConfirmationMode,
7
7
  } from '../../ConfirmDialog';
8
+ import { SvgElement } from '../../VisualElements/SvgElement';
8
9
  import { BaseFormControl, BaseInputEvents } from '../Form.models';
9
10
  import { FormElementContainer } from '../FormElementContainer';
10
11
  import classes from './Radio.scss';
@@ -42,7 +43,7 @@ export const RadioButton: React.FC<RadioButtonProps> = ({
42
43
  confirmValue,
43
44
  disabled = false,
44
45
  }) => (
45
- <svg
46
+ <SvgElement
46
47
  className={clsx(classes.buttonContainer, {
47
48
  [classes.checked]: checked,
48
49
  [classes.hasError]: hasError,
@@ -59,7 +60,7 @@ export const RadioButton: React.FC<RadioButtonProps> = ({
59
60
  >
60
61
  <circle className={classes.radioOutline} cx="17" cy="17" r="15" />
61
62
  <circle className={classes.radioDot} cx="17" cy="17" r="7.5" />
62
- </svg>
63
+ </SvgElement>
63
64
  );
64
65
 
65
66
  /**
@@ -94,7 +94,7 @@
94
94
  ul {
95
95
  display: grid;
96
96
  row-gap: 1px;
97
- background-color: var(--popper-background-color, $popper-background-color);
97
+ background-color: white;
98
98
  padding: 0px;
99
99
  margin-top: 1px;
100
100
  margin-bottom: 1px;
@@ -105,7 +105,7 @@
105
105
  li {
106
106
  display: grid;
107
107
  place-items: center left;
108
- height: 50px;
108
+ height: 40px;
109
109
  font-size: var(--popper-item-font-size, $popper-item-font-size);
110
110
  color: var(--popper-text-color, $popper-text-color);
111
111
  background-color: white;
@@ -116,18 +116,23 @@
116
116
  &:hover {
117
117
  cursor: pointer;
118
118
  background-color: var(
119
- --popper-background-selected-color,
120
- $popper-background-selected-color
119
+ --popper-item-hover-color,
120
+ $popper-item-hover-color
121
121
  );
122
122
  }
123
123
 
124
- &[aria-selected='true'],
125
- &[class='Mui-focused Mui-focusVisible'] {
124
+ &[aria-selected='true'] {
126
125
  background-color: var(
127
126
  --popper-background-selected-color,
128
127
  $popper-background-selected-color
129
128
  );
130
129
  }
130
+ &[class='Mui-focused Mui-focusVisible'] {
131
+ background-color: var(
132
+ --popper-item-selected-color,
133
+ $popper-item-selected-color
134
+ );
135
+ }
131
136
  }
132
137
  }
133
138
  }
@@ -7,6 +7,7 @@ import {
7
7
  ConfirmationConfig,
8
8
  ConfirmationMode,
9
9
  } from '../../ConfirmDialog';
10
+ import { SvgElement } from '../../VisualElements/SvgElement';
10
11
  import { BaseFormControl } from '../Form.models';
11
12
  import { FormElementContainer } from '../FormElementContainer';
12
13
  import classes from './ToggleButton.scss';
@@ -119,43 +120,22 @@ export const ToggleButton: React.FC<ToggleButtonProps> = ({
119
120
  data-test-checked={selected}
120
121
  >
121
122
  <div className={clsx(classes.off, { [classes.active]: !selected })}>
122
- <svg
123
- version="1.1"
124
- xmlns="http://www.w3.org/2000/svg"
125
- viewBox="0 0 40 40"
126
- >
123
+ <SvgElement viewBox="0 0 40 40">
127
124
  {showONOFFText && !selected && (
128
125
  <g className={classes.svgText}>
129
- <path
130
- d="M6.5,20.1c0-1,0.2-1.9,0.5-2.6c0.2-0.5,0.5-1,0.9-1.4c0.4-0.4,0.8-0.7,1.3-0.9c0.6-0.3,1.4-0.4,2.2-0.4
131
- c1.5,0,2.7,0.5,3.6,1.4c0.9,0.9,1.3,2.2,1.3,3.8c0,1.6-0.4,2.9-1.3,3.8c-0.9,0.9-2.1,1.4-3.6,1.4c-1.5,0-2.7-0.5-3.6-1.4
132
- S6.5,21.7,6.5,20.1z M8.6,20c0,1.1,0.3,2,0.8,2.6c0.5,0.6,1.2,0.9,2,0.9c0.8,0,1.5-0.3,2-0.9c0.5-0.6,0.8-1.5,0.8-2.6
133
- c0-1.1-0.3-2-0.8-2.6s-1.2-0.8-2-0.8c-0.8,0-1.5,0.3-2,0.9C8.8,18,8.6,18.8,8.6,20z"
134
- ></path>
135
- <path d="M17.9,25V15h6.9v1.7H20v2.4h4.2v1.7H20V25H17.9z"></path>
136
- <path d="M26.6,25V15h6.9v1.7h-4.9v2.4h4.2v1.7h-4.2V25H26.6z"></path>
126
+ <OffIcon />
137
127
  </g>
138
128
  )}
139
- </svg>
129
+ </SvgElement>
140
130
  </div>
141
131
  <div className={clsx(classes.on, { [classes.active]: selected })}>
142
- <svg
143
- version="1.1"
144
- xmlns="http://www.w3.org/2000/svg"
145
- viewBox="0 0 40 40"
146
- >
132
+ <SvgElement viewBox="0 0 40 40">
147
133
  {showONOFFText && selected && (
148
134
  <g className={classes.svgText}>
149
- <path
150
- d="M10.4,20.1c0-1,0.2-1.9,0.5-2.6c0.2-0.5,0.5-1,0.9-1.4s0.8-0.7,1.3-0.9c0.6-0.3,1.3-0.4,2.2-0.4
151
- c1.5,0,2.7,0.5,3.5,1.4s1.3,2.2,1.3,3.8c0,1.6-0.4,2.9-1.3,3.8c-0.9,0.9-2.1,1.4-3.5,1.4c-1.5,0-2.7-0.5-3.6-1.4
152
- C10.8,22.9,10.4,21.7,10.4,20.1z M12.4,20c0,1.1,0.3,2,0.8,2.6c0.5,0.6,1.2,0.9,2,0.9s1.5-0.3,2-0.9C17.7,22,18,21.1,18,20
153
- c0-1.1-0.3-2-0.8-2.6s-1.2-0.8-2-0.8s-1.5,0.3-2,0.9C12.7,18,12.4,18.8,12.4,20z"
154
- ></path>
155
- <path d="M21.7,25V15h2l4.1,6.7V15h1.9v10h-2l-4-6.5V25H21.7z"></path>
135
+ <OnIcon />
156
136
  </g>
157
137
  )}
158
- </svg>
138
+ </SvgElement>
159
139
  </div>
160
140
  </button>
161
141
  {confirmation && (
@@ -176,3 +156,28 @@ export const ToggleButton: React.FC<ToggleButtonProps> = ({
176
156
  </>
177
157
  );
178
158
  };
159
+
160
+ const OffIcon: React.FC = () => (
161
+ <>
162
+ <path
163
+ d="M6.5,20.1c0-1,0.2-1.9,0.5-2.6c0.2-0.5,0.5-1,0.9-1.4c0.4-0.4,0.8-0.7,1.3-0.9c0.6-0.3,1.4-0.4,2.2-0.4
164
+ c1.5,0,2.7,0.5,3.6,1.4c0.9,0.9,1.3,2.2,1.3,3.8c0,1.6-0.4,2.9-1.3,3.8c-0.9,0.9-2.1,1.4-3.6,1.4c-1.5,0-2.7-0.5-3.6-1.4
165
+ S6.5,21.7,6.5,20.1z M8.6,20c0,1.1,0.3,2,0.8,2.6c0.5,0.6,1.2,0.9,2,0.9c0.8,0,1.5-0.3,2-0.9c0.5-0.6,0.8-1.5,0.8-2.6
166
+ c0-1.1-0.3-2-0.8-2.6s-1.2-0.8-2-0.8c-0.8,0-1.5,0.3-2,0.9C8.8,18,8.6,18.8,8.6,20z"
167
+ />
168
+ <path d="M17.9,25V15h6.9v1.7H20v2.4h4.2v1.7H20V25H17.9z" />
169
+ <path d="M26.6,25V15h6.9v1.7h-4.9v2.4h4.2v1.7h-4.2V25H26.6z" />
170
+ </>
171
+ );
172
+
173
+ const OnIcon: React.FC = () => (
174
+ <>
175
+ <path
176
+ d="M10.4,20.1c0-1,0.2-1.9,0.5-2.6c0.2-0.5,0.5-1,0.9-1.4s0.8-0.7,1.3-0.9c0.6-0.3,1.3-0.4,2.2-0.4
177
+ c1.5,0,2.7,0.5,3.5,1.4s1.3,2.2,1.3,3.8c0,1.6-0.4,2.9-1.3,3.8c-0.9,0.9-2.1,1.4-3.5,1.4c-1.5,0-2.7-0.5-3.6-1.4
178
+ C10.8,22.9,10.4,21.7,10.4,20.1z M12.4,20c0,1.1,0.3,2,0.8,2.6c0.5,0.6,1.2,0.9,2,0.9s1.5-0.3,2-0.9C17.7,22,18,21.1,18,20
179
+ c0-1.1-0.3-2-0.8-2.6s-1.2-0.8-2-0.8s-1.5,0.3-2,0.9C12.7,18,12.4,18.8,12.4,20z"
180
+ />
181
+ <path d="M21.7,25V15h2l4.1,6.7V15h1.9v10h-2l-4-6.5V25H21.7z" />
182
+ </>
183
+ );
@@ -1,6 +1,7 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
  import React from 'react';
3
3
  import { MemoryRouter } from 'react-router-dom';
4
+ import { SvgElement } from '../VisualElements/SvgElement';
4
5
  import { Hub } from './Hub';
5
6
  import { HubItem } from './Hub.model';
6
7
 
@@ -14,7 +15,7 @@ const defaultContainer = {
14
15
 
15
16
  const DefaultIcon: React.FC = () => {
16
17
  return (
17
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
18
+ <SvgElement viewBox="0 0 40 40">
18
19
  <path
19
20
  vectorEffect="non-scaling-stroke"
20
21
  fill="none"
@@ -22,7 +23,7 @@ const DefaultIcon: React.FC = () => {
22
23
  d="M39,39H1V1h38V39z M39.1,26l-8.4-8.7l-9.1,11.5
23
24
  l-6.4-5.4L3.6,39.1 M12.8,7.8c-2.4,0-4.4,2-4.4,4.4s2,4.4,4.4,4.4s4.4-2,4.4-4.4S15.3,7.8,12.8,7.8z"
24
25
  />
25
- </svg>
26
+ </SvgElement>
26
27
  );
27
28
  };
28
29
 
@@ -1,5 +1,6 @@
1
- import { shallow } from 'enzyme';
1
+ import { mount, shallow } from 'enzyme';
2
2
  import React from 'react';
3
+ import { MemoryRouter } from 'react-router-dom'; // Add this import
3
4
  import { Tile } from './Tile';
4
5
  import { TileProps } from './Tile.model';
5
6
 
@@ -31,7 +32,11 @@ describe('Tile', () => {
31
32
  });
32
33
 
33
34
  it('renders an icon when passed as a string URL', () => {
34
- const wrapper = shallow(<Tile {...mockProps} />);
35
+ const wrapper = mount(
36
+ <MemoryRouter>
37
+ <Tile {...mockProps} />
38
+ </MemoryRouter>,
39
+ );
35
40
  const iconUrl = wrapper.find('img').prop('src');
36
41
 
37
42
  expect(iconUrl).toBe(`${mockProps.icon}`);
@@ -1,6 +1,7 @@
1
1
  import clsx from 'clsx';
2
2
  import React from 'react';
3
3
  import { Link } from 'react-router-dom';
4
+ import { ImgElement } from '../../VisualElements/ImgElement';
4
5
  import { TileProps } from './Tile.model';
5
6
  import classes from './Tile.scss';
6
7
 
@@ -34,7 +35,7 @@ export const Tile: React.FC<TileProps> = ({
34
35
  {React.isValidElement(icon)
35
36
  ? icon
36
37
  : typeof icon === 'string' && (
37
- <img src={icon} alt={`${label} icon`} />
38
+ <ImgElement src={icon} decorative={true} />
38
39
  )}
39
40
  </div>
40
41
  <div className={classes.label}>
@@ -5,6 +5,7 @@
5
5
 
6
6
  height: 35px;
7
7
 
8
+ rect,
8
9
  polygon,
9
10
  polyline,
10
11
  path,
@@ -11,50 +11,73 @@ describe('Icons', () => {
11
11
  });
12
12
 
13
13
  it.each`
14
- key | result
15
- ${IconName.Archive} | ${1}
16
- ${IconName.Block} | ${1}
17
- ${IconName.Bulk} | ${1}
18
- ${IconName.Calendar} | ${1}
19
- ${IconName.Checkmark} | ${1}
20
- ${IconName.ChevronDown} | ${1}
21
- ${IconName.ChevronLeft} | ${1}
22
- ${IconName.ChevronRight} | ${1}
23
- ${IconName.ChevronUp} | ${1}
24
- ${IconName.Copy} | ${1}
25
- ${IconName.Delete} | ${1}
26
- ${IconName.Details} | ${1}
27
- ${IconName.Drag} | ${6}
28
- ${IconName.Ellipsis} | ${1}
29
- ${IconName.Error} | ${1}
30
- ${IconName.External} | ${1}
31
- ${IconName.File} | ${1}
32
- ${IconName.Info} | ${1}
33
- ${IconName.MidlineEllipsis} | ${1}
34
- ${IconName.Minus} | ${1}
35
- ${IconName.NavigateRight} | ${1}
36
- ${IconName.Pause} | ${1}
37
- ${IconName.Play} | ${1}
38
- ${IconName.Plus} | ${1}
39
- ${IconName.Publish} | ${1}
40
- ${IconName.RemoveFilter} | ${1}
41
- ${IconName.Replace} | ${1}
42
- ${IconName.Retry} | ${1}
43
- ${IconName.Snapshot} | ${1}
44
- ${IconName.Stop} | ${1}
45
- ${IconName.Success} | ${1}
46
- ${IconName.Unarchive} | ${1}
47
- ${IconName.Undo} | ${1}
48
- ${IconName.Unpublish} | ${1}
49
- ${IconName.Upload} | ${1}
50
- ${IconName.Warning} | ${1}
51
- ${IconName.X} | ${1}
52
- `('renders an icon for each key in IconName', ({ key, result }) => {
14
+ key | result
15
+ ${IconName.Axi} | ${1}
16
+ ${IconName.Archive} | ${1}
17
+ ${IconName.Audio} | ${1}
18
+ ${IconName.DescriptiveAudio} | ${1}
19
+ ${IconName.BackwardOne} | ${1}
20
+ ${IconName.BackwardTen} | ${1}
21
+ ${IconName.Block} | ${1}
22
+ ${IconName.Bulk} | ${1}
23
+ ${IconName.BulkEdit} | ${1}
24
+ ${IconName.Calendar} | ${1}
25
+ ${IconName.Checkmark} | ${1}
26
+ ${IconName.ChevronDown} | ${1}
27
+ ${IconName.ChevronLeft} | ${1}
28
+ ${IconName.ChevronRight} | ${1}
29
+ ${IconName.ChevronUp} | ${1}
30
+ ${IconName.ClosedCaption} | ${1}
31
+ ${IconName.Copy} | ${1}
32
+ ${IconName.Delete} | ${1}
33
+ ${IconName.Details} | ${1}
34
+ ${IconName.Drag} | ${6}
35
+ ${IconName.Ellipsis} | ${1}
36
+ ${IconName.Error} | ${1}
37
+ ${IconName.External} | ${1}
38
+ ${IconName.File} | ${1}
39
+ ${IconName.Filters} | ${1}
40
+ ${IconName.ForwardOne} | ${1}
41
+ ${IconName.ForwardTen} | ${1}
42
+ ${IconName.Info} | ${1}
43
+ ${IconName.InProgress} | ${1}
44
+ ${IconName.MidlineEllipsis} | ${1}
45
+ ${IconName.Minus} | ${1}
46
+ ${IconName.Mute} | ${1}
47
+ ${IconName.NavigateRight} | ${1}
48
+ ${IconName.Pause} | ${1}
49
+ ${IconName.Play} | ${1}
50
+ ${IconName.Plus} | ${1}
51
+ ${IconName.Publish} | ${1}
52
+ ${IconName.QuickEdit} | ${1}
53
+ ${IconName.QuickEditStation} | ${1}
54
+ ${IconName.RemoveFilter} | ${1}
55
+ ${IconName.Replace} | ${1}
56
+ ${IconName.Retry} | ${1}
57
+ ${IconName.Save} | ${2}
58
+ ${IconName.Snapshot} | ${1}
59
+ ${IconName.Stop} | ${1}
60
+ ${IconName.Subtitles} | ${1}
61
+ ${IconName.Success} | ${1}
62
+ ${IconName.Unarchive} | ${1}
63
+ ${IconName.Undo} | ${1}
64
+ ${IconName.Unmute} | ${1}
65
+ ${IconName.Unpublish} | ${1}
66
+ ${IconName.Upload} | ${1}
67
+ ${IconName.Video} | ${1}
68
+ ${IconName.Warning} | ${1}
69
+ ${IconName.X} | ${1}
70
+ `('renders $key icon with $result children', ({ key, result }) => {
53
71
  const wrapper = mount(<Icons icon={key} />);
54
72
 
55
- const icon = wrapper.find('svg');
73
+ const svgElement = wrapper.find('svg');
74
+ expect(svgElement).toHaveLength(1);
75
+
76
+ // Get the actual DOM node and count its children
77
+ const domNode = svgElement.getDOMNode() as SVGElement;
78
+ const childrenCount = domNode.children.length;
56
79
 
57
- expect(icon.children()).toHaveLength(result);
80
+ expect(childrenCount).toBe(result);
58
81
  });
59
82
 
60
83
  it('passes down optional className to icon', () => {
@@ -75,4 +98,30 @@ describe('Icons', () => {
75
98
 
76
99
  expect(icon.children()).toHaveLength(0);
77
100
  });
101
+
102
+ it('applies accessibility attributes correctly', () => {
103
+ const wrapper = mount(
104
+ <Icons
105
+ icon={IconName.Play}
106
+ aria-label="Play video"
107
+ title="Start playback"
108
+ />,
109
+ );
110
+
111
+ const svg = wrapper.find('svg');
112
+
113
+ expect(svg.prop('aria-label')).toBe('Play video');
114
+ expect(svg.prop('role')).toBe('img');
115
+ expect(svg.prop('aria-hidden')).toBeUndefined();
116
+ expect(wrapper.find('title').text()).toBe('Start playback');
117
+ });
118
+
119
+ it('marks decorative icons as presentation', () => {
120
+ const wrapper = mount(<Icons icon={IconName.Play} />);
121
+
122
+ const svg = wrapper.find('svg');
123
+
124
+ expect(svg.prop('role')).toBe('presentation');
125
+ expect(svg.prop('aria-hidden')).toBe('true');
126
+ });
78
127
  });