feat: add v-tooltip, fix sort demo, replace custom blocks with <veui-alert>
This commit is contained in:
parent
146c87244d
commit
e812df7fa4
@ -8,7 +8,7 @@ margin-y($top, $bottom = $top)
|
|||||||
padding 30px 60px
|
padding 30px 60px
|
||||||
font-size 14px
|
font-size 14px
|
||||||
line-height 1.8
|
line-height 1.8
|
||||||
color #666
|
color #282c33
|
||||||
font-weight 400
|
font-weight 400
|
||||||
hyphens auto
|
hyphens auto
|
||||||
|
|
||||||
@ -265,22 +265,12 @@ margin-y($top, $bottom = $top)
|
|||||||
& > :last-child
|
& > :last-child
|
||||||
margin-bottom 0
|
margin-bottom 0
|
||||||
|
|
||||||
.alert
|
.veui-alert
|
||||||
.warning
|
p:first-child
|
||||||
.tip
|
margin-top 0
|
||||||
font-size 13px
|
|
||||||
|
|
||||||
.alert
|
p:last-child
|
||||||
border-color #fee
|
margin-bottom 0
|
||||||
background-color tint(#fee, 50%)
|
|
||||||
|
|
||||||
.warning
|
|
||||||
border-color #fef4e6
|
|
||||||
background-color tint(#fef4e6, 50%)
|
|
||||||
|
|
||||||
.tip
|
|
||||||
border-color #d8ebff
|
|
||||||
background-color tint(#d8ebff, 50%)
|
|
||||||
|
|
||||||
.badges
|
.badges
|
||||||
border none
|
border none
|
||||||
|
@ -59,7 +59,7 @@ export function renderDocToPage (file) {
|
|||||||
let src = resolve(DOCS_DIR, file)
|
let src = resolve(DOCS_DIR, file)
|
||||||
let dest = resolve(PAGES_DIR, replaceExtSync(file, 'vue'))
|
let dest = resolve(PAGES_DIR, replaceExtSync(file, 'vue'))
|
||||||
let { contents, data } = renderFile(src, dest)
|
let { contents, data } = renderFile(src, dest)
|
||||||
let { demos = {}, components = {}, meta = {}, deps = {} } = data
|
let { demos = {}, components = {}, meta = {}, deps = {}, hasAlert = false } = data
|
||||||
|
|
||||||
Object.keys(deps || {}).forEach(dep => {
|
Object.keys(deps || {}).forEach(dep => {
|
||||||
add({ [dep]: { [src]: true } })
|
add({ [dep]: { [src]: true } })
|
||||||
@ -77,7 +77,8 @@ export function renderDocToPage (file) {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
components: componentList,
|
components: componentList,
|
||||||
boilerplate: demoList.length || componentList.length,
|
alert: hasAlert,
|
||||||
|
boilerplate: demoList.length || componentList.length || hasAlert,
|
||||||
layout,
|
layout,
|
||||||
style: style || 'post'
|
style: style || 'post'
|
||||||
})
|
})
|
||||||
|
@ -4,6 +4,11 @@ import { render } from './page'
|
|||||||
|
|
||||||
const NAME = 'customblock'
|
const NAME = 'customblock'
|
||||||
|
|
||||||
|
const typeMap = {
|
||||||
|
tip: 'info',
|
||||||
|
warning: 'warning'
|
||||||
|
}
|
||||||
|
|
||||||
export default function attacher () {
|
export default function attacher () {
|
||||||
let proto = this.Parser.prototype
|
let proto = this.Parser.prototype
|
||||||
|
|
||||||
@ -16,15 +21,25 @@ export default function attacher () {
|
|||||||
methods.unshift(NAME)
|
methods.unshift(NAME)
|
||||||
|
|
||||||
return (tree, file) => {
|
return (tree, file) => {
|
||||||
let { path } = file
|
let { path, data } = file
|
||||||
|
|
||||||
visit(tree, NAME, ({ className, value }, index, parent) => {
|
visit(tree, NAME, ({ className, value }, index, parent) => {
|
||||||
let { contents } = render(value, path, {})
|
let { contents } = render(value, path, {})
|
||||||
className = className ? `${className} custom-block` : 'custom-block'
|
if (typeMap[className]) {
|
||||||
parent.children.splice(index, 1, {
|
if (!data.hasAlert) {
|
||||||
type: 'html',
|
data.hasAlert = true
|
||||||
value: `<div class="${className}">${contents}</div>`
|
}
|
||||||
})
|
parent.children.splice(index, 1, {
|
||||||
|
type: 'html',
|
||||||
|
value: `<veui-alert ui="s" type="${typeMap[className]}">${contents}</veui-alert>`
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
className = className ? `${className} custom-block` : 'custom-block'
|
||||||
|
parent.children.splice(index, 1, {
|
||||||
|
type: 'html',
|
||||||
|
value: `<div class="${className}">${contents}</div>`
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<article>
|
<article>
|
||||||
<section ref="itemGroup">
|
<transition-group
|
||||||
<h2>Axis: X(v-drag.sort.x)</h2>
|
ref="group"
|
||||||
<transition-group
|
name="list"
|
||||||
ref="transitionGroup"
|
tag="div"
|
||||||
name="list"
|
class="items"
|
||||||
tag="div"
|
>
|
||||||
class="items"
|
<div
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item"
|
||||||
|
v-drag.sort.x="{
|
||||||
|
name: 'words',
|
||||||
|
containment: 'group',
|
||||||
|
sort: sortCallback,
|
||||||
|
}"
|
||||||
|
class="item"
|
||||||
>
|
>
|
||||||
<div
|
{{ item }}
|
||||||
v-for="item in items"
|
</div>
|
||||||
:key="item"
|
</transition-group>
|
||||||
v-drag.sort.x="{
|
|
||||||
name: 'mySortableButton',
|
|
||||||
containment: 'itemGroup',
|
|
||||||
callback: handleAxisXSortCallback,
|
|
||||||
debug,
|
|
||||||
align
|
|
||||||
}"
|
|
||||||
class="item"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</div>
|
|
||||||
</transition-group>
|
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
@ -30,25 +26,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import drag from 'veui/directives/drag'
|
import drag from 'veui/directives/drag'
|
||||||
|
|
||||||
const items = [
|
const items = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'.split(/[,. ]+/).filter(Boolean)
|
||||||
'须菩提',
|
|
||||||
'菩萨亦如是',
|
|
||||||
'若作是言',
|
|
||||||
'我当灭度无量众生',
|
|
||||||
'即不名菩萨',
|
|
||||||
'🍎🍎',
|
|
||||||
'🍋',
|
|
||||||
'🍉🍉🍉',
|
|
||||||
'🍓🍓',
|
|
||||||
'何以故',
|
|
||||||
'须菩提',
|
|
||||||
'无有法名为菩萨',
|
|
||||||
'是故佛说',
|
|
||||||
'一切法无我',
|
|
||||||
'无人',
|
|
||||||
'无众生',
|
|
||||||
'无寿者'
|
|
||||||
]
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
directives: {
|
directives: {
|
||||||
@ -56,51 +34,21 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
debug: false,
|
items
|
||||||
align: undefined,
|
|
||||||
items: items.map((item, i) => `${i}. ${item}`)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
handleAxisXSortCallback () {
|
|
||||||
return this.getTransitionSortCallback('items', 'transitionGroup')
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getTransitionSortCallback (itemsKey, transitionGroupRefKey) {
|
sortCallback (fromIndex, toIndex) {
|
||||||
return (toIndex, fromIndex) => {
|
let items = this.items
|
||||||
if (toIndex === fromIndex) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let promise
|
|
||||||
if (transitionGroupRefKey) {
|
|
||||||
promise = new Promise((resolve, reject) => {
|
|
||||||
let el = this.$refs[transitionGroupRefKey].$el
|
|
||||||
let handleTransitionEnd = () => {
|
|
||||||
el.removeEventListener('transitionend', handleTransitionEnd)
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
el.addEventListener('transitionend', handleTransitionEnd)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.moveItem(this[itemsKey], fromIndex, toIndex)
|
|
||||||
// 动画完了再回调成功
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
},
|
|
||||||
moveItem (items, fromIndex, toIndex) {
|
|
||||||
let item = items[fromIndex]
|
let item = items[fromIndex]
|
||||||
items.splice(fromIndex, 1)
|
items.splice(fromIndex, 1)
|
||||||
if (toIndex > fromIndex) {
|
|
||||||
toIndex--
|
|
||||||
}
|
|
||||||
items.splice(toIndex, 0, item)
|
items.splice(toIndex, 0, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped docs>
|
<style lang="less" scoped>
|
||||||
.items {
|
.items {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -113,16 +61,9 @@ export default {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
margin: 0 10px 8px 0;
|
margin: 0 10px 8px 0;
|
||||||
padding: 1px 2px;
|
padding: 1px 2px;
|
||||||
|
|
||||||
&:nth-child(3n) {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.list-move {
|
.list-move {
|
||||||
// 动画曲线是 0.25, 0.1, 0.25, 1,就是 ease
|
|
||||||
transition: transform 200ms ease;
|
transition: transform 200ms ease;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,50 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<article>
|
<article>
|
||||||
<section>
|
<transition-group
|
||||||
<h2>Axis: Y(v-drag.sort.y)</h2>
|
ref="group"
|
||||||
<transition-group
|
name="list"
|
||||||
ref="transitionGroup2"
|
tag="div"
|
||||||
name="list"
|
class="items"
|
||||||
tag="ol"
|
>
|
||||||
class="list"
|
<div
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item"
|
||||||
|
v-drag.sort.y="{
|
||||||
|
name: 'words',
|
||||||
|
containment: 'group',
|
||||||
|
sort: sortCallback,
|
||||||
|
}"
|
||||||
|
class="item"
|
||||||
>
|
>
|
||||||
<li
|
{{ item }}
|
||||||
v-for="item in items2"
|
</div>
|
||||||
:key="item"
|
</transition-group>
|
||||||
v-drag.sort.y="{
|
|
||||||
name: 'otherSortableButton',
|
|
||||||
callback: handleAxisYSortCallback,
|
|
||||||
debug,
|
|
||||||
align
|
|
||||||
}"
|
|
||||||
class="item"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</li>
|
|
||||||
</transition-group>
|
|
||||||
</section>
|
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import drag from 'veui/directives/drag'
|
import drag from 'veui/directives/drag'
|
||||||
|
|
||||||
const items = [
|
const items = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'.split(/[,. ]+/).filter(Boolean)
|
||||||
'须菩提',
|
|
||||||
'若菩萨作是言',
|
|
||||||
'我当庄严佛土',
|
|
||||||
'是不名菩萨',
|
|
||||||
'何以故',
|
|
||||||
'🦁',
|
|
||||||
'🙈🙉🙊',
|
|
||||||
'🐷🐶',
|
|
||||||
'如来说',
|
|
||||||
'庄严佛土者',
|
|
||||||
'即非庄严',
|
|
||||||
'是名庄严',
|
|
||||||
'须菩提',
|
|
||||||
'若菩萨通达无我法者'
|
|
||||||
]
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
directives: {
|
directives: {
|
||||||
@ -52,64 +33,30 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
debug: false,
|
items
|
||||||
align: undefined,
|
|
||||||
items2: items.map((item, i) => `${i}${item}`)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
handleAxisYSortCallback () {
|
|
||||||
return this.getTransitionSortCallback('items2', 'transitionGroup2')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
getTransitionSortCallback (itemsKey, transitionGroupRefKey) {
|
sortCallback (fromIndex, toIndex) {
|
||||||
return (toIndex, fromIndex) => {
|
let items = this.items
|
||||||
if (toIndex === fromIndex) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let promise
|
|
||||||
if (transitionGroupRefKey) {
|
|
||||||
promise = new Promise((resolve, reject) => {
|
|
||||||
let el = this.$refs[transitionGroupRefKey].$el
|
|
||||||
let handleTransitionEnd = () => {
|
|
||||||
el.removeEventListener('transitionend', handleTransitionEnd)
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
el.addEventListener('transitionend', handleTransitionEnd)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.moveItem(this[itemsKey], fromIndex, toIndex)
|
|
||||||
// 动画完了再回调成功
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
},
|
|
||||||
moveItem (items, fromIndex, toIndex) {
|
|
||||||
let item = items[fromIndex]
|
let item = items[fromIndex]
|
||||||
items.splice(fromIndex, 1)
|
items.splice(fromIndex, 1)
|
||||||
if (toIndex > fromIndex) {
|
|
||||||
toIndex--
|
|
||||||
}
|
|
||||||
items.splice(toIndex, 0, item)
|
items.splice(toIndex, 0, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped docs>
|
<style lang="less" scoped>
|
||||||
.item {
|
.item {
|
||||||
background: white;
|
background: white;
|
||||||
border: 1px solid pink;
|
border: 1px solid pink;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
margin: 0 10px 8px 0;
|
margin: 0 10px 8px 0;
|
||||||
padding: 1px 2px;
|
padding: 1px 2px;
|
||||||
|
|
||||||
&:nth-child(3n) {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.items {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style-position: inside;
|
list-style-position: inside;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -117,18 +64,14 @@ export default {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
resize: both;
|
resize: both;
|
||||||
overflow: scroll;
|
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
width: 40%;
|
width: 20%;
|
||||||
border-color: peachpuff;
|
border-color: peachpuff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.list-move {
|
.list-move {
|
||||||
// 动画曲线是 0.25, 0.1, 0.25, 1,就是 ease
|
|
||||||
transition: transform 200ms ease;
|
transition: transform 200ms ease;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
46
one/docs/demo/directives/tooltip.vue
Normal file
46
one/docs/demo/directives/tooltip.vue
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<article>
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="'Preview'"
|
||||||
|
ui="icon"
|
||||||
|
>
|
||||||
|
<veui-icon name="zoom-in"/>
|
||||||
|
</veui-button>
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="'Upload'"
|
||||||
|
ui="icon"
|
||||||
|
>
|
||||||
|
<veui-icon name="upload"/>
|
||||||
|
</veui-button>
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="'Remove'"
|
||||||
|
ui="icon"
|
||||||
|
>
|
||||||
|
<veui-icon name="trash"/>
|
||||||
|
</veui-button>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Button, Icon } from 'veui'
|
||||||
|
import tooltip from 'veui/directives/tooltip'
|
||||||
|
import 'veui-theme-dls-icons/zoom-in'
|
||||||
|
import 'veui-theme-dls-icons/upload'
|
||||||
|
import 'veui-theme-dls-icons/trash'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
'veui-button': Button,
|
||||||
|
'veui-icon': Icon
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
tooltip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped docs>
|
||||||
|
.veui-button + .veui-button {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -6,27 +6,27 @@
|
|||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
拖动元素。
|
### 拖动元素
|
||||||
|
|
||||||
[[ demo src="/demo/directives/drag/base.vue" ]]
|
[[ demo src="/demo/directives/drag/base.vue" ]]
|
||||||
|
|
||||||
在指定元素区域内拖动。
|
### 在指定元素区域内拖动
|
||||||
|
|
||||||
[[ demo src="/demo/directives/drag/containment.vue" ]]
|
[[ demo src="/demo/directives/drag/containment.vue" ]]
|
||||||
|
|
||||||
拖动多个元素。
|
### 拖动多个元素
|
||||||
|
|
||||||
[[ demo src="/demo/directives/drag/targets.vue" ]]
|
[[ demo src="/demo/directives/drag/targets.vue" ]]
|
||||||
|
|
||||||
限制拖动方向。
|
### 限制拖动方向。
|
||||||
|
|
||||||
[[ demo src="/demo/directives/drag/axis.vue" ]]
|
[[ demo src="/demo/directives/drag/axis.vue" ]]
|
||||||
|
|
||||||
水平排序。
|
### 水平排序
|
||||||
|
|
||||||
[[ demo src="/demo/directives/drag/sort-x.vue" ]]
|
[[ demo src="/demo/directives/drag/sort-x.vue" ]]
|
||||||
|
|
||||||
垂直排序。
|
### 垂直排序
|
||||||
|
|
||||||
[[ demo src="/demo/directives/drag/sort-y.vue" ]]
|
[[ demo src="/demo/directives/drag/sort-y.vue" ]]
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@ VEUI 对通过 `v-tooltip` 定义的全局浮层提示进行了统一的体验
|
|||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
|
[[ demo src="/demo/directives/tooltip.vue" ]]
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
@ -6,14 +6,16 @@ ${content | raw}</article>
|
|||||||
import { htmlAttrs } from '~/common/i18n'<!-- for: ${components} as ${component} -->
|
import { htmlAttrs } from '~/common/i18n'<!-- for: ${components} as ${component} -->
|
||||||
import ${component} from '~/components/${component}'<!-- /for --><!-- for: ${demos} as ${demo}, ${index} -->
|
import ${component} from '~/components/${component}'<!-- /for --><!-- for: ${demos} as ${demo}, ${index} -->
|
||||||
import Demo${index} from '${demo.src}'<!-- /for --><!-- if: ${demos.length} -->
|
import Demo${index} from '${demo.src}'<!-- /for --><!-- if: ${demos.length} -->
|
||||||
import OneDemo from '~/components/OneDemo'<!-- /if -->
|
import OneDemo from '~/components/OneDemo'<!-- /if --><!-- if: ${alert} -->
|
||||||
|
import { VeuiAlert } from 'veui'<!-- /if -->
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [htmlAttrs],
|
mixins: [htmlAttrs],
|
||||||
components: {
|
components: {
|
||||||
<!-- for: ${components} as ${component}, ${index} -->${component}<!-- if: (${index} < ${component.length} - 1) && ${demos.length} -->,
|
<!-- for: ${components} as ${component}, ${index} -->${component}<!-- if: (${index} < ${component.length} - 1) && ${demos.length} -->,
|
||||||
<!-- /if--><!-- /for --><!-- for: ${demos} as ${demo}, ${index} -->'${demo.name}': Demo${index},
|
<!-- /if--><!-- /for --><!-- for: ${demos} as ${demo}, ${index} -->'${demo.name}': Demo${index},
|
||||||
<!-- /for --><!-- if: ${demos.length} -->OneDemo<!-- /if -->
|
<!-- /for --><!-- if: ${demos.length} -->OneDemo<!-- /if --><!-- if: (${components.length} || ${demos.length}) && ${alert} -->,<!-- /if --><!-- if: ${alert} -->
|
||||||
|
VeuiAlert<!-- /if -->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script><!-- else -->
|
</script><!-- else -->
|
||||||
|
Loading…
Reference in New Issue
Block a user