Skip to content

Commit d67fbb0

Browse files
committed
feat: initial implementation of AutoSizer component
1 parent 089805f commit d67fbb0

13 files changed

Lines changed: 2205 additions & 13 deletions

jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "template-solidjs-library",
2+
"name": "@dschz/solid-auto-sizer",
33
"version": "0.0.0",
44
"license": "MIT",
55
"exports": "./src/index.tsx",

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
{
2-
"name": "template-solidjs-library",
2+
"name": "@dschz/solid-auto-sizer",
33
"version": "0.0.0",
4-
"description": "Template for SolidJS library using tsup for bundling. Configured with Bun, NVM, TypeScript, ESLint, Prettier, Vitest, and GHA",
4+
"description": "SolidJS component that automatically measures and provides the width and height of its parent — useful for virtualized lists, grids, and charts.",
55
"type": "module",
66
"author": "Daniel Sanchez <dsanc89@icloud.com>",
77
"license": "MIT",
8-
"homepage": "https://github.com/thedanchez/template-solidjs-library#readme",
8+
"homepage": "https://github.com/dsnchz/solid-auto-sizer#readme",
99
"repository": {
1010
"type": "git",
11-
"url": "https://github.com/thedanchez/template-solidjs-library.git"
11+
"url": "https://github.com/dsnchz/solid-auto-sizer.git"
1212
},
1313
"bugs": {
14-
"url": "https://github.com/thedanchez/template-solidjs-library/issues"
14+
"url": "https://github.com/dsnchz/solid-auto-sizer/issues"
1515
},
1616
"publishConfig": {
1717
"access": "public"

playground/App.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import { Route, Router } from "@solidjs/router";
22
import { ErrorBoundary, type ParentProps } from "solid-js";
33

44
import { Navbar } from "./Navbar";
5+
import { BasicExample } from "./pages/BasicExample";
6+
import { ChartsExample } from "./pages/ChartsExample";
57
import { ErrorPage } from "./pages/Error";
8+
import { GridsExample } from "./pages/GridsExample";
69
import { Home } from "./pages/Home";
10+
import { ListsExample } from "./pages/ListsExample";
711
import { NotFound } from "./pages/NotFound";
812

913
const MainContent = (props: ParentProps) => {
@@ -26,6 +30,10 @@ export const App = () => {
2630
<ErrorBoundary fallback={(e, r) => <ErrorPage error={e} reset={r} />}>
2731
<Router root={RootLayout}>
2832
<Route path="/" component={Home} />
33+
<Route path="/basic" component={BasicExample} />
34+
<Route path="/charts" component={ChartsExample} />
35+
<Route path="/lists" component={ListsExample} />
36+
<Route path="/grids" component={GridsExample} />
2937
<Route path="*" component={NotFound} />
3038
</Router>
3139
</ErrorBoundary>

playground/Navbar.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,23 @@ import { A } from "@solidjs/router";
33
export const Navbar = () => {
44
return (
55
<nav class="bg-gray-800 text-white p-2 flex items-center">
6-
<div class="text-lg font-semibold mr-6">Playground</div>
7-
<div>
8-
<A href="/" class="hover:text-gray-300">
6+
<div class="text-lg font-semibold mr-6">AutoSizer Playground</div>
7+
<div class="flex space-x-4">
8+
<A href="/" class="hover:text-gray-300 px-2 py-1 rounded">
99
Home
1010
</A>
11+
<A href="/basic" class="hover:text-gray-300 px-2 py-1 rounded">
12+
Basic
13+
</A>
14+
<A href="/charts" class="hover:text-gray-300 px-2 py-1 rounded">
15+
Charts
16+
</A>
17+
<A href="/lists" class="hover:text-gray-300 px-2 py-1 rounded">
18+
Lists
19+
</A>
20+
<A href="/grids" class="hover:text-gray-300 px-2 py-1 rounded">
21+
Grids
22+
</A>
1123
</div>
1224
</nav>
1325
);

playground/pages/BasicExample.tsx

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import { createSignal } from "solid-js";
2+
3+
import { AutoSizer } from "../../src/AutoSizer";
4+
5+
export const BasicExample = () => {
6+
const [resizeCount, setResizeCount] = createSignal(0);
7+
const [lastSize, setLastSize] = createSignal({ width: 0, height: 0 });
8+
9+
const handleResize = (size: { width: number; height: number }) => {
10+
setResizeCount((prev) => prev + 1);
11+
setLastSize(size);
12+
};
13+
14+
return (
15+
<div class="p-6 max-w-6xl mx-auto">
16+
<h1 class="text-3xl font-bold mb-6">Basic AutoSizer Examples</h1>
17+
18+
<div class="space-y-8">
19+
{/* Example 1: Simple responsive content */}
20+
<section class="bg-white rounded-lg shadow-md p-6">
21+
<h2 class="text-xl font-semibold mb-4">1. Simple Responsive Content</h2>
22+
<p class="text-gray-600 mb-4">
23+
AutoSizer automatically provides dimensions to its children. Resize the container to see
24+
it adapt.
25+
</p>
26+
27+
<div class="border-2 border-dashed border-gray-300 h-64 resize overflow-auto">
28+
<AutoSizer>
29+
{({ width, height }) => (
30+
<div
31+
class="bg-gradient-to-br from-blue-400 to-purple-600 text-white flex items-center justify-center text-lg font-semibold"
32+
style={{ width: `${width}px`, height: `${height}px` }}
33+
>
34+
<div class="text-center">
35+
<div>Container Size</div>
36+
<div class="text-2xl">
37+
{width} × {height}
38+
</div>
39+
</div>
40+
</div>
41+
)}
42+
</AutoSizer>
43+
</div>
44+
</section>
45+
46+
{/* Example 2: With resize callback */}
47+
<section class="bg-white rounded-lg shadow-md p-6">
48+
<h2 class="text-xl font-semibold mb-4">2. With Resize Callback</h2>
49+
<p class="text-gray-600 mb-4">
50+
Track resize events and display statistics about size changes.
51+
</p>
52+
53+
<div class="mb-4 p-3 bg-gray-100 rounded">
54+
<div class="grid grid-cols-2 gap-4 text-sm">
55+
<div>
56+
Resize Count: <span class="font-semibold">{resizeCount()}</span>
57+
</div>
58+
<div>
59+
Last Size:{" "}
60+
<span class="font-semibold">
61+
{lastSize().width} × {lastSize().height}
62+
</span>
63+
</div>
64+
</div>
65+
</div>
66+
67+
<div class="border-2 border-dashed border-gray-300 h-48 resize overflow-auto">
68+
<AutoSizer onResize={handleResize}>
69+
{({ width, height }) => (
70+
<div
71+
class="bg-gradient-to-r from-green-400 to-blue-500 text-white flex items-center justify-center"
72+
style={{ width: `${width}px`, height: `${height}px` }}
73+
>
74+
<div class="text-center">
75+
<div class="text-lg">Resize me!</div>
76+
<div class="text-sm opacity-80">Events tracked: {resizeCount()}</div>
77+
</div>
78+
</div>
79+
)}
80+
</AutoSizer>
81+
</div>
82+
</section>
83+
84+
{/* Example 3: Initial dimensions */}
85+
<section class="bg-white rounded-lg shadow-md p-6">
86+
<h2 class="text-xl font-semibold mb-4">3. Custom Initial Dimensions</h2>
87+
<p class="text-gray-600 mb-4">
88+
Set initial width and height for server-side rendering or to avoid layout shifts.
89+
</p>
90+
91+
<div class="border-2 border-dashed border-gray-300 h-56 resize overflow-auto">
92+
<AutoSizer initialWidth={400} initialHeight={200}>
93+
{({ width, height }) => (
94+
<div
95+
class="bg-gradient-to-tr from-pink-400 to-red-500 text-white flex flex-col items-center justify-center"
96+
style={{ width: `${width}px`, height: `${height}px` }}
97+
>
98+
<div class="text-lg font-semibold">Initial: 400 × 200</div>
99+
<div class="text-sm opacity-80">
100+
Current: {width} × {height}
101+
</div>
102+
<div class="text-xs opacity-60 mt-2">
103+
{width === 400 && height === 200
104+
? "Using initial size"
105+
: "Measured actual size"}
106+
</div>
107+
</div>
108+
)}
109+
</AutoSizer>
110+
</div>
111+
</section>
112+
113+
{/* Example 4: Flexbox integration */}
114+
<section class="bg-white rounded-lg shadow-md p-6">
115+
<h2 class="text-xl font-semibold mb-4">4. Flexbox Integration</h2>
116+
<p class="text-gray-600 mb-4">
117+
AutoSizer works well with flexbox layouts. The container grows to fill available space.
118+
</p>
119+
120+
<div class="flex h-64 gap-4">
121+
<div class="w-1/3 bg-gray-200 flex items-center justify-center">
122+
<span class="text-gray-600">Sidebar</span>
123+
</div>
124+
125+
<div class="flex-1 border-2 border-dashed border-gray-300">
126+
<AutoSizer>
127+
{({ width, height }) => (
128+
<div
129+
class="bg-gradient-to-bl from-yellow-400 to-orange-500 text-white flex items-center justify-center"
130+
style={{ width: `${width}px`, height: `${height}px` }}
131+
>
132+
<div class="text-center">
133+
<div class="text-lg">Flex Content</div>
134+
<div class="text-sm">
135+
{width} × {height}
136+
</div>
137+
</div>
138+
</div>
139+
)}
140+
</AutoSizer>
141+
</div>
142+
143+
<div class="w-1/4 bg-gray-200 flex items-center justify-center">
144+
<span class="text-gray-600">Panel</span>
145+
</div>
146+
</div>
147+
</section>
148+
149+
{/* Example 5: Multiple AutoSizers */}
150+
<section class="bg-white rounded-lg shadow-md p-6">
151+
<h2 class="text-xl font-semibold mb-4">5. Multiple AutoSizers</h2>
152+
<p class="text-gray-600 mb-4">
153+
Multiple AutoSizers can be used independently in the same layout.
154+
</p>
155+
156+
<div class="grid grid-cols-2 gap-4 h-48">
157+
<div class="border-2 border-dashed border-gray-300">
158+
<AutoSizer>
159+
{({ width, height }) => (
160+
<div
161+
class="bg-gradient-to-r from-indigo-400 to-purple-500 text-white flex items-center justify-center"
162+
style={{ width: `${width}px`, height: `${height}px` }}
163+
>
164+
<div class="text-center">
165+
<div>Left Panel</div>
166+
<div class="text-sm">
167+
{width} × {height}
168+
</div>
169+
</div>
170+
</div>
171+
)}
172+
</AutoSizer>
173+
</div>
174+
175+
<div class="border-2 border-dashed border-gray-300">
176+
<AutoSizer>
177+
{({ width, height }) => (
178+
<div
179+
class="bg-gradient-to-l from-teal-400 to-cyan-500 text-white flex items-center justify-center"
180+
style={{ width: `${width}px`, height: `${height}px` }}
181+
>
182+
<div class="text-center">
183+
<div>Right Panel</div>
184+
<div class="text-sm">
185+
{width} × {height}
186+
</div>
187+
</div>
188+
</div>
189+
)}
190+
</AutoSizer>
191+
</div>
192+
</div>
193+
</section>
194+
</div>
195+
</div>
196+
);
197+
};

0 commit comments

Comments
 (0)