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

[SFS-1685] Feature/height siteeditor #96

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- Possibility to explicit set height for images

## [0.22.3] - 2024-09-04

### Removed
Expand Down
54 changes: 27 additions & 27 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,47 +63,47 @@ Note that the `slider-layout` block exported from the Slider Layout app is a chi

### `list-context.image-list` props

| Prop name | Type | Description | Default value |
| --------- | --------- | ------------------------------------------------------------------------------------- | ------------- |
| `images` | `array` | Array of objects that declares all the images to be rendered. | `undefined` |
| `height` | `number` | Image height for all images declared in the `image` object (in `px`). | `undefined` |
| `preload` | `boolean` | Preloads the first image in a list, prioritizing the image display over other assets. | `false` |
| Prop name | Type | Description | Default value |
| ----------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------- | ------------- |
| `images` | `array` | Array of objects that declares all the images to be rendered. | `undefined` |
| `height` | `number` | Image height for all images declared in the `image` object (in `px`). | `undefined` |
| `preload` | `boolean` | Preloads the first image in a list, prioritizing the image display over other assets. | `false` |
| `experimentalSetExplicitDimensions` | `boolean` | Sets explicit `width` and/or `height` attributes for an image, if `width` and/or `height` props are provided in `px`. |

### `image-list` props

| Prop name | Type | Description | Default value |
| --------- | -------- | --------------------------------------------------------------------- | ------------- |
| `images` | `array` | Array of objects that declares all the images to be rendered. | `undefined` |
| `height` | `number` | Image height for all images declared in the `image` object (in `px`). | `undefined` |
| Prop name | Type | Description | Default value |
| -------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------- | ------------- |
| `images` | `array` | Array of objects that declares all the images to be rendered. | `undefined` |
| `height` | `number` | Image height for all images declared in the `image` object (in `px`). | `undefined` |
| `experimentalPreventLayoutShift` | `boolean` | Wraps the image in a `<span>` tag with a preset `width` and/or `height` to minimize layout shift during page loading. |

- **`images` array:**

| Prop name | Type | Description | Default value |
|------------------------|---------------------|----------------------------------------------------------------------------------------------------|---------------|
| `image` | `string` | Image URL. | `undefined` |
| `mobileImage` | `string` | Mobile image URL. | `undefined` |
| `description` | `string` | Image description. | `undefined` |
| `link` | `object` | Links a URL to the image being rendered. | `undefined` |
| `width` | `string` / `number` | Image width (in `%` or `px`). | `100%` |
| Prop name | Type | Description | Default value |
| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------- | ------------- |
| `image` | `string` | Image URL. | `undefined` |
| `mobileImage` | `string` | Mobile image URL. | `undefined` |
| `description` | `string` | Image description. | `undefined` |
| `link` | `object` | Links a URL to the image being rendered. | `undefined` |
| `width` | `string` / `number` | Image width (in `%` or `px`). | `100%` |
| `loading` | `string` | Loading strategy, either when the page loads (`'eager'`) or when closer to the viewport (`'lazy'`). | `'eager'` |
| `fetchpriority` | `string` | The fetch priority hint (`'high'`, `'low'`, or `'auto'`). | `'auto'` |
| `fetchpriority` | `string` | The fetch priority hint (`'high'`, `'low'`, or `'auto'`). | `'auto'` |
| `analyticsProperties` | `string` | Whether analytics props should be set (`'provided'`) or not (`'none'`). | `'none'` |
| `promotionId` | `string` | The ID of the promotion associated with the event. | `undefined` |
| `promotionName` | `string` | The name of the promotion associated with the event. | `undefined` |
| `promotionPosition` | `string` | The name of the promotional creative slot associated with the event. | `undefined` |
| `promotionProductId` | `string` | The ID of the product associated with the event. | `undefined` |
| `promotionProductName` | `string` | The name of the product associated with the event. | `undefined` |
| `promotionId` | `string` | The ID of the promotion associated with the event. | `undefined` |
| `promotionName` | `string` | The name of the promotion associated with the event. | `undefined` |
| `promotionPosition` | `string` | The name of the promotional creative slot associated with the event. | `undefined` |
| `promotionProductId` | `string` | The ID of the product associated with the event. | `undefined` |
| `promotionProductName` | `string` | The name of the product associated with the event. | `undefined` |

- **`link` object:**

| Prop name | Type | Description | Default value |
| ------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `url` | `string` | URL users will be redirected to when they click the image. | `undefined` |
| Prop name | Type | Description | Default value |
| ------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `url` | `string` | URL users will be redirected to when they click the image. | `undefined` |
| `noFollow` | `boolean` | Whether the page owner endorses the linked URL the user was navigating on, i.e., if there is a business relationship between both pages (`true`) or (`false`). | `false` |
| `openNewTab` | `string` | Whether a new tab will be opened on the browser (`true`) or (`false`). | `undefined` |
| `title` | `string` | Text label used to identify the image in the Admin Site Editor. | `undefined` |
| `openNewTab` | `string` | Whether a new tab will be opened on the browser (`true`) or (`false`). | `undefined` |
| `title` | `string` | Text label used to identify the image in the Admin Site Editor. | `undefined` |

> ℹ️ Use the **Admin Site Editor** to manage all images declared in the `list-context.image-list` block.

Expand Down
4 changes: 2 additions & 2 deletions messages/context.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
"admin/editor.image-list.description": "Show a list of images",
"admin/editor.image-list.height.title": "Maximum height for each image (px)",
"admin/editor.image-list.images.description.title": "Image alt text",
"admin/editor.image-list.images.height.description": "Image height for a single image (px)",
"admin/editor.image-list.images.height.title": "Image height",
"admin/editor.image-list.images.image.title": "Image",
"admin/editor.image-list.images.link.noFollow.title": "Should be a nofollow link",
"admin/editor.image-list.images.link.openNewTab.title": "Should open on new tab",
Expand All @@ -13,6 +11,8 @@
"admin/editor.image-list.images.title.title": "Image title",
"admin/editor.image-list.images.title": "Images",
"admin/editor.image-list.images.width.description": "Image width for a single image (% or px)",
"admin/editor.image-list.images.height.title": "Image height",
"admin/editor.image-list.images.height.description": "Image height for a single image (px)",
"admin/editor.image-list.images.width.title": "Image width",
"admin/editor.image-list.title": "Image List",
"admin/editor.image-slider.description": "Image Slider",
Expand Down
4 changes: 2 additions & 2 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
"admin/editor.image-list.description": "Show a list of images",
"admin/editor.image-list.height.title": "Maximum height for each image (px)",
"admin/editor.image-list.images.description.title": "Image alt text",
"admin/editor.image-list.images.height.description": "Image height for a single image (px)",
"admin/editor.image-list.images.height.title": "Image height",
"admin/editor.image-list.images.image.title": "Image",
"admin/editor.image-list.images.link.noFollow.title": "Nofollow link",
"admin/editor.image-list.images.link.openNewTab.title": "Open in new tab",
Expand All @@ -13,6 +11,8 @@
"admin/editor.image-list.images.title.title": "Image title",
"admin/editor.image-list.images.title": "Images",
"admin/editor.image-list.images.width.description": "Image width for a single image (% or px)",
"admin/editor.image-list.images.height.title": "Image height",
"admin/editor.image-list.images.height.description": "Image height for a single image (px)",
"admin/editor.image-list.images.width.title": "Image width",
"admin/editor.image-list.title": "Image List",
"admin/editor.image-slider.description": "Image slider",
Expand Down
4 changes: 2 additions & 2 deletions messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
"admin/editor.image-list.description": "Mostrar una lista de imágenes",
"admin/editor.image-list.height.title": "Altura máxima de cada imagen (px)",
"admin/editor.image-list.images.description.title": "Texto alternativo de la imagen",
"admin/editor.image-list.images.height.description": "Altura de la imagen para una única imagen (px)",
"admin/editor.image-list.images.height.title": "Altura de la imagen",
"admin/editor.image-list.images.image.title": "Imagen",
"admin/editor.image-list.images.link.noFollow.title": "Debe ser un enlace nofollow",
"admin/editor.image-list.images.link.openNewTab.title": "Abrir en una nueva pestaña",
Expand All @@ -13,6 +11,8 @@
"admin/editor.image-list.images.title.title": "Título de la imagen",
"admin/editor.image-list.images.title": "Imágenes",
"admin/editor.image-list.images.width.description": "Anchura de la imagen para una sola imagen (% o px)",
"admin/editor.image-list.images.height.title": "Altura de la imagen",
"admin/editor.image-list.images.height.description": "Altura de la imagen para una única imagen (px)",
"admin/editor.image-list.images.width.title": "Anchura de la imagen",
"admin/editor.image-list.title": "Lista de imágenes",
"admin/editor.image-slider.description": "Control deslizante de imágenes",
Expand Down
4 changes: 2 additions & 2 deletions messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
"admin/editor.image-list.description": "Exibe uma lista de imagens",
"admin/editor.image-list.height.title": "Altura máxima de cada imagem (px)",
"admin/editor.image-list.images.description.title": "Descrição alternativa para a imagem",
"admin/editor.image-list.images.height.description": "Altura de imagem para uma única imagem (px)",
"admin/editor.image-list.images.height.title": "Altura da imagem",
"admin/editor.image-list.images.image.title": "Imagem",
"admin/editor.image-list.images.link.noFollow.title": "Link nofollow",
"admin/editor.image-list.images.link.openNewTab.title": "Abrir em uma nova aba",
Expand All @@ -13,6 +11,8 @@
"admin/editor.image-list.images.title.title": "Título da imagem",
"admin/editor.image-list.images.title": "Imagens",
"admin/editor.image-list.images.width.description": "Largura de imagem para uma única imagem (% ou px)",
"admin/editor.image-list.images.height.title": "Altura da imagem",
"admin/editor.image-list.images.height.description": "Altura de imagem para uma única imagem (px)",
"admin/editor.image-list.images.width.title": "Largura da imagem",
"admin/editor.image-list.title": "Lista de imagens",
"admin/editor.image-slider.description": "Slider de imagens",
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"license": "UNLICENSED",
"scripts": {
"lint": "eslint --quiet --fix --ext ts,tsx ./react",
"test": "cd ./react && yarn test",
"format": "prettier --write \"**/*.{ts,js,json}\"",
"test": "cd ./react && yarn test",
"lint:locales": "intl-equalizer",
"locales:fix": "intl-equalizer --fix",
"verify": "yarn lint && yarn lint:locales && yarn test"
Expand All @@ -21,6 +21,9 @@
"eslint --fix",
"prettier --write"
],
"*.{json,graphql,gql}": [
"prettier --write"
],
"*.json": [
"prettier --write"
]
Expand All @@ -41,4 +44,4 @@
"referenceLocale": "en",
"localeDirectory": "messages"
}
}
}
56 changes: 40 additions & 16 deletions react/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ export interface ImageProps
classes?: CssHandlesTypes.CustomClasses<typeof CSS_HANDLES>
preload?: boolean
loading?: 'eager' | 'lazy'
fetchpriority?: 'high' | 'low' | 'auto'
fetchpriority?: 'high' | 'low' | 'auto'
width?: string | number
height?: string | number
specificHeight?: string | number
/**
* Warning: This property is for internal usage, please avoid using it.
* This property is used when the Image is children of the SliderTrack component and it prevents triggering the promoView event twice for cloned images.
Expand Down Expand Up @@ -80,7 +83,8 @@ function Image(props: ImageProps) {
minWidth,
minHeight,
width,
height,
height: genericHeight,
specificHeight,
srcSet = '',
sizes = '',
link,
Expand Down Expand Up @@ -112,26 +116,46 @@ function Image(props: ImageProps) {
classes,
})

const imageDimensions = {
const imageDimensionsWithoutExplicitDimensions = {
minWidth,
minHeight,
maxWidth,
maxHeight,
}

const imageDimensionsWithExplicitDimensions = {
...imageDimensionsWithoutExplicitDimensions,
genericHeight,
width,
height,
}

const placeholderSize = height ?? minHeight ?? maxHeight ?? 'auto'
const placeholderSize =
specificHeight ?? genericHeight ?? maxHeight ?? minHeight ?? 'auto'

const allowedExplicitDimensionsRegex = /(auto|inherit|initial|unset)|[^\d]/g

const explicitDimensions = (dimension: string | number | undefined) =>
dimension !== '' && dimension
? dimension.toString().replace(allowedExplicitDimensionsRegex, '$1')
: null

const widthWithoutUnits = width ? width.toString().replace(/\D/g, '') : null
const heightWithoutUnits = height
? height.toString().replace(/\D/g, '')
: null
const widthWithoutUnits = explicitDimensions(width)

const heightWithoutUnits =
explicitDimensions(specificHeight) ??
explicitDimensions(genericHeight) ??
explicitDimensions(maxHeight)

const hasPercentage = (dimension: string | number | undefined) =>
dimension?.toString().includes('%')

const explicitDimensionsAreAvailable =
!width?.toString().includes('%') &&
!height?.toString().includes('%') &&
(widthWithoutUnits || heightWithoutUnits)
!!width &&
(!!specificHeight || !!maxHeight || !!genericHeight) &&
!hasPercentage(width) &&
(!hasPercentage(specificHeight) ||
!hasPercentage(maxHeight) ||
!hasPercentage(genericHeight))

const formattedSrc = formatIOMessage({ id: src, intl })
const formattedAlt = formatIOMessage({ id: alt, intl })
Expand All @@ -143,17 +167,17 @@ function Image(props: ImageProps) {
srcSet={srcSet}
src={typeof formattedSrc === 'string' ? formattedSrc : ''}
alt={typeof formattedAlt === 'string' ? formattedAlt : ''}
style={imageDimensions}
ref={imageRef}
className={handles.imageElement}
loading={loading}
fetchpriority={fetchpriority}
{...(experimentalSetExplicitDimensions && explicitDimensionsAreAvailable
? {
width: widthWithoutUnits ?? undefined,
height: heightWithoutUnits ?? undefined,
width: widthWithoutUnits ?? width ?? 'auto',
height: heightWithoutUnits ?? 'auto',
style: imageDimensionsWithoutExplicitDimensions,
}
: {})}
: { style: imageDimensionsWithExplicitDimensions })}
{...(preload
? {
'data-vtex-preload': 'true',
Expand Down
2 changes: 1 addition & 1 deletion react/ImageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { ImagesSchema } from './ImageTypes'

export interface ImageListProps {
images: ImagesSchema
height?: number
height?: number | string
preload?: boolean
experimentalPreventLayoutShift?: boolean
experimentalSetExplicitDimensions?: boolean
Expand Down
Loading
Loading