@mackin.com/styleguide 11.0.1 → 11.0.2
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 +24 -17
- package/index.esm.js +76 -26
- package/index.js +76 -26
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -151,6 +151,7 @@ interface CheckboxProps extends Omit<React.DetailedHTMLProps<React.InputHTMLAttr
|
|
|
151
151
|
declare const Checkbox: (props: CheckboxProps) => React.JSX.Element;
|
|
152
152
|
|
|
153
153
|
interface ConfirmModalProps {
|
|
154
|
+
id: string;
|
|
154
155
|
show: boolean;
|
|
155
156
|
text: string;
|
|
156
157
|
header: string;
|
|
@@ -160,7 +161,6 @@ interface ConfirmModalProps {
|
|
|
160
161
|
cancelText?: string;
|
|
161
162
|
className?: string;
|
|
162
163
|
variant?: 'omg';
|
|
163
|
-
id?: string;
|
|
164
164
|
__debug?: boolean;
|
|
165
165
|
}
|
|
166
166
|
declare const ConfirmModal: (props: ConfirmModalProps) => React.JSX.Element;
|
|
@@ -176,9 +176,9 @@ declare const Divider: (p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHREl
|
|
|
176
176
|
declare const ErrorModal: (props: {
|
|
177
177
|
message: string;
|
|
178
178
|
show: boolean;
|
|
179
|
-
id
|
|
179
|
+
id: string;
|
|
180
180
|
__debug?: boolean;
|
|
181
|
-
|
|
181
|
+
onClose: () => void;
|
|
182
182
|
}) => React.JSX.Element;
|
|
183
183
|
|
|
184
184
|
interface FileUploaderProps {
|
|
@@ -293,18 +293,18 @@ interface InfoTipProps {
|
|
|
293
293
|
bgColor?: string;
|
|
294
294
|
/** Defaults to nav font color. */
|
|
295
295
|
fontColor?: string;
|
|
296
|
-
/** For variant=modal only. */
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
296
|
+
/** For variant=modal only. The InfoTip will not render if `variant=modal` and this is missing. */
|
|
297
|
+
modalProps?: {
|
|
298
|
+
heading: string;
|
|
299
|
+
id: string;
|
|
300
|
+
__debug?: boolean;
|
|
301
|
+
};
|
|
302
302
|
/** Whether to move the popover on collision with the parent's bounds. Default is false. For variant=info only. */
|
|
303
303
|
reposition?: boolean;
|
|
304
304
|
/** Order of positions as the Popover colides with the window edge. The default order is ['right', 'top', 'left', 'bottom']. For variant=info only. */
|
|
305
305
|
positions?: ("bottom" | "left" | "right" | "top")[] | undefined;
|
|
306
306
|
}
|
|
307
|
-
declare const InfoTip: (props: InfoTipProps) => React.JSX.Element;
|
|
307
|
+
declare const InfoTip: (props: InfoTipProps) => React.JSX.Element | null;
|
|
308
308
|
|
|
309
309
|
interface BaseInputProps extends React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> {
|
|
310
310
|
rightControl?: JSX.Element;
|
|
@@ -403,30 +403,34 @@ interface ListItemProps extends React.DetailedHTMLProps<React.LiHTMLAttributes<H
|
|
|
403
403
|
declare const ListItem: (props: ListItemProps) => React.JSX.Element;
|
|
404
404
|
|
|
405
405
|
interface ModalProps {
|
|
406
|
+
/** Required for various ARIA support choices. */
|
|
407
|
+
id: string;
|
|
406
408
|
show: boolean;
|
|
407
409
|
children: React__default.ReactNode;
|
|
410
|
+
heading: string;
|
|
408
411
|
/** Defaults to theme.breakpoints.tablet. */
|
|
409
412
|
maxWidth?: string;
|
|
410
413
|
minWidth?: string;
|
|
411
|
-
/** Will not apply a background color to the modal body. */
|
|
412
|
-
noBackground?: boolean;
|
|
413
|
-
closeButton?: boolean;
|
|
414
|
-
heading?: string;
|
|
415
414
|
/** Use to override default heading styling. */
|
|
416
415
|
headerClassName?: string;
|
|
417
|
-
/** Selector of the element to focus on initial show. */
|
|
416
|
+
/** Selector of the element to focus on initial show. Will default to the close button. */
|
|
418
417
|
focusSelector?: string;
|
|
419
418
|
scrollable?: boolean;
|
|
420
|
-
id?: string;
|
|
421
419
|
/** Applied to the modal body. */
|
|
422
420
|
className?: string;
|
|
423
421
|
__debug?: boolean;
|
|
424
|
-
|
|
422
|
+
/** Only used for the `WaitingIndicator`. This will break accessiblity so do not use. */
|
|
423
|
+
__noHeader?: boolean;
|
|
424
|
+
onClose: () => void;
|
|
425
425
|
}
|
|
426
426
|
declare const Modal: (p: ModalProps) => React__default.ReactPortal | null;
|
|
427
427
|
|
|
428
428
|
declare const Nav: (props: {
|
|
429
429
|
show: boolean;
|
|
430
|
+
/** Required for ARIA. The element to focus when first opened. */
|
|
431
|
+
focusSelector: string;
|
|
432
|
+
/** Required for ARIA. Description of the `Nav` purpose. */
|
|
433
|
+
ariaLabel: string;
|
|
430
434
|
toggle: (show: boolean) => void;
|
|
431
435
|
id?: string;
|
|
432
436
|
children?: React.ReactNode;
|
|
@@ -952,6 +956,7 @@ declare const TabLocker: (props: {
|
|
|
952
956
|
disabled?: boolean;
|
|
953
957
|
children?: React.ReactNode;
|
|
954
958
|
style?: React.CSSProperties;
|
|
959
|
+
className?: string;
|
|
955
960
|
}) => React.JSX.Element;
|
|
956
961
|
|
|
957
962
|
type SupportedTags = 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'span' | 'div';
|
|
@@ -977,11 +982,13 @@ interface TextProps {
|
|
|
977
982
|
/** Will remove all margin/padding from specified tag */
|
|
978
983
|
noPad?: boolean;
|
|
979
984
|
leftPad?: string;
|
|
985
|
+
id?: string;
|
|
980
986
|
}
|
|
981
987
|
/** Wraps common needs for displaying text. Use for all text-containing elements to save on duplicated styling. */
|
|
982
988
|
declare const Text: (props: TextProps) => React.DetailedReactHTMLElement<{
|
|
983
989
|
style: React.CSSProperties;
|
|
984
990
|
className: string;
|
|
991
|
+
id: string | undefined;
|
|
985
992
|
}, HTMLElement>;
|
|
986
993
|
|
|
987
994
|
type BaseProps = Omit<React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, 'value'> & InputOnFocusProps;
|
package/index.esm.js
CHANGED
|
@@ -288,7 +288,8 @@ const Text = (props) => {
|
|
|
288
288
|
});
|
|
289
289
|
return React.createElement(tagChoice, {
|
|
290
290
|
style: style,
|
|
291
|
-
className: cx('text', styles, props.className)
|
|
291
|
+
className: cx('text', styles, props.className),
|
|
292
|
+
id: props.id
|
|
292
293
|
}, props.children);
|
|
293
294
|
};
|
|
294
295
|
|
|
@@ -949,7 +950,7 @@ const ListItem = (props) => {
|
|
|
949
950
|
|
|
950
951
|
const TabLocker = (props) => {
|
|
951
952
|
const tabLocker = React.useRef(null);
|
|
952
|
-
return (React.createElement("div", { className:
|
|
953
|
+
return (React.createElement("div", { className: cx('tabLocker', props.className), style: props.style, ref: tabLocker, onKeyDown: e => {
|
|
953
954
|
var _a, _b;
|
|
954
955
|
if (props.disabled) {
|
|
955
956
|
return;
|
|
@@ -1662,7 +1663,7 @@ const Modal = (p) => {
|
|
|
1662
1663
|
const backdrop = useBackdropContext();
|
|
1663
1664
|
const mouseDownElement = useRef(undefined);
|
|
1664
1665
|
const theme = useThemeSafely();
|
|
1665
|
-
const hasHeader = p.
|
|
1666
|
+
const hasHeader = !p.__noHeader;
|
|
1666
1667
|
const contentRef = React__default.useRef(null);
|
|
1667
1668
|
const log = useLogger((_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
|
|
1668
1669
|
const showing = useRef(p.show);
|
|
@@ -1701,10 +1702,22 @@ const Modal = (p) => {
|
|
|
1701
1702
|
}
|
|
1702
1703
|
};
|
|
1703
1704
|
const zIndex = theme.zIndexes.modal;
|
|
1705
|
+
const { getText, language } = useLocalization();
|
|
1706
|
+
const closeText = React__default.useMemo(() => {
|
|
1707
|
+
return getText('Close');
|
|
1708
|
+
}, [language]);
|
|
1704
1709
|
useEffect(() => {
|
|
1705
1710
|
log('mounted');
|
|
1711
|
+
const escapeRemover = createBodyEscapeHandler(() => {
|
|
1712
|
+
if (showing.current) {
|
|
1713
|
+
p.onClose();
|
|
1714
|
+
}
|
|
1715
|
+
});
|
|
1716
|
+
log('body escape handler created');
|
|
1706
1717
|
return () => {
|
|
1707
1718
|
var _a;
|
|
1719
|
+
escapeRemover();
|
|
1720
|
+
log('body escape handler removed');
|
|
1708
1721
|
if (showing.current) {
|
|
1709
1722
|
log(`un-mount in progress and this modal is showing. decrement the backdrop and try to remove singleton body styles.`);
|
|
1710
1723
|
backdrop.setShow(false, { key: (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', zIndex });
|
|
@@ -1751,9 +1764,9 @@ const Modal = (p) => {
|
|
|
1751
1764
|
zIndex,
|
|
1752
1765
|
cursor: 'default',
|
|
1753
1766
|
margin: '1rem',
|
|
1754
|
-
backgroundColor:
|
|
1755
|
-
border:
|
|
1756
|
-
boxShadow:
|
|
1767
|
+
backgroundColor: !hasHeader ? undefined : theme.colors.modalBg,
|
|
1768
|
+
border: !hasHeader ? undefined : theme.controls.border,
|
|
1769
|
+
boxShadow: !hasHeader ? undefined : theme.controls.boxShadow,
|
|
1757
1770
|
maxWidth: (_c = p.maxWidth) !== null && _c !== void 0 ? _c : theme.breakpoints.tablet,
|
|
1758
1771
|
minWidth: (_d = p.minWidth) !== null && _d !== void 0 ? _d : (hasHeader ? '250px' : undefined),
|
|
1759
1772
|
opacity: p.show ? 1 : 0,
|
|
@@ -1780,26 +1793,30 @@ const Modal = (p) => {
|
|
|
1780
1793
|
display: 'flex',
|
|
1781
1794
|
justifyContent: 'center',
|
|
1782
1795
|
alignItems: 'center',
|
|
1783
|
-
cursor:
|
|
1796
|
+
cursor: 'pointer'
|
|
1784
1797
|
}, p.scrollable && {
|
|
1785
1798
|
overflowY: 'auto',
|
|
1786
1799
|
overflowX: 'hidden',
|
|
1787
1800
|
alignItems: 'flex-start'
|
|
1788
1801
|
}]);
|
|
1802
|
+
const ariaLabelId = `${p.id}_label`;
|
|
1789
1803
|
if (p.show) {
|
|
1790
1804
|
const backdropContainer = document.getElementById(backdrop.portalId);
|
|
1791
1805
|
if (backdropContainer) {
|
|
1792
|
-
return createPortal((React__default.createElement("div", { onClick: e => {
|
|
1806
|
+
return createPortal((React__default.createElement("div", { id: p.id, role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelId, onClick: e => {
|
|
1793
1807
|
e.stopPropagation();
|
|
1794
1808
|
if (!mouseDownElement.current) {
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
p.onClick();
|
|
1798
|
-
}
|
|
1809
|
+
log('backdropContainer onClick');
|
|
1810
|
+
p.onClose();
|
|
1799
1811
|
}
|
|
1800
1812
|
mouseDownElement.current = undefined;
|
|
1813
|
+
}, onKeyDown: e => {
|
|
1814
|
+
if (e.code === 'Escape') {
|
|
1815
|
+
e.stopPropagation();
|
|
1816
|
+
p.onClose();
|
|
1817
|
+
}
|
|
1801
1818
|
}, className: cx('modalContainer', modalContainerStyles) },
|
|
1802
|
-
React__default.createElement("div", {
|
|
1819
|
+
React__default.createElement("div", { ref: contentRef, onClick: e => e.stopPropagation(), onMouseDown: e => {
|
|
1803
1820
|
mouseDownElement.current = e.target;
|
|
1804
1821
|
e.stopPropagation();
|
|
1805
1822
|
}, onMouseUp: () => {
|
|
@@ -1813,21 +1830,35 @@ const Modal = (p) => {
|
|
|
1813
1830
|
}, className: cx('modalBody', modalBodyStyles, p.className) },
|
|
1814
1831
|
React__default.createElement(TabLocker, null,
|
|
1815
1832
|
hasHeader && (React__default.createElement("header", { className: cx('modalHeader', modalHeaderStyles) },
|
|
1816
|
-
|
|
1833
|
+
React__default.createElement(Text, { id: ariaLabelId, className: css({
|
|
1817
1834
|
margin: 0,
|
|
1818
1835
|
flexGrow: 1
|
|
1819
|
-
}), tag: "h1", bold: true }, p.heading)
|
|
1820
|
-
|
|
1836
|
+
}), tag: "h1", bold: true }, p.heading),
|
|
1837
|
+
React__default.createElement(Button, { className: cx('modalCloseButton', css({
|
|
1821
1838
|
color: theme.colors.headerFont,
|
|
1822
1839
|
marginLeft: '1rem',
|
|
1823
1840
|
backgroundColor: 'transparent'
|
|
1824
|
-
})), "aria-label":
|
|
1825
|
-
|
|
1841
|
+
})), "aria-label": closeText, variant: "icon", onClick: e => {
|
|
1842
|
+
e.stopPropagation();
|
|
1843
|
+
p.onClose();
|
|
1844
|
+
} },
|
|
1845
|
+
React__default.createElement(Icon, { id: "close" })))),
|
|
1826
1846
|
p.children)))), backdropContainer);
|
|
1827
1847
|
}
|
|
1828
1848
|
}
|
|
1829
1849
|
return null;
|
|
1830
1850
|
};
|
|
1851
|
+
function createBodyEscapeHandler(onEscape) {
|
|
1852
|
+
const handler = (e) => {
|
|
1853
|
+
if (e.code === 'Escape') {
|
|
1854
|
+
onEscape();
|
|
1855
|
+
}
|
|
1856
|
+
};
|
|
1857
|
+
document.addEventListener('keydown', handler);
|
|
1858
|
+
return () => {
|
|
1859
|
+
document.removeEventListener('keydown', handler);
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1831
1862
|
|
|
1832
1863
|
const ConfirmModal = (props) => {
|
|
1833
1864
|
const theme = useThemeSafely();
|
|
@@ -1845,7 +1876,7 @@ const ConfirmModal = (props) => {
|
|
|
1845
1876
|
const cancelText = props.cancelText || getText('Cancel');
|
|
1846
1877
|
return { confirmText, cancelText };
|
|
1847
1878
|
}, [language, props.confirmText, props.cancelText]);
|
|
1848
|
-
return (React.createElement(Modal, { id: props.id, __debug: props.__debug, className: cx('confirmModal', modalStyle, props.className), heading: props.header,
|
|
1879
|
+
return (React.createElement(Modal, { id: props.id, __debug: props.__debug, className: cx('confirmModal', modalStyle, props.className), heading: props.header, show: props.show, onClose: props.onCancel },
|
|
1849
1880
|
React.createElement("div", { className: css({ padding: '1rem' }) },
|
|
1850
1881
|
React.createElement(Text, { align: "center" }, props.text),
|
|
1851
1882
|
React.createElement("div", { className: css({ textAlign: 'center' }) },
|
|
@@ -1909,7 +1940,7 @@ const ErrorModal = (props) => {
|
|
|
1909
1940
|
color: ${theme.colors.omgFont};
|
|
1910
1941
|
}
|
|
1911
1942
|
`;
|
|
1912
|
-
return (React.createElement(Modal, { id: props.id, __debug: props.__debug, className: cx('errorModal', modalStyles), heading: heading,
|
|
1943
|
+
return (React.createElement(Modal, { id: props.id, __debug: props.__debug, className: cx('errorModal', modalStyles), heading: heading, show: props.show, onClose: props.onClose },
|
|
1913
1944
|
React.createElement("div", { className: css({ padding: '1rem' }) },
|
|
1914
1945
|
React.createElement(Text, { align: "center" }, message))));
|
|
1915
1946
|
};
|
|
@@ -2381,6 +2412,10 @@ const InfoTip = (props) => {
|
|
|
2381
2412
|
var _a, _b, _c;
|
|
2382
2413
|
const [showTip, setShowTip] = React.useState(false);
|
|
2383
2414
|
const theme = useThemeSafely();
|
|
2415
|
+
if (props.variant === 'modal' && !props.modalProps) {
|
|
2416
|
+
console.warn(`InfoTip with variant=modal requires modalProps.`);
|
|
2417
|
+
return null;
|
|
2418
|
+
}
|
|
2384
2419
|
const bgColor = (_a = props.bgColor) !== null && _a !== void 0 ? _a : theme.colors.nav;
|
|
2385
2420
|
const fontColor = (_b = props.fontColor) !== null && _b !== void 0 ? _b : theme.colors.navFont;
|
|
2386
2421
|
const onClick = () => {
|
|
@@ -2437,12 +2472,12 @@ const InfoTip = (props) => {
|
|
|
2437
2472
|
display:inline-block;
|
|
2438
2473
|
`;
|
|
2439
2474
|
const button = React.createElement(Button, { className: buttonStyles, disabled: props.disabled, variant: 'circle', tabIndex: props.tabIndex, onClick: onClick, onMouseEnter: onMouseOver, onMouseLeave: onMouseOut }, "i");
|
|
2440
|
-
if (props.variant === 'modal') {
|
|
2475
|
+
if (props.variant === 'modal' && props.modalProps) {
|
|
2441
2476
|
return (React.createElement(React.Fragment, null,
|
|
2442
2477
|
button,
|
|
2443
|
-
React.createElement(Modal, { id: props.
|
|
2478
|
+
React.createElement(Modal, { id: props.modalProps.id, __debug: props.modalProps.__debug, show: showTip, heading: props.modalProps.heading, onClose: closeTip, className: css({
|
|
2444
2479
|
whiteSpace: 'normal'
|
|
2445
|
-
})
|
|
2480
|
+
}) },
|
|
2446
2481
|
React.createElement("div", { className: css({ padding: '1rem' }) }, props.content))));
|
|
2447
2482
|
}
|
|
2448
2483
|
else {
|
|
@@ -2848,6 +2883,7 @@ const Nav = (props) => {
|
|
|
2848
2883
|
padding-top:0;
|
|
2849
2884
|
`;
|
|
2850
2885
|
React.useEffect(() => {
|
|
2886
|
+
console.log('useEffect');
|
|
2851
2887
|
if (!backdrop.showing) {
|
|
2852
2888
|
props.toggle(false);
|
|
2853
2889
|
}
|
|
@@ -2858,10 +2894,16 @@ const Nav = (props) => {
|
|
|
2858
2894
|
backdrop.setShow(current, { key: (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav', zIndex });
|
|
2859
2895
|
}, props.show);
|
|
2860
2896
|
React.useLayoutEffect(() => {
|
|
2897
|
+
console.log('useLayoutEffect');
|
|
2861
2898
|
if (nav && nav.current) {
|
|
2862
2899
|
if (props.show) {
|
|
2863
2900
|
if (!nav.current.classList.contains(classNavShowing)) {
|
|
2864
2901
|
nav.current.classList.add(classNavShowing);
|
|
2902
|
+
setTimeout(() => {
|
|
2903
|
+
var _a;
|
|
2904
|
+
(_a = document.querySelector(props.focusSelector)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
2905
|
+
console.log(props.focusSelector, document.querySelector(props.focusSelector), 'focused');
|
|
2906
|
+
}, slideMs + 1);
|
|
2865
2907
|
}
|
|
2866
2908
|
}
|
|
2867
2909
|
else {
|
|
@@ -2877,7 +2919,12 @@ const Nav = (props) => {
|
|
|
2877
2919
|
}
|
|
2878
2920
|
}
|
|
2879
2921
|
});
|
|
2880
|
-
return (React.createElement("nav", { ref: nav, className: cx('nav', navStyles, props.className)
|
|
2922
|
+
return (React.createElement("nav", { role: "dialog", "aria-modal": "true", "aria-label": props.ariaLabel, ref: nav, className: cx('nav', navStyles, props.className), onKeyDown: e => {
|
|
2923
|
+
if (e.code === 'Escape') {
|
|
2924
|
+
props.toggle(false);
|
|
2925
|
+
}
|
|
2926
|
+
} },
|
|
2927
|
+
React.createElement(TabLocker, { className: css({ height: '100%' }) }, props.children)));
|
|
2881
2928
|
};
|
|
2882
2929
|
|
|
2883
2930
|
const LinkContent = (props) => {
|
|
@@ -4430,7 +4477,7 @@ const TogglePasswordInput = React.forwardRef((props, ref) => {
|
|
|
4430
4477
|
});
|
|
4431
4478
|
|
|
4432
4479
|
const WaitingIndicator = (p) => {
|
|
4433
|
-
var _a, _b;
|
|
4480
|
+
var _a, _b, _c;
|
|
4434
4481
|
const [show, setShow] = useState(p.show);
|
|
4435
4482
|
const hideTimer = useRef(0);
|
|
4436
4483
|
const lastShowStatus = useRef(false);
|
|
@@ -4482,7 +4529,10 @@ const WaitingIndicator = (p) => {
|
|
|
4482
4529
|
}
|
|
4483
4530
|
}
|
|
4484
4531
|
}, [p.show]);
|
|
4485
|
-
|
|
4532
|
+
const id = (_c = p.id) !== null && _c !== void 0 ? _c : 'WaitingIndicator';
|
|
4533
|
+
return (React__default.createElement(Modal, { id: id, __debug: p.__debug, __noHeader: true, heading: '', onClose: () => {
|
|
4534
|
+
/* noop */
|
|
4535
|
+
}, className: "waitingIndicator", show: show },
|
|
4486
4536
|
React__default.createElement("div", { className: css({
|
|
4487
4537
|
color: 'white',
|
|
4488
4538
|
fontSize: '3rem',
|
package/index.js
CHANGED
|
@@ -306,7 +306,8 @@ const Text = (props) => {
|
|
|
306
306
|
});
|
|
307
307
|
return React__namespace.createElement(tagChoice, {
|
|
308
308
|
style: style,
|
|
309
|
-
className: css.cx('text', styles, props.className)
|
|
309
|
+
className: css.cx('text', styles, props.className),
|
|
310
|
+
id: props.id
|
|
310
311
|
}, props.children);
|
|
311
312
|
};
|
|
312
313
|
|
|
@@ -967,7 +968,7 @@ const ListItem = (props) => {
|
|
|
967
968
|
|
|
968
969
|
const TabLocker = (props) => {
|
|
969
970
|
const tabLocker = React__namespace.useRef(null);
|
|
970
|
-
return (React__namespace.createElement("div", { className:
|
|
971
|
+
return (React__namespace.createElement("div", { className: css.cx('tabLocker', props.className), style: props.style, ref: tabLocker, onKeyDown: e => {
|
|
971
972
|
var _a, _b;
|
|
972
973
|
if (props.disabled) {
|
|
973
974
|
return;
|
|
@@ -1680,7 +1681,7 @@ const Modal = (p) => {
|
|
|
1680
1681
|
const backdrop = useBackdropContext();
|
|
1681
1682
|
const mouseDownElement = React.useRef(undefined);
|
|
1682
1683
|
const theme = useThemeSafely();
|
|
1683
|
-
const hasHeader = p.
|
|
1684
|
+
const hasHeader = !p.__noHeader;
|
|
1684
1685
|
const contentRef = React.useRef(null);
|
|
1685
1686
|
const log = useLogger((_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
|
|
1686
1687
|
const showing = React.useRef(p.show);
|
|
@@ -1719,10 +1720,22 @@ const Modal = (p) => {
|
|
|
1719
1720
|
}
|
|
1720
1721
|
};
|
|
1721
1722
|
const zIndex = theme.zIndexes.modal;
|
|
1723
|
+
const { getText, language } = useLocalization();
|
|
1724
|
+
const closeText = React.useMemo(() => {
|
|
1725
|
+
return getText('Close');
|
|
1726
|
+
}, [language]);
|
|
1722
1727
|
React.useEffect(() => {
|
|
1723
1728
|
log('mounted');
|
|
1729
|
+
const escapeRemover = createBodyEscapeHandler(() => {
|
|
1730
|
+
if (showing.current) {
|
|
1731
|
+
p.onClose();
|
|
1732
|
+
}
|
|
1733
|
+
});
|
|
1734
|
+
log('body escape handler created');
|
|
1724
1735
|
return () => {
|
|
1725
1736
|
var _a;
|
|
1737
|
+
escapeRemover();
|
|
1738
|
+
log('body escape handler removed');
|
|
1726
1739
|
if (showing.current) {
|
|
1727
1740
|
log(`un-mount in progress and this modal is showing. decrement the backdrop and try to remove singleton body styles.`);
|
|
1728
1741
|
backdrop.setShow(false, { key: (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', zIndex });
|
|
@@ -1769,9 +1782,9 @@ const Modal = (p) => {
|
|
|
1769
1782
|
zIndex,
|
|
1770
1783
|
cursor: 'default',
|
|
1771
1784
|
margin: '1rem',
|
|
1772
|
-
backgroundColor:
|
|
1773
|
-
border:
|
|
1774
|
-
boxShadow:
|
|
1785
|
+
backgroundColor: !hasHeader ? undefined : theme.colors.modalBg,
|
|
1786
|
+
border: !hasHeader ? undefined : theme.controls.border,
|
|
1787
|
+
boxShadow: !hasHeader ? undefined : theme.controls.boxShadow,
|
|
1775
1788
|
maxWidth: (_c = p.maxWidth) !== null && _c !== void 0 ? _c : theme.breakpoints.tablet,
|
|
1776
1789
|
minWidth: (_d = p.minWidth) !== null && _d !== void 0 ? _d : (hasHeader ? '250px' : undefined),
|
|
1777
1790
|
opacity: p.show ? 1 : 0,
|
|
@@ -1798,26 +1811,30 @@ const Modal = (p) => {
|
|
|
1798
1811
|
display: 'flex',
|
|
1799
1812
|
justifyContent: 'center',
|
|
1800
1813
|
alignItems: 'center',
|
|
1801
|
-
cursor:
|
|
1814
|
+
cursor: 'pointer'
|
|
1802
1815
|
}, p.scrollable && {
|
|
1803
1816
|
overflowY: 'auto',
|
|
1804
1817
|
overflowX: 'hidden',
|
|
1805
1818
|
alignItems: 'flex-start'
|
|
1806
1819
|
}]);
|
|
1820
|
+
const ariaLabelId = `${p.id}_label`;
|
|
1807
1821
|
if (p.show) {
|
|
1808
1822
|
const backdropContainer = document.getElementById(backdrop.portalId);
|
|
1809
1823
|
if (backdropContainer) {
|
|
1810
|
-
return reactDom.createPortal((React.createElement("div", { onClick: e => {
|
|
1824
|
+
return reactDom.createPortal((React.createElement("div", { id: p.id, role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelId, onClick: e => {
|
|
1811
1825
|
e.stopPropagation();
|
|
1812
1826
|
if (!mouseDownElement.current) {
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
p.onClick();
|
|
1816
|
-
}
|
|
1827
|
+
log('backdropContainer onClick');
|
|
1828
|
+
p.onClose();
|
|
1817
1829
|
}
|
|
1818
1830
|
mouseDownElement.current = undefined;
|
|
1831
|
+
}, onKeyDown: e => {
|
|
1832
|
+
if (e.code === 'Escape') {
|
|
1833
|
+
e.stopPropagation();
|
|
1834
|
+
p.onClose();
|
|
1835
|
+
}
|
|
1819
1836
|
}, className: css.cx('modalContainer', modalContainerStyles) },
|
|
1820
|
-
React.createElement("div", {
|
|
1837
|
+
React.createElement("div", { ref: contentRef, onClick: e => e.stopPropagation(), onMouseDown: e => {
|
|
1821
1838
|
mouseDownElement.current = e.target;
|
|
1822
1839
|
e.stopPropagation();
|
|
1823
1840
|
}, onMouseUp: () => {
|
|
@@ -1831,21 +1848,35 @@ const Modal = (p) => {
|
|
|
1831
1848
|
}, className: css.cx('modalBody', modalBodyStyles, p.className) },
|
|
1832
1849
|
React.createElement(TabLocker, null,
|
|
1833
1850
|
hasHeader && (React.createElement("header", { className: css.cx('modalHeader', modalHeaderStyles) },
|
|
1834
|
-
|
|
1851
|
+
React.createElement(Text, { id: ariaLabelId, className: css.css({
|
|
1835
1852
|
margin: 0,
|
|
1836
1853
|
flexGrow: 1
|
|
1837
|
-
}), tag: "h1", bold: true }, p.heading)
|
|
1838
|
-
|
|
1854
|
+
}), tag: "h1", bold: true }, p.heading),
|
|
1855
|
+
React.createElement(Button, { className: css.cx('modalCloseButton', css.css({
|
|
1839
1856
|
color: theme.colors.headerFont,
|
|
1840
1857
|
marginLeft: '1rem',
|
|
1841
1858
|
backgroundColor: 'transparent'
|
|
1842
|
-
})), "aria-label":
|
|
1843
|
-
|
|
1859
|
+
})), "aria-label": closeText, variant: "icon", onClick: e => {
|
|
1860
|
+
e.stopPropagation();
|
|
1861
|
+
p.onClose();
|
|
1862
|
+
} },
|
|
1863
|
+
React.createElement(Icon, { id: "close" })))),
|
|
1844
1864
|
p.children)))), backdropContainer);
|
|
1845
1865
|
}
|
|
1846
1866
|
}
|
|
1847
1867
|
return null;
|
|
1848
1868
|
};
|
|
1869
|
+
function createBodyEscapeHandler(onEscape) {
|
|
1870
|
+
const handler = (e) => {
|
|
1871
|
+
if (e.code === 'Escape') {
|
|
1872
|
+
onEscape();
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
document.addEventListener('keydown', handler);
|
|
1876
|
+
return () => {
|
|
1877
|
+
document.removeEventListener('keydown', handler);
|
|
1878
|
+
};
|
|
1879
|
+
}
|
|
1849
1880
|
|
|
1850
1881
|
const ConfirmModal = (props) => {
|
|
1851
1882
|
const theme = useThemeSafely();
|
|
@@ -1863,7 +1894,7 @@ const ConfirmModal = (props) => {
|
|
|
1863
1894
|
const cancelText = props.cancelText || getText('Cancel');
|
|
1864
1895
|
return { confirmText, cancelText };
|
|
1865
1896
|
}, [language, props.confirmText, props.cancelText]);
|
|
1866
|
-
return (React__namespace.createElement(Modal, { id: props.id, __debug: props.__debug, className: css.cx('confirmModal', modalStyle, props.className), heading: props.header,
|
|
1897
|
+
return (React__namespace.createElement(Modal, { id: props.id, __debug: props.__debug, className: css.cx('confirmModal', modalStyle, props.className), heading: props.header, show: props.show, onClose: props.onCancel },
|
|
1867
1898
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) },
|
|
1868
1899
|
React__namespace.createElement(Text, { align: "center" }, props.text),
|
|
1869
1900
|
React__namespace.createElement("div", { className: css.css({ textAlign: 'center' }) },
|
|
@@ -1927,7 +1958,7 @@ const ErrorModal = (props) => {
|
|
|
1927
1958
|
color: ${theme.colors.omgFont};
|
|
1928
1959
|
}
|
|
1929
1960
|
`;
|
|
1930
|
-
return (React__namespace.createElement(Modal, { id: props.id, __debug: props.__debug, className: css.cx('errorModal', modalStyles), heading: heading,
|
|
1961
|
+
return (React__namespace.createElement(Modal, { id: props.id, __debug: props.__debug, className: css.cx('errorModal', modalStyles), heading: heading, show: props.show, onClose: props.onClose },
|
|
1931
1962
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) },
|
|
1932
1963
|
React__namespace.createElement(Text, { align: "center" }, message))));
|
|
1933
1964
|
};
|
|
@@ -2399,6 +2430,10 @@ const InfoTip = (props) => {
|
|
|
2399
2430
|
var _a, _b, _c;
|
|
2400
2431
|
const [showTip, setShowTip] = React__namespace.useState(false);
|
|
2401
2432
|
const theme = useThemeSafely();
|
|
2433
|
+
if (props.variant === 'modal' && !props.modalProps) {
|
|
2434
|
+
console.warn(`InfoTip with variant=modal requires modalProps.`);
|
|
2435
|
+
return null;
|
|
2436
|
+
}
|
|
2402
2437
|
const bgColor = (_a = props.bgColor) !== null && _a !== void 0 ? _a : theme.colors.nav;
|
|
2403
2438
|
const fontColor = (_b = props.fontColor) !== null && _b !== void 0 ? _b : theme.colors.navFont;
|
|
2404
2439
|
const onClick = () => {
|
|
@@ -2455,12 +2490,12 @@ const InfoTip = (props) => {
|
|
|
2455
2490
|
display:inline-block;
|
|
2456
2491
|
`;
|
|
2457
2492
|
const button = React__namespace.createElement(Button, { className: buttonStyles, disabled: props.disabled, variant: 'circle', tabIndex: props.tabIndex, onClick: onClick, onMouseEnter: onMouseOver, onMouseLeave: onMouseOut }, "i");
|
|
2458
|
-
if (props.variant === 'modal') {
|
|
2493
|
+
if (props.variant === 'modal' && props.modalProps) {
|
|
2459
2494
|
return (React__namespace.createElement(React__namespace.Fragment, null,
|
|
2460
2495
|
button,
|
|
2461
|
-
React__namespace.createElement(Modal, { id: props.
|
|
2496
|
+
React__namespace.createElement(Modal, { id: props.modalProps.id, __debug: props.modalProps.__debug, show: showTip, heading: props.modalProps.heading, onClose: closeTip, className: css.css({
|
|
2462
2497
|
whiteSpace: 'normal'
|
|
2463
|
-
})
|
|
2498
|
+
}) },
|
|
2464
2499
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) }, props.content))));
|
|
2465
2500
|
}
|
|
2466
2501
|
else {
|
|
@@ -2866,6 +2901,7 @@ const Nav = (props) => {
|
|
|
2866
2901
|
padding-top:0;
|
|
2867
2902
|
`;
|
|
2868
2903
|
React__namespace.useEffect(() => {
|
|
2904
|
+
console.log('useEffect');
|
|
2869
2905
|
if (!backdrop.showing) {
|
|
2870
2906
|
props.toggle(false);
|
|
2871
2907
|
}
|
|
@@ -2876,10 +2912,16 @@ const Nav = (props) => {
|
|
|
2876
2912
|
backdrop.setShow(current, { key: (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav', zIndex });
|
|
2877
2913
|
}, props.show);
|
|
2878
2914
|
React__namespace.useLayoutEffect(() => {
|
|
2915
|
+
console.log('useLayoutEffect');
|
|
2879
2916
|
if (nav && nav.current) {
|
|
2880
2917
|
if (props.show) {
|
|
2881
2918
|
if (!nav.current.classList.contains(classNavShowing)) {
|
|
2882
2919
|
nav.current.classList.add(classNavShowing);
|
|
2920
|
+
setTimeout(() => {
|
|
2921
|
+
var _a;
|
|
2922
|
+
(_a = document.querySelector(props.focusSelector)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
2923
|
+
console.log(props.focusSelector, document.querySelector(props.focusSelector), 'focused');
|
|
2924
|
+
}, slideMs + 1);
|
|
2883
2925
|
}
|
|
2884
2926
|
}
|
|
2885
2927
|
else {
|
|
@@ -2895,7 +2937,12 @@ const Nav = (props) => {
|
|
|
2895
2937
|
}
|
|
2896
2938
|
}
|
|
2897
2939
|
});
|
|
2898
|
-
return (React__namespace.createElement("nav", { ref: nav, className: css.cx('nav', navStyles, props.className)
|
|
2940
|
+
return (React__namespace.createElement("nav", { role: "dialog", "aria-modal": "true", "aria-label": props.ariaLabel, ref: nav, className: css.cx('nav', navStyles, props.className), onKeyDown: e => {
|
|
2941
|
+
if (e.code === 'Escape') {
|
|
2942
|
+
props.toggle(false);
|
|
2943
|
+
}
|
|
2944
|
+
} },
|
|
2945
|
+
React__namespace.createElement(TabLocker, { className: css.css({ height: '100%' }) }, props.children)));
|
|
2899
2946
|
};
|
|
2900
2947
|
|
|
2901
2948
|
const LinkContent = (props) => {
|
|
@@ -4448,7 +4495,7 @@ const TogglePasswordInput = React__namespace.forwardRef((props, ref) => {
|
|
|
4448
4495
|
});
|
|
4449
4496
|
|
|
4450
4497
|
const WaitingIndicator = (p) => {
|
|
4451
|
-
var _a, _b;
|
|
4498
|
+
var _a, _b, _c;
|
|
4452
4499
|
const [show, setShow] = React.useState(p.show);
|
|
4453
4500
|
const hideTimer = React.useRef(0);
|
|
4454
4501
|
const lastShowStatus = React.useRef(false);
|
|
@@ -4500,7 +4547,10 @@ const WaitingIndicator = (p) => {
|
|
|
4500
4547
|
}
|
|
4501
4548
|
}
|
|
4502
4549
|
}, [p.show]);
|
|
4503
|
-
|
|
4550
|
+
const id = (_c = p.id) !== null && _c !== void 0 ? _c : 'WaitingIndicator';
|
|
4551
|
+
return (React.createElement(Modal, { id: id, __debug: p.__debug, __noHeader: true, heading: '', onClose: () => {
|
|
4552
|
+
/* noop */
|
|
4553
|
+
}, className: "waitingIndicator", show: show },
|
|
4504
4554
|
React.createElement("div", { className: css.css({
|
|
4505
4555
|
color: 'white',
|
|
4506
4556
|
fontSize: '3rem',
|