@douyinfe/semi-ui 2.7.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_utils/index.ts +29 -1
- package/datePicker/_story/v2/FixDefaultPickerValue.jsx +31 -0
- package/datePicker/_story/v2/InsetInput.jsx +1 -1
- package/datePicker/_story/v2/index.js +1 -0
- package/datePicker/monthsGrid.tsx +3 -13
- package/dist/css/semi.css +25 -16
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +654 -309
- package/dist/umd/semi-ui.js.map +1 -1
- package/dist/umd/semi-ui.min.js +1 -1
- package/dist/umd/semi-ui.min.js.map +1 -1
- package/inputNumber/_story/inputNumber.stories.js +4 -0
- package/lib/cjs/_utils/index.d.ts +3 -1
- package/lib/cjs/_utils/index.js +25 -1
- package/lib/cjs/datePicker/monthsGrid.js +11 -19
- package/lib/cjs/notification/useNotification/index.js +1 -1
- package/lib/cjs/popover/index.d.ts +18 -3
- package/lib/cjs/popover/index.js +53 -23
- package/lib/cjs/tooltip/index.d.ts +22 -4
- package/lib/cjs/tooltip/index.js +64 -26
- package/lib/es/_utils/index.d.ts +3 -1
- package/lib/es/_utils/index.js +18 -0
- package/lib/es/datePicker/monthsGrid.js +11 -19
- package/lib/es/notification/useNotification/index.js +2 -1
- package/lib/es/popover/index.d.ts +18 -3
- package/lib/es/popover/index.js +52 -23
- package/lib/es/tooltip/index.d.ts +22 -4
- package/lib/es/tooltip/index.js +64 -26
- package/notification/useNotification/index.tsx +1 -1
- package/package.json +10 -10
- package/popover/_story/popover.stories.js +75 -1
- package/popover/index.tsx +24 -8
- package/select/__test__/select.test.js +16 -0
- package/tooltip/index.tsx +71 -21
|
@@ -67,4 +67,6 @@ export interface HighLightTextHTMLChunk {
|
|
|
67
67
|
* @returns boolean
|
|
68
68
|
*/
|
|
69
69
|
export declare const isSemiIcon: (icon: any) => boolean;
|
|
70
|
-
export declare function getActiveElement(): HTMLElement;
|
|
70
|
+
export declare function getActiveElement(): HTMLElement | null;
|
|
71
|
+
export declare function isNodeContainsFocus(node: HTMLElement): boolean;
|
|
72
|
+
export declare function getFocusableElements(node: HTMLElement): HTMLElement[];
|
package/lib/cjs/_utils/index.js
CHANGED
|
@@ -10,7 +10,10 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
10
10
|
|
|
11
11
|
exports.cloneDeep = cloneDeep;
|
|
12
12
|
exports.getActiveElement = getActiveElement;
|
|
13
|
-
exports.
|
|
13
|
+
exports.getFocusableElements = getFocusableElements;
|
|
14
|
+
exports.getHighLightTextHTML = void 0;
|
|
15
|
+
exports.isNodeContainsFocus = isNodeContainsFocus;
|
|
16
|
+
exports.registerMediaQuery = exports.isSemiIcon = void 0;
|
|
14
17
|
exports.stopPropagation = stopPropagation;
|
|
15
18
|
|
|
16
19
|
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/is-array"));
|
|
@@ -23,6 +26,8 @@ var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-sta
|
|
|
23
26
|
|
|
24
27
|
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
|
|
25
28
|
|
|
29
|
+
var _from = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/from"));
|
|
30
|
+
|
|
26
31
|
var _get2 = _interopRequireDefault(require("lodash/get"));
|
|
27
32
|
|
|
28
33
|
var _set2 = _interopRequireDefault(require("lodash/set"));
|
|
@@ -35,6 +40,8 @@ var _warning = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs
|
|
|
35
40
|
|
|
36
41
|
var _getHighlight = require("@douyinfe/semi-foundation/lib/cjs/utils/getHighlight");
|
|
37
42
|
|
|
43
|
+
var _dom = require("@douyinfe/semi-foundation/lib/cjs/utils/dom");
|
|
44
|
+
|
|
38
45
|
/* eslint-disable max-len */
|
|
39
46
|
|
|
40
47
|
/* argus-disable unPkgSensitiveInfo */
|
|
@@ -202,4 +209,21 @@ exports.isSemiIcon = isSemiIcon;
|
|
|
202
209
|
|
|
203
210
|
function getActiveElement() {
|
|
204
211
|
return document ? document.activeElement : null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function isNodeContainsFocus(node) {
|
|
215
|
+
const activeElement = getActiveElement();
|
|
216
|
+
return activeElement === node || node.contains(activeElement);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function getFocusableElements(node) {
|
|
220
|
+
if (!(0, _dom.isHTMLElement)(node)) {
|
|
221
|
+
return [];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const focusableSelectorsList = ["input:not([disabled]):not([tabindex='-1'])", "textarea:not([disabled]):not([tabindex='-1'])", "button:not([disabled]):not([tabindex='-1'])", "a[href]:not([tabindex='-1'])", "select:not([disabled]):not([tabindex='-1'])", "area[href]:not([tabindex='-1'])", "iframe:not([tabindex='-1'])", "object:not([tabindex='-1'])", "*[tabindex]:not([tabindex='-1'])", "*[contenteditable]:not([tabindex='-1'])"];
|
|
225
|
+
const focusableSelectorsStr = focusableSelectorsList.join(','); // we are not filtered elements which are invisible
|
|
226
|
+
|
|
227
|
+
const focusableElements = (0, _from.default)(node.querySelectorAll(focusableSelectorsStr));
|
|
228
|
+
return focusableElements;
|
|
205
229
|
}
|
|
@@ -12,8 +12,6 @@ exports.default = void 0;
|
|
|
12
12
|
|
|
13
13
|
var _forEach = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/for-each"));
|
|
14
14
|
|
|
15
|
-
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/is-array"));
|
|
16
|
-
|
|
17
15
|
var _set = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/set"));
|
|
18
16
|
|
|
19
17
|
var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/assign"));
|
|
@@ -54,6 +52,8 @@ var _semiIcons = require("@douyinfe/semi-icons");
|
|
|
54
52
|
|
|
55
53
|
var _getDefaultFormatToken = require("@douyinfe/semi-foundation/lib/cjs/datePicker/_utils/getDefaultFormatToken");
|
|
56
54
|
|
|
55
|
+
var _getDefaultPickerDate = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/datePicker/_utils/getDefaultPickerDate"));
|
|
56
|
+
|
|
57
57
|
/* eslint-disable jsx-a11y/interactive-supports-focus,jsx-a11y/click-events-have-key-events */
|
|
58
58
|
|
|
59
59
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
@@ -165,23 +165,15 @@ class MonthsGrid extends _baseComponent.default {
|
|
|
165
165
|
return this.foundation.getYAMOpenType();
|
|
166
166
|
};
|
|
167
167
|
|
|
168
|
-
let nowDate = (0, _isArray.default)(props.defaultPickerValue) ? props.defaultPickerValue[0] : props.defaultPickerValue;
|
|
169
168
|
const validFormat = props.format || (0, _getDefaultFormatToken.getDefaultFormatTokenByType)(props.type);
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (!nextDate) {
|
|
180
|
-
nextDate = (0, _dateFns.addMonths)(nowDate, 1);
|
|
181
|
-
} else {
|
|
182
|
-
nextDate = (0, _parser.compatiableParse)(nextDate, validFormat, undefined, props.dateFnsLocale);
|
|
183
|
-
}
|
|
184
|
-
|
|
169
|
+
const {
|
|
170
|
+
nowDate,
|
|
171
|
+
nextDate
|
|
172
|
+
} = (0, _getDefaultPickerDate.default)({
|
|
173
|
+
defaultPickerValue: props.defaultPickerValue,
|
|
174
|
+
format: validFormat,
|
|
175
|
+
dateFnsLocale: props.dateFnsLocale
|
|
176
|
+
});
|
|
185
177
|
const dateState = {
|
|
186
178
|
// Direct use of full date string storage, mainly considering the month rendering comparison to save a conversion
|
|
187
179
|
// The selected value for single or multiple selection, full date string, eg. {'2019-10-01', '2019-10-02'}
|
|
@@ -676,7 +668,7 @@ class MonthsGrid extends _baseComponent.default {
|
|
|
676
668
|
className: monthGridCls,
|
|
677
669
|
"x-type": type,
|
|
678
670
|
"x-panel-yearandmonth-open-type": yearOpenType,
|
|
679
|
-
"x-
|
|
671
|
+
"x-insetinput": insetInput ? "true" : "false",
|
|
680
672
|
ref: current => this.cacheRefCurrent('monthGrid', current)
|
|
681
673
|
}, content);
|
|
682
674
|
}
|
|
@@ -111,9 +111,9 @@ function usePatchElement() {
|
|
|
111
111
|
function useNotification() {
|
|
112
112
|
const [elements, patchElement] = usePatchElement();
|
|
113
113
|
const noticeRef = new _map2.default();
|
|
114
|
-
const id = (0, _uuid.default)('semi_notice_');
|
|
115
114
|
|
|
116
115
|
const addNotice = config => {
|
|
116
|
+
const id = (0, _uuid.default)('semi_notice_');
|
|
117
117
|
const mergeConfig = (0, _assign.default)((0, _assign.default)({}, config), {
|
|
118
118
|
id
|
|
119
119
|
}); // eslint-disable-next-line prefer-const
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { ArrowBounding, Position, Trigger } from '../tooltip/index';
|
|
3
|
+
import { ArrowBounding, Position, TooltipProps, Trigger, RenderContentProps } from '../tooltip/index';
|
|
4
4
|
import '@douyinfe/semi-foundation/lib/cjs/popover/popover.css';
|
|
5
5
|
import { BaseProps } from '../_base/baseComponent';
|
|
6
6
|
import { Motion } from '../_base/base';
|
|
@@ -12,7 +12,7 @@ declare interface ArrowStyle {
|
|
|
12
12
|
}
|
|
13
13
|
export interface PopoverProps extends BaseProps {
|
|
14
14
|
children?: React.ReactNode;
|
|
15
|
-
content?:
|
|
15
|
+
content?: TooltipProps['content'];
|
|
16
16
|
visible?: boolean;
|
|
17
17
|
autoAdjustOverflow?: boolean;
|
|
18
18
|
motion?: Motion;
|
|
@@ -33,6 +33,10 @@ export interface PopoverProps extends BaseProps {
|
|
|
33
33
|
rePosKey?: string | number;
|
|
34
34
|
getPopupContainer?: () => HTMLElement;
|
|
35
35
|
zIndex?: number;
|
|
36
|
+
closeOnEsc?: TooltipProps['closeOnEsc'];
|
|
37
|
+
guardFocus?: TooltipProps['guardFocus'];
|
|
38
|
+
returnFocusOnClose?: TooltipProps['returnFocusOnClose'];
|
|
39
|
+
onEscKeyDown?: TooltipProps['onEscKeyDown'];
|
|
36
40
|
}
|
|
37
41
|
export interface PopoverState {
|
|
38
42
|
popConfirmVisible: boolean;
|
|
@@ -64,6 +68,7 @@ declare class Popover extends React.PureComponent<PopoverProps, PopoverState> {
|
|
|
64
68
|
arrowPointAtCenter: PropTypes.Requireable<boolean>;
|
|
65
69
|
arrowBounding: PropTypes.Requireable<object>;
|
|
66
70
|
prefixCls: PropTypes.Requireable<string>;
|
|
71
|
+
guardFocus: PropTypes.Requireable<boolean>;
|
|
67
72
|
};
|
|
68
73
|
static defaultProps: {
|
|
69
74
|
arrowBounding: {
|
|
@@ -82,8 +87,18 @@ declare class Popover extends React.PureComponent<PopoverProps, PopoverState> {
|
|
|
82
87
|
position: string;
|
|
83
88
|
prefixCls: string;
|
|
84
89
|
onClickOutSide: (...args: any[]) => void;
|
|
90
|
+
onEscKeyDown: (...args: any[]) => void;
|
|
91
|
+
closeOnEsc: boolean;
|
|
92
|
+
returnFocusOnClose: boolean;
|
|
93
|
+
guardFocus: boolean;
|
|
85
94
|
};
|
|
86
|
-
renderPopCard(
|
|
95
|
+
renderPopCard: ({ initialFocusRef }: {
|
|
96
|
+
initialFocusRef: RenderContentProps['initialFocusRef'];
|
|
97
|
+
}) => JSX.Element;
|
|
98
|
+
renderContentNode: (props: {
|
|
99
|
+
content: TooltipProps['content'];
|
|
100
|
+
initialFocusRef: RenderContentProps['initialFocusRef'];
|
|
101
|
+
}) => React.ReactNode;
|
|
87
102
|
render(): JSX.Element;
|
|
88
103
|
}
|
|
89
104
|
export default Popover;
|
package/lib/cjs/popover/index.js
CHANGED
|
@@ -18,6 +18,8 @@ var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-sta
|
|
|
18
18
|
|
|
19
19
|
var _noop2 = _interopRequireDefault(require("lodash/noop"));
|
|
20
20
|
|
|
21
|
+
var _isFunction2 = _interopRequireDefault(require("lodash/isFunction"));
|
|
22
|
+
|
|
21
23
|
var _react = _interopRequireDefault(require("react"));
|
|
22
24
|
|
|
23
25
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
@@ -49,23 +51,45 @@ const positionSet = _constants.strings.POSITION_SET;
|
|
|
49
51
|
const triggerSet = _constants.strings.TRIGGER_SET;
|
|
50
52
|
|
|
51
53
|
class Popover extends _react.default.PureComponent {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
constructor() {
|
|
55
|
+
super(...arguments);
|
|
56
|
+
|
|
57
|
+
this.renderPopCard = _ref => {
|
|
58
|
+
let {
|
|
59
|
+
initialFocusRef
|
|
60
|
+
} = _ref;
|
|
61
|
+
const {
|
|
62
|
+
content,
|
|
63
|
+
contentClassName,
|
|
64
|
+
prefixCls
|
|
65
|
+
} = this.props;
|
|
66
|
+
const {
|
|
67
|
+
direction
|
|
68
|
+
} = this.context;
|
|
69
|
+
const popCardCls = (0, _classnames.default)(prefixCls, contentClassName, {
|
|
70
|
+
["".concat(prefixCls, "-rtl")]: direction === 'rtl'
|
|
71
|
+
});
|
|
72
|
+
const contentNode = this.renderContentNode({
|
|
73
|
+
initialFocusRef,
|
|
74
|
+
content
|
|
75
|
+
});
|
|
76
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
77
|
+
className: popCardCls
|
|
78
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
79
|
+
className: "".concat(prefixCls, "-content")
|
|
80
|
+
}, contentNode));
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
this.renderContentNode = props => {
|
|
84
|
+
const {
|
|
85
|
+
initialFocusRef,
|
|
86
|
+
content
|
|
87
|
+
} = props;
|
|
88
|
+
const contentProps = {
|
|
89
|
+
initialFocusRef
|
|
90
|
+
};
|
|
91
|
+
return !(0, _isFunction2.default)(content) ? content : content(contentProps);
|
|
92
|
+
};
|
|
69
93
|
}
|
|
70
94
|
|
|
71
95
|
render() {
|
|
@@ -85,7 +109,6 @@ class Popover extends _react.default.PureComponent {
|
|
|
85
109
|
let {
|
|
86
110
|
spacing
|
|
87
111
|
} = this.props;
|
|
88
|
-
const popContent = this.renderPopCard();
|
|
89
112
|
const arrowProps = {
|
|
90
113
|
position,
|
|
91
114
|
className: '',
|
|
@@ -99,11 +122,13 @@ class Popover extends _react.default.PureComponent {
|
|
|
99
122
|
}
|
|
100
123
|
|
|
101
124
|
const role = trigger === 'click' || trigger === 'custom' ? 'dialog' : 'tooltip';
|
|
102
|
-
return /*#__PURE__*/_react.default.createElement(_index.default, (0, _assign.default)({
|
|
125
|
+
return /*#__PURE__*/_react.default.createElement(_index.default, (0, _assign.default)({
|
|
126
|
+
guardFocus: true
|
|
127
|
+
}, attr, {
|
|
103
128
|
trigger: trigger,
|
|
104
129
|
position: position,
|
|
105
130
|
style: style,
|
|
106
|
-
content:
|
|
131
|
+
content: this.renderPopCard,
|
|
107
132
|
prefixCls: prefixCls,
|
|
108
133
|
spacing: spacing,
|
|
109
134
|
showArrow: arrow,
|
|
@@ -117,7 +142,7 @@ class Popover extends _react.default.PureComponent {
|
|
|
117
142
|
Popover.contextType = _context.default;
|
|
118
143
|
Popover.propTypes = {
|
|
119
144
|
children: _propTypes.default.node,
|
|
120
|
-
content: _propTypes.default.node,
|
|
145
|
+
content: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
|
|
121
146
|
visible: _propTypes.default.bool,
|
|
122
147
|
autoAdjustOverflow: _propTypes.default.bool,
|
|
123
148
|
motion: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.object, _propTypes.default.func]),
|
|
@@ -140,7 +165,8 @@ Popover.propTypes = {
|
|
|
140
165
|
}),
|
|
141
166
|
arrowPointAtCenter: _propTypes.default.bool,
|
|
142
167
|
arrowBounding: _propTypes.default.object,
|
|
143
|
-
prefixCls: _propTypes.default.string
|
|
168
|
+
prefixCls: _propTypes.default.string,
|
|
169
|
+
guardFocus: _propTypes.default.bool
|
|
144
170
|
};
|
|
145
171
|
Popover.defaultProps = {
|
|
146
172
|
arrowBounding: _constants.numbers.ARROW_BOUNDING,
|
|
@@ -153,7 +179,11 @@ Popover.defaultProps = {
|
|
|
153
179
|
okText: 'Yes',
|
|
154
180
|
position: 'bottom',
|
|
155
181
|
prefixCls: _constants.cssClasses.PREFIX,
|
|
156
|
-
onClickOutSide: _noop2.default
|
|
182
|
+
onClickOutSide: _noop2.default,
|
|
183
|
+
onEscKeyDown: _noop2.default,
|
|
184
|
+
closeOnEsc: true,
|
|
185
|
+
returnFocusOnClose: true,
|
|
186
|
+
guardFocus: true
|
|
157
187
|
};
|
|
158
188
|
var _default = Popover;
|
|
159
189
|
exports.default = _default;
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import Event from '@douyinfe/semi-foundation/lib/cjs/utils/Event';
|
|
4
4
|
import { ArrayElement } from '@douyinfe/semi-foundation/lib/cjs/utils/type';
|
|
5
|
-
import { TooltipAdapter, Position } from '@douyinfe/semi-foundation/lib/cjs/tooltip/foundation';
|
|
5
|
+
import TooltipFoundation, { TooltipAdapter, Position } from '@douyinfe/semi-foundation/lib/cjs/tooltip/foundation';
|
|
6
6
|
import { strings } from '@douyinfe/semi-foundation/lib/cjs/tooltip/constants';
|
|
7
7
|
import '@douyinfe/semi-foundation/lib/cjs/tooltip/tooltip.css';
|
|
8
8
|
import BaseComponent, { BaseProps } from '../_base/baseComponent';
|
|
@@ -15,6 +15,10 @@ export interface ArrowBounding {
|
|
|
15
15
|
width?: number;
|
|
16
16
|
height?: number;
|
|
17
17
|
}
|
|
18
|
+
export interface RenderContentProps {
|
|
19
|
+
initialFocusRef?: React.RefObject<HTMLElement>;
|
|
20
|
+
}
|
|
21
|
+
export declare type RenderContent = (props: RenderContentProps) => React.ReactNode;
|
|
18
22
|
export interface TooltipProps extends BaseProps {
|
|
19
23
|
children?: React.ReactNode;
|
|
20
24
|
motion?: Motion;
|
|
@@ -28,7 +32,7 @@ export interface TooltipProps extends BaseProps {
|
|
|
28
32
|
clickToHide?: boolean;
|
|
29
33
|
visible?: boolean;
|
|
30
34
|
style?: React.CSSProperties;
|
|
31
|
-
content?: React.ReactNode;
|
|
35
|
+
content?: React.ReactNode | RenderContent;
|
|
32
36
|
prefixCls?: string;
|
|
33
37
|
onVisibleChange?: (visible: boolean) => void;
|
|
34
38
|
onClickOutSide?: (e: React.MouseEvent) => void;
|
|
@@ -44,6 +48,10 @@ export interface TooltipProps extends BaseProps {
|
|
|
44
48
|
stopPropagation?: boolean;
|
|
45
49
|
clickTriggerToHide?: boolean;
|
|
46
50
|
wrapperClassName?: string;
|
|
51
|
+
closeOnEsc?: boolean;
|
|
52
|
+
guardFocus?: boolean;
|
|
53
|
+
returnFocusOnClose?: boolean;
|
|
54
|
+
onEscKeyDown?: (e: React.KeyboardEvent) => void;
|
|
47
55
|
}
|
|
48
56
|
interface TooltipState {
|
|
49
57
|
visible: boolean;
|
|
@@ -97,6 +105,8 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
|
|
|
97
105
|
stopPropagation: PropTypes.Requireable<boolean>;
|
|
98
106
|
role: PropTypes.Requireable<string>;
|
|
99
107
|
wrapWhenSpecial: PropTypes.Requireable<boolean>;
|
|
108
|
+
guardFocus: PropTypes.Requireable<boolean>;
|
|
109
|
+
returnFocusOnClose: PropTypes.Requireable<boolean>;
|
|
100
110
|
};
|
|
101
111
|
static defaultProps: {
|
|
102
112
|
arrowBounding: {
|
|
@@ -121,10 +131,15 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
|
|
|
121
131
|
showArrow: boolean;
|
|
122
132
|
wrapWhenSpecial: boolean;
|
|
123
133
|
zIndex: 1060;
|
|
134
|
+
closeOnEsc: boolean;
|
|
135
|
+
guardFocus: boolean;
|
|
136
|
+
returnFocusOnClose: boolean;
|
|
137
|
+
onEscKeyDown: (...args: any[]) => void;
|
|
124
138
|
};
|
|
125
139
|
eventManager: Event;
|
|
126
140
|
triggerEl: React.RefObject<unknown>;
|
|
127
|
-
containerEl: React.RefObject<
|
|
141
|
+
containerEl: React.RefObject<HTMLDivElement>;
|
|
142
|
+
initialFocusRef: React.RefObject<HTMLElement>;
|
|
128
143
|
clickOutsideHandler: any;
|
|
129
144
|
resizeHandler: any;
|
|
130
145
|
isWrapped: boolean;
|
|
@@ -132,6 +147,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
|
|
|
132
147
|
scrollHandler: any;
|
|
133
148
|
getPopupContainer: () => HTMLElement;
|
|
134
149
|
containerPosition: string;
|
|
150
|
+
foundation: TooltipFoundation;
|
|
135
151
|
constructor(props: TooltipProps);
|
|
136
152
|
setContainerEl: (node: HTMLDivElement) => {
|
|
137
153
|
current: HTMLDivElement;
|
|
@@ -142,10 +158,12 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
|
|
|
142
158
|
isSpecial: (elem: React.ReactNode | HTMLElement | any) => boolean | "disabled" | "loading";
|
|
143
159
|
didLeave: () => void;
|
|
144
160
|
/** for transition - end */
|
|
145
|
-
rePosition():
|
|
161
|
+
rePosition(): Record<string, string | number>;
|
|
146
162
|
componentDidUpdate(prevProps: TooltipProps, prevState: TooltipState): void;
|
|
147
163
|
renderIcon: () => any;
|
|
148
164
|
handlePortalInnerClick: (e: React.MouseEvent) => void;
|
|
165
|
+
handlePortalInnerKeyDown: (e: React.KeyboardEvent) => void;
|
|
166
|
+
renderContentNode: (content: TooltipProps['content']) => React.ReactNode;
|
|
149
167
|
renderPortal: () => JSX.Element;
|
|
150
168
|
wrapSpan: (elem: React.ReactNode | React.ReactElement) => JSX.Element;
|
|
151
169
|
mergeEvents: (rawEvents: Record<string, any>, events: Record<string, any>) => {};
|
package/lib/cjs/tooltip/index.js
CHANGED
|
@@ -24,6 +24,8 @@ var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-sta
|
|
|
24
24
|
|
|
25
25
|
var _setTimeout2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/set-timeout"));
|
|
26
26
|
|
|
27
|
+
var _isFunction2 = _interopRequireDefault(require("lodash/isFunction"));
|
|
28
|
+
|
|
27
29
|
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
|
|
28
30
|
|
|
29
31
|
var _each2 = _interopRequireDefault(require("lodash/each"));
|
|
@@ -185,6 +187,17 @@ class Tooltip extends _baseComponent.default {
|
|
|
185
187
|
}
|
|
186
188
|
};
|
|
187
189
|
|
|
190
|
+
this.handlePortalInnerKeyDown = e => {
|
|
191
|
+
this.foundation.handleContainerKeydown(e);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
this.renderContentNode = content => {
|
|
195
|
+
const contentProps = {
|
|
196
|
+
initialFocusRef: this.initialFocusRef
|
|
197
|
+
};
|
|
198
|
+
return !(0, _isFunction2.default)(content) ? content : content(contentProps);
|
|
199
|
+
};
|
|
200
|
+
|
|
188
201
|
this.renderPortal = () => {
|
|
189
202
|
const {
|
|
190
203
|
containerStyle = {},
|
|
@@ -204,6 +217,7 @@ class Tooltip extends _baseComponent.default {
|
|
|
204
217
|
role,
|
|
205
218
|
zIndex
|
|
206
219
|
} = this.props;
|
|
220
|
+
const contentNode = this.renderContentNode(content);
|
|
207
221
|
const {
|
|
208
222
|
className: propClassName
|
|
209
223
|
} = this.props;
|
|
@@ -238,7 +252,7 @@ class Tooltip extends _baseComponent.default {
|
|
|
238
252
|
role: role,
|
|
239
253
|
"x-placement": placement,
|
|
240
254
|
id: id
|
|
241
|
-
}),
|
|
255
|
+
}), contentNode, icon);
|
|
242
256
|
} : null) : /*#__PURE__*/_react.default.createElement("div", (0, _assign.default)({
|
|
243
257
|
className: className
|
|
244
258
|
}, portalEventSet, {
|
|
@@ -246,7 +260,7 @@ class Tooltip extends _baseComponent.default {
|
|
|
246
260
|
style: (0, _assign.default)({
|
|
247
261
|
visibility: motion ? undefined : 'visible'
|
|
248
262
|
}, style)
|
|
249
|
-
}),
|
|
263
|
+
}), contentNode, icon);
|
|
250
264
|
return /*#__PURE__*/_react.default.createElement(_index.default, {
|
|
251
265
|
getPopupContainer: this.props.getPopupContainer,
|
|
252
266
|
style: {
|
|
@@ -256,7 +270,8 @@ class Tooltip extends _baseComponent.default {
|
|
|
256
270
|
className: "".concat(_constants.BASE_CLASS_PREFIX, "-portal-inner"),
|
|
257
271
|
style: portalInnerStyle,
|
|
258
272
|
ref: this.setContainerEl,
|
|
259
|
-
onClick: this.handlePortalInnerClick
|
|
273
|
+
onClick: this.handlePortalInnerClick,
|
|
274
|
+
onKeyDown: this.handlePortalInnerKeyDown
|
|
260
275
|
}, inner));
|
|
261
276
|
};
|
|
262
277
|
|
|
@@ -319,6 +334,7 @@ class Tooltip extends _baseComponent.default {
|
|
|
319
334
|
this.eventManager = new _Event.default();
|
|
320
335
|
this.triggerEl = /*#__PURE__*/_react.default.createRef();
|
|
321
336
|
this.containerEl = /*#__PURE__*/_react.default.createRef();
|
|
337
|
+
this.initialFocusRef = /*#__PURE__*/_react.default.createRef();
|
|
322
338
|
this.clickOutsideHandler = null;
|
|
323
339
|
this.resizeHandler = null;
|
|
324
340
|
this.isWrapped = false; // Identifies whether a span element is wrapped
|
|
@@ -370,7 +386,8 @@ class Tooltip extends _baseComponent.default {
|
|
|
370
386
|
mouseOver: 'onMouseOver',
|
|
371
387
|
click: 'onClick',
|
|
372
388
|
focus: 'onFocus',
|
|
373
|
-
blur: 'onBlur'
|
|
389
|
+
blur: 'onBlur',
|
|
390
|
+
keydown: 'onKeyDown'
|
|
374
391
|
}),
|
|
375
392
|
registerTriggerEvent: triggerEventSet => {
|
|
376
393
|
this.setState({
|
|
@@ -388,15 +405,8 @@ class Tooltip extends _baseComponent.default {
|
|
|
388
405
|
// eslint-disable-next-line
|
|
389
406
|
// It may be a React component or an html element
|
|
390
407
|
// There is no guarantee that triggerE l.current can get the real dom, so call findDOMNode to ensure that you can get the real dom
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if (!(0, _reactUtils.isHTMLElement)(this.triggerEl.current)) {
|
|
394
|
-
const realDomNode = _reactDom.default.findDOMNode(this.triggerEl.current);
|
|
395
|
-
|
|
396
|
-
this.triggerEl.current = realDomNode;
|
|
397
|
-
triggerDOM = realDomNode;
|
|
398
|
-
}
|
|
399
|
-
|
|
408
|
+
const triggerDOM = this.adapter.getTriggerNode();
|
|
409
|
+
this.triggerEl.current = triggerDOM;
|
|
400
410
|
return triggerDOM && triggerDOM.getBoundingClientRect();
|
|
401
411
|
},
|
|
402
412
|
// Gets the outer size of the specified container
|
|
@@ -533,12 +543,7 @@ class Tooltip extends _baseComponent.default {
|
|
|
533
543
|
return false;
|
|
534
544
|
}
|
|
535
545
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
if (!(0, _reactUtils.isHTMLElement)(this.triggerEl.current)) {
|
|
539
|
-
triggerDOM = _reactDom.default.findDOMNode(this.triggerEl.current);
|
|
540
|
-
}
|
|
541
|
-
|
|
546
|
+
const triggerDOM = this.adapter.getTriggerNode();
|
|
542
547
|
const isRelativeScroll = e.target.contains(triggerDOM);
|
|
543
548
|
|
|
544
549
|
if (isRelativeScroll) {
|
|
@@ -569,7 +574,33 @@ class Tooltip extends _baseComponent.default {
|
|
|
569
574
|
this.containerPosition = position;
|
|
570
575
|
}
|
|
571
576
|
},
|
|
572
|
-
getContainerPosition: () => this.containerPosition
|
|
577
|
+
getContainerPosition: () => this.containerPosition,
|
|
578
|
+
getContainer: () => this.containerEl && this.containerEl.current,
|
|
579
|
+
getTriggerNode: () => {
|
|
580
|
+
let triggerDOM = this.triggerEl.current;
|
|
581
|
+
|
|
582
|
+
if (!(0, _reactUtils.isHTMLElement)(this.triggerEl.current)) {
|
|
583
|
+
triggerDOM = _reactDom.default.findDOMNode(this.triggerEl.current);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return triggerDOM;
|
|
587
|
+
},
|
|
588
|
+
getFocusableElements: node => {
|
|
589
|
+
return (0, _utils.getFocusableElements)(node);
|
|
590
|
+
},
|
|
591
|
+
getActiveElement: () => {
|
|
592
|
+
return (0, _utils.getActiveElement)();
|
|
593
|
+
},
|
|
594
|
+
setInitialFocus: () => {
|
|
595
|
+
const focusRefNode = (0, _get2.default)(this, 'initialFocusRef.current');
|
|
596
|
+
|
|
597
|
+
if (focusRefNode && 'focus' in focusRefNode) {
|
|
598
|
+
focusRefNode.focus();
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
notifyEscKeydown: event => {
|
|
602
|
+
this.props.onEscKeyDown(event);
|
|
603
|
+
}
|
|
573
604
|
});
|
|
574
605
|
}
|
|
575
606
|
|
|
@@ -611,7 +642,8 @@ class Tooltip extends _baseComponent.default {
|
|
|
611
642
|
} = this.state;
|
|
612
643
|
const {
|
|
613
644
|
wrapWhenSpecial,
|
|
614
|
-
role
|
|
645
|
+
role,
|
|
646
|
+
trigger
|
|
615
647
|
} = this.props;
|
|
616
648
|
let {
|
|
617
649
|
children
|
|
@@ -669,7 +701,8 @@ class Tooltip extends _baseComponent.default {
|
|
|
669
701
|
} else if (ref && typeof ref === 'object') {
|
|
670
702
|
ref.current = node;
|
|
671
703
|
}
|
|
672
|
-
}
|
|
704
|
+
},
|
|
705
|
+
tabIndex: trigger === 'hover' ? 0 : undefined
|
|
673
706
|
})); // If you do not add a layer of div, in order to bind the events and className in the tooltip, you need to cloneElement children, but this time it may overwrite the children's original ref reference
|
|
674
707
|
// So if the user adds ref to the content, you need to use callback ref: https://github.com/facebook/react/issues/8873
|
|
675
708
|
|
|
@@ -697,7 +730,7 @@ Tooltip.propTypes = {
|
|
|
697
730
|
clickTriggerToHide: _propTypes.default.bool,
|
|
698
731
|
visible: _propTypes.default.bool,
|
|
699
732
|
style: _propTypes.default.object,
|
|
700
|
-
content: _propTypes.default.node,
|
|
733
|
+
content: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
|
|
701
734
|
prefixCls: _propTypes.default.string,
|
|
702
735
|
onVisibleChange: _propTypes.default.func,
|
|
703
736
|
onClickOutSide: _propTypes.default.func,
|
|
@@ -711,8 +744,9 @@ Tooltip.propTypes = {
|
|
|
711
744
|
stopPropagation: _propTypes.default.bool,
|
|
712
745
|
// private
|
|
713
746
|
role: _propTypes.default.string,
|
|
714
|
-
wrapWhenSpecial: _propTypes.default.bool
|
|
715
|
-
|
|
747
|
+
wrapWhenSpecial: _propTypes.default.bool,
|
|
748
|
+
guardFocus: _propTypes.default.bool,
|
|
749
|
+
returnFocusOnClose: _propTypes.default.bool
|
|
716
750
|
};
|
|
717
751
|
Tooltip.defaultProps = {
|
|
718
752
|
arrowBounding: _constants2.numbers.ARROW_BOUNDING,
|
|
@@ -731,5 +765,9 @@ Tooltip.defaultProps = {
|
|
|
731
765
|
spacing: _constants2.numbers.SPACING,
|
|
732
766
|
showArrow: true,
|
|
733
767
|
wrapWhenSpecial: true,
|
|
734
|
-
zIndex: _constants2.numbers.DEFAULT_Z_INDEX
|
|
768
|
+
zIndex: _constants2.numbers.DEFAULT_Z_INDEX,
|
|
769
|
+
closeOnEsc: false,
|
|
770
|
+
guardFocus: false,
|
|
771
|
+
returnFocusOnClose: false,
|
|
772
|
+
onEscKeyDown: _noop2.default
|
|
735
773
|
};
|
package/lib/es/_utils/index.d.ts
CHANGED
|
@@ -67,4 +67,6 @@ export interface HighLightTextHTMLChunk {
|
|
|
67
67
|
* @returns boolean
|
|
68
68
|
*/
|
|
69
69
|
export declare const isSemiIcon: (icon: any) => boolean;
|
|
70
|
-
export declare function getActiveElement(): HTMLElement;
|
|
70
|
+
export declare function getActiveElement(): HTMLElement | null;
|
|
71
|
+
export declare function isNodeContainsFocus(node: HTMLElement): boolean;
|
|
72
|
+
export declare function getFocusableElements(node: HTMLElement): HTMLElement[];
|
package/lib/es/_utils/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
|
|
|
6
6
|
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
|
|
7
7
|
import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign";
|
|
8
8
|
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
|
|
9
|
+
import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
|
|
9
10
|
|
|
10
11
|
/* eslint-disable max-len */
|
|
11
12
|
|
|
@@ -13,6 +14,7 @@ import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance
|
|
|
13
14
|
import React from 'react';
|
|
14
15
|
import warning from '@douyinfe/semi-foundation/lib/es/utils/warning';
|
|
15
16
|
import { findAll } from '@douyinfe/semi-foundation/lib/es/utils/getHighlight';
|
|
17
|
+
import { isHTMLElement } from '@douyinfe/semi-foundation/lib/es/utils/dom';
|
|
16
18
|
/**
|
|
17
19
|
* stop propagation
|
|
18
20
|
*
|
|
@@ -168,4 +170,20 @@ export const registerMediaQuery = (media, _ref2) => {
|
|
|
168
170
|
export const isSemiIcon = icon => /*#__PURE__*/React.isValidElement(icon) && _get(icon.type, 'elementType') === 'Icon';
|
|
169
171
|
export function getActiveElement() {
|
|
170
172
|
return document ? document.activeElement : null;
|
|
173
|
+
}
|
|
174
|
+
export function isNodeContainsFocus(node) {
|
|
175
|
+
const activeElement = getActiveElement();
|
|
176
|
+
return activeElement === node || node.contains(activeElement);
|
|
177
|
+
}
|
|
178
|
+
export function getFocusableElements(node) {
|
|
179
|
+
if (!isHTMLElement(node)) {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const focusableSelectorsList = ["input:not([disabled]):not([tabindex='-1'])", "textarea:not([disabled]):not([tabindex='-1'])", "button:not([disabled]):not([tabindex='-1'])", "a[href]:not([tabindex='-1'])", "select:not([disabled]):not([tabindex='-1'])", "area[href]:not([tabindex='-1'])", "iframe:not([tabindex='-1'])", "object:not([tabindex='-1'])", "*[tabindex]:not([tabindex='-1'])", "*[contenteditable]:not([tabindex='-1'])"];
|
|
184
|
+
const focusableSelectorsStr = focusableSelectorsList.join(','); // we are not filtered elements which are invisible
|
|
185
|
+
|
|
186
|
+
const focusableElements = _Array$from(node.querySelectorAll(focusableSelectorsStr));
|
|
187
|
+
|
|
188
|
+
return focusableElements;
|
|
171
189
|
}
|