segmentio / ui-box

Blazing Fast React UI Primitive
MIT License
1.07k stars 54 forks source link

Generated class name should include hashed selector for uniqueness #126

Closed brandongregoryscott closed 1 year ago

brandongregoryscott commented 1 year ago

Currently, the class name that gets generated is hashed by the value of the key when a selector is provided. However, this can lead to unintended leaking of styles, which I discovered while testing https://github.com/segmentio/evergreen/pull/1554

Take a small example:

<Box
  is="input"
  width={100}
  height={100}
  backgroundColor="yellow"
  selectors={{ "&:disabled": { backgroundColor: "red" } }}
/>
<Box
  width={100}
  height={100}
  backgroundColor="blue"
  selectors={{
    "&:hover": {
      backgroundColor: "red"
    }
  }}
/>

Box 1 should only have a red background when it is disabled.

Box 2 should only have a red background when it is hovered (which works).

However, because we are only hashing the value of the styles inside, i.e. red -> 169mlyl, both of the boxes get the same class name ub-bg-clr_169mlyl.

<input class="ub-w_100px ub-h_100px ub-bg-clr_yellow ub-bg-clr_169mlyl ub-box-szg_border-box">
<div class="ub-w_100px ub-h_100px ub-bg-clr_blue ub-bg-clr_169mlyl ub-box-szg_border-box"></div>

The class name that is added to the stylesheet with the selector appended looks like this: .ub-bg-clr_169mlyl:hover, which means any element with ub-bg-clr_169mlyl will receive a red background on hover.

This simple example can be demoed in this CodeSandbox: https://codesandbox.io/s/ui-box-selector-uniqueness-bug-n7i3sj

Additionally, this behavior can be observed in the deployment preview of that Evergreen PR