-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathYStack.vue
95 lines (84 loc) · 2.26 KB
/
YStack.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<script lang="ts">
import Vue, { PropType, VNode, defineComponent } from 'vue';
import { Spaces } from '../constants';
import { Space } from '../types';
import { getSpace } from '../utilities';
/**
* 子要素を均等の間隔で垂直に並べます。
*/
export default defineComponent({
name: 'YStack',
props: {
/**
* 要素を指定します。Center
*/
tag: { type: String, default: 'div' },
/**
* 子要素間の距離を指定します。スペーシングのインデックスを指定します。「100px」や「10em」といった具体的な方法で幅を指定することはできません。
*/
space: { type: String as PropType<Space>, validator: (value: string) => Object.keys(Spaces).includes(value), required: true },
},
data(): {
parentIsYStack: boolean;
} {
return {
parentIsYStack: false,
};
},
computed: {
wrapperClass(): string | null {
return this.parentIsYStack ? null : 'stack';
},
innerWrapperTag(): string | null {
return this.parentIsYStack ? this.tag : null;
},
style(): { [property: string]: string } {
if (!this.space) {
return {};
}
const setSpace = getSpace(this.space);
return {
'--design-system-layout-stack-space': setSpace ? setSpace : '',
};
},
},
mounted(): void {
if (this.$parent == null) {
return;
}
if (this.$parent instanceof Vue && this.$parent.$options.name === 'YStack') {
this.parentIsYStack = true;
}
},
render(createElement: Vue.CreateElement): VNode {
let el;
let props;
let children;
if (this.parentIsYStack) {
el = 'div';
props = {};
children = [createElement(this.tag, { class: 'stack', style: this.style }, this.$slots.default)];
} else {
el = this.tag;
props = { class: 'stack', style: this.style };
children = this.$slots.default;
}
return createElement(el, props, children);
},
});
</script>
<style lang="scss" scoped>
.stack {
// --design-system-layout-stack-spaceを使用
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.stack > * {
margin-top: 0;
margin-bottom: 0;
}
.stack > * + * {
margin-top: var(--design-system-layout-stack-space);
}
</style>