Skip to content
This repository was archived by the owner on Apr 15, 2025. It is now read-only.

Commit 8a2b953

Browse files
authored
Merge pull request #33 from GrabarzUndPartner/feature/sample-accordion
feat(components): sample accordion
2 parents f370a47 + 7995128 commit 8a2b953

File tree

3 files changed

+217
-74
lines changed

3 files changed

+217
-74
lines changed
Lines changed: 124 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,153 @@
11
<template>
2-
<base-accordeon class="button" :class="classes" v-bind="$attrs" v-on="$listeners">
3-
<icon v-if="icon || loading" :icon="loading? 'loading' : icon" />
4-
<slot name="default" :label="label">
5-
<span v-if="label" v-html="label" />
6-
</slot>
7-
<slot name="after" />
2+
<base-accordeon
3+
class="molecule-accordeon"
4+
v-bind="$attrs"
5+
:dataset="getDataset"
6+
v-on="$listeners"
7+
>
8+
<template #label="{option}">
9+
<span
10+
v-font="$getFont('Poppins', 400)"
11+
>
12+
{{ option.label }}
13+
</span>
14+
</template>
15+
<template #content="{show, option}">
16+
<transition-expand>
17+
<section v-show="show">
18+
<div>
19+
<slot name="content" v-bind="{show, option}">
20+
<component :is="getContentComponent(component.type)" v-for="(component, index) in option.content" :key="index" v-bind="component.props" />
21+
</slot>
22+
</div>
23+
</section>
24+
</transition-expand>
25+
</template>
826
</base-accordeon>
927
</template>
1028

1129
<script>
12-
import BaseAccordeon from '@foundation/core/mutation/Accordeon';
13-
import Icon from '@/components/atoms/Icon';
30+
import BaseAccordeon from '@foundation/core/CollapsibleContainer/Accordeon';
31+
import TransitionExpand from '@foundation/core/CollapsibleContainer/transition/expand';
32+
import Dataset from '@foundation/core/CollapsibleContainer/classes/Dataset';
33+
import Model from '@foundation/core/CollapsibleContainer/classes/Model';
34+
35+
const CONTENT_COMPONENTS = {
36+
Headline: () => import('@/components/atoms/Headline'),
37+
RichText: () => import('@/components/atoms/RichText'),
38+
Link: () => import('@/components/atoms/Link'),
39+
Button: () => import('@/components/atoms/Button')
40+
};
1441
1542
export default {
16-
components: {
17-
BaseAccordeon,
18-
Icon
19-
},
43+
components: { BaseAccordeon, TransitionExpand },
44+
inheritAttrs: false,
45+
2046
props: {
21-
label: {
22-
type: String,
23-
default: null
24-
},
25-
icon: {
26-
type: String,
27-
default: null
28-
},
29-
loading: {
30-
type: Boolean,
31-
default: null
47+
items: {
48+
type: Array,
49+
required: true,
50+
default () {
51+
return [
52+
{
53+
label: 'Item 1',
54+
value: 'item1',
55+
content: [
56+
{
57+
type: 'RichText',
58+
props: {
59+
text: 'Lorem Ipsum item 1'
60+
}
61+
}
62+
]
63+
}
64+
];
65+
}
3266
}
3367
},
68+
69+
data () {
70+
return { unsubscribe: null };
71+
},
72+
3473
computed: {
35-
classes () {
36-
return {
37-
loading: this.loading
38-
};
74+
getDataset () {
75+
return new Dataset(this.items, new Model('default-a', 'b'));
76+
}
77+
78+
},
79+
80+
mounted () {
81+
this.unsubscribe = this.$router.afterEach(() => {
82+
const model = this.dataset.model;
83+
model.value = null;
84+
});
85+
},
86+
87+
destroyed () {
88+
this.unsubscribe();
89+
},
90+
91+
methods: {
92+
getContentComponent (type) {
93+
return CONTENT_COMPONENTS[String(type)];
3994
}
4095
}
4196
};
97+
4298
</script>
4399

44100
<style lang="postcss" scoped>
45-
.button {
46-
position: relative;
101+
.molecule-accordeon {
47102
display: flex;
48-
align-items: center;
49-
padding: calc(8 / 14 * 1em) calc(16 / 14 * 1em);
50-
font-size: calc(14 / 16 * 1em);
51-
line-height: 1;
52-
cursor: pointer;
53-
background: #fff;
54-
border: solid #aaa calc(1 / 14 * 1em);
55-
appearance: none;
56-
57-
&:not([disabled]):hover {
58-
background: #eee;
59-
}
60-
61-
&.loading {
62-
pointer-events: none;
103+
flex-wrap: wrap;
104+
font-family: monospace;
63105
64-
}
65-
66-
&[disabled] {
67-
cursor: not-allowed;
106+
& >>> {
107+
& input:checked + label {
108+
& > .icon {
109+
transform: rotate(180deg);
110+
}
111+
}
68112
69-
& >>> .icon {
70-
opacity: 0.5;
113+
& input:checked + label,
114+
& input:focus + label,
115+
& label:hover {
116+
color: #fff;
117+
background: #333;
71118
}
72-
}
73119
74-
& >>> .icon {
75-
width: 1em;
76-
margin-right: calc(8 / 14 * 1em);
77-
}
120+
& label {
121+
display: flex;
122+
align-items: center;
123+
width: 100%;
124+
padding: 8px;
125+
cursor: pointer;
126+
background: #eee;
78127
79-
}
128+
& .icon {
129+
order: 0;
130+
margin-right: 8px;
131+
transition: transform 0.2s;
132+
}
80133
81-
@keyframes spin {
82-
0% {
83-
transform: translate(-50%, -50%) rotate(0deg);
134+
& > span {
135+
flex: 1;
136+
order: 1;
137+
font-size: 14px;
138+
line-height: 1;
139+
}
140+
}
84141
}
85142
86-
100% {
87-
transform: translate(-50%, -50%) rotate(360deg);
143+
& > section {
144+
width: 100%;
145+
146+
& > div {
147+
padding: 8px;
148+
border: solid #eee 1px;
149+
border-top-width: 0;
150+
}
88151
}
89152
}
90153
</style>
Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
<template>
22
<layout-lost-container class="organism-accordeon">
3-
<molecule-accordeon />
3+
<molecule-accordeon class="accordeon" :items="items" />
44
</layout-lost-container>
55
</template>
66

77
<script>
88
import MoleculeAccordeon from '@/components/molecules/Accordeon';
99
import LayoutLostContainer from '@/components/layouts/LostContainer';
10+
1011
export default {
1112
components: { MoleculeAccordeon, LayoutLostContainer },
1213
props: {
13-
overline: {
14-
type: String,
15-
default: 'Overline'
16-
},
17-
headline: {
18-
type: String,
19-
default: 'Headline'
20-
},
21-
content: {
22-
type: String,
23-
default: '<p>Text</p>'
14+
items: {
15+
type: Array,
16+
required: true,
17+
default () {
18+
return [
19+
{
20+
label: 'Item 1',
21+
value: 'item1',
22+
content: [
23+
{
24+
type: 'RichText',
25+
props: {
26+
text: 'Lorem Ipsum item 1'
27+
}
28+
}
29+
]
30+
}
31+
];
32+
}
2433
}
2534
}
2635
};
@@ -33,6 +42,11 @@ export default {
3342
@media (--sm) {
3443
margin: em(48) 0;
3544
}
45+
46+
& .accordeon {
47+
lost-offset: 1 / 12;
48+
lost-column: 10 / 12;
49+
}
3650
}
3751
3852
</style>

packages/sample/src/pages/index.vue

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ export default {
1515
OrganismText: speedkitHydrate(() => import('@/components/organisms/Text')),
1616
OrganismGallery: speedkitHydrate(() => import('@/components/organisms/Gallery')),
1717
OrganismTextImage: speedkitHydrate(() => import('@/components/organisms/TextImage')),
18-
OrganismTeaserWall: speedkitHydrate(() => import('@/components/organisms/TeaserWall'))
18+
OrganismTeaserWall: speedkitHydrate(() => import('@/components/organisms/TeaserWall')),
19+
OrganismAccordeon: speedkitHydrate(() => import('@/components/organisms/Accordeon'))
1920
2021
},
2122
data () {
@@ -91,6 +92,71 @@ export default {
9192
headline: 'Sample Headline',
9293
content: '<p>Lorem ipsum dolor sit amet, <strong>consetetur sadipscing elitr</strong>, <em>sed diam nonumy eirmod tempor invidunt</em> <strong><em>ut labore et dolore magna aliquyam erat</em></strong>, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, <strong>consetetur sadipscing elitr</strong>, sed diam</p> <p>Lorem ipsum dolor sit amet, <strong>consetetur sadipscing elitr</strong>, <em>sed diam nonumy eirmod tempor invidunt</em></p> <ul> <li>List Item 1</li> <li>List Item 2</li> <li>List Item 3</li> </ul> <ol> <li>List Item 1</li> <li>List Item 2</li> <li>List Item 3</li> </ol>'
9394
}
95+
},
96+
{
97+
component: 'OrganismAccordeon',
98+
props: {
99+
items: [
100+
{
101+
label: 'Item 1',
102+
value: 'item1',
103+
content: [
104+
{
105+
type: 'Headline',
106+
props: {
107+
overline: 'This is an overline',
108+
text: 'This is the headline.'
109+
}
110+
},
111+
{
112+
type: 'RichText',
113+
props: {
114+
value: '<p>RichText Lorem Ipsum item 1</p>'
115+
}
116+
},
117+
{
118+
type: 'Link',
119+
props: {
120+
title: 'Sample Link',
121+
to: {
122+
hash: 'sample'
123+
}
124+
}
125+
}
126+
]
127+
},
128+
{
129+
label: 'Item 2',
130+
value: 'item2',
131+
content: [
132+
{
133+
type: 'RichText',
134+
props: {
135+
value: '<p>RichText Lorem Ipsum item 2</p>'
136+
}
137+
},
138+
{
139+
type: 'Button',
140+
props: {
141+
label: 'Sample Button'
142+
}
143+
}
144+
]
145+
},
146+
{
147+
label: 'Item 3',
148+
value: 'item3',
149+
content: [
150+
{
151+
type: 'RichText',
152+
props: {
153+
value: '<p>RichText Lorem Ipsum item 3</p>'
154+
}
155+
}
156+
]
157+
}
158+
]
159+
}
94160
}
95161
],
96162

0 commit comments

Comments
 (0)