Skip to content

Commit

Permalink
feat: expose photoswipe API
Browse files Browse the repository at this point in the history
closes #20
  • Loading branch information
irudoy committed Apr 26, 2020
1 parent 923d911 commit c1542f3
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 38 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const MyGallery = () => {
| - | - | - | - |
| `id` | Number or String | ✓ (for hash navigation) | Item ID, for hash navigation |
| `options` | Object | | PhotoSwipe [options](https://photoswipe.com/documentation/options.html) |
| `onOpen` | Function | | Triggers after `PhotoSwipe.init()` call. Use it for accessing PhotoSwipe [API](https://photoswipe.com/documentation/api.html). It will receive PhotoSwipe instance as the first argument: `(photoswipe: PhotoSwipe) => void` |

### Item

Expand Down Expand Up @@ -183,6 +184,7 @@ type RenderItem = (props: {
| `ui` | PhotoSwipeUI || PhotoSwipe UI class |
| `id` | Number or String | ✓ (for hash navigation) | Item ID, for hash navigation |
| `options` | Object | | PhotoSwipe [options](https://photoswipe.com/documentation/options.html) |
| `onOpen` | Function | | Triggers after `PhotoSwipe.init()` call. Use it for accessing PhotoSwipe [API](https://photoswipe.com/documentation/api.html). It will receive PhotoSwipe instance as the first argument: `(photoswipe: PhotoSwipe) => void` |

### DefaultLayout

Expand Down
1 change: 0 additions & 1 deletion src/__tests__/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ exports[`gallery should render with external layout 1`] = `
"current": undefined,
}
}
options={Object {}}
ui={[Function]}
>
<Component
Expand Down
24 changes: 22 additions & 2 deletions src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ import {

const PhotoSwipeMocked = PhotoSwipe as jest.MockedClass<typeof PhotoSwipe>

const applyZoomPan = jest.fn()

jest.mock('photoswipe', () => {
return jest.fn().mockImplementation(() => {
return { init: () => {} }
return { init: () => {}, applyZoomPan }
})
})

beforeEach(() => PhotoSwipeMocked.mockClear())
beforeEach(() => {
PhotoSwipeMocked.mockClear()
applyZoomPan.mockClear()
})

const photoswipeArgsMock = (
items: InternalItem[] | null,
Expand Down Expand Up @@ -310,4 +315,19 @@ describe('gallery', () => {
...photoswipeArgsMock(items, 2, galleryID),
)
})

test('should call exposed photoswipe instance method after open', () => {
const items = createItems(1)
const wrapper = mount(
<TestGallery
items={items}
onOpen={(pswp) => pswp.applyZoomPan(0, 0, 0)}
/>,
)
wrapper.find(Item).first().simulate('click')
expect(PhotoSwipeMocked).toHaveBeenCalledWith(
...photoswipeArgsMock(items, 0),
)
expect(applyZoomPan).toHaveBeenCalled()
})
})
31 changes: 31 additions & 0 deletions src/gallery-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import PropTypes from 'prop-types'
import { Options as PhotoswipeUiDefaultOptions } from 'photoswipe/dist/photoswipe-ui-default'

export const baseGalleryPropTypes = {
children: PropTypes.any,
options: PropTypes.object,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
}

export interface BaseGalleryProps {
/**
* PhotoSwipe options
*
* https://photoswipe.com/documentation/options.html
*/
options?: PhotoSwipe.Options & PhotoswipeUiDefaultOptions

/**
* Gallery ID, for hash navigation
*/
id?: string | number

/**
* Triggers after PhotoSwipe.init() call
*
* Use it for accessing PhotoSwipe API
*
* https://photoswipe.com/documentation/api.html
*/
onOpen?: (photoswipe: PhotoSwipe<PhotoSwipe.Options>) => void
}
33 changes: 12 additions & 21 deletions src/gallery-custom.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import PhotoSwipe from 'photoswipe'
import { Options as PhotoswipeUiDefaultOptions } from 'photoswipe/dist/photoswipe-ui-default'
import React, { useRef, useCallback, useEffect, FC } from 'react'
import PropTypes from 'prop-types'
import { getElBounds, sortNodes } from './helpers'
import { Context } from './context'
import { ItemRef, InternalItem } from './types'
import { baseGalleryPropTypes, BaseGalleryProps } from './gallery-base'

interface PhotoSwipeItem extends PhotoSwipe.Item {
el: HTMLElement
Expand All @@ -18,7 +18,7 @@ type PhotoSwipeUI =
) => PhotoSwipe.UI<PhotoSwipe.Options>)
| boolean

export interface CustomGalleryProps {
export interface CustomGalleryProps extends BaseGalleryProps {
/**
* Ref to your layout element
*/
Expand All @@ -28,16 +28,6 @@ export interface CustomGalleryProps {
* PhotoSwipe UI class
*/
ui: PhotoSwipeUI

/**
* PhotoSwipe options
*/
options?: PhotoSwipe.Options & PhotoswipeUiDefaultOptions

/**
* Gallery ID, for hash navigation
*/
id?: string | number
}

/**
Expand All @@ -49,6 +39,7 @@ export const CustomGallery: FC<CustomGalleryProps> = ({
ui,
options,
id: galleryUID,
onOpen,
}) => {
const items = useRef(new Map<ItemRef, InternalItem>())

Expand Down Expand Up @@ -95,7 +86,7 @@ export const CustomGallery: FC<CustomGalleryProps> = ({
const layoutEl = layoutRef.current

if (layoutEl) {
new PhotoSwipe(layoutEl, ui, normalized, {
const instance = new PhotoSwipe(layoutEl, ui, normalized, {
index: index === null ? parseInt(targetId, 10) - 1 : index,
getThumbBoundsFn: (thumbIndex) => {
const { el } = normalized[thumbIndex]
Expand All @@ -106,7 +97,13 @@ export const CustomGallery: FC<CustomGalleryProps> = ({
? { galleryUID: galleryUID as number, history: true }
: {}),
...(options || {}),
}).init()
})

instance.init()

if (onOpen !== undefined && typeof onOpen === 'function') {
onOpen(instance)
}
}
}, [])

Expand Down Expand Up @@ -156,18 +153,12 @@ export const CustomGallery: FC<CustomGalleryProps> = ({
}

CustomGallery.propTypes = {
children: PropTypes.any,
options: PropTypes.object,
...baseGalleryPropTypes,
// @ts-ignore
layoutRef: PropTypes.shape({
current: PropTypes.instanceOf(
typeof Element === 'undefined' ? class Element {} : Element,
),
}).isRequired,
ui: PropTypes.any.isRequired,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
}

CustomGallery.defaultProps = {
options: {},
}
19 changes: 5 additions & 14 deletions src/gallery-default.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import PhotoswipeUIDefault from 'photoswipe/dist/photoswipe-ui-default'
import React, { useRef, FC } from 'react'
import PropTypes from 'prop-types'
import { CustomGallery, DefaultLayout, layoutPropTypes, LayoutProps } from '.'
import { baseGalleryPropTypes, BaseGalleryProps } from './gallery-base'

export interface GalleryProps extends LayoutProps {
/**
* PhotoSwipe options
*/
options?: PhotoSwipe.Options & PhotoswipeUIDefault.Options

/**
* Gallery ID, for hash navigation
*/
id?: string | number
}
export type GalleryProps = BaseGalleryProps & LayoutProps

/**
* Gallery component with default Layout and UI
Expand All @@ -22,6 +12,7 @@ export const Gallery: FC<GalleryProps> = ({
children,
options,
id,
onOpen,
...restProps
}) => {
const defaultLayoutRef = useRef<HTMLElement>()
Expand All @@ -31,6 +22,7 @@ export const Gallery: FC<GalleryProps> = ({
ui={PhotoswipeUIDefault}
options={options}
id={id}
onOpen={onOpen}
>
{children}
<DefaultLayout {...restProps} ref={defaultLayoutRef} />
Expand All @@ -39,7 +31,6 @@ export const Gallery: FC<GalleryProps> = ({
}

Gallery.propTypes = {
options: PropTypes.object,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
...baseGalleryPropTypes,
...layoutPropTypes,
}

0 comments on commit c1542f3

Please sign in to comment.