feature(divider): 增加 Divider 组件 (#354 close) (#471)

* feature(divider): 增加 Divider 组件 (#354 close)

* fix: 移除 lock 文件的提交

* fix: 还原移除的 pnpm-lock.yaml 文件

* fix: 使用 dev 覆盖本地 pnpm-lock.yaml.lock 文件
This commit is contained in:
vaebe 2023-09-13 18:05:03 +08:00 committed by GitHub
parent 9911dd4a31
commit 7d6120ed1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 484 additions and 15 deletions

View File

@ -0,0 +1,13 @@
<template>
<tiny-divider></tiny-divider>
</template>
<script lang="jsx">
import { Divider } from '@opentiny/vue'
export default {
components: {
TinyDivider: Divider
}
}
</script>

View File

@ -0,0 +1,18 @@
<template>
<p>文案在左侧</p>
<tiny-divider content-position="left">文案</tiny-divider>
<p>文案在中间</p>
<tiny-divider content-position="center">文案</tiny-divider>
<p>文案在右侧</p>
<tiny-divider content-position="right">文案</tiny-divider>
</template>
<script lang="jsx">
import { Divider } from '@opentiny/vue'
export default {
components: {
TinyDivider: Divider
}
}
</script>

View File

@ -0,0 +1,20 @@
<template>
<p>自定义分隔线颜色</p>
<tiny-divider color="#7693f5"></tiny-divider>
<p>自定义分隔线的样式</p>
<tiny-divider border-style="dashed"></tiny-divider>
<p>自定义文案的颜色</p>
<tiny-divider content-color="#7693f5">文案</tiny-divider>
<p>文案的背景颜色</p>
<tiny-divider content-color="#ffffff" content-background-color="#7693f5">文案</tiny-divider>
</template>
<script lang="jsx">
import { Divider } from '@opentiny/vue'
export default {
components: {
TinyDivider: Divider
}
}
</script>

View File

@ -0,0 +1,17 @@
<template>
<span>分隔线</span>
<tiny-divider direction="vertical"></tiny-divider>
<span>分隔线</span>
<tiny-divider direction="vertical"></tiny-divider>
<span>分隔线</span>
</template>
<script lang="jsx">
import { Divider } from '@opentiny/vue'
export default {
components: {
TinyDivider: Divider
}
}
</script>

View File

@ -0,0 +1,7 @@
---
title: Divider 分隔线
---
# Divider 分隔线
<div>Divider 分隔线组件,用于对不同内容的分隔。</div>

View File

@ -0,0 +1,7 @@
---
title: Divider
---
# Divider
<div>Divider divider component, Used to separate different content.</div>

View File

@ -0,0 +1,109 @@
export default {
column: '2',
owner: '',
demos: [
{
'demoId': 'basic-usage',
'name': { 'zh-CN': '基本用法', 'en-US': 'Basic Usage' },
'desc': { 'zh-CN': '详细用法参考如下示例', 'en-US': 'For details, see the following example.' },
'codeFiles': ['base.vue']
},
{
'demoId': 'direction',
'name': { 'zh-CN': '垂直分隔线', 'en-US': 'Basic Usage' },
'desc': {
'zh-CN': '通过 props direction 可以设置分隔线的方向',
'en-US': 'The direction of the divider can be set using the props "direction".'
},
'codeFiles': ['direction.vue']
},
{
'demoId': 'content-position',
'name': { 'zh-CN': '分隔线文案的位置', 'en-US': 'Basic Usage' },
'desc': {
'zh-CN': '通过 props content-position 可以分隔线文案的位置',
'en-US': 'The position of the divider content can be set using the prop "content-position".'
},
'codeFiles': ['contentPosition.vue']
},
{
'demoId': 'custom-style',
'name': { 'zh-CN': '自定义分隔线样式', 'en-US': 'Basic Usage' },
'desc': {
'zh-CN': '通过 props 自定义分隔线样式',
'en-US': 'You can customize the divider style through props.'
},
'codeFiles': ['customStyle.vue']
}
],
apis: [
{
'name': 'divider',
'type': 'component',
'properties': [
{
'name': 'color',
'type': 'string',
'defaultValue': '',
'desc': { 'zh-CN': '设置分隔线的颜色', 'en-US': 'Set the color of the divider.' },
'demoId': 'basic-usage'
},
{
'name': 'direction',
'type': 'string',
'defaultValue': 'horizontal',
'desc': {
'zh-CN': '设置分隔线的方向,该属性的可选值为 horizontal / vertical 。',
'en-US':
'Set the direction of the divider; the possible values for this property are "horizontal" or "vertical".'
},
'demoId': 'direction'
},
{
'name': 'content-position',
'type': 'string',
'defaultValue': 'center',
'desc': {
'zh-CN': '设置分隔线文案的位置,该属性的可选值为 left / center / right 。',
'en-US':
'Set the position of the divider content; the possible values for this property are "left", "center", or "right".'
},
'demoId': 'contentPosition'
},
{
'name': 'border-style',
'type': 'string',
'defaultValue': 'solid',
'desc': {
'zh-CN': '设置分隔线的样式,该属性的可选值为 solid / dashed',
'en-US': 'Set the style of the divider; the possible values for this property are "solid" or "dashed".'
},
'demoId': 'custom-style'
},
{
'name': 'content-color',
'type': 'string',
'defaultValue': '',
'desc': { 'zh-CN': '设置分隔线文案的颜色', 'en-US': 'Set the color of the divider content.' },
'demoId': 'custom-style'
},
{
'name': 'content-background-color',
'type': 'string',
'defaultValue': '',
'desc': { 'zh-CN': '设置分割线文案的背景颜色', 'en-US': 'Set the background color of the divider content.' },
'demoId': 'custom-style'
}
],
'slots': [
{
'name': 'default',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '默认插槽', 'en-US': 'Default slot' },
'demoId': 'content-position'
}
]
}
]
}

View File

@ -241,7 +241,8 @@ export const cmpMenus = [
{ 'nameCn': '联系人', 'name': 'UserContact', 'key': 'user-contact' },
{ 'nameCn': '用户头像', 'name': 'UserHead', 'key': 'user-head' },
{ 'nameCn': '全屏显示', 'name': 'Fullscreen', 'key': 'fullscreen' },
{ 'nameCn': '全局设置', 'name': 'ConfigProvider', 'key': 'config-provider' }
{ 'nameCn': '全局设置', 'name': 'ConfigProvider', 'key': 'config-provider' },
{ 'nameCn': '分割线', 'name': 'Divider', 'key': 'divider' }
]
}
]

View File

@ -7,14 +7,6 @@
"pc"
]
},
"RichTextEditor": {
"path": "vue/src/rich-text-editor/index.ts",
"type": "component",
"exclude": false,
"mode": [
"pc"
]
},
"ActionSheet": {
"path": "vue/src/action-sheet/index.ts",
"type": "component",
@ -360,13 +352,13 @@
"mobile"
]
},
"CascaderSelectMobileFirst": {
"path": "vue/src/cascader-select/src/mobile-first.vue",
"CascaderSelectMobile": {
"path": "vue/src/cascader-select/src/mobile.vue",
"type": "template",
"exclude": false
},
"CascaderSelectMobile": {
"path": "vue/src/cascader-select/src/mobile.vue",
"CascaderSelectMobileFirst": {
"path": "vue/src/cascader-select/src/mobile-first.vue",
"type": "template",
"exclude": false
},
@ -613,6 +605,20 @@
"ColorPicker": {
"path": "vue/src/color-picker/index.ts",
"type": "component",
"exclude": false,
"mode": [
"mobile",
"pc"
]
},
"ColorPickerMobile": {
"path": "vue/src/color-picker/src/mobile.vue",
"type": "template",
"exclude": false
},
"ColorPickerPc": {
"path": "vue/src/color-picker/src/pc.vue",
"type": "template",
"exclude": false
},
"ColumnListGroup": {
@ -846,6 +852,19 @@
"type": "template",
"exclude": false
},
"Divider": {
"path": "vue/src/divider/index.ts",
"type": "component",
"exclude": false,
"mode": [
"pc"
]
},
"DividerPc": {
"path": "vue/src/divider/src/pc.vue",
"type": "template",
"exclude": false
},
"Drawer": {
"path": "vue/src/drawer/index.ts",
"type": "component",
@ -1911,6 +1930,14 @@
"type": "template",
"exclude": false
},
"RichTextEditor": {
"path": "vue/src/rich-text-editor/index.ts",
"type": "component",
"exclude": false,
"mode": [
"pc"
]
},
"River": {
"path": "vue/src/river/index.ts",
"type": "component",
@ -2689,4 +2716,4 @@
"pc"
]
}
}
}

View File

@ -0,0 +1,5 @@
export const api = []
export const renderless = () => {
return api
}

View File

@ -0,0 +1,49 @@
@import '../custom.less';
@import './vars.less';
@divider-prefix-cls: ~'@{css-prefix}divider';
.@{divider-prefix-cls} {
.component-css-vars-divider();
position: relative;
&&--horizontal {
display: block;
height: 1px;
margin: 24px 0;
border-top: var(--ti-divider-dividing-line);
}
&&--vertical {
display: inline-block;
width: 1px;
height: 1em;
margin: 0 8px;
vertical-align: middle;
border-left: var(--ti-divider-dividing-line);
}
&__text {
position: absolute;
padding: 0 20px;
font-size: 14px;
font-weight: 500;
color: var(--ti-divider-text-color);
background-color: var(--ti-divider-text-bg);
&.is-left {
left: 20px;
transform: translateY(-50%);
}
&.is-center {
left: 50%;
transform: translate(-50%) translateY(-50%);
}
&.is-right {
right: 20px;
transform: translateY(-50%);
}
}
}

View File

@ -0,0 +1,5 @@
.component-css-vars-divider() {
--ti-divider-dividing-line: 1px solid var(--ti-common-color-border);
--ti-divider-text-bg: var(--ti-base-color-bg-1);
--ti-divider-text-color: var(--ti-common-color-text-primary);
}

View File

@ -107,6 +107,7 @@
"@opentiny/vue-detail-page": "workspace:~",
"@opentiny/vue-dialog-box": "workspace:~",
"@opentiny/vue-dialog-select": "workspace:~",
"@opentiny/vue-divider": "workspace:~",
"@opentiny/vue-drawer": "workspace:~",
"@opentiny/vue-drop-roles": "workspace:~",
"@opentiny/vue-drop-times": "workspace:~",

View File

@ -0,0 +1,73 @@
import { mountPcMode } from '@opentiny-internal/vue-test-utils'
import { describe, test, expect } from 'vitest'
import Divider from '@opentiny/vue-divider'
describe('PC Mode', () => {
const mount = mountPcMode
test('base 基本用法', async () => {
const wrapper = mount(() => <Divider></Divider>)
const triggerEle = wrapper.find('.tiny-divider')
expect(triggerEle.exists()).toBe(true)
wrapper.unmount()
})
test('props direction', async () => {
const wrapper = mount(() => <Divider direction="vertical"></Divider>)
expect(wrapper.find('.tiny-divider--vertical').exists()).toBeTruthy()
wrapper.unmount()
})
test('props content position', async () => {
const wrapper = mount(() => <Divider contentPosition="center"></Divider>)
expect(wrapper.find('.is-center').exists()).toBeTruthy()
wrapper.unmount()
})
test('custom border color', async () => {
const borderColor = 'red'
const wrapper = mount(() => <Divider color={borderColor}></Divider>)
const style = window.getComputedStyle(wrapper.element)
expect(style.borderColor).toBe(borderColor)
wrapper.unmount()
})
test('custom text style', async () => {
const contentColor = 'red'
const contentBackgroundColor = 'orange'
const wrapper = mount(() => (
<Divider contentColor={contentColor} contentBackgroundColor={contentBackgroundColor}>
</Divider>
))
const textDom = wrapper.find('.tiny-divider__text')
const textStyle = window.getComputedStyle(textDom.element)
expect(textStyle.color).toBe(contentColor)
expect(textStyle.backgroundColor).toBe(contentBackgroundColor)
wrapper.unmount()
})
test('slots', async () => {
const TEXT = 'slots'
const wrapper = mount(() => <Divider>{TEXT}</Divider>)
expect(wrapper.find('.tiny-divider').text()).toBe(TEXT)
wrapper.unmount()
})
})

View File

@ -0,0 +1,19 @@
import Divider from './src/index'
import '@opentiny/vue-theme/divider/index.less'
import { version } from './package.json'
/* istanbul ignore next */
Divider.install = function (Vue) {
Vue.component(Divider.name, Divider)
}
Divider.version = version
/* istanbul ignore next */
if (process.env.BUILD_TARGET === 'runtime') {
if (typeof window !== 'undefined' && window.Vue) {
Divider.install(window.Vue)
}
}
export default Divider

View File

@ -0,0 +1,18 @@
{
"name": "@opentiny/vue-divider",
"version": "3.7.0",
"description": "",
"main": "lib/index.js",
"module": "index.ts",
"sideEffects": false,
"type": "module",
"devDependencies": {
"@opentiny-internal/vue-test-utils": "workspace:*",
"vitest": "^0.31.0"
},
"dependencies": {
"@opentiny/vue-common": "workspace:~",
"@opentiny/vue-renderless": "workspace:~"
},
"license": "MIT"
}

View File

@ -0,0 +1,47 @@
import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common'
import type { PropType } from '@opentiny/vue-common'
import template from 'virtual-template?pc|mobile-first'
export type DirectionType = 'horizontal' | 'vertical'
export type BorderStyleType = 'dashed' | 'solid'
export type ContentPositionType = 'left' | 'right' | 'center'
const $constants = {}
export default defineComponent({
name: $prefix + 'Divider',
props: {
...$props,
_constants: {
type: Object,
default: () => $constants
},
direction: {
type: String as PropType<DirectionType>,
default: 'horizontal'
},
color: {
type: String,
default: ''
},
borderStyle: {
type: String as PropType<BorderStyleType>,
default: 'solid'
},
contentPosition: {
type: String as PropType<ContentPositionType>,
default: 'center'
},
contentColor: {
type: String,
default: ''
},
contentBackgroundColor: {
type: String,
default: ''
}
},
setup(props, context) {
return $setup({ props, context, template })
}
})

View File

@ -0,0 +1,33 @@
<template>
<div
:class="['tiny-divider', 'tiny-divider--' + direction]"
:style="{
'border-top-style': direction === 'horizontal' ? borderStyle : '',
'border-left-style': direction === 'vertical' ? borderStyle : '',
'border-color': color
}"
>
<div
v-if="slots.default"
:class="['tiny-divider__text', 'is-' + contentPosition]"
:style="{
color: contentColor,
'background-color': contentBackgroundColor
}"
>
<slot></slot>
</div>
</div>
</template>
<script>
import { renderless, api } from '@opentiny/vue-renderless/divider/vue'
import { props, setup, defineComponent } from '@opentiny/vue-common'
export default defineComponent({
props: [...props, 'direction', 'color', 'borderStyle', 'contentPosition', 'contentColor', 'contentBackgroundColor'],
setup(props, context) {
return setup({ props, context, renderless, api })
}
})
</script>

View File

@ -25295,4 +25295,4 @@ packages:
resolution: {integrity: sha512-M4Z05BHWtajY2241EmMPHglDQAJ1UyHQcYsxDNzD9XLSkPDqMq4bB28v9Pb4mvHnVQ0GxyTklZ/69xCFP6RXBA==}
dependencies:
tslib: 2.4.0
dev: false
dev: false