-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(b-row): add Bootstrap v4.4 row columns support (#4439)
* feat(b-row): add Bootstrap v4.4 row columns support * Update row.js * Update row.js * Update row.js * Update row.spec.js * Update row.spec.js * Update row.js * Update README.md * Update package.json * Update package.json * Update col.js * Update col.js * Update package.json * Minor tweaks * Update row.js * Update package.json * minor adjustments to row columns excamples
- Loading branch information
1 parent
ee1c10e
commit 833b028
Showing
5 changed files
with
263 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,110 @@ | ||
import Vue from '../../utils/vue' | ||
import { mergeData } from 'vue-functional-data-merge' | ||
import identity from '../../utils/identity' | ||
import memoize from '../../utils/memoize' | ||
import suffixPropName from '../../utils/suffix-prop-name' | ||
import { arrayIncludes } from '../../utils/array' | ||
import { getBreakpointsUpCached } from '../../utils/config' | ||
import { create, keys } from '../../utils/object' | ||
import { lowerCase, toString, trim } from '../../utils/string' | ||
|
||
const COMMON_ALIGNMENT = ['start', 'end', 'center'] | ||
|
||
export const props = { | ||
tag: { | ||
type: String, | ||
default: 'div' | ||
}, | ||
noGutters: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
alignV: { | ||
type: String, | ||
default: null, | ||
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['baseline', 'stretch']), str) | ||
}, | ||
alignH: { | ||
type: String, | ||
default: null, | ||
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around']), str) | ||
}, | ||
alignContent: { | ||
type: String, | ||
default: null, | ||
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around', 'stretch']), str) | ||
// Generates a prop object with a type of `[String, Number]` | ||
const strNum = () => ({ | ||
type: [String, Number], | ||
default: null | ||
}) | ||
|
||
// Compute a `row-cols-{breakpoint}-{cols}` class name | ||
// Memoized function for better performance on generating class names | ||
const computeRowColsClass = memoize((breakpoint, cols) => { | ||
cols = trim(toString(cols)) | ||
return cols ? lowerCase(['row-cols', breakpoint, cols].filter(identity).join('-')) : null | ||
}) | ||
|
||
// Get the breakpoint name from the `rowCols` prop name | ||
// Memoized function for better performance on extracting breakpoint names | ||
const computeRowColsBreakpoint = memoize(prop => lowerCase(prop.replace('cols', ''))) | ||
|
||
// Cached copy of the `row-cols` breakpoint prop names | ||
// Will be populated when the props are generated | ||
let rowColsPropList = [] | ||
|
||
// Lazy evaled props factory for <b-row> (called only once, | ||
// the first time the component is used) | ||
const generateProps = () => { | ||
// Grab the breakpoints from the cached config (including the '' (xs) breakpoint) | ||
const breakpoints = getBreakpointsUpCached() | ||
|
||
// Supports classes like: `row-cols-2`, `row-cols-md-4`, `row-cols-xl-6` | ||
const rowColsProps = breakpoints.reduce((props, breakpoint) => { | ||
props[suffixPropName(breakpoint, 'cols')] = strNum() | ||
return props | ||
}, create(null)) | ||
|
||
// Cache the row-cols prop names | ||
rowColsPropList = keys(rowColsProps) | ||
|
||
// Return the generated props | ||
return { | ||
tag: { | ||
type: String, | ||
default: 'div' | ||
}, | ||
noGutters: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
alignV: { | ||
type: String, | ||
default: null, | ||
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['baseline', 'stretch']), str) | ||
}, | ||
alignH: { | ||
type: String, | ||
default: null, | ||
validator: str => arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around']), str) | ||
}, | ||
alignContent: { | ||
type: String, | ||
default: null, | ||
validator: str => | ||
arrayIncludes(COMMON_ALIGNMENT.concat(['between', 'around', 'stretch']), str) | ||
}, | ||
...rowColsProps | ||
} | ||
} | ||
|
||
// We do not use `Vue.extend()` here as that would evaluate the props | ||
// immediately, which we do not want to happen | ||
// @vue/component | ||
export const BRow = /*#__PURE__*/ Vue.extend({ | ||
export const BRow = { | ||
name: 'BRow', | ||
functional: true, | ||
props, | ||
get props() { | ||
// Allow props to be lazy evaled on first access and | ||
// then they become a non-getter afterwards | ||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#Smart_self-overwriting_lazy_getters | ||
delete this.props | ||
this.props = generateProps() | ||
return this.props | ||
}, | ||
render(h, { props, data, children }) { | ||
return h( | ||
props.tag, | ||
mergeData(data, { | ||
staticClass: 'row', | ||
class: { | ||
'no-gutters': props.noGutters, | ||
[`align-items-${props.alignV}`]: props.alignV, | ||
[`justify-content-${props.alignH}`]: props.alignH, | ||
[`align-content-${props.alignContent}`]: props.alignContent | ||
} | ||
}), | ||
children | ||
) | ||
const classList = [] | ||
// Loop through row-cols breakpoint props and generate the classes | ||
rowColsPropList.forEach(prop => { | ||
const c = computeRowColsClass(computeRowColsBreakpoint(prop), props[prop]) | ||
// If a class is returned, push it onto the array | ||
if (c) { | ||
classList.push(c) | ||
} | ||
}) | ||
classList.push({ | ||
'no-gutters': props.noGutters, | ||
[`align-items-${props.alignV}`]: props.alignV, | ||
[`justify-content-${props.alignH}`]: props.alignH, | ||
[`align-content-${props.alignContent}`]: props.alignContent | ||
}) | ||
return h(props.tag, mergeData(data, { staticClass: 'row', class: classList }), children) | ||
} | ||
}) | ||
} |
Oops, something went wrong.