Skip to content

Commit

Permalink
feat: integrate vue-docgen-api in preview (#6)
Browse files Browse the repository at this point in the history
* integrate vue-docgen-api in preview

* chore: update deps

* feat: add collapse of left panel

* fix: remove weird margin at bottom of body

* feat: first rendering of docs

* rename docs folder to "docsParts"

* documentation release #1
  • Loading branch information
elevatebart authored Nov 30, 2020
1 parent a4dd96d commit d851b96
Show file tree
Hide file tree
Showing 16 changed files with 717 additions and 168 deletions.
5 changes: 4 additions & 1 deletion packages/example/source/Button.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<template>
<button class="bg-blue-500 py-2 px-4 text-white rounded"><slot /></button>
<button class="bg-blue-500 py-2 px-4 text-white rounded">
<!-- @slot content of the button -->
<slot />
</button>
</template>

<preview name="Primary Button">
Expand Down
100 changes: 100 additions & 0 deletions packages/example/source/Input.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<div>
<input
ref="input"
v-model="val"
@input="updateValue($event.target.value)"
@change="emitChange"
/>
<button @click="fireEvent()">Fire example event!</button>
</div>
</template>

<script>
/**
* An input field with a button
*/
export default {
name: 'Input',
model: {
prop: 'value',
},
props: {
value: {
default: null,
type: [Number, String],
},
/**
* Using for: String.prototype.replace(regexp, replacement)
*/
regExp: {
type: RegExp,
default: null,
},
/**
* Using for: String.prototype.replace(regexp, replacement)
*/
replacement: {
type: String,
default: '',
},
},
data() {
return {
val: '',
};
},
watch: {
// watch value prop
value(val) {
this.updateValue(val);
},
},
mounted() {
this.updateValue(this.value);
},
methods: {
// format the value of input
formatValue(val) {
const formattedValue = !val ? '' : val.toString().replace(this.regExp, this.replacement);
return formattedValue;
},
updateValue(val) {
const formattedValue = this.formatValue(val);
this.val = formattedValue;
this.emitInput(formattedValue);
},
emitInput(val) {
/**
* Input event
* @event input
* @type {number|string}
* @property {number} called - test called
* @property {boolean} isPacked - Indicates whether the snowball is tightly packed.
*/
this.$emit('input', val, 1, false);
},
// emit change event
emitChange() {
/**
* Change event
* @event change
*/
this.$emit('change', this.val);
},
fireEvent() {
/**
* Fire event
* @event fire
* @type {string}
*/
this.$emit('fire', 'hello fire!!');
},
},
};
</script>
45 changes: 45 additions & 0 deletions packages/preview/browser/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,48 @@ html {
.dark {
color: #efefef;
}

/* Documentation Panel */
.docs {
width: 400px;
margin: 5px 10px;
}

.docs h2 {
margin-bottom: 10px;
padding: 5px;
border-bottom: 1px solid #ccc;
}

.docs h3 {
margin-top: 20px;
padding: 0 5px;
}
.docs table {
margin: 10px 5px;
color: #333;
font-size: small;
}

.docs table td,
.docs table th {
border-bottom: 1px solid #cccccc;
padding: 5px 8px;
}

.docs table th {
background-color: #f2f2f2;
color: #000;
}

.docs table li {
padding: 0;
margin: 5px 0;
list-style-type: none;
}

.docs table li strong {
display: inline-block;
font-weight: bold;
width: 70px;
}
41 changes: 33 additions & 8 deletions packages/preview/browser/components/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { inject, computed, ref, watch, markRaw, defineComponent, provide } from
import { COMPONENTS, ZOOM, THEME } from '../config';
import { ComponentModule } from '../types';
import Preview from './Preview.vue';
import Documentation from './Documentation.vue';
const current = ref<string>(localStorage.getItem('@preview:current'));
const currentPreview = ref<Record<string, boolean>>({});
Expand All @@ -12,11 +13,13 @@ const defaultPreviews = [
{ name: 'Desktop', device: 'MacBook Pro 16"' },
];
export default defineComponent({
components: { Preview },
components: { Preview, Documentation },
setup() {
const components = inject(COMPONENTS)!;
const zoom = ref(50);
const theme = ref<string>('light');
const asideOpen = ref(true);
const docsAsideOpen = ref(false);
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
theme.value = 'dark';
Expand All @@ -36,6 +39,7 @@ export default defineComponent({
...preview,
})
),
docgen: component.docgen,
}));
options.sort((a, b) => a.name.localeCompare(b.name));
Expand All @@ -53,11 +57,23 @@ export default defineComponent({
return `id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`;
}
return { options, current, currentPreview, component, zoom, getPreviewId, theme };
return {
options,
current,
currentPreview,
component,
zoom,
getPreviewId,
theme,
asideOpen,
docsAsideOpen,
};
},
});
// @ts-ignore
if (import.meta.hot) {
// @ts-ignore
import.meta.hot.on('@preview', (event) => {
if (event.type === 'pick') {
current.value = event.id;
Expand All @@ -68,12 +84,12 @@ if (import.meta.hot) {

<template>
<div class="dashboard" :class="theme">
<aside class="sidebar">
<aside class="sidebar" v-show="asideOpen">
<div class="controls">
<input type="range" v-model="zoom" min="10" max="200" step="10" list="zoom-levels" />
<button @click="zoom = 50">50%</button>
<button @click="zoom = 100">100%</button>
</div>
</div>

<section>
<header class="header">Components</header>
Expand Down Expand Up @@ -105,7 +121,7 @@ if (import.meta.hot) {
</ul>
</section>

<div style="flex: 1;"></div>
<div style="flex: 1"></div>
<label>
<input
type="checkbox"
Expand All @@ -115,6 +131,9 @@ if (import.meta.hot) {
Dark Mode
</label>
</aside>
<button @click.prevent="asideOpen = !asideOpen">
{{ asideOpen ? '&lt;' : '&gt;' }}
</button>
<main class="previews">
<template v-if="component">
<template v-for="preview of component.previews">
Expand All @@ -129,10 +148,16 @@ if (import.meta.hot) {
</template>
</template>

<div v-else class="empty-state">
Select a component!
</div>
<div v-else class="empty-state">Select a component!</div>
</main>
<button @click.prevent="docsAsideOpen = !docsAsideOpen">
{{ docsAsideOpen ? '&gt;' : '&lt;' }}
</button>
<Suspense :key="component?.id || 0">
<template #default>
<Documentation v-show="docsAsideOpen" v-if="component" :docsSupplier="component.docgen" />
</template>
</Suspense>
</div>
</template>

Expand Down
30 changes: 30 additions & 0 deletions packages/preview/browser/components/Documentation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<div class="docs">
<h2>{{ docValue.displayName }}</h2>
<p>{{ docValue.description }}</p>
<Props v-if="docValue.props" :props="docValue.props" />
<Events v-if="docValue.events" :events="docValue.events" />
<Slots v-if="docValue.slots" :slots="docValue.slots" />
</div>
</template>

<script>
import { ref } from 'vue';
import Slots from './docsParts/Slots.vue';
import Events from './docsParts/Events.vue';
import Props from './docsParts/Props.vue';
export default {
components: { Props, Events, Slots },
props: {
docsSupplier: {
type: Function,
required: true,
},
},
async setup({ docsSupplier }) {
const mod = await docsSupplier();
return { docValue: mod.default };
},
};
</script>
Loading

0 comments on commit d851b96

Please sign in to comment.