From ad972c7f92a54a0fa345bfc702aab1198f539b9d Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 25 Oct 2021 21:42:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A9=BF=E6=A2=AD=E6=A1=86=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0tooltip=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/transfer/common/use-transfer-base.ts | 8 ++ devui/transfer/common/use-transfer.ts | 38 +++++-- devui/transfer/src/transfer-base.tsx | 112 +++++++++++++++------ devui/transfer/src/transfer.scss | 28 +++++- devui/transfer/src/transfer.tsx | 36 ++++++- 5 files changed, 172 insertions(+), 50 deletions(-) diff --git a/devui/transfer/common/use-transfer-base.ts b/devui/transfer/common/use-transfer-base.ts index ff58c152..5597efc2 100644 --- a/devui/transfer/common/use-transfer-base.ts +++ b/devui/transfer/common/use-transfer-base.ts @@ -53,6 +53,14 @@ export const transferBaseProps = { type: Number, default: (): number => 0 }, + showTooltip: { + type: Boolean, + default: (): boolean => false + }, + positionTooltip: { + type: String as PropType<'top' | 'right' | 'bottom' | 'left'>, + default: (): string => 'top' + }, scopedSlots: { type: Object }, diff --git a/devui/transfer/common/use-transfer.ts b/devui/transfer/common/use-transfer.ts index 42eee67d..ecdea4e3 100644 --- a/devui/transfer/common/use-transfer.ts +++ b/devui/transfer/common/use-transfer.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes, PropType, SetupContext } from 'vue' -import { IItem, ITitles, IModel } from '../types' +import { IItem, ITitles, IModel, TState } from '../types' export const transferProps = { sourceOption: { @@ -26,30 +26,52 @@ export const transferProps = { }, height: { type: String, - default: '320px' + default: (): string => '320px' }, isSearch: { type: Boolean, - default: false + default: (): boolean => false }, isSourceDroppable: { type: Boolean, - default: false + default: (): boolean => false }, isTargetDroppable: { type: Boolean, - default: false + default: (): boolean => false }, disabled: { type: Boolean, - default: false + default: (): boolean => false }, - showOptionTitle: { + showTooltip: { type: Boolean, - default: false + default: (): boolean => false + }, + positionTooltip: { + type: String as PropType<'top' | 'right' | 'bottom' | 'left'>, + default: (): string => 'top' + }, + beforeTransfer: { + type: Boolean }, slots: { type: Object + }, + searching: { + type: Function as unknown as () => ((direction: string, keyword: string, targetOption: TState) => void) + }, + transferToSource: { + type: Function as unknown as () => ((sourceOption: TState, targetOption: TState) => void) + }, + transferToTarget: { + type: Function as unknown as () => ((sourceOption: TState, targetOption: TState) => void) + }, + transferring: { + type: Function as unknown as () => ((targetOption: TState) => void) + }, + afterTransfer: { + type: Function as unknown as () => ((targetOption: TState) => void) } } diff --git a/devui/transfer/src/transfer-base.tsx b/devui/transfer/src/transfer-base.tsx index 605057af..b10c8708 100644 --- a/devui/transfer/src/transfer-base.tsx +++ b/devui/transfer/src/transfer-base.tsx @@ -1,19 +1,22 @@ -import { defineComponent, computed } from 'vue' -import { transferBaseProps, TransferBaseClass , TransferBaseProps } from '../common/use-transfer-base' +import { defineComponent, computed, ref } from 'vue' +import { transferBaseProps, TransferBaseClass, TransferBaseProps } from '../common/use-transfer-base' import DCheckbox from '../../checkbox/src/checkbox' import DCheckboxGroup from '../../checkbox/src/checkbox-group' import DSearch from '../../search/src/search' +import DTooltip from '../../tooltip/src/tooltip' export default defineComponent({ name: 'DTransferBase', components: { DSearch, DCheckboxGroup, - DCheckbox + DCheckbox, + DTooltip }, props: transferBaseProps, setup(props: TransferBaseProps, ctx) { /** data start **/ - const modelValues = computed(() => props.checkedValues) + const modelValues = computed(() => props.checkedValues as Array) + // const modelValues = computed(() => props.checkedValues)// as Array) const searchQuery = computed(() => props.query) const baseClass = TransferBaseClass(props) /** data end **/ @@ -23,13 +26,50 @@ export default defineComponent({ /** methods start **/ const updateSearchQuery = (val: string): void => ctx.emit('changeQuery', val) + + const renderBody = () => { + if (props.showTooltip) { + return ( ctx.emit('updateCheckeds', values)}> + { + props.sourceOption.map((item, idx) => { + return + + + + }) + } + ) + } else { + return ( ctx.emit('updateCheckeds', values)}> + { + props.sourceOption.map((item, idx) => { + return + + }) + } + ) + } + } /** methods start **/ return { baseClass, searchQuery, modelValues, - updateSearchQuery + updateSearchQuery, + renderBody } }, render() { @@ -43,9 +83,10 @@ export default defineComponent({ updateSearchQuery, search, searchQuery, - modelValues + modelValues, + renderBody } = this - + return (
{ @@ -61,33 +102,38 @@ export default defineComponent({
) } { - this.$slots.body ? this.$slots.body() :
- {search && } -
- { - sourceOption.length ? this.$emit('updateCheckeds', values)}> - { - sourceOption.map((item, idx) => { - return - - }) - } - : -
无数据
- } + this.$slots.body ? this.$slots.body() : +
+ {search && } +
+ { + sourceOption.length ? renderBody() : +
无数据
+ // sourceOption.length ? this.$emit('updateCheckeds', values)}> + // { + // sourceOption.map((item, idx) => { + // return + // + // + // + // }) + // } + // : + //
无数据
+ } +
-
}
) diff --git a/devui/transfer/src/transfer.scss b/devui/transfer/src/transfer.scss index 9328c50e..374721c9 100644 --- a/devui/transfer/src/transfer.scss +++ b/devui/transfer/src/transfer.scss @@ -36,12 +36,12 @@ $devui-transfer-body-list-item-height: 36px; height: 100%; &-search { - height: $devui-transfer-body-search-height; display: flex; justify-content: center; - width: calc(100% - 40px); align-items: center; - margin: 0 auto; + width: 100%; + height: $devui-transfer-body-search-height; + padding: 0 20px; .devui-search, .devui-input__wrap { @@ -53,11 +53,31 @@ $devui-transfer-body-list-item-height: 36px; overflow: auto; height: calc(100% - #{$devui-transfer-header-height} - #{$devui-transfer-body-search-height}); width: 100%; + padding: 0 20px; &-item { - margin: 0 20px; height: $devui-transfer-body-list-item-height; line-height: $devui-transfer-body-list-item-height; + width: min-content; + max-width: 100%; + + label { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + height: auto; + } + } + + &-tooltip { + // display: flex; + // max-width: calc(100% - 20px); + // overflow: hidden; + // text-overflow: ellipsis; + // white-space: nowrap; + .slotElement { + max-width: 100%; + } } &-empty { diff --git a/devui/transfer/src/transfer.tsx b/devui/transfer/src/transfer.tsx index e05273d0..2ec0eba7 100644 --- a/devui/transfer/src/transfer.tsx +++ b/devui/transfer/src/transfer.tsx @@ -70,8 +70,18 @@ export default defineComponent({ } } - const updateFilterData = (source: TState, target: TState): void => { + const updateFilterData = (source: TState, target: TState, direction: string): void => { const newData = [] + const hasToSource = isFunction('transferToSource') + const hasToTarget = isFunction('transferToTarget') + const hasTransfer = isFunction('transferring') + + if (hasToSource || hasToTarget || hasTransfer) { + hasToSource && direction === 'right' && props.transferToSource.call(null, source, target) + hasToTarget && direction === 'left' && props.transferToTarget.call(null, source, target) + hasTransfer && props.transferring.call(null, target) + return + } source.data = source.data.filter(item => { const hasInclues = source.checkedValues.includes(item.value) hasInclues && newData.push(item) @@ -83,6 +93,7 @@ export default defineComponent({ searchFilterData(source, target) searchFilterData(target, source) setOrigin('click') + isFunction('afterTransfer') && props.afterTransfer.call(null, target) } const changeAllSource = (source: TState, value: boolean): void => { if (source.filterData.every(item => item.disabled)) return @@ -112,6 +123,17 @@ export default defineComponent({ const setOrigin = (value: string): void => { origin.value = value } + const changeQueryHandle = (source: TState, direction: string, value: string): void => { + if (props?.searching && typeof props.searching === 'function') { + props.searching.call(null, direction, value, source) + return + } + source.query = value + } + + const isFunction = (type: string): boolean => { + return props[type] && typeof props[type] === 'function' + } /** methods end **/ return () => { @@ -129,6 +151,8 @@ export default defineComponent({ query={leftOptions.query} checkedValues={leftOptions.checkedValues} allCount={leftOptions.data.length} + showTooltip={props.showTooltip} + positionTooltip={props.positionTooltip} v-slots={ { header: headerSlot(ctx, 'left'), @@ -137,7 +161,7 @@ export default defineComponent({ } onChangeAllSource={(value) => changeAllSource(leftOptions, value)} onUpdateCheckeds={updateLeftCheckeds} - onChangeQuery={(value) => leftOptions.query = value} + onChangeQuery={(value) => changeQueryHandle(leftOptions, 'left', value)} /> 0 ? false : true} targetDisabled={leftOptions.checkedNum > 0 ? false : true} - onUpdateSourceData={() => { updateFilterData(rightOptions, leftOptions) }} - onUpdateTargetData={() => { updateFilterData(leftOptions, rightOptions) }} + onUpdateSourceData={() => { updateFilterData(rightOptions, leftOptions, 'left') }} + onUpdateTargetData={() => { updateFilterData(leftOptions, rightOptions, 'right') }} /> changeAllSource(rightOptions, value)} onUpdateCheckeds={updateRightCheckeds} - onChangeQuery={(value) => rightOptions.query = value} + onChangeQuery={(value) => changeQueryHandle(rightOptions, 'right', value)} /> } -- Gitee