Tài liệu

Dùng 3.504 icon, 4 kiểu với framework của bạn, qua CDN, hoặc dưới dạng SVG thuần.

Bắt đầu

Healing Icons có 3.504 icon, 4 kiểu. Chọn gói hợp với dự án của bạn: gói nào cũng có cùng bộ icon, cùng tên và cùng tùy chọn.

Tên icon là tiếng Anh dạng kebab-case, ví dụ arrow-left. Tên component là PascalCase thêm hậu tố Icon: ArrowLeftIcon (tên bắt đầu bằng số thì thêm tiền tố: Icon2fa). Tìm tên icon bằng ô tìm kiếm ở thư viện icon, hoặc bấm Ctrl K.

Các kiểu

outline
outline-duo
fill
glyph-duo

Mỗi gói chia theo kiểu: …/outline (mặc định), …/outline-duo, …/fill và …/glyph-duo. Icon được vẽ trên lưới 18 × 18; icon outline có nét 1.5.

Icon một màu dùng currentColor, nên tự theo màu chữ nếu bạn không đặt color. Kiểu duo có thêm một lớp phụ, đổi màu riêng bằng secondaryColor.

React

Like.jsx
import { HeartIcon } from "@healing-icons/react";              // outline (default)
import { HeartIcon as HeartFill } from "@healing-icons/react/fill";

export function Like({ liked }) {
  return liked ? <HeartFill color="tomato" title="Liked" /> : <HeartIcon size={20} />;
}

Mỗi icon là một module riêng nên bundler chỉ đóng gói icon bạn import. Có thể import từng file: import HeartIcon from "@healing-icons/react/outline/HeartIcon". Component chuyển tiếp ref và truyền các prop khác (className, onClick, aria-*) xuống <svg>. Dùng được trong Server Components.

Vue

Like.vue
<script setup>
import { HeartIcon } from "@healing-icons/vue";
import { HeartIcon as HeartFill } from "@healing-icons/vue/fill";
defineProps(["liked"]);
</script>

<template>
  <HeartFill v-if="liked" color="tomato" title="Liked" />
  <HeartIcon v-else :size="20" :stroke-width="2" />
</template>

Cần Vue 3.3 trở lên. Prop viết được dạng kebab-case (secondary-color, stroke-width). class, style và sự kiện như @click được chuyển xuống <svg>.

Svelte

Like.svelte
<script>
  import HeartIcon from "@healing-icons/svelte/outline/HeartIcon";
  import HeartFill from "@healing-icons/svelte/fill/HeartIcon";

  let { liked } = $props();
</script>

{#if liked}
  <HeartFill color="tomato" title="Liked" />
{:else}
  <HeartIcon size={20} />
{/if}

Cần Svelte 5. Import từng icon (…/<style>/<Component>) là nhanh nhất, cả lúc dev lẫn lúc build. Import có tên như import { HeartIcon } from "@healing-icons/svelte/fill" vẫn dùng được và được tree-shake, nhưng dev server của Vite sẽ phải xử lý cả kiểu đó một lần.

Angular

like.component.ts
import { Component, input } from "@angular/core";
import { HealingIcon, HeartIcon } from "@healing-icons/angular";
import { HeartIcon as HeartFill } from "@healing-icons/angular/fill";

@Component({
  selector: "app-like",
  imports: [HealingIcon],
  template: `
    @if (liked()) {
      <healing-icon [icon]="HeartFill" color="tomato" title="Liked" />
    } @else {
      <healing-icon [icon]="HeartIcon" [size]="20" />
    }
  `,
})
export class LikeComponent {
  readonly liked = input(false);
  protected readonly HeartIcon = HeartIcon;
  protected readonly HeartFill = HeartFill;
}

Cần Angular 17 trở lên. <healing-icon> là standalone component; icon chỉ là dữ liệu nên bản build chỉ chứa icon bạn import. Hỗ trợ server rendering (hydration bỏ qua icon và vẽ lại ở client).

React Native

Với Expo, cài renderer bằng npx expo install react-native-svg.

Like.tsx
import HeartIcon from "@healing-icons/react-native/outline/HeartIcon";
import HeartFill from "@healing-icons/react-native/fill/HeartIcon";

export function Like({ liked }: { liked: boolean }) {
  return liked ? <HeartFill color="tomato" title="Liked" /> : <HeartIcon size={20} color="#14201b" />;
}

React Native không có màu chữ kế thừa nên color mặc định là đen. Metro không tree-shake, nên hãy import từng icon như trên. title trở thành nhãn trợ năng; các prop khác của react-native-svg (style, onPress, testID) được truyền xuống <Svg>.

Web Components

<healing-icon> dùng được trong HTML thuần và mọi framework. Cách nhanh nhất là qua CDN: bản lazy tự tải từng icon khi được dùng lần đầu.

index.html
<script type="module" src="https://cdn.jsdelivr.net/npm/@healing-icons/elements/dist/lazy.js"></script>

<healing-icon name="heart"></healing-icon>
<healing-icon name="heart" variant="fill" size="32" color="tomato" label="Liked"></healing-icon>

Khi dùng bundler, cài gói rồi import các icon bạn cần:

main.js
import "@healing-icons/elements";
import "@healing-icons/elements/outline/heart";   // registers <healing-icon name="heart">
import "@healing-icons/elements/fill/star";       // registers <healing-icon name="star" variant="fill">

Thuộc tính giống prop của component nhưng viết kebab-case (secondary-color, stroke-width, absolute-stroke-width); dùng label để đặt tên cho trình đọc màn hình. Icon nằm trong shadow root; chỉnh style bằng healing-icon::part(svg). Với Vue, khai báo là custom element (compilerOptions.isCustomElement); với Angular, thêm CUSTOM_ELEMENTS_SCHEMA.

File SVG, CDN và sprite

Gói healing-icons chứa các file SVG đã tối ưu, ở healing-icons/svg/<style>/<name>.svg.

any bundler
import heartUrl from "healing-icons/svg/outline/heart.svg";

<img src={heartUrl} width="24" height="24" alt="" />

Mọi file đều có trên jsDelivr và unpkg. Khi chạy thật nên ghim phiên bản. <img> không theo được màu chữ; muốn vậy thì dùng icon làm CSS mask:

CDN
<img src="https://cdn.jsdelivr.net/npm/healing-icons@0.7/svg/outline/heart.svg" width="24" height="24" alt="">

<style>
  .icon-heart {
    width: 24px; height: 24px;
    background: currentColor;
    mask: url(https://cdn.jsdelivr.net/npm/healing-icons@0.7/svg/outline/heart.svg) center / contain no-repeat;
  }
</style>

Sprite gom nhiều icon vào một file. Tạo sprite chỉ với các icon bạn cần, rồi dùng bằng <use>:

terminal
npx healing-icons sprite heart star arrow-left --style outline --out public/icons.svg
index.html
<svg width="24" height="24"><use href="/icons.svg#heart"/></svg>

Trên thư viện icon, bấm Chọn để tải các icon đã chọn dưới dạng ZIP file SVG hoặc sprite.

Công cụ cho editor và thiết kế

  • VS Code

    Tìm icon có ảnh xem trước và chèn code đúng với file đang mở (Ctrl Alt I), tự thêm dòng import. Rê chuột lên tên icon để xem icon.

terminal
code --install-extension hoanghuilinh.healing-icons-vscode

Thuộc tính

Gói nào cũng có cùng các tùy chọn. React Native chỉ nhận số cho size; web component nhận chúng dưới dạng thuộc tính kebab-case.

Thuộc tínhMặc địnhMô tả
size24Chiều rộng và cao (số hoặc độ dài CSS)
colorcurrentColorMàu icon; icon một màu tự theo màu chữ
secondaryColorcolorMàu lớp phụ của icon duo
strokeWidth1.5Độ dày nét của icon outline, theo đơn vị lưới (18 mỗi icon)
absoluteStrokeWidthfalseTính strokeWidth theo pixel, giữ nguyên ở mọi cỡ
titleTên cho trình đọc màn hình; không có thì icon bị ẩn với trình đọc

Tên icon từ dữ liệu

Gói nào cũng export kiểu IconName (hợp của mọi tên icon) và IconStyle. Khi chỉ biết icon lúc chạy (CMS, cấu hình), DynamicIcon sẽ tải icon khi cần:

React
import { DynamicIcon, type IconName } from "@healing-icons/react/dynamic";

function MenuItem({ icon, label }: { icon: IconName; label: string }) {
  return (
    <li>
      <DynamicIcon name={icon} variant="fill" fallback={<span className="size-6" />} />
      {label}
    </li>
  );
}

Vue và Svelte: DynamicIcon từ …/dynamic (có slot / snippet fallback). Angular: <healing-dynamic-icon [name]="…"> từ @healing-icons/angular/dynamic. Web component: bản lazy luôn tải theo tên.

Nên import tĩnh khi có thể. Với DynamicIcon, mỗi icon trở thành một chunk tải lười trong bản build (Metro của React Native thì gói tất cả vào), và hiện icon tốn thêm một request.

Trợ năng

Mặc định icon chỉ để trang trí: trình đọc màn hình bỏ qua (aria-hidden). Khi icon tự mang ý nghĩa, hãy đặt title (label với web component), icon sẽ thành hình ảnh có tên đó.

React
// Icon-only button: name the button, keep the icon decorative.
<button aria-label="Delete"><TrashIcon /></button>

// Icon that stands alone
<WarningIcon title="Warning" color="#b45309" />