@astryxdesign/lab 0.7.8-canary.ea33daf → 0.7.8-canary.f10bc91

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":"Chart.d.ts","sourceRoot":"","sources":["../../src/Chart/Chart.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EAEL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAC,WAAW,EAAa,MAAM,SAAS,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAgBD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAY,EACZ,MAAM,EAAE,cAAc,EACtB,SAAkB,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,WAAW,EACpB,WAAmB,EACnB,KAAK,EACL,QAAQ,GACT,EAAE,UAAU,+BA+OZ"}
1
+ {"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../../src/Chart/Chart.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EAEL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAC,WAAW,EAAa,MAAM,SAAS,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAgBD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAY,EACZ,MAAM,EAAE,cAAc,EACtB,SAAkB,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,WAAW,EACpB,WAAmB,EACnB,KAAK,EACL,QAAQ,GACT,EAAE,UAAU,+BAgPZ"}
@@ -73,18 +73,19 @@ export function Chart({
73
73
  const containerRef = useRef(null);
74
74
  const svgRef = useRef(null);
75
75
  const [containerWidth, setContainerWidth] = useState(0);
76
- useLayoutEffect(() => {
77
- if (!containerRef.current) {
78
- return;
79
- }
76
+ const attachContainer = useCallback(container => {
77
+ containerRef.current = container;
80
78
  const observer = new ResizeObserver(entries => {
81
79
  const entry = entries[0];
82
80
  if (entry) {
83
81
  setContainerWidth(entry.contentRect.width);
84
82
  }
85
83
  });
86
- observer.observe(containerRef.current);
87
- return () => observer.disconnect();
84
+ observer.observe(container);
85
+ return () => {
86
+ observer.disconnect();
87
+ containerRef.current = null;
88
+ };
88
89
  }, []);
89
90
 
90
91
  // Block scroll/zoom on the container when interactive.
@@ -236,7 +237,7 @@ export function Chart({
236
237
  const accessibleLabel = label ?? `Chart of ${yKeys.join(', ')} by ${xKey}`;
237
238
  const showDataTable = data.length > 0 && data.length * Math.max(yKeys.length, 1) <= MAX_TABLE_POINTS;
238
239
  return /*#__PURE__*/_jsxs("div", {
239
- ref: containerRef,
240
+ ref: attachContainer,
240
241
  style: containerStyle,
241
242
  children: [containerWidth > 0 && /*#__PURE__*/_jsxs("svg", {
242
243
  ref: svgRef,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/lab",
3
- "version": "0.7.8-canary.ea33daf",
3
+ "version": "0.7.8-canary.f10bc91",
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",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@stylexjs/stylex": ">=0.10.0",
52
- "@astryxdesign/core": "0.7.8-canary.ea33daf",
52
+ "@astryxdesign/core": "0.7.8-canary.f10bc91",
53
53
  "react": ">=19.0.0",
54
54
  "react-dom": ">=19.0.0"
55
55
  },
@@ -59,9 +59,9 @@
59
59
  "d3-shape": "^3.2.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@astryxdesign/a11y-spec": "0.7.8-canary.ea33daf",
63
- "@astryxdesign/cli": "0.7.8-canary.ea33daf",
64
- "@astryxdesign/interaction-harness": "0.7.8-canary.ea33daf",
62
+ "@astryxdesign/a11y-spec": "0.7.8-canary.f10bc91",
63
+ "@astryxdesign/cli": "0.7.8-canary.f10bc91",
64
+ "@astryxdesign/interaction-harness": "0.7.8-canary.f10bc91",
65
65
  "@babel/cli": "^7.29.7",
66
66
  "@babel/core": "^7.29.7",
67
67
  "@babel/preset-react": "^7.29.7",
@@ -171,6 +171,37 @@ describe('Chart measurement gate', () => {
171
171
  });
172
172
  });
173
173
 
174
+ describe('Chart container observation', () => {
175
+ it('observes its container while mounted and stops on unmount', () => {
176
+ const observed = new Set<Element>();
177
+ vi.stubGlobal(
178
+ 'ResizeObserver',
179
+ class {
180
+ observe(element: Element) {
181
+ observed.add(element);
182
+ }
183
+ unobserve(element: Element) {
184
+ observed.delete(element);
185
+ }
186
+ disconnect() {
187
+ observed.clear();
188
+ }
189
+ },
190
+ );
191
+ const {container, unmount} = render(
192
+ <Chart data={data} xKey="month" yKeys={['revenue']}>
193
+ <g />
194
+ </Chart>,
195
+ );
196
+ const chartContainer = container.firstElementChild;
197
+ expect(chartContainer).not.toBeNull();
198
+ expect(observed.has(chartContainer!)).toBe(true);
199
+
200
+ unmount();
201
+ expect(observed.size).toBe(0);
202
+ });
203
+ });
204
+
174
205
  describe('useChart', () => {
175
206
  it('throws a clear error when used outside <Chart>', () => {
176
207
  // React reports the uncaught render error via console.error; keep the
@@ -134,18 +134,19 @@ export function Chart({
134
134
  const svgRef = useRef<SVGSVGElement>(null);
135
135
  const [containerWidth, setContainerWidth] = useState(0);
136
136
 
137
- useLayoutEffect(() => {
138
- if (!containerRef.current) {
139
- return;
140
- }
137
+ const attachContainer = useCallback((container: HTMLDivElement) => {
138
+ containerRef.current = container;
141
139
  const observer = new ResizeObserver(entries => {
142
140
  const entry = entries[0];
143
141
  if (entry) {
144
142
  setContainerWidth(entry.contentRect.width);
145
143
  }
146
144
  });
147
- observer.observe(containerRef.current);
148
- return () => observer.disconnect();
145
+ observer.observe(container);
146
+ return () => {
147
+ observer.disconnect();
148
+ containerRef.current = null;
149
+ };
149
150
  }, []);
150
151
 
151
152
  // Block scroll/zoom on the container when interactive.
@@ -320,7 +321,7 @@ export function Chart({
320
321
  data.length * Math.max(yKeys.length, 1) <= MAX_TABLE_POINTS;
321
322
 
322
323
  return (
323
- <div ref={containerRef} style={containerStyle}>
324
+ <div ref={attachContainer} style={containerStyle}>
324
325
  {containerWidth > 0 && (
325
326
  <svg
326
327
  ref={svgRef}