mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-30 12:52:43 +08:00
feat(collapse): light theme
This commit is contained in:
parent
d4a3cc71a4
commit
325a96ddf7
@ -38,6 +38,7 @@ import themeable from '../../../mixins/themeable'
|
|||||||
import hollowoutable from '../../../mixins/hollowoutable'
|
import hollowoutable from '../../../mixins/hollowoutable'
|
||||||
import CheckMark from './CheckMark'
|
import CheckMark from './CheckMark'
|
||||||
import LineMark from './LineMark'
|
import LineMark from './LineMark'
|
||||||
|
import registerable from '../../../mixins/registerable'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NCheckbox',
|
name: 'NCheckbox',
|
||||||
@ -53,7 +54,8 @@ export default {
|
|||||||
mixins: [
|
mixins: [
|
||||||
withapp,
|
withapp,
|
||||||
themeable,
|
themeable,
|
||||||
hollowoutable
|
hollowoutable,
|
||||||
|
registerable('NCheckboxGroup', 'collectedCheckboxValues')
|
||||||
],
|
],
|
||||||
model: {
|
model: {
|
||||||
prop: 'checked',
|
prop: 'checked',
|
||||||
@ -89,23 +91,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
value (value, oldValue) {
|
|
||||||
if (this.NCheckboxGroup) {
|
|
||||||
this.registerValue(value, oldValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created () {
|
|
||||||
if (this.NCheckboxGroup) {
|
|
||||||
this.registerValue(this.value)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy () {
|
|
||||||
if (this.NCheckboxGroup) {
|
|
||||||
this.registerValue(undefined, this.value)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
registerValue (value = undefined, oldValue = undefined) {
|
registerValue (value = undefined, oldValue = undefined) {
|
||||||
if (this.NCheckboxGroup) {
|
if (this.NCheckboxGroup) {
|
||||||
|
@ -2,12 +2,15 @@
|
|||||||
<div
|
<div
|
||||||
class="n-collapse-item"
|
class="n-collapse-item"
|
||||||
:class="{
|
:class="{
|
||||||
'n-collapse-item--active': value
|
'n-collapse-item--active': !collapse,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="n-collapse-item__title"
|
class="n-collapse-item__title"
|
||||||
@click="handleTitleClick"
|
:class="{
|
||||||
|
'n-collapse-item__title--active': !collapse
|
||||||
|
}"
|
||||||
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<n-icon type="ios-arrow-forward" />{{ title }}
|
<n-icon type="ios-arrow-forward" />{{ title }}
|
||||||
</div>
|
</div>
|
||||||
@ -18,7 +21,7 @@
|
|||||||
@leave="handleLeave"
|
@leave="handleLeave"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="value"
|
v-if="!collapse"
|
||||||
ref="contentContainer"
|
ref="contentContainer"
|
||||||
class="n-collapse-item__content-wrapper"
|
class="n-collapse-item__content-wrapper"
|
||||||
>
|
>
|
||||||
@ -35,12 +38,19 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NIcon from '../../Icon'
|
import NIcon from '../../Icon'
|
||||||
|
import registerable from '../../../mixins/registerable'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NCollapseItem',
|
name: 'NCollapseItem',
|
||||||
components: {
|
components: {
|
||||||
NIcon
|
NIcon
|
||||||
},
|
},
|
||||||
|
mixins: [registerable('NCollapse', 'collectedItemNames', 'name')],
|
||||||
|
inject: {
|
||||||
|
NCollapse: {
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -55,6 +65,14 @@ export default {
|
|||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
collapse () {
|
||||||
|
if (this.NCollapse && Array.isArray(this.NCollapse.value)) {
|
||||||
|
return !~this.NCollapse.value.findIndex(name => name === this.name)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleEnter () {
|
handleEnter () {
|
||||||
this.$refs.contentContainer.style.maxHeight = 0
|
this.$refs.contentContainer.style.maxHeight = 0
|
||||||
@ -69,9 +87,10 @@ export default {
|
|||||||
this.$el.getBoundingClientRect()
|
this.$el.getBoundingClientRect()
|
||||||
this.$refs.contentContainer.style.maxHeight = 0
|
this.$refs.contentContainer.style.maxHeight = 0
|
||||||
},
|
},
|
||||||
handleTitleClick () {
|
handleClick () {
|
||||||
const newValue = !this.value
|
if (this.NCollapse) {
|
||||||
this.$emit('input', newValue, this.name)
|
this.NCollapse.toggleItem(this.collapse, this.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,19 @@
|
|||||||
<script>
|
<script>
|
||||||
function mapSlot (slot, activeNames, isAccordion, handleInput, self) {
|
import intersection from 'lodash/intersection'
|
||||||
const names = []
|
import withapp from '../../../mixins/withapp'
|
||||||
for (const vNode of slot) {
|
import themeable from '../../../mixins/themeable'
|
||||||
if (vNode.componentOptions && (vNode.componentOptions.tag === 'NCollapseItem' || vNode.componentOptions.tag === 'n-collapse-item')) {
|
|
||||||
const name = vNode.componentOptions.propsData.name
|
|
||||||
names.push(name)
|
|
||||||
vNode.componentOptions.listeners = {
|
|
||||||
...vNode.componentOptions.listeners,
|
|
||||||
input: handleInput
|
|
||||||
}
|
|
||||||
if (isAccordion) {
|
|
||||||
console.log(name, activeNames)
|
|
||||||
if (name === activeNames) {
|
|
||||||
vNode.componentOptions.propsData.value = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Array.isArray(activeNames) && activeNames.includes(name)) {
|
|
||||||
vNode.componentOptions.propsData.value = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.memorizedNames = names
|
|
||||||
return slot
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NCollapse',
|
name: 'NCollapse',
|
||||||
|
provide () {
|
||||||
|
return {
|
||||||
|
NCollapse: this
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [
|
||||||
|
withapp,
|
||||||
|
themeable
|
||||||
|
],
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: [Array, String],
|
type: [Array, String],
|
||||||
@ -39,22 +26,22 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
memorizedNames: null
|
collectedItemNames: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleInput (value, name) {
|
toggleItem (collapse, name) {
|
||||||
if (this.accordion) {
|
if (this.accordion) {
|
||||||
if (value) {
|
if (collapse) {
|
||||||
this.$emit('input', name)
|
this.$emit('input', [name])
|
||||||
} else {
|
} else {
|
||||||
this.$emit('input', null)
|
this.$emit('input', [])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!Array.isArray(this.value)) {
|
if (!Array.isArray(this.value)) {
|
||||||
this.$emit('input', [name])
|
this.$emit('input', [name])
|
||||||
} else {
|
} else {
|
||||||
const activeNames = Array.from(new Set(this.value.filter(v => this.memorizedNames.includes(v))))
|
const activeNames = intersection(this.value, this.collectedItemNames)
|
||||||
const index = activeNames.findIndex(activeName => name === activeName)
|
const index = activeNames.findIndex(activeName => name === activeName)
|
||||||
if (~index) {
|
if (~index) {
|
||||||
activeNames.splice(index, 1)
|
activeNames.splice(index, 1)
|
||||||
@ -69,8 +56,11 @@ export default {
|
|||||||
},
|
},
|
||||||
render (h) {
|
render (h) {
|
||||||
return h('div', {
|
return h('div', {
|
||||||
staticClass: 'n-collapse'
|
staticClass: 'n-collapse',
|
||||||
}, mapSlot(this.$slots.default, this.value, this.accordion, this.handleInput, this))
|
class: {
|
||||||
|
[`n-${this.synthesizedTheme}-theme`]: this.synthesizedTheme
|
||||||
|
}
|
||||||
|
}, this.$slots.default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
35
packages/mixins/registerable.js
Normal file
35
packages/mixins/registerable.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
export default function (
|
||||||
|
inject,
|
||||||
|
collectionProperty,
|
||||||
|
registerProperty = 'value'
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
watch: {
|
||||||
|
[registerProperty]: function (value, oldValue) {
|
||||||
|
if (this[inject]) {
|
||||||
|
this.registerValue(value, oldValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
if (this[inject]) {
|
||||||
|
this.registerValue(this[registerProperty])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
if (this[inject]) {
|
||||||
|
this.registerValue(undefined, this[registerProperty])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
registerValue (value = undefined, oldValue = undefined) {
|
||||||
|
if (this[inject]) {
|
||||||
|
const values = new Set(this[inject][collectionProperty])
|
||||||
|
if (oldValue !== undefined) values.delete(oldValue)
|
||||||
|
if (value !== undefined) values.add(value)
|
||||||
|
this[inject][collectionProperty] = Array.from(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,48 +5,66 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include b(collapse-item) {
|
@include themes-mixin {
|
||||||
overflow: hidden;
|
@include b(collapse) {
|
||||||
font-size: 14px;
|
@include b(collapse-item) {
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
@include once {
|
||||||
padding-top: 16px;
|
overflow: hidden;
|
||||||
&:first-child {
|
font-size: 14px;
|
||||||
padding-top: 0px;
|
transition: border-color .3s $default-cubic-bezier;
|
||||||
}
|
margin-top: 16px;
|
||||||
&:last-child {
|
&:first-child {
|
||||||
border-bottom: none;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
@include b(collapse-item) {
|
&:first-child > {
|
||||||
margin-left: 18px;
|
@include e(title) {
|
||||||
}
|
padding-top: 0px;
|
||||||
&.n-collapse-item--active {
|
}
|
||||||
.n-collapse-item__title {
|
}
|
||||||
.n-icon {
|
@include b(collapse-item) {
|
||||||
transform: rotate(90deg);
|
margin-left: 32px;
|
||||||
|
}
|
||||||
|
@include e(content-wrapper) {
|
||||||
|
@include fade-in-height-expand-transition($duration: .15s);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
@include m(active) {
|
||||||
|
@include e(title) {
|
||||||
|
@include m(active) {
|
||||||
|
@include b(icon) {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:not(:first-child) {
|
||||||
|
border-top: 1px solid $--n-border-color;
|
||||||
|
}
|
||||||
|
@include e(title) {
|
||||||
|
@include once {
|
||||||
|
transition: color .3s $default-cubic-bezier;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 18px;
|
||||||
|
padding: 16px 0 0 0;
|
||||||
|
@include b(icon) {
|
||||||
|
transition: transform .15s $default-cubic-bezier;
|
||||||
|
font-size: 16px;
|
||||||
|
position: absolute;
|
||||||
|
left: -18px;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color: $--n-text-color;
|
||||||
|
}
|
||||||
|
@include e(content-inner) {
|
||||||
|
@include once {
|
||||||
|
transition: color .3s $default-cubic-bezier;
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
color: $--n-secondary-text-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.n-collapse-item__title {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
.n-icon {
|
|
||||||
transition: transform .3s $default-cubic-bezier;
|
|
||||||
font-size: 16px;
|
|
||||||
position: absolute;
|
|
||||||
left: -18px;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
color: rgba(233, 233, 236, 1);
|
|
||||||
margin-left: 18px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
.n-collapse-item__content-wrapper {
|
|
||||||
@include fade-in-height-expand-transition($duration: .15s);
|
|
||||||
overflow: hidden;
|
|
||||||
// transition: max-height .3s $default-cubic-bezier;
|
|
||||||
}
|
|
||||||
.n-collapse-item__content-inner {
|
|
||||||
color: rgba(233, 233, 236, .7);
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -154,9 +154,6 @@ $layout-nav-height: 64px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@include m(is-group-header) {
|
@include m(is-group-header) {
|
||||||
// span {
|
|
||||||
// transition: color 0.3s $default-cubic-bezier;
|
|
||||||
// }
|
|
||||||
&::after { // down arrow
|
&::after { // down arrow
|
||||||
content: '';
|
content: '';
|
||||||
height: 6px;
|
height: 6px;
|
||||||
@ -170,11 +167,11 @@ $layout-nav-height: 64px;
|
|||||||
transform-origin: 25% 25%;
|
transform-origin: 25% 25%;
|
||||||
transition: transform 0.3s $default-cubic-bezier, opacity 0.3s $default-cubic-bezier;
|
transition: transform 0.3s $default-cubic-bezier, opacity 0.3s $default-cubic-bezier;
|
||||||
}
|
}
|
||||||
@include m(group-item-is-choosed) {
|
// @include m(group-item-is-choosed) {
|
||||||
span {
|
// span {
|
||||||
color: #63E2B7;
|
// color: #63E2B7;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
@include m(collapsed) {
|
@include m(collapsed) {
|
||||||
&::after {
|
&::after {
|
||||||
transform: rotate(225deg) ;
|
transform: rotate(225deg) ;
|
||||||
|
@ -361,11 +361,11 @@ $default-cubic-bezier: cubic-bezier(.4, 0, .2, 1);
|
|||||||
}
|
}
|
||||||
&.#{$namespace}-#{$block}-leave-active {
|
&.#{$namespace}-#{$block}-leave-active {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: max-height $duration $default-cubic-bezier, opacity $duration $slow-out-cubic-bezier;
|
transition: max-height $duration $default-cubic-bezier, opacity $duration $fast-in-cubic-bezier;
|
||||||
}
|
}
|
||||||
&.#{$namespace}-#{$block}-enter-active {
|
&.#{$namespace}-#{$block}-enter-active {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: max-height $duration $default-cubic-bezier, opacity $duration $fast-in-cubic-bezier;
|
transition: max-height $duration $default-cubic-bezier, opacity $duration $slow-out-cubic-bezier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user