UNPKG

@nine-slice-frame/react

Version:

Nine-slice scaling component for React using CSS border-image

151 lines (113 loc) • 6.14 kB
# @nine-slice-frame/react [![npm version](https://img.shields.io/npm/v/@nine-slice-frame/react.svg)](https://www.npmjs.com/package/@nine-slice-frame/react) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Nine-slice scaling component for React using CSS `border-image`. šŸŽÆ **[Live Demo & Tester Tool](https://callum-gander.github.io/nine-slice-frame/)** ## What is Nine-Slice Scaling? Nine-slice scaling divides an image into 9 sections, allowing it to scale to any size while preserving corner details and preventing distortion. Perfect for UI frames, borders, panels, and buttons that need to scale dynamically. ``` ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Corner │ Top Edge │ Corner │ │ (Fixed) │ (Scale H) │ (Fixed) │ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤ │ Left │ Center │ Right │ │ Edge │ (Scale │ Edge │ │(Scale V)│ Both) │(Scale V)│ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤ │ Corner │ Bottom │ Corner │ │ (Fixed) │ Edge │ (Fixed) │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ``` ## Why Nine-Slice Scaling? **The Problem:** Traditional image scaling stretches the entire image uniformly, distorting corners, borders, and decorative elements. This makes UI elements look unprofessional and breaks visual consistency. **The Solution:** Nine-slice scaling keeps corners and edges crisp while only stretching the middle sections. This means: - **Single image, infinite sizes** - One asset works for buttons, dialogs, and panels of any dimension - **Pixel-perfect corners** - Ornate borders and rounded corners stay sharp at any scale - **Smaller file sizes** - No need for multiple image variants for different sizes - **Ideal for pixel art** - Preserves the crisp aesthetic of retro-style UIs - **CSS-native performance** - Uses browser-native `border-image`, no canvas or WebGL overhead **Common Use Cases:** - Game UI frames and dialog boxes - Decorative borders and panels - Scalable buttons with ornate edges - Retro/pixel art interfaces - Dynamic content containers ## Why This Library? **Zero Dependencies** - No runtime dependencies beyond React. This package only requires React as a peer dependency. **Incredibly Small** - Minimal bundle impact: **~881B (ESM)** **Native Performance** - Uses browser-native CSS `border-image` property, not canvas rendering or heavy image manipulation libraries. Fast, efficient, and hardware-accelerated. **Framework-Agnostic API** - Same simple, consistent API across all frameworks: - [@nine-slice-frame/react](https://www.npmjs.com/package/@nine-slice-frame/react) (you are here) - [@nine-slice-frame/vue](https://www.npmjs.com/package/@nine-slice-frame/vue) - [@nine-slice-frame/svelte](https://www.npmjs.com/package/@nine-slice-frame/svelte) - [@nine-slice-frame/solid](https://www.npmjs.com/package/@nine-slice-frame/solid) ## Installation ```bash npm install @nine-slice-frame/react # or pnpm add @nine-slice-frame/react # or yarn add @nine-slice-frame/react ``` ## Usage ```tsx import { NineSliceFrame } from '@nine-slice-frame/react'; function App() { return ( <NineSliceFrame imagePath="/ui/frame.png" slice={7} borderWidth={5} repeat="stretch" fill={true} pixelated={true} > <p>Your content here</p> </NineSliceFrame> ); } ``` ## Props | Prop | Type | Default | Description | | ------------- | --------------------------------------------- | ----------- | --------------------------------------------------------------------------------- | | `imagePath` | `string` | required | Path to the image (relative to public folder) | | `slice` | `number \| object` | `8` | Slice values - number for uniform, or `{ top, right, bottom, left }` for per-edge | | `borderWidth` | `number` | `5` | Visual border width in pixels | | `repeat` | `'stretch' \| 'repeat' \| 'round' \| 'space'` | `'stretch'` | Border repeat mode | | `fill` | `boolean` | `true` | Use 'fill' to show center of image as background | | `pixelated` | `boolean` | `true` | Use pixelated rendering for pixel art | | `className` | `string` | `''` | Additional CSS class names | | `style` | `React.CSSProperties` | `{}` | Additional inline styles | ## Advanced Usage ### Different Slice Values Per Edge ```tsx <NineSliceFrame imagePath="/ui/fancy-frame.png" slice={{ top: 10, right: 8, bottom: 10, left: 8 }} borderWidth={6} > Content with asymmetric border </NineSliceFrame> ``` ### Custom Styling ```tsx <NineSliceFrame imagePath="/ui/frame.png" slice={8} borderWidth={10} className="my-custom-frame" style={{ padding: '20px', minHeight: '200px' }} > Styled content </NineSliceFrame> ``` ## TypeScript This package includes TypeScript definitions out of the box. ## Requirements - React >= 18.0.0 ## License MIT Ā© Callum Gander ## Links - [Main Repository](https://github.com/callum-gander/nine-slice-frame) - [Live Demo](https://callum-gander.github.io/nine-slice-frame/) - [Report Issues](https://github.com/callum-gander/nine-slice-frame/issues)