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

chore: initialize zui demo project

上级
import { createStyleSheet } from '../../../_utils/jss'
export const styles = createStyleSheet({
root: {
position: 'relative',
display: 'inline-flex',
},
badge: {
position: 'absolute',
top: 0,
right: 0,
minWidth: 16,
height: 16,
padding: [0, 5],
borderRadius: 8,
color: '#fff',
fontSize: 12,
lineHeight: '16px',
textAlign: 'center',
transform: 'translate(50%, -50%)',
transformOrigin: '100% 0%',
},
dot: {
minWidth: 8,
width: 8,
height: 8,
padding: 0,
borderRadius: '50%',
},
})
<template>
<div style="display: flex; gap: 12px;">
<ZButton>默认按钮</ZButton>
<ZButton type="primary">
主要按钮
</ZButton>
<ZButton type="danger">
危险按钮
</ZButton>
</div>
</template>
# 按钮 Button
TODO: 补充组件用途、适用场景和注意事项。
## 演示
<!-- DEMO -->
<demo vue="button/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/button/src/interface.ts` 补充 Props、Events、Slots 表格。
<!-- API -->
export { default as ZButton } from './src/Button.vue'
export * from './src/interface'
<script setup lang="ts">
import type { ButtonEvents, ButtonSlots } from './interface'
import { computed } from 'vue'
import { buttonProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZButton' })
const props = defineProps(buttonProps)
const emit = defineEmits<ButtonEvents>()
defineSlots<ButtonSlots>()
const typeClass = computed(() => {
return {
default: styles.classes.defaultType,
primary: styles.classes.primary,
danger: styles.classes.danger,
}[props.type]
})
const buttonClass = computed(() => [
styles.classes.root,
typeClass.value,
props.loading ? styles.classes.loading : undefined,
])
function handleClick(event: MouseEvent) {
if (props.disabled || props.loading)
return
emit('click', event)
}
</script>
<template>
<button
type="button"
:class="buttonClass"
:disabled="disabled || loading"
@click="handleClick"
>
<span
v-if="loading"
:class="styles.classes.spinner"
aria-hidden="true"
/>
<slot />
</button>
</template>
import type { ExtractPublicPropTypes, PropType, VNodeChild } from 'vue'
export type ButtonType = 'default' | 'primary' | 'danger'
export const buttonProps = {
type: {
type: String as PropType<ButtonType>,
default: 'default',
},
loading: Boolean,
disabled: Boolean,
} as const
export type ButtonProps = ExtractPublicPropTypes<typeof buttonProps>
export interface ButtonEvents {
(e: 'click', event: MouseEvent): void
}
export interface ButtonSlots {
default?: () => VNodeChild
}
import { createStyleSheet } from '../../../_utils/jss'
export const styles = createStyleSheet({
'root': {
'display': 'inline-flex',
'alignItems': 'center',
'justifyContent': 'center',
'gap': 6,
'height': 32,
'padding': [0, 14],
'border': '1px solid transparent',
'borderRadius': 6,
'fontSize': 14,
'lineHeight': '20px',
'cursor': 'pointer',
'transition': 'all 0.2s ease',
'&:disabled': {
cursor: 'not-allowed',
opacity: 0.56,
},
},
'defaultType': {
'borderColor': '#d9d9d9',
'background': '#fff',
'color': '#1f2329',
'&:not(:disabled):hover': {
borderColor: '#1677ff',
color: '#1677ff',
},
},
'primary': {
'background': '#1677ff',
'color': '#fff',
'&:not(:disabled):hover': {
background: '#4096ff',
},
},
'danger': {
'background': '#d92d20',
'color': '#fff',
'&:not(:disabled):hover': {
background: '#f04438',
},
},
'loading': {
pointerEvents: 'none',
},
'spinner': {
width: 12,
height: 12,
border: '2px solid currentColor',
borderTopColor: 'transparent',
borderRadius: '50%',
animation: '$spin 0.8s linear infinite',
},
'@keyframes spin': {
to: {
transform: 'rotate(360deg)',
},
},
})
<template>
<ZCard title="基础卡片">
这里是卡片内容,可以放置文本、表单或列表。
</ZCard>
</template>
# 卡片 Card
TODO: 补充基础卡片、标题、extra 插槽、无边框和内容布局示例。
## 演示
<!-- DEMO -->
<demo vue="card/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/card/src/interface.ts` 补充 Props 和 Slots 表格。
<!-- API -->
export { default as ZCard } from './src/Card.vue'
export * from './src/interface'
<script setup lang="ts">
import type { CardSlots } from './interface'
import { cardProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZCard' })
defineProps(cardProps)
defineSlots<CardSlots>()
</script>
<template>
<section :class="[styles.classes.root, bordered ? styles.classes.bordered : undefined]">
<header
v-if="title || $slots.title || $slots.extra"
:class="styles.classes.header"
>
<div :class="styles.classes.title">
<slot name="title">
{{ title }}
</slot>
</div>
<slot name="extra" />
</header>
<div :class="styles.classes.body">
<slot />
</div>
</section>
</template>
import type { ExtractPublicPropTypes, VNodeChild } from 'vue'
export const cardProps = {
title: String,
bordered: {
type: Boolean,
default: true,
},
} as const
export type CardProps = ExtractPublicPropTypes<typeof cardProps>
export interface CardSlots {
title?: () => VNodeChild
extra?: () => VNodeChild
default?: () => VNodeChild
}
import { createStyleSheet } from '../../../_utils/jss'
export const styles = createStyleSheet({
root: {
borderRadius: 8,
background: '#fff',
},
bordered: {
border: '1px solid #e5e6eb',
},
header: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: [12, 16],
borderBottom: '1px solid #e5e6eb',
},
title: {
color: '#1f2329',
fontSize: 16,
fontWeight: 600,
},
body: {
padding: 16,
},
})
<template>
<ZCopyText text="https://example.com">
复制链接
</ZCopyText>
</template>
# 复制文本 CopyText
TODO: 补充基础复制、自定义内容、复制成功反馈和异常处理示例。
## 演示
<!-- DEMO -->
<demo vue="copy-text/demos/basic.vue" />
<!-- DEMO -->
## API
<!-- API -->
TODO: 对照 `src/copy-text/src/interface.ts` 补充 Props、Events 和 Slots 表格。
<!-- API -->
export { default as ZCopyText } from './src/CopyText.vue'
export * from './src/interface'
<script setup lang="ts">
import type { CopyTextEvents, CopyTextSlots } from './interface'
import { copyTextProps } from './interface'
import { styles } from './styles'
defineOptions({ name: 'ZCopyText' })
const props = defineProps(copyTextProps)
const emit = defineEmits<CopyTextEvents>()
defineSlots<CopyTextSlots>()
async function handleCopy() {
if (!props.text)
return
await navigator.clipboard.writeText(props.text)
emit('copied', props.text)
}
</script>
<template>
<button
type="button"
:class="styles.classes.root"
@click="handleCopy"
>
<slot>
{{ text }}
</slot>
</button>
</template>
import type { ExtractPublicPropTypes, VNodeChild } from 'vue'
export const copyTextProps = {
text: {
type: String,
default: '',
},
} as const
export type CopyTextProps = ExtractPublicPropTypes<typeof copyTextProps>
export interface CopyTextEvents {
(e: 'copied', text: string): void
}
export interface CopyTextSlots {
default?: () => VNodeChild
}
支持 Markdown
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册