mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-02 03:58:05 +08:00
feat: select auto-complete support virtual list
This commit is contained in:
parent
4d63b7cab6
commit
46149b660b
@ -1,18 +1,21 @@
|
||||
import { App, defineComponent, inject, provide } from 'vue';
|
||||
import { Option, OptGroup } from '../vc-select';
|
||||
import Select, { SelectProps } from '../select';
|
||||
import Input from '../input';
|
||||
import InputElement from './InputElement';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util';
|
||||
import Omit from 'omit.js';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
const { Option, OptGroup } = Select;
|
||||
|
||||
function isSelectOptionOrSelectOptGroup(child: any): Boolean {
|
||||
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
|
||||
}
|
||||
|
||||
const AutoCompleteProps = {
|
||||
...SelectProps,
|
||||
...SelectProps(),
|
||||
dataSource: PropTypes.array,
|
||||
dropdownMenuStyle: PropTypes.style,
|
||||
optionLabelProp: PropTypes.string,
|
||||
@ -39,7 +42,12 @@ const AutoComplete = defineComponent({
|
||||
},
|
||||
Option: { ...Option, name: 'AAutoCompleteOption' },
|
||||
OptGroup: { ...OptGroup, name: 'AAutoCompleteOptGroup' },
|
||||
setup() {
|
||||
setup(props, { slots }) {
|
||||
warning(
|
||||
!('dataSource' in props || 'dataSource' in slots),
|
||||
'AutoComplete',
|
||||
'`dataSource` is deprecated, please use `options` instead.',
|
||||
);
|
||||
return {
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
popupRef: null,
|
||||
@ -59,11 +67,7 @@ const AutoComplete = defineComponent({
|
||||
getInputElement() {
|
||||
const children = getSlot(this);
|
||||
const element = children.length ? children[0] : <Input lazy={false} />;
|
||||
return (
|
||||
<InputElement placeholder={this.placeholder} {...element.props}>
|
||||
{element}
|
||||
</InputElement>
|
||||
);
|
||||
return <InputElement {...element.props}>{element}</InputElement>;
|
||||
},
|
||||
|
||||
focus() {
|
||||
@ -80,8 +84,8 @@ const AutoComplete = defineComponent({
|
||||
},
|
||||
|
||||
render() {
|
||||
const { size, prefixCls: customizePrefixCls, optionLabelProp, dataSource } = this;
|
||||
|
||||
const { size, prefixCls: customizePrefixCls, dataSource } = this;
|
||||
let optionChildren: any;
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
||||
const { class: className } = this.$attrs as any;
|
||||
@ -92,22 +96,28 @@ const AutoComplete = defineComponent({
|
||||
[`${prefixCls}-show-search`]: true,
|
||||
[`${prefixCls}-auto-complete`]: true,
|
||||
};
|
||||
|
||||
let options;
|
||||
const childArray = getSlot(this, 'dataSource');
|
||||
if (childArray.length && isSelectOptionOrSelectOptGroup(childArray[0])) {
|
||||
options = childArray;
|
||||
optionChildren = childArray;
|
||||
} else {
|
||||
options = dataSource
|
||||
optionChildren = dataSource
|
||||
? dataSource.map((item: any) => {
|
||||
if (isValidElement(item)) {
|
||||
return item;
|
||||
}
|
||||
switch (typeof item) {
|
||||
case 'string':
|
||||
return <Option key={item}>{item}</Option>;
|
||||
return (
|
||||
<Option key={item} value={item}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
case 'object':
|
||||
return <Option key={item.value}>{item.text}</Option>;
|
||||
return (
|
||||
<Option key={item.value} value={item.value}>
|
||||
{item.text}
|
||||
</Option>
|
||||
);
|
||||
default:
|
||||
throw new Error(
|
||||
'AutoComplete[dataSource] only supports type `string[] | Object[]`.',
|
||||
@ -117,17 +127,17 @@ const AutoComplete = defineComponent({
|
||||
: [];
|
||||
}
|
||||
const selectProps = {
|
||||
...getOptionProps(this),
|
||||
...Omit(getOptionProps(this), ['dataSource', 'optionLabelProp'] as any),
|
||||
...this.$attrs,
|
||||
mode: Select.SECRET_COMBOBOX_MODE_DO_NOT_USE,
|
||||
optionLabelProp,
|
||||
// optionLabelProp,
|
||||
getInputElement: this.getInputElement,
|
||||
notFoundContent: getComponent(this, 'notFoundContent'),
|
||||
placeholder: '',
|
||||
// placeholder: '',
|
||||
class: cls,
|
||||
ref: this.saveSelect,
|
||||
};
|
||||
return <Select {...selectProps}>{options}</Select>;
|
||||
return <Select {...selectProps}>{optionChildren}</Select>;
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -9,84 +9,8 @@
|
||||
.@{autocomplete-prefix-cls} {
|
||||
.reset-component;
|
||||
|
||||
&.@{select-prefix-cls} {
|
||||
.@{select-prefix-cls} {
|
||||
&-selection {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
&__rendered {
|
||||
height: 100%;
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
line-height: @input-height-base;
|
||||
}
|
||||
&__placeholder {
|
||||
margin-right: (@input-padding-horizontal-base + 1px);
|
||||
margin-left: (@input-padding-horizontal-base + 1px);
|
||||
}
|
||||
|
||||
&--single {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix https://github.com/ant-design/ant-design/issues/7800
|
||||
.@{select-prefix-cls}-search--inline {
|
||||
position: static;
|
||||
float: left;
|
||||
}
|
||||
|
||||
&-allow-clear {
|
||||
.@{select-prefix-cls}-selection:hover .@{select-prefix-cls}-selection__rendered {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.@{input-prefix-cls} {
|
||||
height: @input-height-base;
|
||||
line-height: @line-height-base;
|
||||
background: transparent;
|
||||
border-width: @border-width-base;
|
||||
&:focus,
|
||||
&:hover {
|
||||
.hover;
|
||||
}
|
||||
&[disabled] {
|
||||
.disabled;
|
||||
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&-lg {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
line-height: @input-height-lg;
|
||||
}
|
||||
.@{input-prefix-cls} {
|
||||
height: @input-height-lg;
|
||||
padding-top: @input-padding-vertical-lg;
|
||||
padding-bottom: @input-padding-vertical-lg;
|
||||
}
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
line-height: @input-height-sm;
|
||||
}
|
||||
.@{input-prefix-cls} {
|
||||
height: @input-height-sm;
|
||||
padding-top: @input-padding-vertical-sm;
|
||||
padding-bottom: @input-padding-vertical-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/14156
|
||||
.@{input-prefix-cls}-group > .@{autocomplete-prefix-cls} {
|
||||
.@{select-prefix-cls}-search__field.@{input-prefix-cls}-affix-wrapper {
|
||||
display: inline;
|
||||
float: none;
|
||||
// https://github.com/ant-design/ant-design/issues/22302
|
||||
.@{select-prefix-cls}-clear {
|
||||
right: 13px;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { getOptionProps, getSlot } from '../_util/props-util';
|
||||
export default {
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
...SelectProps,
|
||||
...SelectProps(),
|
||||
},
|
||||
Option: VcSelect.Option,
|
||||
render() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import omit from 'omit.js';
|
||||
import classNames from '../_util/classNames';
|
||||
import RcSelect, { Option, OptGroup, SelectProps as RcSelectProps, props } from '../vc-select2';
|
||||
import { OptionProps } from '../vc-select2/Option';
|
||||
import RcSelect, { Option, OptGroup, SelectProps as RcSelectProps, BaseProps } from '../vc-select2';
|
||||
import { OptionProps as OptionPropsType } from '../vc-select2/Option';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import getIcons from './utils/iconUtil';
|
||||
import { computed, defineComponent, inject, ref, VNodeChild, App, PropType } from 'vue';
|
||||
@ -10,7 +10,7 @@ import { tuple } from '../_util/type';
|
||||
|
||||
type RawValue = string | number;
|
||||
|
||||
export { OptionProps };
|
||||
export type OptionProps = OptionPropsType;
|
||||
|
||||
export type OptionType = typeof Option;
|
||||
|
||||
@ -31,36 +31,40 @@ export interface InternalSelectProps<VT> extends Omit<RcSelectProps<VT>, 'mode'>
|
||||
}
|
||||
|
||||
export interface SelectPropsTypes<VT>
|
||||
extends Omit<InternalSelectProps<VT>, 'inputIcon' | 'mode' | 'getInputElement' | 'backfill' | 'class' | 'style'> {
|
||||
extends Omit<
|
||||
InternalSelectProps<VT>,
|
||||
'inputIcon' | 'mode' | 'getInputElement' | 'backfill' | 'class' | 'style'
|
||||
> {
|
||||
mode?: 'multiple' | 'tags';
|
||||
}
|
||||
export type SelectTypes = SelectPropsTypes<SelectValue>
|
||||
export const SelectProps = {
|
||||
...omit(props, ['inputIcon' ,'mode' ,'getInputElement' ,'backfill' ,'class' ,'style']),
|
||||
export type SelectTypes = SelectPropsTypes<SelectValue>;
|
||||
export const SelectProps = () => ({
|
||||
...omit(BaseProps(), ['inputIcon', 'mode', 'getInputElement', 'backfill', 'class', 'style']),
|
||||
value: {
|
||||
type: [Array, Object, String, Number] as PropType<SelectValue>
|
||||
type: [Array, Object, String, Number] as PropType<SelectValue>,
|
||||
},
|
||||
defaultValue: {
|
||||
type: [Array, Object, String, Number] as PropType<SelectValue>
|
||||
type: [Array, Object, String, Number] as PropType<SelectValue>,
|
||||
},
|
||||
notFoundContent: PropTypes.VNodeChild,
|
||||
suffixIcon: PropTypes.VNodeChild,
|
||||
itemIcon: PropTypes.VNodeChild,
|
||||
size: PropTypes.oneOf(tuple('small', 'middle', 'large', undefined, 'default')),
|
||||
mode: PropTypes.oneOf(tuple('multiple', 'tags')),
|
||||
size: PropTypes.oneOf(tuple('small', 'middle', 'large', 'default')),
|
||||
mode: PropTypes.oneOf(tuple('multiple', 'tags', 'SECRET_COMBOBOX_MODE_DO_NOT_USE')),
|
||||
bordered: PropTypes.looseBool.def(true),
|
||||
transitionName: PropTypes.string.def('slide-up'),
|
||||
choiceTransitionName: PropTypes.string.def(''),
|
||||
}
|
||||
});
|
||||
|
||||
const Select = defineComponent({
|
||||
name: 'ASelect',
|
||||
Option,
|
||||
OptGroup,
|
||||
inheritAttrs: false,
|
||||
props: SelectProps,
|
||||
props: SelectProps(),
|
||||
SECRET_COMBOBOX_MODE_DO_NOT_USE: 'SECRET_COMBOBOX_MODE_DO_NOT_USE',
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props: any, {attrs, emit}) {
|
||||
setup(props: any, { attrs, emit }) {
|
||||
const selectRef = ref(null);
|
||||
|
||||
const configProvider = inject('configProvider', defaultConfigProvider);
|
||||
@ -77,8 +81,8 @@ const Select = defineComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const mode = computed(()=>{
|
||||
const { mode } = props
|
||||
const mode = computed(() => {
|
||||
const { mode } = props;
|
||||
|
||||
if ((mode as any) === 'combobox') {
|
||||
return undefined;
|
||||
@ -90,35 +94,47 @@ const Select = defineComponent({
|
||||
|
||||
return mode;
|
||||
});
|
||||
|
||||
const mergedClassName = computed(()=> classNames(
|
||||
{
|
||||
[`${props.prefixCls}-lg`]: props.size === 'large',
|
||||
[`${props.prefixCls}-sm`]: props.size === 'small',
|
||||
[`${props.prefixCls}-rtl`]: props.direction === 'rtl',
|
||||
[`${props.prefixCls}-borderless`]: !props.bordered,
|
||||
},
|
||||
attrs.class,
|
||||
));
|
||||
const triggerChange=(...args: any[])=>{
|
||||
console.log(args)
|
||||
emit('update:value', ...args)
|
||||
emit('change', ...args)
|
||||
}
|
||||
const prefixCls = computed(() => {
|
||||
return configProvider.getPrefixCls('select', props.prefixCls);
|
||||
});
|
||||
const mergedClassName = computed(() =>
|
||||
classNames(
|
||||
{
|
||||
[`${prefixCls.value}-lg`]: props.size === 'large',
|
||||
[`${prefixCls.value}-sm`]: props.size === 'small',
|
||||
[`${prefixCls.value}-rtl`]: props.direction === 'rtl',
|
||||
[`${prefixCls.value}-borderless`]: !props.bordered,
|
||||
},
|
||||
attrs.class,
|
||||
),
|
||||
);
|
||||
const triggerChange = (...args: any[]) => {
|
||||
console.log(args);
|
||||
emit('update:value', ...args);
|
||||
emit('change', ...args);
|
||||
};
|
||||
return {
|
||||
mergedClassName,
|
||||
mode,
|
||||
focus,
|
||||
blur,
|
||||
configProvider,
|
||||
triggerChange
|
||||
}
|
||||
triggerChange,
|
||||
prefixCls,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
const {configProvider, mode, mergedClassName,triggerChange, $slots: slots, $props} = this as any;
|
||||
const props: SelectTypes = $props
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
configProvider,
|
||||
mode,
|
||||
mergedClassName,
|
||||
triggerChange,
|
||||
prefixCls,
|
||||
$slots: slots,
|
||||
$props,
|
||||
} = this as any;
|
||||
const props: SelectTypes = $props;
|
||||
const {
|
||||
notFoundContent,
|
||||
listHeight = 256,
|
||||
listItemHeight = 24,
|
||||
@ -126,11 +142,10 @@ const Select = defineComponent({
|
||||
dropdownClassName,
|
||||
direction,
|
||||
virtual,
|
||||
dropdownMatchSelectWidth
|
||||
dropdownMatchSelectWidth,
|
||||
} = props;
|
||||
|
||||
const { getPrefixCls, renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider
|
||||
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
||||
const { renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider;
|
||||
|
||||
const isMultiple = mode === 'multiple' || mode === 'tags';
|
||||
|
||||
@ -138,20 +153,24 @@ const Select = defineComponent({
|
||||
let mergedNotFound: VNodeChild;
|
||||
if (notFoundContent !== undefined) {
|
||||
mergedNotFound = notFoundContent;
|
||||
} else if(slots.notFoundContent){
|
||||
mergedNotFound = slots.notFoundContent()
|
||||
} else if (slots.notFoundContent) {
|
||||
mergedNotFound = slots.notFoundContent();
|
||||
} else if (mode === 'combobox') {
|
||||
mergedNotFound = null;
|
||||
} else {
|
||||
console.log(111);
|
||||
mergedNotFound = renderEmpty('Select') as any;
|
||||
}
|
||||
|
||||
// ===================== Icons =====================
|
||||
const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons({
|
||||
...this.$props,
|
||||
multiple: isMultiple,
|
||||
prefixCls,
|
||||
}, slots);
|
||||
const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons(
|
||||
{
|
||||
...this.$props,
|
||||
multiple: isMultiple,
|
||||
prefixCls,
|
||||
},
|
||||
slots,
|
||||
);
|
||||
|
||||
const selectProps = omit(props, [
|
||||
'prefixCls',
|
||||
@ -166,30 +185,33 @@ const Select = defineComponent({
|
||||
const rcSelectRtlDropDownClassName = classNames(dropdownClassName, {
|
||||
[`${prefixCls}-dropdown-${direction}`]: direction === 'rtl',
|
||||
});
|
||||
<RcSelect
|
||||
ref="selectRef"
|
||||
virtual={virtual}
|
||||
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
|
||||
{...selectProps}
|
||||
listHeight={listHeight}
|
||||
listItemHeight={listItemHeight}
|
||||
mode={mode}
|
||||
prefixCls={prefixCls}
|
||||
direction={direction}
|
||||
inputIcon={suffixIcon}
|
||||
menuItemSelectedIcon={itemIcon}
|
||||
removeIcon={removeIcon}
|
||||
clearIcon={clearIcon}
|
||||
notFoundContent={mergedNotFound}
|
||||
class={mergedClassName}
|
||||
getPopupContainer={getPopupContainer || getContextPopupContainer}
|
||||
dropdownClassName={rcSelectRtlDropDownClassName}
|
||||
onChange={triggerChange}
|
||||
>
|
||||
{slots?.default()}
|
||||
</RcSelect>
|
||||
}
|
||||
})
|
||||
return (
|
||||
<RcSelect
|
||||
ref="selectRef"
|
||||
virtual={virtual}
|
||||
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
|
||||
{...selectProps}
|
||||
{...this.$attrs}
|
||||
listHeight={listHeight}
|
||||
listItemHeight={listItemHeight}
|
||||
mode={mode}
|
||||
prefixCls={prefixCls}
|
||||
direction={direction}
|
||||
inputIcon={suffixIcon}
|
||||
menuItemSelectedIcon={itemIcon}
|
||||
removeIcon={removeIcon}
|
||||
clearIcon={clearIcon}
|
||||
notFoundContent={mergedNotFound}
|
||||
class={mergedClassName}
|
||||
getPopupContainer={getPopupContainer || getContextPopupContainer}
|
||||
dropdownClassName={rcSelectRtlDropDownClassName}
|
||||
onChange={triggerChange}
|
||||
>
|
||||
{slots?.default()}
|
||||
</RcSelect>
|
||||
);
|
||||
},
|
||||
});
|
||||
/* istanbul ignore next */
|
||||
Select.install = function(app: App) {
|
||||
app.component(Select.name, Select);
|
||||
|
@ -99,7 +99,7 @@ const Select = defineComponent({
|
||||
...SelectProps,
|
||||
showSearch: PropTypes.looseBool.def(false),
|
||||
transitionName: PropTypes.string.def('slide-up'),
|
||||
choiceTransitionName: PropTypes.string.def('zoom'),
|
||||
choiceTransitionName: PropTypes.string.def(''),
|
||||
},
|
||||
propTypes: SelectPropTypes,
|
||||
setup() {
|
||||
|
@ -2,603 +2,303 @@
|
||||
@import '../../style/mixins/index';
|
||||
@import '../../input/style/mixin';
|
||||
|
||||
@select-prefix-cls: ~'@{ant-prefix}-select';
|
||||
@import './single';
|
||||
@import './multiple';
|
||||
|
||||
.selection__clear() {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: @control-padding-horizontal - 1px;
|
||||
z-index: 1;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-top: -6px;
|
||||
color: @disabled-color;
|
||||
font-size: @font-size-sm;
|
||||
font-style: normal;
|
||||
line-height: 12px;
|
||||
text-align: center;
|
||||
text-transform: none;
|
||||
background: @component-background;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition: color 0.3s ease, opacity 0.15s ease;
|
||||
text-rendering: auto;
|
||||
&::before {
|
||||
display: block;
|
||||
@select-prefix-cls: ~'@{ant-prefix}-select';
|
||||
@select-height-without-border: @input-height-base - 2 * @border-width-base;
|
||||
@select-dropdown-edge-child-vertical-padding: @dropdown-edge-child-vertical-padding;
|
||||
|
||||
.select-selector() {
|
||||
position: relative;
|
||||
background-color: @select-background;
|
||||
border: @border-width-base @border-style-base @select-border-color;
|
||||
border-radius: @border-radius-base;
|
||||
transition: all 0.3s @ease-in-out;
|
||||
|
||||
input {
|
||||
cursor: pointer;
|
||||
}
|
||||
&:hover {
|
||||
color: @text-color-secondary;
|
||||
|
||||
.@{select-prefix-cls}-show-search& {
|
||||
cursor: text;
|
||||
|
||||
input {
|
||||
cursor: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-focused:not(.@{select-prefix-cls}-disabled)& {
|
||||
.active();
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-disabled& {
|
||||
color: @disabled-color;
|
||||
background: @input-disabled-bg;
|
||||
cursor: not-allowed;
|
||||
|
||||
input {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset search input style */
|
||||
.select-search-input-without-border() {
|
||||
.@{select-prefix-cls}-selection-search-input {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
appearance: none;
|
||||
|
||||
&::-webkit-search-cancel-button {
|
||||
display: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls} {
|
||||
.reset-component;
|
||||
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
&:not(.@{select-prefix-cls}-disabled):hover &-selector {
|
||||
.hover();
|
||||
}
|
||||
|
||||
> ul > li > a {
|
||||
padding: 0;
|
||||
background-color: @component-background;
|
||||
// ======================== Selection ========================
|
||||
&-selection-item {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
// IE11 css hack. `*::-ms-backdrop,` is a must have
|
||||
@media all and (-ms-high-contrast: none) {
|
||||
*::-ms-backdrop,
|
||||
& {
|
||||
flex: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// arrow
|
||||
// ======================= Placeholder =======================
|
||||
&-selection-placeholder {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
color: @input-placeholder-color;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
// IE11 css hack. `*::-ms-backdrop,` is a must have
|
||||
@media all and (-ms-high-contrast: none) {
|
||||
*::-ms-backdrop,
|
||||
& {
|
||||
flex: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================== Arrow ==========================
|
||||
&-arrow {
|
||||
.iconfont-mixin();
|
||||
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
top: 53%;
|
||||
right: @control-padding-horizontal - 1px;
|
||||
width: @font-size-sm;
|
||||
height: @font-size-sm;
|
||||
margin-top: -@font-size-sm / 2;
|
||||
color: @disabled-color;
|
||||
font-size: @font-size-sm;
|
||||
line-height: 1;
|
||||
transform-origin: 50% 50%;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
|
||||
& &-icon svg {
|
||||
.@{iconfont-css-prefix} {
|
||||
vertical-align: top;
|
||||
transition: transform 0.3s;
|
||||
|
||||
> svg {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&:not(.@{select-prefix-cls}-suffix) {
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-disabled & {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&-selection {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
background-color: @select-background;
|
||||
border: @border-width-base @border-style-base @select-border-color;
|
||||
// strange align fix for chrome but works
|
||||
// https://gw.alipayobjects.com/zos/rmsportal/VFTfKXJuogBAXcvfAUWJ.gif
|
||||
border-top-width: @border-width-base + 0.02px;
|
||||
border-radius: @border-radius-base;
|
||||
outline: none;
|
||||
transition: all 0.3s @ease-in-out;
|
||||
user-select: none;
|
||||
|
||||
// ========================== Clear ==========================
|
||||
&-clear {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: @control-padding-horizontal - 1px;
|
||||
z-index: 1;
|
||||
display: inline-block;
|
||||
width: @font-size-sm;
|
||||
height: @font-size-sm;
|
||||
margin-top: -@font-size-sm / 2;
|
||||
color: @disabled-color;
|
||||
font-size: @font-size-sm;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
text-transform: none;
|
||||
background: @select-clear-background;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition: color 0.3s ease, opacity 0.15s ease;
|
||||
text-rendering: auto;
|
||||
&::before {
|
||||
display: block;
|
||||
}
|
||||
&:hover {
|
||||
.hover;
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-focused &,
|
||||
&:focus,
|
||||
&:active {
|
||||
.active;
|
||||
}
|
||||
|
||||
&__clear {
|
||||
.selection__clear();
|
||||
}
|
||||
|
||||
&:hover &__clear {
|
||||
.@{select-prefix-cls}:hover & {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&-selected-value {
|
||||
float: left;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
&-no-arrow &-selection-selected-value {
|
||||
padding-right: 0;
|
||||
}
|
||||
// ========================== Popup ==========================
|
||||
&-dropdown {
|
||||
.reset-component;
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
z-index: @zindex-dropdown;
|
||||
box-sizing: border-box;
|
||||
padding: @select-dropdown-edge-child-vertical-padding 0;
|
||||
overflow: hidden;
|
||||
font-size: @font-size-base;
|
||||
// Fix select render lag of long text in chrome
|
||||
// https://github.com/ant-design/ant-design/issues/11456
|
||||
// https://github.com/ant-design/ant-design/issues/11843
|
||||
font-variant: initial;
|
||||
background-color: @select-dropdown-bg;
|
||||
border-radius: @border-radius-base;
|
||||
outline: none;
|
||||
box-shadow: @box-shadow-base;
|
||||
|
||||
&-disabled {
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&-disabled &-selection {
|
||||
background: @input-disabled-bg;
|
||||
cursor: not-allowed;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
border-color: @select-border-color;
|
||||
box-shadow: none;
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-bottomLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-bottomLeft {
|
||||
animation-name: antSlideUpIn;
|
||||
}
|
||||
|
||||
&__clear {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-topLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-topLeft {
|
||||
animation-name: antSlideDownIn;
|
||||
}
|
||||
}
|
||||
|
||||
&-disabled &-selection--multiple &-selection__choice {
|
||||
padding-right: 10px;
|
||||
color: fade(@black, 33%);
|
||||
background: @background-color-base;
|
||||
&__remove {
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-bottomLeft {
|
||||
animation-name: antSlideUpOut;
|
||||
}
|
||||
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-topLeft {
|
||||
animation-name: antSlideDownOut;
|
||||
}
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-selection--single {
|
||||
position: relative;
|
||||
height: @input-height-base;
|
||||
cursor: pointer;
|
||||
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
margin-right: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-no-arrow {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
margin-right: @control-padding-horizontal - 1px;
|
||||
}
|
||||
}
|
||||
|
||||
&-selection__rendered {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-right: @control-padding-horizontal - 1px;
|
||||
margin-left: @control-padding-horizontal - 1px;
|
||||
line-height: @input-height-base - 2px;
|
||||
// https://github.com/ant-design/ant-design/issues/3481#issuecomment-254721026
|
||||
&::after {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
visibility: hidden;
|
||||
content: '.';
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-lg {
|
||||
font-size: @font-size-lg;
|
||||
.@{select-prefix-cls}-selection--single {
|
||||
height: @input-height-lg;
|
||||
}
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
line-height: @input-height-lg - 2px;
|
||||
}
|
||||
.@{select-prefix-cls}-selection--multiple {
|
||||
min-height: @input-height-lg;
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
li {
|
||||
height: @input-height-lg - 8px;
|
||||
line-height: @input-height-lg - 8px;
|
||||
}
|
||||
}
|
||||
.@{select-prefix-cls}-selection__clear,
|
||||
.@{select-prefix-cls}-arrow {
|
||||
top: @input-height-lg / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.@{select-prefix-cls}-selection--single {
|
||||
height: @input-height-sm;
|
||||
}
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
margin-left: @control-padding-horizontal-sm - 1px;
|
||||
line-height: @input-height-sm - 2px;
|
||||
}
|
||||
.@{select-prefix-cls}-selection--multiple {
|
||||
min-height: @input-height-sm;
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
li {
|
||||
height: @input-height-sm - 8px;
|
||||
line-height: @input-height-sm - 10px;
|
||||
}
|
||||
}
|
||||
.@{select-prefix-cls}-selection__clear,
|
||||
.@{select-prefix-cls}-arrow {
|
||||
top: @input-height-sm / 2;
|
||||
}
|
||||
}
|
||||
.@{select-prefix-cls}-selection__clear,
|
||||
.@{select-prefix-cls}-arrow {
|
||||
right: @control-padding-horizontal-sm;
|
||||
}
|
||||
}
|
||||
|
||||
&-disabled &-selection__choice__remove {
|
||||
color: @disabled-color;
|
||||
cursor: default;
|
||||
&:hover {
|
||||
&-empty {
|
||||
color: @disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-search__field__wrap {
|
||||
// ========================= Options =========================
|
||||
.item() {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
display: block;
|
||||
min-height: @select-dropdown-height;
|
||||
padding: @select-dropdown-vertical-padding @control-padding-horizontal;
|
||||
color: @text-color;
|
||||
font-weight: normal;
|
||||
font-size: @select-dropdown-font-size;
|
||||
line-height: @select-dropdown-line-height;
|
||||
}
|
||||
|
||||
&-selection__placeholder,
|
||||
&-search__field__placeholder {
|
||||
// for TreeSelect compatibility
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 9px;
|
||||
left: 0;
|
||||
max-width: 100%;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
overflow: hidden;
|
||||
color: @input-placeholder-color;
|
||||
line-height: 20px;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
&-item-empty {
|
||||
.item();
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&-search__field__placeholder {
|
||||
left: @control-padding-horizontal;
|
||||
}
|
||||
&-item {
|
||||
.item();
|
||||
|
||||
&-search__field__mirror {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
white-space: pre;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
|
||||
&-search--inline {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.@{select-prefix-cls}-search__field__wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-search__field {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 100%;
|
||||
line-height: 1;
|
||||
background: transparent;
|
||||
border-width: 0;
|
||||
border-radius: @border-radius-base;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
> i {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
&-selection--multiple {
|
||||
min-height: @input-height-base;
|
||||
padding-bottom: 3px;
|
||||
cursor: text;
|
||||
.clearfix;
|
||||
|
||||
.@{select-prefix-cls}-search--inline {
|
||||
position: static;
|
||||
float: left;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
.@{select-prefix-cls}-search__field {
|
||||
width: 0.75em;
|
||||
max-width: 100%;
|
||||
padding: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
height: auto;
|
||||
margin-bottom: -3px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection__placeholder {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
> ul > li,
|
||||
.@{select-prefix-cls}-selection__rendered > ul > li {
|
||||
height: @input-height-base - 8px;
|
||||
// for tree-select
|
||||
margin-top: 3px;
|
||||
line-height: @input-height-base - 8px - 2px;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection__choice {
|
||||
position: relative;
|
||||
float: left;
|
||||
max-width: 99%;
|
||||
margin-right: 4px;
|
||||
padding: 0 20px 0 10px;
|
||||
overflow: hidden;
|
||||
color: @tag-default-color;
|
||||
background-color: @tag-default-bg;
|
||||
border: 1px solid @border-color-split;
|
||||
border-radius: @border-radius-sm;
|
||||
// =========== Group ============
|
||||
&-group {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-sm;
|
||||
cursor: default;
|
||||
transition: padding 0.3s @ease-in-out;
|
||||
&__disabled {
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection__choice__content {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
transition: margin 0.3s @ease-in-out;
|
||||
}
|
||||
// =========== Option ===========
|
||||
&-option {
|
||||
display: flex;
|
||||
|
||||
.@{select-prefix-cls}-selection__choice__remove {
|
||||
.iconfont-mixin();
|
||||
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
display: inline-block;
|
||||
color: @text-color-secondary;
|
||||
font-weight: bold;
|
||||
font-size: @font-size-sm;
|
||||
line-height: inherit;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
.iconfont-size-under-12px(10px);
|
||||
&:hover {
|
||||
color: @icon-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection__clear,
|
||||
.@{select-prefix-cls}-arrow {
|
||||
top: @input-height-base / 2;
|
||||
}
|
||||
}
|
||||
|
||||
&-allow-clear &-selection--multiple &-selection__rendered,
|
||||
&-show-arrow &-selection--multiple &-selection__rendered {
|
||||
margin-right: 20px; // In case that clear button will overlap content
|
||||
}
|
||||
|
||||
&-open {
|
||||
.@{select-prefix-cls}-arrow {
|
||||
&-icon svg {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
.@{select-prefix-cls}-selection {
|
||||
.active();
|
||||
}
|
||||
}
|
||||
|
||||
&-combobox {
|
||||
.@{select-prefix-cls}-arrow {
|
||||
display: none;
|
||||
}
|
||||
.@{select-prefix-cls}-search--inline {
|
||||
float: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.@{select-prefix-cls}-search__field__wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.@{select-prefix-cls}-search__field {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: none;
|
||||
transition: all 0.3s @ease-in-out, height 0s;
|
||||
}
|
||||
}
|
||||
&-combobox&-allow-clear &-selection:hover &-selection__rendered,
|
||||
&-combobox&-show-arrow &-selection:hover &-selection__rendered {
|
||||
margin-right: 20px; // In case that clear button will overlap content
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-dropdown {
|
||||
.reset-component;
|
||||
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
z-index: @zindex-dropdown;
|
||||
box-sizing: border-box;
|
||||
font-size: @font-size-base;
|
||||
// Fix select render lag of long text in chrome
|
||||
// https://github.com/ant-design/ant-design/issues/11456
|
||||
// https://github.com/ant-design/ant-design/issues/11843
|
||||
font-variant: initial;
|
||||
background-color: @select-dropdown-bg;
|
||||
border-radius: @border-radius-base;
|
||||
outline: none;
|
||||
box-shadow: @box-shadow-base;
|
||||
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-bottomLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-bottomLeft {
|
||||
animation-name: antSlideUpIn;
|
||||
}
|
||||
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-topLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-topLeft {
|
||||
animation-name: antSlideDownIn;
|
||||
}
|
||||
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-bottomLeft {
|
||||
animation-name: antSlideUpOut;
|
||||
}
|
||||
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-topLeft {
|
||||
animation-name: antSlideDownOut;
|
||||
}
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-menu {
|
||||
max-height: 250px;
|
||||
margin-bottom: 0;
|
||||
padding: @select-dropdown-edge-child-vertical-padding 0; //Change
|
||||
padding-left: 0; // Override default ul/ol
|
||||
overflow: auto;
|
||||
list-style: none;
|
||||
outline: none;
|
||||
|
||||
&-item-group-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
> .@{select-prefix-cls}-dropdown-menu-item {
|
||||
padding-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&-item-group-title {
|
||||
height: 32px;
|
||||
padding: 0 @control-padding-horizontal;
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-sm;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
&-item-group-list &-item:first-child:not(:last-child),
|
||||
&-item-group:not(:last-child) &-item-group-list &-item:last-child {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: @select-dropdown-vertical-padding @control-padding-horizontal;
|
||||
overflow: hidden;
|
||||
color: @text-color;
|
||||
font-weight: normal;
|
||||
font-size: @select-dropdown-font-size;
|
||||
line-height: @select-dropdown-line-height;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
|
||||
&:hover:not(&-disabled) {
|
||||
background-color: @item-hover-bg;
|
||||
&-content {
|
||||
flex: auto;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
& when (@select-dropdown-edge-child-vertical-padding = 0) {
|
||||
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
& when (@select-dropdown-edge-child-vertical-padding = 0) {
|
||||
border-radius: 0 0 @border-radius-base @border-radius-base;
|
||||
}
|
||||
}
|
||||
|
||||
&-selected {
|
||||
color: @select-item-selected-color;
|
||||
font-weight: @select-item-selected-font-weight;
|
||||
background-color: @select-item-selected-bg;
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
color: @disabled-color;
|
||||
cursor: not-allowed;
|
||||
|
||||
&:hover {
|
||||
color: @disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
&-state {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
&-active:not(&-disabled) {
|
||||
background-color: @select-item-active-bg;
|
||||
}
|
||||
|
||||
&-divider {
|
||||
height: 1px;
|
||||
margin: 1px 0;
|
||||
overflow: hidden;
|
||||
line-height: 0;
|
||||
background-color: @border-color-split;
|
||||
&-selected:not(&-disabled) {
|
||||
color: @select-item-selected-color;
|
||||
font-weight: @select-item-selected-font-weight;
|
||||
background-color: @select-item-selected-bg;
|
||||
|
||||
.@{select-prefix-cls}-item-option-state {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
color: @disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&-grouped {
|
||||
padding-left: @control-padding-horizontal * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&&--multiple {
|
||||
.@{select-prefix-cls}-dropdown-menu-item {
|
||||
padding-right: @control-padding-horizontal + 20;
|
||||
& .@{select-prefix-cls}-selected-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: @control-padding-horizontal;
|
||||
color: transparent;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
text-shadow: 0 0.1px 0, 0.1px 0 0, 0 -0.1px 0, -0.1px 0;
|
||||
transform: translateY(-50%);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
&:hover .@{select-prefix-cls}-selected-icon {
|
||||
color: fade(@black, 87%);
|
||||
}
|
||||
|
||||
&-disabled .@{select-prefix-cls}-selected-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-selected .@{select-prefix-cls}-selected-icon,
|
||||
&-selected:hover .@{select-prefix-cls}-selected-icon {
|
||||
display: inline-block;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
// ============================================================
|
||||
// == Size ==
|
||||
// ============================================================
|
||||
&-lg {
|
||||
font-size: @font-size-lg;
|
||||
}
|
||||
|
||||
// Patch for popup adjust
|
||||
// https://github.com/ant-design/ant-design/issues/14422
|
||||
&--empty&--multiple &-menu-item {
|
||||
padding-right: @control-padding-horizontal;
|
||||
}
|
||||
|
||||
&-container-open,
|
||||
&-open {
|
||||
.@{select-prefix-cls}-dropdown {
|
||||
display: block;
|
||||
}
|
||||
// no border style
|
||||
&-borderless &-selector {
|
||||
background-color: transparent !important;
|
||||
border-color: transparent !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@import './rtl';
|
||||
|
206
components/select/style/multiple.less
Normal file
206
components/select/style/multiple.less
Normal file
@ -0,0 +1,206 @@
|
||||
@import './index';
|
||||
|
||||
@select-multiple-item-border-width: 1px;
|
||||
|
||||
@select-multiple-padding: max(
|
||||
@input-padding-vertical-base - @select-multiple-item-border-width -
|
||||
@select-multiple-item-spacing-half,
|
||||
0
|
||||
);
|
||||
|
||||
/**
|
||||
* Do not merge `height` & `line-height` under style with `selection` & `search`,
|
||||
* since chrome may update to redesign with its align logic.
|
||||
*/
|
||||
|
||||
.@{select-prefix-cls} {
|
||||
&-multiple {
|
||||
// ========================= Selector =========================
|
||||
.@{select-prefix-cls}-selector {
|
||||
.select-selector();
|
||||
.select-search-input-without-border();
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
// Multiple is little different that horizontal is follow the vertical
|
||||
padding: @select-multiple-padding @input-padding-vertical-base;
|
||||
|
||||
.@{select-prefix-cls}-show-search& {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-disabled& {
|
||||
background: @select-multiple-disabled-background;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
margin: @select-multiple-item-spacing-half 0;
|
||||
line-height: @select-multiple-item-height;
|
||||
content: '\a0';
|
||||
}
|
||||
}
|
||||
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selector,
|
||||
&.@{select-prefix-cls}-allow-clear .@{select-prefix-cls}-selector {
|
||||
padding-right: @font-size-sm + @control-padding-horizontal;
|
||||
}
|
||||
|
||||
// ======================== Selections ========================
|
||||
.@{select-prefix-cls}-selection-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: none;
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
|
||||
height: @select-multiple-item-height;
|
||||
margin-top: @select-multiple-item-spacing-half;
|
||||
margin-right: @input-padding-vertical-base;
|
||||
margin-bottom: @select-multiple-item-spacing-half;
|
||||
padding: 0 (@padding-xs / 2) 0 @padding-xs;
|
||||
line-height: @select-multiple-item-height - @select-multiple-item-border-width * 2;
|
||||
background: @select-selection-item-bg;
|
||||
border: 1px solid @select-selection-item-border-color;
|
||||
border-radius: @border-radius-base;
|
||||
cursor: default;
|
||||
transition: font-size 0.3s, line-height 0.3s, height 0.3s;
|
||||
user-select: none;
|
||||
|
||||
.@{select-prefix-cls}-disabled& {
|
||||
color: @select-multiple-item-disabled-color;
|
||||
border-color: @select-multiple-item-disabled-border-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
// It's ok not to do this, but 24px makes bottom narrow in view should adjust
|
||||
&-content {
|
||||
display: inline-block;
|
||||
margin-right: @padding-xs / 2;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&-remove {
|
||||
.iconfont-mixin();
|
||||
display: inline-block;
|
||||
color: @text-color-secondary;
|
||||
font-weight: bold;
|
||||
font-size: @font-size-sm;
|
||||
line-height: inherit;
|
||||
cursor: pointer;
|
||||
.iconfont-size-under-12px(10px);
|
||||
|
||||
> .@{iconfont-css-prefix} {
|
||||
vertical-align: -0.2em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: @icon-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================== Input ==========================
|
||||
.@{select-prefix-cls}-selection-search {
|
||||
position: relative;
|
||||
margin-left: @select-multiple-padding / 2;
|
||||
|
||||
&-input,
|
||||
&-mirror {
|
||||
font-family: @font-family;
|
||||
line-height: @line-height-base;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
&-input {
|
||||
width: 100%;
|
||||
min-width: 4.1px; // fix search cursor missing
|
||||
}
|
||||
|
||||
&-mirror {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
white-space: nowrap;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/22906
|
||||
&:first-child .@{select-prefix-cls}-selection-search-input {
|
||||
margin-left: 6.5px;
|
||||
}
|
||||
}
|
||||
|
||||
// ======================= Placeholder =======================
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: @input-padding-horizontal;
|
||||
left: @input-padding-horizontal;
|
||||
transform: translateY(-50%);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// == Size ==
|
||||
// ============================================================
|
||||
.select-size(@suffix, @input-height) {
|
||||
@merged-cls: ~'@{select-prefix-cls}-@{suffix}';
|
||||
&.@{merged-cls} {
|
||||
@select-selection-height: @input-height - @input-padding-vertical-base * 2;
|
||||
@select-height-without-border: @input-height - @border-width-base * 2;
|
||||
|
||||
.@{select-prefix-cls}-selector::after {
|
||||
line-height: @select-selection-height;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-item {
|
||||
height: @select-selection-height;
|
||||
line-height: @select-selection-height - @border-width-base * 2;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-search {
|
||||
height: @select-selection-height + @select-multiple-padding;
|
||||
line-height: @select-selection-height + @select-multiple-padding;
|
||||
|
||||
&-input,
|
||||
&-mirror {
|
||||
height: @select-selection-height;
|
||||
line-height: @select-selection-height - @border-width-base * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-size('lg', @input-height-lg);
|
||||
.select-size('sm', @input-height-sm);
|
||||
|
||||
// Size small need additional set padding
|
||||
&.@{select-prefix-cls}-sm {
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
left: @input-padding-horizontal-sm;
|
||||
}
|
||||
// https://github.com/ant-design/ant-design/issues/22906
|
||||
.@{select-prefix-cls}-selection-search:first-child
|
||||
.@{select-prefix-cls}-selection-search-input {
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
&.@{select-prefix-cls}-lg {
|
||||
.@{select-prefix-cls}-selection-item {
|
||||
height: @select-multiple-item-height-lg;
|
||||
line-height: @select-multiple-item-height-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-disabled .@{select-prefix-cls}-selection-item-remove {
|
||||
display: none;
|
||||
}
|
||||
}
|
188
components/select/style/rtl.less
Normal file
188
components/select/style/rtl.less
Normal file
@ -0,0 +1,188 @@
|
||||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import '../../input/style/mixin';
|
||||
|
||||
@select-prefix-cls: ~'@{ant-prefix}-select';
|
||||
|
||||
.@{select-prefix-cls} {
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
// ========================== Arrow ==========================
|
||||
&-arrow {
|
||||
.@{select-prefix-cls}-rtl & {
|
||||
right: initial;
|
||||
left: @control-padding-horizontal - 1px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================== Clear ==========================
|
||||
&-clear {
|
||||
.@{select-prefix-cls}-rtl & {
|
||||
right: initial;
|
||||
left: @control-padding-horizontal - 1px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================== Popup ==========================
|
||||
&-dropdown {
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================= Options =========================
|
||||
&-item {
|
||||
&-option {
|
||||
&-grouped {
|
||||
.@{select-prefix-cls}-dropdown-rtl & {
|
||||
padding-right: @control-padding-horizontal * 2;
|
||||
padding-left: @control-padding-horizontal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// multiple
|
||||
@select-multiple-item-border-width: 1px;
|
||||
@select-multiple-item-spacing-half: ceil(@input-padding-vertical-base / 2);
|
||||
@select-multiple-padding: max(
|
||||
@input-padding-vertical-base - @select-multiple-item-border-width -
|
||||
@select-multiple-item-spacing-half,
|
||||
0
|
||||
);
|
||||
|
||||
.@{select-prefix-cls}-multiple {
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selector,
|
||||
&.@{select-prefix-cls}-allow-clear .@{select-prefix-cls}-selector {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
padding-right: @input-padding-vertical-base;
|
||||
padding-left: @font-size-sm + @control-padding-horizontal;
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== Selections ========================
|
||||
.@{select-prefix-cls}-selection-item {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
margin-right: 0;
|
||||
margin-left: @input-padding-vertical-base;
|
||||
padding: 0 @padding-xs 0 (@padding-xs / 2);
|
||||
text-align: right;
|
||||
}
|
||||
// It's ok not to do this, but 24px makes bottom narrow in view should adjust
|
||||
&-content {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
margin-right: 0;
|
||||
margin-left: @padding-xs / 2;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================== Input ==========================
|
||||
.@{select-prefix-cls}-selection-search {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
margin-right: @select-multiple-padding / 2;
|
||||
margin-left: @input-padding-vertical-base;
|
||||
}
|
||||
|
||||
&-mirror {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ======================= Placeholder =======================
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
right: @input-padding-horizontal;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// == Size ==
|
||||
// ============================================================
|
||||
|
||||
// Size small need additional set padding
|
||||
&.@{select-prefix-cls}-sm {
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
right: @input-padding-horizontal-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// single
|
||||
@selection-item-padding: ceil(@font-size-base * 1.25);
|
||||
|
||||
.@{select-prefix-cls}-single {
|
||||
// ========================= Selector =========================
|
||||
.@{select-prefix-cls}-selector {
|
||||
.@{select-prefix-cls}-selection-item,
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
right: 0;
|
||||
left: 9px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// With arrow should provides `padding-right` to show the arrow
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-search {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
right: @input-padding-horizontal-base;
|
||||
left: @input-padding-horizontal-base + @font-size-base;
|
||||
}
|
||||
}
|
||||
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-item,
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-placeholder {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
padding-right: 0;
|
||||
padding-left: @selection-item-padding;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================== Input ==========================
|
||||
// We only change the style of non-customize input which is only support by `combobox` mode.
|
||||
|
||||
// Not customize
|
||||
&:not(.@{select-prefix-cls}-customize-input) {
|
||||
.@{select-prefix-cls}-selector {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
padding: 0 @input-padding-horizontal-base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// == Size ==
|
||||
// ============================================================
|
||||
|
||||
// Size small need additional set padding
|
||||
&.@{select-prefix-cls}-sm {
|
||||
&:not(.@{select-prefix-cls}-customize-input) {
|
||||
// With arrow should provides `padding-right` to show the arrow
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-search {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-item,
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-placeholder {
|
||||
.@{select-prefix-cls}-rtl& {
|
||||
padding-right: 0;
|
||||
padding-left: @font-size-base * 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
180
components/select/style/single.less
Normal file
180
components/select/style/single.less
Normal file
@ -0,0 +1,180 @@
|
||||
@import './index';
|
||||
|
||||
@selection-item-padding: ceil(@font-size-base * 1.25);
|
||||
|
||||
.@{select-prefix-cls}-single {
|
||||
// ========================= Selector =========================
|
||||
.@{select-prefix-cls}-selector {
|
||||
display: flex;
|
||||
|
||||
.@{select-prefix-cls}-selection-search {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: @input-padding-horizontal-base;
|
||||
bottom: 0;
|
||||
left: @input-padding-horizontal-base;
|
||||
|
||||
&-input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-item,
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
padding: 0;
|
||||
line-height: @select-height-without-border;
|
||||
transition: all 0.3s;
|
||||
|
||||
// Firefox inline-block position calculation is not same as Chrome & Safari. Patch this:
|
||||
@supports (-moz-appearance: meterbar) {
|
||||
& {
|
||||
line-height: @select-height-without-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-item {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// For common baseline align
|
||||
&::after,
|
||||
// For '' value baseline align
|
||||
.@{select-prefix-cls}-selection-item::after,
|
||||
// For undefined value baseline align
|
||||
.@{select-prefix-cls}-selection-placeholder::after {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
visibility: hidden;
|
||||
content: '\a0';
|
||||
}
|
||||
}
|
||||
|
||||
// With arrow should provides `padding-right` to show the arrow
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-search {
|
||||
right: @input-padding-horizontal-base + @font-size-base;
|
||||
}
|
||||
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-item,
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-placeholder {
|
||||
padding-right: @selection-item-padding;
|
||||
}
|
||||
|
||||
// Opacity selection if open
|
||||
&.@{select-prefix-cls}-open .@{select-prefix-cls}-selection-item {
|
||||
color: @input-placeholder-color;
|
||||
}
|
||||
|
||||
// ========================== Input ==========================
|
||||
// We only change the style of non-customize input which is only support by `combobox` mode.
|
||||
|
||||
// Not customize
|
||||
&:not(.@{select-prefix-cls}-customize-input) {
|
||||
.@{select-prefix-cls}-selector {
|
||||
.select-selector();
|
||||
.select-search-input-without-border();
|
||||
width: 100%;
|
||||
|
||||
height: @input-height-base;
|
||||
padding: 0 @input-padding-horizontal-base;
|
||||
|
||||
.@{select-prefix-cls}-selection-search-input {
|
||||
height: @select-height-without-border;
|
||||
}
|
||||
|
||||
&::after {
|
||||
line-height: @select-height-without-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.@{select-prefix-cls}-customize-input {
|
||||
.@{select-prefix-cls}-selector {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-search {
|
||||
position: static;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
padding: 0 @input-padding-horizontal-base;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// == Size ==
|
||||
// ============================================================
|
||||
.select-size(@suffix, @input-height) {
|
||||
@merged-cls: ~'@{select-prefix-cls}-@{suffix}';
|
||||
|
||||
&.@{merged-cls}:not(.@{select-prefix-cls}-customize-input) {
|
||||
.@{select-prefix-cls}-selector {
|
||||
height: @input-height;
|
||||
|
||||
&::after,
|
||||
.@{select-prefix-cls}-selection-item,
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
line-height: @input-height - 2 * @border-width-base;
|
||||
}
|
||||
}
|
||||
|
||||
// Not customize
|
||||
&:not(.@{select-prefix-cls}-customize-input) {
|
||||
.@{select-prefix-cls}-selection-search-input {
|
||||
height: @input-height - 2 * @border-width-base;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-size('lg', @select-single-item-height-lg);
|
||||
.select-size('sm', @input-height-sm);
|
||||
|
||||
// Size small need additional set padding
|
||||
&.@{select-prefix-cls}-sm {
|
||||
&:not(.@{select-prefix-cls}-customize-input) {
|
||||
.@{select-prefix-cls}-selection-search {
|
||||
right: @input-padding-horizontal-sm;
|
||||
left: @input-padding-horizontal-sm;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selector {
|
||||
padding: 0 @input-padding-horizontal-sm;
|
||||
}
|
||||
|
||||
// With arrow should provides `padding-right` to show the arrow
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-search {
|
||||
right: @input-padding-horizontal-sm + @font-size-base * 1.5;
|
||||
}
|
||||
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-item,
|
||||
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-placeholder {
|
||||
padding-right: @font-size-base * 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.@{select-prefix-cls}-lg {
|
||||
&:not(.@{select-prefix-cls}-customize-input) {
|
||||
.@{select-prefix-cls}-selector {
|
||||
padding: 0 @input-padding-horizontal-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -339,13 +339,23 @@
|
||||
@select-item-selected-color: @text-color;
|
||||
@select-item-selected-font-weight: 600;
|
||||
@select-dropdown-bg: @component-background;
|
||||
@select-item-selected-bg: @primary-1;
|
||||
@select-item-active-bg: @item-hover-bg;
|
||||
@select-dropdown-vertical-padding: @dropdown-vertical-padding;
|
||||
@select-dropdown-edge-child-vertical-padding: @dropdown-edge-child-vertical-padding;
|
||||
@select-dropdown-font-size: @dropdown-font-size;
|
||||
@select-dropdown-line-height: @dropdown-line-height;
|
||||
@select-item-selected-bg: @background-color-light;
|
||||
@select-item-active-bg: @item-active-bg;
|
||||
@select-dropdown-height: 32px;
|
||||
@select-background: @component-background;
|
||||
@select-clear-background: @select-background;
|
||||
@select-selection-item-bg: @background-color-base;
|
||||
@select-selection-item-border-color: @border-color-split;
|
||||
@select-single-item-height-lg: 40px;
|
||||
@select-multiple-item-height: @input-height-base - @input-padding-vertical-base * 2; // Normal 24px
|
||||
@select-multiple-item-height-lg: 32px;
|
||||
@select-multiple-item-spacing-half: ceil(@input-padding-vertical-base / 2);
|
||||
@select-multiple-disabled-background: @input-disabled-bg;
|
||||
@select-multiple-item-disabled-color: #bfbfbf;
|
||||
@select-multiple-item-disabled-border-color: @select-border-color;
|
||||
|
||||
// Cascader
|
||||
// ----
|
||||
|
@ -23,7 +23,7 @@ const TreeSelect = {
|
||||
name: 'ATreeSelect',
|
||||
props: initDefaultProps(TreeSelectProps(), {
|
||||
transitionName: 'slide-up',
|
||||
choiceTransitionName: 'zoom',
|
||||
choiceTransitionName: '',
|
||||
showSearch: false,
|
||||
}),
|
||||
setup() {
|
||||
|
@ -10,7 +10,7 @@ export const TreeData = PropTypes.shape({
|
||||
}).loose;
|
||||
|
||||
export const TreeSelectProps = () => ({
|
||||
...SelectProps,
|
||||
...SelectProps(),
|
||||
autofocus: PropTypes.looseBool,
|
||||
dropdownStyle: PropTypes.object,
|
||||
filterTreeNode: withUndefined(PropTypes.oneOfType([Function, Boolean])),
|
||||
|
@ -55,7 +55,7 @@ const props = {
|
||||
accessibilityIndex: PropTypes.number,
|
||||
tabindex: PropTypes.number,
|
||||
|
||||
removeIcon: PropTypes.looseBool,
|
||||
removeIcon: PropTypes.VNodeChild,
|
||||
choiceTransitionName: PropTypes.string,
|
||||
|
||||
maxTagCount: PropTypes.number,
|
||||
@ -158,9 +158,11 @@ const SelectSelector = defineComponent<SelectorProps>({
|
||||
: maxTagPlaceholder,
|
||||
});
|
||||
}
|
||||
const transitionProps = getTransitionGroupProps(choiceTransitionName, {
|
||||
appear: motionAppear,
|
||||
});
|
||||
const transitionProps = choiceTransitionName
|
||||
? getTransitionGroupProps(choiceTransitionName, {
|
||||
appear: motionAppear,
|
||||
})
|
||||
: { css: false };
|
||||
selectionNode.value = (
|
||||
<TransitionGroup {...transitionProps}>
|
||||
{...displayValues.map(
|
||||
@ -237,7 +239,6 @@ const SelectSelector = defineComponent<SelectorProps>({
|
||||
onInputMouseDown,
|
||||
onInputCompositionStart,
|
||||
onInputCompositionEnd,
|
||||
choiceTransitionName,
|
||||
} = props;
|
||||
return (
|
||||
<>
|
||||
|
@ -49,9 +49,11 @@ import {
|
||||
VNode,
|
||||
VNodeChild,
|
||||
watch,
|
||||
watchEffect,
|
||||
} from 'vue';
|
||||
import createRef from '../_util/createRef';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||
|
||||
const DEFAULT_OMIT_PROPS = [
|
||||
'children',
|
||||
@ -65,7 +67,7 @@ const DEFAULT_OMIT_PROPS = [
|
||||
'onInputKeyDown',
|
||||
];
|
||||
|
||||
export const props = {
|
||||
export const BaseProps = () => ({
|
||||
prefixCls: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
class: PropTypes.string,
|
||||
@ -84,7 +86,7 @@ export const props = {
|
||||
// Search
|
||||
inputValue: PropTypes.string,
|
||||
searchValue: PropTypes.string,
|
||||
optionFilterProp: PropTypes.string.def('value'),
|
||||
optionFilterProp: PropTypes.string,
|
||||
/**
|
||||
* In Select, `false` means do nothing.
|
||||
* In TreeSelect, `false` will highlight match item.
|
||||
@ -98,20 +100,20 @@ export const props = {
|
||||
|
||||
// Icons
|
||||
allowClear: PropTypes.looseBool,
|
||||
clearIcon: PropTypes.any,
|
||||
clearIcon: PropTypes.VNodeChild,
|
||||
showArrow: PropTypes.looseBool,
|
||||
inputIcon: PropTypes.any,
|
||||
removeIcon: PropTypes.any,
|
||||
menuItemSelectedIcon: PropTypes.func,
|
||||
inputIcon: PropTypes.VNodeChild,
|
||||
removeIcon: PropTypes.VNodeChild,
|
||||
menuItemSelectedIcon: PropTypes.VNodeChild,
|
||||
|
||||
// Dropdown
|
||||
open: PropTypes.looseBool,
|
||||
defaultOpen: PropTypes.looseBool,
|
||||
listHeight: PropTypes.number.def(200),
|
||||
listItemHeight: PropTypes.number.def(20),
|
||||
listHeight: PropTypes.number,
|
||||
listItemHeight: PropTypes.number,
|
||||
dropdownStyle: PropTypes.object,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownMatchSelectWidth: PropTypes.oneOfType([Boolean, Number]).def(true),
|
||||
dropdownMatchSelectWidth: withUndefined(PropTypes.oneOfType([Boolean, Number])),
|
||||
virtual: PropTypes.looseBool,
|
||||
dropdownRender: PropTypes.func,
|
||||
dropdownAlign: PropTypes.any,
|
||||
@ -125,8 +127,8 @@ export const props = {
|
||||
loading: PropTypes.looseBool,
|
||||
autofocus: PropTypes.looseBool,
|
||||
defaultActiveFirstOption: PropTypes.looseBool,
|
||||
notFoundContent: PropTypes.any.def('Not Found'),
|
||||
placeholder: PropTypes.any,
|
||||
notFoundContent: PropTypes.VNodeChild,
|
||||
placeholder: PropTypes.VNodeChild,
|
||||
backfill: PropTypes.looseBool,
|
||||
getInputElement: PropTypes.func,
|
||||
optionLabelProp: PropTypes.string,
|
||||
@ -135,7 +137,7 @@ export const props = {
|
||||
maxTagPlaceholder: PropTypes.any,
|
||||
tokenSeparators: PropTypes.array,
|
||||
tagRender: PropTypes.func,
|
||||
showAction: PropTypes.array.def([]),
|
||||
showAction: PropTypes.array,
|
||||
tabindex: PropTypes.number,
|
||||
|
||||
// Events
|
||||
@ -162,8 +164,8 @@ export const props = {
|
||||
* Only used in current version for internal event process.
|
||||
* Do not use in production environment.
|
||||
*/
|
||||
internalProps: PropTypes.object.def({}),
|
||||
}
|
||||
internalProps: PropTypes.object,
|
||||
});
|
||||
|
||||
export interface SelectProps<OptionsType extends object[], ValueType> {
|
||||
prefixCls?: string;
|
||||
@ -336,7 +338,9 @@ export default function generateSelector<
|
||||
const Select = defineComponent<SelectProps<OptionsType, ValueType>>({
|
||||
name: 'Select',
|
||||
setup(props: SelectProps<OptionsType, ValueType>) {
|
||||
const useInternalProps = computed(() => props.internalProps.mark === INTERNAL_PROPS_MARK);
|
||||
const useInternalProps = computed(
|
||||
() => props.internalProps && props.internalProps.mark === INTERNAL_PROPS_MARK,
|
||||
);
|
||||
|
||||
const containerRef = ref(null);
|
||||
const triggerRef = ref(null);
|
||||
@ -526,8 +530,8 @@ export default function generateSelector<
|
||||
const triggerSelect = (newValue: RawValueType, isSelect: boolean, source: SelectSource) => {
|
||||
const newValueOption = getValueOption([newValue]);
|
||||
const outOption = findValueOption([newValue], newValueOption)[0];
|
||||
|
||||
if (!props.internalProps.skipTriggerSelect) {
|
||||
const { internalProps = {} } = props;
|
||||
if (!internalProps.skipTriggerSelect) {
|
||||
// Skip trigger `onSelect` or `onDeselect` if configured
|
||||
const selectValue = (mergedLabelInValue.value
|
||||
? getLabeledValue(newValue, {
|
||||
@ -547,10 +551,10 @@ export default function generateSelector<
|
||||
|
||||
// Trigger internal event
|
||||
if (useInternalProps.value) {
|
||||
if (isSelect && props.internalProps.onRawSelect) {
|
||||
props.internalProps.onRawSelect(newValue, outOption, source);
|
||||
} else if (!isSelect && props.internalProps.onRawDeselect) {
|
||||
props.internalProps.onRawDeselect(newValue, outOption, source);
|
||||
if (isSelect && internalProps.onRawSelect) {
|
||||
internalProps.onRawSelect(newValue, outOption, source);
|
||||
} else if (!isSelect && internalProps.onRawDeselect) {
|
||||
internalProps.onRawDeselect(newValue, outOption, source);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -561,7 +565,11 @@ export default function generateSelector<
|
||||
prevValueOptions.value = val;
|
||||
};
|
||||
const triggerChange = (newRawValues: RawValueType[]) => {
|
||||
if (useInternalProps.value && props.internalProps.skipTriggerChange) {
|
||||
if (
|
||||
useInternalProps.value &&
|
||||
props.internalProps &&
|
||||
props.internalProps.skipTriggerChange
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const newRawValuesOptions = getValueOption(newRawValues);
|
||||
@ -656,8 +664,10 @@ export default function generateSelector<
|
||||
const innerOpen = ref(undefined);
|
||||
const mergedOpen = ref(undefined);
|
||||
const setInnerOpen = (val: boolean) => {
|
||||
innerOpen.value = val;
|
||||
mergedOpen.value = innerOpen.value;
|
||||
setTimeout(() => {
|
||||
innerOpen.value = val;
|
||||
mergedOpen.value = innerOpen.value;
|
||||
});
|
||||
};
|
||||
watch(
|
||||
computed(() => [props.defaultOpen, props.open]),
|
||||
@ -671,21 +681,16 @@ export default function generateSelector<
|
||||
const emptyListContent = computed(
|
||||
() => !props.notFoundContent && !displayOptions.value.length,
|
||||
);
|
||||
watch(
|
||||
computed(
|
||||
() =>
|
||||
props.disabled ||
|
||||
(emptyListContent.value && innerOpen.value && props.mode === 'combobox'),
|
||||
),
|
||||
val => {
|
||||
if (val) {
|
||||
mergedOpen.value = false;
|
||||
} else {
|
||||
mergedOpen.value = innerOpen.value;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
mergedOpen.value = innerOpen.value;
|
||||
if (
|
||||
props.disabled ||
|
||||
(emptyListContent.value && mergedOpen.value && props.mode === 'combobox')
|
||||
) {
|
||||
mergedOpen.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
const triggerOpen = computed(() => (emptyListContent.value ? false : mergedOpen.value));
|
||||
|
||||
@ -706,6 +711,7 @@ export default function generateSelector<
|
||||
const triggerSearch = (searchText: string, fromTyping: boolean, isCompositing: boolean) => {
|
||||
let ret = true;
|
||||
let newSearchText = searchText;
|
||||
const preSearchValue = mergedSearchValue.value;
|
||||
setActiveValue(null);
|
||||
|
||||
// Check if match the `tokenSeparators`
|
||||
@ -750,7 +756,7 @@ export default function generateSelector<
|
||||
|
||||
setInnerSearchValue(newSearchText);
|
||||
|
||||
if (props.onSearch && mergedSearchValue.value !== newSearchText) {
|
||||
if (props.onSearch && preSearchValue !== newSearchText) {
|
||||
props.onSearch(newSearchText);
|
||||
}
|
||||
|
||||
@ -806,7 +812,6 @@ export default function generateSelector<
|
||||
const onInternalKeyDown = (event: KeyboardEvent) => {
|
||||
const clearLock = getClearLock();
|
||||
const { which } = event;
|
||||
|
||||
// We only manage open state here, close logic should handle by list component
|
||||
if (!mergedOpen.value && which === KeyCode.ENTER) {
|
||||
onToggleOpen(true);
|
||||
@ -863,7 +868,7 @@ export default function generateSelector<
|
||||
}
|
||||
|
||||
// `showAction` should handle `focus` if set
|
||||
if (props.showAction.includes('focus')) {
|
||||
if (props.showAction && props.showAction.includes('focus')) {
|
||||
onToggleOpen(true);
|
||||
}
|
||||
}
|
||||
@ -1321,6 +1326,6 @@ export default function generateSelector<
|
||||
},
|
||||
});
|
||||
Select.inheritAttrs = false;
|
||||
Select.props = props;
|
||||
Select.props = initDefaultProps(BaseProps(), {});
|
||||
return Select;
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
import Select, { ExportedSelectProps as SelectProps } from './Select';
|
||||
import Select from './Select';
|
||||
import Option from './Option';
|
||||
import OptGroup from './OptGroup';
|
||||
import { props } from './generate';
|
||||
export { Option, OptGroup, SelectProps, props };
|
||||
import { BaseProps } from './generate';
|
||||
|
||||
// eslint-disable-next-line prettier/prettier
|
||||
export type { ExportedSelectProps as SelectProps } from './Select';
|
||||
|
||||
export { Option, OptGroup, BaseProps };
|
||||
|
||||
export default Select;
|
||||
|
@ -13,7 +13,6 @@
|
||||
"noUnusedParameters": true,
|
||||
"noUnusedLocals": true,
|
||||
"noImplicitAny": false,
|
||||
"module": "esnext",
|
||||
"target": "es6",
|
||||
"lib": ["dom", "es2017"],
|
||||
"skipLibCheck": true,
|
||||
|
Loading…
Reference in New Issue
Block a user