Workday / canvas-kit

Development kits to implement UI following the Workday Canvas Design System (https://canvas.workday.com/). See our Component Storybook -
https://workday.github.io/canvas-kit/
Apache License 2.0
301 stars 221 forks source link

feat: Create new Graphic component #3049

Open alanbsmith opened 3 days ago

alanbsmith commented 3 days ago

🚀 Feature Proposal

Create a new Graphic component that pulls SVGs from a URL instead of injecting the graphic as inner HTML within the component.

Motivation

  1. Allow our consumers to pull assets from a CDN instead of our graphics package
  2. Assets can be cached by the browser and are only pulled in on request instead of bloating their app bundle
  3. Move away from using __dangerouslySetInnerHTML
  4. Opens the option to easily support PNGs

We could also refactor the existing Graphic component, but I think it's a better idea to add this to canvas-kit-preview-react and allow consumers to adjust over time. Adding a new component would also allow us to roll this out to teams sooner.

Example

The API could look something like this:

<Graphic imageName="empty-state-critical" />

🗒️ We would still need to figure out how to elegantly handle setting the base URL for various consumers and environments.

Under the hood, we would use set the imageName as a CSS var in our stencil and pass it along to the backgroundImage.

base: ({ imageName }) => ({
  backgroundImage: `${baseUrl}/${imageName}.svg`,
})

🤔 Maybe there should be a warning if the image is not found or is invalid?

Open to discussion on this. 😄

vibdev commented 3 days ago

We would still need to figure out how to elegantly handle setting the base URL for various consumers and environments

If we assumed the base URL was always the same it could go in the CKR provider.


One downside with background images is you don't get the same callbacks you get with <img> tag. e.g. onerror and onload

alanbsmith commented 3 days ago

@vibdev Yeah, it could be an img tag and use src instead. 🤔

vibdev commented 20 hours ago

Is there any desire to make it a <Picture /> element so we could serve different graphics depending on media queries?

Also one other thought is, this might be a really good use case for web components, there is no reactivity so might fit.