Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Drawer, Menu, Select, Progress issues #840

Merged
merged 9 commits into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/transfer/demos/base.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:data="list"
:checked="checked"
@change="onChange"
@checkedChange="handleCheckedChange"
@checked-change="handleCheckedChange"
/>
</div>
</template>
Expand Down
3 changes: 1 addition & 2 deletions examples/transfer/demos/search.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div>
<t-transfer v-model="targetValue" theme="primary" :data="list" :checked-value="checkedValue" :search="true" />
<t-transfer v-model="targetValue" theme="primary" :data="list" :search="true" />
</div>
</template>
<script setup>
Expand All @@ -15,5 +15,4 @@ for (let i = 0; i < 20; i++) {
}

const targetValue = ref([]);
const checkedValue = ref([]);
</script>
18 changes: 6 additions & 12 deletions src/drawer/drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { computed, defineComponent, nextTick, onUpdated, ref, watch } from 'vue';
import { computed, defineComponent, nextTick, onUpdated, toRefs, ref, watch } from 'vue';
import { CloseIcon } from 'tdesign-icons-vue-next';
import { useConfig, usePrefixClass } from '../hooks/useConfig';
import { isServer, addClass, removeClass } from '../utils/dom';
Expand All @@ -14,17 +14,10 @@ type FooterButtonType = 'confirm' | 'cancel';

export default defineComponent({
name: 'TDrawer',

components: {
CloseIcon,
TButton,
},

directives: {
TransferDom,
},
props,
// TODO update:visible 是否是受控的
emits: ['update:visible'],
setup(props, context) {
const { global } = useConfig('drawer');
Expand Down Expand Up @@ -119,14 +112,14 @@ export default defineComponent({
const theme = isCancel ? 'default' : 'primary';
const isApiObject = typeof btnApi === 'object';
return (
<t-button
<TButton
theme={theme}
onClick={clickAction}
props={isApiObject ? btnApi : {}}
class={`${COMPONENT_NAME.value}-${btnType}`}
>
{btnApi && typeof btnApi === 'object' ? btnApi.content : btnApi}
</t-button>
</TButton>
);
};
const isUseDefault = (btnApi: FooterButton) => {
Expand Down Expand Up @@ -224,18 +217,19 @@ export default defineComponent({
render() {
const { COMPONENT_NAME } = this;
if (this.destroyOnClose && !this.visible) return;
const defaultCloseBtn = <close-icon class="t-submenu-icon"></close-icon>;
const defaultCloseBtn = <CloseIcon class="t-submenu-icon"></CloseIcon>;
const body = renderContent(this, 'body', 'default');
const headerContent = renderTNodeJSX(this, 'header');
const defaultFooter = this.getDefaultFooter();
return (
<div
ref="drawerEle"
class={this.drawerClasses}
style={{ zIndex: this.zIndex }}
onKeydown={this.onKeyDown}
v-transfer-dom={this.attach}
{...this.$attrs}
ref="drawerEle"
tabindex={0}
>
{this.showOverlay && <div class={`${COMPONENT_NAME}__mask`} onClick={this.handleWrapperClick} />}
<div class={this.wrapperClasses} style={this.wrapperStyles}>
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/useDefaultValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { ref, Ref, getCurrentInstance, watch } from 'vue';
import { ChangeHandler } from './useVModel';

// 用于实现 v-model:propsName
export default function useDefaultValue<T, P extends any[]>(
export default function useDefaultValue<T, P extends (...args: any) => void>(
value: Ref<T>,
defaultValue: T,
onChange: ChangeHandler<T, P>,
onChange: P,
propsName: string,
): [Ref<T>, ChangeHandler<T, P>] {
): [Ref<T>, ChangeHandler<T>] {
const { emit, attrs } = getCurrentInstance();
const internalValue = ref();
internalValue.value = defaultValue;
Expand Down
8 changes: 4 additions & 4 deletions src/hooks/useVModel.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ref, Ref, getCurrentInstance, watch } from 'vue';

export type ChangeHandler<T, P extends any[]> = (value: T, ...args: P) => void;
export type ChangeHandler<T> = (value: T, ...args: any) => void;

export default function useVModel<T, P extends any[]>(
export default function useVModel<T, P extends (...args: any) => void>(
value: Ref<T>,
modelValue: Ref<T>,
defaultValue: T,
onChange: ChangeHandler<T, P>,
onChange: P,
propName = 'value',
// emit 和 eventName 用于支持 v-model 和 xxx.sync 语法糖
): [Ref<T>, ChangeHandler<T, P>] {
): [Ref<T>, ChangeHandler<T>] {
const { emit, attrs } = getCurrentInstance();
const internalValue: Ref<T> = ref();

Expand Down
2 changes: 1 addition & 1 deletion src/menu/submenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export default defineComponent({
class={[
// ...this.popupClass,
`${this.classPrefix}-menu__spacer`,
`${this.classPrefix}-menu__spacer--${!this.isNested && this.head ? 'top' : 'left'}`,
`${this.classPrefix}-menu__spacer--${!this.isNested && this.isHead ? 'top' : 'left'}`,
]}
onMouseenter={this.handleEnterPopup}
onMouseleave={this.handleMouseLeavePopup}
Expand Down
20 changes: 12 additions & 8 deletions src/progress/progress.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineComponent, VNode, computed } from 'vue';
import { defineComponent, VNode, computed, CSSProperties } from 'vue';
import {
CloseCircleFilledIcon,
CheckCircleFilledIcon,
Expand All @@ -23,16 +23,20 @@ export default defineComponent({
if (props.percentage >= 100) {
return 'success';
}
return props.status;
return props.status || 'default';
});

const trackBgStyle = computed(() => {
const height = typeof props.strokeWidth === 'string' ? props.strokeWidth : `${props.strokeWidth}px`;
return {
height,
backgroundColor: props.trackColor,
borderRadius: height,
};
const style: CSSProperties = {};
if (props.strokeWidth) {
const height = typeof props.strokeWidth === 'string' ? props.strokeWidth : `${props.strokeWidth}px`;
style.height = height;
style.borderRadius = height;
}
if (props.trackColor) {
style.backgroundColor = props.trackColor;
}
return style;
});

const barStyle = computed(() => {
Expand Down
7 changes: 6 additions & 1 deletion src/select/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,12 @@ export default {
selectInputProps: {
type: Object as PropType<TdSelectProps['selectInputProps']>,
},
/** 是否显示右侧箭头,默认显示 */
/** 【讨论中】是否显示全选 */
showCheckAlll: Boolean,
/**
* 是否显示右侧箭头,默认显示
* @default true
*/
showArrow: {
type: Boolean,
default: true,
Expand Down
18 changes: 10 additions & 8 deletions src/select/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,12 @@ export default defineComponent({
// to fix Computed property "showArrow" is already defined in Props.
innerShowArrow(): boolean {
return (
!this.clearable ||
!this.isHover ||
this.disabled ||
(!this.multiple && !this.value && this.value !== 0) ||
(this.multiple && (!Array.isArray(this.value) || (Array.isArray(this.value) && !this.value.length)))
this.showArrow &&
(!this.clearable ||
!this.isHover ||
this.disabled ||
(!this.multiple && !this.value && this.value !== 0) ||
(this.multiple && (!Array.isArray(this.value) || (Array.isArray(this.value) && !this.value.length))))
);
},
canFilter(): boolean {
Expand Down Expand Up @@ -478,6 +479,10 @@ export default defineComponent({
emitEvent<Parameters<TdSelectProps['onChange']>>(this, 'change', value, { trigger });
},
createOption(value: string) {
this.$nextTick(() => {
this.searchInput = '';
this.showCreateOption = false;
});
emitEvent<Parameters<TdSelectProps['onCreate']>>(this, 'create', value);
},
debounceOnRemote: debounce(function (this: any) {
Expand Down Expand Up @@ -534,9 +539,6 @@ export default defineComponent({
case 'Enter':
if (this.showCreateOption) {
this.createOption(this.searchInput);
this.$nextTick(() => {
this.searchInput = '';
});
}
this.hoverOptions[this.hoverIndex] &&
this.onOptionClick(this.hoverOptions[this.hoverIndex][this.realValue], e);
Expand Down
8 changes: 3 additions & 5 deletions src/transfer/components/transfer-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '../interface';
import { PageInfo, TdPaginationProps, Pagination } from '../../pagination';
import { Checkbox as TCheckbox, CheckboxGroup as TCheckboxGroup, CheckboxProps } from '../../checkbox';
import { getLeefCount, getDataValues } from '../utils';
import { getLefCount, getDataValues } from '../utils';
import Search from './transfer-search';
import { useTNodeDefault } from '../../hooks/tnode';

Expand Down Expand Up @@ -121,9 +121,7 @@ export default defineComponent({
}
: {};
});
const hasFooter = computed(() => {
return !!slots.default;
});

const isAllChecked = computed(() => {
return (
props.checkedValue.length > 0 &&
Expand All @@ -135,7 +133,7 @@ export default defineComponent({
});

const totalCount = computed(() => {
return getLeefCount(props.dataSource);
return getLefCount(props.dataSource);
});

const handlePaginationChange = (pageInfo: PageInfo) => {
Expand Down
2 changes: 1 addition & 1 deletion src/transfer/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default {
/** 数据列表选中项 */
checked: {
type: Array as PropType<TdTransferProps['checked']>,
default: (): TdTransferProps['checked'] => [],
default: undefined,
},
/** 数据列表选中项,非受控属性 */
defaultChecked: {
Expand Down
44 changes: 9 additions & 35 deletions src/transfer/transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,14 @@ import { defineComponent, computed, toRefs, ref } from 'vue';
import pick from 'lodash/pick';
import TransferList from './components/transfer-list';
import TransferOperations from './components/transfer-operations';
import {
TransferListType,
TransferItemOption,
CheckedOptions,
TransferValue,
EmptyType,
TargetParams,
SearchEvent,
} from './interface';
import { TransferListType, CheckedOptions, TransferValue, EmptyType, TargetParams, SearchEvent } from './interface';

import { getTransferListOption, getDataValues, getTransferData, filterTransferData, TRANSFER_NAME } from './utils';
import { PageInfo, TdPaginationProps } from '../pagination/type';
import props from './props';
import { TNode } from '../common';
import useVModel from '../hooks/useVModel';
import useDefaultValue from '../hooks/useDefaultValue';

// hooks
import { useFormDisabled } from '../form/hooks';
Expand All @@ -33,18 +26,9 @@ export default defineComponent({
const disabled = useFormDisabled();
const classPrefix = usePrefixClass();
const { t, global } = useConfig('transfer');
const { value, modelValue } = toRefs(props);
const { value, modelValue, checked } = toRefs(props);
const [innerValue, setInnerValue] = useVModel(value, modelValue, props.defaultValue, props.onChange);
const initChecked = computed(() => {
if (props.checked && props.checked.length) {
return props.checked;
}
if (props.defaultChecked && props.defaultChecked.length) {
return props.defaultChecked;
}
return [];
});
const checkedValueList = computed(() => initChecked.value);
const [innerChecked] = useDefaultValue(checked, props.defaultChecked, props.onCheckedChange, 'checked');
const valueList = ref(innerValue.value || []);

const isTreeMode = computed(() => {
Expand All @@ -67,8 +51,8 @@ export default defineComponent({
// 被选中的value
const checkedValue = computed(() => {
return {
[SOURCE]: getDataValues(sourceList.value, checkedValueList.value, { isTreeMode: isTreeMode.value }),
[TARGET]: getDataValues(targetList.value, checkedValueList.value, { isTreeMode: isTreeMode.value }),
[SOURCE]: getDataValues(sourceList.value, innerChecked.value, { isTreeMode: isTreeMode.value }),
[TARGET]: getDataValues(targetList.value, innerChecked.value, { isTreeMode: isTreeMode.value }),
};
});
const hasFooter = computed(() => {
Expand Down Expand Up @@ -115,9 +99,8 @@ export default defineComponent({
targetChecked,
type: listType,
};
// 支持v-model:checked
// TODO: 换成 useVModel
props['onUpdate:checked']?.(checked);
// TODO onCheckedChange 参数有点不合理
LeeJim marked this conversation as resolved.
Show resolved Hide resolved
innerChecked.value = checked;
props.onCheckedChange?.(event);
};

Expand Down Expand Up @@ -158,16 +141,7 @@ export default defineComponent({
const transferToLeft = () => {
transferTo(SOURCE);
};
const filterMethod = (
transferList: Array<TransferItemOption>,
targetValueList: Array<TransferValue>,
needMatch: boolean,
): Array<TransferItemOption> => {
return transferList.filter((item) => {
const isMatch = targetValueList.includes(item.value);
return needMatch ? isMatch : !isMatch;
});
};

const handleScroll = (e: Event, listType: TransferListType) => {
const target = e.target as HTMLElement;
const bottomDistance = target.scrollHeight - target.scrollTop - target.clientHeight;
Expand Down
6 changes: 3 additions & 3 deletions src/transfer/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ function filterTransferData(
}

// 获取树节点的叶子数量
function getLeefCount(nodes: Array<TreeNode>): number {
function getLefCount(nodes: Array<TreeNode>): number {
let total = 0;
nodes.forEach((child) => {
if (child.children && child.children.length > 0) {
total += getLeefCount(child.children);
total += getLefCount(child.children);
} else {
total += 1;
}
Expand All @@ -200,5 +200,5 @@ export {
getTransferData,
cloneTreeWithFilter,
filterTransferData,
getLeefCount,
getLefCount,
};
Loading