-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
move to vuepress #94
Comments
{
"height": 100,
"description": "<p></p>",
"source": "…"
} |
<template>
<div class="component">
<!-- tools -->
<div class="component__tools">
<!-- code button -->
<button v-on:click="toggleCodeView" class="component__tools__button" v-bind:class="{ 'active': showsource }" v-if="jsonLoaded && source">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path d="M0.7 9.3l4.8-4.8 1.4 1.42-4.060 4.080 4.070 4.070-1.41 1.42-5.5-5.49 0.7-0.7zM19.3 10.7l0.7-0.7-5.49-5.49-1.4 1.42 4.050 4.070-4.070 4.070 1.41 1.42 4.78-4.78z"></path>
</svg>
<span>code</span>
</button>
<!-- link button -->
<a :href="htmlFile" target="_blank" class="component__tools__button">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path d="M9.26 13c-0.167-0.286-0.266-0.63-0.266-0.996 0-0.374 0.103-0.724 0.281-1.023l-0.005 0.009c1.549-0.13 2.757-1.419 2.757-2.99 0-1.657-1.343-3-3-3-0.009 0-0.019 0-0.028 0l0.001-0h-4c-1.657 0-3 1.343-3 3s1.343 3 3 3v0h0.080c-0.053 0.301-0.083 0.647-0.083 1s0.030 0.699 0.088 1.036l-0.005-0.036h-0.080c-2.761 0-5-2.239-5-5s2.239-5 5-5v0h4c0.039-0.001 0.084-0.002 0.13-0.002 2.762 0 5.002 2.239 5.002 5.002 0 2.717-2.166 4.927-4.865 5l-0.007 0zM10.74 7c0.167 0.286 0.266 0.63 0.266 0.996 0 0.374-0.103 0.724-0.281 1.023l0.005-0.009c-1.549 0.13-2.757 1.419-2.757 2.99 0 1.657 1.343 3 3 3 0.009 0 0.019-0 0.028-0l-0.001 0h4c1.657 0 3-1.343 3-3s-1.343-3-3-3v0h-0.080c0.053-0.301 0.083-0.647 0.083-1s-0.030-0.699-0.088-1.036l0.005 0.036h0.080c2.761 0 5 2.239 5 5s-2.239 5-5 5v0h-4c-0.039 0.001-0.084 0.002-0.13 0.002-2.762 0-5.002-2.239-5.002-5.002 0-2.717 2.166-4.927 4.865-5l0.007-0z"></path>
</svg>
<span>{{ htmlFile }}</span>
</a>
</div>
<!-- code view -->
<div class="component__code" v-if="showsource && jsonLoaded && source">
<pre class="language-html"><code v-html="prettifyHTML(source)"></code></pre>
</div>
<!-- component iframe -->
<div class="component__preview" v-show="!showsource">
<!-- resizer -->
<span class="component__preview__handle">
<span class="component__preview__handle__overlay"></span>
<svg class="component__preview__handle__icon" width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M10 12c-1.105 0-2-0.895-2-2s0.895-2 2-2v0c1.105 0 2 0.895 2 2s-0.895 2-2 2v0zM10 6c-1.105 0-2-0.895-2-2s0.895-2 2-2v0c1.105 0 2 0.895 2 2s-0.895 2-2 2v0zM10 18c-1.105 0-2-0.895-2-2s0.895-2 2-2v0c1.105 0 2 0.895 2 2s-0.895 2-2 2v0z"></path>
</svg>
</span>
<!-- height spacer -->
<div ref="iframe_spacer" v-if="!htmlLoaded" v-bind:style="{ height: height + 'px' }"></div>
<!-- component iframe -->
<iframe class="component__preview__iframe" ref="iframe" v-if="inview" :src="htmlFile" frameborder="0" scrolling="no" v-on:load="onIframeLoad"></iframe>
</div>
</div>
</template>
<script>
export default {
props: ["name"],
data() {
return {
htmlLoaded: false,
jsonLoaded: false,
height: 0,
source: null,
showsource: false,
inview: false,
htmlFile: this.getHTMLFilePath(this.$props.name),
jsonFile: this.getJSONFilePath(this.$props.name),
};
},
mounted() {
/**
* set in view observer for async loading iframe
*/
var observer = new IntersectionObserver(
function(entries, observer) {
entries.forEach(
function(entry) {
if (entry.isIntersecting) {
if (!this.inview) {
this.inview = true;
}
}
}.bind(this)
);
}.bind(this)
);
observer.observe(this.$el);
/**
* get meta info from lib/file.json
*/
fetch(this.jsonFile).then((res) => {
if (res.status === 200) {
return res.json();
}
}).then((obj) => {
this.jsonLoaded = true;
if (obj) {
this.height = obj.height;
this.source = obj.source;
}
}).catch((err) => {});
},
methods: {
/**
* get html file path
*/
getHTMLFilePath: function(str) {
return "/lib/" + this.slugify(str) + ".html";
},
/**
* get json file path
*/
getJSONFilePath: function(str) {
return "/lib/" + this.slugify(str) + ".json";
},
/**
* beautify and highlight html
*/
prettifyHTML: function(str) {
return window.Prism.highlight(window.html_beautify(str), window.Prism.languages.markup)
},
/**
* create slug-from-string
*/
slugify: function(str) {
return str
.toString()
.toLowerCase()
.replace(/\s+/g, "-") // Replace spaces with -
.replace(/[^\w-]+/g, "") // Remove all non-word chars
.replace(/--+/g, "-") // Replace multiple - with single -
.replace(/^-+/, "") // Trim - from start of text
.replace(/-+$/, ""); // Trim - from end of text
},
/**
* toggle code/preview view
*/
toggleCodeView: function (e) {
this.showsource = !this.showsource;
if (!this.showsource) {
window.iFrameResize({ checkOrigin: false }, this.$refs.iframe);
}
},
/**
* iframe loaded handler
*/
onIframeLoad: function(e) {
// resize iframe
window.iFrameResize({ checkOrigin: false }, this.$refs.iframe);
// make preview draggable
window.interact(this.$el.querySelector(".component__preview")).resizable({
edges: {
left: false,
right: ".component__preview__handle",
bottom: false,
top: false
},
onmove: function(e) {
e.target.style.width = e.rect.width - 24 + "px";
e.target.querySelector('iframe').contentWindow.parentIFrame.size();
if (!e.target.classList.contains("component-is-resizing")) {
e.target.classList.add("component-is-resizing");
}
},
onend: function(e) {
e.target.querySelector("iframe").contentWindow.parentIFrame.size();
if (e.target.classList.contains("component-is-resizing")) {
e.target.classList.remove("component-is-resizing");
}
}
});
// set loaded state
this.htmlLoaded = true;
}
}
};
</script>
<style scoped>
iframe {
width: 100%;
}
.component {
--grey: #eaecef;
--darkgrey: #111;
margin-top: 20px;
margin-bottom: 150px;
}
/**
* Tools
*/
.component__tools {
display: flex;
}
.component__tools__button {
border: 1px solid var(--grey);
border-radius: 3px;
padding: 6px 8px;
margin-left: 5px;
display: inline-flex;
outline: 0;
text-decoration: none !important;
cursor: pointer;
}
.component__tools__button:hover,
.component__tools__button.active {
background-color: var(--grey);
}
.component__tools__button svg {
margin: auto;
}
.component__tools__button span {
font-size: 12px;
font-weight: normal;
color: var(--darkgrey);
margin: auto 0 auto 6px;
}
/**
* Code
*/
.component__code {
max-width: 100vw;
margin-top: 20px;
width: 1200px;
transform: translateX(-50%) translateX(370px);
position: relative;
min-width: 275px;
}
/**
* Preview
*/
.component__preview {
max-width: 100vw;
margin-top: 20px;
width: 1200px;
transform: translateX(-50%) translateX(370px);
position: relative;
min-width: 275px;
padding-right: 24px;
border: 1px solid var(--grey);
}
.component__preview__iframe {
display: block;
width: 100%;
}
/**
* Resize handle
*/
.component__preview__handle {
display: block;
position: absolute;
width: 24px;
height: 100%;
right: 0;
top: 0;
bottom: 0;
}
.component-is-resizing >>> .component__preview__handle {
left: 0;
width: 100%;
}
.component__preview__handle__overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 24px;
content: "";
background-color: white;
transition: background-color 0.15s, border-color 0.15s;
border-left: 1px solid var(--grey);
}
.component__preview__handle:hover >>> .component__preview__handle__overlay,
.component-is-resizing >>> .component__preview__handle__overlay {
background-color: #f5f5f5;
border-color: var(--grey);
}
/**
* Resize handle icon
*/
.component__preview__handle__icon {
display: block;
width: 20px;
height: 20px;
position: absolute;
top: 50%;
right: 2px;
transform: translate(0, -50%);
opacity: 0.25;
transition: opacity 0.15s;
}
.component-is-resizing >>> .component__preview__handle__icon {
opacity: 0.5;
}
</style> |
module.exports = {
title: "Design Manual",
description: "this is my design manual",
head: [
['script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.6.0/iframeResizer.min.js' }],
['script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/10.14.0/lazyload.min.js' }],
['script', { src: 'https://unpkg.com/[email protected]/dist/interact.min.js' }],
['script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/prism.min.js' }],
['script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/components/prism-markup-templating.js' }],
['script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify-html.min.js' }],
],
themeConfig: {
nav: [
{ text: "Home", link: "/" },
{ text: "Guide", link: "/guide/" },
{ text: "External", link: "https://google.com" }
],
sidebar: [
{
title: "Components",
collapsable: false,
children: ["/"]
},
{
title: "Content",
children: [
/* ... */
]
},
{
title: "Whatever",
children: [
/* ... */
]
}
]
}
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
let Design Manual only do the generating of components, let Vuepress handle the pages.
The text was updated successfully, but these errors were encountered: