pull/8354/merge
selicens 2025-09-12 17:42:25 +08:00 committed by GitHub
commit 9e14e19403
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 573 additions and 0 deletions

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
</script>
<template>
<a-divider style="border-width: 2px; border-color: #7cb305" />
<a-divider style="border-color: #7cb305" dashed />
<a-divider style="border-color: #7cb305" dashed>
Text
</a-divider>
<a-divider type="vertical" style="height: 60px; border-color: #7cb305" />
<a-divider type="vertical" style="height: 60px; border-color: #7cb305" dashed />
<div style="display: flex; flex-direction: column; height: 50px; box-shadow: 0 0 1px red">
<a-divider style="background: rgba(0,255,0,0.05)" orientation="left">
Text
</a-divider>
</div>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,24 @@
<script setup lang="ts">
</script>
<template>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider dashed />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,33 @@
<script setup lang="ts">
</script>
<template>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider plain>Text</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider orientation="left" plain>
Left Text
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider orientation="right" plain>
Right Text
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,29 @@
<script setup lang="ts">
</script>
<template>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider size="small" />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider size="middle" />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider size="large" />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,35 @@
<script setup lang="ts">
</script>
<template>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider style="border-color: #7cb305">
Solid
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider variant="dotted" style="border-color: #7cb305">
Dotted
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider variant="dashed" style="border-color: #7cb305" dashed>
Dashed
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,15 @@
<script setup lang="ts">
</script>
<template>
Text
<a-divider type="vertical"></a-divider>
<a href="#">Link</a>
<a-divider type="vertical"></a-divider>
<a href="#">Link</a>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,47 @@
<script setup lang="ts">
</script>
<template>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider>Text</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider orientation="left">
Left Text
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider orientation="right">
Right Text
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider orientation="left" orientation-margin="0">
Left Text with 0 orientationMargin
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
<a-divider orientation="right" orientation-margin="50px">
Right Text with 50px orientationMargin
</a-divider>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista
probare, quae sunt a te dicta? Refert tamen, quo modo.
</p>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,3 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Divider > should render correctly 1`] = `"<div class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center" role="separator"><span class="ant-divider-inner-text">test</span></div>"`;

View File

@ -0,0 +1,76 @@
import { describe, expect, it, vi } from 'vitest'
import { Divider } from '@ant-design-vue/ui'
import { mount } from '@vue/test-utils'
describe('Divider', () => {
it('should render correctly', () => {
const wrapper = mount(Divider, {
slots: {
default: `test`
}
})
expect(wrapper.html()).toMatchSnapshot()
});
it('not show children when vertical', () => {
const wrapper = mount(Divider, {
props: {
orientation: 'right',
orientationMargin: '10px',
},
slots: {
default: `test`,
},
})
expect(wrapper.find('.ant-divider-inner-text').exists()).toBe(true)
const innerTextElement = wrapper.find('.ant-divider-inner-text')
expect(innerTextElement.attributes('style')).toContain('margin-inline-end: 10px')
})
it('support bool dashed', () => {
const wrapper = mount(Divider, {
props: {
dashed: true,
},
slots: {
default: `test`,
},
})
expect(wrapper.find('.ant-divider-dashed').exists()).toBe(true)
})
it('support string variant', () => {
const wrapper = mount(Divider, {
props: {
variant: 'dotted',
},
slots: {
default: `test`,
},
})
expect(wrapper.find('.ant-divider-dotted').exists()).toBe(true)
})
it('support vertical size', () => {
const wrapper1= mount(Divider, {
props: {
size: 'small',
},
slots: {
default: `test`,
},
})
expect(wrapper1.find('.ant-divider-sm')).toBeTruthy();
const wrapper2 = mount(Divider, {
props: {
size: 'middle',
},
slots: {
default: `test`,
},
})
expect(wrapper2.find('.ant-divider-md')).toBeTruthy()
})
})

View File

@ -0,0 +1,87 @@
<script setup lang="ts">
import type { ComputedRef, CSSProperties } from 'vue'
import { computed, shallowRef } from 'vue'
import type { DividerProps, DividerSlots } from './meta'
import { DividerDefaultProps } from './meta'
type SizeType = 'small' | 'middle' | 'large' | undefined
const props = withDefaults(defineProps<DividerProps>(), DividerDefaultProps)
const slots = defineSlots<DividerSlots>()
const prefixCls = props.prefixCls
// directionconfig-provider
const direction = shallowRef<'ltr' | 'rtl'>('ltr')
const sizeClassNameMap: Record<string, string> = { small: 'sm', middle: 'md' }
// config-provider
function useSize<T extends string | undefined | number | object>(customSize?: T | ((ctxSize: SizeType) => T)): ComputedRef<T> {
// sizeconfig-provider
const size = undefined
return computed(() => {
if (!customSize) {
return size as T
}
if (typeof customSize === 'string') {
return customSize ?? size
}
if (typeof customSize === 'function') {
return customSize(size)
}
return size as T
})
}
const sizeFullName = useSize(props.size)
const sizeCls = computed(() => sizeClassNameMap[sizeFullName.value])
const hasChildren = computed(() => !!slots.default)
const mergedOrientation = computed(() => {
if (props.orientation === 'left') {
return direction.value === 'rtl' ? 'end' : 'start'
}
if (props.orientation === 'right') {
return direction.value === 'rtl' ? 'start' : 'end'
}
return props.orientation
})
const hasMarginStart = computed(() => mergedOrientation.value === 'start' && props.orientationMargin !== null)
const hasMarginEnd = computed(() => mergedOrientation.value === 'end' && props.orientationMargin !== null)
const cls = computed(() => {
return {
[prefixCls]: true,
[`${prefixCls}-${props.type}`]: true,
[`${prefixCls}-with-text`]: hasChildren.value,
[`${prefixCls}-with-text-${mergedOrientation.value}`]: hasChildren.value,
[`${prefixCls}-dashed`]: !!props.dashed,
[`${prefixCls}-${props.variant}`]: props.variant !== 'solid',
[`${prefixCls}-plain`]: !!props.plain,
[`${prefixCls}-rtl`]: direction.value === 'rtl',
[`${prefixCls}-no-default-orientation-margin-start`]: hasMarginStart.value,
[`${prefixCls}-no-default-orientation-margin-end`]: hasMarginEnd.value,
[`${prefixCls}-${sizeCls.value}`]: !!sizeCls.value,
}
})
const memoizedOrientationMargin = computed(() => {
if (typeof props.orientationMargin === 'number') {
return props.orientationMargin
}
if (/^\d+$/.test(props.orientationMargin!)) {
return Number(props.orientationMargin)
}
return props.orientationMargin!
})
const innerStyle: CSSProperties = {
marginInlineStart: hasMarginStart.value ? memoizedOrientationMargin.value : undefined,
marginInlineEnd: hasMarginEnd.value ? memoizedOrientationMargin.value : undefined,
}
</script>
<template>
<div v-bind="$attrs" :class="[cls]" :style="[innerStyle]" role="separator">
<template v-if="$slots.default && type !== 'vertical'">
<span :class="[`${prefixCls}-inner-text`]" :style="innerStyle">
<slot />
</span>
</template>
</div>
</template>
<style scoped></style>

View File

@ -0,0 +1,12 @@
import type { App, Plugin } from 'vue'
import Divider from './divider.vue'
import './style/index.css'
export { default as Divider } from './divider.vue'
Divider.install = function(app: App){
app.component('ADivider', Divider)
return app
}
export default Divider as typeof Divider & Plugin

View File

@ -0,0 +1,36 @@
type SizeType = 'small' | 'middle' | 'large' | undefined
export type DividerProps = {
prefixCls?: string
type?: 'horizontal' | 'vertical'
/**
* @default center
*/
orientation?:
| 'left'
| 'right'
| 'center'
| 'start' // 👈 5.24.0+
| 'end' // 👈 5.24.0+
orientationMargin?: string | number
rootClassName?: string
dashed?: boolean
/**
* @since 5.20.0
* @default solid
*/
variant?: 'dashed' | 'dotted' | 'solid'
size?: SizeType
plain?: boolean
}
export const DividerDefaultProps = {
prefixCls: 'ant-divider',
type: 'horizontal',
orientation: 'center',
variant: 'solid',
} as const
export type DividerSlots = {
default: any
}

View File

@ -0,0 +1,152 @@
@reference '../../../style/tailwind.css';
.ant-divider {
@apply box-border;
@apply m-0;
@apply p-0;
@apply text-black/[0.88];
@apply text-sm;
@apply leading-[1.5714285714285714];
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
list-style: none;
border-block-start: 1px solid rgba(5, 5, 5, 0.06);
&:where(.ant-divider-vertical) {
@apply relative;
@apply top-[-0.06em];
@apply inline-block;
@apply h-3.5;
@apply mx-[1em];
@apply my-0;
@apply align-middle;
border-top: 0;
border-inline-start: 1px solid rgba(5, 5, 5, 0.06);
}
&:where(.ant-divider-horizontal) {
@apply flex;
@apply clear-both;
@apply w-full;
@apply min-w-full;
/* @apply my-6;
@apply mx-0; */
margin: 24px 0;
}
&:where(.ant-divider-horizontal.ant-divider-with-text) {
@apply flex;
@apply items-center;
@apply font-medium;
@apply text-[16px];
@apply whitespace-nowrap;
@apply text-center;
margin: 16px 0;
border-block-start: 0 rgba(5, 5, 5, 0.06);
color: rgba(0, 0, 0, 0.88);
}
&:where(.ant-divider-horizontal.ant-divider-with-text)::before, &:where(.ant-divider-horizontal.ant-divider-with-text)::after{
@apply relative;
@apply w-2/4;
border-block-start: 1px solid transparent;
border-block-start-color: inherit;
border-block-end: 0;
transform: translateY(50%);
content: '';
}
&:where(.ant-dividerhorizontal.ant-divider-with-text-start)::before{
width: calc(0.05px * 100%);
}
&:where(.ant-dividerhorizontal.ant-divider-with-text-start)::after {
width: calc(100% - 0.05px * 100%);
}
&:where(.ant-dividerhorizontal.ant-divider-with-text-end)::before{
width: calc(100% - 0.05px * 100%);
}
&:where(.ant-dividerhorizontal.ant-divider-with-text-end)::after {
width: calc(0.05px * 100%);
}
.ant-divider-inner-text {
@apply inline-block;
@apply py-0;
@apply px-[1em];
}
&:where(.ant-divider-dashed) {
background: none;
border-color: rgba(5, 5, 5, 0.06);
@apply border-dashed;
border-width: 1px 0 0;
}
&:where(.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed)::before, &:where(.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed)::after {
border-style: dashed none none;
}
&:where(.ant-divider-vertical.ant-divider-dashed) {
@apply border-s-1;
border-inline-end: 0;
border-block-start: 0;
border-block-end: 0;
}
&:where(.ant-divider-dotted) {
background: none;
border-color: rgba(5, 5, 5, 0.06);
@apply border-dotted;
border-width: 1px 0 0;
}
&:where(.ant-divider-horizontal.ant-divider-with-text.ant-divider-dotted)::before, &:where(.ant-divider-horizontal.ant-divider-with-text.ant-divider-dotted)::after {
border-style: dotted none none;
}
&:where(.ant-divider-vertical.ant-divider-dotted) {
@apply border-s-1;
border-inline-end: 0;
border-block-start: 0;
border-block-end: 0;
}
&:where(.ant-divider-plain.ant-divider-with-text) {
color: rgba(0, 0, 0, 0.88);
@apply font-normal;
@apply text-[14px];
}
&:where(.ant-divider-horizontal.ant-divider-with-text-start.ant-divider-no-default-orientation-margin-start) {
.ant-divider-inner-text {
@apply ms-0;
}
}
&:where(.ant-divider-horizontal.ant-divider-with-text-start.ant-divider-no-default-orientation-margin-start)::before {
@apply w-0;
}
&:where(.ant-divider-horizontal.ant-divider-with-text-start.ant-divider-no-default-orientation-margin-start)::after {
@apply w-full;
}
&:where(.ant-divider-horizontal.ant-divider-with-text-end.ant-divider-no-default-orientation-margin-end) {
.ant-divider-inner-text {
@apply ms-0;
}
}
&:where(.ant-divider-horizontal.ant-divider-with-text-end.ant-divider-no-default-orientation-margin-end)::before {
@apply w-full;
}
&:where(.ant-divider-horizontal.ant-divider-with-text-end.ant-divider-no-default-orientation-margin-end)::after {
@apply w-0;
}
}
.ant-divider {
&:where(.ant-divider-horizontal) {
&:where(.ant-divider) {
&:where(.ant-divider-sm) {
@apply my-[8px];
}
&:where(.ant-divider-md) {
@apply my-[16px];
}
}
}
}

View File

@ -3,3 +3,4 @@ export { default as Input } from './input'
export { default as Theme } from './theme'
export { default as Affix } from './affix'
export { default as Flex } from './flex'
export { default as Divider } from './divider'