Skip to content

Commit 337342d

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

15 files changed

Lines changed: 2402 additions & 52 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ jobs:
2727
run: bun run lint
2828
- name: Format Check
2929
run: bun run format
30+
- name: Run Tests
31+
run: bun run test

README.md

Lines changed: 195 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,218 @@
11
<p>
2-
<img width="100%" src="https://assets.solidjs.com/banner?type=Ecosystem&background=tiles&project=library-name" alt="solid-create-script">
2+
<img width="100%" src="https://assets.solidjs.com/banner?type=Ecosystem&background=tiles&project=solid-auto-sizer" alt="SolidJS AutoSizer">
33
</p>
44

5-
# Template: SolidJS Library
5+
# @dschz/solid-auto-sizer
66

7-
Template for [SolidJS](https://www.solidjs.com/) library package. Bundling of the library is managed by [tsup](https://tsup.egoist.dev/).
7+
> A SolidJS component that automatically measures and provides the width and height of its parent container, making it perfect for responsive layouts and virtualized components.
88
9-
Other things configured include:
9+
![SolidJS](https://img.shields.io/badge/SolidJS-2c4f7c?logo=solid&logoColor=c8c9cb)
10+
[![npm version](https://badge.fury.io/js/@dschz%2Fsolid-auto-sizer.svg)](https://badge.fury.io/js/@dschz%2Fsolid-auto-sizer)
11+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
1012

11-
- Bun (for dependency management and running scripts)
12-
- TypeScript
13-
- ESLint / Prettier
14-
- Solid Testing Library + Vitest (for testing)
15-
- Playground app using library
16-
- GitHub Actions (for all CI/CD)
13+
**Inspired by [React Virtualized Auto Sizer](https://github.com/bvaughn/react-virtualized-auto-sizer)**, this component brings the same powerful auto-sizing capabilities to SolidJS with modern improvements like ResizeObserver API and reactive signals for better performance and developer experience.
1714

18-
## Getting Started
15+
## ✨ Features
1916

20-
Some pre-requisites before install dependencies:
17+
- 🔍 **Modern ResizeObserver API** - Better performance and reliability
18+
-**Reactive updates** - Uses SolidJS signals for efficient re-rendering
19+
- 🎛️ **Customizable initial dimensions** - Set default width/height for initial render
20+
- 📞 **Optional resize callbacks** - Get notified when size changes
21+
- 🎨 **Style and class prop support** - Full styling flexibility
22+
- 📦 **Lightweight** - Minimal bundle size with zero dependencies
2123

22-
- Install Node Version Manager (NVM)
23-
```bash
24-
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
25-
```
26-
- Install Bun
27-
```bash
28-
curl -fsSL https://bun.sh/install | bash
29-
```
24+
## 📦 Installation
3025

31-
### Installing Dependencies
26+
Install via your favorite package manager:
3227

3328
```bash
34-
nvm use
35-
bun install
29+
npm install solid-js @dschz/solid-auto-sizer
30+
pnpm install solid-js @dschz/solid-auto-sizer
31+
yarn install solid-js @dschz/solid-auto-sizer
32+
bun install solid-js @dschz/solid-auto-sizer
3633
```
3734

38-
### Local Development Build
35+
> This is a **peer dependency**, so it must be installed manually:
36+
>
37+
> - `solid-js@>=1.6.0`
38+
39+
## 🚀 Quick Start
40+
41+
```tsx
42+
import { AutoSizer } from "@dschz/solid-auto-sizer";
43+
44+
function MyComponent() {
45+
return (
46+
<div style={{ width: "100%", height: "400px" }}>
47+
<AutoSizer>
48+
{({ width, height }) => (
49+
<div style={{ width: `${width}px`, height: `${height}px` }}>
50+
Content that adapts to container size: {width} × {height}
51+
</div>
52+
)}
53+
</AutoSizer>
54+
</div>
55+
);
56+
}
57+
```
3958

40-
```bash
41-
bun start
59+
## 📖 Usage Examples
60+
61+
### Basic Usage
62+
63+
```tsx
64+
import { AutoSizer } from "@dschz/solid-auto-sizer";
65+
66+
<AutoSizer>{({ width, height }) => <canvas width={width} height={height} />}</AutoSizer>;
4267
```
4368

44-
### Linting & Formatting
69+
### With Initial Dimensions
4570

46-
```bash
47-
bun run lint # checks source for lint violations
48-
bun run format # checks source for format violations
71+
```tsx
72+
<AutoSizer initialWidth={400} initialHeight={300}>
73+
{({ width, height }) => <MyChart width={width} height={height} data={data} />}
74+
</AutoSizer>
75+
```
76+
77+
### With Resize Callback
78+
79+
```tsx
80+
<AutoSizer
81+
onResize={({ width, height }) => {
82+
console.log(`Container resized to: ${width}x${height}`);
83+
}}
84+
>
85+
{({ width, height }) => <VirtualizedList width={width} height={height} items={items} />}
86+
</AutoSizer>
87+
```
88+
89+
### With Custom Styling
90+
91+
```tsx
92+
<AutoSizer
93+
class="my-auto-sizer"
94+
style={{
95+
"background-color": "#f0f0f0",
96+
border: "1px solid #ccc",
97+
padding: "10px",
98+
}}
99+
>
100+
{({ width, height }) => (
101+
<div>
102+
Styled container: {width} × {height}
103+
</div>
104+
)}
105+
</AutoSizer>
106+
```
107+
108+
## 📚 API Reference
109+
110+
### Props
111+
112+
| Prop | Type | Default | Description |
113+
| --------------- | ----------------------------- | ------------ | ----------------------------------------------------------- |
114+
| `children` | `(size: Size) => JSX.Element` | **Required** | Render prop that receives the measured dimensions |
115+
| `initialWidth` | `number` | `0` | Default width for initial render before measurement |
116+
| `initialHeight` | `number` | `0` | Default height for initial render before measurement |
117+
| `onResize` | `(size: Size) => void` | `undefined` | Callback fired when container size changes |
118+
| `class` | `string` | `undefined` | CSS class for the container element |
119+
| `style` | `JSX.CSSProperties` | `undefined` | Inline styles for the container (width/height are reserved) |
120+
121+
### Types
122+
123+
```tsx
124+
type Size = {
125+
readonly width: number;
126+
readonly height: number;
127+
};
128+
129+
type AutoSizerProps = {
130+
readonly class?: string;
131+
readonly style?: Omit<JSX.CSSProperties, "width" | "height">;
132+
readonly initialWidth?: number;
133+
readonly initialHeight?: number;
134+
readonly onResize?: (size: Size) => void;
135+
readonly children: (size: Size) => JSX.Element;
136+
};
137+
```
138+
139+
## 💡 Common Use Cases
140+
141+
### Charts and Visualizations
142+
143+
```tsx
144+
import { AutoSizer } from "@dschz/solid-auto-sizer";
145+
import { LineChart } from "my-chart-library";
49146

50-
bun run lint:fix # fixes lint violations
51-
bun run format:fix # fixes format violations
147+
<div style={{ width: "100%", height: "400px" }}>
148+
<AutoSizer>
149+
{({ width, height }) => <LineChart width={width} height={height} data={chartData} />}
150+
</AutoSizer>
151+
</div>;
52152
```
53153

54-
### Contributing
154+
### Virtualized Lists
155+
156+
```tsx
157+
import { AutoSizer } from "@dschz/solid-auto-sizer";
158+
import { VirtualList } from "my-virtualization-library";
159+
160+
<div style={{ width: "100%", height: "600px" }}>
161+
<AutoSizer>
162+
{({ width, height }) => (
163+
<VirtualList
164+
width={width}
165+
height={height}
166+
itemCount={items.length}
167+
itemSize={50}
168+
renderItem={({ index }) => <div>{items[index].name}</div>}
169+
/>
170+
)}
171+
</AutoSizer>
172+
</div>;
173+
```
174+
175+
### Responsive Grids
176+
177+
```tsx
178+
import { AutoSizer } from "@dschz/solid-auto-sizer";
179+
180+
<AutoSizer>
181+
{({ width }) => {
182+
const columns = Math.floor(width / 200); // 200px per column
183+
return (
184+
<div
185+
style={{
186+
display: "grid",
187+
"grid-template-columns": `repeat(${columns}, 1fr)`,
188+
gap: "16px",
189+
}}
190+
>
191+
{items.map((item) => (
192+
<GridItem key={item.id} {...item} />
193+
))}
194+
</div>
195+
);
196+
}}
197+
</AutoSizer>;
198+
```
199+
200+
## 🌐 Browser Support
201+
202+
AutoSizer uses the [ResizeObserver API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver), which is supported in:
203+
204+
- Chrome 64+
205+
- Firefox 69+
206+
- Safari 13.1+
207+
- Edge 79+
208+
209+
For older browsers, you can use a [ResizeObserver polyfill](https://github.com/que-etc/resize-observer-polyfill).
210+
211+
## 📄 License
212+
213+
MIT License - see [LICENSE](LICENSE) file for details.
55214

56-
The only requirements when contributing are:
215+
## 🙏 Acknowledgments
57216

58-
- You keep a clean git history in your branch
59-
- rebasing `main` instead of making merge commits.
60-
- Using proper commit message formats that adhere to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
61-
- Additionally, squashing (via rebase) commits that are not [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
62-
- CI checks pass before merging into `main`
217+
- Inspired by [React Virtualized Auto Sizer](https://github.com/bvaughn/react-virtualized-auto-sizer)
218+
- Built with [SolidJS](https://www.solidjs.com/)

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
);

0 commit comments

Comments
 (0)