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

chore: initialize zui demo project

上级
import type { Styles, StyleSheet } from 'jss'
import { create } from 'jss'
import pluginCamelCase from 'jss-plugin-camel-case'
import pluginCompose from 'jss-plugin-compose'
import pluginDefaultUnit from 'jss-plugin-default-unit'
import pluginExpand from 'jss-plugin-expand'
import pluginExtend from 'jss-plugin-extend'
import pluginGlobal from 'jss-plugin-global'
import pluginNested from 'jss-plugin-nested'
import pluginPropsSort from 'jss-plugin-props-sort'
import pluginRuleValueFunction from 'jss-plugin-rule-value-function'
import preset from 'jss-preset-default'
const jss = create({
// 插件顺序会影响最终样式生成,不要轻易调整。
plugins: [
pluginNested(),
pluginCamelCase(),
pluginExpand(),
pluginExtend(),
pluginGlobal(),
pluginPropsSort(),
pluginRuleValueFunction(),
pluginDefaultUnit(),
pluginCompose(),
],
id: {
minify: true,
},
}).setup(preset())
export function createStyleSheet<T extends string>(style: Styles<T>, options?: Parameters<typeof jss.createStyleSheet>['1']) {
const res = jss.createStyleSheet(style, options)
res.attach()
return res as StyleSheet<T>
}
export function removeStyleSheet<T extends string>(styleSheet: StyleSheet<T>) {
styleSheet.detach()
jss.removeStyleSheet(styleSheet)
}
export * from './inject'
import type { InjectionKey } from 'vue'
export function createInjectionKey<T>(name: string): InjectionKey<T> {
return Symbol(name)
}
<template>
<ZAlert
type="info"
message="提示信息"
description="这是一条基础提示,用于展示 Alert 的默认结构。"
/>
</template>
# 警告提示 Alert
TODO: 补充不同类型、描述信息、可关闭和插槽自定义示例。
## 演示
<!-- DEMO -->
<demo vue="alert/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/alert/src/interface.ts` 补充 Props、Events 和 Slots 表格。
<!-- API -->
export { default as ZAlert } from './src/Alert.vue'
export * from './src/interface'
<script setup lang="ts">
import type { AlertEvents, AlertSlots } from './interface'
import { computed } from 'vue'
import { alertProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZAlert' })
const props = defineProps(alertProps)
const emit = defineEmits<AlertEvents>()
defineSlots<AlertSlots>()
const typeClass = computed(() => {
return {
info: styles.classes.info,
success: styles.classes.success,
warning: styles.classes.warning,
error: styles.classes.error,
}[props.type]
})
</script>
<template>
<div :class="[styles.classes.root, typeClass]">
<div :class="styles.classes.body">
<div :class="styles.classes.message">
<slot name="message">
{{ message }}
</slot>
</div>
<div
v-if="description || $slots.default"
:class="styles.classes.description"
>
<slot>
{{ description }}
</slot>
</div>
</div>
<button
v-if="closable"
type="button"
:class="styles.classes.close"
@click="emit('close')"
>
×
</button>
</div>
</template>
import type { ExtractPublicPropTypes, PropType, VNodeChild } from 'vue'
export type AlertType = 'info' | 'success' | 'warning' | 'error'
export const alertProps = {
type: {
type: String as PropType<AlertType>,
default: 'info',
},
message: String,
description: String,
closable: Boolean,
} as const
export type AlertProps = ExtractPublicPropTypes<typeof alertProps>
export interface AlertEvents {
(e: 'close'): void
}
export interface AlertSlots {
message?: () => VNodeChild
default?: () => VNodeChild
}
import { createStyleSheet } from '../../../_utils/jss'
export const styles = createStyleSheet({
root: {
display: 'flex',
gap: 12,
padding: 12,
borderRadius: 6,
border: '1px solid transparent',
},
body: {
flex: 1,
minWidth: 0,
},
message: {
fontWeight: 600,
lineHeight: '22px',
},
description: {
marginTop: 4,
fontSize: 14,
lineHeight: '22px',
},
close: {
border: 0,
background: 'transparent',
color: 'currentColor',
cursor: 'pointer',
},
info: {
borderColor: '#91caff',
background: '#e6f4ff',
color: '#0958d9',
},
success: {
borderColor: '#b7eb8f',
background: '#f6ffed',
color: '#237804',
},
warning: {
borderColor: '#ffe58f',
background: '#fffbe6',
color: '#ad6800',
},
error: {
borderColor: '#ffa39e',
background: '#fff1f0',
color: '#a8071a',
},
})
<template>
<ZAvatarTag name="张三" />
</template>
# 头像标签 AvatarTag
TODO: 补充组件用途、头像加载、颜色、默认插槽和空名称场景。
## 演示
<!-- DEMO -->
<demo vue="avatar-tag/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/avatar-tag/src/interface.ts` 补充 Props 和 Slots 表格。
<!-- API -->
export { default as ZAvatarTag } from './src/AvatarTag.vue'
export * from './src/interface'
<script setup lang="ts">
import type { AvatarTagSlots } from './interface'
import { computed } from 'vue'
import { avatarTagProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZAvatarTag' })
const props = defineProps(avatarTagProps)
defineSlots<AvatarTagSlots>()
const initial = computed(() => props.name.trim().slice(0, 1).toUpperCase())
</script>
<template>
<span :class="styles.classes.root">
<img
v-if="avatar"
:class="styles.classes.avatar"
:src="avatar"
:alt="name"
>
<span
v-else
:class="styles.classes.avatar"
:style="{ backgroundColor: color }"
>
{{ initial }}
</span>
<span :class="styles.classes.name">
<slot>
{{ name }}
</slot>
</span>
</span>
</template>
import type { ExtractPublicPropTypes, VNodeChild } from 'vue'
export const avatarTagProps = {
name: {
type: String,
default: '',
},
avatar: String,
color: {
type: String,
default: '#1677ff',
},
} as const
export type AvatarTagProps = ExtractPublicPropTypes<typeof avatarTagProps>
export interface AvatarTagSlots {
default?: () => VNodeChild
}
import { createStyleSheet } from '../../../_utils/jss'
export const styles = createStyleSheet({
root: {
display: 'inline-flex',
alignItems: 'center',
gap: 8,
height: 28,
padding: [2, 10, 2, 2],
border: '1px solid #e5e6eb',
borderRadius: 14,
background: '#fff',
},
avatar: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
width: 24,
height: 24,
borderRadius: '50%',
color: '#fff',
fontSize: 12,
fontWeight: 600,
objectFit: 'cover',
},
name: {
color: '#1f2329',
fontSize: 14,
lineHeight: '20px',
},
})
<template>
<ZBadge :value="8">
<ZButton>消息</ZButton>
</ZBadge>
</template>
# 徽标 Badge
TODO: 补充数字徽标、红点、自定义颜色、最大值等示例。
## 演示
<!-- DEMO -->
<demo vue="badge/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/badge/src/interface.ts` 补充 Props 和 Slots 表格。
<!-- API -->
export { default as ZBadge } from './src/Badge.vue'
export * from './src/interface'
<script setup lang="ts">
import { computed } from 'vue'
import { badgeProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZBadge' })
const props = defineProps(badgeProps)
const displayValue = computed(() => {
if (props.dot)
return ''
if (typeof props.value === 'number' && props.max && props.value > props.max)
return `${props.max}+`
return props.value
})
</script>
<template>
<span :class="styles.classes.root">
<slot />
<sup
:class="[styles.classes.badge, dot ? styles.classes.dot : undefined]"
:style="{ backgroundColor: color }"
>
{{ displayValue }}
</sup>
</span>
</template>
import type { ExtractPublicPropTypes, PropType, VNodeChild } from 'vue'
export const badgeProps = {
value: [String, Number] as PropType<string | number>,
max: Number,
dot: Boolean,
color: {
type: String,
default: '#ff4d4f',
},
} as const
export type BadgeProps = ExtractPublicPropTypes<typeof badgeProps>
export interface BadgeSlots {
default?: () => VNodeChild
}
支持 Markdown
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册