-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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(astro): add Built-in SVG component support #12067
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 5f8997c The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
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.
This PR is blocked because it contains a major
changeset. A reviewer will merge this at the next release if approved.
934d200
to
5a7b888
Compare
12cd643
to
2ff0715
Compare
2ff0715
to
5f8997c
Compare
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.
Left a few suggestions, but this looks really good!
/** | ||
* Bypasses automatic sprite optimization by directly inlinining the SVG | ||
*/ | ||
inline?: boolean |
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.
After sitting with this for a while, inline behavior should be the default. There are a few edge-cases that have come up with dynamic client-side behavior in astro-icon
, so while I still think the optimization is very useful, we should prioritize flexibility by keeping the sprite behavior opt-in.
Object.defineProperty(Component, Symbol.for('nodejs.util.inspect.custom'), { | ||
value: (_: any, opts: any, inspect: any) => inspect(meta, opts), | ||
}); |
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.
Not sure how necessary this is, but maintaining the current console.log
behavior seems like a good idea.
A comment here explaining why we're doing this would be helpful 👍
// Attach file data for SVGs | ||
if (fileMetadata.format === 'svg') { | ||
emittedImage.contents = fileData; | ||
} |
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.
Would love @Princesseuh's take on this. Any expected footguns with including the file content for SVGs in the image metadata?
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.
If you have a lot of SVGs, this can be problematic for SSR since it'll get in your bundle, that's my only concerns
if (size) { | ||
props.height = size; | ||
props.width = size; | ||
} |
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.
Looks like size
will override width
and height
attributes if present. I think size
should only apply when they are undefined
.
it('has height and width overridden - size set', () => { | ||
let $svg = $('#override-attrs svg'); | ||
assert.equal($svg.length, 1); | ||
assert.equal($svg.attr('height'), '16'); | ||
assert.equal($svg.attr('width'), '16'); | ||
assert.equal(!!$svg.attr('size'), false); | ||
}); |
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.
This test will need updating if the size
behavior switches
assert.equal(!!$svg.attr('version'), false); | ||
}); | ||
}); | ||
describe('additional props', () => { |
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.
Would be nice to assert that the default role="img"
is overwritable. Now that I think of it, we should also double check that role="img"
is the best default since I know aria-hidden
and role="presentation"
are also used sometimes.
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.
😩 this is the old logo
@@ -0,0 +1,54 @@ | |||
import { parse, renderSync } from 'ultrahtml'; |
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.
Just a callout that I maintain ultrahtml
—this could easily be swapped for another XML parser if preferred, but keep in mind that it will be bundled into the server runtime so we should try to keep a light footprint.
@@ -1,6 +1,7 @@ | |||
/// <reference types="vite/types/import-meta.d.ts" /> | |||
/// <reference path="./types/content.d.ts" /> | |||
/// <reference path="./types/actions.d.ts" /> | |||
/// <reference path="./jsx-runtime.d.ts" /> |
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.
This shouldn't be needed, was there something you were encountering?
// Attach file data for SVGs | ||
if (fileMetadata.format === 'svg') { | ||
emittedImage.contents = fileData; | ||
} |
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.
If you have a lot of SVGs, this can be problematic for SSR since it'll get in your bundle, that's my only concerns
Changes
This PR implements Built-in SVG Components following up on the discussions on withastro/roadmap#699
By default, SVG files will be components and can be imported by referencing their file path and then treating them like a component. Take this for example:
previously:
now:
GOALS:
This builds a foundation for us which can be extended in the future within the core astro and even by third-parties. For instance using
astro-icon
, which has been the critical plugin when it comes to icons, as a playground, I was able to extend the foundation built here to add dynamic icon import for Iconify.FUTURE:
/cc @natemoo-re
Testing
I have ensured that existing tests are functioning properly and added additional suite for SVG Components.
Manually, I have updated the blog example to include using the SVG components. I have also tested locally against
astro-icon
and its demo application. Will work on some testing for this change.Docs
This will definitely need documentation added to it. Will need some assistance in writing it.
/cc @withastro/maintainers-docs for feedback!