2.3.7 • Published 12 months ago

react-editable-photo-grid v2.3.7

Weekly downloads
-
License
GPL-3.0
Repository
github
Last release
12 months ago

react-editable-photo-grid

An editable photo grid for react applications.

import React, { useState, useEffect }  from 'react';
import { PhotoGrid, PhotoRows } from 'react-editable-photo-grid';

const Photos: React.FC = () => {
    const [photos, setPhotos] = useState<PhotoRows>({}),
        [changes, setChanges] = useState<Number>(0),
        [selectedPhotos, setSelectedPhotos] = useState<Array<string>>([]);

    const getData = () => {
        // Fetch photos from API and update state
    }

    useEffect(() => {
        getData();
    }, []);

    return (
      <PhotoGrid
        isEditing={true}
        rows={photos}
        updateRows={setPhotos}
        selectedPhotos={selectedPhotos}
        updateSelectedPhotos={setSelectedPhotos}
        changes={changes}
        increaseChanges={() => setChanges(changes + 1)}
        imageSrcPrefix="/api/image"
        imageSrcProperty="thumbnail_path"
      />
    );
}

export default Photos;

How to Install

npm i react-editable-photo-grid

Required Props

PropertiesTypeDescription
isEditingBooleanSwitches the grid from display to editable
rowsPhotoRowsAn array of rows where the keys are row numbers and items are photo arrays.
updateRowsVoidA method that updates the rows data from the parent
selectedPhotosArrayThis can be populated with photo ids for batch operations
updateSelectedPhotosVoidA method to update the selectedPhotos prop
changesNumberTracks when changes have been made (the editable part)
increaseChangesVoidA method to update the changes prop
imageSrcPrefixStringA string that represents the url prefix for each photo image src attribute. This will be used for the grid and gallery.
imageSrcPropertyStringDetermines which photo property is used for the grid img src parameter.
useGalleryBooleanActivate the Gallery component.
buttonArrowsButtonArrowsAllows you to override the basic button arrows with custom html.
gallerySrcPropertyStringDetermines which photo property is used for the gallery image src parameter.
galleryButtonArrowsGalleryButtonArrowsAllows you to override the gallery prev and next button arrows with custom html.
onPhotoClickVoidA method that receives the photo id on click
onGallerySwipeVoidA method that receives a photo object when the gallery is swiped
galleryTypeStringDetermines if the legacy gallery or the scroll gallery (beta) is to be used

How to Use

To use the PhotoGrid component you can import it like this:

import { PhotoGrid, PhotoRows, PhotoItem, sortPhotosIntoRows } from 'react-editable-photo-grid';
import { getPhotos } from 'api';

PhotoGrid represents the component and PhotoRows is the TS type for the data. You can add the component to your code like this:

    const [photos, setPhotos] = useState<PhotoItem[]>([]),
      [rows, setRows] = useState<PhotoRows[]>({})

    const loadPhotos = (): void => {
      const photos = await getPhotos();
      setPhotos(photos);
      setRows(sortPhotosIntoRows(photos));
    }

    return (
      <PhotoGrid
        isEditing={true}
        photos={photos}
        rows={rows}
        updateRows={setRows}
        selectedPhotos={selectedPhotos}
        updateSelectedPhotos={setSelectedPhotos}
        changes={changes}
        increaseChanges={() => setChanges(changes + 1)}
        imageSrcPrefix="/api/image"
        imageSrcProperty="/thumbnail_path"
      />
    );

How data should be structured

Structure the data for the PhotoGrid like this:

export interface PhotoRows {
  [key: number]: PhotoItem[];
}

export interface PhotoItem {
  id: string;
  column: number;
  image_path: string;
  thumbnail_path: string;
  carousel_key: number;
  width: number;
  height: number;
}

PhotoItem represents a single photo data object. PhotoRows is an associative array where each key is a row number and items an array of associated photos.

Passing a custom dropdown menu

You can add a menu to the grid by passing a component as the photoMenu prop. The grid will clone this prop and add it to each photo. There isn't a set format that a menu has to be but here is an example:

const PhotoMenu = (props: PhotoMenuProps) => {
  return (
    <div className="photomenu">
      <Checkbox
        value={props.photo.id}
        onClick={props.updateSelectedPhotos}
        checked={props.selectedPhotos.includes(props.photo.id)}
      />
      <div>
        <button
          data-key={props.photo.id}
          type="button"
          onClick={props.openDropdown}
        >
          Edit
        </button>
        <ul
          style={{ display: props.activeDropdown ===    props.photo.id ? 'block' : 'none' }}
        >
          <li>
            <a
              href={props.photo.id}
              onClick={props.edit}>
              Edit
              </a>
          </li>
        </ul>
      </div>
    </div>
  );
};

And here is how you can prepare it for the grid:

  const photoMenu = <PhotoMenu
    selectedPhotos={selectedPhotos}
    updateSelectedPhotos={updateSelectedPhotos}
    activeDropdown={activeDropdown}
    openDropdown={openDropdown}
    edit={edit}
  />

You can then pass photoMenu to the grid as a prop. See the sample component for more details

Using the gallery

You can enable the gallery by passing the the required props like this:

  <PhotoGrid
    { ... other props}
    useGallery={true}
    gallerySrcProperty="image_path"
  />

This will make the gallery appear when a photo is clicked.

Examples

See the samples directory for sample usage.

How is it editable?

The PhotoGrid component allows you to structure your photos in rows and columns. As such it provides controls to change the position of the rows within the page and the columns within the rows. Each time an edit is made it updates the rows prop. It also increases the changes prop.

You can use the changes prop to work out if any edits have been made. You can then submit your edits to your API to permanently store the changes. The easiest way to achieve this is to add 'row' and 'column' properties to the data handled by your API.

2.3.7

12 months ago

2.3.6

12 months ago

2.3.5

12 months ago

2.3.4

12 months ago

2.3.3

12 months ago

2.3.2

12 months ago

2.3.1

12 months ago

2.3.0

12 months ago

2.2.6

12 months ago

2.2.5

12 months ago

2.2.4

12 months ago

2.2.3

12 months ago

2.2.2

12 months ago

2.2.1

12 months ago

2.2.0

12 months ago

2.1.9

12 months ago

2.1.8

12 months ago

2.1.7

12 months ago

2.1.6

12 months ago

2.1.5

12 months ago

2.1.4

12 months ago

2.1.3

12 months ago

2.1.2

12 months ago

2.1.1

12 months ago

2.1.0

12 months ago

2.0.1

12 months ago

2.0.0

12 months ago

1.9.9

12 months ago

1.9.8

12 months ago

1.9.7

12 months ago

1.9.6

12 months ago

1.9.5

12 months ago

1.9.4

12 months ago

1.9.3

12 months ago

1.9.2

12 months ago

1.9.1

12 months ago

1.9.0

12 months ago

1.8.9

12 months ago

1.8.8

12 months ago

1.8.7

12 months ago

1.8.6

12 months ago

1.8.5

12 months ago

1.8.4

12 months ago

1.8.3

12 months ago

1.8.2

12 months ago

1.8.1

12 months ago

1.8.0

12 months ago

1.7.3

12 months ago

1.7.2

12 months ago

1.7.1

12 months ago

1.7.0

12 months ago

1.6.9

12 months ago

1.6.8

12 months ago

1.6.7

12 months ago

1.6.6

12 months ago

1.6.5

12 months ago

1.6.4

12 months ago

1.6.3

12 months ago

1.6.2

1 year ago

1.6.1

1 year ago

1.6.0

1 year ago

1.5.6

1 year ago

1.5.5

1 year ago

1.5.3

1 year ago

1.5.2

1 year ago

1.5.1

1 year ago

1.5.0

1 year ago

1.4.9

1 year ago

1.4.8

1 year ago

1.4.7

1 year ago

1.4.6

1 year ago

1.4.5

1 year ago

1.4.4

1 year ago

1.4.3

1 year ago

1.4.2

1 year ago

1.4.1

1 year ago

1.4.0

1 year ago

1.3.9

1 year ago

1.3.8

1 year ago

1.3.7

1 year ago

1.3.6

1 year ago

1.3.5

1 year ago

1.3.4

1 year ago

1.3.3

1 year ago

1.3.2

1 year ago

1.3.1

1 year ago

1.3.0

1 year ago

1.2.8

1 year ago

1.2.7

1 year ago

1.2.6

1 year ago

1.2.5

1 year ago

1.2.4

1 year ago

1.2.3

1 year ago

1.2.2

1 year ago

1.2.1

1 year ago

1.2.0

1 year ago

1.1.4

1 year ago

1.1.3

1 year ago

1.1.2

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.0.8

1 year ago

1.0.7

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago