Button
5 variants, 3 sizes, 3 shapes, plus loading and disabled states.
Basic usage
The five visual variants cover every level from primary action to subtle action, ordered from heaviest to lightest visual weight.
primary is the single primary action on a page; danger is for irreversible actions like delete.
背景
<script setup lang="ts">
import { CfButton } from '@chufix-design/vue';
</script>
<template>
<div class="demo-row">
<CfButton variant="primary">Primary</CfButton>
<CfButton variant="secondary">Secondary</CfButton>
<CfButton variant="tertiary">Tertiary</CfButton>
<CfButton variant="ghost">Ghost</CfButton>
<CfButton variant="danger">Danger</CfButton>
</div>
</template> <script setup>
import { CfButton } from '@chufix-design/vue';
</script>
<template>
<div class="demo-row">
<CfButton variant="primary">Primary</CfButton>
<CfButton variant="secondary">Secondary</CfButton>
<CfButton variant="tertiary">Tertiary</CfButton>
<CfButton variant="ghost">Ghost</CfButton>
<CfButton variant="danger">Danger</CfButton>
</div>
</template> import { CfButton } from '@chufix-design/react';
export default function Demo() {
return (
<>
<CfButton variant="primary">Primary</CfButton>
<CfButton variant="secondary">Secondary</CfButton>
<CfButton variant="tertiary">Tertiary</CfButton>
<CfButton variant="ghost">Ghost</CfButton>
<CfButton variant="danger">Danger</CfButton>
</>
);
} import { CfButton } from '@chufix-design/react';
export default function Demo() {
return (
<>
<CfButton variant="primary">Primary</CfButton>
<CfButton variant="secondary">Secondary</CfButton>
<CfButton variant="tertiary">Tertiary</CfButton>
<CfButton variant="ghost">Ghost</CfButton>
<CfButton variant="danger">Danger</CfButton>
</>
);
} Size and shape
Three sizes (sm / md / lg) match different information densities; among the three shapes, pill is fully rounded and square is square (typically used for icon-only buttons).
背景
<script setup lang="ts">
import { CfButton } from '@chufix-design/vue';
</script>
<template>
<div class="demo-stack">
<div class="demo-row">
<CfButton size="sm">Small</CfButton>
<CfButton size="md">Medium</CfButton>
<CfButton size="lg">Large</CfButton>
</div>
<div class="demo-row">
<CfButton shape="default">默认圆角</CfButton>
<CfButton shape="pill">Pill</CfButton>
<CfButton shape="square" aria-label="设置">⚙</CfButton>
</div>
</div>
</template> <script setup>
import { CfButton } from '@chufix-design/vue';
</script>
<template>
<div class="demo-stack">
<div class="demo-row">
<CfButton size="sm">Small</CfButton>
<CfButton size="md">Medium</CfButton>
<CfButton size="lg">Large</CfButton>
</div>
<div class="demo-row">
<CfButton shape="default">默认圆角</CfButton>
<CfButton shape="pill">Pill</CfButton>
<CfButton shape="square" aria-label="设置">⚙</CfButton>
</div>
</div>
</template> <CfButton size="sm">Small</CfButton>
<CfButton size="md">Medium</CfButton>
<CfButton size="lg">Large</CfButton>
<CfButton shape="default">Default radius</CfButton>
<CfButton shape="pill">Pill</CfButton>
<CfButton shape="square" aria-label="Settings">⚙</CfButton> <CfButton size="sm">Small</CfButton>
<CfButton size="md">Medium</CfButton>
<CfButton size="lg">Large</CfButton>
<CfButton shape="default">Default radius</CfButton>
<CfButton shape="pill">Pill</CfButton>
<CfButton shape="square" aria-label="Settings">⚙</CfButton> States
loading automatically renders a spinner and blocks clicks; disabled makes the button non-interactive; block makes it fill the parent’s width.
背景
<script setup lang="ts">
import { ref } from 'vue';
import { CfButton } from '@chufix-design/vue';
const loading = ref(false);
async function load() {
loading.value = true;
await new Promise((r) => setTimeout(r, 1500));
loading.value = false;
}
</script>
<template>
<div class="demo-stack">
<div class="demo-row">
<CfButton :loading="loading" @click="load">{{ loading ? '加载中…' : '点击加载' }}</CfButton>
<CfButton disabled>Disabled</CfButton>
<CfButton variant="tertiary" disabled>Outline Disabled</CfButton>
</div>
<CfButton block>整行铺满(block)</CfButton>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfButton } from '@chufix-design/vue';
const loading = ref(false);
async function load() {
loading.value = true;
await new Promise((r) => setTimeout(r, 1500));
loading.value = false;
}
</script>
<template>
<div class="demo-stack">
<div class="demo-row">
<CfButton :loading="loading" @click="load">{{ loading ? '加载中…' : '点击加载' }}</CfButton>
<CfButton disabled>Disabled</CfButton>
<CfButton variant="tertiary" disabled>Outline Disabled</CfButton>
</div>
<CfButton block>整行铺满(block)</CfButton>
</div>
</template> import { useState } from 'react';
import { CfButton } from '@chufix-design/react';
export default function Demo() {
const [loading, setLoading] = useState(false);
async function load() {
setLoading(true);
await new Promise((r) => setTimeout(r, 1500));
setLoading(false);
}
return (
<>
<CfButton loading={loading} onClick={load}>
{loading ? 'Loading…' : 'Click to load'}
</CfButton>
<CfButton disabled>Disabled</CfButton>
<CfButton block>Full-width (block)</CfButton>
</>
);
} import { useState } from 'react';
import { CfButton } from '@chufix-design/react';
export default function Demo() {
const [loading, setLoading] = useState(false);
async function load() {
setLoading(true);
await new Promise((r) => setTimeout(r, 1500));
setLoading(false);
}
return (
<>
<CfButton loading={loading} onClick={load}>
{loading ? 'Loading…' : 'Click to load'}
</CfButton>
<CfButton disabled>Disabled</CfButton>
<CfButton block>Full-width (block)</CfButton>
</>
);
} API
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'danger' | 'primary' | Visual variant (heaviest to lightest weight) |
size | 'sm' | 'md' | 'lg' | 'md' | Height and font size |
shape | 'default' | 'pill' | 'square' | 'default' | Corner shape |
loading | boolean | false | Show a spinner and block clicks |
block | boolean | false | Stretch to fill the parent’s width |
disabled | boolean | false | Disabled |
Slots / Children
- Vue: the default slot is the label;
leading/trailingnamed slots accept icons. - React:
childrenis the label;leading/trailingprops accept icon nodes.
反馈与讨论
Button · Discussion