Create Beautiful and Functional Image Galleries with PhotoSwipe React

A configurable and flexible React component wrapper around PhotoSwipe.

ā„¹ļø react-photoswipe-gallery v2 only works with PhotoSwipe v5 and above. Use v1 for PhotoSwipe <= 4.

Basic Usage

import 'photoswipe/dist/photoswipe.css'

import { Gallery, Item } from 'react-photoswipe-gallery'

const MyGallery = () => (
  <Gallery>
    <Item
      original="https://placekitten.com/1024/768?image=1"
      thumbnail="https://placekitten.com/80/60?image=1"
      width="1024"
      height="768"
    >
      {({ ref, open }) => (
        <img ref={ref} onClick={open} src="https://placekitten.com/80/60?image=1" />
      )}
    </Item>
    <Item
      original="https://placekitten.com/1024/768?image=2"
      thumbnail="https://placekitten.com/80/60?image=2"
      width="1024"
      height="768"
    >
      {({ ref, open }) => (
        <img ref={ref} onClick={open} src="https://placekitten.com/80/60?image=2" />
      )}
    </Item>
  </Gallery>
)

Demo

Check out the Storybook to see it in action šŸš€

Stories are written as real-world examples, so you can see them at the bottom of Storybook UI in the Story tab. Or browse the source code on GitHub. It covers most of the use-cases and provides examples for configuration options.

Installation

yarn add photoswipe react-photoswipe-gallery

or

npm install photoswipe react-photoswipe-gallery --save

Hash Navigation

You should pass a unique id prop to <Gallery /> component, to enable hash navigation.

Optionally, you can also pass the id to <Item /> component. Otherwise, the index will be used.

const MyGallery = () => (
  <Gallery id="my-gallery">
    <Item
      id="first-pic"
      {/*...*/}
    />
    <Item
      id="second-pic"
      {/*...*/}
    />
  </Gallery>
)

Example

Captions

If you want to add captions to your slides, you need to pass withCaption prop to the <Gallery /> and pass caption prop to each <Item />. It accepts html as well. If caption isn't provided - it will use alt prop.

const MyGallery = () => (
  <Gallery withCaption>
    <Item
      caption="Foo"
      {/*...*/}
    />
    <Item
      alt="Bar"
      {/*...*/}
    />
  </Gallery>
)

Example

Plugins

You can use native PhotoSwipe plugins with plugins prop. It accepts the function in which you should register all of your plugins, providing pswpLightbox to the plugin constructor.

Example for photoswipe-dynamic-caption-plugin:

import 'photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css'
import PhotoSwipeDynamicCaption from 'photoswipe-dynamic-caption-plugin'

const MyGallery = () => (
  <Gallery
      plugins={(pswpLightbox) => {
        // register plugin
        const captionPlugin = new PhotoSwipeDynamicCaption(pswpLightbox, {
          captionContent: (slide) => slide.data.alt,
        })

        // register another plugin
        // ...
      }}
  >
    {/*...*/}
  </Gallery>
)

Example

Custom UI Elements

You can add custom UI elements to PhotoSwipe with uiElements prop. It accepts an array of configuration objects for custom UI elements.

const uiElements = [
  // add custom UI element
  {
    name: 'custom-button',
    ariaLabel: 'Custom button',
    order: 9,
    isButton: true,
    html: {
      isCustomSVG: true,
      inner:
        '<path d="<ICON_PATH>" id="pswp__icn-cstm-btn"/>',
      outlineID: 'pswp__icn-cstm-btn',
    },
    appendTo: 'bar',
    onInit: (el, pswpInstance) => {
      // do something on UI element's init event
    },
    onClick: (e, el, pswpInstance) => {
      // do something on UI element's click event
    },
  },

  // add another custom UI element
  // ...
]

const MyGallery = () => (
  <Gallery uiElements={uiElements}>
    {/*...*/}
  </Gallery>
)

Example

Custom slide content

You can add your own custom slide content with content and html props.

const MyGallery = () => (
  <Gallery>
    <Item
      content={<h1>Hi!</h1>}
      {/*...*/}
    />
    <Item
      html="<h1>Hi!</h1>"
      {/*...*/}
    />
  </Gallery>
)

Example

Access to Photoswipe instance

If you need to get access to Photoswipe instance (for example, to subscribe on Photoswipe events or call some Photoswipe method), you can do it via onOpen and onBeforeOpen props of Gallery component.

onBeforeOpen triggers before PhotoSwipe.init() call.

onOpen triggers after PhotoSwipe.init() call.

onBeforeOpen and onOpen will receive PhotoSwipe instance as the first argument.

const onBeforeOpen = (pswpInstance) => {
  pswpInstance.on('change', () => {
    console.log('slide was changed')
  })
}

const onOpen = (pswpInstance) => {
  pswpInstance.currSlide.zoomTo(
    1,
    { x: 0, y: 0 },
    2000,
    false
  )
}

const MyGallery = () => (
  <Gallery onBeforeOpen={onBeforeOpen} onOpen={onOpen}>
    {/*...*/}
  </Gallery>
)

Photoswipe customization

If you need to customize Photoswipe options or Photoswipe styling you can do it via options prop of Gallery component.

const options = {
  arrowPrev: false,
  arrowNext: false,
  zoom: false,
  close: false,
  counter: false,
  bgOpacity: 0.2,
  padding: { top: 20, bottom: 40, left: 100, right: 100 },
}

const MyGallery = () => (
  <Gallery options={options}>
    {/*...*/}
  </Gallery>
)

Props

Gallery

 

PropTypeRequiredDescription
idNumber or Stringāœ“ (for hash navigation)Item ID, for hash navigation
optionsObject Object containing PhotoSwipe options and styling properties
pluginsFunction Function for registering PhotoSwipe plugins. You should pass photoswipeLightbox to each plugin constructor (example)
uiElementsArray Array of configuration objects for custom UI elements. Use it for adding custom UI elements (example)
onBeforeOpenFunction Triggers before PhotoSwipe.init() call. Use it for accessing PhotoSwipe API. It will receive PhotoSwipe instance as the first argument: (photoswipe: PhotoSwipe) => void
onOpenFunction Triggers after PhotoSwipe.init() call. Use it for accessing PhotoSwipe API. It will receive PhotoSwipe instance as the first argument: (photoswipe: PhotoSwipe) => void
withCaptionBooleanāœ“ (for default captions)Enables built-in caption display. Use the caption prop of the Item component to control caption text (example)
withDownloadButtonBooleanāœ“ (for download button)Adds UI control for downloading the original image of the current slide (example)

Item

Should be children of the Gallery.

 

PropTypeRequiredDescription
childrenFunctionāœ“Render prop for exposing Gallery API
originalString Url of original image
originalSrcsetString Srcset of original image (example)
thumbnailString Url of thumbnail
widthNumber or String Width of original image
heightNumber or String Height of original image
altString Alternate text for original image
captionString Text or html for caption (example)
croppedBoolean Thumbnail is cropped (example)
contentReactElement Custom slide content (example)
htmlString Custom slide content (raw html) (example)
idNumber or String Item ID, for hash navigation (example)

Note about Item's children render prop.

Item accepts only function as children.

type RenderItem = (props: {
  /**
   * Required `ref` object to any html node of item
   *
   * Can be omitted if there is only one item in the gallery
   */
  ref: React.MutableRefObject

  /**
   * Function that opens the gallery at the current item's index
   */
  open: (e: MouseEvent) => void
}) => JSX.Element

<Item>
  {({ ref, open }) => (
    <img ref={ref} onClick={open} />
  ) as RenderItem}
</Item>

<Item>
  {({ ref, open }) => (
    <span ref={ref} onClick={open}>Open gallery</span>
  ) as RenderItem}
</Item>

Hooks

useGallery

The useGallery hook returns an object with some useful methods.

PropertyTypeDescription
open(index: number) => voidThis function allows programmatically open Photoswipe UI at index

useGallery hook gets context provided by Gallery component. So to use useGallery hook you need to store your gallery content as separate component and then wrap it into Gallery component.

const GalleryContent = () => {
  const { open } = useGallery()

  useEffect(() => {
      open(1) // you can open second slide by calling open(1) in useEffect
  }, [open])

  return (
    <div>
      {/* or you can open second slide on button click */}
      <button onClick={() => open(1)}>Open second slide</button>
      <div>
        <Item>...</Item>
        <Item>...</Item>
        <Item>...</Item>
      </div>
    </div>
  )
}

const MyGallery = () => {
  return (
    {/* Gallery component provides context for useGallery hook used in GalleryContent */}
    <Gallery>
      <GalleryContent />
    </Gallery>
  )
}

Example

Requirements

Development

yarn install
yarn sdks vscode

then

yarn storybook

or

yarn start

License

MIT


View on GitHub: https://github.com/dromru/react-photoswipe-gallery 

#react #javascript 

Create Beautiful and Functional Image Galleries with PhotoSwipe React
1.45 GEEK