ricokahler / hacker-ui

A design system for the modern developer. (development on hiatus)
https://hacker-ui.com/
MIT License
241 stars 10 forks source link

CSS-in-JS audit #9

Closed ricokahler closed 4 years ago

ricokahler commented 4 years ago

The first set of contributions I'm looking for is actually in the form of code review. I wrote a lot of this code myself and it would be nice to have others:

  1. read it and give feedback on both the idea of what the code is trying to accomplish and then also (does it solve the right problem?)
  2. read and review the actual implementation. (does it work as intended?)

This issue is also the first set of "audit" issues I'm opening up. The idea behind the "audit" label is that it's a call out to community experts to openly review some part of Hacker UI.


Does it solve the right problem?

In case you didn't catch it, Hacker UI ships its own CSS-in-JS solution. The reason Hacker UI ships with its own CSS-in-JS system is because I had certain requirements and I couldn't find a CSS-in-JS solution that met all of these.

Wish list/requirements

1. Purely component based styles

The way you write css with styled-components or emotion is not really scoped to a component per-se. When you write styles with these tools, you write a style for an element but that's not really the relationship I'm going for.

The purpose of declaring the styles with createStyles in one section is that this section will have specific variables related to the component. In other words, createStyles creates a scope for you to define styles that pull in data specific to the component you're writing styles for.

2. Composable set of styles as part of the component's API

If you're familiar with Material-UI, they allow you to style any sub-element in the component using the classes prop. I like this a lot because it expands what a component can do without expanding its API footprint and this eliminates the need for having props for styling (e.g. bold, noMargin, etc).

3. Embrace HTML semantics and classNames

Another thing I'm somewhat passionate about is using semantic HTML elements. When you use a syntax like const Title = styled.div, when you go to use the Title component, you almost forget that it was a div. To me it's important to remember what HTML element you're using and having it up front with a style matches that philosophy.

4. The ability to be define the color of a component dynamically, including derived states

This is kind of a big one for me. I find that defining colors of a component adds a significant amount of complexity and duplication because colors adds another dimension of styling required.

E.g. for every button, you have to create 3 extra classes, one for the primary, secondary, and tertiary color, and within each of those classes, you have to create derived colors for hover, focus, and action states.

If your set of colors is small, it's possible to handle this but then throw in "dark mode" as a requirement and everything just gets out of hand.

So to get the point, the wish list item for this define a way write styles as a function that takes in two colors, the desired color and the surface color (mostly white or black), and output styles. This will make it easy to support dark mode for every color.

Conceptually, you can think of it like this:

const myButtonStyle = (desiredColor, surfaceColor) => css`
  color: ${readableColorOnSurface(desiredColor, surfaceColor)};
  background-color: ${desiredColor};
`;

5. The ability to work in any react environment without the need for a special compiler step or pragma

Hacker UI should just work. If there are significant benefits in having the user install a babel plugin then I'll consider it but ideally and by philosophy, Hacker UI should be ready out of the box and work in any React environment.


Anyway, given all these requirements, I made sense to me to attempt another CSS-in-JS solution 🤷‍♀️

The current solution

WIP

Does it work as intended?

ricokahler commented 4 years ago

oops, held cmd while pressing enter, still editing…