Skip to content

Commit 8018bdf

Browse files
authored
feat(core): create configurable base global configuration (#2905)
1 parent 67d12a4 commit 8018bdf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1615
-739
lines changed

docs/components/anchored-heading.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export default {
2+
props: {
3+
level: {
4+
type: [Number, String],
5+
default: 2
6+
},
7+
id: {
8+
type: String,
9+
default: ''
10+
}
11+
},
12+
render(h) {
13+
const $anchor = h(
14+
'b-link',
15+
{
16+
staticClass: 'anchorjs-link',
17+
attrs: { to: { hash: `#${this.id}` }, 'aria-label': 'Anchor' }
18+
},
19+
[h(false)]
20+
)
21+
const $content = h('span', { staticClass: 'bd-content-title' }, [this.$slots.default, $anchor])
22+
return h(`h${this.level}`, { attrs: { id: this.id, tabindex: '-1' } }, [$content])
23+
}
24+
}

docs/components/componentdoc.vue

+116-49
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
>
66
<b-row tag="header" align-v="center">
77
<b-col sm="9">
8-
<h2 :id="`comp-ref-${componentName}`"><code>{{ tag }}</code></h2>
8+
<anchored-heading :id="`comp-ref-${componentName}`" level="2">
9+
<code>{{ tag }}</code>
10+
</anchored-heading>
911
</b-col>
1012
<b-col sm="3" class="text-sm-right">
1113
<b-btn variant="outline-secondary" size="sm" :href="githubURL" target="_blank">
@@ -15,30 +17,66 @@
1517
</b-row>
1618

1719
<article v-if="aliases && aliases.length > 0">
18-
<h4 :id="`comp-ref-${componentName}-aliases`">Component aliases</h4>
20+
<anchored-heading :id="`comp-ref-${componentName}-aliases`" level="4">
21+
Component aliases
22+
</anchored-heading>
1923
<p><code>{{ tag }}</code> can also be used via the following aliases:</p>
2024
<ul>
2125
<li v-for="alias in aliases" :key="alias"><code>&lt;{{ kebabCase(alias) }}&gt;</code></li>
2226
</ul>
2327
</article>
2428

2529
<article v-if="propsItems && propsItems.length > 0">
26-
<h4 :id="`comp-ref-${componentName}-props`">Properties</h4>
30+
<anchored-heading :id="`comp-ref-${componentName}-props`" level="4">
31+
Properties
32+
</anchored-heading>
2733
<b-table
2834
:items="propsItems"
2935
:fields="propsFields"
3036
small
3137
head-variant="default"
3238
striped
3339
>
34-
<template slot="default" slot-scope="field">
35-
<code v-if="field.value">{{ field.value }}</code>
40+
<template slot="prop" slot-scope="{ value }">
41+
<code>{{ value }}</code>
42+
</template>
43+
<template slot="row-details" slot-scope="{ item }">
44+
<b-badge variant="warning">
45+
{{ typeof item.deprecated === 'string' ? 'deprecation' : 'deprecated' }}
46+
</b-badge>
47+
<!-- if deprecated is a string, show the string value -->
48+
<small v-if="typeof item.deprecated === 'string'">{{ item.deprecated }}</small>
49+
</template>
50+
<template slot="defaultValue" slot-scope="{ value }">
51+
<code v-if="value">{{ value }}</code>
3652
</template>
3753
</b-table>
54+
55+
<template v-if="componentVModel">
56+
<anchored-heading :id="`comp-ref-${componentName}-v-model`" level="4">
57+
V-Model
58+
</anchored-heading>
59+
<b-table
60+
:items="[componentVModel]"
61+
:fields="['prop', 'event']"
62+
small
63+
head-variant="default"
64+
striped
65+
>
66+
<template slot="prop" slot-scope="{ value }">
67+
<code>{{ kebabCase(value) }}</code>
68+
</template>
69+
<template slot="event" slot-scope="{ value }">
70+
<code>{{ value }}</code>
71+
</template>
72+
</b-table>
73+
</template>
3874
</article>
3975

4076
<article v-if="slots && slots.length > 0">
41-
<h4 :id="`comp-ref-${componentName}-slots`">Slots</h4>
77+
<anchored-heading :id="`comp-ref-${componentName}-slots`" level="4">
78+
Slots
79+
</anchored-heading>
4280
<b-table
4381
:items="slots"
4482
:fields="slotsFields"
@@ -49,28 +87,32 @@
4987
</article>
5088

5189
<article v-if="events && events.length > 0">
52-
<h4 :id="`comp-ref-${componentName}-events`">Events</h4>
90+
<anchored-heading :id="`comp-ref-${componentName}-events`" level="4">
91+
Events
92+
</anchored-heading>
5393
<b-table
5494
:items="events"
5595
:fields="eventsFields"
5696
small
5797
head-variant="default"
5898
striped
5999
>
60-
<template slot="args" slot-scope="field">
100+
<template slot="args" slot-scope="{ value, item }">
61101
<div
62-
v-for="arg in field.value"
63-
:key="`event-${field.item.event}-${arg.arg ? arg.arg : 'none'}`"
102+
v-for="arg in value"
103+
:key="`event-${item.event}-${arg.arg ? arg.arg : 'none'}`"
64104
>
65105
<template v-if="arg.arg"><code>{{ arg.arg }}</code> - </template>
66-
<span v-html="arg.description" />
106+
<span v-html="arg.description"></span>
67107
</div>
68108
</template>
69109
</b-table>
70110
</article>
71111

72112
<article v-if="rootEventListeners && rootEventListeners.length > 0">
73-
<h4 :id="`comp-ref-${componentName}-rootEventListeners`">$root Event Listeners</h4>
113+
<anchored-heading :id="`comp-ref-${componentName}-rootEventListeners`" level="4">
114+
$root Event Listeners
115+
</anchored-heading>
74116
<p>You can control <code>{{ tag }}</code> by emitting the following events on <samp>$root</samp>:</p>
75117
<b-table
76118
:items="rootEventListeners"
@@ -79,13 +121,13 @@
79121
head-variant="default"
80122
striped
81123
>
82-
<template slot="args" slot-scope="field">
124+
<template slot="args" slot-scope="{ value, item }">
83125
<div
84-
v-for="arg in field.value"
85-
:key="`event-${field.item.event}-${arg.arg ? arg.arg : 'none'}`"
126+
v-for="arg in value"
127+
:key="`event-${item.event}-${arg.arg ? arg.arg : 'none'}`"
86128
>
87129
<template v-if="arg.arg"><code>{{ arg.arg }}</code> - </template>
88-
<span v-html="arg.description" />
130+
<span v-html="arg.description"></span>
89131
</div>
90132
</template>
91133
</b-table>
@@ -106,8 +148,12 @@ h5 {
106148
<script>
107149
import Vue from 'vue'
108150
import kebabCase from 'lodash/kebabCase'
151+
import AnchoredHeading from './anchored-heading'
109152
110153
export default {
154+
components: {
155+
AnchoredHeading
156+
},
111157
props: {
112158
component: {},
113159
slots: {
@@ -130,56 +176,73 @@ export default {
130176
computed: {
131177
componentOptions() {
132178
const component = Vue.options.components[this.component]
133-
return component && component.options ? component.options : {}
134-
},
135-
propsFields() {
136-
const component = Vue.options.components[this.component]
137-
let props = []
138-
if (component) {
139-
props = component.options.props
179+
if (!component) {
180+
return {}
140181
}
141-
const hasRequired = props.length > 0 && props.filter(p => p.required).length > 0
142182
143-
const fields = {
144-
prop: { label: 'Property' },
145-
type: { label: 'Type' },
146-
default: { label: 'Default Value' }
183+
let options = {}
184+
if (!component.options && typeof component === 'function') {
185+
// Async component that hans't been resolved yet
186+
component(opts => {
187+
options = opts ? { ...opts } : {}
188+
})
189+
} else {
190+
// Regular component
191+
options = component.options || {}
192+
}
193+
194+
return options
195+
},
196+
componentVModel() {
197+
const model = this.componentOptions.model
198+
if (model && model.prop && model.event) {
199+
return model
200+
} else {
201+
return false
147202
}
203+
},
204+
componentProps() {
205+
return this.componentOptions.props || {}
206+
},
207+
propsFields() {
208+
const props = this.componentProps
209+
210+
const hasRequired = Object.keys(props).some(p => props[p].required)
211+
212+
const fields = [
213+
{ key: 'prop', label: 'Property' },
214+
{ key: 'type', label: 'Type' },
215+
{ key: 'defaultValue', label: 'Default Value' }
216+
]
148217
149218
// Add the required column if there are required field(s)
150219
if (hasRequired) {
151-
fields.required = { label: 'Required' }
220+
// Insert required field after prop name
221+
fields.splice(1, 0, { key: 'required', label: 'Required' })
152222
}
153223
154224
return fields
155225
},
156226
eventsFields() {
157-
return {
158-
event: { label: 'Event' },
159-
args: { label: 'Arguments' },
160-
description: { label: 'Description' }
161-
}
227+
return [
228+
{ key: 'event', label: 'Event' },
229+
{ key: 'args', label: 'Arguments' },
230+
{ key: 'description', label: 'Description' }
231+
]
162232
},
163233
rootEventListenersFields() {
164-
return {
165-
event: { label: 'Event' },
166-
args: { label: 'Arguments' },
167-
description: { label: 'Description' }
168-
}
234+
return [
235+
{ key: 'event', label: 'Event' },
236+
{ key: 'args', label: 'Arguments' },
237+
{ key: 'description', label: 'Description' }
238+
]
169239
},
170240
slotsFields() {
171-
return {
172-
name: { label: 'Slot' },
173-
description: { label: 'Description' }
174-
}
241+
return [{ key: 'name', label: 'Slot' }, { key: 'description', label: 'Description' }]
175242
},
176243
propsItems() {
177-
const component = Vue.options.components[this.component]
178-
if (!component) {
179-
return {}
180-
}
244+
const props = this.componentProps
181245
182-
const props = component.options.props
183246
return Object.keys(props).map(prop => {
184247
const p = props[prop]
185248
@@ -213,13 +276,17 @@ export default {
213276
214277
// Requied prop?
215278
const required = p.required ? 'Yes' : ''
279+
// Deprecation?
280+
const deprecated = p.deprecated || false
216281
217282
return {
218283
prop: kebabCase(prop),
219284
type,
220285
required,
221286
typeClass,
222-
default: defaultVal
287+
defaultValue: defaultVal,
288+
deprecated,
289+
_showDetails: !!deprecated
223290
}
224291
})
225292
},

0 commit comments

Comments
 (0)