@douyinfe/semi-ui 2.7.1 → 2.8.0-beta.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.
@@ -63,6 +63,10 @@ export const _InputNumber = () => {
63
63
  />
64
64
  <br />
65
65
 
66
+ <label>小数(没有初始化值)</label>
67
+ <InputNumber precision={2} onChange={log} />
68
+ <br />
69
+
66
70
  <label>小数</label>
67
71
  <InputNumber defaultValue={10.08} precision={2} onChange={log} />
68
72
  <br />
@@ -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[];
@@ -10,7 +10,10 @@ _Object$defineProperty(exports, "__esModule", {
10
10
 
11
11
  exports.cloneDeep = cloneDeep;
12
12
  exports.getActiveElement = getActiveElement;
13
- exports.registerMediaQuery = exports.isSemiIcon = exports.getHighLightTextHTML = void 0;
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
- if (!nowDate) {
172
- nowDate = new Date();
173
- } else {
174
- nowDate = (0, _parser.compatiableParse)(nowDate, validFormat, undefined, props.dateFnsLocale);
175
- }
176
-
177
- let nextDate = (0, _isArray.default)(props.defaultPickerValue) ? props.defaultPickerValue[1] : undefined;
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-insetInput": insetInput ? "true" : "false",
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?: React.ReactNode;
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(): JSX.Element;
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;
@@ -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
- renderPopCard() {
53
- const {
54
- content,
55
- contentClassName,
56
- prefixCls
57
- } = this.props;
58
- const {
59
- direction
60
- } = this.context;
61
- const popCardCls = (0, _classnames.default)(prefixCls, contentClassName, {
62
- ["".concat(prefixCls, "-rtl")]: direction === 'rtl'
63
- });
64
- return /*#__PURE__*/_react.default.createElement("div", {
65
- className: popCardCls
66
- }, /*#__PURE__*/_react.default.createElement("div", {
67
- className: "".concat(prefixCls, "-content")
68
- }, content));
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)({}, attr, {
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: popContent,
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<unknown>;
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(): any;
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>) => {};
@@ -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
- }), content, icon);
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
- }), content, icon);
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
- let triggerDOM = this.triggerEl.current;
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
- let triggerDOM = this.triggerEl.current;
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 // when trigger has special status such as "disabled" or "loading", wrap span
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
  };
@@ -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[];
@@ -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
  }