@slidy/svelte
v3.5.3
Published
Simple, configurable & reusable carousel component built with SvelteJS
Downloads
1,310
Maintainers
Readme
@slidy/svelte
Simple, configurable & reusable carousel component built with SvelteJS based on @slidy/core.
Try the demo.
Getting started
The package is available via npm:
npm i @slidy/svelte
Playground is available in REPL.
Usage
The most simple way to get started is to use named import of <Slidy />
component:
<script>
import { Slidy } from "@slidy/svelte";
const slides = [
{
id: 1,
width: 800,
height: 1200,
src: "static/img/some-image.webp",
},
];
</script>
<Slidy {slides} />
All props are optional. The only property to get started is slides
- an array of objects with image related data.
Core Component
Core
is a wrapper component for @slidy/core available via named import. It is best to use to build up the custom component for specific needs or when just the basic functionality is needed.
<script>
import { Core } from "@slidy/svelte";
</script>
<Core>
<!-- your carousel items passed via slot -->
</Core>
Core Component API
| Property | Default | Type | Description |
| :------------ | :--------------: | :--------: | :------------------ |
| animation
| undefined
| AnimationFunc
| Custom slide animation. |
| axis
| "x"
| "x" | "y"
| The scroll direction. |
| clamp
| 0
| number
| Defines number of items to jump over at one slide action. |
| className
| ""
| string
| Passes the class
to the node. |
| duration
| 450
| number
| Slide transitions duration value. |
| easing
| undefined
| (t: number => number)
| Inertion scroll easing behaviour. |
| gravity
| 1.2
| number
| Scroll inertia value. |
| indent
| 0
| number
| Custom scroll indent value, calculates as gap * indent
. |
| index
| 0
| number
| The index of the initial slide. |
| loop
| false
| boolean
| Makes the slideshow continious. |
| plugins
| []
| PluginFunc[]
| The array of plugins. |
| position
| 0
| number
| The current position value of the carousel. |
| sensity
| 5
| number
| Defines the sliding sensity as the number of pixels required to drag. |
| snap
| undefined
| "start" | "center" | "end" | "deck"
| Enforces the scroll stop positions. |
| tag
| "ol"
| string
| The HTML tag name to render. |
For TypeScript users there is the SlidyCoreOptions
interface available via named import.
Slidy Component
<Slidy />
component uses <Core />
internally and provides more features expected from carousel.
Slidy Component API
The <Slidy />
component interface extends the <Core />
. There are a list of additional options available:
| Property | Default | Type | Description |
| :------- | :-----: | :--: | :---------- |
| arrows
| true
| boolean
| Renders the arrow button controls for accessible slide navigation. |
| background
| false
| boolean
| Sets background-image
instead of <img />
elements to display slides. |
| classNames
| SlidyStyles
| SlidyStylesDefault
| The class names object used over the component. |
| getImgSrc
| item => item.src
| function
| The slide's src
attribute getter. |
| getThumbSrc
| item => item.src
| function
| The thumbnail's src
attribute getter. |
| groups
| 0
| number
| Controls the number of items displayed per viewport. |
| i18n
| i18nDefaults
| I18NDict
| The i18n localization dictionary. |
| navigation
| false
| boolean
| Renders the navigation controls for pagination-like slide navigation. |
| progress
| false
| boolean
| Renders the progress bar. |
| slides
| []
| Slides[]
| An array of objects with image metadata. |
| thumbnail
| false
| boolean
| Renders the thumbnail navigation panel. |
| vertical
| false
| boolean
| Defines the slides flow by using aria-orientation
. |
By default component works with images. Image object should contain width
and height
attributes to prevent layout shifts and alt
for accessibility.
Styling
Extending/Overriding classes
To extend default component styles use classNames
property. Default classes are available via object, that can be extended or overridden:
<script>
import { Slidy, classNames } from "@slidy/svelte";
</script>
<Slidy
classNames={{
root: `${classNames.root} custom-class`,
...classNames
}}
/>
The classNames
consist of { target: className }
pairs:
| Target | Default class | Description |
| :-------- | :----------------: | :-----------|
| arrow | slidy-arrow
| Arrow controls. |
| autoplay | slidy-autoplay
| Autoplay control. |
| counter | slidy-counter
| Slide progress counter. |
| img | slidy-img
| Slide image node. |
| nav | slidy-nav
| Slide navigation panel. |
| nav-item | slidy-nav-item
| Navigtion panel item. |
| overlay | slidy-overlay
| Slides overlay node. |
| progress | slidy-progress
| Slide progress bar. |
| progress-handle | slidy-progress-hadle
| Slide progress bar control handle. |
| root | slidy
| Component's root node. |
| slide | slidy-slide
| Slide item node. |
| slides | slidy-slides
| Slides list node. |
| thumbnail | slidy-thumbnail
| Thumbnail item. |
| thumbnail | slidy-thumbnails
| Thumbnails bar. |
The classNames
object is available via context using classNames
key.
Custom Properties API
For easier style customization Slidy
provides a set of predefined custom properties to inherit:
List of available public custom properties:
| Property | Default | Type | Description |
| :----------------------------- | :--------: | :---------: | :--------------------------------------------------- |
| --slidy-arrow-bg
| #4e4e4ebf | <color>
| The arrow control background color. |
| --slidy-arrow-bg-hover
| #4e4e4e54 | <color>
| The arrow control hover background color. |
| --slidy-arrow-icon-color
| currentColor | <color>
| The arrow control icon fill color. |
| --slidy-arrow-size
| 24px | <length>
| The arrow controls size. |
| --slidy-counter-bg
| #4e4e4ebf | <color>
| The counter's background color. |
| --slidy-focus-ring-color
| #c9c9c9e6 | <color>
| Focus ring color for all focusable elements. |
| --slidy-height
| 100% | <length>
| The height of the component's node. |
| --slidy-nav-item-color
| white | <color>
| The navigation elements color. |
| --slidy-nav-item-radius
| 0.35em | <length>
| The navigation elements border radius. |
| --slidy-nav-item-size
| 16px | <length>
| The navigation elements size. |
| --slidy-progress-thumb-color
| #c44f61 | <color>
| The progress bar active track color. |
| --slidy-progress-track-color
| #96969680 | <color>
| The progress bar track color. |
| --slidy-progress-track-size
| 10px | <length>
| The progress bar height. |
| --slidy-slide-aspect-ratio
| unset | <int/int>
| Defines the slide aspect-ratio. |
| --slidy-slide-bg-color
| darkgray | <color>
| The placeholder background color for loading images. |
| --slidy-slide-gap
| 1rem | <length>
| The gap between items in carousel. |
| --slidy-slide-height
| 100% | <length>
| The carousel items height. |
| --slidy-slide-object-fit
| cover | - | The carousel items (images) resize behaviour. |
| --slidy-slide-radius
| 1rem | <length>
| The slide's border radius value. |
| --slidy-slide-width
| auto | <length>
| The carousel items width. |
| --slidy-thumbnail-radius
| 0.5rem | <length>
| The thumbnail border-radius
value. |
| --slidy-thumbnail-size
| 50px | <length>
| The thumbnail panel size. |
| --slidy-width
| 100% | <length>
| The width of the component's node. |
There are two options:
--style-props
Svelte supports passing down custom properties to component via --style-props
:
<Slidy --slidy-slide-gap="1rem" />
Bear in mind that this way Svelte wraps the component in extra <div />
with display: contents
.
Inherited custom properties
More optimal way is to use cascade. All supported custom properties starts with --slidy-
. For example, to recolor navigation controls, let the component inherit a --slidy-nav-item-color
custom property from any parent:
<div class="parent">
<Slidy />
</div>
<style>
.parent {
--slidy-navigation-color: red;
}
</style>
Or just pass a class with a set of custom properties:
<script>
import { Slidy, classNames } from "@slidy/svelte";
</script>
<Slidy
classNames={{
root: `${classNames.root} .some-class`,
...classNames
}}
/>
<style>
.some-class {
--slidy-navigation-color: red;
--slidy-nav-item-size: 1rem;
}
</style>
Slots
arrow
Customizes the content of the default arrow controls.
arrows
Provides a slot for custom arrow buttons.
If the nodes are <button />
and the data-step
attribute is present, the event listener is not needed. Just provide the values -1
and 1
for data-step
on custom buttons.
Also, there are grid-area
is present in the layout for this custom controls: prev-slide
and next-slide
respectively.
<Slidy>
<svelte:fragment slot="arrows">
<button data-step="-1"> Show the previous slide </button>
<button data-step="1"> Show the next slide </button>
</svelte:fragment>
</Slidy>
<style>
button:first-of-type {
grid-area: prev-slide;
}
button:last-of-type {
grid-area: next-slide;
}
</style>
default
Usually the default markup is not enough. The default
slot solves this problem. To use custom slide markup slot expose each slides
prop item as let:item
directive.
<Slidy let:item>
<figure>
<img src={item.src} alt={item.figcaption} />
<figcaption>
{item.figcaption}
</figcaption>
</figure>
</Slidy>
nav-item
Provides a slot for custom pagination buttons.
Slot receives optional index
and active
props for proper functionality.
Custom navigation item should be a <button />
and have data-index
attribute to function. Otherwise, control the component externally.
<Slidy let:active let:index>
<button slot="nav-item" data-index={index} {active} {index} />
</Slidy>
overlay
Slot to display content overlaid content. It covers the slides area and can be customized by overriding the .slidy-overlay
. For example, it is used to display the counter.
<Slidy>
<svelte:fragment slot="overlay">
<button> Share </button>
</svelte:fragment>
</Slidy>
thumbnail
Work in progress
Events
The component forwards custom events:
| Name | Description | Event detail |
| :-------- | :------------------------------- | :-----------------------------------: |
| destroy
| Component is destroyed. | node
|
| index
| The current slide index changes. | { index: number, position: number }
|
| keys
| The key pressed on focus. | event.code
|
| mount
| Component is mounted to the DOM. | { childs, options }
|
| move
| Navigation occurs. | { index: number, position: number }
|
| resize
| Component's dimentions changes. | { node, options }
|
| update
| Component's props changes. | options
|
i18n
To modify all texts used in the component use pass the dictionary as i18n
prop. For the sake of accessibility, it is recommended translating defaults:
| Key | Default | Event detail |
| :-------- | :------------------------------ | :-----------------------------------: |
| carousel
| "carousel" | aria-label
of a root element. |
| counter
| "%s of %s" | aria-label
of each slide as {slide number} of {slide length} |
| first
| "Go to the first slide" | aria-label
of the first item at the navigation. |
| last
| "Go to the last slide" | aria-label
of the last item at the navigation. |
| next
| "Go to the next slide" | aria-label
of the arrow control. |
| play
| "Start autoplay" | aria-label
of the autoplay control. |
| prev
| "Return back to previous slide" | aria-label
of the arrow control. |
| slide
| "Slide" | aria-roledescription
of each slide item. |
| slideN
| "Go to the slide %s" | aria-label
of pagination of each slide item. |
| stop
| "Stop autoplay" | aria-label
of the autoplay control. |
Recipes
External controls
It is possible to control the navigation of the Slidy
instance from the parent component via binding.
There are two variables available to control the component externally: index
and position
. Declare the variables to hold the values and bind them to the instance for the carousel control.
<script>
import { Slidy } from "svelte-slidy";
let index = 0;
let position = 0;
</script>
<button on:click={() => (index += 1)}> Next slide </button>
<button on:click={() => (position += 50)}> Move </button>
<Slidy bind:index bind:position />
Possible issues
- Slides should not have
absolute
positioning, otherwise the core-package script won't get correct dimentions; - Using the
background
option usually is not recommended. In case you need to use it, specify the slide sizes with custom properties:width
andheight
, or justaspect-ratio
.
License
MIT © EricRovell