Trying to add Ligthbox effect in Chakra Theme

Hi, i need help to add Lightbox react effect to frontity-chackra-theme images.
This is the React component:
react-lightbox-component
I search in chakra theme code and found this in src/helpers.js:

export function getMediaAttributes(state, id) {
  const media = state.source.attachment[id];
  if (!media) return {};
  const srcSet = getSrcSet(media);
  return {
    id,
    alt: media.title.rendered,
    src: media.source_url,
    srcSet
  };
}

And this is the demo code of the Lightbox react component:

import Lightbox from 'react-lightbox-component';
const App = () => (
  <div>
    <Lightbox images={
      [
        {
          src: 'some image url',
          title: 'image title',
          description: 'image description'
        }
      ]
    }/>
  </div>
);

Is possible to merge these codes to put all images in a lightbox component?
Maybe in another file? html2react? processors/image.js?

Thanks so much

I think the best option would be to create a Lightbox component as show in the demo, and a processor to use that component in all the images of the theme. This processor may be similar to the image processor but loading your new component instead of the Image one we built.

You can find more info about how to create a processor at our docs, but it should be something similar to this:

import LightboxImage from "../your-folder";

const image = {
  // We can add a name to identify it later.
  name: "image",

  // We can add a priority so it executes before or after other processors.
  priority: 10,

  // Only process the node it if it's an image.
  test: node => node.component === "img",
  
  process: node => {
    // If the image is inside a <noscript> tag, we don't want to process it.
    if (node.parent.component === "noscript") return null;

    // Many WP lazy load plugins move the real "src" to "data-src", so we move it back.
    if (node.props["data-src"])
      node.props.src = node.props["data-src"];
    if (node.props["data-srcset"])
      node.props.srcSet = node.props["data-srcset"];
      
    // We tell Html2React that it should use the <LightboxImage /> component
    node.component = LightboxImage;

    return node;
  }
};

export default image;

Once you’ve created your processor, you have to load it in your theme. Again, you can check our docs, and here you have a quick example:

At the index.js file of your theme

import image from "../your-processor-file";

const marsTheme = {
  ...
  actions: {
    theme: {
      init: ({ libraries }) => {
        // Add the Html2React processor for the <img> tags.
        libraries.html2react.processors.push(image);
      }
    }
  }
  ...
};

export default marsTheme;

Keep us posted if it works in your case and feel free to share more questions :slightly_smiling_face:

1 Like

Thanks for your help @SantosGuillamot.
I have an error:
ReferenceError: Image is not defined
at Object.eval (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:32903)
at t (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:327)
at Object.eval (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:12145)
at t (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:327)
at Object.eval (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:9125)
at t (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:327)
at Object.eval (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:8458)
at t (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:327)
at Object.eval (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:8366)
at t (webpack-internal:///./node_modules/react-lightbox-component/build/index.js:1:327)

Maybe lightbox module is waiting for this parameter:
src: ‘some image url’,
and the code is not passing the parameter correctly.

It seems that the error is returned because the LightBox component is not properly configured. Could you share it with us in order to take a look?

Just to clarify, you may need something like this:

A LightboxImage component

Inside this component you’ll use the Lightbox from the library you share, and it gets the props from the <img> tag attributes. You have to make sure you pass the correct parameters to the <Lightbox> component. It could be similar to this:

import Lightbox from 'react-lightbox-component';
import { connect } from "frontity";

const LightboxImage = (props) => (
  <div>
    <Lightbox images={
      [
        {
          src: props.src,
          title: props.alt,
          description: props.description
        }
      ]
    }/>
  </div>
);

export default connect(LightboxImage);

Not sure if inside the Lightbox library, title and description are mandatory fields. But if not, you could make that optional.

A new processor for the images

You have create a new processor for the images in order to use your new component instead of the default one. It could be something like the current one, adapting it to your own needs, but using your component.

import LightboxImage from "../your-new-component";

const lightboxImage = {
  // We can add a name to identify it later.
  name: "image",

  // We can add a priority so it executes before or after other processors.
  priority: 5,

  // Only process the node it if it's an image.
  test: node => node.component === "img",
  
  process: node => {
    // If the image is inside a <noscript> tag, we don't want to process it.
    if (node.parent.component === "noscript") return null;

    // Many WP lazy load plugins move the real "src" to "data-src", so we move it back.
    if (node.props["data-src"])
      node.props.src = node.props["data-src"];
    if (node.props["data-srcset"])
      node.props.srcSet = node.props["data-srcset"];
      
    // We tell Html2React that it should use the <LightboxImage /> component
    node.component = LightboxImage;

    return node;
  }
};

export default lightboxImage;

Add the new processor to your theme

You need to include the new processor in your settings so it’s executed by @frontity/html2react package. You’ll need to include it in the index.js file of your theme.

import lightboxImage from "../your-processor-file";

const marsTheme = {
  ...
  libraries: {
    html2react: {
      processors: [lightboxImage]
    }
  }
  ...
};

export default marsTheme;

Hope this helps, let us know if you solve the problem!