refactor(md-loader): use typography

This commit is contained in:
07akioni 2019-12-22 15:31:04 +08:00
parent e45b4e0137
commit 9c5f932229
33 changed files with 152 additions and 601 deletions

View File

@ -1,13 +0,0 @@
export default {
mounted () {
const textAreaNotToRender = new Set(this.$refs.doc.querySelectorAll('.not-code textarea'))
this.$refs.doc.querySelectorAll('textarea').forEach(ta => {
if (textAreaNotToRender.has(ta)) {
return
}
const rows = ta.value.split('\n').length
ta.style.width = '100%'
ta.setAttribute('rows', rows)
})
}
}

View File

@ -94,13 +94,11 @@
</template>
<script>
import docCodeEditorMixin from './docCodeEditorMixin'
import mdMusicalNotes from 'naive-ui/lib/icons/md-musical-notes'
export default {
components: {
mdMusicalNotes
},
mixins: [docCodeEditorMixin],
data () {
return {
disableMenu: false,

View File

@ -1,32 +0,0 @@
<template>
<div
ref="doc"
class="readme"
>
<readme />
</div>
</template>
<script>
import readme from './devGuidelines.vue.md'
import { replaceEmojiWithImages } from '../../utils'
export default {
components: {
readme
},
mounted () {
replaceEmojiWithImages(this.$refs.doc)
},
methods: {
}
}
</script>
<style scoped>
.readme {
padding: 24px 0 24px 0;
max-width: 720px;
margin: auto;
}
</style>

View File

@ -1,3 +1,4 @@
<!--no-demo-->
# Develop Guidelines
## Git Commit Message Style
You **MUST** follow [Angular Commit Format](https://gist.github.com/brianclements/841ea7bffdb01346392c).

View File

@ -1,32 +0,0 @@
<template>
<div
ref="doc"
class="readme"
>
<readme />
</div>
</template>
<script>
import readme from './intro.vue.md'
import { replaceEmojiWithImages } from '../../utils'
export default {
components: {
readme
},
mounted () {
replaceEmojiWithImages(this.$refs.doc)
},
methods: {
}
}
</script>
<style scoped>
.readme {
padding: 24px 0 24px 0;
max-width: 720px;
margin: auto;
}
</style>

View File

@ -1,2 +1,3 @@
<!--no-demo-->
# Naive UI
Naive UI is a Vue-Based Frontend Component Library of TuSimple.

View File

@ -1,3 +1,4 @@
<!--no-demo-->
# Getting Started
## Installation

View File

@ -1,39 +0,0 @@
<template>
<div
ref="doc"
class="readme"
>
<private-readme v-if="token === 'naive'" />
<readme v-else />
</div>
</template>
<script>
import readme from './start.vue.md'
import privateReadme from './privateStart.vue.md'
import { replaceEmojiWithImages } from '../../utils'
export default {
components: {
readme,
privateReadme
},
data () {
return {
token: null
}
},
mounted () {
replaceEmojiWithImages(this.$refs.doc)
this.token = localStorage.token
}
}
</script>
<style scoped>
.readme {
padding: 24px 0 24px 0;
max-width: 720px;
margin: auto;
}
</style>

View File

@ -0,0 +1,18 @@
<!--no-demo-->
# Getting Started
## Installation
First install it.
```bash
npm install --save-dev naive-ui
```
## Usage
Add the following lines in you entry point js file.
```js
import naive from 'naive-ui'
import 'naive-ui/dist/lib/index.css'
Vue.use(naive)
```

View File

@ -0,0 +1,18 @@
<!--no-demo-->
# 起步
## Installation
First install it.
```bash
npm install --save-dev naive-ui
```
## Usage
Add the following lines in you entry point js file.
```js
import naive from 'naive-ui'
import 'naive-ui/dist/lib/index.css'
Vue.use(naive)
```

View File

@ -1,32 +0,0 @@
<template>
<div
ref="doc"
class="readme"
>
<readme />
</div>
</template>
<script>
import readme from './status.vue.md'
import { replaceEmojiWithImages } from '../../utils'
export default {
components: {
readme
},
mounted () {
replaceEmojiWithImages(this.$refs.doc)
},
methods: {
}
}
</script>
<style scoped>
.readme {
padding: 24px 0 24px 0;
max-width: 720px;
margin: auto;
}
</style>

View File

@ -1,96 +0,0 @@
# Develop Status
## Components
|Component|Develop Status|Unit Test|Note|
|--|:--:|:--:|--|
|Alert|😍|❌||
|Button|😍|❌||
|Checkbox|😍|❌||
|DatePicker|😍|❌||
|TimePicker|😍|❌||
|GradientText|😍|❌||
|Icon|😍|❌||
|Input|😍|❌||
|Message|😍|❌||
|Modal|😍|❌||
|Notification|😍|❌|Code clean in need|
|Pagination|😍|❌||
|Select|😍|❌||
|Switch|😍|❌||
|Tooltip|😍|❌||
|Popover|😍|❌||
|InputNumber|😍|❌||
|Radio|😍|||
|Tab|😍|||
|Badge|😍|||
|Steps|😍|||
|Tag|😍|||
|Divider|😍|||
|Popconfirm|😍|||
|BackTop|😍|||
|Progress|😍|||
|Timeline|😍|||
|Collapse|😍|||
|Cascader|😍|||
|Dropdown|😍|||
|Transfer|😍|||
|Spin|😍|||
|Drawer|🤔|||
|FormItem|🤔|❌||
|Form|🤔|❌||
|Table|🤔|❌|Function is not fulfilled|
|Slider|🤔|||
|LoadingBar|😍|||
|AutoComplete|🚧|||
|Tree|🤔|||
|TreeSelect|🚧|||
|Upload|🚧|||
|Time|😍|||
|Anchor|😍|||
|Statistic|🚧|||
|Breadcrumb|🚧|||
|Card|🚧|||
|Empty|🚧|||
|Grid|😍|||
|Layout|🚧|||
|Affix|😍|||
|Rating|🚧|||
|Avatar|🚧|||
|Result|🚧|||
|Menu|🚧|||
|Markdown|🚧|||
|Description|🚧|||
|Typography|🚧|||
|Mentions|✋||Not Planned|
|Calendar|✋||Not Planned|
|Carousel|✋||Not Planned|
## Todos
1. <del>Z-index management on `Select` & `Tooltip` & `Modal`(Low Priority)</del>
2. Full featured table component(Medium Priority)
3. Form component(Medium Priority)
4. FormItem component(High Priority)
5. Complete unit test for all existing components(High Priority)
6. <del>Create a Markdown webpack loader to convert documentation(Low Priority)</del>
7. <del>Refactor documentation page(for code clairity)</del>
8. Code refactor for some 😢 messy code(which is my bad...)
9. Refactor CSS use mixins(which means I should learn SCSS hard...)
10. Split icons for components.
11. Fulfill props for all components.
12. Add keyboard event on planned components.
13. Finish all planned components
14. Refactor using proper html tags
15. Unit Test
## RoadMap
|Version|Milestone|
|-|-|
|0.3|Cascader|
|0.4|Refactor popover, remove wrap element of it|
|0.5|Refactor CSS using mixin. Refactor documentation. Light theme.|
|0.6|Refactor form component|
|0.7|Refactor table component|
|0.8|i18n|
|0.9|Unit Test|
|0.10| Import on demand|
|?| See `Todos`|

View File

@ -1,17 +1,13 @@
import Vue from 'vue/dist/vue'
import VueRouter from 'vue-router'
import '../styles/index.scss'
import './styles/atom-one-dark-reasonable.scss'
import './styles/atom-one-light.scss'
import './styles/markdown.scss'
import './styles/font.scss'
import NaiveUI from '../index'
import VueI18n from 'vue-i18n'
import intro from './documentation/intro/intro'
import start from './documentation/intro/start'
import devGuildlines from './documentation/intro/devGuidelines'
import status from './documentation/intro/status'
import nimbusServiceLayoutDemo from './documentation/components/nimbusServiceLayoutDemo'
import gradientText from './documentation/components/gradientText'
@ -155,7 +151,6 @@ const routes = [
{ path: '/intro', component: intro },
{ path: '/start', component: start },
{ path: '/dev-guildlines', component: devGuildlines },
{ path: '/status', component: status },
{ path: '/n-nimbus-service-layout', component: nimbusServiceLayoutDemo },
{ path: '/n-layout', component: layout },
{ path: '/n-gradient-text', component: gradientText },

View File

@ -1,41 +1,29 @@
const hljs = require('highlight.js')
const marked = require('marked')
// const prettier = require('prettier')
const renderer = require('./mdRenderer')
const escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
function parseMdAsAnchor (content) {
const tokens = marked.lexer(content)
const titles = tokens.filter(token => token.type === 'heading' && token.depth === 2).map(token => token.text)
const linkTags = titles.map(title => {
const href = title.replace(/ /g, '-')
return `<n-anchor-link title="${title}" href="#${href}"/>`
})
return `<n-anchor :top="24" position="absolute" affix style="width: 132px;">${linkTags.join('\n')}</n-anchor>`
}
function escapeForHTML (input) {
return input.replace(/([&<>'"])/g, char => escapeMap[char])
}
// Create your custom renderer.
const renderer = new marked.Renderer()
renderer.code = (code, language) => {
// Check whether the given language is valid for highlight.js.
const validLang = !!(language && hljs.getLanguage(language))
// Highlight only if the language is valid.
// highlight.js escapes HTML in the code, but we need to escape by ourselves
// when we don't use it.
const highlighted = validLang
? hljs.highlight(language, code).value
: escapeForHTML(code)
// Render the highlighted code with `hljs` class.
return `<pre v-pre><code class="${language}">${highlighted}</code></pre>`
}
marked.setOptions({
renderer
})
module.exports = function (content) {
// console.log(convertMd2Doc(content))
return `<template><div class="markdown">${marked(content)}</div></template>`
return `<template>
<component-documentation>
<div style="display: flex; flex-wrap: nowrap;">
<div style="width: calc(100% - 148px); margin-right: 16px;">
${marked(content, {
renderer
})}
</div>
<div style="width: 132px;">
${parseMdAsAnchor(content)}
</div>
</div>
</component-documentation>
</template>`
}

View File

@ -1,45 +1,8 @@
const hljs = require('highlight.js')
const marked = require('marked')
const camelCase = require('lodash/camelCase')
const kababCase = require('lodash/kebabCase')
// const prettier = require('prettier')
const escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
}
function escapeForHTML (input) {
return input.replace(/([&<>'"])/g, char => escapeMap[char])
}
marked.setOptions({
gfm: true
})
// Create your custom renderer.
const renderer = new marked.Renderer()
renderer.code = (code, language) => {
// Check whether the given language is valid for highlight.js.
const validLang = !!(language && hljs.getLanguage(language))
// Highlight only if the language is valid.
// highlight.js escapes HTML in the code, but we need to escape by ourselves
// when we don't use it.
const highlighted = validLang
? hljs.highlight(language, code).value
: escapeForHTML(code)
// Render the highlighted code with `hljs` class.
return `<pre><code class="${language}">${highlighted}</code></pre>`
}
marked.setOptions({
renderer
})
const renderer = require('./mdRenderer')
const mdLoader = require('./NaiveUIMdLoader')
function template (demos, demosLiteral, isSingleColumn = false) {
// return `<component-demos :single-column="${isSingleColumn}">
@ -106,6 +69,10 @@ export default {
}
function convertMd2ComponentDocumentation (text) {
const isNoDemo = !!~text.search('<!--no-demo-->')
if (isNoDemo) {
return mdLoader(text)
}
const isSingleColumn = !!~text.search('<!--single-column-->')
const tokens = marked.lexer(text)
const componentsIndex = tokens.findIndex(token => token.type === 'code' && token.lang === 'component')
@ -134,7 +101,13 @@ function convertMd2ComponentDocumentation (text) {
}
headerPart.links = {}
footerPart.links = {}
const documentationHTML = `<section class="markdown header-part">${marked.parser(headerPart)}</section>\n` + '<!--demos-->\n' + `<section class="markdown footer-part">${marked.parser(footerPart)}</section>\n`
const documentationHTML = `<section class="markdown header-part">${marked.parser(headerPart, {
gfm: true,
renderer
})}</section>\n` + '<!--demos-->\n' + `<section class="markdown footer-part">${marked.parser(footerPart, {
gfm: true,
renderer
})}</section>\n`
// console.log(documentationHTML)
// const classedDocumentationHTML = addClassToHTML(documentationHTML, 'markdown')
const demosReg = /<!--demos-->/

View File

@ -0,0 +1,49 @@
const hljs = require('highlight.js')
const marked = require('marked')
const renderer = new marked.Renderer()
const overrides = {
code: (code, language) => {
const isLanguageValid = !!(language && hljs.getLanguage(language))
if (!isLanguageValid) {
throw new Error(`MdRendererError: ${language} is not valid for code`)
}
const highlighted = hljs.highlight(language, code).value
return `<n-card size="small">
<n-config-consumer transparent>
<template v-slot="{ theme }">
<pre class="n-code" :class="'n-' + theme + '-theme'"><code>${highlighted}</code></pre>
</template>
</n-config-consumer>
</n-card>`
},
heading: (text, level) => {
const id = text.replace(/ /g, '-')
return `<n-h${level} id="${id}">${text}</n-h${level}>`
},
blockquote: quote => {
return `<n-blockquote>${quote}</n-blockquote>`
},
hr: () => `<n-hr />`,
paragraph: text => {
return `<n-p>${text}</n-p>`
},
link (href, title, text) {
return `<n-a title="${title}" href="${href}">${text}</n-a>`
},
list (body, ordered, start) {
const type = ordered ? 'n-ol' : 'n-ul',
startatt = (ordered && start !== 1) ? (' start="' + start + '"') : ''
return `<${type}${startatt}>\n` + body + `</${type}>\n`
},
listitem (text) {
return `<n-li>${text}</n-li>`
},
codespan (code) {
return `<n-text code>${code}</n-text>`
}
}
Object.keys(overrides).forEach(key => renderer[key] = overrides[key])
module.exports = renderer

View File

@ -0,0 +1,18 @@
const mdLoader = require('./NaiveUIMdLoader')
const marked = require('marked')
const fs = require('fs')
const path = require('path')
const content = fs.readFileSync(path.resolve(__dirname, '../documentation/intro/start.vue.md')).toString()
// console.log('rendered', mdLoader(content))
function parseMdAsAnchor (content) {
const tokens = marked.lexer(content)
const titles = tokens.filter(token => token.type === 'heading' && token.depth === 2).map(token => token.text)
const linkTags = titles.map(title => {
const href = title.replace(/ /g, '-')
return `<n-anchor-link title="${title}" href="#${href}"/>`
})
return `<n-anchor :top="24" position="absolute" affix style="width: 132px;">${linkTags.join('\n')}</n-anchor>`
}
console.log(parseMdAsAnchor(content))

View File

@ -1,79 +0,0 @@
/*
Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
*/
.n-dark-theme {
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
line-height: 1.3em;
color: #abb2bf;
background: #282c34;
border-radius: 5px;
}
.hljs-keyword, .hljs-operator {
color: #F92672;
}
.hljs-pattern-match {
color: #F92672;
}
.hljs-pattern-match .hljs-constructor {
color: #61aeee;
}
.hljs-function {
color: #61aeee;
}
.hljs-function .hljs-params {
color: #A6E22E;
}
.hljs-function .hljs-params .hljs-typing {
color: #FD971F;
}
.hljs-module-access .hljs-module {
color: #7e57c2;
}
.hljs-constructor {
color: #e2b93d;
}
.hljs-constructor .hljs-string {
color: #9CCC65;
}
.hljs-comment, .hljs-quote {
color: #b18eb1;
font-style: italic;
}
.hljs-doctag, .hljs-formula {
color: #c678dd;
}
.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string {
color: #98c379;
}
.hljs-built_in, .hljs-class .hljs-title {
color: #e6c07b;
}
.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number {
color: #d19a66;
}
.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title {
color: #61aeee;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: 700;
}
.hljs-link {
text-decoration: underline;
}
}

View File

@ -1,97 +0,0 @@
/*
Atom One Light by Daniel Gamage
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
base: #fafafa
mono-1: #383a42
mono-2: #686b77
mono-3: #a0a1a7
hue-1: #0184bb
hue-2: #4078f2
hue-3: #a626a4
hue-4: #50a14f
hue-5: #e45649
hue-5-2: #c91243
hue-6: #986801
hue-6-2: #c18401
*/
.n-light-theme {
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #383a42;
background: #fafafa;
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic;
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #a626a4;
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #e45649;
}
.hljs-literal {
color: #0184bb;
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta-string {
color: #50a14f;
}
.hljs-built_in,
.hljs-class .hljs-title {
color: #c18401;
}
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #986801;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
color: #4078f2;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: 700;
}
.hljs-link {
text-decoration: underline;
}
}

View File

@ -1,5 +0,0 @@
@font-face {
font-family: 'FiraCode';
font-weight: 400;
src: url('../assets/fonts/FiraCode-Regular.woff2');
}

View File

@ -4,81 +4,6 @@
@include themes-mixin {
@if $theme == 'dark' {
.markdown {
font-size: 16px;
strong {
font-weight: 700;
}
h1, h2, h3, h4, h5, h6 {
transition: color .3s $default-cubic-bezier;
margin: 0;
font-weight: 700;
}
h1 {
font-size: 32px;
margin-bottom: 12px;
}
h2 {
font-size: 24px;
margin-top: 24px;
margin-bottom: 12px;
}
h3 {
font-size: 18px;
margin-top: 18px;
margin-bottom: 12px;
}
h4 {
font-size: 16px;
margin-top: 16px;
margin-bottom: 8px;
}
ul, ol {
padding-left: 0;
li {
transition: color .3s $default-cubic-bezier;
line-height: 1.875;
margin-bottom: 0px;
font-size: 14px;
color: $--n-secondary-text-color;
}
}
p {
transition: color .3s $default-cubic-bezier;
margin: 8px 0 0 0;
font-size: 14px;
line-height: 1.875;
color: $--n-secondary-text-color;
}
a {
transition: color .3s $default-cubic-bezier;
color: $--primary-6;
font-size: 14px;
}
code {
transition: background-color .3s $default-cubic-bezier, border-color .3s $default-cubic-bezier, color .3s $default-cubic-bezier;
}
pre {
width: 100%;
box-sizing: border-box;
& > code {
border-radius: 6px;
border: 1px solid $--n-divider-color;
display: block;
padding: 12px 16px 12px 16px;
background-color: $--n-card-color;
}
}
:not(pre) > code {
white-space: nowrap;
box-sizing: border-box;
border-radius: 3px;
background-color: rgba(255, 255, 255, .12);
color: $--n-secondary-text-color;
padding: 0em .4em .1em .4em;
font-size: 14px;
font-family: $--n-font-family;
border: 1px solid transparent;
}
table {
font-size: 14px;
width: 100%;
@ -120,22 +45,6 @@
}
} @else {
.n-light-theme .markdown {
p, li, code {
color: $--n-secondary-text-color;
}
a {
color: $--primary-6;
}
pre {
& > code {
background-color: white;
border: 1px solid $--n-divider-color;
}
}
:not(pre) > code {
background-color: rgb(244, 244, 244);
border: 1px solid rgb(230, 230, 230);
}
table {
border: 1px solid $--n-divider-color;
th {

View File

@ -150,7 +150,7 @@ $--header-bar-width: (
}
@include b(li) {
transition: color .3s $default-cubic-bezier;
line-height: 1.625;
line-height: 1.625em;
margin-bottom: 0px;
font-size: 14px;
color: $--n-secondary-text-color;
@ -165,15 +165,16 @@ $--header-bar-width: (
transition: color .3s $default-cubic-bezier;
color: $--n-secondary-text-color;
@include m(code) {
line-height: 1.4;
font-family: $--n-mono-font-family;
transition: color .3s $default-cubic-bezier, background-color .3s $default-cubic-bezier, border-color .3s $default-cubic-bezier;
white-space: nowrap;
box-sizing: border-box;
background-clip: padding-box;
color: $--n-secondary-text-color;
padding: .15em .45em .15em .45em;
padding: .15em .45em 0 .45em;
border-radius: 3px;
font-size: .85em;
font-size: .9em;
background-color: $--n-alpha-input-color;
border: 1px solid $--n-alpha-border-color;
}

View File

@ -1,4 +1,5 @@
@import './fonts/Lato.scss';
@import './fonts/FiraCode.scss';
@import './themes/commonVars.scss';
@import './themes/light/index.scss';
@import './Detachable.scss';

View File

@ -0,0 +1,5 @@
@font-face {
font-family: 'FiraCode';
font-weight: 400;
src: url('./resources/fonts/FiraCode-Regular.woff2');
}