-
Notifications
You must be signed in to change notification settings - Fork 40
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
feat: add <PrismicImage>
#140
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, left my comments on the @prismicio/helpers
for opt-in/naming :)
|
||
const actual = renderJSON(<PrismicImage field={field} />); | ||
const expected = renderJSON( | ||
<img src={src} srcSet={srcset} alt={undefined} />, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this renders to an empty string alt
? (<img src="..." srcset="..." alt="" />
)
From: prismicio/prismic-vue#55, this is a better accessibility trade-off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not; it will render <img>
without an alt
attribute by default if the Image field's alt text is null
.
Using alt=""
explicitly states that the image is decorative and should be ignored by screen readers. A null
alt text in Prismic, however, does not always mean the image is decorative. In most cases, this happens because the content writer forgot to or just didn't write alt text.
Omitting alt
is a signal to the developer that the Image field needs alt text to be added in Prismic, or that it needs to be explicitly opted-out of the screen reader's flow. Automated checkers could also flag these alt-less <img>
s and provide reports, where an <img>
with alt=""
may not be flagged.
I think declaring an image as decorative should be explicit, requiring the developer to state it with alt=""
or fallbackAlt=""
.
I know there are nuances to this, and I might not have a correct understanding of <img>
and alt
. If this is incorrect, please let me know. 😀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok got it, I like this approach with the default alt.
Personally, I think I still side for the approach that was taken with Vue, but this way is great also!
test/PrismicImage.test.tsx
Outdated
test("supports overriding alt explicitly when field has an alt value", (t) => { | ||
const field = prismicM.value.image({ | ||
seed: t.title, | ||
model: prismicM.model.image({ seed: t.title }), | ||
}); | ||
field.alt = "provided alt"; | ||
|
||
const { src, srcset } = prismicH.asImageWidthSrcSet(field); | ||
|
||
const actual = renderJSON(<PrismicImage field={field} alt="explicit alt" />); | ||
const expected = renderJSON( | ||
<img src={src} srcSet={srcset} alt="explicit alt" />, | ||
); | ||
|
||
t.deepEqual(actual, expected); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is really an anti-pattern to overwrite content writers' work with explicit alt
. Are there use-cases where this is really needed?
To me, we should not provide that possibility and let it be a manual process (users would have to override the field's object so that it feels like something wrong to do).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only legitimate use cases I can think of is providing alt=""
or populating alt
with content from another field (e.g. a distinct "Alt Text" Key Text field).
I see what you mean though. There isn't really a good reason for overwriting an Image field's alt text with a static string, at least not that I can think of.
Disallowing alt
flexibility seems overly restrictive, even if it is not recommended. Perhaps there's a different API that could handle this without requiring users to hack their API responses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm by far not an accessibility expert, but the following is pretty much what I know
e.g. a distinct "Alt Text" Key Text field
I don't think this is a real use case (but maybe I'm wrong), every image you append in Prismic gets a free alt
field that you can use to overwrite the default image's alt for that purpose in the editor (and you cannot disable it, maybe there should be a way to mark an image field as decorative within the content type definition).
Using a distinct "Alt Text" Key Text field makes for a confusing UI because you end up with 2 alt text fields (the image one, and the additional one) and there's little way to let the content writer know which one has priority.
Computing the alt text value after another element of the design leads to duplication of information for screenreader users. For example, naming the alt
of a video thumbnail after the video title next to it is wrong as you end up duplicating information (screenreaders will read the video title, then the video thumbnail alt, which would be the same). Such alt
value should either be omitted (mark image as decorative with role="presentation"
or alt=""
) or left empty (alt=""
) when the content writer didn't bother to describe the thumbnail.
Maybe we could think about a decorative
prop to hide images from screenreaders properly. Although role="presentation"
is not the only/always preferred way to hide images from screenreaders (I think alt=""
tends to be preferred) so it would make the component more opinionated which I'm not really a fan of.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I agree with all of that. Using a separate field for alt text is an anti-pattern.
Adding alt=""
is in itself declaring the image as decorative, so I don't think we need to have a specialize API over that to declare it as such. With this approach, the JSX more closely matches the HTML output.
Compared to role="presentation"
, alt=""
seems to be the more standard approach for images.
It seems the only valid use case for a configurable alt
prop is to declare it as decorative. As such, what if we do this:
- Only allow an empty string
alt
(i.e.alt=""
). This is less opinionated than adecorative
prop and represents exactly what the HTML output will look like. Declaringalt=""
overrides the field's alt text in all cases. - Warn the user via
console.warn()
if a non-empty stringalt
is given only whenprocess.env.NODE_ENV === "development"
. - Type
alt
to only accept""
. - Apply the same behavior to
fallbackAlt
(i.e. only allowfallbackAlt=""
).
I'm going to move forward with this approach, but I can write a patch if you think we should adjust it.
Codecov Report
@@ Coverage Diff @@
## master #140 +/- ##
==========================================
+ Coverage 92.41% 92.58% +0.16%
==========================================
Files 16 18 +2
Lines 277 310 +33
Branches 62 72 +10
==========================================
+ Hits 256 287 +31
Misses 5 5
- Partials 16 18 +2
Continue to review full report at Codecov.
|
size-limit report 📦
|
Types of changes
Description
This PR adds a
<PrismicImage>
component. It renders a Prismic Image field.This renders the following HTML (using placeholder values for the full image URLs).
Note that a viewport-width-based
srcset
is automatically generated. This takes advantage of Imgix's Image URL API which is available to all Prismic users by default.Note: Prefer using framework-specific image integrations over this component. For example, use Next.js's
next/image
component or Gatsby'sgatsby-plugin-image
component if you are using those frameworks. Only use<PrismicImage>
if your environment does not have a built-in optimized image component.Editing images with Imgix
Images can be edited through the image's URL parameters. This includes transformations like saturation, cropping, and blurring.
Arbitrary Imgix parameters can be provided using the
imgixParams
prop. See Imgix's Image URL API Reference for a full list of what's available.The
src
URL and each URL insrcset
will contain thesat: -100
URL parameter as a result:Customizing the
srcset
widthsThe widths used in the produced
srcset
can be controlled using thewidths
prop. It accepts the following values:[100, 200, 300]
)"thumbnails"
- This will use the Image field's thumbnails (also called responsive views) for each srcset value and its widths."defaults"
- Use a good set of defaults (currently[640, 750, 828, 1080, 1200, 1920, 2048, 3840]
)Using pixel density-based
srcset
sPixel density
srcset
s can also be generated in place of width-basedsrcset
s by using thepixelDensities
prop.This renders the following HTML (using placeholder values for the full image URLs).
The
pixelDensities
prop accepts the following values:[2, 4]
)"defaults"
- Use a good set of defaults (currently[1, 2, 3]
)Checklist:
🖼️🦙