You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

@neodx/svg

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@neodx/svg - npm Package Compare versions

Comparing version

to
0.2.0

dist/_internal/build-sprites-78334e39.cjs

82

dist/index.d.ts

@@ -1,39 +0,14 @@

import { Command } from 'commander';
import { LoggerMethods } from '@neodx/log';
import { VFS } from '@neodx/vfs';
import { C as CreateSpriteBuilderParams, S as SpriteBuilder } from './_internal/create-sprite-builder-f5d1f843.js';
export { c as createSpriteBuilder } from './_internal/create-sprite-builder-f5d1f843.js';
import * as chokidar from 'chokidar';
import { S as SvgSpritePluginHooks, a as SvgSpritePlugin } from './_internal/reset-colors-3b2e91d7.js';
export { C as Context, c as SpriteGroup, b as SpriteGroupsMap, d as SvgFile, e as SvgNode } from './_internal/reset-colors-3b2e91d7.js';
export { i as plugins } from './_internal/index-1523c0b0.js';
declare function createCli(cwd?: string): Command;
interface GenerateParams {
vfs: VFS;
interface GenerateParams extends CreateSpriteBuilderParams {
/**
* Logger instance
*/
logger?: LoggerMethods<'info' | 'debug'>;
/**
* Globs to icons files
*/
input: string[];
input: string | string[];
/**
* Path to generated sprite/sprites folder
*/
output: string;
/**
* Root folder for inputs, useful for correct groups naming
*/
root?: string;
/**
* Should we group icons?
* @default false
*/
group?: boolean;
/**
* Template of sprite file name
* @example {name}.svg
* @example sprite-{name}.svg
*/
fileName?: string;
optimize?: boolean;
definitions?: string;
/**
* Keep tree changes after generation even if dry-run mode is enabled

@@ -43,4 +18,2 @@ * Useful for testing (for example, to check what EXACTLY was changed)

keepTreeChanges?: boolean;
resetColorValues?: string[];
resetColorProperties?: string[];
}

@@ -51,38 +24,13 @@ /**

*/
declare function generateSvgSprites({ vfs, input, logger, group: enableGroup, root, optimize, definitions, resetColorValues, resetColorProperties, output, fileName, keepTreeChanges }: GenerateParams): Promise<void>;
declare function buildSprites({ vfs, logger, input, keepTreeChanges, ...builderParams }: GenerateParams): Promise<void>;
interface Context {
vfs: VFS;
interface CreateWatcherParams {
builder: SpriteBuilder;
root: string;
input: string | string[];
}
interface SvgSpritePlugin extends Partial<SvgSpritePluginHooks> {
name: string;
}
interface SvgSpritePluginHooks {
afterWrite(groups: SpriteGroupsMap, context: Context): unknown | Promise<unknown>;
afterWriteGroup(group: SpriteGroup, context: Context): unknown | Promise<unknown>;
resolveEntriesMap(groups: SpriteGroupsMap, context: Context): SpriteGroupsMap;
transformNode(node: SvgFile): SvgNode;
transformSourceContent(path: string, content: string): string | Promise<string>;
transformOutputEntryContent(content: string): string | Promise<string>;
}
type SpriteGroupsMap = Map<string, SpriteGroup>;
interface SpriteGroup {
name: string;
files: SvgFile[];
}
interface SvgFile {
node: SvgNode;
path: string;
name: string;
}
interface SvgNode {
name: string;
type: string;
value: string;
children: SvgNode[];
attributes: Record<string, string>;
}
declare function createWatcher({ root, input, builder }: CreateWatcherParams): chokidar.FSWatcher;
declare function createPlugin(name: string, hooks: Partial<SvgSpritePluginHooks>): SvgSpritePlugin;
export { GenerateParams, SvgFile, SvgNode, SvgSpritePlugin, SvgSpritePluginHooks, createCli, createPlugin, generateSvgSprites };
export { CreateSpriteBuilderParams, CreateWatcherParams, GenerateParams, SpriteBuilder, SvgSpritePlugin, SvgSpritePluginHooks, buildSprites, createPlugin, createWatcher };
{
"name": "@neodx/svg",
"packageManager": "yarn@3.2.0",
"version": "0.1.9",
"version": "0.2.0",
"description": "Supercharge your icons ⚡️",

@@ -31,3 +31,12 @@ "author": {

],
"source": "src/index.ts",
"source": [
"src/index.ts",
"src/cli.ts",
"src/esbuild.ts",
"src/rollup.ts",
"src/rspack.ts",
"src/vite.ts",
"src/webpack.ts",
"src/plugins/index.ts"
],
"type": "module",

@@ -54,7 +63,10 @@ "main": "./dist/index.cjs",

"dependencies": {
"@neodx/fs": "*",
"@neodx/log": "*",
"@neodx/std": "*",
"@neodx/vfs": "*",
"@neodx/fs": "^0.0.8",
"@neodx/log": "^0.1.7",
"@neodx/std": "^0.1.4",
"@neodx/vfs": "^0.1.7",
"chokidar": "^3.5.3",
"colord": "2.9.3",
"commander": "10.0.1",
"pathe": "^1.1.0",
"react": "^18.2.0",

@@ -64,2 +76,3 @@ "react-dom": "^18.2.0",

"svgson": "^5.2.1",
"unplugin": "^1.3.1",
"zod": "^3.21.4"

@@ -81,4 +94,39 @@ },

"require": "./dist/index.cjs"
},
"./cli": {
"types": "./dist/cli.d.ts",
"import": "./dist/cli.mjs",
"require": "./dist/cli.cjs"
},
"./plugins": {
"types": "./dist/plugins/index.d.ts",
"import": "./dist/plugins/index.mjs",
"require": "./dist/plugins/index.cjs"
},
"./esbuild": {
"types": "./dist/esbuild.d.ts",
"require": "./dist/esbuild.cjs",
"default": "./dist/esbuild.mjs"
},
"./rollup": {
"types": "./dist/rollup.d.ts",
"require": "./dist/rollup.cjs",
"default": "./dist/rollup.mjs"
},
"./rspack": {
"types": "./dist/rspack.d.ts",
"require": "./dist/rspack.cjs",
"default": "./dist/rspack.mjs"
},
"./vite": {
"types": "./dist/vite.d.ts",
"require": "./dist/vite.cjs",
"default": "./dist/vite.mjs"
},
"./webpack": {
"types": "./dist/webpack.d.ts",
"require": "./dist/webpack.cjs",
"default": "./dist/webpack.mjs"
}
}
}

@@ -27,5 +27,6 @@ # @neodx/svg

- TypeScript support out of box - generated types and information about your sprites
- Built-in plugins for all major bundlers: `vite`, `webpack`, `rollup`, `esbuild`, etc.
- Optional grouping by folders
- Optimization with svgo
- Built-in colors reset
- Flexible colors reset
- Powerful files selection

@@ -44,4 +45,11 @@

You can try it even without any configuration, just run `sprite` command:
### CLI Mode
> **Warning:**
> While the CLI mode is currently available, it's not the recommended method of use and might be removed in future major versions.
>
> Now we're providing built-it bundlers integration, please, use [our plugin](#plugins) instead.
To get started, you can try the CLI mode even without any configuration, just run `sprite` command:
```shell

@@ -51,36 +59,164 @@ yarn sprite

It will search for all SVG files except files in `public/sprites` folder and generate sprites in `public/sprites`.
This command searches for all SVG files, excluding those in the `public/sprites` folder and generate sprites in `public/sprites`.
In default mode, it will be the single sprite with all icons without grouping and TS definitions, but you can customize it, see below.
By default, it creates a single sprite containing all icons without any grouping or TS definitions. However, this can be customized. See [CLI options](#cli-options) for more information
## Options
### Plugins
| option | default | description |
| -------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `-i`, `--input` | `"**/*.svg"` | Glob paths to icons files (output path will be automatically excluded) |
| `-o`, `--output` | `"public/sprites"` | Base path to generated sprite/sprites folder |
| `-d`, `--definitions` | Not provided (**disabled**) | Path to generated TS file with sprite meta |
| `--root` | `"."` (same as the current dir) | Base path to your assets, useful for correct groups names<br/>**careful:** `--input` should be relative to `--root` |
| `--group` | `false` | Should we group icons by folders? |
| `--dry-run` | `false` | Print proposal of generated file paths without actually generating it |
| `--optimize` | `true` | Should we optimize SVG with [svgo](https://github.com/svg/svgo)? |
| `--reset-color-values` | `"#000,#000000"` | An array of colors to replace as `currentColor` |
| `--reset-color-properties` | `"fill,stroke"` | An array of SVG properties that will be replaced with `currentColor` if they're present |
Our plugins provide a consistent interface and working principle across all major bundlers.
> **Note:** `--reset-color-values` and `--reset-color-properties` are strings with comma-separated values, don't forget to wrap them with quotes:
>
> `sprite ... --reset-color-values "#000,#000000,#fff"`
For instance, here's an example of `vite` plugin with some options:
```typescript
import svg from '@neodx/svg/vite';
export default defineConfig({
plugins: [
svg({
root: 'assets',
group: true,
output: 'public',
definitions: 'src/shared/ui/icon/sprite.h.ts',
resetColors: {
replaceUnknown: 'currentColor'
}
})
]
});
```
It will search for all SVG files in `assets` folder, group them by folders, optimize them with `svgo`,
reset all colors to `currentColor` and generate sprites in `public` folder with TS definitions in `src/shared/ui/icon/sprite.h.ts`.
For more details see our [Step-by-step guide](#step-by-step).
Another plugins:
<details>
<summary>Webpack</summary>
```typescript
import svg from '@neodx/svg/webpack';
export default {
plugins: [
svg({
root: 'assets',
output: 'public',
definition: 'src/shared/ui/icon/sprite.h.ts'
})
]
};
```
</details>
<details>
<summary>Rollup</summary>
```typescript
import svg from '@neodx/svg/rollup';
export default {
plugins: [
svg({
root: 'assets',
output: 'public',
definition: 'src/shared/ui/icon/sprite.h.ts'
})
]
};
```
</details>
<details>
<summary>ESBuild</summary>
```typescript
import svg from '@neodx/svg/esbuild';
export default {
plugins: [
svg({
root: 'assets',
output: 'public',
definition: 'src/shared/ui/icon/sprite.h.ts'
})
]
};
```
</details>
## Step-by-step
Our example stack details:
- `vite`
- `react`
- `typescript`
- `tailwindcss`
We'll be working with the following icons in our project:
```diff
assets/
common/
add.svg
close.svg
other/
cut.svg
search.svg
```
We want to generate separate sprites for each folder and use them in our React components.
### Build icons
Firstly, we adopt configuration from [Plugins](#plugins) section:
```typescript
import svg from '@neodx/svg/vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
plugins: [
react(),
tsconfigPaths(),
svg({
root: 'assets',
group: true,
output: 'public',
definitions: 'src/shared/ui/icon/sprite.h.ts',
resetColors: {
replaceUnknown: 'currentColor'
}
})
]
});
```
<details>
<summary>If you decided to use CLI mode:</summary>
Let's run `sprite` with some additional options:
```bash
yarn sprite --group --root assets -o public/sprite -d src/shared/ui/icon/sprite.h.ts
yarn sprite --group --root assets -o public/sprite -d src/shared/ui/icon/sprite.h.ts --reset-unknown-colors
```
As a result, we will get:
In details:
- The `--group` option group icons by folders (`common` and `other`)
- The `--root` option sets `assets` as a base path for icons (you can try to remove it and see the difference)
- The `-o` option sets `public/sprite` as a base path for generated sprites (it's default value, but let's keep it for now)
- The `-d` option generates TS definitions file with sprite meta information
</details>
Now let's run `vite` (or `vite build`) and see what we have:
```diff

@@ -96,18 +232,6 @@ ...

+ other.svg
assets/
common/
add.svg
close.svg
other/
cut.svg
search.svg
```
In details:
For each folder in `assets`, a separate sprite is created, along with a TS definitions file containing metadata about all icons.
- with `--group` option we will group icons by folders (`common` and `other`)
- with `--root` option we will use `assets` as a base path for icons (you can try to remove it and see the difference)
- with `-o` option we will use `public/sprite` as a base path for generated sprites (it's default value, but let's keep it for now)
- with `-d` option we will generate TS definitions file with sprite meta
### Look at generated TS definitions

@@ -171,4 +295,27 @@

### Real Icon component ([see example](./examples/react))
### Building Icon component with TailwindCSS ([see example](./examples/react))
#### Add base `icon` class
```css
/* shared/ui/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
/*
Our base class for all icons, includes:
- `fill-current` - fill icon with current text color, so we can use `color` to change it
- `w-[1em] h-[1em]` - set icon size to 1em, so we can use `font-size` to scale it
- `box-content` - it's up to you, I choose it to keep icon size fixed
*/
.icon {
@apply select-none fill-current w-[1em] h-[1em] inline-block text-inherit box-content;
}
}
```
#### Add `Icon` component
```tsx

@@ -180,3 +327,4 @@ // shared/ui/icon/icon.tsx

export type SpriteKey = {
// Merging all icons as `SPRITE_NAME/SPRITE_ICON_NAME`
export type IconName = {
[Key in keyof SpritesMap]: `${Key}/${SpritesMap[Key]}`;

@@ -186,3 +334,3 @@ }[keyof SpritesMap];

export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'name' | 'type'> {
name: SpriteKey;
name: IconName;
}

@@ -195,6 +343,4 @@

<svg
className={clsx(
'select-none fill-current w-[1em] h-[1em] inline-block text-inherit',
className
)}
// We recommend to use specific component class for avoid collisions with other styles and simple override it
className={clsx('icon', className)}
viewBox={viewBox}

@@ -205,3 +351,4 @@ focusable="false"

>
<use xlinkHref={`/path/to/sprites/${spriteName}.svg#${iconName}`} />
{/* For example, "/common.svg#favourite". Change base path if you don't store sprites under the root. */}
<use xlinkHref={`/${spriteName}.svg#${iconName}`} />
</svg>

@@ -221,4 +368,5 @@ );

<Icon name="common/add" />
<Icon name="common/close" />
<Icon name="other/search" />
<Icon name="common/close" className="text-red-500" />
<Icon name="text/bold" className="text-lg" />
<Icon name="actions/delete" className="p-2 rounded-md bg-stone-300" />
</div>

@@ -228,1 +376,95 @@ );

```
### Multiple colors
Let's imagine that we have a really different icons with next requirements:
- We have some known list of the accent colors, and we want to specify them in our CSS
- All other colors should be inherited from the parent (for example, `currentColor`)
#### Configure `resetColors` option
```typescript
import svg from '@neodx/svg/vite';
svg({
// ...
resetColors: {
// 1. Define known accent colors
replace: {
from: ['#6C707E', '#A8ADBD', '#818594'],
to: 'var(--icon-accent-color)'
},
// 2. Replace all other colors with `currentColor`
replaceUnknown: 'currentColor'
}
});
```
#### Add CSS variables
```css
/* shared/ui/index.css */
@layer base {
:root {
/* make default accent color */
--icon-primary-color: #6c707e;
}
}
```
#### Usage
Dirty but works 🫢
Probably, you can find a better solution 🫠
```tsx
import { Icon } from '@/shared/ui';
export function SomeFeature() {
return (
<Icon
name="common/add"
className="text-red-800 [--icon-primary-color:theme(colors.green.800)]"
/>
);
}
```
## API
### Node.JS API
```typescript
import { buildSprites } from '@neodx/svg';
import { createVfs } from '@neodx/vfs';
await buildSprites({
vfs: createVfs(process.cwd()),
root: 'assets',
input: '**/*.svg',
output: 'public',
definition: 'src/shared/ui/icon/sprite.h.ts'
});
```
### CLI Options
| option | default | description |
| -------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `-i`, `--input` | `"**/*.svg"` | Glob paths to icons files (output path will be automatically excluded) |
| `-o`, `--output` | `"public/sprites"` | Base path to generated sprite/sprites folder |
| `-d`, `--definitions` | Not provided (**disabled**) | Path to generated TS file with sprite meta |
| `--root` | `"."` (same as the current dir) | Base path to your assets, useful for correct groups names<br/>**careful:** `--input` should be relative to `--root` |
| `--group` | `false` | Should we group icons by folders? |
| `--dry-run` | `false` | Print proposal of generated file paths without actually generating it |
| `--optimize` | `true` | Should we optimize SVG with [svgo](https://github.com/svg/svgo)? |
| `--reset-color-values` | `"#000,#000000"` | An array of colors to replace as `currentColor` |
| `--reset-unknown-colors` | `false` | Should we set `currentColor` for all colors not defined in `--reset-color-values`, or for all colors if this option isn't provided? |
| `--reset-color-properties` | `"fill,stroke"` | An array of SVG properties that will be replaced with `currentColor` if they're present |
> **Note:** `--reset-color-values` and `--reset-color-properties` are strings with comma-separated values, don't forget to wrap them with quotes:
>
> `sprite ... --reset-color-values "#000,#000000,#fff"`

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet