@servicetitan/design-system 14.5.2 → 14.5.11

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.
@@ -15,18 +15,36 @@ import { ButtonToggleItem } from './ButtonToggleItem';
15
15
  import { useArrowNav } from '../../hooks/useArrowNav';
16
16
  import { useMergedRef } from '../../hooks';
17
17
  export const ButtonToggle = React.forwardRef(function (_a, ref) {
18
- var { color = 'primary', primary, negative, className, disabled, el: ButtonToggleElement = 'div', clearable, options = [], large, small, xsmall, name, size = 'medium', value, onChange } = _a, props = __rest(_a, ["color", "primary", "negative", "className", "disabled", "el", "clearable", "options", "large", "small", "xsmall", "name", "size", "value", "onChange"]);
18
+ var { color = 'primary', primary, negative, className, disabled, el: ButtonToggleElement = 'div', clearable, options = [], large, small, xsmall, name, size = 'medium', value, onChange, onFocus, onBlur } = _a, props = __rest(_a, ["color", "primary", "negative", "className", "disabled", "el", "clearable", "options", "large", "small", "xsmall", "name", "size", "value", "onChange", "onFocus", "onBlur"]);
19
19
  const [selected, setSelected] = React.useState(value);
20
+ const [focusedIndex, setFocusedIndex] = React.useState(null);
21
+ const lastTabStopIndex = React.useRef(0);
20
22
  React.useEffect(() => {
21
23
  setSelected(value);
22
24
  }, [value]);
25
+ const handleFocus = (e) => {
26
+ const buttons = Array.from(e.currentTarget.querySelectorAll('button'));
27
+ const index = buttons.indexOf(e.target);
28
+ if (index >= 0)
29
+ setFocusedIndex(index);
30
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(e);
31
+ };
32
+ const handleBlur = (e) => {
33
+ setFocusedIndex(null);
34
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
35
+ };
23
36
  const arrowNavRef = React.useRef(null);
24
37
  const mergedRef = useMergedRef(ref, arrowNavRef);
25
38
  useArrowNav({
26
39
  scope: arrowNavRef,
27
40
  handleY: false,
28
41
  focusableSelector: { selector: 'button:not([disabled])' },
29
- onKeyDown: (e, data) => { var _a; return (_a = data.next) === null || _a === void 0 ? void 0 : _a.click(); }, // Auto-selection
42
+ onKeyDown: (e, data) => { var _a; return (_a = data.next) === null || _a === void 0 ? void 0 : _a.click(); },
43
+ /*
44
+ * The tab stop is set while rendering; the hook's tab grouping would measure and
45
+ * rewrite every button after each render, forcing a layout per toggle.
46
+ */
47
+ tabIndexGroup: false,
30
48
  });
31
49
  const handleClick = (select) => {
32
50
  const realSelected = select !== selected || !clearable ? select : undefined;
@@ -82,7 +100,9 @@ export const ButtonToggle = React.forwardRef(function (_a, ref) {
82
100
  realColor = 'negative';
83
101
  return realColor;
84
102
  };
103
+ let tabStopIndex = -1;
85
104
  const getButtonToggleItemProps = (options) => {
105
+ var _a, _b, _c;
86
106
  let realSize = size;
87
107
  // Override string props with boolean values
88
108
  if (xsmall)
@@ -91,6 +111,16 @@ export const ButtonToggle = React.forwardRef(function (_a, ref) {
91
111
  realSize = 'small';
92
112
  if (large)
93
113
  realSize = 'large';
114
+ const isFocusable = (option) => !option.disabled && !option.hidden;
115
+ const focusableAt = (index) => index !== null && options[index] && isFocusable(options[index])
116
+ ? options[index]
117
+ : undefined;
118
+ /*
119
+ * Same order as the tab grouping of useArrowNav: the focused option, the selected one,
120
+ * the previous tab stop, then the first option that can be focused.
121
+ */
122
+ const tabStop = (_c = (_b = (_a = focusableAt(focusedIndex)) !== null && _a !== void 0 ? _a : options.find((option) => option.selected && isFocusable(option))) !== null && _b !== void 0 ? _b : focusableAt(lastTabStopIndex.current)) !== null && _c !== void 0 ? _c : options.find(isFocusable);
123
+ tabStopIndex = tabStop ? options.indexOf(tabStop) : -1;
94
124
  const buttonToggleItemProps = options.map((option) => {
95
125
  return {
96
126
  name,
@@ -108,6 +138,7 @@ export const ButtonToggle = React.forwardRef(function (_a, ref) {
108
138
  },
109
139
  icon: option.icon,
110
140
  iconName: option.iconName,
141
+ tabIndex: option === tabStop ? 0 : -1,
111
142
  };
112
143
  });
113
144
  return buttonToggleItemProps;
@@ -116,6 +147,11 @@ export const ButtonToggle = React.forwardRef(function (_a, ref) {
116
147
  const onlySelectedOptions = getOnlySelected(copiedOptions);
117
148
  const normalizedOptions = getNormalized(onlySelectedOptions);
118
149
  const buttonToggleItemProps = getButtonToggleItemProps(normalizedOptions);
150
+ // Written after commit so that a render React discards cannot move the tab stop
151
+ React.useEffect(() => {
152
+ if (tabStopIndex >= 0)
153
+ lastTabStopIndex.current = tabStopIndex;
154
+ });
119
155
  const contents = buttonToggleItemProps.map((buttonProp, index) => {
120
156
  return React.createElement(ButtonToggleItem, Object.assign({ key: index }, buttonProp));
121
157
  });
@@ -124,6 +160,6 @@ export const ButtonToggle = React.forwardRef(function (_a, ref) {
124
160
  'ButtonToggle--disabled': disabled,
125
161
  [`ButtonToggle--${realColor}`]: realColor,
126
162
  });
127
- return (React.createElement(ButtonToggleElement, Object.assign({ className: ButtonToggleClasses, "data-anvil-component": "ButtonToggle", ref: mergedRef, role: clearable ? null : 'radiogroup' }, props), contents));
163
+ return (React.createElement(ButtonToggleElement, Object.assign({ className: ButtonToggleClasses, "data-anvil-component": "ButtonToggle", ref: mergedRef, role: clearable ? null : 'radiogroup', onFocus: handleFocus, onBlur: handleBlur }, props), contents));
128
164
  });
129
165
  //# sourceMappingURL=ButtonToggle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonToggle.js","sourceRoot":"","sources":["../../../src/components/ButtonToggle/ButtonToggle.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport classnames from 'classnames';\n\nimport { ButtonToggleItem, ButtonToggleItemProps } from './ButtonToggleItem';\nimport { useArrowNav } from '../../hooks/useArrowNav';\nimport { useMergedRef } from '../../hooks';\n\n/**\n * Option properties\n */\nexport interface OptionProps<T> {\n\t/** Content of the element, i.e. the displayed text */\n\ttext?: ButtonToggleItemProps<T>['text'];\n\n\t/** Value of the option */\n\tvalue: ButtonToggleItemProps<T>['value'];\n\n\t/** Returns value of option for the click event */\n\tonClick?: ButtonToggleItemProps<T>['onClick'];\n\n\t/** Indicates whether the element is disabled or not. It makes the option unselectable */\n\tdisabled?: ButtonToggleItemProps<T>['disabled'];\n\n\t/** Sets the option's selected state */\n\tselected?: ButtonToggleItemProps<T>['selected'];\n\n\t/** Hide the option (not commonly used) */\n\thidden?: ButtonToggleItemProps<T>['hidden'];\n\n\t/** React element to be rendered as an icon */\n\ticon?: ButtonToggleItemProps<T>['icon'];\n\n\t/** Name of icon to render inside of button */\n\ticonName?: ButtonToggleItemProps<T>['iconName'];\n}\n\n/**\n * ButtonToggle properties\n */\nexport interface ButtonTogglePropsStrict<T> {\n\t/** String of class names to add to component */\n\tclassName?: string;\n\n\t/** Switch on unselected state */\n\tclearable?: boolean;\n\n\t/** Selected button background color.<br /> Possible values: <i>'primary'</i>, <i>'blue'</i>, <i>'negative'</i>, <i>'red'</i> */\n\tcolor?: ButtonToggleItemProps<T>['color']; // 'default', 'grey' are colors of not selected buttons\n\n\t/** Sets all the option's unselectable */\n\tdisabled?: ButtonToggleItemProps<T>['disabled'];\n\n\t/** Element to use for base component */\n\tel?: any;\n\n\t/** Shortcut for large-sized buttons */\n\tlarge?: boolean;\n\n\t/** Specifies the name of the ButtonToggle element */\n\tname?: string;\n\n\t/** Negative styling (red) */\n\tnegative?: boolean;\n\n\t/** Called when the user changes the value */\n\tonChange?: (value: T | undefined) => void;\n\n\t/** List of options */\n\toptions?: OptionProps<T>[];\n\n\t/** Primary button */\n\tprimary?: boolean;\n\n\t/** Sets size of the buttons.<br /> Possible values: <i>'large'</i>, <i>'small'</i> */\n\tsize?: ButtonToggleItemProps<T>['size'];\n\n\t/** Shortcut for small-sized buttons */\n\tsmall?: boolean;\n\n\t/** Value of the ButtonToggle element. Sets corresponding option selected */\n\tvalue?: ButtonToggleItemProps<T>['value'];\n\n\t/** Shortcut for x-small-sized buttons */\n\txsmall?: boolean;\n}\n\nexport interface ButtonToggleProps<T> extends ButtonTogglePropsStrict<T> {\n\t/** Unstrict Props */\n\t[propName: string]: any;\n}\n\ninterface ButtonToggleState<T> {\n\tselected: ButtonToggleItemProps<T>['value'];\n}\n\nexport const ButtonToggle: <T>(\n\tprops: React.PropsWithoutRef<ButtonToggleProps<T>> &\n\t\tReact.RefAttributes<HTMLElement>\n) => React.ReactElement | null = React.forwardRef(function <T>(\n\t{\n\t\tcolor = 'primary',\n\t\tprimary,\n\t\tnegative,\n\t\tclassName,\n\t\tdisabled,\n\t\tel: ButtonToggleElement = 'div',\n\t\tclearable,\n\t\toptions = [],\n\t\tlarge,\n\t\tsmall,\n\t\txsmall,\n\t\tname,\n\t\tsize = 'medium',\n\t\tvalue,\n\t\tonChange,\n\t\t...props\n\t}: ButtonToggleProps<T>,\n\tref: React.RefObject<HTMLElement>\n) {\n\tconst [selected, setSelected] =\n\t\tReact.useState<ButtonToggleState<T>['selected']>(value);\n\n\tReact.useEffect(() => {\n\t\tsetSelected(value);\n\t}, [value]);\n\n\tconst arrowNavRef = React.useRef(null);\n\tconst mergedRef = useMergedRef(ref, arrowNavRef);\n\n\tuseArrowNav({\n\t\tscope: arrowNavRef,\n\t\thandleY: false,\n\t\tfocusableSelector: { selector: 'button:not([disabled])' },\n\t\tonKeyDown: (e: KeyboardEvent, data: any) => data.next?.click(), // Auto-selection\n\t});\n\n\tconst handleClick = (select: ButtonToggleItemProps<T>['value']) => {\n\t\tconst realSelected =\n\t\t\tselect !== selected || !clearable ? select : undefined;\n\n\t\tif (onChange) onChange(realSelected);\n\t\tsetSelected(realSelected);\n\t};\n\n\tconst copyOptions = (options: OptionProps<T>[]): OptionProps<T>[] => {\n\t\tconst copiedOptions = options.map((option) => {\n\t\t\treturn {\n\t\t\t\ttext: option.text,\n\t\t\t\tvalue: option.value,\n\t\t\t\tonClick: option.onClick,\n\t\t\t\tdisabled: option.disabled,\n\t\t\t\tselected: option.selected,\n\t\t\t\thidden: option.hidden,\n\t\t\t\ticon: option.icon,\n\t\t\t\ticonName: option.iconName,\n\t\t\t};\n\t\t});\n\n\t\treturn copiedOptions;\n\t};\n\n\tconst getOnlySelected = (options: OptionProps<T>[]): OptionProps<T>[] => {\n\t\tlet isSelected = false;\n\n\t\tconst onlyOneSelectedOptions = options.map((option) => {\n\t\t\tif (option.selected && !isSelected) {\n\t\t\t\tisSelected = true;\n\t\t\t} else {\n\t\t\t\toption.selected = false;\n\t\t\t}\n\t\t\treturn option;\n\t\t});\n\n\t\treturn onlyOneSelectedOptions;\n\t};\n\n\tconst getNormalized = (options: OptionProps<T>[]): OptionProps<T>[] => {\n\t\tconst realOptions = options.map((option) => {\n\t\t\tif (disabled) option.disabled = disabled;\n\t\t\tif (option.text === undefined) option.text = null;\n\t\t\tif (selected !== undefined || clearable)\n\t\t\t\toption.selected = selected === option.value;\n\n\t\t\treturn option;\n\t\t});\n\n\t\treturn realOptions;\n\t};\n\n\tconst getRealColor = () => {\n\t\tlet realColor: ButtonToggleItemProps<T>['color'] = color;\n\n\t\tif (primary) realColor = 'primary';\n\t\tif (negative) realColor = 'negative';\n\n\t\treturn realColor;\n\t};\n\n\tconst getButtonToggleItemProps = (\n\t\toptions: OptionProps<T>[]\n\t): ButtonToggleItemProps<T>[] => {\n\t\tlet realSize: ButtonToggleItemProps<T>['size'] = size;\n\n\t\t// Override string props with boolean values\n\t\tif (xsmall) realSize = 'xsmall';\n\t\tif (small) realSize = 'small';\n\t\tif (large) realSize = 'large';\n\n\t\tconst buttonToggleItemProps = options.map((option) => {\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\ttext: option.text,\n\t\t\t\tvalue: option.value,\n\t\t\t\tdisabled: option.disabled,\n\t\t\t\tselected: option.selected,\n\t\t\t\tcolor: getRealColor(),\n\t\t\t\tsize: realSize,\n\t\t\t\thidden: option.hidden,\n\t\t\t\tonClick: (value: ButtonToggleItemProps<T>['value']) => {\n\t\t\t\t\tif (option.onClick) option.onClick(value);\n\t\t\t\t\thandleClick(value);\n\t\t\t\t},\n\t\t\t\ticon: option.icon,\n\t\t\t\ticonName: option.iconName,\n\t\t\t};\n\t\t});\n\n\t\treturn buttonToggleItemProps;\n\t};\n\n\tconst copiedOptions = copyOptions(options);\n\n\tconst onlySelectedOptions = getOnlySelected(copiedOptions);\n\n\tconst normalizedOptions = getNormalized(onlySelectedOptions);\n\n\tconst buttonToggleItemProps = getButtonToggleItemProps(normalizedOptions);\n\n\tconst contents = buttonToggleItemProps.map((buttonProp, index) => {\n\t\treturn <ButtonToggleItem<T> key={index} {...buttonProp} />;\n\t});\n\n\tconst realColor = getRealColor();\n\n\tconst ButtonToggleClasses = classnames('ButtonToggle', className, {\n\t\t'ButtonToggle--disabled': disabled,\n\t\t[`ButtonToggle--${realColor}`]: realColor,\n\t});\n\n\treturn (\n\t\t<ButtonToggleElement\n\t\t\tclassName={ButtonToggleClasses}\n\t\t\tdata-anvil-component=\"ButtonToggle\"\n\t\t\tref={mergedRef}\n\t\t\trole={clearable ? null : 'radiogroup'}\n\t\t\t{...props}\n\t\t>\n\t\t\t{contents}\n\t\t</ButtonToggleElement>\n\t);\n});\n"]}
1
+ {"version":3,"file":"ButtonToggle.js","sourceRoot":"","sources":["../../../src/components/ButtonToggle/ButtonToggle.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport classnames from 'classnames';\n\nimport { ButtonToggleItem, ButtonToggleItemProps } from './ButtonToggleItem';\nimport { useArrowNav } from '../../hooks/useArrowNav';\nimport { useMergedRef } from '../../hooks';\n\n/**\n * Option properties\n */\nexport interface OptionProps<T> {\n\t/** Content of the element, i.e. the displayed text */\n\ttext?: ButtonToggleItemProps<T>['text'];\n\n\t/** Value of the option */\n\tvalue: ButtonToggleItemProps<T>['value'];\n\n\t/** Returns value of option for the click event */\n\tonClick?: ButtonToggleItemProps<T>['onClick'];\n\n\t/** Indicates whether the element is disabled or not. It makes the option unselectable */\n\tdisabled?: ButtonToggleItemProps<T>['disabled'];\n\n\t/** Sets the option's selected state */\n\tselected?: ButtonToggleItemProps<T>['selected'];\n\n\t/** Hide the option (not commonly used) */\n\thidden?: ButtonToggleItemProps<T>['hidden'];\n\n\t/** React element to be rendered as an icon */\n\ticon?: ButtonToggleItemProps<T>['icon'];\n\n\t/** Name of icon to render inside of button */\n\ticonName?: ButtonToggleItemProps<T>['iconName'];\n}\n\n/**\n * ButtonToggle properties\n */\nexport interface ButtonTogglePropsStrict<T> {\n\t/** String of class names to add to component */\n\tclassName?: string;\n\n\t/** Switch on unselected state */\n\tclearable?: boolean;\n\n\t/** Selected button background color.<br /> Possible values: <i>'primary'</i>, <i>'blue'</i>, <i>'negative'</i>, <i>'red'</i> */\n\tcolor?: ButtonToggleItemProps<T>['color']; // 'default', 'grey' are colors of not selected buttons\n\n\t/** Sets all the option's unselectable */\n\tdisabled?: ButtonToggleItemProps<T>['disabled'];\n\n\t/** Element to use for base component */\n\tel?: any;\n\n\t/** Shortcut for large-sized buttons */\n\tlarge?: boolean;\n\n\t/** Specifies the name of the ButtonToggle element */\n\tname?: string;\n\n\t/** Negative styling (red) */\n\tnegative?: boolean;\n\n\t/** Called when the user changes the value */\n\tonChange?: (value: T | undefined) => void;\n\n\t/** List of options */\n\toptions?: OptionProps<T>[];\n\n\t/** Primary button */\n\tprimary?: boolean;\n\n\t/** Sets size of the buttons.<br /> Possible values: <i>'large'</i>, <i>'small'</i> */\n\tsize?: ButtonToggleItemProps<T>['size'];\n\n\t/** Shortcut for small-sized buttons */\n\tsmall?: boolean;\n\n\t/** Value of the ButtonToggle element. Sets corresponding option selected */\n\tvalue?: ButtonToggleItemProps<T>['value'];\n\n\t/** Shortcut for x-small-sized buttons */\n\txsmall?: boolean;\n}\n\nexport interface ButtonToggleProps<T> extends ButtonTogglePropsStrict<T> {\n\t/** Unstrict Props */\n\t[propName: string]: any;\n}\n\ninterface ButtonToggleState<T> {\n\tselected: ButtonToggleItemProps<T>['value'];\n}\n\nexport const ButtonToggle: <T>(\n\tprops: React.PropsWithoutRef<ButtonToggleProps<T>> &\n\t\tReact.RefAttributes<HTMLElement>\n) => React.ReactElement | null = React.forwardRef(function <T>(\n\t{\n\t\tcolor = 'primary',\n\t\tprimary,\n\t\tnegative,\n\t\tclassName,\n\t\tdisabled,\n\t\tel: ButtonToggleElement = 'div',\n\t\tclearable,\n\t\toptions = [],\n\t\tlarge,\n\t\tsmall,\n\t\txsmall,\n\t\tname,\n\t\tsize = 'medium',\n\t\tvalue,\n\t\tonChange,\n\t\tonFocus,\n\t\tonBlur,\n\t\t...props\n\t}: ButtonToggleProps<T>,\n\tref: React.RefObject<HTMLElement>\n) {\n\tconst [selected, setSelected] =\n\t\tReact.useState<ButtonToggleState<T>['selected']>(value);\n\tconst [focusedIndex, setFocusedIndex] = React.useState<number | null>(null);\n\tconst lastTabStopIndex = React.useRef(0);\n\n\tReact.useEffect(() => {\n\t\tsetSelected(value);\n\t}, [value]);\n\n\tconst handleFocus = (e: React.FocusEvent<HTMLElement>) => {\n\t\tconst buttons = Array.from(e.currentTarget.querySelectorAll('button'));\n\t\tconst index = buttons.indexOf(e.target as HTMLButtonElement);\n\t\tif (index >= 0) setFocusedIndex(index);\n\t\tonFocus?.(e);\n\t};\n\n\tconst handleBlur = (e: React.FocusEvent<HTMLElement>) => {\n\t\tsetFocusedIndex(null);\n\t\tonBlur?.(e);\n\t};\n\n\tconst arrowNavRef = React.useRef(null);\n\tconst mergedRef = useMergedRef(ref, arrowNavRef);\n\n\tuseArrowNav({\n\t\tscope: arrowNavRef,\n\t\thandleY: false,\n\t\tfocusableSelector: { selector: 'button:not([disabled])' },\n\t\tonKeyDown: (e: KeyboardEvent, data: any) => data.next?.click(), // Auto-selection\n\t\t/*\n\t\t * The tab stop is set while rendering; the hook's tab grouping would measure and\n\t\t * rewrite every button after each render, forcing a layout per toggle.\n\t\t */\n\t\ttabIndexGroup: false,\n\t});\n\n\tconst handleClick = (select: ButtonToggleItemProps<T>['value']) => {\n\t\tconst realSelected =\n\t\t\tselect !== selected || !clearable ? select : undefined;\n\n\t\tif (onChange) onChange(realSelected);\n\t\tsetSelected(realSelected);\n\t};\n\n\tconst copyOptions = (options: OptionProps<T>[]): OptionProps<T>[] => {\n\t\tconst copiedOptions = options.map((option) => {\n\t\t\treturn {\n\t\t\t\ttext: option.text,\n\t\t\t\tvalue: option.value,\n\t\t\t\tonClick: option.onClick,\n\t\t\t\tdisabled: option.disabled,\n\t\t\t\tselected: option.selected,\n\t\t\t\thidden: option.hidden,\n\t\t\t\ticon: option.icon,\n\t\t\t\ticonName: option.iconName,\n\t\t\t};\n\t\t});\n\n\t\treturn copiedOptions;\n\t};\n\n\tconst getOnlySelected = (options: OptionProps<T>[]): OptionProps<T>[] => {\n\t\tlet isSelected = false;\n\n\t\tconst onlyOneSelectedOptions = options.map((option) => {\n\t\t\tif (option.selected && !isSelected) {\n\t\t\t\tisSelected = true;\n\t\t\t} else {\n\t\t\t\toption.selected = false;\n\t\t\t}\n\t\t\treturn option;\n\t\t});\n\n\t\treturn onlyOneSelectedOptions;\n\t};\n\n\tconst getNormalized = (options: OptionProps<T>[]): OptionProps<T>[] => {\n\t\tconst realOptions = options.map((option) => {\n\t\t\tif (disabled) option.disabled = disabled;\n\t\t\tif (option.text === undefined) option.text = null;\n\t\t\tif (selected !== undefined || clearable)\n\t\t\t\toption.selected = selected === option.value;\n\n\t\t\treturn option;\n\t\t});\n\n\t\treturn realOptions;\n\t};\n\n\tconst getRealColor = () => {\n\t\tlet realColor: ButtonToggleItemProps<T>['color'] = color;\n\n\t\tif (primary) realColor = 'primary';\n\t\tif (negative) realColor = 'negative';\n\n\t\treturn realColor;\n\t};\n\n\tlet tabStopIndex = -1;\n\n\tconst getButtonToggleItemProps = (\n\t\toptions: OptionProps<T>[]\n\t): ButtonToggleItemProps<T>[] => {\n\t\tlet realSize: ButtonToggleItemProps<T>['size'] = size;\n\n\t\t// Override string props with boolean values\n\t\tif (xsmall) realSize = 'xsmall';\n\t\tif (small) realSize = 'small';\n\t\tif (large) realSize = 'large';\n\n\t\tconst isFocusable = (option: OptionProps<T>) =>\n\t\t\t!option.disabled && !option.hidden;\n\t\tconst focusableAt = (index: number | null) =>\n\t\t\tindex !== null && options[index] && isFocusable(options[index])\n\t\t\t\t? options[index]\n\t\t\t\t: undefined;\n\n\t\t/*\n\t\t * Same order as the tab grouping of useArrowNav: the focused option, the selected one,\n\t\t * the previous tab stop, then the first option that can be focused.\n\t\t */\n\t\tconst tabStop =\n\t\t\tfocusableAt(focusedIndex) ??\n\t\t\toptions.find((option) => option.selected && isFocusable(option)) ??\n\t\t\tfocusableAt(lastTabStopIndex.current) ??\n\t\t\toptions.find(isFocusable);\n\t\ttabStopIndex = tabStop ? options.indexOf(tabStop) : -1;\n\n\t\tconst buttonToggleItemProps = options.map((option) => {\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\ttext: option.text,\n\t\t\t\tvalue: option.value,\n\t\t\t\tdisabled: option.disabled,\n\t\t\t\tselected: option.selected,\n\t\t\t\tcolor: getRealColor(),\n\t\t\t\tsize: realSize,\n\t\t\t\thidden: option.hidden,\n\t\t\t\tonClick: (value: ButtonToggleItemProps<T>['value']) => {\n\t\t\t\t\tif (option.onClick) option.onClick(value);\n\t\t\t\t\thandleClick(value);\n\t\t\t\t},\n\t\t\t\ticon: option.icon,\n\t\t\t\ticonName: option.iconName,\n\t\t\t\ttabIndex: option === tabStop ? 0 : -1,\n\t\t\t};\n\t\t});\n\n\t\treturn buttonToggleItemProps;\n\t};\n\n\tconst copiedOptions = copyOptions(options);\n\n\tconst onlySelectedOptions = getOnlySelected(copiedOptions);\n\n\tconst normalizedOptions = getNormalized(onlySelectedOptions);\n\n\tconst buttonToggleItemProps = getButtonToggleItemProps(normalizedOptions);\n\n\t// Written after commit so that a render React discards cannot move the tab stop\n\tReact.useEffect(() => {\n\t\tif (tabStopIndex >= 0) lastTabStopIndex.current = tabStopIndex;\n\t});\n\n\tconst contents = buttonToggleItemProps.map((buttonProp, index) => {\n\t\treturn <ButtonToggleItem<T> key={index} {...buttonProp} />;\n\t});\n\n\tconst realColor = getRealColor();\n\n\tconst ButtonToggleClasses = classnames('ButtonToggle', className, {\n\t\t'ButtonToggle--disabled': disabled,\n\t\t[`ButtonToggle--${realColor}`]: realColor,\n\t});\n\n\treturn (\n\t\t<ButtonToggleElement\n\t\t\tclassName={ButtonToggleClasses}\n\t\t\tdata-anvil-component=\"ButtonToggle\"\n\t\t\tref={mergedRef}\n\t\t\trole={clearable ? null : 'radiogroup'}\n\t\t\tonFocus={handleFocus}\n\t\t\tonBlur={handleBlur}\n\t\t\t{...props}\n\t\t>\n\t\t\t{contents}\n\t\t</ButtonToggleElement>\n\t);\n});\n"]}
@@ -1,6 +1,22 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import React from 'react';
2
- import { render } from '@testing-library/react';
11
+ import { act, render, screen } from '@testing-library/react';
12
+ import userEvent from '@testing-library/user-event';
3
13
  import { ButtonToggle } from './ButtonToggle';
14
+ import { mockElementOffset } from '../../utilities/KeyboardAccessTests/utils';
15
+ mockElementOffset();
16
+ const tabStops = () => screen
17
+ .getAllByRole('button')
18
+ .filter((button) => !button.disabled && button.tabIndex === 0)
19
+ .map((button) => button.textContent);
4
20
  describe('ButtonToggle', () => {
5
21
  beforeEach(() => jest.spyOn(console, 'error'));
6
22
  it('should pass through data automation attributes', () => {
@@ -11,5 +27,65 @@ describe('ButtonToggle', () => {
11
27
  const element = container.querySelector('[data-auto-sel="automation-selector"]');
12
28
  expect(element).not.toBeNull();
13
29
  });
30
+ it('should make only the selected option tabbable', () => {
31
+ render(React.createElement(ButtonToggle, { value: 2, options: [
32
+ { text: '1', value: 1 },
33
+ { text: '2', value: 2 },
34
+ { text: '3', value: 3 },
35
+ ] }));
36
+ expect(tabStops()).toEqual(['2']);
37
+ });
38
+ it('should make the first enabled and visible option tabbable when nothing is selected', () => {
39
+ render(React.createElement(ButtonToggle, { clearable: true, options: [
40
+ { text: '1', value: 1, disabled: true },
41
+ { text: '2', value: 2, hidden: true },
42
+ { text: '3', value: 3 },
43
+ ] }));
44
+ expect(tabStops()).toEqual(['3']);
45
+ });
46
+ it('should move the tab stop to the first visible option when the selected one is hidden', () => {
47
+ render(React.createElement(ButtonToggle, { value: 1, options: [
48
+ { text: '1', value: 1, hidden: true },
49
+ { text: '2', value: 2 },
50
+ { text: '3', value: 3 },
51
+ ] }));
52
+ expect(tabStops()).toEqual(['2']);
53
+ });
54
+ it('should make the focused option tabbable until focus leaves', () => {
55
+ render(React.createElement(ButtonToggle, { value: 1, options: [
56
+ { text: '1', value: 1 },
57
+ { text: '2', value: 2 },
58
+ ] }));
59
+ const second = screen.getByRole('button', { name: '2' });
60
+ act(() => second.focus());
61
+ expect(tabStops()).toEqual(['2']);
62
+ act(() => second.blur());
63
+ expect(tabStops()).toEqual(['1']);
64
+ });
65
+ it('should keep the cleared option tabbable', () => __awaiter(void 0, void 0, void 0, function* () {
66
+ const user = userEvent.setup();
67
+ const ClearableToggle = () => {
68
+ const [value, setValue] = React.useState(2);
69
+ return (React.createElement(ButtonToggle, { clearable: true, value: value, onChange: setValue, options: [
70
+ { text: '1', value: 1 },
71
+ { text: '2', value: 2 },
72
+ ] }));
73
+ };
74
+ render(React.createElement(ClearableToggle, null));
75
+ yield user.click(screen.getByRole('button', { name: '2' }));
76
+ yield user.tab();
77
+ expect(tabStops()).toEqual(['2']);
78
+ }));
79
+ it('should not rewrite tab indexes when re-rendered with the same props', () => {
80
+ const options = [
81
+ { text: '1', value: 1 },
82
+ { text: '2', value: 2 },
83
+ ];
84
+ const { rerender } = render(React.createElement(ButtonToggle, { value: 2, options: options }));
85
+ const setTabIndex = jest.spyOn(HTMLElement.prototype, 'tabIndex', 'set');
86
+ rerender(React.createElement(ButtonToggle, { value: 2, options: options }));
87
+ expect(setTabIndex).not.toHaveBeenCalled();
88
+ setTabIndex.mockRestore();
89
+ });
14
90
  });
15
91
  //# sourceMappingURL=ButtonToggle.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonToggle.test.js","sourceRoot":"","sources":["../../../src/components/ButtonToggle/ButtonToggle.test.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC7B,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAE/C,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACzD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAC3B,oBAAC,YAAY,IACZ,KAAK,EAAE,CAAC,EACR,KAAK,QACL,OAAO,EAAE;gBACR,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE;aACvB,mBACa,qBAAqB,GAClC,CACF,CAAC;QAEF,MAAM,OAAO,GAAG,SAAS,CAAC,aAAa,CACtC,uCAAuC,CACvC,CAAC;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport { render } from '@testing-library/react';\nimport { ButtonToggle } from './ButtonToggle';\n\ndescribe('ButtonToggle', () => {\n\tbeforeEach(() => jest.spyOn(console, 'error'));\n\n\tit('should pass through data automation attributes', () => {\n\t\tconst { container } = render(\n\t\t\t<ButtonToggle\n\t\t\t\tvalue={2}\n\t\t\t\tsmall\n\t\t\t\toptions={[\n\t\t\t\t\t{ text: '1', value: 1 },\n\t\t\t\t\t{ text: '2', value: 2 },\n\t\t\t\t]}\n\t\t\t\tdata-auto-sel=\"automation-selector\"\n\t\t\t/>\n\t\t);\n\n\t\tconst element = container.querySelector(\n\t\t\t'[data-auto-sel=\"automation-selector\"]'\n\t\t);\n\n\t\texpect(element).not.toBeNull();\n\t});\n});\n"]}
1
+ {"version":3,"file":"ButtonToggle.test.js","sourceRoot":"","sources":["../../../src/components/ButtonToggle/ButtonToggle.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { act, render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { ButtonToggle } from './ButtonToggle';\nimport { mockElementOffset } from '../../utilities/KeyboardAccessTests/utils';\n\nmockElementOffset();\n\nconst tabStops = () =>\n\tscreen\n\t\t.getAllByRole('button')\n\t\t.filter(\n\t\t\t(button: HTMLButtonElement) =>\n\t\t\t\t!button.disabled && button.tabIndex === 0\n\t\t)\n\t\t.map((button) => button.textContent);\n\ndescribe('ButtonToggle', () => {\n\tbeforeEach(() => jest.spyOn(console, 'error'));\n\n\tit('should pass through data automation attributes', () => {\n\t\tconst { container } = render(\n\t\t\t<ButtonToggle\n\t\t\t\tvalue={2}\n\t\t\t\tsmall\n\t\t\t\toptions={[\n\t\t\t\t\t{ text: '1', value: 1 },\n\t\t\t\t\t{ text: '2', value: 2 },\n\t\t\t\t]}\n\t\t\t\tdata-auto-sel=\"automation-selector\"\n\t\t\t/>\n\t\t);\n\n\t\tconst element = container.querySelector(\n\t\t\t'[data-auto-sel=\"automation-selector\"]'\n\t\t);\n\n\t\texpect(element).not.toBeNull();\n\t});\n\n\tit('should make only the selected option tabbable', () => {\n\t\trender(\n\t\t\t<ButtonToggle\n\t\t\t\tvalue={2}\n\t\t\t\toptions={[\n\t\t\t\t\t{ text: '1', value: 1 },\n\t\t\t\t\t{ text: '2', value: 2 },\n\t\t\t\t\t{ text: '3', value: 3 },\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\n\t\texpect(tabStops()).toEqual(['2']);\n\t});\n\n\tit('should make the first enabled and visible option tabbable when nothing is selected', () => {\n\t\trender(\n\t\t\t<ButtonToggle\n\t\t\t\tclearable\n\t\t\t\toptions={[\n\t\t\t\t\t{ text: '1', value: 1, disabled: true },\n\t\t\t\t\t{ text: '2', value: 2, hidden: true },\n\t\t\t\t\t{ text: '3', value: 3 },\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\n\t\texpect(tabStops()).toEqual(['3']);\n\t});\n\n\tit('should move the tab stop to the first visible option when the selected one is hidden', () => {\n\t\trender(\n\t\t\t<ButtonToggle\n\t\t\t\tvalue={1}\n\t\t\t\toptions={[\n\t\t\t\t\t{ text: '1', value: 1, hidden: true },\n\t\t\t\t\t{ text: '2', value: 2 },\n\t\t\t\t\t{ text: '3', value: 3 },\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\n\t\texpect(tabStops()).toEqual(['2']);\n\t});\n\n\tit('should make the focused option tabbable until focus leaves', () => {\n\t\trender(\n\t\t\t<ButtonToggle\n\t\t\t\tvalue={1}\n\t\t\t\toptions={[\n\t\t\t\t\t{ text: '1', value: 1 },\n\t\t\t\t\t{ text: '2', value: 2 },\n\t\t\t\t]}\n\t\t\t/>\n\t\t);\n\n\t\tconst second = screen.getByRole('button', { name: '2' });\n\n\t\tact(() => second.focus());\n\t\texpect(tabStops()).toEqual(['2']);\n\n\t\tact(() => second.blur());\n\t\texpect(tabStops()).toEqual(['1']);\n\t});\n\n\tit('should keep the cleared option tabbable', async () => {\n\t\tconst user = userEvent.setup();\n\t\tconst ClearableToggle = () => {\n\t\t\tconst [value, setValue] = React.useState<number>(2);\n\n\t\t\treturn (\n\t\t\t\t<ButtonToggle\n\t\t\t\t\tclearable\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tonChange={setValue}\n\t\t\t\t\toptions={[\n\t\t\t\t\t\t{ text: '1', value: 1 },\n\t\t\t\t\t\t{ text: '2', value: 2 },\n\t\t\t\t\t]}\n\t\t\t\t/>\n\t\t\t);\n\t\t};\n\t\trender(<ClearableToggle />);\n\n\t\tawait user.click(screen.getByRole('button', { name: '2' }));\n\t\tawait user.tab();\n\n\t\texpect(tabStops()).toEqual(['2']);\n\t});\n\n\tit('should not rewrite tab indexes when re-rendered with the same props', () => {\n\t\tconst options = [\n\t\t\t{ text: '1', value: 1 },\n\t\t\t{ text: '2', value: 2 },\n\t\t];\n\t\tconst { rerender } = render(\n\t\t\t<ButtonToggle value={2} options={options} />\n\t\t);\n\t\tconst setTabIndex = jest.spyOn(\n\t\t\tHTMLElement.prototype,\n\t\t\t'tabIndex',\n\t\t\t'set'\n\t\t);\n\n\t\trerender(<ButtonToggle value={2} options={options} />);\n\n\t\texpect(setTabIndex).not.toHaveBeenCalled();\n\t\tsetTabIndex.mockRestore();\n\t});\n});\n"]}
@@ -26,5 +26,7 @@ export interface ButtonToggleItemProps<T> {
26
26
  icon?: ButtonProps['icon'];
27
27
  /** Name of icon to render inside of button */
28
28
  iconName?: ButtonProps['iconName'];
29
+ /** Tab index of the Button; 0 makes it the group's tab stop */
30
+ tabIndex?: number;
29
31
  }
30
32
  export declare const ButtonToggleItem: <T>(props: React.PropsWithoutRef<ButtonToggleItemProps<T>> & React.RefAttributes<HTMLDivElement>) => React.ReactElement | null;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { Button } from '../Button';
4
- export const ButtonToggleItem = React.forwardRef(function ({ color, disabled, hidden, icon, iconName, name, onClick, selected, size, text, value, }, ref) {
4
+ export const ButtonToggleItem = React.forwardRef(function ({ color, disabled, hidden, icon, iconName, name, onClick, selected, size, tabIndex, text, value, }, ref) {
5
5
  let realColor = 'default';
6
6
  if (selected)
7
7
  realColor = color;
@@ -13,6 +13,6 @@ export const ButtonToggleItem = React.forwardRef(function ({ color, disabled, hi
13
13
  });
14
14
  return (React.createElement("div", { className: ButtonToggleItemClasses, ref: ref },
15
15
  React.createElement("input", { name: name, type: "radio", defaultChecked: selected, className: "ButtonToggle__radio", tabIndex: -1 }),
16
- React.createElement(Button, { color: realColor, disabled: disabled, fill: "solid", full: true, icon: icon, iconName: iconName, onClick: onClick.bind(null, value), size: size, "aria-pressed": selected ? true : null }, text)));
16
+ React.createElement(Button, { color: realColor, disabled: disabled, fill: "solid", full: true, icon: icon, iconName: iconName, onClick: onClick.bind(null, value), size: size, tabIndex: tabIndex, "aria-pressed": selected ? true : null }, text)));
17
17
  });
18
18
  //# sourceMappingURL=ButtonToggleItem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonToggleItem.js","sourceRoot":"","sources":["../../../src/components/ButtonToggle/ButtonToggleItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,MAAM,EAAe,MAAM,WAAW,CAAC;AAwChD,MAAM,CAAC,MAAM,gBAAgB,GAGI,KAAK,CAAC,UAAU,CAAC,UACjD,EACC,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,KAAK,GACqB,EAC3B,GAAoC;IAEpC,IAAI,SAAS,GAAsC,SAAS,CAAC;IAE7D,IAAI,QAAQ;QAAE,SAAS,GAAG,KAAK,CAAC;IAEhC,MAAM,uBAAuB,GAAG,UAAU,CAAC,oBAAoB,EAAE;QAChE,4BAA4B,EAAE,MAAM;QACpC,8BAA8B,EAAE,QAAQ;QACxC,kCAAkC,EAAE,CAAC,QAAQ;QAC7C,8BAA8B,EAAE,QAAQ;KACxC,CAAC,CAAC;IAEH,OAAO,CACN,6BAAK,SAAS,EAAE,uBAAuB,EAAE,GAAG,EAAE,GAAG;QAChD,+BACC,IAAI,EAAE,IAAI,EACV,IAAI,EAAC,OAAO,EACZ,cAAc,EAAE,QAAQ,EACxB,SAAS,EAAC,qBAAqB,EAC/B,QAAQ,EAAE,CAAC,CAAC,GACX;QACF,oBAAC,MAAM,IACN,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,OAAO,EACZ,IAAI,QACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAClC,IAAI,EAAE,IAAI,kBACI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAEnC,IAAI,CACG,CACJ,CACN,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport classnames from 'classnames';\nimport { Button, ButtonProps } from '../Button';\n\n/**\n * ButtonToggleItem properties\n */\nexport interface ButtonToggleItemProps<T> {\n\t/** Content of the Button, i.e. the displayed text */\n\ttext: React.ReactNode;\n\n\t/** Value of the Button */\n\tvalue: T;\n\n\t/** Returns value of option for the click event */\n\tonClick?: (value: T) => void;\n\n\t/** Indicates whether the Button is disabled or not. It makes the Button unselectable */\n\tdisabled?: ButtonProps['disabled'];\n\n\t/** Sets the option's selected state */\n\tselected?: boolean;\n\n\t/** Selected button background color.<br /> Possible values: <i>'primary'</i>, <i>'blue'</i>, <i>'negative'</i>, <i>'red'</i> */\n\tcolor?: ButtonProps['color'];\n\n\t/** Sets size of the button.<br /> Possible values: <i>'large'</i>, <i>'small'</i> */\n\tsize?: ButtonProps['size'];\n\n\t/** Specifies the name of the Button */\n\tname: string;\n\n\t/** Hide the option (not commonly used) */\n\thidden?: boolean;\n\n\t/** React element to be rendered as an icon */\n\ticon?: ButtonProps['icon'];\n\n\t/** Name of icon to render inside of button */\n\ticonName?: ButtonProps['iconName'];\n}\n\nexport const ButtonToggleItem: <T>(\n\tprops: React.PropsWithoutRef<ButtonToggleItemProps<T>> &\n\t\tReact.RefAttributes<HTMLDivElement>\n) => React.ReactElement | null = React.forwardRef(function <T>(\n\t{\n\t\tcolor,\n\t\tdisabled,\n\t\thidden,\n\t\ticon,\n\t\ticonName,\n\t\tname,\n\t\tonClick,\n\t\tselected,\n\t\tsize,\n\t\ttext,\n\t\tvalue,\n\t}: ButtonToggleItemProps<T>,\n\tref: React.RefObject<HTMLDivElement>\n) {\n\tlet realColor: ButtonToggleItemProps<T>['color'] = 'default';\n\n\tif (selected) realColor = color;\n\n\tconst ButtonToggleItemClasses = classnames('ButtonToggle__Item', {\n\t\t'ButtonToggle__Item--hidden': hidden,\n\t\t'ButtonToggle__Item--selected': selected,\n\t\t'ButtonToggle__Item--not-selected': !selected,\n\t\t'ButtonToggle__Item--disabled': disabled,\n\t});\n\n\treturn (\n\t\t<div className={ButtonToggleItemClasses} ref={ref}>\n\t\t\t<input\n\t\t\t\tname={name}\n\t\t\t\ttype=\"radio\"\n\t\t\t\tdefaultChecked={selected}\n\t\t\t\tclassName=\"ButtonToggle__radio\"\n\t\t\t\ttabIndex={-1} // Prevent focusing on invisible input\n\t\t\t/>\n\t\t\t<Button\n\t\t\t\tcolor={realColor}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tfill=\"solid\"\n\t\t\t\tfull\n\t\t\t\ticon={icon}\n\t\t\t\ticonName={iconName}\n\t\t\t\tonClick={onClick.bind(null, value)}\n\t\t\t\tsize={size}\n\t\t\t\taria-pressed={selected ? true : null}\n\t\t\t>\n\t\t\t\t{text}\n\t\t\t</Button>\n\t\t</div>\n\t);\n});\n"]}
1
+ {"version":3,"file":"ButtonToggleItem.js","sourceRoot":"","sources":["../../../src/components/ButtonToggle/ButtonToggleItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,MAAM,EAAe,MAAM,WAAW,CAAC;AA2ChD,MAAM,CAAC,MAAM,gBAAgB,GAGI,KAAK,CAAC,UAAU,CAAC,UACjD,EACC,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,KAAK,GACqB,EAC3B,GAAoC;IAEpC,IAAI,SAAS,GAAsC,SAAS,CAAC;IAE7D,IAAI,QAAQ;QAAE,SAAS,GAAG,KAAK,CAAC;IAEhC,MAAM,uBAAuB,GAAG,UAAU,CAAC,oBAAoB,EAAE;QAChE,4BAA4B,EAAE,MAAM;QACpC,8BAA8B,EAAE,QAAQ;QACxC,kCAAkC,EAAE,CAAC,QAAQ;QAC7C,8BAA8B,EAAE,QAAQ;KACxC,CAAC,CAAC;IAEH,OAAO,CACN,6BAAK,SAAS,EAAE,uBAAuB,EAAE,GAAG,EAAE,GAAG;QAChD,+BACC,IAAI,EAAE,IAAI,EACV,IAAI,EAAC,OAAO,EACZ,cAAc,EAAE,QAAQ,EACxB,SAAS,EAAC,qBAAqB,EAC/B,QAAQ,EAAE,CAAC,CAAC,GACX;QACF,oBAAC,MAAM,IACN,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,OAAO,EACZ,IAAI,QACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAClC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,kBACJ,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAEnC,IAAI,CACG,CACJ,CACN,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport classnames from 'classnames';\nimport { Button, ButtonProps } from '../Button';\n\n/**\n * ButtonToggleItem properties\n */\nexport interface ButtonToggleItemProps<T> {\n\t/** Content of the Button, i.e. the displayed text */\n\ttext: React.ReactNode;\n\n\t/** Value of the Button */\n\tvalue: T;\n\n\t/** Returns value of option for the click event */\n\tonClick?: (value: T) => void;\n\n\t/** Indicates whether the Button is disabled or not. It makes the Button unselectable */\n\tdisabled?: ButtonProps['disabled'];\n\n\t/** Sets the option's selected state */\n\tselected?: boolean;\n\n\t/** Selected button background color.<br /> Possible values: <i>'primary'</i>, <i>'blue'</i>, <i>'negative'</i>, <i>'red'</i> */\n\tcolor?: ButtonProps['color'];\n\n\t/** Sets size of the button.<br /> Possible values: <i>'large'</i>, <i>'small'</i> */\n\tsize?: ButtonProps['size'];\n\n\t/** Specifies the name of the Button */\n\tname: string;\n\n\t/** Hide the option (not commonly used) */\n\thidden?: boolean;\n\n\t/** React element to be rendered as an icon */\n\ticon?: ButtonProps['icon'];\n\n\t/** Name of icon to render inside of button */\n\ticonName?: ButtonProps['iconName'];\n\n\t/** Tab index of the Button; 0 makes it the group's tab stop */\n\ttabIndex?: number;\n}\n\nexport const ButtonToggleItem: <T>(\n\tprops: React.PropsWithoutRef<ButtonToggleItemProps<T>> &\n\t\tReact.RefAttributes<HTMLDivElement>\n) => React.ReactElement | null = React.forwardRef(function <T>(\n\t{\n\t\tcolor,\n\t\tdisabled,\n\t\thidden,\n\t\ticon,\n\t\ticonName,\n\t\tname,\n\t\tonClick,\n\t\tselected,\n\t\tsize,\n\t\ttabIndex,\n\t\ttext,\n\t\tvalue,\n\t}: ButtonToggleItemProps<T>,\n\tref: React.RefObject<HTMLDivElement>\n) {\n\tlet realColor: ButtonToggleItemProps<T>['color'] = 'default';\n\n\tif (selected) realColor = color;\n\n\tconst ButtonToggleItemClasses = classnames('ButtonToggle__Item', {\n\t\t'ButtonToggle__Item--hidden': hidden,\n\t\t'ButtonToggle__Item--selected': selected,\n\t\t'ButtonToggle__Item--not-selected': !selected,\n\t\t'ButtonToggle__Item--disabled': disabled,\n\t});\n\n\treturn (\n\t\t<div className={ButtonToggleItemClasses} ref={ref}>\n\t\t\t<input\n\t\t\t\tname={name}\n\t\t\t\ttype=\"radio\"\n\t\t\t\tdefaultChecked={selected}\n\t\t\t\tclassName=\"ButtonToggle__radio\"\n\t\t\t\ttabIndex={-1} // Prevent focusing on invisible input\n\t\t\t/>\n\t\t\t<Button\n\t\t\t\tcolor={realColor}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tfill=\"solid\"\n\t\t\t\tfull\n\t\t\t\ticon={icon}\n\t\t\t\ticonName={iconName}\n\t\t\t\tonClick={onClick.bind(null, value)}\n\t\t\t\tsize={size}\n\t\t\t\ttabIndex={tabIndex}\n\t\t\t\taria-pressed={selected ? true : null}\n\t\t\t>\n\t\t\t\t{text}\n\t\t\t</Button>\n\t\t</div>\n\t);\n});\n"]}
@@ -26,7 +26,7 @@ export const DateRangeOptionList = ({ options, min, max, onChange, enableTimezon
26
26
  }
27
27
  else {
28
28
  start = toDateFormat.startOfDay(option.value.start);
29
- start = toDateFormat.endOfDay(option.value.end);
29
+ end = toDateFormat.endOfDay(option.value.end);
30
30
  }
31
31
  return Object.assign(Object.assign({}, option), { value: {
32
32
  start,
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangeOptionList.js","sourceRoot":"","sources":["../../../../src/components/DateRangePicker/components/DateRangeOptionList.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { FC, useContext } from 'react';\nimport { DateTime } from 'luxon';\nimport { OptionList, OptionListProps } from '../../OptionList';\nimport { DateRangePickerProps } from '../DateRangePicker';\nimport { checkScope } from '../utils';\nimport { Tooltip } from '../../Tooltip';\nimport { BodyText } from '../../BodyText';\nimport { TimezoneContext, toDateFormat } from '../../../utilities';\n\nexport interface DateRangeOptionProps {\n\tvalue: {\n\t\tstart: Date;\n\t\tend: Date;\n\t};\n\tcontent: React.ReactElement;\n\ttext: string;\n\tdisabled?: boolean;\n}\n\nexport interface DateRangeOptionListProps {\n\toptions: OptionListProps['options'];\n\tenableTimezoneContext?: boolean;\n\tmin: Date;\n\tmax: Date;\n\tonChange: (value: DateRangePickerProps['value']) => void;\n}\n\nexport const DateRangeOptionList: FC<DateRangeOptionListProps> = ({\n\toptions,\n\tmin,\n\tmax,\n\tonChange,\n\tenableTimezoneContext,\n}) => {\n\tconst timezone = useContext(TimezoneContext);\n\n\tconst normalizeValueInOptions = options.map((option) => {\n\t\tlet start: Date | null;\n\t\tlet end: Date | null;\n\n\t\tif (enableTimezoneContext) {\n\t\t\tstart = option.value.start\n\t\t\t\t? DateTime.fromJSDate(option.value.start)\n\t\t\t\t\t\t.setZone(timezone)\n\t\t\t\t\t\t.startOf('day')\n\t\t\t\t\t\t.toJSDate()\n\t\t\t\t: null;\n\n\t\t\tend = option.value.end\n\t\t\t\t? DateTime.fromJSDate(option.value.end)\n\t\t\t\t\t\t.setZone(timezone)\n\t\t\t\t\t\t.endOf('day')\n\t\t\t\t\t\t.toJSDate()\n\t\t\t\t: null;\n\t\t} else {\n\t\t\tstart = toDateFormat.startOfDay(option.value.start);\n\t\t\tstart = toDateFormat.endOfDay(option.value.end);\n\t\t}\n\n\t\treturn {\n\t\t\t...option,\n\t\t\tvalue: {\n\t\t\t\tstart,\n\t\t\t\tend,\n\t\t\t},\n\t\t};\n\t});\n\n\tconst checkOptions = normalizeValueInOptions.map(\n\t\t(option: DateRangeOptionProps) => {\n\t\t\tconst isOutOfScope = checkScope(option.value, min, max);\n\n\t\t\tif (isOutOfScope.start || isOutOfScope.end) {\n\t\t\t\treturn {\n\t\t\t\t\t...option,\n\t\t\t\t\tdisabled: true,\n\t\t\t\t\tcontent: (\n\t\t\t\t\t\t<Tooltip direction=\"r\" portal text=\"Out of Date Range\">\n\t\t\t\t\t\t\t<BodyText size=\"small\">{option.text}</BodyText>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn option;\n\t\t}\n\t);\n\n\tconst handleOnChange = (data: DateRangePickerProps['value']) => {\n\t\tonChange(data);\n\t};\n\n\treturn (\n\t\t<React.Fragment>\n\t\t\t{checkOptions.length > 0 && (\n\t\t\t\t<div className=\"DateRangePicker__options\">\n\t\t\t\t\t<OptionList\n\t\t\t\t\t\toptions={checkOptions}\n\t\t\t\t\t\tonChange={(data) => handleOnChange(data)}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</React.Fragment>\n\t);\n};\n"]}
1
+ {"version":3,"file":"DateRangeOptionList.js","sourceRoot":"","sources":["../../../../src/components/DateRangePicker/components/DateRangeOptionList.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { FC, useContext } from 'react';\nimport { DateTime } from 'luxon';\nimport { OptionList, OptionListProps } from '../../OptionList';\nimport { DateRangePickerProps } from '../DateRangePicker';\nimport { checkScope } from '../utils';\nimport { Tooltip } from '../../Tooltip';\nimport { BodyText } from '../../BodyText';\nimport { TimezoneContext, toDateFormat } from '../../../utilities';\n\nexport interface DateRangeOptionProps {\n\tvalue: {\n\t\tstart: Date;\n\t\tend: Date;\n\t};\n\tcontent: React.ReactElement;\n\ttext: string;\n\tdisabled?: boolean;\n}\n\nexport interface DateRangeOptionListProps {\n\toptions: OptionListProps['options'];\n\tenableTimezoneContext?: boolean;\n\tmin: Date;\n\tmax: Date;\n\tonChange: (value: DateRangePickerProps['value']) => void;\n}\n\nexport const DateRangeOptionList: FC<DateRangeOptionListProps> = ({\n\toptions,\n\tmin,\n\tmax,\n\tonChange,\n\tenableTimezoneContext,\n}) => {\n\tconst timezone = useContext(TimezoneContext);\n\n\tconst normalizeValueInOptions = options.map((option) => {\n\t\tlet start: Date | null;\n\t\tlet end: Date | null;\n\n\t\tif (enableTimezoneContext) {\n\t\t\tstart = option.value.start\n\t\t\t\t? DateTime.fromJSDate(option.value.start)\n\t\t\t\t\t\t.setZone(timezone)\n\t\t\t\t\t\t.startOf('day')\n\t\t\t\t\t\t.toJSDate()\n\t\t\t\t: null;\n\n\t\t\tend = option.value.end\n\t\t\t\t? DateTime.fromJSDate(option.value.end)\n\t\t\t\t\t\t.setZone(timezone)\n\t\t\t\t\t\t.endOf('day')\n\t\t\t\t\t\t.toJSDate()\n\t\t\t\t: null;\n\t\t} else {\n\t\t\tstart = toDateFormat.startOfDay(option.value.start);\n\t\t\tend = toDateFormat.endOfDay(option.value.end);\n\t\t}\n\n\t\treturn {\n\t\t\t...option,\n\t\t\tvalue: {\n\t\t\t\tstart,\n\t\t\t\tend,\n\t\t\t},\n\t\t};\n\t});\n\n\tconst checkOptions = normalizeValueInOptions.map(\n\t\t(option: DateRangeOptionProps) => {\n\t\t\tconst isOutOfScope = checkScope(option.value, min, max);\n\n\t\t\tif (isOutOfScope.start || isOutOfScope.end) {\n\t\t\t\treturn {\n\t\t\t\t\t...option,\n\t\t\t\t\tdisabled: true,\n\t\t\t\t\tcontent: (\n\t\t\t\t\t\t<Tooltip direction=\"r\" portal text=\"Out of Date Range\">\n\t\t\t\t\t\t\t<BodyText size=\"small\">{option.text}</BodyText>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn option;\n\t\t}\n\t);\n\n\tconst handleOnChange = (data: DateRangePickerProps['value']) => {\n\t\tonChange(data);\n\t};\n\n\treturn (\n\t\t<React.Fragment>\n\t\t\t{checkOptions.length > 0 && (\n\t\t\t\t<div className=\"DateRangePicker__options\">\n\t\t\t\t\t<OptionList\n\t\t\t\t\t\toptions={checkOptions}\n\t\t\t\t\t\tonChange={(data) => handleOnChange(data)}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</React.Fragment>\n\t);\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  /* Hide element visually, keeping it focusable (with keyboard) and available for screen-readers */
2
2
  html {
3
- --anvil1-version: "14.5.2";
3
+ --anvil1-version: "14.5.11";
4
4
  }
5
5
 
6
6
  /*
@@ -1,5 +1,5 @@
1
1
  html {
2
- --anvil1-version: "14.5.2";
2
+ --anvil1-version: "14.5.11";
3
3
  }
4
4
 
5
5
  /*# sourceMappingURL=version.css.map */
@@ -1,6 +1,6 @@
1
1
  /* Hide element visually, keeping it focusable (with keyboard) and available for screen-readers */
2
2
  html {
3
- --anvil1-version: "14.5.2";
3
+ --anvil1-version: "14.5.11";
4
4
  }
5
5
 
6
6
  /*