refactor(select): empty status & data utils

This commit is contained in:
07akioni 2020-01-21 21:32:42 +08:00
parent 554052e1fe
commit 3b9e318887
9 changed files with 42 additions and 101 deletions

View File

@ -6,6 +6,7 @@
'n-base-select-menu--multiple': multiple,
[`n-${theme}-theme`]: theme
}"
:style="{
width: width && (width + 'px')
}"
@ -14,6 +15,7 @@
@mousedown.prevent="() => {}"
>
<n-scrollbar
v-show="!empty"
ref="scrollbar"
:theme="theme"
:without-scrollbar="withoutScrollbar"
@ -22,7 +24,7 @@
@scroll="handleMenuScroll"
>
<div class="n-base-select-menu-option-wrapper">
<template v-if="!loading">
<template v-show="empty">
<recycle-scroller
ref="virtualScroller"
class="n-virtual-scroller"
@ -54,39 +56,30 @@
</div>
</n-scrollbar>
<div
v-if="loading"
class="n-base-select-option n-base-select-option--loading"
v-if="empty"
style="padding: 14px 0;"
>
loading
</div>
<div
v-else-if="noData"
class="n-base-select-option n-base-select-option--no-data"
>
{{ noDataContent }}
</div>
<div
v-else-if="notFound"
class="n-base-select-option n-base-select-option--not-found"
>
{{ notFoundContent }}
<slot name="empty">
<n-empty description="No Data" />
</slot>
</div>
</div>
</template>
<script>
import NScrollbar from '../../../common/Scrollbar'
import NSelectOption from './SelectOption.vue'
import NSelectGroupHeader from './SelectGroupHeader.vue'
import NBaseLightBar from '../../LightBar'
import NEmpty from '../../../common/Empty'
import { RecycleScroller } from 'vue-virtual-scroller'
import debounce from 'lodash-es/debounce'
import {
getPrevAvailableIndex,
getNextAvailableIndex,
flattenOptions,
OPTION_TYPE
} from '../../../utils/data/flattenedOptions'
import NSelectOption from './SelectOption.vue'
import NSelectGroupHeader from './SelectGroupHeader.vue'
import NBaseLightBar from '../../LightBar'
import debounce from 'lodash-es/debounce'
import { RecycleScroller } from 'vue-virtual-scroller'
} from '../../../utils/component/select'
export default {
name: 'NBaseSelectMenu',
@ -99,6 +92,7 @@ export default {
NScrollbar,
NBaseLightBar,
NSelectOption,
NEmpty,
NSelectGroupHeader,
RecycleScroller
},
@ -131,10 +125,6 @@ export default {
type: String,
default: 'default'
},
loading: {
type: Boolean,
default: false
},
pattern: {
type: String,
default: null
@ -155,14 +145,6 @@ export default {
emitOption: {
type: Boolean,
default: false
},
noDataContent: {
type: [String, Function],
default: 'no data'
},
notFoundContent: {
type: [String, Function],
default: 'none result matched'
}
},
data () {
@ -182,11 +164,9 @@ export default {
const flattenedOptions = flattenOptions(this.options)
return flattenedOptions
},
notFound () {
return this.filterable && (this.pattern.length && !this.flattenedOptions.length)
},
noData () {
return this.flattenedOptions && this.flattenedOptions.length === 0
empty () {
const flattenedOptions = this.flattenedOptions
return flattenedOptions && flattenedOptions.length === 0
},
itemSize () {
return ({
@ -197,17 +177,7 @@ export default {
}
},
watch: {
notFound (value) {
if (value) {
this.hideLightBar(0)
}
},
noData (value) {
if (value) {
this.hideLightBar(0)
}
},
loading (value) {
empty (value) {
if (value) {
this.hideLightBar(0)
}

View File

@ -1,10 +0,0 @@
export const createValueAttribute = function createValueAttribute (value) {
if (typeof value === 'string') {
return 's-' + value
} else if (typeof value === 'number') {
return 'd-' + String(value)
} else {
console.error(['[naive-ui/select-option]: option value is neither string or number'])
return 'invalid'
}
}

View File

@ -7,7 +7,7 @@
:style="synthesizedStyle"
>
<div class="n-empty__icon">
<empty-icon />
<ios-remove-circle-outline />
</div>
<div v-if="showDescription" class="n-empty__description">
<slot>
@ -21,14 +21,14 @@
</template>
<script>
import EmptyIcon from './EmptyIcon'
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
import iosRemoveCircleOutline from '../../../icons/ios-remove-circle-outline'
export default {
name: 'NEmpty',
components: {
EmptyIcon
iosRemoveCircleOutline
},
mixins: [ withapp, themeable ],
props: {

View File

@ -1,10 +1,8 @@
/* istanbul ignore file */
import Select from './src/Select.vue'
import SelectOption from './src/SelectOption.vue'
Select.install = function (Vue) {
Vue.component(Select.name, Select)
Vue.component('NSelectOption', SelectOption)
}
export default Select

View File

@ -31,6 +31,7 @@
:disabled="disabled"
:size="size"
:theme="synthesizedTheme"
:loading="loading"
@click="handleActivatorClick"
@delete-last-option="handleDeleteLastOption"
@delete-option="handleToggleOption"
@ -64,16 +65,23 @@
:options="filteredOptions"
:multiple="multiple"
:size="size"
:loading="loading"
:no-data-content="noDataContent"
:not-found-content="notFoundContent"
:filterable="filterable"
:is-option-selected="isOptionSelected"
:mirror="false"
@menu-toggle-option="handleToggleOption"
@menu-scroll="handleMenuScroll"
@menu-visible="handleMenuVisible"
/>
>
<template v-if="$slots.empty" v-slot:empty>
<slot name="empty" />
</template>
<template v-if="$slots.unmatch" v-slot:unmatch>
<slot name="unmatch" />
</template>
<template v-if="$slots.action" v-slot:action>
<slot name="action" />
</template>
</n-base-select-menu>
</transition>
</div>
</div>
@ -91,7 +99,7 @@ import {
import {
filterOptions,
valueToOptionMap
} from '../../../utils/data/flattenedOptions'
} from '../../../utils/component/select'
import NBasePicker from '../../../base/Picker'
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
@ -193,14 +201,6 @@ export default {
items: {
type: Array,
default: undefined
},
noDataContent: {
type: [String, Function],
default: 'No Data'
},
notFoundContent: {
type: [String, Function],
default: 'No Result'
}
},
data () {
@ -208,8 +208,7 @@ export default {
active: false,
scrolling: false,
pattern: '',
memorizedValueToOptionMap: new Map(),
disablePlaceableTracingWhenActive: true
memorizedValueToOptionMap: new Map()
}
},
computed: {
@ -273,7 +272,6 @@ export default {
methods: {
activate () {
this.active = true
this.disablePlaceableTracingWhenActive = true
},
deactivate () {
this.active = false
@ -442,7 +440,6 @@ export default {
}
},
handleMenuVisible () {
this.disablePlaceableTracingWhenActive = false
this.updatePosition()
},
/**

View File

@ -1,5 +0,0 @@
<script>
import NBaseSelectOption from '../../../base/SelectMenu/src/SelectOption.vue'
export default NBaseSelectOption
</script>

View File

@ -86,17 +86,6 @@
}
cursor: not-allowed;
}
@include m(no-data) {
color: map-get($map: $--base-select-menu-option-color, $key: "disabled");
text-align: center;
pointer-events: none;
}
@include m(not-found) {
color: map-get($map: $--base-select-menu-option-color, $key: "disabled");
text-align: center;
pointer-events: none;
}
@include m(loading) {
color: map-get($map: $--base-select-menu-option-color, $key: "disabled");
text-align: center;

View File

@ -10,20 +10,22 @@
@include e(icon) {
@include once {
transition: fill .3s $--n-ease-in-out-cubic-bezier;
width: 40px;
height: 40px;
width: 28px;
height: 28px;
}
fill: $--empty-icon-fill;
}
@include e(description) {
@include once {
margin-top: 8px;
font-size: 14px;
margin-top: 4px;
transition: color .3s $--n-ease-in-out-cubic-bezier;
}
color: $--empty-text-color;
}
@include e(extra) {
@include once {
font-size: 14px;;
text-align: center;
transition: color .3s $--n-ease-in-out-cubic-bezier;
margin-top: 16px;