amis 1.9.1-beta.3 → 1.9.1-beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. package/lib/SchemaRenderer.js +6 -9
  2. package/lib/SchemaRenderer.js.map +2 -2
  3. package/lib/actions/CmptAction.js +4 -4
  4. package/lib/actions/CmptAction.js.map +2 -2
  5. package/lib/components/WithRemoteConfig.d.ts +2 -2
  6. package/lib/components/WithRemoteConfig.js +6 -3
  7. package/lib/components/WithRemoteConfig.js.map +2 -2
  8. package/lib/components/table/ItemActionsWrapper.d.ts +10 -0
  9. package/lib/components/table/ItemActionsWrapper.js +25 -0
  10. package/lib/components/table/ItemActionsWrapper.js.map +13 -0
  11. package/lib/components/table/index.d.ts +48 -41
  12. package/lib/components/table/index.js +46 -18
  13. package/lib/components/table/index.js.map +2 -2
  14. package/lib/index.js +1 -1
  15. package/lib/renderers/Form/JSONSchema.js +3 -3
  16. package/lib/renderers/Form/JSONSchema.js.map +2 -2
  17. package/lib/renderers/Form/Options.js +11 -5
  18. package/lib/renderers/Form/Options.js.map +2 -2
  19. package/lib/renderers/Form/wrapControl.js.map +2 -2
  20. package/lib/renderers/Table-v2/index.d.ts +14 -2
  21. package/lib/renderers/Table-v2/index.js +33 -3
  22. package/lib/renderers/Table-v2/index.js.map +2 -2
  23. package/package.json +1 -1
  24. package/schema.json +13 -2
  25. package/sdk/barcode.js +51 -51
  26. package/sdk/charts.js +14 -14
  27. package/sdk/codemirror.js +7 -7
  28. package/sdk/color-picker.js +65 -65
  29. package/sdk/cropperjs.js +2 -2
  30. package/sdk/exceljs.js +1 -1
  31. package/sdk/markdown.js +69 -69
  32. package/sdk/papaparse.js +1 -1
  33. package/sdk/renderers/Form/CityDB.js +1 -1
  34. package/sdk/rest.js +16 -16
  35. package/sdk/rich-text.js +62 -62
  36. package/sdk/sdk.js +1299 -1297
  37. package/sdk/thirds/hls.js/hls.js +1 -1
  38. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  39. package/sdk/tinymce.js +57 -57
  40. package/src/SchemaRenderer.tsx +1 -4
  41. package/src/actions/CmptAction.ts +4 -4
  42. package/src/components/WithRemoteConfig.tsx +20 -11
  43. package/src/components/table/ItemActionsWrapper.tsx +32 -0
  44. package/src/components/table/index.tsx +115 -58
  45. package/src/renderers/Form/JSONSchema.tsx +3 -3
  46. package/src/renderers/Form/Options.tsx +17 -7
  47. package/src/renderers/Form/wrapControl.tsx +0 -1
  48. package/src/renderers/Table-v2/index.tsx +65 -2
@@ -391,13 +391,10 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
391
391
  ref: this.refFn,
392
392
  render: this.renderChild,
393
393
  rootStore: rootStore,
394
+ disabled: disable ?? rest.disabled ?? restSchema.disabled,
394
395
  dispatchEvent: this.dispatchEvent
395
396
  };
396
397
 
397
- if (disable) {
398
- (props as any).disabled = true;
399
- }
400
-
401
398
  // 自动解析变量模式,主要是方便直接引入第三方组件库,无需为了支持变量封装一层
402
399
  if (renderer.autoVar) {
403
400
  for (const key of Object.keys($schema)) {
@@ -56,16 +56,16 @@ export class CmptAction implements RendererAction {
56
56
 
57
57
  // 数据更新
58
58
  if (action.actionType === 'setValue') {
59
- if (component.setData) {
60
- return component.setData(action.args?.value);
59
+ if (component?.setData) {
60
+ return component?.setData(action.args?.value);
61
61
  } else {
62
- return component.props.onChange?.(action.args?.value);
62
+ return component?.props.onChange?.(action.args?.value);
63
63
  }
64
64
  }
65
65
 
66
66
  // 刷新
67
67
  if (action.actionType === 'reload') {
68
- return component.reload?.(undefined, action.args);
68
+ return component?.reload?.(undefined, action.args);
69
69
  }
70
70
 
71
71
  // 执行组件动作
@@ -24,7 +24,12 @@ import {
24
24
  tokenize
25
25
  } from '../utils/tpl-builtin';
26
26
  import {reaction} from 'mobx';
27
- import {createObject, findIndex, findTreeIndex} from '../utils/helper';
27
+ import {
28
+ createObject,
29
+ findIndex,
30
+ findTreeIndex,
31
+ isObject
32
+ } from '../utils/helper';
28
33
 
29
34
  export const Store = types
30
35
  .model('RemoteConfigStore')
@@ -166,12 +171,15 @@ export interface WithRemoteConfigSettings {
166
171
  props: any
167
172
  ) => any;
168
173
 
169
- injectedPropsFilter?: (props: {
170
- config: any;
171
- loading?: boolean;
172
- deferLoad: (term: string) => any;
173
- updateConfig: (config: any) => void;
174
- }) => any;
174
+ injectedPropsFilter?: (
175
+ injectedProps: {
176
+ config: any;
177
+ loading?: boolean;
178
+ deferLoad: (term: string) => any;
179
+ updateConfig: (config: any) => void;
180
+ },
181
+ props: any
182
+ ) => any;
175
183
  }
176
184
 
177
185
  export function withRemoteConfig<P = any>(
@@ -219,6 +227,8 @@ export function withRemoteConfig<P = any>(
219
227
  props.store.setComponent(this);
220
228
  this.deferLoadConfig = this.deferLoadConfig.bind(this);
221
229
  props.remoteConfigRef?.(this);
230
+ props.store.setData(props.data);
231
+ this.syncConfig();
222
232
  }
223
233
 
224
234
  componentDidMount() {
@@ -226,10 +236,7 @@ export function withRemoteConfig<P = any>(
226
236
  const {store, data} = this.props;
227
237
  const source = (this.props as any)[config.sourceField || 'source'];
228
238
 
229
- store.setData(data);
230
-
231
239
  if (isPureVariable(source)) {
232
- this.syncConfig();
233
240
  this.toDispose.push(
234
241
  reaction(
235
242
  () =>
@@ -323,6 +330,8 @@ export function withRemoteConfig<P = any>(
323
330
  config,
324
331
  'syncConfig'
325
332
  );
333
+ } else if (isObject(source) && !isEffectiveApi(source, data)) {
334
+ store.setConfig(source, config, 'syncConfig');
326
335
  }
327
336
  }
328
337
 
@@ -389,7 +398,7 @@ export function withRemoteConfig<P = any>(
389
398
  ? {loadOptions: this.loadOptions}
390
399
  : {})}
391
400
  {...(config.injectedPropsFilter
392
- ? config.injectedPropsFilter(injectedProps)
401
+ ? config.injectedPropsFilter(injectedProps, this.props)
393
402
  : injectedProps)}
394
403
  />
395
404
  );
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+
3
+ import {ClassNamesFn} from '../../theme';
4
+
5
+ export interface ItemActionsProps {
6
+ classnames: ClassNamesFn;
7
+ children?: JSX.Element;
8
+ dom: HTMLTableRowElement;
9
+ }
10
+
11
+ export default class ItemActionsWrapper extends React.Component<ItemActionsProps, {}> {
12
+ render() {
13
+ const {classnames: cx, children, dom} = this.props;
14
+ if (!dom) {
15
+ return;
16
+ }
17
+
18
+ const frame = dom.closest('table')?.parentElement?.parentElement as HTMLElement;
19
+
20
+ const rect = dom.getBoundingClientRect();
21
+ const height = rect.height;
22
+ const top = rect.top - frame.getBoundingClientRect().top;
23
+
24
+ return (
25
+ <div
26
+ className={cx('Table-itemActions-wrap')}
27
+ style={{top: top + 'px', height: height + 'px'}}>
28
+ {children}
29
+ </div>
30
+ );
31
+ }
32
+ }
@@ -23,12 +23,13 @@ import Spinner from '../Spinner';
23
23
  import HeadCellSort from './HeadCellSort';
24
24
  import HeadCellFilter from './HeadCellFilter';
25
25
  import HeadCellSelect from './HeadCellSelect';
26
+ import ItemActionsWrapper from './ItemActionsWrapper';
26
27
  import Cell from './Cell';
27
28
 
28
29
  export interface ColumnProps {
29
30
  title: string | React.ReactNode | Function;
30
31
  key: string;
31
- className?: string;
32
+ className?: Function;
32
33
  children?: Array<ColumnProps>;
33
34
  render: Function;
34
35
  fixed?: boolean | string;
@@ -144,6 +145,7 @@ export interface TableProps extends ThemeProps, LocaleProps {
144
145
  showHeader?: boolean; // 是否展示表头
145
146
  onSelect?: Function;
146
147
  onSelectAll?: Function;
148
+ itemActions?: Function;
147
149
  }
148
150
 
149
151
  export interface ScrollProps {
@@ -156,6 +158,11 @@ export interface TableState {
156
158
  dataSource: Array<any>;
157
159
  expandedRowKeys: Array<string | number>;
158
160
  colWidths: Array<number>;
161
+ hoverRow: {
162
+ rowIndex?: number,
163
+ record: any,
164
+ target: HTMLTableRowElement
165
+ } | null;
159
166
  }
160
167
 
161
168
  function getMaxLevelThRowSpan(columns: Array<ColumnProps>) {
@@ -336,7 +343,8 @@ export class Table extends React.PureComponent<TableProps, TableState> {
336
343
  ? props.expandable.defaultExpandedRowKeys || []
337
344
  : [])
338
345
  ],
339
- colWidths: []
346
+ colWidths: [],
347
+ hoverRow: null
340
348
  };
341
349
 
342
350
  this.onTableContentScroll = this.onTableContentScroll.bind(this);
@@ -1104,43 +1112,43 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1104
1112
  );
1105
1113
  }
1106
1114
 
1107
- const children = (
1108
- <span>
1109
- {sort}
1110
- {filter}
1111
- {resizable ? (
1112
- <i
1113
- className={cx('Table-thead-resizable')}
1114
- onMouseDown={e => this.onResizeMouseDown(e, item.key)}
1115
- ></i>
1116
- ) : null}
1117
- </span>
1118
- );
1119
-
1120
- return (
1121
- <Cell
1122
- wrapperComponent="th"
1123
- rowSpan={item.rowSpan}
1124
- colSpan={item.colSpan}
1125
- key={'cell' + (item.key || i)}
1126
- fixed={item.fixed === true ? 'left' : item.fixed}
1127
- className={cx({
1128
- 'Table-cell-last':
1129
- i === maxCount - 1 && i === data.length - 1
1130
- })}
1131
- groupId={item.groupId}
1132
- depth={item.depth}
1133
- >
1134
- {typeof item.title === 'function'
1135
- ? item.title(children)
1136
- : item.title}
1137
- </Cell>
1138
- );
1139
- })}
1140
- </tr>
1141
- );
1142
- })}
1143
- </thead>
1115
+ const children = (
1116
+ <span>
1117
+ {sort}
1118
+ {filter}
1119
+ {resizable ? (
1120
+ <i
1121
+ className={cx('Table-thead-resizable')}
1122
+ onMouseDown={e => this.onResizeMouseDown(e, item.key)}
1123
+ ></i>
1124
+ ) : null}
1125
+ </span>
1126
+ );
1127
+
1128
+ return (
1129
+ <Cell
1130
+ wrapperComponent="th"
1131
+ rowSpan={item.rowSpan}
1132
+ colSpan={item.colSpan}
1133
+ key={`cell-${i}`}
1134
+ fixed={item.fixed === true ? 'left' : item.fixed}
1135
+ className={cx({
1136
+ 'Table-cell-last':
1137
+ i === maxCount - 1 && i === data.length - 1
1138
+ })}
1139
+ groupId={item.groupId}
1140
+ depth={item.depth}
1141
+ >
1142
+ {typeof item.title === 'function'
1143
+ ? item.title(children)
1144
+ : item.title}
1145
+ </Cell>
1146
+ );
1147
+ })}
1148
+ </tr>
1149
+ );
1150
+ })}
1151
+ </thead>
1144
1152
  );
1145
1153
  }
1146
1154
 
@@ -1182,8 +1190,17 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1182
1190
  }
1183
1191
  }
1184
1192
 
1185
- if (record && onRow) {
1186
- onRow.onRowMouseEnter && onRow.onRowMouseEnter(event, record, rowIndex);
1193
+ if (record) {
1194
+ let target = event.target;
1195
+ if (target.tagName !== 'TR') {
1196
+ target = target.closest('tr');
1197
+ }
1198
+
1199
+ this.setState({hoverRow: {target, rowIndex, record}}, () => {
1200
+ if (onRow) {
1201
+ onRow.onRowMouseEnter && onRow.onRowMouseEnter(event, record, rowIndex);
1202
+ }
1203
+ });
1187
1204
  }
1188
1205
  }
1189
1206
 
@@ -1206,11 +1223,17 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1206
1223
  }
1207
1224
  }
1208
1225
 
1209
- if (record && onRow) {
1210
- onRow.onRowMouseLeave && onRow.onRowMouseLeave(event, record, rowIndex);
1226
+ if (record) {
1227
+ if (onRow) {
1228
+ onRow.onRowMouseLeave && onRow.onRowMouseLeave(event, record, rowIndex);
1229
+ }
1211
1230
  }
1212
1231
  }
1213
1232
 
1233
+ onMouseLeave(event: React.ChangeEvent<any>) {
1234
+ this.setState({hoverRow: null});
1235
+ }
1236
+
1214
1237
  onExpandRow(data: any) {
1215
1238
  const {expandedRowKeys} = this.state;
1216
1239
  const {expandable} = this.props;
@@ -1396,7 +1419,8 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1396
1419
  levels.length > 0 ? (
1397
1420
  <span
1398
1421
  className={cx('Table-row-indent', `indent-level-${levels.length}`)}
1399
- style={{paddingLeft: indentSize * levels.length + 'px'}}
1422
+ style={levels.length > 0
1423
+ ? {paddingLeft: (indentSize * levels.length) + 'px'} : {}}
1400
1424
  ></span>
1401
1425
  ) : null;
1402
1426
 
@@ -1415,6 +1439,9 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1415
1439
  props.rowSpan === 1;
1416
1440
  }
1417
1441
  }
1442
+
1443
+ const className = typeof item.className === 'function'
1444
+ ? item.className(data, rowIndex) : ''
1418
1445
  return props.rowSpan === 0 || props.colSpan === 0 ? null : (
1419
1446
  <Cell
1420
1447
  key={i}
@@ -1422,15 +1449,16 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1422
1449
  fixed={item.fixed === true ? 'left' : item.fixed}
1423
1450
  column={item}
1424
1451
  groupId={item.groupId}
1452
+ className={cx({
1453
+ [`${className}`]: !!className
1454
+ })}
1425
1455
  >
1426
- <div
1427
- className={cx('Table-cell-wrapper', {
1428
- [cx('Table-cell-wrapper-prefix')]:
1429
- i === 0 &&
1430
- (!!indentDom || (levels.length === 0 && hasChildrenRow)),
1431
- [cx(`Table-cell-height-${lineHeight}`)]: !!lineHeight
1432
- })}
1433
- >
1456
+ <div className={cx('Table-cell-wrapper', {
1457
+ [cx('Table-cell-wrapper-prefix')]:
1458
+ i === 0 &&
1459
+ (!!indentDom || levels.length === 0 && hasChildrenRow),
1460
+ [cx(`Table-cell-height-${lineHeight}`)]: !!lineHeight
1461
+ })}>
1434
1462
  {i === 0 && levels.length > 0 ? indentDom : null}
1435
1463
  {i === 0 && hasChildrenRow
1436
1464
  ? this.getExpandedIcons(isExpanded, data)
@@ -1759,18 +1787,28 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1759
1787
  footSummary,
1760
1788
  loading,
1761
1789
  showHeader,
1790
+ itemActions,
1762
1791
  classnames: cx
1763
1792
  } = this.props;
1764
1793
 
1765
1794
  // 设置了横向滚动轴 则table的table-layout为fixed
1766
1795
  const hasScrollX = scroll && scroll.x;
1796
+ const hoverRow = this.state.hoverRow;
1767
1797
 
1768
1798
  return (
1769
1799
  <div
1770
1800
  ref={this.contentDom}
1771
1801
  className={cx('Table-content')}
1772
1802
  style={hasScrollX ? {overflow: 'auto hidden'} : {}}
1803
+ onMouseLeave={this.onMouseLeave.bind(this)}
1773
1804
  >
1805
+ {itemActions && hoverRow
1806
+ ? <ItemActionsWrapper
1807
+ dom={hoverRow.target}
1808
+ classnames={cx}>
1809
+ {typeof itemActions === 'function'
1810
+ ? itemActions(hoverRow.record, hoverRow.rowIndex) : null}
1811
+ </ItemActionsWrapper> : null}
1774
1812
  <table
1775
1813
  style={
1776
1814
  hasScrollX
@@ -1831,7 +1869,11 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1831
1869
  }
1832
1870
 
1833
1871
  renderScrollTableBody() {
1834
- const {scroll, classnames: cx} = this.props;
1872
+ const {
1873
+ scroll,
1874
+ itemActions,
1875
+ classnames: cx
1876
+ } = this.props;
1835
1877
 
1836
1878
  const style = {};
1837
1879
  const tableStyle = {};
@@ -1847,12 +1889,27 @@ export class Table extends React.PureComponent<TableProps, TableState> {
1847
1889
  });
1848
1890
  }
1849
1891
 
1892
+ const hoverRow = this.state.hoverRow;
1893
+
1850
1894
  return (
1851
- <div ref={this.bodyDom} className={cx('Table-body')} style={style}>
1852
- <table className={cx('Table-table')} style={tableStyle}>
1853
- {this.renderColGroup()}
1854
- {this.renderTBody()}
1855
- </table>
1895
+ <div
1896
+ ref={this.bodyDom}
1897
+ className={cx('Table-body')}
1898
+ style={style}
1899
+ onMouseLeave={this.onMouseLeave.bind(this)}>
1900
+ {itemActions && hoverRow
1901
+ ? <ItemActionsWrapper
1902
+ dom={hoverRow.target}
1903
+ classnames={cx}>
1904
+ {typeof itemActions === 'function'
1905
+ ? itemActions(hoverRow.record, hoverRow.rowIndex) : null}
1906
+ </ItemActionsWrapper> : null}
1907
+ <table
1908
+ className={cx('Table-table')}
1909
+ style={tableStyle}>
1910
+ {this.renderColGroup()}
1911
+ {this.renderTBody()}
1912
+ </table>
1856
1913
  </div>
1857
1914
  );
1858
1915
  }
@@ -34,10 +34,10 @@ export interface JSONSchemaProps
34
34
 
35
35
  const EnhancedInputJSONSchema = withRemoteConfig({
36
36
  sourceField: 'schema',
37
- injectedPropsFilter: props => {
37
+ injectedPropsFilter: (injectedProps, props) => {
38
38
  return {
39
- schema: props.config,
40
- loading: props.loading
39
+ schema: injectedProps.config,
40
+ loading: injectedProps.loading
41
41
  };
42
42
  }
43
43
  })(InputJSONSchema as any);
@@ -15,7 +15,10 @@ import {
15
15
  getTree,
16
16
  isEmpty,
17
17
  getTreeAncestors,
18
- normalizeNodePath
18
+ normalizeNodePath,
19
+ mapTree,
20
+ getTreeDepth,
21
+ flattenTree
19
22
  } from '../../utils/helper';
20
23
  import {reaction} from 'mobx';
21
24
  import {
@@ -637,16 +640,19 @@ export function registerOptionsControl(config: OptionsConfig) {
637
640
  } = this.props;
638
641
  let newValue: string | Array<Option> | Option = '';
639
642
  if (multiple) {
640
- newValue = valueArray;
643
+ /** 兼容tree数据结构 */
644
+ newValue =
645
+ getTreeDepth(valueArray) > 1 ? flattenTree(valueArray) : valueArray;
641
646
 
642
647
  if (joinValues) {
643
648
  newValue = (newValue as Array<any>)
644
649
  .map(item => item[valueField || 'value'])
650
+ .filter(item => item != null) /** tree的父节点可能没有value值 */
645
651
  .join(delimiter);
646
652
  } else if (extractValue) {
647
- newValue = (newValue as Array<any>).map(
648
- item => item[valueField || 'value']
649
- );
653
+ newValue = (newValue as Array<any>)
654
+ .map(item => item[valueField || 'value'])
655
+ .filter(item => item != null);
650
656
  }
651
657
  } else {
652
658
  newValue = valueArray[0] || resetValue;
@@ -660,14 +666,18 @@ export function registerOptionsControl(config: OptionsConfig) {
660
666
 
661
667
  @autobind
662
668
  async handleToggleAll() {
663
- const {value, onChange, formItem} = this.props;
669
+ const {value, onChange, formItem, valueField} = this.props;
664
670
 
665
671
  if (!formItem) {
666
672
  return;
667
673
  }
668
674
  const selectedOptions = formItem.getSelectedOptions(value);
675
+ /** 打平并过滤掉valueField不存在的case,保证全选时对比length一致 */
676
+ const filteredOptions = flattenTree(
677
+ formItem.filteredOptions.concat()
678
+ ).filter(item => item != null && item[valueField || 'value'] != null);
669
679
  let valueArray =
670
- selectedOptions.length === formItem.filteredOptions.length
680
+ selectedOptions.length === filteredOptions.length
671
681
  ? []
672
682
  : formItem.filteredOptions.concat();
673
683
  const newValue = this.formatValueArray(valueArray);
@@ -657,7 +657,6 @@ export function wrapControl<
657
657
  defaultValue: control.value,
658
658
  formItemValue: value, // 为了兼容老版本的自定义组件
659
659
  onChange: this.handleChange,
660
-
661
660
  onBlur: this.handleBlur,
662
661
  setValue: this.setValue,
663
662
  getValue: this.getValue,
@@ -113,6 +113,21 @@ export interface ColumnSchema {
113
113
  * 当前列是否展示
114
114
  */
115
115
  toggled?: boolean;
116
+
117
+ /**
118
+ * 列样式
119
+ */
120
+ className?: string;
121
+
122
+ /**
123
+ * 表头单元格样式
124
+ */
125
+ titleClassName?: string;
126
+
127
+ /**
128
+ * 单元格样式
129
+ */
130
+ classNameExpr?: string;
116
131
  }
117
132
 
118
133
  export interface RowSelectionOptionsSchema {
@@ -156,7 +171,7 @@ export interface RowSelectionSchema {
156
171
  /**
157
172
  * 已选择的key值表达式
158
173
  */
159
- selectedRowKeysExpr: string;
174
+ selectedRowKeysExpr?: string;
160
175
 
161
176
  /**
162
177
  * 已选择的key值表达式
@@ -583,7 +598,12 @@ export default class TableRenderer extends React.Component<
583
598
  }
584
599
 
585
600
  return (
586
- <div className={cx('Table-head-cell-wrapper')}>
601
+ <div
602
+ key={col}
603
+ className={cx('Table-head-cell-wrapper', {
604
+ [`${column.className}`]: !!column.className,
605
+ [`${column.titleClassName}`]: !!column.titleClassName
606
+ })}>
587
607
  {content}
588
608
  {remark}
589
609
  {children}
@@ -686,6 +706,14 @@ export default class TableRenderer extends React.Component<
686
706
  });
687
707
  }
688
708
 
709
+ // 设置了单元格样式
710
+ if (column.classNameExpr) {
711
+ clone.className = (record: any, rowIndex: number) => {
712
+ const className = filter(column.classNameExpr, {record, rowIndex});
713
+ return `${className}${column.className ? ` ${column.className}` : ''}`;
714
+ };
715
+ }
716
+
689
717
  // 设置了列搜索
690
718
  if (column.searchable) {
691
719
  clone.filterDropdown = (
@@ -1129,6 +1157,7 @@ export default class TableRenderer extends React.Component<
1129
1157
  classnames: cx,
1130
1158
  placeholder,
1131
1159
  rowClassNameExpr,
1160
+ itemActions,
1132
1161
  store,
1133
1162
  ...rest
1134
1163
  } = this.props;
@@ -1233,6 +1262,39 @@ export default class TableRenderer extends React.Component<
1233
1262
  };
1234
1263
  }
1235
1264
 
1265
+ let itemActionsConfig = undefined;
1266
+ if (itemActions) {
1267
+ const finalActions = Array.isArray(itemActions)
1268
+ ? itemActions.filter(action => !action.hiddenOnHover)
1269
+ : [];
1270
+
1271
+ if (!finalActions.length) {
1272
+ return null;
1273
+ }
1274
+
1275
+ itemActionsConfig = (record: any, rowIndex: number) => {
1276
+ return (
1277
+ <div className={cx('Table-itemActions')}>
1278
+ {finalActions.map((action, index) =>
1279
+ render(
1280
+ `itemAction/${index}`,
1281
+ {
1282
+ ...(action as any),
1283
+ isMenuItem: true
1284
+ },
1285
+ {
1286
+ key: index,
1287
+ item: record,
1288
+ data: record,
1289
+ rowIndex
1290
+ }
1291
+ )
1292
+ )}
1293
+ </div>
1294
+ );
1295
+ };
1296
+ }
1297
+
1236
1298
  return (
1237
1299
  <Table
1238
1300
  {...rest}
@@ -1252,6 +1314,7 @@ export default class TableRenderer extends React.Component<
1252
1314
  onSort={this.handleSort}
1253
1315
  onFilter={this.handleFilter}
1254
1316
  onDrag={this.handleDragOver}
1317
+ itemActions={itemActionsConfig}
1255
1318
  ></Table>
1256
1319
  );
1257
1320
  }