@mackin.com/styleguide 10.2.6 → 11.0.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.
- package/index.d.ts +11 -5
- package/index.esm.js +140 -104
- package/index.js +140 -104
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
|
4
4
|
|
|
5
5
|
type HeaderVariant = 'label' | 'link' | 'primary' | 'secondary' | 'omg' | 'primary2' | 'positive' | 'negative';
|
|
6
6
|
interface AccordianProps {
|
|
7
|
+
/** Required for ARIA. */
|
|
8
|
+
id: string;
|
|
7
9
|
header: JSX.Element | string;
|
|
8
10
|
children: React.ReactNode;
|
|
9
11
|
variant?: HeaderVariant;
|
|
@@ -33,8 +35,12 @@ interface InputOnFocusProps {
|
|
|
33
35
|
allowUpdateOnFocus?: boolean;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
type BaseInputProps$1 = Omit<TextInputProps, 'value' | 'className' | 'wrapperClassName' | 'type' | 'showErrorDisplay'> & InputOnFocusProps;
|
|
38
|
+
type BaseInputProps$1 = Omit<TextInputProps, 'value' | 'className' | 'wrapperClassName' | 'type' | 'showErrorDisplay' | 'id' | 'aria-label'> & InputOnFocusProps;
|
|
37
39
|
interface AutocompleteProps extends BaseInputProps$1 {
|
|
40
|
+
/** Required for ARIA. Will be used to add unique IDs to the options. */
|
|
41
|
+
id: string;
|
|
42
|
+
/** Required for ARIA. Will be applied to both the input and the popup listbox. */
|
|
43
|
+
ariaLabel: string;
|
|
38
44
|
value: string | undefined;
|
|
39
45
|
options: string[];
|
|
40
46
|
/** Applied to the Autocomplete wrapper. */
|
|
@@ -43,15 +49,12 @@ interface AutocompleteProps extends BaseInputProps$1 {
|
|
|
43
49
|
inputClassName?: string;
|
|
44
50
|
listClassName?: string;
|
|
45
51
|
listItemClassName?: string;
|
|
46
|
-
listItemButtonClassName?: string;
|
|
47
52
|
/** Limits what will be show in the autocomplete options. Default is 7. */
|
|
48
53
|
maxShownValues?: number;
|
|
49
54
|
/** Will enable scrolling in the results list. */
|
|
50
55
|
allowScroll?: boolean;
|
|
51
56
|
/** Delay before the input is re-focused after picking a value. Adjust if there are issues with the displayed input value after pick. Defaults to 100ms. */
|
|
52
57
|
onPickFocusWaitMs?: number;
|
|
53
|
-
/** The option `title` attribute will be filled with the option text. Defaults to `true`. */
|
|
54
|
-
showOptionTextAsTitle?: boolean;
|
|
55
58
|
onPick: (value: string | undefined, index?: number) => void;
|
|
56
59
|
}
|
|
57
60
|
declare const Autocomplete: (p: AutocompleteProps) => React.JSX.Element;
|
|
@@ -130,10 +133,11 @@ interface CalendarProps {
|
|
|
130
133
|
declare const Calendar: (p: CalendarProps) => React.JSX.Element;
|
|
131
134
|
|
|
132
135
|
interface CheckboxProps extends Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, 'checked' | 'onChange' | 'type'> {
|
|
136
|
+
/** Required for the internal label (ARIA). Pass `true` to `hideLabel` to treat this label as an aria-label. */
|
|
137
|
+
label: string;
|
|
133
138
|
checked: boolean;
|
|
134
139
|
onChange: (checked: boolean, event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
135
140
|
readOnly?: boolean;
|
|
136
|
-
label?: string;
|
|
137
141
|
checkedIcon?: string;
|
|
138
142
|
uncheckedIcon?: string;
|
|
139
143
|
/** Background color when checked based on the current theme. Mutually exclusive with 'checkedColor'. */
|
|
@@ -141,6 +145,8 @@ interface CheckboxProps extends Omit<React.DetailedHTMLProps<React.InputHTMLAttr
|
|
|
141
145
|
/** Background color when checked. Mutually exclusive with 'checkedThemeColor'. */
|
|
142
146
|
checkedColor?: string;
|
|
143
147
|
tabIndex?: number | undefined;
|
|
148
|
+
/** Pass `true` to `hideLabel` to treat `label` as an aria-label. */
|
|
149
|
+
hideLabel?: boolean;
|
|
144
150
|
}
|
|
145
151
|
declare const Checkbox: (props: CheckboxProps) => React.JSX.Element;
|
|
146
152
|
|
package/index.esm.js
CHANGED
|
@@ -292,7 +292,6 @@ const Text = (props) => {
|
|
|
292
292
|
}, props.children);
|
|
293
293
|
};
|
|
294
294
|
|
|
295
|
-
//TB: FUTURE de-dup these styles. create individual styles and compose them manually.
|
|
296
295
|
const Button = React.forwardRef((props, ref) => {
|
|
297
296
|
var _a;
|
|
298
297
|
const { variant, round, rightIcon, leftIcon, iconBlock, small, readOnly, waiting, enforceMinWidth, controlAlign } = props, nativeProps = __rest(props, ["variant", "round", "rightIcon", "leftIcon", "iconBlock", "small", "readOnly", "waiting", "enforceMinWidth", "controlAlign"]);
|
|
@@ -551,26 +550,33 @@ const Accordian = (props) => {
|
|
|
551
550
|
}
|
|
552
551
|
setOpen((_a = props.open) !== null && _a !== void 0 ? _a : false);
|
|
553
552
|
}, [props.open]);
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
|
|
553
|
+
const expandedPanelId = `${props.id}_expanded`;
|
|
554
|
+
return (React.createElement("div", { id: props.id, className: "accordian" },
|
|
555
|
+
React.createElement("h3", { className: css({
|
|
556
|
+
// required for ARIA
|
|
557
|
+
margin: 0,
|
|
558
|
+
padding: 0,
|
|
559
|
+
fontSize: 'inherit'
|
|
560
|
+
}) },
|
|
561
|
+
React.createElement(Button, { "aria-controls": expandedPanelId, "aria-expanded": open, "aria-disabled": props.disabled, readOnly: props.disabled, variant: props.variant, className: cx(css({
|
|
562
|
+
display: 'flex',
|
|
563
|
+
alignItems: 'center',
|
|
564
|
+
justifyContent: 'space-between',
|
|
565
|
+
height: 'auto',
|
|
566
|
+
minHeight: theme.controls.height,
|
|
567
|
+
width: ((_d = props.block) !== null && _d !== void 0 ? _d : true) ? '100%' : 'auto'
|
|
568
|
+
}, props.className)), onClick: e => {
|
|
569
|
+
e.stopPropagation();
|
|
570
|
+
if (props.onChange) {
|
|
571
|
+
props.onChange(!open);
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
setOpen(!open);
|
|
575
|
+
}
|
|
576
|
+
}, rightIcon: !props.disabled ? React.createElement(Icon, { id: open ? 'collapse' : 'expand' }) : undefined },
|
|
577
|
+
React.createElement("span", null, props.header))),
|
|
572
578
|
React.createElement("div", { ref: content, className: cx('accordian__body', contentStyles) },
|
|
573
|
-
React.createElement("div", { className: expandedContentWrapperStyles }, children))));
|
|
579
|
+
React.createElement("div", { className: expandedContentWrapperStyles, id: expandedPanelId }, children))));
|
|
574
580
|
};
|
|
575
581
|
const useAccordianState = (count, openIndex) => {
|
|
576
582
|
const [panels, setShowPanel] = React.useState(new Array(count).fill(false).map((b, i) => {
|
|
@@ -972,18 +978,23 @@ const TabLocker = (props) => {
|
|
|
972
978
|
} }, props.children));
|
|
973
979
|
};
|
|
974
980
|
|
|
981
|
+
/*
|
|
982
|
+
ARIA info:
|
|
983
|
+
https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
984
|
+
https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-autocomplete-list/
|
|
985
|
+
This would be considered "List autocomplete with manual selection"
|
|
986
|
+
*/
|
|
975
987
|
const defaultMaxShownValues = 7;
|
|
976
|
-
const buttonMarkerClass = 'ListItem__button';
|
|
977
988
|
const defaultOnPickFocusMs = 100;
|
|
978
989
|
const Autocomplete = (p) => {
|
|
979
|
-
var _a
|
|
990
|
+
var _a;
|
|
980
991
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
981
|
-
const inputProps = __rest(p, ["value", "className", "inputWrapperClassName", "inputClassName", "listClassName", "listItemClassName", "
|
|
992
|
+
const inputProps = __rest(p, ["value", "className", "inputWrapperClassName", "inputClassName", "listClassName", "listItemClassName", "maxShownValues", "allowScroll", "options", "onPick", "onPickFocusWaitMs", "ariaLabel"]);
|
|
982
993
|
const theme = useThemeSafely();
|
|
983
994
|
const element = React.useRef(null);
|
|
984
995
|
const input = React.useRef(null);
|
|
985
996
|
const list = React.useRef(null);
|
|
986
|
-
const [selectedResultIndex, setSelectedResultIndex] = React.useState();
|
|
997
|
+
const [selectedResultIndex, setSelectedResultIndex] = React.useState(-1);
|
|
987
998
|
const maxShowValues = (_a = p.maxShownValues) !== null && _a !== void 0 ? _a : defaultMaxShownValues;
|
|
988
999
|
const displayOptions = React.useMemo(() => {
|
|
989
1000
|
if (!p.allowScroll) {
|
|
@@ -995,27 +1006,6 @@ const Autocomplete = (p) => {
|
|
|
995
1006
|
const resultsText = React.useMemo(() => {
|
|
996
1007
|
return `${getText("Showing")} ${displayOptions.length.toLocaleString()} ${getText("of")} ${p.options.length.toLocaleString()} ${getText("results")}.`;
|
|
997
1008
|
}, [language, displayOptions, p.options]);
|
|
998
|
-
const getNextTabElement = (fromIndex, direction) => {
|
|
999
|
-
var _a, _b, _c;
|
|
1000
|
-
if (fromIndex === -1) {
|
|
1001
|
-
let buttonIndex = 0;
|
|
1002
|
-
if (direction === -1) {
|
|
1003
|
-
buttonIndex = displayOptions.length - 1;
|
|
1004
|
-
}
|
|
1005
|
-
setSelectedResultIndex(buttonIndex);
|
|
1006
|
-
return (_a = list.current) === null || _a === void 0 ? void 0 : _a.querySelector(`.${buttonMarkerClass}${buttonIndex}`);
|
|
1007
|
-
}
|
|
1008
|
-
else {
|
|
1009
|
-
const nextIndex = fromIndex + direction;
|
|
1010
|
-
setSelectedResultIndex(nextIndex);
|
|
1011
|
-
if (nextIndex >= displayOptions.length || nextIndex < 0) {
|
|
1012
|
-
return (_b = input.current) !== null && _b !== void 0 ? _b : undefined;
|
|
1013
|
-
}
|
|
1014
|
-
else {
|
|
1015
|
-
return (_c = list.current) === null || _c === void 0 ? void 0 : _c.querySelector(`.${buttonMarkerClass}${nextIndex}`);
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
};
|
|
1019
1009
|
React.useEffect(() => {
|
|
1020
1010
|
const clearItems = () => {
|
|
1021
1011
|
if (p.options.length) {
|
|
@@ -1031,57 +1021,118 @@ const Autocomplete = (p) => {
|
|
|
1031
1021
|
if (p.round || theme.controls.borderRadius) {
|
|
1032
1022
|
listBorderRadius = theme.controls.borderRadius || '0.5rem';
|
|
1033
1023
|
}
|
|
1034
|
-
const
|
|
1035
|
-
const onPickValue = (v) => {
|
|
1024
|
+
const onPickValue = (v, keepFocus = true) => {
|
|
1036
1025
|
var _a;
|
|
1037
1026
|
// the TextInput will not respond to outer value changes if it has focus.
|
|
1038
1027
|
// here we clear first and then onPickValue will re-focus after all updates.
|
|
1039
1028
|
(_a = input.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
1040
1029
|
setTimeout(() => {
|
|
1041
|
-
// blur is now complete
|
|
1042
1030
|
var _a;
|
|
1031
|
+
// blur is now complete
|
|
1043
1032
|
let index = v ? p.options.findIndex(o => o === v) : undefined;
|
|
1044
1033
|
if (index !== undefined && index < 0) {
|
|
1045
1034
|
index = undefined;
|
|
1046
1035
|
}
|
|
1047
1036
|
p.onPick(v, index);
|
|
1048
1037
|
// wait for the re-render. the value will not update if the control has focus
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1038
|
+
if (keepFocus) {
|
|
1039
|
+
setTimeout(() => {
|
|
1040
|
+
var _a;
|
|
1041
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1042
|
+
}, (_a = p.onPickFocusWaitMs) !== null && _a !== void 0 ? _a : defaultOnPickFocusMs);
|
|
1043
|
+
}
|
|
1053
1044
|
}, 0);
|
|
1054
1045
|
};
|
|
1046
|
+
React.useEffect(() => {
|
|
1047
|
+
if (selectedResultIndex === -1) {
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1050
|
+
const element = document.getElementById(getOptionId(p.id, selectedResultIndex));
|
|
1051
|
+
if (element) {
|
|
1052
|
+
element.scrollIntoView();
|
|
1053
|
+
}
|
|
1054
|
+
}, [selectedResultIndex]);
|
|
1055
|
+
const popupId = `${p.id}_ul`;
|
|
1056
|
+
const listItemStyles = css({
|
|
1057
|
+
paddingLeft: theme.controls.padding,
|
|
1058
|
+
paddingRight: theme.controls.padding,
|
|
1059
|
+
backgroundColor: 'white',
|
|
1060
|
+
cursor: 'pointer',
|
|
1061
|
+
color: theme.colors.font,
|
|
1062
|
+
height: theme.controls.height,
|
|
1063
|
+
transition: theme.controls.transition,
|
|
1064
|
+
fontsize: '1rem',
|
|
1065
|
+
fontWeight: 'bold',
|
|
1066
|
+
':hover': {
|
|
1067
|
+
filter: theme.controls.hoverBrightness
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
const listItemFocusStyles = css({
|
|
1071
|
+
outline: 'none',
|
|
1072
|
+
boxShadow: theme.controls.focusOutlineShadow,
|
|
1073
|
+
// prevents box shadow clipping
|
|
1074
|
+
position: 'relative',
|
|
1075
|
+
zIndex: 2
|
|
1076
|
+
});
|
|
1077
|
+
const listItemTextStyles = css({
|
|
1078
|
+
lineHeight: theme.controls.height
|
|
1079
|
+
});
|
|
1055
1080
|
return (React.createElement("div", { onClick: e => {
|
|
1056
1081
|
e.stopPropagation();
|
|
1057
1082
|
}, onKeyDown: e => {
|
|
1058
1083
|
if (e.key === 'Escape') {
|
|
1059
1084
|
onPickValue(undefined);
|
|
1085
|
+
setSelectedResultIndex(-1);
|
|
1060
1086
|
}
|
|
1061
|
-
}, ref: element, className: cx(
|
|
1062
|
-
position: 'relative',
|
|
1063
|
-
width: '100%',
|
|
1064
|
-
label: 'Autocomplete'
|
|
1065
|
-
}), p.className, 'autocomplete') },
|
|
1087
|
+
}, ref: element, className: cx(styles.autocomplete, p.className, 'autocomplete') },
|
|
1066
1088
|
React.createElement(TabLocker, { disabled: !displayOptions.length, style: { position: 'relative' } },
|
|
1067
1089
|
React.createElement(TextInput, Object.assign({}, inputProps, { showErrorDisplay: false, ref: input, value: p.value, className: p.inputClassName, wrapperClassName: p.inputWrapperClassName, onKeyDown: e => {
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1090
|
+
let handled = false;
|
|
1091
|
+
switch (e.code) {
|
|
1092
|
+
case 'ArrowDown': {
|
|
1093
|
+
if (displayOptions.length) {
|
|
1094
|
+
let nextIndex = selectedResultIndex + 1;
|
|
1095
|
+
if (nextIndex >= displayOptions.length) {
|
|
1096
|
+
nextIndex = 0;
|
|
1097
|
+
}
|
|
1098
|
+
setSelectedResultIndex(nextIndex);
|
|
1099
|
+
handled = true;
|
|
1100
|
+
}
|
|
1101
|
+
break;
|
|
1074
1102
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1103
|
+
case 'ArrowUp': {
|
|
1104
|
+
if (displayOptions.length) {
|
|
1105
|
+
let nextIndex = selectedResultIndex - 1;
|
|
1106
|
+
if (nextIndex < 0) {
|
|
1107
|
+
nextIndex = displayOptions.length - 1;
|
|
1108
|
+
}
|
|
1109
|
+
setSelectedResultIndex(nextIndex);
|
|
1110
|
+
handled = true;
|
|
1111
|
+
}
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
case 'Enter': {
|
|
1115
|
+
let pickedValue = p.value;
|
|
1116
|
+
if (selectedResultIndex >= 0) {
|
|
1117
|
+
pickedValue = displayOptions[selectedResultIndex];
|
|
1118
|
+
}
|
|
1119
|
+
onPickValue(pickedValue);
|
|
1120
|
+
setSelectedResultIndex(-1);
|
|
1121
|
+
handled = true;
|
|
1122
|
+
break;
|
|
1079
1123
|
}
|
|
1124
|
+
case 'Tab': {
|
|
1125
|
+
onPickValue(p.value, false);
|
|
1126
|
+
setSelectedResultIndex(-1);
|
|
1127
|
+
break;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
if (handled) {
|
|
1131
|
+
e.preventDefault();
|
|
1132
|
+
e.stopPropagation();
|
|
1080
1133
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
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."),
|
|
1084
|
-
!!displayOptions.length && (React.createElement(List, { id: id, ref: list, role: "listbox", className: cx(css({
|
|
1134
|
+
}, role: "combobox", "aria-expanded": !!displayOptions.length, "aria-controls": popupId, "aria-autocomplete": "list", "aria-activedescendant": selectedResultIndex >= 0 ? getOptionId(p.id, selectedResultIndex) : undefined, "aria-label": p.ariaLabel })),
|
|
1135
|
+
!!displayOptions.length && (React.createElement(List, { id: popupId, ref: list, role: "listbox", "aria-label": p.ariaLabel, className: cx(css({
|
|
1085
1136
|
position: 'absolute',
|
|
1086
1137
|
width: '100%',
|
|
1087
1138
|
border: theme.controls.border,
|
|
@@ -1090,11 +1141,11 @@ const Autocomplete = (p) => {
|
|
|
1090
1141
|
backgroundColor: theme.colors.bg,
|
|
1091
1142
|
marginTop: `-4px !important`,
|
|
1092
1143
|
zIndex: theme.zIndexes.backdrop,
|
|
1093
|
-
'li:first-child
|
|
1144
|
+
'li:first-child': {
|
|
1094
1145
|
borderTopRightRadius: listBorderRadius,
|
|
1095
1146
|
borderTopLeftRadius: listBorderRadius,
|
|
1096
1147
|
},
|
|
1097
|
-
'li:last-child
|
|
1148
|
+
'li:last-child': {
|
|
1098
1149
|
borderBottomRightRadius: listBorderRadius,
|
|
1099
1150
|
borderBottomLeftRadius: listBorderRadius,
|
|
1100
1151
|
}
|
|
@@ -1103,36 +1154,23 @@ const Autocomplete = (p) => {
|
|
|
1103
1154
|
maxHeight: `calc(${theme.controls.height} * ${maxShowValues})`
|
|
1104
1155
|
}), p.listClassName) },
|
|
1105
1156
|
displayOptions.map((v, listItemIndex) => {
|
|
1106
|
-
|
|
1107
|
-
return (React.createElement(ListItem, { key: v, variant: "full", className: p.listItemClassName, role: "option", "aria-selected":
|
|
1108
|
-
React.createElement(
|
|
1109
|
-
var _a, _b;
|
|
1110
|
-
if (e.key === 'ArrowDown') {
|
|
1111
|
-
e.stopPropagation();
|
|
1112
|
-
e.preventDefault();
|
|
1113
|
-
(_a = getNextTabElement(listItemIndex, 1)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1114
|
-
}
|
|
1115
|
-
else if (e.key === 'ArrowUp') {
|
|
1116
|
-
e.stopPropagation();
|
|
1117
|
-
e.preventDefault();
|
|
1118
|
-
(_b = getNextTabElement(listItemIndex, -1)) === null || _b === void 0 ? void 0 : _b.focus();
|
|
1119
|
-
}
|
|
1120
|
-
else if (e.key === 'Enter') {
|
|
1121
|
-
e.stopPropagation();
|
|
1122
|
-
// this will prevent the click event from firing in addition to this enter key event.
|
|
1123
|
-
e.preventDefault();
|
|
1124
|
-
onPickValue(v);
|
|
1125
|
-
}
|
|
1126
|
-
}, className: cx(buttonMarkerClass + listItemIndex, css({
|
|
1127
|
-
borderRadius: 0,
|
|
1128
|
-
}), p.listItemButtonClassName), onClick: () => {
|
|
1129
|
-
onPickValue(v);
|
|
1130
|
-
} },
|
|
1131
|
-
React.createElement(Text, { tag: "div", ellipsis: true, align: "left" }, v))));
|
|
1157
|
+
const selected = selectedResultIndex === listItemIndex;
|
|
1158
|
+
return (React.createElement(ListItem, { key: v, variant: "full", className: cx(listItemStyles, selected ? listItemFocusStyles : undefined, p.listItemClassName), role: "option", id: getOptionId(p.id, listItemIndex), "aria-selected": selected },
|
|
1159
|
+
React.createElement(Text, { tag: "div", ellipsis: true, align: "left", className: listItemTextStyles }, v)));
|
|
1132
1160
|
}),
|
|
1133
1161
|
!p.allowScroll && displayOptions.length < p.options.length && (React.createElement(ListItem, { className: p.listItemClassName },
|
|
1134
1162
|
React.createElement(Text, { tag: "div", italics: true, align: "center" }, resultsText))))))));
|
|
1135
1163
|
};
|
|
1164
|
+
function getOptionId(baseId, optionIndex) {
|
|
1165
|
+
return `${baseId}_li_${optionIndex}`;
|
|
1166
|
+
}
|
|
1167
|
+
const styles = {
|
|
1168
|
+
autocomplete: css({
|
|
1169
|
+
position: 'relative',
|
|
1170
|
+
width: '100%',
|
|
1171
|
+
label: 'Autocomplete'
|
|
1172
|
+
}),
|
|
1173
|
+
};
|
|
1136
1174
|
|
|
1137
1175
|
/** Returns a UID. Use this instead of a direct call to a library. */
|
|
1138
1176
|
function createUid() {
|
|
@@ -1493,7 +1531,7 @@ const Calendar = (p) => {
|
|
|
1493
1531
|
|
|
1494
1532
|
const Checkbox = (props) => {
|
|
1495
1533
|
var _a;
|
|
1496
|
-
const { onChange, label, checkedIcon, uncheckedIcon, checkedThemeColor, checkedColor, readOnly } = props, inputProps = __rest(props, ["onChange", "label", "checkedIcon", "uncheckedIcon", "checkedThemeColor", "checkedColor", "readOnly"]);
|
|
1534
|
+
const { onChange, label, checkedIcon, uncheckedIcon, checkedThemeColor, checkedColor, readOnly, hideLabel } = props, inputProps = __rest(props, ["onChange", "label", "checkedIcon", "uncheckedIcon", "checkedThemeColor", "checkedColor", "readOnly", "hideLabel"]);
|
|
1497
1535
|
const selected = checkedIcon || 'selected';
|
|
1498
1536
|
const unselected = uncheckedIcon || 'unselected';
|
|
1499
1537
|
const theme = useThemeSafely();
|
|
@@ -1557,7 +1595,7 @@ const Checkbox = (props) => {
|
|
|
1557
1595
|
`;
|
|
1558
1596
|
return (React.createElement("span", { className: cx('checkbox', checkboxStyles, props.className) },
|
|
1559
1597
|
React.createElement("label", { className: labelStyles },
|
|
1560
|
-
React.createElement("input", Object.assign({}, inputProps, { tabIndex: readOnly ? -1 : (_a = props.tabIndex) !== null && _a !== void 0 ? _a : undefined, className: nativeCheckboxStyles, type: "checkbox", onChange: e => {
|
|
1598
|
+
React.createElement("input", Object.assign({}, inputProps, { "aria-label": hideLabel ? label : undefined, tabIndex: readOnly ? -1 : (_a = props.tabIndex) !== null && _a !== void 0 ? _a : undefined, className: nativeCheckboxStyles, type: "checkbox", onChange: e => {
|
|
1561
1599
|
if (readOnly) {
|
|
1562
1600
|
e.preventDefault();
|
|
1563
1601
|
return;
|
|
@@ -1565,7 +1603,7 @@ const Checkbox = (props) => {
|
|
|
1565
1603
|
return onChange(e.currentTarget.checked, e);
|
|
1566
1604
|
} })),
|
|
1567
1605
|
React.createElement(Icon, { className: cx('checkboxIcon', iconStyles), id: props.checked ? selected : unselected }),
|
|
1568
|
-
label,
|
|
1606
|
+
!hideLabel && label,
|
|
1569
1607
|
props.children)));
|
|
1570
1608
|
};
|
|
1571
1609
|
|
|
@@ -2860,7 +2898,6 @@ const LinkContent = (props) => {
|
|
|
2860
2898
|
}) }, props.rightIcon)));
|
|
2861
2899
|
};
|
|
2862
2900
|
|
|
2863
|
-
//TB: FUTURE de-dup these styles. create individual styles and compose them manually.
|
|
2864
2901
|
const generateLinkStyles = (props, theme) => {
|
|
2865
2902
|
const disabled = props.disabled || props.waiting;
|
|
2866
2903
|
let color = props.colorOverride;
|
|
@@ -4229,7 +4266,6 @@ const TextArea = React.forwardRef((props, ref) => {
|
|
|
4229
4266
|
}
|
|
4230
4267
|
else {
|
|
4231
4268
|
if (reportValueOnError) {
|
|
4232
|
-
//TB: temp, add a custom list of validators that will be run for all inputs if a pattern cannot be decided.
|
|
4233
4269
|
onValueChange(localValue);
|
|
4234
4270
|
}
|
|
4235
4271
|
else {
|
package/index.js
CHANGED
|
@@ -310,7 +310,6 @@ const Text = (props) => {
|
|
|
310
310
|
}, props.children);
|
|
311
311
|
};
|
|
312
312
|
|
|
313
|
-
//TB: FUTURE de-dup these styles. create individual styles and compose them manually.
|
|
314
313
|
const Button = React__namespace.forwardRef((props, ref) => {
|
|
315
314
|
var _a;
|
|
316
315
|
const { variant, round, rightIcon, leftIcon, iconBlock, small, readOnly, waiting, enforceMinWidth, controlAlign } = props, nativeProps = __rest(props, ["variant", "round", "rightIcon", "leftIcon", "iconBlock", "small", "readOnly", "waiting", "enforceMinWidth", "controlAlign"]);
|
|
@@ -569,26 +568,33 @@ const Accordian = (props) => {
|
|
|
569
568
|
}
|
|
570
569
|
setOpen((_a = props.open) !== null && _a !== void 0 ? _a : false);
|
|
571
570
|
}, [props.open]);
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
|
|
571
|
+
const expandedPanelId = `${props.id}_expanded`;
|
|
572
|
+
return (React__namespace.createElement("div", { id: props.id, className: "accordian" },
|
|
573
|
+
React__namespace.createElement("h3", { className: css.css({
|
|
574
|
+
// required for ARIA
|
|
575
|
+
margin: 0,
|
|
576
|
+
padding: 0,
|
|
577
|
+
fontSize: 'inherit'
|
|
578
|
+
}) },
|
|
579
|
+
React__namespace.createElement(Button, { "aria-controls": expandedPanelId, "aria-expanded": open, "aria-disabled": props.disabled, readOnly: props.disabled, variant: props.variant, className: css.cx(css.css({
|
|
580
|
+
display: 'flex',
|
|
581
|
+
alignItems: 'center',
|
|
582
|
+
justifyContent: 'space-between',
|
|
583
|
+
height: 'auto',
|
|
584
|
+
minHeight: theme.controls.height,
|
|
585
|
+
width: ((_d = props.block) !== null && _d !== void 0 ? _d : true) ? '100%' : 'auto'
|
|
586
|
+
}, props.className)), onClick: e => {
|
|
587
|
+
e.stopPropagation();
|
|
588
|
+
if (props.onChange) {
|
|
589
|
+
props.onChange(!open);
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
setOpen(!open);
|
|
593
|
+
}
|
|
594
|
+
}, rightIcon: !props.disabled ? React__namespace.createElement(Icon, { id: open ? 'collapse' : 'expand' }) : undefined },
|
|
595
|
+
React__namespace.createElement("span", null, props.header))),
|
|
590
596
|
React__namespace.createElement("div", { ref: content, className: css.cx('accordian__body', contentStyles) },
|
|
591
|
-
React__namespace.createElement("div", { className: expandedContentWrapperStyles }, children))));
|
|
597
|
+
React__namespace.createElement("div", { className: expandedContentWrapperStyles, id: expandedPanelId }, children))));
|
|
592
598
|
};
|
|
593
599
|
const useAccordianState = (count, openIndex) => {
|
|
594
600
|
const [panels, setShowPanel] = React__namespace.useState(new Array(count).fill(false).map((b, i) => {
|
|
@@ -990,18 +996,23 @@ const TabLocker = (props) => {
|
|
|
990
996
|
} }, props.children));
|
|
991
997
|
};
|
|
992
998
|
|
|
999
|
+
/*
|
|
1000
|
+
ARIA info:
|
|
1001
|
+
https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
1002
|
+
https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-autocomplete-list/
|
|
1003
|
+
This would be considered "List autocomplete with manual selection"
|
|
1004
|
+
*/
|
|
993
1005
|
const defaultMaxShownValues = 7;
|
|
994
|
-
const buttonMarkerClass = 'ListItem__button';
|
|
995
1006
|
const defaultOnPickFocusMs = 100;
|
|
996
1007
|
const Autocomplete = (p) => {
|
|
997
|
-
var _a
|
|
1008
|
+
var _a;
|
|
998
1009
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
999
|
-
const inputProps = __rest(p, ["value", "className", "inputWrapperClassName", "inputClassName", "listClassName", "listItemClassName", "
|
|
1010
|
+
const inputProps = __rest(p, ["value", "className", "inputWrapperClassName", "inputClassName", "listClassName", "listItemClassName", "maxShownValues", "allowScroll", "options", "onPick", "onPickFocusWaitMs", "ariaLabel"]);
|
|
1000
1011
|
const theme = useThemeSafely();
|
|
1001
1012
|
const element = React__namespace.useRef(null);
|
|
1002
1013
|
const input = React__namespace.useRef(null);
|
|
1003
1014
|
const list = React__namespace.useRef(null);
|
|
1004
|
-
const [selectedResultIndex, setSelectedResultIndex] = React__namespace.useState();
|
|
1015
|
+
const [selectedResultIndex, setSelectedResultIndex] = React__namespace.useState(-1);
|
|
1005
1016
|
const maxShowValues = (_a = p.maxShownValues) !== null && _a !== void 0 ? _a : defaultMaxShownValues;
|
|
1006
1017
|
const displayOptions = React__namespace.useMemo(() => {
|
|
1007
1018
|
if (!p.allowScroll) {
|
|
@@ -1013,27 +1024,6 @@ const Autocomplete = (p) => {
|
|
|
1013
1024
|
const resultsText = React__namespace.useMemo(() => {
|
|
1014
1025
|
return `${getText("Showing")} ${displayOptions.length.toLocaleString()} ${getText("of")} ${p.options.length.toLocaleString()} ${getText("results")}.`;
|
|
1015
1026
|
}, [language, displayOptions, p.options]);
|
|
1016
|
-
const getNextTabElement = (fromIndex, direction) => {
|
|
1017
|
-
var _a, _b, _c;
|
|
1018
|
-
if (fromIndex === -1) {
|
|
1019
|
-
let buttonIndex = 0;
|
|
1020
|
-
if (direction === -1) {
|
|
1021
|
-
buttonIndex = displayOptions.length - 1;
|
|
1022
|
-
}
|
|
1023
|
-
setSelectedResultIndex(buttonIndex);
|
|
1024
|
-
return (_a = list.current) === null || _a === void 0 ? void 0 : _a.querySelector(`.${buttonMarkerClass}${buttonIndex}`);
|
|
1025
|
-
}
|
|
1026
|
-
else {
|
|
1027
|
-
const nextIndex = fromIndex + direction;
|
|
1028
|
-
setSelectedResultIndex(nextIndex);
|
|
1029
|
-
if (nextIndex >= displayOptions.length || nextIndex < 0) {
|
|
1030
|
-
return (_b = input.current) !== null && _b !== void 0 ? _b : undefined;
|
|
1031
|
-
}
|
|
1032
|
-
else {
|
|
1033
|
-
return (_c = list.current) === null || _c === void 0 ? void 0 : _c.querySelector(`.${buttonMarkerClass}${nextIndex}`);
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
};
|
|
1037
1027
|
React__namespace.useEffect(() => {
|
|
1038
1028
|
const clearItems = () => {
|
|
1039
1029
|
if (p.options.length) {
|
|
@@ -1049,57 +1039,118 @@ const Autocomplete = (p) => {
|
|
|
1049
1039
|
if (p.round || theme.controls.borderRadius) {
|
|
1050
1040
|
listBorderRadius = theme.controls.borderRadius || '0.5rem';
|
|
1051
1041
|
}
|
|
1052
|
-
const
|
|
1053
|
-
const onPickValue = (v) => {
|
|
1042
|
+
const onPickValue = (v, keepFocus = true) => {
|
|
1054
1043
|
var _a;
|
|
1055
1044
|
// the TextInput will not respond to outer value changes if it has focus.
|
|
1056
1045
|
// here we clear first and then onPickValue will re-focus after all updates.
|
|
1057
1046
|
(_a = input.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
1058
1047
|
setTimeout(() => {
|
|
1059
|
-
// blur is now complete
|
|
1060
1048
|
var _a;
|
|
1049
|
+
// blur is now complete
|
|
1061
1050
|
let index = v ? p.options.findIndex(o => o === v) : undefined;
|
|
1062
1051
|
if (index !== undefined && index < 0) {
|
|
1063
1052
|
index = undefined;
|
|
1064
1053
|
}
|
|
1065
1054
|
p.onPick(v, index);
|
|
1066
1055
|
// wait for the re-render. the value will not update if the control has focus
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1056
|
+
if (keepFocus) {
|
|
1057
|
+
setTimeout(() => {
|
|
1058
|
+
var _a;
|
|
1059
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1060
|
+
}, (_a = p.onPickFocusWaitMs) !== null && _a !== void 0 ? _a : defaultOnPickFocusMs);
|
|
1061
|
+
}
|
|
1071
1062
|
}, 0);
|
|
1072
1063
|
};
|
|
1064
|
+
React__namespace.useEffect(() => {
|
|
1065
|
+
if (selectedResultIndex === -1) {
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
const element = document.getElementById(getOptionId(p.id, selectedResultIndex));
|
|
1069
|
+
if (element) {
|
|
1070
|
+
element.scrollIntoView();
|
|
1071
|
+
}
|
|
1072
|
+
}, [selectedResultIndex]);
|
|
1073
|
+
const popupId = `${p.id}_ul`;
|
|
1074
|
+
const listItemStyles = css.css({
|
|
1075
|
+
paddingLeft: theme.controls.padding,
|
|
1076
|
+
paddingRight: theme.controls.padding,
|
|
1077
|
+
backgroundColor: 'white',
|
|
1078
|
+
cursor: 'pointer',
|
|
1079
|
+
color: theme.colors.font,
|
|
1080
|
+
height: theme.controls.height,
|
|
1081
|
+
transition: theme.controls.transition,
|
|
1082
|
+
fontsize: '1rem',
|
|
1083
|
+
fontWeight: 'bold',
|
|
1084
|
+
':hover': {
|
|
1085
|
+
filter: theme.controls.hoverBrightness
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
const listItemFocusStyles = css.css({
|
|
1089
|
+
outline: 'none',
|
|
1090
|
+
boxShadow: theme.controls.focusOutlineShadow,
|
|
1091
|
+
// prevents box shadow clipping
|
|
1092
|
+
position: 'relative',
|
|
1093
|
+
zIndex: 2
|
|
1094
|
+
});
|
|
1095
|
+
const listItemTextStyles = css.css({
|
|
1096
|
+
lineHeight: theme.controls.height
|
|
1097
|
+
});
|
|
1073
1098
|
return (React__namespace.createElement("div", { onClick: e => {
|
|
1074
1099
|
e.stopPropagation();
|
|
1075
1100
|
}, onKeyDown: e => {
|
|
1076
1101
|
if (e.key === 'Escape') {
|
|
1077
1102
|
onPickValue(undefined);
|
|
1103
|
+
setSelectedResultIndex(-1);
|
|
1078
1104
|
}
|
|
1079
|
-
}, ref: element, className: css.cx(
|
|
1080
|
-
position: 'relative',
|
|
1081
|
-
width: '100%',
|
|
1082
|
-
label: 'Autocomplete'
|
|
1083
|
-
}), p.className, 'autocomplete') },
|
|
1105
|
+
}, ref: element, className: css.cx(styles.autocomplete, p.className, 'autocomplete') },
|
|
1084
1106
|
React__namespace.createElement(TabLocker, { disabled: !displayOptions.length, style: { position: 'relative' } },
|
|
1085
1107
|
React__namespace.createElement(TextInput, Object.assign({}, inputProps, { showErrorDisplay: false, ref: input, value: p.value, className: p.inputClassName, wrapperClassName: p.inputWrapperClassName, onKeyDown: e => {
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1108
|
+
let handled = false;
|
|
1109
|
+
switch (e.code) {
|
|
1110
|
+
case 'ArrowDown': {
|
|
1111
|
+
if (displayOptions.length) {
|
|
1112
|
+
let nextIndex = selectedResultIndex + 1;
|
|
1113
|
+
if (nextIndex >= displayOptions.length) {
|
|
1114
|
+
nextIndex = 0;
|
|
1115
|
+
}
|
|
1116
|
+
setSelectedResultIndex(nextIndex);
|
|
1117
|
+
handled = true;
|
|
1118
|
+
}
|
|
1119
|
+
break;
|
|
1092
1120
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1121
|
+
case 'ArrowUp': {
|
|
1122
|
+
if (displayOptions.length) {
|
|
1123
|
+
let nextIndex = selectedResultIndex - 1;
|
|
1124
|
+
if (nextIndex < 0) {
|
|
1125
|
+
nextIndex = displayOptions.length - 1;
|
|
1126
|
+
}
|
|
1127
|
+
setSelectedResultIndex(nextIndex);
|
|
1128
|
+
handled = true;
|
|
1129
|
+
}
|
|
1130
|
+
break;
|
|
1131
|
+
}
|
|
1132
|
+
case 'Enter': {
|
|
1133
|
+
let pickedValue = p.value;
|
|
1134
|
+
if (selectedResultIndex >= 0) {
|
|
1135
|
+
pickedValue = displayOptions[selectedResultIndex];
|
|
1136
|
+
}
|
|
1137
|
+
onPickValue(pickedValue);
|
|
1138
|
+
setSelectedResultIndex(-1);
|
|
1139
|
+
handled = true;
|
|
1140
|
+
break;
|
|
1097
1141
|
}
|
|
1142
|
+
case 'Tab': {
|
|
1143
|
+
onPickValue(p.value, false);
|
|
1144
|
+
setSelectedResultIndex(-1);
|
|
1145
|
+
break;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
if (handled) {
|
|
1149
|
+
e.preventDefault();
|
|
1150
|
+
e.stopPropagation();
|
|
1098
1151
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
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."),
|
|
1102
|
-
!!displayOptions.length && (React__namespace.createElement(List, { id: id, ref: list, role: "listbox", className: css.cx(css.css({
|
|
1152
|
+
}, role: "combobox", "aria-expanded": !!displayOptions.length, "aria-controls": popupId, "aria-autocomplete": "list", "aria-activedescendant": selectedResultIndex >= 0 ? getOptionId(p.id, selectedResultIndex) : undefined, "aria-label": p.ariaLabel })),
|
|
1153
|
+
!!displayOptions.length && (React__namespace.createElement(List, { id: popupId, ref: list, role: "listbox", "aria-label": p.ariaLabel, className: css.cx(css.css({
|
|
1103
1154
|
position: 'absolute',
|
|
1104
1155
|
width: '100%',
|
|
1105
1156
|
border: theme.controls.border,
|
|
@@ -1108,11 +1159,11 @@ const Autocomplete = (p) => {
|
|
|
1108
1159
|
backgroundColor: theme.colors.bg,
|
|
1109
1160
|
marginTop: `-4px !important`,
|
|
1110
1161
|
zIndex: theme.zIndexes.backdrop,
|
|
1111
|
-
'li:first-child
|
|
1162
|
+
'li:first-child': {
|
|
1112
1163
|
borderTopRightRadius: listBorderRadius,
|
|
1113
1164
|
borderTopLeftRadius: listBorderRadius,
|
|
1114
1165
|
},
|
|
1115
|
-
'li:last-child
|
|
1166
|
+
'li:last-child': {
|
|
1116
1167
|
borderBottomRightRadius: listBorderRadius,
|
|
1117
1168
|
borderBottomLeftRadius: listBorderRadius,
|
|
1118
1169
|
}
|
|
@@ -1121,36 +1172,23 @@ const Autocomplete = (p) => {
|
|
|
1121
1172
|
maxHeight: `calc(${theme.controls.height} * ${maxShowValues})`
|
|
1122
1173
|
}), p.listClassName) },
|
|
1123
1174
|
displayOptions.map((v, listItemIndex) => {
|
|
1124
|
-
|
|
1125
|
-
return (React__namespace.createElement(ListItem, { key: v, variant: "full", className: p.listItemClassName, role: "option", "aria-selected":
|
|
1126
|
-
React__namespace.createElement(
|
|
1127
|
-
var _a, _b;
|
|
1128
|
-
if (e.key === 'ArrowDown') {
|
|
1129
|
-
e.stopPropagation();
|
|
1130
|
-
e.preventDefault();
|
|
1131
|
-
(_a = getNextTabElement(listItemIndex, 1)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1132
|
-
}
|
|
1133
|
-
else if (e.key === 'ArrowUp') {
|
|
1134
|
-
e.stopPropagation();
|
|
1135
|
-
e.preventDefault();
|
|
1136
|
-
(_b = getNextTabElement(listItemIndex, -1)) === null || _b === void 0 ? void 0 : _b.focus();
|
|
1137
|
-
}
|
|
1138
|
-
else if (e.key === 'Enter') {
|
|
1139
|
-
e.stopPropagation();
|
|
1140
|
-
// this will prevent the click event from firing in addition to this enter key event.
|
|
1141
|
-
e.preventDefault();
|
|
1142
|
-
onPickValue(v);
|
|
1143
|
-
}
|
|
1144
|
-
}, className: css.cx(buttonMarkerClass + listItemIndex, css.css({
|
|
1145
|
-
borderRadius: 0,
|
|
1146
|
-
}), p.listItemButtonClassName), onClick: () => {
|
|
1147
|
-
onPickValue(v);
|
|
1148
|
-
} },
|
|
1149
|
-
React__namespace.createElement(Text, { tag: "div", ellipsis: true, align: "left" }, v))));
|
|
1175
|
+
const selected = selectedResultIndex === listItemIndex;
|
|
1176
|
+
return (React__namespace.createElement(ListItem, { key: v, variant: "full", className: css.cx(listItemStyles, selected ? listItemFocusStyles : undefined, p.listItemClassName), role: "option", id: getOptionId(p.id, listItemIndex), "aria-selected": selected },
|
|
1177
|
+
React__namespace.createElement(Text, { tag: "div", ellipsis: true, align: "left", className: listItemTextStyles }, v)));
|
|
1150
1178
|
}),
|
|
1151
1179
|
!p.allowScroll && displayOptions.length < p.options.length && (React__namespace.createElement(ListItem, { className: p.listItemClassName },
|
|
1152
1180
|
React__namespace.createElement(Text, { tag: "div", italics: true, align: "center" }, resultsText))))))));
|
|
1153
1181
|
};
|
|
1182
|
+
function getOptionId(baseId, optionIndex) {
|
|
1183
|
+
return `${baseId}_li_${optionIndex}`;
|
|
1184
|
+
}
|
|
1185
|
+
const styles = {
|
|
1186
|
+
autocomplete: css.css({
|
|
1187
|
+
position: 'relative',
|
|
1188
|
+
width: '100%',
|
|
1189
|
+
label: 'Autocomplete'
|
|
1190
|
+
}),
|
|
1191
|
+
};
|
|
1154
1192
|
|
|
1155
1193
|
/** Returns a UID. Use this instead of a direct call to a library. */
|
|
1156
1194
|
function createUid() {
|
|
@@ -1511,7 +1549,7 @@ const Calendar = (p) => {
|
|
|
1511
1549
|
|
|
1512
1550
|
const Checkbox = (props) => {
|
|
1513
1551
|
var _a;
|
|
1514
|
-
const { onChange, label, checkedIcon, uncheckedIcon, checkedThemeColor, checkedColor, readOnly } = props, inputProps = __rest(props, ["onChange", "label", "checkedIcon", "uncheckedIcon", "checkedThemeColor", "checkedColor", "readOnly"]);
|
|
1552
|
+
const { onChange, label, checkedIcon, uncheckedIcon, checkedThemeColor, checkedColor, readOnly, hideLabel } = props, inputProps = __rest(props, ["onChange", "label", "checkedIcon", "uncheckedIcon", "checkedThemeColor", "checkedColor", "readOnly", "hideLabel"]);
|
|
1515
1553
|
const selected = checkedIcon || 'selected';
|
|
1516
1554
|
const unselected = uncheckedIcon || 'unselected';
|
|
1517
1555
|
const theme = useThemeSafely();
|
|
@@ -1575,7 +1613,7 @@ const Checkbox = (props) => {
|
|
|
1575
1613
|
`;
|
|
1576
1614
|
return (React__namespace.createElement("span", { className: css.cx('checkbox', checkboxStyles, props.className) },
|
|
1577
1615
|
React__namespace.createElement("label", { className: labelStyles },
|
|
1578
|
-
React__namespace.createElement("input", Object.assign({}, inputProps, { tabIndex: readOnly ? -1 : (_a = props.tabIndex) !== null && _a !== void 0 ? _a : undefined, className: nativeCheckboxStyles, type: "checkbox", onChange: e => {
|
|
1616
|
+
React__namespace.createElement("input", Object.assign({}, inputProps, { "aria-label": hideLabel ? label : undefined, tabIndex: readOnly ? -1 : (_a = props.tabIndex) !== null && _a !== void 0 ? _a : undefined, className: nativeCheckboxStyles, type: "checkbox", onChange: e => {
|
|
1579
1617
|
if (readOnly) {
|
|
1580
1618
|
e.preventDefault();
|
|
1581
1619
|
return;
|
|
@@ -1583,7 +1621,7 @@ const Checkbox = (props) => {
|
|
|
1583
1621
|
return onChange(e.currentTarget.checked, e);
|
|
1584
1622
|
} })),
|
|
1585
1623
|
React__namespace.createElement(Icon, { className: css.cx('checkboxIcon', iconStyles), id: props.checked ? selected : unselected }),
|
|
1586
|
-
label,
|
|
1624
|
+
!hideLabel && label,
|
|
1587
1625
|
props.children)));
|
|
1588
1626
|
};
|
|
1589
1627
|
|
|
@@ -2878,7 +2916,6 @@ const LinkContent = (props) => {
|
|
|
2878
2916
|
}) }, props.rightIcon)));
|
|
2879
2917
|
};
|
|
2880
2918
|
|
|
2881
|
-
//TB: FUTURE de-dup these styles. create individual styles and compose them manually.
|
|
2882
2919
|
const generateLinkStyles = (props, theme) => {
|
|
2883
2920
|
const disabled = props.disabled || props.waiting;
|
|
2884
2921
|
let color = props.colorOverride;
|
|
@@ -4247,7 +4284,6 @@ const TextArea = React__namespace.forwardRef((props, ref) => {
|
|
|
4247
4284
|
}
|
|
4248
4285
|
else {
|
|
4249
4286
|
if (reportValueOnError) {
|
|
4250
|
-
//TB: temp, add a custom list of validators that will be run for all inputs if a pattern cannot be decided.
|
|
4251
4287
|
onValueChange(localValue);
|
|
4252
4288
|
}
|
|
4253
4289
|
else {
|