Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"semi": false,
"singleQuote": true,
"jsxSingleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"insertFinalNewline": true,
"sortPackageJson": false,
"ignorePatterns": [
"coverage/**",
"dist/**",
"node_modules/**",
"pnpm-lock.yaml",
"packages/icons/ts/**"
]
}
26 changes: 26 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["eslint", "oxc", "typescript", "unicorn", "react", "import"],
"categories": {
"correctness": "error",
"suspicious": "error"
},
"ignorePatterns": ["dist/**", "coverage/**", "node_modules/**"],
"options": {
"reportUnusedDisableDirectives": "error"
},
"overrides": [
{
"files": ["packages/icons/scripts/**/*.ts", "packages/svg/scripts/**/*.ts"],
"env": {
"node": true
}
},
{
"files": ["packages/icons/ts/**/*.ts", "packages/icons/ts/**/*.tsx"],
"env": {
"browser": true
}
}
]
}
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["oxc.oxc-vscode"]
}
80 changes: 37 additions & 43 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,50 +1,44 @@
{
// Disable the default formatter, use eslint instead
// Use Oxc for formatting on supported files
"prettier.enable": false,
"editor.formatOnSave": false,

// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
"[javascript]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[javascriptreact]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[typescript]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[json]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[markdown]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[yaml]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},

// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },
{ "rule": "*-order", "severity": "off", "fixable": true },
{ "rule": "*-dangle", "severity": "off", "fixable": true },
{ "rule": "*-newline", "severity": "off", "fixable": true },
{ "rule": "*quotes", "severity": "off", "fixable": true },
{ "rule": "*semi", "severity": "off", "fixable": true }
],

// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml",
"toml",
"xml",
"gql",
"graphql",
"astro",
"svelte",
"css",
"less",
"scss",
"pcss",
"postcss"
]
// Auto fix lint issues on save
"editor.codeActionsOnSave": {
"source.fixAll.oxc": "always",
"source.organizeImports": "never"
}
}
8 changes: 0 additions & 8 deletions eslint.config.mjs

This file was deleted.

47 changes: 32 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,50 @@
"name": "@univerjs/icons-workspace",
"version": "1.1.1",
"private": true,
"packageManager": "pnpm@10.26.0",
"packageManager": "pnpm@10.32.1",
"description": "Icons used by Univer",
"author": "DreamNum Co., Ltd. <developer@univer.ai>",
"license": "MIT",
"repository": "https://github.com/dream-num/univer-icons.git",
"sideEffects": false,
"main": "index.js",
"engines": {
"node": ">=22",
"pnpm": ">=10"
"devEngines": {
"runtime": [
{
"name": "node",
"range": ">=22.18"
},
{
"name": "pnpm",
"range": ">=10.1"
}
]
},
"scripts": {
"build": "pnpm --filter ./packages/icons run build",
"lint": "eslint"
},
"dependencies": {
"tsx": "^4.21.0"
"format": "oxfmt .",
"format:check": "oxfmt --check .",
"lint": "oxlint .",
"lint:fix": "oxlint --fix .",
"lint:staged": "lint-staged",
"prepare": "simple-git-hooks"
},
"dependencies": {},
"devDependencies": {
"@antfu/eslint-config": "^6.7.3",
"@eslint-react/eslint-plugin": "^2.4.0",
"@types/node": "^25.0.3",
"@types/react": "^19.2.7",
"@types/node": "^25.5.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"eslint": "^9.39.2",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.26",
"lint-staged": "^16.4.0",
"oxfmt": "^0.40.0",
"oxlint": "^1.55.0",
"simple-git-hooks": "^2.13.1",
"typescript": "^5.9.3"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint:staged"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,cjs,cts,mjs,mts}": "oxlint",
"*.{md,markdown,yml,yaml}": "oxfmt --check ."
}
}
9 changes: 6 additions & 3 deletions packages/icons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
"univer"
],
"sideEffects": false,
"imports": {
"#build/*": "./scripts/build/*.ts"
},
"exports": {
".": {
"import": "./dist/esm/index.js",
Expand All @@ -31,7 +34,7 @@
"dist"
],
"scripts": {
"build": "tsx ./scripts/build/index.ts && tsc"
"build": "node --experimental-strip-types ./scripts/build/index.ts && tsc"
},
"peerDependencies": {
"react": "*",
Expand All @@ -40,9 +43,9 @@
"devDependencies": {
"@types/svg-parser": "^2.0.6",
"@univerjs/icons-svg": "workspace:*",
"rolldown": "1.0.0-beta.57",
"rolldown": "1.0.0-rc.9",
"svg-parser": "^2.0.4",
"svgo": "^4.0.0",
"svgo": "^4.0.1",
"typescript": "^5.9.3"
}
}
15 changes: 6 additions & 9 deletions packages/icons/scripts/build/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { IconNode } from './normalize-ast'
import type { IconNode } from '#build/normalize-ast'
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import manifest from '@univerjs/icons-svg/manifest'
import manifest from '@univerjs/icons-svg/manifest' with { type: 'json' }
import { rolldown } from 'rolldown'
import { normalizeAST } from './normalize-ast'
import { parseSvg } from './parse-svg'
import { getIconComponent } from './templates'
import { normalizeAST } from '#build/normalize-ast'
import { parseSvg } from '#build/parse-svg'
import { getIconComponent } from '#build/templates'

const __dirname = fileURLToPath(new URL('.', import.meta.url))

Expand Down Expand Up @@ -45,10 +45,7 @@ async function compileTsFile() {
for (const icon of [{ name: 'base' }, ...Object.values(manifest).flat(), { name: 'index' }]) {
const bundle = await rolldown({
input: `ts/${icon.name}.tsx`,
external: [
/^react/,
/^.\//,
],
external: [/^react/, /^.\//],
})

await bundle.write({
Expand Down
29 changes: 8 additions & 21 deletions packages/icons/scripts/build/normalize-ast.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { camelCase } from './camel-case'
import { camelCase } from '#build/camel-case'

interface Attrs {
style: object | string
Expand Down Expand Up @@ -26,10 +26,7 @@ interface NormalizationContext {
idReplacementSet: Set<string>
}

function normalizeDefinitions(
node: IconElement,
context: NormalizationContext,
) {
function normalizeDefinitions(node: IconElement, context: NormalizationContext) {
if (node.tag === 'defs') {
node.children?.forEach((def) => {
if (typeof def.attrs.id === 'string') {
Expand Down Expand Up @@ -63,12 +60,9 @@ function createNormalizationContext(): NormalizationContext {
/**
* map svg-parser ast to React element, so it would be convenient to render
*/
function doNormalize(
roots: IconNode[],
context: NormalizationContext,
): IconElement[] {
function doNormalize(roots: IconNode[], context: NormalizationContext): IconElement[] {
return roots
.map(node => ({
.map((node) => ({
tag: node.tagName,
attrs: node.properties,
children: doNormalize(node.children, context),
Expand All @@ -95,17 +89,13 @@ function normalizeChildren(node: IconElement) {

function addDefIds(root: IconElement, context: NormalizationContext) {
const defIds = Array.from(context.idReplacementSet)
if (defIds.length === 0)
return
if (defIds.length === 0) return
root.defIds = defIds
}

function replaceIds(name: string, str: string, set: Set<string>): string {
return Array.from(set.keys()).reduce((parsed, currentToReplace) => {
return parsed.replace(
new RegExp(currentToReplace, 'g'),
`${name}_${currentToReplace}`,
)
return parsed.replace(new RegExp(currentToReplace, 'g'), `${name}_${currentToReplace}`)
}, str)
}

Expand Down Expand Up @@ -133,10 +123,7 @@ function normalizeClassName(node: IconElement) {
}
}

export function normalizeAST(
name: string,
roots: IconNode[],
): string[] {
export function normalizeAST(name: string, roots: IconNode[]): string[] {
const context = createNormalizationContext()
const normalizedRoots = doNormalize(roots, context)

Expand All @@ -148,7 +135,7 @@ export function normalizeAST(
normalizeWidthAndHeight(root)
})

return normalizedRoots.map(root =>
return normalizedRoots.map((root) =>
replaceIds(name, JSON.stringify(root), context.idReplacementSet),
)
}
Expand Down
23 changes: 13 additions & 10 deletions packages/icons/scripts/build/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ export function getIconComponent({
name: string
componentName: string
}) {
return `/* eslint-disable */
import { createElement, forwardRef } from 'react';
import type { IconProps } from './base';
import { IconBase } from './base';
const element = ${element};
return `import { createElement, forwardRef } from 'react'
import type { IconProps } from './base'
import { IconBase } from './base'

const element = ${element}

export const ${componentName} = forwardRef<SVGElement, IconProps>(function ${componentName}(props, ref) {
return createElement(IconBase, Object.assign({}, props, {
id: '${name}',
ref: ref,
ref,
icon: element,
}));
});
${componentName}.displayName = '${componentName}';
export default ${componentName};
}))
})

${componentName}.displayName = '${componentName}'

export default ${componentName}
`
}
Loading
Loading