@astryxdesign/lab 0.1.6-canary.e82deeb → 0.1.6-canary.e8d4c3f

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ChartDotGLInteractive.d.ts","sourceRoot":"","sources":["../../src/Chart/ChartDotGLInteractive.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,MAAM,WAAW,0BAA0B;IACzC,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;CAC9E;AAoHD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,IAAQ,EACR,OAAa,EACb,aAAa,GACd,EAAE,0BAA0B,sCAyV5B"}
1
+ {"version":3,"file":"ChartDotGLInteractive.d.ts","sourceRoot":"","sources":["../../src/Chart/ChartDotGLInteractive.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,MAAM,WAAW,0BAA0B;IACzC,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;CAC9E;AA+GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,IAAQ,EACR,OAAa,EACb,aAAa,GACd,EAAE,0BAA0B,sCAyV5B"}
@@ -13,12 +13,8 @@
13
13
  import { useRef, useEffect, useCallback, useState, useMemo } from 'react';
14
14
  import { useChart } from "./ChartContext.js";
15
15
  import { xPixel } from "./utils.js";
16
+ import { hexToGL } from "./webgl.js";
16
17
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
17
- function hexToGL(hex) {
18
- const n = parseInt(hex.replace('#', ''), 16);
19
- return [(n >> 16) / 255, (n >> 8 & 0xff) / 255, (n & 0xff) / 255];
20
- }
21
-
22
18
  /** Encode a point index as an RGB color (supports up to 16.7M points) */
23
19
  function indexToColor(i) {
24
20
  // Add 1 so index 0 isn't black (which is our clear color)
@@ -1 +1 @@
1
- {"version":3,"file":"getChartColors.d.ts","sourceRoot":"","sources":["../../src/Chart/getChartColors.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AAM3D,kDAAkD;AAClD,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,UAAU,GACV,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,KAAK,GACL,MAAM,GACN,QAAQ,GACR,MAAM,CAAC;AAEX,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;IAC3D,SAAS,EAAE;QACT,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACtC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC7B,MAAM,CACJ,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,aAAa,EAClB,CAAC,EAAE,MAAM,EACT,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,EAAE,CAAC;KACb,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,qEAAqE;IACrE,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7C;AAED,iEAAiE;AACjE,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAgErD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,aAAa,GACrB,cAAc,CA+EhB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,IAAI,GAAE,OAAO,GAAG,MAAgB,GAC/B,cAAc,CAsBhB"}
1
+ {"version":3,"file":"getChartColors.d.ts","sourceRoot":"","sources":["../../src/Chart/getChartColors.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AAO3D,kDAAkD;AAClD,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,UAAU,GACV,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,KAAK,GACL,MAAM,GACN,QAAQ,GACR,MAAM,CAAC;AAEX,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;IAC3D,SAAS,EAAE;QACT,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACtC,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC7B,MAAM,CACJ,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,aAAa,EAClB,CAAC,EAAE,MAAM,EACT,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,EAAE,CAAC;KACb,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,qEAAqE;IACrE,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7C;AAED,iEAAiE;AACjE,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAoErD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,aAAa,GACrB,cAAc,CA+EhB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,IAAI,GAAE,OAAO,GAAG,MAAgB,GAC/B,cAAc,CAsBhB"}
@@ -9,6 +9,8 @@
9
9
  * the full chart colors API. The useChartColors hook wraps this.
10
10
  */
11
11
 
12
+ import { parseHex, parseColor, formatColor } from '@astryxdesign/core/utils';
13
+
12
14
  // =============================================================================
13
15
  // Types
14
16
  // =============================================================================
@@ -39,15 +41,25 @@ function pickFromRamp(stops, n) {
39
41
  length: n
40
42
  }, (_, i) => stops[Math.round(i * 4 / (n - 1))]);
41
43
  }
44
+
45
+ /**
46
+ * Apply an opacity to a concrete CSS color (hex — with or without the leading
47
+ * `#` — `rgb()`/`rgba()`, named). The `opacity` argument always wins over any
48
+ * alpha already in the color. Unparseable input (e.g. `var()`) is returned
49
+ * unchanged.
50
+ */
42
51
  function hexAlpha(hex, opacity) {
43
- const match = hex.match(/^#?([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/);
44
- if (!match) {
52
+ // parseColor requires the `#` for hex; fall back to parseHex so bare hex
53
+ // strings (`0064E0`) keep working as they did before #3739.
54
+ const rgba = parseColor(hex) ?? parseHex(hex);
55
+ if (rgba === null) {
45
56
  return hex;
46
57
  }
47
- const r = parseInt(match[1], 16);
48
- const g = parseInt(match[2], 16);
49
- const b = parseInt(match[3], 16);
50
- return `rgba(${r},${g},${b},${Math.max(0, Math.min(1, opacity))})`;
58
+ const a = Number.isFinite(opacity) ? Math.max(0, Math.min(1, opacity)) : 1;
59
+ return formatColor({
60
+ ...rgba,
61
+ a
62
+ });
51
63
  }
52
64
 
53
65
  // =============================================================================
@@ -1,19 +1,11 @@
1
- /**
2
- * @file webgl.ts
3
- * @output Shared WebGL utilities for chart components
4
- * @position Internal helpers; consumed by all GL mark components
5
- *
6
- * Provides:
7
- * - Canvas mounting outside SVG (avoids foreignObject DPR blur)
8
- * - Premultiplied alpha setup (correct compositing over page)
9
- * - Shader compilation helpers
10
- * - Smoothstep circle fragment for crisp point sprites
11
- */
12
1
  /** Compile a WebGL shader, returns null on failure */
13
2
  export declare function compileShader(gl: WebGLRenderingContext, type: number, src: string): WebGLShader | null;
14
3
  /** Link a vertex + fragment shader into a program */
15
4
  export declare function createProgram(gl: WebGLRenderingContext, vertSrc: string, fragSrc: string): WebGLProgram | null;
16
- /** Parse hex (#RRGGBB) to [r, g, b] floats 0-1 */
5
+ /**
6
+ * Parse a hex color (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`) to [r, g, b]
7
+ * floats 0-1. Unparseable input returns a neutral fallback instead of NaN.
8
+ */
17
9
  export declare function hexToGL(hex: string): [number, number, number];
18
10
  /** DPR with supersampling for crisp circles */
19
11
  export declare function getCanvasDPR(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"webgl.d.ts","sourceRoot":"","sources":["../../src/Chart/webgl.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,sDAAsD;AACtD,wBAAgB,aAAa,CAC3B,EAAE,EAAE,qBAAqB,EACzB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,WAAW,GAAG,IAAI,CAYpB;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,EAAE,EAAE,qBAAqB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,YAAY,GAAG,IAAI,CAkBrB;AAED,kDAAkD;AAClD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAG7D;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,GACxB,qBAAqB,GAAG,IAAI,CAM9B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,qBAAqB,GAAG,IAAI,CAK5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,CAOR;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAwC1B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,iPAO5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAa,CAAC"}
1
+ {"version":3,"file":"webgl.d.ts","sourceRoot":"","sources":["../../src/Chart/webgl.ts"],"names":[],"mappings":"AAkBA,sDAAsD;AACtD,wBAAgB,aAAa,CAC3B,EAAE,EAAE,qBAAqB,EACzB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,WAAW,GAAG,IAAI,CAYpB;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,EAAE,EAAE,qBAAqB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,YAAY,GAAG,IAAI,CAkBrB;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAE7D;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,GACxB,qBAAqB,GAAG,IAAI,CAM9B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,qBAAqB,GAAG,IAAI,CAK5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,CAOR;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAwC1B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,iPAO5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAa,CAAC"}
@@ -10,8 +10,12 @@
10
10
  * - Premultiplied alpha setup (correct compositing over page)
11
11
  * - Shader compilation helpers
12
12
  * - Smoothstep circle fragment for crisp point sprites
13
+ * - Hex-to-GL color conversion via the shared @astryxdesign/core/utils/color
14
+ * parsers (fallback instead of NaN)
13
15
  */
14
16
 
17
+ import { parseHex, toGLFloats } from '@astryxdesign/core/utils';
18
+
15
19
  /** Compile a WebGL shader, returns null on failure */
16
20
  export function compileShader(gl, type, src) {
17
21
  const s = gl.createShader(type);
@@ -48,10 +52,12 @@ export function createProgram(gl, vertSrc, fragSrc) {
48
52
  return p;
49
53
  }
50
54
 
51
- /** Parse hex (#RRGGBB) to [r, g, b] floats 0-1 */
55
+ /**
56
+ * Parse a hex color (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`) to [r, g, b]
57
+ * floats 0-1. Unparseable input returns a neutral fallback instead of NaN.
58
+ */
52
59
  export function hexToGL(hex) {
53
- const n = parseInt(hex.replace('#', ''), 16);
54
- return [(n >> 16) / 255, (n >> 8 & 0xff) / 255, (n & 0xff) / 255];
60
+ return toGLFloats(parseHex(hex));
55
61
  }
56
62
 
57
63
  /** DPR with supersampling for crisp circles */
@@ -40,47 +40,6 @@ export declare function ListEventRow({ event, timezoneID, isPast, }: {
40
40
  isPast?: boolean;
41
41
  }): import("react").JSX.Element;
42
42
  export declare function getEventCategory(event: CalendarEvent, categories: ReadonlyArray<ScheduleCategory>): ScheduleCategory;
43
- export declare function eventColorStyle(color: ScheduleEventColor | undefined): Readonly<{
44
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#014975, #A1EEF9)">;
45
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#03A7D733, #03A7D733)">;
46
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#089DD0, #0171A4)">;
47
- }> | Readonly<{
48
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#0A1317, #E7EAED)">;
49
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#0A131733, #666A724C)">;
50
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#647685, #748695)">;
51
- }> | Readonly<{
52
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#09441F, #A5F690)">;
53
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#24BB5E33, #24BB5E33)">;
54
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#0D8626, #0B991F)">;
55
- }> | Readonly<{
56
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#6B2203, #FDB876)">;
57
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#F2790233, #F2790233)">;
58
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#EB6E00, #B34A01)">;
59
- }> | Readonly<{
60
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#650053, #FEADE3)">;
61
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#E638B333, #E638B333)">;
62
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#F351C0, #C02294)">;
63
- }> | Readonly<{
64
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#3E0697, #B3B0FE)">;
65
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#7952FF33, #7952FF33)">;
66
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#9081FF, #7340FE)">;
67
- }> | Readonly<{
68
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#7B0210, #FFB2B8)">;
69
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#E3193B33, #E3193B33)">;
70
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#E3193B, #F5394F)">;
71
- }> | Readonly<{
72
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#083943, #40DCCD)">;
73
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#0DB7AF33, #0DB7AF33)">;
74
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#08A3A3, #08767D)">;
75
- }> | Readonly<{
76
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#753F07, #FBCE03)">;
77
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#E2A40033, #E2A40033)">;
78
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#C58600, #B47700)">;
79
- }> | Readonly<{
80
- readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#042F97, #AFD7FF)">;
81
- readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#0171E333, #0171E333)">;
82
- readonly borderColor: stylex.StyleXClassNameFor<"borderColor", "light-dark(#0064E0, #2694FE)">;
83
- }>;
84
43
  export declare function eventDotColorStyle(color: ScheduleEventColor | undefined): Readonly<{
85
44
  readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#089DD0, #0171A4)">;
86
45
  }> | Readonly<{
@@ -187,9 +146,7 @@ export declare function eventPastSurfaceColorStyle(color: ScheduleEventColor | u
187
146
  export declare function formatWithPlainDate(date: PlainDate, timezoneID: string, options: Intl.DateTimeFormatOptions): string;
188
147
  export declare function formatMonthTitle(date: PlainDate, timezoneID: string): string;
189
148
  export declare function formatWeekTitle(start: PlainDate, end: PlainDate, timezoneID: string): string;
190
- export declare function formatRangeTitle(start: PlainDate, end: PlainDate, timezoneID: string): string;
191
149
  export declare function formatFullDate(date: PlainDate, timezoneID: string): string;
192
- export declare function formatShortDate(date: PlainDate, timezoneID: string): string;
193
150
  export declare function formatWeekday(date: PlainDate, timezoneID: string, weekday: 'short' | 'long'): string;
194
151
  export declare function formatDayNumber(date: PlainDate, timezoneID: string): string;
195
152
  export declare function formatHour(hour: number): string;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/Schedule/shared.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/Schedule/shared.tsx"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAa3C,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,OAAO,EACP,gBAAgB,EAEhB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAOjB,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,UAAU,EACV,SAAS,EACT,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAgDA;AAED,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,UAAU,GACX,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,+BAUA;AAED,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,GAAG,EACH,UAAU,GACX,EAAE;IACD,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,SAAS,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,+BAmBA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,GAAG,EACH,UAAU,EACV,MAAc,GACf,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,+BA6BA;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,UAAU,EACV,MAAc,GACf,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,+BA4BA;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,UAAU,EACV,MAAc,GACf,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,+BAoBA;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAC1C,gBAAgB,CAOlB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;GAwBvE;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,kBAAkB,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyBtC;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,kBAAkB,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyBtC;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,IAAI,CAAC,qBAAqB,GAClC,MAAM,CAKR;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAK5E;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CASR;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAO1E;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,GAAG,MAAM,GACxB,MAAM,CAER;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,GACjB,MAAM,CAQR;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,oBAAoB,EAC3B,GAAG,EAAE,SAAS,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,CASR;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,oBAAoB,EAC3B,UAAU,EAAE,MAAM,GACjB,MAAM,CASR;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,oBAAoB,EAC3B,UAAU,EAAE,MAAM,GACjB,MAAM,CAMR;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,SAAS,EACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAC1C,MAAM,CAMR;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,MAAM,CAaR;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,oBAAoB,EAC3B,GAAG,EAAE,SAAS,EACd,UAAU,EAAE,MAAM,GACjB,OAAO,CAKT;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,OAAO,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAQT;AAOD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAktBjB,CAAC"}
@@ -240,31 +240,6 @@ export function getEventCategory(event, categories) {
240
240
  color: DEFAULT_EVENT_CATEGORY.color
241
241
  } : DEFAULT_EVENT_CATEGORY);
242
242
  }
243
- export function eventColorStyle(color) {
244
- switch (color) {
245
- case 'cyan':
246
- return styles.eventCyan;
247
- case 'gray':
248
- return styles.eventGray;
249
- case 'green':
250
- return styles.eventGreen;
251
- case 'orange':
252
- return styles.eventOrange;
253
- case 'pink':
254
- return styles.eventPink;
255
- case 'purple':
256
- return styles.eventPurple;
257
- case 'red':
258
- return styles.eventRed;
259
- case 'teal':
260
- return styles.eventTeal;
261
- case 'yellow':
262
- return styles.eventYellow;
263
- case 'blue':
264
- default:
265
- return styles.eventBlue;
266
- }
267
- }
268
243
  export function eventDotColorStyle(color) {
269
244
  switch (color) {
270
245
  case 'cyan':
@@ -364,9 +339,6 @@ export function formatWeekTitle(start, end, timezoneID) {
364
339
  });
365
340
  return start.year === end.year ? `${startMonth} - ${endMonth} ${end.year}` : `${startMonth} ${start.year} - ${endMonth} ${end.year}`;
366
341
  }
367
- export function formatRangeTitle(start, end, timezoneID) {
368
- return `${formatShortDate(start, timezoneID)} - ${formatShortDate(end, timezoneID)}`;
369
- }
370
342
  export function formatFullDate(date, timezoneID) {
371
343
  return formatWithPlainDate(date, timezoneID, {
372
344
  weekday: 'long',
@@ -375,12 +347,6 @@ export function formatFullDate(date, timezoneID) {
375
347
  year: 'numeric'
376
348
  });
377
349
  }
378
- export function formatShortDate(date, timezoneID) {
379
- return formatWithPlainDate(date, timezoneID, {
380
- month: 'short',
381
- day: 'numeric'
382
- });
383
- }
384
350
  export function formatWeekday(date, timezoneID, weekday) {
385
351
  return formatWithPlainDate(date, timezoneID, {
386
352
  weekday
@@ -1 +1 @@
1
- {"version":3,"file":"ThreeDScatterGL.d.ts","sourceRoot":"","sources":["../../src/ThreeD/ThreeDScatterGL.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4FD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,IAAQ,EACR,OAAc,GACf,EAAE,oBAAoB,sCAuJtB"}
1
+ {"version":3,"file":"ThreeDScatterGL.d.ts","sourceRoot":"","sources":["../../src/ThreeD/ThreeDScatterGL.tsx"],"names":[],"mappings":"AAmBA,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuFD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,IAAQ,EACR,OAAc,GACf,EAAE,oBAAoB,sCAuJtB"}
@@ -14,13 +14,9 @@
14
14
  */
15
15
 
16
16
  import { useRef, useEffect, useMemo } from 'react';
17
+ import { parseHex, toGLFloats } from '@astryxdesign/core/utils';
17
18
  import { use3D } from "./ThreeDContext.js";
18
19
  import { jsx as _jsx } from "react/jsx-runtime";
19
- function hexToGL(hex) {
20
- const n = parseInt(hex.replace('#', ''), 16);
21
- return [(n >> 16) / 255, (n >> 8 & 0xff) / 255, (n & 0xff) / 255];
22
- }
23
-
24
20
  // SYNC: Steps 1-5 match ThreeDChart.project() exactly.
25
21
  const VERT = `
26
22
  attribute vec3 a_position;
@@ -218,7 +214,7 @@ export function ThreeDScatterGL({
218
214
  const azRad = camera.azimuth * Math.PI / 180;
219
215
  const elRad = camera.elevation * Math.PI / 180;
220
216
  const scale = Math.min(width, height) * 0.35;
221
- const [r, g, b] = hexToGL(color);
217
+ const [r, g, b] = toGLFloats(parseHex(color));
222
218
  gl.uniform2f(gl.getUniformLocation(program, 'u_resolution'), width, height);
223
219
  gl.uniform2f(gl.getUniformLocation(program, 'u_center'), width / 2, height / 2);
224
220
  gl.uniform1f(gl.getUniformLocation(program, 'u_scale'), scale);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/lab",
3
- "version": "0.1.6-canary.e82deeb",
3
+ "version": "0.1.6-canary.e8d4c3f",
4
4
  "description": "Experimental Astryx components — published to npm only under the @canary dist-tag for early testing; never released as a stable (latest) version.",
5
5
  "author": "Meta Open Source",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@stylexjs/stylex": ">=0.10.0",
48
- "@astryxdesign/core": "0.1.6-canary.e82deeb",
48
+ "@astryxdesign/core": "0.1.6-canary.e8d4c3f",
49
49
  "react": ">=19.0.0",
50
50
  "react-dom": ">=19.0.0"
51
51
  },
@@ -55,7 +55,6 @@
55
55
  "d3-shape": "^3.2.0"
56
56
  },
57
57
  "devDependencies": {
58
- "@types/d3-array": "^3.2.2",
59
58
  "@types/d3-scale": "^4.0.9",
60
59
  "@types/d3-shape": "^3.1.8"
61
60
  },
@@ -20,6 +20,7 @@ import {
20
20
  } from 'react';
21
21
  import {useChart} from './ChartContext';
22
22
  import {xPixel} from './utils';
23
+ import {hexToGL} from './webgl';
23
24
 
24
25
  export interface ChartDotGLInteractiveProps {
25
26
  /** Which data key for the y values */
@@ -37,11 +38,6 @@ export interface ChartDotGLInteractiveProps {
37
38
  renderTooltip?: (datum: Record<string, unknown>, index: number) => ReactNode;
38
39
  }
39
40
 
40
- function hexToGL(hex: string): [number, number, number] {
41
- const n = parseInt(hex.replace('#', ''), 16);
42
- return [(n >> 16) / 255, ((n >> 8) & 0xff) / 255, (n & 0xff) / 255];
43
- }
44
-
45
41
  /** Encode a point index as an RGB color (supports up to 16.7M points) */
46
42
  function indexToColor(i: number): [number, number, number] {
47
43
  // Add 1 so index 0 isn't black (which is our clear color)
@@ -0,0 +1,28 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, expect, it} from 'vitest';
4
+ import {getChartColorsFromResolver} from './getChartColors';
5
+
6
+ describe('getChartColorsFromResolver alpha', () => {
7
+ const colors = getChartColorsFromResolver(name => `resolved(${name})`);
8
+
9
+ it('applies opacity to a hex color', () => {
10
+ expect(colors.alpha('#0064E0', 0.2)).toBe('rgba(0, 100, 224, 0.2)');
11
+ });
12
+
13
+ it('applies opacity to bare hex without the leading # (pre-#3739 behavior)', () => {
14
+ expect(colors.alpha('0064E0', 0.2)).toBe('rgba(0, 100, 224, 0.2)');
15
+ });
16
+
17
+ it('applies opacity to rgba() input, overriding its alpha', () => {
18
+ expect(colors.alpha('rgba(0, 100, 224, 0.9)', 0.2)).toBe(
19
+ 'rgba(0, 100, 224, 0.2)',
20
+ );
21
+ });
22
+
23
+ it('preserves unparseable input unchanged', () => {
24
+ expect(colors.alpha('var(--color-accent)', 0.5)).toBe(
25
+ 'var(--color-accent)',
26
+ );
27
+ });
28
+ });
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import type {DefinedTheme} from '@astryxdesign/core/theme';
13
+ import {parseHex, parseColor, formatColor} from '@astryxdesign/core/utils';
13
14
 
14
15
  // =============================================================================
15
16
  // Types
@@ -105,17 +106,21 @@ function pickFromRamp(stops: string[], n: number): string[] {
105
106
  );
106
107
  }
107
108
 
109
+ /**
110
+ * Apply an opacity to a concrete CSS color (hex — with or without the leading
111
+ * `#` — `rgb()`/`rgba()`, named). The `opacity` argument always wins over any
112
+ * alpha already in the color. Unparseable input (e.g. `var()`) is returned
113
+ * unchanged.
114
+ */
108
115
  function hexAlpha(hex: string, opacity: number): string {
109
- const match = hex.match(
110
- /^#?([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/,
111
- );
112
- if (!match) {
116
+ // parseColor requires the `#` for hex; fall back to parseHex so bare hex
117
+ // strings (`0064E0`) keep working as they did before #3739.
118
+ const rgba = parseColor(hex) ?? parseHex(hex);
119
+ if (rgba === null) {
113
120
  return hex;
114
121
  }
115
- const r = parseInt(match[1], 16);
116
- const g = parseInt(match[2], 16);
117
- const b = parseInt(match[3], 16);
118
- return `rgba(${r},${g},${b},${Math.max(0, Math.min(1, opacity))})`;
122
+ const a = Number.isFinite(opacity) ? Math.max(0, Math.min(1, opacity)) : 1;
123
+ return formatColor({...rgba, a});
119
124
  }
120
125
 
121
126
  // =============================================================================
@@ -10,8 +10,12 @@
10
10
  * - Premultiplied alpha setup (correct compositing over page)
11
11
  * - Shader compilation helpers
12
12
  * - Smoothstep circle fragment for crisp point sprites
13
+ * - Hex-to-GL color conversion via the shared @astryxdesign/core/utils/color
14
+ * parsers (fallback instead of NaN)
13
15
  */
14
16
 
17
+ import {parseHex, toGLFloats} from '@astryxdesign/core/utils';
18
+
15
19
  /** Compile a WebGL shader, returns null on failure */
16
20
  export function compileShader(
17
21
  gl: WebGLRenderingContext,
@@ -56,10 +60,12 @@ export function createProgram(
56
60
  return p;
57
61
  }
58
62
 
59
- /** Parse hex (#RRGGBB) to [r, g, b] floats 0-1 */
63
+ /**
64
+ * Parse a hex color (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`) to [r, g, b]
65
+ * floats 0-1. Unparseable input returns a neutral fallback instead of NaN.
66
+ */
60
67
  export function hexToGL(hex: string): [number, number, number] {
61
- const n = parseInt(hex.replace('#', ''), 16);
62
- return [(n >> 16) / 255, ((n >> 8) & 0xff) / 255, (n & 0xff) / 255];
68
+ return toGLFloats(parseHex(hex));
63
69
  }
64
70
 
65
71
  /** DPR with supersampling for crisp circles */
@@ -274,32 +274,6 @@ export function getEventCategory(
274
274
  );
275
275
  }
276
276
 
277
- export function eventColorStyle(color: ScheduleEventColor | undefined) {
278
- switch (color) {
279
- case 'cyan':
280
- return styles.eventCyan;
281
- case 'gray':
282
- return styles.eventGray;
283
- case 'green':
284
- return styles.eventGreen;
285
- case 'orange':
286
- return styles.eventOrange;
287
- case 'pink':
288
- return styles.eventPink;
289
- case 'purple':
290
- return styles.eventPurple;
291
- case 'red':
292
- return styles.eventRed;
293
- case 'teal':
294
- return styles.eventTeal;
295
- case 'yellow':
296
- return styles.eventYellow;
297
- case 'blue':
298
- default:
299
- return styles.eventBlue;
300
- }
301
- }
302
-
303
277
  export function eventDotColorStyle(color: ScheduleEventColor | undefined) {
304
278
  switch (color) {
305
279
  case 'cyan':
@@ -415,17 +389,6 @@ export function formatWeekTitle(
415
389
  : `${startMonth} ${start.year} - ${endMonth} ${end.year}`;
416
390
  }
417
391
 
418
- export function formatRangeTitle(
419
- start: PlainDate,
420
- end: PlainDate,
421
- timezoneID: string,
422
- ): string {
423
- return `${formatShortDate(start, timezoneID)} - ${formatShortDate(
424
- end,
425
- timezoneID,
426
- )}`;
427
- }
428
-
429
392
  export function formatFullDate(date: PlainDate, timezoneID: string): string {
430
393
  return formatWithPlainDate(date, timezoneID, {
431
394
  weekday: 'long',
@@ -435,13 +398,6 @@ export function formatFullDate(date: PlainDate, timezoneID: string): string {
435
398
  });
436
399
  }
437
400
 
438
- export function formatShortDate(date: PlainDate, timezoneID: string): string {
439
- return formatWithPlainDate(date, timezoneID, {
440
- month: 'short',
441
- day: 'numeric',
442
- });
443
- }
444
-
445
401
  export function formatWeekday(
446
402
  date: PlainDate,
447
403
  timezoneID: string,
@@ -14,6 +14,7 @@
14
14
  */
15
15
 
16
16
  import {useRef, useEffect, useMemo} from 'react';
17
+ import {parseHex, toGLFloats} from '@astryxdesign/core/utils';
17
18
  import {use3D} from './ThreeDContext';
18
19
 
19
20
  export interface ThreeDScatterGLProps {
@@ -22,11 +23,6 @@ export interface ThreeDScatterGLProps {
22
23
  opacity?: number;
23
24
  }
24
25
 
25
- function hexToGL(hex: string): [number, number, number] {
26
- const n = parseInt(hex.replace('#', ''), 16);
27
- return [(n >> 16) / 255, ((n >> 8) & 0xff) / 255, (n & 0xff) / 255];
28
- }
29
-
30
26
  // SYNC: Steps 1-5 match ThreeDChart.project() exactly.
31
27
  const VERT = `
32
28
  attribute vec3 a_position;
@@ -240,7 +236,7 @@ export function ThreeDScatterGL({
240
236
  const azRad = (camera.azimuth * Math.PI) / 180;
241
237
  const elRad = (camera.elevation * Math.PI) / 180;
242
238
  const scale = Math.min(width, height) * 0.35;
243
- const [r, g, b] = hexToGL(color);
239
+ const [r, g, b] = toGLFloats(parseHex(color));
244
240
 
245
241
  gl.uniform2f(gl.getUniformLocation(program, 'u_resolution'), width, height);
246
242
  gl.uniform2f(