Skip to content

Commit 4b0c060

Browse files
committed
refactor(autoResize): remove min-height fallback, add dev warning for 0px height
autoResize now means 'fill the container, period' — the container must provide dimensions. The height prop is no longer used as a min-height fallback when autoResize is enabled. - Change inner chart div min-height from height prop to 0 - Add dev-only console.warn when ResizeObserver reports 0px height - Update JSDoc on width, height, and autoResize props - Update component example to show container with explicit height - Update source code comments explaining the CSS strategy
1 parent 0af43f1 commit 4b0c060

File tree

1 file changed

+51
-27
lines changed

1 file changed

+51
-27
lines changed

packages/solid-uplot/src/SolidUplot.tsx

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ import type { SolidUplotPluginBus, UplotPluginFactory, VoidStruct } from "./crea
1818
import { createCursorMovePlugin, type OnCursorMoveParams } from "./eventPlugins";
1919
import { getSeriesData, type SeriesDatum } from "./utils/getSeriesData";
2020

21+
const __DEV__ = (() => {
22+
try {
23+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
24+
const g = globalThis as any;
25+
return g.process?.env?.NODE_ENV !== "production";
26+
} catch {
27+
return false;
28+
}
29+
})();
30+
2131
/** Placement options for children components relative to the chart */
2232
type ChildrenPlacement = "top" | "bottom";
2333

@@ -44,19 +54,19 @@ export type SolidUplotOptions<T extends VoidStruct = VoidStruct> = Omit<
4454
/**
4555
* Chart width in pixels.
4656
*
47-
* When `autoResize` is enabled, this value is used as the `min-width`
48-
* fallback for unconstrained containers. The chart will grow beyond
49-
* this value if the container allows it.
57+
* Used as a fixed dimension when `autoResize` is disabled.
58+
* Ignored when `autoResize` is enabled — the chart fills its
59+
* container's width automatically.
5060
*
5161
* @default 600
5262
*/
5363
readonly width?: number;
5464
/**
5565
* Chart height in pixels.
5666
*
57-
* When `autoResize` is enabled, this value is used as the `min-height`
58-
* fallback for unconstrained containers. The chart will grow beyond
59-
* this value if the container allows it.
67+
* Used as a fixed dimension when `autoResize` is disabled.
68+
* Ignored when `autoResize` is enabled — the chart fills its
69+
* container's height automatically.
6070
*
6171
* @default 300
6272
*/
@@ -108,16 +118,11 @@ type SolidUplotProps<T extends VoidStruct = VoidStruct> = SolidUplotOptions<T> &
108118
*
109119
* When enabled, the chart uses a ResizeObserver to continuously
110120
* match its container's dimensions. The `width` and `height` props
111-
* are **not** used as fixed dimensions — instead they serve as
112-
* `min-width` / `min-height` fallbacks for containers that have
113-
* no explicit size constraint. If neither prop is provided, the
114-
* defaults are 600×300.
121+
* are ignored — the chart fills whatever space its container provides.
115122
*
116-
* - **Constrained container** (explicit height/width on parent):
117-
* the chart fills the available space via flexbox.
118-
* - **Unconstrained container** (no explicit height on parent):
119-
* the chart renders at the `min-height` value (the `height`
120-
* prop, defaulting to 300px) and will not grow infinitely.
123+
* The container **must** have defined dimensions (explicit height/width,
124+
* flex layout, grid layout, etc.). If the container has no height, the
125+
* chart will render at 0px and a development-mode warning will be logged.
121126
*
122127
* @default false
123128
*/
@@ -152,16 +157,22 @@ type SolidUplotProps<T extends VoidStruct = VoidStruct> = SolidUplotOptions<T> &
152157
*
153158
* @example
154159
* ```tsx
160+
* // Fixed size
155161
* <SolidUplot
156162
* data={chartData}
163+
* width={600}
157164
* height={400}
158-
* autoResize
159-
* series={[
160-
* {},
161-
* { label: "Series 1", stroke: "red" }
162-
* ]}
163-
* onCreate={(chart) => console.log("Chart created:", chart)}
165+
* series={[{}, { label: "Series 1", stroke: "red" }]}
164166
* />
167+
*
168+
* // Auto resize (container must have dimensions)
169+
* <div style={{ height: "400px" }}>
170+
* <SolidUplot
171+
* data={chartData}
172+
* autoResize
173+
* series={[{}, { label: "Series 1", stroke: "red" }]}
174+
* />
175+
* </div>
165176
* ```
166177
*/
167178
export const SolidUplot = <T extends VoidStruct = VoidStruct>(
@@ -224,7 +235,9 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
224235
createEffect(() => {
225236
const getInitialSize = () => {
226237
if (local.autoResize) {
227-
// For autoResize, use container dimensions or fallback
238+
// For autoResize, use container dimensions if available.
239+
// Fallback to 600x300 for initial uPlot construction only —
240+
// the ResizeObserver will immediately correct to actual size.
228241
const rect = container.getBoundingClientRect();
229242
return {
230243
width: rect.width > 0 ? Math.floor(rect.width) : 600,
@@ -258,9 +271,21 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
258271
createEffect(() => {
259272
if (!local.autoResize) return;
260273

274+
let hasWarnedZeroHeight = false;
275+
261276
const resizeObserver = new ResizeObserver((entries) => {
262277
for (const entry of entries) {
263278
const { width, height } = entry.contentRect;
279+
280+
if (!hasWarnedZeroHeight && height === 0 && __DEV__) {
281+
hasWarnedZeroHeight = true;
282+
console.warn(
283+
"[SolidUplot] autoResize observed 0px height. " +
284+
"Ensure the parent container has an explicit height " +
285+
"or is within a flex/grid layout that provides height.",
286+
);
287+
}
288+
264289
chart.setSize({ width: Math.floor(width), height: Math.floor(height) });
265290
}
266291
});
@@ -307,13 +332,12 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
307332
position: "relative",
308333
// When autoResize is enabled, use flex to fill remaining space.
309334
// flex-basis: 0 prevents content from dictating size (fixes infinite height bug).
310-
// min-width: 0 is sufficient because block elements naturally fill horizontal
311-
// space from their parent. min-height uses the height prop as a fallback floor
312-
// because height does not flow from parent to child in CSS — without it,
313-
// unconstrained containers would collapse the chart to 0px.
335+
// min-width/min-height: 0 allow the chart to shrink freely within
336+
// the flex container. The parent must provide dimensions — if it
337+
// doesn't, the chart collapses to 0px (with a dev-mode warning).
314338
...(local.autoResize && {
315339
flex: "1 1 0",
316-
"min-height": `${updateableOptions.height}px`,
340+
"min-height": "0",
317341
"min-width": "0",
318342
}),
319343
}}

0 commit comments

Comments
 (0)