feat: update vc-tree-select

feat-dayjs^2
tanjinzhou 2020-10-20 17:41:11 +08:00
parent 4be3da0701
commit 7a2e2e3c3b
13 changed files with 102 additions and 106 deletions

View File

@ -3,18 +3,18 @@ const getTransitionGroupProps = (transitionName, opt = {}) => {
if (process.env.NODE_ENV === 'test') {
return { css: false, ...opt };
}
const transitionProps = {
const transitionProps = transitionName ? {
appear: true,
appearFromClass: `${transitionName}-appear ${transitionName}-appear-prepare`,
appearActiveClass: `${transitionName}`,
appearToClass: `${transitionName}-appear-active`,
appearToClass: `${transitionName}-appear ${transitionName}-appear-active`,
enterFromClass: `${transitionName}-appear ${transitionName}-enter ${transitionName}-appear-prepare ${transitionName}-enter-prepare`,
enterActiveClass: `${transitionName}`,
enterToClass: `${transitionName}-appear-active ${transitionName}-enter-active`,
enterToClass: `${transitionName}-enter ${transitionName}-appear ${transitionName}-appear-active ${transitionName}-enter-active`,
leaveActiveClass: `${transitionName} ${transitionName}-leave`,
leaveToClass: `${transitionName}-leave-active`,
...opt,
};
} : { css: false, ...opt };
return transitionProps;
};

View File

@ -2,7 +2,7 @@ const getTransitionProps = (transitionName, opt = {}) => {
if (process.env.NODE_ENV === 'test') {
return { css: false, ...opt };
}
const transitionProps = {
const transitionProps = transitionName ? {
appear: true,
appearFromClass: `${transitionName}-appear ${transitionName}-appear-prepare`,
// appearActiveClass: `antdv-base-transtion`,
@ -14,7 +14,7 @@ const getTransitionProps = (transitionName, opt = {}) => {
leaveActiveClass: `${transitionName}-leave ${transitionName}-leave-active`,
leaveToClass: `${transitionName}-leave ${transitionName}-leave-active`,
...opt,
};
}: { css: false, ...opt };
return transitionProps;
};

View File

@ -15,6 +15,7 @@ import Tooltip from '../tooltip';
import Progress from '../progress';
import classNames from '../_util/classNames';
import { UploadListProps } from './interface';
import getTransitionGroupProps from '../_util/getTransitionGroupProps';
export default {
name: 'AUploadList',
@ -265,7 +266,7 @@ export default {
[`${prefixCls}-list-${listType}`]: true,
});
const animationDirection = listType === 'picture-card' ? 'animate-inline' : 'animate';
const transitionGroupProps = getTransitionProps(`${prefixCls}-${animationDirection}`);
const transitionGroupProps = getTransitionGroupProps(`${prefixCls}-${animationDirection}`);
return (
<TransitionGroup {...transitionGroupProps} tag="div" class={listClassNames}>
{list}

View File

@ -3,8 +3,8 @@ import PropTypes from '../_util/vue-types';
import { getComponent } from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin';
import createChainedFunction from '../_util/createChainedFunction';
import getTransitionProps from '../_util/getTransitionProps';
import Notice from './Notice';
import getTransitionGroupProps from '../_util/getTransitionGroupProps';
function noop() {}
@ -75,7 +75,7 @@ const Notification = defineComponent({
render() {
const { prefixCls, notices, remove, getTransitionName, $attrs } = this;
const transitionProps = getTransitionProps(getTransitionName());
const transitionProps = getTransitionGroupProps(getTransitionName());
const noticeNodes = notices.map((notice, index) => {
const update = Boolean(index === notices.length - 1 && notice.updateKey);
const key = notice.updateKey ? notice.updateKey : notice.key;

View File

@ -158,11 +158,9 @@ const SelectSelector = defineComponent<SelectorProps>({
: maxTagPlaceholder,
});
}
const transitionProps = choiceTransitionName
? getTransitionGroupProps(choiceTransitionName, {
appear: motionAppear,
})
: { css: false };
const transitionProps = getTransitionGroupProps(choiceTransitionName, {
appear: motionAppear,
})
selectionNode.value = (
<TransitionGroup {...transitionProps}>
{...displayValues.map(

View File

@ -30,10 +30,12 @@ export const selectorPropTypes = () => ({
placeholder: PropTypes.any,
disabled: PropTypes.looseBool,
focused: PropTypes.looseBool,
isMultiple: PropTypes.looseBool,
showSearch: PropTypes.looseBool,
});
function noop() {}
export default function(modeName) {
export default function() {
const BaseSelector = {
name: 'BaseSelector',
inheritAttrs: false,
@ -101,7 +103,7 @@ export default function(modeName) {
}
const clearIcon = getComponent(this, 'clearIcon');
return (
<span key="clear" class={`${prefixCls}-selection__clear`} onClick={onSelectorClear}>
<span key="clear" unselectable="on" aria-hidden="true" style="user-select: none;" class={`${prefixCls}-clear`} onClick={onSelectorClear}>
{clearIcon}
</span>
);
@ -114,7 +116,7 @@ export default function(modeName) {
}
const inputIcon = getComponent(this, 'inputIcon');
return (
<span key="arrow" class={`${prefixCls}-arrow`} style={{ outline: 'none' }}>
<span key="arrow" class={`${prefixCls}-arrow`} style={{ outline: 'none', userSelect: 'none' }}>
{inputIcon}
</span>
);
@ -132,6 +134,9 @@ export default function(modeName) {
renderSelection,
renderPlaceholder,
tabindex,
isMultiple,
showArrow,
showSearch,
} = this.$props;
const { class: className, style, onClick = noop } = this.$attrs;
const {
@ -142,18 +147,21 @@ export default function(modeName) {
if (disabled) {
myTabIndex = null;
}
const mergedClassName = classNames(prefixCls, className, {
[`${prefixCls}-focused`]: open || focused,
[`${prefixCls}-multiple`]: isMultiple,
[`${prefixCls}-single`]: !isMultiple,
[`${prefixCls}-allow-clear`]: allowClear,
[`${prefixCls}-show-arrow`]: showArrow,
[`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-open`]: open,
[`${prefixCls}-show-search`]: showSearch,
});
return (
<span
<div
style={style}
onClick={onClick}
class={classNames(className, prefixCls, {
[`${prefixCls}-open`]: open,
[`${prefixCls}-focused`]: open || focused,
[`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-enabled`]: !disabled,
[`${prefixCls}-allow-clear`]: allowClear,
})}
class={mergedClassName}
ref={this.domRef}
role="combobox"
aria-expanded={open}
@ -166,17 +174,13 @@ export default function(modeName) {
onBlur={this.onBlur}
onKeydown={onSelectorKeyDown}
>
<span
key="selection"
class={classNames(`${prefixCls}-selection`, `${prefixCls}-selection--${modeName}`)}
>
<span class={`${prefixCls}-selector`}>
{renderSelection()}
{this.renderClear()}
{this.renderArrow()}
{renderPlaceholder && renderPlaceholder()}
</span>
</span>
{this.renderArrow()}
{this.renderClear()}
</div>
);
},
};

View File

@ -40,7 +40,7 @@ const SinglePopup = {
display: searchValue ? 'none' : 'block',
}}
onClick={this.onPlaceholderClick}
class={`${prefixCls}-search__field__placeholder`}
class={`${prefixCls}-selection-placeholder`}
>
{searchPlaceholder}
</span>

View File

@ -4,7 +4,7 @@
* - multiple: in the selector
* Move the code as a SearchInput for easy management.
*/
import { inject, withDirectives } from 'vue';
import { inject, withDirectives, ref, onMounted, computed, watch } from 'vue';
import antInput from '../../_util/antInputDirective';
import PropTypes from '../../_util/vue-types';
import { createRef } from './util';
@ -21,8 +21,22 @@ const SearchInput = {
needAlign: PropTypes.looseBool,
ariaId: PropTypes.string,
},
setup() {
setup(props) {
const measureRef = ref();
const inputWidth = ref(0);
// We measure width and set to the input immediately
onMounted(() => {
watch(
computed(()=>props.searchValue),
() => {
inputWidth.value = measureRef.value.scrollWidth;
},
{ flush: 'post' },
);
});
return {
measureRef,
inputWidth,
vcTreeSelect: inject('vcTreeSelect', {}),
};
},
@ -38,7 +52,7 @@ const SearchInput = {
},
created() {
this.inputRef = createRef();
this.mirrorInputRef = createRef();
// this.mirrorInputRef = createRef();
this.prevProps = { ...this.$props };
},
mounted() {
@ -55,15 +69,15 @@ const SearchInput = {
},
updated() {
const { open, searchValue, needAlign } = this.$props;
const { open } = this.$props;
const { prevProps } = this;
this.$nextTick(() => {
if (open && prevProps.open !== open) {
this.focus();
}
if (needAlign && searchValue !== prevProps.searchValue) {
this.alignInputWidth();
}
// if (needAlign && searchValue !== prevProps.searchValue) {
// this.alignInputWidth();
// }
this.prevProps = { ...this.$props };
});
},
@ -73,10 +87,10 @@ const SearchInput = {
* ref: https://github.com/react-component/tree-select/issues/65
* clientWidth 0 when mounted in vue. why?
*/
alignInputWidth() {
this.inputRef.current.style.width = `${this.mirrorInputRef.current.clientWidth ||
this.mirrorInputRef.current.offsetWidth}px`;
},
// alignInputWidth() {
// this.inputRef.current.style.width = `${this.mirrorInputRef.current.clientWidth ||
// this.mirrorInputRef.current.offsetWidth}px`;
// },
/**
* Need additional timeout for focus cause parent dom is not ready when didMount trigger
@ -116,31 +130,34 @@ const SearchInput = {
vcTreeSelect: { onSearchInputKeyDown },
handleInputChange,
mirrorSearchValue,
inputWidth,
} = this;
return (
<span class={`${prefixCls}-search__field__wrap`}>
{withDirectives(
<input
type="text"
ref={this.inputRef}
onInput={handleInputChange}
onChange={handleInputChange}
onKeydown={onSearchInputKeyDown}
value={searchValue}
disabled={disabled}
class={`${prefixCls}-search__field`}
aria-label="filter select"
aria-autocomplete="list"
aria-controls={open ? ariaId : undefined}
aria-multiline="false"
/>,
[[antInput]],
)}
<span ref={this.mirrorInputRef} class={`${prefixCls}-search__field__mirror`}>
{mirrorSearchValue}&nbsp;
<>
<span class={`${prefixCls}-selection-search`} style={{ width: inputWidth + 'px' }}>
{withDirectives(
<input
type="text"
ref={this.inputRef}
onInput={handleInputChange}
onChange={handleInputChange}
onKeydown={onSearchInputKeyDown}
value={searchValue}
disabled={disabled}
class={`${prefixCls}-selection-search-input`}
aria-label="filter select"
aria-autocomplete="list"
aria-controls={open ? ariaId : undefined}
aria-multiline="false"
/>,
[[antInput]],
)}
<span ref="measureRef" class={`${prefixCls}-selection-search-mirror`} aria-hidden>
{mirrorSearchValue}&nbsp;
</span>
</span>
{renderPlaceholder && !mirrorSearchValue ? renderPlaceholder() : null}
</span>
</>
);
},
};

View File

@ -1096,7 +1096,7 @@ const Select = defineComponent({
const $popup = <Popup {...popupProps} __propsSymbol__={[]} />;
const Selector = isMultiple ? MultipleSelector : SingleSelector;
const $selector = <Selector {...passProps} ref={this.selectorRef} />;
const $selector = <Selector {...passProps} isMultiple={isMultiple} ref={this.selectorRef} />;
const selectTriggerProps = {
...passProps,
popupElement: $popup,

View File

@ -32,20 +32,20 @@ const Selection = {
}
const { class: className, style, onRemove } = this.$attrs;
return (
<li
<span
style={{ ...UNSELECTABLE_STYLE, ...style }}
{...UNSELECTABLE_ATTRIBUTE}
role="menuitem"
class={classNames(`${prefixCls}-selection__choice`, className)}
class={classNames(`${prefixCls}-selection-item`, className)}
title={toTitle(label)}
>
<span class={`${prefixCls}-selection-item-content`}>{content}</span>
{onRemove && (
<span class={`${prefixCls}-selection__choice__remove`} onClick={this.onRemove}>
<span class={`${prefixCls}-selection-item-remove`} onClick={this.onRemove}>
{getComponent(this, 'removeIcon')}
</span>
)}
<span class={`${prefixCls}-selection__choice__content`}>{content}</span>
</li>
</span>
);
},
};

View File

@ -1,11 +1,10 @@
import { inject, TransitionGroup } from 'vue';
import { inject } from 'vue';
import PropTypes from '../../../../_util/vue-types';
import { createRef } from '../../util';
import generateSelector, { selectorPropTypes } from '../../Base/BaseSelector';
import SearchInput from '../../SearchInput';
import Selection from './Selection';
import { getComponent, getSlot } from '../../../../_util/props-util';
import getTransitionProps from '../../../../_util/getTransitionProps';
import BaseMixin from '../../../../_util/BaseMixin';
const TREE_SELECT_EMPTY_VALUE_KEY = 'RC_TREE_SELECT_EMPTY_VALUE_KEY';
@ -73,7 +72,7 @@ const MultipleSelector = {
display: hidden ? 'none' : 'block',
}}
onClick={this.onPlaceholderClick}
class={`${prefixCls}-search__field__placeholder`}
class={`${prefixCls}-selection-placeholder`}
>
{currentPlaceholder}
</span>
@ -85,8 +84,6 @@ const MultipleSelector = {
renderSelection() {
const {
selectorValueList,
choiceTransitionName,
prefixCls,
labelInValue,
maxTagCount,
} = this.$props;
@ -144,7 +141,6 @@ const MultipleSelector = {
}
selectedValueNodes.push(
<li class={`${prefixCls}-search ${prefixCls}-search--inline`} key="__input">
<SearchInput
{...{
...this.$props,
@ -154,26 +150,10 @@ const MultipleSelector = {
ref={this.inputRef}
>
{children}
</SearchInput>
</li>,
);
const className = `${prefixCls}-selection__rendered`;
if (choiceTransitionName) {
const transitionProps = getTransitionProps(choiceTransitionName, {
tag: 'ul',
onAfterLeave: this.onChoiceAnimationLeave,
});
return (
<TransitionGroup class={className} {...transitionProps}>
{selectedValueNodes}
</TransitionGroup>
);
}
return (
<ul class={className} role="menubar">
{selectedValueNodes}
</ul>
</SearchInput>,
);
return selectedValueNodes;
},
},

View File

@ -21,24 +21,20 @@ const SingleSelector = {
renderSelection() {
const { selectorValueList, placeholder, prefixCls } = this.$props;
let innerNode;
if (selectorValueList.length) {
const { label, value } = selectorValueList[0];
innerNode = (
<span key="value" title={toTitle(label)} class={`${prefixCls}-selection-selected-value`}>
return (
<span key="value" title={toTitle(label)} class={`${prefixCls}-selection-item`}>
{label || value}
</span>
);
} else {
innerNode = (
<span key="placeholder" class={`${prefixCls}-selection__placeholder`}>
return (
<span key="placeholder" class={`${prefixCls}-selection-placeholder`}>
{placeholder}
</span>
);
}
return <span class={`${prefixCls}-selection__rendered`}>{innerNode}</span>;
},
},