From 9d75b0972e87e6aa9d428ee33b513f9c179dd851 Mon Sep 17 00:00:00 2001 From: MyPrototypeWhat Date: Fri, 14 Nov 2025 17:55:44 +0800 Subject: [PATCH] Refactor icon management and update dependencies - Removed the ICON_IMPLEMENTATION_GUIDE.md file and several unused SVG icons from the `icons/` directory. - Added new SVG icons to enhance the icon library, including various brand logos. - Updated package.json to reflect the new version of the `tsx` dependency. - Introduced a script for generating icons and improved the structure of the icons module for better organization and accessibility. - Updated the stories for icons to showcase the new additions and ensure proper documentation. --- packages/ui/ICON_IMPLEMENTATION_GUIDE.md | 1321 ----------------- packages/ui/icons/dmxapi-logo-dark.svg | 9 - packages/ui/icons/openai-1.svg | 10 - packages/ui/icons/perplexity-1.svg | 3 - .../{Tesseract.js.svg => tesseract-js.svg} | 0 packages/ui/package.json | 9 +- packages/ui/scripts/generate-icons.ts | 170 +++ packages/ui/src/components/icons/index.ts | 6 + .../ui/src/components/icons/logos/302ai.tsx | 26 + .../ui/src/components/icons/logos/aiOnly.tsx | 28 + .../src/components/icons/logos/aihubmix.tsx | 34 + .../src/components/icons/logos/alayanew.tsx | 27 + .../src/components/icons/logos/anthropic.tsx | 22 + .../src/components/icons/logos/awsBedrock.tsx | 48 + .../ui/src/components/icons/logos/azureai.tsx | 85 ++ .../src/components/icons/logos/baichuan.tsx | 25 + .../src/components/icons/logos/baiduCloud.tsx | 19 + .../ui/src/components/icons/logos/bailian.tsx | 32 + .../ui/src/components/icons/logos/bocha.tsx | 32 + .../src/components/icons/logos/burncloud.tsx | 27 + .../src/components/icons/logos/bytedance.tsx | 23 + .../src/components/icons/logos/cephalon.tsx | 11 + .../src/components/icons/logos/cherryin.tsx | 27 + .../ui/src/components/icons/logos/cohere.tsx | 30 + .../src/components/icons/logos/dashscope.tsx | 184 +++ .../src/components/icons/logos/deepseek.tsx | 18 + .../ui/src/components/icons/logos/dmxapi.tsx | 27 + .../src/components/icons/logos/dmxapiLogo.tsx | 27 + .../components/icons/logos/dmxapiToImg.tsx | 40 + .../ui/src/components/icons/logos/doc2x.tsx | 15 + .../ui/src/components/icons/logos/doubao.tsx | 30 + .../ui/src/components/icons/logos/exa.tsx | 13 + .../src/components/icons/logos/fireworks.tsx | 13 + .../ui/src/components/icons/logos/gemini.tsx | 34 + .../ui/src/components/icons/logos/giteeAi.tsx | 20 + .../ui/src/components/icons/logos/github.tsx | 20 + .../ui/src/components/icons/logos/google.tsx | 306 ++++ .../src/components/icons/logos/gpustack.tsx | 31 + .../src/components/icons/logos/graphRag.tsx | 51 + .../ui/src/components/icons/logos/grok.tsx | 11 + .../ui/src/components/icons/logos/groq.tsx | 19 + .../components/icons/logos/huggingface.tsx | 69 + .../src/components/icons/logos/hyperbolic.tsx | 18 + .../ui/src/components/icons/logos/index.ts | 89 ++ .../ui/src/components/icons/logos/infini.tsx | 40 + .../ui/src/components/icons/logos/intel.tsx | 24 + .../ui/src/components/icons/logos/jimeng.tsx | 171 +++ .../ui/src/components/icons/logos/jina.tsx | 15 + .../ui/src/components/icons/logos/lanyun.tsx | 27 + .../ui/src/components/icons/logos/lepton.tsx | 27 + .../src/components/icons/logos/lmstudio.tsx | 33 + .../ui/src/components/icons/logos/longcat.tsx | 24 + .../ui/src/components/icons/logos/macos.tsx | 18 + .../src/components/icons/logos/mcprouter.tsx | 27 + .../ui/src/components/icons/logos/meta.tsx | 48 + .../ui/src/components/icons/logos/mineru.tsx | 67 + .../ui/src/components/icons/logos/minimax.tsx | 23 + .../ui/src/components/icons/logos/mistral.tsx | 17 + .../src/components/icons/logos/mixedbread.tsx | 278 ++++ .../components/icons/logos/mixedbread1.tsx | 23 + .../src/components/icons/logos/moonshot.tsx | 19 + .../components/icons/logos/neteaseYoudao.tsx | 15 + .../ui/src/components/icons/logos/newapi.tsx | 51 + .../ui/src/components/icons/logos/nomic.tsx | 36 + .../ui/src/components/icons/logos/nvidia.tsx | 11 + packages/ui/src/components/icons/logos/o3.tsx | 27 + .../ui/src/components/icons/logos/ocoolai.tsx | 11 + .../ui/src/components/icons/logos/ollama.tsx | 13 + .../ui/src/components/icons/logos/openai.tsx | 18 + .../src/components/icons/logos/openrouter.tsx | 20 + .../src/components/icons/logos/paddleocr.tsx | 27 + .../src/components/icons/logos/perplexity.tsx | 13 + .../ui/src/components/icons/logos/ph8.tsx | 46 + .../ui/src/components/icons/logos/ppio.tsx | 18 + .../ui/src/components/icons/logos/qiniu.tsx | 11 + .../ui/src/components/icons/logos/searxng.tsx | 18 + .../ui/src/components/icons/logos/silicon.tsx | 13 + .../ui/src/components/icons/logos/sophnet.tsx | 23 + .../ui/src/components/icons/logos/step.tsx | 30 + .../ui/src/components/icons/logos/tavily.tsx | 38 + .../components/icons/logos/tencentCloudTi.tsx | 19 + .../components/icons/logos/tesseractJs.tsx | 27 + .../src/components/icons/logos/together.tsx | 18 + .../src/components/icons/logos/tokenflux.tsx | 27 + .../src/components/icons/logos/vertexai.tsx | 50 + .../src/components/icons/logos/volcengine.tsx | 27 + .../ui/src/components/icons/logos/voyage.tsx | 24 + .../ui/src/components/icons/logos/xirang.tsx | 13 + .../ui/src/components/icons/logos/zeroOne.tsx | 40 + .../ui/src/components/icons/logos/zhipu.tsx | 15 + packages/ui/src/components/index.ts | 34 +- .../stories/components/icons/Icon.stories.tsx | 290 ---- .../components/icons/Logos.stories.tsx | 237 +++ yarn.lock | 597 +++++++- 94 files changed, 4130 insertions(+), 1667 deletions(-) delete mode 100644 packages/ui/ICON_IMPLEMENTATION_GUIDE.md delete mode 100644 packages/ui/icons/dmxapi-logo-dark.svg delete mode 100644 packages/ui/icons/openai-1.svg delete mode 100644 packages/ui/icons/perplexity-1.svg rename packages/ui/icons/{Tesseract.js.svg => tesseract-js.svg} (100%) create mode 100644 packages/ui/scripts/generate-icons.ts create mode 100644 packages/ui/src/components/icons/index.ts create mode 100644 packages/ui/src/components/icons/logos/302ai.tsx create mode 100644 packages/ui/src/components/icons/logos/aiOnly.tsx create mode 100644 packages/ui/src/components/icons/logos/aihubmix.tsx create mode 100644 packages/ui/src/components/icons/logos/alayanew.tsx create mode 100644 packages/ui/src/components/icons/logos/anthropic.tsx create mode 100644 packages/ui/src/components/icons/logos/awsBedrock.tsx create mode 100644 packages/ui/src/components/icons/logos/azureai.tsx create mode 100644 packages/ui/src/components/icons/logos/baichuan.tsx create mode 100644 packages/ui/src/components/icons/logos/baiduCloud.tsx create mode 100644 packages/ui/src/components/icons/logos/bailian.tsx create mode 100644 packages/ui/src/components/icons/logos/bocha.tsx create mode 100644 packages/ui/src/components/icons/logos/burncloud.tsx create mode 100644 packages/ui/src/components/icons/logos/bytedance.tsx create mode 100644 packages/ui/src/components/icons/logos/cephalon.tsx create mode 100644 packages/ui/src/components/icons/logos/cherryin.tsx create mode 100644 packages/ui/src/components/icons/logos/cohere.tsx create mode 100644 packages/ui/src/components/icons/logos/dashscope.tsx create mode 100644 packages/ui/src/components/icons/logos/deepseek.tsx create mode 100644 packages/ui/src/components/icons/logos/dmxapi.tsx create mode 100644 packages/ui/src/components/icons/logos/dmxapiLogo.tsx create mode 100644 packages/ui/src/components/icons/logos/dmxapiToImg.tsx create mode 100644 packages/ui/src/components/icons/logos/doc2x.tsx create mode 100644 packages/ui/src/components/icons/logos/doubao.tsx create mode 100644 packages/ui/src/components/icons/logos/exa.tsx create mode 100644 packages/ui/src/components/icons/logos/fireworks.tsx create mode 100644 packages/ui/src/components/icons/logos/gemini.tsx create mode 100644 packages/ui/src/components/icons/logos/giteeAi.tsx create mode 100644 packages/ui/src/components/icons/logos/github.tsx create mode 100644 packages/ui/src/components/icons/logos/google.tsx create mode 100644 packages/ui/src/components/icons/logos/gpustack.tsx create mode 100644 packages/ui/src/components/icons/logos/graphRag.tsx create mode 100644 packages/ui/src/components/icons/logos/grok.tsx create mode 100644 packages/ui/src/components/icons/logos/groq.tsx create mode 100644 packages/ui/src/components/icons/logos/huggingface.tsx create mode 100644 packages/ui/src/components/icons/logos/hyperbolic.tsx create mode 100644 packages/ui/src/components/icons/logos/index.ts create mode 100644 packages/ui/src/components/icons/logos/infini.tsx create mode 100644 packages/ui/src/components/icons/logos/intel.tsx create mode 100644 packages/ui/src/components/icons/logos/jimeng.tsx create mode 100644 packages/ui/src/components/icons/logos/jina.tsx create mode 100644 packages/ui/src/components/icons/logos/lanyun.tsx create mode 100644 packages/ui/src/components/icons/logos/lepton.tsx create mode 100644 packages/ui/src/components/icons/logos/lmstudio.tsx create mode 100644 packages/ui/src/components/icons/logos/longcat.tsx create mode 100644 packages/ui/src/components/icons/logos/macos.tsx create mode 100644 packages/ui/src/components/icons/logos/mcprouter.tsx create mode 100644 packages/ui/src/components/icons/logos/meta.tsx create mode 100644 packages/ui/src/components/icons/logos/mineru.tsx create mode 100644 packages/ui/src/components/icons/logos/minimax.tsx create mode 100644 packages/ui/src/components/icons/logos/mistral.tsx create mode 100644 packages/ui/src/components/icons/logos/mixedbread.tsx create mode 100644 packages/ui/src/components/icons/logos/mixedbread1.tsx create mode 100644 packages/ui/src/components/icons/logos/moonshot.tsx create mode 100644 packages/ui/src/components/icons/logos/neteaseYoudao.tsx create mode 100644 packages/ui/src/components/icons/logos/newapi.tsx create mode 100644 packages/ui/src/components/icons/logos/nomic.tsx create mode 100644 packages/ui/src/components/icons/logos/nvidia.tsx create mode 100644 packages/ui/src/components/icons/logos/o3.tsx create mode 100644 packages/ui/src/components/icons/logos/ocoolai.tsx create mode 100644 packages/ui/src/components/icons/logos/ollama.tsx create mode 100644 packages/ui/src/components/icons/logos/openai.tsx create mode 100644 packages/ui/src/components/icons/logos/openrouter.tsx create mode 100644 packages/ui/src/components/icons/logos/paddleocr.tsx create mode 100644 packages/ui/src/components/icons/logos/perplexity.tsx create mode 100644 packages/ui/src/components/icons/logos/ph8.tsx create mode 100644 packages/ui/src/components/icons/logos/ppio.tsx create mode 100644 packages/ui/src/components/icons/logos/qiniu.tsx create mode 100644 packages/ui/src/components/icons/logos/searxng.tsx create mode 100644 packages/ui/src/components/icons/logos/silicon.tsx create mode 100644 packages/ui/src/components/icons/logos/sophnet.tsx create mode 100644 packages/ui/src/components/icons/logos/step.tsx create mode 100644 packages/ui/src/components/icons/logos/tavily.tsx create mode 100644 packages/ui/src/components/icons/logos/tencentCloudTi.tsx create mode 100644 packages/ui/src/components/icons/logos/tesseractJs.tsx create mode 100644 packages/ui/src/components/icons/logos/together.tsx create mode 100644 packages/ui/src/components/icons/logos/tokenflux.tsx create mode 100644 packages/ui/src/components/icons/logos/vertexai.tsx create mode 100644 packages/ui/src/components/icons/logos/volcengine.tsx create mode 100644 packages/ui/src/components/icons/logos/voyage.tsx create mode 100644 packages/ui/src/components/icons/logos/xirang.tsx create mode 100644 packages/ui/src/components/icons/logos/zeroOne.tsx create mode 100644 packages/ui/src/components/icons/logos/zhipu.tsx delete mode 100644 packages/ui/stories/components/icons/Icon.stories.tsx create mode 100644 packages/ui/stories/components/icons/Logos.stories.tsx diff --git a/packages/ui/ICON_IMPLEMENTATION_GUIDE.md b/packages/ui/ICON_IMPLEMENTATION_GUIDE.md deleted file mode 100644 index d8a8ee7d6c..0000000000 --- a/packages/ui/ICON_IMPLEMENTATION_GUIDE.md +++ /dev/null @@ -1,1321 +0,0 @@ -# Cherry Studio UI - 彩色 Logo 图标系统实施方案 - -> 借鉴 Lucide IconNode 架构,为 Cherry Studio UI 库构建专门支持彩色品牌 Logo 的轻量级图标系统 - -## 📋 目录 - -- [项目概述](#项目概述) -- [架构设计](#架构设计) -- [核心概念](#核心概念) -- [实施步骤](#实施步骤) -- [使用示例](#使用示例) -- [工作流程](#工作流程) -- [常见问题](#常见问题) - ---- - -## 项目概述 - -### 背景 - -Cherry Studio 是一个 Electron + React 的 monorepo 项目,主包通过 Vite alias 直接引用 UI 包的源码。我们需要为 UI 库添加 40+ 个 **彩色品牌 Logo 图标**(如 Anthropic、OpenAI、DeepSeek、Cohere 等)。 - -### 图标特点 - -这些图标与传统线性图标(如 Lucide)有本质区别: - -| 特征 | 传统线性图标 | 我们的彩色 Logo | -|------|------------|----------------| -| **颜色方式** | `stroke="currentColor"` | `fill="#3F3FAA"` 等固定颜色 | -| **结构** | 简单 path | 复杂嵌套 (``, ``, ``) | -| **样式控制** | 可动态改变颜色/描边 | 必须保留原始颜色 | -| **使用场景** | UI 通用图标 | 品牌标识 | - -### 方案特点 - -- ✅ **保留原色**:完整保留 SVG 中的所有 fill 颜色 -- ✅ **支持嵌套**:处理复杂的 ``、``、`` 结构 -- ✅ **借鉴 Lucide**:采用 IconNode 数据结构,工厂模式创建组件 -- ✅ **轻量级实现**:简化构建流程,无需复杂工具链 -- ✅ **源码直连**:主包通过 alias 直接使用源码,支持热更新 -- ✅ **TypeScript 支持**:完整的类型推导和类型安全 -- ✅ **Tailwind 友好**:完美支持 Tailwind CSS 样式 -- ✅ **自动化生成**:一键从 SVG 生成 React 组件 - -### 技术栈 - -- React 19 -- TypeScript 5.8 -- SVGO 3.0 (SVG 优化) -- Tailwind CSS 4.1 - ---- - -## 架构设计 - -### 目录结构 - -``` -cherry-studio/ -├── packages/ui/ -│ ├── icons/ # ① 源 SVG 文件目录 -│ │ ├── arrow-right.svg -│ │ ├── check.svg -│ │ ├── close.svg -│ │ └── ... (40+ SVG 文件) -│ │ -│ ├── scripts/ -│ │ └── generate-icons.ts # ② 生成脚本 -│ │ -│ ├── src/ -│ │ └── components/ -│ │ └── icons/ -│ │ ├── Icon.tsx # ③ 基础组件 -│ │ ├── generated/ # ④ 自动生成的图标组件 -│ │ │ ├── ArrowRight.tsx -│ │ │ ├── Check.tsx -│ │ │ ├── Close.tsx -│ │ │ └── index.ts -│ │ └── index.ts # ⑤ 统一导出 -│ │ -│ └── package.json -│ -└── src/renderer/src/ # ⑦ 主包使用 - └── components/ - └── YourComponent.tsx -``` - -### 架构分层 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ 用户层 │ -│ │ -└────────────────────────┬────────────────────────────────────┘ - │ -┌────────────────────────▼────────────────────────────────────┐ -│ 具体图标组件层 │ -│ ArrowRight = createIcon('ArrowRight', iconNode) │ -└────────────────────────┬────────────────────────────────────┘ - │ -┌────────────────────────▼────────────────────────────────────┐ -│ 工厂函数层 │ -│ createIcon(name, iconNode) → IconComponent │ -└────────────────────────┬────────────────────────────────────┘ - │ -┌────────────────────────▼────────────────────────────────────┐ -│ 基础组件层 │ -│ Icon: 渲染 SVG,处理 props,映射 IconNode │ -└────────────────────────┬────────────────────────────────────┘ - │ -┌────────────────────────▼────────────────────────────────────┐ -│ 数据层 │ -│ IconNode: [['path', { d: '...' }], ['circle', {...}]] │ -└─────────────────────────────────────────────────────────────┘ -``` - ---- - -## 核心概念 - -### 1. IconNode 数据结构(支持嵌套) - -借鉴 Lucide 的核心设计,扩展为支持嵌套结构的数组格式: - -```typescript -type IconNode = [ - tag: string, // SVG 元素标签名 - attrs: Record, // 元素属性 - children?: IconNode // 子元素(支持嵌套) -][]; - -// 简单示例(平面结构) -const simpleIcon: IconNode = [ - ['path', { d: 'M5 12h14', fill: '#000' }], - ['circle', { cx: '12', cy: '12', r: '10', fill: '#fff' }] -]; - -// 复杂示例(嵌套结构,品牌 Logo 常见) -const complexIcon: IconNode = [ - ['g', { clipPath: 'url(#clip0)' }, [ - ['path', { d: 'M18 0H6...', fill: '#CA9F7B' }], - ['path', { d: 'M15.38 6.43...', fill: '#191918' }] - ]], - ['defs', {}, [ - ['clipPath', { id: 'clip0' }, [ - ['rect', { width: '24', height: '24', fill: 'white' }] - ]] - ]] -]; -``` - -**优势:** -- 📦 体积极小(只存储数据,不存储模板) -- 🔄 框架无关(可复用于 Vue/Svelte 等) -- ⚡ 渲染快速(直接 createElement,无需解析) -- 🎨 **保留原色**(完整保留 fill 等样式属性) -- 🌲 **支持嵌套**(处理复杂的品牌 Logo 结构) - -### 2. 工厂模式 - -使用 `createIcon` 函数统一创建图标组件: - -```typescript -export function createIcon( - componentName: string, - iconNode: IconNode -) { - const IconComponent = forwardRef( - (props, ref) => { - return ; - } - ); - - IconComponent.displayName = componentName; - return IconComponent; -} -``` - -**优势:** -- ✅ 代码复用(40+ 图标共享同一套逻辑) -- ✅ 统一行为(所有图标的 props 处理完全一致) -- ✅ 易于维护(修改一处,全部更新) - -### 3. 自动化生成 - -从 SVG 到 React 组件的自动化流程: - -``` -SVG 文件 → SVGO 优化 → 正则解析 → IconNode → 组件代码 → 写入文件 -``` - ---- - -## 实施步骤 - -### 步骤 1:创建基础 Icon 组件 - -创建文件:`packages/ui/src/components/icons/Icon.tsx` - -```tsx -import React, { forwardRef, memo } from 'react'; -import { cn } from '@/utils'; - -/** - * IconNode 数据结构(借鉴 lucide,扩展支持嵌套) - * 格式: [标签名, 属性对象, 子元素(可选)] - */ -export type IconNode = [ - tag: string, - attrs: Record, - children?: IconNode -][]; - -/** - * Icon 组件的 Props(专为彩色 Logo 优化) - */ -export interface IconProps extends React.SVGProps { - /** 图标大小,支持数字(px)或字符串(如 "1rem") */ - size?: number | string; - /** 自定义类名 */ - className?: string; - /** 子元素 */ - children?: React.ReactNode; -} - -/** - * Icon 组件内部 Props(包含 iconNode) - */ -interface IconComponentProps extends IconProps { - iconNode: IconNode; - /** 图标名称(用于 className) */ - iconName?: string; -} - -/** - * 递归渲染 IconNode(支持嵌套结构) - */ -function renderNodes(nodes: IconNode, keyPrefix = ''): React.ReactNode[] { - return nodes.map((node, index) => { - const [tag, attrs, children] = node; - const key = `${keyPrefix}${index}`; - - // 如果有子元素,递归渲染 - const childElements = children ? renderNodes(children, `${key}-`) : undefined; - - return React.createElement( - tag, - { key, ...attrs }, - childElements - ); - }); -} - -/** - * 基础 Icon 组件(专为彩色品牌 Logo 设计) - * - 保留 SVG 原始颜色(不强制 fill/stroke) - * - 支持嵌套结构(g, clipPath, defs 等) - * - 只控制 size 和 className - */ -export const Icon = memo( - forwardRef( - ( - { - iconNode, - iconName, - size = 24, - className, - children, - ...props - }, - ref - ) => { - return ( - - {/* 递归渲染 IconNode(支持嵌套) */} - {renderNodes(iconNode)} - {children} - - ); - } - ) -); - -Icon.displayName = 'Icon'; - -/** - * 工厂函数:创建具体的图标组件 - * @param componentName - 组件名称(PascalCase) - * @param iconNode - 图标数据 - * @returns 图标组件 - */ -export function createIcon( - componentName: string, - iconNode: IconNode -) { - const IconComponent = forwardRef( - (props, ref) => { - return ( - - ); - } - ); - - IconComponent.displayName = componentName; - return IconComponent; -} -``` - ---- - -### 步骤 2:创建生成脚本 - -创建文件:`packages/ui/scripts/generate-icons.ts` - -```typescript -import fs from 'fs/promises'; -import path from 'path'; -import { optimize } from 'svgo'; - -const ICONS_DIR = path.join(__dirname, '../icons'); -const OUTPUT_DIR = path.join(__dirname, '../src/components/icons/generated'); - -// SVGO 优化配置(专为彩色 Logo 优化) -const svgoConfig = { - plugins: [ - { - name: 'preset-default', - params: { - overrides: { - // 保留 viewBox(必须!) - removeViewBox: false, - // 不转换为 path(保持原始形状) - convertShapeToPath: false, - // 不移除隐藏元素(可能包含 defs) - removeHiddenElems: false, - }, - }, - }, - { - // 只移除 width 和 height(保留所有颜色和样式) - name: 'removeAttrs', - params: { - attrs: '(width|height)', - }, - }, - ], -}; - -/** - * 转换命名:kebab-case → PascalCase - * 例: arrow-right → ArrowRight, 302ai → Ai302 - */ -function toPascalCase(str: string): string { - // 处理数字开头的情况(如 302ai) - if (/^\d/.test(str)) { - // 提取开头的数字和后续部分 - const match = str.match(/^(\d+)(.*)$/); - if (match) { - const [, numbers, rest] = match; - // 将数字放在后面:302ai → Ai302 - str = rest + numbers; - } - } - - return str - .split('-') - .map(word => word.charAt(0).toUpperCase() + word.slice(1)) - .join(''); -} - -/** - * 解析 SVG 为 IconNode 格式(支持嵌套结构) - * 使用 svgson 库来可靠地处理复杂的嵌套结构 - */ -async function parseSvg(svgContent: string): Promise { - const { parse } = await import('svgson'); - - // 1. SVGO 优化 - const optimized = optimize(svgContent, svgoConfig); - const svgString = optimized.data; - - // 2. 使用 svgson 解析为 AST - const ast = await parse(svgString); - - // 3. 转换为 IconNode 格式 - const iconNode = convertToIconNode(ast.children); - - // 4. 格式化为 TypeScript 代码 - return formatIconNode(iconNode); -} - -/** - * 将 svgson AST 转换为 IconNode 格式 - */ -function convertToIconNode(nodes: any[]): any[] { - return nodes.map(node => { - const { name, attributes, children } = node; - - if (children && children.length > 0) { - const childNodes = convertToIconNode(children); - return [name, attributes, childNodes]; - } else { - return [name, attributes]; - } - }); -} - -/** - * 格式化 IconNode 为 TypeScript 代码 - */ -function formatIconNode(nodes: any[], indent = 0): string { - const indentStr = ' '.repeat(indent + 1); - - const items = nodes.map(node => { - const [tag, attrs, children] = node; - - if (children) { - const childrenStr = formatIconNode(children, indent + 1); - return `${indentStr}['${tag}', ${JSON.stringify(attrs)}, ${childrenStr}]`; - } else { - return `${indentStr}['${tag}', ${JSON.stringify(attrs)}]`; - } - }); - - if (indent === 0) { - return `[\n${items.join(',\n')}\n]`; - } else { - return `[\n${items.join(',\n')}\n${' '.repeat(indent)}]`; - } -} - -/** - * 生成单个图标组件文件 - */ -async function generateIconComponent( - iconName: string, - iconNode: string -): Promise { - const componentName = toPascalCase(iconName); - - return `import { forwardRef } from 'react'; -import { createIcon, type IconProps } from '../Icon'; -import type { IconNode } from '../Icon'; - -const iconNode: IconNode = ${iconNode}; - -/** - * ${componentName} icon component - * - * @example - * <${componentName} size={24} color="red" /> - * <${componentName} className="text-blue-500" /> - */ -export const ${componentName} = createIcon('${componentName}', iconNode); - -export default ${componentName}; -`; -} - -/** - * 主函数:生成所有图标 - */ -async function generateIcons() { - console.log('🚀 开始生成图标组件...\n'); - - try { - // 检查 icons 目录是否存在 - try { - await fs.access(ICONS_DIR); - } catch { - console.error(`❌ 错误: 找不到 icons 目录: ${ICONS_DIR}`); - console.log(`💡 提示: 请创建 ${ICONS_DIR} 目录并放入 SVG 文件`); - process.exit(1); - } - - // 确保输出目录存在 - await fs.mkdir(OUTPUT_DIR, { recursive: true }); - - // 读取所有 SVG 文件 - const files = await fs.readdir(ICONS_DIR); - const svgFiles = files.filter(f => f.endsWith('.svg')); - - if (svgFiles.length === 0) { - console.warn(`⚠️ 警告: ${ICONS_DIR} 目录中没有找到 SVG 文件`); - process.exit(0); - } - - console.log(`📁 找到 ${svgFiles.length} 个 SVG 文件\n`); - - const exports: string[] = []; - let successCount = 0; - let errorCount = 0; - - // 处理每个 SVG 文件 - for (const file of svgFiles) { - const iconName = file.replace('.svg', ''); - const componentName = toPascalCase(iconName); - - try { - console.log(`⚙️ 处理: ${iconName}`); - - // 读取 SVG 内容 - const svgPath = path.join(ICONS_DIR, file); - const svgContent = await fs.readFile(svgPath, 'utf-8'); - - // 解析为 IconNode - const iconNode = await parseSvg(svgContent); - - // 生成组件代码 - const componentCode = await generateIconComponent(iconName, iconNode); - - // 写入文件 - const outputPath = path.join(OUTPUT_DIR, `${componentName}.tsx`); - await fs.writeFile(outputPath, componentCode, 'utf-8'); - - // 收集导出语句 - exports.push(`export { ${componentName} } from './${componentName}';`); - successCount++; - } catch (error) { - console.error(`❌ 处理 ${iconName} 失败:`, error); - errorCount++; - } - } - - // 生成 index.ts(统一导出) - const indexContent = `/** - * 自动生成的图标导出文件 - * 请勿手动编辑 - * - * 生成时间: ${new Date().toISOString()} - * 图标数量: ${successCount} - */ - -${exports.sort().join('\n')} -`; - - await fs.writeFile( - path.join(OUTPUT_DIR, 'index.ts'), - indexContent, - 'utf-8' - ); - - // 输出结果 - console.log(`\n✅ 成功生成 ${successCount} 个图标组件!`); - if (errorCount > 0) { - console.log(`⚠️ 失败 ${errorCount} 个图标`); - } - console.log(`📦 输出目录: ${OUTPUT_DIR}`); - } catch (error) { - console.error('\n❌ 生成过程发生错误:', error); - process.exit(1); - } -} - -// 执行生成 -generateIcons(); -``` - ---- - -### 步骤 3:更新 package.json - -在 `packages/ui/package.json` 中添加: - -```json -{ - "scripts": { - "generate:icons": "tsx scripts/generate-icons.ts", - "build": "pnpm generate:icons && tsdown", - "dev": "tsc -w" - }, - "devDependencies": { - "svgo": "^3.0.0", - "svgson": "^5.3.1", - "tsx": "^4.20.5" - } -} -``` - -安装依赖: - -```bash -cd packages/ui -pnpm add -D svgo svgson tsx -``` - ---- - -### 步骤 4:创建统一导出 - -创建文件:`packages/ui/src/components/icons/index.ts` - -```typescript -/** - * Icons 模块统一导出 - */ - -// 导出基础组件和类型 -export { Icon, createIcon, type IconProps, type IconNode } from './Icon'; - -// 导出所有生成的图标 -export * from './generated'; -``` - ---- - -### 步骤 5:更新主导出文件 - -在 `packages/ui/src/components/index.ts` 中添加: - -```typescript -// Icons -export * from './icons'; -``` - ---- - -### 步骤 6:配置子路径导出(推荐) - -为了支持 `@cherrystudio/ui/icons` 导入路径,需要在 `package.json` 中配置 `exports` 字段: - -```json -{ - "name": "@cherrystudio/ui", - "version": "1.0.0", - "type": "module", - "exports": { - ".": { - "import": "./src/components/index.ts", - "types": "./src/components/index.ts" - }, - "./icons": { - "import": "./src/components/icons/index.ts", - "types": "./src/components/icons/index.ts" - } - } -} -``` - -**同时更新主包的 Vite 配置**(`electron.vite.config.ts`): - -```typescript -export default defineConfig({ - resolve: { - alias: { - '@cherrystudio/ui': resolve('packages/ui/src/components'), - '@cherrystudio/ui/icons': resolve('packages/ui/src/components/icons'), - } - } -}); -``` - -这样你就可以使用两种导入方式: - -```tsx -// 推荐:从 icons 子路径导入(84个图标) -import { Anthropic, Deepseek } from '@cherrystudio/ui/icons'; - -// 兼容:从主包导入 -import { Anthropic, Deepseek } from '@cherrystudio/ui'; -``` - ---- - -### 步骤 7:创建 icons 目录 - -```bash -cd packages/ui -mkdir icons -``` - -将你的 84 个 SVG 文件放入 `icons/` 目录。 - ---- - -## 使用示例 - -### 基础用法(彩色品牌 Logo) - -```tsx -// 推荐:从 icons 子路径导入(84个图标,语义更清晰) -import { Anthropic, Deepseek, Cohere, Ai302 } from '@cherrystudio/ui/icons'; - -// 也可以:从主包导入(兼容方式) -// import { Anthropic, Deepseek } from '@cherrystudio/ui'; - -export function BasicExample() { - return ( -
- {/* 默认大小(24px) */} - - - {/* 自定义大小 */} - - - - {/* 使用字符串大小 */} - -
- ); -} -``` - -### Tailwind CSS 集成 - -```tsx -import { Anthropic, Deepseek } from '@cherrystudio/ui/icons'; - -export function TailwindExample() { - return ( -
- {/* 使用 Tailwind 控制大小 */} - - - {/* 悬停效果(注意:颜色不可更改,但可添加缩放、阴影等效果) */} - - - {/* 响应式设计 */} - - - {/* 添加阴影和圆角效果 */} - -
- ); -} -``` - -**重要提示:** - -- ❌ **不要尝试修改图标颜色**(这些是品牌 Logo,颜色是固定的) -- ✅ 可以修改 `size`、`className` -- ✅ 可以使用 Tailwind 的 `scale`、`opacity`、`transform`、`shadow` 等效果 - -### 事件处理 - -```tsx -import { Anthropic, Deepseek } from '@cherrystudio/ui/icons'; - -export function EventExample() { - const handleClick = () => { - console.log('Logo clicked!'); - }; - - return ( -
- {/* onClick 事件 */} - - - {/* 其他事件 */} - console.log('Mouse enter')} - onMouseLeave={() => console.log('Mouse leave')} - className="cursor-pointer transition-opacity hover:opacity-75" - /> -
- ); -} -``` - -### 使用 ref - -```tsx -import { Anthropic } from '@cherrystudio/ui/icons'; -import { useRef, useEffect } from 'react'; - -export function RefExample() { - const iconRef = useRef(null); - - useEffect(() => { - if (iconRef.current) { - console.log('Logo SVG element:', iconRef.current); - // 可以执行 DOM 操作,如添加动画 - } - }, []); - - return ; -} -``` - -### 自定义彩色图标 - -如果你有自己的彩色 SVG 图标,可以手动创建: - -```tsx -import { createIcon, type IconNode } from '@cherrystudio/ui/icons'; - -// 定义自定义彩色图标数据(带嵌套和颜色) -const customLogoNode: IconNode = [ - ['g', { clipPath: 'url(#clip0)' }, [ - ['circle', { cx: '12', cy: '12', r: '10', fill: '#FF6B6B' }], - ['path', { d: 'M12 6v6l4 2', stroke: '#fff', strokeWidth: '2' }] - ]], - ['defs', {}, [ - ['clipPath', { id: 'clip0' }, [ - ['rect', { width: '24', height: '24', fill: 'white' }] - ]] - ]] -]; - -// 创建自定义图标组件 -const MyBrandLogo = createIcon('MyBrandLogo', customLogoNode); - -export function CustomIconExample() { - return ; -} -``` - -### 组合使用 - -```tsx -import { Anthropic, Deepseek, Cohere } from '@cherrystudio/ui/icons'; - -export function CompositeExample() { - return ( -
- {/* AI 模型选择器 */} -
- {[ - { Logo: Anthropic, name: 'Claude' }, - { Logo: Deepseek, name: 'DeepSeek' }, - { Logo: Cohere, name: 'Cohere' } - ].map(({ Logo, name }) => ( - - ))} -
- - {/* Logo 网格展示 */} -
-
- -
-
- -
-
- -
-
-
- ); -} -``` - ---- - -## 工作流程 - -### 开发流程 - -```bash -# 1. 准备 SVG 文件 -# 将 SVG 文件放到 packages/ui/icons/ 目录 - -# 2. 生成图标组件 -cd packages/ui -pnpm generate:icons - -# 3. 在主包中使用 -# 主包会通过 Vite alias 自动识别,直接导入使用 -``` - -### 生成的文件 - -``` -packages/ui/src/components/icons/ -├── Icon.tsx # ✅ 手写(基础组件) -├── generated/ # ⚠️ 自动生成(不要手动编辑) -│ ├── ArrowRight.tsx -│ ├── Check.tsx -│ ├── Close.tsx -│ ├── ... (40+ 个文件) -│ └── index.ts -└── index.ts # ✅ 手写(统一导出) -``` - -### 构建流程 - -**开发模式:** -- 主包通过 Vite alias 直接引用 UI 包源码 -- 支持热更新(HMR) -- 无需构建 UI 包 - -**生产构建:** - -```bash -# UI 包单独构建(如需发布) -cd packages/ui -pnpm build # 会先 generate:icons,然后 tsdown 打包 - -# 主包构建 -cd cherry-studio -pnpm build # Vite 会处理 UI 包的源码 -``` - ---- - -## 常见问题 - -### Q1: 为什么主包可以直接使用源码? - -**A:** 因为主包的 Vite 配置了 alias: - -```typescript -// electron.vite.config.ts -'@cherrystudio/ui': resolve('packages/ui/src') -``` - -这样导入的是 `.tsx` 源文件,Vite 会像处理主包代码一样处理这些文件,支持热更新和 TypeScript 类型推导。 - ---- - -### Q2: 彩色 Logo SVG 文件有什么要求? - -**A:** 针对彩色品牌 Logo 的要求: - -- ✅ 使用标准的 24x24 viewBox(推荐) -- ✅ 保留所有 `fill` 颜色(会自动保留) -- ✅ 支持复杂嵌套结构(``, ``, `` 等) -- ✅ 文件名使用 kebab-case(如 `anthropic.svg`、`deep-seek.svg`) -- ✅ 数字开头的文件名会自动转换(如 `302ai.svg` → `Ai302` 组件) - -示例彩色 Logo SVG: -```xml - - - - - - - - - - - -``` - -**注意事项:** - -- ⚠️ 确保 SVG 格式正确(使用 Figma/Illustrator 导出时选择"优化") -- ⚠️ ID 属性可能需要全局唯一(如 `clip0` 改为 `clip-anthropic`) -- ⚠️ 过大的 SVG 文件(超过 100KB)建议先手动优化 - ---- - -### Q3: 如何调试生成错误? - -**A:** 如果某个图标生成失败: - -1. **检查 SVG 文件语法**:使用浏览器直接打开 SVG 文件,看是否正常显示 -2. **测试 SVGO 优化**: - ```bash - npx svgo icons/your-icon.svg -o test.svg - ``` -3. **查看生成脚本的错误日志**:运行 `pnpm generate:icons` 时会显示详细错误 -4. **验证 SVG 结构**:本方案支持所有标准 SVG 元素(通过 svgson 解析) -5. **检查文件编码**:确保 SVG 文件是 UTF-8 编码 - ---- - -### Q4: 如何添加新图标? - -**A:** 非常简单: - -```bash -# 1. 将新的 SVG 文件放入 icons/ 目录 -cp new-icon.svg packages/ui/icons/ - -# 2. 重新生成 -cd packages/ui -pnpm generate:icons - -# 3. 立即可用(无需重启开发服务器) -import { NewIcon } from '@cherrystudio/ui/icons'; -``` - ---- - -### Q5: 如何自定义生成的代码? - -**A:** 修改 `scripts/generate-icons.ts` 中的 `generateIconComponent` 函数: - -```typescript -async function generateIconComponent( - iconName: string, - iconNode: string -): Promise { - const componentName = toPascalCase(iconName); - - // 在这里自定义生成的代码模板 - return `...`; -} -``` - ---- - -### Q6: TypeScript 类型如何工作? - -**A:** 完全自动,无需手动声明: - -```typescript -// IconProps 继承自 React.SVGProps -// 所以支持所有 SVG 属性 - - {}} // SVGProps - onMouseEnter={() => {}} // SVGProps - style={{ opacity: 0.8 }} // SVGProps - aria-label="Anthropic" // SVGProps - // ... 所有 SVG 属性 -/> -``` - -**注意:** 彩色 Logo 版本移除了 `color` 和 `strokeWidth` 属性(因为颜色是固定的) - ---- - -### Q7: 生成的文件需要提交到 Git 吗? - -**A:** 推荐做法: - -- ✅ **提交** `generated/` 目录(方便团队协作) -- ✅ **在 CI/CD 中重新生成**(确保一致性) - -`.gitignore` 配置: -```gitignore -# 可选:不提交生成文件(需要在 CI 中生成) -# packages/ui/src/components/icons/generated/ - -# 必须提交 icons 源文件 -!packages/ui/icons/*.svg -``` - ---- - -### Q8: 能否修改 Logo 的颜色? - -**A:** ❌ **不建议修改品牌 Logo 的颜色** - -这些是品牌官方 Logo,颜色是品牌标识的一部分,**不应该修改**。 - -**替代方案:** - -```tsx -import { Anthropic } from '@cherrystudio/ui/icons'; - -// ✅ 可以调整透明度 - - - -// ✅ 可以添加滤镜效果(慎用) - // 灰度滤镜 - - -// ❌ 不要尝试修改颜色 -// // 无效 -// // 无效 -``` - -**为什么无法修改颜色?** - -- 颜色信息存储在 IconNode 数据中(如 `fill="#CA9F7B"`) -- 这是设计决策:保护品牌标识的完整性 -- 如果需要可变颜色的图标,应该使用 Lucide 等线性图标库 - ---- - -### Q9: 如何与 Lucide React 共存? - -**A:** 完全可以同时使用: - -```tsx -// 使用彩色品牌 Logo(84个) -import { Anthropic, Deepseek } from '@cherrystudio/ui/icons'; - -// 使用 Lucide 线性图标 -import { Heart, Settings, User } from 'lucide-react'; - -export function MixedExample() { - return ( -
- {/* 品牌 Logo:固定颜色 */} - - - - {/* Lucide 图标:可变颜色 */} - - -
- ); -} -``` - -两者的 API 基本一致(都继承自 Lucide 的设计),但用途不同: - -- **Cherry Studio Icons**:彩色品牌 Logo -- **Lucide Icons**:单色通用图标 - ---- - -### Q10: 性能如何? - -**A:** 性能优秀: - -- 📦 **体积小**:每个图标约 0.5-1.5KB(IconNode 数据) -- ⚡ **渲染快**:直接 `createElement`,无需解析 -- 🌲 **Tree-shaking**:只打包使用的图标 -- 💾 **无运行时**:零运行时依赖 -- 🎨 **保留细节**:完整保留彩色 Logo 的所有颜色和细节 - -对比: - -``` -传统方式(内联 SVG JSX):~2-3KB/Logo -IconNode 方式(彩色):~0.5-1.5KB/Logo -节省:~50-75% 体积 -``` - -**注意:** 彩色 Logo 比简单线性图标稍大,因为包含更多颜色和路径信息,但仍然非常高效。 - ---- - -### Q11: 如何批量更新图标? - -**A:** 直接替换 SVG 文件,然后重新生成: - -```bash -# 1. 更新 SVG 文件(替换现有的或添加新的) -cp new-logos/*.svg packages/ui/icons/ - -# 2. 重新生成组件 -cd packages/ui -pnpm generate:icons - -# 3. 所有使用该图标的地方自动更新(无需修改代码) -``` - -**批量处理技巧:** - -```bash -# 批量优化 SVG(使用 SVGO) -npx svggo -f icons/ -o icons-optimized/ - -# 批量重命名(确保 kebab-case) -# 使用 rename 工具或脚本处理 -``` - ---- - -## 附录 - -### A. 命名规范 - -**SVG 文件名(品牌 Logo):** - -- 使用 kebab-case:`anthropic.svg`、`deep-seek.svg` -- 只包含小写字母、数字、连字符 -- 使用品牌官方名称 -- 数字开头会自动处理:`302ai.svg` → `Ai302` - -**组件名(自动生成):** - -- 自动转换为 PascalCase:`Anthropic`、`DeepSeek`、`Ai302` -- 无需手动指定 - -### B. SVGO 配置说明(彩色 Logo 专用) - -```javascript -{ - plugins: [ - { - name: 'preset-default', - params: { - overrides: { - removeViewBox: false, // 保留 viewBox(必须) - convertShapeToPath: false, // 不转换为 path(保持原始形状) - removeHiddenElems: false, // 不移除隐藏元素(保留 defs) - }, - }, - }, - { - name: 'removeAttrs', - params: { - attrs: '(width|height)', // 只移除 width/height,保留所有颜色 - }, - }, - ], -} -``` - -**关键差异:** - -- ✅ **保留 fill**:不移除颜色属性(传统方案会移除) -- ✅ **保留 defs**:保留 clipPath、linearGradient 等定义 -- ✅ **保留嵌套**:完整保留 `` 嵌套结构 - -### C. 目录结构完整示例(彩色品牌 Logo) - -``` -packages/ui/ -├── icons/ # 彩色 Logo SVG 源文件 -│ ├── 302ai.svg -│ ├── aiOnly.svg -│ ├── aihubmix.svg -│ ├── anthropic.svg -│ ├── aws-bedrock.svg -│ ├── baichuan.svg -│ ├── baidu-cloud.svg -│ ├── bailian.svg -│ ├── bytedance.svg -│ ├── cephalon.svg -│ ├── cherryin.svg -│ ├── cohere.svg -│ ├── dashscope.svg -│ ├── deepseek.svg -│ └── ... (40+ 品牌 Logo) -│ -├── scripts/ -│ └── generate-icons.ts # 生成脚本(支持嵌套和彩色) -│ -├── src/ -│ └── components/ -│ └── icons/ -│ ├── Icon.tsx # 基础组件(支持嵌套渲染) -│ ├── index.ts # 统一导出 -│ └── generated/ # 自动生成的 Logo 组件 -│ ├── Ai302.tsx -│ ├── AiOnly.tsx -│ ├── Aihubmix.tsx -│ ├── Anthropic.tsx -│ ├── AwsBedrock.tsx -│ ├── Baichuan.tsx -│ ├── BaiduCloud.tsx -│ ├── Bailian.tsx -│ ├── Bytedance.tsx -│ ├── Cephalon.tsx -│ ├── Cherryin.tsx -│ ├── Cohere.tsx -│ ├── Dashscope.tsx -│ ├── Deepseek.tsx -│ ├── ... (40+ 组件) -│ └── index.ts -│ -└── package.json -``` - ---- - -## 总结 - -本方案借鉴 Lucide 的核心 IconNode 架构,专门为 Cherry Studio UI 库打造了一个轻量级、高性能的**彩色品牌 Logo 图标系统**: - -### 核心优势 - -✅ **保留原色**:完整保留品牌 Logo 的所有颜色和细节 -✅ **支持嵌套**:处理复杂的 SVG 结构(g, clipPath, defs 等) -✅ **自动生成**:一键从 SVG 生成 React 组件,无需手动编写 -✅ **高效轻量**:IconNode 数据结构,体积小、渲染快 -✅ **类型安全**:完整的 TypeScript 支持 -✅ **Tailwind 友好**:完美集成 Tailwind CSS -✅ **易于维护**:工厂模式,统一管理,易于扩展 - -### 与传统方案的区别 - -| 特性 | 传统线性图标(Lucide) | 本方案(彩色 Logo) | -|------|---------------------|------------------| -| **颜色** | 单色,可动态改变 | 多色,保留原色 | -| **复杂度** | 简单路径 | 支持嵌套结构 | -| **用途** | 通用 UI 图标 | 品牌 Logo 展示 | -| **体积** | ~0.3KB | ~0.5-1.5KB | - -### 快速开始 - -```bash -cd packages/ui - -# 1. 安装依赖 -pnpm add -D svgo svgson tsx - -# 2. 准备 SVG 文件(已有 84 个品牌 Logo) -# icons/ 目录已包含: anthropic.svg, deepseek.svg, cohere.svg... - -# 3. 生成组件 -pnpm generate:icons - -# 4. 在代码中使用(推荐使用 /icons 子路径) -# import { Anthropic, Deepseek } from '@cherrystudio/ui/icons'; -``` - -现在就可以在主包中使用彩色品牌 Logo 了!🎉 - -### 下一步 - -1. 阅读[使用示例](#使用示例)了解更多用法 -2. 查看[常见问题](#常见问题)解决疑惑 -3. 将更多品牌 Logo SVG 添加到 `icons/` 目录 -4. 运行 `pnpm generate:icons` 生成新组件 diff --git a/packages/ui/icons/dmxapi-logo-dark.svg b/packages/ui/icons/dmxapi-logo-dark.svg deleted file mode 100644 index 571a918120..0000000000 --- a/packages/ui/icons/dmxapi-logo-dark.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/packages/ui/icons/openai-1.svg b/packages/ui/icons/openai-1.svg deleted file mode 100644 index a0b49d226e..0000000000 --- a/packages/ui/icons/openai-1.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/packages/ui/icons/perplexity-1.svg b/packages/ui/icons/perplexity-1.svg deleted file mode 100644 index 5134503045..0000000000 --- a/packages/ui/icons/perplexity-1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/packages/ui/icons/Tesseract.js.svg b/packages/ui/icons/tesseract-js.svg similarity index 100% rename from packages/ui/icons/Tesseract.js.svg rename to packages/ui/icons/tesseract-js.svg diff --git a/packages/ui/package.json b/packages/ui/package.json index 324aa42715..6df25ee88e 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -16,7 +16,7 @@ "type-check": "tsc --noEmit -p tsconfig.json --composite false", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", - "tokens:build": "node scripts/generate-theme-from-tokens.mjs" + "icons:generate": "tsx scripts/generate-icons.ts" }, "keywords": [ "ui", @@ -67,6 +67,10 @@ "@storybook/addon-docs": "^10.0.5", "@storybook/addon-themes": "^10.0.5", "@storybook/react-vite": "^10.0.5", + "@svgr/core": "^8.1.0", + "@svgr/plugin-jsx": "^8.1.0", + "@svgr/plugin-prettier": "^8.1.0", + "@svgr/plugin-svgo": "^8.1.0", "@types/react": "^19.0.12", "@types/react-dom": "^19.0.4", "@types/styled-components": "^5.1.34", @@ -81,8 +85,9 @@ "react-dom": "^19.0.0", "storybook": "^10.0.5", "styled-components": "^6.1.15", + "svgo": "^4.0.0", "tsdown": "^0.15.5", - "tsx": "^4.20.5", + "tsx": "^4.20.6", "typescript": "^5.6.2", "vitest": "^3.2.4" }, diff --git a/packages/ui/scripts/generate-icons.ts b/packages/ui/scripts/generate-icons.ts new file mode 100644 index 0000000000..eed250af56 --- /dev/null +++ b/packages/ui/scripts/generate-icons.ts @@ -0,0 +1,170 @@ +/** + * Generate React components from SVG files using @svgr/core + * Simple approach: use SVGR defaults + component name handling + */ +import { transform } from '@svgr/core' +import fs from 'fs/promises' +import path from 'path' + +const ICONS_DIR = path.join(__dirname, '../icons') +const OUTPUT_DIR = path.join(__dirname, '../src/components/icons/logos') + +/** + * Convert filename to PascalCase component name + * Handle numeric prefix: 302ai -> Ai302 + */ +function toPascalCase(filename: string): string { + const name = filename.replace(/\.svg$/, '') + + if (/^\d/.test(name)) { + const match = name.match(/^(\d+)(.*)$/) + if (match) { + const [, numbers, rest] = match + const restCamel = rest.replace(/-([a-z])/g, (_, char) => char.toUpperCase()) + return restCamel.charAt(0).toUpperCase() + restCamel.slice(1) + numbers + } + } + + // Convert kebab-case to PascalCase: aws-bedrock -> AwsBedrock + return name + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join('') +} + +/** + * Convert kebab-case to camelCase for filename + */ +function toCamelCase(filename: string): string { + const name = filename.replace(/\.svg$/, '') + const parts = name.split('-') + + if (parts.length === 1) { + return parts[0] + } + + return ( + parts[0] + + parts + .slice(1) + .map((p) => p.charAt(0).toUpperCase() + p.slice(1)) + .join('') + ) +} + +/** + * Generate a single icon component + */ +async function generateIcon(svgFile: string): Promise<{ filename: string; componentName: string }> { + const svgPath = path.join(ICONS_DIR, svgFile) + const svgCode = await fs.readFile(svgPath, 'utf-8') + + const componentName = toPascalCase(svgFile) + const outputFilename = toCamelCase(svgFile) + '.tsx' + const outputPath = path.join(OUTPUT_DIR, outputFilename) + + // Use SVGR with simple config + let jsCode = await transform( + svgCode, + { + plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier'], + icon: true, + typescript: true, + jsxRuntime: 'automatic', + svgoConfig: { + plugins: [ + // { + // name: 'preset-default', + // params: { + // overrides: { + // removeViewBox: false, + // // Important: Keep IDs but make them unique per component + // cleanupIds: false + // } + // } + // }, + { + // Add unique prefix to all IDs based on component name + name: 'prefixIds', + params: { + prefix: componentName.toLowerCase() + } + } + ] + } + }, + { componentName } + ) + + // Add named export + jsCode = jsCode.replace( + `export default ${componentName};`, + `export { ${componentName} };\nexport default ${componentName};` + ) + + await fs.writeFile(outputPath, jsCode, 'utf-8') + + return { filename: outputFilename, componentName } +} + +/** + * Generate index.ts file + */ +async function generateIndex(components: Array<{ filename: string; componentName: string }>) { + const exports = components + .map(({ filename, componentName }) => { + const basename = filename.replace('.tsx', '') + return `export { ${componentName} } from './${basename}'` + }) + .sort() + .join('\n') + + const indexContent = `/** + * Auto-generated icon exports + * Do not edit manually + * + * Generated at: ${new Date().toISOString()} + * Total icons: ${components.length} + */ + +${exports} +` + + await fs.writeFile(path.join(OUTPUT_DIR, 'index.ts'), indexContent, 'utf-8') +} + +/** + * Main function + */ +async function main() { + console.log('🔧 Starting icon generation...\n') + + // Ensure output directory exists + await fs.mkdir(OUTPUT_DIR, { recursive: true }) + + // Get all SVG files + const files = await fs.readdir(ICONS_DIR) + const svgFiles = files.filter((f) => f.endsWith('.svg')) + + console.log(`📁 Found ${svgFiles.length} SVG files\n`) + + const components: Array<{ filename: string; componentName: string }> = [] + + for (const svgFile of svgFiles) { + try { + const result = await generateIcon(svgFile) + components.push(result) + console.log(`✅ ${svgFile} -> ${result.filename} (${result.componentName})`) + } catch (error) { + console.error(`❌ Failed to process ${svgFile}:`, error) + } + } + + // Generate index.ts + console.log('\n📝 Generating index.ts...') + await generateIndex(components) + + console.log(`\n✨ Generation complete! Successfully processed ${components.length}/${svgFiles.length} files`) +} + +main() diff --git a/packages/ui/src/components/icons/index.ts b/packages/ui/src/components/icons/index.ts new file mode 100644 index 0000000000..ce739c93e2 --- /dev/null +++ b/packages/ui/src/components/icons/index.ts @@ -0,0 +1,6 @@ +/** + * Icons 模块统一导出 + */ + +// 导出所有生成的彩色品牌 Logo 图标(81个) +export * from './logos' diff --git a/packages/ui/src/components/icons/logos/302ai.tsx b/packages/ui/src/components/icons/logos/302ai.tsx new file mode 100644 index 0000000000..e28700af61 --- /dev/null +++ b/packages/ui/src/components/icons/logos/302ai.tsx @@ -0,0 +1,26 @@ +import type { SVGProps } from 'react' +const Ai302 = (props: SVGProps) => ( + + + + + + + + + + + + +) +export { Ai302 } +export default Ai302 diff --git a/packages/ui/src/components/icons/logos/aiOnly.tsx b/packages/ui/src/components/icons/logos/aiOnly.tsx new file mode 100644 index 0000000000..867c64643d --- /dev/null +++ b/packages/ui/src/components/icons/logos/aiOnly.tsx @@ -0,0 +1,28 @@ +import type { SVGProps } from 'react' +const AiOnly = (props: SVGProps) => ( + + + + + + + + + + +) +export { AiOnly } +export default AiOnly diff --git a/packages/ui/src/components/icons/logos/aihubmix.tsx b/packages/ui/src/components/icons/logos/aihubmix.tsx new file mode 100644 index 0000000000..cc21a8140f --- /dev/null +++ b/packages/ui/src/components/icons/logos/aihubmix.tsx @@ -0,0 +1,34 @@ +import type { SVGProps } from 'react' +const Aihubmix = (props: SVGProps) => ( + + + + + + + + + + + + + + + +) +export { Aihubmix } +export default Aihubmix diff --git a/packages/ui/src/components/icons/logos/alayanew.tsx b/packages/ui/src/components/icons/logos/alayanew.tsx new file mode 100644 index 0000000000..ab7446e305 --- /dev/null +++ b/packages/ui/src/components/icons/logos/alayanew.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Alayanew = (props: SVGProps) => ( + + + + + + + + + +) +export { Alayanew } +export default Alayanew diff --git a/packages/ui/src/components/icons/logos/anthropic.tsx b/packages/ui/src/components/icons/logos/anthropic.tsx new file mode 100644 index 0000000000..d85307c55b --- /dev/null +++ b/packages/ui/src/components/icons/logos/anthropic.tsx @@ -0,0 +1,22 @@ +import type { SVGProps } from 'react' +const Anthropic = (props: SVGProps) => ( + + + + + + + + + + + +) +export { Anthropic } +export default Anthropic diff --git a/packages/ui/src/components/icons/logos/awsBedrock.tsx b/packages/ui/src/components/icons/logos/awsBedrock.tsx new file mode 100644 index 0000000000..7a1a5ae4ee --- /dev/null +++ b/packages/ui/src/components/icons/logos/awsBedrock.tsx @@ -0,0 +1,48 @@ +import type { SVGProps } from 'react' +const AwsBedrock = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + +) +export { AwsBedrock } +export default AwsBedrock diff --git a/packages/ui/src/components/icons/logos/azureai.tsx b/packages/ui/src/components/icons/logos/azureai.tsx new file mode 100644 index 0000000000..1bd7f3db0b --- /dev/null +++ b/packages/ui/src/components/icons/logos/azureai.tsx @@ -0,0 +1,85 @@ +import type { SVGProps } from 'react' +const Azureai = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) +export { Azureai } +export default Azureai diff --git a/packages/ui/src/components/icons/logos/baichuan.tsx b/packages/ui/src/components/icons/logos/baichuan.tsx new file mode 100644 index 0000000000..e62487ab1c --- /dev/null +++ b/packages/ui/src/components/icons/logos/baichuan.tsx @@ -0,0 +1,25 @@ +import type { SVGProps } from 'react' +const Baichuan = (props: SVGProps) => ( + + + + + + + + + +) +export { Baichuan } +export default Baichuan diff --git a/packages/ui/src/components/icons/logos/baiduCloud.tsx b/packages/ui/src/components/icons/logos/baiduCloud.tsx new file mode 100644 index 0000000000..dbc59b5b48 --- /dev/null +++ b/packages/ui/src/components/icons/logos/baiduCloud.tsx @@ -0,0 +1,19 @@ +import type { SVGProps } from 'react' +const BaiduCloud = (props: SVGProps) => ( + + + + + +) +export { BaiduCloud } +export default BaiduCloud diff --git a/packages/ui/src/components/icons/logos/bailian.tsx b/packages/ui/src/components/icons/logos/bailian.tsx new file mode 100644 index 0000000000..30812b416d --- /dev/null +++ b/packages/ui/src/components/icons/logos/bailian.tsx @@ -0,0 +1,32 @@ +import type { SVGProps } from 'react' +const Bailian = (props: SVGProps) => ( + + + + + + + + + +) +export { Bailian } +export default Bailian diff --git a/packages/ui/src/components/icons/logos/bocha.tsx b/packages/ui/src/components/icons/logos/bocha.tsx new file mode 100644 index 0000000000..f32705c2a9 --- /dev/null +++ b/packages/ui/src/components/icons/logos/bocha.tsx @@ -0,0 +1,32 @@ +import type { SVGProps } from 'react' +const Bocha = (props: SVGProps) => ( + + + + + + +) +export { Bocha } +export default Bocha diff --git a/packages/ui/src/components/icons/logos/burncloud.tsx b/packages/ui/src/components/icons/logos/burncloud.tsx new file mode 100644 index 0000000000..6feae25070 --- /dev/null +++ b/packages/ui/src/components/icons/logos/burncloud.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Burncloud = (props: SVGProps) => ( + + + + + + + + + +) +export { Burncloud } +export default Burncloud diff --git a/packages/ui/src/components/icons/logos/bytedance.tsx b/packages/ui/src/components/icons/logos/bytedance.tsx new file mode 100644 index 0000000000..b405d20bb9 --- /dev/null +++ b/packages/ui/src/components/icons/logos/bytedance.tsx @@ -0,0 +1,23 @@ +import type { SVGProps } from 'react' +const Bytedance = (props: SVGProps) => ( + + + + + + +) +export { Bytedance } +export default Bytedance diff --git a/packages/ui/src/components/icons/logos/cephalon.tsx b/packages/ui/src/components/icons/logos/cephalon.tsx new file mode 100644 index 0000000000..39a7b92208 --- /dev/null +++ b/packages/ui/src/components/icons/logos/cephalon.tsx @@ -0,0 +1,11 @@ +import type { SVGProps } from 'react' +const Cephalon = (props: SVGProps) => ( + + + +) +export { Cephalon } +export default Cephalon diff --git a/packages/ui/src/components/icons/logos/cherryin.tsx b/packages/ui/src/components/icons/logos/cherryin.tsx new file mode 100644 index 0000000000..87e0cf38ad --- /dev/null +++ b/packages/ui/src/components/icons/logos/cherryin.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Cherryin = (props: SVGProps) => ( + + + + + + + + + +) +export { Cherryin } +export default Cherryin diff --git a/packages/ui/src/components/icons/logos/cohere.tsx b/packages/ui/src/components/icons/logos/cohere.tsx new file mode 100644 index 0000000000..56d156a51e --- /dev/null +++ b/packages/ui/src/components/icons/logos/cohere.tsx @@ -0,0 +1,30 @@ +import type { SVGProps } from 'react' +const Cohere = (props: SVGProps) => ( + + + + + + + + + + + + +) +export { Cohere } +export default Cohere diff --git a/packages/ui/src/components/icons/logos/dashscope.tsx b/packages/ui/src/components/icons/logos/dashscope.tsx new file mode 100644 index 0000000000..eb78aaf238 --- /dev/null +++ b/packages/ui/src/components/icons/logos/dashscope.tsx @@ -0,0 +1,184 @@ +import type { SVGProps } from 'react' +const Dashscope = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) +export { Dashscope } +export default Dashscope diff --git a/packages/ui/src/components/icons/logos/deepseek.tsx b/packages/ui/src/components/icons/logos/deepseek.tsx new file mode 100644 index 0000000000..f9a7f6aa8b --- /dev/null +++ b/packages/ui/src/components/icons/logos/deepseek.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +const Deepseek = (props: SVGProps) => ( + + + + + + + + + + +) +export { Deepseek } +export default Deepseek diff --git a/packages/ui/src/components/icons/logos/dmxapi.tsx b/packages/ui/src/components/icons/logos/dmxapi.tsx new file mode 100644 index 0000000000..760e9283f4 --- /dev/null +++ b/packages/ui/src/components/icons/logos/dmxapi.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Dmxapi = (props: SVGProps) => ( + + + + + + + + + +) +export { Dmxapi } +export default Dmxapi diff --git a/packages/ui/src/components/icons/logos/dmxapiLogo.tsx b/packages/ui/src/components/icons/logos/dmxapiLogo.tsx new file mode 100644 index 0000000000..9b03bfc656 --- /dev/null +++ b/packages/ui/src/components/icons/logos/dmxapiLogo.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const DmxapiLogo = (props: SVGProps) => ( + + + + + + + + + +) +export { DmxapiLogo } +export default DmxapiLogo diff --git a/packages/ui/src/components/icons/logos/dmxapiToImg.tsx b/packages/ui/src/components/icons/logos/dmxapiToImg.tsx new file mode 100644 index 0000000000..113524da56 --- /dev/null +++ b/packages/ui/src/components/icons/logos/dmxapiToImg.tsx @@ -0,0 +1,40 @@ +import type { SVGProps } from "react"; +const DmxapiToImg = (props: SVGProps) => ( + + + + + + + + + +); +export { DmxapiToImg }; +export default DmxapiToImg; diff --git a/packages/ui/src/components/icons/logos/doc2x.tsx b/packages/ui/src/components/icons/logos/doc2x.tsx new file mode 100644 index 0000000000..70367a8895 --- /dev/null +++ b/packages/ui/src/components/icons/logos/doc2x.tsx @@ -0,0 +1,15 @@ +import type { SVGProps } from 'react' +const Doc2x = (props: SVGProps) => ( + + + + +) +export { Doc2x } +export default Doc2x diff --git a/packages/ui/src/components/icons/logos/doubao.tsx b/packages/ui/src/components/icons/logos/doubao.tsx new file mode 100644 index 0000000000..08ef6e57b0 --- /dev/null +++ b/packages/ui/src/components/icons/logos/doubao.tsx @@ -0,0 +1,30 @@ +import type { SVGProps } from 'react' +const Doubao = (props: SVGProps) => ( + + + + + + + + + + + + + +) +export { Doubao } +export default Doubao diff --git a/packages/ui/src/components/icons/logos/exa.tsx b/packages/ui/src/components/icons/logos/exa.tsx new file mode 100644 index 0000000000..28fa3732f3 --- /dev/null +++ b/packages/ui/src/components/icons/logos/exa.tsx @@ -0,0 +1,13 @@ +import type { SVGProps } from 'react' +const Exa = (props: SVGProps) => ( + + + +) +export { Exa } +export default Exa diff --git a/packages/ui/src/components/icons/logos/fireworks.tsx b/packages/ui/src/components/icons/logos/fireworks.tsx new file mode 100644 index 0000000000..593cd46bab --- /dev/null +++ b/packages/ui/src/components/icons/logos/fireworks.tsx @@ -0,0 +1,13 @@ +import type { SVGProps } from 'react' +const Fireworks = (props: SVGProps) => ( + + + +) +export { Fireworks } +export default Fireworks diff --git a/packages/ui/src/components/icons/logos/gemini.tsx b/packages/ui/src/components/icons/logos/gemini.tsx new file mode 100644 index 0000000000..9669e151f5 --- /dev/null +++ b/packages/ui/src/components/icons/logos/gemini.tsx @@ -0,0 +1,34 @@ +import type { SVGProps } from 'react' +const Gemini = (props: SVGProps) => ( + + + + + + + + + + + + + + + + +) +export { Gemini } +export default Gemini diff --git a/packages/ui/src/components/icons/logos/giteeAi.tsx b/packages/ui/src/components/icons/logos/giteeAi.tsx new file mode 100644 index 0000000000..983ac42b52 --- /dev/null +++ b/packages/ui/src/components/icons/logos/giteeAi.tsx @@ -0,0 +1,20 @@ +import type { SVGProps } from 'react' +const GiteeAi = (props: SVGProps) => ( + + + + + + + + + + +) +export { GiteeAi } +export default GiteeAi diff --git a/packages/ui/src/components/icons/logos/github.tsx b/packages/ui/src/components/icons/logos/github.tsx new file mode 100644 index 0000000000..936904810d --- /dev/null +++ b/packages/ui/src/components/icons/logos/github.tsx @@ -0,0 +1,20 @@ +import type { SVGProps } from 'react' +const Github = (props: SVGProps) => ( + + + + + + + + + + +) +export { Github } +export default Github diff --git a/packages/ui/src/components/icons/logos/google.tsx b/packages/ui/src/components/icons/logos/google.tsx new file mode 100644 index 0000000000..7cf1c7bd14 --- /dev/null +++ b/packages/ui/src/components/icons/logos/google.tsx @@ -0,0 +1,306 @@ +import type { SVGProps } from 'react' +const Google = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) +export { Google } +export default Google diff --git a/packages/ui/src/components/icons/logos/gpustack.tsx b/packages/ui/src/components/icons/logos/gpustack.tsx new file mode 100644 index 0000000000..fe65cc2be7 --- /dev/null +++ b/packages/ui/src/components/icons/logos/gpustack.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react' +const Gpustack = (props: SVGProps) => ( + + + + + + + + + + + + + + + +) +export { Gpustack } +export default Gpustack diff --git a/packages/ui/src/components/icons/logos/graphRag.tsx b/packages/ui/src/components/icons/logos/graphRag.tsx new file mode 100644 index 0000000000..8c3ecb1f1e --- /dev/null +++ b/packages/ui/src/components/icons/logos/graphRag.tsx @@ -0,0 +1,51 @@ +import type { SVGProps } from 'react' +const GraphRag = (props: SVGProps) => ( + + + + + + + + + + + +) +export { GraphRag } +export default GraphRag diff --git a/packages/ui/src/components/icons/logos/grok.tsx b/packages/ui/src/components/icons/logos/grok.tsx new file mode 100644 index 0000000000..ea1092a301 --- /dev/null +++ b/packages/ui/src/components/icons/logos/grok.tsx @@ -0,0 +1,11 @@ +import type { SVGProps } from 'react' +const Grok = (props: SVGProps) => ( + + + + + + +) +export { Grok } +export default Grok diff --git a/packages/ui/src/components/icons/logos/groq.tsx b/packages/ui/src/components/icons/logos/groq.tsx new file mode 100644 index 0000000000..31620f68b3 --- /dev/null +++ b/packages/ui/src/components/icons/logos/groq.tsx @@ -0,0 +1,19 @@ +import type { SVGProps } from 'react' +const Groq = (props: SVGProps) => ( + + + + + + + + + + + +) +export { Groq } +export default Groq diff --git a/packages/ui/src/components/icons/logos/huggingface.tsx b/packages/ui/src/components/icons/logos/huggingface.tsx new file mode 100644 index 0000000000..baa72dab62 --- /dev/null +++ b/packages/ui/src/components/icons/logos/huggingface.tsx @@ -0,0 +1,69 @@ +import type { SVGProps } from 'react' +const Huggingface = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + +) +export { Huggingface } +export default Huggingface diff --git a/packages/ui/src/components/icons/logos/hyperbolic.tsx b/packages/ui/src/components/icons/logos/hyperbolic.tsx new file mode 100644 index 0000000000..00183569b3 --- /dev/null +++ b/packages/ui/src/components/icons/logos/hyperbolic.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +const Hyperbolic = (props: SVGProps) => ( + + + + + + + + + + +) +export { Hyperbolic } +export default Hyperbolic diff --git a/packages/ui/src/components/icons/logos/index.ts b/packages/ui/src/components/icons/logos/index.ts new file mode 100644 index 0000000000..7a79151975 --- /dev/null +++ b/packages/ui/src/components/icons/logos/index.ts @@ -0,0 +1,89 @@ +/** + * Auto-generated icon exports + * Do not edit manually + * + * Generated at: 2025-11-14T09:47:05.207Z + * Total icons: 81 + */ + +export { Ai302 } from './302ai' +export { Aihubmix } from './aihubmix' +export { AiOnly } from './aiOnly' +export { Alayanew } from './alayanew' +export { Anthropic } from './anthropic' +export { AwsBedrock } from './awsBedrock' +export { Azureai } from './azureai' +export { Baichuan } from './baichuan' +export { BaiduCloud } from './baiduCloud' +export { Bailian } from './bailian' +export { Bocha } from './bocha' +export { Burncloud } from './burncloud' +export { Bytedance } from './bytedance' +export { Cephalon } from './cephalon' +export { Cherryin } from './cherryin' +export { Cohere } from './cohere' +export { Dashscope } from './dashscope' +export { Deepseek } from './deepseek' +export { Dmxapi } from './dmxapi' +export { DmxapiLogo } from './dmxapiLogo' +export { DmxapiToImg } from './dmxapiToImg' +export { Doc2x } from './doc2x' +export { Doubao } from './doubao' +export { Exa } from './exa' +export { Fireworks } from './fireworks' +export { Gemini } from './gemini' +export { GiteeAi } from './giteeAi' +export { Github } from './github' +export { Google } from './google' +export { Gpustack } from './gpustack' +export { GraphRag } from './graphRag' +export { Grok } from './grok' +export { Groq } from './groq' +export { Huggingface } from './huggingface' +export { Hyperbolic } from './hyperbolic' +export { Infini } from './infini' +export { Intel } from './intel' +export { Jimeng } from './jimeng' +export { Jina } from './jina' +export { Lanyun } from './lanyun' +export { Lepton } from './lepton' +export { Lmstudio } from './lmstudio' +export { Longcat } from './longcat' +export { Macos } from './macos' +export { Mcprouter } from './mcprouter' +export { Meta } from './meta' +export { Mineru } from './mineru' +export { Minimax } from './minimax' +export { Mistral } from './mistral' +export { Mixedbread } from './mixedbread' +export { Mixedbread1 } from './mixedbread1' +export { Moonshot } from './moonshot' +export { NeteaseYoudao } from './neteaseYoudao' +export { Newapi } from './newapi' +export { Nomic } from './nomic' +export { Nvidia } from './nvidia' +export { O3 } from './o3' +export { Ocoolai } from './ocoolai' +export { Ollama } from './ollama' +export { Openai } from './openai' +export { Openrouter } from './openrouter' +export { Paddleocr } from './paddleocr' +export { Perplexity } from './perplexity' +export { Ph8 } from './ph8' +export { Ppio } from './ppio' +export { Qiniu } from './qiniu' +export { Searxng } from './searxng' +export { Silicon } from './silicon' +export { Sophnet } from './sophnet' +export { Step } from './step' +export { Tavily } from './tavily' +export { TencentCloudTi } from './tencentCloudTi' +export { TesseractJs } from './tesseractJs' +export { Together } from './together' +export { Tokenflux } from './tokenflux' +export { Vertexai } from './vertexai' +export { Volcengine } from './volcengine' +export { Voyage } from './voyage' +export { Xirang } from './xirang' +export { ZeroOne } from './zeroOne' +export { Zhipu } from './zhipu' diff --git a/packages/ui/src/components/icons/logos/infini.tsx b/packages/ui/src/components/icons/logos/infini.tsx new file mode 100644 index 0000000000..c248c07488 --- /dev/null +++ b/packages/ui/src/components/icons/logos/infini.tsx @@ -0,0 +1,40 @@ +import type { SVGProps } from 'react' +const Infini = (props: SVGProps) => ( + + + + + + + + + + + + + + +) +export { Infini } +export default Infini diff --git a/packages/ui/src/components/icons/logos/intel.tsx b/packages/ui/src/components/icons/logos/intel.tsx new file mode 100644 index 0000000000..dd80334ae5 --- /dev/null +++ b/packages/ui/src/components/icons/logos/intel.tsx @@ -0,0 +1,24 @@ +import type { SVGProps } from 'react' +const Intel = (props: SVGProps) => ( + + + + + + + + +) +export { Intel } +export default Intel diff --git a/packages/ui/src/components/icons/logos/jimeng.tsx b/packages/ui/src/components/icons/logos/jimeng.tsx new file mode 100644 index 0000000000..1b0594eef7 --- /dev/null +++ b/packages/ui/src/components/icons/logos/jimeng.tsx @@ -0,0 +1,171 @@ +import type { SVGProps } from 'react' +const Jimeng = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) +export { Jimeng } +export default Jimeng diff --git a/packages/ui/src/components/icons/logos/jina.tsx b/packages/ui/src/components/icons/logos/jina.tsx new file mode 100644 index 0000000000..fc75b57549 --- /dev/null +++ b/packages/ui/src/components/icons/logos/jina.tsx @@ -0,0 +1,15 @@ +import type { SVGProps } from 'react' +const Jina = (props: SVGProps) => ( + + + + +) +export { Jina } +export default Jina diff --git a/packages/ui/src/components/icons/logos/lanyun.tsx b/packages/ui/src/components/icons/logos/lanyun.tsx new file mode 100644 index 0000000000..011ba0ca80 --- /dev/null +++ b/packages/ui/src/components/icons/logos/lanyun.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Lanyun = (props: SVGProps) => ( + + + + + + + + + +) +export { Lanyun } +export default Lanyun diff --git a/packages/ui/src/components/icons/logos/lepton.tsx b/packages/ui/src/components/icons/logos/lepton.tsx new file mode 100644 index 0000000000..d44770d84f --- /dev/null +++ b/packages/ui/src/components/icons/logos/lepton.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Lepton = (props: SVGProps) => ( + + + + + + +) +export { Lepton } +export default Lepton diff --git a/packages/ui/src/components/icons/logos/lmstudio.tsx b/packages/ui/src/components/icons/logos/lmstudio.tsx new file mode 100644 index 0000000000..a8369a1f1b --- /dev/null +++ b/packages/ui/src/components/icons/logos/lmstudio.tsx @@ -0,0 +1,33 @@ +import type { SVGProps } from 'react' +const Lmstudio = (props: SVGProps) => ( + + + + + + + + + + + +) +export { Lmstudio } +export default Lmstudio diff --git a/packages/ui/src/components/icons/logos/longcat.tsx b/packages/ui/src/components/icons/logos/longcat.tsx new file mode 100644 index 0000000000..df9cace079 --- /dev/null +++ b/packages/ui/src/components/icons/logos/longcat.tsx @@ -0,0 +1,24 @@ +import type { SVGProps } from 'react' +const Longcat = (props: SVGProps) => ( + + + + + + + + + + + +) +export { Longcat } +export default Longcat diff --git a/packages/ui/src/components/icons/logos/macos.tsx b/packages/ui/src/components/icons/logos/macos.tsx new file mode 100644 index 0000000000..bb42902441 --- /dev/null +++ b/packages/ui/src/components/icons/logos/macos.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +const Macos = (props: SVGProps) => ( + + + + + + + + + + +) +export { Macos } +export default Macos diff --git a/packages/ui/src/components/icons/logos/mcprouter.tsx b/packages/ui/src/components/icons/logos/mcprouter.tsx new file mode 100644 index 0000000000..f32ed0079f --- /dev/null +++ b/packages/ui/src/components/icons/logos/mcprouter.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Mcprouter = (props: SVGProps) => ( + + + + + + + + + +) +export { Mcprouter } +export default Mcprouter diff --git a/packages/ui/src/components/icons/logos/meta.tsx b/packages/ui/src/components/icons/logos/meta.tsx new file mode 100644 index 0000000000..24489bf51c --- /dev/null +++ b/packages/ui/src/components/icons/logos/meta.tsx @@ -0,0 +1,48 @@ +import type { SVGProps } from 'react' +const Meta = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + +) +export { Meta } +export default Meta diff --git a/packages/ui/src/components/icons/logos/mineru.tsx b/packages/ui/src/components/icons/logos/mineru.tsx new file mode 100644 index 0000000000..a88a63a2d3 --- /dev/null +++ b/packages/ui/src/components/icons/logos/mineru.tsx @@ -0,0 +1,67 @@ +import type { SVGProps } from 'react' +const Mineru = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + +) +export { Mineru } +export default Mineru diff --git a/packages/ui/src/components/icons/logos/minimax.tsx b/packages/ui/src/components/icons/logos/minimax.tsx new file mode 100644 index 0000000000..57df2a0087 --- /dev/null +++ b/packages/ui/src/components/icons/logos/minimax.tsx @@ -0,0 +1,23 @@ +import type { SVGProps } from 'react' +const Minimax = (props: SVGProps) => ( + + + + + + + + + +) +export { Minimax } +export default Minimax diff --git a/packages/ui/src/components/icons/logos/mistral.tsx b/packages/ui/src/components/icons/logos/mistral.tsx new file mode 100644 index 0000000000..09ff68bb05 --- /dev/null +++ b/packages/ui/src/components/icons/logos/mistral.tsx @@ -0,0 +1,17 @@ +import type { SVGProps } from 'react' +const Mistral = (props: SVGProps) => ( + + + + + + + + + + + + +) +export { Mistral } +export default Mistral diff --git a/packages/ui/src/components/icons/logos/mixedbread.tsx b/packages/ui/src/components/icons/logos/mixedbread.tsx new file mode 100644 index 0000000000..8a7c2e5da6 --- /dev/null +++ b/packages/ui/src/components/icons/logos/mixedbread.tsx @@ -0,0 +1,278 @@ +import type { SVGProps } from 'react' +const Mixedbread = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) +export { Mixedbread } +export default Mixedbread diff --git a/packages/ui/src/components/icons/logos/mixedbread1.tsx b/packages/ui/src/components/icons/logos/mixedbread1.tsx new file mode 100644 index 0000000000..e21941c3d4 --- /dev/null +++ b/packages/ui/src/components/icons/logos/mixedbread1.tsx @@ -0,0 +1,23 @@ +import type { SVGProps } from 'react' +const Mixedbread1 = (props: SVGProps) => ( + + + + + + + + + +) +export { Mixedbread1 } +export default Mixedbread1 diff --git a/packages/ui/src/components/icons/logos/moonshot.tsx b/packages/ui/src/components/icons/logos/moonshot.tsx new file mode 100644 index 0000000000..32e564fc9b --- /dev/null +++ b/packages/ui/src/components/icons/logos/moonshot.tsx @@ -0,0 +1,19 @@ +import type { SVGProps } from 'react' +const Moonshot = (props: SVGProps) => ( + + + + +) +export { Moonshot } +export default Moonshot diff --git a/packages/ui/src/components/icons/logos/neteaseYoudao.tsx b/packages/ui/src/components/icons/logos/neteaseYoudao.tsx new file mode 100644 index 0000000000..e67d07091f --- /dev/null +++ b/packages/ui/src/components/icons/logos/neteaseYoudao.tsx @@ -0,0 +1,15 @@ +import type { SVGProps } from 'react' +const NeteaseYoudao = (props: SVGProps) => ( + + + + +) +export { NeteaseYoudao } +export default NeteaseYoudao diff --git a/packages/ui/src/components/icons/logos/newapi.tsx b/packages/ui/src/components/icons/logos/newapi.tsx new file mode 100644 index 0000000000..a940725ae3 --- /dev/null +++ b/packages/ui/src/components/icons/logos/newapi.tsx @@ -0,0 +1,51 @@ +import type { SVGProps } from 'react' +const Newapi = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + +) +export { Newapi } +export default Newapi diff --git a/packages/ui/src/components/icons/logos/nomic.tsx b/packages/ui/src/components/icons/logos/nomic.tsx new file mode 100644 index 0000000000..be0aff7ff3 --- /dev/null +++ b/packages/ui/src/components/icons/logos/nomic.tsx @@ -0,0 +1,36 @@ +import type { SVGProps } from 'react' +const Nomic = (props: SVGProps) => ( + + + + + + + + + + + + + + + + +) +export { Nomic } +export default Nomic diff --git a/packages/ui/src/components/icons/logos/nvidia.tsx b/packages/ui/src/components/icons/logos/nvidia.tsx new file mode 100644 index 0000000000..8ff33e0921 --- /dev/null +++ b/packages/ui/src/components/icons/logos/nvidia.tsx @@ -0,0 +1,11 @@ +import type { SVGProps } from 'react' +const Nvidia = (props: SVGProps) => ( + + + +) +export { Nvidia } +export default Nvidia diff --git a/packages/ui/src/components/icons/logos/o3.tsx b/packages/ui/src/components/icons/logos/o3.tsx new file mode 100644 index 0000000000..469a2a5f1a --- /dev/null +++ b/packages/ui/src/components/icons/logos/o3.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const O3 = (props: SVGProps) => ( + + + + + + + + + +) +export { O3 } +export default O3 diff --git a/packages/ui/src/components/icons/logos/ocoolai.tsx b/packages/ui/src/components/icons/logos/ocoolai.tsx new file mode 100644 index 0000000000..4ebe159e1a --- /dev/null +++ b/packages/ui/src/components/icons/logos/ocoolai.tsx @@ -0,0 +1,11 @@ +import type { SVGProps } from 'react' +const Ocoolai = (props: SVGProps) => ( + + + +) +export { Ocoolai } +export default Ocoolai diff --git a/packages/ui/src/components/icons/logos/ollama.tsx b/packages/ui/src/components/icons/logos/ollama.tsx new file mode 100644 index 0000000000..26728af641 --- /dev/null +++ b/packages/ui/src/components/icons/logos/ollama.tsx @@ -0,0 +1,13 @@ +import type { SVGProps } from 'react' +const Ollama = (props: SVGProps) => ( + + + +) +export { Ollama } +export default Ollama diff --git a/packages/ui/src/components/icons/logos/openai.tsx b/packages/ui/src/components/icons/logos/openai.tsx new file mode 100644 index 0000000000..37097d2ce4 --- /dev/null +++ b/packages/ui/src/components/icons/logos/openai.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +const Openai = (props: SVGProps) => ( + + + + + + + + + + +) +export { Openai } +export default Openai diff --git a/packages/ui/src/components/icons/logos/openrouter.tsx b/packages/ui/src/components/icons/logos/openrouter.tsx new file mode 100644 index 0000000000..6f96006b0b --- /dev/null +++ b/packages/ui/src/components/icons/logos/openrouter.tsx @@ -0,0 +1,20 @@ +import type { SVGProps } from 'react' +const Openrouter = (props: SVGProps) => ( + + + + + + + + + + +) +export { Openrouter } +export default Openrouter diff --git a/packages/ui/src/components/icons/logos/paddleocr.tsx b/packages/ui/src/components/icons/logos/paddleocr.tsx new file mode 100644 index 0000000000..b16a0ee59d --- /dev/null +++ b/packages/ui/src/components/icons/logos/paddleocr.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Paddleocr = (props: SVGProps) => ( + + + + + + + + + +) +export { Paddleocr } +export default Paddleocr diff --git a/packages/ui/src/components/icons/logos/perplexity.tsx b/packages/ui/src/components/icons/logos/perplexity.tsx new file mode 100644 index 0000000000..c0119a7063 --- /dev/null +++ b/packages/ui/src/components/icons/logos/perplexity.tsx @@ -0,0 +1,13 @@ +import type { SVGProps } from 'react' +const Perplexity = (props: SVGProps) => ( + + + +) +export { Perplexity } +export default Perplexity diff --git a/packages/ui/src/components/icons/logos/ph8.tsx b/packages/ui/src/components/icons/logos/ph8.tsx new file mode 100644 index 0000000000..ce5a7ffed1 --- /dev/null +++ b/packages/ui/src/components/icons/logos/ph8.tsx @@ -0,0 +1,46 @@ +import type { SVGProps } from 'react' +const Ph8 = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + +) +export { Ph8 } +export default Ph8 diff --git a/packages/ui/src/components/icons/logos/ppio.tsx b/packages/ui/src/components/icons/logos/ppio.tsx new file mode 100644 index 0000000000..4a31dbd0b0 --- /dev/null +++ b/packages/ui/src/components/icons/logos/ppio.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +const Ppio = (props: SVGProps) => ( + + + + + + + + + + +) +export { Ppio } +export default Ppio diff --git a/packages/ui/src/components/icons/logos/qiniu.tsx b/packages/ui/src/components/icons/logos/qiniu.tsx new file mode 100644 index 0000000000..7aaba3a892 --- /dev/null +++ b/packages/ui/src/components/icons/logos/qiniu.tsx @@ -0,0 +1,11 @@ +import type { SVGProps } from 'react' +const Qiniu = (props: SVGProps) => ( + + + +) +export { Qiniu } +export default Qiniu diff --git a/packages/ui/src/components/icons/logos/searxng.tsx b/packages/ui/src/components/icons/logos/searxng.tsx new file mode 100644 index 0000000000..397335a9c3 --- /dev/null +++ b/packages/ui/src/components/icons/logos/searxng.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +const Searxng = (props: SVGProps) => ( + + + + + + + + + + +) +export { Searxng } +export default Searxng diff --git a/packages/ui/src/components/icons/logos/silicon.tsx b/packages/ui/src/components/icons/logos/silicon.tsx new file mode 100644 index 0000000000..179c12a970 --- /dev/null +++ b/packages/ui/src/components/icons/logos/silicon.tsx @@ -0,0 +1,13 @@ +import type { SVGProps } from 'react' +const Silicon = (props: SVGProps) => ( + + + +) +export { Silicon } +export default Silicon diff --git a/packages/ui/src/components/icons/logos/sophnet.tsx b/packages/ui/src/components/icons/logos/sophnet.tsx new file mode 100644 index 0000000000..09189f5dd5 --- /dev/null +++ b/packages/ui/src/components/icons/logos/sophnet.tsx @@ -0,0 +1,23 @@ +import type { SVGProps } from 'react' +const Sophnet = (props: SVGProps) => ( + + + + + + +) +export { Sophnet } +export default Sophnet diff --git a/packages/ui/src/components/icons/logos/step.tsx b/packages/ui/src/components/icons/logos/step.tsx new file mode 100644 index 0000000000..53cfe4e25a --- /dev/null +++ b/packages/ui/src/components/icons/logos/step.tsx @@ -0,0 +1,30 @@ +import type { SVGProps } from 'react' +const Step = (props: SVGProps) => ( + + + + + + + + + + + + + + +) +export { Step } +export default Step diff --git a/packages/ui/src/components/icons/logos/tavily.tsx b/packages/ui/src/components/icons/logos/tavily.tsx new file mode 100644 index 0000000000..80620b7cde --- /dev/null +++ b/packages/ui/src/components/icons/logos/tavily.tsx @@ -0,0 +1,38 @@ +import type { SVGProps } from 'react' +const Tavily = (props: SVGProps) => ( + + + + + + + + + + + + + + + +) +export { Tavily } +export default Tavily diff --git a/packages/ui/src/components/icons/logos/tencentCloudTi.tsx b/packages/ui/src/components/icons/logos/tencentCloudTi.tsx new file mode 100644 index 0000000000..abf779e607 --- /dev/null +++ b/packages/ui/src/components/icons/logos/tencentCloudTi.tsx @@ -0,0 +1,19 @@ +import type { SVGProps } from 'react' +const TencentCloudTi = (props: SVGProps) => ( + + + + + +) +export { TencentCloudTi } +export default TencentCloudTi diff --git a/packages/ui/src/components/icons/logos/tesseractJs.tsx b/packages/ui/src/components/icons/logos/tesseractJs.tsx new file mode 100644 index 0000000000..40b8546880 --- /dev/null +++ b/packages/ui/src/components/icons/logos/tesseractJs.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const TesseractJs = (props: SVGProps) => ( + + + + + + + + + +) +export { TesseractJs } +export default TesseractJs diff --git a/packages/ui/src/components/icons/logos/together.tsx b/packages/ui/src/components/icons/logos/together.tsx new file mode 100644 index 0000000000..07f1338f40 --- /dev/null +++ b/packages/ui/src/components/icons/logos/together.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' +const Together = (props: SVGProps) => ( + + + + +) +export { Together } +export default Together diff --git a/packages/ui/src/components/icons/logos/tokenflux.tsx b/packages/ui/src/components/icons/logos/tokenflux.tsx new file mode 100644 index 0000000000..e87afafdd9 --- /dev/null +++ b/packages/ui/src/components/icons/logos/tokenflux.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Tokenflux = (props: SVGProps) => ( + + + + + + + + + +) +export { Tokenflux } +export default Tokenflux diff --git a/packages/ui/src/components/icons/logos/vertexai.tsx b/packages/ui/src/components/icons/logos/vertexai.tsx new file mode 100644 index 0000000000..c550e09aa1 --- /dev/null +++ b/packages/ui/src/components/icons/logos/vertexai.tsx @@ -0,0 +1,50 @@ +import type { SVGProps } from 'react' +const Vertexai = (props: SVGProps) => ( + + + + + + + + + + + + + + + + + +) +export { Vertexai } +export default Vertexai diff --git a/packages/ui/src/components/icons/logos/volcengine.tsx b/packages/ui/src/components/icons/logos/volcengine.tsx new file mode 100644 index 0000000000..2318598a48 --- /dev/null +++ b/packages/ui/src/components/icons/logos/volcengine.tsx @@ -0,0 +1,27 @@ +import type { SVGProps } from 'react' +const Volcengine = (props: SVGProps) => ( + + + + + + + +) +export { Volcengine } +export default Volcengine diff --git a/packages/ui/src/components/icons/logos/voyage.tsx b/packages/ui/src/components/icons/logos/voyage.tsx new file mode 100644 index 0000000000..159a96db9a --- /dev/null +++ b/packages/ui/src/components/icons/logos/voyage.tsx @@ -0,0 +1,24 @@ +import type { SVGProps } from 'react' +const Voyage = (props: SVGProps) => ( + + + + + + + + + + + +) +export { Voyage } +export default Voyage diff --git a/packages/ui/src/components/icons/logos/xirang.tsx b/packages/ui/src/components/icons/logos/xirang.tsx new file mode 100644 index 0000000000..7126a2952e --- /dev/null +++ b/packages/ui/src/components/icons/logos/xirang.tsx @@ -0,0 +1,13 @@ +import type { SVGProps } from 'react' +const Xirang = (props: SVGProps) => ( + + + +) +export { Xirang } +export default Xirang diff --git a/packages/ui/src/components/icons/logos/zeroOne.tsx b/packages/ui/src/components/icons/logos/zeroOne.tsx new file mode 100644 index 0000000000..c95655d44e --- /dev/null +++ b/packages/ui/src/components/icons/logos/zeroOne.tsx @@ -0,0 +1,40 @@ +import type { SVGProps } from 'react' +const ZeroOne = (props: SVGProps) => ( + + + + + + + + + + + + + + +) +export { ZeroOne } +export default ZeroOne diff --git a/packages/ui/src/components/icons/logos/zhipu.tsx b/packages/ui/src/components/icons/logos/zhipu.tsx new file mode 100644 index 0000000000..f88bf587bc --- /dev/null +++ b/packages/ui/src/components/icons/logos/zhipu.tsx @@ -0,0 +1,15 @@ +import type { SVGProps } from 'react' +const Zhipu = (props: SVGProps) => ( + + + + +) +export { Zhipu } +export default Zhipu diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 2646b14107..ae7ff6de33 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -23,24 +23,28 @@ export { default as ThinkingEffect } from './composites/ThinkingEffect' // Icon Components export { FilePngIcon, FileSvgIcon } from './icons/FileIcons' -export type { LucideIcon, LucideProps } from './icons/Icon' -export { - CopyIcon, - createIcon, - DeleteIcon, - EditIcon, - OcrIcon, - RefreshIcon, - ResetIcon, - ToolIcon, - UnWrapIcon, - VisionIcon, - WebSearchIcon, - WrapIcon -} from './icons/Icon' +// export type { LucideIcon, LucideProps } from './icons/Icon' +// export { +// CopyIcon, +// createIcon, +// DeleteIcon, +// EditIcon, +// OcrIcon, +// RefreshIcon, +// ResetIcon, +// ToolIcon, +// UnWrapIcon, +// VisionIcon, +// WebSearchIcon, +// WrapIcon +// } from './icons/Icon' export { default as SvgSpinners180Ring } from './icons/SvgSpinners180Ring' export { default as ToolsCallingIcon } from './icons/ToolsCallingIcon' +// Brand Logo Icons (彩色品牌 Logo 图标 - 84个) +// 推荐使用 '@cherrystudio/ui/icons' 路径导入 +export * from './icons' + // /* Selector Components */ // export { default as Selector } from './primitives/select' // export { default as SearchableSelector } from './primitives/Selector/SearchableSelector' diff --git a/packages/ui/stories/components/icons/Icon.stories.tsx b/packages/ui/stories/components/icons/Icon.stories.tsx deleted file mode 100644 index e12a45c5a6..0000000000 --- a/packages/ui/stories/components/icons/Icon.stories.tsx +++ /dev/null @@ -1,290 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import { ChevronRight, Download, Settings, Upload } from 'lucide-react' - -import { - CopyIcon, - createIcon, - DeleteIcon, - EditIcon, - OcrIcon, - RefreshIcon, - ResetIcon, - ToolIcon, - UnWrapIcon, - VisionIcon, - WebSearchIcon, - WrapIcon -} from '../../../src/components/icons/Icon' - -// Create a dummy component for the story -const IconShowcase = () =>
- -const meta: Meta = { - title: 'Components/Icons/Icon', - component: IconShowcase, - parameters: { - layout: 'centered' - }, - tags: ['autodocs'], - argTypes: { - size: { - description: '图标大小 (支持数字或字符串)', - control: { type: 'text' }, - defaultValue: '1rem' - }, - color: { - description: '图标颜色', - control: { type: 'color' } - }, - className: { - description: '自定义 CSS 类名', - control: { type: 'text' } - } - } -} - -export default meta -type Story = StoryObj - -// Predefined Icons -export const PredefinedIcons: Story = { - render: () => ( -
-
-

预定义图标 (默认尺寸: 1rem)

-
-
- - CopyIcon -
-
- - DeleteIcon -
-
- - EditIcon -
-
- - RefreshIcon -
-
- - ResetIcon -
-
- - ToolIcon -
-
- - VisionIcon -
-
- - WebSearchIcon -
-
- - WrapIcon -
-
- - UnWrapIcon -
-
- - OcrIcon -
-
-
-
- ) -} - -// Different Sizes -export const DifferentSizes: Story = { - render: () => ( -
-
- - - - - - -
-
- 12px - 16px - 20px - 24px - 32px - 48px -
-
- ) -} - -// Custom Colors -export const CustomColors: Story = { - render: () => ( -
- - - - - - -
- ) -} - -// Custom Icon Creation -export const CustomIconCreation: Story = { - render: () => { - // Create custom icons using the factory - const SettingsIcon = createIcon(Settings, 24) - const DownloadIcon = createIcon(Download, 20) - const UploadIcon = createIcon(Upload, 20) - const ChevronIcon = createIcon(ChevronRight, 16) - - return ( -
-
-

使用工厂函数创建的自定义图标

-
-
- - Settings (24px) -
-
- - Download (20px) -
-
- - Upload (20px) -
-
- - Chevron (16px) -
-
-
- -
-

覆盖默认尺寸

-
- - - - -
-
-
- ) - } -} - -// Icon States -export const IconStates: Story = { - render: () => ( -
-
- - - -
-
- Normal - Disabled - Active -
-
- ) -} - -// In Context -export const InContext: Story = { - render: () => ( -
-
-
-

Document.pdf

-
- - - -
-
-
- -
-
- - Image Processing -
-

Process your images with advanced AI tools

- -
- -
-
- Auto-refresh - -
-
-
- ) -} - -// Icon Grid -export const IconGrid: Story = { - render: () => { - const AllIcons = [ - { Icon: CopyIcon, name: 'Copy' }, - { Icon: DeleteIcon, name: 'Delete' }, - { Icon: EditIcon, name: 'Edit' }, - { Icon: RefreshIcon, name: 'Refresh' }, - { Icon: ResetIcon, name: 'Reset' }, - { Icon: ToolIcon, name: 'Tool' }, - { Icon: VisionIcon, name: 'Vision' }, - { Icon: WebSearchIcon, name: 'Search' }, - { Icon: WrapIcon, name: 'Wrap' }, - { Icon: UnWrapIcon, name: 'Unwrap' }, - { Icon: OcrIcon, name: 'OCR' } - ] - - return ( -
- {AllIcons.map(({ Icon, name }) => ( -
- - {name} -
- ))} -
- ) - } -} diff --git a/packages/ui/stories/components/icons/Logos.stories.tsx b/packages/ui/stories/components/icons/Logos.stories.tsx new file mode 100644 index 0000000000..15a2d43532 --- /dev/null +++ b/packages/ui/stories/components/icons/Logos.stories.tsx @@ -0,0 +1,237 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { + Ai302, + Aihubmix, + AiOnly, + Alayanew, + Anthropic, + AwsBedrock, + Azureai, + Baichuan, + BaiduCloud, + Bailian, + Bocha, + Burncloud, + Bytedance, + Cephalon, + Cherryin, + Cohere, + Dashscope, + Deepseek, + Dmxapi, + DmxapiLogo, + DmxapiToImg, + Doc2x, + Doubao, + Exa, + Fireworks, + Gemini, + GiteeAi, + Github, + Google, + Gpustack, + GraphRag, + Grok, + Groq, + Huggingface, + Hyperbolic, + Infini, + Intel, + Jimeng, + Jina, + Lanyun, + Lepton, + Lmstudio, + Longcat, + Macos, + Mcprouter, + Meta as MetaLogo, + Mineru, + Minimax, + Mistral, + Mixedbread, + Mixedbread1, + Moonshot, + NeteaseYoudao, + Newapi, + Nomic, + Nvidia, + O3, + Ocoolai, + Ollama, + Openai, + Openrouter, + Paddleocr, + Perplexity, + Ph8, + Ppio, + Qiniu, + Searxng, + Silicon, + Sophnet, + Step, + Tavily, + TencentCloudTi, + TesseractJs, + Together, + Tokenflux, + Vertexai, + Volcengine, + Voyage, + Xirang, + ZeroOne, + Zhipu +} from '../../../src/components/icons/logos' + +// Logo 列表,包含组件和名称 +const logos = [ + { Component: Ai302, name: 'Ai302' }, + { Component: Aihubmix, name: 'Aihubmix' }, + { Component: AiOnly, name: 'AiOnly' }, + { Component: Alayanew, name: 'Alayanew' }, + { Component: Anthropic, name: 'Anthropic' }, + { Component: AwsBedrock, name: 'AwsBedrock' }, + { Component: Azureai, name: 'Azureai' }, + { Component: Baichuan, name: 'Baichuan' }, + { Component: BaiduCloud, name: 'BaiduCloud' }, + { Component: Bailian, name: 'Bailian' }, + { Component: Bocha, name: 'Bocha' }, + { Component: Burncloud, name: 'Burncloud' }, + { Component: Bytedance, name: 'Bytedance' }, + { Component: Cephalon, name: 'Cephalon' }, + { Component: Cherryin, name: 'Cherryin' }, + { Component: Cohere, name: 'Cohere' }, + { Component: Dashscope, name: 'Dashscope' }, + { Component: Deepseek, name: 'Deepseek' }, + { Component: Dmxapi, name: 'Dmxapi' }, + { Component: DmxapiLogo, name: 'DmxapiLogo' }, + { Component: DmxapiToImg, name: 'DmxapiToImg' }, + { Component: Doc2x, name: 'Doc2x' }, + { Component: Doubao, name: 'Doubao' }, + { Component: Exa, name: 'Exa' }, + { Component: Fireworks, name: 'Fireworks' }, + { Component: Gemini, name: 'Gemini' }, + { Component: GiteeAi, name: 'GiteeAi' }, + { Component: Github, name: 'Github' }, + { Component: Google, name: 'Google' }, + { Component: Gpustack, name: 'Gpustack' }, + { Component: GraphRag, name: 'GraphRag' }, + { Component: Grok, name: 'Grok' }, + { Component: Groq, name: 'Groq' }, + { Component: Huggingface, name: 'Huggingface' }, + { Component: Hyperbolic, name: 'Hyperbolic' }, + { Component: Infini, name: 'Infini' }, + { Component: Intel, name: 'Intel' }, + { Component: Jimeng, name: 'Jimeng' }, + { Component: Jina, name: 'Jina' }, + { Component: Lanyun, name: 'Lanyun' }, + { Component: Lepton, name: 'Lepton' }, + { Component: Lmstudio, name: 'Lmstudio' }, + { Component: Longcat, name: 'Longcat' }, + { Component: Macos, name: 'Macos' }, + { Component: Mcprouter, name: 'Mcprouter' }, + { Component: MetaLogo, name: 'Meta' }, + { Component: Mineru, name: 'Mineru' }, + { Component: Minimax, name: 'Minimax' }, + { Component: Mistral, name: 'Mistral' }, + { Component: Mixedbread, name: 'Mixedbread' }, + { Component: Mixedbread1, name: 'Mixedbread1' }, + { Component: Moonshot, name: 'Moonshot' }, + { Component: NeteaseYoudao, name: 'NeteaseYoudao' }, + { Component: Newapi, name: 'Newapi' }, + { Component: Nomic, name: 'Nomic' }, + { Component: Nvidia, name: 'Nvidia' }, + { Component: O3, name: 'O3' }, + { Component: Ocoolai, name: 'Ocoolai' }, + { Component: Ollama, name: 'Ollama' }, + { Component: Openai, name: 'Openai' }, + { Component: Openrouter, name: 'Openrouter' }, + { Component: Paddleocr, name: 'Paddleocr' }, + { Component: Perplexity, name: 'Perplexity' }, + { Component: Ph8, name: 'Ph8' }, + { Component: Ppio, name: 'Ppio' }, + { Component: Qiniu, name: 'Qiniu' }, + { Component: Searxng, name: 'Searxng' }, + { Component: Silicon, name: 'Silicon' }, + { Component: Sophnet, name: 'Sophnet' }, + { Component: Step, name: 'Step' }, + { Component: Tavily, name: 'Tavily' }, + { Component: TencentCloudTi, name: 'TencentCloudTi' }, + { Component: TesseractJs, name: 'TesseractJs' }, + { Component: Together, name: 'Together' }, + { Component: Tokenflux, name: 'Tokenflux' }, + { Component: Vertexai, name: 'Vertexai' }, + { Component: Volcengine, name: 'Volcengine' }, + { Component: Voyage, name: 'Voyage' }, + { Component: Xirang, name: 'Xirang' }, + { Component: ZeroOne, name: 'ZeroOne' }, + { Component: Zhipu, name: 'Zhipu' } +] + +interface LogosShowcaseProps { + fontSize?: number +} + +const LogosShowcase = ({ fontSize = 32 }: LogosShowcaseProps) => { + return ( +
+ {logos.map(({ Component, name }) => ( +
+
+ +
+

{name}

+
+ ))} +
+ ) +} + +const meta: Meta = { + title: 'Components/Icons/Logos', + component: LogosShowcase, + parameters: { + layout: 'fullscreen' + }, + tags: ['autodocs'], + argTypes: { + fontSize: { + control: { type: 'number', min: 16, max: 64, step: 4 }, + description: 'Logo 大小(通过 fontSize 控制,因为图标使用 1em 单位)', + defaultValue: 32 + } + } +} + +export default meta +type Story = StoryObj + +/** + * 展示所有 81 个品牌 Logo 图标 + * + * 这些图标使用 SVGR 的 `icon: true` 选项生成,具有以下特点: + * - 使用 `width="1em"` 和 `height="1em"`,响应父元素的 `fontSize` + * - 保留所有原始 SVG 属性(颜色、渐变、clipPath 等) + * - 支持标准的 SVG props(className, style, onClick 等) + * + * ## 使用示例 + * + * ```tsx + * // 通过 fontSize 控制大小 + *
+ * + *
+ * + * // 通过 className 控制(Tailwind) + * + * + * // 使用标准 SVG props + * + * ``` + */ +export const AllLogos: Story = { + args: { + fontSize: 32 + } +} diff --git a/yarn.lock b/yarn.lock index 05b252a54e..534dd235ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1454,7 +1454,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.27.1": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.27.1": version: 7.27.1 resolution: "@babel/code-frame@npm:7.27.1" dependencies: @@ -1472,6 +1472,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.21.3": + version: 7.28.5 + resolution: "@babel/core@npm:7.28.5" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.5" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-module-transforms": "npm:^7.28.3" + "@babel/helpers": "npm:^7.28.4" + "@babel/parser": "npm:^7.28.5" + "@babel/template": "npm:^7.27.2" + "@babel/traverse": "npm:^7.28.5" + "@babel/types": "npm:^7.28.5" + "@jridgewell/remapping": "npm:^2.3.5" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10c0/535f82238027621da6bdffbdbe896ebad3558b311d6f8abc680637a9859b96edbf929ab010757055381570b29cf66c4a295b5618318d27a4273c0e2033925e72 + languageName: node + linkType: hard + "@babel/core@npm:^7.27.7, @babel/core@npm:^7.28.0": version: 7.28.4 resolution: "@babel/core@npm:7.28.4" @@ -1508,6 +1531,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/generator@npm:7.28.5" + dependencies: + "@babel/parser": "npm:^7.28.5" + "@babel/types": "npm:^7.28.5" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/9f219fe1d5431b6919f1a5c60db8d5d34fe546c0d8f5a8511b32f847569234ffc8032beb9e7404649a143f54e15224ecb53a3d11b6bb85c3203e573d91fca752 + languageName: node + linkType: hard + "@babel/helper-compilation-targets@npm:^7.27.2": version: 7.27.2 resolution: "@babel/helper-compilation-targets@npm:7.27.2" @@ -1572,6 +1608,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-validator-identifier@npm:7.28.5" + checksum: 10c0/42aaebed91f739a41f3d80b72752d1f95fd7c72394e8e4bd7cdd88817e0774d80a432451bcba17c2c642c257c483bf1d409dd4548883429ea9493a3bc4ab0847 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-validator-option@npm:7.27.1" @@ -1600,6 +1643,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/parser@npm:7.28.5" + dependencies: + "@babel/types": "npm:^7.28.5" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/5bbe48bf2c79594ac02b490a41ffde7ef5aa22a9a88ad6bcc78432a6ba8a9d638d531d868bd1f104633f1f6bba9905746e15185b8276a3756c42b765d131b1ef + languageName: node + linkType: hard + "@babel/plugin-transform-arrow-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" @@ -1644,6 +1698,21 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/traverse@npm:7.28.5" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.5" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/parser": "npm:^7.28.5" + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.28.5" + debug: "npm:^4.3.1" + checksum: 10c0/f6c4a595993ae2b73f2d4cd9c062f2e232174d293edd4abe1d715bd6281da8d99e47c65857e8d0917d9384c65972f4acdebc6749a7c40a8fcc38b3c7fb3e706f + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.4, @babel/types@npm:^7.27.1, @babel/types@npm:^7.28.1, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4": version: 7.28.4 resolution: "@babel/types@npm:7.28.4" @@ -1654,6 +1723,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.21.3, @babel/types@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/types@npm:7.28.5" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10c0/a5a483d2100befbf125793640dec26b90b95fd233a94c19573325898a5ce1e52cdfa96e495c7dcc31b5eca5b66ce3e6d4a0f5a4a62daec271455959f208ab08a + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^1.0.2": version: 1.0.2 resolution: "@bcoe/v8-coverage@npm:1.0.2" @@ -2082,6 +2161,11 @@ __metadata: "@storybook/addon-docs": "npm:^10.0.5" "@storybook/addon-themes": "npm:^10.0.5" "@storybook/react-vite": "npm:^10.0.5" + "@svgr/cli": "npm:^8.1.0" + "@svgr/core": "npm:^8.1.0" + "@svgr/plugin-jsx": "npm:^8.1.0" + "@svgr/plugin-prettier": "npm:^8.1.0" + "@svgr/plugin-svgo": "npm:^8.1.0" "@types/react": "npm:^19.0.12" "@types/react-dom": "npm:^19.0.4" "@types/styled-components": "npm:^5.1.34" @@ -2101,9 +2185,11 @@ __metadata: react-dropzone: "npm:^14.3.8" storybook: "npm:^10.0.5" styled-components: "npm:^6.1.15" + svgo: "npm:^4.0.0" + svgson: "npm:^5.3.1" tailwind-merge: "npm:^2.5.5" tsdown: "npm:^0.15.5" - tsx: "npm:^4.20.5" + tsx: "npm:^4.20.6" typescript: "npm:^5.6.2" vitest: "npm:^3.2.4" peerDependencies: @@ -10299,6 +10385,178 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/a50bd0baa34faf16bcba712091f94c7f0e230431fe99a9dfc3401fa92823ad3f68495b86ab9bf9044b53839e8c416cfbb37eb3f246ff33f261e0fa9ee1779c5b + languageName: node + linkType: hard + +"@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/8a98e59bd9971e066815b4129409932f7a4db4866834fe75677ea6d517972fb40b380a69a4413189f20e7947411f9ab1b0f029dd5e8068686a5a0188d3ccd4c7 + languageName: node + linkType: hard + +"@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/517dcca75223bd05d3f056a8514dbba3031278bea4eadf0842c576d84f4651e7a4e0e7082d3ee4ef42456de0f9c4531d8a1917c04876ca64b014b859ca8f1bde + languageName: node + linkType: hard + +"@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/004bd1892053b7e9c1b0bb14acc44e77634ec393722b87b1e4fae53e2c35122a2dd0d5c15e9070dbeec274e22e7693a2b8b48506733a8009ee92b12946fcb10a + languageName: node + linkType: hard + +"@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/80e0a7fcf902f984c705051ca5c82ea6050ccbb70b651a8fea6d0eb5809e4dac274b49ea6be2d87f1eb9dfc0e2d6cdfffe1669ec2117f44b67a60a07d4c0b8b8 + languageName: node + linkType: hard + +"@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/73e92c8277a89279745c0c500f59f083279a8dc30cd552b22981fade2a77628fb2bd2819ee505725fcd2e93f923e3790b52efcff409a159e657b46604a0b9a21 + languageName: node + linkType: hard + +"@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/655ed6bc7a208ceaa4ecff0a54ccc36008c3cb31efa90d11e171cab325ebbb21aa78f09c7b65f9b3ddeda3a85f348c0c862902c48be13c14b4de165c847974e3 + languageName: node + linkType: hard + +"@svgr/babel-plugin-transform-svg-component@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-transform-svg-component@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4ac00bb99a3db4ef05e4362f116a3c608ee365a2d26cf7318d8d41a4a5b30a02c80455cce0e62c65b60ed815b5d632bedabac2ccd4b56f998fadef5286e3ded4 + languageName: node + linkType: hard + +"@svgr/babel-preset@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/babel-preset@npm:8.1.0" + dependencies: + "@svgr/babel-plugin-add-jsx-attribute": "npm:8.0.0" + "@svgr/babel-plugin-remove-jsx-attribute": "npm:8.0.0" + "@svgr/babel-plugin-remove-jsx-empty-expression": "npm:8.0.0" + "@svgr/babel-plugin-replace-jsx-attribute-value": "npm:8.0.0" + "@svgr/babel-plugin-svg-dynamic-title": "npm:8.0.0" + "@svgr/babel-plugin-svg-em-dimensions": "npm:8.0.0" + "@svgr/babel-plugin-transform-react-native-svg": "npm:8.1.0" + "@svgr/babel-plugin-transform-svg-component": "npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/49367d3ad0831f79b1056871b91766246f449d4d1168623af5e283fbaefce4a01d77ab00de6b045b55e956f9aae27895823198493cd232d88d3435ea4517ffc5 + languageName: node + linkType: hard + +"@svgr/cli@npm:^8.1.0": + version: 8.1.0 + resolution: "@svgr/cli@npm:8.1.0" + dependencies: + "@svgr/core": "npm:8.1.0" + "@svgr/plugin-jsx": "npm:8.1.0" + "@svgr/plugin-prettier": "npm:8.1.0" + "@svgr/plugin-svgo": "npm:8.1.0" + camelcase: "npm:^6.2.0" + chalk: "npm:^4.1.2" + commander: "npm:^9.4.1" + dashify: "npm:^2.0.0" + glob: "npm:^8.0.3" + snake-case: "npm:^3.0.4" + bin: + svgr: bin/svgr + checksum: 10c0/c682defbd1d00c864353a0d03b946547b2dbac6ddcd82467c5c3698cb2995d17595cf1603e4953930ca240092b36aedad4108e567c1162e6df4bd331b2423269 + languageName: node + linkType: hard + +"@svgr/core@npm:8.1.0, @svgr/core@npm:^8.1.0": + version: 8.1.0 + resolution: "@svgr/core@npm:8.1.0" + dependencies: + "@babel/core": "npm:^7.21.3" + "@svgr/babel-preset": "npm:8.1.0" + camelcase: "npm:^6.2.0" + cosmiconfig: "npm:^8.1.3" + snake-case: "npm:^3.0.4" + checksum: 10c0/6a2f6b1bc79bce39f66f088d468985d518005fc5147ebf4f108570a933818b5951c2cb7da230ddff4b7c8028b5a672b2d33aa2acce012b8b9770073aa5a2d041 + languageName: node + linkType: hard + +"@svgr/hast-util-to-babel-ast@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/hast-util-to-babel-ast@npm:8.0.0" + dependencies: + "@babel/types": "npm:^7.21.3" + entities: "npm:^4.4.0" + checksum: 10c0/f4165b583ba9eaf6719e598977a7b3ed182f177983e55f9eb55a6a73982d81277510e9eb7ab41f255151fb9ed4edd11ac4bef95dd872f04ed64966d8c85e0f79 + languageName: node + linkType: hard + +"@svgr/plugin-jsx@npm:8.1.0, @svgr/plugin-jsx@npm:^8.1.0": + version: 8.1.0 + resolution: "@svgr/plugin-jsx@npm:8.1.0" + dependencies: + "@babel/core": "npm:^7.21.3" + "@svgr/babel-preset": "npm:8.1.0" + "@svgr/hast-util-to-babel-ast": "npm:8.0.0" + svg-parser: "npm:^2.0.4" + peerDependencies: + "@svgr/core": "*" + checksum: 10c0/07b4d9e00de795540bf70556fa2cc258774d01e97a12a26234c6fdf42b309beb7c10f31ee24d1a71137239347b1547b8bb5587d3a6de10669f95dcfe99cddc56 + languageName: node + linkType: hard + +"@svgr/plugin-prettier@npm:8.1.0, @svgr/plugin-prettier@npm:^8.1.0": + version: 8.1.0 + resolution: "@svgr/plugin-prettier@npm:8.1.0" + dependencies: + deepmerge: "npm:^4.3.1" + prettier: "npm:^2.8.7" + peerDependencies: + "@svgr/core": "*" + checksum: 10c0/ad1798d93a24bc51a369f817448f47abc1eaf7b940aae205c985ff94672abb2b59aa7357717e93643b4394f5f1b176966c9605f23334eeda13ac20c2e0f1c580 + languageName: node + linkType: hard + +"@svgr/plugin-svgo@npm:8.1.0, @svgr/plugin-svgo@npm:^8.1.0": + version: 8.1.0 + resolution: "@svgr/plugin-svgo@npm:8.1.0" + dependencies: + cosmiconfig: "npm:^8.1.3" + deepmerge: "npm:^4.3.1" + svgo: "npm:^3.0.2" + peerDependencies: + "@svgr/core": "*" + checksum: 10c0/bfd25460f23f1548bfb8f6f3bedd6d6972c1a4f8881bd35a4f8c115218da6e999e8f9ac0ef0ed88c4e0b93fcec37f382b94c0322f4ec2b26752a89e5cc8b9d7a + languageName: node + linkType: hard + "@svta/common-media-library@npm:^0.12.4": version: 0.12.4 resolution: "@svta/common-media-library@npm:0.12.4" @@ -11264,6 +11522,13 @@ __metadata: languageName: node linkType: hard +"@trysound/sax@npm:0.2.0": + version: 0.2.0 + resolution: "@trysound/sax@npm:0.2.0" + checksum: 10c0/44907308549ce775a41c38a815f747009ac45929a45d642b836aa6b0a536e4978d30b8d7d680bbd116e9dd73b7dbe2ef0d1369dcfc2d09e83ba381e485ecbe12 + languageName: node + linkType: hard + "@tybys/wasm-util@npm:^0.10.0, @tybys/wasm-util@npm:^0.10.1": version: 0.10.1 resolution: "@tybys/wasm-util@npm:0.10.1" @@ -14784,7 +15049,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:6": +"camelcase@npm:6, camelcase@npm:^6.2.0": version: 6.3.0 resolution: "camelcase@npm:6.3.0" checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710 @@ -15464,13 +15729,20 @@ __metadata: languageName: node linkType: hard -"commander@npm:7": +"commander@npm:7, commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" checksum: 10c0/8d690ff13b0356df7e0ebbe6c59b4712f754f4b724d4f473d3cc5b3fdcf978e3a5dc3078717858a2ceb50b0f84d0660a7f22a96cdc50fb877d0c9bb31593d23a languageName: node linkType: hard +"commander@npm:^11.1.0": + version: 11.1.0 + resolution: "commander@npm:11.1.0" + checksum: 10c0/13cc6ac875e48780250f723fb81c1c1178d35c5decb1abb1b628b3177af08a8554e76b2c0f29de72d69eef7c864d12613272a71fabef8047922bc622ab75a179 + languageName: node + linkType: hard + "commander@npm:^2.19.0, commander@npm:^2.8.1": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -15703,6 +15975,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:^8.1.3": + version: 8.3.6 + resolution: "cosmiconfig@npm:8.3.6" + dependencies: + import-fresh: "npm:^3.3.0" + js-yaml: "npm:^4.1.0" + parse-json: "npm:^5.2.0" + path-type: "npm:^4.0.0" + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/0382a9ed13208f8bfc22ca2f62b364855207dffdb73dc26e150ade78c3093f1cf56172df2dd460c8caf2afa91c0ed4ec8a88c62f8f9cd1cf423d26506aa8797a + languageName: node + linkType: hard + "country-flag-emoji-polyfill@npm:0.1.8": version: 0.1.8 resolution: "country-flag-emoji-polyfill@npm:0.1.8" @@ -15812,6 +16101,36 @@ __metadata: languageName: node linkType: hard +"css-tree@npm:^2.3.1": + version: 2.3.1 + resolution: "css-tree@npm:2.3.1" + dependencies: + mdn-data: "npm:2.0.30" + source-map-js: "npm:^1.0.1" + checksum: 10c0/6f8c1a11d5e9b14bf02d10717fc0351b66ba12594166f65abfbd8eb8b5b490dd367f5c7721db241a3c792d935fc6751fbc09f7e1598d421477ad9fadc30f4f24 + languageName: node + linkType: hard + +"css-tree@npm:^3.0.1": + version: 3.1.0 + resolution: "css-tree@npm:3.1.0" + dependencies: + mdn-data: "npm:2.12.2" + source-map-js: "npm:^1.0.1" + checksum: 10c0/b5715852c2f397c715ca00d56ec53fc83ea596295ae112eb1ba6a1bda3b31086380e596b1d8c4b980fe6da09e7d0fc99c64d5bb7313030dd0fba9c1415f30979 + languageName: node + linkType: hard + +"css-tree@npm:~2.2.0": + version: 2.2.1 + resolution: "css-tree@npm:2.2.1" + dependencies: + mdn-data: "npm:2.0.28" + source-map-js: "npm:^1.0.1" + checksum: 10c0/47e87b0f02f8ac22f57eceb65c58011dd142d2158128882a0bf963cf2eabb81a4ebbc2e3790c8289be7919fa8b83750c7b69272bd66772c708143b772ba3c186 + languageName: node + linkType: hard + "css-what@npm:^6.1.0": version: 6.2.2 resolution: "css-what@npm:6.2.2" @@ -15826,6 +16145,15 @@ __metadata: languageName: node linkType: hard +"csso@npm:^5.0.5": + version: 5.0.5 + resolution: "csso@npm:5.0.5" + dependencies: + css-tree: "npm:~2.2.0" + checksum: 10c0/ab4beb1e97dd7e207c10e9925405b45f15a6cd1b4880a8686ad573aa6d476aed28b4121a666cffd26c37a26179f7b54741f7c257543003bfb244d06a62ad569b + languageName: node + linkType: hard + "cssstyle@npm:^4.2.1": version: 4.3.0 resolution: "cssstyle@npm:4.3.0" @@ -16259,6 +16587,13 @@ __metadata: languageName: node linkType: hard +"dashify@npm:^2.0.0": + version: 2.0.0 + resolution: "dashify@npm:2.0.0" + checksum: 10c0/b9ab76cbd9739b6dba4359083cc9a670e6a0876f90ab3409b9984cf386b82a28a89009afe15d13ce62f97bc84ce49be2fe85f3a6791481a8d31e962cd0f0e710 + languageName: node + linkType: hard + "dashjs@npm:^5.0.3": version: 5.0.3 resolution: "dashjs@npm:5.0.3" @@ -16487,6 +16822,16 @@ __metadata: languageName: node linkType: hard +"deep-rename-keys@npm:^0.2.1": + version: 0.2.1 + resolution: "deep-rename-keys@npm:0.2.1" + dependencies: + kind-of: "npm:^3.0.2" + rename-keys: "npm:^1.1.2" + checksum: 10c0/841eb25a07f1853651e5061c84e9d0eb2be44d7a7b16381de778e5378e87aa7fb6a97cf49f3723d861f77ac857f3bfee85121168cf01ecfe86de16125e138627 + languageName: node + linkType: hard + "deepmerge@npm:4.3.1, deepmerge@npm:^4.3.1": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" @@ -16822,6 +17167,16 @@ __metadata: languageName: node linkType: hard +"dot-case@npm:^3.0.4": + version: 3.0.4 + resolution: "dot-case@npm:3.0.4" + dependencies: + no-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/5b859ea65097a7ea870e2c91b5768b72ddf7fa947223fd29e167bcdff58fe731d941c48e47a38ec8aa8e43044c8fbd15cd8fa21689a526bc34b6548197cd5b05 + languageName: node + linkType: hard + "dot-prop@npm:^6.0.1": version: 6.0.1 resolution: "dot-prop@npm:6.0.1" @@ -17352,6 +17707,15 @@ __metadata: languageName: node linkType: hard +"error-ex@npm:^1.3.1": + version: 1.3.4 + resolution: "error-ex@npm:1.3.4" + dependencies: + is-arrayish: "npm:^0.2.1" + checksum: 10c0/b9e34ff4778b8f3b31a8377e1c654456f4c41aeaa3d10a1138c3b7635d8b7b2e03eb2475d46d8ae055c1f180a1063e100bffabf64ea7e7388b37735df5328664 + languageName: node + linkType: hard + "es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": version: 1.0.1 resolution: "es-define-property@npm:1.0.1" @@ -17971,6 +18335,13 @@ __metadata: languageName: node linkType: hard +"eventemitter3@npm:^2.0.0": + version: 2.0.3 + resolution: "eventemitter3@npm:2.0.3" + checksum: 10c0/001ff65ddf1c2d627edcdde5efc2a8335a42af72406970de3b4917368e9f0fab5de7d02cdbfb0f5fca944543b2057e045be91c91b9ae3adc6a4dc10c99ad814f + languageName: node + linkType: hard + "eventemitter3@npm:^4.0.4": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" @@ -18991,7 +19362,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.1, glob@npm:^8.1.0": +"glob@npm:^8.0.1, glob@npm:^8.0.3, glob@npm:^8.1.0": version: 8.1.0 resolution: "glob@npm:8.1.0" dependencies: @@ -19742,7 +20113,7 @@ __metadata: languageName: node linkType: hard -"import-fresh@npm:^3.2.1": +"import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.1 resolution: "import-fresh@npm:3.3.1" dependencies: @@ -19907,6 +20278,13 @@ __metadata: languageName: node linkType: hard +"is-arrayish@npm:^0.2.1": + version: 0.2.1 + resolution: "is-arrayish@npm:0.2.1" + checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729 + languageName: node + linkType: hard + "is-arrayish@npm:^0.3.1": version: 0.3.2 resolution: "is-arrayish@npm:0.3.2" @@ -19923,6 +20301,13 @@ __metadata: languageName: node linkType: hard +"is-buffer@npm:^1.1.5, is-buffer@npm:~1.1.6": + version: 1.1.6 + resolution: "is-buffer@npm:1.1.6" + checksum: 10c0/ae18aa0b6e113d6c490ad1db5e8df9bdb57758382b313f5a22c9c61084875c6396d50bbf49315f5b1926d142d74dfb8d31b40d993a383e0a158b15fea7a82234 + languageName: node + linkType: hard + "is-buffer@npm:^2.0.0": version: 2.0.5 resolution: "is-buffer@npm:2.0.5" @@ -19930,13 +20315,6 @@ __metadata: languageName: node linkType: hard -"is-buffer@npm:~1.1.6": - version: 1.1.6 - resolution: "is-buffer@npm:1.1.6" - checksum: 10c0/ae18aa0b6e113d6c490ad1db5e8df9bdb57758382b313f5a22c9c61084875c6396d50bbf49315f5b1926d142d74dfb8d31b40d993a383e0a158b15fea7a82234 - languageName: node - linkType: hard - "is-ci@npm:^3.0.0": version: 3.0.1 resolution: "is-ci@npm:3.0.1" @@ -20439,6 +20817,13 @@ __metadata: languageName: node linkType: hard +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3 + languageName: node + linkType: hard + "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -20618,6 +21003,15 @@ __metadata: languageName: node linkType: hard +"kind-of@npm:^3.0.2": + version: 3.2.2 + resolution: "kind-of@npm:3.2.2" + dependencies: + is-buffer: "npm:^1.1.5" + checksum: 10c0/7e34bc29d4b02c997f92f080de34ebb92033a96736bbb0bb2410e033a7e5ae6571f1fa37b2d7710018f95361473b816c604234197f4f203f9cf149d8ef1574d9 + languageName: node + linkType: hard + "kind-of@npm:^6.0.0, kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" @@ -21040,6 +21434,13 @@ __metadata: languageName: node linkType: hard +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 10c0/3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d + languageName: node + linkType: hard + "linguist-languages@npm:^8.1.0": version: 8.1.0 resolution: "linguist-languages@npm:8.1.0" @@ -21293,6 +21694,15 @@ __metadata: languageName: node linkType: hard +"lower-case@npm:^2.0.2": + version: 2.0.2 + resolution: "lower-case@npm:2.0.2" + dependencies: + tslib: "npm:^2.0.3" + checksum: 10c0/3d925e090315cf7dc1caa358e0477e186ffa23947740e4314a7429b6e62d72742e0bbe7536a5ae56d19d7618ce998aba05caca53c2902bd5742fdca5fc57fd7b + languageName: node + linkType: hard + "lowercase-keys@npm:^2.0.0": version: 2.0.0 resolution: "lowercase-keys@npm:2.0.0" @@ -21901,6 +22311,27 @@ __metadata: languageName: node linkType: hard +"mdn-data@npm:2.0.28": + version: 2.0.28 + resolution: "mdn-data@npm:2.0.28" + checksum: 10c0/20000932bc4cd1cde9cba4e23f08cc4f816398af4c15ec81040ed25421d6bf07b5cf6b17095972577fb498988f40f4cb589e3169b9357bb436a12d8e07e5ea7b + languageName: node + linkType: hard + +"mdn-data@npm:2.0.30": + version: 2.0.30 + resolution: "mdn-data@npm:2.0.30" + checksum: 10c0/a2c472ea16cee3911ae742593715aa4c634eb3d4b9f1e6ada0902aa90df13dcbb7285d19435f3ff213ebaa3b2e0c0265c1eb0e3fb278fda7f8919f046a410cd9 + languageName: node + linkType: hard + +"mdn-data@npm:2.12.2": + version: 2.12.2 + resolution: "mdn-data@npm:2.12.2" + checksum: 10c0/b22443b71d70f72ccc3c6ba1608035431a8fc18c3c8fc53523f06d20e05c2ac10f9b53092759a2ca85cf02f0d37036f310b581ce03e7b99ac74d388ef8152ade + languageName: node + linkType: hard + "mdurl@npm:^2.0.0": version: 2.0.0 resolution: "mdurl@npm:2.0.0" @@ -23013,6 +23444,16 @@ __metadata: languageName: node linkType: hard +"no-case@npm:^3.0.4": + version: 3.0.4 + resolution: "no-case@npm:3.0.4" + dependencies: + lower-case: "npm:^2.0.2" + tslib: "npm:^2.0.3" + checksum: 10c0/8ef545f0b3f8677c848f86ecbd42ca0ff3cd9dd71c158527b344c69ba14710d816d8489c746b6ca225e7b615108938a0bda0a54706f8c255933703ac1cf8e703 + languageName: node + linkType: hard + "node-abi@npm:4.12.0": version: 4.12.0 resolution: "node-abi@npm:4.12.0" @@ -23801,6 +24242,18 @@ __metadata: languageName: node linkType: hard +"parse-json@npm:^5.2.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": "npm:^7.0.0" + error-ex: "npm:^1.3.1" + json-parse-even-better-errors: "npm:^2.3.0" + lines-and-columns: "npm:^1.1.6" + checksum: 10c0/77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585 + languageName: node + linkType: hard + "parse5-htmlparser2-tree-adapter@npm:^7.1.0": version: 7.1.0 resolution: "parse5-htmlparser2-tree-adapter@npm:7.1.0" @@ -23926,6 +24379,13 @@ __metadata: languageName: node linkType: hard +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + "pathe@npm:^2.0.1, pathe@npm:^2.0.3": version: 2.0.3 resolution: "pathe@npm:2.0.3" @@ -24007,7 +24467,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.1.1": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -24283,6 +24743,15 @@ __metadata: languageName: node linkType: hard +"prettier@npm:^2.8.7": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" + bin: + prettier: bin-prettier.js + checksum: 10c0/463ea8f9a0946cd5b828d8cf27bd8b567345cf02f56562d5ecde198b91f47a76b7ac9eae0facd247ace70e927143af6135e8cf411986b8cb8478784a4d6d724a + languageName: node + linkType: hard + "pretty-format@npm:^27.0.2": version: 27.5.1 resolution: "pretty-format@npm:27.5.1" @@ -26009,6 +26478,13 @@ __metadata: languageName: node linkType: hard +"rename-keys@npm:^1.1.2": + version: 1.2.0 + resolution: "rename-keys@npm:1.2.0" + checksum: 10c0/db7b819ec3dc480492d3840dad9f30fa0ed267e6e77b15e99fb8ad1b4e84ca12bbda9968c186a3eded994fdcad88cd8277d9986af20dbbd30fe5e3c409862244 + languageName: node + linkType: hard + "repeat-string@npm:^1.0.0": version: 1.6.1 resolution: "repeat-string@npm:1.6.1" @@ -26604,6 +27080,13 @@ __metadata: languageName: node linkType: hard +"sax@npm:^1.4.1": + version: 1.4.3 + resolution: "sax@npm:1.4.3" + checksum: 10c0/45bba07561d93f184a8686e1a543418ced8c844b994fbe45cc49d5cd2fc8ac7ec949dae38565e35e388ad0cca2b75997a29b6857c927bf6553da3f80ed0e4e62 + languageName: node + linkType: hard + "saxes@npm:^5.0.1": version: 5.0.1 resolution: "saxes@npm:5.0.1" @@ -27092,6 +27575,16 @@ __metadata: languageName: node linkType: hard +"snake-case@npm:^3.0.4": + version: 3.0.4 + resolution: "snake-case@npm:3.0.4" + dependencies: + dot-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/ab19a913969f58f4474fe9f6e8a026c8a2142a01f40b52b79368068343177f818cdfef0b0c6b9558f298782441d5ca8ed5932eb57822439fad791d866e62cecd + languageName: node + linkType: hard + "socket.io-adapter@npm:~2.5.2": version: 2.5.5 resolution: "socket.io-adapter@npm:2.5.5" @@ -27159,7 +27652,7 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": +"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf @@ -27681,6 +28174,57 @@ __metadata: languageName: node linkType: hard +"svg-parser@npm:^2.0.4": + version: 2.0.4 + resolution: "svg-parser@npm:2.0.4" + checksum: 10c0/02f6cb155dd7b63ebc2f44f36365bc294543bebb81b614b7628f1af3c54ab64f7e1cec20f06e252bf95bdde78441ae295a412c68ad1678f16a6907d924512b7a + languageName: node + linkType: hard + +"svgo@npm:^3.0.2": + version: 3.3.2 + resolution: "svgo@npm:3.3.2" + dependencies: + "@trysound/sax": "npm:0.2.0" + commander: "npm:^7.2.0" + css-select: "npm:^5.1.0" + css-tree: "npm:^2.3.1" + css-what: "npm:^6.1.0" + csso: "npm:^5.0.5" + picocolors: "npm:^1.0.0" + bin: + svgo: ./bin/svgo + checksum: 10c0/a6badbd3d1d6dbb177f872787699ab34320b990d12e20798ecae915f0008796a0f3c69164f1485c9def399e0ce0a5683eb4a8045e51a5e1c364bb13a0d9f79e1 + languageName: node + linkType: hard + +"svgo@npm:^4.0.0": + version: 4.0.0 + resolution: "svgo@npm:4.0.0" + dependencies: + commander: "npm:^11.1.0" + css-select: "npm:^5.1.0" + css-tree: "npm:^3.0.1" + css-what: "npm:^6.1.0" + csso: "npm:^5.0.5" + picocolors: "npm:^1.1.1" + sax: "npm:^1.4.1" + bin: + svgo: ./bin/svgo.js + checksum: 10c0/2b01c910d59d10bb15e17714181a8fa96531b09a4e2cf2ca1abe24dbcb8400725b6d542d6e456c62222546e334d5b344799c170c5b6be0c48e31b02c23297275 + languageName: node + linkType: hard + +"svgson@npm:^5.3.1": + version: 5.3.1 + resolution: "svgson@npm:5.3.1" + dependencies: + deep-rename-keys: "npm:^0.2.1" + xml-reader: "npm:2.4.3" + checksum: 10c0/44d9cf62ec3eaf00d6ed5b2b939971c46aabfba08847dac6ac494c2177e5d08dddfebc2946891adf8705a0c5409c55766ba74a4c6a41f7dc41fce66c95dcb4ee + languageName: node + linkType: hard + "swagger-jsdoc@npm:^6.2.8": version: 6.2.8 resolution: "swagger-jsdoc@npm:6.2.8" @@ -28429,14 +28973,14 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.7.0, tslib@npm:^2.8.0": +"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.7.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 languageName: node linkType: hard -"tsx@npm:^4.20.3, tsx@npm:^4.20.5": +"tsx@npm:^4.20.3, tsx@npm:^4.20.6": version: 4.20.6 resolution: "tsx@npm:4.20.6" dependencies: @@ -29734,6 +30278,15 @@ __metadata: languageName: node linkType: hard +"xml-lexer@npm:^0.2.2": + version: 0.2.2 + resolution: "xml-lexer@npm:0.2.2" + dependencies: + eventemitter3: "npm:^2.0.0" + checksum: 10c0/592f8520a654836b2eb458895c108c6493a2cee52f8e38c027ff6d922d45484b6e7386647f70362cbb0324f705465bdf040a4076f842af265e2e368a3b29d5a7 + languageName: node + linkType: hard + "xml-name-validator@npm:^5.0.0": version: 5.0.0 resolution: "xml-name-validator@npm:5.0.0" @@ -29741,6 +30294,16 @@ __metadata: languageName: node linkType: hard +"xml-reader@npm:2.4.3": + version: 2.4.3 + resolution: "xml-reader@npm:2.4.3" + dependencies: + eventemitter3: "npm:^2.0.0" + xml-lexer: "npm:^0.2.2" + checksum: 10c0/b2514806af287800f1cc7756c0d9773ec45ce26acc32f8e23bd22c04eaa18ffe6b05275acc276e291f037f9f9ffd3d65dc9044363f6a087a95a7a1c62428aec2 + languageName: node + linkType: hard + "xml2js@npm:0.6.2": version: 0.6.2 resolution: "xml2js@npm:0.6.2"