Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ImageGallery): adds ImageGallery and ImageGalleryImage component for gallery view of photos #315

Merged
merged 45 commits into from
Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
81b0ed4
chore: checking in progress work
abbeyhrt Jul 25, 2019
29fcb01
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Jul 30, 2019
5539011
chore:check in progress
abbeyhrt Jul 30, 2019
ff03df4
chore: check in progress
abbeyhrt Aug 1, 2019
301c762
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 1, 2019
e6ca185
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 2, 2019
5299ff9
feature: adds imageGallery and ImageGalleryImage to create gallery vi…
abbeyhrt Aug 6, 2019
9a3cf1c
chore: add comment explaining eslint-disable-next-line
abbeyhrt Aug 6, 2019
10e8887
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 6, 2019
95c66be
chore: style changes to fix butotn click space
abbeyhrt Aug 7, 2019
bfdfff8
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 7, 2019
82264aa
chore: remove unnecessary images from static folder
abbeyhrt Aug 7, 2019
55c166f
chore: remove unnecessary packages
abbeyhrt Aug 7, 2019
c845718
chore: remove accidentally added gallery page
abbeyhrt Aug 7, 2019
379c83d
chore: add tokens and fix mobile view
abbeyhrt Aug 8, 2019
e977cdc
Merge branch 'master' into 229-feature-imade-gallery-component
abbeyhrt Aug 8, 2019
304abb9
Merge branch 'master' into 229-feature-imade-gallery-component
abbeyhrt Aug 8, 2019
c90fc10
Merge branch 'master' into 229-feature-imade-gallery-component
abbeyhrt Aug 8, 2019
734ffc4
refactor: add Row to ImageGallery
abbeyhrt Aug 8, 2019
8b770c9
docs: update imagegallery.mdx
abbeyhrt Aug 8, 2019
f9df35e
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 8, 2019
f3012d5
Merge branch '229-feature-imade-gallery-component' of https://github.…
abbeyhrt Aug 8, 2019
2d5f816
chore: adds focus outline to ImageGallery and check to verify type of…
abbeyhrt Aug 9, 2019
3ee1684
chore: fixes addNoScroll staying, adds color token and adds a11y anno…
abbeyhrt Aug 12, 2019
bf8c128
chore: removes margin on AddNoScroll, scopes column changes, adds dar…
abbeyhrt Aug 13, 2019
8bc2256
Merge branch 'master' into 229-feature-imade-gallery-component
abbeyhrt Aug 13, 2019
0fc4e9b
chore: add margin to image
abbeyhrt Aug 13, 2019
604d169
Merge branch '229-feature-imade-gallery-component' of https://github.…
abbeyhrt Aug 13, 2019
9034a7c
chore: remove dark theme
abbeyhrt Aug 13, 2019
ce94211
Merge branch 'master' into 229-feature-imade-gallery-component
abbeyhrt Aug 13, 2019
5508db6
Merge branch 'master' into 229-feature-imade-gallery-component
alisonjoseph Aug 15, 2019
2cf9879
chore: center image and restyle title
abbeyhrt Aug 16, 2019
6acd637
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 16, 2019
09fbb55
Merge branch '229-feature-imade-gallery-component' of https://github.…
abbeyhrt Aug 16, 2019
f68516f
refactor: adds markdown image ability, updates styles, fixes firefox …
abbeyhrt Aug 16, 2019
c44d2fe
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 16, 2019
efd95c4
chore: remove comments
abbeyhrt Aug 16, 2019
c6a3923
Merge branch 'master' into 229-feature-imade-gallery-component
vpicone Aug 16, 2019
773891d
chore: adds styling to remove outline and change margins
abbeyhrt Aug 19, 2019
81caecd
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 19, 2019
35f0e33
Merge branch '229-feature-imade-gallery-component' of https://github.…
abbeyhrt Aug 19, 2019
bbe9fe1
Merge branch 'master' of https://github.com/carbon-design-system/gats…
abbeyhrt Aug 20, 2019
aa92f93
chore: updates margins on arrows, close button, and title position
abbeyhrt Aug 20, 2019
ea08552
Merge branch 'master' into 229-feature-imade-gallery-component
abbeyhrt Aug 21, 2019
7cfc6fe
Merge branch 'master' into 229-feature-imade-gallery-component
jeanservaas Aug 21, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/example/src/data/nav-items.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@
path: /components/Tabs
- title: Video
path: /components/Video
- title: Image Gallery
path: /components/ImageGallery
130 changes: 130 additions & 0 deletions packages/example/src/pages/components/ImageGallery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
title: Image Gallery
theme: dark
---

<PageDescription>

A small scale example of the Image Gallery from the [IBM Design Language Gallery](https://www.ibm.com/design/language/gallery).

</PageDescription>

## Image Gallery Example

Click on an image to open the gallery.

<ImageGallery>
<ImageGalleryImage
src="/images/IBM_Design_landing.jpg"
title="IBM Design"
alt="IBM Design"
col={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Logo.png"
title="IBM Cloud"
alt="IBM Cloud"
col={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Developers.jpg"
title="IBM Cloud"
alt="IBM Cloud"
col={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Data_Center.jpg"
title="IBM Cloud Data Center"
alt="IBM Cloud Data Center"
col={8}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Interconnect.jpg"
title="IBM Cloud Interconnect"
alt="IBM Cloud Interconnect"
col={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Notebook.jpg"
title="IBM Cloud Notebook"
alt="IBM Cloud Notebook"
col={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Platform_Prototype.gif"
title="IBM Cloud Platform"
alt="IBM Cloud Platform"
col={8}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Pictograms.gif"
title="IBM Cloud"
alt="IBM Cloud"
col={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Server.png"
title="IBM Cloud Server"
alt="IBM Cloud Server"
col={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Think_Keynote.jpg"
title="IBM Cloud Think"
alt="IBM Cloud Think"
col={4}
/>
</ImageGallery>

## Markdown Code

You can use the ImageGallery component in markdown by nesting your images inside the ImageGallery component and using the ImageGalleryImage component to define the image's location, title, alt tag, and the columns the image on the page will span at the medium and large breakpoints. There is no gallery view for mobile so the small breakpoint is not defined.

Here's an example of how to use the ImageGallery and the ImageGalleryImage components in markdown.

```markdown path=/components/ImageGallery.mdx src=https://gatsby-theme-carbon.now.sh
<ImageGallery>

<ImageGalleryImage
src="/images/IBM_Design_landing.jpg"
title="IBM Design"
alt="IBM Design"
colMd={2}
colLg={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Logo.png"
title="IBM Cloud"
alt="IBM Cloud"
colMd={2}
colLg={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Developers.jpg"
title="IBM Cloud"
alt="IBM Cloud"
colMd={2}
colLg={4}
/>

<ImageGalleryImage
src="/images/IBM_Cloud_Data_Center.jpg"
title="IBM Cloud Data Center"
alt="IBM Cloud Data Center"
colMd={4}
colLg={8}
/>

</ImageGallery>
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/example/static/images/IBM_Cloud_Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/example/static/images/SignaltoNoise.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/example/static/images/npm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions packages/example/static/images/npm.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/gatsby-theme-carbon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.2.0",
"emotion-theming": "^10.0.10",
"focus-trap-react": "^6.0.0",
"gatsby-plugin-catch-links": "^2.0.15",
"gatsby-plugin-emotion": "^4.0.7",
"gatsby-plugin-manifest": "^2.1.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import React, { useState, useEffect, Children } from 'react';
import ReactDOM from 'react-dom';
import { breakpoints } from '@carbon/elements';
import { ChevronRight32, ChevronLeft32, Close32 } from '@carbon/icons-react';
import cx from 'classnames';
import FocusTrap from 'focus-trap-react';
import useMedia from 'use-media';
import PropTypes from 'prop-types';
import { Grid, Row, Column } from '../Grid';
import {
galleryContainer,
inDialogGalleryContainer,
galleryGrid,
galleryRow,
navButtons,
closeButton,
icon,
navButtonsContainer,
firstRightNav,
rightNav,
leftNav,
addNoScroll,
} from './ImageGallery.module.scss';

function ImageGallery({ children }) {
const [portalsNode, updateNode] = useState(null);
const [isGalleryOpen, setIsGalleryOpen] = useState(false);
const [activeImageIndex, updateActiveImageIndex] = useState(null);
const mediaChildren = Children.toArray(children).filter(
child => child.props.src
);
const rightNavButton = cx({
[rightNav]: true,
[firstRightNav]: activeImageIndex === 0,
[navButtons]: activeImageIndex > 0,
});
const leftNavButton = cx([leftNav], [navButtons]);
const isMobile = useMedia({ maxWidth: breakpoints.md.width });

// Creates the node to go into the portalsNode state.
useEffect(() => {
const node = document.createElement('div');
document.body.appendChild(node);
updateNode(node);

return () => {
node.parentNode.removeChild(node);
};
}, []);

// Depending on if the gallery is open or not, this adds the addNoScroll class so the screen behind the modal doesn't scroll when opened.
useEffect(() => {
if (isGalleryOpen) {
document.body.classList.add(addNoScroll);
}

return () => {
document.body.classList.remove(addNoScroll);
};
}, [isGalleryOpen]);

// Removes addNoScroll if view is shrunk to mobile view when the gallery is open
useEffect(() => {
if (
(isMobile && document.body.classList.contains(addNoScroll)) ||
!isGalleryOpen
) {
document.body.classList.remove(addNoScroll);
}

return () => {
if (!isMobile && isGalleryOpen) {
document.body.classList.add(addNoScroll);
}
};
}, [isGalleryOpen, isMobile]);

// Opens gallery if the breakpoint isn't mobile and the child has a src prop
function openGalleryForImage(child, index) {
return () => {
if (!isMobile && child.props.src) {
setIsGalleryOpen(true);
updateActiveImageIndex(index);
}
};
}

function closeGallery() {
setIsGalleryOpen(false);
updateActiveImageIndex(null);
}

function selectNextImage() {
if (activeImageIndex + 1 < mediaChildren.length) {
updateActiveImageIndex(activeImageIndex + 1);
}
}

function selectPrevImage() {
if (activeImageIndex - 1 >= 0) {
updateActiveImageIndex(activeImageIndex - 1);
}
}

function onKeyDown(event) {
if (event.key === 'Escape') {
closeGallery();
return;
}
if (event.key === 'ArrowLeft') {
selectPrevImage();
return;
}
if (event.key === 'ArrowRight') {
selectNextImage();
}
}

return (
<>
<Row className={galleryContainer}>
{Children.map(children, (child, index) =>
React.cloneElement(child, {
onClick: openGalleryForImage(child, index),
})
)}
</Row>
{portalsNode &&
isGalleryOpen &&
!isMobile &&
ReactDOM.createPortal(
<FocusTrap>
{/* Because of FocusTrap, the key down events will propagate up removing the accessibility problem that would be created by having a keydown event listener on a non-interactive element. */}
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
<div
role="group"
className={inDialogGalleryContainer}
onKeyDown={onKeyDown}
>
<Row>
<Column colLg={2}>
<button
type="button"
className={closeButton}
onClick={closeGallery}
>
<Close32 className={icon} />
</button>
</Column>
</Row>
<Grid className={galleryGrid}>
<Row className={galleryRow}>
<Column colLg={3} className={navButtonsContainer}>
{activeImageIndex - 1 >= 0 && (
<button
type="button"
className={leftNavButton}
onClick={selectPrevImage}
>
<ChevronLeft32 className={icon} />
</button>
)}
</Column>
<Column colLg={6}>
{React.cloneElement(mediaChildren[activeImageIndex], {
isInDialog: true,
})}
</Column>
<Column colLg={3} className={navButtonsContainer}>
{activeImageIndex + 1 < mediaChildren.length && (
<button
type="button"
className={rightNavButton}
onClick={selectNextImage}
>
<ChevronRight32 className={icon} />
</button>
)}
</Column>
</Row>
</Grid>
</div>
</FocusTrap>,
portalsNode
)}
</>
);
}

ImageGallery.propTypes = {
children: PropTypes.arrayOf(PropTypes.element).isRequired,
};

export default ImageGallery;
Loading