truss icon indicating copy to clipboard operation
truss copied to clipboard

feat: Proof of concept non-component-based css prop.

Open stephenh opened this issue 3 years ago • 1 comments

This is a spike related to https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b and specifically re "can we get rid of the wrapping EmotionCssPropInternal components" that currently are required anytime a css= prop is used.

See https://github.com/reactwg/react-18/discussions/110 but it would be great if React had a non-hook way of subscribing to useInsertionEffect events, like document.addEventElement('insertionEffect", () => ...).

Misc ideas:

  1. Just try stock fela & FelaComponent, to see perf vs. emotion
    • Would still have wrapper components in the React tree, but just curious
  2. Call the fela renderer directly inline in __jsxDEV (no FelaComponent) and :shrug: if the performance of "not using useInsertionEffect really matters
    • I.e. styles would be injected ~randomly after each render and not necessarily at "safe insertion points", which would cause more DOM/CSS recalcs per the React-18 link
    • Complain to react about the lack of a global insertionEffect event/hook
  3. Output any non-selector styles directly to the style attribute, and skip class names all together (recommended in the react-18 doc as what FB does, but technically only for dynamic styles)
    • Output any selector-based styles via Emotion/Fela as usual
  4. Use already-injected awareness to only conditionally wrap in a FelaComponent, otherwise use the existing/injected classes directly on className (no FelaComponent)

stephenh avatar Nov 09 '22 15:11 stephenh

Another idea for component-less usage:

export function FooComponent() {
  const css = useTruss();

  return <div className={css.mt2.mb3.$} />;
}
  • Pro: "Fine, fine" uses a hook to get css, which will play nicer with React 18's useInsertionEffect hook
    • See the useCSS example from the reactwg link in the PR description
    • Granted, Emotion's css= prop already does this for us: https://github.com/emotion-js/emotion/blob/acb72a45592881d9d1f72003b6db2e488b981599/packages/react/src/emotion-element.js#L61
  • Con: Burns a LOC in basically every component
  • Pro: Uses just className so doesn't need the css=... JSX wrapper
    • This removes the jsxImportSource / jsxFactory build config from vite/storybook/etc (which we have working now, but can be flakey when upgrading/changing configs)
    • This also removes the EmotionalInternalCss wrapper component that Emotion's css= prop is forced to inject for it to add its own hooks to resolve emotion from a context

stephenh avatar Jan 18 '23 22:01 stephenh