@slidy/react v1.2.1
@slidy/react
Simple, configurable & reusable carousel component built with React based on @slidy/core.
Try the demo.
Getting started
The package is available via npm:
npm i @slidy/reactUsage
The most simple way to get started is to use named import of <Slidy /> component:
import { Slidy } from '@slidy/react';
import '@slidy/react/dist/slidy.css';
const slides = [
    {
        id: 1,
        width: 800,
        height: 1200,
        src: 'static/img/some-image.webp',
    },
];
export default () => {
    return <Slidy slides={slides} />;
};All props are optional. The only property to get started is slides - an array of objects with image related data.
You will also have to import css styles:
import '@slidy/react/dist/slidy.css';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.
import { Core } from '@slidy/react';
export default () => {
    return <Core />;
};Core Component API
| Property | Default | Type | Description | 
|---|---|---|---|
animation | undefined | AnimationFunc | Custom slide animation. | 
axis | "x" | "x" or "y" | The scroll direction. | 
clamp | 0 | number | Clamps sliding index as {clamp} - {index} + {clamp} | 
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. | 
setIndex | undefined | React.Dispatch<React.SetStateAction<number>> | Set's index of a current slide. | 
plugins | undefined | ReturnType<PluginFunc>[] | Plugins to operate with the slidy instance and its options directly. | 
loop | false | boolean | Makes the slideshow continious. | 
sensity | 5 | number | Defines the sliding sensity as the number of pixels required to drag. | 
snap | undefined | "start" or "center" or "end" or "deck" | Enforces the scroll stop positions. | 
tag | ol | string | The HTML tag name to render. | 
onResize | undefined | (event: CustomEvent<{ ROE: ResizeObserverEntry[] }>) => void | Listen to the core event resize to fire. | 
onMount | undefined | (event: CustomEvent<Options>) => void | Listen to the core event mount to fire. | 
onMove | undefined | (event: CustomEvent<{ index: number; position: number }>) => void | Listen to the core event move to fire. | 
onIndex | undefined | (event: CustomEvent<{ index: number }>) => void | Listen to the core event index to fire. | 
onKeys | undefined | (event: CustomEvent<string>) => void | Listen to the core event keys to fire. | 
onUpdate | undefined | (event: CustomEvent<Options>) => void | Listen to the core event update to fire. | 
onDestroy | undefined | (event: CustomEvent<HTMLElement>) => void | Listen to the core event destroy to fire. | 
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 or () => JSXElement | Renders the arrow button controls for accessible slide navigation. | 
arrow | undefined | () => JSXElement | Renders the arrow. | 
children | undefined | (item: Slide) => JSXElement | Renders each slide. | 
overlay | undefined | () => JSXElement | Renders the overlay. | 
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. | 
i18n | i18nDefaults | I18NDict | The i18n localization dictionary. | 
navigation | false | boolean | Renders the navigation controls for pagination-like slide navigation. | 
groups | 0 | number | Controls the number of items displayed per viewport. | 
progress | false | boolean | Renders the progress bar. | 
slides | [] | Slides[] | An array of objects with image metadata. | 
thumbnail | false | boolean or () => JSXElement | Renders the thumbnail navigation panel. | 
onResize | undefined | (event: CustomEvent<{ ROE: ResizeObserverEntry[] }>) => void | Listen to the core event resize to fire. | 
onMount | undefined | (event: CustomEvent<Options>) => void | Listen to the core event mount to fire. | 
onMove | undefined | (event: CustomEvent<{ index: number; position: number }>) => void | Listen to the core event move to fire. | 
onIndex | undefined | (event: CustomEvent<{ index: number }>) => void | Listen to the core event index to fire. | 
onKeys | undefined | (event: CustomEvent<string>) => void | Listen to the core event keys to fire. | 
onUpdate | undefined | (event: CustomEvent<Options>) => void | Listen to the core event update to fire. | 
onDestroy | undefined | (event: CustomEvent<HTMLElement>) => void | Listen to the core event destroy to fire. | 
plugins | undefined | ReturnType<PluginFunc>[] | Plugins to operate with the slidy instance and its options directly. | 
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:
import { Slidy, classNames } from '@slidy/react';
import '@slidy/react/dist/slidy.css';
export default () => {
    return (
        <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. | 
| 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. | 
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-autoplay-control-size | 2.25em | <length> | The autoplay control size. | 
--slidy-autoplay-indicator-accent | lightpink | The autoplay control indicator ring color. | |
--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 | 50% | <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 | 5px | <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. | 
Inherited custom properties
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:
.parent {
    --slidy-navigation-color: red;
}export default () => {
    return (
        <div class="parent">
            <Slidy />
        </div>
    );
};Or just pass a class with a set of custom properties:
.some-class {
    --slidy-navigation-color: red;
    --slidy-nav-item-size: 1rem;
}import { Slidy, classNames } from '@slidy/react';
import '@slidy/react/dist/slidy.css';
export default () => {
    return (
        <Slidy
            classNames={{
                root: `${classNames.root} .some-class`,
                ...classNames,
            }}
        />
    );
};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.
button:first-of-type {
    grid-area: prev-slide;
}
button:last-of-type {
    grid-area: next-slide;
}export default () => {
    return (
        <Slidy
            arrows={() => (
                <>
                    <button data-step="-1"> Show the previous slide </button>
                    <button data-step="1"> Show the next slide </button>
                </>
            )}
        />
    );
};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 item argument.
export default () => {
    return (
        <Slidy>
            {(item) => (
                <figure>
                    <img src={item.src} alt={item.figcaption} />
                    <figcaption>{item.figcaption}</figcaption>
                </figure>
            )}
        </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.
export default () => {
    return <Slidy overlay={() => <button> Share </button>} />;
};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.
import { Slidy } from '@slidy/react';
import { useState } from 'react';
import '@slidy/react/dist/slidy.css';
export default () => {
    const [index, setIndex] = useState(0);
    return (
        <>
            <Slidy slides={slides} index={index} setIndex={setIndex} />
            <button onClick={() => setIndex((prev) => prev + 1)}>Next slide</button>
        </>
    );
};Possible issues
- Slides should not have 
absolutepositioning, otherwise the core script won't get correct dimentions; - Using the 
backgroundoption usually is not recommended. In case you need to use it, specify the slide sizes with custom properties:widthandheight, or justaspect-ratio. 
License
Slidy is distributed under the MIT license