mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-17 13:20:52 +08:00
feat(base-picker): for select & cascader
This commit is contained in:
parent
c381db1f36
commit
240a65fa30
2
index.js
2
index.js
@ -50,7 +50,7 @@ import Anchor from './packages/common/Anchor'
|
||||
import Dropdown from './packages/common/Dropdown'
|
||||
import Popselect from './packages/common/Popselect'
|
||||
import App from './packages/common/App'
|
||||
import CancelMark from './packages/common/CancelMark'
|
||||
import CancelMark from './packages/base/CancelMark'
|
||||
|
||||
function install (Vue) {
|
||||
Card.install(Vue)
|
||||
|
8
packages/base/Picker/index.js
Normal file
8
packages/base/Picker/index.js
Normal file
@ -0,0 +1,8 @@
|
||||
/* istanbul ignore file */
|
||||
import BasePicker from './src/main.vue'
|
||||
|
||||
BasePicker.install = function (Vue) {
|
||||
Vue.component(BasePicker.name, BasePicker)
|
||||
}
|
||||
|
||||
export default BasePicker
|
199
packages/base/Picker/src/main.vue
Normal file
199
packages/base/Picker/src/main.vue
Normal file
@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<div
|
||||
class="n-base-picker"
|
||||
:class="{
|
||||
'n-base-picker--active': active,
|
||||
'n-base-picker--selected': selected || (active && pattern),
|
||||
'n-base-picker--disabled': disabled,
|
||||
[`n-base-picker--${size}-size`]: true,
|
||||
'n-base-picker--multiple': multiple
|
||||
}"
|
||||
@click="handleActivatorClick"
|
||||
>
|
||||
<template v-if="multiple">
|
||||
<div
|
||||
class="n-base-picker-tags"
|
||||
:class="{
|
||||
'n-base-picker-tags--selected': selected
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-for="option in selectedOptions"
|
||||
:key="option.value"
|
||||
class="n-base-picker-tag"
|
||||
>
|
||||
<div class="n-base-picker-tag__content">
|
||||
{{ option.label }}
|
||||
</div>
|
||||
<n-icon
|
||||
class="n-base-picker-tag__icon"
|
||||
type="md-close"
|
||||
@click.stop="toggleOption(option)"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="filterable && active"
|
||||
class="n-base-picker-input-tag"
|
||||
>
|
||||
<input
|
||||
ref="inputTagInput"
|
||||
:value="pattern"
|
||||
class="n-base-picker-input-tag__input"
|
||||
@keyup.delete="handlePatternInputDelete"
|
||||
@input="handlePatternInput"
|
||||
>
|
||||
<span
|
||||
ref="inputTagMirror"
|
||||
class="n-base-picker-input-tag__mirror"
|
||||
>{{ pattern ? pattern : ' ' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="n-base-picker__placeholder"
|
||||
>
|
||||
{{ placeholder }}
|
||||
</div>
|
||||
<n-base-cancel-mark
|
||||
class="n-base-picker__mark"
|
||||
arrow
|
||||
:show="!remote"
|
||||
:disabled="disabled"
|
||||
:active="active"
|
||||
:clearable="clearable && selected"
|
||||
@clear="handleClear"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="n-base-picker-label">
|
||||
<input
|
||||
ref="singleInput"
|
||||
:value="singleInputActive ? pattern : (selectedOption && selectedOption.label)"
|
||||
class="n-base-picker-label__input"
|
||||
:placeholder="selectedOption ? selectedOption.label : placeholder"
|
||||
:readonly="!disabled && filterable ? false : 'readonly'"
|
||||
@input="handlePatternInput"
|
||||
@focus="handleSingleInputFocus"
|
||||
>
|
||||
</div>
|
||||
<n-base-cancel-mark
|
||||
class="n-base-picker__mark"
|
||||
arrow
|
||||
:show="!remote"
|
||||
:disabled="disabled"
|
||||
:active="active"
|
||||
:clearable="clearable && selected"
|
||||
@clear="handleClear"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NBaseCancelMark from '../../CancelMark'
|
||||
import NIcon from '../../../common/Icon'
|
||||
|
||||
export default {
|
||||
name: 'NBasePicker',
|
||||
components: {
|
||||
NBaseCancelMark,
|
||||
NIcon
|
||||
},
|
||||
props: {
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
pattern: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
selectedOption: {
|
||||
validator () {
|
||||
return true
|
||||
},
|
||||
default: null
|
||||
},
|
||||
selectedOptions: {
|
||||
validator () {
|
||||
return true
|
||||
},
|
||||
default: null
|
||||
},
|
||||
toggleOption: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
singleInputActive: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
remote: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selected () {
|
||||
if (this.multiple) return !!(Array.isArray(this.selectedOptions) && this.selectedOptions.length)
|
||||
else {
|
||||
return this.selectedOption !== null
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClear () {
|
||||
this.$emit('clear')
|
||||
},
|
||||
handleActivatorClick () {
|
||||
this.$emit('activator-click')
|
||||
},
|
||||
handlePatternInputDelete () {
|
||||
this.$emit('pattern-input-delete')
|
||||
},
|
||||
handlePatternInput (e) {
|
||||
if (this.multiple) {
|
||||
this.$nextTick().then(() => {
|
||||
const textWidth = this.$refs.inputTagMirror.getBoundingClientRect().width
|
||||
this.$refs.inputTagInput.style.width = textWidth + 'px'
|
||||
this.$emit('pattern-input', e)
|
||||
})
|
||||
} else {
|
||||
this.$emit('pattern-input', e)
|
||||
}
|
||||
},
|
||||
handleSingleInputFocus () {
|
||||
this.$emit('single-input-focus')
|
||||
},
|
||||
blurSingleInput () {
|
||||
this.$refs.singleInput.blur()
|
||||
},
|
||||
focusInputTag () {
|
||||
this.$refs.inputTagInput.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -64,7 +64,7 @@
|
||||
<script>
|
||||
import NIcon from '../../Icon'
|
||||
import Emitter from '../../../mixins/emitter'
|
||||
import NCancelMark from '../../CancelMark'
|
||||
import NCancelMark from '../../../base/CancelMark'
|
||||
|
||||
export default {
|
||||
name: 'NInput',
|
||||
|
200
styles/BasePicker.scss
Normal file
200
styles/BasePicker.scss
Normal file
@ -0,0 +1,200 @@
|
||||
@import './mixins/mixins.scss';
|
||||
@import './theme/default.scss';
|
||||
|
||||
@include b(base-picker) {
|
||||
position: relative;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
border-radius: $select-border-radius;
|
||||
.n-base-picker__mark {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 14px;
|
||||
}
|
||||
.n-base-picker__placeholder {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
left: 14px;
|
||||
top: 0;
|
||||
color: $select-placeholder-color;
|
||||
opacity: 1;
|
||||
}
|
||||
.n-base-picker-label, .n-base-picker-tags {
|
||||
position: relative;
|
||||
transition: box-shadow .3s $default-cubic-bezier, background-color .3s $default-cubic-bezier;
|
||||
box-sizing: border-box;
|
||||
border-radius: $select-border-radius;
|
||||
background-color: $select-background-color;
|
||||
}
|
||||
.n-base-picker-label {
|
||||
display: flex;
|
||||
.n-base-picker-label__input {
|
||||
vertical-align: baseline;
|
||||
display: inline-block;
|
||||
border:none;
|
||||
width: 100%;
|
||||
cursor: inherit;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
color: $select-text-color;
|
||||
padding: 0 32px 0 14px;
|
||||
&::placeholder {
|
||||
color: $select-placeholder-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.n-base-picker-tags {
|
||||
padding: 4px 32px 0 14px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
.n-base-picker-tag {
|
||||
vertical-align: bottom;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border: 1px solid #63E2B7FF;
|
||||
color: #63E2B7FF;
|
||||
border-radius: 4px;
|
||||
margin-right: 7px;
|
||||
margin-bottom: 4px;
|
||||
font-size: 14px;
|
||||
max-width: 100%;
|
||||
.n-base-picker-tag__content {
|
||||
transform: translateY(-1px);
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.n-base-picker-tag__icon {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
i::before {
|
||||
color: #63E2B7FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.n-base-picker--selected {
|
||||
.n-base-picker__placeholder {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
&.n-base-picker--active {
|
||||
.n-base-picker-label, .n-base-picker-tags {
|
||||
box-shadow: inset 0 0 0 1px $select-border-color--active, 0px 0px 10px 1px #366555;
|
||||
background-color: $select-background-color--active;
|
||||
}
|
||||
}
|
||||
&.n-base-picker--small-size {
|
||||
font-size: 14px;
|
||||
.n-base-picker__placeholder {
|
||||
height: $small-height;
|
||||
line-height: $small-height;
|
||||
}
|
||||
.n-base-picker-tags {
|
||||
min-height: $small-height;
|
||||
.n-base-picker-tag {
|
||||
font-size: 13px;
|
||||
padding: 0px 20px 0 7px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.n-base-picker-input-tag {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
.n-base-picker-label {
|
||||
height: $small-height;
|
||||
line-height: $small-height;
|
||||
.n-base-picker-label__input {
|
||||
height: $small-height;
|
||||
line-height: $small-height;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.n-base-picker--default-size, &.n-base-picker--medium-size {
|
||||
font-size: 14px;
|
||||
.n-base-picker__placeholder {
|
||||
height: $medium-height;
|
||||
line-height: $medium-height;
|
||||
}
|
||||
.n-base-picker-tags {
|
||||
min-height: $medium-height;
|
||||
.n-base-picker-tag {
|
||||
padding: 0px 20px 0 7px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.n-base-picker-input-tag {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
}
|
||||
.n-base-picker-label {
|
||||
height: $medium-height;
|
||||
line-height: $medium-height;
|
||||
.n-base-picker-label__input {
|
||||
height: $medium-height;
|
||||
line-height: $medium-height;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.n-base-picker--large-size {
|
||||
font-size: 14px;
|
||||
.n-base-picker__placeholder {
|
||||
height: $large-height;
|
||||
line-height: $large-height;
|
||||
}
|
||||
.n-base-picker-tags {
|
||||
min-height: $large-height;
|
||||
.n-base-picker-tag {
|
||||
padding: 0px 20px 0 7px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.n-base-picker-input-tag {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
.n-base-picker-label {
|
||||
height: $large-height;
|
||||
line-height: $large-height;
|
||||
.n-base-picker-label__input {
|
||||
height: $large-height;
|
||||
line-height: $large-height;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.n-base-picker--disabled {
|
||||
cursor: not-allowed;
|
||||
.n-base-picker-label, .n-base-picker-tags {
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
.n-base-picker-tag {
|
||||
border-color: rgba(255, 255, 255, 0.20);
|
||||
color: rgba(255, 255, 255, 0.20);
|
||||
}
|
||||
.n-base-picker__placeholder {
|
||||
color: rgba(255, 255, 255, 0.20);
|
||||
}
|
||||
.n-base-picker-label {
|
||||
.n-base-picker-label__input {
|
||||
color: rgba(255, 255, 255, 0.20);
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.20);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover:not(.n-base-picker--disabled) {
|
||||
.n-base-picker-label, .n-base-picker-tags {
|
||||
box-shadow: inset 0 0 0 1px $select-border-color--active;
|
||||
}
|
||||
}
|
||||
}
|
@ -39,7 +39,8 @@
|
||||
@import './Anchor.scss';
|
||||
@import './Dropdown.scss';
|
||||
@import './Popselect.scss';
|
||||
@import './CancelMark.scss';
|
||||
@import './BaseCancelMark.scss';
|
||||
@import './BasePicker.scss';
|
||||
|
||||
@import "./NimbusServiceLayout.scss";
|
||||
@import "./Popover.scss";
|
||||
|
Loading…
Reference in New Issue
Block a user