@douyinfe/semi-ui 2.41.3 → 2.42.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 (63) hide show
  1. package/dist/css/semi.css +28 -7
  2. package/dist/css/semi.min.css +1 -1
  3. package/dist/umd/semi-ui.js +1245 -1496
  4. package/dist/umd/semi-ui.js.map +1 -1
  5. package/dist/umd/semi-ui.min.js +1 -1
  6. package/dist/umd/semi-ui.min.js.map +1 -1
  7. package/lib/cjs/button/splitButtonGroup.d.ts +2 -0
  8. package/lib/cjs/button/splitButtonGroup.js +14 -0
  9. package/lib/cjs/collapse/item.d.ts +2 -1
  10. package/lib/cjs/collapse/item.js +4 -1
  11. package/lib/cjs/form/baseForm.d.ts +12 -10
  12. package/lib/cjs/form/baseForm.js +17 -13
  13. package/lib/cjs/form/hoc/withField.js +13 -11
  14. package/lib/cjs/form/interface.d.ts +5 -3
  15. package/lib/cjs/inputNumber/index.js +1 -1
  16. package/lib/cjs/modal/confirm.d.ts +1 -1
  17. package/lib/cjs/table/ResizableHeaderCell.d.ts +2 -0
  18. package/lib/cjs/table/ResizableHeaderCell.js +6 -4
  19. package/lib/cjs/table/TableHeader.d.ts +2 -2
  20. package/lib/cjs/table/TableHeaderRow.d.ts +2 -1
  21. package/lib/cjs/table/TableHeaderRow.js +3 -0
  22. package/lib/cjs/table/interface.d.ts +2 -1
  23. package/lib/cjs/toast/index.d.ts +18 -0
  24. package/lib/cjs/toast/index.js +49 -4
  25. package/lib/cjs/toast/toast.d.ts +11 -0
  26. package/lib/cjs/toast/toast.js +22 -2
  27. package/lib/cjs/tooltip/index.d.ts +1 -1
  28. package/lib/cjs/tooltip/index.js +2 -1
  29. package/lib/cjs/tree/treeNode.js +1 -2
  30. package/lib/cjs/typography/base.js +1 -3
  31. package/lib/cjs/upload/fileCard.d.ts +13 -2
  32. package/lib/cjs/upload/fileCard.js +52 -11
  33. package/lib/cjs/upload/index.d.ts +4 -0
  34. package/lib/cjs/upload/index.js +16 -4
  35. package/lib/es/button/splitButtonGroup.d.ts +2 -0
  36. package/lib/es/button/splitButtonGroup.js +14 -0
  37. package/lib/es/collapse/item.d.ts +2 -1
  38. package/lib/es/collapse/item.js +4 -1
  39. package/lib/es/form/baseForm.d.ts +12 -10
  40. package/lib/es/form/baseForm.js +17 -13
  41. package/lib/es/form/hoc/withField.js +14 -12
  42. package/lib/es/form/interface.d.ts +5 -3
  43. package/lib/es/inputNumber/index.js +1 -1
  44. package/lib/es/modal/confirm.d.ts +1 -1
  45. package/lib/es/table/ResizableHeaderCell.d.ts +2 -0
  46. package/lib/es/table/ResizableHeaderCell.js +6 -4
  47. package/lib/es/table/TableHeader.d.ts +2 -2
  48. package/lib/es/table/TableHeaderRow.d.ts +2 -1
  49. package/lib/es/table/TableHeaderRow.js +3 -0
  50. package/lib/es/table/interface.d.ts +2 -1
  51. package/lib/es/toast/index.d.ts +18 -0
  52. package/lib/es/toast/index.js +49 -4
  53. package/lib/es/toast/toast.d.ts +11 -0
  54. package/lib/es/toast/toast.js +22 -2
  55. package/lib/es/tooltip/index.d.ts +1 -1
  56. package/lib/es/tooltip/index.js +2 -1
  57. package/lib/es/tree/treeNode.js +1 -2
  58. package/lib/es/typography/base.js +1 -3
  59. package/lib/es/upload/fileCard.d.ts +13 -2
  60. package/lib/es/upload/fileCard.js +52 -9
  61. package/lib/es/upload/index.d.ts +4 -0
  62. package/lib/es/upload/index.js +16 -4
  63. package/package.json +2 -2
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { Subtract } from 'utility-types';
3
3
  import type { RuleItem } from 'async-validator';
4
4
  import type { Options as ScrollIntoViewOptions } from 'scroll-into-view-if-needed';
5
- import type { BaseFormApi as FormApi, FormState, WithFieldOption, AllErrors } from '@douyinfe/semi-foundation/lib/es/form/interface';
5
+ import type { BaseFormApi as FormApi, FormState, WithFieldOption, AllErrors, FieldValidateTriggerType } from '@douyinfe/semi-foundation/lib/es/form/interface';
6
6
  import type { SelectProps } from '../select/index';
7
7
  import Option from '../select/option';
8
8
  import OptGroup from '../select/optionGroup';
@@ -88,6 +88,7 @@ export interface BaseFormProps<Values extends Record<string, any> = any> extends
88
88
  onReset?: () => void;
89
89
  onValueChange?: (values: Values, changedValue: Partial<Values>) => void;
90
90
  onChange?: (formState: FormState<Values>) => void;
91
+ allowEmpty?: boolean;
91
92
  validateFields?: (values: Values) => string | Partial<AllErrors<Values>>;
92
93
  /** Use this if you want to populate the form with initial values. */
93
94
  initValues?: Values;
@@ -96,18 +97,19 @@ export interface BaseFormProps<Values extends Record<string, any> = any> extends
96
97
  getFormApi?: (formApi: FormApi<Values>) => void;
97
98
  style?: React.CSSProperties;
98
99
  className?: string;
100
+ extraTextPosition?: 'middle' | 'bottom';
99
101
  layout?: 'horizontal' | 'vertical';
100
102
  labelPosition?: 'top' | 'left' | 'inset';
101
103
  labelWidth?: number | string;
102
104
  labelAlign?: 'left' | 'right';
103
105
  labelCol?: Record<string, any>;
104
106
  wrapperCol?: Record<string, any>;
105
- allowEmpty?: boolean;
106
107
  render?: (internalProps: FormFCChild) => React.ReactNode;
107
108
  component?: React.FC<any> | React.ComponentClass<any>;
108
109
  children?: React.ReactNode | ((internalProps: FormFCChild) => React.ReactNode);
109
110
  autoScrollToError?: boolean | ScrollIntoViewOptions;
110
111
  disabled?: boolean;
111
112
  showValidateIcon?: boolean;
112
- extraTextPosition?: 'middle' | 'bottom';
113
+ stopValidateWithError?: boolean;
114
+ trigger?: FieldValidateTriggerType;
113
115
  }
@@ -251,7 +251,7 @@ class InputNumber extends BaseComponent {
251
251
  } else {
252
252
  let valueStr = value;
253
253
  if (typeof value === 'number') {
254
- valueStr = value.toString();
254
+ valueStr = this.foundation.doFormat(value);
255
255
  }
256
256
  const parsedNum = this.foundation.doParse(valueStr, false, true, true);
257
257
  const toNum = typeof value === 'number' ? value : this.foundation.doParse(valueStr, false, false, false);
@@ -382,6 +382,7 @@ export declare function withError(props: ModalReactProps): {
382
382
  formMethod?: string;
383
383
  formNoValidate?: boolean;
384
384
  formTarget?: string;
385
+ contextMenu?: string;
385
386
  dir?: string;
386
387
  draggable?: boolean | "true" | "false";
387
388
  lang?: string;
@@ -395,7 +396,6 @@ export declare function withError(props: ModalReactProps): {
395
396
  'aria-haspopup'?: boolean | "dialog" | "menu" | "grid" | "listbox" | "tree" | "true" | "false";
396
397
  'aria-controls'?: string;
397
398
  'aria-describedby'?: string;
398
- contextMenu?: string;
399
399
  placeholder?: string;
400
400
  spellCheck?: boolean | "true" | "false";
401
401
  radioGroup?: string;
@@ -5,6 +5,8 @@ export interface ResizableHeaderCellProps {
5
5
  onResizeStart?: ResizeFn;
6
6
  onResizeStop?: ResizeFn;
7
7
  width?: number | string;
8
+ /** For compatibility with previous versions, the default value is true. If you don't want to resize, set it to false */
9
+ resize?: boolean;
8
10
  }
9
11
  declare class ResizableHeaderCell extends React.PureComponent<ResizableHeaderCellProps> {
10
12
  render(): JSX.Element;
@@ -15,10 +15,11 @@ class ResizableHeaderCell extends React.PureComponent {
15
15
  onResize,
16
16
  onResizeStart,
17
17
  onResizeStop,
18
- width
18
+ width,
19
+ resize
19
20
  } = _a,
20
- restProps = __rest(_a, ["onResize", "onResizeStart", "onResizeStop", "width"]);
21
- if (typeof width !== 'number') {
21
+ restProps = __rest(_a, ["onResize", "onResizeStart", "onResizeStop", "width", "resize"]);
22
+ if (typeof width !== 'number' || resize === false) {
22
23
  return /*#__PURE__*/React.createElement("th", Object.assign({}, restProps));
23
24
  }
24
25
  let {
@@ -36,7 +37,8 @@ class ResizableHeaderCell extends React.PureComponent {
36
37
  onResizeStop: onResizeStop,
37
38
  draggableOpts: {
38
39
  enableUserSelectHack: false
39
- }
40
+ },
41
+ axis: 'x'
40
42
  }, /*#__PURE__*/React.createElement("th", Object.assign({}, restProps), children));
41
43
  }
42
44
  }
@@ -1,6 +1,6 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { BaseProps } from '../_base/baseComponent';
3
- import { Fixed, TableComponents, OnHeaderRow } from './interface';
3
+ import { Fixed, TableComponents, OnHeaderRow, ColumnProps } from './interface';
4
4
  export interface TableHeaderProps extends BaseProps {
5
5
  columns?: any[];
6
6
  components?: TableComponents;
@@ -15,7 +15,7 @@ export interface TableHeaderCell {
15
15
  key: string | number;
16
16
  className: string;
17
17
  children: ReactNode;
18
- column: any[];
18
+ column: ColumnProps;
19
19
  colStart: number;
20
20
  level: number;
21
21
  parents: any[];
@@ -3,9 +3,10 @@ import PropTypes from 'prop-types';
3
3
  import BaseComponent from '../_base/baseComponent';
4
4
  import { TableContextProps } from './table-context';
5
5
  import { TableComponents, OnHeaderRow, Fixed } from './interface';
6
+ import type { TableHeaderCell } from './TableHeader';
6
7
  export interface TableHeaderRowProps {
7
8
  components?: TableComponents;
8
- row?: any[];
9
+ row?: TableHeaderCell[];
9
10
  prefixCls?: string;
10
11
  onHeaderRow?: OnHeaderRow<any>;
11
12
  index?: number;
@@ -131,6 +131,9 @@ export default class TableHeaderRow extends BaseComponent {
131
131
  }
132
132
  }
133
133
  }
134
+ Object.assign(cellProps, {
135
+ resize: column.resize
136
+ });
134
137
  const props = _omit(Object.assign(Object.assign({}, cellProps), customProps), ['colStart', 'colEnd', 'hasSubColumns', 'parents', 'level']);
135
138
  const {
136
139
  rowSpan,
@@ -90,6 +90,7 @@ export interface ColumnProps<RecordType extends Record<string, any> = any> {
90
90
  onFilterDropdownVisibleChange?: OnFilterDropdownVisibleChange;
91
91
  onHeaderCell?: OnHeaderCell<RecordType>;
92
92
  ellipsis?: BaseEllipsis;
93
+ resize?: boolean;
93
94
  }
94
95
  export type Align = BaseAlign;
95
96
  export type SortOrder = BaseSortOrder;
@@ -103,7 +104,7 @@ export type Fixed = BaseFixed;
103
104
  export type OnCell<RecordType> = (record?: RecordType, rowIndex?: number) => OnCellReturnObject;
104
105
  export type OnFilter<RecordType> = (filteredValue?: any, record?: RecordType) => boolean;
105
106
  export type OnFilterDropdownVisibleChange = (visible?: boolean) => void;
106
- export type OnHeaderCell<RecordType> = (record?: RecordType, columnIndex?: number) => OnHeaderCellReturnObject;
107
+ export type OnHeaderCell<RecordType> = (record?: RecordType, columnIndex?: number, index?: number) => OnHeaderCellReturnObject;
107
108
  export type ColumnRender<RecordType> = (text: any, record: RecordType, index: number, options?: RenderOptions) => ColumnRenderReturnType;
108
109
  export type RenderFilterDropdownItem = (itemInfo?: FilterDropdownItem) => ReactNode;
109
110
  export type Sorter<RecordType> = BaseSorter<RecordType>;
@@ -13,7 +13,11 @@ export interface ToastReactProps extends ToastProps {
13
13
  export type { ConfigProps, ToastListProps, ToastListState, ToastState };
14
14
  declare const createBaseToast: () => {
15
15
  new (props: ToastListProps): {
16
+ stack: boolean;
17
+ innerWrapperRef: React.RefObject<HTMLDivElement>;
16
18
  readonly adapter: ToastListAdapter;
19
+ handleMouseEnter: (e: React.MouseEvent) => void;
20
+ handleMouseLeave: (e: React.MouseEvent) => void;
17
21
  has(id: string): any;
18
22
  add(opts: ToastInstance): any;
19
23
  update(id: string, opts: ToastInstance): any;
@@ -47,7 +51,11 @@ declare const createBaseToast: () => {
47
51
  UNSAFE_componentWillUpdate?(nextProps: Readonly<ToastListProps>, nextState: Readonly<ToastListState>, nextContext: any): void;
48
52
  };
49
53
  ref: {
54
+ stack: boolean;
55
+ innerWrapperRef: React.RefObject<HTMLDivElement>;
50
56
  readonly adapter: ToastListAdapter;
57
+ handleMouseEnter: (e: React.MouseEvent) => void;
58
+ handleMouseLeave: (e: React.MouseEvent) => void;
51
59
  has(id: string): any;
52
60
  add(opts: ToastInstance): any;
53
61
  update(id: string, opts: ToastInstance): any;
@@ -90,6 +98,7 @@ declare const createBaseToast: () => {
90
98
  onClose: PropTypes.Requireable<(...args: any[]) => any>;
91
99
  icon: PropTypes.Requireable<PropTypes.ReactNodeLike>;
92
100
  direction: PropTypes.Requireable<string>;
101
+ stack: PropTypes.Requireable<boolean>;
93
102
  };
94
103
  defaultProps: {};
95
104
  wrapperId: null | string;
@@ -109,7 +118,11 @@ export declare class ToastFactory {
109
118
  }
110
119
  declare const _default: {
111
120
  new (props: ToastListProps): {
121
+ stack: boolean;
122
+ innerWrapperRef: React.RefObject<HTMLDivElement>;
112
123
  readonly adapter: ToastListAdapter;
124
+ handleMouseEnter: (e: React.MouseEvent<Element, MouseEvent>) => void;
125
+ handleMouseLeave: (e: React.MouseEvent<Element, MouseEvent>) => void;
113
126
  has(id: string): any;
114
127
  add(opts: ToastInstance): any;
115
128
  update(id: string, opts: ToastInstance): any;
@@ -143,7 +156,11 @@ declare const _default: {
143
156
  UNSAFE_componentWillUpdate?(nextProps: Readonly<ToastListProps>, nextState: Readonly<ToastListState>, nextContext: any): void;
144
157
  };
145
158
  ref: {
159
+ stack: boolean;
160
+ innerWrapperRef: React.RefObject<HTMLDivElement>;
146
161
  readonly adapter: ToastListAdapter;
162
+ handleMouseEnter: (e: React.MouseEvent<Element, MouseEvent>) => void;
163
+ handleMouseLeave: (e: React.MouseEvent<Element, MouseEvent>) => void;
147
164
  has(id: string): any;
148
165
  add(opts: ToastInstance): any;
149
166
  update(id: string, opts: ToastInstance): any;
@@ -186,6 +203,7 @@ declare const _default: {
186
203
  onClose: PropTypes.Requireable<(...args: any[]) => any>;
187
204
  icon: PropTypes.Requireable<PropTypes.ReactNodeLike>;
188
205
  direction: PropTypes.Requireable<string>;
206
+ stack: PropTypes.Requireable<boolean>;
189
207
  };
190
208
  defaultProps: {};
191
209
  wrapperId: string;
@@ -15,10 +15,27 @@ const createBaseToast = () => {
15
15
  return _a = class ToastList extends BaseComponent {
16
16
  constructor(props) {
17
17
  super(props);
18
+ this.stack = false;
19
+ this.innerWrapperRef = /*#__PURE__*/React.createRef();
20
+ this.handleMouseEnter = e => {
21
+ if (this.stack) {
22
+ this.foundation.handleMouseInSideChange(true);
23
+ }
24
+ };
25
+ this.handleMouseLeave = e => {
26
+ var _a;
27
+ if (this.stack) {
28
+ const height = (_a = this.foundation.getInputWrapperRect()) === null || _a === void 0 ? void 0 : _a.height;
29
+ if (height) {
30
+ this.foundation.handleMouseInSideChange(false);
31
+ }
32
+ }
33
+ };
18
34
  this.state = {
19
35
  list: [],
20
36
  removedItems: [],
21
- updatedItems: []
37
+ updatedItems: [],
38
+ mouseInSide: false
22
39
  };
23
40
  this.foundation = new ToastListFoundation(this.adapter);
24
41
  }
@@ -30,6 +47,15 @@ const createBaseToast = () => {
30
47
  removedItems,
31
48
  updatedItems
32
49
  });
50
+ },
51
+ handleMouseInSideChange: mouseInSide => {
52
+ this.setState({
53
+ mouseInSide
54
+ });
55
+ },
56
+ getInputWrapperRect: () => {
57
+ var _a;
58
+ return (_a = this.innerWrapperRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
33
59
  }
34
60
  });
35
61
  }
@@ -64,6 +90,7 @@ const createBaseToast = () => {
64
90
  ToastList.ref.add(Object.assign(Object.assign({}, opts), {
65
91
  id
66
92
  }));
93
+ ToastList.ref.stack = Boolean(opts.stack);
67
94
  });
68
95
  } else {
69
96
  const node = document.querySelector(`#${this.wrapperId}`);
@@ -72,6 +99,9 @@ const createBaseToast = () => {
72
99
  node.style[pos] = typeof opts[pos] === 'number' ? `${opts[pos]}px` : opts[pos];
73
100
  }
74
101
  });
102
+ if (Boolean(opts.stack) !== ToastList.ref.stack) {
103
+ ToastList.ref.stack = Boolean(opts.stack);
104
+ }
75
105
  if (ToastList.ref.has(id)) {
76
106
  ToastList.ref.update(id, Object.assign(Object.assign({}, opts), {
77
107
  id
@@ -197,7 +227,15 @@ const createBaseToast = () => {
197
227
  toast.foundation.restartCloseTimer();
198
228
  }
199
229
  };
200
- return /*#__PURE__*/React.createElement(React.Fragment, null, list.map((item, index) => {
230
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
231
+ className: cls({
232
+ [`${cssClasses.PREFIX}-innerWrapper`]: true,
233
+ [`${cssClasses.PREFIX}-innerWrapper-hover`]: this.state.mouseInSide
234
+ }),
235
+ ref: this.innerWrapperRef,
236
+ onMouseEnter: this.handleMouseEnter,
237
+ onMouseLeave: this.handleMouseLeave
238
+ }, list.map((item, index) => {
201
239
  const isRemoved = removedItems.find(removedItem => removedItem.id === item.id) !== undefined;
202
240
  return /*#__PURE__*/React.createElement(CSSAnimation, {
203
241
  key: item.id,
@@ -211,6 +249,12 @@ const createBaseToast = () => {
211
249
  isAnimating
212
250
  } = _ref2;
213
251
  return isRemoved && !isAnimating ? null : /*#__PURE__*/React.createElement(Toast, Object.assign({}, item, {
252
+ stack: this.stack,
253
+ stackExpanded: this.state.mouseInSide,
254
+ positionInList: {
255
+ length: list.length,
256
+ index
257
+ },
214
258
  className: cls({
215
259
  [item.className]: Boolean(item.className),
216
260
  [animationClassName]: true
@@ -221,7 +265,7 @@ const createBaseToast = () => {
221
265
  ref: refFn
222
266
  }));
223
267
  });
224
- }));
268
+ })));
225
269
  }
226
270
  }, _a.defaultOpts = {
227
271
  motion: true,
@@ -232,7 +276,8 @@ const createBaseToast = () => {
232
276
  duration: PropTypes.number,
233
277
  onClose: PropTypes.func,
234
278
  icon: PropTypes.node,
235
- direction: PropTypes.oneOf(strings.directions)
279
+ direction: PropTypes.oneOf(strings.directions),
280
+ stack: PropTypes.bool
236
281
  }, _a.defaultProps = {}, _a;
237
282
  };
238
283
  export class ToastFactory {
@@ -7,10 +7,17 @@ export interface ToastReactProps extends ToastProps {
7
7
  style?: CSSProperties;
8
8
  icon?: React.ReactNode;
9
9
  content: React.ReactNode;
10
+ stack?: boolean;
11
+ stackExpanded?: boolean;
10
12
  onAnimationEnd?: (e: React.AnimationEvent) => void;
11
13
  onAnimationStart?: (e: React.AnimationEvent) => void;
14
+ positionInList?: {
15
+ index: number;
16
+ length: number;
17
+ };
12
18
  }
13
19
  declare class Toast extends BaseComponent<ToastReactProps, ToastState> {
20
+ toastEle: React.RefObject<HTMLDivElement>;
14
21
  static contextType: React.Context<ContextValue>;
15
22
  static propTypes: {
16
23
  onClose: PropTypes.Requireable<(...args: any[]) => any>;
@@ -23,6 +30,8 @@ declare class Toast extends BaseComponent<ToastReactProps, ToastState> {
23
30
  style: PropTypes.Requireable<object>;
24
31
  className: PropTypes.Requireable<string>;
25
32
  showClose: PropTypes.Requireable<boolean>;
33
+ stack: PropTypes.Requireable<boolean>;
34
+ stackExpanded: PropTypes.Requireable<boolean>;
26
35
  icon: PropTypes.Requireable<NonNullable<PropTypes.ReactNodeLike>>;
27
36
  direction: PropTypes.Requireable<string>;
28
37
  };
@@ -33,6 +42,8 @@ declare class Toast extends BaseComponent<ToastReactProps, ToastState> {
33
42
  duration: number;
34
43
  textMaxWidth: number;
35
44
  showClose: boolean;
45
+ stack: boolean;
46
+ stackExpanded: boolean;
36
47
  theme: string;
37
48
  };
38
49
  constructor(props: ToastReactProps);
@@ -13,6 +13,7 @@ const prefixCls = cssClasses.PREFIX;
13
13
  class Toast extends BaseComponent {
14
14
  constructor(props) {
15
15
  super(props);
16
+ this.toastEle = /*#__PURE__*/React.createRef();
16
17
  this.clearCloseTimer = () => {
17
18
  this.foundation.clearCloseTimer_();
18
19
  };
@@ -92,11 +93,15 @@ class Toast extends BaseComponent {
92
93
  textStyle.maxWidth = textMaxWidth;
93
94
  const btnTheme = 'borderless';
94
95
  const btnSize = 'small';
95
- return /*#__PURE__*/React.createElement("div", {
96
+ const reservedIndex = this.props.positionInList ? this.props.positionInList.length - this.props.positionInList.index - 1 : 0;
97
+ const toastEle = /*#__PURE__*/React.createElement("div", {
98
+ ref: this.toastEle,
96
99
  role: "alert",
97
100
  "aria-label": `${type ? type : 'default'} type`,
98
101
  className: toastCls,
99
- style: style,
102
+ style: Object.assign(Object.assign({}, style), {
103
+ transform: `translate3d(0,0,${reservedIndex * -10}px)`
104
+ }),
100
105
  onMouseEnter: this.clearCloseTimer,
101
106
  onMouseLeave: this.startCloseTimer,
102
107
  onAnimationStart: this.props.onAnimationStart,
@@ -118,6 +123,17 @@ class Toast extends BaseComponent {
118
123
  theme: btnTheme,
119
124
  size: btnSize
120
125
  }))));
126
+ if (this.props.stack) {
127
+ const height = this.props.stackExpanded && this.toastEle.current && getComputedStyle(this.toastEle.current).height || 0;
128
+ return /*#__PURE__*/React.createElement("div", {
129
+ className: `${prefixCls}-zero-height-wrapper`,
130
+ style: {
131
+ height
132
+ }
133
+ }, toastEle);
134
+ } else {
135
+ return toastEle;
136
+ }
121
137
  }
122
138
  }
123
139
  Toast.contextType = ConfigContext;
@@ -132,6 +148,8 @@ Toast.propTypes = {
132
148
  style: PropTypes.object,
133
149
  className: PropTypes.string,
134
150
  showClose: PropTypes.bool,
151
+ stack: PropTypes.bool,
152
+ stackExpanded: PropTypes.bool,
135
153
  icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
136
154
  direction: PropTypes.oneOf(strings.directions)
137
155
  };
@@ -142,6 +160,8 @@ Toast.defaultProps = {
142
160
  duration: numbers.duration,
143
161
  textMaxWidth: 450,
144
162
  showClose: true,
163
+ stack: false,
164
+ stackExpanded: false,
145
165
  theme: 'normal'
146
166
  };
147
167
  export default Toast;
@@ -92,7 +92,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
92
92
  getPopupContainer: PropTypes.Requireable<(...args: any[]) => any>;
93
93
  mouseEnterDelay: PropTypes.Requireable<number>;
94
94
  mouseLeaveDelay: PropTypes.Requireable<number>;
95
- trigger: PropTypes.Validator<NonNullable<"hover" | "focus" | "click" | "custom">>;
95
+ trigger: PropTypes.Validator<NonNullable<"hover" | "focus" | "click" | "custom" | "contextMenu">>;
96
96
  className: PropTypes.Requireable<string>;
97
97
  wrapperClassName: PropTypes.Requireable<string>;
98
98
  clickToHide: PropTypes.Requireable<boolean>;
@@ -329,7 +329,8 @@ export default class Tooltip extends BaseComponent {
329
329
  click: 'onClick',
330
330
  focus: 'onFocus',
331
331
  blur: 'onBlur',
332
- keydown: 'onKeyDown'
332
+ keydown: 'onKeyDown',
333
+ contextMenu: 'onContextMenu'
333
334
  }),
334
335
  registerTriggerEvent: triggerEventSet => {
335
336
  this.setState({
@@ -208,7 +208,7 @@ export default class TreeNode extends PureComponent {
208
208
  } = this.props;
209
209
  if (_isFunction(renderLabel)) {
210
210
  return renderLabel(label, data);
211
- } else if (_isString(label) && filtered && keyword && treeNodeFilterProp === 'label') {
211
+ } else if (_isString(label) && filtered && keyword) {
212
212
  return getHighLightTextHTML({
213
213
  sourceString: label,
214
214
  searchWords: [keyword],
@@ -358,7 +358,6 @@ export default class TreeNode extends PureComponent {
358
358
  [`${prefixcls}-selected`]: selected,
359
359
  [`${prefixcls}-active`]: !multiple && active,
360
360
  [`${prefixcls}-ellipsis`]: labelEllipsis,
361
- [`${prefixcls}-filtered`]: filtered && treeNodeFilterProp !== 'label',
362
361
  [`${prefixcls}-drag-over`]: !disabled && dragOver,
363
362
  [`${prefixcls}-draggable`]: !disabled && draggable && !renderFullLabel,
364
363
  // When draggable + renderFullLabel is enabled, the default style
@@ -117,9 +117,7 @@ export default class Base extends Component {
117
117
  if (showTooltip.type && showTooltip.type.toLowerCase() === 'popover') {
118
118
  return _merge({
119
119
  opts: {
120
- style: {
121
- width: '240px'
122
- },
120
+ // style: { width: '240px' },
123
121
  showArrow: true
124
122
  }
125
123
  }, showTooltip);
@@ -1,12 +1,19 @@
1
- import { PureComponent, ReactNode, MouseEvent, CSSProperties } from 'react';
1
+ import { ReactNode, MouseEvent, CSSProperties } from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import { FileCardAdapter } from '@douyinfe/semi-foundation/lib/es/upload/fileCardFoundation';
3
4
  import { Locale } from '../locale/interface';
5
+ import BaseComponent from '../_base/baseComponent';
4
6
  import { RenderFileItemProps } from './interface';
5
7
  export interface FileCardProps extends RenderFileItemProps {
6
8
  className?: string;
7
9
  style?: CSSProperties;
10
+ picWidth?: string | number;
11
+ picHeight?: string | number;
8
12
  }
9
- declare class FileCard extends PureComponent<FileCardProps> {
13
+ export interface FileCardState {
14
+ fallbackPreview?: boolean;
15
+ }
16
+ declare class FileCard extends BaseComponent<FileCardProps, FileCardState> {
10
17
  static propTypes: {
11
18
  className: PropTypes.Requireable<string>;
12
19
  disabled: PropTypes.Requireable<boolean>;
@@ -19,6 +26,8 @@ declare class FileCard extends PureComponent<FileCardProps> {
19
26
  percent: PropTypes.Requireable<number>;
20
27
  preview: PropTypes.Requireable<boolean>;
21
28
  previewFile: PropTypes.Requireable<(...args: any[]) => any>;
29
+ picWidth: PropTypes.Requireable<NonNullable<string | number>>;
30
+ picHeight: PropTypes.Requireable<NonNullable<string | number>>;
22
31
  showReplace: PropTypes.Requireable<boolean>;
23
32
  showRetry: PropTypes.Requireable<boolean>;
24
33
  size: PropTypes.Requireable<NonNullable<string | number>>;
@@ -36,6 +45,8 @@ declare class FileCard extends PureComponent<FileCardProps> {
36
45
  preview: boolean;
37
46
  size: string;
38
47
  };
48
+ constructor(props: FileCardProps);
49
+ get adapter(): FileCardAdapter<FileCardProps, FileCardState>;
39
50
  transSize(size: string | number): string;
40
51
  renderValidateMessage(): ReactNode;
41
52
  renderPicValidateMsg(): ReactNode;
@@ -1,10 +1,12 @@
1
- import React, { PureComponent } from 'react';
1
+ import React from 'react';
2
2
  import cls from 'classnames';
3
3
  import PropTypes from 'prop-types';
4
4
  import { cssClasses, strings } from '@douyinfe/semi-foundation/lib/es/upload/constants';
5
+ import FileCardFoundation from '@douyinfe/semi-foundation/lib/es/upload/fileCardFoundation';
5
6
  import { getFileSize } from '@douyinfe/semi-foundation/lib/es/upload/utils';
6
7
  import { IconAlertCircle, IconClose, IconClear, IconFile, IconRefresh } from '@douyinfe/semi-icons';
7
8
  import LocaleConsumer from '../locale/localeConsumer';
9
+ import BaseComponent from '../_base/baseComponent';
8
10
  import Button from '../button/index';
9
11
  import Progress from '../progress/index';
10
12
  import Tooltip from '../tooltip/index';
@@ -79,7 +81,21 @@ const DirectorySvg = function () {
79
81
  strokeLinejoin: "round"
80
82
  }));
81
83
  };
82
- class FileCard extends PureComponent {
84
+ class FileCard extends BaseComponent {
85
+ constructor(props) {
86
+ super(props);
87
+ this.state = {
88
+ fallbackPreview: false
89
+ };
90
+ this.foundation = new FileCardFoundation(this.adapter);
91
+ }
92
+ get adapter() {
93
+ return Object.assign(Object.assign({}, super.adapter), {
94
+ updateFallbackPreview: fallbackPreview => this.setState({
95
+ fallbackPreview
96
+ })
97
+ });
98
+ }
83
99
  transSize(size) {
84
100
  if (typeof size === 'number') {
85
101
  return getFileSize(size);
@@ -140,6 +156,9 @@ class FileCard extends PureComponent {
140
156
  }, icon) : null;
141
157
  }
142
158
  renderPic(locale) {
159
+ const {
160
+ fallbackPreview
161
+ } = this.state;
143
162
  const {
144
163
  url,
145
164
  percent,
@@ -152,7 +171,9 @@ class FileCard extends PureComponent {
152
171
  renderPicPreviewIcon,
153
172
  renderThumbnail,
154
173
  name,
155
- index
174
+ index,
175
+ picHeight,
176
+ picWidth
156
177
  } = this.props;
157
178
  const showProgress = status === strings.FILE_STATUS_UPLOADING && percent !== 100;
158
179
  const showRetry = status === strings.FILE_STATUS_UPLOAD_FAIL && this.props.showRetry;
@@ -160,6 +181,7 @@ class FileCard extends PureComponent {
160
181
  const showPreview = status === strings.FILE_STATUS_SUCCESS && !this.props.showReplace;
161
182
  const filePicCardCls = cls({
162
183
  [`${prefixCls}-picture-file-card`]: true,
184
+ [`${prefixCls}-picture-file-card-preview-fallback`]: fallbackPreview,
163
185
  [`${prefixCls}-picture-file-card-disabled`]: disabled,
164
186
  [`${prefixCls}-picture-file-card-show-pointer`]: typeof onPreviewClick !== 'undefined',
165
187
  [`${prefixCls}-picture-file-card-error`]: status === strings.FILE_STATUS_UPLOAD_FAIL,
@@ -201,14 +223,29 @@ class FileCard extends PureComponent {
201
223
  const picInfo = typeof renderPicInfo === 'function' ? renderPicInfo(this.props) : /*#__PURE__*/React.createElement("div", {
202
224
  className: `${prefixCls}-picture-file-card-pic-info`
203
225
  }, index + 1);
204
- const thumbnail = typeof renderThumbnail === 'function' ? renderThumbnail(this.props) : /*#__PURE__*/React.createElement("img", {
226
+ let imgStyle = {};
227
+ let itemStyle = style ? Object.assign({}, style) : {};
228
+ if (picHeight) {
229
+ itemStyle.height = picHeight;
230
+ imgStyle.height = picHeight;
231
+ }
232
+ if (picWidth) {
233
+ itemStyle.width = picWidth;
234
+ imgStyle.width = picWidth;
235
+ }
236
+ const defaultThumbTail = !fallbackPreview ? /*#__PURE__*/React.createElement("img", {
205
237
  src: url,
206
- alt: name
238
+ alt: name,
239
+ onError: error => this.foundation.handleImageError(error),
240
+ style: imgStyle
241
+ }) : /*#__PURE__*/React.createElement(IconFile, {
242
+ size: "large"
207
243
  });
244
+ const thumbnail = typeof renderThumbnail === 'function' ? renderThumbnail(this.props) : defaultThumbTail;
208
245
  return /*#__PURE__*/React.createElement("div", {
209
246
  role: "listitem",
210
247
  className: filePicCardCls,
211
- style: style,
248
+ style: itemStyle,
212
249
  onClick: onPreviewClick
213
250
  }, thumbnail, showProgress ? /*#__PURE__*/React.createElement(Progress, {
214
251
  percent: percent,
@@ -233,6 +270,9 @@ class FileCard extends PureComponent {
233
270
  onPreviewClick,
234
271
  renderFileOperation
235
272
  } = this.props;
273
+ const {
274
+ fallbackPreview
275
+ } = this.state;
236
276
  const fileCardCls = cls({
237
277
  [`${prefixCls}-file-card`]: true,
238
278
  [`${prefixCls}-file-card-fail`]: status === strings.FILE_STATUS_VALID_FAIL || status === strings.FILE_STATUS_UPLOAD_FAIL,
@@ -240,7 +280,7 @@ class FileCard extends PureComponent {
240
280
  });
241
281
  const previewCls = cls({
242
282
  [`${prefixCls}-file-card-preview`]: true,
243
- [`${prefixCls}-file-card-preview-placeholder`]: !preview || previewFile
283
+ [`${prefixCls}-file-card-preview-placeholder`]: !preview || previewFile || fallbackPreview
244
284
  });
245
285
  const infoCls = `${prefixCls}-file-card-info`;
246
286
  const closeCls = `${prefixCls}-file-card-close`;
@@ -250,9 +290,10 @@ class FileCard extends PureComponent {
250
290
  const showRetry = status === strings.FILE_STATUS_UPLOAD_FAIL && propsShowRetry;
251
291
  const showReplace = status === strings.FILE_STATUS_SUCCESS && propsShowReplace;
252
292
  const fileSize = this.transSize(size);
253
- let previewContent = preview ? /*#__PURE__*/React.createElement("img", {
293
+ let previewContent = preview && !fallbackPreview ? /*#__PURE__*/React.createElement("img", {
254
294
  src: url,
255
- alt: name
295
+ alt: name,
296
+ onError: error => this.foundation.handleImageError(error)
256
297
  }) : /*#__PURE__*/React.createElement(IconFile, {
257
298
  size: "large"
258
299
  });
@@ -352,6 +393,8 @@ FileCard.propTypes = {
352
393
  percent: PropTypes.number,
353
394
  preview: PropTypes.bool,
354
395
  previewFile: PropTypes.func,
396
+ picWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
397
+ picHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
355
398
  showReplace: PropTypes.bool,
356
399
  showRetry: PropTypes.bool,
357
400
  size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),