Skip to content

Collection of UI components build to create a production grade front-end experience with React & Next.js

License

Notifications You must be signed in to change notification settings

storyofams/react-ui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

64 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Story of AMS

@storyofams/react-ui


A collection of UI components build to create a production grade front-end experience with react & Next.js


component description
Accordion Vertically stacked list of items that can be collapsed/expanded individually
Box The base for all components
Breadcrumb Shows the current path with the ability to navigate to each sub-path individually
Button Simple button component (see storybook for the most up to date variants)
Checkbox Checkbox with label and an optional statusmessage (optimized for usage with react-hook-form)
DatePicker Datepicker that utilizes 'react-flatpickr'
Flex Mimics a flexbox implementation
Grid Mimics a grid implementation using flexbox for compatibility reasons (with few limitations in comparison to the actual grid spec)
Heading Semantically correct headings (see storybook for all default variants)
Icon Allows for svgs to be used as icon. We also provide some default icons you can choose to import and use with the icon component (see storybook for a complete overview). *Note: please consider using something like SVGR when using your own icons
Input Input box with label and an optional statusmessage (optimized for usage with react-hook-form)
Modal Modal build with reach-dialog which uses framer-motion to ensure smooth state transition animations
Radio Radio group with labels and an optional statusmessage (optimized for usage with react-hook-form)
Select Select (created with react-select) input with label and an optional statusmessage (optimized for usage with react-hook-form)
Spinner Indicator to display a loading state
Stack Automagically creates a (horizontal or vertical) stack of items with evenly spaced
StatusMessage Displays a message in a certain colour based on the type of status (default, warning, error, success)
Tag Tag component used to create a list of toggleable tags with an optional statusmessage (optimized for usage with react-hook-form)
Text Semantically correct text blocks (see storybook for all default variants)
TextArea Text area with label and an optional statusmessage (optimized for usage with react-hook-form)
Toggle Toggle with label and an optional statusmessage (optimized for usage with react-hook-form)
  • Note: If a component does not satisfies your needs you can easily copy the contents of the components into your own project to extend / modify to fit your use-case (for other, less dramatic, customization options keep on reading πŸ˜‰)

Motivation

When the thought about creating (yet another) ui-library for react, the obvious questions were unavoidable:

  • Why?
  • Aren't there already many ui-libraries out there? What are we solving that others don't?

Yes there are already a bunch of ui-libraries but none specifically tailored to our setup which in the end resulted in a lot of repetitive work and/or tweaking or customizing the already existing libraries to the point where "building your own" becomes a viable option.

Our focus was to redo as less as possible and utilize as much as possible with battled tested libraries (preferably backed by an open source community). So we took some time to stitch everthing together to come up with a setup that enables us to get up and running quickly.

Getting started

During development of this library certain choices have been made which enforce certain constraints on the developer πŸ”’

This done in order make the experience between projects as similar as possible. Most of these constraints are considered 'best-practices' anyway so they shouldn't be surprising to deal with πŸ€“

Using typescript is highly recommended

Installation

Quickest way to get started is by running the following command:

yarn install @storyofams/react-ui

The library requires the following dependencies to be already installed:

- React (^17.0.0)
- Next.js (^10.0.0)
- styled-system (^5.1.0)
  - @styled-system/css (^5.1.0)
  - @styled-system/props (^5.1.0)
- styled-components (^5.2.0)
- @reach/alert (^0.13.0)
- @reach/checkbox (^0.13.0)
- @reach/dialog (^0.13.0)
- flatpickr (^4.6.9)
- react-flatpickr (^3.10.7)
- framer-motion (^3.10.0)
- react-id-generator (^3.0.0)
- react-select (^4.1.0)

Setup

You can get started right away by importing whichever component you fancy into your project, however to get the most optimal developer experience keep on reading!

Types

Add the following file to your project as styled.d.ts

import 'styled-components';

export interface Breakpoints extends Array<string> {
  sm?: string;
  md?: string;
  lg?: string;
  xl?: string;
}

declare module 'styled-components' {
  type Theme = typeof import('./path/to/theme-default-export.ts').default;

  export interface DefaultTheme extends Theme {
    breakpoints: Breakpoints;
  }
}

Theme

Setting up requires adding a theme that should comply with the theme definition specified here with a slight adjustment to the breakpoints. If you want to get started quickly just copy and paste the theme from the library (for the Breakpoints import see the above Types step).

Icons

We export a list of commonly used icons to get started quickly which you can view here. Besides the icons we provide you can also supply your own svg to the Icon component as a React component. This recommended way of adding icons to load them into your application is by using svgr.

Out of the box

Have a look at the latest storybook deployment to view all the components. Most likely you'll find what you need there and won't even have to look further.

Extended variants

This library is made to get up and running fast which means we're providing variants we think that are useful that work for most use-cases. There will however always be projects that require new variants or slight adjustments on the already existing variants. To allow for this we're exporting a function called styled. This function is a wrapper on top of styled-components that pretty much works like the styled function created by stitches.

example:

import { Button, styled } from '@storyofams/react-ui';

// Button has the following variants by default:
// - variant (primary, secondary, link, underline)
// - buttonSize (small, medium, large)

const ExtendedButton = styled(Button, {
  variants: {
    newVariant: {
      primary: {
        fontSize: 21,
        '&:hover': {
          backgroundColor: 'primary100',
        },
      },
    },
    buttonSize: {
      'medium-screen-xl': {
        fontSize: 2.2,
        lineHeight: 'medium',
      },
    },
    variant: {
      icon: {
        fontSize: 14,
        borderRadius: 9999,
      },
    },
  },
});

export const Extended = () => (
  <>
    <ExtendedButton variant="primary">button</ExtendedButton>
    <ExtendedButton variant="icon" newVariant="primary">
      button
    </ExtendedButton>
    <ExtendedButton
      variant="icon"
      buttonSize={['large', 'medium', 'medium-screen-xl']}
    >
      button
    </ExtendedButton>
  </>
);

Css

Thanks to styled-system we get access to a css function. This css function can be used when you don't quite want to wrap a whole new styled-component, but you do need some specific css selectors to make it look pretty πŸ₯°

To utilize the full potential of typescript we've re-exported the css function for you but added some autocomplete for values that live in your theme.

comparison:

import { css } from '@styled-system/css'

<Component
  css={css({
    backgroundColor: 'red' // autocompleted
    backgroundColor: 'primary500' // not-autocompleted
  })}
/>

VS

import { css } from '@storyofams/react-ui'

<Component
  css={css({
    backgroundColor: 'red' // autocompleted
    backgroundColor: 'primary500' // autocompleted
  })}
/>

Adding custom props

For those components that just require extra customization or that really can't do without those few extra lines of css you can extend systemprops.

example:

import styled from 'styled-components';

import { Box, SystemProps } from '@storyofams/react-ui';

type CustomBoxProps = SystemProps & {
  /** add any CustomBoxProps here */
  customProp: string;
}

const CustomBox = styled(Box)<CustomBoxProps>`
  // very specific styling that cannot be applied through either;
  // * props
  // * cssProp
`;

export const CustomComponent = (({ customProp, ...rest}): CustomBoxProps) => {
  return (
    <CustomBox {...rest}>
      {/** ... */}
    </CustomBox>
  )
};

Gotchas

Following are some things to take note of when using the library.

I'm not using next.js, why do I need to install next.js?

Every project is different, we've found that next.js offers us a rich environment to get up and running fast for small to huge applications. Having that said, using react-ui is not completely depended on Next.js, with the only exception being the button component. This component can act as a link between content for your application and uses the next link since that's what we use most. We are looking into the possibilities to allow to provide a custom Link component to the button.

I'm seeing a lot of properties on the dom but no actual styling is applied?

This is a know issue when using a component that uses a forwardingRef. Our current setup requires the as prop to enable autocomplete on certain HTML properties, since that components accepts an as property but is also forwarding a ref to another styled-component (which again accepts as) you'll need to forward the as. We're looking into the misconfiguration that is happening between those properties and why it's causing the properties to be passed to the dom rather than being used for styling.

Some things do not have color am I going colourblind?

Most likely a theme variable we're using isn't covered in your theme. Don't worry you can style those all individually as component props. If you do find a color that's playing nice please let us know by filing an issue

Props are not autocompleting with values from my theme

Make sure to go through the setup section of this readme. If the problem persists check if your implementation differs from the one in the /example folder. If all of the above fails let us know by filing an issue

Acknowledgements

When creating this library we couldn't have done it without the following pioneers.

styled-components

This library has really been on the forefront of developing react applications that are easily styled since the early days. It has served us very well over the course of the years and it will be hard to part ways if there ever comes a time where on of the other solutions in this space takes over.

You're probably already familiar with styled-component but be sure to give them some love πŸ’œ

styled-system

This library, but more specifically Brent Jackson has really shaped up how we look to design systems. The foundation he has created with styled-system is really the dream of every developer.

Not sure what happened but the repo's have stayed unmaintained / unchanged for a while now. So we are using styled-system and the complimentary packages props and css to create the best DX we could come up with.

Huge shout out to this library and it's author for paving the way that enabled us to do this πŸ’―

system-props

This library is a more recent addition to the stack, but caught our eye because the shared philosophy that builds on styled-system and even includes some extensive pseudo elements as props (based on the chakra-ui implementation).

reach-ui

Another library that has been there for a while is reach-ui. This library gives you the building blocks to build, the hard to get right, react components with a great attention to accessibility πŸ•΅οΈβ€β™‚οΈ

This has been our go to when it comes to implementing those impossible components, with great success and most importantly ease of use.

Modulz / Radix / Stitches

If you are not aware of these guys already I highly recommend checking out both radix and modulz. They have been a great source of inspiration for some aspects of this UI-library. We feel like they are the breath of fresh air this section of industry is really urging for. Stitches is highly innovative taking modern css capabilities to the css-in-js that we've all gotten to love. Radix is just a work of love, a product of hard work and dedication, to make the web more accessible to everyone πŸ₯°

Having that said we also feel like it is still too early to convert our entire codebase. We are however keeping a close eye on what they are up to and will most likely jump on the wagon as soon as we feel it's matured enough to be steadily used in production grade font-end applications.