@ringcentral/juno 2.41.1 → 2.41.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/components/Forms/Picker/DatePicker/Calendar.js +1 -1
  2. package/components/Forms/Picker/DatePicker/DatePickerHeader.js +1 -1
  3. package/components/Forms/Picker/DatePicker/Year.js +1 -1
  4. package/components/Forms/Picker/TimePicker/NumberPicker.js +1 -1
  5. package/components/Forms/Picker/TimePicker/SelectionView.js +1 -1
  6. package/components/Forms/Picker/TimePicker/TimePicker.js +1 -1
  7. package/components/Forms/Picker/utils/PickerTextField/PickerTextField.js +5 -1
  8. package/es6/components/Forms/Picker/DatePicker/Calendar.js +1 -1
  9. package/es6/components/Forms/Picker/DatePicker/DatePickerHeader.js +1 -1
  10. package/es6/components/Forms/Picker/DatePicker/Year.js +1 -1
  11. package/es6/components/Forms/Picker/TimePicker/NumberPicker.js +1 -1
  12. package/es6/components/Forms/Picker/TimePicker/SelectionView.js +1 -1
  13. package/es6/components/Forms/Picker/TimePicker/TimePicker.js +1 -1
  14. package/es6/components/Forms/Picker/utils/PickerTextField/PickerTextField.js +6 -2
  15. package/es6/foundation/hooks/index.js +1 -0
  16. package/es6/foundation/hooks/useFocusInside/index.js +1 -0
  17. package/es6/foundation/hooks/useFocusInside/useFocusInside.js +56 -0
  18. package/foundation/hooks/index.d.ts +1 -0
  19. package/foundation/hooks/index.js +1 -0
  20. package/foundation/hooks/useFocusInside/index.d.ts +1 -0
  21. package/foundation/hooks/useFocusInside/index.js +4 -0
  22. package/foundation/hooks/useFocusInside/package.json +5 -0
  23. package/foundation/hooks/useFocusInside/useFocusInside.d.ts +26 -0
  24. package/foundation/hooks/useFocusInside/useFocusInside.js +58 -0
  25. package/package.json +1 -1
@@ -139,7 +139,7 @@ var Calendar = react_1.forwardRef(function (_a, ref) {
139
139
  // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
140
140
  react_1.default.createElement("div", { role: "rowgroup", "data-transition-tag": true, onKeyDown: handleKeyDown }, weeks.current.map(function (week) { return (react_1.default.createElement(styles_1.WeekWrapper, { role: "row", size: size, key: "week-" + week[0].toString() }, renderDays(week))); })))),
141
141
  react_1.default.createElement(styles_1.DayFooterWrapper, { className: classes.footer },
142
- react_1.default.createElement(Buttons_1.RcButton, { variant: "plain", onClick: backToToday, disabled: isTodayDisabled, "aria-label": backToTodayAriaLabel, "data-test-automation-id": "date-picker-today" }, todayButtonText))));
142
+ react_1.default.createElement(Buttons_1.RcButton, { "data-focusable": true, variant: "plain", onClick: backToToday, disabled: isTodayDisabled, "aria-label": backToTodayAriaLabel, "data-test-automation-id": "date-picker-today" }, todayButtonText))));
143
143
  case 'year':
144
144
  return (react_1.default.createElement(Years_1.Years, { date: focusedDate, size: size, minDate: min, maxDate: max, onYearChange: function (day) {
145
145
  setView('day');
@@ -33,7 +33,7 @@ var DatePickerHeader = react_1.memo(function (props) {
33
33
  ? nextMonthAriaLabel
34
34
  : previousMonthAriaLabel)),
35
35
  react_1.default.createElement(styles_1.SwitchHeaderWrapper, { size: size, className: classes.header },
36
- react_1.default.createElement(styles_1.StyledCurrentMonth, { role: 'button', tabIndex: 0, view: view, onClick: onViewChange, "aria-label": monthYearAriaLabel, "aria-expanded": ariaExpanded, "data-test-automation-id": "date-picker-month-year", className: classes.select },
36
+ react_1.default.createElement(styles_1.StyledCurrentMonth, { role: 'button', tabIndex: 0, "data-focusable": true, view: view, onClick: onViewChange, "aria-label": monthYearAriaLabel, "aria-expanded": ariaExpanded, "data-test-automation-id": "date-picker-month-year", className: classes.select },
37
37
  monthLabel,
38
38
  react_1.default.createElement(SelectArrowDownIcon_1.SelectArrowDownIcon, null)),
39
39
  react_1.default.createElement(styles_1.SwitchHeaderButtonWrapper, { size: size, gap: 3, view: view },
@@ -16,7 +16,7 @@ var Year = react_1.memo(react_1.forwardRef(function (props, ref) {
16
16
  });
17
17
  var yearAriaLabel = getYearAriaLabel === null || getYearAriaLabel === void 0 ? void 0 : getYearAriaLabel("" + value, selected);
18
18
  var handleClick = !disabled ? _handleClick : undefined;
19
- return (react_1.default.createElement(styles_1.StyledYear, tslib_1.__assign({ radius: "round", onClick: handleClick, onKeyPress: handleClick, ref: ref, selected: selected, "aria-pressed": focused, size: "medium", "aria-label": yearAriaLabel, className: className, "data-test-automation-class": "date-picker-year", "data-test-automation-value": children }, rest),
19
+ return (react_1.default.createElement(styles_1.StyledYear, tslib_1.__assign({ radius: "round", onClick: handleClick, onKeyPress: handleClick, ref: ref, selected: selected, "aria-pressed": focused, size: "medium", "aria-label": yearAriaLabel, className: className, "data-focusable": selected, "data-test-automation-class": "date-picker-year", "data-test-automation-value": children }, rest),
20
20
  react_1.default.createElement(react_1.default.Fragment, null,
21
21
  // TODO: that <></> will fix when `RcIconButton` ready
22
22
  children)));
@@ -109,7 +109,7 @@ var _NumberPicker = react_1.forwardRef(function (props, ref) {
109
109
  return 'large';
110
110
  }
111
111
  })();
112
- return (react_1.default.createElement(StyledNumberPicker_1.StyledNumberPicker, tslib_1.__assign({ tabIndex: 0, onKeyDown: handleKeyDown, "aria-live": "assertive", "aria-label": label, ref: pickerRef }, rest),
112
+ return (react_1.default.createElement(StyledNumberPicker_1.StyledNumberPicker, tslib_1.__assign({ tabIndex: 0, onKeyDown: handleKeyDown, "aria-live": "assertive", "aria-label": label, ref: pickerRef, "data-focusable": true }, rest),
113
113
  react_1.default.createElement(StyledTimeIconButton_1.StyledTimeIconButton, { tabIndex: -1, size: iconSize, color: "neutral.f04", wrapperSize: size, disabled: increaseDisabled, onClick: function () {
114
114
  onUpdateValue(increaseValue);
115
115
  }, symbol: juno_icon_1.ArrowUp, "data-test-automation-id": automationId && automationId + "-prev-pagination", "aria-label": "Arrow Up" }),
@@ -23,7 +23,7 @@ var SelectionView = function (props) {
23
23
  var disabled = !!((max !== undefined && v > max) ||
24
24
  (min !== undefined && v < min));
25
25
  var itemShowValue = utils_1.parseNumberToString(v, isTwelveHourSystem);
26
- return (react_1.default.createElement(styles_1.StyledSelectionItem, { disabled: disabled, radius: "round", wrapperSize: size, key: v, onClick: handleClick(v, disabled), selected: itemShowValue === showValue, "data-test-automation-id": automationId && automationId + "-" + itemShowValue, itemLength: source.length },
26
+ return (react_1.default.createElement(styles_1.StyledSelectionItem, { disabled: disabled, "data-focusable": true, radius: "round", wrapperSize: size, key: v, onClick: handleClick(v, disabled), selected: itemShowValue === showValue, "data-test-automation-id": automationId && automationId + "-" + itemShowValue, itemLength: source.length },
27
27
  react_1.default.createElement(react_1.default.Fragment, null, itemShowValue)));
28
28
  })));
29
29
  };
@@ -251,7 +251,7 @@ var _RcTimePicker = react_1.forwardRef(function (inProps, ref) {
251
251
  react_1.default.createElement(Box_1.RcBox, { textAlign: "center", width: "48px" }, ":"),
252
252
  react_1.default.createElement(NumberPicker_1.NumberPicker, tslib_1.__assign({ ref: minuteRef, size: size }, boundary.minute, { onUpdateValue: handleMinuteChange, onClick: setMinuteSelectionShow, onClose: closeMenu, value: minuteValue, source: utils_2.minuteSource, step: utils_2.TIME_GAP, automationId: "time-picker-minute" }, MinutePickerProps)),
253
253
  isTwelveHourSystem && (react_1.default.createElement("div", null,
254
- react_1.default.createElement(ToggleText_1.ToggleText, tslib_1.__assign({ periodTexts: periodTexts.toggle, ref: periodRef, size: size, disabled: toggleTextDisabled, onUpdateValue: onTogglePeriod, onInnerChange: handlePeriodInnerChange, onClose: closeMenu, value: periodValue }, PeriodToggleProps)))))) : (react_1.default.createElement(SelectionView_1.SelectionView, tslib_1.__assign({ size: size }, (isHourView ? boundary.hour : boundary.minute), { source: isHourView
254
+ react_1.default.createElement(ToggleText_1.ToggleText, tslib_1.__assign({ periodTexts: periodTexts.toggle, ref: periodRef, size: size, disabled: toggleTextDisabled, onUpdateValue: onTogglePeriod, onInnerChange: handlePeriodInnerChange, onClose: closeMenu, value: periodValue, "data-focusable": true }, PeriodToggleProps)))))) : (react_1.default.createElement(SelectionView_1.SelectionView, tslib_1.__assign({ size: size }, (isHourView ? boundary.hour : boundary.minute), { source: isHourView
255
255
  ? isTwelveHourSystem
256
256
  ? utils_2.twelveHourSystemSource
257
257
  : utils_2.twentyFourHourSystemSource
@@ -19,6 +19,7 @@ var popoverTransformOrigin = {
19
19
  var PICKER_DISPLAY_NAME = 'PickerTextField';
20
20
  var PickerTextField = react_1.forwardRef(function (props, ref) {
21
21
  var onClear = props.onClear, InputProps = props.InputProps, disabled = props.disabled, action = props.action, onKeyDown = props.onKeyDown, _a = props.inputProps, _b = _a === void 0 ? {} : _a, announcementText = _b.announcementText, inputProps = tslib_1.__rest(_b, ["announcementText"]), PopoverPropsProp = props.PopoverProps, children = props.children, ActionSymbol = props.ActionSymbol, clearBtn = props.clearBtn, clearButtonProps = props.clearButtonProps, value = props.value, rest = tslib_1.__rest(props, ["onClear", "InputProps", "disabled", "action", "onKeyDown", "inputProps", "PopoverProps", "children", "ActionSymbol", "clearBtn", "clearButtonProps", "value"]);
22
+ var focusInside = foundation_1.useFocusInside();
22
23
  var idForInput = react_1.useRef(uniqueId_1.default(PICKER_DISPLAY_NAME + "-")).current;
23
24
  var _c = tslib_1.__read(react_1.useState(null), 2), anchorEl = _c[0], setAnchorEl = _c[1];
24
25
  var idForHelperText = idForInput + "-helper-text";
@@ -91,7 +92,10 @@ var PickerTextField = react_1.forwardRef(function (props, ref) {
91
92
  }); }, [onPickerViewClose]);
92
93
  return (react_1.default.createElement(react_1.default.Fragment, null,
93
94
  react_1.default.createElement(styles_1.StyledPickerTextField, tslib_1.__assign({ id: idForInput, ref: ref, InputProps: _InputProps, FormHelperTextProps: _FormHelperTextProps, focused: popoverOpen ? true : undefined, disabled: disabled, clearBtn: clearBtn, value: value }, rest)),
94
- react_1.default.createElement(styles_1.StyledPopover, tslib_1.__assign({ open: popoverOpen, anchorEl: anchorEl, onClose: onPickerViewClose, anchorOrigin: popoverAnchorOrigin, transformOrigin: popoverTransformOrigin }, PopoverProps), children),
95
+ react_1.default.createElement(styles_1.StyledPopover, tslib_1.__assign({ open: popoverOpen, anchorEl: anchorEl, onClose: onPickerViewClose, anchorOrigin: popoverAnchorOrigin, transformOrigin: popoverTransformOrigin }, PopoverProps),
96
+ focusInside.start,
97
+ children,
98
+ focusInside.end),
95
99
  react_1.default.createElement(VisuallyHidden_1.RcVisuallyHidden, { id: idForInstruction }, announcementText)));
96
100
  });
97
101
  exports.PickerTextField = PickerTextField;
@@ -137,7 +137,7 @@ var Calendar = forwardRef(function (_a, ref) {
137
137
  // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
138
138
  React.createElement("div", { role: "rowgroup", "data-transition-tag": true, onKeyDown: handleKeyDown }, weeks.current.map(function (week) { return (React.createElement(WeekWrapper, { role: "row", size: size, key: "week-" + week[0].toString() }, renderDays(week))); })))),
139
139
  React.createElement(DayFooterWrapper, { className: classes.footer },
140
- React.createElement(RcButton, { variant: "plain", onClick: backToToday, disabled: isTodayDisabled, "aria-label": backToTodayAriaLabel, "data-test-automation-id": "date-picker-today" }, todayButtonText))));
140
+ React.createElement(RcButton, { "data-focusable": true, variant: "plain", onClick: backToToday, disabled: isTodayDisabled, "aria-label": backToTodayAriaLabel, "data-test-automation-id": "date-picker-today" }, todayButtonText))));
141
141
  case 'year':
142
142
  return (React.createElement(Years, { date: focusedDate, size: size, minDate: min, maxDate: max, onYearChange: function (day) {
143
143
  setView('day');
@@ -30,7 +30,7 @@ var DatePickerHeader = memo(function (props) {
30
30
  ? nextMonthAriaLabel
31
31
  : previousMonthAriaLabel)),
32
32
  React.createElement(SwitchHeaderWrapper, { size: size, className: classes.header },
33
- React.createElement(StyledCurrentMonth, { role: 'button', tabIndex: 0, view: view, onClick: onViewChange, "aria-label": monthYearAriaLabel, "aria-expanded": ariaExpanded, "data-test-automation-id": "date-picker-month-year", className: classes.select },
33
+ React.createElement(StyledCurrentMonth, { role: 'button', tabIndex: 0, "data-focusable": true, view: view, onClick: onViewChange, "aria-label": monthYearAriaLabel, "aria-expanded": ariaExpanded, "data-test-automation-id": "date-picker-month-year", className: classes.select },
34
34
  monthLabel,
35
35
  React.createElement(SelectArrowDownIcon, null)),
36
36
  React.createElement(SwitchHeaderButtonWrapper, { size: size, gap: 3, view: view },
@@ -14,7 +14,7 @@ var Year = memo(forwardRef(function (props, ref) {
14
14
  });
15
15
  var yearAriaLabel = getYearAriaLabel === null || getYearAriaLabel === void 0 ? void 0 : getYearAriaLabel("" + value, selected);
16
16
  var handleClick = !disabled ? _handleClick : undefined;
17
- return (React.createElement(StyledYear, __assign({ radius: "round", onClick: handleClick, onKeyPress: handleClick, ref: ref, selected: selected, "aria-pressed": focused, size: "medium", "aria-label": yearAriaLabel, className: className, "data-test-automation-class": "date-picker-year", "data-test-automation-value": children }, rest),
17
+ return (React.createElement(StyledYear, __assign({ radius: "round", onClick: handleClick, onKeyPress: handleClick, ref: ref, selected: selected, "aria-pressed": focused, size: "medium", "aria-label": yearAriaLabel, className: className, "data-focusable": selected, "data-test-automation-class": "date-picker-year", "data-test-automation-value": children }, rest),
18
18
  React.createElement(React.Fragment, null,
19
19
  // TODO: that <></> will fix when `RcIconButton` ready
20
20
  children)));
@@ -107,7 +107,7 @@ var _NumberPicker = forwardRef(function (props, ref) {
107
107
  return 'large';
108
108
  }
109
109
  })();
110
- return (React.createElement(StyledNumberPicker, __assign({ tabIndex: 0, onKeyDown: handleKeyDown, "aria-live": "assertive", "aria-label": label, ref: pickerRef }, rest),
110
+ return (React.createElement(StyledNumberPicker, __assign({ tabIndex: 0, onKeyDown: handleKeyDown, "aria-live": "assertive", "aria-label": label, ref: pickerRef, "data-focusable": true }, rest),
111
111
  React.createElement(StyledTimeIconButton, { tabIndex: -1, size: iconSize, color: "neutral.f04", wrapperSize: size, disabled: increaseDisabled, onClick: function () {
112
112
  onUpdateValue(increaseValue);
113
113
  }, symbol: ArrowUpIcon, "data-test-automation-id": automationId && automationId + "-prev-pagination", "aria-label": "Arrow Up" }),
@@ -20,7 +20,7 @@ var SelectionView = function (props) {
20
20
  var disabled = !!((max !== undefined && v > max) ||
21
21
  (min !== undefined && v < min));
22
22
  var itemShowValue = parseNumberToString(v, isTwelveHourSystem);
23
- return (React.createElement(StyledSelectionItem, { disabled: disabled, radius: "round", wrapperSize: size, key: v, onClick: handleClick(v, disabled), selected: itemShowValue === showValue, "data-test-automation-id": automationId && automationId + "-" + itemShowValue, itemLength: source.length },
23
+ return (React.createElement(StyledSelectionItem, { disabled: disabled, "data-focusable": true, radius: "round", wrapperSize: size, key: v, onClick: handleClick(v, disabled), selected: itemShowValue === showValue, "data-test-automation-id": automationId && automationId + "-" + itemShowValue, itemLength: source.length },
24
24
  React.createElement(React.Fragment, null, itemShowValue)));
25
25
  })));
26
26
  };
@@ -249,7 +249,7 @@ var _RcTimePicker = forwardRef(function (inProps, ref) {
249
249
  React.createElement(RcBox, { textAlign: "center", width: "48px" }, ":"),
250
250
  React.createElement(NumberPicker, __assign({ ref: minuteRef, size: size }, boundary.minute, { onUpdateValue: handleMinuteChange, onClick: setMinuteSelectionShow, onClose: closeMenu, value: minuteValue, source: minuteSource, step: TIME_GAP, automationId: "time-picker-minute" }, MinutePickerProps)),
251
251
  isTwelveHourSystem && (React.createElement("div", null,
252
- React.createElement(ToggleText, __assign({ periodTexts: periodTexts.toggle, ref: periodRef, size: size, disabled: toggleTextDisabled, onUpdateValue: onTogglePeriod, onInnerChange: handlePeriodInnerChange, onClose: closeMenu, value: periodValue }, PeriodToggleProps)))))) : (React.createElement(SelectionView, __assign({ size: size }, (isHourView ? boundary.hour : boundary.minute), { source: isHourView
252
+ React.createElement(ToggleText, __assign({ periodTexts: periodTexts.toggle, ref: periodRef, size: size, disabled: toggleTextDisabled, onUpdateValue: onTogglePeriod, onInnerChange: handlePeriodInnerChange, onClose: closeMenu, value: periodValue, "data-focusable": true }, PeriodToggleProps)))))) : (React.createElement(SelectionView, __assign({ size: size }, (isHourView ? boundary.hour : boundary.minute), { source: isHourView
253
253
  ? isTwelveHourSystem
254
254
  ? twelveHourSystemSource
255
255
  : twentyFourHourSystemSource
@@ -2,7 +2,7 @@ import { __assign, __read, __rest } from "tslib";
2
2
  import React, { forwardRef, useImperativeHandle, useMemo, useRef, useState, } from 'react';
3
3
  import uniqueId from 'lodash/uniqueId';
4
4
  import { DeleteCircle as DeleteCircleIcon } from '@ringcentral/juno-icon';
5
- import { combineProps, useA11yKeyEvent, useEventCallback, } from '../../../../../foundation';
5
+ import { combineProps, useA11yKeyEvent, useEventCallback, useFocusInside, } from '../../../../../foundation';
6
6
  import { RcIconButton } from '../../../../Buttons/IconButton';
7
7
  import { RcVisuallyHidden } from '../../../../VisuallyHidden';
8
8
  import { StyledPickerTextField, StyledPopover } from '../../styles';
@@ -17,6 +17,7 @@ var popoverTransformOrigin = {
17
17
  var PICKER_DISPLAY_NAME = 'PickerTextField';
18
18
  var PickerTextField = forwardRef(function (props, ref) {
19
19
  var onClear = props.onClear, InputProps = props.InputProps, disabled = props.disabled, action = props.action, onKeyDown = props.onKeyDown, _a = props.inputProps, _b = _a === void 0 ? {} : _a, announcementText = _b.announcementText, inputProps = __rest(_b, ["announcementText"]), PopoverPropsProp = props.PopoverProps, children = props.children, ActionSymbol = props.ActionSymbol, clearBtn = props.clearBtn, clearButtonProps = props.clearButtonProps, value = props.value, rest = __rest(props, ["onClear", "InputProps", "disabled", "action", "onKeyDown", "inputProps", "PopoverProps", "children", "ActionSymbol", "clearBtn", "clearButtonProps", "value"]);
20
+ var focusInside = useFocusInside();
20
21
  var idForInput = useRef(uniqueId(PICKER_DISPLAY_NAME + "-")).current;
21
22
  var _c = __read(useState(null), 2), anchorEl = _c[0], setAnchorEl = _c[1];
22
23
  var idForHelperText = idForInput + "-helper-text";
@@ -89,7 +90,10 @@ var PickerTextField = forwardRef(function (props, ref) {
89
90
  }); }, [onPickerViewClose]);
90
91
  return (React.createElement(React.Fragment, null,
91
92
  React.createElement(StyledPickerTextField, __assign({ id: idForInput, ref: ref, InputProps: _InputProps, FormHelperTextProps: _FormHelperTextProps, focused: popoverOpen ? true : undefined, disabled: disabled, clearBtn: clearBtn, value: value }, rest)),
92
- React.createElement(StyledPopover, __assign({ open: popoverOpen, anchorEl: anchorEl, onClose: onPickerViewClose, anchorOrigin: popoverAnchorOrigin, transformOrigin: popoverTransformOrigin }, PopoverProps), children),
93
+ React.createElement(StyledPopover, __assign({ open: popoverOpen, anchorEl: anchorEl, onClose: onPickerViewClose, anchorOrigin: popoverAnchorOrigin, transformOrigin: popoverTransformOrigin }, PopoverProps),
94
+ focusInside.start,
95
+ children,
96
+ focusInside.end),
93
97
  React.createElement(RcVisuallyHidden, { id: idForInstruction }, announcementText)));
94
98
  });
95
99
  PickerTextField.displayName = PICKER_DISPLAY_NAME;
@@ -7,6 +7,7 @@ export * from './useDebounce';
7
7
  export * from './useEventCallback';
8
8
  export * from './useEventListener';
9
9
  export * from './useEver';
10
+ export * from './useFocusInside';
10
11
  export * from './useForceUpdate';
11
12
  export * from './useForkRef';
12
13
  export * from './useGlobalListener';
@@ -0,0 +1 @@
1
+ export * from './useFocusInside';
@@ -0,0 +1,56 @@
1
+ import { __assign, __makeTemplateObject } from "tslib";
2
+ import styled from '../../styled-components';
3
+ import React, { useMemo } from 'react';
4
+ import { logInDev } from '../../utils';
5
+ var FOCUSABLE_QUERY = '[data-focusable="true"]';
6
+ /**
7
+ * non size for just render hidden element
8
+ */
9
+ export var RcFocusInside = styled.span(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 0;\n height: 0;\n"], ["\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 0;\n height: 0;\n"])));
10
+ /**
11
+ * focus always inside the container which `[data-focusable="true"]`
12
+ */
13
+ export var useFocusInside = function (options) {
14
+ if (options === void 0) { options = {}; }
15
+ var containerRef = options.containerRef, _a = options.selector, selector = _a === void 0 ? FOCUSABLE_QUERY : _a;
16
+ return useMemo(function () {
17
+ var start = (React.createElement(RcFocusInside, __assign({ tabIndex: 0 }, (process.env.NODE_ENV !== 'production'
18
+ ? { 'data-test-automation-id': 'focus-inside-start' }
19
+ : undefined), { onFocus: function (e) {
20
+ var container = (containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) || e.target.parentElement;
21
+ var nodes = container === null || container === void 0 ? void 0 : container.querySelectorAll(selector);
22
+ if (nodes) {
23
+ var last = nodes[nodes.length - 1];
24
+ last.focus();
25
+ }
26
+ else if (process.env.NODE_ENV !== 'production') {
27
+ logInDev({
28
+ component: 'useFocusInside',
29
+ message: 'Not found any [data-focusable="true"] element in container, please check your containerRef',
30
+ level: 'warn',
31
+ });
32
+ }
33
+ } })));
34
+ var end = (React.createElement(RcFocusInside, __assign({ tabIndex: 0 }, (process.env.NODE_ENV !== 'production'
35
+ ? { 'data-test-automation-id': 'focus-inside-end' }
36
+ : undefined), { onFocus: function (e) {
37
+ var container = (containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) || e.target.parentElement;
38
+ var node = container === null || container === void 0 ? void 0 : container.querySelector(selector);
39
+ if (node) {
40
+ node === null || node === void 0 ? void 0 : node.focus();
41
+ }
42
+ else if (process.env.NODE_ENV !== 'production') {
43
+ logInDev({
44
+ component: 'useFocusInside',
45
+ message: 'Not found any [data-focusable="true"] element in container, please check your containerRef',
46
+ level: 'warn',
47
+ });
48
+ }
49
+ } })));
50
+ return {
51
+ start: start,
52
+ end: end,
53
+ };
54
+ }, [containerRef, selector]);
55
+ };
56
+ var templateObject_1;
@@ -7,6 +7,7 @@ export * from './useDebounce';
7
7
  export * from './useEventCallback';
8
8
  export * from './useEventListener';
9
9
  export * from './useEver';
10
+ export * from './useFocusInside';
10
11
  export * from './useForceUpdate';
11
12
  export * from './useForkRef';
12
13
  export * from './useGlobalListener';
@@ -10,6 +10,7 @@ tslib_1.__exportStar(require("./useDebounce"), exports);
10
10
  tslib_1.__exportStar(require("./useEventCallback"), exports);
11
11
  tslib_1.__exportStar(require("./useEventListener"), exports);
12
12
  tslib_1.__exportStar(require("./useEver"), exports);
13
+ tslib_1.__exportStar(require("./useFocusInside"), exports);
13
14
  tslib_1.__exportStar(require("./useForceUpdate"), exports);
14
15
  tslib_1.__exportStar(require("./useForkRef"), exports);
15
16
  tslib_1.__exportStar(require("./useGlobalListener"), exports);
@@ -0,0 +1 @@
1
+ export * from './useFocusInside';
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./useFocusInside"), exports);
@@ -0,0 +1,5 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "../../../es6/foundation/hooks/useFocusInside/index.js",
4
+ "typings": "./index.d.ts"
5
+ }
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ /**
3
+ * non size for just render hidden element
4
+ */
5
+ export declare const RcFocusInside: import("styled-components").StyledComponentClass<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, import("../..").RcTheme, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>;
6
+ export declare type useFocusInsideParams = {
7
+ /**
8
+ * the container that should move focus inside witch `[data-focusable="true"]`
9
+ *
10
+ * @default host element's parent
11
+ */
12
+ containerRef?: React.RefObject<HTMLElement>;
13
+ /**
14
+ * the custom selector for focusable element
15
+ *
16
+ * @default '[data-focusable="true"]'
17
+ */
18
+ selector?: string;
19
+ };
20
+ /**
21
+ * focus always inside the container which `[data-focusable="true"]`
22
+ */
23
+ export declare const useFocusInside: (options?: useFocusInsideParams) => {
24
+ start: JSX.Element;
25
+ end: JSX.Element;
26
+ };
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var tslib_1 = require("tslib");
4
+ var styled_components_1 = tslib_1.__importDefault(require("../../styled-components"));
5
+ var react_1 = tslib_1.__importStar(require("react"));
6
+ var utils_1 = require("../../utils");
7
+ var FOCUSABLE_QUERY = '[data-focusable="true"]';
8
+ /**
9
+ * non size for just render hidden element
10
+ */
11
+ exports.RcFocusInside = styled_components_1.default.span(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 0;\n height: 0;\n"], ["\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 0;\n height: 0;\n"])));
12
+ /**
13
+ * focus always inside the container which `[data-focusable="true"]`
14
+ */
15
+ exports.useFocusInside = function (options) {
16
+ if (options === void 0) { options = {}; }
17
+ var containerRef = options.containerRef, _a = options.selector, selector = _a === void 0 ? FOCUSABLE_QUERY : _a;
18
+ return react_1.useMemo(function () {
19
+ var start = (react_1.default.createElement(exports.RcFocusInside, tslib_1.__assign({ tabIndex: 0 }, (process.env.NODE_ENV !== 'production'
20
+ ? { 'data-test-automation-id': 'focus-inside-start' }
21
+ : undefined), { onFocus: function (e) {
22
+ var container = (containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) || e.target.parentElement;
23
+ var nodes = container === null || container === void 0 ? void 0 : container.querySelectorAll(selector);
24
+ if (nodes) {
25
+ var last = nodes[nodes.length - 1];
26
+ last.focus();
27
+ }
28
+ else if (process.env.NODE_ENV !== 'production') {
29
+ utils_1.logInDev({
30
+ component: 'useFocusInside',
31
+ message: 'Not found any [data-focusable="true"] element in container, please check your containerRef',
32
+ level: 'warn',
33
+ });
34
+ }
35
+ } })));
36
+ var end = (react_1.default.createElement(exports.RcFocusInside, tslib_1.__assign({ tabIndex: 0 }, (process.env.NODE_ENV !== 'production'
37
+ ? { 'data-test-automation-id': 'focus-inside-end' }
38
+ : undefined), { onFocus: function (e) {
39
+ var container = (containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) || e.target.parentElement;
40
+ var node = container === null || container === void 0 ? void 0 : container.querySelector(selector);
41
+ if (node) {
42
+ node === null || node === void 0 ? void 0 : node.focus();
43
+ }
44
+ else if (process.env.NODE_ENV !== 'production') {
45
+ utils_1.logInDev({
46
+ component: 'useFocusInside',
47
+ message: 'Not found any [data-focusable="true"] element in container, please check your containerRef',
48
+ level: 'warn',
49
+ });
50
+ }
51
+ } })));
52
+ return {
53
+ start: start,
54
+ end: end,
55
+ };
56
+ }, [containerRef, selector]);
57
+ };
58
+ var templateObject_1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ringcentral/juno",
3
- "version": "2.41.1",
3
+ "version": "2.41.2",
4
4
  "author": "RingCentral",
5
5
  "license": "MIT",
6
6
  "main": "./index.js",