diff --git a/CHANGELOG.md b/CHANGELOG.md index 372b8b7453..49fd0e1446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -729,6 +729,7 @@ See https://docs.voltocms.com/upgrade-guide/ for more information about all the ### Feature +- Add Image with srcset and lazy loading using Plone scales @nzambello - Add runtime configuration for `@babel/plugin-transform-react-jsx` set to `automatic`. This enables the new JSX runtime: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html So no longer `import React from 'react'` is needed anymore. - Update favicon and related tags with best practices @sneridagh diff --git a/cypress/tests/core/blocks-image.js b/cypress/tests/core/blocks-image.js index 4c722b506f..b43a3b4141 100644 --- a/cypress/tests/core/blocks-image.js +++ b/cypress/tests/core/blocks-image.js @@ -113,7 +113,7 @@ describe('Blocks Tests', () => { // then image src must be equal to image name cy.get('.block img') .should('have.attr', 'src') - .and('eq', '/my-page/image.png/@@images/image'); + .and('eq', '/my-page/image.png/@@images/image/icon'); cy.get('.block img') .should('be.visible') diff --git a/cypress/tests/core/blocks-listing-templates.js b/cypress/tests/core/blocks-listing-templates.js index 245bab3bec..50f78be339 100644 --- a/cypress/tests/core/blocks-listing-templates.js +++ b/cypress/tests/core/blocks-listing-templates.js @@ -48,7 +48,7 @@ describe('Folder Contents Tests', () => { cy.url().should('eq', Cypress.config().baseUrl + '/my-folder/my-document'); cy.get('.listing-item img') .should('have.attr', 'src') - .and('contain', '/my-folder/my-document/my-image/@@images/image/preview'); + .and('contain', '/my-folder/my-document/my-image/@@images/image/icon'); cy.get('.listing-item img') .should('be.visible') .and(($img) => { diff --git a/cypress/tests/core/objectBrowser.js b/cypress/tests/core/objectBrowser.js index 58a7b0c444..6c9b78558d 100644 --- a/cypress/tests/core/objectBrowser.js +++ b/cypress/tests/core/objectBrowser.js @@ -44,7 +44,7 @@ describe('Object Browser Tests', () => { // then we should see a image cy.get('.block img') .should('have.attr', 'src') - .and('eq', '/my-page-1/my-image/@@images/image'); + .and('eq', '/my-page-1/my-image/@@images/image/icon'); }); it('As editor I can add the full url in search box in sidebar', () => { @@ -61,7 +61,7 @@ describe('Object Browser Tests', () => { // then we should see a image cy.get('.block img') .should('have.attr', 'src') - .and('eq', '/my-page-1/my-image/@@images/image'); + .and('eq', '/my-page-1/my-image/@@images/image/icon'); }); it('As editor I get focus on search box in sidebar when clicking on lens icon', () => { diff --git a/docs/source/developer-guidelines/images.md b/docs/source/developer-guidelines/images.md new file mode 100644 index 0000000000..e081bdd4d8 --- /dev/null +++ b/docs/source/developer-guidelines/images.md @@ -0,0 +1,65 @@ +# Images + +Images are rendered with the Volto component `Image`. +It renders images using Plone scales from [plone.app.imaging](https://github.com/plone/plone.app.imaging) and handles: + +- Lazy load of images +- Loads the most correct one for current image size with `srcset` + +## Usage + +Basic example: + +```jsx +import Image from '@plone/volto/components/theme/Image/Image'; + + + +``` + +### Usage in a CT view or in a block + +Example from NewsItem or Event default views, with some layout props: + +```jsx + +``` + +### Usage in a listing block + +Or in general, when dealing with catalog brains: + +```jsx + +``` + +## Image props + +| prop | type | required | default | descirption | +| ------------------ | ------------------------------------- | ------------------ | ------- | ------------------------------------------------------------------------------ | +| image | object or string | :white_check_mark: | | Plone image object or image url | +| imageField | string | | `image` | Image field (see https://github.com/plone/volto/pull/2731) | +| alt | string | | `''` | Alternative text for the image | +| className | string | | | CSS class for the image | +| containerClassName | string | | | Additional CSS classes for the container picture element | +| floated | `left` or `right` | | | Float the image to left or right | +| size | `thumb`, `small`, `medium` or `large` | | | Image size (CSS-level, not related to img resolution) | +| role | string | | `img` | img role attribute | +| critical | boolean | | `false` | If true, it will render the actual image on SSR and it will not be lazy loaded | +| maxSize | number | | | Maximum size to render in pixel, will skip the larger ones | +| useOriginal | boolean | | `false` | If true, it will includes the original size in srcset | + +### Image prop + +If it is an object, it assumes it is a Plone Image content object and it will render the scales it has inside. +Else if it is a string, it checks if it is an internal URL: if so, it will generate the scales URLs based on the settings in `config.settings.imageScales` which should match the ones in Plone imaging controlpanel (so in Plone registry). +If it is an external URL, it will set it as source for the image. diff --git a/src/components/manage/Blocks/HeroImageLeft/View.jsx b/src/components/manage/Blocks/HeroImageLeft/View.jsx index 6d17b049f6..4ce95b4738 100644 --- a/src/components/manage/Blocks/HeroImageLeft/View.jsx +++ b/src/components/manage/Blocks/HeroImageLeft/View.jsx @@ -5,7 +5,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { flattenToAppURL } from '@plone/volto/helpers'; +import Image from '@plone/volto/components/theme/Image/Image'; import { LinkMore } from '@plone/volto/components'; /** @@ -16,14 +16,7 @@ import { LinkMore } from '@plone/volto/components'; const View = ({ data }) => (
- {data.url && ( - - )} + {data.url && }
{data.title &&

{data.title}

} diff --git a/src/components/manage/Blocks/HeroImageLeft/View.test.jsx b/src/components/manage/Blocks/HeroImageLeft/View.test.jsx index ce2fe7c83b..5c88be3f2f 100644 --- a/src/components/manage/Blocks/HeroImageLeft/View.test.jsx +++ b/src/components/manage/Blocks/HeroImageLeft/View.test.jsx @@ -2,8 +2,22 @@ import React from 'react'; import renderer from 'react-test-renderer'; import View from './View'; +import config from '@plone/volto/registry'; + +config.settings.imageScales = { + large: 768, + preview: 400, + mini: 200, + thumb: 128, + tile: 64, + icon: 32, + listing: 16, +}; + test('renders a view hero component', () => { - const component = renderer.create(); + const component = renderer.create( + , + ); const json = component.toJSON(); expect(json).toMatchSnapshot(); }); diff --git a/src/components/manage/Blocks/HeroImageLeft/__snapshots__/View.test.jsx.snap b/src/components/manage/Blocks/HeroImageLeft/__snapshots__/View.test.jsx.snap index a3a7a80066..c05c8f35e6 100644 --- a/src/components/manage/Blocks/HeroImageLeft/__snapshots__/View.test.jsx.snap +++ b/src/components/manage/Blocks/HeroImageLeft/__snapshots__/View.test.jsx.snap @@ -7,11 +7,33 @@ exports[`renders a view hero component 1`] = `
- + + +