@tokens-studio/tokenscript-schemas 0.0.13 → 0.1.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.
Files changed (153) hide show
  1. package/README.md +21 -0
  2. package/bundled/functions/adjust_chroma.json +60 -0
  3. package/bundled/functions/adjust_hue.json +60 -0
  4. package/bundled/functions/adjust_lightness.json +60 -0
  5. package/bundled/functions/adjust_to_contrast.json +67 -0
  6. package/bundled/functions/alpha_blend.json +31 -0
  7. package/bundled/functions/alpha_scale.json +27 -0
  8. package/bundled/functions/analogous.json +32 -0
  9. package/bundled/functions/apca_contrast.json +27 -0
  10. package/bundled/functions/are_similar.json +73 -0
  11. package/bundled/functions/auto_text_color.json +66 -0
  12. package/bundled/functions/best_contrast.json +28 -0
  13. package/bundled/functions/chroma.json +54 -0
  14. package/bundled/functions/clamp_chroma.json +66 -0
  15. package/bundled/functions/clamp_lightness.json +66 -0
  16. package/bundled/functions/clamp_to_gamut.json +23 -0
  17. package/bundled/functions/complement.json +24 -0
  18. package/bundled/functions/contrast_ratio.json +27 -0
  19. package/bundled/functions/cooler.json +52 -0
  20. package/bundled/functions/darken.json +28 -0
  21. package/bundled/functions/delta_e_2000.json +40 -0
  22. package/bundled/functions/delta_e_76.json +27 -0
  23. package/bundled/functions/delta_e_ok.json +27 -0
  24. package/bundled/functions/desaturate.json +28 -0
  25. package/bundled/functions/distributed.json +36 -0
  26. package/bundled/functions/diverging.json +36 -0
  27. package/bundled/functions/grayscale.json +24 -0
  28. package/bundled/functions/harmonize.json +65 -0
  29. package/bundled/functions/hue.json +54 -0
  30. package/bundled/functions/hue_difference.json +27 -0
  31. package/bundled/functions/in_gamut.json +27 -0
  32. package/bundled/functions/interpolate.json +66 -0
  33. package/bundled/functions/invert.json +1 -1
  34. package/bundled/functions/is_cool.json +23 -0
  35. package/bundled/functions/is_dark.json +27 -0
  36. package/bundled/functions/is_light.json +27 -0
  37. package/bundled/functions/is_neutral.json +65 -0
  38. package/bundled/functions/is_warm.json +23 -0
  39. package/bundled/functions/lighten.json +28 -0
  40. package/bundled/functions/lightness.json +61 -0
  41. package/bundled/functions/luminance.json +23 -0
  42. package/bundled/functions/meets_contrast.json +31 -0
  43. package/bundled/functions/mix.json +32 -0
  44. package/bundled/functions/monochromatic.json +28 -0
  45. package/bundled/functions/muted.json +59 -0
  46. package/bundled/functions/neutral_variant.json +59 -0
  47. package/bundled/functions/relative_luminance.json +61 -0
  48. package/bundled/functions/rotate_hue.json +28 -0
  49. package/bundled/functions/saturate.json +28 -0
  50. package/bundled/functions/scale_chroma.json +60 -0
  51. package/bundled/functions/scale_lightness.json +60 -0
  52. package/bundled/functions/sepia.json +59 -0
  53. package/bundled/functions/set_chroma.json +28 -0
  54. package/bundled/functions/set_hue.json +28 -0
  55. package/bundled/functions/set_lightness.json +28 -0
  56. package/bundled/functions/shade_scale.json +28 -0
  57. package/bundled/functions/split_complement.json +28 -0
  58. package/bundled/functions/steps.json +32 -0
  59. package/bundled/functions/tetradic.json +24 -0
  60. package/bundled/functions/tint_scale.json +36 -0
  61. package/bundled/functions/to_gamut.json +59 -0
  62. package/bundled/functions/triadic.json +24 -0
  63. package/bundled/functions/vibrant.json +59 -0
  64. package/bundled/functions/warmer.json +52 -0
  65. package/bundled/functions/wcag_level.json +60 -0
  66. package/bundled/functions.json +2602 -6
  67. package/bundled/registry.json +3705 -84
  68. package/bundled/types/css-color.json +151 -0
  69. package/bundled/types/hsl-color.json +66 -0
  70. package/bundled/types/hsv-color.json +57 -0
  71. package/bundled/types/hwb-color.json +66 -0
  72. package/bundled/types/lab-color.json +57 -0
  73. package/bundled/types/lch-color.json +57 -0
  74. package/bundled/types/okhsl-color.json +57 -0
  75. package/bundled/types/okhsv-color.json +57 -0
  76. package/bundled/types/oklab-color.json +87 -0
  77. package/bundled/types/oklch-color.json +57 -0
  78. package/bundled/types/p3-color.json +57 -0
  79. package/bundled/types/p3-linear-color.json +57 -0
  80. package/bundled/types/rgb-color.json +12 -3
  81. package/bundled/types/srgb-color.json +77 -0
  82. package/bundled/types/srgb-linear-color.json +67 -0
  83. package/bundled/types/xyz-d50-color.json +57 -0
  84. package/bundled/types/xyz-d65-color.json +77 -0
  85. package/bundled/types.json +1067 -43
  86. package/dist/cli/index.cjs +231 -22
  87. package/dist/cli/index.cjs.map +1 -1
  88. package/dist/cli/index.js +231 -22
  89. package/dist/cli/index.js.map +1 -1
  90. package/dist/index.cjs +5 -2
  91. package/dist/index.cjs.map +1 -1
  92. package/dist/index.d.cts +4 -1
  93. package/dist/index.d.ts +4 -1
  94. package/dist/index.js +5 -2
  95. package/dist/index.js.map +1 -1
  96. package/package.json +4 -2
  97. package/src/bundler/index.ts +7 -0
  98. package/src/bundler/presets/css.ts +21 -0
  99. package/src/bundler/presets/index.ts +47 -0
  100. package/src/bundler/presets/types.ts +10 -0
  101. package/src/bundler/selective-bundler.ts +9 -0
  102. package/src/bundler/types.ts +1 -0
  103. package/src/cli/commands/bundle.test.ts +34 -0
  104. package/src/cli/commands/bundle.ts +37 -11
  105. package/src/cli/commands/list.ts +36 -4
  106. package/src/cli/commands/presets.ts +81 -0
  107. package/src/cli/index.ts +12 -1
  108. package/src/cli/output-generator.ts +8 -2
  109. package/src/cli/version-info.ts +93 -0
  110. package/src/schemas/types/css-color/from-hsl-color.tokenscript +17 -4
  111. package/src/schemas/types/css-color/from-hwb-color.tokenscript +17 -4
  112. package/src/schemas/types/css-color/from-lab-color.tokenscript +17 -4
  113. package/src/schemas/types/css-color/from-lch-color.tokenscript +17 -4
  114. package/src/schemas/types/css-color/from-oklab-color.tokenscript +17 -4
  115. package/src/schemas/types/css-color/from-oklch-color.tokenscript +17 -4
  116. package/src/schemas/types/css-color/from-p3-color.tokenscript +17 -4
  117. package/src/schemas/types/css-color/from-rgb-color.tokenscript +17 -4
  118. package/src/schemas/types/css-color/from-srgb-color.tokenscript +17 -4
  119. package/src/schemas/types/css-color/from-xyz-d50-color.tokenscript +17 -4
  120. package/src/schemas/types/css-color/from-xyz-d65-color.tokenscript +17 -4
  121. package/src/schemas/types/css-color/unit.test.ts +216 -0
  122. package/src/schemas/types/hex-color/unit.test.ts +18 -0
  123. package/src/schemas/types/hsl-color/hsla-initializer.tokenscript +17 -0
  124. package/src/schemas/types/hsl-color/initializer.tokenscript +6 -1
  125. package/src/schemas/types/hsl-color/schema.json +9 -0
  126. package/src/schemas/types/hsl-color/unit.test.ts +95 -1
  127. package/src/schemas/types/hsv-color/initializer.tokenscript +6 -1
  128. package/src/schemas/types/hsv-color/unit.test.ts +44 -0
  129. package/src/schemas/types/hwb-color/hwba-initializer.tokenscript +17 -0
  130. package/src/schemas/types/hwb-color/initializer.tokenscript +6 -1
  131. package/src/schemas/types/hwb-color/schema.json +9 -0
  132. package/src/schemas/types/hwb-color/unit.test.ts +70 -0
  133. package/src/schemas/types/lab-color/initializer.tokenscript +6 -1
  134. package/src/schemas/types/lab-color/unit.test.ts +44 -0
  135. package/src/schemas/types/lch-color/initializer.tokenscript +6 -1
  136. package/src/schemas/types/lch-color/unit.test.ts +44 -0
  137. package/src/schemas/types/okhsl-color/initializer.tokenscript +8 -1
  138. package/src/schemas/types/okhsl-color/unit.test.ts +37 -0
  139. package/src/schemas/types/okhsv-color/initializer.tokenscript +8 -1
  140. package/src/schemas/types/okhsv-color/unit.test.ts +37 -0
  141. package/src/schemas/types/oklab-color/initializer.tokenscript +6 -1
  142. package/src/schemas/types/oklab-color/unit.test.ts +58 -0
  143. package/src/schemas/types/oklch-color/initializer.tokenscript +6 -1
  144. package/src/schemas/types/oklch-color/unit.test.ts +58 -0
  145. package/src/schemas/types/p3-color/initializer.tokenscript +6 -1
  146. package/src/schemas/types/p3-color/unit.test.ts +47 -0
  147. package/src/schemas/types/rgb-color/initializer.tokenscript +7 -1
  148. package/src/schemas/types/rgb-color/rgba-initializer.tokenscript +17 -0
  149. package/src/schemas/types/rgb-color/schema.json +9 -0
  150. package/src/schemas/types/rgb-color/unit.test.ts +110 -1
  151. package/src/schemas/types/srgb-color/initializer.tokenscript +6 -1
  152. package/src/schemas/types/srgb-color/unit.test.ts +89 -0
  153. package/bundled/types/rgba-color.json +0 -89
@@ -399,4 +399,220 @@ describe("CSS Color Schema", () => {
399
399
  expect(typeof css).toBe("string");
400
400
  });
401
401
  });
402
+
403
+ describe("Alpha Channel Support", () => {
404
+ it("should output RGB with alpha in CSS format", async () => {
405
+ const result = await executeWithCssColor(
406
+ ["rgb-color"],
407
+ `
408
+ variable c: Color.Rgb = rgb(255, 128, 64, 0.5);
409
+ c.to.css()
410
+ `,
411
+ );
412
+
413
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
414
+ log.info(`\n=== RGB with alpha → CSS ===`);
415
+ log.info(`Output: ${css}`);
416
+
417
+ expect(css).toBe("rgb(255 128 64 / 0.5)");
418
+ });
419
+
420
+ it("should omit alpha = 1.0 from RGB CSS output", async () => {
421
+ const result = await executeWithCssColor(
422
+ ["rgb-color"],
423
+ `
424
+ variable c: Color.Rgb = rgb(255, 128, 64, 1);
425
+ c.to.css()
426
+ `,
427
+ );
428
+
429
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
430
+ expect(css).toBe("rgb(255 128 64)");
431
+ });
432
+
433
+ it("should omit null alpha from RGB CSS output", async () => {
434
+ const result = await executeWithCssColor(
435
+ ["rgb-color"],
436
+ `
437
+ variable c: Color.Rgb = rgb(255, 128, 64);
438
+ c.to.css()
439
+ `,
440
+ );
441
+
442
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
443
+ expect(css).toBe("rgb(255 128 64)");
444
+ });
445
+
446
+ it("should output HSL with alpha in CSS format", async () => {
447
+ const result = await executeWithCssColor(
448
+ ["hsl-color", "srgb-color"],
449
+ `
450
+ variable c: Color.HSL = hsl(180, 0.5, 0.5, 0.8);
451
+ c.to.css()
452
+ `,
453
+ );
454
+
455
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
456
+ log.info(`\n=== HSL with alpha → CSS ===`);
457
+ log.info(`Output: ${css}`);
458
+
459
+ expect(css).toMatch(/^hsl\(180 50% 50% \/ 0\.8\)$/);
460
+ });
461
+
462
+ it("should output HWB with alpha in CSS format", async () => {
463
+ const result = await executeWithCssColor(
464
+ ["hwb-color", "hsv-color", "hsl-color", "srgb-color"],
465
+ `
466
+ variable c: Color.HWB = hwb(240, 0.2, 0.3, 0.7);
467
+ c.to.css()
468
+ `,
469
+ );
470
+
471
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
472
+ log.info(`\n=== HWB with alpha → CSS ===`);
473
+ log.info(`Output: ${css}`);
474
+
475
+ expect(css).toMatch(/^hwb\(240 20% 30% \/ 0\.7\)$/);
476
+ });
477
+
478
+ it("should output Lab with alpha in CSS format", async () => {
479
+ const result = await executeWithCssColor(
480
+ ["lab-color", "xyz-d50-color", "xyz-d65-color", "srgb-linear-color", "srgb-color"],
481
+ `
482
+ variable c: Color.Lab;
483
+ c.l = 75;
484
+ c.a = 20;
485
+ c.b = -30;
486
+ c.alpha = 0.6;
487
+ c.to.css()
488
+ `,
489
+ );
490
+
491
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
492
+ log.info(`\n=== Lab with alpha → CSS ===`);
493
+ log.info(`Output: ${css}`);
494
+
495
+ expect(css).toMatch(/^lab\(75% 20 -30 \/ 0\.6\)$/);
496
+ });
497
+
498
+ it("should output LCH with alpha in CSS format", async () => {
499
+ const result = await executeWithCssColor(
500
+ [
501
+ "lch-color",
502
+ "lab-color",
503
+ "xyz-d50-color",
504
+ "xyz-d65-color",
505
+ "srgb-linear-color",
506
+ "srgb-color",
507
+ ],
508
+ `
509
+ variable c: Color.LCH;
510
+ c.l = 75;
511
+ c.c = 50;
512
+ c.h = 180;
513
+ c.alpha = 0.4;
514
+ c.to.css()
515
+ `,
516
+ );
517
+
518
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
519
+ log.info(`\n=== LCH with alpha → CSS ===`);
520
+ log.info(`Output: ${css}`);
521
+
522
+ expect(css).toMatch(/^lch\(75% 50 180 \/ 0\.4\)$/);
523
+ });
524
+
525
+ it("should output OKLab with alpha in CSS format", async () => {
526
+ const result = await executeWithCssColor(
527
+ ["oklab-color", "xyz-d65-color", "srgb-linear-color", "srgb-color"],
528
+ `
529
+ variable c: Color.OKLab;
530
+ c.l = 0.7;
531
+ c.a = 0.1;
532
+ c.b = -0.05;
533
+ c.alpha = 0.3;
534
+ c.to.css()
535
+ `,
536
+ );
537
+
538
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
539
+ log.info(`\n=== OKLab with alpha → CSS ===`);
540
+ log.info(`Output: ${css}`);
541
+
542
+ expect(css).toMatch(/^oklab\(0\.7 0\.1 -0\.05 \/ 0\.3\)$/);
543
+ });
544
+
545
+ it("should output OKLCH with alpha in CSS format", async () => {
546
+ const result = await executeWithCssColor(
547
+ ["oklch-color", "oklab-color", "xyz-d65-color", "srgb-linear-color", "srgb-color"],
548
+ `
549
+ variable c: Color.OKLCH;
550
+ c.l = 0.7;
551
+ c.c = 0.15;
552
+ c.h = 180;
553
+ c.alpha = 0.9;
554
+ c.to.css()
555
+ `,
556
+ );
557
+
558
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
559
+ log.info(`\n=== OKLCH with alpha → CSS ===`);
560
+ log.info(`Output: ${css}`);
561
+
562
+ expect(css).toMatch(/^oklch\(0\.7 0\.15 180 \/ 0\.9\)$/);
563
+ });
564
+
565
+ it("should output Display-P3 with alpha in CSS format", async () => {
566
+ const result = await executeWithCssColor(
567
+ ["p3-color", "p3-linear-color", "xyz-d65-color", "srgb-linear-color", "srgb-color"],
568
+ `
569
+ variable c: Color.P3;
570
+ c.r = 1;
571
+ c.g = 0.5;
572
+ c.b = 0.25;
573
+ c.alpha = 0.85;
574
+ c.to.css()
575
+ `,
576
+ );
577
+
578
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
579
+ log.info(`\n=== Display-P3 with alpha → CSS ===`);
580
+ log.info(`Output: ${css}`);
581
+
582
+ expect(css).toMatch(/^color\(display-p3 1 0\.5 0\.25 \/ 0\.85\)$/);
583
+ });
584
+
585
+ it("should output sRGB with alpha in CSS format", async () => {
586
+ const result = await executeWithCssColor(
587
+ ["srgb-color"],
588
+ `
589
+ variable c: Color.SRGB;
590
+ c.r = 1;
591
+ c.g = 0.5;
592
+ c.b = 0.25;
593
+ c.alpha = 0.2;
594
+ c.to.css()
595
+ `,
596
+ );
597
+
598
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
599
+ log.info(`\n=== sRGB with alpha → CSS ===`);
600
+ log.info(`Output: ${css}`);
601
+
602
+ expect(css).toMatch(/^color\(srgb 1 0\.5 0\.25 \/ 0\.2\)$/);
603
+ });
604
+
605
+ it("should handle alpha = 0 (fully transparent)", async () => {
606
+ const result = await executeWithCssColor(
607
+ ["rgb-color"],
608
+ `
609
+ variable c: Color.Rgb = rgb(255, 0, 0, 0);
610
+ c.to.css()
611
+ `,
612
+ );
613
+
614
+ const css = (result as any)?.value?.value?.value || (result as any)?.toString?.();
615
+ expect(css).toBe("rgb(255 0 0 / 0)");
616
+ });
617
+ });
402
618
  });
@@ -120,4 +120,22 @@ describe("Hex Color Schema", () => {
120
120
  expect((result as any).value).toBe("#ffffff");
121
121
  });
122
122
  });
123
+
124
+ describe("Alpha Channel Support", () => {
125
+ it("should allow setting alpha on hex color", async () => {
126
+ const result = await executeWithSchema(
127
+ "hex-color",
128
+ "type",
129
+ `
130
+ variable hex: Color.Hex = #ff0000;
131
+ hex.alpha = 0.7;
132
+ hex.alpha
133
+ `,
134
+ );
135
+
136
+ expect((result as any).value).toBe(0.7);
137
+ });
138
+
139
+ // Note: Conversion tests are in rgb-color/unit.test.ts since RGB owns the conversions
140
+ });
123
141
  });
@@ -0,0 +1,17 @@
1
+ // HSLA Color Initializer
2
+ // Creates an HSL color with alpha from H, S, L, A values
3
+ //
4
+ // Usage: hsla(180, 0.5, 0.5, 0.8) → Color.HSL { h: 180, s: 0.5, l: 0.5, alpha: 0.8 }
5
+ //
6
+ // Input: List of 4 numbers [h, s, l, alpha]
7
+ // Output: Color.HSL with alpha
8
+
9
+ variable hsl_values: List = {input};
10
+ variable output: Color.HSL;
11
+
12
+ output.h = hsl_values.get(0);
13
+ output.s = hsl_values.get(1);
14
+ output.l = hsl_values.get(2);
15
+ output.alpha = hsl_values.get(3);
16
+
17
+ return output;
@@ -1,6 +1,6 @@
1
1
  // HSL Color Initializer
2
2
  // Creates an HSL color from H, S, L values
3
- // Input: List of [h, s, l] values
3
+ // Input: List of [h, s, l] or [h, s, l, alpha] values
4
4
 
5
5
  variable hsl_values: List = {input};
6
6
  variable output: Color.HSL;
@@ -9,6 +9,11 @@ output.h = hsl_values.get(0);
9
9
  output.s = hsl_values.get(1);
10
10
  output.l = hsl_values.get(2);
11
11
 
12
+ // Set alpha if provided as 4th parameter
13
+ if (hsl_values.length() > 3) [
14
+ output.alpha = hsl_values.get(3);
15
+ ];
16
+
12
17
  return output;
13
18
 
14
19
 
@@ -31,6 +31,15 @@
31
31
  "type": "/api/v1/core/tokenscript/0/",
32
32
  "script": "./initializer.tokenscript"
33
33
  }
34
+ },
35
+ {
36
+ "title": "HSLA Color Initializer",
37
+ "keyword": "hsla",
38
+ "description": "Creates an HSL color with alpha from H, S, L, A values",
39
+ "script": {
40
+ "type": "/api/v1/core/tokenscript/0/",
41
+ "script": "./hsla-initializer.tokenscript"
42
+ }
34
43
  }
35
44
  ],
36
45
  "conversions": [
@@ -32,8 +32,9 @@ describe("HSL Color Schema", () => {
32
32
  it("should have hsl initializer", async () => {
33
33
  const schema = (await getBundledSchema("hsl-color")) as ColorSpecification;
34
34
 
35
- expect(schema.initializers).toHaveLength(1);
35
+ expect(schema.initializers).toHaveLength(2);
36
36
  expect(schema.initializers[0].keyword).toBe("hsl");
37
+ expect(schema.initializers[1].keyword).toBe("hsla");
37
38
  });
38
39
 
39
40
  it("should have conversion from sRGB", async () => {
@@ -198,4 +199,97 @@ describe("HSL Color Schema", () => {
198
199
  expect((result as any).value.l.value).toBeCloseTo(0.5, 9);
199
200
  });
200
201
  });
202
+
203
+ describe("Alpha Channel Support", () => {
204
+ it("should accept optional 4th parameter for alpha using hsl()", async () => {
205
+ const result = await executeWithSchema(
206
+ "hsl-color",
207
+ "type",
208
+ `
209
+ variable c: Color.HSL = hsl(180, 0.5, 0.5, 0.7);
210
+ c
211
+ `,
212
+ );
213
+
214
+ expect(result?.constructor.name).toBe("ColorSymbol");
215
+ expect((result as any).subType).toBe("HSL");
216
+ expect((result as any).value.h.value).toBe(180);
217
+ expect((result as any).value.s.value).toBe(0.5);
218
+ expect((result as any).value.l.value).toBe(0.5);
219
+ expect((result as any).alpha).toBe(0.7);
220
+ });
221
+
222
+ it("should create color with hsla() initializer", async () => {
223
+ const result = await executeWithSchema(
224
+ "hsl-color",
225
+ "type",
226
+ `
227
+ variable c: Color.HSL = hsla(240, 0.8, 0.6, 0.9);
228
+ c
229
+ `,
230
+ );
231
+
232
+ expect(result?.constructor.name).toBe("ColorSymbol");
233
+ expect((result as any).subType).toBe("HSL");
234
+ expect((result as any).value.h.value).toBe(240);
235
+ expect((result as any).value.s.value).toBe(0.8);
236
+ expect((result as any).value.l.value).toBe(0.6);
237
+ expect((result as any).alpha).toBe(0.9);
238
+ });
239
+
240
+ it("should get alpha property", async () => {
241
+ const result = await executeWithSchema(
242
+ "hsl-color",
243
+ "type",
244
+ `
245
+ variable c: Color.HSL = hsl(0, 1, 0.5, 0.5);
246
+ c.alpha
247
+ `,
248
+ );
249
+
250
+ expect((result as any).value).toBe(0.5);
251
+ });
252
+
253
+ it("should set alpha property", async () => {
254
+ const result = await executeWithSchema(
255
+ "hsl-color",
256
+ "type",
257
+ `
258
+ variable c: Color.HSL = hsl(0, 1, 0.5);
259
+ c.alpha = 0.8;
260
+ c.alpha
261
+ `,
262
+ );
263
+
264
+ expect((result as any).value).toBe(0.8);
265
+ });
266
+
267
+ it("should preserve alpha through conversion to sRGB", async () => {
268
+ const result = await executeWithSchema(
269
+ "hsl-color",
270
+ "type",
271
+ `
272
+ variable c: Color.HSL = hsl(120, 1, 0.5, 0.6);
273
+ variable srgb: Color.SRGB = c.to.srgb();
274
+ srgb.alpha
275
+ `,
276
+ );
277
+
278
+ expect((result as any).value).toBe(0.6);
279
+ });
280
+
281
+ it("should preserve alpha through conversion from sRGB", async () => {
282
+ const result = await executeWithSchema(
283
+ "hsl-color",
284
+ "type",
285
+ `
286
+ variable srgb: Color.SRGB = srgb(1, 0, 0, 0.4);
287
+ variable c: Color.HSL = srgb.to.hsl();
288
+ c.alpha
289
+ `,
290
+ );
291
+
292
+ expect((result as any).value).toBe(0.4);
293
+ });
294
+ });
201
295
  });
@@ -1,6 +1,6 @@
1
1
  // HSV Color Initializer
2
2
  // Creates an HSV color from H, S, V values
3
- // Input: List of [h, s, v] values
3
+ // Input: List of [h, s, v] or [h, s, v, alpha] values
4
4
 
5
5
  variable hsv_values: List = {input};
6
6
  variable output: Color.HSV;
@@ -9,6 +9,11 @@ output.h = hsv_values.get(0);
9
9
  output.s = hsv_values.get(1);
10
10
  output.v = hsv_values.get(2);
11
11
 
12
+ // Set alpha if provided as 4th parameter
13
+ if (hsv_values.length() > 3) [
14
+ output.alpha = hsv_values.get(3);
15
+ ];
16
+
12
17
  return output;
13
18
 
14
19
 
@@ -159,4 +159,48 @@ describe("HSV Color Schema", () => {
159
159
  expect((result as any).value.v.value).toBeCloseTo(0.5, 9);
160
160
  });
161
161
  });
162
+
163
+ describe("Alpha Channel Support", () => {
164
+ it("should accept optional 4th parameter for alpha", async () => {
165
+ const result = await executeWithSchema(
166
+ "hsv-color",
167
+ "type",
168
+ `
169
+ variable c: Color.HSV = hsv(180, 0.5, 0.5, 0.7);
170
+ c
171
+ `,
172
+ );
173
+
174
+ expect(result?.constructor.name).toBe("ColorSymbol");
175
+ expect((result as any).subType).toBe("HSV");
176
+ expect((result as any).alpha).toBe(0.7);
177
+ });
178
+
179
+ it("should get alpha property", async () => {
180
+ const result = await executeWithSchema(
181
+ "hsv-color",
182
+ "type",
183
+ `
184
+ variable c: Color.HSV = hsv(0, 1, 1, 0.5);
185
+ c.alpha
186
+ `,
187
+ );
188
+
189
+ expect((result as any).value).toBe(0.5);
190
+ });
191
+
192
+ it("should set alpha property", async () => {
193
+ const result = await executeWithSchema(
194
+ "hsv-color",
195
+ "type",
196
+ `
197
+ variable c: Color.HSV = hsv(0, 1, 1);
198
+ c.alpha = 0.8;
199
+ c.alpha
200
+ `,
201
+ );
202
+
203
+ expect((result as any).value).toBe(0.8);
204
+ });
205
+ });
162
206
  });
@@ -0,0 +1,17 @@
1
+ // HWBA Color Initializer
2
+ // Creates an HWB color with alpha from H, W, B, A values
3
+ //
4
+ // Usage: hwba(180, 0.2, 0.3, 0.9) → Color.HWB { h: 180, w: 0.2, b: 0.3, alpha: 0.9 }
5
+ //
6
+ // Input: List of 4 numbers [h, w, b, alpha]
7
+ // Output: Color.HWB with alpha
8
+
9
+ variable hwb_values: List = {input};
10
+ variable output: Color.HWB;
11
+
12
+ output.h = hwb_values.get(0);
13
+ output.w = hwb_values.get(1);
14
+ output.b = hwb_values.get(2);
15
+ output.alpha = hwb_values.get(3);
16
+
17
+ return output;
@@ -1,6 +1,6 @@
1
1
  // HWB Color Initializer
2
2
  // Creates an HWB color from H, W, B values
3
- // Input: List of [h, w, b] values
3
+ // Input: List of [h, w, b] or [h, w, b, alpha] values
4
4
 
5
5
  variable hwb_values: List = {input};
6
6
  variable output: Color.HWB;
@@ -9,6 +9,11 @@ output.h = hwb_values.get(0);
9
9
  output.w = hwb_values.get(1);
10
10
  output.b = hwb_values.get(2);
11
11
 
12
+ // Set alpha if provided as 4th parameter
13
+ if (hwb_values.length() > 3) [
14
+ output.alpha = hwb_values.get(3);
15
+ ];
16
+
12
17
  return output;
13
18
 
14
19
 
@@ -31,6 +31,15 @@
31
31
  "type": "/api/v1/core/tokenscript/0/",
32
32
  "script": "./initializer.tokenscript"
33
33
  }
34
+ },
35
+ {
36
+ "title": "HWBA Color Initializer",
37
+ "keyword": "hwba",
38
+ "description": "Creates an HWB color with alpha from H, W, B, A values",
39
+ "script": {
40
+ "type": "/api/v1/core/tokenscript/0/",
41
+ "script": "./hwba-initializer.tokenscript"
42
+ }
34
43
  }
35
44
  ],
36
45
  "conversions": [
@@ -27,6 +27,14 @@ describe("HWB Color Schema", () => {
27
27
  expect(schema.schema?.properties).toHaveProperty("w");
28
28
  expect(schema.schema?.properties).toHaveProperty("b");
29
29
  });
30
+
31
+ it("should have hwb initializer", async () => {
32
+ const schema = (await getBundledSchema("hwb-color")) as ColorSpecification;
33
+
34
+ expect(schema.initializers).toHaveLength(2);
35
+ expect(schema.initializers[0].keyword).toBe("hwb");
36
+ expect(schema.initializers[1].keyword).toBe("hwba");
37
+ });
30
38
  });
31
39
 
32
40
  describe("ColorJS Parity", () => {
@@ -147,4 +155,66 @@ describe("HWB Color Schema", () => {
147
155
  expect((result as any).value.b.value).toBeCloseTo(0.5, 9);
148
156
  });
149
157
  });
158
+
159
+ describe("Alpha Channel Support", () => {
160
+ it("should accept optional 4th parameter for alpha using hwb()", async () => {
161
+ const result = await executeWithSchema(
162
+ "hwb-color",
163
+ "type",
164
+ `
165
+ variable c: Color.HWB = hwb(180, 0.2, 0.3, 0.7);
166
+ c
167
+ `,
168
+ );
169
+
170
+ expect(result?.constructor.name).toBe("ColorSymbol");
171
+ expect((result as any).subType).toBe("HWB");
172
+ expect((result as any).alpha).toBe(0.7);
173
+ });
174
+
175
+ it("should create color with hwba() initializer", async () => {
176
+ const result = await executeWithSchema(
177
+ "hwb-color",
178
+ "type",
179
+ `
180
+ variable c: Color.HWB = hwba(240, 0.1, 0.2, 0.85);
181
+ c
182
+ `,
183
+ );
184
+
185
+ expect(result?.constructor.name).toBe("ColorSymbol");
186
+ expect((result as any).subType).toBe("HWB");
187
+ expect((result as any).value.h.value).toBe(240);
188
+ expect((result as any).value.w.value).toBe(0.1);
189
+ expect((result as any).value.b.value).toBe(0.2);
190
+ expect((result as any).alpha).toBe(0.85);
191
+ });
192
+
193
+ it("should get alpha property", async () => {
194
+ const result = await executeWithSchema(
195
+ "hwb-color",
196
+ "type",
197
+ `
198
+ variable c: Color.HWB = hwb(0, 0, 0, 0.3);
199
+ c.alpha
200
+ `,
201
+ );
202
+
203
+ expect((result as any).value).toBe(0.3);
204
+ });
205
+
206
+ it("should set alpha property", async () => {
207
+ const result = await executeWithSchema(
208
+ "hwb-color",
209
+ "type",
210
+ `
211
+ variable c: Color.HWB = hwb(0, 0, 0);
212
+ c.alpha = 0.9;
213
+ c.alpha
214
+ `,
215
+ );
216
+
217
+ expect((result as any).value).toBe(0.9);
218
+ });
219
+ });
150
220
  });
@@ -1,6 +1,6 @@
1
1
  // CIE Lab Color Initializer
2
2
  // Creates a Lab color from L, a, b values
3
- // Input: List of [l, a, b] values
3
+ // Input: List of [l, a, b] or [l, a, b, alpha] values
4
4
 
5
5
  variable lab_values: List = {input};
6
6
  variable output: Color.Lab;
@@ -9,6 +9,11 @@ output.l = lab_values.get(0);
9
9
  output.a = lab_values.get(1);
10
10
  output.b = lab_values.get(2);
11
11
 
12
+ // Set alpha if provided as 4th parameter
13
+ if (lab_values.length() > 3) [
14
+ output.alpha = lab_values.get(3);
15
+ ];
16
+
12
17
  return output;
13
18
 
14
19
 
@@ -260,4 +260,48 @@ describe("CIE Lab Color Schema", () => {
260
260
  expect(Math.abs((result as any).value.b.value)).toBeLessThan(0.01);
261
261
  });
262
262
  });
263
+
264
+ describe("Alpha Channel Support", () => {
265
+ it("should accept optional 4th parameter for alpha", async () => {
266
+ const result = await executeWithSchema(
267
+ "lab-color",
268
+ "type",
269
+ `
270
+ variable c: Color.Lab = lab(50, 20, 30, 0.7);
271
+ c
272
+ `,
273
+ );
274
+
275
+ expect(result?.constructor.name).toBe("ColorSymbol");
276
+ expect((result as any).subType).toBe("Lab");
277
+ expect((result as any).alpha).toBe(0.7);
278
+ });
279
+
280
+ it("should get alpha property", async () => {
281
+ const result = await executeWithSchema(
282
+ "lab-color",
283
+ "type",
284
+ `
285
+ variable c: Color.Lab = lab(50, 20, 30, 0.5);
286
+ c.alpha
287
+ `,
288
+ );
289
+
290
+ expect((result as any).value).toBe(0.5);
291
+ });
292
+
293
+ it("should set alpha property", async () => {
294
+ const result = await executeWithSchema(
295
+ "lab-color",
296
+ "type",
297
+ `
298
+ variable c: Color.Lab = lab(50, 20, 30);
299
+ c.alpha = 0.8;
300
+ c.alpha
301
+ `,
302
+ );
303
+
304
+ expect((result as any).value).toBe(0.8);
305
+ });
306
+ });
263
307
  });