1
-
import Vue from '../../utils/vue'
2
1
import { mergeData } from 'vue-functional-data-merge'
2
+
import identity from '../../utils/identity'
3
+
import memoize from '../../utils/memoize'
4
+
import suffixPropName from '../../utils/suffix-prop-name'
3
5
import { arrayIncludes } from '../../utils/array'
6
+
import { getBreakpointsUpCached } from '../../utils/config'
7
+
import { create, keys } from '../../utils/object'
8
+
import { lowerCase, toString, trim } from '../../utils/string'
4
9
5
10
const COMMON_ALIGNMENT = ['start', 'end', 'center']
6
11
7
-
export const props = {
8
-
tag: {
9
-
type: String,
10
-
default: 'div'
11
-
},
12
-
noGutters: {
13
-
type: Boolean,
14
-
default: false
15
-
},
16
-
alignV: {
17
-
type: String,
18
-
default: null,
19
-
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['baseline', 'stretch']), str)
20
-
},
21
-
alignH: {
22
-
type: String,
23
-
default: null,
24
-
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around']), str)
25
-
},
26
-
alignContent: {
27
-
type: String,
28
-
default: null,
29
-
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around', 'stretch']), str)
12
+
// Generates a prop object with a type of `[String, Number]`
13
+
const strNum = () => ({
14
+
type: [String, Number],
15
+
default: null
16
+
})
17
+
18
+
// Compute a `row-cols-{breakpoint}-{cols}` class name
19
+
// Memoized function for better performance on generating class names
20
+
const computeRowColsClass = memoize((breakpoint, cols) => {
21
+
cols = trim(toString(cols))
22
+
return cols ? lowerCase(['row-cols', breakpoint, cols].filter(identity).join('-')) : null
23
+
})
24
+
25
+
// Get the breakpoint name from the `rowCols` prop name
26
+
// Memoized function for better performance on extracting breakpoint names
27
+
const computeRowColsBreakpoint = memoize(prop => lowerCase(prop.replace('cols', '')))
28
+
29
+
// Cached copy of the `row-cols` breakpoint prop names
30
+
// Will be populated when the props are generated
31
+
let rowColsPropList = []
32
+
33
+
// Lazy evaled props factory for <b-row> (called only once,
34
+
// the first time the component is used)
35
+
const generateProps = () => {
36
+
// Grab the breakpoints from the cached config (including the '' (xs) breakpoint)
37
+
const breakpoints = getBreakpointsUpCached()
38
+
39
+
// Supports classes like: `row-cols-2`, `row-cols-md-4`, `row-cols-xl-6`
40
+
const rowColsProps = breakpoints.reduce((props, breakpoint) => {
41
+
props[suffixPropName(breakpoint, 'cols')] = strNum()
42
+
return props
43
+
}, create(null))
44
+
45
+
// Cache the row-cols prop names
46
+
rowColsPropList = keys(rowColsProps)
47
+
48
+
// Return the generated props
49
+
return {
50
+
tag: {
51
+
type: String,
52
+
default: 'div'
53
+
},
54
+
noGutters: {
55
+
type: Boolean,
56
+
default: false
57
+
},
58
+
alignV: {
59
+
type: String,
60
+
default: null,
61
+
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['baseline', 'stretch']), str)
62
+
},
63
+
alignH: {
64
+
type: String,
65
+
default: null,
66
+
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around']), str)
67
+
},
68
+
alignContent: {
69
+
type: String,
70
+
default: null,
71
+
validator: str =>
72
+
arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around', 'stretch']), str)
73
+
},
74
+
...rowColsProps
30
75
}
31
76
}
32
77
78
+
// We do not use `Vue.extend()` here as that would evaluate the props
79
+
// immediately, which we do not want to happen
33
80
// @vue/component
34
-
export const BRow = /*#__PURE__*/ Vue.extend({
81
+
export const BRow = {
35
82
name: 'BRow',
36
83
functional: true,
37
-
props,
84
+
get props() {
85
+
// Allow props to be lazy evaled on first access and
86
+
// then they become a non-getter afterwards
87
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#Smart_self-overwriting_lazy_getters
88
+
delete this.props
89
+
this.props = generateProps()
90
+
return this.props
91
+
},
38
92
render(h, { props, data, children }) {
39
-
return h(
40
-
props.tag,
41
-
mergeData(data, {
42
-
staticClass: 'row',
43
-
class: {
44
-
'no-gutters': props.noGutters,
45
-
[`align-items-${props.alignV}`]: props.alignV,
46
-
[`justify-content-${props.alignH}`]: props.alignH,
47
-
[`align-content-${props.alignContent}`]: props.alignContent
48
-
}
49
-
}),
50
-
children
51
-
)
93
+
const classList = []
94
+
// Loop through row-cols breakpoint props and generate the classes
95
+
rowColsPropList.forEach(prop => {
96
+
const c = computeRowColsClass(computeRowColsBreakpoint(prop), props[prop])
97
+
// If a class is returned, push it onto the array
98
+
if (c) {
99
+
classList.push(c)
100
+
}
101
+
})
102
+
classList.push({
103
+
'no-gutters': props.noGutters,
104
+
[`align-items-${props.alignV}`]: props.alignV,
105
+
[`justify-content-${props.alignH}`]: props.alignH,
106
+
[`align-content-${props.alignContent}`]: props.alignContent
107
+
})
108
+
return h(props.tag, mergeData(data, { staticClass: 'row', class: classList }), children)
52
109
}
53
-
})
110
+
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4