This commit is contained in:
wangxueliang 2018-01-25 15:29:34 +08:00
commit 93be6359e2
29 changed files with 337 additions and 207 deletions

View File

@ -16,6 +16,8 @@
"selector-list-comma-newline-after": null,
"selector-pseudo-element-colon-notation": null,
"unit-no-unknown": null,
"value-list-max-empty-lines": null
"value-list-max-empty-lines": null,
"font-family-no-missing-generic-family-keyword": null,
"no-descending-specificity": null
}
}

15
.vscode/settings.json vendored
View File

@ -2,13 +2,19 @@
{
"eslint.enable": true,
"eslint.options": {
"extensions": [".js", ".vue"],
"extensions": [
".js",
".vue"
],
"configFile": ".eslintrc"
},
"eslint.validate": [
"javascript",
"javascriptreact",
{ "language": "vue", "autoFix": true }
{
"language": "vue",
"autoFix": true
}
],
"emmet.syntaxProfiles": {
"vue-html": "html",
@ -17,5 +23,8 @@
"eslint.autoFixOnSave": true,
"vetur.validation.template": true,
"vetur.format.html.wrap_line_length": 60,
"vetur.format.js.InsertSpaceBeforeFunctionParenthesis": true
"vetur.format.js.InsertSpaceBeforeFunctionParenthesis": true,
"stylefmt.config": {
"fix": true
}
}

View File

@ -1,10 +1,5 @@
<template>
<div :class="classes">
<slot></slot>
</div>
</template>
<script>
import { filterEmpty } from '../_util/vnode'
export default {
name: 'ButtonGroup',
props: {
@ -38,5 +33,13 @@ export default {
]
},
},
render () {
const { classes, $slots } = this
return (
<div class={classes}>
{filterEmpty($slots.default)}
</div>
)
},
}
</script>

View File

@ -1,8 +1,13 @@
::: demo
<summary>
#### 按钮类型
按钮有四种类型:主按钮、次按钮、虚线按钮、危险按钮。主按钮在同一个操作区域最多出现一次。
</summary>
<cn>
#### 按钮类型
按钮有四种类型:主按钮、次按钮、虚线按钮、危险按钮。主按钮在同一个操作区域最多出现一次。
</cn>
<us>
#### Type
There are `primary` button, `default` button, `dashed` button and `danger` button in antd.
</us>
```html
<template>
@ -14,4 +19,4 @@
</div>
</template>
```
:::

View File

@ -1,8 +0,0 @@
<template>
<div>
<a-button type="primary">Primary</a-button>
<a-button>Default</a-button>
<a-button type="dashed">Dashed</a-button>
<a-button type="danger">Danger</a-button>
</div>
</template>

View File

@ -1,3 +1,16 @@
<cn>
#### 按钮组合
可以将多个 `Button` 放入 `Button.Group` 的容器中。
通过设置 `size``large` `small` 分别把按钮组合设为大、小尺寸。若不设置 `size`,则尺寸为中。
</cn>
<us>
#### Button Group
Buttons can be grouped by placing multiple `Button` components into a `Button.Group`.
The `size` can be set to `large`, `small` or left unset resulting in a default size.
</us>
```html
<template>
<div id="components-button-demo-button-group">
<h4>Basic</h4>
@ -46,3 +59,4 @@
margin-right: 8px;
}
</style>
```

View File

@ -1,3 +1,15 @@
<cn>
#### 不可用状态
添加 `disabled` 属性即可让按钮处于不可用状态,同时按钮样式也会改变。
</cn>
<us>
#### Disabled
To mark a button as disabled, add the `disabled` property to the `Button`.
</us>
```html
<template>
<div>
<a-button type="primary">Primary</a-button>
@ -13,3 +25,4 @@
<a-button type="dashed" disabled>Dashed(disabled)</a-button>
</div>
</template>
```

View File

@ -1,3 +1,13 @@
<cn>
#### 幽灵按钮
幽灵按钮将其他按钮的内容反色,背景变为透明,常用在有色背景上。
</cn>
<us>
#### Ghost Button
`ghost` property will make button's background transparent, it is common used in colored background.
</us>
```html
<template>
<div :style="{ background: 'rgb(190, 200, 200)', padding: '26px 16px 16px' }">
<a-button type="primary" ghost>Primary</a-button>
@ -6,3 +16,4 @@
<a-button type="danger" ghost>danger</a-button>
</div>
</template>
```

View File

@ -0,0 +1,26 @@
<cn>
#### 图标按钮
当需要在 `Button` 内嵌入 `Icon` 时,可以设置 `icon` 属性,或者直接在 `Button` 内使用 `Icon` 组件。
如果想控制 `Icon` 具体的位置,只能直接使用 `Icon` 组件,而非 `icon` 属性。
</cn>
<us>
#### Icon
`Button` components can contain an `Icon`. This is done by setting the `icon` property or placing an `Icon` component within the `Button`
If you want specific control over the positioning and placement of the `Icon`, then that should be done by placing the `Icon` component within the `Button` rather than using the `icon` property.
</us>
```html
<template>
<div>
<a-button type="primary" shape="circle" icon="search"></a-button>
<a-button type="primary" icon="search">Search</a-button>
<a-button shape="circle" icon="search" />
<a-button icon="search">Search</a-button>
<a-button shape="circle" icon="search" />
<a-button icon="search">Search</a-button>
<a-button type="dashed" shape="circle" icon="search" />
<a-button type="dashed" icon="search">Search</a-button>
</div>
</template>
```

View File

@ -1,13 +0,0 @@
<template>
<div>
<a-button type="primary" shape="circle" icon="search" />
<a-button type="primary" icon="search">Search</a-button>
<a-button shape="circle" icon="search" />
<a-button icon="search">Search</a-button>
<br />
<a-button shape="circle" icon="search" />
<a-button icon="search">Search</a-button>
<a-button type="dashed" shape="circle" icon="search" />
<a-button type="dashed" icon="search">Search</a-button>
</div>
</template>

View File

@ -1,27 +1,5 @@
<template>
<div>
<md>
# Button 按钮
按钮用于开始一个即时操作
## 何时使用
标记了一个或封装一组操作命令响应用户点击行为触发相应的业务逻辑
## 代码演示
</md>
<Basic />
<ButtonGroup />
<Disabled />
<Ghost />
<Icon />
<Loading />
<h1>TODO Multiple</h1>
<Multiple />
<Size />
<Doc class="markdown"/>
</div>
</template>
<script>
import Basic from './basic.md'
import Basic from './basic'
import ButtonGroup from './button-group'
import Disabled from './disabled'
import Ghost from './ghost'
@ -29,18 +7,44 @@ import Icon from './icon'
import Loading from './loading'
import Multiple from './multiple'
import Size from './size'
import Doc from '../index.zh-CN.md'
import CN from '../index.zh-CN.md'
import US from '../index.en-US.md'
export default {
components: {
Basic,
ButtonGroup,
Disabled,
Ghost,
Icon,
Loading,
Multiple,
Size,
Doc,
render () {
const md = {
cn: `# Button 按钮
按钮用于开始一个即时操作
## 何时使用
标记了一个或封装一组操作命令响应用户点击行为触发相应的业务逻辑
## 代码演示`,
us: `# Button
To trigger an operation.
## When To Use
A button means an operation (or a series of operations). Clicking a button will trigger corresponding business logic.
`,
}
return (
<div>
<md md={md}/>
<Basic />
<ButtonGroup />
<Disabled />
<Ghost />
<Icon/>
<Loading />
<h1>TODO Multiple</h1>
<Multiple />
<Size />
<api>
<template slot='cn'>
<CN/>
</template>
<template slot='us'>
<US/>
</template>
</api>
</div>
)
},
}
</script>

View File

@ -1,3 +1,14 @@
<cn>
#### 加载中状态
添加 `loading` 属性即可让按钮处于加载状态,最后两个按钮演示点击后进入加载状态。
</cn>
<us>
#### Loading
A loading indicator can be added to a button by setting the `loading` property on the `Button`.
</us>
```html
<template>
<div>
<a-button type="primary" loading>
@ -36,3 +47,4 @@ export default {
},
}
</script>
```

View File

@ -0,0 +1,21 @@
<cn>
#### 多个按钮组合
按钮组合使用时推荐使用1个主操作 + n 个次操作3个以上操作时把更多操作放到 `Dropdown.Button` 中组合使用。
</cn>
<us>
#### Multiple Buttons
If you need several buttons, we recommend that you use 1 primary button + n secondary buttons, and if there are more than three operations, you can group some of them into `Dropdown.Button`.
</us>
```html
// TODO: 依赖组件开发中
<template>
<div>
<a-button type="primary">Primary</a-button>
<a-button>Default</a-button>
<a-button type="dashed">Dashed</a-button>
<a-button type="danger">Danger</a-button>
</div>
</template>
```

View File

@ -1,9 +0,0 @@
// TODO:
<template>
<div>
<a-button type="primary">Primary</a-button>
<a-button>Default</a-button>
<a-button type="dashed">Dashed</a-button>
<a-button type="danger">Danger</a-button>
</div>
</template>

View File

@ -1,3 +1,16 @@
<cn>
#### 按钮尺寸
按钮有大、中、小三种尺寸。
通过设置 `size``large` `small` 分别把按钮设为大、小尺寸。若不设置 `size`,则尺寸为中。
</cn>
<us>
#### Size
Ant Design supports a default button size as well as a large and small size.
If a large or small button is desired, set the `size` property to either `large` or `small` respectively. Omit the `size` property for a button with the default size.
</us>
```html
<template>
<div>
<a-radio-group :value="size" @change="handleSizeChange">
@ -38,3 +51,4 @@ export default {
},
}
</script>
```

View File

@ -1,15 +1,3 @@
---
category: Components
type: General
title: Button
---
To trigger an operation.
## When To Use
A button means an operation (or a series of operations). Clicking a button will trigger corresponding business logic.
## API
To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
@ -25,14 +13,10 @@ To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
| type | can be set to `primary` `ghost` `dashed` `danger`(added in 2.7) or omitted (meaning `default`) | string | `default` |
| onClick | set the handler to handle `click` event | function | - |
### events
| Events Name | Description | Arguments |
| --- | --- | --- |
| click | handle `click` event | function(e) |
`<Button>Hello world!</Button>` will be rendered into `<button><span>Hello world!</span></button>`, and all the properties which are not listed above will be transferred to the `<button>` tag.
<style>
[id^=components-button-demo-] .ant-btn {
margin-right: 8px;
margin-bottom: 12px;
}
[id^=components-button-demo-] .ant-btn-group > .ant-btn {
margin-right: 0;
}
</style>

View File

@ -6,7 +6,7 @@
| 属性 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| ghost | 幽灵属性,使按钮背景透明,版本 2.7 中增加 | boolean | false |
| ghost | 幽灵属性,使按钮背景透明 | boolean | false |
| htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` |
| icon | 设置按钮的图标类型 | string | - |
| loading | 设置按钮载入状态 | boolean \| { delay: number } | `false` |

View File

@ -1,7 +1,5 @@
<template>
<i :title="title" :class="classes"
@click="handleClick">
</i>
<i :title="title" :class="classes" @click="handleClick"></i>
</template>
<script>
export default {

View File

@ -0,0 +1,17 @@
<template>
<div class='markdown'>
<slot v-if="lang === 'cn'" name="cn"></slot>
<slot v-else name="us"></slot>
</div>
</template>
<script>
export default {
name: 'api',
data () {
const { lang } = this.$route.params
return {
lang,
}
},
}
</script>

View File

@ -1,16 +1,20 @@
<script>
import { Menu } from 'antd'
import * as AllDemo from './demo'
import * as AllDemo from '../demo'
const MenuItem = Menu.Item
export default {
render () {
const { name, demo } = this.$route.params // eslint-disable-line
let { lang } = this.$route.params
const Demo = AllDemo[name]
if (lang !== 'cn') {
lang = 'us'
}
return (
<div class='site page-container'>
<Menu class='nav' selectedKeys={[name]}>
{Object.keys(AllDemo).map(d => <MenuItem key={d}>
<router-link to={{ path: `/components/${d}` }}>{d}</router-link>
<router-link to={{ path: `/components/${lang}/${d}` }}>{d}</router-link>
</MenuItem>)}
</Menu>
<div class='content'>

View File

@ -2,7 +2,8 @@
<div class="box box-demo">
<slot name="component"></slot>
<div class="box-demo-description">
<slot name="description"></slot>
<slot v-if="lang === 'cn'" name="description"></slot>
<slot v-else name="us-description"></slot>
<span class="btn-toggle" :class="{open: isOpen}" @click="toggle"><i class="anticon anticon-down-circle-o"></i></span>
</div>
<transition appear :css="false" @enter="enter" @leave="leave">
@ -20,8 +21,10 @@ export default {
jsfiddle: Object,
},
data () {
const { lang } = this.$route.params
return {
isOpen: false,
lang,
}
},
methods: {

View File

@ -0,0 +1,38 @@
<template>
<div v-html="marked(text)" />
</template>
<script>
import marked from 'marked'
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: true,
pedantic: true,
sanitize: true,
smartLists: true,
smartypants: true,
})
export default {
name: 'md',
props: {
md: [Object, String],
},
data () {
const { lang } = this.$route.params
let text = ''
const md = this.md
if (this.$slots.default && this.$slots.default[0] && this.$slots.default[0].text) {
text = this.$slots.default[0].text
} else {
text = typeof md === 'string' ? md : (md[lang] || md.us)
}
text = text || ''
text = text.split('\n').map(t => t.trim()).join('\n')
return {
marked,
text,
}
},
}
</script>

View File

@ -4,11 +4,13 @@ import 'highlight.js/styles/solarized-light.css'
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
import Md from './md'
import Md from './components/md'
import Api from './components/api'
import * as Components from '../components/index'
import demoBox from './components/demoBox'
Vue.use(VueRouter)
Vue.component(Md.name, Md)
Vue.component(Api.name, Api)
Vue.component('demo-box', demoBox)
Object.keys(Components).forEach(k => {
const name = `a${k.replace(/([A-Z])/g, '-$1').toLowerCase()}`

View File

@ -1,5 +1,3 @@
#app {
}
.site {
display: flex;
.nav {
@ -10,10 +8,6 @@
padding: 20px;
}
}
.code-section,
.box-demo + summary {
display: none;
}
.highlight > .code-section {
display: block;
margin: 0;
@ -38,23 +32,21 @@
}
.page-container {
/*color: #666;*/
font-size: 14px;
line-height: 1.5;
.table {
font-size: 13px;
border-collapse: collapse;
border-spacing: 0px;
border-spacing: 0;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 100%;
margin: 16px 0;
th{
background: #F7F7F7;
th {
background: #f7f7f7;
white-space: nowrap;
color: #5C6B77;
color: #5c6b77;
font-weight: 600;
}
td:first-child {
@ -63,7 +55,7 @@
width: 20%;
font-family: "Lucida Console", Consolas, Menlo, Courier, monospace;
}
th,td{
th,td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
@ -92,7 +84,7 @@
}
.markdown {
& > ul{
& > ul {
margin-top: 1rem;
margin-bottom: 1rem;
& > li {
@ -100,8 +92,8 @@
margin-left: 1rem;
}
}
h1, h2, h3{
a{
h1, h2, h3 {
a {
font-size: .8em;
opacity: 0;
font-weight: normal;

View File

@ -1,24 +0,0 @@
<template>
<div v-html="marked($slots.default[0].text.trim() || '')" />
</template>
<script>
import marked from 'marked'
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: true,
sanitize: true,
smartLists: true,
smartypants: true,
})
export default {
name: 'md',
data () {
return {
marked,
}
},
}
</script>

View File

@ -1,11 +1,11 @@
import Demo from './demo.vue'
import Demo from './components/demo.vue'
const AsyncComp = () => {
return {
component: import(`../components/button/demo/index.vue`),
}
}
export default [
{ path: '/components/:name/:demo?', component: Demo },
{ path: '/test/:name/:demo?', component: AsyncComp },
{ path: '/*', redirect: '/components/menu' },
{ path: '/components/:lang/:name/:demo?', component: Demo },
{ path: 'test/:name/:demo', component: AsyncComp },
{ path: '/*', redirect: '/components/cn/menu' },
]

6
package-lock.json generated
View File

@ -7662,12 +7662,6 @@
"string": "3.3.3"
}
},
"markdown-it-container": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/markdown-it-container/download/markdown-it-container-2.0.0.tgz",
"integrity": "sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU=",
"dev": true
},
"markdown-table": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/markdown-table/download/markdown-table-1.1.1.tgz",

View File

@ -8,7 +8,7 @@
"test": "karma start test/karma.conf.js --single-run",
"build": "sh build.sh",
"lint": "eslint -c ./.eslintrc --fix --ext .js ./src/",
"lint:style": "stylelint \"./src/**/*.less\" --syntax less"
"lint:style": "stylelint \"./examples/**/*.less\" --fix --syntax less"
},
"repository": {
"type": "git",
@ -65,7 +65,6 @@
"less-loader": "^4.0.5",
"markdown-it": "^8.4.0",
"markdown-it-anchor": "^4.0.0",
"markdown-it-container": "^2.0.0",
"marked": "^0.3.7",
"mocha": "^3.2.0",
"pre-commit": "^1.2.2",
@ -77,8 +76,8 @@
"stylelint": "^8.1.1",
"stylelint-config-standard": "^17.0.0",
"transliteration": "^1.6.2",
"vue-antd-md-loader": "^1.0.1",
"vue-loader": "^13.0.5",
"vue-markdown-loader": "^2.3.0",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.5.13",
"webpack": "^3.6.0",

View File

@ -1,11 +1,11 @@
const path = require('path')
const slugify = require('transliteration').slugify
const hljs = require('highlight.js')
const Token = require('markdown-it/lib/token')
const cheerio = require('cheerio')
const fetch = (str, tag) => {
const $ = cheerio.load(str, { decodeEntities: false })
const $ = cheerio.load(str, { decodeEntities: false, xmlMode: true })
if (!tag) return str
return $(tag).html()
@ -37,7 +37,7 @@ const renderHighlight = function (str, lang) {
}
function wrap (render) {
return function () {
return function (tokens) {
return render.apply(this, arguments)
.replace('<code class="', '<code class="hljs ')
.replace('<code>', '<code class="hljs">')
@ -55,50 +55,69 @@ md.use(require('markdown-it-anchor'), {
slugify: slugify,
permalink: true,
permalinkBefore: true,
}).use(require('markdown-it-container'), 'demo', {
validate: function (params) {
return params.trim().match(/^demo\s*(.*)$/)
},
render: function (tokens, idx) {
if (tokens[idx].nesting === 1) {
const summaryContent = tokens[idx + 1].content
const summary = fetch(summaryContent, 'summary')
const summaryHTML = summary ? md.render(summary) : ''
const content = tokens[idx + 2].content
const html = fetch(content, 'template')
const script = fetch(content, 'script') || ''
const style = fetch(content, 'style') || ''
const code = tokens[idx + 2].markup + tokens[idx + 2].info + '\n' + content + tokens[idx + 2].markup
const codeHtml = code ? md.render(code) : ''
let jsfiddle = { html: html, script: script, style: style }
jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle))
// opening tag
return `<template>
<demo-box :jsfiddle="${jsfiddle}">
<div class="box-demo-show" slot="component">${html}</div>
<template slot="description">${summaryHTML}</template>
<div class="highlight" slot="code">${codeHtml}</div>
</demo-box>
</template>
<script>
${script}
</script>
<style>
${style}
</style>
`
} else {
return '\n'
}
},
})
md.renderer.rules.table_open = function () {
return '<table class="table">'
}
md.renderer.rules.fence = wrap(md.renderer.rules.fence)
const cnReg = new RegExp('<(cn)(?:[^<]|<)+</\\1>', 'g')
const usReg = new RegExp('<(us)(?:[^<]|<)+</\\1>', 'g')
md.core.ruler.push('update_template', function replace ({ tokens }) {
let cn = ''
let us = ''
let template = ''
let script = ''
let style = ''
let code = ''
tokens.forEach(token => {
if (token.type === 'html_block') {
if (token.content.match(cnReg)) {
cn = fetch(token.content, 'cn')
token.content = ''
}
if (token.content.match(usReg)) {
us = fetch(token.content, 'us')
token.content = ''
}
}
if (token.type === 'fence' && token.info === 'html' && token.markup === '```') {
code = '````html\n' + token.content + '````'
template = fetch(token.content, 'template')
script = fetch(token.content, 'script')
style = fetch(token.content, 'style')
token.content = ''
token.type = 'html_block'
}
})
if (template) {
let jsfiddle = {
html: template,
script,
style,
}
jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle))
const codeHtml = code ? md.render(code) : ''
const cnHtml = cn ? md.render(cn) : ''
const newContent = `
<template>
<demo-box :jsfiddle="${jsfiddle}">
<div class="box-demo-show" slot="component">${template}</div>
<template slot="description">${cnHtml}</template>
<template slot="us-description">${us ? md.render(us) : ''}</template>
<div class="highlight" slot="code">${codeHtml}</div>
</demo-box>
</template>
<script>
${script || ''}
</script>
<style>
${style || ''}
</style>`
const t = new Token('html_block', '', 0)
t.content = newContent
tokens.push(t)
}
})
module.exports = {
entry: {
@ -112,8 +131,8 @@ module.exports = {
test: /\.md/,
use: [
{
loader: 'vue-markdown-loader',
options: Object.assign(md, { wrapper: 'section', preventExtract: true }),
loader: 'vue-antd-md-loader',
options: md,
},
],
},
@ -135,7 +154,7 @@ module.exports = {
],
},
resolve: {
extensions: ['.js', '.vue'],
extensions: ['.js', '.vue', '.md'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'antd': path.join(__dirname, 'components'),