SuperAPI AI Directory

opendesign-scripts

Design & creation

View repository

Updated 10-16 01:06

About this skill

OpenDesign Scripts Usage Guide

This Skill corresponds to @opensig/open-scripts v1.0.6(generated 2026-07), minimum dependency version ≥1.0.6. To find out in which version a specific command API was introduced/changed, check ReleaseNote。

@opensig/open-scripts is the CLI build toolkit of the OpenDesign ecosystem, providing full-process build capabilities from SVG icon generation to component library packaging.

Installation

pnpm add -D @opensig/open-scripts
# 或
npm install -D @opensig/open-scripts

After installation, you can use the package.json in the scripts of open-scripts command.


Who needs which commands?

The 5 commands of open-scripts fall into two usage scenarios. Please choose according to your project type:

Component library development (such as @opensig/opendesign itself)

When building and publishing a component library npm package, you need to useall 5 commands:

Command When to use
gen:icon After adding/modifying SVG icons, regenerate the icon Vue components
clean:svg After receiving the original SVG delivered by the designer, clean it first and then hand it to gen:icon
build:component Build component library artifacts (ES/CJS/UMD) before publishing
build:style Compile SCSS styles into CSS artifacts before publishing
gen:token After the design token JSON is updated, regenerate the theme CSS variable files (used for the build of the @opensig/opendesign-token package)

Standard build process:gen:icon → build:component → build:style

Business project development (websites/applications using the OpenDesign component library)

Business projectsdo not need build:component、build:style and gen:token:

  • build:component / build:style are specifically for building component library npm packages; business projects can directly install @opensig/opendesign and that is enough
  • gen:token is specifically for building the @opensig/opendesign-token package; business projects can directly install that package and import the CSS file for the corresponding theme (see the installation section of the opendesign-components skill)

Commands that business projects may use:

Command When to use
gen:icon When the project has its own custom icons (not the component library's built-in icons), convert the SVG into Vue components for unified use
clean:svg Clean the original SVG delivered by the designer (optional, depending on SVG quality)

Command index

  • gen:icon — Generate Vue icon components from SVG files (component library + business projects) · Reference documentation
  • clean:svg — Clean and optimize SVG files (component library + business projects) · Reference documentation
  • build:component — Build a Vue component library (component library development only) · Reference documentation
  • build:style — Compile SCSS styles into CSS (component library development only) · Reference documentation
  • gen:token — Generate design token CSS variables from JSON (token package building only) · Reference documentation

gen:icon

Classify the SVG icon files provided by the designer into three types by fill/stroke/color, optimize them with SVGO, and automatically convert them into Vue single-file components that can be imported and used directly.

Applicable scenarios: Both component library development and business projects can use it. In business projects, when the design draft contains custom icons that are not built into the component library, use this command for unified management.

Workflow from design mockups to code for SVG assets

When a design mockup (Pixso/Figma, etc.) contains slices that can be converted into SVG icons, follow the process below:

  1. Prefer obtaining via MCP: If the design tool provides MCP (Model Context Protocol) capabilities, prefer calling its MCP interface to batch export SVG assets, rather than manually exporting them one by one
  2. Manually export SVG: If there is no MCP capability, export the icon slices from the design mockup one by one as .svg format
  3. Store by category: Determine the type based on the icon content, and place the SVG into the corresponding subdirectory (see "SVG Export Specifications and Classification Rules" below)
  4. Optional cleanup: If the exported SVG contains redundant attributes, first run clean:svg cleanup
  5. After all exports are complete, run the gen:icon command once to generate the Vue components for all icons
  6. Import and use in business code (see "How to Import Icon Components" below)

Note: You should run gen:iconuniformly only after all SVG slices have been exported, because this command clears the output directory and regenerates all components each time it is executed.

Best Practices for Adding and Modifying Icons

When a task involvesaddingormodifyingicons, the following principles must be followed:

  1. Prioritize reusing existing icons: Before adding an icon, first check the SVG source file directory (theinput subdirectory pointed to by the fill/、stroke/、color/ configuration) and the already generated icon components to confirm whether an identical or semantically similar icon already exists. If a usable icon already exists, import and use it directly; do not add it again
  2. Adopt an incremental strategy: When new icons need to be added, onlyappendthe new SVG files to the corresponding fill/、stroke/、color/ subdirectory, anddo not delete or overwriteexisting SVG files.gen:icon reads all SVGs from the input directory and regenerates the components, so you only need to ensure the new files are placed correctly
  3. Replace in place when modifying icons: If you need to modify the visual style of an existing icon, directly replace the file with the same namewith the new SVG, keeping the file name unchanged, so that the generated component name and all referencing code do not need to be changed

How to Check Existing Icons:

  • Check the file names in each subdirectory under the SVG source file directory, and determine whether the semantics match according to the naming convention
  • Search the generated icon component directory (the directory pointed to by theoutput configuration), and look it up by component name
  • If the project uses built-in icons from a component library (@opensig/opendesign), you should also check whether the required icon is already built into the component library

Anti-pattern: Do not clear the SVG source file directory and then put all files back in just to be "clean"—this will cause a large number of meaningless deletion + addition records in Git history, and it is easy to miss existing icons.

SVG Export Specifications and Classification Rules

Export Specifications:

  • Icons should be exported asa square with appropriate white marginscanvas, preferably using the 24×24px size
  • If an icon has special size requirements, still export the SVG at the standard size, and adjust the display size at the call site via CSS font-size or width/height .
  • Remove unnecessary layers, masks, and clipping paths during export.
  • Paths that need dynamic styling: If a certain <path> needs to change color or style individually during interaction, a meaningful IDshould be set for that path in the design tool (such as highlight、badge),gen:icon The SVGO process will automatically convert id to class, so the caller can control the style of that path through a CSS class selector.
<!-- 示例:通过类名控制 SVG 内部路径的颜色 -->
<OIcon :icon="OIconNotification" class="my-icon" />

<style scoped>
/* 设计师在 SVG 中为小红点路径设置了 id="badge",生成后变为 class="badge" */
.my-icon :deep(.badge) {
  fill: red;
}
</style>

Classification Rules—Determine which subdirectory to place it in based on the visual content of the icon:

Directory Basis for Determination Color Control Method After Generation Typical Scenarios
fill/ The icon is mainlysolid filled, with color controlled by the fill attribute. Use CSS color to change color uniformly. Solid arrows, solid checkmarks, solid favorite stars.
stroke/ The icon is mainlyline stroked, with color controlled by the stroke attribute. Use CSS color to change color uniformly. Wireframe close, wireframe search, wireframe settings.
color/ The icon containsmultiple fixed colors, and should not have its color changed uniformly by CSS. Preserve the original SVG colors. Brand logos, color illustrations, multi-color status icons.

Judgment Tips: Open the SVG in a text editor. If elements such as <path> mainly use the fill attribute for coloring → fill/; if they mainly use the stroke attribute for coloring → stroke/; if they use multiple different color values at the same time → color/。

SVG File Naming Conventions

The SVG file name directly determines the generated Vue component name (such as arrow-right.svg → OIconArrowRight), and should follow unified naming rules:

Naming Format:{语义名}[-{形态变体}].svg

  • Semantic name: Describes the meaning of the icon, uses kebab-case (lowercase + hyphens), and consists of an "object" or an "action".
  • Form variant(optional): A suffix for different visual forms of the same semantic meaning.

Semantic Name Selection Rules:

Priority Composition Method Example
1 A single action or object (when the meaning is clear) search.svg、home.svg、close.svg
2 Action + Object file-download.svg、user-add.svg、link-copy.svg
3 Object + Qualifier arrow-right.svg、chevron-down.svg、caret-up.svg

Common Form Variant Suffixes:

Suffix Meaning Example
-circle With circular background check-circle.svg、info-circle.svg
-square With square background plus-square.svg
-line Linear stroke version heart-line.svg
-solid Solid fill version heart-solid.svg

Common Semantic Word Reference:

Category Recommended Vocabulary
Navigation arrow-{up/down/left/right}、chevron-{方向}、caret-{方向}、expand、collapse、menu、more
Action add、delete、edit、search、download、upload、save、copy、share、refresh、close、filter、sort
Object file、folder、user、home、calendar、mail、image、link、bell、lock、key、settings
State check、warning、error、info、loading、success、question
Media play、pause、stop、mute、volume

Naming Principles:

  • Based on the icon'svisual meaning/purposeNaming, do not name by business function (close.svg instead of dialog-dismiss.svg)
  • Keep the same prefix for a group of related icons (arrow-up、arrow-down、arrow-left、arrow-right)
  • Avoid redundant prefixes—the file is already in the fill/、stroke/、color/ subdirectory, so there is no need to repeat the type information in the file name

How to import icon components

The generated icon components support multiple import methods; choose the appropriate one according to the project structure:

<script setup>
// 方式 1:从组件库包导入(使用组件库内置图标)
import { OIconArrowRight, OIconClose } from '@opensig/opendesign';

// 方式 2:通过路径别名导入(业务项目自定义图标,需在 vite.config / tsconfig 中配置别名)
import { OIconCustom } from '@/icon-components';

// 方式 3:相对路径导入
import { OIconCustom } from '../icon-components';

// 方式 4:从 monorepo 的其他子包导入(通过包名引用)
import { DocIconLogo } from '@my-org/docs-icons';
</script>

Best practices:

  • Built-in icons in the component libraryImport directly from @opensig/opendesign , no need to run gen:icon
  • Custom icons for business projectsIt is recommended to configure a path alias (such as @/icon-components) to avoid deep relative paths
  • Sharing icons across packages in a monorepoIt is recommended to generate icons into a separate subpackage and publish it, and other packages import it by package name
open-scripts gen:icon --config ./icons/icon.config.ts

Core configuration file fields:

Field Type Required Default value Description
input string No './svgs' SVG source file directory, must contain the fill/、stroke/、color/ subdirectory
output string No './components/' Output directory for the generated Vue components
prefix string No '' Component name prefix (such as 'o-' generates OIconXxx)
componentClass string No 'svg-icon' CSS class name of the SVG root element
renderOnServer boolean No false Whether SSR is supported (when false, icons are rendered only on the client)

Configuration example

// icon.config.ts
export default {
  input: './svgs',
  output: '../src/icon-components/',
  componentClass: 'o-svg-icon',
  prefix: 'o-',
};

SVG directory structure requirements:

svgs/
├── fill/       ← 填充型图标(移除 fill 属性,通过 CSS color 控制颜色)
│   ├── arrow-right.svg
│   └── check.svg
├── stroke/     ← 描边型图标(移除 stroke 属性,通过 CSS color 控制颜色)
│   └── close.svg
└── color/      ← 多色图标(保留原始颜色)
    └── logo.svg

For detailed configuration instructions, please see references/gen-icon.md


clean:svg

Use SVGO to batch clean and optimize SVG files, remove redundant attributes, style elements, and scripts, and output streamlined SVG files. Usually used before gen:icon to preprocess the original SVGs delivered by designers.

Applicable scenarios: Can be used for both component library development and business projects. When the SVG exported by the designer contains redundant <style>、<script>, inline styles, and other redundant information, use this command to batch clean it first.

open-scripts clean:svg --config ./icons/cleansvg.config.ts

Core configuration file fields:

Field Type Required Default value Description
input string No './src/icons/svgs' SVG source file directory
output string No './src/icons/output/' Cleaned output directory
svgo Config No Built-in default configuration SVGO optimization configuration

Configuration example

// cleansvg.config.ts
export default {
  input: './svgs',
  output: './_svgs',
};

For detailed configuration instructions, please see references/clean-svg.md


build:component

Use Vite to build the Vue component library and output three module formats: ES Module (es/)、CommonJS(lib/) and UMD (dist/). It also generates TypeScript type declaration files. This command does not accept a configuration file; execute it directly in the root directory of the component library package.

Applicable scenarios: Only used for component library development. Business projects can directly install the @opensig/opendesign npm package; there is no need to build the component library yourself.

open-scripts build:component

Build artifacts:

Directory Format Description
es/ ESM(.mjs) Preserves module structure and supports tree-shaking
lib/ CJS(.js) CommonJS format, compatible with Node.js
dist/opendesign.js UMD Direct browser import
dist/opendesign.min.js UMD (minified) For production use
dist/opendesign-icon.js UMD Icons packaged separately
dist/opendesign-icon.min.js UMD (minified) Icon production bundle

For detailed instructions, see references/build-component.md


build:style

Compile the component library's SCSS style files into CSS, generating style artifacts with multiple import methods. This command does not accept a config file and reads the hardcoded ./src directory as input.

Use case: For component library development only. Business projects import the already-compiled styles via import '@opensig/opendesign/es/index.css' and do not need to compile SCSS themselves.

open-scripts build:style

Build artifacts:

Artifact Description
es/**/*.scss + lib/**/*.scss Copy of the original SCSS files
es/**/*.css + lib/**/*.css Compiled CSS
es/**/css.js + lib/**/css.js CSS import entry (replaces the SCSS entry)
dist/index.css Full styles
dist/index.min.css Full styles (minified)
dist/theme/*/index.css Styles for each theme

For detailed instructions, see references/build-style.md


gen:token

Generate multi-theme CSS variable files and VS Code snippet files from a JSON-format design token definition file. Used to convert tokens exported by designers from tools such as Pixso/Figma into CSS custom properties usable on the frontend.

Use case: Only for building the @opensig/opendesign-token token package. Business projectsdo not need torun this command—simply install @opensig/opendesign-token and import the CSS file for the corresponding theme:

pnpm add @opensig/opendesign-token
// main.ts — 以 openEuler 社区为例
import '@opensig/opendesign-token/themes/e.light.token.css'
import '@opensig/opendesign-token/themes/e.dark.token.css'
open-scripts gen:token --config ./tokens/token.config.ts

Core config file fields:

Field Type Required Default value Description
prefix string Yes — CSS variable prefix (e.g. '--o-')
output string No './' Output directory
tokenFile string[] Yes — Array of token JSON file paths
themeMap Array<{valueKey, name, root?}> Yes — Theme mapping (defines the CSS selector for each theme)
codeSnippetsFile string No — VS Code snippet output path

Config example

// token.config.ts
export default {
  prefix: '--o-',
  output: './dist',
  themeMap: [
    { valueKey: 'light', name: ['o.light', 'default'] },
    { valueKey: 'dark', name: 'o.dark' },
    { valueKey: 'light', name: 'o', root: true },
  ],
  tokenFile: ['./opendesign-token.json'],
  codeSnippetsFile: './dist/opendesign.token.code-snippets',
};

For detailed configuration instructions, see references/gen-token.md


Typical build workflow

Component library release build

In the OpenDesign component library, the standard execution order before release is:

gen:icon → build:component → build:style

Corresponding package.json configuration:

{
  "scripts": {
    "gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts",
    "clean:svg": "open-scripts clean:svg --config ./icons/cleansvg.config.ts",
    "build:component": "open-scripts build:component",
    "build:style": "open-scripts build:style",
    "gen:token": "open-scripts gen:token --config ./tokens/token.config.ts",
    "build": "pnpm gen:icon && pnpm build:component && pnpm build:style"
  }
}

Business project usage

Business projects only need to configure the commands they use:

{
  "scripts": {
    "gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts"
  }
}

Command dependencies

Command Prerequisite Description
clean:svg None Can be executed independently, used to preprocess SVG
gen:icon clean:svg(optional) It is recommended to clean up the SVG first, but not mandatory
build:component gen:icon Icon components must be generated first before they can be packaged together
build:style None Independent of build:component , but usually executed after it
gen:token None Executed independently, does not depend on other commands

Git ignore rules for build artifacts

The output directories of all commands are automatically generated artifacts and should not be included in version control. Please add the corresponding rules in the project's .gitignore . Before executing any command, first check whether .gitignore already covers that command's output directory; if not, add it immediately.

Recommended .gitignore configuration:

# open-scripts 构建产物(自动生成,勿提交)

# gen:icon 生成的图标组件
icon-components

# clean:svg 清理后的 SVG 输出
_svgs

# build:component 构建产物
es
lib
dist

# gen:token 生成的令牌 CSS(若 output 为 dist 则已被上方覆盖)

Note: if a command's output is configured with a custom path, make sure that path is also .gitignore covered.


First use: automatically create missing files and directories

When a command requires a configuration file or input directory but the corresponding file/directory does not exist, it should be created automatically according to the following best practices:

gen:icon

If the configuration file and input directory are missing, create the following structure:

icons/
├── icon.config.ts          ← 配置文件
└── svgs/                   ← input 目录
    ├── fill/               ← 存放单色填充图标
    ├── stroke/             ← 存放单色描边图标
    └── color/              ← 存放多色图标

Configuration file template:

// icons/icon.config.ts
export default {
  input: './svgs',
  output: '../src/icon-components/',
  componentClass: 'o-svg-icon',
  prefix: 'o-',
};

Also in package.json add:

{
  "scripts": {
    "gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts"
  }
}

and make sure .gitignore contains icon-components。

clean:svg

If the configuration file and input directory are missing, create the following structure:

icons/
├── cleansvg.config.ts      ← 配置文件
└── svgs/                   ← input 目录(可与 gen:icon 共用)

Configuration file template:

// icons/cleansvg.config.ts
export default {
  input: './svgs',
  output: './_svgs',
};

Also in package.json add:

{
  "scripts": {
    "clean:svg": "open-scripts clean:svg --config ./icons/cleansvg.config.ts"
  }
}

and make sure .gitignore contains _svgs。

gen:token

If the configuration file and token JSON file are missing, create the following structure:

tokens/
├── token.config.ts          ← 配置文件
└── opendesign-token.json    ← 令牌 JSON 数据(从设计工具导出)

Configuration file template:

// tokens/token.config.ts
export default {
  prefix: '--o-',
  output: './dist',
  themeMap: [
    { valueKey: 'light', name: ['o.light', 'default'] },
    { valueKey: 'dark', name: 'o.dark' },
  ],
  tokenFile: ['./opendesign-token.json'],
};

Also in package.json add:

{
  "scripts": {
    "gen:token": "open-scripts gen:token --config ./tokens/token.config.ts"
  }
}

build:component / build:style

These two commands do not require a configuration file, but they require the project to have a specific source directory structure. If the structure is missing, it means the project has not yet completed the component library source setup and empty directories should not be created directly—the component development should be completed first before using these two commands.


Path planning in monorepo projects

In a monorepo project, each command's configuration file, input directory, and output directory should be placed inthe corresponding subpackage, and paths are resolved relative to the directory containing the configuration file. The following is the recommended directory structure (using opendesign-components as a reference):

Component library package (e.g. packages/opendesign/)

packages/opendesign/
├── package.json                          ← scripts 定义在此
├── icons/
│   ├── icon.config.ts                    ← gen:icon 配置
│   ├── cleansvg.config.ts                ← clean:svg 配置
│   └── svgs/                             ← SVG 源文件(提交到 git)
│       ├── fill/
│       ├── stroke/
│       └── color/
├── src/
│   ├── index.ts                          ← 组件主入口
│   ├── icon/
│   │   └── index.ts                      ← 图标入口
│   ├── icon-components/                  ← gen:icon 输出(git 忽略)
│   └── {component}/
│       └── style/
│           └── index.scss
├── es/                                   ← build:component 输出(git 忽略)
├── lib/                                  ← build:component 输出(git 忽略)
└── dist/                                 ← build:component UMD 输出(git 忽略)

corresponds to package.json scripts:

{
  "scripts": {
    "gen:icon": "open-scripts gen:icon --config ./icons/icon.config.ts",
    "clean:svg": "open-scripts clean:svg --config ./icons/cleansvg.config.ts",
    "build:component": "open-scripts build:component",
    "build:style": "open-scripts build:style",
    "build": "pnpm gen:icon && pnpm build:component && pnpm build:style"
  }
}

in icon.config.ts, output: '../src/icon-components/' means relative to the icons/ directory, go up one level to the package root directory and then enter src/icon-components/。

Business application package (e.g. packages/docs/)

packages/docs/
├── package.json
├── icons/
│   ├── icon.config.ts                    ← gen:icon 配置
│   └── svgs/
│       ├── fill/
│       ├── stroke/
│       └── color/
└── src/
    └── icon-components/                  ← gen:icon 输出(git 忽略)

Business application packages usually only use gen:icon,prefix should use a prefix different from the component library (e.g. 'doc-') to avoid naming conflicts:

// packages/docs/icons/icon.config.ts
export default {
  input: './svgs',
  output: '../src/icon-components/',
  componentClass: 'o-svg-icon',
  prefix: 'doc-',                        // 使用不同前缀,避免与组件库图标冲突
};

Key principles

  • Place configuration files inside subpackages: each subpackage has its own configuration, pointed to via the --config parameter
  • input paths are relative to the configuration file:input: './svgs' means the svgs/ directory at the same level as the configuration file
  • output paths are relative to the configuration file:output: '../src/icon-components/' means a relative path starting from the configuration file's location
  • Commit SVG source files to git:input directory (svgs/) contains the original SVG assets delivered by designers and should be included in version control
  • Generated artifacts are not committed:output directory and build artifact directory should all be covered by .gitignore covered
  • Each subpackage uses a different prefix: when multiple packages in a monorepo use gen:icon , different prefixshould be set (e.g. 'o-'、'doc-') to prevent component name conflicts