@douyinfe/semi-ui 2.7.0-beta.0 → 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.
Files changed (70) hide show
  1. package/_base/_story/index.stories.js +2 -6
  2. package/_portal/_story/portal.stories.js +1 -5
  3. package/_utils/hooks/usePrevFocus.ts +1 -0
  4. package/_utils/index.ts +29 -1
  5. package/datePicker/_story/v2/FixDefaultPickerValue.jsx +31 -0
  6. package/datePicker/_story/v2/InsetInput.jsx +1 -1
  7. package/datePicker/_story/v2/index.js +1 -0
  8. package/datePicker/monthsGrid.tsx +3 -13
  9. package/dist/css/semi.css +30 -21
  10. package/dist/css/semi.min.css +1 -1
  11. package/dist/umd/semi-ui.js +627 -287
  12. package/dist/umd/semi-ui.js.map +1 -1
  13. package/dist/umd/semi-ui.min.js +1 -1
  14. package/dist/umd/semi-ui.min.js.map +1 -1
  15. package/form/hooks/useFormApi.tsx +3 -2
  16. package/input/_story/input.stories.js +10 -1
  17. package/inputNumber/_story/inputNumber.stories.js +4 -0
  18. package/lib/cjs/_utils/hooks/usePrevFocus.js +1 -0
  19. package/lib/cjs/_utils/index.d.ts +3 -1
  20. package/lib/cjs/_utils/index.js +25 -1
  21. package/lib/cjs/datePicker/monthsGrid.js +11 -19
  22. package/lib/cjs/form/hooks/useFormApi.d.ts +2 -1
  23. package/lib/cjs/modal/useModal/HookModal.js +2 -0
  24. package/lib/cjs/notification/useNotification/index.js +1 -1
  25. package/lib/cjs/popover/index.d.ts +18 -3
  26. package/lib/cjs/popover/index.js +53 -23
  27. package/lib/cjs/radio/radioGroup.js +6 -0
  28. package/lib/cjs/select/index.js +5 -2
  29. package/lib/cjs/tag/group.d.ts +2 -0
  30. package/lib/cjs/tag/group.js +4 -2
  31. package/lib/cjs/tooltip/index.d.ts +22 -4
  32. package/lib/cjs/tooltip/index.js +65 -27
  33. package/lib/cjs/tree/nodeList.js +1 -0
  34. package/lib/cjs/treeSelect/index.js +4 -0
  35. package/lib/es/_utils/hooks/usePrevFocus.js +2 -0
  36. package/lib/es/_utils/index.d.ts +3 -1
  37. package/lib/es/_utils/index.js +18 -0
  38. package/lib/es/datePicker/monthsGrid.js +11 -19
  39. package/lib/es/form/hooks/useFormApi.d.ts +2 -1
  40. package/lib/es/modal/useModal/HookModal.js +2 -0
  41. package/lib/es/notification/useNotification/index.js +2 -1
  42. package/lib/es/popover/index.d.ts +18 -3
  43. package/lib/es/popover/index.js +52 -23
  44. package/lib/es/radio/radioGroup.js +6 -0
  45. package/lib/es/select/index.js +5 -2
  46. package/lib/es/tag/group.d.ts +2 -0
  47. package/lib/es/tag/group.js +4 -2
  48. package/lib/es/tooltip/index.d.ts +22 -4
  49. package/lib/es/tooltip/index.js +65 -27
  50. package/lib/es/tree/nodeList.js +1 -0
  51. package/lib/es/treeSelect/index.js +4 -0
  52. package/modal/_story/modal.stories.js +93 -1
  53. package/modal/useModal/HookModal.tsx +1 -0
  54. package/notification/_story/useNotification/index.jsx +21 -7
  55. package/notification/useNotification/index.tsx +1 -1
  56. package/package.json +9 -9
  57. package/popover/_story/popover.stories.js +75 -1
  58. package/popover/index.tsx +24 -8
  59. package/radio/__test__/radioGroup.test.jsx +9 -1
  60. package/radio/_story/radio.stories.js +22 -1
  61. package/radio/radioGroup.tsx +9 -0
  62. package/select/_story/select.stories.js +73 -2
  63. package/select/index.tsx +5 -3
  64. package/table/_story/v2/FixedMemoryLeak/index.jsx +33 -0
  65. package/table/_story/v2/index.js +2 -1
  66. package/tag/group.tsx +5 -3
  67. package/toast/_story/toast.stories.js +41 -0
  68. package/tooltip/index.tsx +72 -22
  69. package/tree/nodeList.tsx +1 -0
  70. package/treeSelect/index.tsx +3 -0
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import Event from '@douyinfe/semi-foundation/lib/es/utils/Event';
4
4
  import { ArrayElement } from '@douyinfe/semi-foundation/lib/es/utils/type';
5
- import { TooltipAdapter, Position } from '@douyinfe/semi-foundation/lib/es/tooltip/foundation';
5
+ import TooltipFoundation, { TooltipAdapter, Position } from '@douyinfe/semi-foundation/lib/es/tooltip/foundation';
6
6
  import { strings } from '@douyinfe/semi-foundation/lib/es/tooltip/constants';
7
7
  import '@douyinfe/semi-foundation/lib/es/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>) => {};
@@ -1,3 +1,4 @@
1
+ import _isFunction from "lodash/isFunction";
1
2
  import _isEmpty from "lodash/isEmpty";
2
3
  import _each from "lodash/each";
3
4
  import _omit from "lodash/omit";
@@ -37,7 +38,7 @@ import { getUuidShort } from '@douyinfe/semi-foundation/lib/es/utils/uuid';
37
38
  import '@douyinfe/semi-foundation/lib/es/tooltip/tooltip.css';
38
39
  import BaseComponent from '../_base/baseComponent';
39
40
  import { isHTMLElement } from '../_base/reactUtils';
40
- import { stopPropagation } from '../_utils';
41
+ import { getActiveElement, getFocusableElements, stopPropagation } from '../_utils';
41
42
  import Portal from '../_portal/index';
42
43
  import ConfigContext from '../configProvider/context';
43
44
  import TriangleArrow from './TriangleArrow';
@@ -137,6 +138,17 @@ export default class Tooltip extends BaseComponent {
137
138
  }
138
139
  };
139
140
 
141
+ this.handlePortalInnerKeyDown = e => {
142
+ this.foundation.handleContainerKeydown(e);
143
+ };
144
+
145
+ this.renderContentNode = content => {
146
+ const contentProps = {
147
+ initialFocusRef: this.initialFocusRef
148
+ };
149
+ return !_isFunction(content) ? content : content(contentProps);
150
+ };
151
+
140
152
  this.renderPortal = () => {
141
153
  const {
142
154
  containerStyle = {},
@@ -156,6 +168,7 @@ export default class Tooltip extends BaseComponent {
156
168
  role,
157
169
  zIndex
158
170
  } = this.props;
171
+ const contentNode = this.renderContentNode(content);
159
172
  const {
160
173
  className: propClassName
161
174
  } = this.props;
@@ -193,7 +206,7 @@ export default class Tooltip extends BaseComponent {
193
206
  role: role,
194
207
  "x-placement": placement,
195
208
  id: id
196
- }), content, icon);
209
+ }), contentNode, icon);
197
210
  } : null) : /*#__PURE__*/React.createElement("div", _Object$assign({
198
211
  className: className
199
212
  }, portalEventSet, {
@@ -201,7 +214,7 @@ export default class Tooltip extends BaseComponent {
201
214
  style: _Object$assign({
202
215
  visibility: motion ? undefined : 'visible'
203
216
  }, style)
204
- }), content, icon);
217
+ }), contentNode, icon);
205
218
  return /*#__PURE__*/React.createElement(Portal, {
206
219
  getPopupContainer: this.props.getPopupContainer,
207
220
  style: {
@@ -211,7 +224,8 @@ export default class Tooltip extends BaseComponent {
211
224
  className: "".concat(BASE_CLASS_PREFIX, "-portal-inner"),
212
225
  style: portalInnerStyle,
213
226
  ref: this.setContainerEl,
214
- onClick: this.handlePortalInnerClick
227
+ onClick: this.handlePortalInnerClick,
228
+ onKeyDown: this.handlePortalInnerKeyDown
215
229
  }, inner));
216
230
  };
217
231
 
@@ -279,6 +293,7 @@ export default class Tooltip extends BaseComponent {
279
293
  this.eventManager = new Event();
280
294
  this.triggerEl = /*#__PURE__*/React.createRef();
281
295
  this.containerEl = /*#__PURE__*/React.createRef();
296
+ this.initialFocusRef = /*#__PURE__*/React.createRef();
282
297
  this.clickOutsideHandler = null;
283
298
  this.resizeHandler = null;
284
299
  this.isWrapped = false; // Identifies whether a span element is wrapped
@@ -330,7 +345,8 @@ export default class Tooltip extends BaseComponent {
330
345
  mouseOver: 'onMouseOver',
331
346
  click: 'onClick',
332
347
  focus: 'onFocus',
333
- blur: 'onBlur'
348
+ blur: 'onBlur',
349
+ keydown: 'onKeyDown'
334
350
  }),
335
351
  registerTriggerEvent: triggerEventSet => {
336
352
  this.setState({
@@ -348,14 +364,8 @@ export default class Tooltip extends BaseComponent {
348
364
  // eslint-disable-next-line
349
365
  // It may be a React component or an html element
350
366
  // 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
351
- let triggerDOM = this.triggerEl.current;
352
-
353
- if (!isHTMLElement(this.triggerEl.current)) {
354
- const realDomNode = ReactDOM.findDOMNode(this.triggerEl.current);
355
- this.triggerEl.current = realDomNode;
356
- triggerDOM = realDomNode;
357
- }
358
-
367
+ const triggerDOM = this.adapter.getTriggerNode();
368
+ this.triggerEl.current = triggerDOM;
359
369
  return triggerDOM && triggerDOM.getBoundingClientRect();
360
370
  },
361
371
  // Gets the outer size of the specified container
@@ -422,7 +432,7 @@ export default class Tooltip extends BaseComponent {
422
432
  willUpdateStates.visible = visible;
423
433
  }
424
434
 
425
- this.setState(willUpdateStates, () => {
435
+ this.mounted && this.setState(willUpdateStates, () => {
426
436
  cb();
427
437
  });
428
438
  },
@@ -492,12 +502,7 @@ export default class Tooltip extends BaseComponent {
492
502
  return false;
493
503
  }
494
504
 
495
- let triggerDOM = this.triggerEl.current;
496
-
497
- if (!isHTMLElement(this.triggerEl.current)) {
498
- triggerDOM = ReactDOM.findDOMNode(this.triggerEl.current);
499
- }
500
-
505
+ const triggerDOM = this.adapter.getTriggerNode();
501
506
  const isRelativeScroll = e.target.contains(triggerDOM);
502
507
 
503
508
  if (isRelativeScroll) {
@@ -528,7 +533,33 @@ export default class Tooltip extends BaseComponent {
528
533
  this.containerPosition = position;
529
534
  }
530
535
  },
531
- getContainerPosition: () => this.containerPosition
536
+ getContainerPosition: () => this.containerPosition,
537
+ getContainer: () => this.containerEl && this.containerEl.current,
538
+ getTriggerNode: () => {
539
+ let triggerDOM = this.triggerEl.current;
540
+
541
+ if (!isHTMLElement(this.triggerEl.current)) {
542
+ triggerDOM = ReactDOM.findDOMNode(this.triggerEl.current);
543
+ }
544
+
545
+ return triggerDOM;
546
+ },
547
+ getFocusableElements: node => {
548
+ return getFocusableElements(node);
549
+ },
550
+ getActiveElement: () => {
551
+ return getActiveElement();
552
+ },
553
+ setInitialFocus: () => {
554
+ const focusRefNode = _get(this, 'initialFocusRef.current');
555
+
556
+ if (focusRefNode && 'focus' in focusRefNode) {
557
+ focusRefNode.focus();
558
+ }
559
+ },
560
+ notifyEscKeydown: event => {
561
+ this.props.onEscKeyDown(event);
562
+ }
532
563
  });
533
564
  }
534
565
 
@@ -570,7 +601,8 @@ export default class Tooltip extends BaseComponent {
570
601
  } = this.state;
571
602
  const {
572
603
  wrapWhenSpecial,
573
- role
604
+ role,
605
+ trigger
574
606
  } = this.props;
575
607
  let {
576
608
  children
@@ -630,7 +662,8 @@ export default class Tooltip extends BaseComponent {
630
662
  } else if (ref && typeof ref === 'object') {
631
663
  ref.current = node;
632
664
  }
633
- }
665
+ },
666
+ tabIndex: trigger === 'hover' ? 0 : undefined
634
667
  })); // 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
635
668
  // So if the user adds ref to the content, you need to use callback ref: https://github.com/facebook/react/issues/8873
636
669
 
@@ -655,7 +688,7 @@ Tooltip.propTypes = {
655
688
  clickTriggerToHide: PropTypes.bool,
656
689
  visible: PropTypes.bool,
657
690
  style: PropTypes.object,
658
- content: PropTypes.node,
691
+ content: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
659
692
  prefixCls: PropTypes.string,
660
693
  onVisibleChange: PropTypes.func,
661
694
  onClickOutSide: PropTypes.func,
@@ -669,8 +702,9 @@ Tooltip.propTypes = {
669
702
  stopPropagation: PropTypes.bool,
670
703
  // private
671
704
  role: PropTypes.string,
672
- wrapWhenSpecial: PropTypes.bool // when trigger has special status such as "disabled" or "loading", wrap span
673
-
705
+ wrapWhenSpecial: PropTypes.bool,
706
+ guardFocus: PropTypes.bool,
707
+ returnFocusOnClose: PropTypes.bool
674
708
  };
675
709
  Tooltip.defaultProps = {
676
710
  arrowBounding: numbers.ARROW_BOUNDING,
@@ -689,5 +723,9 @@ Tooltip.defaultProps = {
689
723
  spacing: numbers.SPACING,
690
724
  showArrow: true,
691
725
  wrapWhenSpecial: true,
692
- zIndex: numbers.DEFAULT_Z_INDEX
726
+ zIndex: numbers.DEFAULT_Z_INDEX,
727
+ closeOnEsc: false,
728
+ guardFocus: false,
729
+ returnFocusOnClose: false,
730
+ onEscKeyDown: _noop
693
731
  };
@@ -22,6 +22,7 @@ export default class NodeList extends PureComponent {
22
22
  super(props);
23
23
 
24
24
  this.onMotionEnd = () => {
25
+ typeof this.props.onMotionEnd === 'function' && this.props.onMotionEnd();
25
26
  this.setState({
26
27
  transitionNodes: []
27
28
  });
@@ -901,6 +901,10 @@ class TreeSelect extends BaseComponent {
901
901
  this.clickOutsideHandler = null;
902
902
  this.foundation = new TreeSelectFoundation(this.adapter);
903
903
  this.treeSelectID = _sliceInstanceProperty(_context2 = Math.random().toString(36)).call(_context2, 2);
904
+
905
+ this.onMotionEnd = () => {
906
+ this.adapter.rePositionDropdown();
907
+ };
904
908
  } // eslint-disable-next-line max-lines-per-function
905
909
 
906
910
 
@@ -1,5 +1,7 @@
1
1
  import React, { useState } from 'react';
2
- import { Select, Modal, Button, Tooltip, Popover } from '../../index';
2
+ import en_GB from '../../locale/source/en_GB';
3
+
4
+ import { Select, Modal, Button, Tooltip, Popover, ConfigProvider, Tag, Space } from '../../index';
3
5
  import CollapsibleInModal from './CollapsibleInModal';
4
6
  import DynamicContextDemo from './DynamicContext';
5
7
 
@@ -248,4 +250,94 @@ KeepDomNotLazy.story = {
248
250
  name: 'keepDOM && not lazy',
249
251
  };
250
252
 
253
+ export const UseModalDemo = () => {
254
+ const [modal, contextHolder] = Modal.useModal();
255
+ const config = { 'title': 'old title', 'content': 'old content' };
256
+
257
+ return (
258
+ <ConfigProvider locale={en_GB}>
259
+ <div>
260
+ <Button
261
+ onClick={() => {
262
+ const currentModal = modal.confirm(config);
263
+
264
+ setTimeout(() => {
265
+ currentModal.update({ title: "new title", content: "new content" });
266
+ }, 1000);
267
+ }}
268
+ >
269
+ Confirm Modal
270
+ </Button>
271
+ </div>
272
+ {contextHolder}
273
+ </ConfigProvider>
274
+ );
275
+ };
276
+ UseModalDemo.storyName = "useModal";
277
+
278
+ export const UseModalDestroy = () => {
279
+ const [modal, contextHolder] = Modal.useModal();
280
+ const config = { 'title': 'old title', 'content': 'old content' };
281
+
282
+ return (
283
+ <ConfigProvider locale={en_GB}>
284
+ <div>
285
+ <Button
286
+ onClick={() => {
287
+ const currentModal = modal.confirm(config);
288
+
289
+ setTimeout(() => {
290
+ currentModal.destroy();
291
+ }, 1000);
292
+ }}
293
+ >
294
+ Confirm Modal
295
+ </Button>
296
+ </div>
297
+ {contextHolder}
298
+ </ConfigProvider>
299
+ );
300
+ };
301
+ UseModalDestroy.storyName = "useModal destroy";
302
+
303
+ export const UseModalAfterClose = () => {
304
+ const [modal, contextHolder] = Modal.useModal();
305
+ const [closed, setClosed] = React.useState(false);
306
+ const [leave, setLeave] = React.useState(false);
307
+
308
+ const config = {
309
+ title: 'old title',
310
+ content: 'old content',
311
+ afterClose: () => {
312
+ setClosed(true);
313
+ },
314
+ motion: {
315
+ didLeave: () => {
316
+ console.log('didLeave');
317
+ setLeave(true);
318
+ }
319
+ }
320
+ };
251
321
 
322
+ return (
323
+ <ConfigProvider locale={en_GB}>
324
+ <Space>
325
+ <Button
326
+ onClick={() => {
327
+ const currentModal = modal.confirm(config);
328
+
329
+ setTimeout(() => {
330
+ currentModal.destroy();
331
+ }, 0);
332
+ }}
333
+ >
334
+ Confirm Modal
335
+ </Button>
336
+ <Tag>{`closed: ${closed}`}</Tag>
337
+ {/* <Tag>{`motion leave: ${leave}`}</Tag> */}
338
+ </Space>
339
+ {contextHolder}
340
+ </ConfigProvider>
341
+ );
342
+ };
343
+ UseModalAfterClose.storyName = "useModal afterClose";
@@ -35,6 +35,7 @@ const HookModal = ({ afterClose, config, ...props }: PropsWithChildren<HookModal
35
35
  }));
36
36
 
37
37
  const { motion } = props;
38
+ /* istanbul ignore next */
38
39
  const mergedMotion =
39
40
  typeof motion === 'undefined' || motion ?
40
41
  {
@@ -4,18 +4,32 @@ import { Button, ConfigProvider } from '../../../index';
4
4
  import Context from './context';
5
5
 
6
6
  function App({ children, globalVars }) {
7
- return <Context.Provider value={{ title: '1111', ...globalVars }}>{children}</Context.Provider>;
7
+ return (
8
+ <div data-cy="notice-container">
9
+ <Context.Provider value={{ title: '1111', ...globalVars }}>{children}</Context.Provider>
10
+ </div>
11
+ );
8
12
  }
9
13
 
10
14
  export default function Demo() {
11
- const [Notice, elements] = useNotification();
15
+ const [notice, elements] = useNotification();
16
+ const config = {
17
+ content: 'Hello World',
18
+ position: 'top',
19
+ title: <Context.Consumer>{({ title }) => <strong>{title}</strong>}</Context.Consumer>,
20
+ duration: 0,
21
+ };
12
22
 
13
23
  const addNotice = () => {
14
- Notice.addNotice({
15
- content: 'Hello World',
16
- position: 'top',
17
- title: <Context.Consumer>{({ title }) => <strong>{title}</strong>}</Context.Consumer>,
18
- });
24
+ const id1 = notice.info(config);
25
+ const id2 = notice.success(config);
26
+ const id3 = notice.warning(config);
27
+ const id4 = notice.error(config);
28
+ const id5 = notice.open(config);
29
+
30
+ // setTimeout(() => {
31
+ // notice.close(id5);
32
+ // }, 1000);
19
33
  };
20
34
 
21
35
  return (
@@ -59,8 +59,8 @@ export default function useNotification() {
59
59
  const [elements, patchElement] = usePatchElement();
60
60
  const noticeRef = new Map<string, { close: () => void } & ReactElement>();
61
61
 
62
- const id = getUuid('semi_notice_');
63
62
  const addNotice = (config: NoticeProps) => {
63
+ const id = getUuid('semi_notice_');
64
64
  const mergeConfig = {
65
65
  ...config,
66
66
  id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@douyinfe/semi-ui",
3
- "version": "2.7.0-beta.0",
3
+ "version": "2.8.0-beta.0",
4
4
  "description": "",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/es/index.js",
@@ -14,12 +14,12 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@babel/runtime-corejs3": "^7.15.4",
17
- "@douyinfe/semi-animation": "2.7.0-beta.0",
18
- "@douyinfe/semi-animation-react": "2.7.0-beta.0",
19
- "@douyinfe/semi-foundation": "2.7.0-beta.0",
20
- "@douyinfe/semi-icons": "2.7.0-beta.0",
21
- "@douyinfe/semi-illustrations": "2.7.0-beta.0",
22
- "@douyinfe/semi-theme-default": "2.7.0-beta.0",
17
+ "@douyinfe/semi-animation": "2.8.0-beta.0",
18
+ "@douyinfe/semi-animation-react": "2.8.0-beta.0",
19
+ "@douyinfe/semi-foundation": "2.8.0-beta.0",
20
+ "@douyinfe/semi-icons": "2.8.0-beta.0",
21
+ "@douyinfe/semi-illustrations": "2.8.0-beta.0",
22
+ "@douyinfe/semi-theme-default": "2.8.0-beta.0",
23
23
  "@types/react-window": "^1.8.2",
24
24
  "async-validator": "^3.5.0",
25
25
  "classnames": "^2.2.6",
@@ -69,13 +69,13 @@
69
69
  ],
70
70
  "author": "",
71
71
  "license": "MIT",
72
- "gitHead": "51cc4f6fa52f3275728d2112a98446ba54619c5b",
72
+ "gitHead": "05140034ad843d6a8d3a4a205e71f02b429f78fe",
73
73
  "devDependencies": {
74
74
  "@babel/plugin-proposal-decorators": "^7.15.8",
75
75
  "@babel/plugin-transform-runtime": "^7.15.8",
76
76
  "@babel/preset-env": "^7.15.8",
77
77
  "@babel/preset-react": "^7.14.5",
78
- "@douyinfe/semi-scss-compile": "2.7.0-beta.0",
78
+ "@douyinfe/semi-scss-compile": "2.8.0-beta.0",
79
79
  "@storybook/addon-knobs": "^6.3.1",
80
80
  "@types/lodash": "^4.14.176",
81
81
  "babel-loader": "^8.2.2",
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
2
2
 
3
3
  import Popover from '../index';
4
4
  import { strings } from '@douyinfe/semi-foundation/tooltip/constants';
5
- import { Button, Input, Table, IconButton, Modal, Tag } from '@douyinfe/semi-ui';
5
+ import { Button, Input, Table, IconButton, Modal, Tag, Space } from '@douyinfe/semi-ui';
6
6
  import SelectInPopover from './SelectInPopover';
7
7
  import BtnClose from './BtnClose';
8
8
  import PopRight from './PopRight';
@@ -572,3 +572,77 @@ export const ArrowPointAtCenterDemo = () => <ArrowPointAtCenter />;
572
572
  ArrowPointAtCenterDemo.story = {
573
573
  name: 'arrow point at center'
574
574
  }
575
+
576
+ export const A11yKeyboard = () => {
577
+ const [visible, setVisible] = React.useState(false);
578
+ const popStyle = { height: 200, width: 200 };
579
+
580
+ const renderContent = ({ initialFocusRef }) => {
581
+ return (
582
+ <div style={popStyle} data-cy="pop">
583
+ <button data-cy="pop-focusable-first">first focusable</button>
584
+ <a href="https://semi.design">link</a>
585
+ {/* <input ref={initialFocusRef} placeholder="init focus" /> */}
586
+ <input placeholder="" defaultValue="semi" />
587
+ <a href="https://semi.design">link2</a>
588
+ <button data-cy="pop-focusable-last">last focusable</button>
589
+ </div>
590
+ );
591
+ };
592
+
593
+ const noFocusableContent = (
594
+ <div style={popStyle}>没有可聚焦元素</div>
595
+ );
596
+
597
+ const initFocusContent = ({ initialFocusRef }) => {
598
+ return (
599
+ <div style={popStyle} data-cy="pop">
600
+ <button data-cy="pop-focusable-first">first focusable</button>
601
+ <input placeholder="" defaultValue="semi" ref={initialFocusRef} data-cy="initial-focus-input" />
602
+ <button data-cy="pop-focusable-last">last focusable</button>
603
+ </div>
604
+ );
605
+ };
606
+
607
+ return (
608
+ <div style={{ paddingLeft: 100, paddingTop: 100 }}>
609
+ <Space spacing={100}>
610
+ <Popover content={renderContent} trigger="click" motion={false}>
611
+ <Button data-cy="click">click</Button>
612
+ </Popover>
613
+ <Popover content={renderContent} trigger="hover">
614
+ <span data-cy="hover">hover</span>
615
+ </Popover>
616
+ <Popover content={renderContent} trigger="focus">
617
+ <Input data-cy="focus" defaultValue="focus" style={{ width: 150 }} />
618
+ </Popover>
619
+ <Popover
620
+ content={renderContent}
621
+ trigger="custom"
622
+ visible={visible}
623
+ onEscKeyDown={() => {
624
+ console.log('esc key down');
625
+ setVisible(false);
626
+ }}
627
+ >
628
+ <Button onClick={() => setVisible(!visible)} data-cy="custom">
629
+ custom trigger + click me toggle show
630
+ </Button>
631
+ </Popover>
632
+ <Popover content={noFocusableContent} trigger="click" data-cy="click-pop-contains-no-focusable">
633
+ <Button>pop内没有可聚焦元素</Button>
634
+ </Popover>
635
+ <Popover content={initFocusContent} trigger="click" motion={false}>
636
+ <Button data-cy="initial-focus">custom initialFocus</Button>
637
+ </Popover>
638
+ <Popover content={renderContent} trigger="click" motion={false} closeOnEsc={false}>
639
+ <Button data-cy="closeOnEsc-false">closeOnEsc=false</Button>
640
+ </Popover>
641
+ <Popover content={renderContent} trigger="click" motion={false} returnFocusOnClose={false}>
642
+ <Button data-cy="returnFocusOnClose-false">returnFocusOnClose=false</Button>
643
+ </Popover>
644
+ </Space>
645
+ </div>
646
+ );
647
+ };
648
+ A11yKeyboard.storyName = "a11y keyboard and focus";