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

fix: updates <Picture /> to pass HTML attributes down to the <img /> element #5038

Merged
merged 8 commits into from
Oct 20, 2022
Merged
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
11 changes: 11 additions & 0 deletions .changeset/wicked-laws-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@astrojs/image': minor
---

HTML attributes included on the `<Picture />` component are now passed down to the underlying `<img />` element.

**Why?**

- when styling a `<picture>` the `class` and `style` attributes belong on the `<img>` itself
- `<picture>` elements [should not](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture#attributes) actually provide any `aria-` attributes
- `width` and `height` can be added to the `<img>` to help prevent layout shift
4 changes: 4 additions & 0 deletions packages/integrations/image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ Position of the crop when fit is `cover` or `contain`.

### `<Picture />`

The built-in `<Picture />` component is used to create an optimized `<picture />` for both remote images hosted on other domains as well as local images imported from your project's `src` directory.

In addition to the component-specific properties, any valid HTML attribute for the `<img />` included in the `<Picture />` component will be included in the built `<img />`.

#### src

<p>
Expand Down
4 changes: 2 additions & 2 deletions packages/integrations/image/components/Picture.astro
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ delete image.width;
delete image.height;
---

<picture {...attrs}>
<picture>
{sources.map((attrs) => <source {...attrs} {sizes} />)}
<img {...image} {loading} {decoding} {alt} />
<img {...image} {loading} {decoding} {alt} {...attrs} />
</picture>

<style>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Picture } from '@astrojs/image/components';
<Picture id='inline' src={import('../assets/social.jpg')} sizes="(min-width: 640px) 50vw, 100vw" widths={[253, 506]} alt="Inline social image" />
<br />
<Picture id="bg-color" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" sizes="(min-width: 640px) 50vw, 100vw" widths={[272, 544]} aspectRatio={544/184} alt="Google logo" background="rgb(51, 51, 51)" formats={['avif', 'jpeg']} />
<br />
<br />
<Picture id="ipsum" src="https://dummyimage.com/200x300" sizes="100vw" widths={[100, 200]} aspectRatio={2/3} formats={["avif", "webp", "jpg"]} alt="ipsum" />
<br />
<Picture id="query" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png?token=abc" sizes="100vw" widths={[544]} aspectRatio={544/184} alt="query" />
Expand Down
28 changes: 16 additions & 12 deletions packages/integrations/image/test/picture-ssg.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ describe('SSG pictures - dev', function () {
},
].forEach(({ title, id, url, query, alt }) => {
it(title, () => {
const sources = $(`${id} source`);
expect(sources.length).to.equal(3);
const image = $(`${id}`);
const picture = image.closest('picture');

const image = $(`${id} img`);
const sources = picture.children('source');
expect(sources.length).to.equal(3);

const src = image.attr('src');
const [route, params] = src.split('?');
Expand Down Expand Up @@ -158,10 +159,11 @@ describe('SSG pictures with subpath - dev', function () {
},
].forEach(({ title, id, url, query, alt }) => {
it(title, () => {
const sources = $(`${id} source`);
expect(sources.length).to.equal(3);
const image = $(`${id}`);
const picture = image.closest('picture');

const image = $(`${id} img`);
const sources = picture.children('source');
expect(sources.length).to.equal(3);

const src = image.attr('src');
const [route, params] = src.split('?');
Expand Down Expand Up @@ -250,10 +252,11 @@ describe('SSG pictures - build', function () {
},
].forEach(({ title, id, regex, size, alt }) => {
it(title, () => {
const sources = $(`${id} source`);
expect(sources.length).to.equal(3);
const image = $(`${id}`);
const picture = image.closest('picture');

const image = $(`${id} img`);
const sources = picture.children('source');
expect(sources.length).to.equal(3);

expect(image.attr('src')).to.match(regex);
expect(image.attr('alt')).to.equal(alt);
Expand Down Expand Up @@ -349,10 +352,11 @@ describe('SSG pictures with subpath - build', function () {
},
].forEach(({ title, id, regex, size, alt }) => {
it(title, () => {
const sources = $(`${id} source`);
expect(sources.length).to.equal(3);
const image = $(`${id}`);
const picture = image.closest('picture');

const image = $(`${id} img`);
const sources = picture.children('source');
expect(sources.length).to.equal(3);

expect(image.attr('src')).to.match(regex);
expect(image.attr('alt')).to.equal(alt);
Expand Down
12 changes: 6 additions & 6 deletions packages/integrations/image/test/picture-ssr-build.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ describe('SSR pictures - build', function () {
const html = await response.text();
const $ = cheerio.load(html);

const sources = $(`${id} source`);
const image = $(`${id}`);
const picture = image.closest('picture');

const sources = picture.children('source');
expect(sources.length).to.equal(3);

const image = $(`${id} img`);

const src = image.attr('src');
const [route, params] = src.split('?');

Expand Down Expand Up @@ -200,12 +200,12 @@ describe('SSR pictures with subpath - build', function () {
const html = await response.text();
const $ = cheerio.load(html);

const sources = $(`${id} source`);
const image = $(`${id}`);
const picture = image.closest('picture');

const sources = picture.children('source');
expect(sources.length).to.equal(3);

const image = $(`${id} img`);

const src = image.attr('src');
const [route, params] = src.split('?');

Expand Down
12 changes: 6 additions & 6 deletions packages/integrations/image/test/picture-ssr-dev.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ describe('SSR pictures - dev', function () {
},
].forEach(({ title, id, url, query, alt, contentType }) => {
it(title, async () => {
const sources = $(`${id} source`);
const image = $(`${id}`);
const picture = image.closest('picture');

const sources = picture.children('source');
expect(sources.length).to.equal(3);

const image = $(`${id} img`);

const src = image.attr('src');
const [route, params] = src.split('?');

Expand Down Expand Up @@ -220,12 +220,12 @@ describe('SSR pictures with subpath - dev', function () {
},
].forEach(({ title, id, url, query, alt, contentType }) => {
it(title, async () => {
const sources = $(`${id} source`);
const image = $(`${id}`);
const picture = image.closest('picture');

const sources = picture.children('source');
expect(sources.length).to.equal(3);

const image = $(`${id} img`);

const src = image.attr('src');
const [route, params] = src.split('?');

Expand Down