@jetbrains/ring-ui-built 6.0.39 → 6.0.40
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/components/checkbox/checkbox.d.ts +1 -0
- package/components/checkbox/checkbox.js +3 -2
- package/components/data-list/data-list.js +1 -1
- package/components/data-list/title.js +1 -1
- package/components/global/composeRefs.d.ts +3 -1
- package/components/global/composeRefs.js +4 -1
- package/components/global/focus-sensor-hoc.js +4 -2
- package/components/global/rerender-hoc.js +4 -2
- package/components/list/list__item.js +1 -1
- package/components/select/select.d.ts +1 -0
- package/components/select/select.js +3 -2
- package/components/select/select__popup.d.ts +1 -0
- package/components/select/select__popup.js +3 -2
- package/components/tab-trap/tab-trap.d.ts +9 -36
- package/components/tab-trap/tab-trap.js +144 -156
- package/components/table/row-with-focus-sensor.js +1 -1
- package/components/table/row.d.ts +1 -0
- package/components/table/row.js +3 -2
- package/components/table/smart-table.js +1 -1
- package/components/table/table.js +1 -1
- package/package.json +1 -1
@@ -42,5 +42,6 @@ export default class Checkbox extends PureComponent<CheckboxProps> {
|
|
42
42
|
componentDidUpdate(prevProps: CheckboxProps): void;
|
43
43
|
input?: HTMLInputElement | null;
|
44
44
|
inputRef: (el: HTMLInputElement | null) => void;
|
45
|
+
composedInputRef: import("memoize-one").MemoizedFn<(...refs: (Ref<HTMLInputElement> | undefined)[]) => (value: HTMLInputElement | null) => void>;
|
45
46
|
render(): import("react").JSX.Element;
|
46
47
|
}
|
@@ -7,7 +7,7 @@ import checkmarkIcon from '@jetbrains/icons/checkmark-12px';
|
|
7
7
|
import minusIcon from '@jetbrains/icons/remove-12px';
|
8
8
|
import Icon from '../icon/icon.js';
|
9
9
|
import { refObject } from '../global/prop-types.js';
|
10
|
-
import
|
10
|
+
import { createComposedRef } from '../global/composeRefs.js';
|
11
11
|
import ControlHelp from '../control-help/control-help.js';
|
12
12
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
13
13
|
import 'util-deprecate';
|
@@ -43,6 +43,7 @@ var Checkbox = /*#__PURE__*/function (_PureComponent) {
|
|
43
43
|
}
|
44
44
|
_this.input = el;
|
45
45
|
});
|
46
|
+
_defineProperty(_this, "composedInputRef", createComposedRef());
|
46
47
|
return _this;
|
47
48
|
}
|
48
49
|
_inherits(Checkbox, _PureComponent);
|
@@ -86,7 +87,7 @@ var Checkbox = /*#__PURE__*/function (_PureComponent) {
|
|
86
87
|
"data-test": "ring-checkbox",
|
87
88
|
children: [/*#__PURE__*/jsx("input", _objectSpread2(_objectSpread2({}, restProps), {}, {
|
88
89
|
"data-checked": restProps.checked,
|
89
|
-
ref:
|
90
|
+
ref: this.composedInputRef(this.inputRef, inputRef),
|
90
91
|
type: "checkbox",
|
91
92
|
className: classes
|
92
93
|
})), /*#__PURE__*/jsx("div", {
|
@@ -19,6 +19,7 @@ import '../global/composeRefs.js';
|
|
19
19
|
import 'core-js/modules/es.object.to-string.js';
|
20
20
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
21
21
|
import 'memoize-one';
|
22
|
+
import 'util-deprecate';
|
22
23
|
import '../table/selection.js';
|
23
24
|
import 'core-js/modules/es.array.filter.js';
|
24
25
|
import 'core-js/modules/es.array.index-of.js';
|
@@ -55,7 +56,6 @@ import '../loader-inline/loader-inline.js';
|
|
55
56
|
import '../button/button.js';
|
56
57
|
import '@jetbrains/icons/chevron-10px';
|
57
58
|
import '../icon/icon.js';
|
58
|
-
import 'util-deprecate';
|
59
59
|
import '../icon/icon__constants.js';
|
60
60
|
import '../_helpers/icon__svg.js';
|
61
61
|
import 'core-js/modules/es.string.replace.js';
|
@@ -13,10 +13,10 @@ import '../global/composeRefs.js';
|
|
13
13
|
import 'core-js/modules/es.object.to-string.js';
|
14
14
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
15
15
|
import 'memoize-one';
|
16
|
+
import 'util-deprecate';
|
16
17
|
import '@jetbrains/icons/checkmark-12px';
|
17
18
|
import '@jetbrains/icons/remove-12px';
|
18
19
|
import '../icon/icon.js';
|
19
|
-
import 'util-deprecate';
|
20
20
|
import '../icon/icon__constants.js';
|
21
21
|
import '../_helpers/icon__svg.js';
|
22
22
|
import 'core-js/modules/es.regexp.exec.js';
|
@@ -1,3 +1,5 @@
|
|
1
1
|
import { Ref } from 'react';
|
2
|
-
|
2
|
+
declare function composeRefs<T>(...refs: (Ref<T> | undefined)[]): (value: T | null) => void;
|
3
|
+
declare const _default: typeof composeRefs;
|
4
|
+
export default _default;
|
3
5
|
export declare function createComposedRef<T>(): import("memoize-one").MemoizedFn<(...refs: (Ref<T> | undefined)[]) => (value: T | null) => void>;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import 'core-js/modules/es.object.to-string.js';
|
2
2
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
3
3
|
import memoizeOne from 'memoize-one';
|
4
|
+
import deprecate from 'util-deprecate';
|
4
5
|
|
5
6
|
function composeRefs() {
|
6
7
|
for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {
|
@@ -16,8 +17,10 @@ function composeRefs() {
|
|
16
17
|
});
|
17
18
|
};
|
18
19
|
}
|
20
|
+
// TODO remove export in 7.0, composeRefs should be used only in createComposedRef and in useComposedRefs in the future
|
21
|
+
var composeRefs$1 = deprecate(composeRefs, 'composeRefs is deprecated and will be removed in 7.0. Use createComposedRef instead.');
|
19
22
|
function createComposedRef() {
|
20
23
|
return memoizeOne(composeRefs);
|
21
24
|
}
|
22
25
|
|
23
|
-
export { createComposedRef, composeRefs as default };
|
26
|
+
export { createComposedRef, composeRefs$1 as default };
|
@@ -3,11 +3,12 @@ import 'core-js/modules/es.array.concat.js';
|
|
3
3
|
import { Component } from 'react';
|
4
4
|
import PropTypes from 'prop-types';
|
5
5
|
import { refObject } from './prop-types.js';
|
6
|
-
import
|
6
|
+
import { createComposedRef } from './composeRefs.js';
|
7
7
|
import { jsx } from 'react/jsx-runtime';
|
8
8
|
import 'core-js/modules/es.object.to-string.js';
|
9
9
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
10
10
|
import 'memoize-one';
|
11
|
+
import 'util-deprecate';
|
11
12
|
|
12
13
|
var _excluded = ["innerRef", "focused", "onFocusReset", "onFocusRestore"],
|
13
14
|
_excluded2 = ["autofocus", "focused", "onFocus", "onBlur", "innerRef", "scrollOnTableFocus"];
|
@@ -42,6 +43,7 @@ function focusSensorHOC(ComposedComponent) {
|
|
42
43
|
_this.node = node;
|
43
44
|
}
|
44
45
|
});
|
46
|
+
_defineProperty(_this, "composedRef", createComposedRef());
|
45
47
|
_defineProperty(_this, "onFocusCapture", function (_ref2) {
|
46
48
|
var _this$node;
|
47
49
|
var target = _ref2.target;
|
@@ -137,7 +139,7 @@ function focusSensorHOC(ComposedComponent) {
|
|
137
139
|
_this$props4.scrollOnTableFocus;
|
138
140
|
var rest = _objectWithoutProperties(_this$props4, _excluded2);
|
139
141
|
return /*#__PURE__*/jsx(ComposedComponent, _objectSpread2(_objectSpread2({}, rest), {}, {
|
140
|
-
innerRef:
|
142
|
+
innerRef: this.composedRef(innerRef, this.onRefUpdate),
|
141
143
|
focused: this.state.focused,
|
142
144
|
onFocusReset: this.onFocusReset,
|
143
145
|
onFocusRestore: this.onFocusRestore
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import { a as _inherits, b as _createClass, d as _objectSpread2, e as _classCallCheck, f as _callSuper, _ as _defineProperty } from '../_helpers/_rollupPluginBabelHelpers.js';
|
2
2
|
import 'core-js/modules/es.array.concat.js';
|
3
3
|
import { forwardRef, Component } from 'react';
|
4
|
-
import
|
4
|
+
import { createComposedRef } from './composeRefs.js';
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
6
6
|
import 'core-js/modules/es.object.to-string.js';
|
7
7
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
8
8
|
import 'memoize-one';
|
9
|
+
import 'util-deprecate';
|
9
10
|
|
10
11
|
function rerenderHOC(ComposedComponent) {
|
11
12
|
var Rerenderer = /*#__PURE__*/function (_Component) {
|
@@ -17,6 +18,7 @@ function rerenderHOC(ComposedComponent) {
|
|
17
18
|
}
|
18
19
|
_this = _callSuper(this, Rerenderer, [].concat(args));
|
19
20
|
_defineProperty(_this, "state", _this.props.props);
|
21
|
+
_defineProperty(_this, "composedRef", createComposedRef());
|
20
22
|
return _this;
|
21
23
|
}
|
22
24
|
_inherits(Rerenderer, _Component);
|
@@ -24,7 +26,7 @@ function rerenderHOC(ComposedComponent) {
|
|
24
26
|
key: "render",
|
25
27
|
value: function render() {
|
26
28
|
var _this2 = this;
|
27
|
-
var _ref =
|
29
|
+
var _ref = this.composedRef(this.props.forwardedRef);
|
28
30
|
return /*#__PURE__*/jsx(ComposedComponent, _objectSpread2(_objectSpread2({}, this.state), {}, {
|
29
31
|
ref: function ref(instance) {
|
30
32
|
return _ref(instance != null ? _objectSpread2(_objectSpread2({}, instance), {}, {
|
@@ -38,8 +38,8 @@ import '@jetbrains/icons/remove-12px';
|
|
38
38
|
import '../global/prop-types.js';
|
39
39
|
import '../global/composeRefs.js';
|
40
40
|
import 'memoize-one';
|
41
|
-
import '../control-help/control-help.js';
|
42
41
|
import 'util-deprecate';
|
42
|
+
import '../control-help/control-help.js';
|
43
43
|
import '../icon/icon__constants.js';
|
44
44
|
import '../_helpers/icon__svg.js';
|
45
45
|
import 'core-js/modules/es.string.starts-with.js';
|
@@ -259,6 +259,7 @@ export default class Select<T = unknown> extends Component<SelectProps<T>, Selec
|
|
259
259
|
private _getAvatar;
|
260
260
|
filter?: HTMLInputElement | null;
|
261
261
|
filterRef: (el: HTMLInputElement | null) => void;
|
262
|
+
composedFilterRef: import("memoize-one").MemoizedFn<(...refs: (Ref<HTMLInputElement> | undefined)[]) => (value: HTMLInputElement | null) => void>;
|
262
263
|
getShortcutsMap(): {
|
263
264
|
enter: () => true | undefined;
|
264
265
|
esc: (event: KeyboardEvent) => boolean | undefined;
|
@@ -33,7 +33,7 @@ import rerenderHOC from '../global/rerender-hoc.js';
|
|
33
33
|
import fuzzyHighlight from '../global/fuzzy-highlight.js';
|
34
34
|
import memoize from '../global/memoize.js';
|
35
35
|
import { I18nContext } from '../i18n/i18n-context.js';
|
36
|
-
import
|
36
|
+
import { createComposedRef } from '../global/composeRefs.js';
|
37
37
|
import { refObject } from '../global/prop-types.js';
|
38
38
|
import { isArray } from '../global/typescript-utils.js';
|
39
39
|
import { ControlsHeightContext, ControlsHeight } from '../global/controls-height.js';
|
@@ -633,6 +633,7 @@ var Select = /*#__PURE__*/function (_Component) {
|
|
633
633
|
_defineProperty(_this, "filterRef", function (el) {
|
634
634
|
_this.filter = el;
|
635
635
|
});
|
636
|
+
_defineProperty(_this, "composedFilterRef", createComposedRef());
|
636
637
|
return _this;
|
637
638
|
}
|
638
639
|
_inherits(Select, _Component);
|
@@ -1010,7 +1011,7 @@ var Select = /*#__PURE__*/function (_Component) {
|
|
1010
1011
|
autoComplete: "off",
|
1011
1012
|
id: this.props.id,
|
1012
1013
|
onClick: this._clickHandler,
|
1013
|
-
inputRef:
|
1014
|
+
inputRef: this.composedFilterRef(this.filterRef, this.props.filterRef),
|
1014
1015
|
disabled: this.props.disabled,
|
1015
1016
|
value: this.state.filterValue,
|
1016
1017
|
borderless: this.props.type === Type.INPUT_WITHOUT_CONTROLS,
|
@@ -126,6 +126,7 @@ export default class SelectPopup<T = unknown> extends PureComponent<SelectPopupP
|
|
126
126
|
list?: List<T> | null;
|
127
127
|
listRef: (el: List<T> | null) => void;
|
128
128
|
filterRef: (el: HTMLInputElement | null) => void;
|
129
|
+
composedFilterRef: import("memoize-one").MemoizedFn<(...refs: (Ref<HTMLInputElement> | undefined)[]) => (value: HTMLInputElement | null) => void>;
|
129
130
|
shortcutsScope: string;
|
130
131
|
shortcutsMap: {
|
131
132
|
tab: (event: Event) => void;
|
@@ -27,7 +27,7 @@ import { Button } from '../button/button.js';
|
|
27
27
|
import Text from '../text/text.js';
|
28
28
|
import { ControlsHeight } from '../global/controls-height.js';
|
29
29
|
import { refObject } from '../global/prop-types.js';
|
30
|
-
import
|
30
|
+
import { createComposedRef } from '../global/composeRefs.js';
|
31
31
|
import { DEFAULT_DIRECTIONS } from '../popup/popup.consts.js';
|
32
32
|
import { S as SelectFilter, m as modules_b607bec2 } from '../_helpers/select__filter.js';
|
33
33
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
@@ -237,6 +237,7 @@ var SelectPopup = /*#__PURE__*/function (_PureComponent) {
|
|
237
237
|
_this.filter = el;
|
238
238
|
_this.caret = el && new Caret(el);
|
239
239
|
});
|
240
|
+
_defineProperty(_this, "composedFilterRef", createComposedRef());
|
240
241
|
_defineProperty(_this, "shortcutsScope", getUID('select-popup-'));
|
241
242
|
_defineProperty(_this, "shortcutsMap", {
|
242
243
|
tab: _this.tabPress
|
@@ -396,7 +397,7 @@ var SelectPopup = /*#__PURE__*/function (_PureComponent) {
|
|
396
397
|
rgShortcutsOptions: this.state.popupFilterShortcutsOptions,
|
397
398
|
rgShortcutsMap: this.popupFilterShortcutsMap,
|
398
399
|
value: this.props.filterValue,
|
399
|
-
inputRef:
|
400
|
+
inputRef: this.composedFilterRef(this.filterRef, this.props.filterRef),
|
400
401
|
onBlur: this.popupFilterOnBlur,
|
401
402
|
onFocus: this.onFilterFocus,
|
402
403
|
className: "ring-js-shortcuts",
|
@@ -1,45 +1,18 @@
|
|
1
|
-
import {
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
2
2
|
import * as React from 'react';
|
3
|
-
import PropTypes from 'prop-types';
|
4
3
|
export declare const FOCUSABLE_ELEMENTS = "input, button, select, textarea, a[href], *[tabindex]:not([data-trap-button]):not([data-scrollable-container])";
|
5
4
|
export interface TabTrapProps extends HTMLAttributes<HTMLElement> {
|
6
5
|
children: ReactNode;
|
7
|
-
trapDisabled
|
8
|
-
autoFocusFirst
|
9
|
-
focusBackOnClose
|
10
|
-
focusBackOnExit
|
6
|
+
trapDisabled?: boolean;
|
7
|
+
autoFocusFirst?: boolean;
|
8
|
+
focusBackOnClose?: boolean;
|
9
|
+
focusBackOnExit?: boolean;
|
11
10
|
}
|
12
11
|
/**
|
13
12
|
* @name TabTrap
|
14
13
|
*/
|
15
|
-
|
16
|
-
|
17
|
-
children: PropTypes.Validator<NonNullable<PropTypes.ReactNodeLike>>;
|
18
|
-
trapDisabled: PropTypes.Requireable<boolean>;
|
19
|
-
autoFocusFirst: PropTypes.Requireable<boolean>;
|
20
|
-
focusBackOnClose: PropTypes.Requireable<boolean>;
|
21
|
-
focusBackOnExit: PropTypes.Requireable<boolean>;
|
22
|
-
};
|
23
|
-
static defaultProps: {
|
24
|
-
trapDisabled: boolean;
|
25
|
-
autoFocusFirst: boolean;
|
26
|
-
focusBackOnClose: boolean;
|
27
|
-
focusBackOnExit: boolean;
|
28
|
-
};
|
29
|
-
constructor(props: TabTrapProps);
|
30
|
-
componentDidMount(): void;
|
31
|
-
componentWillUnmount(): void;
|
32
|
-
previousFocusedNode?: Element | null;
|
33
|
-
trapWithoutFocus?: boolean;
|
34
|
-
restoreFocus: () => void;
|
35
|
-
node?: HTMLElement | null;
|
36
|
-
containerRef: (node: HTMLElement | null) => void;
|
37
|
-
focusElement: (first?: boolean) => void;
|
38
|
-
focusFirst: () => void;
|
39
|
-
focusLast: () => void;
|
40
|
-
focusLastIfEnabled: (event: React.FocusEvent) => void;
|
41
|
-
handleBlurIfWithoutFocus: (event: React.FocusEvent) => void;
|
42
|
-
trapButtonNode?: HTMLElement | null;
|
43
|
-
trapButtonRef: (node: HTMLElement | null) => void;
|
44
|
-
render(): React.JSX.Element;
|
14
|
+
interface TabTrap {
|
15
|
+
node: HTMLElement | null;
|
45
16
|
}
|
17
|
+
declare const TabTrap: React.ForwardRefExoticComponent<TabTrapProps & React.RefAttributes<TabTrap>>;
|
18
|
+
export default TabTrap;
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import {
|
1
|
+
import { c as _objectWithoutProperties, j as _toConsumableArray, d as _objectSpread2 } from '../_helpers/_rollupPluginBabelHelpers.js';
|
2
2
|
import 'core-js/modules/es.array.filter.js';
|
3
3
|
import 'core-js/modules/es.object.to-string.js';
|
4
|
-
import {
|
4
|
+
import { forwardRef, useRef, useImperativeHandle, useCallback, useEffect } from 'react';
|
5
5
|
import PropTypes from 'prop-types';
|
6
6
|
import { isNodeInVisiblePartOfPage } from '../global/dom.js';
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
@@ -18,173 +18,161 @@ var modules_6dce58ae = {"light":"light_rui_2ac4","trapButton":"trapButton_rui_11
|
|
18
18
|
|
19
19
|
var _excluded = ["children", "trapDisabled", "autoFocusFirst", "focusBackOnClose", "focusBackOnExit"];
|
20
20
|
var FOCUSABLE_ELEMENTS = 'input, button, select, textarea, a[href], *[tabindex]:not([data-trap-button]):not([data-scrollable-container])';
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
22
|
+
var TabTrap = /*#__PURE__*/forwardRef(function TabTrap(_ref, ref) {
|
23
|
+
var children = _ref.children,
|
24
|
+
_ref$trapDisabled = _ref.trapDisabled,
|
25
|
+
trapDisabled = _ref$trapDisabled === void 0 ? false : _ref$trapDisabled,
|
26
|
+
_ref$autoFocusFirst = _ref.autoFocusFirst,
|
27
|
+
autoFocusFirst = _ref$autoFocusFirst === void 0 ? true : _ref$autoFocusFirst,
|
28
|
+
_ref$focusBackOnClose = _ref.focusBackOnClose,
|
29
|
+
focusBackOnClose = _ref$focusBackOnClose === void 0 ? true : _ref$focusBackOnClose,
|
30
|
+
_ref$focusBackOnExit = _ref.focusBackOnExit,
|
31
|
+
focusBackOnExit = _ref$focusBackOnExit === void 0 ? false : _ref$focusBackOnExit,
|
32
|
+
restProps = _objectWithoutProperties(_ref, _excluded);
|
33
|
+
var nodeRef = useRef(null);
|
34
|
+
var trapButtonNodeRef = useRef(null);
|
35
|
+
var previousFocusedNodeRef = useRef(null);
|
36
|
+
var trapWithoutFocusRef = useRef(false);
|
37
|
+
var mountedRef = useRef(false);
|
38
|
+
// It's the same approach as in focus-trap-react:
|
39
|
+
// https://github.com/focus-trap/focus-trap-react/commit/3b22fca9eebeb883edc89548850fe5a5b9d6d50e
|
40
|
+
// We can't do it in useEffect because it's too late, some children might have already
|
41
|
+
// focused itself.
|
42
|
+
if (previousFocusedNodeRef.current === null) {
|
43
|
+
previousFocusedNodeRef.current = document.activeElement;
|
44
|
+
}
|
45
|
+
useImperativeHandle(ref, function () {
|
46
|
+
return {
|
47
|
+
node: nodeRef.current
|
48
|
+
};
|
49
|
+
}, []);
|
50
|
+
var focusFirst = useCallback(function () {
|
51
|
+
return focusElement(true);
|
52
|
+
}, []);
|
53
|
+
var focusLast = function focusLast() {
|
54
|
+
return focusElement(false);
|
55
|
+
};
|
56
|
+
useEffect(function () {
|
57
|
+
mountedRef.current = true;
|
58
|
+
return function () {
|
59
|
+
mountedRef.current = false;
|
60
|
+
};
|
61
|
+
}, []);
|
62
|
+
useEffect(function () {
|
63
|
+
if (autoFocusFirst) {
|
64
|
+
focusFirst();
|
65
|
+
} else if (!trapDisabled) {
|
66
|
+
var _nodeRef$current, _nodeRef$current2;
|
67
|
+
var previousFocusedElementIsInContainer = previousFocusedNodeRef.current && ((_nodeRef$current = nodeRef.current) === null || _nodeRef$current === void 0 ? void 0 : _nodeRef$current.contains(previousFocusedNodeRef.current));
|
68
|
+
// The component wrapped in TabTrap can already have a focused element (e.g. Date Picker),
|
69
|
+
// so we need to check if it does. If so, we don't need to focus anything.
|
70
|
+
var currentlyFocusedElementIsInContainer = (_nodeRef$current2 = nodeRef.current) === null || _nodeRef$current2 === void 0 ? void 0 : _nodeRef$current2.contains(document.activeElement);
|
71
|
+
if (!nodeRef.current || !previousFocusedElementIsInContainer && !currentlyFocusedElementIsInContainer) {
|
72
|
+
var _trapButtonNodeRef$cu;
|
73
|
+
trapWithoutFocusRef.current = true;
|
74
|
+
(_trapButtonNodeRef$cu = trapButtonNodeRef.current) === null || _trapButtonNodeRef$cu === void 0 || _trapButtonNodeRef$cu.focus();
|
64
75
|
}
|
65
|
-
}
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
_defineProperty(_this, "focusLast", function () {
|
70
|
-
return _this.focusElement(false);
|
71
|
-
});
|
72
|
-
_defineProperty(_this, "focusLastIfEnabled", function (event) {
|
73
|
-
if (_this.trapWithoutFocus) {
|
74
|
-
return;
|
76
|
+
}
|
77
|
+
return function () {
|
78
|
+
if (focusBackOnClose) {
|
79
|
+
restoreFocus();
|
75
80
|
}
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
81
|
+
};
|
82
|
+
}, [autoFocusFirst, trapDisabled, focusBackOnClose, focusFirst]);
|
83
|
+
function restoreFocus() {
|
84
|
+
var previousFocusedNode = previousFocusedNodeRef.current;
|
85
|
+
if (previousFocusedNode instanceof HTMLElement && previousFocusedNode.focus && isNodeInVisiblePartOfPage(previousFocusedNode)) {
|
86
|
+
// If no delay is added, restoring focus caused by pressing Enter will trigger
|
87
|
+
// the onClick event on the previousFocusedNode, e.g.
|
88
|
+
// https://youtrack.jetbrains.com/issue/RG-2450/Anchor-should-be-focused-after-closing-datepicker#focus=Comments-27-10044234.0-0.
|
89
|
+
setTimeout(function () {
|
90
|
+
// This is to prevent the focus from being restored the first time
|
91
|
+
// componentWillUnmount is called in StrictMode.
|
92
|
+
if (!mountedRef.current) {
|
93
|
+
previousFocusedNode.focus({
|
94
|
+
preventScroll: true
|
95
|
+
});
|
80
96
|
}
|
81
|
-
}
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
if (!newFocused) {
|
93
|
-
return;
|
94
|
-
}
|
95
|
-
if (newFocused instanceof Element && (_this$node = _this.node) !== null && _this$node !== void 0 && _this$node.contains(newFocused)) {
|
96
|
-
return;
|
97
|
-
}
|
98
|
-
_this.focusLast();
|
99
|
-
});
|
100
|
-
_defineProperty(_this, "trapButtonNode", void 0);
|
101
|
-
_defineProperty(_this, "trapButtonRef", function (node) {
|
102
|
-
if (!node) {
|
103
|
-
return;
|
104
|
-
}
|
105
|
-
_this.trapButtonNode = node;
|
97
|
+
});
|
98
|
+
}
|
99
|
+
}
|
100
|
+
function focusElement() {
|
101
|
+
var first = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
102
|
+
var node = nodeRef.current;
|
103
|
+
if (!node) {
|
104
|
+
return;
|
105
|
+
}
|
106
|
+
var tabables = _toConsumableArray(node.querySelectorAll(FOCUSABLE_ELEMENTS)).filter(function (item) {
|
107
|
+
return item.tabIndex >= 0;
|
106
108
|
});
|
107
|
-
|
108
|
-
|
109
|
+
var toBeFocused = first ? tabables[0] : tabables[tabables.length - 1];
|
110
|
+
if (toBeFocused) {
|
111
|
+
toBeFocused.focus();
|
112
|
+
}
|
109
113
|
}
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
value: function componentDidMount() {
|
114
|
-
if (this.props.autoFocusFirst) {
|
115
|
-
this.focusFirst();
|
116
|
-
} else if (!this.props.trapDisabled) {
|
117
|
-
var _this$node2, _this$node3;
|
118
|
-
var previousFocusedElementIsInContainer = this.previousFocusedNode && ((_this$node2 = this.node) === null || _this$node2 === void 0 ? void 0 : _this$node2.contains(this.previousFocusedNode));
|
119
|
-
// The component wrapped in TabTrap can already have a focused element (e.g. Date Picker),
|
120
|
-
// so we need to check if it does. If so, we don't need to focus anything.
|
121
|
-
var currentlyFocusedElementIsInContainer = (_this$node3 = this.node) === null || _this$node3 === void 0 ? void 0 : _this$node3.contains(document.activeElement);
|
122
|
-
if (!this.node || !previousFocusedElementIsInContainer && !currentlyFocusedElementIsInContainer) {
|
123
|
-
var _this$trapButtonNode;
|
124
|
-
this.trapWithoutFocus = true;
|
125
|
-
(_this$trapButtonNode = this.trapButtonNode) === null || _this$trapButtonNode === void 0 || _this$trapButtonNode.focus();
|
126
|
-
}
|
127
|
-
}
|
114
|
+
function focusLastIfEnabled(event) {
|
115
|
+
if (trapWithoutFocusRef.current) {
|
116
|
+
return;
|
128
117
|
}
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
this.restoreFocus();
|
118
|
+
if (focusBackOnExit) {
|
119
|
+
var prevFocused = event.nativeEvent.relatedTarget;
|
120
|
+
if (prevFocused != null && nodeRef.current != null && prevFocused instanceof Element && nodeRef.current.contains(prevFocused)) {
|
121
|
+
restoreFocus();
|
134
122
|
}
|
123
|
+
} else {
|
124
|
+
focusLast();
|
135
125
|
}
|
136
|
-
}
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
if (trapDisabled) {
|
147
|
-
return /*#__PURE__*/jsx("div", _objectSpread2(_objectSpread2({
|
148
|
-
ref: this.containerRef
|
149
|
-
}, restProps), {}, {
|
150
|
-
children: children
|
151
|
-
}));
|
152
|
-
}
|
153
|
-
return /*#__PURE__*/jsxs("div", _objectSpread2(_objectSpread2({
|
154
|
-
ref: this.containerRef
|
155
|
-
}, restProps), {}, {
|
156
|
-
children: [/*#__PURE__*/jsx("div", {
|
157
|
-
// It never actually stays focused
|
158
|
-
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
159
|
-
tabIndex: 0,
|
160
|
-
ref: this.trapButtonRef,
|
161
|
-
className: modules_6dce58ae.trapButton,
|
162
|
-
onFocus: this.focusLastIfEnabled,
|
163
|
-
onBlur: this.handleBlurIfWithoutFocus,
|
164
|
-
"data-trap-button": true
|
165
|
-
}), children, /*#__PURE__*/jsx("div", {
|
166
|
-
// It never actually stays focused
|
167
|
-
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
168
|
-
tabIndex: 0,
|
169
|
-
onFocus: focusBackOnExit ? this.restoreFocus : this.focusFirst,
|
170
|
-
"data-trap-button": true
|
171
|
-
})]
|
172
|
-
}));
|
126
|
+
}
|
127
|
+
function handleBlurIfWithoutFocus(event) {
|
128
|
+
var _nodeRef$current3;
|
129
|
+
if (!trapWithoutFocusRef.current) {
|
130
|
+
return;
|
131
|
+
}
|
132
|
+
trapWithoutFocusRef.current = false;
|
133
|
+
var newFocused = event.nativeEvent.relatedTarget;
|
134
|
+
if (!newFocused) {
|
135
|
+
return;
|
173
136
|
}
|
174
|
-
|
175
|
-
|
176
|
-
|
137
|
+
if (newFocused instanceof Element && (_nodeRef$current3 = nodeRef.current) !== null && _nodeRef$current3 !== void 0 && _nodeRef$current3.contains(newFocused)) {
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
focusLast();
|
141
|
+
}
|
142
|
+
if (trapDisabled) {
|
143
|
+
return /*#__PURE__*/jsx("div", _objectSpread2(_objectSpread2({
|
144
|
+
ref: nodeRef
|
145
|
+
}, restProps), {}, {
|
146
|
+
children: children
|
147
|
+
}));
|
148
|
+
}
|
149
|
+
return /*#__PURE__*/jsxs("div", _objectSpread2(_objectSpread2({
|
150
|
+
ref: nodeRef
|
151
|
+
}, restProps), {}, {
|
152
|
+
children: [/*#__PURE__*/jsx("div", {
|
153
|
+
// It never actually stays focused
|
154
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
155
|
+
tabIndex: 0,
|
156
|
+
ref: trapButtonNodeRef,
|
157
|
+
className: modules_6dce58ae.trapButton,
|
158
|
+
onFocus: focusLastIfEnabled,
|
159
|
+
onBlur: handleBlurIfWithoutFocus,
|
160
|
+
"data-trap-button": true
|
161
|
+
}), children, /*#__PURE__*/jsx("div", {
|
162
|
+
// It never actually stays focused
|
163
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
164
|
+
tabIndex: 0,
|
165
|
+
onFocus: focusBackOnExit ? restoreFocus : focusFirst,
|
166
|
+
"data-trap-button": true
|
167
|
+
})]
|
168
|
+
}));
|
169
|
+
});
|
170
|
+
TabTrap.propTypes = {
|
177
171
|
children: PropTypes.node.isRequired,
|
178
172
|
trapDisabled: PropTypes.bool,
|
179
173
|
autoFocusFirst: PropTypes.bool,
|
180
174
|
focusBackOnClose: PropTypes.bool,
|
181
175
|
focusBackOnExit: PropTypes.bool
|
182
|
-
}
|
183
|
-
_defineProperty(TabTrap, "defaultProps", {
|
184
|
-
trapDisabled: false,
|
185
|
-
autoFocusFirst: true,
|
186
|
-
focusBackOnClose: true,
|
187
|
-
focusBackOnExit: false
|
188
|
-
});
|
176
|
+
};
|
189
177
|
|
190
178
|
export { FOCUSABLE_ELEMENTS, TabTrap as default };
|
@@ -10,6 +10,7 @@ import '../global/composeRefs.js';
|
|
10
10
|
import 'core-js/modules/es.object.to-string.js';
|
11
11
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
12
12
|
import 'memoize-one';
|
13
|
+
import 'util-deprecate';
|
13
14
|
import 'core-js/modules/es.array.map.js';
|
14
15
|
import 'classnames';
|
15
16
|
import '@jetbrains/icons/chevron-right';
|
@@ -19,7 +20,6 @@ import '../checkbox/checkbox.js';
|
|
19
20
|
import '@jetbrains/icons/checkmark-12px';
|
20
21
|
import '@jetbrains/icons/remove-12px';
|
21
22
|
import '../icon/icon.js';
|
22
|
-
import 'util-deprecate';
|
23
23
|
import '../icon/icon__constants.js';
|
24
24
|
import '../_helpers/icon__svg.js';
|
25
25
|
import 'core-js/modules/es.regexp.exec.js';
|
@@ -56,6 +56,7 @@ export default class Row<T extends SelectionItem> extends PureComponent<RowProps
|
|
56
56
|
onDoubleClick: () => void;
|
57
57
|
row?: HTMLElement | null;
|
58
58
|
rowRef: (el: HTMLElement | null) => void;
|
59
|
+
composedRowRef: import("memoize-one").MemoizedFn<(...refs: (React.Ref<HTMLElement> | undefined)[]) => (value: HTMLElement | null) => void>;
|
59
60
|
render(): React.JSX.Element;
|
60
61
|
}
|
61
62
|
export type RowAttrs<T extends SelectionItem> = JSX.LibraryManagedAttributes<typeof Row, RowProps<T>>;
|
package/components/table/row.js
CHANGED
@@ -12,7 +12,7 @@ import { Button } from '../button/button.js';
|
|
12
12
|
import Tooltip from '../tooltip/tooltip.js';
|
13
13
|
import joinDataTestAttributes from '../global/data-tests.js';
|
14
14
|
import getUID from '../global/get-uid.js';
|
15
|
-
import
|
15
|
+
import { createComposedRef } from '../global/composeRefs.js';
|
16
16
|
import Cell from './cell.js';
|
17
17
|
import { m as modules_1db4bbca } from '../_helpers/table.js';
|
18
18
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
@@ -122,6 +122,7 @@ var Row = /*#__PURE__*/function (_PureComponent) {
|
|
122
122
|
_defineProperty(_this, "rowRef", function (el) {
|
123
123
|
_this.row = el;
|
124
124
|
});
|
125
|
+
_defineProperty(_this, "composedRowRef", createComposedRef());
|
125
126
|
return _this;
|
126
127
|
}
|
127
128
|
_inherits(Row, _PureComponent);
|
@@ -249,7 +250,7 @@ var Row = /*#__PURE__*/function (_PureComponent) {
|
|
249
250
|
});
|
250
251
|
return /*#__PURE__*/jsx("tr", _objectSpread2(_objectSpread2(_objectSpread2({
|
251
252
|
id: this.id,
|
252
|
-
ref:
|
253
|
+
ref: this.composedRowRef(this.rowRef, innerRef),
|
253
254
|
className: classes,
|
254
255
|
tabIndex: 0,
|
255
256
|
"data-test": joinDataTestAttributes('ring-table-row', dataTest)
|
@@ -14,6 +14,7 @@ import '../global/composeRefs.js';
|
|
14
14
|
import 'core-js/modules/es.object.to-string.js';
|
15
15
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
16
16
|
import 'memoize-one';
|
17
|
+
import 'util-deprecate';
|
17
18
|
import '../global/get-uid.js';
|
18
19
|
import 'core-js/modules/es.regexp.to-string.js';
|
19
20
|
import '../shortcuts/shortcuts.js';
|
@@ -46,7 +47,6 @@ import '../checkbox/checkbox.js';
|
|
46
47
|
import '@jetbrains/icons/checkmark-12px';
|
47
48
|
import '@jetbrains/icons/remove-12px';
|
48
49
|
import '../icon/icon.js';
|
49
|
-
import 'util-deprecate';
|
50
50
|
import '../icon/icon__constants.js';
|
51
51
|
import '../_helpers/icon__svg.js';
|
52
52
|
import 'core-js/modules/es.string.replace.js';
|
@@ -21,6 +21,7 @@ import '../global/composeRefs.js';
|
|
21
21
|
import 'core-js/modules/es.object.to-string.js';
|
22
22
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
23
23
|
import 'memoize-one';
|
24
|
+
import 'util-deprecate';
|
24
25
|
import 'core-js/modules/es.regexp.to-string.js';
|
25
26
|
import '../shortcuts/core.js';
|
26
27
|
import 'core-js/modules/es.array.find-index.js';
|
@@ -50,7 +51,6 @@ import '../checkbox/checkbox.js';
|
|
50
51
|
import '@jetbrains/icons/checkmark-12px';
|
51
52
|
import '@jetbrains/icons/remove-12px';
|
52
53
|
import '../icon/icon.js';
|
53
|
-
import 'util-deprecate';
|
54
54
|
import '../icon/icon__constants.js';
|
55
55
|
import '../_helpers/icon__svg.js';
|
56
56
|
import 'core-js/modules/es.string.replace.js';
|