import DownOutlined from '@ant-design/icons-vue/DownOutlined'; import Checkbox from '../checkbox'; import Dropdown from '../dropdown'; import Menu from '../menu'; import classNames from '../_util/classNames'; import { SelectionCheckboxAllProps } from './interface'; import BaseMixin from '../_util/BaseMixin'; import { computed, defineComponent } from 'vue'; function checkSelection({ store, getCheckboxPropsByItem, getRecordKey, data, type, byDefaultChecked, }) { return byDefaultChecked ? data[type]((item, i) => getCheckboxPropsByItem(item, i).defaultChecked) : data[type]((item, i) => store.selectedRowKeys.indexOf(getRecordKey(item, i)) >= 0); } function getIndeterminateState(props) { const { store, data } = props; if (!data.length) { return false; } const someCheckedNotByDefaultChecked = checkSelection({ ...props, data, type: 'some', byDefaultChecked: false, }) && !checkSelection({ ...props, data, type: 'every', byDefaultChecked: false, }); const someCheckedByDefaultChecked = checkSelection({ ...props, data, type: 'some', byDefaultChecked: true, }) && !checkSelection({ ...props, data, type: 'every', byDefaultChecked: true, }); if (store.selectionDirty) { return someCheckedNotByDefaultChecked; } return someCheckedNotByDefaultChecked || someCheckedByDefaultChecked; } function getCheckState(props) { const { store, data } = props; if (!data.length) { return false; } if (store.selectionDirty) { return checkSelection({ ...props, data, type: 'every', byDefaultChecked: false, }); } return ( checkSelection({ ...props, data, type: 'every', byDefaultChecked: false, }) || checkSelection({ ...props, data, type: 'every', byDefaultChecked: true, }) ); } export default defineComponent({ name: 'SelectionCheckboxAll', mixins: [BaseMixin], inheritAttrs: false, props: SelectionCheckboxAllProps, setup(props) { return { defaultSelections: [], checked: computed(() => { return getCheckState(props); }), indeterminate: computed(() => { return getIndeterminateState(props); }), }; }, created() { const { $props: props } = this; this.defaultSelections = props.hideDefaultSelections ? [] : [ { key: 'all', text: props.locale.selectAll, }, { key: 'invert', text: props.locale.selectInvert, }, ]; }, methods: { handleSelectAllChange(e) { const { checked } = e.target; this.$emit('select', checked ? 'all' : 'removeAll', 0, null); }, renderMenus(selections) { return selections.map((selection, index) => { return ( <Menu.Item key={selection.key || index}> <div onClick={() => { this.$emit('select', selection.key, index, selection.onSelect); }} > {selection.text} </div> </Menu.Item> ); }); }, }, render() { const { disabled, prefixCls, selections, getPopupContainer, checked, indeterminate } = this; const selectionPrefixCls = `${prefixCls}-selection`; let customSelections = null; if (selections) { const newSelections = Array.isArray(selections) ? this.defaultSelections.concat(selections) : this.defaultSelections; const menu = ( <Menu class={`${selectionPrefixCls}-menu`} selectedKeys={[]}> {this.renderMenus(newSelections)} </Menu> ); customSelections = newSelections.length > 0 ? ( <Dropdown getPopupContainer={getPopupContainer} overlay={menu}> <div class={`${selectionPrefixCls}-down`}> <DownOutlined /> </div> </Dropdown> ) : null; } return ( <div class={selectionPrefixCls}> <Checkbox class={classNames({ [`${selectionPrefixCls}-select-all-custom`]: customSelections })} checked={checked} indeterminate={indeterminate} disabled={disabled} onChange={this.handleSelectAllChange} /> {customSelections} </div> ); }, });