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>
<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>
</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>
</>
);
} 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).
<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>
<CfButton :loading="loading" @click="load">
{{ loading ? 'Loading…' : 'Click to load' }}
</CfButton>
<CfButton disabled>Disabled</CfButton>
<CfButton block>Full-width (block)</CfButton>
</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>
</>
);
} 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