@okta/odyssey-react-mui 1.12.4 → 1.12.6
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.
- package/CHANGELOG.md +16 -0
- package/dist/Select.js +14 -8
- package/dist/Select.js.map +1 -1
- package/dist/TextField.js +1 -1
- package/dist/TextField.js.map +1 -1
- package/dist/labs/DataFilters.js +101 -24
- package/dist/labs/DataFilters.js.map +1 -1
- package/dist/src/Select.d.ts.map +1 -1
- package/dist/src/labs/DataFilters.d.ts.map +1 -1
- package/dist/tsconfig.production.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/Select.tsx +17 -12
- package/src/TextField.tsx +1 -1
- package/src/labs/DataFilters.tsx +129 -43
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@okta/odyssey-react-mui",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.6",
|
|
4
4
|
"description": "React MUI components for Odyssey, Okta's design system",
|
|
5
5
|
"author": "Okta, Inc.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@mui/system": "^5.14.9",
|
|
52
52
|
"@mui/utils": "^5.11.2",
|
|
53
53
|
"@mui/x-date-pickers": "^5.0.15",
|
|
54
|
-
"@okta/odyssey-design-tokens": "1.12.
|
|
54
|
+
"@okta/odyssey-design-tokens": "1.12.6",
|
|
55
55
|
"date-fns": "^2.30.0",
|
|
56
56
|
"i18next": "^23.5.1",
|
|
57
57
|
"material-react-table": "^2.0.2",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"react": ">=17 <19",
|
|
64
64
|
"react-dom": ">=17 <19"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "00daa33877428125405ce716101dd4c089081922"
|
|
67
67
|
}
|
package/src/Select.tsx
CHANGED
|
@@ -212,18 +212,23 @@ const Select = <
|
|
|
212
212
|
// data types that might be passed
|
|
213
213
|
const normalizedOptions = useMemo(
|
|
214
214
|
() =>
|
|
215
|
-
options.map((option) =>
|
|
216
|
-
typeof option === "object"
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
215
|
+
options.map((option) => {
|
|
216
|
+
if (typeof option === "object") {
|
|
217
|
+
/**
|
|
218
|
+
* If the value of `option?.value is an empty string, we need to make sure that we
|
|
219
|
+
* set an empty string to `value` in the normalized option so that the select component
|
|
220
|
+
* can potentially set it as the selected one in the text input
|
|
221
|
+
*/
|
|
222
|
+
const value =
|
|
223
|
+
option?.value === "" ? option.value : option.value || option.text;
|
|
224
|
+
return {
|
|
225
|
+
text: option.text,
|
|
226
|
+
value,
|
|
227
|
+
type: option.type === "heading" ? "heading" : "option",
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
return { text: option, value: option, type: "option" };
|
|
231
|
+
}),
|
|
227
232
|
[options]
|
|
228
233
|
);
|
|
229
234
|
|
package/src/TextField.tsx
CHANGED
|
@@ -191,7 +191,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
191
191
|
"aria-errormessage": errorMessageElementId,
|
|
192
192
|
"aria-labelledby": labelElementId,
|
|
193
193
|
"data-se": testId,
|
|
194
|
-
|
|
194
|
+
inputMode,
|
|
195
195
|
}}
|
|
196
196
|
inputRef={localInputRef}
|
|
197
197
|
multiline={isMultiline}
|
package/src/labs/DataFilters.tsx
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
useRef,
|
|
21
21
|
useState,
|
|
22
22
|
} from "react";
|
|
23
|
+
import styled from "@emotion/styled";
|
|
23
24
|
import { Autocomplete } from "../Autocomplete";
|
|
24
25
|
import { Box } from "../Box";
|
|
25
26
|
import { TagList } from "../TagList";
|
|
@@ -175,22 +176,60 @@ const DataFilters = ({
|
|
|
175
176
|
}
|
|
176
177
|
}, [onChangeSearch, searchValue, searchDelayTime, hasSearchSubmitButton]);
|
|
177
178
|
|
|
178
|
-
const
|
|
179
|
-
|
|
179
|
+
const autocompleteOptions = useMemo(() => {
|
|
180
|
+
// Check if filterPopoverCurrentFilter and filterPopoverCurrentFilter.options are defined
|
|
181
|
+
if (
|
|
182
|
+
filterPopoverCurrentFilter?.variant === "autocomplete" &&
|
|
183
|
+
filterPopoverCurrentFilter?.options
|
|
184
|
+
) {
|
|
185
|
+
return filterPopoverCurrentFilter.options.map((option) => ({
|
|
186
|
+
label: option.label,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// if filterPopoverCurrentFilter or filterPopoverCurrentFilter.options is undefined
|
|
191
|
+
return [];
|
|
192
|
+
}, [filterPopoverCurrentFilter]);
|
|
193
|
+
|
|
194
|
+
const updateInputValue = useCallback(
|
|
195
|
+
({ filterId, value }: { filterId: string; value: DataFilterValue }) => {
|
|
180
196
|
setInputValues({ ...inputValues, [filterId]: value });
|
|
197
|
+
},
|
|
198
|
+
[inputValues]
|
|
199
|
+
);
|
|
181
200
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
201
|
+
const updateFilters = useCallback(
|
|
202
|
+
({ filterId, value }: { filterId: string; value: DataFilterValue }) => {
|
|
203
|
+
const updatedFilters = filtersProp.map((filter) => ({
|
|
204
|
+
...filter,
|
|
205
|
+
value: filter.id === filterId ? value : inputValues[filter.id],
|
|
206
|
+
}));
|
|
187
207
|
|
|
188
|
-
|
|
189
|
-
}
|
|
208
|
+
setFilters(updatedFilters);
|
|
190
209
|
},
|
|
191
210
|
[inputValues, filtersProp]
|
|
192
211
|
);
|
|
193
212
|
|
|
213
|
+
const getAutoCompleteLabel = <
|
|
214
|
+
Value extends { label: string } | Array<{ label: string }>
|
|
215
|
+
>(
|
|
216
|
+
value: Value
|
|
217
|
+
) => {
|
|
218
|
+
if (Array.isArray(value)) {
|
|
219
|
+
// Iterating to find the label
|
|
220
|
+
return value
|
|
221
|
+
.map((valueElement) => {
|
|
222
|
+
if (typeof valueElement === "string") {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
return valueElement.label;
|
|
226
|
+
})
|
|
227
|
+
.filter((item): item is string => Boolean(item));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return value?.label;
|
|
231
|
+
};
|
|
232
|
+
|
|
194
233
|
const handleMultiSelectChange = useCallback(
|
|
195
234
|
(filterId: string, value: string, submit: boolean = false) => {
|
|
196
235
|
const startingValues = filtersProp
|
|
@@ -245,6 +284,15 @@ const DataFilters = ({
|
|
|
245
284
|
setFilters(updatedFilters);
|
|
246
285
|
}, [inputValues, filtersProp]);
|
|
247
286
|
|
|
287
|
+
const AutocompleteOuterContainer = styled.div`
|
|
288
|
+
display: flex;
|
|
289
|
+
gap: 2;
|
|
290
|
+
align-items: center;
|
|
291
|
+
alignitems: "flex-end";
|
|
292
|
+
`;
|
|
293
|
+
const AutocompleteInnerContainer = styled.div`
|
|
294
|
+
width: "100%";
|
|
295
|
+
`;
|
|
248
296
|
const filterMenu = useMemo(
|
|
249
297
|
() => (
|
|
250
298
|
<>
|
|
@@ -367,23 +415,43 @@ const DataFilters = ({
|
|
|
367
415
|
{/* Autocomplete */}
|
|
368
416
|
{filterPopoverCurrentFilter?.variant === "autocomplete" &&
|
|
369
417
|
filterPopoverCurrentFilter?.options && (
|
|
370
|
-
<
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
418
|
+
<AutocompleteOuterContainer>
|
|
419
|
+
<AutocompleteInnerContainer>
|
|
420
|
+
<Autocomplete
|
|
421
|
+
label={filterPopoverCurrentFilter.label}
|
|
422
|
+
value={
|
|
423
|
+
inputValues[filterPopoverCurrentFilter.id] ?? ""
|
|
424
|
+
}
|
|
425
|
+
onChange={(_, value) => {
|
|
426
|
+
const label =
|
|
427
|
+
typeof value === "string"
|
|
428
|
+
? getAutoCompleteLabel({ label: value })
|
|
429
|
+
: Array.isArray(value)
|
|
430
|
+
? getAutoCompleteLabel(
|
|
431
|
+
value.map((item) =>
|
|
432
|
+
typeof item === "string"
|
|
433
|
+
? { label: item }
|
|
434
|
+
: item
|
|
435
|
+
)
|
|
436
|
+
)
|
|
437
|
+
: value
|
|
438
|
+
? getAutoCompleteLabel(value)
|
|
439
|
+
: "";
|
|
440
|
+
|
|
441
|
+
updateInputValue({
|
|
442
|
+
filterId: filterPopoverCurrentFilter.id,
|
|
443
|
+
value: label,
|
|
444
|
+
});
|
|
445
|
+
}}
|
|
446
|
+
options={autocompleteOptions}
|
|
447
|
+
/>
|
|
448
|
+
</AutocompleteInnerContainer>
|
|
449
|
+
<Button
|
|
450
|
+
variant="primary"
|
|
451
|
+
endIcon={<CheckIcon />}
|
|
452
|
+
type="submit"
|
|
453
|
+
/>
|
|
454
|
+
</AutocompleteOuterContainer>
|
|
387
455
|
)}
|
|
388
456
|
{/* Text or Number */}
|
|
389
457
|
{(filterPopoverCurrentFilter?.variant === "text" ||
|
|
@@ -410,10 +478,10 @@ const DataFilters = ({
|
|
|
410
478
|
] as string) ?? ""
|
|
411
479
|
}
|
|
412
480
|
onChange={(ev) =>
|
|
413
|
-
|
|
414
|
-
filterPopoverCurrentFilter.id,
|
|
415
|
-
ev.currentTarget.value
|
|
416
|
-
)
|
|
481
|
+
updateInputValue({
|
|
482
|
+
filterId: filterPopoverCurrentFilter.id,
|
|
483
|
+
value: ev.currentTarget.value,
|
|
484
|
+
})
|
|
417
485
|
}
|
|
418
486
|
endAdornment={
|
|
419
487
|
inputValues[filterPopoverCurrentFilter.id] && (
|
|
@@ -421,11 +489,15 @@ const DataFilters = ({
|
|
|
421
489
|
size="small"
|
|
422
490
|
aria-label="Clear filter"
|
|
423
491
|
onClick={() => {
|
|
424
|
-
|
|
425
|
-
filterPopoverCurrentFilter.id,
|
|
426
|
-
undefined,
|
|
427
|
-
|
|
428
|
-
|
|
492
|
+
updateInputValue({
|
|
493
|
+
filterId: filterPopoverCurrentFilter.id,
|
|
494
|
+
value: undefined,
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
updateFilters({
|
|
498
|
+
filterId: filterPopoverCurrentFilter.id,
|
|
499
|
+
value: undefined,
|
|
500
|
+
});
|
|
429
501
|
}}
|
|
430
502
|
>
|
|
431
503
|
<CloseCircleFilledIcon />
|
|
@@ -480,13 +552,17 @@ const DataFilters = ({
|
|
|
480
552
|
filterPopoverCurrentFilter?.options && (
|
|
481
553
|
<RadioGroup
|
|
482
554
|
label={filterPopoverCurrentFilter.label}
|
|
483
|
-
onChange={(_, value) =>
|
|
484
|
-
|
|
485
|
-
filterPopoverCurrentFilter.id,
|
|
555
|
+
onChange={(_, value) => {
|
|
556
|
+
updateInputValue({
|
|
557
|
+
filterId: filterPopoverCurrentFilter.id,
|
|
486
558
|
value,
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
updateFilters({
|
|
562
|
+
filterId: filterPopoverCurrentFilter.id,
|
|
563
|
+
value,
|
|
564
|
+
});
|
|
565
|
+
}}
|
|
490
566
|
>
|
|
491
567
|
<Radio
|
|
492
568
|
label="Any"
|
|
@@ -561,7 +637,7 @@ const DataFilters = ({
|
|
|
561
637
|
<Button
|
|
562
638
|
variant="secondary"
|
|
563
639
|
label="Clear filters"
|
|
564
|
-
onClick={
|
|
640
|
+
onClick={clearAllFilters}
|
|
565
641
|
/>
|
|
566
642
|
</Box>
|
|
567
643
|
)}
|
|
@@ -585,7 +661,17 @@ const DataFilters = ({
|
|
|
585
661
|
<Tag
|
|
586
662
|
key={filter.label}
|
|
587
663
|
label={`${filter.label}: ${filter.value}`}
|
|
588
|
-
onRemove={() =>
|
|
664
|
+
onRemove={() => {
|
|
665
|
+
updateInputValue({
|
|
666
|
+
filterId: filter.id,
|
|
667
|
+
value: undefined,
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
updateFilters({
|
|
671
|
+
filterId: filter.id,
|
|
672
|
+
value: undefined,
|
|
673
|
+
});
|
|
674
|
+
}}
|
|
589
675
|
/>
|
|
590
676
|
))}
|
|
591
677
|
</TagList>
|