|
1 |
| -import { css } from 'emotion' |
| 1 | +/** |
| 2 | + * Hey! Welcome to @chakra-ui/vue Stack |
| 3 | + * |
| 4 | + * Stack is a layout utility component that makes |
| 5 | + * it easy to stack elements together and apply a space between them. |
| 6 | + * |
| 7 | + * @see Docs https://vue.chakra-ui.com/stack |
| 8 | + * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CStack/CStack.js |
| 9 | + */ |
| 10 | + |
| 11 | +import { StringArray, SNA } from '../config/props/props.types' |
| 12 | +import { cloneVNode, createStyledAttrsMixin } from '../utils' |
2 | 13 |
|
3 | 14 | import CFlex from '../CFlex'
|
4 |
| -import { createStyledAttrsMixin } from '../utils' |
| 15 | +import CBox from '../CBox' |
5 | 16 |
|
| 17 | +/** |
| 18 | + * CStack component |
| 19 | + * |
| 20 | + * Flex container to stck it's children |
| 21 | + * |
| 22 | + * @extends CFlex |
| 23 | + * @see Docs https://vue.chakra-ui.com/stack |
| 24 | + */ |
6 | 25 | const CStack = {
|
7 | 26 | name: 'CStack',
|
8 | 27 | mixins: [createStyledAttrsMixin('CStack')],
|
9 | 28 | props: {
|
10 |
| - ...CFlex.props, |
11 |
| - isInline: [Boolean, String, Array], |
12 |
| - isReversed: [Boolean, String, Array], |
13 |
| - direction: [Boolean, String, Array] |
| 29 | + direction: [String, Array], |
| 30 | + isInline: { |
| 31 | + type: Boolean, |
| 32 | + default: false |
| 33 | + }, |
| 34 | + isReversed: { |
| 35 | + type: Boolean, |
| 36 | + default: false |
| 37 | + }, |
| 38 | + align: StringArray, |
| 39 | + justify: StringArray, |
| 40 | + spacing: { |
| 41 | + type: SNA, |
| 42 | + default: 2 |
| 43 | + }, |
| 44 | + shouldWrapChildren: { |
| 45 | + type: Boolean, |
| 46 | + default: false |
| 47 | + } |
14 | 48 | },
|
15 | 49 | computed: {
|
16 | 50 | _isInline () {
|
@@ -39,28 +73,65 @@ const CStack = {
|
39 | 73 | }
|
40 | 74 |
|
41 | 75 | return _direction
|
42 |
| - }, |
43 |
| - spacingProps () { |
44 |
| - return this._isInline |
45 |
| - ? this._isReversed |
46 |
| - ? { mr: this.spacing, mb: 0 } |
47 |
| - : { ml: this.spacing, mt: 0 } |
48 |
| - : this._isReversed |
49 |
| - ? { mb: this.spacing, mr: 0 } |
50 |
| - : { mt: this.spacing, ml: 0 } |
51 | 76 | }
|
52 | 77 | },
|
53 | 78 | render (h) {
|
| 79 | + const children = this.$slots.default.filter(e => e.tag) |
| 80 | + const stackables = children.map((node, index) => { |
| 81 | + const isLastChild = children.length === index + 1 |
| 82 | + const spacingProps = this._isInline |
| 83 | + ? { [this._isReversed ? 'ml' : 'mr']: isLastChild ? null : this.spacing } |
| 84 | + : { [this._isReversed ? 'mt' : 'mb']: isLastChild ? null : this.spacing } |
| 85 | + |
| 86 | + let clone = cloneVNode(node, h) |
| 87 | + |
| 88 | + if (!clone.componentOptions) { |
| 89 | + clone = h(CBox, [clone]) |
| 90 | + } |
| 91 | + |
| 92 | + const { propsData } = clone.componentOptions |
| 93 | + const { attrs } = clone.data |
| 94 | + |
| 95 | + // If children nodes should wrap, |
| 96 | + // we wrap them inside block with |
| 97 | + // display set to inline block. |
| 98 | + if (this.shouldWrapChildren) { |
| 99 | + return h(CBox, { |
| 100 | + props: { |
| 101 | + as: this.as, |
| 102 | + to: this.to |
| 103 | + }, |
| 104 | + attrs: { |
| 105 | + d: 'inline-block', |
| 106 | + ...spacingProps |
| 107 | + } |
| 108 | + }, [clone]) |
| 109 | + } |
| 110 | + |
| 111 | + // Otherwise we simply set spacing props |
| 112 | + // to current node. |
| 113 | + clone.componentOptions.propsData = { |
| 114 | + ...propsData |
| 115 | + } |
| 116 | + |
| 117 | + clone.data.attrs = { |
| 118 | + ...attrs, |
| 119 | + ...spacingProps |
| 120 | + } |
| 121 | + |
| 122 | + return clone |
| 123 | + }) |
| 124 | + |
54 | 125 | return h(CFlex, {
|
55 |
| - class: [this.className, css({ |
56 |
| - '& > *:not(template) ~ *:not(template)': this.$chakraSystem(this.spacingProps) |
57 |
| - })], |
| 126 | + class: this.className, |
58 | 127 | props: {
|
59 |
| - ...this.$props, |
| 128 | + as: this.as, |
| 129 | + align: this.align, |
| 130 | + justify: this.justify, |
60 | 131 | direction: this._direction
|
61 | 132 | },
|
62 | 133 | attrs: this.computedAttrs
|
63 |
| - }, this.$slots.default) |
| 134 | + }, stackables) |
64 | 135 | }
|
65 | 136 | }
|
66 | 137 |
|
|
0 commit comments