Merge branches 'next' and 'next' of https://github.com/vueComponent/ant-design-vue into next
						commit
						948727a2ef
					
				|  | @ -0,0 +1,55 @@ | |||
| import { VNodeTypes, HTMLAttributes, FunctionalComponent } from 'vue'; | ||||
| 
 | ||||
| function notEmpty(val: any) { | ||||
|   return val !== undefined && val !== null; | ||||
| } | ||||
| 
 | ||||
| interface CellProps extends HTMLAttributes { | ||||
|   itemPrefixCls: string; | ||||
|   span: number; | ||||
|   component: string; | ||||
|   bordered?: boolean; | ||||
|   label?: VNodeTypes; | ||||
|   content?: VNodeTypes; | ||||
|   colon?: boolean; | ||||
| } | ||||
| 
 | ||||
| const Cell: FunctionalComponent<CellProps> = props => { | ||||
|   const { itemPrefixCls, component, span, bordered, label, content, colon } = props; | ||||
|   const Component = component as any; | ||||
|   if (bordered) { | ||||
|     return ( | ||||
|       <Component | ||||
|         class={[ | ||||
|           { | ||||
|             [`${itemPrefixCls}-item-label`]: notEmpty(label), | ||||
|             [`${itemPrefixCls}-item-content`]: notEmpty(content), | ||||
|           }, | ||||
|         ]} | ||||
|         colSpan={span} | ||||
|       > | ||||
|         {notEmpty(label) ? label : content} | ||||
|       </Component> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <Component class={[`${itemPrefixCls}-item`]} colSpan={span}> | ||||
|       {label && ( | ||||
|         <span | ||||
|           class={[ | ||||
|             `${itemPrefixCls}-item-label`, | ||||
|             { | ||||
|               [`${itemPrefixCls}-item-no-colon`]: !colon, | ||||
|             }, | ||||
|           ]} | ||||
|         > | ||||
|           {label} | ||||
|         </span> | ||||
|       )} | ||||
|       {content && <span class={`${itemPrefixCls}-item-content`}>{content}</span>} | ||||
|     </Component> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Cell; | ||||
|  | @ -1,82 +0,0 @@ | |||
| import { SetupContext, VNode } from 'vue'; | ||||
| import { getOptionProps } from '../_util/props-util'; | ||||
| 
 | ||||
| interface ColProps { | ||||
|   child: VNode; | ||||
|   bordered: boolean; | ||||
|   colon: boolean; | ||||
|   type?: 'label' | 'content'; | ||||
|   layout?: 'horizontal' | 'vertical'; | ||||
|   colKey?: string; | ||||
| } | ||||
| const Col = (_props: ColProps, { attrs }: SetupContext) => { | ||||
|   const { | ||||
|     child = {} as VNode, | ||||
|     bordered, | ||||
|     colon, | ||||
|     type, | ||||
|     layout, | ||||
|     colKey: key, | ||||
|   } = (attrs as unknown) as ColProps; | ||||
|   const { prefixCls, span = 1 } = getOptionProps(child); | ||||
|   const { children = {} as any, props = {} } = child; | ||||
|   const label = props.label || (children.label && children.label()); | ||||
|   const defaultSlot = children.default && children.default(); | ||||
| 
 | ||||
|   const labelProps: any = { | ||||
|     class: [ | ||||
|       `${prefixCls}-item-label`, | ||||
|       { | ||||
|         [`${prefixCls}-item-colon`]: colon, | ||||
|         [`${prefixCls}-item-no-label`]: !label, | ||||
|       }, | ||||
|     ], | ||||
|     key: `${key}-label`, | ||||
|   }; | ||||
| 
 | ||||
|   if (layout === 'vertical') { | ||||
|     labelProps.colspan = span * 2 - 1; | ||||
|   } | ||||
| 
 | ||||
|   if (bordered) { | ||||
|     if (type === 'label') { | ||||
|       return <th {...labelProps}>{label}</th>; | ||||
|     } | ||||
|     return ( | ||||
|       <td class={`${prefixCls}-item-content`} key={`${key}-content`} colspan={span * 2 - 1}> | ||||
|         {defaultSlot} | ||||
|       </td> | ||||
|     ); | ||||
|   } | ||||
|   if (layout === 'vertical') { | ||||
|     if (type === 'content') { | ||||
|       return ( | ||||
|         <td colspan={span} class={`${prefixCls}-item`}> | ||||
|           <span class={`${prefixCls}-item-content`} key={`${key}-content`}> | ||||
|             {defaultSlot} | ||||
|           </span> | ||||
|         </td> | ||||
|       ); | ||||
|     } | ||||
|     return ( | ||||
|       <td colspan={span} class={`${prefixCls}-item`}> | ||||
|         <span | ||||
|           class={[`${prefixCls}-item-label`, { [`${prefixCls}-item-colon`]: colon }]} | ||||
|           key={`${key}-label`} | ||||
|         > | ||||
|           {label} | ||||
|         </span> | ||||
|       </td> | ||||
|     ); | ||||
|   } | ||||
|   return ( | ||||
|     <td colspan={span} class={`${prefixCls}-item`}> | ||||
|       <span {...labelProps}>{label}</span> | ||||
|       <span class={`${prefixCls}-item-content`} key={`${key}-content`}> | ||||
|         {defaultSlot} | ||||
|       </span> | ||||
|     </td> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Col; | ||||
|  | @ -0,0 +1,109 @@ | |||
| import Cell from './Cell'; | ||||
| import { getOptionProps, getSlot, getClass, getStyle, getComponent } from '../_util/props-util'; | ||||
| import { FunctionalComponent } from 'vue'; | ||||
| 
 | ||||
| interface CellConfig { | ||||
|   component: string | [string, string]; | ||||
|   type: string; | ||||
|   showLabel?: boolean; | ||||
|   showContent?: boolean; | ||||
| } | ||||
| 
 | ||||
| export interface RowProps { | ||||
|   prefixCls: string; | ||||
|   vertical: boolean; | ||||
|   row: any[]; | ||||
|   bordered: boolean; | ||||
|   colon: boolean; | ||||
|   index: number; | ||||
| } | ||||
| 
 | ||||
| const Row: FunctionalComponent<RowProps> = props => { | ||||
|   const renderCells = ( | ||||
|     items, | ||||
|     { colon, prefixCls, bordered }, | ||||
|     { component, type, showLabel, showContent }: CellConfig, | ||||
|   ) => { | ||||
|     return items.map((item, index) => { | ||||
|       const { prefixCls: itemPrefixCls = prefixCls, span = 1 } = getOptionProps(item); | ||||
|       const label = getComponent(item, 'label'); | ||||
| 
 | ||||
|       const children = getSlot(item); | ||||
|       const className = getClass(item); | ||||
|       const style = getStyle(item); | ||||
|       const { key } = item; | ||||
| 
 | ||||
|       if (typeof component === 'string') { | ||||
|         return ( | ||||
|           <Cell | ||||
|             key={`${type}-${key || index}`} | ||||
|             class={className} | ||||
|             style={style} | ||||
|             span={span} | ||||
|             colon={colon} | ||||
|             component={component} | ||||
|             itemPrefixCls={itemPrefixCls} | ||||
|             bordered={bordered} | ||||
|             label={showLabel ? label : null} | ||||
|             content={showContent ? children : null} | ||||
|           /> | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|       return [ | ||||
|         <Cell | ||||
|           key={`label-${key || index}`} | ||||
|           class={className} | ||||
|           style={style} | ||||
|           span={1} | ||||
|           colon={colon} | ||||
|           component={component[0]} | ||||
|           itemPrefixCls={itemPrefixCls} | ||||
|           bordered={bordered} | ||||
|           label={label} | ||||
|         />, | ||||
|         <Cell | ||||
|           key={`content-${key || index}`} | ||||
|           class={className} | ||||
|           style={style} | ||||
|           span={span * 2 - 1} | ||||
|           component={component[1]} | ||||
|           itemPrefixCls={itemPrefixCls} | ||||
|           bordered={bordered} | ||||
|           content={children} | ||||
|         />, | ||||
|       ]; | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   const { prefixCls, vertical, row, index, bordered } = props; | ||||
|   if (vertical) { | ||||
|     return ( | ||||
|       <> | ||||
|         <tr key={`label-${index}`} class={`${prefixCls}-row`}> | ||||
|           {renderCells(row, props, { component: 'th', type: 'label', showLabel: true })} | ||||
|         </tr> | ||||
|         <tr key={`content-${index}`} class={`${prefixCls}-row`}> | ||||
|           {renderCells(row, props, { | ||||
|             component: 'td', | ||||
|             type: 'content', | ||||
|             showContent: true, | ||||
|           })} | ||||
|         </tr> | ||||
|       </> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <tr key={index} class={`${prefixCls}-row`}> | ||||
|       {renderCells(row, props, { | ||||
|         component: bordered ? ['th', 'td'] : 'td', | ||||
|         type: 'item', | ||||
|         showLabel: true, | ||||
|         showContent: true, | ||||
|       })} | ||||
|     </tr> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Row; | ||||
|  | @ -7,7 +7,7 @@ exports[`Descriptions Descriptions support colon 1`] = ` | |||
|     <table> | ||||
|       <tbody> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="3" class="ant-descriptions-item"><span class="ant-descriptions-item-label">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="3"><span class="ant-descriptions-item-label ant-descriptions-item-no-colon">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|         </tr> | ||||
|       </tbody> | ||||
|     </table> | ||||
|  | @ -22,7 +22,9 @@ exports[`Descriptions Descriptions support style 1`] = ` | |||
|     <table> | ||||
|       <tbody> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="3" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon ant-descriptions-item-no-label"><!----></span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="3"> | ||||
|             <!----><span class="ant-descriptions-item-content">Cloud Database</span> | ||||
|           </td> | ||||
|         </tr> | ||||
|       </tbody> | ||||
|     </table> | ||||
|  | @ -37,7 +39,7 @@ exports[`Descriptions Descriptions.Item support className 1`] = ` | |||
|     <table> | ||||
|       <tbody> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="3" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td class="ant-descriptions-item my-class" colspan="3"><span class="ant-descriptions-item-label">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|         </tr> | ||||
|       </tbody> | ||||
|     </table> | ||||
|  | @ -52,12 +54,12 @@ exports[`Descriptions column is number 1`] = ` | |||
|     <table> | ||||
|       <tbody> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Billing</span><span class="ant-descriptions-item-content">Prepaid</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">time</span><span class="ant-descriptions-item-content">18:00:00</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">Billing</span><span class="ant-descriptions-item-content">Prepaid</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">time</span><span class="ant-descriptions-item-content">18:00:00</span></td> | ||||
|         </tr> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="3" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Amount</span><span class="ant-descriptions-item-content">$80.00</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="3"><span class="ant-descriptions-item-label">Amount</span><span class="ant-descriptions-item-content">$80.00</span></td> | ||||
|         </tr> | ||||
|       </tbody> | ||||
|     </table> | ||||
|  | @ -72,20 +74,36 @@ exports[`Descriptions vertical layout 1`] = ` | |||
|     <table> | ||||
|       <tbody> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Product</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Billing</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">time</span></td> | ||||
|           <th class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">Product</span> | ||||
|             <!----> | ||||
|           </th> | ||||
|           <th class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">Billing</span> | ||||
|             <!----> | ||||
|           </th> | ||||
|           <th class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">time</span> | ||||
|             <!----> | ||||
|           </th> | ||||
|         </tr> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-content">Prepaid</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-content">18:00:00</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="1"> | ||||
|             <!----><span class="ant-descriptions-item-content">Cloud Database</span> | ||||
|           </td> | ||||
|           <td class="ant-descriptions-item" colspan="1"> | ||||
|             <!----><span class="ant-descriptions-item-content">Prepaid</span> | ||||
|           </td> | ||||
|           <td class="ant-descriptions-item" colspan="1"> | ||||
|             <!----><span class="ant-descriptions-item-content">18:00:00</span> | ||||
|           </td> | ||||
|         </tr> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="3" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Amount</span></td> | ||||
|           <th class="ant-descriptions-item" colspan="3"><span class="ant-descriptions-item-label">Amount</span> | ||||
|             <!----> | ||||
|           </th> | ||||
|         </tr> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="3" class="ant-descriptions-item"><span class="ant-descriptions-item-content">$80.00</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="3"> | ||||
|             <!----><span class="ant-descriptions-item-content">$80.00</span> | ||||
|           </td> | ||||
|         </tr> | ||||
|       </tbody> | ||||
|     </table> | ||||
|  | @ -100,12 +118,12 @@ exports[`Descriptions when item is rendered conditionally 1`] = ` | |||
|     <table> | ||||
|       <tbody> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Billing</span><span class="ant-descriptions-item-content">Prepaid</span></td> | ||||
|           <td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">time</span><span class="ant-descriptions-item-content">18:00:00</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">Billing</span><span class="ant-descriptions-item-content">Prepaid</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="1"><span class="ant-descriptions-item-label">time</span><span class="ant-descriptions-item-content">18:00:00</span></td> | ||||
|         </tr> | ||||
|         <tr class="ant-descriptions-row"> | ||||
|           <td colspan="3" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Amount</span><span class="ant-descriptions-item-content">$80.00</span></td> | ||||
|           <td class="ant-descriptions-item" colspan="3"><span class="ant-descriptions-item-label">Amount</span><span class="ant-descriptions-item-content">$80.00</span></td> | ||||
|         </tr> | ||||
|       </tbody> | ||||
|     </table> | ||||
|  |  | |||
|  | @ -33,7 +33,9 @@ describe('Descriptions', () => { | |||
|       { sync: false, attachTo: 'body' }, | ||||
|     ); | ||||
|     await asyncExpect(() => { | ||||
|       expect(wrapper.vm.$refs.descriptions.getColumn()).toBe(8); | ||||
|       expect( | ||||
|         wrapper.findAll('td').reduce((total, td) => total + parseInt(td.attributes().colspan), 0), | ||||
|       ).toBe(8); | ||||
|     }, 100); | ||||
|     wrapper.unmount(); | ||||
|   }); | ||||
|  | @ -74,7 +76,7 @@ describe('Descriptions', () => { | |||
|       }, | ||||
|     }); | ||||
|     expect(errorSpy).toHaveBeenCalledWith( | ||||
|       'Warning: [antdv: Descriptions] Sum of column `span` in a line exceeds `column` of Descriptions.', | ||||
|       'Warning: [antdv: Descriptions] Sum of column `span` in a line not match `column` of Descriptions.', | ||||
|     ); | ||||
|   }); | ||||
| 
 | ||||
|  | @ -120,7 +122,7 @@ describe('Descriptions', () => { | |||
|       render() { | ||||
|         return ( | ||||
|           <Descriptions> | ||||
|             <Descriptions.Item label="Product" className="my-class"> | ||||
|             <Descriptions.Item label="Product" class="my-class"> | ||||
|               Cloud Database | ||||
|             </Descriptions.Item> | ||||
|           </Descriptions> | ||||
|  | @ -176,7 +178,7 @@ describe('Descriptions', () => { | |||
|     ); | ||||
|     await asyncExpect(() => { | ||||
|       expect(wrapper.findAll('tr')).toHaveLength(5); | ||||
|       expect(wrapper.findAll('.ant-descriptions-item-no-label')).toHaveLength(1); | ||||
|       expect(wrapper.findAll('.ant-descriptions-item-label')).toHaveLength(4); | ||||
|     }); | ||||
| 
 | ||||
|     wrapper.unmount(); | ||||
|  | @ -198,8 +200,86 @@ describe('Descriptions', () => { | |||
|       }, | ||||
|       { sync: false, attachTo: 'body' }, | ||||
|     ); | ||||
|     await asyncExpect(() => {}); | ||||
|     expect(wrapper.findAll('tr')).toHaveLength(2); | ||||
|     await asyncExpect(() => { | ||||
|       expect(wrapper.findAll('tr')).toHaveLength(2); | ||||
|     }); | ||||
|     wrapper.unmount(); | ||||
|   }); | ||||
| 
 | ||||
|   it('columns 5 with customize', () => { | ||||
|     const wrapper = mount({ | ||||
|       render() { | ||||
|         return ( | ||||
|           <Descriptions layout="vertical" column={4}> | ||||
|             {/* 1 1 1 1 */} | ||||
|             <Descriptions.Item label="bamboo">bamboo</Descriptions.Item> | ||||
|             <Descriptions.Item label="bamboo">bamboo</Descriptions.Item> | ||||
|             <Descriptions.Item label="bamboo">bamboo</Descriptions.Item> | ||||
|             <Descriptions.Item label="bamboo">bamboo</Descriptions.Item> | ||||
|             {/* 2 2 */} | ||||
|             <Descriptions.Item label="bamboo" span={2}> | ||||
|               bamboo | ||||
|             </Descriptions.Item> | ||||
|             <Descriptions.Item label="bamboo" span={2}> | ||||
|               bamboo | ||||
|             </Descriptions.Item> | ||||
|             {/* 3 1 */} | ||||
|             <Descriptions.Item label="bamboo" span={3}> | ||||
|               bamboo | ||||
|             </Descriptions.Item> | ||||
|             <Descriptions.Item label="bamboo">bamboo</Descriptions.Item> | ||||
|           </Descriptions> | ||||
|         ); | ||||
|       }, | ||||
|     }); | ||||
| 
 | ||||
|     function matchSpan(rowIndex, spans) { | ||||
|       const tr = wrapper.findAll('tr')[rowIndex]; | ||||
|       const tds = tr.findAll('th'); | ||||
|       expect(tds.length).toEqual(spans.length); | ||||
|       tds.forEach((td, index) => { | ||||
|         expect(parseInt(td.attributes().colspan)).toEqual(spans[index]); | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     matchSpan(0, [1, 1, 1, 1]); | ||||
|     matchSpan(2, [2, 2]); | ||||
|     matchSpan(4, [3, 1]); | ||||
|   }); | ||||
| 
 | ||||
|   it('number value should render correct', () => { | ||||
|     const wrapper = mount({ | ||||
|       render() { | ||||
|         return ( | ||||
|           <Descriptions bordered> | ||||
|             <Descriptions.Item label={0}>{0}</Descriptions.Item> | ||||
|           </Descriptions> | ||||
|         ); | ||||
|       }, | ||||
|     }); | ||||
| 
 | ||||
|     expect(wrapper.find('th').classes()).toContain('ant-descriptions-item-label'); | ||||
|     expect(wrapper.find('td').classes()).toContain('ant-descriptions-item-content'); | ||||
|   }); | ||||
| 
 | ||||
|   it('Descriptions support extra', async () => { | ||||
|     const wrapper = mount({ | ||||
|       render() { | ||||
|         return ( | ||||
|           <Descriptions extra="Edit"> | ||||
|             <Descriptions.Item label="UserName">Zhou Maomao</Descriptions.Item> | ||||
|           </Descriptions> | ||||
|         ); | ||||
|       }, | ||||
|     }); | ||||
| 
 | ||||
|     await asyncExpect(() => { | ||||
|       expect(wrapper.find('.ant-descriptions-extra').exists()).toBe(true); | ||||
|       wrapper.setProps({ extra: undefined }); | ||||
|     }); | ||||
| 
 | ||||
|     await asyncExpect(() => { | ||||
|       expect(wrapper.find('.ant-descriptions-extra').exists()).toBe(false); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -1,12 +1,27 @@ | |||
| import { inject, cloneVNode, App, defineComponent, PropType, VNode, Plugin } from 'vue'; | ||||
| import { | ||||
|   inject, | ||||
|   ref, | ||||
|   App, | ||||
|   defineComponent, | ||||
|   PropType, | ||||
|   VNode, | ||||
|   HTMLAttributes, | ||||
|   ExtractPropTypes, | ||||
|   onMounted, | ||||
|   onBeforeUnmount, | ||||
| } from 'vue'; | ||||
| import warning from '../_util/warning'; | ||||
| import ResponsiveObserve, { Breakpoint, responsiveArray } from '../_util/responsiveObserve'; | ||||
| import ResponsiveObserve, { | ||||
|   Breakpoint, | ||||
|   responsiveArray, | ||||
|   ScreenMap, | ||||
| } from '../_util/responsiveObserve'; | ||||
| import { defaultConfigProvider } from '../config-provider'; | ||||
| import Col from './Col'; | ||||
| import Row from './Row'; | ||||
| import PropTypes from '../_util/vue-types'; | ||||
| import { getOptionProps, getComponent, isValidElement, getSlot } from '../_util/props-util'; | ||||
| import BaseMixin from '../_util/BaseMixin'; | ||||
| import { tuple, VueNode } from '../_util/type'; | ||||
| import { tuple } from '../_util/type'; | ||||
| import { cloneElement } from '../_util/vnode'; | ||||
| import { filterEmpty } from '../_util/props-util'; | ||||
| 
 | ||||
| export const DescriptionsItemProps = { | ||||
|   prefixCls: PropTypes.string, | ||||
|  | @ -14,16 +29,6 @@ export const DescriptionsItemProps = { | |||
|   span: PropTypes.number, | ||||
| }; | ||||
| 
 | ||||
| function toArray(value: any) { | ||||
|   let ret = value; | ||||
|   if (value === undefined) { | ||||
|     ret = []; | ||||
|   } else if (!Array.isArray(value)) { | ||||
|     ret = [value]; | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| export const DescriptionsItem = { | ||||
|   name: 'ADescriptionsItem', | ||||
|   props: { | ||||
|  | @ -36,7 +41,7 @@ export const DescriptionsItem = { | |||
|   }, | ||||
| }; | ||||
| 
 | ||||
| const defaultColumnMap = { | ||||
| const DEFAULT_COLUMN_MAP: Record<Breakpoint, number> = { | ||||
|   xxl: 3, | ||||
|   xl: 3, | ||||
|   lg: 3, | ||||
|  | @ -45,229 +50,172 @@ const defaultColumnMap = { | |||
|   xs: 1, | ||||
| }; | ||||
| 
 | ||||
| export const DescriptionsProps = { | ||||
| function getColumn(column: DescriptionsProps['column'], screens: ScreenMap): number { | ||||
|   if (typeof column === 'number') { | ||||
|     return column; | ||||
|   } | ||||
| 
 | ||||
|   if (typeof column === 'object') { | ||||
|     for (let i = 0; i < responsiveArray.length; i++) { | ||||
|       const breakpoint: Breakpoint = responsiveArray[i]; | ||||
|       if (screens[breakpoint] && column[breakpoint] !== undefined) { | ||||
|         return column[breakpoint] || DEFAULT_COLUMN_MAP[breakpoint]; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return 3; | ||||
| } | ||||
| 
 | ||||
| function getFilledItem(node: VNode, span: number | undefined, rowRestCol: number): VNode { | ||||
|   let clone = node; | ||||
| 
 | ||||
|   if (span === undefined || span > rowRestCol) { | ||||
|     clone = cloneElement(node, { | ||||
|       span: rowRestCol, | ||||
|     }); | ||||
| 
 | ||||
|     warning( | ||||
|       span === undefined, | ||||
|       'Descriptions', | ||||
|       'Sum of column `span` in a line not match `column` of Descriptions.', | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   return clone; | ||||
| } | ||||
| 
 | ||||
| function getRows(children: VNode[], column: number) { | ||||
|   const childNodes = filterEmpty(children); | ||||
|   const rows: VNode[][] = []; | ||||
| 
 | ||||
|   let tmpRow: VNode[] = []; | ||||
|   let rowRestCol = column; | ||||
| 
 | ||||
|   childNodes.forEach((node, index) => { | ||||
|     const span: number | undefined = node.props?.span; | ||||
|     const mergedSpan = span || 1; | ||||
| 
 | ||||
|     // Additional handle last one
 | ||||
|     if (index === childNodes.length - 1) { | ||||
|       tmpRow.push(getFilledItem(node, span, rowRestCol)); | ||||
|       rows.push(tmpRow); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     if (mergedSpan < rowRestCol) { | ||||
|       rowRestCol -= mergedSpan; | ||||
|       tmpRow.push(node); | ||||
|     } else { | ||||
|       tmpRow.push(getFilledItem(node, mergedSpan, rowRestCol)); | ||||
|       rows.push(tmpRow); | ||||
|       rowRestCol = column; | ||||
|       tmpRow = []; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   return rows; | ||||
| } | ||||
| 
 | ||||
| const descriptionsProps = { | ||||
|   prefixCls: PropTypes.string, | ||||
|   bordered: PropTypes.looseBool, | ||||
|   size: PropTypes.oneOf(tuple('default', 'middle', 'small')).def('default'), | ||||
|   title: PropTypes.VNodeChild, | ||||
|   extra: PropTypes.VNodeChild, | ||||
|   column: { | ||||
|     type: [Number, Object] as PropType<number | Partial<Record<Breakpoint, number>>>, | ||||
|     default: () => defaultColumnMap, | ||||
|     default: () => DEFAULT_COLUMN_MAP, | ||||
|   }, | ||||
|   layout: PropTypes.oneOf(tuple('horizontal', 'vertical')), | ||||
|   colon: PropTypes.looseBool, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Convert children into `column` groups. | ||||
|  * @param children: DescriptionsItem | ||||
|  * @param column: number | ||||
|  */ | ||||
| const generateChildrenRows = (children: VueNode, column: number) => { | ||||
|   const rows = []; | ||||
|   let columns = null; | ||||
|   let leftSpans: number; | ||||
| export type DescriptionsProps = HTMLAttributes & | ||||
|   Partial<ExtractPropTypes<typeof descriptionsProps>>; | ||||
| 
 | ||||
|   const itemNodes = toArray(children); | ||||
|   itemNodes.forEach((node: VNode, index: number) => { | ||||
|     const itemProps = getOptionProps(node); | ||||
|     let itemNode = node; | ||||
| 
 | ||||
|     if (!columns) { | ||||
|       leftSpans = column; | ||||
|       columns = []; | ||||
|       rows.push(columns); | ||||
|     } | ||||
| 
 | ||||
|     // Always set last span to align the end of Descriptions
 | ||||
|     const lastItem = index === itemNodes.length - 1; | ||||
|     let lastSpanSame = true; | ||||
|     if (lastItem) { | ||||
|       lastSpanSame = !itemProps.span || itemProps.span === leftSpans; | ||||
|       itemNode = cloneVNode(itemNode, { | ||||
|         span: leftSpans, | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     // Calculate left fill span
 | ||||
|     const { span = 1 } = itemProps; | ||||
|     columns.push(itemNode); | ||||
|     leftSpans -= span; | ||||
| 
 | ||||
|     if (leftSpans <= 0) { | ||||
|       columns = null; | ||||
| 
 | ||||
|       warning( | ||||
|         leftSpans === 0 && lastSpanSame, | ||||
|         'Descriptions', | ||||
|         'Sum of column `span` in a line exceeds `column` of Descriptions.', | ||||
|       ); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   return rows; | ||||
| }; | ||||
| 
 | ||||
| const Descriptions = defineComponent({ | ||||
| const Descriptions = defineComponent<DescriptionsProps>({ | ||||
|   name: 'ADescriptions', | ||||
|   Item: DescriptionsItem, | ||||
|   mixins: [BaseMixin], | ||||
|   props: DescriptionsProps, | ||||
|   setup() { | ||||
|     return { | ||||
|       configProvider: inject('configProvider', defaultConfigProvider), | ||||
|     }; | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       screens: {}, | ||||
|       token: undefined, | ||||
|     }; | ||||
|   }, | ||||
|   methods: { | ||||
|     getColumn() { | ||||
|       const { column } = this.$props; | ||||
|       if (typeof column === 'object') { | ||||
|         for (let i = 0; i < responsiveArray.length; i++) { | ||||
|           const breakpoint = responsiveArray[i]; | ||||
|           if (this.screens[breakpoint] && column[breakpoint] !== undefined) { | ||||
|             return column[breakpoint] || defaultColumnMap[breakpoint]; | ||||
|           } | ||||
|   setup(props, { slots }) { | ||||
|     const { getPrefixCls } = inject('configProvider', defaultConfigProvider); | ||||
| 
 | ||||
|     let token: number; | ||||
| 
 | ||||
|     const screens = ref<ScreenMap>({}); | ||||
| 
 | ||||
|     onMounted(() => { | ||||
|       token = ResponsiveObserve.subscribe(screen => { | ||||
|         if (typeof props.column !== 'object') { | ||||
|           return; | ||||
|         } | ||||
|       } | ||||
|       // If the configuration is not an object, it is a number, return number
 | ||||
|       if (typeof column === 'number') { | ||||
|         return column; | ||||
|       } | ||||
|       // If it is an object, but no response is found, this happens only in the test.
 | ||||
|       // Maybe there are some strange environments
 | ||||
|       return 3; | ||||
|     }, | ||||
|     renderRow( | ||||
|       children: VNode[], | ||||
|       index: number, | ||||
|       { prefixCls }: { prefixCls: string }, | ||||
|       bordered: boolean, | ||||
|       layout: 'horizontal' | 'vertical', | ||||
|       colon: boolean, | ||||
|     ) { | ||||
|       const renderCol = (colItem: VNode, type: 'label' | 'content', idx: number) => { | ||||
|         return ( | ||||
|           <Col | ||||
|             child={colItem} | ||||
|             bordered={bordered} | ||||
|             colon={colon} | ||||
|             type={type} | ||||
|             key={`${type}-${colItem.key || idx}`} | ||||
|             colKey={`${type}-${colItem.key || idx}`} | ||||
|             layout={layout} | ||||
|           /> | ||||
|         ); | ||||
|       }; | ||||
| 
 | ||||
|       const cloneChildren = []; | ||||
|       const cloneContentChildren = []; | ||||
|       toArray(children).forEach((childrenItem: VNode, idx: number) => { | ||||
|         cloneChildren.push(renderCol(childrenItem, 'label', idx)); | ||||
|         if (layout === 'vertical') { | ||||
|           cloneContentChildren.push(renderCol(childrenItem, 'content', idx)); | ||||
|         } else if (bordered) { | ||||
|           cloneChildren.push(renderCol(childrenItem, 'content', idx)); | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       if (layout === 'vertical') { | ||||
|         return [ | ||||
|           <tr class={`${prefixCls}-row`} key={`label-${index}`}> | ||||
|             {cloneChildren} | ||||
|           </tr>, | ||||
|           <tr class={`${prefixCls}-row`} key={`content-${index}`}> | ||||
|             {cloneContentChildren} | ||||
|           </tr>, | ||||
|         ]; | ||||
|       } | ||||
| 
 | ||||
|       return ( | ||||
|         <tr class={`${prefixCls}-row`} key={index}> | ||||
|           {cloneChildren} | ||||
|         </tr> | ||||
|       ); | ||||
|     }, | ||||
|   }, | ||||
|   mounted() { | ||||
|     const { column } = this.$props; | ||||
|     this.token = ResponsiveObserve.subscribe(screens => { | ||||
|       if (typeof column !== 'object') { | ||||
|         return; | ||||
|       } | ||||
|       this.setState({ | ||||
|         screens, | ||||
|         screens.value = screen; | ||||
|       }); | ||||
|     }); | ||||
|   }, | ||||
|   beforeUnmount() { | ||||
|     ResponsiveObserve.unsubscribe(this.token); | ||||
|   }, | ||||
|   render() { | ||||
|     const { | ||||
|       prefixCls: customizePrefixCls, | ||||
|       size, | ||||
|       bordered = false, | ||||
|       layout = 'horizontal', | ||||
|       colon = true, | ||||
|     } = this.$props; | ||||
|     const title = getComponent(this, 'title'); | ||||
|     const getPrefixCls = this.configProvider.getPrefixCls; | ||||
|     const prefixCls = getPrefixCls('descriptions', customizePrefixCls); | ||||
| 
 | ||||
|     const column = this.getColumn(); | ||||
|     const children = getSlot(this); | ||||
|     const cloneChildren = toArray(children) | ||||
|       .map((child: VNode) => { | ||||
|         if (isValidElement(child)) { | ||||
|           return cloneVNode(child, { | ||||
|     onBeforeUnmount(() => { | ||||
|       ResponsiveObserve.unsubscribe(token); | ||||
|     }); | ||||
| 
 | ||||
|     return () => { | ||||
|       const { | ||||
|         prefixCls: customizePrefixCls, | ||||
|         column, | ||||
|         size, | ||||
|         bordered = false, | ||||
|         layout = 'horizontal', | ||||
|         colon = true, | ||||
|         title = slots.title?.(), | ||||
|         extra = slots.extra?.(), | ||||
|       } = props; | ||||
| 
 | ||||
|       const prefixCls = getPrefixCls('descriptions', customizePrefixCls); | ||||
|       const mergeColumn = getColumn(column, screens.value); | ||||
|       const children = slots.default?.(); | ||||
|       const rows = getRows(children, mergeColumn); | ||||
| 
 | ||||
|       return ( | ||||
|         <div | ||||
|           class={[ | ||||
|             prefixCls, | ||||
|           }); | ||||
|         } | ||||
|         return null; | ||||
|       }) | ||||
|       .filter(node => node); | ||||
| 
 | ||||
|     const childrenArray = generateChildrenRows(cloneChildren, column); | ||||
|     return ( | ||||
|       <div | ||||
|         class={[ | ||||
|           prefixCls, | ||||
|           { | ||||
|             [`${prefixCls}-${size}`]: size !== 'default', | ||||
|             [`${prefixCls}-bordered`]: !!bordered, | ||||
|           }, | ||||
|         ]} | ||||
|       > | ||||
|         {title && <div class={`${prefixCls}-title`}>{title}</div>} | ||||
|         <div class={`${prefixCls}-view`}> | ||||
|           <table> | ||||
|             <tbody> | ||||
|               {childrenArray.map((child, index) => | ||||
|                 this.renderRow( | ||||
|                   child, | ||||
|                   index, | ||||
|                   { | ||||
|                     prefixCls, | ||||
|                   }, | ||||
|                   bordered, | ||||
|                   layout, | ||||
|                   colon, | ||||
|                 ), | ||||
|               )} | ||||
|             </tbody> | ||||
|           </table> | ||||
|             { | ||||
|               [`${prefixCls}-${size}`]: size !== 'default', | ||||
|               [`${prefixCls}-bordered`]: !!bordered, | ||||
|             }, | ||||
|           ]} | ||||
|         > | ||||
|           {(title || extra) && ( | ||||
|             <div class={`${prefixCls}-header`}> | ||||
|               <div class={`${prefixCls}-title`}>{title}</div> | ||||
|               <div class={`${prefixCls}-extra`}>{extra}</div> | ||||
|             </div> | ||||
|           )} | ||||
|           <div class={`${prefixCls}-view`}> | ||||
|             <table> | ||||
|               <tbody> | ||||
|                 {rows.map((row, index) => ( | ||||
|                   <Row | ||||
|                     key={index} | ||||
|                     index={index} | ||||
|                     colon={colon} | ||||
|                     prefixCls={prefixCls} | ||||
|                     vertical={layout === 'vertical'} | ||||
|                     bordered={bordered} | ||||
|                     row={row} | ||||
|                   /> | ||||
|                 ))} | ||||
|               </tbody> | ||||
|             </table> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|       ); | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| Descriptions.props = descriptionsProps; | ||||
| 
 | ||||
| Descriptions.install = function(app: App) { | ||||
|   app.component(Descriptions.name, Descriptions); | ||||
|   app.component(Descriptions.Item.name, Descriptions.Item); | ||||
|  |  | |||
|  | @ -3,17 +3,28 @@ | |||
| 
 | ||||
| @descriptions-prefix-cls: ~'@{ant-prefix}-descriptions'; | ||||
| 
 | ||||
| @descriptions-default-padding: 16px 24px; | ||||
| @descriptions-middle-padding: 12px 24px; | ||||
| @descriptions-small-padding: 8px 16px; | ||||
| 
 | ||||
| .@{descriptions-prefix-cls} { | ||||
|   &-header { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     margin-bottom: @descriptions-title-margin-bottom; | ||||
|   } | ||||
| 
 | ||||
|   &-title { | ||||
|     margin-bottom: 20px; | ||||
|     flex: auto; | ||||
|     overflow: hidden; | ||||
|     color: @heading-color; | ||||
|     font-weight: bold; | ||||
|     font-size: @font-size-lg; | ||||
|     line-height: @line-height-base; | ||||
|     white-space: nowrap; | ||||
|     text-overflow: ellipsis; | ||||
|   } | ||||
| 
 | ||||
|   &-extra { | ||||
|     margin-left: auto; | ||||
|     color: @descriptions-extra-color; | ||||
|     font-size: @font-size-base; | ||||
|   } | ||||
| 
 | ||||
|   &-view { | ||||
|  | @ -29,7 +40,7 @@ | |||
|   &-row { | ||||
|     > th, | ||||
|     > td { | ||||
|       padding-bottom: 16px; | ||||
|       padding-bottom: @descriptions-item-padding-bottom; | ||||
|     } | ||||
|     &:last-child { | ||||
|       border-bottom: none; | ||||
|  | @ -41,18 +52,24 @@ | |||
|     font-weight: normal; | ||||
|     font-size: @font-size-base; | ||||
|     line-height: @line-height-base; | ||||
|     text-align: start; | ||||
| 
 | ||||
|     &::after { | ||||
|       & when (@descriptions-item-trailing-colon=true) { | ||||
|         content: ':'; | ||||
|       } | ||||
|       & when not (@descriptions-item-trailing-colon=true) { | ||||
|         content: ' '; | ||||
|       } | ||||
| 
 | ||||
|       position: relative; | ||||
|       top: -0.5px; | ||||
|       margin: 0 8px 0 2px; | ||||
|       content: ' '; | ||||
|       margin: 0 @descriptions-item-label-colon-margin-right 0 | ||||
|         @descriptions-item-label-colon-margin-left; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-item-colon { | ||||
|     &::after { | ||||
|       content: ':'; | ||||
|     &.@{descriptions-prefix-cls}-item-no-colon::after { | ||||
|       content: ' '; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | @ -65,15 +82,23 @@ | |||
| 
 | ||||
|   &-item-content { | ||||
|     display: table-cell; | ||||
|     flex: 1; | ||||
|     color: @text-color; | ||||
|     font-size: @font-size-base; | ||||
|     line-height: @line-height-base; | ||||
|     overflow-wrap: break-word; | ||||
|   } | ||||
| 
 | ||||
|   &-item { | ||||
|     padding-bottom: 0; | ||||
|     vertical-align: top; | ||||
|     > span { | ||||
|       display: inline-block; | ||||
|       display: inline-flex; | ||||
|       align-items: baseline; | ||||
|     } | ||||
| 
 | ||||
|     &-container { | ||||
|       display: flex; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | @ -90,7 +115,7 @@ | |||
|     .@{descriptions-prefix-cls}-row { | ||||
|       > th, | ||||
|       > td { | ||||
|         padding-bottom: 8px; | ||||
|         padding-bottom: @padding-xs; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -192,6 +192,15 @@ | |||
| 
 | ||||
| // Descriptions | ||||
| @descriptions-bg: #fafafa; | ||||
| @descriptions-title-margin-bottom: 20px; | ||||
| @descriptions-default-padding: @padding-md @padding-lg; | ||||
| @descriptions-middle-padding: @padding-sm @padding-lg; | ||||
| @descriptions-small-padding: @padding-xs @padding-md; | ||||
| @descriptions-item-padding-bottom: @padding-md; | ||||
| @descriptions-item-trailing-colon: true; | ||||
| @descriptions-item-label-colon-margin-right: 8px; | ||||
| @descriptions-item-label-colon-margin-left: 2px; | ||||
| @descriptions-extra-color: @text-color; | ||||
| 
 | ||||
| // Dropdown | ||||
| @dropdown-selected-color: @primary-color; | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import { defineComponent } from 'vue'; | ||||
| import { ColumnProps } from './interface'; | ||||
| import { columnProps } from './interface'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   name: 'ATableColumn', | ||||
|   props: ColumnProps, | ||||
|   props: columnProps, | ||||
|   render() { | ||||
|     return null; | ||||
|   }, | ||||
|  |  | |||
|  | @ -17,11 +17,11 @@ import initDefaultProps from '../_util/props-util/initDefaultProps'; | |||
| import BaseMixin from '../_util/BaseMixin'; | ||||
| import { defaultConfigProvider } from '../config-provider'; | ||||
| import { | ||||
|   TableProps, | ||||
|   tableProps, | ||||
|   TableComponents, | ||||
|   TableState, | ||||
|   ITableProps, | ||||
|   IColumnProps, | ||||
|   TableProps, | ||||
|   ColumnProps, | ||||
|   TableStateFilters, | ||||
| } from './interface'; | ||||
| import Pagination from '../pagination'; | ||||
|  | @ -38,15 +38,15 @@ function stopPropagation(e) { | |||
|   e.stopPropagation(); | ||||
| } | ||||
| 
 | ||||
| function getRowSelection(props: ITableProps) { | ||||
| function getRowSelection(props: TableProps) { | ||||
|   return props.rowSelection || {}; | ||||
| } | ||||
| 
 | ||||
| function getColumnKey(column: IColumnProps, index?: number) { | ||||
| function getColumnKey(column: ColumnProps, index?: number) { | ||||
|   return column.key || column.dataIndex || index; | ||||
| } | ||||
| 
 | ||||
| function isSameColumn(a: IColumnProps, b: IColumnProps): boolean { | ||||
| function isSameColumn(a: ColumnProps, b: ColumnProps): boolean { | ||||
|   if (a && b && a.key && a.key === b.key) { | ||||
|     return true; | ||||
|   } | ||||
|  | @ -94,16 +94,16 @@ function isTheSameComponents(components1: TableComponents = {}, components2: Tab | |||
|   ); | ||||
| } | ||||
| 
 | ||||
| function getFilteredValueColumns(state: TableState, columns?: IColumnProps) { | ||||
| function getFilteredValueColumns(state: TableState, columns?: ColumnProps) { | ||||
|   return flatFilter( | ||||
|     columns || (state || {}).columns || [], | ||||
|     (column: IColumnProps) => typeof column.filteredValue !== 'undefined', | ||||
|     (column: ColumnProps) => typeof column.filteredValue !== 'undefined', | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| function getFiltersFromColumns(state: TableState, columns: IColumnProps) { | ||||
| function getFiltersFromColumns(state: TableState, columns: ColumnProps) { | ||||
|   const filters = {}; | ||||
|   getFilteredValueColumns(state, columns).forEach((col: IColumnProps) => { | ||||
|   getFilteredValueColumns(state, columns).forEach((col: ColumnProps) => { | ||||
|     const colKey = getColumnKey(col); | ||||
|     filters[colKey] = col.filteredValue; | ||||
|   }); | ||||
|  | @ -117,26 +117,28 @@ function isFiltersChanged(state: TableState, filters: TableStateFilters[]) { | |||
|   return Object.keys(filters).some(columnKey => filters[columnKey] !== state.filters[columnKey]); | ||||
| } | ||||
| 
 | ||||
| export const defaultTableProps = initDefaultProps(tableProps, { | ||||
|   dataSource: [], | ||||
|   useFixedHeader: false, | ||||
|   // rowSelection: null,
 | ||||
|   size: 'default', | ||||
|   loading: false, | ||||
|   bordered: false, | ||||
|   indentSize: 20, | ||||
|   locale: {}, | ||||
|   rowKey: 'key', | ||||
|   showHeader: true, | ||||
|   sortDirections: ['ascend', 'descend'], | ||||
|   childrenColumnName: 'children', | ||||
| }); | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   name: 'Table', | ||||
|   mixins: [BaseMixin], | ||||
|   inheritAttrs: false, | ||||
|   Column, | ||||
|   ColumnGroup, | ||||
|   props: initDefaultProps(TableProps, { | ||||
|     dataSource: [], | ||||
|     useFixedHeader: false, | ||||
|     // rowSelection: null,
 | ||||
|     size: 'default', | ||||
|     loading: false, | ||||
|     bordered: false, | ||||
|     indentSize: 20, | ||||
|     locale: {}, | ||||
|     rowKey: 'key', | ||||
|     showHeader: true, | ||||
|     sortDirections: ['ascend', 'descend'], | ||||
|     childrenColumnName: 'children', | ||||
|   }), | ||||
|   props: defaultTableProps, | ||||
| 
 | ||||
|   setup() { | ||||
|     return { | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import { App, defineComponent } from 'vue'; | ||||
| import T from './Table'; | ||||
| import T, { defaultTableProps } from './Table'; | ||||
| import Column from './Column'; | ||||
| import ColumnGroup from './ColumnGroup'; | ||||
| import {} from './interface'; | ||||
|  | @ -9,7 +9,7 @@ const Table = defineComponent({ | |||
|   name: 'ATable', | ||||
|   Column: T.Column, | ||||
|   ColumnGroup: T.ColumnGroup, | ||||
|   props: T.props, | ||||
|   props: defaultTableProps, | ||||
|   inheritAttrs: false, | ||||
|   methods: { | ||||
|     normalize(elements = []) { | ||||
|  |  | |||
|  | @ -1,21 +1,21 @@ | |||
| import { ExtractPropTypes, PropType } from 'vue'; | ||||
| import PropTypes, { withUndefined } from '../_util/vue-types'; | ||||
| import { PaginationProps as getPaginationProps } from '../pagination'; | ||||
| import { SpinProps as getSpinProps } from '../spin'; | ||||
| import { Store } from './createStore'; | ||||
| import { tuple } from '../_util/type'; | ||||
| import { ExtractPropTypes } from 'vue'; | ||||
| 
 | ||||
| const PaginationProps = getPaginationProps(); | ||||
| const SpinProps = getSpinProps(); | ||||
| 
 | ||||
| // export type CompareFn<T> = ((a: T, b: T) => number);
 | ||||
| export type CompareFn<T> = (a: T, b: T, sortOrder?: SortOrder) => number; | ||||
| export const ColumnFilterItem = PropTypes.shape({ | ||||
|   text: PropTypes.string, | ||||
|   value: PropTypes.string, | ||||
|   children: PropTypes.array, | ||||
| }).loose; | ||||
| 
 | ||||
| export const ColumnProps = { | ||||
| export const columnProps = { | ||||
|   title: PropTypes.VNodeChild, | ||||
|   key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||||
|   dataIndex: PropTypes.string, | ||||
|  | @ -52,7 +52,7 @@ export const ColumnProps = { | |||
|   // onHeaderCell?: (props: ColumnProps<T>) => any;
 | ||||
| }; | ||||
| 
 | ||||
| export type IColumnProps = Partial<ExtractPropTypes<typeof ColumnProps>>; | ||||
| export type ColumnProps = Partial<ExtractPropTypes<typeof columnProps>>; | ||||
| 
 | ||||
| export interface TableComponents { | ||||
|   table?: any; | ||||
|  | @ -80,10 +80,10 @@ export const TableLocale = PropTypes.shape({ | |||
|   collapse: PropTypes.string, | ||||
| }).loose; | ||||
| 
 | ||||
| export const RowSelectionType = PropTypes.oneOf(['checkbox', 'radio']); | ||||
| export const RowSelectionType = PropTypes.oneOf(tuple('checkbox', 'radio')); | ||||
| // export type SelectionSelectFn<T> = (record: T, selected: boolean, selectedRows: Object[]) => any;
 | ||||
| 
 | ||||
| export const TableRowSelection = { | ||||
| export const tableRowSelection = { | ||||
|   type: RowSelectionType, | ||||
|   selectedRowKeys: PropTypes.array, | ||||
|   // onChange?: (selectedRowKeys: string[] | number[], selectedRows: Object[]) => any;
 | ||||
|  | @ -101,10 +101,12 @@ export const TableRowSelection = { | |||
|   columnTitle: PropTypes.any, | ||||
| }; | ||||
| 
 | ||||
| export const TableProps = { | ||||
| export type SortOrder = 'descend' | 'ascend'; | ||||
| 
 | ||||
| export const tableProps = { | ||||
|   prefixCls: PropTypes.string, | ||||
|   dropdownPrefixCls: PropTypes.string, | ||||
|   rowSelection: PropTypes.oneOfType([PropTypes.shape(TableRowSelection).loose, Object]), | ||||
|   rowSelection: PropTypes.oneOfType([PropTypes.shape(tableRowSelection).loose, Object]), | ||||
|   pagination: withUndefined( | ||||
|     PropTypes.oneOfType([ | ||||
|       PropTypes.shape({ | ||||
|  | @ -117,7 +119,9 @@ export const TableProps = { | |||
|   size: PropTypes.oneOf(tuple('default', 'middle', 'small', 'large')), | ||||
|   dataSource: PropTypes.array, | ||||
|   components: PropTypes.object, | ||||
|   columns: PropTypes.array, | ||||
|   columns: { | ||||
|     type: Array as PropType<ColumnProps>, | ||||
|   }, | ||||
|   rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||||
|   rowClassName: PropTypes.func, | ||||
|   expandedRowRender: PropTypes.any, | ||||
|  | @ -137,10 +141,18 @@ export const TableProps = { | |||
|   showHeader: PropTypes.looseBool, | ||||
|   footer: PropTypes.func, | ||||
|   title: PropTypes.func, | ||||
|   scroll: PropTypes.object, | ||||
|   scroll: { | ||||
|     type: Object as PropType<{ | ||||
|       x?: boolean | number | string; | ||||
|       y?: boolean | number | string; | ||||
|       scrollToFirstRowOnChange?: boolean; | ||||
|     }>, | ||||
|   }, | ||||
|   childrenColumnName: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), | ||||
|   bodyStyle: PropTypes.any, | ||||
|   sortDirections: PropTypes.array, | ||||
|   bodyStyle: PropTypes.style, | ||||
|   sortDirections: { | ||||
|     type: Array as PropType<SortOrder[]>, | ||||
|   }, | ||||
|   tableLayout: PropTypes.string, | ||||
|   getPopupContainer: PropTypes.func, | ||||
|   expandIcon: PropTypes.func, | ||||
|  | @ -153,9 +165,9 @@ export const TableProps = { | |||
|   // children?: React.ReactNode;
 | ||||
| }; | ||||
| 
 | ||||
| export type ITableRowSelection = Partial<ExtractPropTypes<typeof TableRowSelection>>; | ||||
| export type TableRowSelection = Partial<ExtractPropTypes<typeof tableRowSelection>>; | ||||
| 
 | ||||
| export type ITableProps = Partial<ExtractPropTypes<typeof TableProps>>; | ||||
| export type TableProps = Partial<ExtractPropTypes<typeof tableProps>>; | ||||
| 
 | ||||
| export interface TableStateFilters { | ||||
|   [key: string]: string[]; | ||||
|  | @ -164,9 +176,9 @@ export interface TableStateFilters { | |||
| export interface TableState { | ||||
|   pagination?: Partial<ExtractPropTypes<typeof PaginationProps>>; | ||||
|   filters?: TableStateFilters; | ||||
|   sortColumn?: Partial<ExtractPropTypes<typeof ColumnProps>> | null; | ||||
|   sortColumn?: ColumnProps | null; | ||||
|   sortOrder?: string; | ||||
|   columns?: IColumnProps[]; | ||||
|   columns?: ColumnProps[]; | ||||
| } | ||||
| 
 | ||||
| // export type SelectionItemSelectFn = (key: string[]) => any;
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tanjinzhou
						tanjinzhou