swipeable-gallery

swipeable-gallery React component

Usage no npm install needed!

<script type="module">
  import swipeableGallery from 'https://cdn.skypack.dev/swipeable-gallery';
</script>

README

Swipeable Gallery

swipeable-gallery is an UI snippet created to dynamically create swipeable components & carousels just out of the box!

Installation

npm i swipeable-components

Setup

Import the package inside your component

import { Gallery } from "swipeable-gallery";

Initial Configuration

By default, this package has a mobile-first approach. Therefore the initial config is just a single box slider, without nav buttons and markers. It takes 100% width using flex-basis to resize the content harmonically. This means that the height will be dynamic as well, according to the flex calculations. Be aware of this.

return (
    <Display>
      <Gallery>{content}</Gallery>
    </Display>
  );
}

It looks like this on a Moto G4:

NoConfig

Passing Children

You can pass any children in the Gallery component:

export default function Demo() {

  const content = Array(6)
    .fill()
    .map((_, i) => (
      <Content key={i} index={i}>
        {i}
      </Content>
    ));

  return (
    <Display>
      <Gallery>
        {content}
      </Gallery>
    </Display>
  );
}

Adding Markers and Nav Buttons

Still on the mobile view, if you wanna add Navigation buttons and markers, it's very simple! Just add the props: withMarkers and withNav to get the default config out of the box!

   <Display>
      <Gallery withMarkers withNav>
        {content}
      </Gallery>
    </Display>

navMarkers

For mobile use, you can define some logic to disable the navigation buttons for smaller screens:

export default function Demo() {

  //simple example of how to dynamically change your config
  const addNav = window.innerWidth < 640 ? false : true;

  return (
    <Display>
      {/* dynamically hide or show the nav buttons setup */}
      <Gallery withMarkers withNav={addNav}>
        {content}
      </Gallery>
    </Display>
  );
}

By understanding this simple way of messing with the config dyamically, you can apply this concept to any other config you want!

Using an image marker

In case you wanna use image markers instead of the dots, you can easily pass an image as a marker by adding a marker prop to the image you are passing within you content cards. Below we are adding marker to the img html tag that we're passing on our image cards.

Note that you can change the markers size dynamically by passing markersSize as a prop at the Gallery component. This value is set to px. Some of the configurable options are discussed during the readme. All of the options can be seen at the end of this doc. I have made the markers bigger in this case, taking advantage of this property.

Note that this feature does not work on the carousel mode, which will be introduced on the next topic.

export default function Demo() {

  const content = Array(20)
    .fill()
    .map((_, i) => (
      <Content className="Content" key={i}>
        <img marker src={image} />
        <Label>
          <Count>#{i}</Count>
          <Panel>
            <OFF>15 USD</OFF>
            <span>10 USD</span>
          </Panel>
        </Label>
      </Content>
    ));

  return (
    <Display>
      <Gallery markersSize={60} withMarkers withNav>
        {content}
      </Gallery>
    </Display>
  );
}

This is how it looks like:

markerImages

Creating a carousel

You can easily define a carousel format by adding carousel prop;

carousel must be an integer which will pass the number of elements that will be placed inside each row of the carousel.

By the example below, we have a total length of 20 items, and we are saying: "Hey, please split this carousel in rows of 3 items each", resulting in 7 rows here.

return (
    <Display>
      <Gallery carousel={3} withMarkers withNav>
        {content}
      </Gallery>
    </Display>
  );

Carousel

Configuring the default Nav Buttons and Markers

Let's say you wanna place these navigation buttons outside of the carousel. This is easy by taking control of the x axis position of the buttons, using the navPosX prop and by shrinking the carousel, taking control of the Gallery's width with the size prop.

Note that the height of the Gallery's component is automatically resized, through the flex-basis calculations. Keep this in mind when messing with the size prop

By default the size is always 100% of its wrapper. Let's shrink it to 75%, place the buttons outside of the carousel by moving it -90px to both directions and turn the navigation buttons a little bit smaller, by using the navSize prop and setting it to 4rem, just by adding 4. By default, the navSize out of the navType="bar" is in rem, 5rem. More can be seen at the end of this doc, regarding the configurations.

return (
    <Display>
      <Gallery
        carousel={3}
        size={75}
        withMarkers
        withNav
        navPosX={-90}
        navSize={4}
      >
        {content}
      </Gallery>
    </Display>
  );

This is how it looks like on the desktop view:

movingNav

Changing the Nav Buttons and Markers Theme

Not let's say you wanna change the default theme colors and the hover effects for both, markers and Nav buttons:

For the default markers you can use:

markerColor for the marker colors

markerActiveColor for the active, bigger, markers.

For the default nav buttons you can use:

navColor for the chevron's wrapper

navHoverColor for the chevron's wrapper hover color

navInnerColor for the chevron color

navInnerHoverColor for the chevron hover color

Below is one example of a theme configuration on this regard:

return (
    <Display>
      <Gallery
        carousel={3}
        size={75}
        withMarkers
        markerColor="#d6fcc0"
        markerActiveColor="#fac9b0"
        withNav
        navPosX={-90}
        navSize={4}
        navColor="transparent"
        navHoverColor="transparent"
        navInnerColor="#fd9e6e"
        navInnerHoverColor="#ee6019"
      >
        {content}
      </Gallery>
    </Display>
  );

It looks like this:

theme

Adding your own Nav Buttons

You can add your own navigation buttons by passing them as props to the Gallery component, like this:

navPrev={() => <YourPrevNav/>} and navNext={() => <YourNextNav/>}

In the following example I am passing two buttons with svg bumble bee icons:

Note that none of the default nav button controls work for custom nav buttons. You must configure all yourself, regarding the positioning, theme colors, size, etc.

 return (
    <Display>
      <Gallery
        carousel={3}
        size={75}
        withMarkers
        markerColor="#d6fcc0"
        markerActiveColor="#fac9b0"
        withNav
        navPrev={() => (
          <NavPrev>
            <Bee />
          </NavPrev>
        )}
        navNext={() => (
          <NavNext>
            <Bee />
          </NavNext>
        )}
      >
        {content}
      </Gallery>
    </Display>
  );

Below are my custom buttons code, as a reference:

const NavPrev = styled.div`
  background: rgba(0, 0, 0, 0.2);
  width: 4rem;
  height: 4rem;
  z-index: 1;
  padding: 0 0.3rem;
  text-align: center;
  box-sizing: border-box;
  border-radius: 50%;
  top: 40%;
  left: -80px;
  cursor: pointer;
  position: absolute;
  transition: all 200ms ease;
  :hover {
    background: rgba(240, 188, 188, 0.6);
    path {
      fill: blue;
    }
  }
`;

const NavNext = styled(NavPrev)`
  left: auto;
  right: -80px;
`;

This is how it looks like:

customNav

Using the "Bar" Theme

This works with either the carousel or default mode. Note that you can't position the nav buttons on this config. The navSize here just messes with the width of the nav buttons, in this case in %.

This theme repositiones the navigation buttons, on a Netflix type of disposition:

Add the navType="bar" prop and let the magic happen!

return (
    <Display>
      <Gallery
        size={60}
        withMarkers
        withNav
        navSize={10}
        navType="bar"
      >
        {content}
      </Gallery>
    </Display>
  );

This is how this config looks like:

navBar

Now with the carousel:

return (
    <Display>
      <Gallery
        size={95}
        carousel={3}
        withMarkers
        withNav
        navSize={6}
        navType="bar"
      >
        {content}
      </Gallery>
    </Display>
  );

navBarCarousel

Now passing your own custom nav buttons with this theme:

Note that some of the styles of your custom buttons are overwritten the moment you choose this theme, in order to have the buttons positioned in this manner.

I am keeping the same styling on the nav buttons here, as per presented above, and the magic still happens without worries!

return (
    <Display>
      <Gallery
        size={95}
        carousel={3}
        withMarkers
        withNav
        navSize={7}
        navType="bar"
        navPrev={() => (
          <NavPrev>
            <Bee />
          </NavPrev>
        )}
        navNext={() => (
          <NavNext>
            <Bee />
          </NavNext>
        )}
      >
        {content}
      </Gallery>
    </Display>
  );

navBarCustomizedButtons

Advanced use cases

Now let's say this all of this is just not enough! You can still take over more control, over some of the components structured in this package.

On the following example we will simulate a Netflix navigation carousel:

By accessing rowStyle and contentWrapperStyle we combine, in this example, some calculated padding percentages and other styles, injected directly, taking the advantage of the styled-components syntax and possibilities:

return (
    <Display>
      <Gallery
        size={95}
        carousel={3}
        withNav
        navSize={7}
        navType="bar"
        navPrev={() => (
          <NavPrev>
            <Bee />
          </NavPrev>
        )}
        navNext={() => (
          <NavNext>
            <Bee />
          </NavNext>
        )}
        rowStyle={`
          padding: 7% 0;
          `}
        contentWrapperStyle={`
    :hover .Content{
      transform: translateX(-25%);
    }
    `}
      >
        {content}
      </Gallery>
      <GlobalStyle />
    </Display>
  );

Add some styling to the component element when hovered:

const Content = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: #819797;
  position: relative;
  transition: all 200ms ease;

  &&&:hover ~ .Content {
    transform: translateX(25%);
  }

  &&&:hover {
    transform: scale(1.5);
    z-index: 3;
  }
`;

And this is the result!

netflixCarousel

Configuration options

You will have a full set of configs available to make your life easier:

Mess around with these options to complement my examples given above.

Prop Performs Accepts Note
size Sets the gallery's width integer The value will be transformed in %. By default the value is set to 100% in case you don't use this prop. When you use this config, the heigh is resized as well, by the use of flex-basis calculations
markerActiveColor Sets the dotted marker's active color string The same way you set colors or hex colors in CSS
markerColor Sets the dotted marker's innactive color string The same way you set colors or hex colors in CSS
withNav Authorizes the use of the navigation buttons boolean You can just add this prop without a value to set its "truish" value
navColor Sets the outer color of the nav buttons string This config is set to background, so you can pass a rgba value
navHoverColor Sets the outer hover color of the nav buttons string This config is set to background, so you can pass a rgba value
navInnerColor Sets the color of the button's chevron string The same way you set colors or hex colors in CSS
navInnerHoverColor Sets the nav button chevron's hover color. string This config is set to background, so you can pass a rgba value
navSize Sets the nav size integer On the default theme the value will be transformed into rem, for either the width / height to keep the circle shape. If used with the navType bar prop theme, the height will be always 100%, mutating just the width, in this case using % instead of rem. The default value is 5rem / 5%
navPosX Sets the X position of the nav button integer The value will be transformed in absolute px. Can pass i.e - navPosX={50} or navPosX={-50}
navPosY Sets the Y position of the nav button integer The value will be transformed in absolute px. Can pass i.e - navPosY={50} or navPosY={-50}. If no value is set it will be 50% by default
carousel Activates the carousel mode integer The value passed will define the number of items per row of the carousel
withMarkers Allows the use of markers boolean You can just add this prop without a value to set its "truish" value
markersSize Sets the markers size integer This value is set in pixels. The Default value is 34px
navType Changes the nav theme string The current only option is bar
navPrev Injects a custom navigation button function navPrev={() => <YourButton/>}
navNext Injects a custom navigation button function navNext={() => <YourButton/>}
marker Injects an image marker boolean This prop must be added to the image you wanna use as a marker, within you content children
rowStyle Injects styling to the row element interpolated string Injects css to the element as a class for advanced control
contentWrapperStyle Injects styling to the content wrapper element interpolated string Injects css to the element as a class for advanced control

Live Demo (Under Construction)

Next minor version => 1.0.5

  • AutoPlay on the carousel & default modes
  • Infinite swipping experience

Author

aliosh romano pimenta

Aliosh Romano

Linkedin Badge Gmail Badge Github Badge