@pikacss/plugin-icons 0.0.46 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/index.d.mts +141 -6
- package/dist/index.mjs +169 -66
- package/package.json +12 -8
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @pikacss/plugin-icons
|
|
2
|
+
|
|
3
|
+
Iconify icons plugin for PikaCSS. Renders icons from Iconify collections as CSS mask-image or background-image.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add -D @pikacss/plugin-icons
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { defineEngineConfig } from '@pikacss/core'
|
|
15
|
+
import { icons } from '@pikacss/plugin-icons'
|
|
16
|
+
|
|
17
|
+
export default defineEngineConfig({
|
|
18
|
+
plugins: [icons()],
|
|
19
|
+
icons: {
|
|
20
|
+
autoInstall: true,
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then use in templates:
|
|
26
|
+
|
|
27
|
+
```vue
|
|
28
|
+
<div :class="pika('i-mdi:home')" />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Documentation
|
|
32
|
+
|
|
33
|
+
See the [full documentation](https://pikacss.com/guide/plugins/icons).
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -1,28 +1,163 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { CustomCollections, IconCustomizations, IconifyLoaderOptions } from "@iconify/utils";
|
|
2
|
+
import { EnginePlugin, StyleItem } from "@pikacss/core";
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
5
5
|
interface IconMeta {
|
|
6
6
|
collection: string;
|
|
7
7
|
name: string;
|
|
8
8
|
svg: string;
|
|
9
|
+
source: IconSource;
|
|
9
10
|
mode?: IconsConfig['mode'];
|
|
10
11
|
}
|
|
11
|
-
type
|
|
12
|
+
type IconSource = 'custom' | 'local' | 'cdn';
|
|
13
|
+
/**
|
|
14
|
+
* Configuration options for the PikaCSS icons plugin.
|
|
15
|
+
*
|
|
16
|
+
* @remarks Controls how icon utilities are resolved, loaded, and rendered as CSS.
|
|
17
|
+
* Icons are loaded from custom collections first, then from locally installed
|
|
18
|
+
* Iconify packages, and finally from a CDN if configured.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { defineEngineConfig } from '@pikacss/core'
|
|
23
|
+
* import { icons } from '@pikacss/plugin-icons'
|
|
24
|
+
*
|
|
25
|
+
* export default defineEngineConfig({
|
|
26
|
+
* plugins: [icons()],
|
|
27
|
+
* icons: {
|
|
28
|
+
* prefix: 'i-',
|
|
29
|
+
* mode: 'auto',
|
|
30
|
+
* scale: 1,
|
|
31
|
+
* cdn: 'https://esm.sh/@iconify-json/{collection}/icons.json',
|
|
32
|
+
* },
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
interface IconsConfig {
|
|
12
37
|
/**
|
|
13
|
-
*
|
|
38
|
+
* One or more prefixes used to match icon utility names. When a utility
|
|
39
|
+
* matches `<prefix><collection>:<name>`, it resolves to an icon style.
|
|
40
|
+
*
|
|
41
|
+
* @default `'i-'`
|
|
42
|
+
*/
|
|
43
|
+
prefix?: string | string[];
|
|
44
|
+
/**
|
|
45
|
+
* Rendering strategy for icon SVGs. `'mask'` uses a CSS mask with
|
|
46
|
+
* `currentColor` as the fill, allowing color inheritance. `'bg'` renders
|
|
47
|
+
* the SVG as a background image with its original colors. `'auto'`
|
|
48
|
+
* chooses `'mask'` when the SVG contains `currentColor`, otherwise `'bg'`.
|
|
49
|
+
*
|
|
50
|
+
* @default `'auto'`
|
|
51
|
+
*/
|
|
52
|
+
mode?: 'auto' | 'mask' | 'bg';
|
|
53
|
+
/**
|
|
54
|
+
* Multiplier applied to the icon's intrinsic width and height.
|
|
55
|
+
* Combined with `unit` to produce the final CSS dimensions.
|
|
56
|
+
*
|
|
57
|
+
* @default `1`
|
|
58
|
+
*/
|
|
59
|
+
scale?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Custom icon collections keyed by collection name. Each entry maps
|
|
62
|
+
* icon names to SVG strings or async loaders, checked before local
|
|
63
|
+
* packages and the CDN.
|
|
64
|
+
*
|
|
65
|
+
* @default `undefined`
|
|
66
|
+
*/
|
|
67
|
+
collections?: CustomCollections;
|
|
68
|
+
/**
|
|
69
|
+
* Iconify customization hooks applied when loading icons. Allows
|
|
70
|
+
* transforming SVG attributes, trimming whitespace, and running
|
|
71
|
+
* per-icon logic via `iconCustomizer`.
|
|
72
|
+
*
|
|
73
|
+
* @default `{}`
|
|
74
|
+
*/
|
|
75
|
+
customizations?: IconCustomizations;
|
|
76
|
+
/**
|
|
77
|
+
* When enabled, automatically installs missing `@iconify-json/*`
|
|
78
|
+
* packages on demand during local icon resolution.
|
|
79
|
+
*
|
|
80
|
+
* @default `false`
|
|
81
|
+
*/
|
|
82
|
+
autoInstall?: IconifyLoaderOptions['autoInstall'];
|
|
83
|
+
/**
|
|
84
|
+
* Working directory used by the Iconify node loader when resolving
|
|
85
|
+
* locally installed icon packages.
|
|
86
|
+
*
|
|
87
|
+
* @default `undefined`
|
|
88
|
+
*/
|
|
89
|
+
cwd?: IconifyLoaderOptions['cwd'];
|
|
90
|
+
/**
|
|
91
|
+
* CDN URL template for fetching remote icon sets. Use `{collection}`
|
|
92
|
+
* as a placeholder for the collection name, or provide a base URL
|
|
93
|
+
* and the collection name will be appended as `<url>/<collection>.json`.
|
|
94
|
+
*
|
|
95
|
+
* @default `undefined`
|
|
96
|
+
*/
|
|
97
|
+
cdn?: string;
|
|
98
|
+
/**
|
|
99
|
+
* CSS unit appended to the icon's width and height (e.g. `'em'`, `'rem'`).
|
|
100
|
+
* When set, produces explicit dimension values like `1em` based on `scale`.
|
|
101
|
+
* When omitted, dimensions are left to the SVG's intrinsic size.
|
|
102
|
+
*
|
|
103
|
+
* @default `undefined`
|
|
104
|
+
*/
|
|
105
|
+
unit?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Additional CSS properties merged into every generated icon style item.
|
|
108
|
+
* Useful for adding `display`, `vertical-align`, or other layout properties.
|
|
109
|
+
*
|
|
110
|
+
* @default `{}`
|
|
111
|
+
*/
|
|
112
|
+
extraProperties?: Record<string, string>;
|
|
113
|
+
/**
|
|
114
|
+
* Post-processing callback invoked on each generated icon style item before
|
|
115
|
+
* it is returned. Receives the mutable style item and resolved icon metadata,
|
|
116
|
+
* allowing custom property injection or conditional transformations.
|
|
117
|
+
*
|
|
118
|
+
* @default `undefined`
|
|
14
119
|
*/
|
|
15
120
|
processor?: (styleItem: StyleItem, meta: Required<IconMeta>) => void;
|
|
16
121
|
/**
|
|
17
|
-
*
|
|
122
|
+
* Explicit list of icon identifiers (e.g. `'mdi:home'`) to include in
|
|
123
|
+
* editor autocomplete suggestions. Each entry is combined with every
|
|
124
|
+
* configured prefix.
|
|
125
|
+
*
|
|
126
|
+
* @default `undefined`
|
|
18
127
|
*/
|
|
19
128
|
autocomplete?: string[];
|
|
20
|
-
}
|
|
129
|
+
}
|
|
21
130
|
declare module '@pikacss/core' {
|
|
22
131
|
interface EngineConfig {
|
|
132
|
+
/**
|
|
133
|
+
* Configuration for the icons plugin. Requires the `icons()` plugin
|
|
134
|
+
* to be registered in `plugins` for this configuration to take effect.
|
|
135
|
+
*
|
|
136
|
+
* @default `undefined`
|
|
137
|
+
*/
|
|
23
138
|
icons?: IconsConfig;
|
|
24
139
|
}
|
|
25
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Creates the PikaCSS icons engine plugin.
|
|
143
|
+
*
|
|
144
|
+
* @returns An engine plugin that registers icon shortcut rules and autocomplete entries.
|
|
145
|
+
*
|
|
146
|
+
* @remarks Resolves icon SVGs from custom collections, locally installed
|
|
147
|
+
* `@iconify-json/*` packages, or a remote CDN. Each matched utility is
|
|
148
|
+
* expanded into a CSS style item using either mask or background rendering.
|
|
149
|
+
* Configure behavior through the `icons` key in your engine config.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* import { icons } from '@pikacss/plugin-icons'
|
|
154
|
+
*
|
|
155
|
+
* export default defineEngineConfig({
|
|
156
|
+
* plugins: [icons()],
|
|
157
|
+
* icons: { prefix: 'i-', mode: 'auto' },
|
|
158
|
+
* })
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
26
161
|
declare function icons(): EnginePlugin;
|
|
27
162
|
//#endregion
|
|
28
163
|
export { IconsConfig, icons };
|
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import process from "node:process";
|
|
2
|
-
import { encodeSvgForCss, loadIcon } from "@iconify/utils";
|
|
2
|
+
import { encodeSvgForCss, loadIcon, quicklyValidateIconSet, searchForIcon, stringToIcon } from "@iconify/utils";
|
|
3
|
+
import { loadNodeIcon } from "@iconify/utils/lib/loader/node-loader";
|
|
3
4
|
import { defineEnginePlugin, log } from "@pikacss/core";
|
|
4
|
-
import { combineLoaders, createCDNFetchLoader, createNodeLoader, parseIconWithLoader } from "@unocss/preset-icons";
|
|
5
5
|
import { $fetch } from "ofetch";
|
|
6
|
-
|
|
7
6
|
//#region src/index.ts
|
|
8
7
|
/**
|
|
9
8
|
* Environment flags helper function to detect the current runtime environment.
|
|
10
|
-
* This replaces the removed `getEnvFlags` export from `@unocss/preset-icons` v66+.
|
|
11
|
-
*
|
|
12
|
-
* @returns An object containing:
|
|
13
|
-
* - `isNode`: Whether the code is running in a Node.js environment
|
|
14
|
-
* - `isVSCode`: Whether the code is running within VS Code (extension host)
|
|
15
|
-
* - `isESLint`: Whether the code is running within ESLint
|
|
16
9
|
*/
|
|
17
10
|
function getEnvFlags() {
|
|
18
11
|
const isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined";
|
|
@@ -22,75 +15,183 @@ function getEnvFlags() {
|
|
|
22
15
|
isESLint: isNode && !!process.env.ESLINT
|
|
23
16
|
};
|
|
24
17
|
}
|
|
18
|
+
const RE_ESCAPE_REGEXP = /[|\\{}()[\]^$+*?.-]/g;
|
|
19
|
+
const RE_CAMEL_CASE_ICON_BOUNDARY = /([a-z])([A-Z])/g;
|
|
20
|
+
const RE_DIGIT_ICON_BOUNDARY = /([a-z])(\d+)/g;
|
|
21
|
+
const RE_TRAILING_SLASH = /\/$/;
|
|
22
|
+
/**
|
|
23
|
+
* Creates the PikaCSS icons engine plugin.
|
|
24
|
+
*
|
|
25
|
+
* @returns An engine plugin that registers icon shortcut rules and autocomplete entries.
|
|
26
|
+
*
|
|
27
|
+
* @remarks Resolves icon SVGs from custom collections, locally installed
|
|
28
|
+
* `@iconify-json/*` packages, or a remote CDN. Each matched utility is
|
|
29
|
+
* expanded into a CSS style item using either mask or background rendering.
|
|
30
|
+
* Configure behavior through the `icons` key in your engine config.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { icons } from '@pikacss/plugin-icons'
|
|
35
|
+
*
|
|
36
|
+
* export default defineEngineConfig({
|
|
37
|
+
* plugins: [icons()],
|
|
38
|
+
* icons: { prefix: 'i-', mode: 'auto' },
|
|
39
|
+
* })
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
25
42
|
function icons() {
|
|
26
|
-
return createIconsPlugin(
|
|
43
|
+
return createIconsPlugin();
|
|
44
|
+
}
|
|
45
|
+
const globalColonRE = /:/g;
|
|
46
|
+
const currentColorRE = /currentColor/;
|
|
47
|
+
function normalizePrefixes(prefix) {
|
|
48
|
+
const prefixes = [prefix].flat().filter(Boolean);
|
|
49
|
+
return [...new Set(prefixes)];
|
|
50
|
+
}
|
|
51
|
+
function escapeRegExp(value) {
|
|
52
|
+
return value.replace(RE_ESCAPE_REGEXP, "\\$&");
|
|
53
|
+
}
|
|
54
|
+
function createShortcutRegExp(prefixes) {
|
|
55
|
+
return new RegExp(`^(?:${prefixes.map(escapeRegExp).join("|")})([\\w:-]+)(?:\\?(mask|bg|auto))?$`);
|
|
56
|
+
}
|
|
57
|
+
function getPossibleIconNames(iconName) {
|
|
58
|
+
return [
|
|
59
|
+
iconName,
|
|
60
|
+
iconName.replace(RE_CAMEL_CASE_ICON_BOUNDARY, "$1-$2").toLowerCase(),
|
|
61
|
+
iconName.replace(RE_DIGIT_ICON_BOUNDARY, "$1-$2")
|
|
62
|
+
];
|
|
27
63
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
64
|
+
function createAutocomplete(prefixes, autocomplete = []) {
|
|
65
|
+
const prefixRE = new RegExp(`^(?:${prefixes.map(escapeRegExp).join("|")})`);
|
|
66
|
+
return [...prefixes, ...prefixes.flatMap((prefix) => autocomplete.map((icon) => `${prefix}${icon.replace(prefixRE, "")}`))];
|
|
30
67
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
68
|
+
function createAutocompletePatterns(prefixes) {
|
|
69
|
+
return prefixes.flatMap((prefix) => [
|
|
70
|
+
`\`${prefix}\${string}:\${string}\``,
|
|
71
|
+
`\`${prefix}\${string}:\${string}?mask\``,
|
|
72
|
+
`\`${prefix}\${string}:\${string}?bg\``,
|
|
73
|
+
`\`${prefix}\${string}:\${string}?auto\``
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
function resolveCdnCollectionUrl(cdn, collection) {
|
|
77
|
+
if (cdn.includes("{collection}")) return cdn.replaceAll("{collection}", collection);
|
|
78
|
+
return `${cdn.replace(RE_TRAILING_SLASH, "")}/${collection}.json`;
|
|
79
|
+
}
|
|
80
|
+
function createLoaderOptions(config, usedProps) {
|
|
81
|
+
const { scale = 1, collections, autoInstall = false, cwd, unit, extraProperties = {}, customizations = {} } = config;
|
|
82
|
+
const iconCustomizer = customizations.iconCustomizer;
|
|
83
|
+
return {
|
|
84
|
+
addXmlNs: true,
|
|
85
|
+
scale,
|
|
86
|
+
customCollections: collections,
|
|
87
|
+
autoInstall,
|
|
88
|
+
cwd,
|
|
89
|
+
usedProps,
|
|
90
|
+
customizations: {
|
|
91
|
+
...customizations,
|
|
92
|
+
additionalProps: {
|
|
93
|
+
...customizations.additionalProps,
|
|
94
|
+
...extraProperties
|
|
95
|
+
},
|
|
96
|
+
trimCustomSvg: customizations.trimCustomSvg ?? true,
|
|
97
|
+
async iconCustomizer(collection, icon, props) {
|
|
98
|
+
await iconCustomizer?.(collection, icon, props);
|
|
99
|
+
if (!unit) return;
|
|
100
|
+
if (!props.width) props.width = `${scale}${unit}`;
|
|
101
|
+
if (!props.height) props.height = `${scale}${unit}`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async function loadCollectionFromCdn(cdn, collection, cache) {
|
|
107
|
+
if (!cache.has(collection)) cache.set(collection, (async () => {
|
|
108
|
+
try {
|
|
109
|
+
return quicklyValidateIconSet(await $fetch(resolveCdnCollectionUrl(cdn, collection))) ?? void 0;
|
|
110
|
+
} catch {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
})());
|
|
114
|
+
return cache.get(collection);
|
|
115
|
+
}
|
|
116
|
+
async function resolveIcon(body, config, flags, cdnCollectionCache) {
|
|
117
|
+
const parsed = stringToIcon(body, true);
|
|
118
|
+
if (parsed == null || !parsed.prefix) return null;
|
|
119
|
+
const customProps = {};
|
|
120
|
+
const customSvg = await loadIcon(parsed.prefix, parsed.name, createLoaderOptions(config, customProps));
|
|
121
|
+
if (customSvg != null) return {
|
|
122
|
+
collection: parsed.prefix,
|
|
123
|
+
name: parsed.name,
|
|
124
|
+
svg: customSvg,
|
|
125
|
+
usedProps: customProps,
|
|
126
|
+
source: "custom"
|
|
127
|
+
};
|
|
128
|
+
if (flags.isNode && !flags.isVSCode && !flags.isESLint) {
|
|
129
|
+
const localProps = {};
|
|
130
|
+
const localSvg = await loadNodeIcon(parsed.prefix, parsed.name, {
|
|
131
|
+
...createLoaderOptions(config, localProps),
|
|
132
|
+
customCollections: void 0
|
|
133
|
+
});
|
|
134
|
+
if (localSvg != null) return {
|
|
135
|
+
collection: parsed.prefix,
|
|
136
|
+
name: parsed.name,
|
|
137
|
+
svg: localSvg,
|
|
138
|
+
usedProps: localProps,
|
|
139
|
+
source: "local"
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (config.cdn) {
|
|
143
|
+
const iconSet = await loadCollectionFromCdn(config.cdn, parsed.prefix, cdnCollectionCache);
|
|
144
|
+
if (iconSet != null) {
|
|
145
|
+
const remoteProps = {};
|
|
146
|
+
const remoteSvg = await searchForIcon(iconSet, parsed.prefix, getPossibleIconNames(parsed.name), createLoaderOptions(config, remoteProps));
|
|
147
|
+
if (remoteSvg != null) return {
|
|
148
|
+
collection: parsed.prefix,
|
|
149
|
+
name: parsed.name,
|
|
150
|
+
svg: remoteSvg,
|
|
151
|
+
usedProps: remoteProps,
|
|
152
|
+
source: "cdn"
|
|
153
|
+
};
|
|
154
|
+
}
|
|
38
155
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
156
|
+
return {
|
|
157
|
+
collection: parsed.prefix,
|
|
158
|
+
name: parsed.name,
|
|
159
|
+
svg: null,
|
|
160
|
+
usedProps: {},
|
|
161
|
+
source: null
|
|
162
|
+
};
|
|
42
163
|
}
|
|
43
|
-
|
|
44
|
-
function createIconsPlugin(lookupIconLoader) {
|
|
164
|
+
function createIconsPlugin() {
|
|
45
165
|
let engine;
|
|
46
|
-
let iconsConfig;
|
|
166
|
+
let iconsConfig = {};
|
|
167
|
+
const flags = getEnvFlags();
|
|
168
|
+
const cdnCollectionCache = /* @__PURE__ */ new Map();
|
|
47
169
|
return defineEnginePlugin({
|
|
48
170
|
name: "icons",
|
|
49
171
|
configureRawConfig: async (config) => {
|
|
50
|
-
iconsConfig = config.icons
|
|
172
|
+
iconsConfig = config.icons ?? {};
|
|
51
173
|
},
|
|
52
174
|
configureEngine: async (_engine) => {
|
|
53
175
|
engine = _engine;
|
|
54
|
-
const {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
autoInstall,
|
|
60
|
-
cwd: collectionsNodeResolvePath,
|
|
61
|
-
warn: void 0,
|
|
62
|
-
customizations: {
|
|
63
|
-
...customizations,
|
|
64
|
-
additionalProps: { ...extraProperties },
|
|
65
|
-
trimCustomSvg: true,
|
|
66
|
-
async iconCustomizer(collection, icon, props) {
|
|
67
|
-
await customizations.iconCustomizer?.(collection, icon, props);
|
|
68
|
-
if (unit) {
|
|
69
|
-
if (!props.width) props.width = `${scale}${unit}`;
|
|
70
|
-
if (!props.height) props.height = `${scale}${unit}`;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
const prefixRE = new RegExp(`^(${[prefix].flat().join("|")})`);
|
|
76
|
-
const autocompletePrefix = [prefix].flat();
|
|
77
|
-
const autocomplete = [...autocompletePrefix, ...autocompletePrefix.flatMap((p) => _autocomplete?.map((a) => `${p}${a.replace(prefixRE, "")}`) || [])];
|
|
78
|
-
let iconLoader;
|
|
176
|
+
const { mode = "auto", prefix = "i-", processor, autocomplete: _autocomplete } = iconsConfig;
|
|
177
|
+
const prefixes = normalizePrefixes(prefix);
|
|
178
|
+
const autocomplete = createAutocomplete(prefixes, _autocomplete);
|
|
179
|
+
const autocompletePatterns = createAutocompletePatterns(prefixes);
|
|
180
|
+
engine.appendAutocomplete({ patterns: { shortcuts: autocompletePatterns } });
|
|
79
181
|
engine.shortcuts.add({
|
|
80
|
-
shortcut:
|
|
182
|
+
shortcut: createShortcutRegExp(prefixes),
|
|
81
183
|
value: async (match) => {
|
|
82
184
|
let [full, body, _mode = mode] = match;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (parsed == null) {
|
|
185
|
+
const resolved = await resolveIcon(body, iconsConfig, flags, cdnCollectionCache);
|
|
186
|
+
if (resolved == null) {
|
|
187
|
+
log.warn(`invalid icon name "${full}"`);
|
|
188
|
+
return {};
|
|
189
|
+
}
|
|
190
|
+
if (resolved.svg == null) {
|
|
90
191
|
log.warn(`failed to load icon "${full}"`);
|
|
91
192
|
return {};
|
|
92
193
|
}
|
|
93
|
-
const url = `url("data:image/svg+xml;utf8,${encodeSvgForCss(
|
|
194
|
+
const url = `url("data:image/svg+xml;utf8,${encodeSvgForCss(resolved.svg)}")`;
|
|
94
195
|
const varName = `--${engine.config.prefix}svg-icon-${body.replace(globalColonRE, "-")}`;
|
|
95
196
|
if (engine.variables.store.has(varName) === false) engine.variables.add({ [varName]: {
|
|
96
197
|
value: url,
|
|
@@ -100,7 +201,7 @@ function createIconsPlugin(lookupIconLoader) {
|
|
|
100
201
|
},
|
|
101
202
|
pruneUnused: true
|
|
102
203
|
} });
|
|
103
|
-
if (_mode === "auto") _mode =
|
|
204
|
+
if (_mode === "auto") _mode = currentColorRE.test(resolved.svg) ? "mask" : "bg";
|
|
104
205
|
let styleItem;
|
|
105
206
|
if (_mode === "mask") styleItem = {
|
|
106
207
|
"--svg-icon": `var(${varName})`,
|
|
@@ -110,17 +211,20 @@ function createIconsPlugin(lookupIconLoader) {
|
|
|
110
211
|
"mask-size": "100% 100%",
|
|
111
212
|
"background-color": "currentColor",
|
|
112
213
|
"color": "inherit",
|
|
113
|
-
...usedProps
|
|
214
|
+
...resolved.usedProps
|
|
114
215
|
};
|
|
115
216
|
else styleItem = {
|
|
116
217
|
"--svg-icon": `var(${varName})`,
|
|
117
218
|
"background": "var(--svg-icon) no-repeat",
|
|
118
219
|
"background-size": "100% 100%",
|
|
119
220
|
"background-color": "transparent",
|
|
120
|
-
...usedProps
|
|
221
|
+
...resolved.usedProps
|
|
121
222
|
};
|
|
122
223
|
processor?.(styleItem, {
|
|
123
|
-
|
|
224
|
+
collection: resolved.collection,
|
|
225
|
+
name: resolved.name,
|
|
226
|
+
svg: resolved.svg,
|
|
227
|
+
source: resolved.source,
|
|
124
228
|
mode: _mode
|
|
125
229
|
});
|
|
126
230
|
return styleItem;
|
|
@@ -130,6 +234,5 @@ function createIconsPlugin(lookupIconLoader) {
|
|
|
130
234
|
}
|
|
131
235
|
});
|
|
132
236
|
}
|
|
133
|
-
|
|
134
237
|
//#endregion
|
|
135
|
-
export { icons };
|
|
238
|
+
export { icons };
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikacss/plugin-icons",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.48",
|
|
5
5
|
"author": "DevilTea <ch19980814@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"homepage": "https://pikacss.com",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/pikacss/pikacss.git",
|
|
10
|
+
"url": "git+https://github.com/pikacss/pikacss.git",
|
|
10
11
|
"directory": "packages/plugin-icons"
|
|
11
12
|
},
|
|
12
13
|
"bugs": {
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
"pikacss-plugin",
|
|
21
22
|
"icons"
|
|
22
23
|
],
|
|
24
|
+
"sideEffects": false,
|
|
23
25
|
"exports": {
|
|
24
26
|
".": {
|
|
25
27
|
"import": {
|
|
@@ -36,24 +38,26 @@
|
|
|
36
38
|
"files": [
|
|
37
39
|
"dist"
|
|
38
40
|
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22"
|
|
43
|
+
},
|
|
39
44
|
"peerDependencies": {
|
|
40
|
-
"@pikacss/core": "0.0.
|
|
45
|
+
"@pikacss/core": "0.0.48"
|
|
41
46
|
},
|
|
42
47
|
"dependencies": {
|
|
43
48
|
"@iconify/utils": "^3.1.0",
|
|
44
|
-
"@unocss/preset-icons": "^66.6.1",
|
|
45
49
|
"ofetch": "^1.5.1"
|
|
46
50
|
},
|
|
47
51
|
"devDependencies": {
|
|
48
|
-
"@pikacss/core": "0.0.
|
|
52
|
+
"@pikacss/core": "0.0.48"
|
|
49
53
|
},
|
|
50
54
|
"scripts": {
|
|
51
|
-
"build": "tsdown
|
|
55
|
+
"build": "tsdown",
|
|
52
56
|
"build:watch": "tsdown --watch",
|
|
53
57
|
"typecheck": "pnpm typecheck:package && pnpm typecheck:test",
|
|
54
58
|
"typecheck:package": "tsc --project ./tsconfig.package.json --noEmit",
|
|
55
59
|
"typecheck:test": "tsc --project ./tsconfig.tests.json --noEmit",
|
|
56
|
-
"test": "vitest run",
|
|
57
|
-
"test:watch": "vitest"
|
|
60
|
+
"test": "vitest run --config ./vitest.config.ts",
|
|
61
|
+
"test:watch": "vitest --config ./vitest.config.ts"
|
|
58
62
|
}
|
|
59
63
|
}
|