Skip to content

Commit fd615e4

Browse files
authored
Update config.js
1 parent 096eb60 commit fd615e4

File tree

1 file changed

+103
-14
lines changed

1 file changed

+103
-14
lines changed

src/utils/config.js

Lines changed: 103 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,71 @@
11
//
2-
// General Bootstrap Vue config parameters
2+
// General Bootstrap Vue configuration
33
//
44
// TODO:
5-
// - Make this cofigurable before bootstrap Vue is loaded, eitther by
5+
//
6+
// - Make this cofigurable before bootstrap Vue is loaded, either by
67
// passing an expression to Vue.use(BootstrapVue, config = {}) or
7-
// via global window.BoostrapVue.config (or similar)
8-
// - Add default variants for each component (that may have a default
9-
// variant, such as button, etc)
8+
// via global window.BoostrapVue.config, or Vue.prototype.XXX (or similar)
9+
//
1010
// - Pull this default config into the documentation (/docs/reference/settings)
1111
// and document how to configure the settings
1212
//
1313
import get from './get'
14+
import { keys, isObject } from './object'
15+
import { isArray } from './array'
16+
17+
// DISCUSSION: Breakpoint definitions
18+
//
19+
// Should breakpoints be stored here, or maybe on the Vue prototype?
20+
//
21+
// i.e. Vue.prototype.$BV_BREAKPOINTS
22+
//
23+
// Some components (BCol and BFormGroup) generate props based on breakpoints, and this
24+
// occurs when the component is first loaded (evaluated), which may happen before the
25+
// config is created/modified
26+
//
27+
// To get around this would be to make the components that need to generate
28+
// prop names based on the config would be to define the component(s) as such:
29+
//
30+
// // we use a named function so that component.name resolves to the components name
31+
// // and that minification doesn't mangle the name
32+
// const BFormGroup = function BFormGroup(resolve, reject) => {
33+
// // prop computation could happen before the resolve
34+
// // or within the component using object spread on a function()
35+
// resolve( /* @vue/component */ {
36+
// // component definition
37+
// })
38+
// }
39+
// export default BFormGroup
40+
//
41+
// Now the component definition is only called/executed when the first access to the
42+
// component is used (and cached on subsequent uses)
43+
//
44+
// See: https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components
45+
//
46+
// This might be the better solution to the problem, although if other components need to
47+
// pluck props from this component, they wont be able to.
48+
// We are safe with BCol and BFormGroup as nothing else users their props
49+
//
1450

15-
const BV_DEFAULTS = {
16-
breakpoints: ['xs', 'sm', 'md', 'lg', 'xl'],
51+
const BREAKPOINTS_DEFAULT = ['xs', 'sm', 'md', 'lg', 'xl']
52+
53+
// DISCUSSION: Prop Defaults
54+
//
55+
// For default values on props, we use the default value factory function approach so
56+
// so that the default values are pulled in at **runtime**
57+
//
58+
// props: {
59+
// variant: {
60+
// type: String,
61+
// default: () => getConfigComponent('BAlert', 'variant')
62+
// }
63+
// }
64+
//
65+
66+
const DEFAULTS = {
67+
// Breakpoints... see discussion above
68+
breakpoints: BREAKPOINTS_DEFAULT,
1769
// Component Specific defaults are keyed by the component
1870
// name (PascalCase) and prop name (camelCase)
1971
BAlert: { variant: 'info' },
@@ -37,19 +89,56 @@ const BV_DEFAULTS = {
3789
}
3890
}
3991

40-
// This will be the object that any future user defined
41-
// configuration will be placed in the future
42-
const config = {}
92+
// This contains user defined configuration
93+
//
94+
// Should this be stored here, or on the Vue.prototype ?????
95+
// For testing purposes, we might want to store this on Vue, so
96+
// we can use localVue so that testing doesn't pollute the config.
97+
// (unless we create a clearConfig() method to reset it)
98+
const CONFIG = {}
4399

44100
// Method to get a deep clone (immutable) copy of the defaults
45-
const getDefaults = () => JSON.parse(JSON.stringify(BV_DEFAULTS))
101+
const getDefaults = () => JSON.parse(JSON.stringify(DEFAULTS))
102+
103+
// Method to set the config.
104+
// Merges in only known top-level and sub-level keys.
105+
//
106+
// Vue.use(BootstrapVue, config)
107+
// or
108+
// BootstrapVue.config(config)
109+
// Vue.use(BootstrapVue)
110+
//
111+
// Breakpoint definition may need to be moved out of the config object
112+
// and set globally before bootstrapVue is loaded
113+
114+
/* istanbul ignore next: just for now to prevent red X on codecov until we can test this */
115+
const setConfig = (opts = {}) => {
116+
if (isObject(opts)) {
117+
keys(opts).forEach(component => {
118+
if (opts.hasOwnProperty(component) && DEFAULTS.hasOwnProperty(component)) {
119+
if (component === 'breakpoints' && isArray(opts.breakpoints)) {
120+
// special case for breakpoints
121+
CONFIG.breakpoints = JSON.parse(JSON.stringify(opts.breakpoints))
122+
} else if (isObject(opts[component])) {
123+
keys(opts[component]).forEach(prop => {
124+
if (opts[component].hasOwnProperty(prop) && DEFAULTS[component].hasOwnProperty(prop)) {
125+
// If we pre-populate the config with the defaults, we can skip this line
126+
CONFIG[component] = CONFIG[component] || {}
127+
CONFIG[component][prop] = opts[component][prop]
128+
}
129+
})
130+
}
131+
}
132+
})
133+
}
134+
}
46135

47136
// Method to grab a config value based on a dotted/array notation key.
48137
// Returns a deep clone (immutable) copy
49138
const getConfigParam = key => {
50-
// First we try the user config, and if key not found we
51-
// fall back to default value.
52-
return JSON.parse(JSON.stringify(get(config, key, get(getDefaults(), key))))
139+
// First we try the user config, and if key not found we fall back to default value.
140+
// NOTE: If we deep clone DEFAULTS into config, then we can skip the fallback for get
141+
return JSON.parse(JSON.stringify(get(CONFIG, key, get(getDefaults(), key))))
53142
}
54143

55144
// Method to grab a config value for a particular component.

0 commit comments

Comments
 (0)