[backend] fix: 修复异常处理和类型转换问题

This commit is contained in:
xsl
2026-01-26 11:53:40 +08:00
parent 7ccc2a6ac6
commit 83e05bf85f
28639 changed files with 2506458 additions and 93 deletions
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../acorn/bin/acorn
+1
View File
@@ -0,0 +1 @@
../baseline-browser-mapping/dist/cli.js
+1
View File
@@ -0,0 +1 @@
../browserslist/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../esbuild/bin/esbuild
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../eslint/bin/eslint.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../js-yaml/bin/js-yaml.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../jsesc/bin/jsesc
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../json5/lib/cli.js
+1
View File
@@ -0,0 +1 @@
../loose-envify/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../lz-string/bin/bin.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../which/bin/node-which
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../@babel/parser/bin/babel-parser.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../@playwright/test/cli.js
+1
View File
@@ -0,0 +1 @@
../playwright-core/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../prettier/bin/prettier.cjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../resolve/bin/resolve
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rimraf/bin.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rollup/dist/bin/rollup
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../semver/bin/semver.js
+1
View File
@@ -0,0 +1 @@
../update-browserslist-db/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite/bin/vite.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite-node/vite-node.mjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vitest/vitest.mjs
+1
View File
@@ -0,0 +1 @@
../why-is-node-running/cli.js
+7146
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
{"version":"1.6.1","results":[[":src/utils/validate.test.js",{"duration":8,"failed":false}],[":src/utils/format.test.js",{"duration":43,"failed":false}],[":src/services/project.test.js",{"duration":3,"failed":false}],[":src/services/user.test.js",{"duration":10,"failed":false}],[":src/contexts/AuthContext.test.jsx",{"duration":18,"failed":false}]]}
+10
View File
@@ -0,0 +1,10 @@
(The MIT License)
Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2022 Jean-Philippe Zolesio <holblin@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+146
View File
@@ -0,0 +1,146 @@
# @adobe/css-tools
> A modern CSS parser and stringifier with TypeScript support
[![npm version](https://badge.fury.io/js/%40adobe%2Fcss-tools.svg)](https://badge.fury.io/js/%40adobe%2Fcss-tools)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
Parse CSS into an Abstract Syntax Tree (AST) and convert it back to CSS with configurable formatting. Built with TypeScript for type safety and modern JavaScript features.
## Install
```bash
npm install @adobe/css-tools
```
## Usage
```js
import { parse, stringify } from '@adobe/css-tools'
// Parse CSS to AST
const ast = parse('body { font-size: 12px; }')
// Stringify AST back to CSS
const css = stringify(ast)
// => "body { font-size: 12px; }"
// Pretty print with custom indentation
const formatted = stringify(ast, { indent: ' ' })
// => "body {\n font-size: 12px;\n}"
// Minify output
const minified = stringify(ast, { compress: true })
// => "body{font-size:12px}"
```
## API
### `parse(code, options?)`
Parses CSS code and returns an Abstract Syntax Tree (AST).
**Parameters:**
- `code` (string) - The CSS code to parse
- `options` (object, optional) - Parsing options
- `silent` (boolean) - Silently fail on parse errors instead of throwing
- `source` (string) - File path for better error reporting
**Returns:** `CssStylesheetAST` - The parsed CSS as an AST
### `stringify(ast, options?)`
Converts a CSS AST back to CSS string with configurable formatting.
**Parameters:**
- `ast` (CssStylesheetAST) - The CSS AST to stringify
- `options` (object, optional) - Stringification options
- `indent` (string) - Indentation string (default: `' '`)
- `compress` (boolean) - Whether to compress/minify the output (default: `false`)
**Returns:** `string` - The formatted CSS string
## Features
- **Complete CSS Support**: All standard CSS features including selectors, properties, values, at-rules, and comments
- **TypeScript Support**: Full type definitions for all AST nodes and functions
- **Error Handling**: Configurable error handling with detailed position information
- **Formatting Options**: Pretty print, minify, or custom formatting
- **Performance Optimized**: Efficient parsing and stringification for large CSS files
- **Source Maps**: Track original source positions for debugging and tooling
### Supported CSS Features
- **Selectors**: Element, class, ID, attribute, pseudo-class, pseudo-element selectors
- **Properties**: All standard CSS properties and custom properties
- **Values**: Colors, lengths, percentages, functions, calc(), etc.
- **At-rules**: @media, @keyframes, @import, @charset, @namespace, @font-face, @page, @document, @supports, @container, @layer, @starting-style, @host, @custom-media
- **Comments**: Both /* */ and // comments
- **Whitespace**: Preserves formatting information
- **Vendor prefixes**: Supports vendor-prefixed at-rules and properties
- **Nested rules**: Media queries, supports, containers, etc.
- **Complex selectors**: Combinators, pseudo-selectors, attribute selectors
## Examples
### Error Handling
```js
import { parse } from '@adobe/css-tools'
const malformedCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
`
// Parse with silent error handling
const result = parse(malformedCss, { silent: true })
// Check for parsing errors
if (result.stylesheet.parsingErrors) {
console.log('Parsing errors:', result.stylesheet.parsingErrors.length)
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error at line ${error.line}: ${error.message}`)
})
}
// Valid rules are still parsed
console.log('Valid rules:', result.stylesheet.rules.length)
```
### Source Tracking
```js
import { parse } from '@adobe/css-tools'
const css = 'body { color: red; }'
const ast = parse(css, { source: 'styles.css' })
// Position information is available
const rule = ast.stylesheet.rules[0]
console.log(rule.position?.source) // "styles.css"
console.log(rule.position?.start) // { line: 1, column: 1 }
console.log(rule.position?.end) // { line: 1, column: 20 }
```
For more examples, see the [Examples documentation](docs/EXAMPLES.md).
## Performance
The library is optimized for performance and can handle large CSS files efficiently. For benchmarking information, see the `benchmark/` directory in the source code.
## Documentation
- [API Reference](docs/API.md) - Complete API documentation
- [AST Structure](docs/AST.md) - Detailed AST node types and structure
- [Examples](docs/EXAMPLES.md) - Comprehensive usage examples
- [Changelog](docs/CHANGELOG.md) - Version history and changes
## Background
This is a fork of the npm `css` package, maintained by Adobe with modern improvements including TypeScript support, enhanced performance, and security updates. It provides a robust foundation for CSS tooling, preprocessing, and analysis.
## License
[MIT](LICENSE)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+176
View File
@@ -0,0 +1,176 @@
declare class CssParseError extends Error {
readonly reason: string;
readonly filename?: string;
readonly line: number;
readonly column: number;
readonly source: string;
constructor(filename: string, msg: string, lineno: number, column: number, css: string);
}
/**
* Store position information for a node
*/
declare class Position {
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
source?: string;
constructor(start: {
line: number;
column: number;
}, end: {
line: number;
column: number;
}, source: string);
}
declare enum CssTypes {
stylesheet = "stylesheet",
rule = "rule",
declaration = "declaration",
comment = "comment",
container = "container",
charset = "charset",
document = "document",
customMedia = "custom-media",
fontFace = "font-face",
host = "host",
import = "import",
keyframes = "keyframes",
keyframe = "keyframe",
layer = "layer",
media = "media",
namespace = "namespace",
page = "page",
startingStyle = "starting-style",
supports = "supports"
}
type CssCommonAST = {
type: CssTypes;
};
type CssCommonPositionAST = CssCommonAST & {
position?: Position;
parent?: unknown;
};
type CssStylesheetAST = CssCommonAST & {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: Array<CssAtRuleAST>;
parsingErrors?: Array<CssParseError>;
};
};
type CssRuleAST = CssCommonPositionAST & {
type: CssTypes.rule;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssDeclarationAST = CssCommonPositionAST & {
type: CssTypes.declaration;
property: string;
value: string;
};
type CssCommentAST = CssCommonPositionAST & {
type: CssTypes.comment;
comment: string;
};
type CssContainerAST = CssCommonPositionAST & {
type: CssTypes.container;
container: string;
rules: Array<CssAtRuleAST>;
};
type CssCharsetAST = CssCommonPositionAST & {
type: CssTypes.charset;
charset: string;
};
type CssCustomMediaAST = CssCommonPositionAST & {
type: CssTypes.customMedia;
name: string;
media: string;
};
type CssDocumentAST = CssCommonPositionAST & {
type: CssTypes.document;
document: string;
vendor?: string;
rules: Array<CssAtRuleAST>;
};
type CssFontFaceAST = CssCommonPositionAST & {
type: CssTypes.fontFace;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssHostAST = CssCommonPositionAST & {
type: CssTypes.host;
rules: Array<CssAtRuleAST>;
};
type CssImportAST = CssCommonPositionAST & {
type: CssTypes.import;
import: string;
};
type CssKeyframesAST = CssCommonPositionAST & {
type: CssTypes.keyframes;
name: string;
vendor?: string;
keyframes: Array<CssKeyframeAST | CssCommentAST>;
};
type CssKeyframeAST = CssCommonPositionAST & {
type: CssTypes.keyframe;
values: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssLayerAST = CssCommonPositionAST & {
type: CssTypes.layer;
layer: string;
rules?: Array<CssAtRuleAST>;
};
type CssMediaAST = CssCommonPositionAST & {
type: CssTypes.media;
media: string;
rules: Array<CssAtRuleAST>;
};
type CssNamespaceAST = CssCommonPositionAST & {
type: CssTypes.namespace;
namespace: string;
};
type CssPageAST = CssCommonPositionAST & {
type: CssTypes.page;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssSupportsAST = CssCommonPositionAST & {
type: CssTypes.supports;
supports: string;
rules: Array<CssAtRuleAST>;
};
type CssStartingStyleAST = CssCommonPositionAST & {
type: CssTypes.startingStyle;
rules: Array<CssAtRuleAST>;
};
type CssAtRuleAST = CssRuleAST | CssCommentAST | CssContainerAST | CssCharsetAST | CssCustomMediaAST | CssDocumentAST | CssFontFaceAST | CssHostAST | CssImportAST | CssKeyframesAST | CssLayerAST | CssMediaAST | CssNamespaceAST | CssPageAST | CssSupportsAST | CssStartingStyleAST;
type CssAllNodesAST = CssAtRuleAST | CssStylesheetAST | CssDeclarationAST | CssKeyframeAST;
type CompilerOptions = {
indent?: string;
compress?: boolean;
};
declare const parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
declare const stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
declare const _default: {
parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
};
export { CssTypes, _default as default, parse, stringify };
export type { CssAllNodesAST, CssAtRuleAST, CssCharsetAST, CssCommentAST, CssCommonAST, CssCommonPositionAST, CssContainerAST, CssCustomMediaAST, CssDeclarationAST, CssDocumentAST, CssFontFaceAST, CssHostAST, CssImportAST, CssKeyframeAST, CssKeyframesAST, CssLayerAST, CssMediaAST, CssNamespaceAST, CssPageAST, CssRuleAST, CssStartingStyleAST, CssStylesheetAST, CssSupportsAST };
+176
View File
@@ -0,0 +1,176 @@
declare class CssParseError extends Error {
readonly reason: string;
readonly filename?: string;
readonly line: number;
readonly column: number;
readonly source: string;
constructor(filename: string, msg: string, lineno: number, column: number, css: string);
}
/**
* Store position information for a node
*/
declare class Position {
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
source?: string;
constructor(start: {
line: number;
column: number;
}, end: {
line: number;
column: number;
}, source: string);
}
declare enum CssTypes {
stylesheet = "stylesheet",
rule = "rule",
declaration = "declaration",
comment = "comment",
container = "container",
charset = "charset",
document = "document",
customMedia = "custom-media",
fontFace = "font-face",
host = "host",
import = "import",
keyframes = "keyframes",
keyframe = "keyframe",
layer = "layer",
media = "media",
namespace = "namespace",
page = "page",
startingStyle = "starting-style",
supports = "supports"
}
type CssCommonAST = {
type: CssTypes;
};
type CssCommonPositionAST = CssCommonAST & {
position?: Position;
parent?: unknown;
};
type CssStylesheetAST = CssCommonAST & {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: Array<CssAtRuleAST>;
parsingErrors?: Array<CssParseError>;
};
};
type CssRuleAST = CssCommonPositionAST & {
type: CssTypes.rule;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssDeclarationAST = CssCommonPositionAST & {
type: CssTypes.declaration;
property: string;
value: string;
};
type CssCommentAST = CssCommonPositionAST & {
type: CssTypes.comment;
comment: string;
};
type CssContainerAST = CssCommonPositionAST & {
type: CssTypes.container;
container: string;
rules: Array<CssAtRuleAST>;
};
type CssCharsetAST = CssCommonPositionAST & {
type: CssTypes.charset;
charset: string;
};
type CssCustomMediaAST = CssCommonPositionAST & {
type: CssTypes.customMedia;
name: string;
media: string;
};
type CssDocumentAST = CssCommonPositionAST & {
type: CssTypes.document;
document: string;
vendor?: string;
rules: Array<CssAtRuleAST>;
};
type CssFontFaceAST = CssCommonPositionAST & {
type: CssTypes.fontFace;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssHostAST = CssCommonPositionAST & {
type: CssTypes.host;
rules: Array<CssAtRuleAST>;
};
type CssImportAST = CssCommonPositionAST & {
type: CssTypes.import;
import: string;
};
type CssKeyframesAST = CssCommonPositionAST & {
type: CssTypes.keyframes;
name: string;
vendor?: string;
keyframes: Array<CssKeyframeAST | CssCommentAST>;
};
type CssKeyframeAST = CssCommonPositionAST & {
type: CssTypes.keyframe;
values: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssLayerAST = CssCommonPositionAST & {
type: CssTypes.layer;
layer: string;
rules?: Array<CssAtRuleAST>;
};
type CssMediaAST = CssCommonPositionAST & {
type: CssTypes.media;
media: string;
rules: Array<CssAtRuleAST>;
};
type CssNamespaceAST = CssCommonPositionAST & {
type: CssTypes.namespace;
namespace: string;
};
type CssPageAST = CssCommonPositionAST & {
type: CssTypes.page;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssSupportsAST = CssCommonPositionAST & {
type: CssTypes.supports;
supports: string;
rules: Array<CssAtRuleAST>;
};
type CssStartingStyleAST = CssCommonPositionAST & {
type: CssTypes.startingStyle;
rules: Array<CssAtRuleAST>;
};
type CssAtRuleAST = CssRuleAST | CssCommentAST | CssContainerAST | CssCharsetAST | CssCustomMediaAST | CssDocumentAST | CssFontFaceAST | CssHostAST | CssImportAST | CssKeyframesAST | CssLayerAST | CssMediaAST | CssNamespaceAST | CssPageAST | CssSupportsAST | CssStartingStyleAST;
type CssAllNodesAST = CssAtRuleAST | CssStylesheetAST | CssDeclarationAST | CssKeyframeAST;
type CompilerOptions = {
indent?: string;
compress?: boolean;
};
declare const parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
declare const stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
declare const _default: {
parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
};
export { CssTypes, _default as default, parse, stringify };
export type { CssAllNodesAST, CssAtRuleAST, CssCharsetAST, CssCommentAST, CssCommonAST, CssCommonPositionAST, CssContainerAST, CssCustomMediaAST, CssDeclarationAST, CssDocumentAST, CssFontFaceAST, CssHostAST, CssImportAST, CssKeyframeAST, CssKeyframesAST, CssLayerAST, CssMediaAST, CssNamespaceAST, CssPageAST, CssRuleAST, CssStartingStyleAST, CssStylesheetAST, CssSupportsAST };
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+176
View File
@@ -0,0 +1,176 @@
declare class CssParseError extends Error {
readonly reason: string;
readonly filename?: string;
readonly line: number;
readonly column: number;
readonly source: string;
constructor(filename: string, msg: string, lineno: number, column: number, css: string);
}
/**
* Store position information for a node
*/
declare class Position {
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
source?: string;
constructor(start: {
line: number;
column: number;
}, end: {
line: number;
column: number;
}, source: string);
}
declare enum CssTypes {
stylesheet = "stylesheet",
rule = "rule",
declaration = "declaration",
comment = "comment",
container = "container",
charset = "charset",
document = "document",
customMedia = "custom-media",
fontFace = "font-face",
host = "host",
import = "import",
keyframes = "keyframes",
keyframe = "keyframe",
layer = "layer",
media = "media",
namespace = "namespace",
page = "page",
startingStyle = "starting-style",
supports = "supports"
}
type CssCommonAST = {
type: CssTypes;
};
type CssCommonPositionAST = CssCommonAST & {
position?: Position;
parent?: unknown;
};
type CssStylesheetAST = CssCommonAST & {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: Array<CssAtRuleAST>;
parsingErrors?: Array<CssParseError>;
};
};
type CssRuleAST = CssCommonPositionAST & {
type: CssTypes.rule;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssDeclarationAST = CssCommonPositionAST & {
type: CssTypes.declaration;
property: string;
value: string;
};
type CssCommentAST = CssCommonPositionAST & {
type: CssTypes.comment;
comment: string;
};
type CssContainerAST = CssCommonPositionAST & {
type: CssTypes.container;
container: string;
rules: Array<CssAtRuleAST>;
};
type CssCharsetAST = CssCommonPositionAST & {
type: CssTypes.charset;
charset: string;
};
type CssCustomMediaAST = CssCommonPositionAST & {
type: CssTypes.customMedia;
name: string;
media: string;
};
type CssDocumentAST = CssCommonPositionAST & {
type: CssTypes.document;
document: string;
vendor?: string;
rules: Array<CssAtRuleAST>;
};
type CssFontFaceAST = CssCommonPositionAST & {
type: CssTypes.fontFace;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssHostAST = CssCommonPositionAST & {
type: CssTypes.host;
rules: Array<CssAtRuleAST>;
};
type CssImportAST = CssCommonPositionAST & {
type: CssTypes.import;
import: string;
};
type CssKeyframesAST = CssCommonPositionAST & {
type: CssTypes.keyframes;
name: string;
vendor?: string;
keyframes: Array<CssKeyframeAST | CssCommentAST>;
};
type CssKeyframeAST = CssCommonPositionAST & {
type: CssTypes.keyframe;
values: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssLayerAST = CssCommonPositionAST & {
type: CssTypes.layer;
layer: string;
rules?: Array<CssAtRuleAST>;
};
type CssMediaAST = CssCommonPositionAST & {
type: CssTypes.media;
media: string;
rules: Array<CssAtRuleAST>;
};
type CssNamespaceAST = CssCommonPositionAST & {
type: CssTypes.namespace;
namespace: string;
};
type CssPageAST = CssCommonPositionAST & {
type: CssTypes.page;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssSupportsAST = CssCommonPositionAST & {
type: CssTypes.supports;
supports: string;
rules: Array<CssAtRuleAST>;
};
type CssStartingStyleAST = CssCommonPositionAST & {
type: CssTypes.startingStyle;
rules: Array<CssAtRuleAST>;
};
type CssAtRuleAST = CssRuleAST | CssCommentAST | CssContainerAST | CssCharsetAST | CssCustomMediaAST | CssDocumentAST | CssFontFaceAST | CssHostAST | CssImportAST | CssKeyframesAST | CssLayerAST | CssMediaAST | CssNamespaceAST | CssPageAST | CssSupportsAST | CssStartingStyleAST;
type CssAllNodesAST = CssAtRuleAST | CssStylesheetAST | CssDeclarationAST | CssKeyframeAST;
type CompilerOptions = {
indent?: string;
compress?: boolean;
};
declare const parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
declare const stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
declare const _default: {
parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
};
export { CssTypes, _default as default, parse, stringify };
export type { CssAllNodesAST, CssAtRuleAST, CssCharsetAST, CssCommentAST, CssCommonAST, CssCommonPositionAST, CssContainerAST, CssCustomMediaAST, CssDeclarationAST, CssDocumentAST, CssFontFaceAST, CssHostAST, CssImportAST, CssKeyframeAST, CssKeyframesAST, CssLayerAST, CssMediaAST, CssNamespaceAST, CssPageAST, CssRuleAST, CssStartingStyleAST, CssStylesheetAST, CssSupportsAST };
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+314
View File
@@ -0,0 +1,314 @@
# API Reference
## Overview
`@adobe/css-tools` provides a modern CSS parser and stringifier with comprehensive TypeScript support. It can parse CSS into an Abstract Syntax Tree (AST) and convert the AST back to CSS with various formatting options.
## Installation
```bash
npm install @adobe/css-tools
```
## Core Functions
### `parse(code, options?)`
Parses CSS code and returns an Abstract Syntax Tree (AST).
#### Parameters
- `code` (string) - The CSS code to parse
- `options` (object, optional) - Parsing options
- `silent` (boolean) - Silently fail on parse errors instead of throwing. When `true`, errors are collected in `ast.stylesheet.parsingErrors`
- `source` (string) - File path for better error reporting
#### Returns
- `CssStylesheetAST` - The parsed CSS as an AST
#### Example
```javascript
import { parse } from '@adobe/css-tools';
const css = `
.example {
color: red;
font-size: 16px;
}
`;
const ast = parse(css);
console.log(ast.stylesheet.rules);
```
### `stringify(ast, options?)`
Converts a CSS AST back to CSS string with configurable formatting.
#### Parameters
- `ast` (CssStylesheetAST) - The CSS AST to stringify
- `options` (CompilerOptions, optional) - Stringification options
- `indent` (string) - Indentation string (default: `' '`)
- `compress` (boolean) - Whether to compress/minify the output (default: `false`)
#### Returns
- `string` - The formatted CSS string
#### Example
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = '.example { color: red; }';
const ast = parse(css);
// Pretty print
const formatted = stringify(ast, { indent: ' ' });
console.log(formatted);
// Output:
// .example {
// color: red;
// }
// Compressed
const minified = stringify(ast, { compress: true });
console.log(minified);
// Output: .example{color:red}
```
## Type Definitions
### Core Types
#### `CssStylesheetAST`
The root AST node representing a complete CSS stylesheet.
```typescript
type CssStylesheetAST = {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: CssRuleAST[];
parsingErrors?: CssParseError[];
};
};
```
#### `CssRuleAST`
Represents a CSS rule (selector + declarations).
```typescript
type CssRuleAST = {
type: CssTypes.rule;
selectors: string[];
declarations: CssDeclarationAST[];
position?: CssPosition;
parent?: CssStylesheetAST;
};
```
#### `CssDeclarationAST`
Represents a CSS property declaration.
```typescript
type CssDeclarationAST = {
type: CssTypes.declaration;
property: string;
value: string;
position?: CssPosition;
parent?: CssRuleAST;
};
```
#### `CssMediaAST`
Represents a CSS @media rule.
```typescript
type CssMediaAST = {
type: CssTypes.media;
media: string;
rules: CssRuleAST[];
position?: CssPosition;
parent?: CssStylesheetAST;
};
```
#### `CssKeyframesAST`
Represents a CSS @keyframes rule.
```typescript
type CssKeyframesAST = {
type: CssTypes.keyframes;
name: string;
keyframes: CssKeyframeAST[];
position?: CssPosition;
parent?: CssStylesheetAST;
};
```
#### `CssPosition`
Represents source position information.
```typescript
type CssPosition = {
source?: string;
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
};
```
#### `CssParseError`
Represents a parsing error.
```typescript
type CssParseError = {
message: string;
reason: string;
filename?: string;
line: number;
column: number;
source?: string;
};
```
### Compiler Options
#### `CompilerOptions`
Options for the stringifier.
```typescript
type CompilerOptions = {
indent?: string; // Default: ' '
compress?: boolean; // Default: false
};
```
## Error Handling
### Silent Parsing
When parsing malformed CSS, you can use the `silent` option to collect errors instead of throwing:
```javascript
import { parse } from '@adobe/css-tools';
const malformedCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
`;
const result = parse(malformedCss, { silent: true });
if (result.stylesheet.parsingErrors) {
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error at line ${error.line}: ${error.message}`);
});
}
// Valid rules are still parsed
console.log('Valid rules:', result.stylesheet.rules.length);
```
### Source Tracking
Enable source tracking for better error reporting:
```javascript
import { parse } from '@adobe/css-tools';
const css = 'body { color: red; }';
const ast = parse(css, { source: 'styles.css' });
const rule = ast.stylesheet.rules[0];
console.log(rule.position?.source); // "styles.css"
console.log(rule.position?.start); // { line: 1, column: 1 }
console.log(rule.position?.end); // { line: 1, column: 20 }
```
## Advanced Usage
### Working with At-Rules
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = `
@media (max-width: 768px) {
.container {
padding: 10px;
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
`;
const ast = parse(css);
// Access media rules
const mediaRule = ast.stylesheet.rules.find(rule => rule.type === 'media');
console.log(mediaRule.media); // "(max-width: 768px)"
// Access keyframes
const keyframesRule = ast.stylesheet.rules.find(rule => rule.type === 'keyframes');
console.log(keyframesRule.name); // "fadeIn"
```
### Custom Formatting
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = '.example{color:red;font-size:16px}';
const ast = parse(css);
// Custom indentation
const formatted = stringify(ast, { indent: ' ' });
console.log(formatted);
// Output:
// .example {
// color: red;
// font-size: 16px;
// }
// Compressed with no spaces
const compressed = stringify(ast, { compress: true });
console.log(compressed);
// Output: .example{color:red;font-size:16px}
```
## TypeScript Integration
The library provides comprehensive TypeScript support with full type definitions for all AST nodes and functions:
```typescript
import { parse, stringify, type CssStylesheetAST } from '@adobe/css-tools';
const css: string = '.example { color: red; }';
const ast: CssStylesheetAST = parse(css);
const output: string = stringify(ast);
```
## Performance Considerations
- The parser is optimized for large CSS files
- AST nodes are lightweight and memory-efficient
- Stringification is fast and supports streaming for large outputs
- Consider using `compress: true` for production builds to reduce file size
## Browser Support
The library works in all modern browsers and Node.js environments. For older environments, you may need to use a bundler with appropriate polyfills.
+366
View File
@@ -0,0 +1,366 @@
# Abstract Syntax Tree (AST)
## Overview
The AST represents CSS as a tree structure where each node has a specific type and properties. All nodes share common properties and have type-specific properties.
## Common Properties
All AST nodes have these properties:
### `type`
The node type as a string. See [Node Types](#node-types) for all possible values.
### `position` (optional)
Position information for the node in the source code:
```typescript
{
start: { line: number; column: number };
end: { line: number; column: number };
source?: string;
}
```
### `parent` (optional)
Reference to the parent node in the AST.
## Node Types
### `stylesheet`
The root node representing an entire CSS document.
**Properties:**
- `stylesheet.source` (optional): Source file path
- `stylesheet.rules`: Array of top-level rules
- `stylesheet.parsingErrors` (optional): Array of parse errors when `silent` option is used
**Example:**
```json
{
"type": "stylesheet",
"stylesheet": {
"rules": [
// ... other nodes
]
}
}
```
### `rule`
A CSS rule with selectors and declarations.
**Properties:**
- `selectors`: Array of CSS selectors as strings
- `declarations`: Array of declarations and comments
**Example:**
```json
{
"type": "rule",
"selectors": ["body", "html"],
"declarations": [
{
"type": "declaration",
"property": "color",
"value": "red"
}
]
}
```
### `declaration`
A CSS property declaration.
**Properties:**
- `property`: The CSS property name
- `value`: The CSS property value as a string
**Example:**
```json
{
"type": "declaration",
"property": "background-color",
"value": "#ffffff"
}
```
### `comment`
A CSS comment.
**Properties:**
- `comment`: The comment text (without `/*` and `*/`)
**Example:**
```json
{
"type": "comment",
"comment": " This is a comment "
}
```
### `media`
A `@media` rule.
**Properties:**
- `media`: The media query string
- `rules`: Array of rules within the media block
**Example:**
```json
{
"type": "media",
"media": "screen and (max-width: 768px)",
"rules": [
// ... nested rules
]
}
```
### `keyframes`
A `@keyframes` rule.
**Properties:**
- `name`: The keyframes name
- `vendor` (optional): Vendor prefix (e.g., "-webkit-")
- `keyframes`: Array of keyframe rules and comments
**Example:**
```json
{
"type": "keyframes",
"name": "fade",
"keyframes": [
{
"type": "keyframe",
"values": ["from"],
"declarations": [
{
"type": "declaration",
"property": "opacity",
"value": "0"
}
]
}
]
}
```
### `keyframe`
A keyframe within a `@keyframes` rule.
**Properties:**
- `values`: Array of keyframe selectors (e.g., `["from"]`, `["to"]`, `["50%"]`)
- `declarations`: Array of declarations and comments
### `import`
An `@import` rule.
**Properties:**
- `import`: The import string (URL or media query)
**Example:**
```json
{
"type": "import",
"import": "url('styles.css')"
}
```
### `charset`
A `@charset` rule.
**Properties:**
- `charset`: The character encoding
**Example:**
```json
{
"type": "charset",
"charset": "utf-8"
}
```
### `namespace`
A `@namespace` rule.
**Properties:**
- `namespace`: The namespace declaration
**Example:**
```json
{
"type": "namespace",
"namespace": "url(http://www.w3.org/1999/xhtml)"
}
```
### `supports`
A `@supports` rule.
**Properties:**
- `supports`: The supports condition
- `rules`: Array of rules within the supports block
**Example:**
```json
{
"type": "supports",
"supports": "(display: grid)",
"rules": [
// ... nested rules
]
}
```
### `document`
A `@document` rule.
**Properties:**
- `document`: The document condition
- `vendor` (optional): Vendor prefix
- `rules`: Array of rules within the document block
### `page`
A `@page` rule.
**Properties:**
- `selectors`: Array of page selectors
- `declarations`: Array of declarations and comments
### `font-face`
A `@font-face` rule.
**Properties:**
- `declarations`: Array of font declarations and comments
### `host`
A `:host` rule.
**Properties:**
- `rules`: Array of rules within the host block
### `container`
A `@container` rule.
**Properties:**
- `container`: The container query
- `rules`: Array of rules within the container block
### `layer`
A `@layer` rule.
**Properties:**
- `layer`: The layer name
- `rules` (optional): Array of rules within the layer block
### `custom-media`
A `@custom-media` rule.
**Properties:**
- `name`: The custom media query name
- `media`: The media query definition
### `starting-style`
A `@starting-style` rule.
**Properties:**
- `rules`: Array of rules within the starting-style block
## Type Hierarchy
The AST nodes are organized in the following hierarchy:
- `CssStylesheetAST` - Root node
- `CssAtRuleAST` - Union of all at-rule and rule nodes
- `CssAllNodesAST` - Union of all possible node types
## Working with the AST
### Traversing Nodes
```typescript
import { parse, CssStylesheetAST } from '@adobe/css-tools';
const ast: CssStylesheetAST = parse('body { color: red; }');
// Access top-level rules
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'rule') {
console.log('Selectors:', rule.selectors);
rule.declarations.forEach(decl => {
if (decl.type === 'declaration') {
console.log(`${decl.property}: ${decl.value}`);
}
});
}
});
```
### Modifying Nodes
```typescript
// Add a new declaration
const newDecl = {
type: 'declaration' as const,
property: 'font-size',
value: '16px'
};
// Find a rule and add the declaration
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'rule' && rule.selectors.includes('body')) {
rule.declarations.push(newDecl);
}
});
```
### Error Handling
When parsing with the `silent` option, errors are collected in the AST:
```typescript
const ast = parse('invalid css {', { silent: true });
if (ast.stylesheet.parsingErrors) {
ast.stylesheet.parsingErrors.forEach(error => {
console.error('Parse error:', error.message);
});
}
```
## Position Information
Position information is available on most nodes and includes:
- `start.line` and `start.column`: Beginning of the node
- `end.line` and `end.column`: End of the node
- `source`: Source file path (if provided during parsing)
This is useful for:
- Error reporting
- Source mapping
- Code analysis tools
- IDE integration
+191
View File
@@ -0,0 +1,191 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [4.4.4] - 2025-07-22
### Changed
- Switch from yarn to npm for package management
- Switch from eslint to biome for code formatting and linting
- Reformat codebase to comply with biome recommendations
- Switch from webpack to rollup for bundling
### Fixed
- Fix module exports to ensure proper compatibility with bundlers
- Add validation check to prevent future export issues
## [4.4.3] - 2025-05-15
### Security
- Fix polynomial regular expression vulnerability on uncontrolled data
- Refactor code to enable GitHub security static analysis
### Performance
- Improve parsing performance with minor optimizations
- Replace regex patterns with string search (indexOf-based) for better performance
### Added
- Add new utility functions with comprehensive unit tests
- Add improved formatting for CSS Grid template areas (#283 by @jogibear9988)
### Fixed
- Fix TypeScript error with ConstructorParameters in Parcel bundler (#444)
## [4.4.2] - 2025-02-12
### Fixed
- Fix regular expression for parsing quoted values in parentheses
## [4.4.0] - 2024-06-05
### Added
- Add support for CSS `@starting-style` at-rule (#319)
## [4.3.3] - 2024-01-24
### Changed
- Update package export configuration (#271)
## [4.3.2] - 2023-11-28
### Security
- Fix ReDoS vulnerability with crafted CSS strings - CVE-2023-48631
### Fixed
- Fix parsing issues with `:is()` and nested `:nth-child()` selectors (#211)
## [4.3.1] - 2023-03-14
### Security
- Fix ReDoS vulnerability with crafted CSS strings - CVE-2023-26364
## [4.3.0] - 2023-03-07
### Changed
- Update build toolchain and dependencies
- Update package exports configuration and file structure
## [4.2.0] - 2023-02-21
### Added
- Add support for CSS `@container` at-rule
- Add support for CSS `@layer` at-rule
## [4.1.0] - 2023-01-25
### Added
- Add support for ES Modules (ESM)
## [4.0.2] - 2023-01-12
### Fixed
- Fix `@import` parsing when URL contains semicolons (#71)
- Fix regression in selector parsing for attribute selectors (#77)
## [4.0.1] - 2022-08-03
### Fixed
- Fix `globalThis` configuration for webpack to enable UMD module usage in Node.js environments
## [4.0.0] - 2022-06-09
### Changed
- Fork from original css library to Adobe's `@adobe/css-tools` package
- Convert codebase from JavaScript to TypeScript
- Improve parsing performance by approximately 25%
- Update all dependencies to latest versions
- Remove source map support
---
## Legacy Versions (Pre-Adobe Fork)
## [3.0.0] - 2020-07-01
### Changed
- Bump major version due to major dependency updates and Node.js version requirement changes
## [2.2.1] - 2015-06-17
### Fixed
- Fix parsing of escaped quotes in quoted strings
## [2.2.0] - 2015-02-18
### Added
- Add `parsingErrors` property to list errors when parsing with `silent: true`
- Accept EOL characters and all whitespace characters in at-rules such as `@media`
## [2.1.0] - 2014-08-05
### Added
- Add `inputSourcemaps` option to disable input source map processing
- Add `sourcemap: 'generator'` option to return the `SourceMapGenerator` object
- Use `inherits` package for inheritance (fixes browser compatibility issues)
### Changed
- Change error message format and add `.reason` property to error objects
## [2.0.0] - 2014-06-18
### Added
- Add non-enumerable parent reference to each AST node
- Add support for `@custom-media`, `@host`, and `@font-face` at-rules
- Allow commas inside selector functions
- Allow empty property values
- Add `node.position.content` property
- Integrate css-parse and css-stringify libraries
- Apply original source maps from source files
### Changed
- Change default `options.position` value to `true`
- Remove comments from properties and values
### Removed
- Drop Component(1) support
### Fixed
- Fix assertion errors when selectors are missing
## [1.6.1] - 2014-01-02
### Fixed
- Fix component.json configuration
## [1.6.0] - 2013-12-21
### Changed
- Update dependencies
## [1.5.0] - 2013-12-03
### Changed
- Update dependencies
## [1.1.0] - 2013-04-04
### Changed
- Update dependencies
## [1.0.7] - 2012-11-21
### Fixed
- Fix component.json configuration
## [1.0.4] - 2012-11-15
### Changed
- Update css-stringify dependency
## [1.0.3] - 2012-09-01
### Added
- Add Component support
## [0.0.1] - 2010-01-03
### Added
- Initial release
+450
View File
@@ -0,0 +1,450 @@
# Usage Examples
## Basic Usage
### Parsing CSS
```javascript
import { parse } from '@adobe/css-tools';
// Basic CSS parsing
const css = `
body {
font-size: 12px;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
`;
const ast = parse(css);
console.log(ast);
```
### Stringifying AST
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = 'body { font-size: 12px; color: #333; }';
const ast = parse(css);
// Convert back to CSS
const output = stringify(ast);
console.log(output); // "body { font-size: 12px; color: #333; }"
```
## Advanced Parsing Options
### Source Tracking
```javascript
import { parse } from '@adobe/css-tools';
const css = 'body { color: red; }';
const ast = parse(css, { source: 'styles.css' });
// Position information is available
const rule = ast.stylesheet.rules[0];
console.log(rule.position?.source); // "styles.css"
console.log(rule.position?.start); // { line: 1, column: 1 }
console.log(rule.position?.end); // { line: 1, column: 20 }
```
### Silent Error Handling
```javascript
import { parse } from '@adobe/css-tools';
const malformedCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
`;
// Parse with silent error handling
const result = parse(malformedCss, { silent: true });
// Check for parsing errors
if (result.stylesheet.parsingErrors) {
console.log('Parsing errors:', result.stylesheet.parsingErrors.length);
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error at line ${error.line}: ${error.message}`);
});
}
// Valid rules are still parsed
console.log('Valid rules:', result.stylesheet.rules.length);
```
## AST Structure Examples
### Basic Rule
```javascript
import { parse } from '@adobe/css-tools';
const css = `
.header {
background: #f0f0f0;
padding: 20px;
border-bottom: 1px solid #ccc;
}
`;
const ast = parse(css);
const rule = ast.stylesheet.rules[0];
console.log(rule.type); // "rule"
console.log(rule.selectors); // [".header"]
console.log(rule.declarations.length); // 3
rule.declarations.forEach(decl => {
console.log(`${decl.property}: ${decl.value}`);
});
// Output:
// background: #f0f0f0
// padding: 20px
// border-bottom: 1px solid #ccc
```
### Media Queries
```javascript
import { parse } from '@adobe/css-tools';
const css = `
@media screen and (max-width: 768px) {
.container {
padding: 10px;
}
.sidebar {
display: none;
}
}
`;
const ast = parse(css);
const mediaRule = ast.stylesheet.rules[0];
console.log(mediaRule.type); // "media"
console.log(mediaRule.media); // "screen and (max-width: 768px)"
console.log(mediaRule.rules.length); // 2
```
### Keyframes
```javascript
import { parse } from '@adobe/css-tools';
const css = `
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
`;
const ast = parse(css);
const keyframesRule = ast.stylesheet.rules[0];
console.log(keyframesRule.type); // "keyframes"
console.log(keyframesRule.name); // "fadeIn"
console.log(keyframesRule.keyframes.length); // 2
keyframesRule.keyframes.forEach(keyframe => {
console.log(`Keyframe: ${keyframe.values.join(', ')}`);
keyframe.declarations.forEach(decl => {
console.log(` ${decl.property}: ${decl.value}`);
});
});
```
### Comments
```javascript
import { parse } from '@adobe/css-tools';
const css = `
/* Header styles */
.header {
background: red; /* Fallback color */
}
/* Footer styles */
.footer {
background: blue;
}
`;
const ast = parse(css);
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'comment') {
console.log(`Comment: ${rule.comment}`);
} else if (rule.type === 'rule') {
console.log(`Rule: ${rule.selectors.join(', ')}`);
rule.declarations.forEach(decl => {
if (decl.type === 'comment') {
console.log(` Comment: ${decl.comment}`);
} else {
console.log(` ${decl.property}: ${decl.value}`);
}
});
}
});
```
## Stringifying Options
### Compressed Output
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = `
body {
font-size: 12px;
color: #333;
margin: 0;
padding: 0;
}
`;
const ast = parse(css);
// Compressed output
const compressed = stringify(ast, { compress: true });
console.log(compressed);
// Output: "body{font-size:12px;color:#333;margin:0;padding:0}"
```
### Custom Indentation
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = 'body { font-size: 12px; color: #333; }';
const ast = parse(css);
// Custom indentation
const formatted = stringify(ast, { indent: ' ' });
console.log(formatted);
// Output:
// body {
// font-size: 12px;
// color: #333;
// }
```
## Working with Complex CSS
### Nested Rules and At-Rules
```javascript
import { parse, stringify } from '@adobe/css-tools';
const complexCss = `
@import url('https://fonts.googleapis.com/css2?family=Roboto');
@charset "UTF-8";
@media print {
body {
font-size: 12pt;
}
}
@supports (display: grid) {
.grid {
display: grid;
}
}
@keyframes slideIn {
0% { transform: translateX(-100%); }
100% { transform: translateX(0); }
}
@font-face {
font-family: 'CustomFont';
src: url('custom-font.woff2') format('woff2');
}
`;
const ast = parse(complexCss);
ast.stylesheet.rules.forEach(rule => {
switch (rule.type) {
case 'import':
console.log(`Import: ${rule.import}`);
break;
case 'charset':
console.log(`Charset: ${rule.charset}`);
break;
case 'media':
console.log(`Media query: ${rule.media}`);
break;
case 'supports':
console.log(`Supports: ${rule.supports}`);
break;
case 'keyframes':
console.log(`Keyframes: ${rule.name}`);
break;
case 'font-face':
console.log('Font-face rule');
break;
}
});
```
### Manipulating the AST
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = `
.button {
background: blue;
color: white;
padding: 10px;
}
`;
const ast = parse(css);
const rule = ast.stylesheet.rules[0];
// Add a new declaration
rule.declarations.push({
type: 'declaration',
property: 'border-radius',
value: '5px'
});
// Modify existing declaration
const backgroundDecl = rule.declarations.find(d => d.property === 'background');
if (backgroundDecl) {
backgroundDecl.value = 'red';
}
// Add a new selector
rule.selectors.push('.btn');
const modifiedCss = stringify(ast);
console.log(modifiedCss);
```
## Error Handling
### Catching Parse Errors
```javascript
import { parse, CssParseError } from '@adobe/css-tools';
try {
const ast = parse('body { color: red; } { invalid }');
} catch (error) {
if (error instanceof CssParseError) {
console.log(`Parse error at line ${error.line}, column ${error.column}:`);
console.log(error.message);
console.log(`Source: ${error.filename}`);
}
}
```
### Working with Silent Errors
```javascript
import { parse } from '@adobe/css-tools';
const problematicCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
.another { border: 1px solid; } /* Missing closing brace */
`;
const result = parse(problematicCss, {
silent: true,
source: 'problematic.css'
});
// Process valid rules
const validRules = result.stylesheet.rules.filter(rule => rule.type === 'rule');
console.log(`Found ${validRules.length} valid rules`);
// Log errors for debugging
if (result.stylesheet.parsingErrors) {
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error: ${error.message} at line ${error.line}`);
});
}
```
### CSS Minification
```javascript
import { parse, stringify } from '@adobe/css-tools';
function minifyCSS(css) {
const ast = parse(css);
return stringify(ast, { compress: true });
}
const css = `
body {
font-size: 12px;
color: #333;
margin: 0;
padding: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
`;
const minified = minifyCSS(css);
console.log(minified);
// Output: "body{font-size:12px;color:#333;margin:0;padding:0}.container{max-width:1200px;margin:0 auto}"
```
### CSS Validation
```javascript
import { parse } from '@adobe/css-tools';
function validateCSS(css, filename = 'unknown') {
try {
const ast = parse(css, { source: filename });
return {
valid: true,
rules: ast.stylesheet.rules.length,
errors: []
};
} catch (error) {
return {
valid: false,
rules: 0,
errors: [{
message: error.message,
line: error.line,
column: error.column,
source: error.filename
}]
};
}
}
const result = validateCSS('body { color: red; } { invalid }', 'test.css');
console.log(result);
```
+82
View File
@@ -0,0 +1,82 @@
{
"name": "@adobe/css-tools",
"version": "4.4.4",
"description": "A modern CSS parser and stringifier with TypeScript support",
"source": "src/index.ts",
"main": "./dist/cjs/adobe-css-tools.cjs",
"module": "./dist/esm/adobe-css-tools.mjs",
"browser": "./dist/umd/adobe-css-tools.js",
"sideEffects": false,
"exports": {
".": {
"import": "./dist/esm/adobe-css-tools.mjs",
"require": "./dist/cjs/adobe-css-tools.cjs"
},
"./package.json": "./package.json"
},
"types": "./dist/esm/adobe-css-tools.d.mts",
"type": "module",
"files": [
"dist/cjs",
"dist/esm",
"dist/umd",
"README.md",
"docs/"
],
"devDependencies": {
"@arethetypeswrong/cli": "^0.18.2",
"@biomejs/biome": "^2.1.2",
"@rollup/plugin-commonjs": "^28.0.6",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.4",
"@types/benchmark": "^2.1.1",
"@types/bytes": "^3.1.5",
"@types/jest": "^29.5.14",
"@types/node": "^24.0.3",
"benchmark": "^2.1.4",
"bytes": "^3.1.0",
"jest": "^29.7.0",
"rollup": "^4.45.1",
"rollup-plugin-dts": "^6.2.1",
"ts-jest": "^29.1.1",
"tslib": "^2.8.1",
"typescript": "^5.7.3"
},
"scripts": {
"benchmark": "npm run build && node benchmark/index.mjs",
"test": "jest",
"clean": "rm -rf ./dist",
"build": "rollup -c",
"fix": "biome check --write",
"check-package-bundle": "attw --pack .",
"lint": "biome check",
"prebuild": "npm run clean",
"prepack": "rollup -c",
"posttest": "npm run lint",
"postbuild": "tar -czf dist/archive.tgz LICENSE README.md dist/cjs dist/esm dist/umd docs package.json && npx attw --format ascii dist/archive.tgz && rm dist/archive.tgz"
},
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Jean-Philippe Zolesio <holblin@gmail.com>"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/adobe/css-tools.git"
},
"keywords": [
"css",
"parser",
"stringifier",
"stylesheet",
"ast",
"typescript",
"css-parser",
"css-ast",
"css-tools",
"minify",
"format",
"preprocessor"
]
}
+22
View File
@@ -0,0 +1,22 @@
MIT LICENSE
Copyright (c) 2018-present Ant UED, https://xtech.antfin.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+119
View File
@@ -0,0 +1,119 @@
<h1 align="center">Ant Design Colors</h1>
<div align="center">
:art: Color palettes calculator of [Ant Design](https://ant.design/docs/spec/colors).
[![CI status][github-action-image]][github-action-url]
[![codecov][codecov-image]][codecov-url]
[![NPM version][npm-image]][npm-url]
[![NPM downloads][download-image]][download-url]
[![][bundlephobia-image]][bundlephobia-url]
![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)
[npm-image]: http://img.shields.io/npm/v/@ant-design/colors.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@ant-design/colors
[github-action-image]: https://github.com/ant-design/ant-design-colors/actions/workflows/ci.yml/badge.svg
[github-action-url]: https://github.com/ant-design/ant-design-colors/actions/workflows/ci.yml
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design-colors/main.svg?style=flat-square
[codecov-url]: https://codecov.io/gh/ant-design/ant-design-colors/tree/main
[download-image]: https://img.shields.io/npm/dm/@ant-design/colors.svg?style=flat-square
[download-url]: https://npmjs.org/package/@ant-design/colors
[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/@ant-design/colors?style=flat-square
[bundlephobia-url]: https://bundlephobia.com/package/@ant-design/colors
</div>
![](https://user-images.githubusercontent.com/507615/55726820-43e68400-5a43-11e9-8541-b0fc28b78f37.png)
## Install
```bash
$ npm install @ant-design/colors
// or
$ yarn add @ant-design/colors
```
## Usage
```bash
$ npm install @ant-design/colors --save
```
```js
import {
red,
volcano,
gold,
yellow,
lime,
green,
cyan,
blue,
geekblue,
purple,
magenta,
grey,
} from '@ant-design/colors';
console.log(blue); // ['#E6F4FF', '#BAE0FF', '#91CAFF', '#69B1FF', '#4096FF', '#1677FF', '#0958D9', '#003EB3', '#002C8C', '#001D66']
console.log(blue.primary); // '#1677FF'
```
```js
import { generate, presetPalettes } from '@ant-design/colors';
// Generate color palettes by a given color
const colors = generate('#1890ff');
console.log(colors); // ['#E6F7FF', '#BAE7FF', '#91D5FF', ''#69C0FF', '#40A9FF', '#1890FF', '#096DD9', '#0050B3', '#003A8C', '#002766']
console.log(presetPalettes);
/*
{
red: [...],
volcano: [...],
orange: [...],
gold: [...],
yellow: [...],
lime: [...],
green: [...],
cyan: [...],
blue: [...],
geekblue: [...],
purple: [...],
magenta: [...],
}
*/
```
```js
import { generate, presetDarkPalettes } from '@ant-design/colors';
// Generate dark color palettes by a given color
const colors = generate('#1890ff', {
theme: 'dark',
backgroundColor: '#141414',
});
console.log(colors); // ['#111d2c', '#112a45', '#15395b', '#164c7e', '#1765ad', '#177ddc', '#3c9ae8', '#65b7f3', '#8dcff8', '#b7e3fa']
console.log(presetDarkPalettes);
/*
{
red: [...],
volcano: [...],
orange: [...],
gold: [...],
yellow: [...],
lime: [...],
green: [...],
cyan: [...],
blue: [...],
geekblue: [...],
purple: [...],
magenta: [...],
}
*/
```
## Articles
- [Ant Design Colors](https://ant.design/docs/spec/colors)
- [Ant Design 色板生成算法演进之路](https://zhuanlan.zhihu.com/p/32422584)
+8
View File
@@ -0,0 +1,8 @@
import type { ColorInput } from '@ant-design/fast-color';
interface Opts {
theme?: 'dark' | 'default';
backgroundColor?: string;
}
export default function generate(color: ColorInput, opts?: Opts): string[];
export {};
//# sourceMappingURL=generate.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAsFzD,UAAU,IAAI;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,IAAS,GAAG,MAAM,EAAE,CA8B7E"}
+128
View File
@@ -0,0 +1,128 @@
import { FastColor } from '@ant-design/fast-color';
var hueStep = 2; // 色相阶梯
var saturationStep = 0.16; // 饱和度阶梯,浅色部分
var saturationStep2 = 0.05; // 饱和度阶梯,深色部分
var brightnessStep1 = 0.05; // 亮度阶梯,浅色部分
var brightnessStep2 = 0.15; // 亮度阶梯,深色部分
var lightColorCount = 5; // 浅色数量,主色上
var darkColorCount = 4; // 深色数量,主色下
// 暗色主题颜色映射关系表
var darkColorMap = [{
index: 7,
amount: 15
}, {
index: 6,
amount: 25
}, {
index: 5,
amount: 30
}, {
index: 5,
amount: 45
}, {
index: 5,
amount: 65
}, {
index: 5,
amount: 85
}, {
index: 4,
amount: 90
}, {
index: 3,
amount: 95
}, {
index: 2,
amount: 97
}, {
index: 1,
amount: 98
}];
function getHue(hsv, i, light) {
var hue;
// 根据色相不同,色相转向不同
if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) {
hue = light ? Math.round(hsv.h) - hueStep * i : Math.round(hsv.h) + hueStep * i;
} else {
hue = light ? Math.round(hsv.h) + hueStep * i : Math.round(hsv.h) - hueStep * i;
}
if (hue < 0) {
hue += 360;
} else if (hue >= 360) {
hue -= 360;
}
return hue;
}
function getSaturation(hsv, i, light) {
// grey color don't change saturation
if (hsv.h === 0 && hsv.s === 0) {
return hsv.s;
}
var saturation;
if (light) {
saturation = hsv.s - saturationStep * i;
} else if (i === darkColorCount) {
saturation = hsv.s + saturationStep;
} else {
saturation = hsv.s + saturationStep2 * i;
}
// 边界值修正
if (saturation > 1) {
saturation = 1;
}
// 第一格的 s 限制在 0.06-0.1 之间
if (light && i === lightColorCount && saturation > 0.1) {
saturation = 0.1;
}
if (saturation < 0.06) {
saturation = 0.06;
}
return Math.round(saturation * 100) / 100;
}
function getValue(hsv, i, light) {
var value;
if (light) {
value = hsv.v + brightnessStep1 * i;
} else {
value = hsv.v - brightnessStep2 * i;
}
// Clamp value between 0 and 1
value = Math.max(0, Math.min(1, value));
return Math.round(value * 100) / 100;
}
export default function generate(color) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var patterns = [];
var pColor = new FastColor(color);
var hsv = pColor.toHsv();
for (var i = lightColorCount; i > 0; i -= 1) {
var c = new FastColor({
h: getHue(hsv, i, true),
s: getSaturation(hsv, i, true),
v: getValue(hsv, i, true)
});
patterns.push(c);
}
patterns.push(pColor);
for (var _i = 1; _i <= darkColorCount; _i += 1) {
var _c = new FastColor({
h: getHue(hsv, _i),
s: getSaturation(hsv, _i),
v: getValue(hsv, _i)
});
patterns.push(_c);
}
// dark theme patterns
if (opts.theme === 'dark') {
return darkColorMap.map(function (_ref) {
var index = _ref.index,
amount = _ref.amount;
return new FastColor(opts.backgroundColor || '#141414').mix(patterns[index], amount).toHexString();
});
}
return patterns.map(function (c) {
return c.toHexString();
});
}
+4
View File
@@ -0,0 +1,4 @@
export { default as generate } from './generate';
export * from './presets';
export type * from './types';
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAC;AACjD,cAAc,WAAW,CAAA;AACzB,mBAAmB,SAAS,CAAA"}
+2
View File
@@ -0,0 +1,2 @@
export { default as generate } from "./generate";
export * from "./presets";
+32
View File
@@ -0,0 +1,32 @@
import type { Palette, PalettesProps } from './types';
export declare const presetPrimaryColors: Record<string, string>;
export declare const red: Palette;
export declare const volcano: Palette;
export declare const orange: Palette;
export declare const gold: Palette;
export declare const yellow: Palette;
export declare const lime: Palette;
export declare const green: Palette;
export declare const cyan: Palette;
export declare const blue: Palette;
export declare const geekblue: Palette;
export declare const purple: Palette;
export declare const magenta: Palette;
export declare const grey: Palette;
export declare const gray: Palette;
export declare const presetPalettes: PalettesProps;
export declare const redDark: Palette;
export declare const volcanoDark: Palette;
export declare const orangeDark: Palette;
export declare const goldDark: Palette;
export declare const yellowDark: Palette;
export declare const limeDark: Palette;
export declare const greenDark: Palette;
export declare const cyanDark: Palette;
export declare const blueDark: Palette;
export declare const geekblueDark: Palette;
export declare const purpleDark: Palette;
export declare const magentaDark: Palette;
export declare const greyDark: Palette;
export declare const presetDarkPalettes: PalettesProps;
//# sourceMappingURL=presets.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["presets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEtD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CActD,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,OAWjB,CAAC;AAGF,eAAO,MAAM,OAAO,EAAE,OAWrB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,OAWpB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,OAWpB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,OAWnB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,OAWpB,CAAC;AAGF,eAAO,MAAM,OAAO,EAAE,OAWrB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,IAAI,SAAO,CAAC;AAEzB,eAAO,MAAM,cAAc,EAAE,aAc5B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,OAWrB,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,OAWzB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,OAWxB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,OAWxB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,SAAS,EAAE,OAWvB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,YAAY,EAAE,OAW1B,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,OAWxB,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,OAWzB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,kBAAkB,EAAE,aAchC,CAAC"}
+100
View File
@@ -0,0 +1,100 @@
// Generated by script. Do NOT modify!
export var presetPrimaryColors = {
"red": "#F5222D",
"volcano": "#FA541C",
"orange": "#FA8C16",
"gold": "#FAAD14",
"yellow": "#FADB14",
"lime": "#A0D911",
"green": "#52C41A",
"cyan": "#13C2C2",
"blue": "#1677FF",
"geekblue": "#2F54EB",
"purple": "#722ED1",
"magenta": "#EB2F96",
"grey": "#666666"
};
export var red = ["#fff1f0", "#ffccc7", "#ffa39e", "#ff7875", "#ff4d4f", "#f5222d", "#cf1322", "#a8071a", "#820014", "#5c0011"];
red.primary = red[5];
export var volcano = ["#fff2e8", "#ffd8bf", "#ffbb96", "#ff9c6e", "#ff7a45", "#fa541c", "#d4380d", "#ad2102", "#871400", "#610b00"];
volcano.primary = volcano[5];
export var orange = ["#fff7e6", "#ffe7ba", "#ffd591", "#ffc069", "#ffa940", "#fa8c16", "#d46b08", "#ad4e00", "#873800", "#612500"];
orange.primary = orange[5];
export var gold = ["#fffbe6", "#fff1b8", "#ffe58f", "#ffd666", "#ffc53d", "#faad14", "#d48806", "#ad6800", "#874d00", "#613400"];
gold.primary = gold[5];
export var yellow = ["#feffe6", "#ffffb8", "#fffb8f", "#fff566", "#ffec3d", "#fadb14", "#d4b106", "#ad8b00", "#876800", "#614700"];
yellow.primary = yellow[5];
export var lime = ["#fcffe6", "#f4ffb8", "#eaff8f", "#d3f261", "#bae637", "#a0d911", "#7cb305", "#5b8c00", "#3f6600", "#254000"];
lime.primary = lime[5];
export var green = ["#f6ffed", "#d9f7be", "#b7eb8f", "#95de64", "#73d13d", "#52c41a", "#389e0d", "#237804", "#135200", "#092b00"];
green.primary = green[5];
export var cyan = ["#e6fffb", "#b5f5ec", "#87e8de", "#5cdbd3", "#36cfc9", "#13c2c2", "#08979c", "#006d75", "#00474f", "#002329"];
cyan.primary = cyan[5];
export var blue = ["#e6f4ff", "#bae0ff", "#91caff", "#69b1ff", "#4096ff", "#1677ff", "#0958d9", "#003eb3", "#002c8c", "#001d66"];
blue.primary = blue[5];
export var geekblue = ["#f0f5ff", "#d6e4ff", "#adc6ff", "#85a5ff", "#597ef7", "#2f54eb", "#1d39c4", "#10239e", "#061178", "#030852"];
geekblue.primary = geekblue[5];
export var purple = ["#f9f0ff", "#efdbff", "#d3adf7", "#b37feb", "#9254de", "#722ed1", "#531dab", "#391085", "#22075e", "#120338"];
purple.primary = purple[5];
export var magenta = ["#fff0f6", "#ffd6e7", "#ffadd2", "#ff85c0", "#f759ab", "#eb2f96", "#c41d7f", "#9e1068", "#780650", "#520339"];
magenta.primary = magenta[5];
export var grey = ["#a6a6a6", "#999999", "#8c8c8c", "#808080", "#737373", "#666666", "#404040", "#1a1a1a", "#000000", "#000000"];
grey.primary = grey[5];
export var gray = grey;
export var presetPalettes = {
red: red,
volcano: volcano,
orange: orange,
gold: gold,
yellow: yellow,
lime: lime,
green: green,
cyan: cyan,
blue: blue,
geekblue: geekblue,
purple: purple,
magenta: magenta,
grey: grey
};
export var redDark = ["#2a1215", "#431418", "#58181c", "#791a1f", "#a61d24", "#d32029", "#e84749", "#f37370", "#f89f9a", "#fac8c3"];
redDark.primary = redDark[5];
export var volcanoDark = ["#2b1611", "#441d12", "#592716", "#7c3118", "#aa3e19", "#d84a1b", "#e87040", "#f3956a", "#f8b692", "#fad4bc"];
volcanoDark.primary = volcanoDark[5];
export var orangeDark = ["#2b1d11", "#442a11", "#593815", "#7c4a15", "#aa6215", "#d87a16", "#e89a3c", "#f3b765", "#f8cf8d", "#fae3b7"];
orangeDark.primary = orangeDark[5];
export var goldDark = ["#2b2111", "#443111", "#594214", "#7c5914", "#aa7714", "#d89614", "#e8b339", "#f3cc62", "#f8df8b", "#faedb5"];
goldDark.primary = goldDark[5];
export var yellowDark = ["#2b2611", "#443b11", "#595014", "#7c6e14", "#aa9514", "#d8bd14", "#e8d639", "#f3ea62", "#f8f48b", "#fafab5"];
yellowDark.primary = yellowDark[5];
export var limeDark = ["#1f2611", "#2e3c10", "#3e4f13", "#536d13", "#6f9412", "#8bbb11", "#a9d134", "#c9e75d", "#e4f88b", "#f0fab5"];
limeDark.primary = limeDark[5];
export var greenDark = ["#162312", "#1d3712", "#274916", "#306317", "#3c8618", "#49aa19", "#6abe39", "#8fd460", "#b2e58b", "#d5f2bb"];
greenDark.primary = greenDark[5];
export var cyanDark = ["#112123", "#113536", "#144848", "#146262", "#138585", "#13a8a8", "#33bcb7", "#58d1c9", "#84e2d8", "#b2f1e8"];
cyanDark.primary = cyanDark[5];
export var blueDark = ["#111a2c", "#112545", "#15325b", "#15417e", "#1554ad", "#1668dc", "#3c89e8", "#65a9f3", "#8dc5f8", "#b7dcfa"];
blueDark.primary = blueDark[5];
export var geekblueDark = ["#131629", "#161d40", "#1c2755", "#203175", "#263ea0", "#2b4acb", "#5273e0", "#7f9ef3", "#a8c1f8", "#d2e0fa"];
geekblueDark.primary = geekblueDark[5];
export var purpleDark = ["#1a1325", "#24163a", "#301c4d", "#3e2069", "#51258f", "#642ab5", "#854eca", "#ab7ae0", "#cda8f0", "#ebd7fa"];
purpleDark.primary = purpleDark[5];
export var magentaDark = ["#291321", "#40162f", "#551c3b", "#75204f", "#a02669", "#cb2b83", "#e0529c", "#f37fb7", "#f8a8cc", "#fad2e3"];
magentaDark.primary = magentaDark[5];
export var greyDark = ["#151515", "#1f1f1f", "#2d2d2d", "#393939", "#494949", "#5a5a5a", "#6a6a6a", "#7b7b7b", "#888888", "#969696"];
greyDark.primary = greyDark[5];
export var presetDarkPalettes = {
red: redDark,
volcano: volcanoDark,
orange: orangeDark,
gold: goldDark,
yellow: yellowDark,
lime: limeDark,
green: greenDark,
cyan: cyanDark,
blue: blueDark,
geekblue: geekblueDark,
purple: purpleDark,
magenta: magentaDark,
grey: greyDark
};
+5
View File
@@ -0,0 +1,5 @@
export type Palette = string[] & {
primary?: string;
};
export type PalettesProps = Record<string, Palette>;
//# sourceMappingURL=types.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,MAAM,EAAE,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
+1
View File
@@ -0,0 +1 @@
export {};
+8
View File
@@ -0,0 +1,8 @@
import type { ColorInput } from '@ant-design/fast-color';
interface Opts {
theme?: 'dark' | 'default';
backgroundColor?: string;
}
export default function generate(color: ColorInput, opts?: Opts): string[];
export {};
//# sourceMappingURL=generate.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAsFzD,UAAU,IAAI;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,IAAS,GAAG,MAAM,EAAE,CA8B7E"}
+134
View File
@@ -0,0 +1,134 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = generate;
var _fastColor = require("@ant-design/fast-color");
var hueStep = 2; // 色相阶梯
var saturationStep = 0.16; // 饱和度阶梯,浅色部分
var saturationStep2 = 0.05; // 饱和度阶梯,深色部分
var brightnessStep1 = 0.05; // 亮度阶梯,浅色部分
var brightnessStep2 = 0.15; // 亮度阶梯,深色部分
var lightColorCount = 5; // 浅色数量,主色上
var darkColorCount = 4; // 深色数量,主色下
// 暗色主题颜色映射关系表
var darkColorMap = [{
index: 7,
amount: 15
}, {
index: 6,
amount: 25
}, {
index: 5,
amount: 30
}, {
index: 5,
amount: 45
}, {
index: 5,
amount: 65
}, {
index: 5,
amount: 85
}, {
index: 4,
amount: 90
}, {
index: 3,
amount: 95
}, {
index: 2,
amount: 97
}, {
index: 1,
amount: 98
}];
function getHue(hsv, i, light) {
var hue;
// 根据色相不同,色相转向不同
if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) {
hue = light ? Math.round(hsv.h) - hueStep * i : Math.round(hsv.h) + hueStep * i;
} else {
hue = light ? Math.round(hsv.h) + hueStep * i : Math.round(hsv.h) - hueStep * i;
}
if (hue < 0) {
hue += 360;
} else if (hue >= 360) {
hue -= 360;
}
return hue;
}
function getSaturation(hsv, i, light) {
// grey color don't change saturation
if (hsv.h === 0 && hsv.s === 0) {
return hsv.s;
}
var saturation;
if (light) {
saturation = hsv.s - saturationStep * i;
} else if (i === darkColorCount) {
saturation = hsv.s + saturationStep;
} else {
saturation = hsv.s + saturationStep2 * i;
}
// 边界值修正
if (saturation > 1) {
saturation = 1;
}
// 第一格的 s 限制在 0.06-0.1 之间
if (light && i === lightColorCount && saturation > 0.1) {
saturation = 0.1;
}
if (saturation < 0.06) {
saturation = 0.06;
}
return Math.round(saturation * 100) / 100;
}
function getValue(hsv, i, light) {
var value;
if (light) {
value = hsv.v + brightnessStep1 * i;
} else {
value = hsv.v - brightnessStep2 * i;
}
// Clamp value between 0 and 1
value = Math.max(0, Math.min(1, value));
return Math.round(value * 100) / 100;
}
function generate(color) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var patterns = [];
var pColor = new _fastColor.FastColor(color);
var hsv = pColor.toHsv();
for (var i = lightColorCount; i > 0; i -= 1) {
var c = new _fastColor.FastColor({
h: getHue(hsv, i, true),
s: getSaturation(hsv, i, true),
v: getValue(hsv, i, true)
});
patterns.push(c);
}
patterns.push(pColor);
for (var _i = 1; _i <= darkColorCount; _i += 1) {
var _c = new _fastColor.FastColor({
h: getHue(hsv, _i),
s: getSaturation(hsv, _i),
v: getValue(hsv, _i)
});
patterns.push(_c);
}
// dark theme patterns
if (opts.theme === 'dark') {
return darkColorMap.map(function (_ref) {
var index = _ref.index,
amount = _ref.amount;
return new _fastColor.FastColor(opts.backgroundColor || '#141414').mix(patterns[index], amount).toHexString();
});
}
return patterns.map(function (c) {
return c.toHexString();
});
}
+4
View File
@@ -0,0 +1,4 @@
export { default as generate } from './generate';
export * from './presets';
export type * from './types';
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAC;AACjD,cAAc,WAAW,CAAA;AACzB,mBAAmB,SAAS,CAAA"}
+28
View File
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _exportNames = {
generate: true
};
Object.defineProperty(exports, "generate", {
enumerable: true,
get: function get() {
return _generate.default;
}
});
var _generate = _interopRequireDefault(require("./generate"));
var _presets = require("./presets");
Object.keys(_presets).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
if (key in exports && exports[key] === _presets[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _presets[key];
}
});
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+32
View File
@@ -0,0 +1,32 @@
import type { Palette, PalettesProps } from './types';
export declare const presetPrimaryColors: Record<string, string>;
export declare const red: Palette;
export declare const volcano: Palette;
export declare const orange: Palette;
export declare const gold: Palette;
export declare const yellow: Palette;
export declare const lime: Palette;
export declare const green: Palette;
export declare const cyan: Palette;
export declare const blue: Palette;
export declare const geekblue: Palette;
export declare const purple: Palette;
export declare const magenta: Palette;
export declare const grey: Palette;
export declare const gray: Palette;
export declare const presetPalettes: PalettesProps;
export declare const redDark: Palette;
export declare const volcanoDark: Palette;
export declare const orangeDark: Palette;
export declare const goldDark: Palette;
export declare const yellowDark: Palette;
export declare const limeDark: Palette;
export declare const greenDark: Palette;
export declare const cyanDark: Palette;
export declare const blueDark: Palette;
export declare const geekblueDark: Palette;
export declare const purpleDark: Palette;
export declare const magentaDark: Palette;
export declare const greyDark: Palette;
export declare const presetDarkPalettes: PalettesProps;
//# sourceMappingURL=presets.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["presets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEtD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CActD,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,OAWjB,CAAC;AAGF,eAAO,MAAM,OAAO,EAAE,OAWrB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,OAWpB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,OAWpB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,OAWnB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,OAWpB,CAAC;AAGF,eAAO,MAAM,OAAO,EAAE,OAWrB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,OAWlB,CAAC;AAGF,eAAO,MAAM,IAAI,SAAO,CAAC;AAEzB,eAAO,MAAM,cAAc,EAAE,aAc5B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,OAWrB,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,OAWzB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,OAWxB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,OAWxB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,SAAS,EAAE,OAWvB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,YAAY,EAAE,OAW1B,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,OAWxB,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,OAWzB,CAAC;AAGF,eAAO,MAAM,QAAQ,EAAE,OAWtB,CAAC;AAGF,eAAO,MAAM,kBAAkB,EAAE,aAchC,CAAC"}
+106
View File
@@ -0,0 +1,106 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.yellowDark = exports.yellow = exports.volcanoDark = exports.volcano = exports.redDark = exports.red = exports.purpleDark = exports.purple = exports.presetPrimaryColors = exports.presetPalettes = exports.presetDarkPalettes = exports.orangeDark = exports.orange = exports.magentaDark = exports.magenta = exports.limeDark = exports.lime = exports.greyDark = exports.grey = exports.greenDark = exports.green = exports.gray = exports.goldDark = exports.gold = exports.geekblueDark = exports.geekblue = exports.cyanDark = exports.cyan = exports.blueDark = exports.blue = void 0;
// Generated by script. Do NOT modify!
var presetPrimaryColors = exports.presetPrimaryColors = {
"red": "#F5222D",
"volcano": "#FA541C",
"orange": "#FA8C16",
"gold": "#FAAD14",
"yellow": "#FADB14",
"lime": "#A0D911",
"green": "#52C41A",
"cyan": "#13C2C2",
"blue": "#1677FF",
"geekblue": "#2F54EB",
"purple": "#722ED1",
"magenta": "#EB2F96",
"grey": "#666666"
};
var red = exports.red = ["#fff1f0", "#ffccc7", "#ffa39e", "#ff7875", "#ff4d4f", "#f5222d", "#cf1322", "#a8071a", "#820014", "#5c0011"];
red.primary = red[5];
var volcano = exports.volcano = ["#fff2e8", "#ffd8bf", "#ffbb96", "#ff9c6e", "#ff7a45", "#fa541c", "#d4380d", "#ad2102", "#871400", "#610b00"];
volcano.primary = volcano[5];
var orange = exports.orange = ["#fff7e6", "#ffe7ba", "#ffd591", "#ffc069", "#ffa940", "#fa8c16", "#d46b08", "#ad4e00", "#873800", "#612500"];
orange.primary = orange[5];
var gold = exports.gold = ["#fffbe6", "#fff1b8", "#ffe58f", "#ffd666", "#ffc53d", "#faad14", "#d48806", "#ad6800", "#874d00", "#613400"];
gold.primary = gold[5];
var yellow = exports.yellow = ["#feffe6", "#ffffb8", "#fffb8f", "#fff566", "#ffec3d", "#fadb14", "#d4b106", "#ad8b00", "#876800", "#614700"];
yellow.primary = yellow[5];
var lime = exports.lime = ["#fcffe6", "#f4ffb8", "#eaff8f", "#d3f261", "#bae637", "#a0d911", "#7cb305", "#5b8c00", "#3f6600", "#254000"];
lime.primary = lime[5];
var green = exports.green = ["#f6ffed", "#d9f7be", "#b7eb8f", "#95de64", "#73d13d", "#52c41a", "#389e0d", "#237804", "#135200", "#092b00"];
green.primary = green[5];
var cyan = exports.cyan = ["#e6fffb", "#b5f5ec", "#87e8de", "#5cdbd3", "#36cfc9", "#13c2c2", "#08979c", "#006d75", "#00474f", "#002329"];
cyan.primary = cyan[5];
var blue = exports.blue = ["#e6f4ff", "#bae0ff", "#91caff", "#69b1ff", "#4096ff", "#1677ff", "#0958d9", "#003eb3", "#002c8c", "#001d66"];
blue.primary = blue[5];
var geekblue = exports.geekblue = ["#f0f5ff", "#d6e4ff", "#adc6ff", "#85a5ff", "#597ef7", "#2f54eb", "#1d39c4", "#10239e", "#061178", "#030852"];
geekblue.primary = geekblue[5];
var purple = exports.purple = ["#f9f0ff", "#efdbff", "#d3adf7", "#b37feb", "#9254de", "#722ed1", "#531dab", "#391085", "#22075e", "#120338"];
purple.primary = purple[5];
var magenta = exports.magenta = ["#fff0f6", "#ffd6e7", "#ffadd2", "#ff85c0", "#f759ab", "#eb2f96", "#c41d7f", "#9e1068", "#780650", "#520339"];
magenta.primary = magenta[5];
var grey = exports.grey = ["#a6a6a6", "#999999", "#8c8c8c", "#808080", "#737373", "#666666", "#404040", "#1a1a1a", "#000000", "#000000"];
grey.primary = grey[5];
var gray = exports.gray = grey;
var presetPalettes = exports.presetPalettes = {
red: red,
volcano: volcano,
orange: orange,
gold: gold,
yellow: yellow,
lime: lime,
green: green,
cyan: cyan,
blue: blue,
geekblue: geekblue,
purple: purple,
magenta: magenta,
grey: grey
};
var redDark = exports.redDark = ["#2a1215", "#431418", "#58181c", "#791a1f", "#a61d24", "#d32029", "#e84749", "#f37370", "#f89f9a", "#fac8c3"];
redDark.primary = redDark[5];
var volcanoDark = exports.volcanoDark = ["#2b1611", "#441d12", "#592716", "#7c3118", "#aa3e19", "#d84a1b", "#e87040", "#f3956a", "#f8b692", "#fad4bc"];
volcanoDark.primary = volcanoDark[5];
var orangeDark = exports.orangeDark = ["#2b1d11", "#442a11", "#593815", "#7c4a15", "#aa6215", "#d87a16", "#e89a3c", "#f3b765", "#f8cf8d", "#fae3b7"];
orangeDark.primary = orangeDark[5];
var goldDark = exports.goldDark = ["#2b2111", "#443111", "#594214", "#7c5914", "#aa7714", "#d89614", "#e8b339", "#f3cc62", "#f8df8b", "#faedb5"];
goldDark.primary = goldDark[5];
var yellowDark = exports.yellowDark = ["#2b2611", "#443b11", "#595014", "#7c6e14", "#aa9514", "#d8bd14", "#e8d639", "#f3ea62", "#f8f48b", "#fafab5"];
yellowDark.primary = yellowDark[5];
var limeDark = exports.limeDark = ["#1f2611", "#2e3c10", "#3e4f13", "#536d13", "#6f9412", "#8bbb11", "#a9d134", "#c9e75d", "#e4f88b", "#f0fab5"];
limeDark.primary = limeDark[5];
var greenDark = exports.greenDark = ["#162312", "#1d3712", "#274916", "#306317", "#3c8618", "#49aa19", "#6abe39", "#8fd460", "#b2e58b", "#d5f2bb"];
greenDark.primary = greenDark[5];
var cyanDark = exports.cyanDark = ["#112123", "#113536", "#144848", "#146262", "#138585", "#13a8a8", "#33bcb7", "#58d1c9", "#84e2d8", "#b2f1e8"];
cyanDark.primary = cyanDark[5];
var blueDark = exports.blueDark = ["#111a2c", "#112545", "#15325b", "#15417e", "#1554ad", "#1668dc", "#3c89e8", "#65a9f3", "#8dc5f8", "#b7dcfa"];
blueDark.primary = blueDark[5];
var geekblueDark = exports.geekblueDark = ["#131629", "#161d40", "#1c2755", "#203175", "#263ea0", "#2b4acb", "#5273e0", "#7f9ef3", "#a8c1f8", "#d2e0fa"];
geekblueDark.primary = geekblueDark[5];
var purpleDark = exports.purpleDark = ["#1a1325", "#24163a", "#301c4d", "#3e2069", "#51258f", "#642ab5", "#854eca", "#ab7ae0", "#cda8f0", "#ebd7fa"];
purpleDark.primary = purpleDark[5];
var magentaDark = exports.magentaDark = ["#291321", "#40162f", "#551c3b", "#75204f", "#a02669", "#cb2b83", "#e0529c", "#f37fb7", "#f8a8cc", "#fad2e3"];
magentaDark.primary = magentaDark[5];
var greyDark = exports.greyDark = ["#151515", "#1f1f1f", "#2d2d2d", "#393939", "#494949", "#5a5a5a", "#6a6a6a", "#7b7b7b", "#888888", "#969696"];
greyDark.primary = greyDark[5];
var presetDarkPalettes = exports.presetDarkPalettes = {
red: redDark,
volcano: volcanoDark,
orange: orangeDark,
gold: goldDark,
yellow: yellowDark,
lime: limeDark,
green: greenDark,
cyan: cyanDark,
blue: blueDark,
geekblue: geekblueDark,
purple: purpleDark,
magenta: magentaDark,
grey: greyDark
};
+5
View File
@@ -0,0 +1,5 @@
export type Palette = string[] & {
primary?: string;
};
export type PalettesProps = Record<string, Palette>;
//# sourceMappingURL=types.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,MAAM,EAAE,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
+5
View File
@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
+50
View File
@@ -0,0 +1,50 @@
{
"name": "@ant-design/colors",
"version": "7.2.1",
"description": "Color palettes calculator of Ant Design",
"homepage": "https://github.com/ant-design/ant-design-colors#readme",
"bugs": {
"url": "https://github.com/ant-design/ant-design-colors/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ant-design/ant-design-colors.git"
},
"license": "MIT",
"author": "afc163 <afc163@gmail.com>",
"main": "./lib/index",
"module": "./es/index",
"typings": "es/index.d.ts",
"files": [
"lib",
"es"
],
"scripts": {
"bench": "vitest bench",
"coverage": "npm test -- --coverage",
"compile": "father build",
"lint": "eslint src --ext .ts",
"prepare": "tsx generate-presets",
"prepublishOnly": "npm run compile && np --no-cleanup --no-publish --branch=antd-5.x",
"prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"",
"test": "jest"
},
"dependencies": {
"@ant-design/fast-color": "^2.0.6"
},
"devDependencies": {
"@ctrl/tinycolor": "^3.6.1",
"@types/jest": "^26.0.24",
"@types/node": "^20.14.9",
"@umijs/fabric": "^3.0.0",
"eslint": "^7.32.0",
"father": "^4.4.4",
"jest": "^26.6.3",
"np": "^7.7.0",
"prettier": "^2.8.8",
"ts-jest": "^26.5.6",
"tsx": "^4.16.1",
"typescript": "~5.8.2",
"vitest": "^1.6.0"
}
}
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2015-present Alipay.com, https://www.alipay.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+30
View File
@@ -0,0 +1,30 @@
# @ant-design/cssinjs-utils
A cssinjs util library to support Ant Design (antd) and its ecosystem libraries.
## Install
``` bash
npm i @ant-design/cssinjs-utils --save
```
## Usage
## Example
http://localhost:8000
## Development
``` bash
npm install
npm start
```
## API
## Test Case
```
npm test
npm run coverage
```
open coverage/ dir
## License
cssinjs-util is released under the MIT license.
@@ -0,0 +1,6 @@
import React from 'react';
/**
* Like `useMemo`, but this hook result will be shared across all instances.
*/
declare function useUniqueMemo<T>(memoFn: () => T, deps: React.DependencyList): T;
export default useUniqueMemo;
@@ -0,0 +1,100 @@
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import React from 'react';
var BEAT_LIMIT = 1000 * 60 * 10;
/**
* A helper class to map keys to values.
* It supports both primitive keys and object keys.
*/
var ArrayKeyMap = /*#__PURE__*/function () {
function ArrayKeyMap() {
_classCallCheck(this, ArrayKeyMap);
_defineProperty(this, "map", new Map());
// Use WeakMap to avoid memory leak
_defineProperty(this, "objectIDMap", new WeakMap());
_defineProperty(this, "nextID", 0);
_defineProperty(this, "lastAccessBeat", new Map());
// We will clean up the cache when reach the limit
_defineProperty(this, "accessBeat", 0);
}
_createClass(ArrayKeyMap, [{
key: "set",
value: function set(keys, value) {
// New set will trigger clear
this.clear();
// Set logic
var compositeKey = this.getCompositeKey(keys);
this.map.set(compositeKey, value);
this.lastAccessBeat.set(compositeKey, Date.now());
}
}, {
key: "get",
value: function get(keys) {
var compositeKey = this.getCompositeKey(keys);
var cache = this.map.get(compositeKey);
this.lastAccessBeat.set(compositeKey, Date.now());
this.accessBeat += 1;
return cache;
}
}, {
key: "getCompositeKey",
value: function getCompositeKey(keys) {
var _this = this;
var ids = keys.map(function (key) {
if (key && _typeof(key) === 'object') {
return "obj_".concat(_this.getObjectID(key));
}
return "".concat(_typeof(key), "_").concat(key);
});
return ids.join('|');
}
}, {
key: "getObjectID",
value: function getObjectID(obj) {
if (this.objectIDMap.has(obj)) {
return this.objectIDMap.get(obj);
}
var id = this.nextID;
this.objectIDMap.set(obj, id);
this.nextID += 1;
return id;
}
}, {
key: "clear",
value: function clear() {
var _this2 = this;
if (this.accessBeat > 10000) {
var now = Date.now();
this.lastAccessBeat.forEach(function (beat, key) {
if (now - beat > BEAT_LIMIT) {
_this2.map.delete(key);
_this2.lastAccessBeat.delete(key);
}
});
this.accessBeat = 0;
}
}
}]);
return ArrayKeyMap;
}();
var uniqueMap = new ArrayKeyMap();
/**
* Like `useMemo`, but this hook result will be shared across all instances.
*/
function useUniqueMemo(memoFn, deps) {
return React.useMemo(function () {
var cachedValue = uniqueMap.get(deps);
if (cachedValue) {
return cachedValue;
}
var newValue = memoFn();
uniqueMap.set(deps, newValue);
return newValue;
}, deps);
}
export default useUniqueMemo;
+8
View File
@@ -0,0 +1,8 @@
export type UseCSP = () => {
nonce?: string;
};
/**
* Provide a default hook since not everyone needs to config this.
*/
declare const useDefaultCSP: UseCSP;
export default useDefaultCSP;
+7
View File
@@ -0,0 +1,7 @@
/**
* Provide a default hook since not everyone needs to config this.
*/
var useDefaultCSP = function useDefaultCSP() {
return {};
};
export default useDefaultCSP;
@@ -0,0 +1,11 @@
export type UsePrefix = () => {
/**
* All the component use `@ant-design/cssinjs-utils` should have same `rootPrefixCls`.
*/
rootPrefixCls: string;
/**
* `iconPrefixCls` comes from the setting of `@ant-design/icons`.
* Here maybe little coupling but everyone need use this.
*/
iconPrefixCls: string;
};
@@ -0,0 +1 @@
export {};
+20
View File
@@ -0,0 +1,20 @@
import type { Theme, TokenType } from '@ant-design/cssinjs';
import type { OverrideTokenMap, TokenMap, GlobalToken } from '../interface';
export type TokenMapWithTheme<CompTokenMap extends TokenMap, AliasToken extends TokenType, DesignToken extends TokenType> = {
[key in keyof OverrideTokenMap<CompTokenMap, AliasToken>]?: OverrideTokenMap<CompTokenMap, AliasToken>[key] & {
theme?: Theme<DesignToken, AliasToken>;
};
};
export interface UseTokenReturn<CompTokenMap extends TokenMap, AliasToken extends TokenType, DesignToken extends TokenType> {
token: GlobalToken<CompTokenMap, AliasToken>;
realToken?: GlobalToken<CompTokenMap, AliasToken>;
theme?: Theme<DesignToken, AliasToken>;
components?: TokenMapWithTheme<CompTokenMap, DesignToken, AliasToken>;
hashId?: string;
hashed?: string | boolean;
cssVar?: {
prefix?: string;
key?: string;
};
}
export type UseToken<CompTokenMap extends TokenMap, DesignToken extends TokenType, AliasToken extends TokenType> = () => UseTokenReturn<CompTokenMap, DesignToken, AliasToken>;
+1
View File
@@ -0,0 +1 @@
export {};
+6
View File
@@ -0,0 +1,6 @@
export { default as genStyleUtils } from './util/genStyleUtils';
export { default as genCalc } from './util/calc';
export { default as statisticToken, merge as mergeToken, statistic } from './util/statistic';
export type { OverrideTokenMap, TokenMap, TokenMapKey, GlobalTokenWithComponent, ComponentToken, ComponentTokenKey, GlobalToken, } from './interface';
export type { default as AbstractCalculator } from './util/calc/calculator';
export type { FullToken, GetDefaultToken, GetDefaultTokenFn, GenStyleFn, TokenWithCommonCls, CSSUtil, } from './util/genStyleUtils';
+3
View File
@@ -0,0 +1,3 @@
export { default as genStyleUtils } from "./util/genStyleUtils";
export { default as genCalc } from "./util/calc";
export { default as statisticToken, merge as mergeToken, statistic } from "./util/statistic";
@@ -0,0 +1,10 @@
import type { TokenType } from '@ant-design/cssinjs';
export type TokenMap = Record<PropertyKey, any>;
export type TokenMapKey<CompTokenMap extends TokenMap> = Extract<keyof CompTokenMap, string>;
export type GlobalToken<CompTokenMap extends TokenMap, AliasToken extends TokenType> = AliasToken & CompTokenMap;
export type OverrideTokenMap<CompTokenMap extends TokenMap, AliasToken extends TokenType> = {
[key in keyof CompTokenMap]: Partial<CompTokenMap[key]> & Partial<AliasToken>;
};
export type GlobalTokenWithComponent<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>> = GlobalToken<CompTokenMap, AliasToken> & CompTokenMap[C];
export type ComponentToken<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>> = Exclude<OverrideTokenMap<CompTokenMap, AliasToken>[C], undefined>;
export type ComponentTokenKey<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>> = keyof ComponentToken<CompTokenMap, AliasToken, C>;
@@ -0,0 +1 @@
export {};
@@ -0,0 +1,3 @@
/// <reference types="react" />
export type { OverrideTokenMap, TokenMap, TokenMapKey, GlobalTokenWithComponent, ComponentToken, ComponentTokenKey, GlobalToken, } from './components';
export type UseComponentStyleResult = [(node: React.ReactNode) => React.ReactElement, string];
@@ -0,0 +1 @@
export {};
@@ -0,0 +1,15 @@
import AbstractCalculator from './calculator';
export default class CSSCalculator extends AbstractCalculator {
result: string;
unitlessCssVar: Set<string>;
lowPriority?: boolean;
constructor(num: number | string | AbstractCalculator, unitlessCssVar: Set<string>);
add(num: number | string | AbstractCalculator): this;
sub(num: number | string | AbstractCalculator): this;
mul(num: number | string | AbstractCalculator): this;
div(num: number | string | AbstractCalculator): this;
getResult(force?: boolean): string;
equal(options?: {
unit?: boolean;
}): string;
}
@@ -0,0 +1,116 @@
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import AbstractCalculator from "./calculator";
var CALC_UNIT = 'CALC_UNIT';
var regexp = new RegExp(CALC_UNIT, 'g');
function unit(value) {
if (typeof value === 'number') {
return "".concat(value).concat(CALC_UNIT);
}
return value;
}
var CSSCalculator = /*#__PURE__*/function (_AbstractCalculator) {
_inherits(CSSCalculator, _AbstractCalculator);
var _super = _createSuper(CSSCalculator);
function CSSCalculator(num, unitlessCssVar) {
var _this;
_classCallCheck(this, CSSCalculator);
_this = _super.call(this);
_defineProperty(_assertThisInitialized(_this), "result", '');
_defineProperty(_assertThisInitialized(_this), "unitlessCssVar", void 0);
_defineProperty(_assertThisInitialized(_this), "lowPriority", void 0);
var numType = _typeof(num);
_this.unitlessCssVar = unitlessCssVar;
if (num instanceof CSSCalculator) {
_this.result = "(".concat(num.result, ")");
} else if (numType === 'number') {
_this.result = unit(num);
} else if (numType === 'string') {
_this.result = num;
}
return _this;
}
_createClass(CSSCalculator, [{
key: "add",
value: function add(num) {
if (num instanceof CSSCalculator) {
this.result = "".concat(this.result, " + ").concat(num.getResult());
} else if (typeof num === 'number' || typeof num === 'string') {
this.result = "".concat(this.result, " + ").concat(unit(num));
}
this.lowPriority = true;
return this;
}
}, {
key: "sub",
value: function sub(num) {
if (num instanceof CSSCalculator) {
this.result = "".concat(this.result, " - ").concat(num.getResult());
} else if (typeof num === 'number' || typeof num === 'string') {
this.result = "".concat(this.result, " - ").concat(unit(num));
}
this.lowPriority = true;
return this;
}
}, {
key: "mul",
value: function mul(num) {
if (this.lowPriority) {
this.result = "(".concat(this.result, ")");
}
if (num instanceof CSSCalculator) {
this.result = "".concat(this.result, " * ").concat(num.getResult(true));
} else if (typeof num === 'number' || typeof num === 'string') {
this.result = "".concat(this.result, " * ").concat(num);
}
this.lowPriority = false;
return this;
}
}, {
key: "div",
value: function div(num) {
if (this.lowPriority) {
this.result = "(".concat(this.result, ")");
}
if (num instanceof CSSCalculator) {
this.result = "".concat(this.result, " / ").concat(num.getResult(true));
} else if (typeof num === 'number' || typeof num === 'string') {
this.result = "".concat(this.result, " / ").concat(num);
}
this.lowPriority = false;
return this;
}
}, {
key: "getResult",
value: function getResult(force) {
return this.lowPriority || force ? "(".concat(this.result, ")") : this.result;
}
}, {
key: "equal",
value: function equal(options) {
var _this2 = this;
var _ref = options || {},
cssUnit = _ref.unit;
var mergedUnit = true;
if (typeof cssUnit === 'boolean') {
mergedUnit = cssUnit;
} else if (Array.from(this.unitlessCssVar).some(function (cssVar) {
return _this2.result.includes(cssVar);
})) {
mergedUnit = false;
}
this.result = this.result.replace(regexp, mergedUnit ? 'px' : '');
if (typeof this.lowPriority !== 'undefined') {
return "calc(".concat(this.result, ")");
}
return this.result;
}
}]);
return CSSCalculator;
}(AbstractCalculator);
export { CSSCalculator as default };
@@ -0,0 +1,11 @@
import AbstractCalculator from './calculator';
declare class NumCalculator extends AbstractCalculator {
result: number;
constructor(num: number | string | AbstractCalculator);
add(num: number | string | AbstractCalculator): this;
sub(num: number | string | AbstractCalculator): this;
mul(num: number | string | AbstractCalculator): this;
div(num: number | string | AbstractCalculator): this;
equal(): number;
}
export default NumCalculator;
@@ -0,0 +1,71 @@
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import AbstractCalculator from "./calculator";
var NumCalculator = /*#__PURE__*/function (_AbstractCalculator) {
_inherits(NumCalculator, _AbstractCalculator);
var _super = _createSuper(NumCalculator);
function NumCalculator(num) {
var _this;
_classCallCheck(this, NumCalculator);
_this = _super.call(this);
_defineProperty(_assertThisInitialized(_this), "result", 0);
if (num instanceof NumCalculator) {
_this.result = num.result;
} else if (typeof num === 'number') {
_this.result = num;
}
return _this;
}
_createClass(NumCalculator, [{
key: "add",
value: function add(num) {
if (num instanceof NumCalculator) {
this.result += num.result;
} else if (typeof num === 'number') {
this.result += num;
}
return this;
}
}, {
key: "sub",
value: function sub(num) {
if (num instanceof NumCalculator) {
this.result -= num.result;
} else if (typeof num === 'number') {
this.result -= num;
}
return this;
}
}, {
key: "mul",
value: function mul(num) {
if (num instanceof NumCalculator) {
this.result *= num.result;
} else if (typeof num === 'number') {
this.result *= num;
}
return this;
}
}, {
key: "div",
value: function div(num) {
if (num instanceof NumCalculator) {
this.result /= num.result;
} else if (typeof num === 'number') {
this.result /= num;
}
return this;
}
}, {
key: "equal",
value: function equal() {
return this.result;
}
}]);
return NumCalculator;
}(AbstractCalculator);
export default NumCalculator;
@@ -0,0 +1,30 @@
declare abstract class AbstractCalculator {
/**
* @descCN 1 + 2
* @descEN Calculate the sum of two numbers, e.g. 1 + 2
*/
abstract add(num: number | string | AbstractCalculator): this;
/**
* @descCN 1 - 2
* @descEN Calculate the difference between two numbers, e.g. 1 - 2
*/
abstract sub(num: number | string | AbstractCalculator): this;
/**
* @descCN 1 * 2
* @descEN Calculate the product of two numbers, e.g. 1 * 2
*/
abstract mul(num: number | string | AbstractCalculator): this;
/**
* @descCN 1 / 2
* @descEN Calculate the quotient of two numbers, e.g. 1 / 2
*/
abstract div(num: number | string | AbstractCalculator): this;
/**
* @descCN
* @descEN Get the calculation result
*/
abstract equal(options?: {
unit?: boolean;
}): string | number;
}
export default AbstractCalculator;
@@ -0,0 +1,6 @@
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
var AbstractCalculator = /*#__PURE__*/_createClass(function AbstractCalculator() {
_classCallCheck(this, AbstractCalculator);
});
export default AbstractCalculator;
@@ -0,0 +1,5 @@
import type AbstractCalculator from './calculator';
import CSSCalculator from './CSSCalculator';
import NumCalculator from './NumCalculator';
declare const genCalc: (type: 'css' | 'js', unitlessCssVar: Set<string>) => (num: number | string | AbstractCalculator) => CSSCalculator | NumCalculator;
export default genCalc;
@@ -0,0 +1,9 @@
import CSSCalculator from "./CSSCalculator";
import NumCalculator from "./NumCalculator";
var genCalc = function genCalc(type, unitlessCssVar) {
var Calculator = type === 'css' ? CSSCalculator : NumCalculator;
return function (num) {
return new Calculator(num, unitlessCssVar);
};
};
export default genCalc;
@@ -0,0 +1,116 @@
import React from 'react';
import type { CSSInterpolation, CSSObject, TokenType } from '@ant-design/cssinjs';
import { useStyleRegister } from '@ant-design/cssinjs';
import type { ComponentTokenKey, GlobalTokenWithComponent, TokenMap, TokenMapKey, UseComponentStyleResult } from '../interface';
import type AbstractCalculator from './calc/calculator';
import type { UseCSP } from '../hooks/useCSP';
import type { UsePrefix } from '../hooks/usePrefix';
import type { UseToken } from '../hooks/useToken';
type LayerConfig = Parameters<typeof useStyleRegister>[0]['layer'];
export interface StyleInfo {
hashId: string;
prefixCls: string;
rootPrefixCls: string;
iconPrefixCls: string;
}
export type CSSUtil = {
calc: (number: any) => AbstractCalculator;
max: (...values: (number | string)[]) => number | string;
min: (...values: (number | string)[]) => number | string;
};
export type TokenWithCommonCls<T> = T & {
/** Wrap component class with `.` prefix */
componentCls: string;
/** Origin prefix which do not have `.` prefix */
prefixCls: string;
/** Wrap icon class with `.` prefix */
iconCls: string;
/** Wrap ant prefixCls class with `.` prefix */
antCls: string;
} & CSSUtil;
export type FullToken<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>> = TokenWithCommonCls<GlobalTokenWithComponent<CompTokenMap, AliasToken, C>>;
export type GenStyleFn<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>> = (token: FullToken<CompTokenMap, AliasToken, C>, info: StyleInfo) => CSSInterpolation;
export type GetDefaultTokenFn<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>> = (token: AliasToken & Partial<CompTokenMap[C]>) => CompTokenMap[C];
export type GetDefaultToken<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>> = null | CompTokenMap[C] | GetDefaultTokenFn<CompTokenMap, AliasToken, C>;
export interface SubStyleComponentProps {
prefixCls: string;
rootCls?: string;
}
export type CSSVarRegisterProps = {
rootCls: string;
component: string;
cssVar: {
prefix?: string;
key?: string;
};
};
type GetResetStylesConfig = {
prefix: ReturnType<UsePrefix>;
csp: ReturnType<UseCSP>;
};
export type GetResetStyles<AliasToken extends TokenType> = (token: AliasToken, config?: GetResetStylesConfig) => CSSInterpolation;
export type GetCompUnitless<CompTokenMap extends TokenMap, AliasToken extends TokenType> = <C extends TokenMapKey<CompTokenMap>>(component: C | [C, string]) => Partial<Record<ComponentTokenKey<CompTokenMap, AliasToken, C>, boolean>>;
declare function genStyleUtils<CompTokenMap extends TokenMap, AliasToken extends TokenType, DesignToken extends TokenType>(config: {
usePrefix: UsePrefix;
useToken: UseToken<CompTokenMap, AliasToken, DesignToken>;
useCSP?: UseCSP;
getResetStyles?: GetResetStyles<AliasToken>;
getCommonStyle?: (token: AliasToken, componentPrefixCls: string, rootCls?: string, resetFont?: boolean) => CSSObject;
getCompUnitless?: GetCompUnitless<CompTokenMap, AliasToken>;
layer?: LayerConfig;
}): {
genStyleHooks: <C extends TokenMapKey<CompTokenMap>>(component: C | [C, string], styleFn: GenStyleFn<CompTokenMap, AliasToken, C>, getDefaultToken?: GetDefaultToken<CompTokenMap, AliasToken, C>, options?: {
resetStyle?: boolean;
resetFont?: boolean;
deprecatedTokens?: [keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C], undefined>, keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C], undefined>][];
/**
* Component tokens that do not need unit.
*/
unitless?: Partial<Record<keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C], undefined>, boolean>>;
/**
* Only use component style in client side. Ignore in SSR.
*/
clientOnly?: boolean;
/**
* Set order of component style.
* @default -999
*/
order?: number;
/**
* Whether generate styles
* @default true
*/
injectStyle?: boolean;
}) => (prefixCls: string, rootCls?: string) => readonly [(node: React.ReactElement) => React.ReactElement, string, string];
genSubStyleComponent: <C_1 extends TokenMapKey<CompTokenMap>>(componentName: C_1 | [C_1, string], styleFn: GenStyleFn<CompTokenMap, AliasToken, C_1>, getDefaultToken?: GetDefaultToken<CompTokenMap, AliasToken, C_1>, options?: {
resetStyle?: boolean;
resetFont?: boolean;
deprecatedTokens?: [keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C_1], undefined>, keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C_1], undefined>][];
/**
* Only use component style in client side. Ignore in SSR.
*/
clientOnly?: boolean;
/**
* Set order of component style. Default is -999.
*/
order?: number;
injectStyle?: boolean;
unitless?: Partial<Record<keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C_1], undefined>, boolean>>;
}) => React.FunctionComponent<SubStyleComponentProps>;
genComponentStyleHook: <C_2 extends TokenMapKey<CompTokenMap>>(componentName: C_2 | [C_2, string], styleFn: GenStyleFn<CompTokenMap, AliasToken, C_2>, getDefaultToken?: GetDefaultToken<CompTokenMap, AliasToken, C_2>, options?: {
resetStyle?: boolean;
resetFont?: boolean;
deprecatedTokens?: [keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C_2], undefined>, keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C_2], undefined>][];
/**
* Only use component style in client side. Ignore in SSR.
*/
clientOnly?: boolean;
/**
* Set order of component style. Default is -999.
*/
order?: number;
injectStyle?: boolean;
unitless?: Partial<Record<keyof Exclude<import("../interface").OverrideTokenMap<CompTokenMap, AliasToken>[C_2], undefined>, boolean>>;
}) => (prefixCls: string, rootCls?: string) => UseComponentStyleResult;
};
export default genStyleUtils;
@@ -0,0 +1,245 @@
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import React from 'react';
import { token2CSSVar, useCSSVarRegister, useStyleRegister } from '@ant-design/cssinjs';
import genCalc from "./calc";
import getCompVarPrefix from "./getCompVarPrefix";
import getComponentToken from "./getComponentToken";
import getDefaultComponentToken from "./getDefaultComponentToken";
import genMaxMin from "./maxmin";
import statisticToken, { merge as mergeToken } from "./statistic";
import useUniqueMemo from "../_util/hooks/useUniqueMemo";
import useDefaultCSP from "../hooks/useCSP";
function genStyleUtils(config) {
// Dependency inversion for preparing basic config.
var _config$useCSP = config.useCSP,
useCSP = _config$useCSP === void 0 ? useDefaultCSP : _config$useCSP,
useToken = config.useToken,
usePrefix = config.usePrefix,
getResetStyles = config.getResetStyles,
getCommonStyle = config.getCommonStyle,
getCompUnitless = config.getCompUnitless;
function genStyleHooks(component, styleFn, getDefaultToken, options) {
var componentName = Array.isArray(component) ? component[0] : component;
function prefixToken(key) {
return "".concat(String(componentName)).concat(key.slice(0, 1).toUpperCase()).concat(key.slice(1));
}
// Fill unitless
var originUnitless = (options === null || options === void 0 ? void 0 : options.unitless) || {};
var originCompUnitless = typeof getCompUnitless === 'function' ? getCompUnitless(component) : {};
var compUnitless = _objectSpread(_objectSpread({}, originCompUnitless), {}, _defineProperty({}, prefixToken('zIndexPopup'), true));
Object.keys(originUnitless).forEach(function (key) {
compUnitless[prefixToken(key)] = originUnitless[key];
});
// Options
var mergedOptions = _objectSpread(_objectSpread({}, options), {}, {
unitless: compUnitless,
prefixToken: prefixToken
});
// Hooks
var useStyle = genComponentStyleHook(component, styleFn, getDefaultToken, mergedOptions);
var useCSSVar = genCSSVarRegister(componentName, getDefaultToken, mergedOptions);
return function (prefixCls) {
var rootCls = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : prefixCls;
var _useStyle = useStyle(prefixCls, rootCls),
_useStyle2 = _slicedToArray(_useStyle, 2),
hashId = _useStyle2[1];
var _useCSSVar = useCSSVar(rootCls),
_useCSSVar2 = _slicedToArray(_useCSSVar, 2),
wrapCSSVar = _useCSSVar2[0],
cssVarCls = _useCSSVar2[1];
return [wrapCSSVar, hashId, cssVarCls];
};
}
function genCSSVarRegister(component, getDefaultToken, options) {
var compUnitless = options.unitless,
_options$injectStyle = options.injectStyle,
injectStyle = _options$injectStyle === void 0 ? true : _options$injectStyle,
prefixToken = options.prefixToken,
ignore = options.ignore;
var CSSVarRegister = function CSSVarRegister(_ref) {
var rootCls = _ref.rootCls,
_ref$cssVar = _ref.cssVar,
cssVar = _ref$cssVar === void 0 ? {} : _ref$cssVar;
var _useToken = useToken(),
realToken = _useToken.realToken;
useCSSVarRegister({
path: [component],
prefix: cssVar.prefix,
key: cssVar.key,
unitless: compUnitless,
ignore: ignore,
token: realToken,
scope: rootCls
}, function () {
var defaultToken = getDefaultComponentToken(component, realToken, getDefaultToken);
var componentToken = getComponentToken(component, realToken, defaultToken, {
deprecatedTokens: options === null || options === void 0 ? void 0 : options.deprecatedTokens
});
Object.keys(defaultToken).forEach(function (key) {
componentToken[prefixToken(key)] = componentToken[key];
delete componentToken[key];
});
return componentToken;
});
return null;
};
var useCSSVar = function useCSSVar(rootCls) {
var _useToken2 = useToken(),
cssVar = _useToken2.cssVar;
return [function (node) {
return injectStyle && cssVar ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CSSVarRegister, {
rootCls: rootCls,
cssVar: cssVar,
component: component
}), node) : node;
}, cssVar === null || cssVar === void 0 ? void 0 : cssVar.key];
};
return useCSSVar;
}
function genComponentStyleHook(componentName, styleFn, getDefaultToken) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var cells = Array.isArray(componentName) ? componentName : [componentName, componentName];
var _cells = _slicedToArray(cells, 1),
component = _cells[0];
var concatComponent = cells.join('-');
var mergedLayer = config.layer || {
name: 'antd'
};
// Return new style hook
return function (prefixCls) {
var rootCls = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : prefixCls;
var _useToken3 = useToken(),
theme = _useToken3.theme,
realToken = _useToken3.realToken,
hashId = _useToken3.hashId,
token = _useToken3.token,
cssVar = _useToken3.cssVar;
var _usePrefix = usePrefix(),
rootPrefixCls = _usePrefix.rootPrefixCls,
iconPrefixCls = _usePrefix.iconPrefixCls;
var csp = useCSP();
var type = cssVar ? 'css' : 'js';
// Use unique memo to share the result across all instances
var calc = useUniqueMemo(function () {
var unitlessCssVar = new Set();
if (cssVar) {
Object.keys(options.unitless || {}).forEach(function (key) {
// Some component proxy the AliasToken (e.g. Image) and some not (e.g. Modal)
// We should both pass in `unitlessCssVar` to make sure the CSSVar can be unitless.
unitlessCssVar.add(token2CSSVar(key, cssVar.prefix));
unitlessCssVar.add(token2CSSVar(key, getCompVarPrefix(component, cssVar.prefix)));
});
}
return genCalc(type, unitlessCssVar);
}, [type, component, cssVar === null || cssVar === void 0 ? void 0 : cssVar.prefix]);
var _genMaxMin = genMaxMin(type),
max = _genMaxMin.max,
min = _genMaxMin.min;
// Shared config
var sharedConfig = {
theme: theme,
token: token,
hashId: hashId,
nonce: function nonce() {
return csp.nonce;
},
clientOnly: options.clientOnly,
layer: mergedLayer,
// antd is always at top of styles
order: options.order || -999
};
// This if statement is safe, as it will only be used if the generator has the function. It's not dynamic.
if (typeof getResetStyles === 'function') {
// Generate style for all need reset tags.
useStyleRegister(_objectSpread(_objectSpread({}, sharedConfig), {}, {
clientOnly: false,
path: ['Shared', rootPrefixCls]
}), function () {
return getResetStyles(token, {
prefix: {
rootPrefixCls: rootPrefixCls,
iconPrefixCls: iconPrefixCls
},
csp: csp
});
});
}
var wrapSSR = useStyleRegister(_objectSpread(_objectSpread({}, sharedConfig), {}, {
path: [concatComponent, prefixCls, iconPrefixCls]
}), function () {
if (options.injectStyle === false) {
return [];
}
var _statisticToken = statisticToken(token),
proxyToken = _statisticToken.token,
flush = _statisticToken.flush;
var defaultComponentToken = getDefaultComponentToken(component, realToken, getDefaultToken);
var componentCls = ".".concat(prefixCls);
var componentToken = getComponentToken(component, realToken, defaultComponentToken, {
deprecatedTokens: options.deprecatedTokens
});
if (cssVar && defaultComponentToken && _typeof(defaultComponentToken) === 'object') {
Object.keys(defaultComponentToken).forEach(function (key) {
defaultComponentToken[key] = "var(".concat(token2CSSVar(key, getCompVarPrefix(component, cssVar.prefix)), ")");
});
}
var mergedToken = mergeToken(proxyToken, {
componentCls: componentCls,
prefixCls: prefixCls,
iconCls: ".".concat(iconPrefixCls),
antCls: ".".concat(rootPrefixCls),
calc: calc,
// @ts-ignore
max: max,
// @ts-ignore
min: min
}, cssVar ? defaultComponentToken : componentToken);
var styleInterpolation = styleFn(mergedToken, {
hashId: hashId,
prefixCls: prefixCls,
rootPrefixCls: rootPrefixCls,
iconPrefixCls: iconPrefixCls
});
flush(component, componentToken);
var commonStyle = typeof getCommonStyle === 'function' ? getCommonStyle(mergedToken, prefixCls, rootCls, options.resetFont) : null;
return [options.resetStyle === false ? null : commonStyle, styleInterpolation];
});
return [wrapSSR, hashId];
};
}
function genSubStyleComponent(componentName, styleFn, getDefaultToken) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var useStyle = genComponentStyleHook(componentName, styleFn, getDefaultToken, _objectSpread({
resetStyle: false,
// Sub Style should default after root one
order: -998
}, options));
var StyledComponent = function StyledComponent(_ref2) {
var prefixCls = _ref2.prefixCls,
_ref2$rootCls = _ref2.rootCls,
rootCls = _ref2$rootCls === void 0 ? prefixCls : _ref2$rootCls;
useStyle(prefixCls, rootCls);
return null;
};
if (process.env.NODE_ENV !== 'production') {
StyledComponent.displayName = "SubStyle_".concat(String(Array.isArray(componentName) ? componentName.join('.') : componentName));
}
return StyledComponent;
}
return {
genStyleHooks: genStyleHooks,
genSubStyleComponent: genSubStyleComponent,
genComponentStyleHook: genComponentStyleHook
};
}
export default genStyleUtils;
@@ -0,0 +1,2 @@
declare const getCompVarPrefix: (component: string, prefix?: string) => string;
export default getCompVarPrefix;
@@ -0,0 +1,4 @@
var getCompVarPrefix = function getCompVarPrefix(component, prefix) {
return "".concat([prefix, component.replace(/([A-Z]+)([A-Z][a-z]+)/g, '$1-$2').replace(/([a-z])([A-Z])/g, '$1-$2')].filter(Boolean).join('-'));
};
export default getCompVarPrefix;
@@ -0,0 +1,9 @@
import type { TokenMap, TokenMapKey, ComponentTokenKey, GlobalToken } from '../interface';
import type { TokenType } from '@ant-design/cssinjs';
declare function getComponentToken<CompTokenMap extends TokenMap, AliasToken extends TokenType, C extends TokenMapKey<CompTokenMap>>(component: C, token: GlobalToken<CompTokenMap, AliasToken>, defaultToken: CompTokenMap[C], options?: {
deprecatedTokens?: [
ComponentTokenKey<CompTokenMap, AliasToken, C>,
ComponentTokenKey<CompTokenMap, AliasToken, C>
][];
}): any;
export default getComponentToken;
@@ -0,0 +1,33 @@
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import { warning } from 'rc-util';
function getComponentToken(component, token, defaultToken, options) {
var customToken = _objectSpread({}, token[component]);
if (options !== null && options !== void 0 && options.deprecatedTokens) {
var deprecatedTokens = options.deprecatedTokens;
deprecatedTokens.forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
oldTokenKey = _ref2[0],
newTokenKey = _ref2[1];
if (process.env.NODE_ENV !== 'production') {
warning(!(customToken !== null && customToken !== void 0 && customToken[oldTokenKey]), "Component Token `".concat(String(oldTokenKey), "` of ").concat(String(component), " is deprecated. Please use `").concat(String(newTokenKey), "` instead."));
}
// Should wrap with `if` clause, or there will be `undefined` in object.
if (customToken !== null && customToken !== void 0 && customToken[oldTokenKey] || customToken !== null && customToken !== void 0 && customToken[newTokenKey]) {
var _customToken$newToken;
(_customToken$newToken = customToken[newTokenKey]) !== null && _customToken$newToken !== void 0 ? _customToken$newToken : customToken[newTokenKey] = customToken === null || customToken === void 0 ? void 0 : customToken[oldTokenKey];
}
});
}
var mergedToken = _objectSpread(_objectSpread({}, defaultToken), customToken);
// Remove same value as global token to minimize size
Object.keys(mergedToken).forEach(function (key) {
if (mergedToken[key] === token[key]) {
delete mergedToken[key];
}
});
return mergedToken;
}
export default getComponentToken;

Some files were not shown because too many files have changed in this diff Show More