Preview Updated 2026-05-10

Icon

ChuFix's built-in SVG icon component. Type-safe `name`, inline rendering by default, no separate sprite mounting required.

Basic usage

name uses the IconName type, drawn from the 231 built-in icon names in @chufix-design/icons. Renders as a decorative icon by default; pass title or label when an accessible name is needed.

背景
search
check-circle
alert-circle
calendar
table
layout
modal
component
theme-token
schema
diff
sandbox
src/App.vue
<script setup lang="ts">
import { CfIcon, type IconName } from '@chufix-design/vue';

const icons: IconName[] = [
  'search',
  'check-circle',
  'alert-circle',
  'calendar',
  'table',
  'layout',
  'modal',
  'component',
  'theme-token',
  'schema',
  'diff',
  'sandbox',
];
</script>
<template>
  <div class="demo-stack">
    <div class="demo-row" style="gap: 1.25rem; align-items: center;">
      <CfIcon name="search" size="sm" />
      <CfIcon name="search" size="md" />
      <CfIcon name="search" size="lg" />
      <CfIcon name="search" :size="28" />
    </div>
    <div class="demo-row" style="gap: 1rem; align-items: center;">
      <CfIcon name="check-circle" color="var(--status-success)" size="lg" />
      <CfIcon name="alert-circle" color="var(--status-error)" size="lg" />
      <CfIcon name="info" color="var(--accent-1)" size="lg" />
      <CfIcon name="loader" motion="spin" size="lg" />
      <CfIcon name="bell" motion="pulse" color="var(--status-warning)" size="lg" />
      <CfIcon name="arrow-down" motion="bounce" color="var(--accent-1)" size="lg" />
    </div>
    <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; width: 100%;">
      <div
        v-for="name in icons"
        :key="name"
        style="display: flex; align-items: center; gap: 8px; min-width: 0; padding: 10px; border: 1px solid var(--line-1); border-radius: var(--r-6); color: var(--fg-2);"
      >
        <CfIcon :name="name" />
        <code style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ name }}</code>
      </div>
    </div>
  </div>
</template>
<script setup>
import { CfIcon } from '@chufix-design/vue';

const icons= [
  'search',
  'check-circle',
  'alert-circle',
  'calendar',
  'table',
  'layout',
  'modal',
  'component',
  'theme-token',
  'schema',
  'diff',
  'sandbox',
];
</script>
<template>
  <div class="demo-stack">
    <div class="demo-row" style="gap: 1.25rem; align-items: center;">
      <CfIcon name="search" size="sm" />
      <CfIcon name="search" size="md" />
      <CfIcon name="search" size="lg" />
      <CfIcon name="search" :size="28" />
    </div>
    <div class="demo-row" style="gap: 1rem; align-items: center;">
      <CfIcon name="check-circle" color="var(--status-success)" size="lg" />
      <CfIcon name="alert-circle" color="var(--status-error)" size="lg" />
      <CfIcon name="info" color="var(--accent-1)" size="lg" />
      <CfIcon name="loader" motion="spin" size="lg" />
      <CfIcon name="bell" motion="pulse" color="var(--status-warning)" size="lg" />
      <CfIcon name="arrow-down" motion="bounce" color="var(--accent-1)" size="lg" />
    </div>
    <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; width: 100%;">
      <div
        v-for="name in icons"
        :key="name"
        style="display: flex; align-items: center; gap: 8px; min-width: 0; padding: 10px; border: 1px solid var(--line-1); border-radius: var(--r-6); color: var(--fg-2);"
      >
        <CfIcon :name="name" />
        <code style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ name }}</code>
      </div>
    </div>
  </div>
</template>
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="search" />
      <CfIcon name="calendar" size="lg" />
      <CfIcon name="component" size={28} />
      <CfIcon name="check-circle" color="var(--status-success)" />
      <CfIcon name="loader" motion="spin" />
      <CfIcon name="alert-circle" title="Error" />
    </>
  );
}
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="search" />
      <CfIcon name="calendar" size="lg" />
      <CfIcon name="component" size={28} />
      <CfIcon name="check-circle" color="var(--status-success)" />
      <CfIcon name="loader" motion="spin" />
      <CfIcon name="alert-circle" title="Error" />
    </>
  );
}

Sizes

size accepts a preset tier (xs / sm / md / lg / xl) or a number / string (custom px / em).

背景
xs sm md lg xl 32px
src/App.vue
<script setup lang="ts">
import { CfIcon } from '@chufix-design/vue';
</script>
<template>
  <div style="display:flex; gap: 16px; align-items: center;">
    <span><CfIcon name="search" size="xs" /> xs</span>
    <span><CfIcon name="search" size="sm" /> sm</span>
    <span><CfIcon name="search" size="md" /> md</span>
    <span><CfIcon name="search" size="lg" /> lg</span>
    <span><CfIcon name="search" size="xl" /> xl</span>
    <span><CfIcon name="search" :size="32" /> 32px</span>
  </div>
</template>
<script setup>
import { CfIcon } from '@chufix-design/vue';
</script>
<template>
  <div style="display:flex; gap: 16px; align-items: center;">
    <span><CfIcon name="search" size="xs" /> xs</span>
    <span><CfIcon name="search" size="sm" /> sm</span>
    <span><CfIcon name="search" size="md" /> md</span>
    <span><CfIcon name="search" size="lg" /> lg</span>
    <span><CfIcon name="search" size="xl" /> xl</span>
    <span><CfIcon name="search" :size="32" /> 32px</span>
  </div>
</template>
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="search" size="xs" />
      <CfIcon name="search" size="sm" />
      <CfIcon name="search" size="md" />
      <CfIcon name="search" size="lg" />
      <CfIcon name="search" size="xl" />
      <CfIcon name="search" size={32} />
    </>
  );
}
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="search" size="xs" />
      <CfIcon name="search" size="sm" />
      <CfIcon name="search" size="md" />
      <CfIcon name="search" size="lg" />
      <CfIcon name="search" size="xl" />
      <CfIcon name="search" size={32} />
    </>
  );
}

Color

When color is not passed, the icon uses currentColor and inherits the parent text color — this is the default and the most flexible option. For semantic colors, pass a token directly: var(--status-success) / var(--accent-1), etc.

背景
继承父级颜色
src/App.vue
<script setup lang="ts">
import { CfIcon } from '@chufix-design/vue';
</script>
<template>
  <div style="display:flex; gap: 16px; align-items: center; flex-wrap: wrap;">
    <CfIcon name="check-circle" color="var(--status-success)" size="lg" />
    <CfIcon name="alert-triangle" color="var(--status-warning)" size="lg" />
    <CfIcon name="x-circle" color="var(--status-error)" size="lg" />
    <CfIcon name="info" color="var(--status-info)" size="lg" />
    <CfIcon name="star" color="var(--accent-1)" size="lg" />
    <span style="color: var(--accent-1);">
      <CfIcon name="zap" size="lg" />
      继承父级颜色
    </span>
  </div>
</template>
<script setup>
import { CfIcon } from '@chufix-design/vue';
</script>
<template>
  <div style="display:flex; gap: 16px; align-items: center; flex-wrap: wrap;">
    <CfIcon name="check-circle" color="var(--status-success)" size="lg" />
    <CfIcon name="alert-triangle" color="var(--status-warning)" size="lg" />
    <CfIcon name="x-circle" color="var(--status-error)" size="lg" />
    <CfIcon name="info" color="var(--status-info)" size="lg" />
    <CfIcon name="star" color="var(--accent-1)" size="lg" />
    <span style="color: var(--accent-1);">
      <CfIcon name="zap" size="lg" />
      继承父级颜色
    </span>
  </div>
</template>
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="check-circle" color="var(--status-success)" size="lg" />
      <CfIcon name="alert-triangle" color="var(--status-warning)" size="lg" />
      <CfIcon name="x-circle" color="var(--status-error)" size="lg" />
      <CfIcon name="info" color="var(--status-info)" size="lg" />
    </>
  );
}
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="check-circle" color="var(--status-success)" size="lg" />
      <CfIcon name="alert-triangle" color="var(--status-warning)" size="lg" />
      <CfIcon name="x-circle" color="var(--status-error)" size="lg" />
      <CfIcon name="info" color="var(--status-info)" size="lg" />
    </>
  );
}

Motion

motion adds a simple looping animation — spin (for loaders), pulse (breathing emphasis), bounce (strong cue). All motion respects prefers-reduced-motion and stops automatically when the user opts in.

背景
spin加载中motion="spin"
pulse状态呼吸motion="pulse"
bounce引导方向motion="bounce"
src/App.vue
<script setup lang="ts">
import { CfIcon } from '@chufix-design/vue';

const motions = [
  {
    icon: 'loader',
    motion: 'spin',
    label: 'spin',
    hint: '加载中',
    tone: 'primary',
  },
  {
    icon: 'circle',
    motion: 'pulse',
    label: 'pulse',
    hint: '状态呼吸',
    tone: 'success',
  },
  {
    icon: 'arrow-down',
    motion: 'bounce',
    label: 'bounce',
    hint: '引导方向',
    tone: 'warning',
  },
] as const;
</script>
<template>
  <div class="motion-demo">
    <div
      v-for="item in motions"
      :key="item.motion"
      class="motion-demo__card"
      :data-tone="item.tone"
    >
      <span class="motion-demo__preview">
        <CfIcon :name="item.icon" :motion="item.motion" size="xl" />
      </span>
      <span class="motion-demo__body">
        <strong>{{ item.label }}</strong>
        <em>{{ item.hint }}</em>
      </span>
      <code>motion="{{ item.motion }}"</code>
    </div>
  </div>
</template>
<style scoped>
.motion-demo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  width: min(100%, 640px);
}

.motion-demo__card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  min-width: 0;
  padding: 12px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-6);
  background: var(--bg-1);
  color: var(--fg-1);
}

.motion-demo__preview {
  display: grid;
  width: 42px;
  height: 42px;
  place-items: center;
  border: 1px solid var(--line-1);
  border-radius: var(--r-6);
  background: var(--bg-inset);
}

.motion-demo__card[data-tone='primary'] .motion-demo__preview { color: var(--accent-1); }
.motion-demo__card[data-tone='success'] .motion-demo__preview { color: var(--status-success); }
.motion-demo__card[data-tone='warning'] .motion-demo__preview { color: var(--status-warning); }

.motion-demo__body {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.motion-demo__body strong {
  font-size: var(--t-13);
  line-height: 1.2;
}

.motion-demo__body em {
  color: var(--fg-3);
  font-size: var(--t-12);
  font-style: normal;
}

.motion-demo__card code {
  grid-column: 1 / -1;
  width: fit-content;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
<script setup>
import { CfIcon } from '@chufix-design/vue';

const motions = [
  {
    icon: 'loader',
    motion: 'spin',
    label: 'spin',
    hint: '加载中',
    tone: 'primary',
  },
  {
    icon: 'circle',
    motion: 'pulse',
    label: 'pulse',
    hint: '状态呼吸',
    tone: 'success',
  },
  {
    icon: 'arrow-down',
    motion: 'bounce',
    label: 'bounce',
    hint: '引导方向',
    tone: 'warning',
  },
];
</script>
<template>
  <div class="motion-demo">
    <div
      v-for="item in motions"
      :key="item.motion"
      class="motion-demo__card"
      :data-tone="item.tone"
    >
      <span class="motion-demo__preview">
        <CfIcon :name="item.icon" :motion="item.motion" size="xl" />
      </span>
      <span class="motion-demo__body">
        <strong>{{ item.label }}</strong>
        <em>{{ item.hint }}</em>
      </span>
      <code>motion="{{ item.motion }}"</code>
    </div>
  </div>
</template>
<style scoped>
.motion-demo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  width: min(100%, 640px);
}

.motion-demo__card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  min-width: 0;
  padding: 12px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-6);
  background: var(--bg-1);
  color: var(--fg-1);
}

.motion-demo__preview {
  display: grid;
  width: 42px;
  height: 42px;
  place-items: center;
  border: 1px solid var(--line-1);
  border-radius: var(--r-6);
  background: var(--bg-inset);
}

.motion-demo__card[data-tone='primary'] .motion-demo__preview { color: var(--accent-1); }
.motion-demo__card[data-tone='success'] .motion-demo__preview { color: var(--status-success); }
.motion-demo__card[data-tone='warning'] .motion-demo__preview { color: var(--status-warning); }

.motion-demo__body {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.motion-demo__body strong {
  font-size: var(--t-13);
  line-height: 1.2;
}

.motion-demo__body em {
  color: var(--fg-3);
  font-size: var(--t-12);
  font-style: normal;
}

.motion-demo__card code {
  grid-column: 1 / -1;
  width: fit-content;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="loader" motion="spin" size="lg" />
      <CfIcon name="circle" motion="pulse" size="lg" />
      <CfIcon name="arrow-down" motion="bounce" size="lg" />
    </>
  );
}
import { CfIcon } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfIcon name="loader" motion="spin" size="lg" />
      <CfIcon name="circle" motion="pulse" size="lg" />
      <CfIcon name="arrow-down" motion="bounce" size="lg" />
    </>
  );
}

API

PropTypeDefaultDescription
nameIconNameIcon name with typed validation
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | number | string'md'Size
strokeWidthnumber1.5Stroke width
colorstringIcon color; inherits currentColor by default
motion'spin' | 'pulse' | 'bounce'Simple animation effect; respects prefers-reduced-motion
titlestringSVG title; also gives the icon img semantics
labelstringVue-only aria-label

In React you can pass aria-label directly:

<CfIcon name="search" aria-label="Search" />

Icon catalog

The full list of built-in icons. Click an entry to copy its prefixed component usage, e.g. <CfIcon name="search" />.

反馈与讨论

Icon · Discussion

0
0 / 600
一键发送
正在加载评论...