@dloizides/ui-forms 1.14.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/index.d.mts +98 -16
- package/dist/index.d.ts +98 -16
- package/dist/index.js +220 -96
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +218 -97
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -946,56 +946,19 @@ var FormField = ({
|
|
|
946
946
|
}
|
|
947
947
|
}
|
|
948
948
|
);
|
|
949
|
+
|
|
950
|
+
// src/ChipSelector/constants.ts
|
|
949
951
|
var TRANSPARENT_COLOR = "transparent";
|
|
950
|
-
var
|
|
952
|
+
var CHIP_HIT_SLOP = { top: 10, bottom: 10, left: 4, right: 4 };
|
|
953
|
+
var CHIP_GUTTER = 8;
|
|
954
|
+
var DEFAULT_CHIP_TESTID_PREFIX = "chip-selector-chip";
|
|
951
955
|
var SOLID_RADIUS = 20;
|
|
952
956
|
var OUTLINE_RADIUS = 999;
|
|
953
957
|
var OUTLINE_PAD_H = 12;
|
|
954
958
|
var OUTLINE_PAD_V = 5;
|
|
955
959
|
var OUTLINE_FONT_SIZE = 13;
|
|
956
|
-
var
|
|
957
|
-
var
|
|
958
|
-
var HEX_RADIX2 = 16;
|
|
959
|
-
var RGB_R_START = 0;
|
|
960
|
-
var RGB_R_END = 2;
|
|
961
|
-
var RGB_G_END = 4;
|
|
962
|
-
var RGB_B_END = 6;
|
|
963
|
-
var CHIP_HIT_SLOP = { top: 10, bottom: 10, left: 4, right: 4 };
|
|
964
|
-
var CHIP_GUTTER = 8;
|
|
965
|
-
var DEFAULT_CHIP_TESTID_PREFIX = "chip-selector-chip";
|
|
966
|
-
var ON_BRAND_SCALE = "onBrand";
|
|
967
|
-
var MAIN_STEP = "500";
|
|
968
|
-
function onBrandInk(palette) {
|
|
969
|
-
const scales = palette;
|
|
970
|
-
return scales[ON_BRAND_SCALE]?.[MAIN_STEP] ?? WHITE_COLOR;
|
|
971
|
-
}
|
|
972
|
-
function withAlpha2(hex, alpha) {
|
|
973
|
-
const normalized = hex.replace("#", "");
|
|
974
|
-
const isShort = normalized.length === HEX_SHORT_LENGTH2;
|
|
975
|
-
const full = isShort ? normalized.split("").map((c) => c + c).join("") : normalized;
|
|
976
|
-
const r = parseInt(full.slice(RGB_R_START, RGB_R_END), HEX_RADIX2);
|
|
977
|
-
const g = parseInt(full.slice(RGB_R_END, RGB_G_END), HEX_RADIX2);
|
|
978
|
-
const b = parseInt(full.slice(RGB_G_END, RGB_B_END), HEX_RADIX2);
|
|
979
|
-
const isValid = !Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b);
|
|
980
|
-
return isValid ? `rgba(${r}, ${g}, ${b}, ${alpha})` : hex;
|
|
981
|
-
}
|
|
982
|
-
var styles5 = StyleSheet.create({
|
|
983
|
-
chipContainer: {
|
|
984
|
-
flexDirection: "row",
|
|
985
|
-
flexWrap: "wrap",
|
|
986
|
-
// `gap`, NOT per-chip margins plus a compensating negative container margin.
|
|
987
|
-
//
|
|
988
|
-
// The old form was `chipWrapper { marginRight: 8, marginBottom: 8 }` with
|
|
989
|
-
// `chipContainer { marginBottom: -8 }`. Its comment blamed `Field`'s 16px container margin —
|
|
990
|
-
// that was WRONG, and worth recording: F3 was briefed on the belief that the -8 compensated for
|
|
991
|
-
// `Field` and had to move in lockstep with it. It did not. -8 cancelled the CHIP's own gutter
|
|
992
|
-
// hanging off the last row, identically whether `Field` contributed 16, 0, or anything else.
|
|
993
|
-
//
|
|
994
|
-
// The pair is still the wrong tool: it holds only while the two constants agree, and it leaves
|
|
995
|
-
// a real negative margin any measuring parent inherits. `gap` produces the byte-identical box
|
|
996
|
-
// and is correct under BOTH of `Field`'s spacing models, not just the one it was tuned against.
|
|
997
|
-
gap: CHIP_GUTTER
|
|
998
|
-
},
|
|
960
|
+
var CHIP_ICON_GAP = 6;
|
|
961
|
+
var chipStyles = StyleSheet.create({
|
|
999
962
|
chip: {
|
|
1000
963
|
paddingHorizontal: 12,
|
|
1001
964
|
paddingVertical: 6,
|
|
@@ -1009,28 +972,21 @@ var styles5 = StyleSheet.create({
|
|
|
1009
972
|
borderRadius: OUTLINE_RADIUS,
|
|
1010
973
|
borderWidth: 1
|
|
1011
974
|
},
|
|
975
|
+
chipContent: { flexDirection: "row", alignItems: "center", gap: CHIP_ICON_GAP },
|
|
1012
976
|
chipText: {},
|
|
1013
977
|
chipTextOutline: { fontSize: OUTLINE_FONT_SIZE }
|
|
1014
978
|
});
|
|
1015
|
-
function
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
};
|
|
979
|
+
function ChipContent({ icon, label, textStyle }) {
|
|
980
|
+
const text = /* @__PURE__ */ jsx(Text, { style: textStyle, children: label });
|
|
981
|
+
if (icon === void 0 || icon === null)
|
|
982
|
+
return text;
|
|
983
|
+
return /* @__PURE__ */ jsxs(View, { style: chipStyles.chipContent, children: [
|
|
984
|
+
/* @__PURE__ */ jsx(View, { "aria-hidden": true, children: icon }),
|
|
985
|
+
text
|
|
986
|
+
] });
|
|
1023
987
|
}
|
|
1024
|
-
function OutlineChip({
|
|
1025
|
-
option,
|
|
1026
|
-
selected,
|
|
1027
|
-
disabled,
|
|
1028
|
-
colors,
|
|
1029
|
-
testID,
|
|
1030
|
-
accessibilityHint,
|
|
1031
|
-
ariaPressed,
|
|
1032
|
-
onPress
|
|
1033
|
-
}) {
|
|
988
|
+
function OutlineChip(props) {
|
|
989
|
+
const { option, selected, disabled, colors, testID, accessibilityHint, onPress } = props;
|
|
1034
990
|
const [hovered, setHovered] = React2.useState(false);
|
|
1035
991
|
const active = selected || hovered;
|
|
1036
992
|
const borderColor = active ? colors.primary : colors.border;
|
|
@@ -1039,49 +995,179 @@ function OutlineChip({
|
|
|
1039
995
|
return /* @__PURE__ */ jsx(
|
|
1040
996
|
Pressable,
|
|
1041
997
|
{
|
|
998
|
+
ref: props.hostRef,
|
|
1042
999
|
accessibilityHint,
|
|
1043
1000
|
accessibilityLabel: option.label,
|
|
1044
|
-
accessibilityRole:
|
|
1001
|
+
accessibilityRole: props.accessibilityRole,
|
|
1045
1002
|
accessibilityState: { selected, disabled },
|
|
1046
|
-
"aria-
|
|
1003
|
+
"aria-checked": props.ariaChecked,
|
|
1004
|
+
"aria-pressed": props.ariaPressed,
|
|
1047
1005
|
disabled,
|
|
1048
1006
|
hitSlop: CHIP_HIT_SLOP,
|
|
1007
|
+
tabIndex: props.tabIndex,
|
|
1049
1008
|
testID,
|
|
1050
1009
|
onHoverIn: () => setHovered(true),
|
|
1051
1010
|
onHoverOut: () => setHovered(false),
|
|
1052
1011
|
onPress,
|
|
1053
|
-
children: /* @__PURE__ */ jsx(View, { style: [
|
|
1012
|
+
children: /* @__PURE__ */ jsx(View, { style: [chipStyles.chipOutline, { borderColor, backgroundColor }], children: /* @__PURE__ */ jsx(
|
|
1013
|
+
ChipContent,
|
|
1014
|
+
{
|
|
1015
|
+
icon: option.icon,
|
|
1016
|
+
label: option.label,
|
|
1017
|
+
textStyle: [chipStyles.chipText, chipStyles.chipTextOutline, { color: textColor }]
|
|
1018
|
+
}
|
|
1019
|
+
) })
|
|
1054
1020
|
}
|
|
1055
1021
|
);
|
|
1056
1022
|
}
|
|
1057
|
-
function SolidChip({
|
|
1058
|
-
option,
|
|
1059
|
-
selected,
|
|
1060
|
-
disabled,
|
|
1061
|
-
colors,
|
|
1062
|
-
testID,
|
|
1063
|
-
accessibilityHint,
|
|
1064
|
-
ariaPressed,
|
|
1065
|
-
onPress
|
|
1066
|
-
}) {
|
|
1023
|
+
function SolidChip(props) {
|
|
1024
|
+
const { option, selected, disabled, colors, testID, accessibilityHint, onPress } = props;
|
|
1067
1025
|
const backgroundColor = selected ? colors.primary : TRANSPARENT_COLOR;
|
|
1068
1026
|
const textColor = selected ? colors.onPrimary : colors.textStrong;
|
|
1027
|
+
const rovingTabStop = { tabIndex: props.tabIndex };
|
|
1069
1028
|
return /* @__PURE__ */ jsx(
|
|
1070
1029
|
TouchableOpacity,
|
|
1071
1030
|
{
|
|
1031
|
+
ref: props.hostRef,
|
|
1072
1032
|
accessibilityHint,
|
|
1073
1033
|
accessibilityLabel: option.label,
|
|
1074
|
-
accessibilityRole:
|
|
1034
|
+
accessibilityRole: props.accessibilityRole,
|
|
1075
1035
|
accessibilityState: { selected, disabled },
|
|
1076
|
-
"aria-
|
|
1036
|
+
"aria-checked": props.ariaChecked,
|
|
1037
|
+
"aria-pressed": props.ariaPressed,
|
|
1077
1038
|
disabled,
|
|
1078
1039
|
hitSlop: CHIP_HIT_SLOP,
|
|
1079
1040
|
testID,
|
|
1080
1041
|
onPress,
|
|
1081
|
-
|
|
1042
|
+
...rovingTabStop,
|
|
1043
|
+
children: /* @__PURE__ */ jsx(View, { style: [chipStyles.chip, { borderColor: colors.border, backgroundColor }], children: /* @__PURE__ */ jsx(ChipContent, { icon: option.icon, label: option.label, textStyle: [chipStyles.chipText, { color: textColor }] }) })
|
|
1082
1044
|
}
|
|
1083
1045
|
);
|
|
1084
1046
|
}
|
|
1047
|
+
|
|
1048
|
+
// src/ChipSelector/utils/radioKeyboard.ts
|
|
1049
|
+
var SPACE_KEYS = [" ", "Spacebar"];
|
|
1050
|
+
var NEXT_KEYS = ["ArrowRight", "ArrowDown"];
|
|
1051
|
+
var PREVIOUS_KEYS = ["ArrowLeft", "ArrowUp"];
|
|
1052
|
+
var ROVING_TAB_STOP = 0;
|
|
1053
|
+
var ROVING_SKIPPED = -1;
|
|
1054
|
+
function radioKeyTarget(key, index, count) {
|
|
1055
|
+
const isOutOfRange = index < 0 || index >= count;
|
|
1056
|
+
if (isOutOfRange)
|
|
1057
|
+
return null;
|
|
1058
|
+
if (SPACE_KEYS.includes(key))
|
|
1059
|
+
return index;
|
|
1060
|
+
const isArrow = NEXT_KEYS.includes(key) || PREVIOUS_KEYS.includes(key);
|
|
1061
|
+
if (!isArrow || count === 1)
|
|
1062
|
+
return null;
|
|
1063
|
+
const step = NEXT_KEYS.includes(key) ? 1 : -1;
|
|
1064
|
+
return (index + step + count) % count;
|
|
1065
|
+
}
|
|
1066
|
+
function radioTabIndex(index, selectedIndex, disabled) {
|
|
1067
|
+
if (disabled)
|
|
1068
|
+
return ROVING_SKIPPED;
|
|
1069
|
+
const tabStop = selectedIndex >= 0 ? selectedIndex : 0;
|
|
1070
|
+
return index === tabStop ? ROVING_TAB_STOP : ROVING_SKIPPED;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
// src/ChipSelector/hooks/useRadioKeyboard.ts
|
|
1074
|
+
var NO_GROUP_PROPS = {};
|
|
1075
|
+
function useRadioKeyboard(config) {
|
|
1076
|
+
const { enabled, disabled, values, selectedIndex, onChange } = config;
|
|
1077
|
+
const nodes = React2.useRef([]);
|
|
1078
|
+
const chipRef = React2.useCallback((index) => (node) => {
|
|
1079
|
+
nodes.current[index] = node;
|
|
1080
|
+
}, []);
|
|
1081
|
+
const onKeyDown = (event) => {
|
|
1082
|
+
if (disabled)
|
|
1083
|
+
return;
|
|
1084
|
+
const index = nodes.current.indexOf(event.target);
|
|
1085
|
+
const target = radioKeyTarget(event.key, index, values.length);
|
|
1086
|
+
const nextValue = target === null ? void 0 : values[target];
|
|
1087
|
+
if (target === null || nextValue === void 0)
|
|
1088
|
+
return;
|
|
1089
|
+
event.preventDefault();
|
|
1090
|
+
if (target !== index)
|
|
1091
|
+
nodes.current[target]?.focus?.();
|
|
1092
|
+
onChange(nextValue);
|
|
1093
|
+
};
|
|
1094
|
+
return {
|
|
1095
|
+
chipRef,
|
|
1096
|
+
tabIndexFor: (index) => enabled ? radioTabIndex(index, selectedIndex, disabled) : void 0,
|
|
1097
|
+
// `onKeyDown` is a web-only View prop RN's types do not declare; RNW forwards it to the DOM.
|
|
1098
|
+
groupProps: enabled ? { onKeyDown } : NO_GROUP_PROPS
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// src/ChipSelector/utils/chipColors.ts
|
|
1103
|
+
var WHITE_COLOR = "#fff";
|
|
1104
|
+
var OUTLINE_TINT_ALPHA = 0.1;
|
|
1105
|
+
var HEX_SHORT_LENGTH2 = 3;
|
|
1106
|
+
var HEX_RADIX2 = 16;
|
|
1107
|
+
var RGB_R_START = 0;
|
|
1108
|
+
var RGB_R_END = 2;
|
|
1109
|
+
var RGB_G_END = 4;
|
|
1110
|
+
var RGB_B_END = 6;
|
|
1111
|
+
var ON_BRAND_SCALE = "onBrand";
|
|
1112
|
+
var MAIN_STEP = "500";
|
|
1113
|
+
function onBrandInk(palette) {
|
|
1114
|
+
const scales = palette;
|
|
1115
|
+
return scales[ON_BRAND_SCALE]?.[MAIN_STEP] ?? WHITE_COLOR;
|
|
1116
|
+
}
|
|
1117
|
+
function withAlpha2(hex, alpha) {
|
|
1118
|
+
const normalized = hex.replace("#", "");
|
|
1119
|
+
const isShort = normalized.length === HEX_SHORT_LENGTH2;
|
|
1120
|
+
const full = isShort ? normalized.split("").map((c) => c + c).join("") : normalized;
|
|
1121
|
+
const r = parseInt(full.slice(RGB_R_START, RGB_R_END), HEX_RADIX2);
|
|
1122
|
+
const g = parseInt(full.slice(RGB_R_END, RGB_G_END), HEX_RADIX2);
|
|
1123
|
+
const b = parseInt(full.slice(RGB_G_END, RGB_B_END), HEX_RADIX2);
|
|
1124
|
+
const isValid = !Number.isNaN(r) && !Number.isNaN(g) && !Number.isNaN(b);
|
|
1125
|
+
return isValid ? `rgba(${r}, ${g}, ${b}, ${alpha})` : hex;
|
|
1126
|
+
}
|
|
1127
|
+
function buildChipColors(colors, palette) {
|
|
1128
|
+
const primary = palette.primary[500];
|
|
1129
|
+
return {
|
|
1130
|
+
border: colors.border,
|
|
1131
|
+
textStrong: colors.text,
|
|
1132
|
+
textMuted: colors.textSecondary,
|
|
1133
|
+
primary,
|
|
1134
|
+
onPrimary: onBrandInk(palette),
|
|
1135
|
+
muted: colors.background,
|
|
1136
|
+
tint: withAlpha2(primary, OUTLINE_TINT_ALPHA)
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// src/ChipSelector/utils/chipIdentity.ts
|
|
1141
|
+
function chipIdentity(option, selected, config) {
|
|
1142
|
+
const isRadio = config.radio === true && !config.multiple;
|
|
1143
|
+
return {
|
|
1144
|
+
testID: `${config.prefix}-${String(option.value)}`,
|
|
1145
|
+
// The English default is retained verbatim: erevna/katalogos assert the exact string
|
|
1146
|
+
// `Selects Red`. Consumers that localize pass `optionAccessibilityHint`.
|
|
1147
|
+
accessibilityHint: config.hint ?? `Selects ${option.label}`,
|
|
1148
|
+
ariaPressed: config.multiple ? selected : void 0,
|
|
1149
|
+
accessibilityRole: isRadio ? "radio" : "button",
|
|
1150
|
+
ariaChecked: isRadio ? selected : void 0
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
var styles5 = StyleSheet.create({
|
|
1154
|
+
chipContainer: {
|
|
1155
|
+
flexDirection: "row",
|
|
1156
|
+
flexWrap: "wrap",
|
|
1157
|
+
// `gap`, NOT per-chip margins plus a compensating negative container margin.
|
|
1158
|
+
//
|
|
1159
|
+
// The old form was `chipWrapper { marginRight: 8, marginBottom: 8 }` with
|
|
1160
|
+
// `chipContainer { marginBottom: -8 }`. Its comment blamed `Field`'s 16px container margin —
|
|
1161
|
+
// that was WRONG, and worth recording: F3 was briefed on the belief that the -8 compensated for
|
|
1162
|
+
// `Field` and had to move in lockstep with it. It did not. -8 cancelled the CHIP's own gutter
|
|
1163
|
+
// hanging off the last row, identically whether `Field` contributed 16, 0, or anything else.
|
|
1164
|
+
//
|
|
1165
|
+
// The pair is still the wrong tool: it holds only while the two constants agree, and it leaves
|
|
1166
|
+
// a real negative margin any measuring parent inherits. `gap` produces the byte-identical box
|
|
1167
|
+
// and is correct under BOTH of `Field`'s spacing models, not just the one it was tuned against.
|
|
1168
|
+
gap: CHIP_GUTTER
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1085
1171
|
var ChipSelector = ({
|
|
1086
1172
|
label,
|
|
1087
1173
|
options,
|
|
@@ -1096,28 +1182,26 @@ var ChipSelector = ({
|
|
|
1096
1182
|
error,
|
|
1097
1183
|
testID,
|
|
1098
1184
|
chipTestIDPrefix = DEFAULT_CHIP_TESTID_PREFIX,
|
|
1099
|
-
optionAccessibilityHint
|
|
1185
|
+
optionAccessibilityHint,
|
|
1186
|
+
singleSelectRole = "button"
|
|
1100
1187
|
}) => {
|
|
1188
|
+
const isRadioGroup = !multiple && singleSelectRole === "radio";
|
|
1101
1189
|
const { theme } = useUi();
|
|
1102
1190
|
const { colors, palette } = theme;
|
|
1103
|
-
const chipColors = React2.useMemo(() =>
|
|
1104
|
-
const primary = palette.primary["500"];
|
|
1105
|
-
return {
|
|
1106
|
-
border: colors.border,
|
|
1107
|
-
textStrong: colors.text,
|
|
1108
|
-
textMuted: colors.textSecondary,
|
|
1109
|
-
primary,
|
|
1110
|
-
onPrimary: onBrandInk(palette),
|
|
1111
|
-
muted: colors.background,
|
|
1112
|
-
tint: withAlpha2(primary, OUTLINE_TINT_ALPHA)
|
|
1113
|
-
};
|
|
1114
|
-
}, [colors.border, colors.text, colors.textSecondary, colors.background, palette]);
|
|
1191
|
+
const chipColors = React2.useMemo(() => buildChipColors(colors, palette), [colors, palette]);
|
|
1115
1192
|
function isSelected(optionValue) {
|
|
1116
1193
|
if (multiple && Array.isArray(value))
|
|
1117
1194
|
return value.includes(optionValue);
|
|
1118
1195
|
return value === optionValue;
|
|
1119
1196
|
}
|
|
1120
|
-
|
|
1197
|
+
const radio = useRadioKeyboard({
|
|
1198
|
+
enabled: isRadioGroup,
|
|
1199
|
+
disabled,
|
|
1200
|
+
values: options.map((option) => option.value),
|
|
1201
|
+
selectedIndex: options.findIndex((option) => isSelected(option.value)),
|
|
1202
|
+
onChange
|
|
1203
|
+
});
|
|
1204
|
+
function renderChip(option, index) {
|
|
1121
1205
|
const selected = isSelected(option.value);
|
|
1122
1206
|
const chipProps = {
|
|
1123
1207
|
colors: chipColors,
|
|
@@ -1127,8 +1211,13 @@ var ChipSelector = ({
|
|
|
1127
1211
|
...chipIdentity(option, selected, {
|
|
1128
1212
|
prefix: chipTestIDPrefix,
|
|
1129
1213
|
hint: optionAccessibilityHint,
|
|
1130
|
-
multiple
|
|
1214
|
+
multiple,
|
|
1215
|
+
radio: isRadioGroup
|
|
1131
1216
|
}),
|
|
1217
|
+
// Radio mode only: roving tab stop + host node for arrow-key focus moves. Both stay
|
|
1218
|
+
// `undefined` otherwise, so button / multi chips keep their existing tab order.
|
|
1219
|
+
tabIndex: radio.tabIndexFor(index),
|
|
1220
|
+
hostRef: isRadioGroup ? radio.chipRef(index) : void 0,
|
|
1132
1221
|
onPress: () => onChange(option.value)
|
|
1133
1222
|
};
|
|
1134
1223
|
const key = String(option.value);
|
|
@@ -1143,7 +1232,16 @@ var ChipSelector = ({
|
|
|
1143
1232
|
required,
|
|
1144
1233
|
spacing,
|
|
1145
1234
|
testID,
|
|
1146
|
-
children: ({ describedById, hasError }) => /* @__PURE__ */ jsx(
|
|
1235
|
+
children: ({ describedById, hasError }) => /* @__PURE__ */ jsx(
|
|
1236
|
+
View,
|
|
1237
|
+
{
|
|
1238
|
+
accessibilityRole: isRadioGroup ? "radiogroup" : void 0,
|
|
1239
|
+
style: styles5.chipContainer,
|
|
1240
|
+
...webFieldA11y({ describedById, hasError }),
|
|
1241
|
+
...radio.groupProps,
|
|
1242
|
+
children: options.map(renderChip)
|
|
1243
|
+
}
|
|
1244
|
+
)
|
|
1147
1245
|
}
|
|
1148
1246
|
);
|
|
1149
1247
|
};
|
|
@@ -1201,8 +1299,7 @@ var FormSwitch = ({
|
|
|
1201
1299
|
{
|
|
1202
1300
|
accessibilityHint: accessibilityHint ?? label,
|
|
1203
1301
|
accessibilityLabel: label,
|
|
1204
|
-
|
|
1205
|
-
accessibilityState: { checked: value },
|
|
1302
|
+
accessibilityState: { checked: value, disabled },
|
|
1206
1303
|
disabled,
|
|
1207
1304
|
testID,
|
|
1208
1305
|
value,
|
|
@@ -1576,6 +1673,30 @@ function DateRangeControl({
|
|
|
1576
1673
|
] });
|
|
1577
1674
|
}
|
|
1578
1675
|
|
|
1579
|
-
|
|
1676
|
+
// src/groupSelection/groupSelection.ts
|
|
1677
|
+
var NONE = 0;
|
|
1678
|
+
function countSelected(selected, groupKeys) {
|
|
1679
|
+
return groupKeys.filter((key) => selected.includes(key)).length;
|
|
1680
|
+
}
|
|
1681
|
+
function resolveGroupSelection(selected, groupKeys) {
|
|
1682
|
+
const count = countSelected(selected, groupKeys);
|
|
1683
|
+
if (count === NONE) return { all: false, some: false };
|
|
1684
|
+
return count === groupKeys.length ? { all: true, some: false } : { all: false, some: true };
|
|
1685
|
+
}
|
|
1686
|
+
function groupAriaChecked(state) {
|
|
1687
|
+
if (state.all) return true;
|
|
1688
|
+
return state.some ? "mixed" : false;
|
|
1689
|
+
}
|
|
1690
|
+
function toggleGroupSelection(selected, groupKeys, order) {
|
|
1691
|
+
const { all } = resolveGroupSelection(selected, groupKeys);
|
|
1692
|
+
if (all) return selected.filter((key) => !groupKeys.includes(key));
|
|
1693
|
+
const merged = [...selected];
|
|
1694
|
+
groupKeys.forEach((key) => {
|
|
1695
|
+
if (!merged.includes(key)) merged.push(key);
|
|
1696
|
+
});
|
|
1697
|
+
return order === void 0 ? merged : order.filter((key) => merged.includes(key));
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
export { AnchoredMenu, ChipSelector, DEFAULT_MAX_RECENTS, DEFAULT_OPTIONAL_LABEL, DEFAULT_TYPEAHEAD_MAX_SUGGESTIONS, DEFAULT_TYPEAHEAD_MIN_CHARS, DateRangeControl, Field, FormActions, FormCell, FormCheckbox, FormField, FormGrid, FormSection, FormSwitch, SelectControl, ThemedTextInput, TypeaheadControl, controlStyles, groupAriaChecked, isUnmatched, resolveGroupSelection, suggestOptions, toggleGroupSelection, useRecentValues, useThemedInput };
|
|
1580
1701
|
//# sourceMappingURL=index.mjs.map
|
|
1581
1702
|
//# sourceMappingURL=index.mjs.map
|