batstack-squircle
v1.0.0
Published
BatStack Squircle for React
Downloads
4
Readme
BatStack Squircle
A React component library for creating beautiful squircle shapes with customizable roundness and responsive behavior.
What is a Squircle?
A squircle is a shape that combines the properties of a square and a circle, creating smooth, rounded corners that are more natural and aesthetically pleasing than traditional CSS border-radius. Popularized by Apple in their interfaces, squircles provide a modern, soft appearance that subtly stands out from simple rounded corners.
Features
- 🎨 Customizable Roundness: Control the squircle shape from sharp corners to fully rounded
- 📱 Responsive: Automatically adapts to container size changes using ResizeObserver
- 🎯 TypeScript Support: Fully typed with TypeScript
- 🖼️ Image Ready: Perfect for creating squircle-shaped images and containers
- 🎭 Stroke Support: Optional border/stroke with customizable width and color
- ⚡ Lightweight: Minimal bundle size with no external dependencies
- 🔧 Flexible: Works with any content - images, divs, or complex layouts
Installation
npm install batstack-squircle
# or
yarn add batstack-squircle
# or
pnpm add batstack-squircleQuick Start
import { SquircleContainer } from 'batstack-squircle';
function App() {
return (
<SquircleContainer roundness={0.4} style={{ width: '300px', height: '300px' }}>
<img
src="https://picsum.photos/300/300"
alt="Squircle image"
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
</SquircleContainer>
);
}API Reference
SquircleContainer
The main component that creates a squircle-shaped container.
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| roundness | number | Required | Controls the roundness of the squircle (0-1). 0 = sharp corners, 1 = fully rounded |
| strokeWidth | number | undefined | Width of the border/stroke in pixels |
| strokeColor | string | '#555' | Color of the border/stroke |
| children | ReactNode | - | Content to be clipped into the squircle shape |
| style | CSSProperties | - | Additional CSS styles (merged with component styles) |
| ...rest | HTMLAttributes<HTMLDivElement> | - | All standard div props |
Examples
Basic Usage
<SquircleContainer roundness={0.5} style={{ width: '200px', height: '200px' }}>
<div style={{ background: 'linear-gradient(45deg, #ff6b6b, #4ecdc4)', width: '100%', height: '100%' }} />
</SquircleContainer>With Border
<SquircleContainer
roundness={0.3}
strokeWidth={3}
strokeColor="#ffffff"
style={{ width: '300px', height: '200px' }}
>
<img src="your-image.jpg" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
</SquircleContainer>Responsive Container
<SquircleContainer
roundness={0.6}
style={{ width: '100%', height: '300px' }}
>
<div style={{ background: 'purple', width: '100%', height: '100%' }} />
</SquircleContainer>generateSquirclePath
Utility function to generate SVG path strings for squircle shapes.
import { generateSquirclePath } from 'batstack-squircle';
const { pathString, curves } = generateSquirclePath(200, 200, 0.4);
// pathString: "M 0 100 C 0 60 60 0 100 0 C 140 0 200 60 200 100 C 200 140 140 200 100 200 C 60 200 0 140 0 100 Z"Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| width | number | Required | Width of the squircle in pixels |
| height | number | Required | Height of the squircle in pixels |
| roundness | number | 0.5 | Roundness level (0-1) |
| precision | number | 2 | Decimal precision for coordinate values |
Returns
| Property | Type | Description |
|----------|------|-------------|
| pathString | string | SVG path string ready for use in clip-path or d attributes |
| curves | Array<Array<{x: number, y: number}>> | Array of Bézier curve control points |
useResizeObserver
Custom hook for observing element size changes.
import { useResizeObserver } from 'batstack-squircle';
function MyComponent() {
const ref = useRef<HTMLDivElement>(null);
const { width, height } = useResizeObserver(ref);
return <div ref={ref}>Size: {width}x{height}</div>;
}Advanced Usage
Custom CSS with Drop Shadow
Since box-shadow doesn't work with clip-path, use filter: drop-shadow() instead:
<SquircleContainer
roundness={0.4}
style={{
width: '400px',
height: '300px',
filter: 'drop-shadow(0 10px 20px rgba(0,0,0,0.3))'
}}
>
<img src="your-image.jpg" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
</SquircleContainer>Dynamic Roundness
function DynamicSquircle() {
const [roundness, setRoundness] = useState(0.5);
return (
<div>
<input
type="range"
min="0"
max="1"
step="0.1"
value={roundness}
onChange={(e) => setRoundness(Number(e.target.value))}
/>
<SquircleContainer roundness={roundness} style={{ width: '200px', height: '200px' }}>
<div style={{ background: 'orange', width: '100%', height: '100%' }} />
</SquircleContainer>
</div>
);
}Browser Support
- Modern Browsers: Full support for ResizeObserver and CSS
clip-path: path() - Fallback: For older browsers, consider using
border-radiusas a fallback
Limitations
When using squircle shapes, you lose access to some CSS features:
- ❌
borderstyles (usestrokeWidthandstrokeColorprops instead) - ❌
box-shadow(usefilter: drop-shadow()instead) - ❌
border-radius(replaced by squircle shape)
Development
# Install dependencies
yarn install:all
# Start development server with example
yarn dev
# Build the package
yarn build
# Watch for changes
yarn watchLearn More
This package is based on the comprehensive guide: Squircle - round the edges differently than everyone else
The article covers:
- Mathematical foundations of squircles
- Bézier curve implementation
- Responsive design considerations
- Performance optimizations
License
MIT © Beniamin Batkowski
