@ts-svg/svelte 0.0.1-beta.0 → 0.0.1

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.
Files changed (3) hide show
  1. package/README.md +226 -0
  2. package/package.json +2 -2
  3. package/src/index.js +2 -2
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # ts-svg
2
+
3
+ Type-safe SVG bundling for Vite. `ts-svg` scans a directory (including subdirectories), generates **typed virtual modules**, and lets you import SVGs as framework components with great DX (autocomplete + type checking) and proper bundling/tree-shaking.
4
+
5
+ ## Why ts-svg?
6
+
7
+ - **Type-safe imports**: virtual modules are generated with types, so importing from `virtual:ts-svg/...` is typed.
8
+ - **Great DX**: namespace import + `<Icon.` gives instant autocomplete for every icon in that folder.
9
+ - **Optimized output**: SVGs are optimized (SVGO) and transformed into **Svelte components**.
10
+ - **Tree-shakable**: only the SVGs you actually use end up bundled.
11
+
12
+ ## Packages
13
+
14
+ - **Svelte / SvelteKit:** `@ts-svg/svelte`
15
+ - (Other framework adapters will be available soon)
16
+
17
+ ---
18
+
19
+ ## SvelteKit Setup (`@ts-svg/svelte`)
20
+
21
+ ### 1) Install
22
+
23
+ ```bash
24
+ npm i -D @ts-svg/svelte
25
+ ```
26
+
27
+ ### 2) Add the Vite plugin
28
+
29
+ Add `tsSvg()` to `vite.config.ts`. The `path` option is required.
30
+
31
+ ```ts
32
+ import { sveltekit } from '@sveltejs/kit/vite';
33
+ import { defineConfig } from 'vite';
34
+ import { tsSvg } from '@ts-svg/svelte';
35
+
36
+ export default defineConfig({
37
+ plugins: [
38
+ sveltekit(),
39
+ // Step 1: Add the vite plugin
40
+ tsSvg({
41
+ path: './src/lib/svgs',
42
+ // svgoConfig: {...} // optional: override default SVGO config
43
+ }),
44
+ ],
45
+ });
46
+ ```
47
+
48
+ `path` is the folder to scan. All `.svg` files inside it (and subfolders) become typed virtual modules.
49
+
50
+ ### 3) Reference the generated ambient types
51
+
52
+ In `src/app.d.ts`, add a reference to the generated `ambient.d.ts`:
53
+
54
+ ```ts
55
+ // Step 2: Import the generated types
56
+ /// <reference types="../.ts-svg/ambient.d.ts" />
57
+ ```
58
+
59
+ ### 4) Ignore the generated directory
60
+
61
+ Add `.ts-svg` to both `.gitignore` and `.prettierignore`:
62
+
63
+ ```gitignore
64
+ .ts-svg
65
+ ```
66
+
67
+ ### 5) Generate types in CI (recommended)
68
+
69
+ In CI (or any non-dev environment), you may not want to rely on the dev server to trigger generation.
70
+ Prepend the CLI `ts-svg` in `package.json` scripts that run in CI:
71
+
72
+ ```json
73
+ {
74
+ "scripts": {
75
+ "prepare": "ts-svg && svelte-kit sync || echo ''",
76
+ "check": "ts-svg && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
77
+ "check:watch": "ts-svg && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
78
+ }
79
+ }
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Usage
85
+
86
+ Put SVGs under the directory you configured (e.g. `./src/lib/svgs`).
87
+
88
+ Then import from `virtual:ts-svg`:
89
+
90
+ - Root folder: `virtual:ts-svg`
91
+ - Subfolder: `virtual:ts-svg/<subfolder>`
92
+
93
+ ### Recommended: namespace import for icon folders
94
+
95
+ If you have `./src/lib/svgs/icons/*.svg`:
96
+
97
+ ```svelte
98
+ <script lang="ts">
99
+ import * as Icon from 'virtual:ts-svg/icons'; // recommended
100
+ // or import one-by-one:
101
+ import { Home } from 'virtual:ts-svg/icons';
102
+ </script>
103
+
104
+ <Icon.Book class="size-200" />
105
+ <Home />
106
+
107
+ <style>
108
+ :global(.size-200) {
109
+ width: 200px;
110
+ height: 200px;
111
+ }
112
+
113
+ :global(svg) {
114
+ width: 150px;
115
+ height: 150px;
116
+ }
117
+ </style>
118
+ ```
119
+
120
+ Typing `<Icon.` will show all icons in autocomplete.
121
+
122
+ ### Props
123
+
124
+ Imported SVGs are Svelte components and accept normal props (e.g. `class`, `style`, etc.).
125
+
126
+ For a complete SvelteKit example (config, generated types, and usage), see the sample setup here: [examples/sveltekit](https://github.com/chunnamwong/ts-svg/tree/main/examples/svelte).
127
+
128
+ ---
129
+
130
+ ## Tip: Create a local re-export for nicer imports
131
+
132
+ If it’s hard to remember import paths like `virtual:ts-svg/icons`, you can create a local module and re-export your namespace.
133
+
134
+ Create `src/lib/Icon.ts`:
135
+
136
+ ```ts
137
+ export * as Icon from 'virtual:ts-svg/icons';
138
+ ```
139
+
140
+ Then import from your app code:
141
+
142
+ ```svelte
143
+ <script lang="ts">
144
+ import { Icon } from '$lib/Icon';
145
+ </script>
146
+ ```
147
+
148
+ You can do the same pattern for other subdirectories (e.g. `brand`, `images`, etc.):
149
+
150
+ ---
151
+
152
+ ## Configuration
153
+
154
+ ### `path` (required)
155
+
156
+ The directory to scan for `.svg` files.
157
+
158
+ ### `svgoConfig` (optional)
159
+
160
+ Override the default SVGO configuration used during optimization.
161
+
162
+ ```ts
163
+ tsSvg({
164
+ path: './src/lib/svgs',
165
+ svgoConfig: {
166
+ // your custom svgo config
167
+ },
168
+ });
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Generated output
174
+
175
+ `ts-svg` generates this file:
176
+
177
+ - `.ts-svg/ambient.d.ts` (referenced from `src/app.d.ts`)
178
+
179
+ ---
180
+
181
+ ## FAQ
182
+
183
+ ### Do I need to commit `.ts-svg`?
184
+
185
+ No. It’s generated output. Add it to `.gitignore` and regenerate it in CI using `ts-svg` in your scripts.
186
+
187
+ ### How do subfolders map to imports?
188
+
189
+ A subfolder becomes an import path segment.
190
+
191
+ Example:
192
+
193
+ - `src/lib/svgs/icons/Home.svg` → `import { Home } from 'virtual:ts-svg/icons'`
194
+
195
+ ### How do I stay safe with tree shaking?
196
+
197
+ Tree-shaking works best when the bundler can see **exactly which exports you use**.
198
+
199
+ If you use a namespace import:
200
+
201
+ ```ts
202
+ import * as Icon from 'virtual:ts-svg/icons';
203
+ ```
204
+
205
+ ✅ **Do** access **specific exports**:
206
+
207
+ ```svelte
208
+ <Icon.Home />
209
+ <Icon.Book />
210
+ ```
211
+
212
+ ⚠️ **Don’t** pass around or “touch” the whole namespace object (e.g. iterating keys, spreading, or indexing dynamically). If the bundler detects the namespace object itself is used as a value, it may conservatively treat **all exports as used**, which can cause **all icons to be bundled**, even if you only use a few.
213
+
214
+ Examples to avoid:
215
+
216
+ ```ts
217
+ Object.keys(Icon); // iterating namespace
218
+ const Comp = Icon[name]; // dynamic access
219
+ const list = { ...Icon }; // spreading namespace
220
+ ```
221
+
222
+ ---
223
+
224
+ ## License
225
+
226
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ts-svg/svelte",
3
- "version": "0.0.1-beta.0",
3
+ "version": "0.0.1",
4
4
  "description": "Vite Plugin for loading all svg files inside a folder with types.",
5
5
  "keywords": [
6
6
  "vite-plugin",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "svgo": "^4.0.0",
36
- "@ts-svg/core": "^0.0.1-beta.0"
36
+ "@ts-svg/core": "^0.0.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^24.6.0"
package/src/index.js CHANGED
@@ -45,7 +45,7 @@ declare module '*.svg?svelte' {
45
45
  export default component;
46
46
  }
47
47
  `,
48
- async transform(_code, id) {
48
+ async transform(_code, id, options) {
49
49
  if (!id.endsWith('.svg?svelte')) {
50
50
  return;
51
51
  }
@@ -57,7 +57,7 @@ declare module '*.svg?svelte' {
57
57
  );
58
58
  const componentCode = optimizedSvgSource.replace(/<svg([^>]*)>/, '<svg$1 {...$$$$props}>');
59
59
  const component = compile(componentCode, {
60
- generate: this.environment.name === 'ssr' ? 'server' : undefined,
60
+ generate: options?.ssr ? 'server' : undefined,
61
61
  });
62
62
  return {
63
63
  code: component.js.code,