|
1 | 1 | <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"> |
3 | 3 | </p> |
4 | 4 |
|
5 | | -# Template: SolidJS Library |
| 5 | +# @dschz/solid-auto-sizer |
6 | 6 |
|
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. |
8 | 8 |
|
9 | | -Other things configured include: |
| 9 | + |
| 10 | +[](https://badge.fury.io/js/@dschz%2Fsolid-auto-sizer) |
| 11 | +[](https://opensource.org/licenses/MIT) |
10 | 12 |
|
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. |
17 | 14 |
|
18 | | -## Getting Started |
| 15 | +## ✨ Features |
19 | 16 |
|
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 |
21 | 23 |
|
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 |
30 | 25 |
|
31 | | -### Installing Dependencies |
| 26 | +Install via your favorite package manager: |
32 | 27 |
|
33 | 28 | ```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 |
36 | 33 | ``` |
37 | 34 |
|
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 | +``` |
39 | 58 |
|
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>; |
42 | 67 | ``` |
43 | 68 |
|
44 | | -### Linting & Formatting |
| 69 | +### With Initial Dimensions |
45 | 70 |
|
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"; |
49 | 146 |
|
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>; |
52 | 152 | ``` |
53 | 153 |
|
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. |
55 | 214 |
|
56 | | -The only requirements when contributing are: |
| 215 | +## 🙏 Acknowledgments |
57 | 216 |
|
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/) |
0 commit comments