UNPKG

svelte-swipeout

Version:

iOS-style swipeable list component for Svelte 5 with delete animations and mobile-optimized touch handling

303 lines (233 loc) 8.42 kB
# svelte-swipeout A powerful and flexible swipeable list component for Svelte 5 applications with iOS-style swipe actions, delete animations, and mobile-optimized touch handling. ## Installation ```bash npm install svelte-swipeout ``` or ```bash pnpm add svelte-swipeout ``` or ```bash yarn add svelte-swipeout ``` ## Features - 🎯 **iOS-style swipe actions** - Smooth, native-feeling swipe gestures - 📱 **Mobile-optimized** - Touch-friendly with proper scroll handling - 🎨 **Customizable actions** - Left and right swipe actions with custom styling - 💥 **Overswipe support** - Trigger actions by swiping past threshold - 🗑️ **Delete animations** - Multiple delete animation styles (fade, collapse, slide, scale) - ⚡ **Performant** - Hardware-accelerated animations using CSS transforms - 🎭 **Svelte 5 ready** - Built with Svelte 5 runes and modern features ## Usage Here is a simple example of how to use the `svelte-swipeout` components: ```svelte <script> import { Swipeout, SwipeoutItem, SwipeoutContent, SwipeoutActionsLeft, SwipeoutActionsRight, SwipeoutAction, } from 'svelte-swipeout'; </script> <Swipeout> <SwipeoutItem> <SwipeoutContent> <div class="item">Swipe me</div> </SwipeoutContent> <SwipeoutActionsRight> <SwipeoutAction onclick={() => console.log('Delete clicked')}> Delete </SwipeoutAction> </SwipeoutActionsRight> </SwipeoutItem> </Swipeout> ``` ## Examples ### Simple Swipe This example shows a simple swipe with left and right actions. ```svelte <Swipeout> <SwipeoutItem> <SwipeoutContent> <div class="item">Swipe me</div> </SwipeoutContent> <SwipeoutActionsLeft> <SwipeoutAction on:click={() => console.log('Archive clicked')}> Archive </SwipeoutAction> </SwipeoutActionsLeft> <SwipeoutActionsRight> <SwipeoutAction onclick={() => console.log('Delete clicked')}> Delete </SwipeoutAction> </SwipeoutActionsRight> </SwipeoutItem> </Swipeout> ``` ### Delete with Animation This example shows how to use the delete functionality with animations. The component supports multiple delete animation styles. ```svelte <script> let items = $state([ { id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }, { id: 3, name: 'Item 3' } ]); function handleDelete(id) { items = items.filter(item => item.id !== id); } </script> <!-- Default fade animation --> <Swipeout> {#each items as item (item.id)} <SwipeoutItem delete onDelete={() => handleDelete(item.id)}> <SwipeoutContent> <div class="item">{item.name}</div> </SwipeoutContent> <SwipeoutActionsRight> <SwipeoutAction overSwipe class="bg-red-500" data-delete="true" > Delete </SwipeoutAction> </SwipeoutActionsRight> </SwipeoutItem> {/each} </Swipeout> <!-- With collapse animation --> <Swipeout class="swipeout-delete-collapse"> <!-- items here --> </Swipeout> <!-- With slide animation --> <Swipeout class="swipeout-delete-slide"> <!-- items here --> </Swipeout> <!-- With scale animation --> <Swipeout class="swipeout-delete-scale"> <!-- items here --> </Swipeout> ``` ### Overswipe Actions Overswipe actions are triggered when the user swipes past a certain threshold. Perfect for destructive actions like delete. ```svelte <Swipeout> <SwipeoutItem> <SwipeoutContent> <div class="item">Swipe me far to trigger overswipe</div> </SwipeoutContent> <SwipeoutActionsLeft> <SwipeoutAction overSwipe class="bg-green-500"> Reply </SwipeoutAction> </SwipeoutActionsLeft> <SwipeoutActionsRight> <SwipeoutAction overSwipe class="bg-red-500"> Delete </SwipeoutAction> </SwipeoutActionsRight> </SwipeoutItem> </Swipeout> ``` ### Programmatic Control You can programmatically close swipeouts using the exported functions: ```svelte <script> import { closeSwipeout, closeAll } from 'svelte-swipeout'; // Close a specific swipeout element function handleClose(element) { closeSwipeout(element); } // Close all open swipeouts function handleCloseAll() { closeAll(); } </script> ``` ### Custom Styling You can customize the colors and styles of the components using CSS variables. ```css :root { --swipeout-delete-button-bg-color: #ff3b30; --swipeout-button-text-color: #fff; --swipeout-button-padding-vertical: 0; --swipeout-button-padding-horizontal: 30px; --swipeout-button-font-size: inherit; --swipeout-button-font-weight: inherit; } ``` You can also use the `class` prop to add custom classes to the components. ```svelte <SwipeoutAction class="my-custom-class"> Delete </SwipeoutAction> ``` ## API ### Swipeout The root component for the swipeout list. | Prop | Type | Default | Description | | -------- | -------- | ------- | --------------------- | | `class` | `string` | `''` | Custom class for the component. | ### SwipeoutItem A single item in the swipeout list. Handles all swipe interactions and animations. | Prop | Type | Default | Description | | -------- | -------- | ------- | --------------------- | | `class` | `string` | `''` | Custom class for the component. | | `delete` | `boolean` | `false` | Enable delete functionality with animations. | | `onDelete` | `function` | `undefined` | Callback function when item is deleted (only used when `delete` is true). | **Events:** - `swipeout:open` - Fired when swipeout starts opening - `swipeout:opened` - Fired when swipeout is fully opened - `swipeout:close` - Fired when swipeout starts closing - `swipeout:closed` - Fired when swipeout is fully closed - `swipeout:delete` - Fired when delete is triggered - `swipeout:deleted` - Fired after delete animation completes ### SwipeoutContent The content of the swipeout item. | Prop | Type | Default | Description | | -------- | -------- | ------- | --------------------- | | `class` | `string` | `''` | Custom class for the component. | ### SwipeoutActionsLeft A container for the left swipeout actions. | Prop | Type | Default | Description | | -------- | -------- | ------- | --------------------- | | `class` | `string` | `''` | Custom class for the component. | ### SwipeoutActionsRight A container for the right swipeout actions. | Prop | Type | Default | Description | | -------- | -------- | ------- | --------------------- | | `class` | `string` | `''` | Custom class for the component. | ### SwipeoutAction A single action button in the swipeout actions. | Prop | Type | Default | Description | | ----------- | ---------- | ------- | --------------------------------------------------------------------------- | | `class` | `string` | `''` | Custom class for the component. | | `overSwipe` | `boolean` | `false` | If `true`, the action will be triggered when the user swipes past a certain threshold. | | `onclick` | `function` | `() => {}` | A function to be called when the action is clicked. | | `data-delete` | `string` | `undefined` | Set to `"true"` to mark this as a delete action (used with SwipeoutItem's delete prop). | ## Mobile Support The component is fully optimized for mobile devices with: - **Touch-action CSS** - Prevents scroll interference during swipes - **Intelligent scroll detection** - Differentiates between vertical scrolling and horizontal swiping - **Proper event handling** - Uses pointer events for unified touch/mouse support - **Momentum scrolling** - Maintains smooth iOS-style scrolling when not swiping - **One-at-a-time** - Only one swipeout can be open at a time for better UX ## Delete Animations The component supports multiple delete animation styles that can be applied by adding a class to the `Swipeout` container: - **Default** - Simple fade out - **`swipeout-delete-collapse`** - Fade out with height collapse - **`swipeout-delete-slide`** - Slide left and collapse - **`swipeout-delete-scale`** - Scale down and collapse ## Browser Support - Modern browsers with ES6+ support - iOS Safari 12+ - Chrome 80+ - Firefox 75+ - Edge 80+ ## License MIT