Skip to content

Commit 632dbaa

Browse files
authored
Forms: update visual representation of "image select field" responses at inbox (#45585)
* Use Photon to load only a small image * Add `lazy` to prevent loading images early when they're outside the viewport, especially on mobile * Wrap images & responses next to each other, each on its own row, wrapped in a button * Open a modal to preview a larger photo when clicked * Simplify CSS to have fewer styles, use more components. * Especially an empty image is now a simpler implementation as more of an edge case; previously it was nicer, but I'm not sure it's worth the code.
1 parent 4503edf commit 632dbaa

File tree

5 files changed

+52
-69
lines changed

5 files changed

+52
-69
lines changed

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: changed
3+
4+
Forms: update visual representation of "image select field" responses at inbox

projects/packages/forms/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"js-sha256": "0.11.1",
7171
"libphonenumber-js": "1.12.23",
7272
"lodash": "4.17.21",
73+
"photon": "4.1.1",
7374
"react-redux": "7.2.8",
7475
"react-router": "7.6.2",
7576
"react-transition-group": "^4.4.5",

projects/packages/forms/src/dashboard/components/response-view/body.tsx

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import { dateI18n, getSettings as getDateSettings } from '@wordpress/date';
1919
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
2020
import { decodeEntities } from '@wordpress/html-entities';
2121
import { __, _n, sprintf } from '@wordpress/i18n';
22-
import { download } from '@wordpress/icons';
22+
import { download, image } from '@wordpress/icons';
2323
import clsx from 'clsx';
24+
import photon from 'photon';
2425
/**
2526
* Internal dependencies
2627
*/
@@ -249,45 +250,46 @@ const ResponseViewBody = ( {
249250
<div className="image-select-field">
250251
{ ( value.choices?.length ?? 0 ) === 0 && '-' }
251252
{ ( value.choices?.length ?? 0 ) > 0 && (
252-
<>
253-
<div className="image-select-field-choices">
254-
{ value.choices
255-
.map( choice => {
256-
let transformedValue = choice.selected;
257-
258-
if ( choice.label != null && choice.label !== '' ) {
259-
transformedValue += ' - ' + choice.label;
253+
<VStack spacing="1">
254+
{ value.choices.map( choice => {
255+
const label = choice.label
256+
? `${ choice.selected }: ${ choice.label }`
257+
: choice.selected;
258+
const hasImage = choice.image?.src;
259+
return (
260+
<Button
261+
__next40pxDefaultSize
262+
key={ choice.selected }
263+
variant="tertiary"
264+
onClick={
265+
hasImage
266+
? handleFilePreview( {
267+
file_id: choice.image.id,
268+
name: label,
269+
url: choice.image.src,
270+
} )
271+
: undefined
260272
}
261-
262-
return transformedValue;
263-
} )
264-
.join( ', ' ) }
265-
</div>
266-
<div className="image-select-field-images">
267-
{ value.choices.map( choice => {
268-
const imageSrc =
269-
choice.image?.src ||
270-
'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
271-
272-
return (
273-
<figure
274-
key={ choice.selected }
275-
className={ clsx( 'image-select-field-image', {
276-
'is-empty': ! choice.image?.src,
277-
} ) }
278-
>
279-
<img
280-
className={ clsx( 'image-select-field-image', {
281-
'is-empty': ! choice.image?.src,
282-
} ) }
283-
src={ imageSrc }
284-
alt={ choice.selected }
285-
/>
286-
</figure>
287-
);
288-
} ) }
289-
</div>
290-
</>
273+
className="image-select-field-button"
274+
icon={
275+
hasImage ? (
276+
<img
277+
alt={ choice.selected }
278+
className="image-select-field-image"
279+
loading="lazy"
280+
src={ photon( choice.image.src, { width: 120, height: 120 } ) }
281+
/>
282+
) : (
283+
image
284+
)
285+
}
286+
iconSize={ 60 }
287+
>
288+
{ label }
289+
</Button>
290+
);
291+
} ) }
292+
</VStack>
291293
) }
292294
</div>
293295
);

projects/packages/forms/src/dashboard/inbox/style.scss

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -274,36 +274,9 @@
274274

275275
.jp-forms__inbox-response-data-value .image-select-field {
276276

277-
.image-select-field-images {
278-
display: flex;
279-
flex-wrap: wrap;
280-
gap: 16px;
281-
}
282-
283-
.image-select-field-image {
284-
margin: 0;
285-
width: 60px;
286-
height: 60px;
287-
288-
&.is-empty {
289-
position: relative;
290-
291-
&::before {
292-
293-
@extend %empty-image-option-background;
294-
}
295-
296-
&::after {
297-
298-
@extend %empty-image-option-icon;
299-
background-color: #000;
300-
}
301-
}
302-
303-
img {
304-
aspect-ratio: 1/1;
305-
object-fit: cover;
306-
}
277+
.image-select-field-button {
278+
gap: variables.$grid-unit-10;
279+
height: auto;
307280
}
308281
}
309282

0 commit comments

Comments
 (0)