Skip to content

Commit c1df301

Browse files
committed
feat: features section with accordion
1 parent e6fc935 commit c1df301

17 files changed

+717
-252
lines changed

assets/scss/settings.scss

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
$gridWidth: 79.125rem;
20+
$halfGridWidth: 39.5625rem;
2021
$standardGutter: 0.75rem;
2122
$baseFontSize: 16;
2223
$baseLeading: 1.2;

assets/scss/theme/utilities.scss

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ $codGray: #060606; // black
3636
$sageGreen: #CBDDBB; // light soft green
3737
$alto: #D3D3D3; // light gray
3838
$burntSienna: #E8655D; // red
39-
$chardonnay: #FFC582; // yellowish orangish
39+
$chardonnay: #FFC582; // peachy orange
4040
$codeBlack: #191919; // black
4141
$tundora: #414141; // gray
4242
$eastSide: #BC8AC3; // lavender purple
43+
$siam: #565D50; // siam
4344

4445
// ====================================================================== Themes
4546
:root {
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<template>
2+
<div class="accordion-content" :style="{ height }">
3+
4+
<slot />
5+
6+
</div>
7+
</template>
8+
9+
<script>
10+
// ===================================================================== Imports
11+
import Throttle from 'lodash/throttle'
12+
13+
// ====================================================================== Export
14+
export default {
15+
name: 'AccordionContent',
16+
17+
data () {
18+
return {
19+
content: false,
20+
height: '0px',
21+
resize: false
22+
}
23+
},
24+
25+
mounted () {
26+
this.$nextTick(() => {
27+
this.content = this.$slots.default[0].elm
28+
this.resize = Throttle(() => {
29+
if (this.height !== '0px') {
30+
this.height = this.content.clientHeight + 'px'
31+
}
32+
}, 100)
33+
window.addEventListener('resize', this.resize)
34+
if (this.content.$on) {
35+
this.content.$on('changed', () => {
36+
this.$nextTick(() => {
37+
const height = this.content.clientHeight + 'px'
38+
if (height !== this.height) {
39+
this.height = height
40+
}
41+
})
42+
})
43+
}
44+
})
45+
},
46+
47+
beforeDestroy () {
48+
if (this.resize) { window.removeEventListener('resize', this.resize) }
49+
},
50+
51+
methods: {
52+
toggleOpen () {
53+
const height = this.height
54+
if (height === '0px') {
55+
this.height = this.content.clientHeight + 'px'
56+
} else {
57+
this.height = '0px'
58+
}
59+
}
60+
}
61+
}
62+
</script>
63+
64+
<style lang="scss" scoped>
65+
// ///////////////////////////////////////////////////////////////////// General
66+
.accordion-content {
67+
transition: height 150ms ease-in-out;
68+
}
69+
</style>
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<template>
2+
<div
3+
class="accordion-header"
4+
@click="toggle"
5+
@keyup.enter="toggle">
6+
7+
<slot />
8+
9+
</div>
10+
</template>
11+
12+
<script>
13+
// ====================================================================== Export
14+
export default {
15+
name: 'AccordionHeader',
16+
17+
mounted () {
18+
this.$nextTick(() => {
19+
const parent = this.$parent.$parent
20+
const count = parent.childCount
21+
const newCount = parent.$children.length
22+
if (parent.toggleOnLoad) {
23+
this.toggle()
24+
} else if (count !== newCount) {
25+
if (parent.toggleWhenAdded) { this.toggle() }
26+
if (parent.scrollToWhenAdded) {
27+
const timeout = setTimeout(() => {
28+
this.$scrollToElement(this.$el, 500, -96)
29+
clearTimeout(timeout)
30+
}, 150)
31+
}
32+
}
33+
})
34+
},
35+
36+
methods: {
37+
toggle () {
38+
this.$parent.$parent.$emit('toggle', this.$parent._uid)
39+
}
40+
}
41+
}
42+
</script>
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<template>
2+
<div :class="['accordion-section', { open }]">
3+
4+
<slot />
5+
6+
</div>
7+
</template>
8+
9+
<script>
10+
// ====================================================================== Export
11+
export default {
12+
name: 'AccordionSection',
13+
14+
props: {
15+
active: {
16+
type: [Boolean, Number, Array],
17+
default: false
18+
},
19+
selected: {
20+
type: Boolean,
21+
default: false
22+
}
23+
},
24+
25+
data () {
26+
return {
27+
id: this._uid
28+
}
29+
},
30+
31+
computed: {
32+
open () {
33+
if (Array.isArray(this.active)) {
34+
return this.active.includes(this.id)
35+
}
36+
return this.active === this.id
37+
}
38+
},
39+
40+
watch: {
41+
open () {
42+
this.$children[1].toggleOpen()
43+
}
44+
},
45+
46+
mounted () {
47+
this.$nextTick(() => {
48+
if (this.selected) {
49+
this.$parent.setSelected(this.id)
50+
}
51+
})
52+
}
53+
}
54+
</script>
55+
56+
<style lang="scss" scoped>
57+
// ///////////////////////////////////////////////////////////////////// General
58+
.accordion-section {
59+
position: relative;
60+
overflow: hidden;
61+
}
62+
</style>

components/accordion/accordion.vue

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<template>
2+
<div class="accordion">
3+
4+
<slot :active="active" />
5+
6+
</div>
7+
</template>
8+
9+
<script>
10+
// ====================================================================== Export
11+
export default {
12+
name: 'Accordion',
13+
14+
props: {
15+
multiple: {
16+
type: Boolean,
17+
default: false
18+
},
19+
toggleOnLoad: {
20+
type: Boolean,
21+
required: false,
22+
default: false
23+
},
24+
toggleWhenAdded: {
25+
type: Boolean,
26+
required: false,
27+
default: false
28+
},
29+
scrollToWhenAdded: {
30+
type: Boolean,
31+
required: false,
32+
default: false
33+
}
34+
},
35+
36+
data () {
37+
return {
38+
active: this.multiple ? [] : false,
39+
childCount: 0
40+
}
41+
},
42+
43+
created () {
44+
this.$on('toggle', (id) => {
45+
if (this.multiple) {
46+
// Open multiple panels
47+
if (this.active.includes(id)) {
48+
this.active = this.active.filter(_id => _id !== id)
49+
} else {
50+
this.active.push(id)
51+
}
52+
} else {
53+
// Open single panel
54+
if (this.active === id) {
55+
this.active = false
56+
} else {
57+
this.active = id
58+
}
59+
}
60+
})
61+
},
62+
63+
mounted () {
64+
this.childCount = this.$children.length
65+
},
66+
67+
methods: {
68+
setSelected (id) {
69+
if (this.multiple) {
70+
this.active.push(id)
71+
} else {
72+
this.active = id
73+
}
74+
}
75+
}
76+
}
77+
</script>

0 commit comments

Comments
 (0)