Giter Club home page Giter Club logo

chroma-react's Introduction

Chroma React

Chroma logo


Chroma is an open source design system from the team at LifeOmic. It is built with React and TypeScript. The goal of Chroma is to provide design-approved components to developers to speed up their development process and build visual consistency throughout web applications.

View our Storybook

Usage

To get started with Chroma, follow these steps:

  1. Install dependencies

    yarn add @lifeomic/chroma-react @material-ui/styles react-router-dom

    Chroma leverages @material-ui/styles for CSS-in-JS and react-router-dom for link-related components.

  2. Wrap your application with the StyledEngineProvider and ThemeProvider provided by Chroma.

    import {
      StyledEngineProvider,
      ThemeProvider,
    } from '@lifeomic/chroma-react/styles';
    
    function App({ children }) {
      return (
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>{children}</ThemeProvider>
        </StyledEngineProvider>
      );
    }
  3. Start using components!

    import { Button } from '@lifeomic/chroma-react/components/Button';
    
    <Button variant="contained">Button</Button>;
  4. Add jest config (optional)

    To include the jest configuration setup, add the following:

    setupFilesAfterEnv: ['@lifeomic/chroma-react/jest'];

    Note: Some components may require support for CSS imports (e.g. import 'some-module/styles.css). All major bundlers can support this behavior (example: webpack's css-loader).

Theming

Want to override the default theme of Chroma? No problem!

  1. Create your component-level overrides and palette overrides. Chroma leverages Material-UI's global theme variation to override specific component styles.

    // theme.ts
    import {
      createPalette,
      createTheme,
      Theme,
    } from '@lifeomic/chroma-react/styles';
    import { Overrides } from '@lifeomic/chroma-react/styles/overrides';
    
    // The overrides specified here will be *global* component overrides!
    export const overrides = (theme: Theme): Overrides => ({
      ChromButton: {
        root: {
          background: 'red',
        },
        outlined: {
          border: '1px solid red',
        },
      },
    });
    
    export const palette = createPalette({
      primary: {
        main: '#02bff1',
      },
    });
    
    export const theme = createTheme({
      overrides,
      palette,
    });
  2. Update your theme provider.

    import { ThemeProvider } from '@lifeomic/chroma-react/styles';
    import { theme } from './theme';
    
    function App({ children }) {
      return (
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>{children}</ThemeProvider>
        </StyledEngineProvider>
      );
    }

Importing Component Styles Only?

Need to build a custom component, but want to use the styles hook of an existing Chroma component?

import { useStyles } from '@lifeomic/chroma-react/components/Button/Button';

const CustomButton = ({}) => {
  const classes = useStyles({});
  return <button className={classes.root}>Custom Button</button>;
};

Development

Getting Started

First you'll need to install the dependencies for the repository.

yarn

Running Storybook

To run the Storybook for Chroma, run the following command.

yarn start

After some time, the Storybook will open. Any local changes made will be reflected in Storybook.

Build

To run the build for the repository, run the following command.

yarn build

This will generate an output in the dist/ directory.

Linking

Yarn

Sometimes linking your local changes is helpful when developing new features or bug fixes. To do so, run the following commands.

yarn build # Run a build so your changes are included
cd dist # You must link from the `dist` directory; otherwise, this will not work
yarn link

Now you can navigate to your application and run the following command.

yarn link @lifeomic/chroma-react

After running the above command, your local version of Chroma is now linked and all changes locally should reflect in your application.

Yalc

yarn link not working? You may want to try yalc.

First you need to global install yalc with: yarn global add yalc.

In your local version of Chroma:

yarn build # Run a build so your changes are included
cd dist # You must link from the `dist` directory; otherwise, this will not work
yalc publish

In your application, run the following:

yalc add @lifeomic/[email protected]
yarn install
yarn start

At the time of this writing, yalc update was not working properly so anytime you make changes in Chroma (after already linking) you'll need to repeat the steps above.

chroma-react's People

Contributors

alexccl avatar chloecourt avatar dependabot[bot] avatar dexterca avatar haleywardo avatar indigocarmen avatar jhbeard avatar jkdowdle avatar joedimarzio avatar jsking216 avatar keeslinp avatar loscm avatar macnaughton avatar markdlv avatar mattalco avatar mmfane avatar mstagg avatar nicolls1 avatar playdohdoh avatar shawnzhu avatar sternetj avatar swain avatar travomic avatar ynotdraw avatar zhengkyl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chroma-react's Issues

Perf: Replace Tooltip library with something that doesn't create an empty portal

This is similar to #36, but specific for the <Tooltip component. Even when the tooltip is not visible, a portal is still put in the DOM. If a page has a table with many actions, there may be 30+ portals due to this. We should look at other options instead. One of the requirements is that it needs to be fully accessible.

A few that come to mind:

Allow adding dynamic content to the Chroma theme

Feature Request

To really make Chroma powerful, it'd be great if consumers could add whatever they wanted to the theme object (and have types as well).

Some examples:

  • "I want to add a tertiary color palette to the theme in my app"
  • "I want to add full classes onto the theme, so I can apply them to particular components"
  • "I want to add additional box shadow options defined by my application to the theme"

This would allow for the above scenarios, instead of defining them outside of the theme as raw objects or something.

Proposal: Add a Skeleton Loader component

One of the feedback items we received is adding a Skeleton Loader component. There are two ways to build these normally:

  1. Render the element, measure it, then build the SVG skeleton based on the measured height / width
  2. Provide an SVG asking the user to provide props such as height, width, shape (rectangle / circle)

From my experience, the second option is normally the least hacky / error prone, but I don't want to put too much bias on that decision if someone can get something working well!

Here's an example of a Select Loading Skeleton I've done in Marketplace. Styles are with tailwind, but you can map those over to a CSS class name.

export const SelectLoadingSkeleton: React.FC<SelectLoadingSkeletonProps> = ({
  ...rootProps
}) => (
  <div
    className="flex flex-col"
    {...rootProps}
    data-testid={loadingSkeletonTestId}
  >
    <svg
      className="w-full h-5 bg-gray-300 rounded-md mb-2 animate-pulse"
      role="presentation"
      aria-hidden
    >
      <rect fill="currentColor" />
    </svg>
    <svg
      className="w-full h-10 bg-gray-300 rounded-md mb-2 animate-pulse"
      role="presentation"
      aria-hidden
    >
      <rect fill="currentColor" />
    </svg>
  </div>
);

PageLayout header flashes default background Image before provided background Image

When providing a background image and refreshing the page, the default background image flashes before rendering the provided backgroundImage.

background.mov

I tried this:

In backgroundCover styles, I remove the background style and added the background color.
backgroundColor: theme.palette.primary.main

Then in the inline style I updated it to this.

{
    backgroundImage: backgroundImage
     ? `url(${backgroundImage})`
     : `url(${PageLayoutDefaultHero})`,
}

But no luck. I wonder if there is some lag in ConditionalWrapper and the styles are painting before the inline styles. ๐Ÿคทโ€โ™€๏ธ

Proposal: Re-evaluate Modal component props

We should re-evaluate the Modal component props. In particular, size and fullWidth are extremely confusing. We have some feedback on this on #116 (comment). What would be nice is if we have a new height and width props, with four different size options for each, allowing a bit deeper customization.

We can make this a breaking change if it makes sense, or provide new props and deprecate the old ones. We could even look at replacing the underpinnings with another library that may help us out a bit too ๐Ÿ‘

Upgrade to the latest version of Storybook

Summary

A major version of Storybook is out and it has MDX support. It would be neat to migrate to the latest version and also potentially move to using MDX instead of storybook-readme?

TableModule row manual ordering

Be able to drag and drop row vertically for TableModule

I will use @dnd-kit to implement this feature because it supports accessibility well compare to other candidates like react-dnd.

Refactor TableModule with TanStack Table

Checkout TanStack Table.

This is a follow up of #330 to cover:

  • adding react-table as implementation and make it backward compatible.
  • when using config of TableModule, no changes to existing apps that use it.
  • when using columns: ColumnRef[] to configure TableModule , it will use react-table 's implementation.

Tasks

  • rendering - adapt stanstack table API
  • row selection
  • sort by column
  • sticky column
  • row actions
  • row click

Popovers, Menus, Selects, Comboxes, and Tooltips should not add things to the DOM if they aren't visible

Summary

Popovers, Menus, Selects, Comboxes, and Tooltips currently always render a portal + display: 'none' elements in the DOM. Here's an example in a LifeOmic app with a TableModule and tooltips for multiple actions.

Screen Shot 2020-11-02 at 4 52 26 PM

As you can see from the image, some of this is the due to the way Reakit works with portals. Maybe we shouldn't portal as much or should cut back on what we do portal?

Options

  • Question: Do we need portals on all of these components?
  • Upgrade to latest version of Reakit and see if there are any improvements in this area. Maybe we are doing something wrong / not recommended as well? May be good to start a GitHub issue or a Spectrum chat about this.
  • Find another a11y solution for these types of elements that don't clutter the DOM with invisible elements and only renders them when they are displayed. The benefit of using Reakit is due to the a11y bits it provides
  • Open to other options as well, as long as we can retain the a11y (WAI-ARIA) standards

Add a CHANGELOG.md

From @epeters3

Idea: Include a Changelog page or a "What's New in Chroma" section on the home page of the Chroma site that allows consumers to see what's new.

I've seen some OSS repos automated changelog.md updates as part of release process via github actions. comments are welcome

Select | ensure every ARIA input field has an accessible name

Title: WCAG 4.1.2: Ensure every ARIA input field has an accessible name (.ChromaSelect-ul-5785[role="listbox"])
Tags: Accessibility, WCAG 4.1.2, aria-input-field-name

Issue: Ensures every ARIA input field has an accessible name (aria-input-field-name - https://accessibilityinsights.io/info-examples/web/aria-input-field-name)

Target application: Form Components / Select - Default โ‹… Storybook - http://localhost:9001/?path=/story/form-components-select--default

Element path: #storybook-preview-iframe;#id-nov4f0 > .ChromaSelect-ul-5785[role="listbox"]

Snippet:

    How to fix:
    Fix any of the following:
    aria-label attribute does not exist or is empty
    aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
    Element has no title attribute

    Environment: Chrome version 89.0.4389.82

    ====

    This accessibility issue was found using Accessibility Insights for Web 2.24.0 (axe-core 4.1.1), a tool that helps find and fix accessibility issues. Get more information & download this tool at http://aka.ms/AccessibilityInsights.

TextArea | ensure every form element has a label

Title: WCAG 1.3.1,WCAG 4.1.2: Ensures every form element has a label (#textArea-a7f1824c85aaa71f36e2a4b784193ed9)
Tags: Accessibility, WCAG 1.3.1, WCAG 4.1.2, label

Issue: Ensures every form element has a label (label - https://accessibilityinsights.io/info-examples/web/label)

Target application: Form Components / TextArea - Default โ‹… Storybook - http://localhost:9001/?path=/story/form-components-textarea--default

Element path: #storybook-preview-iframe;#textArea-a7f1824c85aaa71f36e2a4b784193ed9

Snippet: <textarea aria-describedby="error-for-textArea-a7f1824c85aaa71f36e2a4b784193ed9" class="ChromaTextArea-textarea-90 ChromaTextArea-textareaInverse-91 ChromaTextArea-textareaError-92" cols="1" id="textArea-a7f1824c85aaa71f36e2a4b784193ed9"></textarea>

How to fix:
Fix all of the following:
Form element has explicit that is hidden

Fix any of the following:
aria-label attribute does not exist or is empty
aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
Form element does not have an implicit (wrapped)
Form element does not have an explicit
Element has no title attribute
Element has no placeholder attribute
Element's default semantics were not overridden with role="none" or role="presentation"

Environment: Chrome version 89.0.4389.82

====

This accessibility issue was found using Accessibility Insights for Web 2.24.0 (axe-core 4.1.1), a tool that helps find and fix accessibility issues. Get more information & download this tool at http://aka.ms/AccessibilityInsights.

Proposal: Add Date Picker component

Having built-in date picker components would be extremely helpful. Probably need to work with design to figure out our use cases and how it should look/work from a UI/UX perspective

Upgrade to latest storybook

I saw these msg when running this repo:

A new version (7.2.1) is available! 
โ”‚                                                                                         
โ”‚   Upgrade now: npx storybook@latest upgrade                                            
โ”‚                                                                                        
โ”‚   Read full changelog: https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md

Have theme typography scale and Text component typography scale merge

At the moment, we have two "sources of truth" for a typography scale:

  1. The <Text component (https://github.com/lifeomic/chroma-react/blob/master/src/components/Text/Text.tsx)
  2. The theme typography (https://github.com/lifeomic/chroma-react/blob/master/src/styles/createTypography.ts#L50)

While somewhat similar, there are differences between the two. Part of the reasoning for this is because Material-UI provides a typography scale on the theme. Our existing app heavily leveraged the theme typography scale for MUI components, and while migrating to Chroma components, we didn't want to totally break the app by shifting font sizes/line-heights/letter-spacing.

We should look at taking the Text component typography scale and adding that to the theme. Once this is completed, the Text component can derive all of Text styles from the theme instead of being hardcoded in the component.

One unanswered question is if we should remove the MUI-specific typography options (h2-h6 for example) from the theme, or instead, add them to our proper typography scale and update <Text to expose these. If we end up removing font sizes from the theme, does that break existing MUI components as they're no longer on the theme?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.