diff --git a/packages/theme/src/base-select/index.less b/packages/theme/src/base-select/index.less new file mode 100644 index 0000000000..192de52b1a --- /dev/null +++ b/packages/theme/src/base-select/index.less @@ -0,0 +1,401 @@ +/** +* Copyright (c) 2022 - present TinyVue Authors. +* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. +* +* Use of this source code is governed by an MIT-style license. +* +* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, +* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR +* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. +* +*/ + +@import '../custom.less'; +@import './vars.less'; + +@base-select-prefix-cls: ~'@{css-prefix}base-select'; +@input-prefix-cls: ~'@{css-prefix}input'; +@tag-prefix-cls: ~'@{css-prefix}tag'; + +.@{base-select-prefix-cls} { + .inject-BaseSelect-vars(); + + display: inline-block; + position: relative; + width: 100%; + outline: 0; + font-size: var(--tv-BaseSelect-font-size); + line-height: var(--tv-BaseSelect-line-height); + + &&__multiple:not(&__collapse-tags):not(&__filterable) &__tags > span { + // 兼容ie10-ie11 + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + align-content: flex-start; + } + + // 兼容edge + @supports (-ms-ime-align: auto) { + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + align-content: flex-start; + } + } + + &&__collapse-tags { + .@{base-select-prefix-cls}__tags { + & > span { + display: flex; + width: 100%; + + & > span { + display: flex; + } + + & > span:not(:only-child):first-child { + max-width: 70%; + } + } + } + + &.@{base-select-prefix-cls}__filterable { + .@{base-select-prefix-cls}__tags { + & > span { + width: auto; + max-width: 76%; + + & > span:first-child { + flex: 1; + + // 兼容ie10-ie11 + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + flex-basis: auto; + } + } + + & > span:only-child, + & > span:not(:only-child):first-child { + max-width: 100%; + } + + & > span:not(:only-child):not(:first-child) { + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + // 兼容ie10-ie11 + flex-shrink: 0; + flex-basis: auto; + } + } + } + } + } + } + + &&__filterable { + .@{base-select-prefix-cls}__tags { + .@{base-select-prefix-cls}__input { + cursor: text; + } + } + } + + &__tags { + position: absolute; + line-height: normal; + white-space: normal; + padding: var(--tv-BaseSelect-tags-padding); + z-index: 1; + top: 50%; + margin-left: 1px; + transform: translateY(-50%); + display: flex; + align-items: center; + flex-wrap: wrap; + cursor: pointer; + + & > span { + display: contents; + + > span { + font-size: 0; + } + } + + .not-visible { + visibility: hidden; + } + + /* 搜索框 */ + .@{base-select-prefix-cls}__input { + cursor: pointer; + border: none; + outline: 0; + padding: 0; + margin-left: 8px; + color: var(--tv-BaseSelect-text-color); + font-size: var(--tv-BaseSelect-font-size); + height: var(--tv-BaseSelect-input-height); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: transparent; + } + + &.is-showicon { + padding-left: 24px; + } + + .@{tag-prefix-cls} { + white-space: nowrap; + box-sizing: border-box; + border-color: transparent; + margin: var(--tv-BaseSelect-tag-margin); + text-overflow: ellipsis; + overflow: hidden; + display: inline-flex; + justify-content: flex-start; + align-items: center; + max-width: 160px; + } + + .@{base-select-prefix-cls}__tags-text { + display: inline-block; + width: 100%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + vertical-align: bottom; + + & + .@{tag-prefix-cls}__close { + flex-shrink: 0; + } + + &.is-disabled { + max-height: 24px; + display: inline-flex; + + > span { + margin: var(--tv-BaseSelect-tag-margin); + display: inline-block; + width: 100%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + } + } + + // 收起按钮 + .@{base-select-prefix-cls}__collapse-text { + display: inline-flex; + align-items: center; + margin-left: var(--tv-BaseSelect-tags-margin-left); + font-size: var(--tv-BaseSelect-font-size); + color: var(--tv-BaseSelect-collapse-text-color); + + .tiny-svg { + margin-left: var(--tv-BaseSelect-collapse-icon-margin-left); + fill: var(--tv-BaseSelect-collapse-icon-color); + } + } + } + + &.is-hover-expand, + &.is-click-expand { + vertical-align: top; + + .@{base-select-prefix-cls}__tags-group { + position: absolute; + top: 0; + left: 0; + right: 0; + } + + &.is-hover { + .is-expand { + z-index: 2; + } + } + + .@{base-select-prefix-cls}__tags { + height: var(--tv-BaseSelect-tags-height); + overflow: hidden; + + &-collapse { + visibility: visible; + position: static; + } + + .is-hidden { + visibility: hidden; + position: absolute; + } + + > span > span { + width: 100%; + display: flex; + flex-wrap: wrap; + } + + .hidden { + visibility: hidden; + } + } + + &.is-hover, + &.collapse-tag-clicked { + .@{base-select-prefix-cls}__tags { + height: auto; + max-height: none; + overflow-y: auto; + + &-collapse { + visibility: hidden; + position: absolute; + + &.is-hidden { + margin: 0; + } + } + + &.not-selected { + overflow-y: hidden; + } + } + } + + & .is-expand { + position: absolute; + width: 100%; + } + + &.@{base-select-prefix-cls}--small { + .@{base-select-prefix-cls}__tags { + padding-top: 2px; + } + } + + &.@{base-select-prefix-cls}--mini { + .@{base-select-prefix-cls}__tags { + padding-top: 2px; + } + } + } + + &.is-hover-expand.is-disabled { + .@{base-select-prefix-cls}__tags { + height: auto; + } + } + + &.is-click-expand .@{base-select-prefix-cls}__tags-collapse { + visibility: visible; + position: static; + + &.is-hidden { + visibility: hidden; + position: absolute; + } + } + + &.is-disabled { + cursor: not-allowed; + + .@{input-prefix-cls} { + &__inner { + padding-right: 12px; + } + + &__suffix { + display: inline-block; + } + } + + .@{base-select-prefix-cls}__tags { + padding-right: 16px; + } + } + + &-tip &-tipcontent { + max-width: 300px; + } + + & .@{input-prefix-cls} { + display: block; + + .@{input-prefix-cls}__inner[readonly] { + cursor: pointer; + } + + .@{base-select-prefix-cls}__caret { + fill: var(--tv-BaseSelect-icon-color); + font-size: var(--tv-BaseSelect-icon-font-size); + transition: transform 0.3s; + transform: rotateZ(180deg); + cursor: pointer; + + &:hover { + fill: var(--tv-BaseSelect-icon-color-hover); + } + + &.is-reverse { + transform: rotateZ(0); + } + } + + .@{base-select-prefix-cls}__limit-txt, + .@{base-select-prefix-cls}__proportion-txt { + color: var(--tv-BaseSelect-suffix-text-color); + font-size: var(--tv-BaseSelect-font-size); + margin: var(--tv-BaseSelect-suffix-txt-margin); + } + + .@{base-select-prefix-cls}__copy { + cursor: pointer; + margin-right: var(--tv-BaseSelect-suffix-icon-margin-right); + } + + .@{input-prefix-cls}__suffix { + top: var(--tv-BaseSelect-suffix-top); + + &-inner { + font-size: 0; + } + } + + & .@{input-prefix-cls}__suffix-inner { + overflow: hidden; + } + + &-medium .@{input-prefix-cls}__suffix { + top: var(--tv-BaseSelect-suffix-top-medium); + } + + // TODO: 尾部按钮应垂直居中,待优化 + &-small .@{input-prefix-cls}__suffix { + top: var(--tv-BaseSelect-suffix-top-small); + } + + &-mini .@{input-prefix-cls}__suffix { + top: var(--tv-BaseSelect-suffix-top-mini); + } + + &.is-disabled { + .@{base-select-prefix-cls}__caret { + fill: var(--tv-BaseSelect-icon-color-disabled); + cursor: not-allowed; + } + + .@{input-prefix-cls}__inner { + cursor: not-allowed; + } + } + + &.is-focus .@{input-prefix-cls}__inner { + border-color: var(--tv-BaseSelect-input-border-color-active); + } + } +} diff --git a/packages/theme/src/base-select/vars.less b/packages/theme/src/base-select/vars.less new file mode 100644 index 0000000000..6adf670f13 --- /dev/null +++ b/packages/theme/src/base-select/vars.less @@ -0,0 +1,63 @@ +/** +* Copyright (c) 2022 - present TinyVue Authors. +* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. +* +* Use of this source code is governed by an MIT-style license. +* +* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, +* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR +* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. +* +*/ + +.inject-BaseSelect-vars() { + // 文本色 + --tv-BaseSelect-text-color: var(--tv-color-text, #191919); + // 字号 + --tv-BaseSelect-font-size: var(--tv-font-size-md, 14px); + // 行高 + --tv-BaseSelect-line-height: var(--tv-line-height-number, 1.5); + + // 图标色 + --tv-BaseSelect-icon-color: var(--tv-color-icon, #808080); + // 图标悬浮色 + --tv-BaseSelect-icon-color-hover: var(--tv-color-icon-hover, #191919); + // 图标禁用色 + --tv-BaseSelect-icon-color-disabled: var(--tv-color-icon-disabled, #c2c2c2); + // 图标尺寸 + --tv-BaseSelect-icon-font-size: var(--tv-icon-size, 16px); + + // 边框激活色 + --tv-BaseSelect-input-border-color-active: var(--tv-color-border-active, #191919); + + // 尾部图标距离输入框的垂直距离(默认尺寸) + --tv-BaseSelect-suffix-top: var(--tv-space-xl, 16px); + // 尾部图标距离输入框的垂直距离(中型尺寸) + --tv-BaseSelect-suffix-top-medium: 20px; + // 尾部图标距离输入框的垂直距离(小型尺寸) + --tv-BaseSelect-suffix-top-small: var(--tv-space-xl, 16px); + // 尾部图标距离输入框的垂直距离(迷你尺寸) + --tv-BaseSelect-suffix-top-mini: var(--tv-space-lg, 12px); + // 尾部图标右侧外间距 + --tv-BaseSelect-suffix-icon-margin-right: var(--tv-space-sm, 4px); + // 尾部文本外间距 + --tv-BaseSelect-suffix-txt-margin: 0 var(--tv-space-sm, 4px); + // 尾部文本色 + --tv-BaseSelect-suffix-text-color: var(--tv-color-text-weaken, #808080); + // 输入框高度(默认尺寸) + --tv-BaseSelect-input-height: var(--tv-size-height-md, 32px); + + // 多选标签容器内边距 + --tv-BaseSelect-tags-padding: var(--tv-space-xs, 2px) 0px var(--tv-space-xs, 2px) var(--tv-space-xs, 2px); + // 多选标签容器高度 + --tv-BaseSelect-tags-height: var(--tv-size-height-md, 32px); + // 标签外边距 + --tv-BaseSelect-tag-margin: var(--tv-space-xs, 2px); + + // 收起按钮文本色 + --tv-BaseSelect-collapse-text-color: var(--tv-color-text-link, #1476ff); + // 收起按钮图标色 + --tv-BaseSelect-collapse-icon-color: var(--tv-color-icon-link, #1476ff); + // 收起按钮图标左侧外边距 + --tv-BaseSelect-collapse-icon-margin-left: var(--tv-space-xs, 2px); +} diff --git a/packages/vue/src/base-select/src/pc.vue b/packages/vue/src/base-select/src/pc.vue index cc95e0873e..25a5931317 100644 --- a/packages/vue/src/base-select/src/pc.vue +++ b/packages/vue/src/base-select/src/pc.vue @@ -26,8 +26,7 @@ clickExpand ? 'is-click-expand' : '', state.showCollapseTag ? 'collapse-tag-clicked' : '', state.selectDisabled ? 'is-disabled' : '', - $parent.$attrs.class, - inputBoxType === 'underline' ? 'tiny-base-select__underline' : '' + $parent.$attrs.class ]" @mouseleave.self=" () => { @@ -253,6 +252,7 @@ :display-only-content="state.displayOnlyContent" :unselectable="state.readonly ? 'on' : 'off'" :validate-event="false" + :input-box-type="inputBoxType" :class="{ 'is-focus': state.visible, overflow: state.overflow, @@ -548,6 +548,7 @@ import RecycleScroller from '@opentiny/vue-recycle-scroller' import TinyCheckbox from '@opentiny/vue-checkbox' import '@opentiny/vue-theme/select/index.less' +import '@opentiny/vue-theme/base-select/index.less' const getReference = (el, binding, vnode) => { const _ref = binding.expression ? binding.value : binding.arg