@douyinfe/semi-foundation 2.96.1 → 2.98.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 (235) hide show
  1. package/cascader/foundation.ts +74 -19
  2. package/codeHighlight/codeHighlight.scss +1 -1
  3. package/datePicker/datePicker.scss +100 -5
  4. package/datePicker/foundation.ts +7 -0
  5. package/datePicker/inputFoundation.ts +5 -0
  6. package/form/foundation.ts +55 -7
  7. package/form/utils.ts +7 -2
  8. package/image/previewImageFoundation.ts +34 -3
  9. package/image/previewInnerFoundation.ts +15 -4
  10. package/input/textarea.scss +35 -0
  11. package/inputNumber/foundation.ts +119 -3
  12. package/jsonViewer/jsonViewer.scss +2 -2
  13. package/lib/cjs/aiChatInput/aiChatInput.css +7 -7
  14. package/lib/cjs/anchor/anchor.css +3 -3
  15. package/lib/cjs/autoComplete/autoComplete.css +1 -1
  16. package/lib/cjs/avatar/avatar.css +5 -5
  17. package/lib/cjs/badge/badge.css +1 -1
  18. package/lib/cjs/breadcrumb/breadcrumb.css +2 -2
  19. package/lib/cjs/calendar/calendar.css +9 -9
  20. package/lib/cjs/cascader/cascader.css +6 -6
  21. package/lib/cjs/cascader/foundation.d.ts +12 -0
  22. package/lib/cjs/cascader/foundation.js +68 -23
  23. package/lib/cjs/checkbox/checkbox.css +2 -2
  24. package/lib/cjs/codeHighlight/codeHighlight.css +1 -1
  25. package/lib/cjs/codeHighlight/codeHighlight.scss +1 -1
  26. package/lib/cjs/collapse/collapse.css +2 -2
  27. package/lib/cjs/datePicker/datePicker.css +75 -13
  28. package/lib/cjs/datePicker/datePicker.scss +100 -5
  29. package/lib/cjs/datePicker/foundation.d.ts +5 -0
  30. package/lib/cjs/datePicker/foundation.js +2 -0
  31. package/lib/cjs/datePicker/inputFoundation.d.ts +5 -0
  32. package/lib/cjs/descriptions/descriptions.css +6 -6
  33. package/lib/cjs/dropdown/dropdown.css +2 -2
  34. package/lib/cjs/form/form.css +4 -4
  35. package/lib/cjs/form/foundation.d.ts +1 -1
  36. package/lib/cjs/form/foundation.js +55 -9
  37. package/lib/cjs/form/utils.js +5 -2
  38. package/lib/cjs/hotKeys/hotKeys.css +2 -2
  39. package/lib/cjs/image/image.css +2 -2
  40. package/lib/cjs/image/previewImageFoundation.d.ts +4 -0
  41. package/lib/cjs/image/previewImageFoundation.js +33 -2
  42. package/lib/cjs/image/previewInnerFoundation.d.ts +1 -0
  43. package/lib/cjs/image/previewInnerFoundation.js +17 -4
  44. package/lib/cjs/input/input.css +8 -8
  45. package/lib/cjs/input/textarea.css +19 -2
  46. package/lib/cjs/input/textarea.scss +35 -0
  47. package/lib/cjs/inputNumber/foundation.d.ts +15 -0
  48. package/lib/cjs/inputNumber/foundation.js +113 -3
  49. package/lib/cjs/jsonViewer/jsonViewer.css +2 -2
  50. package/lib/cjs/jsonViewer/jsonViewer.scss +2 -2
  51. package/lib/cjs/list/list.css +1 -1
  52. package/lib/cjs/modal/modal.css +1 -1
  53. package/lib/cjs/navigation/navigation.css +4 -3
  54. package/lib/cjs/navigation/navigation.scss +1 -0
  55. package/lib/cjs/navigation/variables.scss +1 -1
  56. package/lib/cjs/notification/notification.css +4 -4
  57. package/lib/cjs/overflowList/foundation.d.ts +1 -0
  58. package/lib/cjs/overflowList/foundation.js +51 -1
  59. package/lib/cjs/pagination/pagination.css +5 -5
  60. package/lib/cjs/popconfirm/popconfirm.css +1 -1
  61. package/lib/cjs/popover/popover.css +1 -1
  62. package/lib/cjs/radio/radio.css +2 -2
  63. package/lib/cjs/scrollList/itemFoundation.js +12 -0
  64. package/lib/cjs/scrollList/scrollList.css +2 -2
  65. package/lib/cjs/select/foundation.d.ts +1 -1
  66. package/lib/cjs/select/foundation.js +28 -2
  67. package/lib/cjs/select/select.css +6 -6
  68. package/lib/cjs/sideSheet/sideSheet.css +2 -2
  69. package/lib/cjs/sidebar/sidebar.css +11 -11
  70. package/lib/cjs/slider/foundation.js +46 -12
  71. package/lib/cjs/slider/rtl.scss +62 -0
  72. package/lib/cjs/slider/slider.css +45 -0
  73. package/lib/cjs/slider/slider.scss +2 -0
  74. package/lib/cjs/steps/steps.css +11 -11
  75. package/lib/cjs/switch/switch.css +1 -0
  76. package/lib/cjs/switch/switch.scss +1 -0
  77. package/lib/cjs/switch/variables.scss +2 -1
  78. package/lib/cjs/table/foundation.d.ts +36 -0
  79. package/lib/cjs/table/foundation.js +164 -29
  80. package/lib/cjs/table/table.css +10 -2
  81. package/lib/cjs/table/table.scss +17 -0
  82. package/lib/cjs/tabs/tabs.css +2 -2
  83. package/lib/cjs/tag/tag.css +28 -2
  84. package/lib/cjs/tag/tag.scss +33 -0
  85. package/lib/cjs/tagInput/tagInput.css +19 -2
  86. package/lib/cjs/tagInput/tagInput.scss +18 -0
  87. package/lib/cjs/timePicker/constants.d.ts +1 -0
  88. package/lib/cjs/timePicker/foundation.d.ts +7 -1
  89. package/lib/cjs/timePicker/foundation.js +62 -11
  90. package/lib/cjs/timePicker/timePicker.css +1 -1
  91. package/lib/cjs/timeline/timeline.css +2 -2
  92. package/lib/cjs/toast/toast.css +1 -1
  93. package/lib/cjs/tooltip/foundation.js +8 -5
  94. package/lib/cjs/tooltip/tooltip.css +1 -1
  95. package/lib/cjs/transfer/constants.d.ts +3 -1
  96. package/lib/cjs/transfer/constants.js +3 -1
  97. package/lib/cjs/transfer/foundation.d.ts +3 -0
  98. package/lib/cjs/transfer/foundation.js +4 -0
  99. package/lib/cjs/transfer/transfer.css +14 -5
  100. package/lib/cjs/transfer/transfer.scss +10 -0
  101. package/lib/cjs/tree/foundation.d.ts +3 -0
  102. package/lib/cjs/tree/foundation.js +31 -4
  103. package/lib/cjs/tree/tree.css +1 -1
  104. package/lib/cjs/treeSelect/foundation.d.ts +1 -0
  105. package/lib/cjs/treeSelect/foundation.js +8 -1
  106. package/lib/cjs/treeSelect/treeSelect.css +36 -4
  107. package/lib/cjs/treeSelect/treeSelect.scss +49 -1
  108. package/lib/cjs/typography/typography.css +8 -8
  109. package/lib/cjs/upload/upload.css +8 -8
  110. package/lib/cjs/utils/Store.d.ts +1 -1
  111. package/lib/cjs/utils/Store.js +1 -0
  112. package/lib/es/aiChatInput/aiChatInput.css +7 -7
  113. package/lib/es/anchor/anchor.css +3 -3
  114. package/lib/es/autoComplete/autoComplete.css +1 -1
  115. package/lib/es/avatar/avatar.css +5 -5
  116. package/lib/es/badge/badge.css +1 -1
  117. package/lib/es/breadcrumb/breadcrumb.css +2 -2
  118. package/lib/es/calendar/calendar.css +9 -9
  119. package/lib/es/cascader/cascader.css +6 -6
  120. package/lib/es/cascader/foundation.d.ts +12 -0
  121. package/lib/es/cascader/foundation.js +68 -23
  122. package/lib/es/checkbox/checkbox.css +2 -2
  123. package/lib/es/codeHighlight/codeHighlight.css +1 -1
  124. package/lib/es/codeHighlight/codeHighlight.scss +1 -1
  125. package/lib/es/collapse/collapse.css +2 -2
  126. package/lib/es/datePicker/datePicker.css +75 -13
  127. package/lib/es/datePicker/datePicker.scss +100 -5
  128. package/lib/es/datePicker/foundation.d.ts +5 -0
  129. package/lib/es/datePicker/foundation.js +2 -0
  130. package/lib/es/datePicker/inputFoundation.d.ts +5 -0
  131. package/lib/es/descriptions/descriptions.css +6 -6
  132. package/lib/es/dropdown/dropdown.css +2 -2
  133. package/lib/es/form/form.css +4 -4
  134. package/lib/es/form/foundation.d.ts +1 -1
  135. package/lib/es/form/foundation.js +55 -9
  136. package/lib/es/form/utils.js +5 -2
  137. package/lib/es/hotKeys/hotKeys.css +2 -2
  138. package/lib/es/image/image.css +2 -2
  139. package/lib/es/image/previewImageFoundation.d.ts +4 -0
  140. package/lib/es/image/previewImageFoundation.js +33 -2
  141. package/lib/es/image/previewInnerFoundation.d.ts +1 -0
  142. package/lib/es/image/previewInnerFoundation.js +17 -4
  143. package/lib/es/input/input.css +8 -8
  144. package/lib/es/input/textarea.css +19 -2
  145. package/lib/es/input/textarea.scss +35 -0
  146. package/lib/es/inputNumber/foundation.d.ts +15 -0
  147. package/lib/es/inputNumber/foundation.js +113 -3
  148. package/lib/es/jsonViewer/jsonViewer.css +2 -2
  149. package/lib/es/jsonViewer/jsonViewer.scss +2 -2
  150. package/lib/es/list/list.css +1 -1
  151. package/lib/es/modal/modal.css +1 -1
  152. package/lib/es/navigation/navigation.css +4 -3
  153. package/lib/es/navigation/navigation.scss +1 -0
  154. package/lib/es/navigation/variables.scss +1 -1
  155. package/lib/es/notification/notification.css +4 -4
  156. package/lib/es/overflowList/foundation.d.ts +1 -0
  157. package/lib/es/overflowList/foundation.js +51 -1
  158. package/lib/es/pagination/pagination.css +5 -5
  159. package/lib/es/popconfirm/popconfirm.css +1 -1
  160. package/lib/es/popover/popover.css +1 -1
  161. package/lib/es/radio/radio.css +2 -2
  162. package/lib/es/scrollList/itemFoundation.js +12 -0
  163. package/lib/es/scrollList/scrollList.css +2 -2
  164. package/lib/es/select/foundation.d.ts +1 -1
  165. package/lib/es/select/foundation.js +28 -2
  166. package/lib/es/select/select.css +6 -6
  167. package/lib/es/sideSheet/sideSheet.css +2 -2
  168. package/lib/es/sidebar/sidebar.css +11 -11
  169. package/lib/es/slider/foundation.js +46 -12
  170. package/lib/es/slider/rtl.scss +62 -0
  171. package/lib/es/slider/slider.css +45 -0
  172. package/lib/es/slider/slider.scss +2 -0
  173. package/lib/es/steps/steps.css +11 -11
  174. package/lib/es/switch/switch.css +1 -0
  175. package/lib/es/switch/switch.scss +1 -0
  176. package/lib/es/switch/variables.scss +2 -1
  177. package/lib/es/table/foundation.d.ts +36 -0
  178. package/lib/es/table/foundation.js +164 -29
  179. package/lib/es/table/table.css +10 -2
  180. package/lib/es/table/table.scss +17 -0
  181. package/lib/es/tabs/tabs.css +2 -2
  182. package/lib/es/tag/tag.css +28 -2
  183. package/lib/es/tag/tag.scss +33 -0
  184. package/lib/es/tagInput/tagInput.css +19 -2
  185. package/lib/es/tagInput/tagInput.scss +18 -0
  186. package/lib/es/timePicker/constants.d.ts +1 -0
  187. package/lib/es/timePicker/foundation.d.ts +7 -1
  188. package/lib/es/timePicker/foundation.js +62 -11
  189. package/lib/es/timePicker/timePicker.css +1 -1
  190. package/lib/es/timeline/timeline.css +2 -2
  191. package/lib/es/toast/toast.css +1 -1
  192. package/lib/es/tooltip/foundation.js +8 -5
  193. package/lib/es/tooltip/tooltip.css +1 -1
  194. package/lib/es/transfer/constants.d.ts +3 -1
  195. package/lib/es/transfer/constants.js +3 -1
  196. package/lib/es/transfer/foundation.d.ts +3 -0
  197. package/lib/es/transfer/foundation.js +4 -0
  198. package/lib/es/transfer/transfer.css +14 -5
  199. package/lib/es/transfer/transfer.scss +10 -0
  200. package/lib/es/tree/foundation.d.ts +3 -0
  201. package/lib/es/tree/foundation.js +31 -4
  202. package/lib/es/tree/tree.css +1 -1
  203. package/lib/es/treeSelect/foundation.d.ts +1 -0
  204. package/lib/es/treeSelect/foundation.js +8 -1
  205. package/lib/es/treeSelect/treeSelect.css +36 -4
  206. package/lib/es/treeSelect/treeSelect.scss +49 -1
  207. package/lib/es/typography/typography.css +8 -8
  208. package/lib/es/upload/upload.css +8 -8
  209. package/lib/es/utils/Store.d.ts +1 -1
  210. package/lib/es/utils/Store.js +1 -0
  211. package/navigation/navigation.scss +1 -0
  212. package/navigation/variables.scss +1 -1
  213. package/overflowList/foundation.ts +48 -2
  214. package/package.json +19 -4
  215. package/scrollList/itemFoundation.ts +12 -0
  216. package/select/foundation.ts +27 -2
  217. package/slider/foundation.ts +55 -15
  218. package/slider/rtl.scss +62 -0
  219. package/slider/slider.scss +2 -0
  220. package/switch/switch.scss +1 -0
  221. package/switch/variables.scss +2 -1
  222. package/table/foundation.ts +199 -30
  223. package/table/table.scss +17 -0
  224. package/tag/tag.scss +33 -0
  225. package/tagInput/tagInput.scss +18 -0
  226. package/timePicker/constants.ts +2 -0
  227. package/timePicker/foundation.ts +62 -10
  228. package/tooltip/foundation.ts +8 -5
  229. package/transfer/constants.ts +3 -1
  230. package/transfer/foundation.ts +8 -1
  231. package/transfer/transfer.scss +10 -0
  232. package/tree/foundation.ts +34 -5
  233. package/treeSelect/foundation.ts +10 -1
  234. package/treeSelect/treeSelect.scss +49 -1
  235. package/utils/Store.ts +2 -1
@@ -21,6 +21,13 @@ import BaseFoundation, { DefaultAdapter } from '../base/foundation';
21
21
  import { strings, numbers } from './constants';
22
22
  import { mergeQueries, flattenColumns, filterColumns } from './utils';
23
23
  import { pullAll, withOrderSort } from '../utils/array';
24
+ import {
25
+ convertDataToEntities,
26
+ calcCheckedKeys,
27
+ calcCheckedKeysForChecked,
28
+ calcCheckedKeysForUnchecked,
29
+ findDescendantKeys,
30
+ } from '../tree/treeUtil';
24
31
 
25
32
  export interface BaseColumnProps<RecordType> {
26
33
  align?: BaseAlign;
@@ -78,8 +85,11 @@ export interface TableAdapter<RecordType> extends DefaultAdapter {
78
85
  setFlattenData: (flattenData: RecordType[]) => void;
79
86
  setAllRowKeys: (allRowKeys: BaseRowKeyType[]) => void;
80
87
  setHoveredRowKey: (hoveredRowKey: BaseRowKeyType) => void;
88
+ setHoveredRowKeys: (hoveredRowKeys: BaseRowKeyType[]) => void;
81
89
  setCachedFilteredSortedDataSource: (filteredSortedDataSource: RecordType[]) => void;
82
90
  setCachedFilteredSortedRowKeys: (filteredSortedRowKeys: BaseRowKeyType[]) => void;
91
+ setHalfCheckedRowKeys: (halfCheckedRowKeys: BaseRowKeyType[]) => void;
92
+ setKeyEntities: (keyEntities: BaseEntitys) => void;
83
93
  getCurrentPage: () => number;
84
94
  getCurrentPageSize: () => number;
85
95
  getCachedFilteredSortedDataSource: () => RecordType[];
@@ -88,6 +98,9 @@ export interface TableAdapter<RecordType> extends DefaultAdapter {
88
98
  setAllDisabledRowKeys: (allDisabledRowKeys: BaseRowKeyType[]) => void;
89
99
  getAllDisabledRowKeys: () => BaseRowKeyType[];
90
100
  getAllDisabledRowKeysSet: () => Set<BaseRowKeyType>;
101
+ getHalfCheckedRowKeys: () => BaseRowKeyType[];
102
+ getHalfCheckedRowKeysSet: () => Set<BaseRowKeyType>;
103
+ getKeyEntities: () => BaseEntitys;
91
104
  notifyFilterDropdownVisibleChange: (visible: boolean, dataIndex: string) => void;
92
105
  notifyChange: (changeInfo: { pagination: BasePagination; filters: BaseChangeInfoFilter<RecordType>[]; sorter: BaseChangeInfoSorter<RecordType>; extra: OnChangeExtra }) => void;
93
106
  notifyExpand: (expanded?: boolean, record?: BaseIncludeGroupRecord<RecordType>, mouseEvent?: any) => void;
@@ -107,7 +120,8 @@ export interface TableAdapter<RecordType> extends DefaultAdapter {
107
120
  getHandleColumns: () => (queries: BaseColumnProps<RecordType>[], cachedColumns: BaseColumnProps<RecordType>[]) => BaseColumnProps<RecordType>[];
108
121
  getMergePagination: () => (pagination: BasePagination) => BasePagination;
109
122
  setBodyHasScrollbar: (bodyHasScrollBar: boolean) => void;
110
- getTableLayout: () => 'fixed' | 'auto'
123
+ getTableLayout: () => 'fixed' | 'auto';
124
+ getCheckRelation: () => CheckRelation
111
125
  }
112
126
 
113
127
  class TableFoundation<RecordType> extends BaseFoundation<TableAdapter<RecordType>> {
@@ -756,30 +770,118 @@ class TableFoundation<RecordType> extends BaseFoundation<TableAdapter<RecordType
756
770
  return !(Array.isArray(dataSource) && dataSource.length > 0);
757
771
  }
758
772
 
773
+ /**
774
+ * Build tree data entities for checkRelation
775
+ * @param dataSource
776
+ * @returns keyEntities map
777
+ */
778
+ buildKeyEntities(dataSource?: RecordType[]): BaseEntitys {
779
+ dataSource = dataSource == null ? this._getDataSource() : dataSource;
780
+ const childrenRecordName = this.getProp('childrenRecordName');
781
+ const rowKey = this.getProp('rowKey');
782
+
783
+ // Convert table data to tree data format
784
+ const convertToTreeData = (data: RecordType[]): any[] => {
785
+ return data.map(record => {
786
+ const key = typeof rowKey === 'function' ? rowKey(record) : get(record, rowKey);
787
+ const children = get(record, childrenRecordName);
788
+ const node: any = { key, ...record };
789
+ if (Array.isArray(children) && children.length) {
790
+ node.children = convertToTreeData(children);
791
+ }
792
+ return node;
793
+ });
794
+ };
795
+
796
+ const treeData = convertToTreeData(dataSource);
797
+ const { keyEntities } = convertDataToEntities(treeData, { key: 'key', children: 'children' });
798
+ return keyEntities;
799
+ }
800
+
801
+ /**
802
+ * Calculate checked keys when checkRelation is 'related'
803
+ * @param realKey
804
+ * @param selected
805
+ * @param checkedKeys
806
+ * @param halfCheckedKeys
807
+ */
808
+ calcCheckedKeysForSelect(realKey: BaseRowKeyType, selected: boolean, checkedKeys: Set<string>, halfCheckedKeys: Set<string>) {
809
+ const keyEntities = this._adapter.getKeyEntities();
810
+ const keyStr = String(realKey);
811
+
812
+ // If keyEntities doesn't contain this key, handle it as a simple add/remove
813
+ if (!keyEntities || !keyEntities[keyStr]) {
814
+ if (selected) {
815
+ checkedKeys.add(keyStr);
816
+ } else {
817
+ checkedKeys.delete(keyStr);
818
+ }
819
+ return { checkedKeys, halfCheckedKeys };
820
+ }
821
+
822
+ if (selected) {
823
+ return calcCheckedKeysForChecked(keyStr, keyEntities, checkedKeys, halfCheckedKeys);
824
+ } else {
825
+ return calcCheckedKeysForUnchecked(keyStr, keyEntities, checkedKeys, halfCheckedKeys);
826
+ }
827
+ }
828
+
759
829
  handleSelectRow(realKey: BaseRowKeyType, selected: boolean, e: any) {
760
830
  this.stopPropagation(e);
761
831
  if (typeof selected === 'boolean' && realKey != null) {
832
+ const checkRelation = this._adapter.getCheckRelation();
762
833
  const selectedRowKeys = this._getSelectedRowKeys();
834
+ const halfCheckedRowKeys = [...(this._adapter.getHalfCheckedRowKeys() || [])];
763
835
  let foundIdx = -1;
764
836
  const selectedRow = this.getSelectedRows(null, [realKey])[0];
765
837
  let selectedRows: BaseIncludeGroupRecord<RecordType>[];
766
838
 
767
- if ((foundIdx = selectedRowKeys.indexOf(realKey)) > -1 && selected === false) {
768
- selectedRowKeys.splice(foundIdx, 1);
769
- selectedRows = this.getSelectedRows(null, selectedRowKeys);
839
+ if (checkRelation === 'related') {
840
+ // When checkRelation is 'related', use tree selection logic
841
+ const keyEntities = this._adapter.getKeyEntities();
842
+ // Convert keys to strings for tree utility functions
843
+ const checkedKeysSet = new Set(selectedRowKeys.map(key => String(key)));
844
+ const halfCheckedKeysSet = new Set(halfCheckedRowKeys.map(key => String(key)));
845
+
846
+ const { checkedKeys, halfCheckedKeys } = this.calcCheckedKeysForSelect(
847
+ String(realKey),
848
+ selected,
849
+ checkedKeysSet,
850
+ halfCheckedKeysSet
851
+ );
852
+
853
+ const newSelectedRowKeys = [...checkedKeys];
854
+ const newHalfCheckedRowKeys = [...halfCheckedKeys];
855
+ selectedRows = this.getSelectedRows(null, newSelectedRowKeys);
856
+
857
+ // Always update halfCheckedRowKeys state for checkRelation='related' mode
858
+ // This is needed for rendering the half-checked state in the UI
859
+ this._adapter.setHalfCheckedRowKeys(newHalfCheckedRowKeys);
860
+
770
861
  if (!this._selectionIsControlled()) {
771
- this._adapter.setSelectedRowKeys(selectedRowKeys);
862
+ this._adapter.setSelectedRowKeys(newSelectedRowKeys);
772
863
  }
773
864
  this._adapter.notifySelect(selectedRow, selected, selectedRows, e);
774
- this._adapter.notifySelectionChange(selectedRowKeys, selectedRows);
775
- } else if (selectedRowKeys.indexOf(realKey) === -1 && selected === true) {
776
- selectedRowKeys.push(realKey);
777
- selectedRows = this.getSelectedRows(null, selectedRowKeys);
778
- if (!this._selectionIsControlled()) {
779
- this._adapter.setSelectedRowKeys(selectedRowKeys);
865
+ this._adapter.notifySelectionChange(newSelectedRowKeys, selectedRows);
866
+ } else {
867
+ // Original logic for unRelated mode
868
+ if ((foundIdx = selectedRowKeys.indexOf(realKey)) > -1 && selected === false) {
869
+ selectedRowKeys.splice(foundIdx, 1);
870
+ selectedRows = this.getSelectedRows(null, selectedRowKeys);
871
+ if (!this._selectionIsControlled()) {
872
+ this._adapter.setSelectedRowKeys(selectedRowKeys);
873
+ }
874
+ this._adapter.notifySelect(selectedRow, selected, selectedRows, e);
875
+ this._adapter.notifySelectionChange(selectedRowKeys, selectedRows);
876
+ } else if (selectedRowKeys.indexOf(realKey) === -1 && selected === true) {
877
+ selectedRowKeys.push(realKey);
878
+ selectedRows = this.getSelectedRows(null, selectedRowKeys);
879
+ if (!this._selectionIsControlled()) {
880
+ this._adapter.setSelectedRowKeys(selectedRowKeys);
881
+ }
882
+ this._adapter.notifySelect(selectedRow, selected, selectedRows, e);
883
+ this._adapter.notifySelectionChange(selectedRowKeys, selectedRows);
780
884
  }
781
- this._adapter.notifySelect(selectedRow, selected, selectedRows, e);
782
- this._adapter.notifySelectionChange(selectedRowKeys, selectedRows);
783
885
  }
784
886
  }
785
887
  }
@@ -792,6 +894,7 @@ class TableFoundation<RecordType> extends BaseFoundation<TableAdapter<RecordType
792
894
  handleSelectAllRow(selected: boolean, e: any) {
793
895
  this.stopPropagation(e);
794
896
  if (typeof selected === 'boolean') {
897
+ const checkRelation = this._adapter.getCheckRelation();
795
898
  const curSelectedRowKeys = this._getSelectedRowKeys();
796
899
  let selectedRowKeys = [...curSelectedRowKeys];
797
900
  const selectedRowKeysSet = this._getSelectedRowKeysSet();
@@ -800,28 +903,78 @@ class TableFoundation<RecordType> extends BaseFoundation<TableAdapter<RecordType
800
903
  const disabledRowKeysSet = this._adapter.getAllDisabledRowKeysSet();
801
904
  let changedRowKeys;
802
905
 
803
- // Select all, if not disabled && not in selectedRowKeys
804
- if (selected) {
805
- for (const key of allRowKeys) {
806
- if (!disabledRowKeysSet.has(key) && !selectedRowKeysSet.has(key)) {
807
- selectedRowKeys.push(key);
906
+ if (checkRelation === 'related') {
907
+ // When checkRelation is 'related', use tree selection logic
908
+ const keyEntities = this._adapter.getKeyEntities();
909
+ const halfCheckedRowKeys = [...(this._adapter.getHalfCheckedRowKeys() || [])];
910
+ // Convert keys to strings for tree utility functions
911
+ let checkedKeysSet = new Set(selectedRowKeys.map(key => String(key)));
912
+ let halfCheckedKeysSet = new Set(halfCheckedRowKeys.map(key => String(key)));
913
+
914
+ if (selected) {
915
+ // Select all: add all non-disabled keys
916
+ const keysToAdd = allRowKeys.filter(key => !disabledRowKeysSet.has(key));
917
+ for (const key of keysToAdd) {
918
+ const keyStr = String(key);
919
+ if (!checkedKeysSet.has(keyStr) && keyEntities && keyEntities[keyStr]) {
920
+ const result = calcCheckedKeysForChecked(keyStr, keyEntities, checkedKeysSet, halfCheckedKeysSet);
921
+ checkedKeysSet = result.checkedKeys;
922
+ halfCheckedKeysSet = result.halfCheckedKeys;
923
+ }
808
924
  }
925
+ changedRowKeys = keysToAdd;
926
+ } else {
927
+ // Deselect all: remove all keys
928
+ const keysToRemove = [...checkedKeysSet];
929
+ for (const key of keysToRemove) {
930
+ if (keyEntities && keyEntities[key]) {
931
+ const result = calcCheckedKeysForUnchecked(key, keyEntities, checkedKeysSet, halfCheckedKeysSet);
932
+ checkedKeysSet = result.checkedKeys;
933
+ halfCheckedKeysSet = result.halfCheckedKeys;
934
+ }
935
+ }
936
+ changedRowKeys = [...curSelectedRowKeys];
937
+ }
938
+
939
+ selectedRowKeys = [...checkedKeysSet];
940
+ const newHalfCheckedRowKeys = [...halfCheckedKeysSet];
941
+ const changedRows = this.getSelectedRows(null, changedRowKeys || []);
942
+ const selectedRows = this.getSelectedRows(null, selectedRowKeys || []);
943
+
944
+ // Always update halfCheckedRowKeys state for checkRelation='related' mode
945
+ // This is needed for rendering the half-checked state in the UI
946
+ this._adapter.setHalfCheckedRowKeys(newHalfCheckedRowKeys);
947
+
948
+ if (!this._selectionIsControlled()) {
949
+ this._adapter.setSelectedRowKeys(selectedRowKeys);
809
950
  }
810
- allRowKeys = pullAll(allRowKeys, [...disabledRowKeys, ...curSelectedRowKeys]);
811
- changedRowKeys = [...allRowKeys];
951
+ this._adapter.notifySelectAll(selected, selectedRows, changedRows, e);
952
+ this._adapter.notifySelectionChange(selectedRowKeys, selectedRows);
812
953
  } else {
813
- selectedRowKeys = pullAll(selectedRowKeys, allRowKeys);
814
- changedRowKeys = [...curSelectedRowKeys];
815
- }
954
+ // Original logic for unRelated mode
955
+ // Select all, if not disabled && not in selectedRowKeys
956
+ if (selected) {
957
+ for (const key of allRowKeys) {
958
+ if (!disabledRowKeysSet.has(key) && !selectedRowKeysSet.has(key)) {
959
+ selectedRowKeys.push(key);
960
+ }
961
+ }
962
+ allRowKeys = pullAll(allRowKeys, [...disabledRowKeys, ...curSelectedRowKeys]);
963
+ changedRowKeys = [...allRowKeys];
964
+ } else {
965
+ selectedRowKeys = pullAll(selectedRowKeys, allRowKeys);
966
+ changedRowKeys = [...curSelectedRowKeys];
967
+ }
816
968
 
817
- const changedRows = this.getSelectedRows(null, changedRowKeys || []);
818
- const selectedRows = this.getSelectedRows(null, selectedRowKeys || []);
969
+ const changedRows = this.getSelectedRows(null, changedRowKeys || []);
970
+ const selectedRows = this.getSelectedRows(null, selectedRowKeys || []);
819
971
 
820
- if (!this._selectionIsControlled()) {
821
- this._adapter.setSelectedRowKeys(selectedRowKeys);
972
+ if (!this._selectionIsControlled()) {
973
+ this._adapter.setSelectedRowKeys(selectedRowKeys);
974
+ }
975
+ this._adapter.notifySelectAll(selected, selectedRows, changedRows, e);
976
+ this._adapter.notifySelectionChange(selectedRowKeys, selectedRows);
822
977
  }
823
- this._adapter.notifySelectAll(selected, selectedRows, changedRows, e);
824
- this._adapter.notifySelectionChange(selectedRowKeys, selectedRows);
825
978
  }
826
979
  }
827
980
 
@@ -1088,7 +1241,8 @@ class TableFoundation<RecordType> extends BaseFoundation<TableAdapter<RecordType
1088
1241
  * @param {*} e
1089
1242
  */
1090
1243
  handleSort(column: { dataIndex?: string; sortOrder?: BaseSortOrder } = {}, e: any, check = false) {
1091
- this.stopPropagation(e);
1244
+ /* Do not call stopPropagation here, otherwise the click event registered via onHeaderCell
1245
+ will be blocked when the click hot area is the whole title (#1861). */
1092
1246
  /* if mouse down to the resizable handle, do not trigger the sorting,fix #2802
1093
1247
  The target of the click event may be different from the target of the mousedown,
1094
1248
  e.g: Press the mouse, move to another node and then release it,
@@ -1282,4 +1436,19 @@ export type BaseIncludeGroupRecord<RecordType> = RecordType | { groupKey: string
1282
1436
 
1283
1437
  export type BaseEllipsis = boolean | { showTitle: boolean };
1284
1438
 
1439
+ export type CheckRelation = 'related' | 'unRelated';
1440
+
1441
+ export interface BaseEntity {
1442
+ key?: string | number;
1443
+ level?: number;
1444
+ children?: BaseEntity[];
1445
+ parent?: BaseEntity | null;
1446
+ data?: Record<string, any>;
1447
+ [key: string]: any
1448
+ }
1449
+
1450
+ export interface BaseEntitys {
1451
+ [key: string]: BaseEntity
1452
+ }
1453
+
1285
1454
  export default TableFoundation;
package/table/table.scss CHANGED
@@ -259,6 +259,23 @@ $module: #{$prefix}-table;
259
259
  display: table-row;
260
260
  background-color: $color-table_body-bg-default;
261
261
 
262
+ // Programmatic hover state (e.g. rowSpanHover feature)
263
+ // Keep visual effect consistent with native :hover
264
+ &.#{$module}-row-hovered {
265
+ & > .#{$module}-row-cell {
266
+ background-image: linear-gradient(0deg, $color-table_body-bg-hover, $color-table_body-bg-hover);
267
+ background-color: $color-table_cell-bg-hover;
268
+
269
+ &.#{$module}-cell-fixed {
270
+ &-left,
271
+ &-right {
272
+ background-image: linear-gradient(0deg, $color-table_body-bg-hover, $color-table_body-bg-hover);
273
+ background-color: $color-table_body-bg-default;
274
+ }
275
+ }
276
+ }
277
+ }
278
+
262
279
  &:hover {
263
280
  & > .#{$module}-row-cell {
264
281
  // $color-table_body-bg-hover has transparency,will reveal the background color $color-table_body-bg-default\
package/tag/tag.scss CHANGED
@@ -329,4 +329,37 @@ $types: "ghost", "solid", "light";
329
329
  color: $color-tag_avatar-text-default;
330
330
  }
331
331
 
332
+ .#{$module}-split {
333
+ display: inline-flex;
334
+ align-items: center;
335
+
336
+ .#{$module} {
337
+ border-radius: 0;
338
+ margin-right: 1px;
339
+
340
+ &-first {
341
+ border-top-left-radius: $radius-tag;
342
+ border-bottom-left-radius: $radius-tag;
343
+ }
344
+
345
+ &-last {
346
+ border-top-right-radius: $radius-tag;
347
+ border-bottom-right-radius: $radius-tag;
348
+ margin-right: unset;
349
+ }
350
+
351
+ &-circle {
352
+ &.#{$module}-first {
353
+ border-top-left-radius: $radius-tag_circle;
354
+ border-bottom-left-radius: $radius-tag_circle;
355
+ }
356
+
357
+ &.#{$module}-last {
358
+ border-top-right-radius: $radius-tag_circle;
359
+ border-bottom-right-radius: $radius-tag_circle;
360
+ }
361
+ }
362
+ }
363
+ }
364
+
332
365
  @import './rtl.scss';
@@ -137,6 +137,7 @@ $module: #{$prefix}-tagInput;
137
137
  padding-left: $spacing-extra-tight;
138
138
  padding-right: $spacing-extra-tight;
139
139
  overflow: hidden;
140
+ position: relative;
140
141
 
141
142
  &-tag {
142
143
  margin-right: $spacing-extra-tight;
@@ -190,6 +191,8 @@ $module: #{$prefix}-tagInput;
190
191
  & &-input {
191
192
  flex-grow: 1;
192
193
  width: min-content;
194
+ min-width: 2px;
195
+ max-width: 100%;
193
196
  // min-width: 38px;
194
197
  border: none;
195
198
  outline: none;
@@ -240,6 +243,21 @@ $module: #{$prefix}-tagInput;
240
243
  }
241
244
  }
242
245
  }
246
+
247
+ /* hidden mirror used to measure input text width */
248
+ &-inputMirror {
249
+ position: absolute;
250
+ top: 0;
251
+ left: 0;
252
+ visibility: hidden;
253
+ pointer-events: none;
254
+ height: 0;
255
+ overflow: hidden;
256
+ white-space: pre;
257
+ font-size: $font-size-regular;
258
+ font-weight: $font-weight-regular;
259
+ font-family: inherit;
260
+ }
243
261
  }
244
262
 
245
263
  &-clearBtn {
@@ -6,6 +6,8 @@ const TYPE_TIME_RANGE_PICKER = 'timeRange' as const;
6
6
  const DEFAULT_RANGE_SEPARATOR = ' ~ ' as const;
7
7
  const DEFAULT_MULTIPLE_SEPARATOR = ',' as const;
8
8
 
9
+ export type PanelType = 'left' | 'right';
10
+
9
11
  const cssClasses = {
10
12
  PREFIX: `${BASE_CLASS_PREFIX}-timepicker`,
11
13
  RANGE_PICKER: `${BASE_CLASS_PREFIX}-timepicker-range-panel`,
@@ -1,4 +1,5 @@
1
1
  import { strings } from './constants';
2
+ import type { PanelType } from './constants';
2
3
  import BaseFoundation, { DefaultAdapter } from '../base/foundation';
3
4
  import {
4
5
  formatToString,
@@ -70,8 +71,35 @@ class TimePickerFoundation<P = Record<string, any>, S = Record<string, any>> ext
70
71
  return position || rtlDirection || strings.DEFAULT_POSITION[type];
71
72
  }
72
73
 
73
- isDisabledHMS({ hours, minutes, seconds }: { hours: number; minutes: number; seconds: number }) {
74
- const { disabledHours, disabledMinutes, disabledSeconds } = this.getProps();
74
+ getDisabledTimeFns(panelType: PanelType, dates: Date[]) {
75
+ const { disabledHours, disabledMinutes, disabledSeconds, disabledTime } = this.getProps() as any;
76
+
77
+ // disabledTime is range-only: only invoke it when the picker is
78
+ // actually a range picker. In single mode panelType has no meaning, so
79
+ // we fall back to the top-level disabledHours / disabledMinutes /
80
+ // disabledSeconds without invoking disabledTime.
81
+ if (typeof disabledTime === 'function' && this._adapter.isRangePicker()) {
82
+ const disabledObj = disabledTime(dates, panelType) || {};
83
+ return {
84
+ disabledHours: disabledObj.disabledHours || disabledHours,
85
+ disabledMinutes: disabledObj.disabledMinutes || disabledMinutes,
86
+ disabledSeconds: disabledObj.disabledSeconds || disabledSeconds,
87
+ };
88
+ }
89
+
90
+ return {
91
+ disabledHours,
92
+ disabledMinutes,
93
+ disabledSeconds,
94
+ };
95
+ }
96
+
97
+ isDisabledHMS(
98
+ { hours, minutes, seconds }: { hours: number; minutes: number; seconds: number },
99
+ panelType: PanelType = 'left',
100
+ dates: Date[] = []
101
+ ) {
102
+ const { disabledHours, disabledMinutes, disabledSeconds } = this.getDisabledTimeFns(panelType, dates);
75
103
  const hDis = !isNullOrUndefined(hours) && hourIsDisabled(disabledHours, hours);
76
104
  const mDis = !isNullOrUndefined(hours) && !isNullOrUndefined(minutes) && minuteIsDisabled(disabledMinutes, hours, minutes);
77
105
  const sDis =
@@ -123,8 +151,8 @@ class TimePickerFoundation<P = Record<string, any>, S = Record<string, any>> ext
123
151
  });
124
152
 
125
153
  const isAM = [true, false];
126
- parsedValues.map((item, idx)=>{
127
- isAM[idx]= getHours(item) < 12;
154
+ parsedValues.map((item, idx) => {
155
+ isAM[idx] = getHours(item) < 12;
128
156
  });
129
157
 
130
158
  if (parsedValues.length === value.length) {
@@ -213,9 +241,21 @@ class TimePickerFoundation<P = Record<string, any>, S = Record<string, any>> ext
213
241
  )
214
242
  );
215
243
  }
216
- invalid = dates.some(d =>
217
- this.isDisabledHMS({ hours: d.getHours(), minutes: d.getMinutes(), seconds: d.getSeconds() })
218
- );
244
+ if (this._adapter.isRangePicker()) {
245
+ invalid = dates.some((d, idx) => {
246
+ const panelType: PanelType = idx === 1 ? 'right' : 'left';
247
+ return this.isDisabledHMS(
248
+ { hours: d.getHours(), minutes: d.getMinutes(), seconds: d.getSeconds() },
249
+ panelType,
250
+ dates
251
+ );
252
+ });
253
+ } else {
254
+ const d = dates[0];
255
+ invalid = d
256
+ ? this.isDisabledHMS({ hours: d.getHours(), minutes: d.getMinutes(), seconds: d.getSeconds() }, 'left', dates)
257
+ : false;
258
+ }
219
259
  }
220
260
  const inputValue = this.formatValue(dates);
221
261
 
@@ -325,9 +365,21 @@ class TimePickerFoundation<P = Record<string, any>, S = Record<string, any>> ext
325
365
  let invalid = dates.some(d => isNaN(Number(d)));
326
366
 
327
367
  if (!invalid) {
328
- invalid = dates.some(d =>
329
- this.isDisabledHMS({ hours: d.getHours(), minutes: d.getMinutes(), seconds: d.getSeconds() })
330
- );
368
+ if (this._adapter.isRangePicker()) {
369
+ invalid = dates.some((d, idx) => {
370
+ const panelType: PanelType = idx === 1 ? 'right' : 'left';
371
+ return this.isDisabledHMS(
372
+ { hours: d.getHours(), minutes: d.getMinutes(), seconds: d.getSeconds() },
373
+ panelType,
374
+ dates
375
+ );
376
+ });
377
+ } else {
378
+ const d = dates[0];
379
+ invalid = d
380
+ ? this.isDisabledHMS({ hours: d.getHours(), minutes: d.getMinutes(), seconds: d.getSeconds() }, 'left', dates)
381
+ : false;
382
+ }
331
383
  }
332
384
 
333
385
  return invalid;
@@ -210,7 +210,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
210
210
  switch (types) {
211
211
  case 'focus':
212
212
  triggerEventSet[eventNames.focus] = () => {
213
- this.delayShow();
213
+ this.getProp('condition') !== false && this.delayShow();
214
214
  };
215
215
  triggerEventSet[eventNames.blur] = () => {
216
216
  this.delayHide();
@@ -220,7 +220,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
220
220
  case 'click':
221
221
  triggerEventSet[eventNames.click] = () => {
222
222
  // this.delayShow();
223
- this.show();
223
+ this.getProp('condition') !== false && this.show();
224
224
  };
225
225
  portalEventSet = {};
226
226
  // Click outside needs special treatment, can not be directly tied to the trigger Element, need to be bound to the document
@@ -229,7 +229,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
229
229
  triggerEventSet[eventNames.mouseEnter] = () => {
230
230
  // console.log(e);
231
231
  this.setCache('isClickToHide', false);
232
- this.delayShow();
232
+ this.getProp('condition') !== false && this.delayShow();
233
233
  // this.show('trigger');
234
234
  };
235
235
  triggerEventSet[eventNames.mouseLeave] = () => {
@@ -240,7 +240,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
240
240
  // bind focus to hover trigger for a11y
241
241
  triggerEventSet[eventNames.focus] = () => {
242
242
  const { disableFocusListener } = this.getProps();
243
- !disableFocusListener && this.delayShow();
243
+ this.getProp('condition') !== false && !disableFocusListener && this.delayShow();
244
244
  };
245
245
  triggerEventSet[eventNames.blur] = () => {
246
246
  const { disableFocusListener } = this.getProps();
@@ -259,7 +259,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
259
259
  return;
260
260
  }
261
261
 
262
- this.delayShow();
262
+ this.getProp('condition') !== false && this.delayShow();
263
263
  };
264
264
  }
265
265
  break;
@@ -269,6 +269,9 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
269
269
  break;
270
270
  case 'contextMenu':
271
271
  triggerEventSet[eventNames.contextMenu] = (e) => {
272
+ if (this.getProp('condition') === false) {
273
+ return;
274
+ }
272
275
  e.preventDefault();
273
276
  this.show();
274
277
  };
@@ -10,6 +10,8 @@ const strings = {
10
10
  TYPE_TREE_TO_LIST: 'treeList',
11
11
  };
12
12
 
13
- const numbers = {};
13
+ const numbers = {
14
+ DEFAULT_PAGE_SIZE: 10,
15
+ };
14
16
 
15
17
  export { cssClasses, strings, numbers };
@@ -40,7 +40,9 @@ export interface TransferAdapter<P = Record<string, any>, S = Record<string, any
40
40
  notifyDeselect: (items: BasicDataItem) => void;
41
41
  updateInput: (input: string) => void;
42
42
  updateSearchResult: (searchResult: Set<number | string>) => void;
43
- searchTree: (keyword: string) => void
43
+ searchTree: (keyword: string) => void;
44
+ updateCurrentPage: (currentPage: number) => void;
45
+ notifyPageChange: (currentPage: number) => void;
44
46
  }
45
47
 
46
48
  export default class TransferFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<TransferAdapter<P, S>> {
@@ -253,4 +255,9 @@ export default class TransferFoundation<P = Record<string, any>, S = Record<stri
253
255
  this._notifyChange(newSelectedItems);
254
256
  }
255
257
 
258
+ handlePageChange(currentPage: number) {
259
+ this._adapter.updateCurrentPage(currentPage);
260
+ this._adapter.notifyPageChange(currentPage);
261
+ }
262
+
256
263
  }
@@ -118,6 +118,16 @@ $module: #{$prefix}-transfer;
118
118
  flex-grow: 1;
119
119
  }
120
120
 
121
+ &-pagination {
122
+ padding-top: $spacing-base-tight;
123
+ padding-bottom: $spacing-base-tight;
124
+ padding-left: $spacing-base-tight;
125
+ padding-right: $spacing-base-tight;
126
+ flex-shrink: 0;
127
+ display: flex;
128
+ justify-content: center;
129
+ }
130
+
121
131
  &-empty {
122
132
  height: $height-transfer_left_empty;
123
133
  }