UNPKG

@loke/icons

Version:

A Loke icon library package for React applications.

221 lines (153 loc) 5.75 kB
--- name: create-custom-icons description: > Build one-off icon components when no @loke/icons library icon fits. Covers createLokeIcon(name, iconNode) factory, Icon base component with iconNode prop, IconNode type ([SVGElementType, attrs][] with attrs as Record<string, string>), supported SVG elements (circle, ellipse, g, line, path, polygon, polyline, rect), LokeIcon and LokeProps exported types. Always check existing icons and aliases first. Activate only when creating a custom icon not available in the library. type: core library: '@loke/icons' library_version: '1.0.0-alpha.1' sources: - 'LOKE/merchant-frontends:packages/icons/src/createLokeIcon.ts' - 'LOKE/merchant-frontends:packages/icons/src/Icon.tsx' - 'LOKE/merchant-frontends:packages/icons/src/types.ts' --- # @loke/icons — Creating Custom Icons Before creating a custom icon, check if the icon already exists in the library. There are 107 icons with 100+ aliases. See find-icons/SKILL.md for the full list and search tips. ## Setup ### Using createLokeIcon ```tsx import { createLokeIcon } from "@loke/icons"; import type { IconNode } from "@loke/icons"; const customIconNode: IconNode = [ ["path", { d: "M10 10 L20 20" }], ["circle", { cx: "10", cy: "10", r: "5" }], ]; const CustomIcon = createLokeIcon("custom-icon", customIconNode); ``` `createLokeIcon` returns a `ForwardRefExoticComponent` with all standard icon props (`size`, `color`, `strokeWidth`, `absoluteStrokeWidth`, `className`). ### Using the Icon base component ```tsx import { Icon } from "@loke/icons"; import type { IconNode } from "@loke/icons"; const iconNode: IconNode = [ ["path", { d: "M12 2 L22 12 L12 22 L2 12 Z" }], ]; function MyComponent() { return <Icon iconNode={iconNode} size={24} color="currentColor" />; } ``` Use `Icon` directly for inline one-off icons. Use `createLokeIcon` when you need a reusable named component. ## Core Patterns ### IconNode format `IconNode` is an array of tuples: `[SVGElementType, Record<string, string>][]` Supported SVG element types: `circle`, `ellipse`, `g`, `line`, `path`, `polygon`, `polyline`, `rect`. All attribute values must be strings: ```tsx import type { IconNode } from "@loke/icons"; const diamondIcon: IconNode = [ ["polygon", { points: "12 2, 22 12, 12 22, 2 12" }], ]; const targetIcon: IconNode = [ ["circle", { cx: "12", cy: "12", r: "10" }], ["circle", { cx: "12", cy: "12", r: "6" }], ["circle", { cx: "12", cy: "12", r: "2" }], ]; ``` ### Typing custom icons ```tsx import { createLokeIcon } from "@loke/icons"; import type { IconNode, LokeIcon } from "@loke/icons"; const node: IconNode = [["path", { d: "M5 12h14" }]]; const HorizontalLine = createLokeIcon("horizontal-line", node); // HorizontalLine is typed as LokeIcon (ForwardRefExoticComponent) // No explicit type annotation needed — inferred from createLokeIcon ``` ## Common Mistakes ### CRITICAL Hand-writing inline SVG instead of using the library Wrong: ```tsx <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path d="M9 18l6-6-6-6" /> </svg> ``` Correct: ```tsx import { ChevronRight } from "@loke/icons"; <ChevronRight size={24} /> ``` Always check the icon list and aliases before creating custom icons or writing inline SVG. The library has 107 icons covering common UI needs. Source: maintainer interview ### HIGH Using unsupported SVG element types Wrong: ```tsx const node: IconNode = [ ["text", { x: "10", y: "20" }], ]; ``` Correct: ```tsx const node: IconNode = [ ["path", { d: "M10 10 L20 20" }], ]; ``` `IconNode` only supports 8 SVG element types: `circle`, `ellipse`, `g`, `line`, `path`, `polygon`, `polyline`, `rect`. Elements like `text`, `image`, `use`, `defs`, `clipPath` are not supported. Source: src/types.ts — SVGElementType union ### HIGH Passing numeric attribute values Wrong: ```tsx const node: IconNode = [ ["circle", { cx: 12, cy: 12, r: 5 }], ]; ``` Correct: ```tsx const node: IconNode = [ ["circle", { cx: "12", cy: "12", r: "5" }], ]; ``` `IconNode` attrs are typed as `Record<string, string>`. All attribute values must be strings. Passing numbers causes a TypeScript error. Source: src/types.ts ### HIGH Not checking if icon already exists Wrong: ```tsx // Creating a custom checkmark icon const checkNode: IconNode = [ ["polyline", { points: "20 6 9 17 4 12" }], ]; const CustomCheck = createLokeIcon("custom-check", checkNode); ``` Correct: ```tsx // Check already exists in the library import { Check } from "@loke/icons"; ``` The library has 107 icons with 100+ aliases including Material UI-style names. Search the icon list before creating custom icons. Source: maintainer interview ### MEDIUM Typing createLokeIcon result as React.FC Wrong: ```tsx import type { LokeProps } from "@loke/icons"; const MyIcon: React.FC<LokeProps> = createLokeIcon("my-icon", node); ``` Correct: ```tsx const MyIcon = createLokeIcon("my-icon", node); ``` `createLokeIcon` returns a `ForwardRefExoticComponent`, not a function component. Let TypeScript infer the type. Source: src/createLokeIcon.ts ### HIGH Tension: Existing icons vs custom creation Agents default to creating custom icons when an existing icon with an alias would suffice. This adds maintenance burden and misses the library's consistent styling, accessibility defaults, and CSS class naming. See also: find-icons/SKILL.md — search icons and aliases before creating custom See also: find-icons/SKILL.md — verify icon exists before creating custom See also: use-icons/SKILL.md — how to use existing icons See also: add-icons/SKILL.md — if the icon is reusable, add it to the library instead