UNPKG

@nine-slice-frame/vue

Version:

Nine-slice scaling component for Vue 3 using CSS border-image

157 lines (118 loc) • 6.31 kB
# @nine-slice-frame/vue [![npm version](https://img.shields.io/npm/v/@nine-slice-frame/vue.svg)](https://www.npmjs.com/package/@nine-slice-frame/vue) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Nine-slice scaling component for Vue 3 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 Vue. This package only requires Vue 3 as a peer dependency. **Incredibly Small** - Minimal bundle impact: **1.33KB / 0.67KB gzipped** **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) - [@nine-slice-frame/vue](https://www.npmjs.com/package/@nine-slice-frame/vue) (you are here) - [@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/vue # or pnpm add @nine-slice-frame/vue # or yarn add @nine-slice-frame/vue ``` ## Usage ```vue <script setup lang="ts"> import { NineSliceFrame } from '@nine-slice-frame/vue'; </script> <template> <NineSliceFrame image-path="/ui/frame.png" :slice="7" :border-width="5" repeat="stretch" :fill="true" :pixelated="true" > <p>Your content here</p> </NineSliceFrame> </template> ``` ## Props | Prop | Type | Default | Description | | ------------- | --------------------------------------------- | ----------- | --------------------------------------------------------------------------------- | | `image-path` | `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 | | `border-width`| `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 | | `class` | `string` | `''` | Additional CSS class names | | `style` | `StyleValue` | `{}` | Additional inline styles | **Note:** Vue uses kebab-case for props in templates (`image-path`, `border-width`). ## Advanced Usage ### Different Slice Values Per Edge ```vue <template> <NineSliceFrame image-path="/ui/fancy-frame.png" :slice="{ top: 10, right: 8, bottom: 10, left: 8 }" :border-width="6" > Content with asymmetric border </NineSliceFrame> </template> ``` ### Custom Styling ```vue <template> <NineSliceFrame image-path="/ui/frame.png" :slice="8" :border-width="10" class="my-custom-frame" :style="{ padding: '20px', minHeight: '200px' }" > Styled content </NineSliceFrame> </template> ``` ## TypeScript This package includes TypeScript definitions out of the box. ## Requirements - Vue >= 3.3.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)