未验证 提交 3bdb469b 编辑于 作者: cyole's avatar cyole
浏览文件

chore: initialize zui demo project

上级
import { mount } from '@vue/test-utils'
import { ZExampleButton } from '../index'
describe('exampleButton', () => {
it('renders slot content', () => {
const wrapper = mount(ZExampleButton, {
slots: {
default: '保存',
},
})
expect(wrapper.text()).toContain('保存')
})
it('emits click event', async () => {
const wrapper = mount(ZExampleButton)
await wrapper.trigger('click')
expect(wrapper.emitted('click')).toHaveLength(1)
})
it('does not emit click when disabled or loading', async () => {
const disabled = mount(ZExampleButton, {
props: {
disabled: true,
},
})
const loading = mount(ZExampleButton, {
props: {
loading: true,
},
})
await disabled.trigger('click')
await loading.trigger('click')
expect(disabled.emitted('click')).toBeUndefined()
expect(loading.emitted('click')).toBeUndefined()
})
})
/// <reference types="vite/client" />
export {}
declare global {
}
interface ImportMetaEnv {
readonly MODE: 'development' | 'production'
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
export * from './alert'
export * from './avatar-tag'
export * from './badge'
export * from './button'
export * from './card'
export * from './components'
export * from './composables'
export * from './copy-text'
export * from './divider'
export * from './empty'
export * from './example-button'
export * from './loading'
export * from './progress'
export * from './section-title'
export * from './stat-card'
export * from './status-dot'
export * from './tag'
export * from './tip'
<template>
<ZLoading tip="加载中">
<div style="height: 96px; border: 1px solid #e5e6eb; border-radius: 8px;" />
</ZLoading>
</template>
# 加载 Loading
TODO: 补充局部加载、加载文案、包裹内容和关闭加载态示例。
## 演示
<!-- DEMO -->
<demo vue="loading/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/loading/src/interface.ts` 补充 Props 和 Slots 表格。
<!-- API -->
export * from './src/interface'
export { default as ZLoading } from './src/Loading.vue'
<script setup lang="ts">
import type { LoadingSlots } from './interface'
import { loadingProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZLoading' })
defineProps(loadingProps)
defineSlots<LoadingSlots>()
</script>
<template>
<div :class="styles.classes.root">
<slot />
<div
v-if="spinning"
:class="styles.classes.mask"
>
<span :class="styles.classes.spinner" />
<span
v-if="tip"
:class="styles.classes.tip"
>
{{ tip }}
</span>
</div>
</div>
</template>
import type { ExtractPublicPropTypes, VNodeChild } from 'vue'
export const loadingProps = {
spinning: {
type: Boolean,
default: true,
},
tip: String,
} as const
export type LoadingProps = ExtractPublicPropTypes<typeof loadingProps>
export interface LoadingSlots {
default?: () => VNodeChild
}
import { createStyleSheet } from '../../../_utils/jss'
export const styles = createStyleSheet({
'root': {
position: 'relative',
minHeight: 48,
},
'mask': {
position: 'absolute',
inset: 0,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
background: 'rgb(255 255 255 / 0.72)',
},
'spinner': {
width: 20,
height: 20,
border: '2px solid #1677ff',
borderTopColor: 'transparent',
borderRadius: '50%',
animation: '$spin 0.8s linear infinite',
},
'tip': {
color: '#4e5969',
fontSize: 14,
},
'@keyframes spin': {
to: {
transform: 'rotate(360deg)',
},
},
})
<template>
<ZProgress :percent="60" />
</template>
# 进度条 Progress
TODO: 补充基础进度、自定义颜色、隐藏文字和边界值示例。
## 演示
<!-- DEMO -->
<demo vue="progress/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/progress/src/interface.ts` 补充 Props 表格。
<!-- API -->
export * from './src/interface'
export { default as ZProgress } from './src/Progress.vue'
<script setup lang="ts">
import { computed } from 'vue'
import { progressProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZProgress' })
const props = defineProps(progressProps)
const safePercent = computed(() => Math.min(100, Math.max(0, props.percent)))
</script>
<template>
<div
:class="styles.classes.root"
role="progressbar"
:aria-valuenow="safePercent"
aria-valuemin="0"
aria-valuemax="100"
>
<div :class="styles.classes.track">
<div
:class="styles.classes.bar"
:style="{ width: `${safePercent}%`, backgroundColor: color }"
/>
</div>
<span
v-if="showText"
:class="styles.classes.text"
>
{{ safePercent }}%
</span>
</div>
</template>
import type { ExtractPublicPropTypes } from 'vue'
export const progressProps = {
percent: {
type: Number,
default: 0,
},
color: {
type: String,
default: '#1677ff',
},
showText: {
type: Boolean,
default: true,
},
} as const
export type ProgressProps = ExtractPublicPropTypes<typeof progressProps>
import { createStyleSheet } from '../../../_utils/jss'
export const styles = createStyleSheet({
root: {
display: 'flex',
alignItems: 'center',
gap: 8,
width: '100%',
},
track: {
flex: 1,
height: 8,
overflow: 'hidden',
borderRadius: 4,
background: '#f2f3f5',
},
bar: {
height: '100%',
borderRadius: 4,
transition: 'width 0.2s ease',
},
text: {
minWidth: 38,
color: '#4e5969',
fontSize: 13,
textAlign: 'right',
},
})
<template>
<ZSectionTitle
title="用户管理"
description="管理用户信息、角色和状态。"
/>
</template>
# 区块标题 SectionTitle
TODO: 补充基础标题、描述文案、右侧操作和插槽自定义示例。
## 演示
<!-- DEMO -->
<demo vue="section-title/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/section-title/src/interface.ts` 补充 Props 和 Slots 表格。
<!-- API -->
export * from './src/interface'
export { default as ZSectionTitle } from './src/SectionTitle.vue'
<script setup lang="ts">
import type { SectionTitleSlots } from './interface'
import { sectionTitleProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZSectionTitle' })
defineProps(sectionTitleProps)
defineSlots<SectionTitleSlots>()
</script>
<template>
<header :class="styles.classes.root">
<div :class="styles.classes.main">
<h2 :class="styles.classes.title">
<slot>
{{ title }}
</slot>
</h2>
<p
v-if="description || $slots.description"
:class="styles.classes.description"
>
<slot name="description">
{{ description }}
</slot>
</p>
</div>
<slot name="actions" />
</header>
</template>
import type { ExtractPublicPropTypes, VNodeChild } from 'vue'
export const sectionTitleProps = {
title: {
type: String,
default: '',
},
description: String,
} as const
export type SectionTitleProps = ExtractPublicPropTypes<typeof sectionTitleProps>
export interface SectionTitleSlots {
default?: () => VNodeChild
description?: () => VNodeChild
actions?: () => VNodeChild
}
支持 Markdown
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册