@mackin.com/styleguide 10.2.1 → 10.2.4
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/index.d.ts +1 -1
- package/index.esm.js +105 -32
- package/index.js +105 -32
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -863,7 +863,7 @@ interface SliderProps<T extends SliderValue> {
|
|
|
863
863
|
innerTrackClassName?: string;
|
|
864
864
|
/** Styles applied to the floating handle text with using 'showValue'. */
|
|
865
865
|
sliderTextClassName?: string;
|
|
866
|
-
/**
|
|
866
|
+
/** Sets the aria-label value. */
|
|
867
867
|
ariaLabel?: (T extends number ? string : readonly string[] | undefined) | undefined;
|
|
868
868
|
}
|
|
869
869
|
declare const Slider: <T extends SliderValue>(p: SliderProps<T>) => React__default.JSX.Element;
|
package/index.esm.js
CHANGED
|
@@ -497,6 +497,45 @@ const Button = React.forwardRef((props, ref) => {
|
|
|
497
497
|
return content;
|
|
498
498
|
});
|
|
499
499
|
|
|
500
|
+
/* Type is not always determinable due to the nature of custom components in typescript. For example OmniLink will not have a type of "a" but rather "OmniLink" so we have to determine
|
|
501
|
+
if the child component is focusable based on certain properties on the control that are found on focusable components */
|
|
502
|
+
const isChildFocusable = (props, type) => {
|
|
503
|
+
if (props.tabIndex !== undefined && props.tabIndex !== null) {
|
|
504
|
+
return true;
|
|
505
|
+
}
|
|
506
|
+
if (props.onClick !== undefined || props.onValueChange !== undefined) { //button or select
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
if (props.href || props.cols || props.rows || props.maxLength) {
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
if ((type === 'button' || type === 'input' || type === 'select' || type === 'textarea') && !props.disabled) {
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
return false;
|
|
516
|
+
};
|
|
517
|
+
const TabIndexContainer = (props) => {
|
|
518
|
+
const processElement = (node) => {
|
|
519
|
+
if (!React__default.isValidElement(node)) {
|
|
520
|
+
return node;
|
|
521
|
+
}
|
|
522
|
+
let updatedNode = node;
|
|
523
|
+
// Use the props-based logic to check focusability
|
|
524
|
+
if (isChildFocusable(node.props, node.type)) {
|
|
525
|
+
updatedNode = React__default.cloneElement(node, { tabIndex: props.tabIndexValue });
|
|
526
|
+
}
|
|
527
|
+
// Recursively process children
|
|
528
|
+
if (updatedNode.props.children) {
|
|
529
|
+
const clonedChildren = React__default.Children.map(updatedNode.props.children, processElement);
|
|
530
|
+
updatedNode = React__default.cloneElement(updatedNode, {
|
|
531
|
+
children: clonedChildren,
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
return updatedNode;
|
|
535
|
+
};
|
|
536
|
+
return (React__default.createElement(React__default.Fragment, null, React__default.Children.map(props.children, processElement)));
|
|
537
|
+
};
|
|
538
|
+
|
|
500
539
|
const accordianExpandTimeMs = 250;
|
|
501
540
|
const accordianMaxHeight = 1020;
|
|
502
541
|
const accordianTimingFunction = 'ease-in-out';
|
|
@@ -544,7 +583,7 @@ const Accordian = (props) => {
|
|
|
544
583
|
}
|
|
545
584
|
setOpen((_a = props.open) !== null && _a !== void 0 ? _a : false);
|
|
546
585
|
}, [props.open]);
|
|
547
|
-
return (React.createElement("div", { className: "accordian" },
|
|
586
|
+
return (React.createElement("div", { className: "accordian", "aria-expanded": open },
|
|
548
587
|
React.createElement(Button, { readOnly: props.disabled, variant: props.variant, className: cx(css({
|
|
549
588
|
display: 'flex',
|
|
550
589
|
alignItems: 'center',
|
|
@@ -563,7 +602,8 @@ const Accordian = (props) => {
|
|
|
563
602
|
}, rightIcon: !props.disabled ? React.createElement(Icon, { id: open ? 'collapse' : 'expand' }) : undefined },
|
|
564
603
|
React.createElement("span", null, props.header)),
|
|
565
604
|
React.createElement("div", { ref: content, className: cx('accordian__body', contentStyles) },
|
|
566
|
-
React.createElement("div", { className: expandedContentWrapperStyles },
|
|
605
|
+
React.createElement("div", { className: expandedContentWrapperStyles },
|
|
606
|
+
React.createElement(TabIndexContainer, { tabIndexValue: open ? 0 : -1 }, props.children)))));
|
|
567
607
|
};
|
|
568
608
|
const useAccordianState = (count, openIndex) => {
|
|
569
609
|
const [panels, setShowPanel] = React.useState(new Array(count).fill(false).map((b, i) => {
|
|
@@ -969,13 +1009,14 @@ const defaultMaxShownValues = 7;
|
|
|
969
1009
|
const buttonMarkerClass = 'ListItem__button';
|
|
970
1010
|
const defaultOnPickFocusMs = 100;
|
|
971
1011
|
const Autocomplete = (p) => {
|
|
972
|
-
var _a;
|
|
1012
|
+
var _a, _b;
|
|
973
1013
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
974
1014
|
const inputProps = __rest(p, ["value", "className", "inputWrapperClassName", "inputClassName", "listClassName", "listItemClassName", "listItemButtonClassName", "maxShownValues", "allowScroll", "options", "onPick", "onPickFocusWaitMs"]);
|
|
975
1015
|
const theme = useThemeSafely();
|
|
976
1016
|
const element = React.useRef(null);
|
|
977
1017
|
const input = React.useRef(null);
|
|
978
1018
|
const list = React.useRef(null);
|
|
1019
|
+
const [selectedResultIndex, setSelectedResultIndex] = React.useState();
|
|
979
1020
|
const maxShowValues = (_a = p.maxShownValues) !== null && _a !== void 0 ? _a : defaultMaxShownValues;
|
|
980
1021
|
const displayOptions = React.useMemo(() => {
|
|
981
1022
|
if (!p.allowScroll) {
|
|
@@ -994,10 +1035,12 @@ const Autocomplete = (p) => {
|
|
|
994
1035
|
if (direction === -1) {
|
|
995
1036
|
buttonIndex = displayOptions.length - 1;
|
|
996
1037
|
}
|
|
1038
|
+
setSelectedResultIndex(buttonIndex);
|
|
997
1039
|
return (_a = list.current) === null || _a === void 0 ? void 0 : _a.querySelector(`.${buttonMarkerClass}${buttonIndex}`);
|
|
998
1040
|
}
|
|
999
1041
|
else {
|
|
1000
1042
|
const nextIndex = fromIndex + direction;
|
|
1043
|
+
setSelectedResultIndex(nextIndex);
|
|
1001
1044
|
if (nextIndex >= displayOptions.length || nextIndex < 0) {
|
|
1002
1045
|
return (_b = input.current) !== null && _b !== void 0 ? _b : undefined;
|
|
1003
1046
|
}
|
|
@@ -1021,6 +1064,7 @@ const Autocomplete = (p) => {
|
|
|
1021
1064
|
if (p.round || theme.controls.borderRadius) {
|
|
1022
1065
|
listBorderRadius = theme.controls.borderRadius || '0.5rem';
|
|
1023
1066
|
}
|
|
1067
|
+
const id = (_b = p.id) !== null && _b !== void 0 ? _b : `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1024
1068
|
const onPickValue = (v) => {
|
|
1025
1069
|
var _a;
|
|
1026
1070
|
// the TextInput will not respond to outer value changes if it has focus.
|
|
@@ -1068,8 +1112,9 @@ const Autocomplete = (p) => {
|
|
|
1068
1112
|
}
|
|
1069
1113
|
}
|
|
1070
1114
|
(_c = p.onKeyDown) === null || _c === void 0 ? void 0 : _c.call(p, e);
|
|
1071
|
-
} })),
|
|
1072
|
-
|
|
1115
|
+
}, "aria-owns": id, "aria-expanded": !!displayOptions.length, "aria-autocomplete": "both", "aria-describedby": `${id}-aria-description` })),
|
|
1116
|
+
React.createElement("span", { id: `${id}-aria-description`, className: css({ display: "none" }) }, "When autocomplete results are available use up and down arrows to review and enter to select."),
|
|
1117
|
+
!!displayOptions.length && (React.createElement(List, { id: id, ref: list, role: "listbox", className: cx(css({
|
|
1073
1118
|
position: 'absolute',
|
|
1074
1119
|
width: '100%',
|
|
1075
1120
|
border: theme.controls.border,
|
|
@@ -1092,7 +1137,7 @@ const Autocomplete = (p) => {
|
|
|
1092
1137
|
}), p.listClassName) },
|
|
1093
1138
|
displayOptions.map((v, listItemIndex) => {
|
|
1094
1139
|
var _a;
|
|
1095
|
-
return (React.createElement(ListItem, { key: v, variant: "full", className: p.listItemClassName },
|
|
1140
|
+
return (React.createElement(ListItem, { key: v, variant: "full", className: p.listItemClassName, role: "option", "aria-selected": selectedResultIndex === listItemIndex },
|
|
1096
1141
|
React.createElement(Button, { title: ((_a = p.showOptionTextAsTitle) !== null && _a !== void 0 ? _a : true) ? v : undefined, onKeyDown: e => {
|
|
1097
1142
|
var _a, _b;
|
|
1098
1143
|
if (e.key === 'ArrowDown') {
|
|
@@ -1258,15 +1303,18 @@ const useLogger = (componentName, enabled) => {
|
|
|
1258
1303
|
const portalId = 'backdrop';
|
|
1259
1304
|
const BackdropContext = React__default.createContext({
|
|
1260
1305
|
showing: false,
|
|
1261
|
-
showCount: 0,
|
|
1262
1306
|
portalId: portalId,
|
|
1307
|
+
children: [],
|
|
1263
1308
|
setShow: () => {
|
|
1264
1309
|
/* empty */
|
|
1265
1310
|
}
|
|
1266
1311
|
});
|
|
1312
|
+
function useBackdropContext() {
|
|
1313
|
+
return useContext(BackdropContext);
|
|
1314
|
+
}
|
|
1267
1315
|
const BackdropContextProvider = (p) => {
|
|
1268
1316
|
var _a;
|
|
1269
|
-
const [
|
|
1317
|
+
const [modalChildren, setModalChildren] = useState([]);
|
|
1270
1318
|
const log = useLogger('BackdropContextProvider', (_a = p.__debug) !== null && _a !== void 0 ? _a : false);
|
|
1271
1319
|
if (p.__debug) {
|
|
1272
1320
|
useEffect(() => {
|
|
@@ -1276,26 +1324,38 @@ const BackdropContextProvider = (p) => {
|
|
|
1276
1324
|
};
|
|
1277
1325
|
}, []);
|
|
1278
1326
|
useIgnoreMount(() => {
|
|
1279
|
-
log('showCount changed',
|
|
1280
|
-
}, [
|
|
1327
|
+
log('showCount changed', modalChildren);
|
|
1328
|
+
}, [modalChildren]);
|
|
1281
1329
|
}
|
|
1282
1330
|
return (React__default.createElement(BackdropContext.Provider, { value: {
|
|
1283
1331
|
portalId: portalId,
|
|
1284
|
-
showing:
|
|
1285
|
-
|
|
1332
|
+
showing: modalChildren.length > 0,
|
|
1333
|
+
children: modalChildren.slice(),
|
|
1286
1334
|
setShow: (show, from) => {
|
|
1287
1335
|
if (show) {
|
|
1288
|
-
|
|
1289
|
-
const
|
|
1290
|
-
log(`
|
|
1291
|
-
return
|
|
1336
|
+
setModalChildren(previousChildren => {
|
|
1337
|
+
const newChildren = [...previousChildren, from];
|
|
1338
|
+
log(`setModalChildren TRUE from ${JSON.stringify(from)}.`);
|
|
1339
|
+
return newChildren;
|
|
1292
1340
|
});
|
|
1293
1341
|
}
|
|
1294
1342
|
else {
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1343
|
+
setModalChildren(previousChildren => {
|
|
1344
|
+
let newChildren;
|
|
1345
|
+
if (from.key === backdropOverlayKey && !show) {
|
|
1346
|
+
if (previousChildren.length === 1) {
|
|
1347
|
+
newChildren = [];
|
|
1348
|
+
}
|
|
1349
|
+
else {
|
|
1350
|
+
newChildren = [...previousChildren];
|
|
1351
|
+
newChildren.pop();
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
else {
|
|
1355
|
+
newChildren = previousChildren.filter(c => c.key !== from.key);
|
|
1356
|
+
}
|
|
1357
|
+
log(`setModalChildren FALSE from ${JSON.stringify(from)}.`);
|
|
1358
|
+
return newChildren;
|
|
1299
1359
|
});
|
|
1300
1360
|
}
|
|
1301
1361
|
}
|
|
@@ -1310,9 +1370,10 @@ const BackdropContextProvider = (p) => {
|
|
|
1310
1370
|
margin: 0,
|
|
1311
1371
|
zIndex: 9999
|
|
1312
1372
|
})) },
|
|
1313
|
-
"Backdrop
|
|
1314
|
-
|
|
1373
|
+
"Backdrop children: ",
|
|
1374
|
+
JSON.stringify(modalChildren, null, 4)))));
|
|
1315
1375
|
};
|
|
1376
|
+
const backdropOverlayKey = 'BackdropOverlay';
|
|
1316
1377
|
const BackdropOverlay = (p) => {
|
|
1317
1378
|
var _a, _b;
|
|
1318
1379
|
const context = useContext(BackdropContext);
|
|
@@ -1330,15 +1391,25 @@ const BackdropOverlay = (p) => {
|
|
|
1330
1391
|
log('context.showing changed', context.showing);
|
|
1331
1392
|
}, [context.showing]);
|
|
1332
1393
|
}
|
|
1394
|
+
let zIndex = -1;
|
|
1395
|
+
if (context.showing) {
|
|
1396
|
+
zIndex = theme.zIndexes.backdrop;
|
|
1397
|
+
context.children.forEach(child => {
|
|
1398
|
+
if (child.zIndex > zIndex) {
|
|
1399
|
+
// -1 so it's always directly below the child
|
|
1400
|
+
zIndex = child.zIndex - 1;
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1333
1404
|
return (React__default.createElement("div", { onClick: () => {
|
|
1334
|
-
context === null || context === void 0 ? void 0 : context.setShow(false,
|
|
1405
|
+
context === null || context === void 0 ? void 0 : context.setShow(false, { key: backdropOverlayKey, zIndex });
|
|
1335
1406
|
log('onClick', 'setShow', false);
|
|
1336
1407
|
}, id: context === null || context === void 0 ? void 0 : context.portalId, className: css({
|
|
1337
1408
|
cursor: 'pointer',
|
|
1338
1409
|
position: 'fixed',
|
|
1339
1410
|
top: 0, right: 0, bottom: 0, left: 0,
|
|
1340
1411
|
backgroundColor: theme.colors.backdrop,
|
|
1341
|
-
zIndex
|
|
1412
|
+
zIndex,
|
|
1342
1413
|
visibility: (context === null || context === void 0 ? void 0 : context.showing) ? 'visible' : 'hidden',
|
|
1343
1414
|
opacity: (context === null || context === void 0 ? void 0 : context.showing) ? 1 : 0,
|
|
1344
1415
|
transition: `opacity ${showTimeMs}ms ease-in-out`,
|
|
@@ -1582,7 +1653,7 @@ const useScrollbarSize = (recalc) => {
|
|
|
1582
1653
|
|
|
1583
1654
|
const Modal = (p) => {
|
|
1584
1655
|
var _a, _b, _c, _d;
|
|
1585
|
-
const backdrop =
|
|
1656
|
+
const backdrop = useBackdropContext();
|
|
1586
1657
|
const mouseDownElement = useRef(undefined);
|
|
1587
1658
|
const theme = useThemeSafely();
|
|
1588
1659
|
const hasHeader = p.closeButton || p.heading;
|
|
@@ -1623,13 +1694,14 @@ const Modal = (p) => {
|
|
|
1623
1694
|
});
|
|
1624
1695
|
}
|
|
1625
1696
|
};
|
|
1697
|
+
const zIndex = theme.zIndexes.modal;
|
|
1626
1698
|
useEffect(() => {
|
|
1627
1699
|
log('mounted');
|
|
1628
1700
|
return () => {
|
|
1629
1701
|
var _a;
|
|
1630
1702
|
if (showing.current) {
|
|
1631
1703
|
log(`un-mount in progress and this modal is showing. decrement the backdrop and try to remove singleton body styles.`);
|
|
1632
|
-
backdrop.setShow(false, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
|
|
1704
|
+
backdrop.setShow(false, { key: (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', zIndex });
|
|
1633
1705
|
log('backdrop.setShow', false);
|
|
1634
1706
|
tryRemoveScrollStyles();
|
|
1635
1707
|
}
|
|
@@ -1642,7 +1714,7 @@ const Modal = (p) => {
|
|
|
1642
1714
|
useBooleanChanged((show, previousShow) => {
|
|
1643
1715
|
var _a;
|
|
1644
1716
|
log('show changed', `${previousShow !== null && previousShow !== void 0 ? previousShow : 'undefined'} > ${show}`);
|
|
1645
|
-
backdrop.setShow(show, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
|
|
1717
|
+
backdrop.setShow(show, { key: (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', zIndex });
|
|
1646
1718
|
showing.current = show;
|
|
1647
1719
|
log('backdrop.setShow', show);
|
|
1648
1720
|
if (show) {
|
|
@@ -1670,7 +1742,7 @@ const Modal = (p) => {
|
|
|
1670
1742
|
const modalBodyStyles = css({
|
|
1671
1743
|
maxHeight: p.scrollable ? undefined : '99vh',
|
|
1672
1744
|
overflow: 'hidden',
|
|
1673
|
-
zIndex
|
|
1745
|
+
zIndex,
|
|
1674
1746
|
cursor: 'default',
|
|
1675
1747
|
margin: '1rem',
|
|
1676
1748
|
backgroundColor: p.noBackground ? undefined : theme.colors.modalBg,
|
|
@@ -2722,7 +2794,7 @@ const Nav = (props) => {
|
|
|
2722
2794
|
const theme = useThemeSafely();
|
|
2723
2795
|
const navWidth = (_a = props.navWidth) !== null && _a !== void 0 ? _a : theme.layout.navWidth;
|
|
2724
2796
|
const totalNavOffset = `calc(${navWidth} + 20px)`;
|
|
2725
|
-
const backdrop =
|
|
2797
|
+
const backdrop = useBackdropContext();
|
|
2726
2798
|
const log = useLogger(`Nav ${(_b = props.id) !== null && _b !== void 0 ? _b : '?'}`, (_c = props.__debug) !== null && _c !== void 0 ? _c : false);
|
|
2727
2799
|
const slideMs = (_d = props.slideMs) !== null && _d !== void 0 ? _d : theme.timings.nav.slideMs;
|
|
2728
2800
|
const slideRight = keyframes `
|
|
@@ -2749,6 +2821,7 @@ const Nav = (props) => {
|
|
|
2749
2821
|
const classNavNotShowing = css `
|
|
2750
2822
|
animation: ${slideLeft} ${slideMs}ms cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
|
|
2751
2823
|
`;
|
|
2824
|
+
const zIndex = theme.zIndexes.nav;
|
|
2752
2825
|
// the padding-top here is to offset the navs' content from the header. the shadow creeps over it.
|
|
2753
2826
|
const navStyles = css `
|
|
2754
2827
|
label: Nav;
|
|
@@ -2761,7 +2834,7 @@ const Nav = (props) => {
|
|
|
2761
2834
|
width: ${navWidth};
|
|
2762
2835
|
min-width: ${navWidth};
|
|
2763
2836
|
box-shadow: 4px 2px 12px 6px rgba(0, 0, 0, 0.2);
|
|
2764
|
-
z-index: ${
|
|
2837
|
+
z-index: ${zIndex};
|
|
2765
2838
|
overflow-y: auto;
|
|
2766
2839
|
.omniLink, .omniLink:active, .omniLink:focus, .omniLink:visited {
|
|
2767
2840
|
color: ${theme.colors.navFont};
|
|
@@ -2776,7 +2849,7 @@ const Nav = (props) => {
|
|
|
2776
2849
|
useBooleanChanged((current, previous) => {
|
|
2777
2850
|
var _a;
|
|
2778
2851
|
log('show changed', `${previous !== null && previous !== void 0 ? previous : 'undefined'} > ${current}`);
|
|
2779
|
-
backdrop.setShow(current, (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav');
|
|
2852
|
+
backdrop.setShow(current, { key: (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav', zIndex });
|
|
2780
2853
|
}, props.show);
|
|
2781
2854
|
React.useLayoutEffect(() => {
|
|
2782
2855
|
if (nav && nav.current) {
|
|
@@ -4016,7 +4089,7 @@ const TabHeader = (p) => {
|
|
|
4016
4089
|
buttonContent = tab.name;
|
|
4017
4090
|
}
|
|
4018
4091
|
return (React.createElement("li", { key: index, className: cx(tabStyles, p.tabClassName) },
|
|
4019
|
-
React.createElement(Button, { disabled: tabsChanging, className: buttonStyles, variant: buttonVariant, title: title, readOnly: active, onClick: () => {
|
|
4092
|
+
React.createElement(Button, { "aria-role": "tab", "aria-selected": active, disabled: tabsChanging, className: buttonStyles, variant: buttonVariant, title: title, readOnly: active, onClick: () => {
|
|
4020
4093
|
const onChange = () => {
|
|
4021
4094
|
var _a;
|
|
4022
4095
|
setTabIndex(index);
|
package/index.js
CHANGED
|
@@ -515,6 +515,45 @@ const Button = React__namespace.forwardRef((props, ref) => {
|
|
|
515
515
|
return content;
|
|
516
516
|
});
|
|
517
517
|
|
|
518
|
+
/* Type is not always determinable due to the nature of custom components in typescript. For example OmniLink will not have a type of "a" but rather "OmniLink" so we have to determine
|
|
519
|
+
if the child component is focusable based on certain properties on the control that are found on focusable components */
|
|
520
|
+
const isChildFocusable = (props, type) => {
|
|
521
|
+
if (props.tabIndex !== undefined && props.tabIndex !== null) {
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
524
|
+
if (props.onClick !== undefined || props.onValueChange !== undefined) { //button or select
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
if (props.href || props.cols || props.rows || props.maxLength) {
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
if ((type === 'button' || type === 'input' || type === 'select' || type === 'textarea') && !props.disabled) {
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
return false;
|
|
534
|
+
};
|
|
535
|
+
const TabIndexContainer = (props) => {
|
|
536
|
+
const processElement = (node) => {
|
|
537
|
+
if (!React.isValidElement(node)) {
|
|
538
|
+
return node;
|
|
539
|
+
}
|
|
540
|
+
let updatedNode = node;
|
|
541
|
+
// Use the props-based logic to check focusability
|
|
542
|
+
if (isChildFocusable(node.props, node.type)) {
|
|
543
|
+
updatedNode = React.cloneElement(node, { tabIndex: props.tabIndexValue });
|
|
544
|
+
}
|
|
545
|
+
// Recursively process children
|
|
546
|
+
if (updatedNode.props.children) {
|
|
547
|
+
const clonedChildren = React.Children.map(updatedNode.props.children, processElement);
|
|
548
|
+
updatedNode = React.cloneElement(updatedNode, {
|
|
549
|
+
children: clonedChildren,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return updatedNode;
|
|
553
|
+
};
|
|
554
|
+
return (React.createElement(React.Fragment, null, React.Children.map(props.children, processElement)));
|
|
555
|
+
};
|
|
556
|
+
|
|
518
557
|
const accordianExpandTimeMs = 250;
|
|
519
558
|
const accordianMaxHeight = 1020;
|
|
520
559
|
const accordianTimingFunction = 'ease-in-out';
|
|
@@ -562,7 +601,7 @@ const Accordian = (props) => {
|
|
|
562
601
|
}
|
|
563
602
|
setOpen((_a = props.open) !== null && _a !== void 0 ? _a : false);
|
|
564
603
|
}, [props.open]);
|
|
565
|
-
return (React__namespace.createElement("div", { className: "accordian" },
|
|
604
|
+
return (React__namespace.createElement("div", { className: "accordian", "aria-expanded": open },
|
|
566
605
|
React__namespace.createElement(Button, { readOnly: props.disabled, variant: props.variant, className: css.cx(css.css({
|
|
567
606
|
display: 'flex',
|
|
568
607
|
alignItems: 'center',
|
|
@@ -581,7 +620,8 @@ const Accordian = (props) => {
|
|
|
581
620
|
}, rightIcon: !props.disabled ? React__namespace.createElement(Icon, { id: open ? 'collapse' : 'expand' }) : undefined },
|
|
582
621
|
React__namespace.createElement("span", null, props.header)),
|
|
583
622
|
React__namespace.createElement("div", { ref: content, className: css.cx('accordian__body', contentStyles) },
|
|
584
|
-
React__namespace.createElement("div", { className: expandedContentWrapperStyles },
|
|
623
|
+
React__namespace.createElement("div", { className: expandedContentWrapperStyles },
|
|
624
|
+
React__namespace.createElement(TabIndexContainer, { tabIndexValue: open ? 0 : -1 }, props.children)))));
|
|
585
625
|
};
|
|
586
626
|
const useAccordianState = (count, openIndex) => {
|
|
587
627
|
const [panels, setShowPanel] = React__namespace.useState(new Array(count).fill(false).map((b, i) => {
|
|
@@ -987,13 +1027,14 @@ const defaultMaxShownValues = 7;
|
|
|
987
1027
|
const buttonMarkerClass = 'ListItem__button';
|
|
988
1028
|
const defaultOnPickFocusMs = 100;
|
|
989
1029
|
const Autocomplete = (p) => {
|
|
990
|
-
var _a;
|
|
1030
|
+
var _a, _b;
|
|
991
1031
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
992
1032
|
const inputProps = __rest(p, ["value", "className", "inputWrapperClassName", "inputClassName", "listClassName", "listItemClassName", "listItemButtonClassName", "maxShownValues", "allowScroll", "options", "onPick", "onPickFocusWaitMs"]);
|
|
993
1033
|
const theme = useThemeSafely();
|
|
994
1034
|
const element = React__namespace.useRef(null);
|
|
995
1035
|
const input = React__namespace.useRef(null);
|
|
996
1036
|
const list = React__namespace.useRef(null);
|
|
1037
|
+
const [selectedResultIndex, setSelectedResultIndex] = React__namespace.useState();
|
|
997
1038
|
const maxShowValues = (_a = p.maxShownValues) !== null && _a !== void 0 ? _a : defaultMaxShownValues;
|
|
998
1039
|
const displayOptions = React__namespace.useMemo(() => {
|
|
999
1040
|
if (!p.allowScroll) {
|
|
@@ -1012,10 +1053,12 @@ const Autocomplete = (p) => {
|
|
|
1012
1053
|
if (direction === -1) {
|
|
1013
1054
|
buttonIndex = displayOptions.length - 1;
|
|
1014
1055
|
}
|
|
1056
|
+
setSelectedResultIndex(buttonIndex);
|
|
1015
1057
|
return (_a = list.current) === null || _a === void 0 ? void 0 : _a.querySelector(`.${buttonMarkerClass}${buttonIndex}`);
|
|
1016
1058
|
}
|
|
1017
1059
|
else {
|
|
1018
1060
|
const nextIndex = fromIndex + direction;
|
|
1061
|
+
setSelectedResultIndex(nextIndex);
|
|
1019
1062
|
if (nextIndex >= displayOptions.length || nextIndex < 0) {
|
|
1020
1063
|
return (_b = input.current) !== null && _b !== void 0 ? _b : undefined;
|
|
1021
1064
|
}
|
|
@@ -1039,6 +1082,7 @@ const Autocomplete = (p) => {
|
|
|
1039
1082
|
if (p.round || theme.controls.borderRadius) {
|
|
1040
1083
|
listBorderRadius = theme.controls.borderRadius || '0.5rem';
|
|
1041
1084
|
}
|
|
1085
|
+
const id = (_b = p.id) !== null && _b !== void 0 ? _b : `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1042
1086
|
const onPickValue = (v) => {
|
|
1043
1087
|
var _a;
|
|
1044
1088
|
// the TextInput will not respond to outer value changes if it has focus.
|
|
@@ -1086,8 +1130,9 @@ const Autocomplete = (p) => {
|
|
|
1086
1130
|
}
|
|
1087
1131
|
}
|
|
1088
1132
|
(_c = p.onKeyDown) === null || _c === void 0 ? void 0 : _c.call(p, e);
|
|
1089
|
-
} })),
|
|
1090
|
-
|
|
1133
|
+
}, "aria-owns": id, "aria-expanded": !!displayOptions.length, "aria-autocomplete": "both", "aria-describedby": `${id}-aria-description` })),
|
|
1134
|
+
React__namespace.createElement("span", { id: `${id}-aria-description`, className: css.css({ display: "none" }) }, "When autocomplete results are available use up and down arrows to review and enter to select."),
|
|
1135
|
+
!!displayOptions.length && (React__namespace.createElement(List, { id: id, ref: list, role: "listbox", className: css.cx(css.css({
|
|
1091
1136
|
position: 'absolute',
|
|
1092
1137
|
width: '100%',
|
|
1093
1138
|
border: theme.controls.border,
|
|
@@ -1110,7 +1155,7 @@ const Autocomplete = (p) => {
|
|
|
1110
1155
|
}), p.listClassName) },
|
|
1111
1156
|
displayOptions.map((v, listItemIndex) => {
|
|
1112
1157
|
var _a;
|
|
1113
|
-
return (React__namespace.createElement(ListItem, { key: v, variant: "full", className: p.listItemClassName },
|
|
1158
|
+
return (React__namespace.createElement(ListItem, { key: v, variant: "full", className: p.listItemClassName, role: "option", "aria-selected": selectedResultIndex === listItemIndex },
|
|
1114
1159
|
React__namespace.createElement(Button, { title: ((_a = p.showOptionTextAsTitle) !== null && _a !== void 0 ? _a : true) ? v : undefined, onKeyDown: e => {
|
|
1115
1160
|
var _a, _b;
|
|
1116
1161
|
if (e.key === 'ArrowDown') {
|
|
@@ -1276,15 +1321,18 @@ const useLogger = (componentName, enabled) => {
|
|
|
1276
1321
|
const portalId = 'backdrop';
|
|
1277
1322
|
const BackdropContext = React.createContext({
|
|
1278
1323
|
showing: false,
|
|
1279
|
-
showCount: 0,
|
|
1280
1324
|
portalId: portalId,
|
|
1325
|
+
children: [],
|
|
1281
1326
|
setShow: () => {
|
|
1282
1327
|
/* empty */
|
|
1283
1328
|
}
|
|
1284
1329
|
});
|
|
1330
|
+
function useBackdropContext() {
|
|
1331
|
+
return React.useContext(BackdropContext);
|
|
1332
|
+
}
|
|
1285
1333
|
const BackdropContextProvider = (p) => {
|
|
1286
1334
|
var _a;
|
|
1287
|
-
const [
|
|
1335
|
+
const [modalChildren, setModalChildren] = React.useState([]);
|
|
1288
1336
|
const log = useLogger('BackdropContextProvider', (_a = p.__debug) !== null && _a !== void 0 ? _a : false);
|
|
1289
1337
|
if (p.__debug) {
|
|
1290
1338
|
React.useEffect(() => {
|
|
@@ -1294,26 +1342,38 @@ const BackdropContextProvider = (p) => {
|
|
|
1294
1342
|
};
|
|
1295
1343
|
}, []);
|
|
1296
1344
|
useIgnoreMount(() => {
|
|
1297
|
-
log('showCount changed',
|
|
1298
|
-
}, [
|
|
1345
|
+
log('showCount changed', modalChildren);
|
|
1346
|
+
}, [modalChildren]);
|
|
1299
1347
|
}
|
|
1300
1348
|
return (React.createElement(BackdropContext.Provider, { value: {
|
|
1301
1349
|
portalId: portalId,
|
|
1302
|
-
showing:
|
|
1303
|
-
|
|
1350
|
+
showing: modalChildren.length > 0,
|
|
1351
|
+
children: modalChildren.slice(),
|
|
1304
1352
|
setShow: (show, from) => {
|
|
1305
1353
|
if (show) {
|
|
1306
|
-
|
|
1307
|
-
const
|
|
1308
|
-
log(`
|
|
1309
|
-
return
|
|
1354
|
+
setModalChildren(previousChildren => {
|
|
1355
|
+
const newChildren = [...previousChildren, from];
|
|
1356
|
+
log(`setModalChildren TRUE from ${JSON.stringify(from)}.`);
|
|
1357
|
+
return newChildren;
|
|
1310
1358
|
});
|
|
1311
1359
|
}
|
|
1312
1360
|
else {
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1361
|
+
setModalChildren(previousChildren => {
|
|
1362
|
+
let newChildren;
|
|
1363
|
+
if (from.key === backdropOverlayKey && !show) {
|
|
1364
|
+
if (previousChildren.length === 1) {
|
|
1365
|
+
newChildren = [];
|
|
1366
|
+
}
|
|
1367
|
+
else {
|
|
1368
|
+
newChildren = [...previousChildren];
|
|
1369
|
+
newChildren.pop();
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
else {
|
|
1373
|
+
newChildren = previousChildren.filter(c => c.key !== from.key);
|
|
1374
|
+
}
|
|
1375
|
+
log(`setModalChildren FALSE from ${JSON.stringify(from)}.`);
|
|
1376
|
+
return newChildren;
|
|
1317
1377
|
});
|
|
1318
1378
|
}
|
|
1319
1379
|
}
|
|
@@ -1328,9 +1388,10 @@ const BackdropContextProvider = (p) => {
|
|
|
1328
1388
|
margin: 0,
|
|
1329
1389
|
zIndex: 9999
|
|
1330
1390
|
})) },
|
|
1331
|
-
"Backdrop
|
|
1332
|
-
|
|
1391
|
+
"Backdrop children: ",
|
|
1392
|
+
JSON.stringify(modalChildren, null, 4)))));
|
|
1333
1393
|
};
|
|
1394
|
+
const backdropOverlayKey = 'BackdropOverlay';
|
|
1334
1395
|
const BackdropOverlay = (p) => {
|
|
1335
1396
|
var _a, _b;
|
|
1336
1397
|
const context = React.useContext(BackdropContext);
|
|
@@ -1348,15 +1409,25 @@ const BackdropOverlay = (p) => {
|
|
|
1348
1409
|
log('context.showing changed', context.showing);
|
|
1349
1410
|
}, [context.showing]);
|
|
1350
1411
|
}
|
|
1412
|
+
let zIndex = -1;
|
|
1413
|
+
if (context.showing) {
|
|
1414
|
+
zIndex = theme.zIndexes.backdrop;
|
|
1415
|
+
context.children.forEach(child => {
|
|
1416
|
+
if (child.zIndex > zIndex) {
|
|
1417
|
+
// -1 so it's always directly below the child
|
|
1418
|
+
zIndex = child.zIndex - 1;
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1351
1422
|
return (React.createElement("div", { onClick: () => {
|
|
1352
|
-
context === null || context === void 0 ? void 0 : context.setShow(false,
|
|
1423
|
+
context === null || context === void 0 ? void 0 : context.setShow(false, { key: backdropOverlayKey, zIndex });
|
|
1353
1424
|
log('onClick', 'setShow', false);
|
|
1354
1425
|
}, id: context === null || context === void 0 ? void 0 : context.portalId, className: css.css({
|
|
1355
1426
|
cursor: 'pointer',
|
|
1356
1427
|
position: 'fixed',
|
|
1357
1428
|
top: 0, right: 0, bottom: 0, left: 0,
|
|
1358
1429
|
backgroundColor: theme.colors.backdrop,
|
|
1359
|
-
zIndex
|
|
1430
|
+
zIndex,
|
|
1360
1431
|
visibility: (context === null || context === void 0 ? void 0 : context.showing) ? 'visible' : 'hidden',
|
|
1361
1432
|
opacity: (context === null || context === void 0 ? void 0 : context.showing) ? 1 : 0,
|
|
1362
1433
|
transition: `opacity ${showTimeMs}ms ease-in-out`,
|
|
@@ -1600,7 +1671,7 @@ const useScrollbarSize = (recalc) => {
|
|
|
1600
1671
|
|
|
1601
1672
|
const Modal = (p) => {
|
|
1602
1673
|
var _a, _b, _c, _d;
|
|
1603
|
-
const backdrop =
|
|
1674
|
+
const backdrop = useBackdropContext();
|
|
1604
1675
|
const mouseDownElement = React.useRef(undefined);
|
|
1605
1676
|
const theme = useThemeSafely();
|
|
1606
1677
|
const hasHeader = p.closeButton || p.heading;
|
|
@@ -1641,13 +1712,14 @@ const Modal = (p) => {
|
|
|
1641
1712
|
});
|
|
1642
1713
|
}
|
|
1643
1714
|
};
|
|
1715
|
+
const zIndex = theme.zIndexes.modal;
|
|
1644
1716
|
React.useEffect(() => {
|
|
1645
1717
|
log('mounted');
|
|
1646
1718
|
return () => {
|
|
1647
1719
|
var _a;
|
|
1648
1720
|
if (showing.current) {
|
|
1649
1721
|
log(`un-mount in progress and this modal is showing. decrement the backdrop and try to remove singleton body styles.`);
|
|
1650
|
-
backdrop.setShow(false, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
|
|
1722
|
+
backdrop.setShow(false, { key: (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', zIndex });
|
|
1651
1723
|
log('backdrop.setShow', false);
|
|
1652
1724
|
tryRemoveScrollStyles();
|
|
1653
1725
|
}
|
|
@@ -1660,7 +1732,7 @@ const Modal = (p) => {
|
|
|
1660
1732
|
useBooleanChanged((show, previousShow) => {
|
|
1661
1733
|
var _a;
|
|
1662
1734
|
log('show changed', `${previousShow !== null && previousShow !== void 0 ? previousShow : 'undefined'} > ${show}`);
|
|
1663
|
-
backdrop.setShow(show, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
|
|
1735
|
+
backdrop.setShow(show, { key: (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', zIndex });
|
|
1664
1736
|
showing.current = show;
|
|
1665
1737
|
log('backdrop.setShow', show);
|
|
1666
1738
|
if (show) {
|
|
@@ -1688,7 +1760,7 @@ const Modal = (p) => {
|
|
|
1688
1760
|
const modalBodyStyles = css.css({
|
|
1689
1761
|
maxHeight: p.scrollable ? undefined : '99vh',
|
|
1690
1762
|
overflow: 'hidden',
|
|
1691
|
-
zIndex
|
|
1763
|
+
zIndex,
|
|
1692
1764
|
cursor: 'default',
|
|
1693
1765
|
margin: '1rem',
|
|
1694
1766
|
backgroundColor: p.noBackground ? undefined : theme.colors.modalBg,
|
|
@@ -2740,7 +2812,7 @@ const Nav = (props) => {
|
|
|
2740
2812
|
const theme = useThemeSafely();
|
|
2741
2813
|
const navWidth = (_a = props.navWidth) !== null && _a !== void 0 ? _a : theme.layout.navWidth;
|
|
2742
2814
|
const totalNavOffset = `calc(${navWidth} + 20px)`;
|
|
2743
|
-
const backdrop =
|
|
2815
|
+
const backdrop = useBackdropContext();
|
|
2744
2816
|
const log = useLogger(`Nav ${(_b = props.id) !== null && _b !== void 0 ? _b : '?'}`, (_c = props.__debug) !== null && _c !== void 0 ? _c : false);
|
|
2745
2817
|
const slideMs = (_d = props.slideMs) !== null && _d !== void 0 ? _d : theme.timings.nav.slideMs;
|
|
2746
2818
|
const slideRight = css.keyframes `
|
|
@@ -2767,6 +2839,7 @@ const Nav = (props) => {
|
|
|
2767
2839
|
const classNavNotShowing = css.css `
|
|
2768
2840
|
animation: ${slideLeft} ${slideMs}ms cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
|
|
2769
2841
|
`;
|
|
2842
|
+
const zIndex = theme.zIndexes.nav;
|
|
2770
2843
|
// the padding-top here is to offset the navs' content from the header. the shadow creeps over it.
|
|
2771
2844
|
const navStyles = css.css `
|
|
2772
2845
|
label: Nav;
|
|
@@ -2779,7 +2852,7 @@ const Nav = (props) => {
|
|
|
2779
2852
|
width: ${navWidth};
|
|
2780
2853
|
min-width: ${navWidth};
|
|
2781
2854
|
box-shadow: 4px 2px 12px 6px rgba(0, 0, 0, 0.2);
|
|
2782
|
-
z-index: ${
|
|
2855
|
+
z-index: ${zIndex};
|
|
2783
2856
|
overflow-y: auto;
|
|
2784
2857
|
.omniLink, .omniLink:active, .omniLink:focus, .omniLink:visited {
|
|
2785
2858
|
color: ${theme.colors.navFont};
|
|
@@ -2794,7 +2867,7 @@ const Nav = (props) => {
|
|
|
2794
2867
|
useBooleanChanged((current, previous) => {
|
|
2795
2868
|
var _a;
|
|
2796
2869
|
log('show changed', `${previous !== null && previous !== void 0 ? previous : 'undefined'} > ${current}`);
|
|
2797
|
-
backdrop.setShow(current, (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav');
|
|
2870
|
+
backdrop.setShow(current, { key: (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav', zIndex });
|
|
2798
2871
|
}, props.show);
|
|
2799
2872
|
React__namespace.useLayoutEffect(() => {
|
|
2800
2873
|
if (nav && nav.current) {
|
|
@@ -4034,7 +4107,7 @@ const TabHeader = (p) => {
|
|
|
4034
4107
|
buttonContent = tab.name;
|
|
4035
4108
|
}
|
|
4036
4109
|
return (React__namespace.createElement("li", { key: index, className: css.cx(tabStyles, p.tabClassName) },
|
|
4037
|
-
React__namespace.createElement(Button, { disabled: tabsChanging, className: buttonStyles, variant: buttonVariant, title: title, readOnly: active, onClick: () => {
|
|
4110
|
+
React__namespace.createElement(Button, { "aria-role": "tab", "aria-selected": active, disabled: tabsChanging, className: buttonStyles, variant: buttonVariant, title: title, readOnly: active, onClick: () => {
|
|
4038
4111
|
const onChange = () => {
|
|
4039
4112
|
var _a;
|
|
4040
4113
|
setTabIndex(index);
|