@axinom/mosaic-ui 0.66.0-rc.9 → 0.66.1

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 (149) hide show
  1. package/dist/components/DynamicDataList/DynamicListHeader/DynamicListHeader.d.ts.map +1 -1
  2. package/dist/components/FieldSelection/FieldSelection.d.ts.map +1 -1
  3. package/dist/components/Filters/Filter/Filter.d.ts.map +1 -1
  4. package/dist/components/Filters/Filters.model.d.ts +5 -0
  5. package/dist/components/Filters/Filters.model.d.ts.map +1 -1
  6. package/dist/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.d.ts +2 -0
  7. package/dist/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.d.ts.map +1 -1
  8. package/dist/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.d.ts +2 -0
  9. package/dist/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.d.ts.map +1 -1
  10. package/dist/components/Filters/SelectionTypes/MultiOptionFilter/MultiOptionFilter.d.ts +2 -0
  11. package/dist/components/Filters/SelectionTypes/MultiOptionFilter/MultiOptionFilter.d.ts.map +1 -1
  12. package/dist/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.d.ts +2 -0
  13. package/dist/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.d.ts.map +1 -1
  14. package/dist/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.d.ts +2 -0
  15. package/dist/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.d.ts.map +1 -1
  16. package/dist/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.d.ts +2 -0
  17. package/dist/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.d.ts.map +1 -1
  18. package/dist/components/FormElements/DateTimeField/DateTimeText.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/Utils/Postgraphile/CreateConnectionRenderer.d.ts +1 -1
  38. package/dist/components/Utils/Postgraphile/CreateConnectionRenderer.d.ts.map +1 -1
  39. package/dist/components/VisualElements/ImgElement.d.ts +50 -0
  40. package/dist/components/VisualElements/ImgElement.d.ts.map +1 -0
  41. package/dist/components/VisualElements/SvgElement.d.ts +14 -0
  42. package/dist/components/VisualElements/SvgElement.d.ts.map +1 -0
  43. package/dist/components/VisualElements/index.d.ts +3 -0
  44. package/dist/components/VisualElements/index.d.ts.map +1 -0
  45. package/dist/components/index.d.ts +1 -0
  46. package/dist/components/index.d.ts.map +1 -1
  47. package/dist/helpers/idleCallbackHelpers.d.ts +42 -0
  48. package/dist/helpers/idleCallbackHelpers.d.ts.map +1 -0
  49. package/dist/helpers/index.d.ts +1 -0
  50. package/dist/helpers/index.d.ts.map +1 -1
  51. package/dist/hooks/useResize/ResizeIndicator.d.ts +8 -0
  52. package/dist/hooks/useResize/ResizeIndicator.d.ts.map +1 -0
  53. package/dist/hooks/useResize/useResize.d.ts +5 -2
  54. package/dist/hooks/useResize/useResize.d.ts.map +1 -1
  55. package/dist/index.d.ts +1 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.es.js +4 -4
  58. package/dist/index.es.js.map +1 -1
  59. package/dist/index.js +4 -4
  60. package/dist/index.js.map +1 -1
  61. package/package.json +2 -2
  62. package/src/components/Accordion/Accordion.scss +1 -1
  63. package/src/components/Accordion/AccordionItem/AccordionItem.scss +2 -2
  64. package/src/components/Buttons/Button/Button.scss +5 -5
  65. package/src/components/Buttons/CompositeButton/CompositeButton.scss +7 -7
  66. package/src/components/Buttons/TextButton/TextButton.scss +6 -6
  67. package/src/components/ConfirmDialog/ConfirmDialog.scss +1 -1
  68. package/src/components/DateTime/DatePicker/DatePicker.scss +12 -12
  69. package/src/components/DateTime/TimePicker/ScrollColumn/ScrollColumn.scss +7 -7
  70. package/src/components/DateTime/TimePicker/TimePicker.scss +1 -1
  71. package/src/components/DynamicDataList/DynamicListHeader/DynamicListHeader.scss +2 -2
  72. package/src/components/DynamicDataList/DynamicListHeader/DynamicListHeader.spec.tsx +2 -0
  73. package/src/components/DynamicDataList/DynamicListHeader/DynamicListHeader.tsx +62 -50
  74. package/src/components/DynamicDataList/DynamicListRow/DynamicListRow.scss +2 -2
  75. package/src/components/FieldSelection/FieldSelection.scss +6 -0
  76. package/src/components/FieldSelection/FieldSelection.tsx +2 -1
  77. package/src/components/Filters/Filter/Filter.scss +34 -15
  78. package/src/components/Filters/Filter/Filter.spec.tsx +1 -1
  79. package/src/components/Filters/Filter/Filter.tsx +46 -34
  80. package/src/components/Filters/Filters.model.ts +6 -0
  81. package/src/components/Filters/SelectionTypes/DateTimeFilter/DateTimeFilter.tsx +5 -0
  82. package/src/components/Filters/SelectionTypes/FreeTextFilter/FreeTextFilter.tsx +4 -0
  83. package/src/components/Filters/SelectionTypes/MultiOptionFilter/MultiOptionFilter.scss +1 -1
  84. package/src/components/Filters/SelectionTypes/MultiOptionFilter/MultiOptionFilter.tsx +9 -1
  85. package/src/components/Filters/SelectionTypes/NumericTextFilter/NumericTextFilter.tsx +5 -0
  86. package/src/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.scss +6 -11
  87. package/src/components/Filters/SelectionTypes/OptionsFilter/OptionsFilter.tsx +8 -0
  88. package/src/components/Filters/SelectionTypes/SearcheableOptionsFilter/SearcheableOptionsFilter.tsx +6 -1
  89. package/src/components/FormElements/Checkbox/Checkbox.scss +4 -4
  90. package/src/components/FormElements/CustomTags/CustomTags.scss +1 -1
  91. package/src/components/FormElements/DateTimeField/DateTimeText.scss +5 -6
  92. package/src/components/FormElements/DateTimeField/DateTimeText.tsx +58 -43
  93. package/src/components/FormElements/FileUploadControl/FileUploadControl.scss +4 -4
  94. package/src/components/FormElements/Radio/Radio.scss +5 -5
  95. package/src/components/FormElements/Radio/Radio.tsx +3 -2
  96. package/src/components/FormElements/Select/Select.scss +11 -6
  97. package/src/components/FormElements/ToggleButton/ToggleButton.scss +7 -7
  98. package/src/components/FormElements/ToggleButton/ToggleButton.tsx +32 -27
  99. package/src/components/Hub/Hub.stories.tsx +3 -2
  100. package/src/components/Hub/Tile/Tile.spec.tsx +7 -2
  101. package/src/components/Hub/Tile/Tile.tsx +2 -1
  102. package/src/components/Icons/Icons.scss +1 -0
  103. package/src/components/Icons/Icons.spec.tsx +90 -41
  104. package/src/components/Icons/Icons.tsx +357 -765
  105. package/src/components/InfoTooltip/InfoTooltip.scss +1 -1
  106. package/src/components/InlineMenu/InlineMenu.scss +2 -2
  107. package/src/components/LandingPageTiles/LandingPageTiles.stories.tsx +3 -2
  108. package/src/components/LandingPageTiles/TileLarge/TileLarge.spec.tsx +5 -1
  109. package/src/components/LandingPageTiles/TileLarge/TileLarge.tsx +2 -1
  110. package/src/components/LandingPageTiles/TileSmall/TileSmall.spec.tsx +7 -2
  111. package/src/components/LandingPageTiles/TileSmall/TileSmall.tsx +2 -1
  112. package/src/components/List/List.scss +4 -4
  113. package/src/components/List/ListCheckBox/ListCheckBox.tsx +1 -0
  114. package/src/components/List/ListHeader/ColumnLabel/ColumnLabel.spec.tsx +6 -6
  115. package/src/components/List/ListHeader/ColumnLabel/ColumnLabel.tsx +10 -13
  116. package/src/components/List/ListHeader/ListHeader.scss +2 -3
  117. package/src/components/List/ListHeader/ListHeader.spec.tsx +2 -0
  118. package/src/components/List/ListHeader/ListHeader.tsx +57 -51
  119. package/src/components/List/ListRow/ListRow.scss +1 -28
  120. package/src/components/List/ListRow/ListRow.spec.tsx +10 -8
  121. package/src/components/List/ListRow/ListRow.tsx +20 -152
  122. package/src/components/List/ListRow/ListRowCell/ListRowCell.scss +26 -0
  123. package/src/components/List/ListRow/ListRowCell/ListRowCell.spec.tsx +491 -0
  124. package/src/components/List/ListRow/ListRowCell/ListRowCell.tsx +57 -0
  125. package/src/components/List/ListRow/ListRowCell/renderData.tsx +124 -0
  126. package/src/components/List/ListRow/Renderers/TagsRenderer/TagsRenderer.spec.tsx +191 -80
  127. package/src/components/List/ListRow/Renderers/TagsRenderer/TagsRenderer.tsx +63 -34
  128. package/src/components/Loaders/ImageLoader/ImageLoader.spec.tsx +13 -14
  129. package/src/components/Loaders/ImageLoader/ImageLoader.tsx +5 -3
  130. package/src/components/PageHeader/PageHeader.scss +1 -1
  131. package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.tsx +13 -2
  132. package/src/components/Tabs/Tab/CustomTab.scss +4 -4
  133. package/src/components/Tabs/TabList/CustomTabList.scss +2 -2
  134. package/src/components/Utils/Postgraphile/CreateConnectionRenderer.spec.ts +48 -12
  135. package/src/components/Utils/Postgraphile/CreateConnectionRenderer.tsx +5 -4
  136. package/src/components/VisualElements/ImgElement.spec.tsx +92 -0
  137. package/src/components/VisualElements/ImgElement.tsx +72 -0
  138. package/src/components/VisualElements/SvgElement.spec.tsx +158 -0
  139. package/src/components/VisualElements/SvgElement.tsx +40 -0
  140. package/src/components/VisualElements/index.ts +7 -0
  141. package/src/components/index.ts +1 -0
  142. package/src/helpers/idleCallbackHelpers.ts +66 -0
  143. package/src/helpers/index.ts +5 -0
  144. package/src/hooks/useResize/ResizeIndicator.scss +7 -0
  145. package/src/hooks/useResize/ResizeIndicator.tsx +39 -0
  146. package/src/hooks/useResize/{useResize.ts → useResize.tsx} +38 -6
  147. package/src/index.ts +2 -0
  148. package/src/styles/branding.scss +89 -0
  149. package/src/styles/variables.scss +245 -187
@@ -1,11 +1,5 @@
1
1
  import clsx from 'clsx';
2
- import React, {
3
- PropsWithChildren,
4
- ReactNode,
5
- useEffect,
6
- useRef,
7
- useState,
8
- } from 'react';
2
+ import React, { PropsWithChildren, ReactNode, useState } from 'react';
9
3
  import { assertNever } from '../../../helpers/utils';
10
4
  import { Data } from '../../../types/data';
11
5
  import { Button, ButtonContext } from '../../Buttons';
@@ -58,18 +52,16 @@ export const Filter = <T extends Data>({
58
52
  }: PropsWithChildren<FilterProps<T>>): JSX.Element => {
59
53
  const [isExpanded, setIsExpanded] = useState<boolean>(false);
60
54
  const [hasError, setHasError] = useState<boolean>(false);
61
- const [contentHeight, setContentHeight] = useState<number>(0);
62
55
  const [stringValue, setStringValue] = useState<string | undefined>();
63
56
 
64
- const contentRef = useRef<HTMLDivElement>(null);
65
- const valueRef = useRef<HTMLDivElement>(null);
66
-
67
- useEffect(() => {
68
- setContentHeight(
69
- (contentRef.current?.scrollHeight ?? 0) +
70
- (valueRef.current?.scrollHeight ?? 0),
71
- );
72
- }, [isExpanded, hasError, value]);
57
+ const inputId = `${String(options.property)}-filter-input`;
58
+ const labelId = `${String(options.property)}-filter-label`;
59
+ const inputBasedFilter = [
60
+ FilterTypes.FreeText,
61
+ FilterTypes.Numeric,
62
+ FilterTypes.Date,
63
+ FilterTypes.DateTime,
64
+ ];
73
65
 
74
66
  const onFilterValueChange = (
75
67
  prop: keyof T,
@@ -135,6 +127,7 @@ export const Filter = <T extends Data>({
135
127
  onError={onError}
136
128
  onValidate={onValidate}
137
129
  selectOnFocus={selectOnFocus}
130
+ inputId={inputId}
138
131
  />
139
132
  );
140
133
 
@@ -147,6 +140,7 @@ export const Filter = <T extends Data>({
147
140
  }
148
141
  onError={onError}
149
142
  onValidate={onValidate}
143
+ inputId={inputId}
150
144
  />
151
145
  );
152
146
 
@@ -158,6 +152,7 @@ export const Filter = <T extends Data>({
158
152
  onSelect={(value: FilterValue) =>
159
153
  onFilterValueChange(options.property, value)
160
154
  }
155
+ labelId={labelId}
161
156
  />
162
157
  );
163
158
 
@@ -169,6 +164,7 @@ export const Filter = <T extends Data>({
169
164
  onSelect={(value: FilterValue) =>
170
165
  onFilterValueChange(options.property, value?.toString())
171
166
  }
167
+ labelId={labelId}
172
168
  />
173
169
  );
174
170
  case FilterTypes.SearcheableOptions:
@@ -181,6 +177,8 @@ export const Filter = <T extends Data>({
181
177
  onFilterValueChange(options.property, value, stringValue)
182
178
  }
183
179
  maxItems={options.maxItems}
180
+ inputId={inputId}
181
+ labelId={labelId}
184
182
  />
185
183
  );
186
184
 
@@ -194,6 +192,7 @@ export const Filter = <T extends Data>({
194
192
  modifyTime={false}
195
193
  onError={onError}
196
194
  onValidate={onValidate}
195
+ inputId={inputId}
197
196
  />
198
197
  );
199
198
 
@@ -207,6 +206,7 @@ export const Filter = <T extends Data>({
207
206
  modifyTime={true}
208
207
  onError={onError}
209
208
  onValidate={onValidate}
209
+ inputId={inputId}
210
210
  />
211
211
  );
212
212
 
@@ -220,6 +220,7 @@ export const Filter = <T extends Data>({
220
220
  }}
221
221
  onError={onError}
222
222
  onValidate={onValidate}
223
+ labelId={labelId}
223
224
  />
224
225
  );
225
226
 
@@ -229,9 +230,16 @@ export const Filter = <T extends Data>({
229
230
  }
230
231
  };
231
232
 
233
+ const hasValue = value !== undefined && value !== '';
234
+
232
235
  return (
233
236
  <div
234
- className={clsx(classes.container, 'filter-container', className)}
237
+ className={clsx(
238
+ classes.container,
239
+ { [classes.hasValue]: hasValue },
240
+ 'filter-container',
241
+ className,
242
+ )}
235
243
  data-test-id={`filter:${options.property as string}`}
236
244
  data-test-type={FilterTypes[options.type]}
237
245
  onClick={() => onFilterClicked()}
@@ -241,31 +249,36 @@ export const Filter = <T extends Data>({
241
249
  setIsExpanded(!isExpanded);
242
250
  setHasError(false);
243
251
  }}
244
- className={clsx(
245
- classes.title,
246
- { [classes.expanded]: isExpanded && isActive },
247
- hasError && classes.hasError,
248
- !!value && classes.active,
249
- )}
252
+ className={clsx(classes.title, {
253
+ [classes.hasValue]: hasValue,
254
+ [classes.active]: isActive && isExpanded,
255
+ [classes.hasError]: hasError,
256
+ })}
250
257
  data-test-id="filter-button-toggle"
251
258
  >
252
- <span data-test-id="filter-label">{options.label}</span>
259
+ <label
260
+ id={labelId}
261
+ {...(inputBasedFilter.includes(options.type)
262
+ ? {}
263
+ : { htmlFor: inputId })}
264
+ data-test-id="filter-label"
265
+ >
266
+ {options.label}
267
+ </label>
253
268
  <Button
254
- icon={IconName.ChevronDown}
255
- className={clsx(classes.button)}
269
+ icon={IconName.ChevronRight}
270
+ className={clsx(classes.button, {
271
+ [classes.rotated]: isExpanded || hasValue,
272
+ })}
256
273
  buttonContext={ButtonContext.None}
257
274
  />
258
275
  </div>
259
276
  <div
260
- className={clsx(classes.content)}
261
- style={{
262
- maxHeight: contentHeight,
263
- }}
277
+ className={clsx(classes.content, { [classes.expanded]: isExpanded })}
264
278
  >
265
- {value !== undefined && !isExpanded && (
279
+ {hasValue && !isExpanded && (
266
280
  <div
267
281
  className={clsx(classes.selectedValue)}
268
- ref={valueRef}
269
282
  onClick={() => {
270
283
  setIsExpanded(!isExpanded);
271
284
  }}
@@ -285,7 +298,6 @@ export const Filter = <T extends Data>({
285
298
  )}
286
299
  {isExpanded && (
287
300
  <div
288
- ref={contentRef}
289
301
  data-test-id="filter-content"
290
302
  className={clsx({ [classes.active]: isActive })}
291
303
  >
@@ -78,6 +78,12 @@ export interface CustomFilterProps {
78
78
  /** Wether or not the filter is active (default: false) */
79
79
  active?: boolean;
80
80
 
81
+ /**
82
+ * Optional id for the label element.
83
+ * Assign to the label's `id` and reference from the input or group via `aria-labelledby`.
84
+ */
85
+ labelId?: string;
86
+
81
87
  /** Callback triggered when a new filter value is selected */
82
88
  onSelect: (
83
89
  value: FilterValue,
@@ -31,6 +31,9 @@ export interface DateTimeFilterProps {
31
31
 
32
32
  /** CSS Class name for additional styles */
33
33
  className?: string;
34
+
35
+ /** Optional id for the input field */
36
+ inputId?: string;
34
37
  }
35
38
 
36
39
  export const DateTimeFilter: React.FC<DateTimeFilterProps> = ({
@@ -40,6 +43,7 @@ export const DateTimeFilter: React.FC<DateTimeFilterProps> = ({
40
43
  onError = noop,
41
44
  onValidate: customValidate,
42
45
  className = '',
46
+ inputId,
43
47
  }) => {
44
48
  const container = useRef<HTMLDivElement>(null);
45
49
  const [showPicker, setShowPicker] = useState(false);
@@ -111,6 +115,7 @@ export const DateTimeFilter: React.FC<DateTimeFilterProps> = ({
111
115
  ref={container}
112
116
  >
113
117
  <input
118
+ id={inputId}
114
119
  autoFocus
115
120
  className={clsx(classes.inputValue)}
116
121
  onKeyDown={handleKeyDown}
@@ -19,6 +19,8 @@ export interface FreeTextFilterProps {
19
19
  className?: string;
20
20
  /** Select text on focus if true (default: true) */
21
21
  selectOnFocus?: boolean;
22
+ /** Optional id for the input field */
23
+ inputId?: string;
22
24
  }
23
25
 
24
26
  export const FreeTextFilter: React.FC<FreeTextFilterProps> = ({
@@ -28,6 +30,7 @@ export const FreeTextFilter: React.FC<FreeTextFilterProps> = ({
28
30
  onValidate: customValidate,
29
31
  className = '',
30
32
  selectOnFocus = true,
33
+ inputId,
31
34
  }) => {
32
35
  const [errorMsg, setErrorMsg] = useState<string>();
33
36
  const ENTER_KEY = 'Enter';
@@ -68,6 +71,7 @@ export const FreeTextFilter: React.FC<FreeTextFilterProps> = ({
68
71
  )}
69
72
  >
70
73
  <input
74
+ id={inputId}
71
75
  ref={inputRef}
72
76
  autoFocus
73
77
  className={clsx(classes.inputValue, errorMsg && classes.hasError)}
@@ -13,7 +13,7 @@
13
13
  input {
14
14
  border-color: var(
15
15
  --multi-option-checbox-border,
16
- $multi-option-checbox-border
16
+ $multi-option-checkbox-border
17
17
  );
18
18
  }
19
19
  &:hover {
@@ -17,19 +17,27 @@ export interface MultiOptionFilterProps {
17
17
 
18
18
  /** CSS Class name for additional styles */
19
19
  className?: string;
20
+
21
+ /** ID for the label */
22
+ labelId?: string;
20
23
  }
21
24
 
22
25
  export const MultiOptionsFilter: React.FC<MultiOptionFilterProps> = ({
23
26
  value,
24
27
  options,
25
28
  onSelect,
29
+ labelId,
26
30
  }) => {
27
31
  const [selectedOptionList, setSelectedOptionList] = useState<string[]>(
28
32
  value ? value.split(',') : [],
29
33
  );
30
34
 
31
35
  return (
32
- <div className={clsx(classes.multiFilterContainer)}>
36
+ <div
37
+ className={classes.multiFilterContainer}
38
+ role="group"
39
+ aria-labelledby={labelId}
40
+ >
33
41
  {options?.map((option: Option) => (
34
42
  <Checkbox
35
43
  className={clsx(
@@ -18,6 +18,9 @@ export interface NumericTextFilterProps {
18
18
 
19
19
  /** CSS Class name for additional styles */
20
20
  className?: string;
21
+
22
+ /** Optional id for the input field */
23
+ inputId?: string;
21
24
  }
22
25
 
23
26
  export const NumericTextFilter: React.FC<NumericTextFilterProps> = ({
@@ -26,6 +29,7 @@ export const NumericTextFilter: React.FC<NumericTextFilterProps> = ({
26
29
  onError = noop,
27
30
  onValidate: customValidate,
28
31
  className = '',
32
+ inputId,
29
33
  }) => {
30
34
  const [errorMsg, setErrorMsg] = useState<string>();
31
35
  const ENTER_KEY = 'Enter';
@@ -64,6 +68,7 @@ export const NumericTextFilter: React.FC<NumericTextFilterProps> = ({
64
68
  )}
65
69
  >
66
70
  <input
71
+ id={inputId}
67
72
  autoFocus
68
73
  value={valueLocal}
69
74
  className={clsx(classes.inputValue, errorMsg && classes.hasError)}
@@ -4,12 +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
- );
12
- gap: 1px;
7
+ grid-auto-rows: 40px;
13
8
  border-top: unset;
14
9
 
15
10
  .option {
@@ -18,7 +13,7 @@
18
13
 
19
14
  span {
20
15
  font-size: var(--filter-font-size, $filter-font-size);
21
- color: var(--filter-title-color, $filter-title-color);
16
+ color: var(--popper-text-color, $popper-text-color);
22
17
  display: grid;
23
18
  place-items: center left;
24
19
  padding: 0 20px;
@@ -27,15 +22,15 @@
27
22
 
28
23
  &:hover {
29
24
  background-color: var(
30
- --filter-background-selected-color,
31
- $filter-background-selected-color
25
+ --popper-item-hover-color,
26
+ $popper-item-hover-color
32
27
  );
33
28
  }
34
29
 
35
30
  &.selected {
36
31
  background-color: var(
37
- --filter-background-selected-color,
38
- $filter-background-selected-color
32
+ --popper-background-selected-color,
33
+ $popper-background-selected-color
39
34
  );
40
35
  }
41
36
  }
@@ -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>
@@ -26,7 +26,7 @@
26
26
  // transition: background-color 0.15s ease-in-out 0s;
27
27
 
28
28
  &.hasConfirm {
29
- border: 1px solid $yellow;
29
+ border: 1px solid var(--ax-warning);
30
30
  }
31
31
 
32
32
  &.hasError {
@@ -54,8 +54,8 @@
54
54
  box-shadow: 0 0 0 2px var(--input-hover-color, $input-hover-color);
55
55
 
56
56
  &.hasConfirm {
57
- border: 1px solid $yellow;
58
- box-shadow: 0 0 0 2px $yellow;
57
+ border: 1px solid var(--ax-warning);
58
+ box-shadow: 0 0 0 2px var(--ax-warning);
59
59
  }
60
60
 
61
61
  &.hasError {
@@ -70,7 +70,7 @@
70
70
  background-color: var(--input-hover-color, $input-hover-color);
71
71
 
72
72
  &.hasConfirm {
73
- background-color: $yellow;
73
+ background-color: var(--ax-warning);
74
74
  }
75
75
 
76
76
  &.hasError {
@@ -145,7 +145,7 @@
145
145
  &.hasError {
146
146
  background-color: white;
147
147
  svg * {
148
- stroke: rgba($gray, 0.5);
148
+ stroke: color-mix(in srgb, var(--ax-neutral) 50%, transparent);
149
149
  }
150
150
  }
151
151
 
@@ -43,16 +43,15 @@
43
43
  display: grid;
44
44
  grid-template-columns: min-content min-content;
45
45
  }
46
+ }
46
47
 
47
- .picker {
48
- position: absolute;
49
- overflow: visible;
50
- z-index: 99999;
51
- }
48
+ .picker {
49
+ overflow: visible;
50
+ z-index: 99999;
52
51
  }
53
52
 
54
53
  .backdrop {
55
- position: absolute;
54
+ position: fixed;
56
55
  top: 0;
57
56
  left: 0;
58
57
  bottom: 0;
@@ -1,6 +1,8 @@
1
1
  import clsx from 'clsx';
2
2
  import { DateTime } from 'luxon';
3
3
  import React, { useCallback, useEffect, useRef, useState } from 'react';
4
+ import { createPortal } from 'react-dom';
5
+ import { usePopper } from 'react-popper';
4
6
  import { noop } from '../../../helpers/utils';
5
7
  import { Button, ButtonContext } from '../../Buttons';
6
8
  import { DateTimePicker } from '../../DateTime/DateTimePicker';
@@ -46,6 +48,9 @@ export const DateTimeText: React.FC<DateTimeTextProps> = ({
46
48
  ...rest
47
49
  }) => {
48
50
  const container = useRef<HTMLDivElement>(null);
51
+ const [pickerElement, setPickerElement] = useState<HTMLDivElement | null>(
52
+ null,
53
+ );
49
54
  const errorMsg: string | undefined = error;
50
55
  const [display, setDisplay] = useState<string>(() => {
51
56
  const locale = fromISODate(value, modifyTime);
@@ -54,6 +59,30 @@ export const DateTimeText: React.FC<DateTimeTextProps> = ({
54
59
 
55
60
  const [showPicker, setShowPicker] = useState(false);
56
61
 
62
+ const { styles, attributes } = usePopper(container.current, pickerElement, {
63
+ placement: 'bottom-start',
64
+ modifiers: [
65
+ {
66
+ name: 'flip',
67
+ options: {
68
+ fallbackPlacements: ['top-start', 'bottom-start'],
69
+ },
70
+ },
71
+ {
72
+ name: 'preventOverflow',
73
+ options: {
74
+ padding: 8,
75
+ },
76
+ },
77
+ {
78
+ name: 'offset',
79
+ options: {
80
+ offset: [0, 4],
81
+ },
82
+ },
83
+ ],
84
+ });
85
+
57
86
  useEffect(() => {
58
87
  const locale = fromISODate(value, modifyTime);
59
88
  setDisplay(locale ?? '');
@@ -119,31 +148,36 @@ export const DateTimeText: React.FC<DateTimeTextProps> = ({
119
148
  }}
120
149
  />
121
150
  </div>
122
- {showPicker && (
123
- <>
124
- <div
125
- className={clsx(classes.picker)}
126
- style={calculatePosition(container.current)}
127
- >
128
- <DateTimePicker
129
- value={getValue(value)}
130
- onSelected={(value) => {
131
- if (!modifyTime) {
132
- setShowPicker(false);
133
- }
134
- onChange && onChange(DateTime.fromJSDate(value).toISO(), true);
151
+ {showPicker &&
152
+ createPortal(
153
+ <>
154
+ <div
155
+ ref={setPickerElement}
156
+ className={clsx(classes.picker)}
157
+ style={styles.popper}
158
+ {...attributes.popper}
159
+ >
160
+ <DateTimePicker
161
+ value={getValue(value)}
162
+ onSelected={(value) => {
163
+ if (!modifyTime) {
164
+ setShowPicker(false);
165
+ }
166
+ onChange &&
167
+ onChange(DateTime.fromJSDate(value).toISO(), true);
168
+ }}
169
+ showTimePicker={modifyTime}
170
+ />
171
+ </div>
172
+ <div
173
+ className={clsx(classes.backdrop)}
174
+ onClick={() => {
175
+ setShowPicker(false);
135
176
  }}
136
- showTimePicker={modifyTime}
137
- />
138
- </div>
139
- <div
140
- className={clsx(classes.backdrop)}
141
- onClick={() => {
142
- setShowPicker(false);
143
- }}
144
- ></div>
145
- </>
146
- )}
177
+ ></div>
178
+ </>,
179
+ document.body,
180
+ )}
147
181
  </FormElementContainer>
148
182
  );
149
183
  };
@@ -172,22 +206,3 @@ function fromISODate(ISODateString: string, modifyTime: boolean): string {
172
206
  return ISODateString;
173
207
  }
174
208
  }
175
-
176
- const calculatePosition = (
177
- container: HTMLDivElement | null,
178
- ): React.CSSProperties => {
179
- if (!container) {
180
- return {};
181
- }
182
-
183
- const PICKER_HEIGHT = 280;
184
-
185
- const rect = container.getBoundingClientRect();
186
- const top = rect.bottom;
187
-
188
- if (top + PICKER_HEIGHT > window.innerHeight) {
189
- return { top: rect.top - PICKER_HEIGHT, left: container.offsetLeft };
190
- } else {
191
- return { top, left: container.offsetLeft };
192
- }
193
- };
@@ -19,7 +19,7 @@
19
19
 
20
20
  margin-left: -50px;
21
21
  border: none;
22
- background-color: $blue;
22
+ background-color: var(--ax-primary);
23
23
 
24
24
  transition: box-shadow 0.15s ease-in-out 0s;
25
25
 
@@ -35,16 +35,16 @@
35
35
 
36
36
  &:hover {
37
37
  border: none;
38
- background-color: rgba($blue, 0.75);
38
+ background-color: color-mix(in srgb, var(--ax-primary) 75%, transparent);
39
39
  }
40
40
 
41
41
  &.disabled {
42
42
  border: none;
43
- background-color: $gray;
43
+ background-color: var(--ax-neutral);
44
44
  cursor: default;
45
45
 
46
46
  svg * {
47
- stroke: rgba(white, 0.5);
47
+ stroke: color-mix(in srgb, white 50%, transparent);
48
48
  }
49
49
  }
50
50
  }
@@ -27,7 +27,7 @@
27
27
  grid: 1fr / 30px 1fr;
28
28
  column-gap: 8px;
29
29
 
30
- color: $dark-gray;
30
+ color: var(--ax-neutral-dark);
31
31
  font-size: 16px;
32
32
  font-weight: unset;
33
33
 
@@ -37,12 +37,12 @@
37
37
 
38
38
  &.disabled {
39
39
  .radioOutline {
40
- fill: $light-gray-2;
40
+ fill: var(--ax-neutral-lighter);
41
41
  }
42
42
 
43
43
  .checked {
44
44
  .radioDot {
45
- fill: $light-gray;
45
+ fill: var(--ax-neutral-light);
46
46
  }
47
47
  }
48
48
  }
@@ -60,7 +60,7 @@
60
60
 
61
61
  .radioOutline {
62
62
  fill: none;
63
- stroke: $gray;
63
+ stroke: var(--ax-neutral);
64
64
  stroke-width: 1;
65
65
  }
66
66
 
@@ -87,7 +87,7 @@
87
87
 
88
88
  &.hasConfirm {
89
89
  .radioOutline {
90
- stroke: $yellow;
90
+ stroke: var(--ax-warning);
91
91
  stroke-width: 3;
92
92
  }
93
93
  }