diff --git a/packages/design/aurora/src/select-wrapper/index.ts b/packages/design/aurora/src/select-wrapper/index.ts
new file mode 100644
index 0000000000..67b5a05801
--- /dev/null
+++ b/packages/design/aurora/src/select-wrapper/index.ts
@@ -0,0 +1,109 @@
+import { iconChevronDown } from '@opentiny/vue-icon'
+
+export default {
+ // 虚拟滚动的默认options不一致
+ baseOpts: { optionHeight: 34, limit: 20 },
+ icons: {
+ dropdownIcon: iconChevronDown()
+ },
+ state: {
+ sizeMap: {
+ default: 30,
+ mini: 24,
+ small: 36,
+ medium: 42
+ },
+ spacingHeight: 2,
+ initialInputHeight: 30,
+ // 显示清除等图标时,不隐藏下拉箭头时
+ autoHideDownIcon: false,
+ delayBlur: true
+ },
+ props: {
+ tagType: 'info',
+ stopPropagation: true
+ },
+ renderless: (props, hooks, { emit }, api) => {
+ const state = api.state
+
+ return {
+ // 兼容不同主题输入框尺寸对应标签尺寸不一致
+ computedCollapseTagSize: () => {
+ let size = 'small'
+
+ if (~['small', 'mini'].indexOf(state.selectSize)) {
+ size = state.selectSize
+ } else if (~['medium', 'default'].indexOf(state.selectSize)) {
+ size = 'small'
+ }
+
+ return size
+ },
+ // 兼容显示清除图标时,是否同时显示下拉图标
+ computedShowDropdownIcon: () => {
+ return !(props.remote && props.filterable && !props.remoteConfig.showIcon)
+ },
+
+ // aui 的勾选未处理disabled的选项,故此放这里。
+ toggleCheckAll: (filtered) => {
+ const getEnabledValues = (options) => {
+ let values = []
+
+ for (let i = 0; i < options.length; i++) {
+ if (!options[i].state.disabled && !options[i].state.groupDisabled && options[i].state.visible) {
+ values.push(options[i].value)
+ }
+ }
+
+ return values
+ }
+
+ let value
+ const enabledValues = getEnabledValues(state.options)
+
+ if (filtered) {
+ if (state.filteredSelectCls === 'check' || state.filteredSelectCls === 'halfselect') {
+ value = Array.from(new Set([...state.modelValue, ...enabledValues]))
+ } else {
+ value = state.modelValue.filter((val) => !enabledValues.includes(val))
+ }
+ } else {
+ if (state.selectCls === 'check') {
+ value = enabledValues
+ } else if (state.selectCls === 'halfselect') {
+ const unchecked = state.options.filter((item) => !item.state.disabled && item.state.selectCls === 'check')
+
+ unchecked.length ? (value = enabledValues) : (value = [])
+ } else if (state.selectCls === 'checked-sur') {
+ value = []
+ }
+ }
+
+ const requiredValue = []
+ if (props.multiple) {
+ state.options.forEach((opt) => {
+ if (opt.required) requiredValue.push(opt.value)
+ })
+ }
+
+ if (Array.isArray(value)) {
+ value = requiredValue.concat(value.filter((val) => !requiredValue.find((requireVal) => requireVal === val)))
+ }
+
+ api.setSoftFocus()
+
+ 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
+ }
+ }
+ }
+}
diff --git a/packages/design/saas/src/select-wrapper/icon-loading.svg b/packages/design/saas/src/select-wrapper/icon-loading.svg
new file mode 100644
index 0000000000..94160f70a1
--- /dev/null
+++ b/packages/design/saas/src/select-wrapper/icon-loading.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/packages/design/saas/src/select-wrapper/index.ts b/packages/design/saas/src/select-wrapper/index.ts
new file mode 100644
index 0000000000..adae4352ed
--- /dev/null
+++ b/packages/design/saas/src/select-wrapper/index.ts
@@ -0,0 +1,106 @@
+import { iconChevronDown, iconPlus } from '@opentiny/vue-icon'
+import loadingIcon from './icon-loading.svg'
+
+export default {
+ // 虚拟滚动的默认options不一致
+ baseOpts: { optionHeight: 34, limit: 20 },
+ icons: {
+ dropdownIcon: iconChevronDown(),
+ addIcon: iconPlus(),
+ loadingIcon
+ },
+ state: {
+ sizeMap: {
+ default: 28,
+ mini: 24,
+ small: 28,
+ medium: 32
+ },
+ spacingHeight: 4,
+ initialInputHeight: 28,
+ // 显示清除等图标时,不隐藏下拉箭头时
+ autoHideDownIcon: false,
+ delayBlur: true
+ },
+ props: {
+ tagType: 'info',
+ stopPropagation: true
+ },
+ renderless: (props, hooks, { emit }, api) => {
+ const state = api.state
+
+ return {
+ computedCollapseTagSize: () => {
+ let size = 'small'
+
+ if (~['small', 'mini'].indexOf(state.selectSize)) {
+ size = state.selectSize
+ } else if (~['medium', 'default'].indexOf(state.selectSize)) {
+ size = 'small'
+ }
+
+ return size
+ },
+ // aui 的勾选未处理disabled的选项,故此放这里。
+ toggleCheckAll: (filtered) => {
+ const getEnabledValues = (options) => {
+ let values = []
+
+ for (let i = 0; i < options.length; i++) {
+ if (!options[i].state.disabled && !options[i].state.groupDisabled && options[i].state.visible) {
+ values.push(options[i].value)
+ }
+ }
+
+ return values
+ }
+
+ let value
+ const enabledValues = getEnabledValues(state.options)
+
+ if (filtered) {
+ if (state.filteredSelectCls === 'check' || state.filteredSelectCls === 'halfselect') {
+ value = Array.from(new Set([...state.modelValue, ...enabledValues]))
+ } else {
+ value = state.modelValue.filter((val) => !enabledValues.includes(val))
+ }
+ } else {
+ if (state.selectCls === 'check') {
+ value = enabledValues
+ } else if (state.selectCls === 'halfselect') {
+ const unchecked = state.options.filter((item) => !item.state.disabled && item.state.selectCls === 'check')
+
+ unchecked.length ? (value = enabledValues) : (value = [])
+ } else if (state.selectCls === 'checked-sur') {
+ value = []
+ }
+ }
+
+ const requiredValue = []
+ if (props.multiple) {
+ state.options.forEach((opt) => {
+ if (opt.required) requiredValue.push(opt.value)
+ })
+ }
+
+ if (Array.isArray(value)) {
+ value = requiredValue.concat(value.filter((val) => !requiredValue.find((requireVal) => requireVal === val)))
+ }
+
+ api.setSoftFocus()
+
+ 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
+ }
+ }
+ }
+}
diff --git a/packages/renderless/src/base-select/index.ts b/packages/renderless/src/base-select/index.ts
index 445bbbe4e7..cc8dc91fdf 100644
--- a/packages/renderless/src/base-select/index.ts
+++ b/packages/renderless/src/base-select/index.ts
@@ -1249,6 +1249,9 @@ const postOperOfToVisible = ({ props, state, constants, vm }) => {
if (props.modelValue && props.initLabel && !state.selectedLabel) {
state.selectedLabel = props.initLabel
}
+ } else if (props.modelValue && props.initLabel) {
+ // 如果 state.selected 不存在,但有 modelValue 和 initLabel,则使用 initLabel
+ state.selectedLabel = props.initLabel
}
}
diff --git a/packages/renderless/src/select-wrapper/vue.ts b/packages/renderless/src/select-wrapper/vue.ts
index 87134f2e4c..8420c214ac 100644
--- a/packages/renderless/src/select-wrapper/vue.ts
+++ b/packages/renderless/src/select-wrapper/vue.ts
@@ -25,11 +25,11 @@ export const renderless = (props, { reactive, computed, useAttrs }, { constants,
: ['tiny-select']
const { class: _omitClass, ...restAttrs } = attrs
-
return {
...props,
...restAttrs,
- class: classArray
+ class: Array.from(new Set(classArray)),
+ dataTag: 'tiny-select'
}
})
diff --git a/packages/vue/src/base-select/src/mobile-first.vue b/packages/vue/src/base-select/src/mobile-first.vue
index 336ef84f70..90ec1e6f17 100644
--- a/packages/vue/src/base-select/src/mobile-first.vue
+++ b/packages/vue/src/base-select/src/mobile-first.vue
@@ -302,6 +302,8 @@
:display-only-content="state.displayOnlyContent"
:unselectable="state.readonly ? 'on' : 'off'"
:validate-event="false"
+ :show-empty-value="showEmptyValue"
+ :input-box-type="inputBoxType"
:tabindex="multiple && filterable ? '-1' : tabindex"
@focus="handleFocus"
@blur="handleBlur"
@@ -758,7 +760,10 @@ export default defineComponent({
'showAllTextTag',
'hoverExpand',
'clickExpand',
- 'maxVisibleRows'
+ 'maxVisibleRows',
+ 'initLabel',
+ 'inputBoxType',
+ 'showEmptyValue'
],
setup(props, context) {
return setup({ props, context, renderless, api, classes })
diff --git a/packages/vue/src/grid-select/src/mobile-first.vue b/packages/vue/src/grid-select/src/mobile-first.vue
index 443d8c26cc..227a42e496 100644
--- a/packages/vue/src/grid-select/src/mobile-first.vue
+++ b/packages/vue/src/grid-select/src/mobile-first.vue
@@ -37,8 +37,8 @@
ref="gridRef"
auto-resize
:row-id="valueField"
- :select-config="state.selectConfig"
- :radio-config="state.radioConfig"
+ :select-config="buildSelectConfig()"
+ :radio-config="buildRadioConfig()"
:highlight-current-row="true"
:columns="gridOp?.columns || []"
:data="Array.isArray(state.gridData) ? state.gridData : state.gridData?.data || state.gridData || []"
diff --git a/packages/vue/src/input/src/mobile-first.vue b/packages/vue/src/input/src/mobile-first.vue
index 2042a69f6f..78ac882ff9 100644
--- a/packages/vue/src/input/src/mobile-first.vue
+++ b/packages/vue/src/input/src/mobile-first.vue
@@ -94,13 +94,15 @@
? 'h-6 leading-6 text-xs placeholder:text-xs'
: 'h-7 leading-7',
slots.prepend || slots.append ? 'align-middle table-cell' : 'inline-block',
- slots.prepend && slots.append
- ? 'rounded-none'
- : slots.prepend
- ? 'rounded-tl-none rounded-bl-none rounded-tr rounded-br'
- : slots.append
- ? 'rounded-tl rounded-bl rounded-tr-none rounded-br-none'
- : 'rounded',
+ inputBoxType === 'underline'
+ ? 'rounded-none border-t-0 border-l-0 border-r-0 border-b sm:border-b'
+ : slots.prepend && slots.append
+ ? 'rounded-none'
+ : slots.prepend
+ ? 'rounded-tl-none rounded-bl-none rounded-tr rounded-br'
+ : slots.append
+ ? 'rounded-tl rounded-bl rounded-tr-none rounded-br-none'
+ : 'rounded',
readonly ? ' text-ellipsis overflow-hidden whitespace-nowrap' : 'sm:border',
(slots.prefix || prefixIcon) && (slots.suffix || suffixIcon || clearable || showPassword)
? 'px-6 sm:px-6'
@@ -427,7 +429,8 @@ export default defineComponent({
'popupMore',
'showTooltip',
'frontClearIcon',
- 'hoverExpand'
+ 'hoverExpand',
+ 'inputBoxType'
],
setup(props, context): any {
return setup({ props, context, renderless, api })
diff --git a/packages/vue/src/select-wrapper/src/index.ts b/packages/vue/src/select-wrapper/src/index.ts
index 292eeb8457..ecd331351f 100644
--- a/packages/vue/src/select-wrapper/src/index.ts
+++ b/packages/vue/src/select-wrapper/src/index.ts
@@ -12,7 +12,7 @@
import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common'
import { t } from '@opentiny/vue-locale'
-import template from 'virtual-template?pc'
+import template from 'virtual-template?pc|mobile-first'
const $constants = {
CLASS: {
@@ -326,9 +326,9 @@ export default defineComponent({
type: Boolean,
default: false
},
- InputBoxType: {
+ inputBoxType: {
type: String,
- default: 'input',
+ default: 'normal',
validator: (value: string) => ['input', 'underline'].includes(value)
},
tagType: {
diff --git a/packages/vue/src/select-wrapper/src/mobile-first.vue b/packages/vue/src/select-wrapper/src/mobile-first.vue
new file mode 100644
index 0000000000..e6773c2b75
--- /dev/null
+++ b/packages/vue/src/select-wrapper/src/mobile-first.vue
@@ -0,0 +1,316 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/vue/src/select-wrapper/src/pc.vue b/packages/vue/src/select-wrapper/src/pc.vue
index babf871bc2..2d3e3fc975 100644
--- a/packages/vue/src/select-wrapper/src/pc.vue
+++ b/packages/vue/src/select-wrapper/src/pc.vue
@@ -263,7 +263,7 @@ export default defineComponent({
type: Boolean,
default: false
},
- InputBoxType: {
+ inputBoxType: {
type: String,
default: 'input',
validator: (value: string) => ['input', 'underline'].includes(value)