fix(select): [select] Adapt to multiple+disabled+showOnly scenarios with different themes (#1835)
This commit is contained in:
parent
b32a7007f1
commit
e694210a1a
|
@ -1,14 +1,20 @@
|
|||
<template>
|
||||
<div>
|
||||
<br />
|
||||
<div>场景1:多选</div>
|
||||
<br />
|
||||
<tiny-select v-model="value1" multiple searchable>
|
||||
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
|
||||
<tiny-option
|
||||
v-for="item in options1"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:disabled="item.disabled"
|
||||
:required="item.required"
|
||||
>
|
||||
</tiny-option>
|
||||
</tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div>场景2:必选</div>
|
||||
<br />
|
||||
<tiny-select v-model="value2" multiple>
|
||||
|
@ -17,25 +23,21 @@
|
|||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:disabled="item.disabled"
|
||||
:required="item.required"
|
||||
>
|
||||
</tiny-option>
|
||||
</tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div>场景3:配置式必选</div>
|
||||
<br />
|
||||
<tiny-select v-model="value3" multiple :options="options2"> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div>场景4:多选个数限制</div>
|
||||
<br />
|
||||
<tiny-select v-model="value4" multiple :multiple-limit="2" show-limit-text>
|
||||
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
|
||||
</tiny-select>
|
||||
<br />
|
||||
<tiny-select v-model="value4" :options="options1" multiple :multiple-limit="2" show-limit-text> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<div>场景5:自定义图标 + 自定义样式</div>
|
||||
|
@ -43,12 +45,45 @@
|
|||
<tiny-select
|
||||
v-model="value4"
|
||||
multiple
|
||||
:options="options1"
|
||||
:dropdown-icon="iconPopup"
|
||||
:drop-style="{ width: '200px', 'min-width': '200px' }"
|
||||
>
|
||||
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
|
||||
</tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<div>场景6:禁用</div>
|
||||
<br />
|
||||
<tiny-select v-model="value5" multiple :options="options1" disabled> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<div>场景7:只展示</div>
|
||||
<br />
|
||||
<tiny-select v-model="value5" multiple :options="options1" display-only> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<div>场景8:显示全选文本</div>
|
||||
<br />
|
||||
<tiny-select v-model="value5" multiple :options="options1" show-all-text-tag> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<tiny-select v-model="value5" multiple :options="options1" show-all-text-tag disabled> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<div>场景9:折叠tag + 必选项 + 禁用项</div>
|
||||
<br />
|
||||
<tiny-select v-model="value5" multiple :options="options1" collapse-tags> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<div>场景10:悬浮展开 + 必选项 + 禁用项</div>
|
||||
<br />
|
||||
<tiny-select v-model="value5" multiple :options="options1" hover-expand> </tiny-select>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div>场景11:点击展开 + 必选项 + 禁用项</div>
|
||||
<br />
|
||||
<tiny-select v-model="value5" multiple :options="options1" click-expand> </tiny-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -64,8 +99,8 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
options1: [
|
||||
{ value: '选项1', label: '北京' },
|
||||
{ value: '选项2', label: '上海' },
|
||||
{ value: '选项1', label: '北京(禁用)', disabled: true }, // 禁用项
|
||||
{ value: '选项2', label: '上海(必选)', required: true }, // 必选项
|
||||
{ value: '选项3', label: '天津' },
|
||||
{ value: '选项4', label: '重庆' },
|
||||
{ value: '选项5', label: '深圳' },
|
||||
|
@ -77,7 +112,7 @@ export default {
|
|||
{ value: '选项2', label: '上海' },
|
||||
{ value: '选项3', label: '天津' },
|
||||
{ value: '选项4', label: '重庆' },
|
||||
{ value: '选项5', label: '深圳', required: true },
|
||||
{ value: '选项5', label: '深圳(必选)', required: true },
|
||||
{ value: '选项6', label: '南京' },
|
||||
{ value: '选项7', label: '成都' }
|
||||
],
|
||||
|
@ -85,6 +120,7 @@ export default {
|
|||
value2: ['选项1', '选项2'],
|
||||
value3: ['选项1', '选项2'],
|
||||
value4: [],
|
||||
value5: ['选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7'],
|
||||
iconPopup: iconPopup()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,6 +94,14 @@ export default {
|
|||
state.isSilentBlur = true
|
||||
api.updateModelValue(value)
|
||||
api.directEmitChange(value)
|
||||
},
|
||||
// aurora 禁用和只展示的时候都是tagText,默认主题是 isDisplayOnly 才显示tagText
|
||||
computedShowTagText: () => {
|
||||
return state.isDisabled || state.isDisplayOnly
|
||||
},
|
||||
// aurora 禁用已选项无效果,必选不显示关闭图标
|
||||
isTagClosable: (item) => {
|
||||
return !item.required
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2262,9 +2262,9 @@ export const computedDisabledTooltipContent =
|
|||
}
|
||||
|
||||
export const computedSelectDisabled =
|
||||
({ props, parent }) =>
|
||||
({ state }) =>
|
||||
() =>
|
||||
props.disabled || (parent.form || {}).disabled || props.displayOnly || (parent.form || {}).displayOnly
|
||||
state.isDisabled || state.isDisplayOnly
|
||||
|
||||
export const computedIsExpand =
|
||||
({ props, state }) =>
|
||||
|
@ -2340,6 +2340,23 @@ export const watchShowClose =
|
|||
}
|
||||
|
||||
// 以下为tiny 新增功能
|
||||
/**
|
||||
* 兼容不同主题多选禁用的展示类型
|
||||
* default 和 smb 主题,displayOnly 时显示为 tagText,否则为 tag
|
||||
* aurora 主题 displayOnly||disabled 时显示为tagText,否则为 tag
|
||||
*/
|
||||
export const computedShowTagText =
|
||||
({ state }) =>
|
||||
() =>
|
||||
state.isDisplayOnly
|
||||
|
||||
/**
|
||||
* 兼容不同主题多选,tag 在disabled 和 required 时是否显示关闭按钮的区别
|
||||
* default 主题 ,禁用显示关闭按钮,required目前和aurora保持一致不显示,待设计图补充时更新
|
||||
* aurora 主题,禁用时无禁用效果,required 时不显示关闭按钮
|
||||
*/
|
||||
export const isTagClosable = () => (item) => !item.required
|
||||
|
||||
export const computedGetIcon =
|
||||
({ designConfig, props }) =>
|
||||
() => {
|
||||
|
@ -2359,6 +2376,7 @@ export const computedGetTagType =
|
|||
}
|
||||
return props.tagType
|
||||
}
|
||||
|
||||
export const clearSearchText =
|
||||
({ state, api }) =>
|
||||
() => {
|
||||
|
@ -2366,6 +2384,7 @@ export const clearSearchText =
|
|||
state.previousQuery = undefined
|
||||
api.handleQueryChange(state.query)
|
||||
}
|
||||
|
||||
export const clearNoMatchValue =
|
||||
({ props, emit }) =>
|
||||
(newModelValue) => {
|
||||
|
|
|
@ -106,7 +106,9 @@ import {
|
|||
clearNoMatchValue,
|
||||
handleDebouncedQueryChange,
|
||||
onClickCollapseTag,
|
||||
computedIsExpand
|
||||
computedIsExpand,
|
||||
computedShowTagText,
|
||||
isTagClosable
|
||||
} from './index'
|
||||
import debounce from '../common/deps/debounce'
|
||||
import { isNumber } from '../common/type'
|
||||
|
@ -170,7 +172,9 @@ export const api = [
|
|||
'loadTreeData',
|
||||
'updateModelValue',
|
||||
'clearSearchText',
|
||||
'onClickCollapseTag'
|
||||
'onClickCollapseTag',
|
||||
'computedShowTagText',
|
||||
'isTagClosable'
|
||||
]
|
||||
|
||||
const initState = ({ reactive, computed, props, api, emitter, parent, constants, useBreakpoint, vm, designConfig }) => {
|
||||
|
@ -287,6 +291,8 @@ const initStateAdd = ({ computed, props, api, parent }) => {
|
|||
formItemSize: computed(() => (parent.formItem || { state: {} }).state.formItemSize),
|
||||
selectDisabled: computed(() => api.computedSelectDisabled()),
|
||||
isDisplayOnly: computed(() => props.displayOnly || (parent.form || {}).displayOnly),
|
||||
isDisabled: computed(() => props.disabled || (parent.form || {}).disabled),
|
||||
isShowTagText: computed(() => api.computedShowTagText()),
|
||||
gridCheckedData: computed(() => api.getcheckedData()),
|
||||
isExpandAll: computed(() => api.computedIsExpandAll()),
|
||||
searchSingleCopy: computed(() => props.allowCopy && !props.multiple && (props.filterable || props.searchable)),
|
||||
|
@ -381,7 +387,7 @@ const initApi = ({
|
|||
computedOptionsAllDisabled: computedOptionsAllDisabled(state),
|
||||
computedDisabledTooltipContent: computedDisabledTooltipContent({ props, state }),
|
||||
|
||||
computedSelectDisabled: computedSelectDisabled({ props, parent }),
|
||||
computedSelectDisabled: computedSelectDisabled({ state }),
|
||||
computedIsExpand: computedIsExpand({ props, state }),
|
||||
computedIsExpandAll: computedIsExpandAll(props),
|
||||
watchInitValue: watchInitValue({ props, emit }),
|
||||
|
@ -390,7 +396,9 @@ const initApi = ({
|
|||
computedGetIcon: computedGetIcon({ designConfig, props }),
|
||||
computedGetTagType: computedGetTagType({ designConfig, props }),
|
||||
clearSearchText: clearSearchText({ state, api }),
|
||||
clearNoMatchValue: clearNoMatchValue({ props, emit })
|
||||
clearNoMatchValue: clearNoMatchValue({ props, emit }),
|
||||
computedShowTagText: computedShowTagText({ state }),
|
||||
isTagClosable: isTagClosable()
|
||||
})
|
||||
|
||||
addApi({ api, props, state, emit, constants, parent, nextTick, dispatch, vm, isMobileFirstMode, designConfig })
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export const tinyInputAuroraTheme = {
|
||||
'ti-input-border-color': '#d9d9d9',
|
||||
'ti-input-hover-border-color': '#1890ff',
|
||||
'ti-input-icon-close-text-color': '#bfbfbf'
|
||||
'ti-input-icon-close-text-color': '#bfbfbf',
|
||||
'ti-input-display-content-line-height': 'var(--ti-common-space-6x)'
|
||||
}
|
||||
|
|
|
@ -303,6 +303,7 @@
|
|||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
line-height: var(--ti-input-display-content-line-height);
|
||||
}
|
||||
|
||||
&__mask {
|
||||
|
|
|
@ -89,4 +89,6 @@
|
|||
--ti-input-suffix-icon-height: 1em;
|
||||
// 输入框placeholder颜色
|
||||
--ti-input-placeholder-color: var(--ti-common-color-placeholder, #adb0b8);
|
||||
// displayOnly 时文本行高
|
||||
--ti-input-display-content-line-height: var(--ti-common-line-height-number);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ export const tinySelectAuroraTheme = {
|
|||
'ti-select-tags-margin-bottom': '2px',
|
||||
'ti-select-tags-margin-left': 'var(--ti-common-space-0)',
|
||||
'ti-select-tags-wrap-padding-left': '8px',
|
||||
'ti-select-tags-padding-right-disabled': 'var(--ti-common-space-4x)',
|
||||
'ti-select-input-icon-close-margin-right': 'var(--ti-common-space-2x)',
|
||||
'ti-select-tags-height': '28px',
|
||||
'ti-select-input-icon-top': '50%',
|
||||
|
|
|
@ -122,6 +122,13 @@
|
|||
|
||||
> span {
|
||||
font-size: 0;
|
||||
|
||||
.tiny-tag.is-required {
|
||||
cursor: not-allowed;
|
||||
> svg {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +199,7 @@
|
|||
display: inline-flex;
|
||||
|
||||
> span {
|
||||
color: red;
|
||||
color: var(--ti-select-tags-text-color-disabled);
|
||||
font-size: var(--ti-tag-font-size);
|
||||
margin: var(--ti-select-tags-margin-top) var(--ti-select-tags-margin-right)
|
||||
var(--ti-select-tags-margin-bottom) var(--ti-select-tags-margin-left);
|
||||
|
@ -318,7 +325,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
&.is-disabled,
|
||||
&.is-display-only {
|
||||
cursor: not-allowed;
|
||||
|
||||
.@{input-prefix-cls} {
|
||||
|
@ -334,6 +342,10 @@
|
|||
.@{select-prefix-cls}__tags {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}__tags.is-show-tag {
|
||||
padding-right: var(--ti-select-tags-padding-right-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
&-tip &-tipcontent {
|
||||
|
|
|
@ -13,6 +13,7 @@ export const tinySelectSmbTheme = {
|
|||
'ti-select-tags-margin-top': 'var(--ti-common-space-2)',
|
||||
'ti-select-tags-margin-bottom': 'var(--ti-common-space-2)',
|
||||
'ti-select-tags-max-height': 'none',
|
||||
'ti-select-tags-padding-right-disabled': 'var(--ti-common-space-8x)',
|
||||
'ti-select-collapse-button-text-icon-color': 'var(--ti-common-color-text-link)',
|
||||
'ti-select-input-icon-top-mini': 'var(--ti-common-space-4x)'
|
||||
}
|
||||
|
|
|
@ -65,6 +65,10 @@
|
|||
--ti-select-tags-height: calc(var(--ti-common-size-base) * 7);
|
||||
// 选择器多选标签最大高度
|
||||
--ti-select-tags-max-height: var(--ti-common-size-24x, 96px);
|
||||
// 多选禁用时右侧内边距
|
||||
--ti-select-tags-padding-right-disabled: var(--ti-common-size-7x, 28px);
|
||||
// 多选禁用文本色
|
||||
--ti-select-tags-text-color-disabled: var(--ti-common-color-text-disabled, #adb0b8);
|
||||
// 选择器后缀图标显示状态
|
||||
--ti-select-suffix-display: 'inline-block';
|
||||
// 选择器右侧图标间距
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
hoverExpand ? 'is-hover-expand' : '',
|
||||
clickExpand ? 'is-click-expand' : '',
|
||||
state.showCollapseTag ? 'collapse-tag-clicked' : '',
|
||||
state.selectDisabled ? 'is-disabled' : '',
|
||||
state.isDisabled ? 'is-disabled' : '',
|
||||
inputBoxType === 'underline' ? 'tiny-select__underline' : ''
|
||||
]"
|
||||
@mouseleave.self="
|
||||
|
@ -69,18 +69,24 @@
|
|||
</tiny-filter-box>
|
||||
<div
|
||||
ref="tags"
|
||||
:class="['tiny-select__tags', { 'is-showicon': slots.prefix, 'not-selected': !state.selected.length }]"
|
||||
:class="[
|
||||
'tiny-select__tags',
|
||||
{ 'is-showicon': slots.prefix, 'not-selected': !state.selected.length },
|
||||
{ 'is-show-tag': !state.isShowTagText }
|
||||
]"
|
||||
v-if="multiple && !state.isDisplayOnly && !shape"
|
||||
:style="state.tagsStyle"
|
||||
>
|
||||
<span v-if="!state.selectDisabled">
|
||||
<span v-if="!state.isShowTagText">
|
||||
<span v-if="collapseTags && state.selected.length">
|
||||
<!-- 显示第1个标签 + 数字 -->
|
||||
<tiny-tag
|
||||
:closable="!state.selectDisabled"
|
||||
:class="{ 'is-required': state.selected[0].required }"
|
||||
:closable="isTagClosable(state.selected[0])"
|
||||
:size="state.collapseTagSize"
|
||||
:hit="state.selected[0].state ? state.selected[0].state.hitState : state.selected[0].hitState"
|
||||
:key="state.key"
|
||||
:disabled="state.selected[0].disabled"
|
||||
:type="state.getTagType"
|
||||
@close="deleteTag($event, state.selected[0])"
|
||||
disable-transitions
|
||||
|
@ -128,6 +134,7 @@
|
|||
:type="state.getTagType"
|
||||
key="tags-all-text-tag"
|
||||
data-tag="tags-all-text-tag"
|
||||
:disabled="state.isDisabled"
|
||||
:closable="true"
|
||||
:size="state.collapseTagSize"
|
||||
@close="toggleCheckAll(false)"
|
||||
|
@ -152,8 +159,12 @@
|
|||
<tiny-tag
|
||||
v-for="(item, index) in state.selected"
|
||||
:key="getValueKey(item)"
|
||||
:class="{ 'not-visible': state.toHideIndex <= index && !state.isExpand }"
|
||||
:closable="!item.disabled && !item.required"
|
||||
:class="{
|
||||
'not-visible': state.toHideIndex <= index && !state.isExpand,
|
||||
'is-required': item.required
|
||||
}"
|
||||
:closable="isTagClosable(item)"
|
||||
:disabled="state.isDisabled || item.disabled"
|
||||
:size="state.collapseTagSize"
|
||||
:hit="item.state ? item.state.hitState : item.hitState"
|
||||
:type="state.getTagType"
|
||||
|
@ -200,7 +211,7 @@
|
|||
</span>
|
||||
</span>
|
||||
|
||||
<span v-else class="tiny-select__tags-text is-disabled">
|
||||
<span v-else :class="['tiny-select__tags-text', 'is-display-only', { 'is-disabled': state.isDisabled }]">
|
||||
<tiny-tooltip
|
||||
:effect="tooltipConfig.effect || 'light'"
|
||||
:placement="tooltipConfig.placement || 'top'"
|
||||
|
|
Loading…
Reference in New Issue