useColumns.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { createVNode as _createVNode } from "vue";
  3. var __rest = this && this.__rest || function (s, e) {
  4. var t = {};
  5. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  6. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  7. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  8. }
  9. return t;
  10. };
  11. import { warning } from '../../vc-util/warning';
  12. import { computed, watchEffect } from 'vue';
  13. import { INTERNAL_COL_DEFINE } from '../utils/legacyUtil';
  14. import { EXPAND_COLUMN } from '../constant';
  15. import { useInjectSlots } from '../../table/context';
  16. import { customRenderSlot } from '../../_util/vnode';
  17. function flatColumns(columns) {
  18. return columns.reduce((list, column) => {
  19. const {
  20. fixed
  21. } = column;
  22. // Convert `fixed='true'` to `fixed='left'` instead
  23. const parsedFixed = fixed === true ? 'left' : fixed;
  24. const subColumns = column.children;
  25. if (subColumns && subColumns.length > 0) {
  26. return [...list, ...flatColumns(subColumns).map(subColum => _extends({
  27. fixed: parsedFixed
  28. }, subColum))];
  29. }
  30. return [...list, _extends(_extends({}, column), {
  31. fixed: parsedFixed
  32. })];
  33. }, []);
  34. }
  35. function warningFixed(flattenColumns) {
  36. let allFixLeft = true;
  37. for (let i = 0; i < flattenColumns.length; i += 1) {
  38. const col = flattenColumns[i];
  39. if (allFixLeft && col.fixed !== 'left') {
  40. allFixLeft = false;
  41. } else if (!allFixLeft && col.fixed === 'left') {
  42. warning(false, `Index ${i - 1} of \`columns\` missing \`fixed='left'\` prop.`);
  43. break;
  44. }
  45. }
  46. let allFixRight = true;
  47. for (let i = flattenColumns.length - 1; i >= 0; i -= 1) {
  48. const col = flattenColumns[i];
  49. if (allFixRight && col.fixed !== 'right') {
  50. allFixRight = false;
  51. } else if (!allFixRight && col.fixed === 'right') {
  52. warning(false, `Index ${i + 1} of \`columns\` missing \`fixed='right'\` prop.`);
  53. break;
  54. }
  55. }
  56. }
  57. function revertForRtl(columns) {
  58. return columns.map(column => {
  59. const {
  60. fixed
  61. } = column,
  62. restProps = __rest(column, ["fixed"]);
  63. // Convert `fixed='left'` to `fixed='right'` instead
  64. let parsedFixed = fixed;
  65. if (fixed === 'left') {
  66. parsedFixed = 'right';
  67. } else if (fixed === 'right') {
  68. parsedFixed = 'left';
  69. }
  70. return _extends({
  71. fixed: parsedFixed
  72. }, restProps);
  73. });
  74. }
  75. /**
  76. * Parse `columns` & `children` into `columns`.
  77. */
  78. function useColumns(_ref, transformColumns) {
  79. let {
  80. prefixCls,
  81. columns: baseColumns,
  82. // children,
  83. expandable,
  84. expandedKeys,
  85. getRowKey,
  86. onTriggerExpand,
  87. expandIcon,
  88. rowExpandable,
  89. expandIconColumnIndex,
  90. direction,
  91. expandRowByClick,
  92. expandColumnWidth,
  93. expandFixed
  94. } = _ref;
  95. const contextSlots = useInjectSlots();
  96. // Add expand column
  97. const withExpandColumns = computed(() => {
  98. if (expandable.value) {
  99. let cloneColumns = baseColumns.value.slice();
  100. // >>> Warning if use `expandIconColumnIndex`
  101. if (process.env.NODE_ENV !== 'production' && expandIconColumnIndex.value >= 0) {
  102. warning(false, '`expandIconColumnIndex` is deprecated. Please use `Table.EXPAND_COLUMN` in `columns` instead.');
  103. }
  104. // >>> Insert expand column if not exist
  105. if (!cloneColumns.includes(EXPAND_COLUMN)) {
  106. const expandColIndex = expandIconColumnIndex.value || 0;
  107. if (expandColIndex >= 0) {
  108. cloneColumns.splice(expandColIndex, 0, EXPAND_COLUMN);
  109. }
  110. }
  111. // >>> Deduplicate additional expand column
  112. if (process.env.NODE_ENV !== 'production' && cloneColumns.filter(c => c === EXPAND_COLUMN).length > 1) {
  113. warning(false, 'There exist more than one `EXPAND_COLUMN` in `columns`.');
  114. }
  115. const expandColumnIndex = cloneColumns.indexOf(EXPAND_COLUMN);
  116. cloneColumns = cloneColumns.filter((column, index) => column !== EXPAND_COLUMN || index === expandColumnIndex);
  117. // >>> Check if expand column need to fixed
  118. const prevColumn = baseColumns.value[expandColumnIndex];
  119. let fixedColumn;
  120. if ((expandFixed.value === 'left' || expandFixed.value) && !expandIconColumnIndex.value) {
  121. fixedColumn = 'left';
  122. } else if ((expandFixed.value === 'right' || expandFixed.value) && expandIconColumnIndex.value === baseColumns.value.length) {
  123. fixedColumn = 'right';
  124. } else {
  125. fixedColumn = prevColumn ? prevColumn.fixed : null;
  126. }
  127. const expandedKeysValue = expandedKeys.value;
  128. const rowExpandableValue = rowExpandable.value;
  129. const expandIconValue = expandIcon.value;
  130. const prefixClsValue = prefixCls.value;
  131. const expandRowByClickValue = expandRowByClick.value;
  132. // >>> Create expandable column
  133. const expandColumn = {
  134. [INTERNAL_COL_DEFINE]: {
  135. class: `${prefixCls.value}-expand-icon-col`,
  136. columnType: 'EXPAND_COLUMN'
  137. },
  138. title: customRenderSlot(contextSlots.value, 'expandColumnTitle', {}, () => ['']),
  139. fixed: fixedColumn,
  140. class: `${prefixCls.value}-row-expand-icon-cell`,
  141. width: expandColumnWidth.value,
  142. customRender: _ref2 => {
  143. let {
  144. record,
  145. index
  146. } = _ref2;
  147. const rowKey = getRowKey.value(record, index);
  148. const expanded = expandedKeysValue.has(rowKey);
  149. const recordExpandable = rowExpandableValue ? rowExpandableValue(record) : true;
  150. const icon = expandIconValue({
  151. prefixCls: prefixClsValue,
  152. expanded,
  153. expandable: recordExpandable,
  154. record,
  155. onExpand: onTriggerExpand
  156. });
  157. if (expandRowByClickValue) {
  158. return _createVNode("span", {
  159. "onClick": e => e.stopPropagation()
  160. }, [icon]);
  161. }
  162. return icon;
  163. }
  164. };
  165. return cloneColumns.map(col => col === EXPAND_COLUMN ? expandColumn : col);
  166. }
  167. if (process.env.NODE_ENV !== 'production' && baseColumns.value.includes(EXPAND_COLUMN)) {
  168. warning(false, '`expandable` is not config but there exist `EXPAND_COLUMN` in `columns`.');
  169. }
  170. return baseColumns.value.filter(col => col !== EXPAND_COLUMN);
  171. });
  172. const mergedColumns = computed(() => {
  173. let finalColumns = withExpandColumns.value;
  174. if (transformColumns.value) {
  175. finalColumns = transformColumns.value(finalColumns);
  176. }
  177. // Always provides at least one column for table display
  178. if (!finalColumns.length) {
  179. finalColumns = [{
  180. customRender: () => null
  181. }];
  182. }
  183. return finalColumns;
  184. });
  185. const flattenColumns = computed(() => {
  186. if (direction.value === 'rtl') {
  187. return revertForRtl(flatColumns(mergedColumns.value));
  188. }
  189. return flatColumns(mergedColumns.value);
  190. });
  191. // Only check out of production since it's waste for each render
  192. if (process.env.NODE_ENV !== 'production') {
  193. watchEffect(() => {
  194. setTimeout(() => {
  195. warningFixed(flattenColumns.value);
  196. });
  197. });
  198. }
  199. return [mergedColumns, flattenColumns];
  200. }
  201. export default useColumns;