better-svelte-email 1.3.2 → 1.4.0

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.
@@ -192,29 +192,72 @@ function parseRgbValues(nodes) {
192
192
  }
193
193
  function transformColorMix(node) {
194
194
  // We're expecting the structure to be something like:
195
- // color-mix(in oklab, rgb(...) X%, transparent)
195
+ // color-mix(in oklab, <color> X%, transparent)
196
196
  // Check if it ends with transparent
197
197
  const lastNode = node.nodes[node.nodes.length - 1];
198
198
  if (lastNode?.type !== 'word' || lastNode.value !== 'transparent') {
199
199
  return null;
200
200
  }
201
- // Find the rgb function and percentage
202
- let rgbFunc = null;
201
+ // Find the color (rgb, oklch function, or hex) and percentage
202
+ let colorFunc = null;
203
+ let colorHex = null;
203
204
  let percentage = null;
204
205
  for (const child of node.nodes) {
205
- if (child.type === 'function' && child.value === 'rgb') {
206
- rgbFunc = child;
206
+ if (child.type === 'function' && (child.value === 'rgb' || child.value === 'oklch')) {
207
+ colorFunc = child;
208
+ }
209
+ if (child.type === 'word' && child.value.startsWith('#')) {
210
+ colorHex = child.value;
207
211
  }
208
212
  if (child.type === 'word' && child.value.endsWith('%')) {
209
213
  percentage = parseFloat(child.value) / 100;
210
214
  }
211
215
  }
212
- if (rgbFunc && percentage !== null) {
213
- const rgbValues = parseRgbValues(rgbFunc.nodes);
214
- if (rgbValues.r !== undefined && rgbValues.g !== undefined && rgbValues.b !== undefined) {
215
- return formatRgb(rgbValues.r, rgbValues.g, rgbValues.b, percentage);
216
+ // Convert color to RGB
217
+ let rgb = null;
218
+ if (colorFunc) {
219
+ if (colorFunc.value === 'rgb') {
220
+ const rgbValues = parseRgbValues(colorFunc.nodes);
221
+ if (rgbValues.r !== undefined && rgbValues.g !== undefined && rgbValues.b !== undefined) {
222
+ rgb = {
223
+ r: rgbValues.r,
224
+ g: rgbValues.g,
225
+ b: rgbValues.b,
226
+ a: rgbValues.a
227
+ };
228
+ }
229
+ }
230
+ else if (colorFunc.value === 'oklch') {
231
+ const oklchValues = parseOklchValues(colorFunc.nodes);
232
+ if (oklchValues.l !== undefined &&
233
+ oklchValues.c !== undefined &&
234
+ oklchValues.h !== undefined) {
235
+ const convertedRgb = oklchToRgb({
236
+ l: oklchValues.l,
237
+ c: oklchValues.c,
238
+ h: oklchValues.h
239
+ });
240
+ rgb = {
241
+ r: convertedRgb.r,
242
+ g: convertedRgb.g,
243
+ b: convertedRgb.b,
244
+ a: oklchValues.a
245
+ };
246
+ }
216
247
  }
217
248
  }
249
+ else if (colorHex) {
250
+ rgb = hexToRgb(colorHex);
251
+ }
252
+ if (rgb && percentage !== null) {
253
+ // Blend color with white background (transparent in email context = white)
254
+ // Formula: final = color * percentage + white * (1 - percentage)
255
+ const blendedR = rgb.r * percentage + 255 * (1 - percentage);
256
+ const blendedG = rgb.g * percentage + 255 * (1 - percentage);
257
+ const blendedB = rgb.b * percentage + 255 * (1 - percentage);
258
+ // Return solid RGB without alpha (email clients don't support alpha)
259
+ return formatRgb(blendedR, blendedG, blendedB);
260
+ }
218
261
  return null;
219
262
  }
220
263
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "better-svelte-email",
3
3
  "description": "Svelte email renderer with Tailwind support",
4
- "version": "1.3.2",
4
+ "version": "1.4.0",
5
5
  "author": "Konixy",
6
6
  "repository": {
7
7
  "type": "git",
@@ -25,21 +25,21 @@
25
25
  "tailwindcss": "^4.1.18"
26
26
  },
27
27
  "optionalDependencies": {
28
- "prettier": "^3.7.4",
29
- "resend": "^6.7.0",
28
+ "prettier": "^3.8.1",
29
+ "resend": "^6.8.0",
30
30
  "shiki": "^3.21.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@eslint/compat": "^2.0.1",
34
34
  "@eslint/js": "^9.39.2",
35
35
  "@sveltejs/adapter-vercel": "^6.3.0",
36
- "@sveltejs/kit": "^2.49.4",
36
+ "@sveltejs/kit": "^2.50.0",
37
37
  "@sveltejs/package": "^2.5.7",
38
38
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
39
39
  "@tailwindcss/vite": "^4.1.18",
40
40
  "@types/html-to-text": "^9.0.4",
41
- "@types/node": "24",
42
- "@vitest/coverage-v8": "^4.0.17",
41
+ "@types/node": "24.10.9",
42
+ "@vitest/coverage-v8": "^4.0.18",
43
43
  "eslint": "^9.39.2",
44
44
  "eslint-config-prettier": "^10.1.8",
45
45
  "eslint-plugin-svelte": "^3.14.0",
@@ -48,16 +48,16 @@
48
48
  "mode-watcher": "^1.1.0",
49
49
  "prettier-plugin-svelte": "^3.4.1",
50
50
  "prettier-plugin-tailwindcss": "^0.7.2",
51
- "publint": "^0.3.16",
51
+ "publint": "^0.3.17",
52
52
  "rehype-autolink-headings": "^7.1.0",
53
53
  "rehype-slug": "^6.0.0",
54
- "svelte": "5.46.3",
54
+ "svelte": "5.48.0",
55
55
  "svelte-check": "^4.3.5",
56
56
  "tailwindcss-motion": "^1.1.1",
57
57
  "typescript": "^5.9.3",
58
- "typescript-eslint": "^8.53.0",
58
+ "typescript-eslint": "^8.53.1",
59
59
  "vite": "^7.3.1",
60
- "vitest": "^4.0.17"
60
+ "vitest": "^4.0.18"
61
61
  },
62
62
  "exports": {
63
63
  ".": {