Skip to content

Commit b8d8b2d

Browse files
authored
Merge pull request #512 from VividLemon/main
Merge branch 'main' into dev
2 parents 8c51f8d + c74a15a commit b8d8b2d

File tree

18 files changed

+729
-5
lines changed

18 files changed

+729
-5
lines changed

.github/workflows/docs-github-pages-deploy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ jobs:
4343
uses: JamesIves/[email protected]
4444
with:
4545
branch: gh-pages # The branch the action should deploy to.
46-
folder: ./apps/docs/.vuepress/dist # The folder the action should deploy.
46+
folder: ./apps/docs/docs/.vuepress/dist # The folder the action should deploy.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {defineClientConfig} from '@vuepress/client'
2+
import ReferenceSection from './client/components/reference-section'
3+
import {h} from 'vue'
4+
5+
export default defineClientConfig({
6+
async enhance({app, router, siteData}) {
7+
if (!__VUEPRESS_SSR__) {
8+
// wrap the `<ComponentReference />` component with plugin options
9+
app.component('ComponentReference', (props) => h(ReferenceSection, {}))
10+
}
11+
},
12+
setup() {},
13+
rootComponents: [],
14+
})
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {computed, defineComponent, resolveComponent, h} from 'vue'
2+
// import BLink from '@/components/BLink'
3+
export default defineComponent({
4+
name: 'BVAnchoredHeading',
5+
functional: true,
6+
props: {
7+
id: {
8+
type: String,
9+
default: '',
10+
},
11+
level: {
12+
type: [Number, String],
13+
default: 2,
14+
},
15+
},
16+
setup(props, {slots}) {
17+
const blink = resolveComponent('b-link')
18+
const $anchor = h(
19+
blink,
20+
{
21+
class: 'header-anchor',
22+
to: {hash: `#${props.id}`},
23+
// 'aria-labelledby': this.id || null,
24+
// 'aria-label': this.id ? null : 'Anchor',
25+
},
26+
() => '#'
27+
)
28+
29+
return () =>
30+
h(
31+
`h${props.level}`,
32+
{
33+
id: props.id,
34+
tabindex: '-1',
35+
},
36+
h('span', {class: ['bd-content-title']}, [slots.default(), $anchor])
37+
)
38+
},
39+
})
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
<template>
2+
<b-row row tag="header" align-v="center">
3+
<b-col sm="9">
4+
<anchored-heading level="3">
5+
<code class="notranslate bigger" translate="no">{{ tag }}</code>
6+
</anchored-heading>
7+
</b-col>
8+
<b-col sm="3">
9+
<b-button
10+
v-if="githubURL"
11+
variant="outline-secondary"
12+
size="sm"
13+
:href="githubURL"
14+
target="_blank"
15+
>
16+
View source
17+
</b-button>
18+
</b-col>
19+
</b-row>
20+
<!-- Componet Ref Quick Links -->
21+
<ul class="component-ref-mini-toc my-3">
22+
<li v-if="propsItems && propsItems.length > 0">
23+
<a :href="`#comp-ref-${componentName}-props`">
24+
<code class="notranslate" translate="no">{{ tag }}</code> Properties
25+
</a>
26+
</li>
27+
<li v-if="emits && emits.length > 0">
28+
<a :href="`#comp-ref-${componentName}-emits`">
29+
<code class="notranslate" translate="no">{{ tag }}</code> Emits
30+
</a>
31+
</li>
32+
</ul>
33+
<div v-if="propsItems && propsItems.length > 0" class="bd-content">
34+
<anchored-heading :id="`comp-ref-${componentName}-props`" level="4" class="mb-3">
35+
Properties
36+
</anchored-heading>
37+
<b-table
38+
:items="propsItems"
39+
:fields="propFields"
40+
primary-key="prop"
41+
table-class="bv-docs-table"
42+
responsive="sm"
43+
sort-icon-left
44+
bordered
45+
table-striped
46+
>
47+
<template #cell(prop)="{value}">
48+
<code class="text-nowrap notranslate" translate="no">{{ value }}</code
49+
><br />
50+
</template>
51+
<template #cell(type)="{value}">
52+
<span v-html="value"></span>
53+
</template>
54+
<template #cell(defaultValue)="{value}">
55+
<code v-if="value" class="word-wrap-normal notranslate" translate="no">{{ value }}</code>
56+
</template>
57+
</b-table>
58+
</div>
59+
<div v-if="emits && emits.length > 0" class="bd-content">
60+
<anchored-heading :id="`comp-ref-${componentName}-emits`" level="4" class="mb-3">
61+
Emits
62+
</anchored-heading>
63+
<b-table
64+
:items="emits"
65+
:fields="emitsFields"
66+
primary-key="emit"
67+
table-class="bv-docs-table"
68+
responsive="sm"
69+
bordered
70+
table-striped
71+
>
72+
<template #cell(args)="{value, item}">
73+
<ol v-if="value && value.length > 0" class="list-unstyled mb-0">
74+
<li v-for="(arg, idx) in value" :key="`emit-${item.emit}-${arg.arg || idx}`">
75+
<template v-if="arg.arg">
76+
<code class="notranslate" translate="no">{{ arg.arg }}</code> -
77+
</template>
78+
<span v-if="arg.description">{{ arg.description }}</span>
79+
</li>
80+
</ol>
81+
</template>
82+
</b-table>
83+
</div>
84+
</template>
85+
<script lang="ts">
86+
import {resolveComponent, defineComponent, computed, ComputedRef, ConcreteComponent} from 'vue'
87+
import AnchoredHeading from './anchored-heading'
88+
import {hyphenate} from '../../../utils'
89+
// type definitions
90+
const SORT_THRESHOLD: number = 10
91+
92+
//Regex for matching v-model
93+
94+
const VMODEL_REGEX: RegExp = /(\A\w+):update/
95+
96+
export default defineComponent({
97+
components: {
98+
AnchoredHeading,
99+
},
100+
name: 'BVComponentdoc',
101+
props: {
102+
component: {type: String},
103+
propsMeta: {
104+
// For getting prop descriptions
105+
type: Array,
106+
default: () => [],
107+
},
108+
slots: {
109+
type: Array,
110+
default: () => [],
111+
},
112+
emits: {
113+
type: Array,
114+
default: () => [],
115+
},
116+
rootEventListeners: {
117+
type: Array,
118+
default: () => [],
119+
},
120+
aliases: {
121+
type: Array,
122+
default: () => [],
123+
},
124+
version: {
125+
type: String,
126+
default: null,
127+
},
128+
},
129+
setup(props) {
130+
const component: ConcreteComponent = resolveComponent(
131+
props.component as string
132+
) as ConcreteComponent
133+
134+
const componentPropsMetaObj: ComputedRef<any> = computed(() => {
135+
return props.propsMeta.reduce((obj, propMeta) => {
136+
if (propMeta.prop) {
137+
obj[propMeta.prop] = propMeta
138+
}
139+
return obj
140+
}, {})
141+
})
142+
const githubURL: ComputedRef<string> = computed(() => {
143+
const name = component.name ?? component.__name ?? ''
144+
if (name.indexOf('{') !== -1) {
145+
// Example component (most likely an auto generated component)
146+
return ''
147+
}
148+
const base = 'https://github.com/cdmoro/bootstrap-vue-3/tree/main/src/components'
149+
// const slug = this.$route.params.slug
150+
// Always point to the `.js` file (which may import a `.vue` file)
151+
return `${base}/${name}/${name}.vue`
152+
})
153+
154+
// component name kebab
155+
156+
const componentName: ComputedRef<string> = computed(() => {
157+
return hyphenate(component.name ?? component.__name ?? '')
158+
})
159+
const tag: ComputedRef<string> = computed(() => {
160+
return `<${componentName.value}>`
161+
})
162+
163+
const propsItems: ComputedRef<any> = computed(() => {
164+
const props: any = component.props
165+
const propsMetaObj = componentPropsMetaObj
166+
return Object.keys(props)
167+
.sort()
168+
.map((prop: string) => {
169+
const p = props[prop]
170+
const meta = {
171+
// ...(commonProps[prop] || {}),
172+
...(propsMetaObj.value[prop] || {}),
173+
}
174+
175+
// Describe type
176+
let type = p.type
177+
let types = []
178+
if (Array.isArray(type)) {
179+
types = type.map((type) => type.name)
180+
} else {
181+
types = type && type.name ? [type.name] : ['Any']
182+
}
183+
184+
type = types
185+
.map((type) => `<code class="notranslate" translate="no">${type}</code>`)
186+
.join(' or ')
187+
188+
//default Value
189+
let defaultValue = p.default
190+
if (defaultValue instanceof Function && !Array.isArray(defaultValue)) {
191+
defaultValue = defaultValue()
192+
}
193+
defaultValue =
194+
typeof defaultValue === 'undefined'
195+
? ''
196+
: String(JSON.stringify(defaultValue, undefined, 1)).replace(/"/g, "'")
197+
198+
return {
199+
prop: hyphenate(prop),
200+
type,
201+
defaultValue,
202+
required: p.required || false,
203+
description: meta.description || '',
204+
version: meta.version || '',
205+
xss: meta.xss || false,
206+
// isVModel: this.componentVModel && this.componentVModel.prop === prop,
207+
deprecated: p.deprecated || false,
208+
deprecation: p.deprecation || false,
209+
_showDetails: typeof p.deprecated === 'string' || typeof p.deprecation === 'string',
210+
}
211+
})
212+
})
213+
214+
const propFields: ComputedRef<any> = computed(() => {
215+
const sortable = propsItems.value.length >= SORT_THRESHOLD
216+
217+
// TODO define Type for propItems
218+
const hasDescriptions = propsItems.value.some((p) => {
219+
return p.description
220+
})
221+
222+
return [
223+
{key: 'prop', label: 'Property', sortable},
224+
{key: 'type', label: 'Type', sortable},
225+
{key: 'defaultValue', label: 'Default'},
226+
...(hasDescriptions ? [{key: 'description', label: 'Description'}] : []),
227+
]
228+
})
229+
230+
const emitsFields: ComputedRef<any> = computed(() => {
231+
const sortable = component.emits?.length >= SORT_THRESHOLD
232+
return [
233+
{key: 'emit', label: 'Emit', sortable},
234+
{key: 'args', label: 'Arguments'},
235+
{key: 'description', label: 'Description'},
236+
]
237+
})
238+
239+
const vmodelItems: ComputedRef<any> = computed(() => {
240+
//TODO loop through props and emits to determine v-model
241+
// let match = VMODEL_REGEX.exec(myString);
242+
return []
243+
})
244+
245+
const vmodelFields: ComputedRef<any> = computed(() => {
246+
//TODO loop
247+
return []
248+
})
249+
return {
250+
componentName,
251+
emitsFields,
252+
propsItems,
253+
propFields,
254+
githubURL,
255+
tag,
256+
}
257+
},
258+
})
259+
</script>
260+
261+
})
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import AnchoredHeading from './anchored-heading'
2+
import ComponentDoc from './component-doc.vue'
3+
import {computed, defineComponent, h, ref, toRefs, resolveComponent} from 'vue'
4+
import {usePageData} from '@vuepress/client'
5+
6+
export default defineComponent({
7+
name: 'BDVComponents',
8+
setup(props, {attrs}) {
9+
const pagedata: any = usePageData()
10+
return {
11+
pagedata,
12+
}
13+
},
14+
render() {
15+
return [
16+
h(AnchoredHeading, {id: 'component-reference'}, () => 'Component reference'),
17+
this.pagedata.componentReference.meta.components.map(
18+
({component, emits, rootEventListeners, slots, aliases, props: propsMeta, version}) => {
19+
return h(ComponentDoc, {
20+
component,
21+
emits,
22+
rootEventListeners,
23+
slots,
24+
aliases,
25+
propsMeta,
26+
version,
27+
})
28+
}
29+
),
30+
]
31+
},
32+
})
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Some previous prop item properties to keep on over.
2+
// xss: meta.xss || false,
3+
// isVModel: this.componentVModel && this.componentVModel.prop === prop,
4+
// _showDetails: typeof p.deprecated === 'string' || typeof p.deprecation === 'string'
5+
6+
interface PaginationPropItem {
7+
prop: string
8+
defaultValue: string
9+
required: boolean
10+
description: string
11+
version: string
12+
deprecated: boolean
13+
deprecation: boolean
14+
type: any
15+
}

0 commit comments

Comments
 (0)