Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

RFC: Version 1 #149

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open

RFC: Version 1 #149

wants to merge 46 commits into from

Conversation

joe-bell
Copy link
Owner

@joe-bell joe-bell commented Feb 18, 2021

⚠️ Please note: V1 is still a work in progress and prone to bugs/sudden API changes.

RFC: Version 1

TL;DR

  • raam V1 introduces a new "mixins" API to roll-your-own layout primitives.
  • Support most CSS-in-JS libraries and theoretically beyond React.js (testing in progress)
  • 78% smaller bundle size (minified):
    • minified: from 22.3kB to 4.8kB (78% smaller)
    • gzipped: from 7.4kB to 1.8kB (75% smaller)
  • Previous components have been deprecated, but guides will be provided to migrate.

See the updated docs for further usage guidelines

Problem

  • Tied to Theme UI (and React.js)

    Initially, raam was built to meet my own use-case for needing layout primitives across multiple Theme UI projects. Given that there are many options to choose from in the CSS-in-JS world, it would be foolish not to support others.

  • Large bundle size

    Relying heavily on third-party libraries makes for a rather large bundle size:

    • minified: 22.3kB
    • gzipped: 7.4kB
  • Lack of extensibility

    raam's layout components make the assumption that you want each item to be wrapped with styles, rather than combined with the item's styles.

    Although this approach works well to separate concerns, it makes use-case changes to individual items (such as flex, or flexGrow) difficult/near impossible.

  • Implementation isn't clear

    • At the end of the day, it's essentially just a collection of flex-based layouts

Solution

A complete refactor and separation of concerns

  • raam (mixins)

    Introduces a new 'Mixins' API to support (and encourage) rolling-your-own layout primitives, starting with flexbox()

    Previous layouts such as 'inline' and 'wrap' are accessible via the variant option: flexbox({ variant: "wrap" }).

    See the updated docs for usage guidelines.

    Under-the-hood, raam replaces gap with a set of custom properties to control parent and child margins. These are toggled off (back to initial) depending on the requirements of specific flex properties; a technique heavily inspired by David Khourshid's "prop-and-lock" technique.

    e.g. when flexWrap is nowrap (for 'stack'-based layouts) the negative offset margin on the flex parent is toggled off.

  • @raam/stitches - util along with variants to spin up your own Flex primitives

  • @raam/tailwind - plugin to replace existing flex styles and support flex-gap

Benefits

Removing components and self-composing the core functionality drastically improves raam's bundle size:

  • minified: from 22.3kB to 4.8kB (78% smaller)
  • gzipped: from 7.4kB to 1.8kB (75% smaller)

More importantly, this new architecture makes it a lot easier to maintain; especially around inheriting responsive styles a ton easier.

Caveats

  • "Why not just use :first-child?"

    Some CSS-in-JS SSR techniques rely on injecting inline <style> components which alter the DOM order. Using :first-child would cause these to gain a margin. Manually defining index is a bit of a pain, but it makes it ensures stability.

  • Combining child and parent causes conflicting styles

  • CSS Custom Properties need thorough testing with various libraries before release.

Future

I'm still keen to implement rowGap and columnGap options, and I hope this PR makes it a little easier to add in later.

Another idea is to distribute plain CSS versions of raam's primitives, along with a PostCSS plugin

Todo

  • Initial project architecture
  • Migrate flex-gap system to bespoke CSS custom property setup
  • Responsive style props
  • Responsive variants
  • Extend and re-implement types
    • External gap prop (should support number)
    • Internal flexGap prop
    • CSS output (help needed and appreciated) should support major libraries/React.js style attribute
  • Extend and update docs
    • Add mixins with props table
    • Add recipes (for users to build their own layout primitives)
  • Extend and update tests
    • Figure out why I can't run tests in raam from src. Maybe babel?
  • Deprecate components and provide documentation
  • Add @raam/stitches
    • Docs
    • Tests
  • Add @raam/tailwind
    • Docs
    • Tests
    • Potentially extract some functionality to @raam/core
  • Organise CSS output (vars, then properties, then media queries)
  • Final cleanup/optimisations/design

@vercel
Copy link

vercel bot commented Feb 18, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/joebell/raam/Eqv4zRwRt1eCR4mqX3eSPQNzh9MY
✅ Preview: https://raam-git-rfc-v1-joebell.vercel.app

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant