-
Notifications
You must be signed in to change notification settings - Fork 3
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
[Theming] Overhaul Icon Generation #529
Conversation
…dd test suite for new icons setup
"rules": { | ||
"no-alert": "off" | ||
"prettier/prettier": "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.
The index.tsx
file generated by @svgr/cli
lacks a newline. Without this, the respective files will always appear to have been modified, which is annoying. 🙃
@@ -60,6 +52,7 @@ export default [ | |||
'@emotion/styled': 'styled', | |||
'@emotion/styled-base': '_styled', | |||
'@react-aria/focus': '@react-aria/focus', | |||
'emotion-theming': 'emotionTheming', |
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.
Fixes build
warning.
@@ -59,9 +59,20 @@ exports[`<Tooltip /> UI snapshot renders content and children 1`] = ` | |||
margin-left: -10px; | |||
} | |||
|
|||
.emotion-4 { |
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 application of emotion-4
on the svg
in the snapshot indicates there's no regression with the behavior we were achieving with the custom @svgr
template, that put the css
prop directly on the <svg>
element.
.size-snapshot.json
Outdated
"bundled": 823371, | ||
"minified": 754553, | ||
"gzipped": 91244 | ||
"bundled": 820258, |
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 shakes up the dist
build artifact since the icons included in Component logic now reside in dist/bundle-es/icons/icons
instead of dist/bundle-es/svgs
, so the file ordering got jumbled around and it's hard to track changes. It's always nice to see a smaller bundle, though 🥳
import { AnxiousEmoji } from './svgs'; | ||
import { useIcon, IconProps } from '../../shared-components/icon'; | ||
|
||
export default (props: IconProps) => useIcon(AnxiousEmoji, AnxiousEmoji, 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.
The default behavior of create-index
is to generate an index.ts
file comprising default
exports renamed as their "safe" named export value. It automatically picks up that this should be export { default as AnxiousEmoji }
from the filename.
There's good React reasons to not use anonymous default exports--the component shows up as Anonymous
in the Component tree in dev tools--but since the underlying components in useIcon
will be named (by @svgr/webpack
), this seemed a fine trade-off to make for maintaining compatibility with create-index
.
Moreover, anonymous default exports reduces auto-import name-spacing noise a bit. (Currently if you add AnxiousEmoji
in a file, the auto-import will suggests both ../../src/icons
and ../../src/icons/emojis
as relative imports, and TypeScript definitions work best with relative imports.)
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 good, I like this solution, I like how you got rid of all those confusing ast templates.
Left 1 comment regarding @svgr/webpack
and I guess I have more cleanups comments for future PRs:
- we have 3 babel configs: I guess we can remove the
babel.config
at root since it was used bysvgr/webpack
the other 2 are for build and storybook, wonder if we can combine those somehow - With this PR I think we reached 100% TS coversion. -> we can remove rules extensions that have
js
in many configs I also saw amd
somewhere
…onfig, update eslint rule for import extensions
Simplified the storybook config and removed the |
This PR does not require urgent review. The diff is large primarily because we're committing more build artifacts in order to better track changes and modifications.
Background
radiance-ui
currently leverages the CLI provided by SVGR to generate all of our icons (as React components) at build time, placed inradiance-ui/lib/icons
, using raw svg files and a custom transform template, with the output looking like this:This setup has worked great for us--adding new icons has been as simple as dropping new SVGs in a folder and letting our build setup handle generating the React component and exporting it from the appropriate directory.
However, this setup does not work with our new theming requirements, where the "themeable" icons may be wholesale swapped out for a distinctly different SVGs. By way of visual example, the
Arrow
andChevronIcon
examples in the screenshots below show totally different icons, made possible by the configuration in this PR.In order to support this behavior (with the bonus of adding type-safety) we're removing the scaffolding around the SVGR CLI in favor of using the built-in defaults. The CLI requires one file at a time for its transform, so we cannot pass it two files and conditionally return the SVG we want based on props. The setup in this PR prefers straightforwardness, even if it is a bit more manual.
Alternatives
Alternatives to the work in this PR included:
babel
reliance.lib
folder usingbabel
directly, but there doesn't currently exist an@svgr
plugin for this. Airbnb has a plugin that transformssvg
imports to directly in-lined code, but it felt incorrect to use a separatebabel
plugin when we rely on@svgr
forrollup
andwebpack
compatibility.@svgr/cli
transform template, means we could slip inuseTheme
logic. However, that would seem to increase the maintenance burden for all parts touched (svg markup,@svgr
usage, etc.) to support separate themes within a single SVG file.This PR does all the manual work of re-configuring the setup with the aim of keeping our setup of adding new SVGs relatively simple, and making sure it is not error-prone.
Adding a new SVG
There are two new considerations for when adding an SVG.
1. Is the SVG new and without a themed counterpart? If so, add the
.svg
file in the appropriate directory insrc/svgs
, generate the component icon (viayarn run build:icons:all
), and then create a complementary TypeScript file that imports it directly and passes it intouseIcon
.2. Is the SVG a themed counterpart to an existing SVG? If so, add the
.svg
as a sibling file insrc/svgs
, and append the icon filenames with-primary
and-secondary
, respectively. Run the same build step and update the exported icon file (with theming logic) to import both the Primary and Secondary icons:Ideally, committing more of these built files gives us a better understanding of how this repo works. I think it would be nice to include more automatic handling, but as it is I've invested a bit too much time into this, and I don't know how important optimizing our icon build workflow actually is, since they do not change very often.
CHANGELOG
src/
andstories/
icon imports updated to use React components with conditional rendering logic, so that when we switch the theme context the icons reflect the changes. (This was not possible with direct.svg
imports.)src/utils/icons
andsrc/utils/svgToIconTemplate
in favor ofsrc/shared-components/icon
and SVGR config options.src/svgs/deprecated
(none were in use).SVGR
packagesTODOs
create-index
: PR is ready to be merged in following approval of this PR: Add TypeScript/index.ts compatibility create-index#1