GithubHelp home page GithubHelp logo

lightspeed / flame Goto Github PK

View Code? Open in Web Editor NEW
77.0 22.0 13.0 6.15 MB

Component library for building Lightspeed products

License: Other

JavaScript 7.49% HTML 0.06% TypeScript 81.27% Shell 0.11% SCSS 9.30% Handlebars 0.59% MDX 1.18%
react emotion styled-system typescript css-in-js design-system

flame's Introduction

Lightspeed Flame

Component library for building Lightspeed products.


npm version GitHub Actions workflow status badge codecov

Storybook

For the deployed version of our development environment visit https://lightspeed-flame.netlify.com.

Playground

Fork this CodeSandbox and start playing around with components:

Edit Flame Sandbox

Installing

Install the package:

yarn add @lightspeed/flame

And its required peer dependencies:

yarn add react@^16 react-dom@^16 @emotion/core@^10 @emotion/styled@^10 emotion-theming@^10

Getting Started

Before being able to implement Flame in your application, there are a few steps to bootstrap the components properly. We also assume that your React application is using a bundler such as webpack.

Steps required:

  • Link fonts
  • Hook the theme provider
  • Load global styles
  • Import components via their namespace

Link fonts

There are two ways to load the proper fonts:

Add this <link> tag to your <head> to load the required fonts:

<link
  href="https://fonts.googleapis.com/css?family=Lato:400,700&subset=latin-ext"
  rel="stylesheet"
/>

Hook the theme provider, load global styles, and import components

In order to have the proper styling, it is necessary to load the theme object into the application.

To do so, wrap the <FlameTheme> provider on your app and add FlameGlobalStyles:

import React from 'react';
import { FlameTheme, FlameGlobalStyles } from '@lightspeed/flame/Core';
// Access components via their namespace
import { Button } from '@lightspeed/flame/Button';
import { Heading1, Text } from '@lightspeed/flame/Text';

// Within your root app component
class App extends React.Component {
  render() {
    return (
      <FlameTheme>
        {/* Wrapping `<div>` is necessary since `<FlameTheme>` is a Provider */}
        <div>
          {/* We set some global styles, like fonts and minimal resets */}
          <FlameGlobalStyles />

          {/* A Flame styled h1, paragraph, and button 🎉 */}
          <Heading1>My heading</Heading1>
          <Text as="p">Welcome to Flame</Text>
          <Button variant="primary" fill={true}>
            It's happening!
          </Button>
        </div>
      </FlameTheme>
    );
  }
}

Please note

If you have Emotion already installed and you would like to use the theme values provided from Flame, you will still need to wrap your application with an Emotion <ThemeProvider /> and pass in the theme object.

import React from 'react';
import { FlameTheme, lightTheme } from '@lightspeed/flame/Core';
import { ThemeProvider } from 'emotion-theming';

class App extends React.Component {
  render() {
    return (
      <ThemeProvider theme={lightTheme}>
        <FlameTheme>
          <div>{/* ... */}</div>
        </FlameTheme>
      </ThemeProvider>
    );
  }
}

This is intentional since we do not want changes on FlameTheme to potentially affect your underlying components, as you might already have custom theme values being added.

Testing your app with Flame components

It's important to wrap your tests with the appropriate theme provider. This is because some flame components requires theme values to be passed in order to compute new color values.

Before rendering your component inside of your tests, ensure you wrap it up with FlameTheme.

For example:

describe('Some component', () => {
  it('renders', () => {
    const component = someTestRenderFunction(
      <FlameTheme>
        <Button />
      </FlameTheme>,
    );
  });
});

Getting started with server-side rendering (SSR)

Flame supports SSR out of the box without any additional configuration needed.

Since Flame uses the latest @emotion package, when loading components on the server, components will automatically have their styles extracted without any required setup.

Styled System props

Many of flame components have been augmented with Styled System props.

<Alert mb={3}>
  This Alert will now have a margin bottom (mb) of 1.125rem. That value corresponds to the 3rd
  spacing value of the design system.
</Alert>

These props are essentially a way to quickly customize various css properties of a component without the need of writing a custom css class or component. These props are automatically attached to the values of the design system, so long as the application was properly wrapped with the <FlameTheme> component.

Please consult the packages READMEs for a list of all activated props:

Contributing

See the contributing guidelines.

Licenses

The source code is licensed with a custom license.

flame's People

Contributors

adityatr-ls avatar alexislightspeed avatar alexismo avatar dependabot-preview[bot] avatar dependabot[bot] avatar glambert avatar immasandwich avatar inooid avatar jonasostir avatar ls-andrew-borstein avatar ls-dennis-marchand avatar ls-remy-jeancolas avatar maartenafink avatar rjmcneill avatar rothlis avatar testerez avatar xdrdak 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  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  avatar  avatar  avatar

flame's Issues

Add spacing props to Card

Description

The vast majority of components already have the spacing props.

There are a few exceptions to this, like the <Card> component. It would be a good idea to add the styled-system properties to this component, since that feels more natural to use than to wrap it with a Box or a Flex. Not to mention, it simplifies the markup.

Input and Group refactor

The time is almost upon us for yet another set of breaking changes.

Nothing is final yet, but we sort of wanna communicate what's in store for the next major release.

So, what's up with this?

Deprecation and rework of the Group component

The infamous group component will receive a massive overhaul.

We plan on removing the component, because as it stands, Group does surprisingly too many things.

So, what's it gonna be replaced by?

InputGroup

InputGroup will be a new component that specifically designed to collapse Buttons/Inputs/Addons together.

This aims to replace the most common usage of group.

Usage will be as follows:

// Old
<Group noSpacing>
  <Button>Some Action</Button>
  <Input placeholder="some placeholder"/>
</Group>
// New
<InputGroup>
  <Button>Some Action</Button>
  <Input placeholder="some placeholder"/>
</InputGroup>

It is also worth nothing that the new InputGroup component will no longer recursively mess around with border radii and will
only affect the direct child for a given component. It will also ONLY affect the above listed components.

ListGroup

ListGroup will only take care of automatically wrapping components with a custom built <li> component
and automatically add spacing between each component.

You may toggle horizontal or vertical spacing.

// Old
<Group>
  <Button>Some Action</Button>
  <Input placeholder="some placeholder"/>
</Group>

<Group type="vertical">
  <Button>Some Action</Button>
  <Input placeholder="some placeholder"/>
</Group>

// New
<ListGroup>
  <Button>Some Action</Button>
  <Input placeholder="some placeholder"/>
</ListGroup>

<ListGroup type="vertical">
  <Button>Some Action</Button>
  <Input placeholder="some placeholder"/>
</ListGroup>

No more Z index shenanigans

Yes, Group has this super bizarre z-index magic going on.

This will be removed entirely.

We'll probably add a zIndex prop instead for all your z-index shenanigans.

FormFields is actually happening

The original issue ticket was opened on Jan 3rd 2018. We now have the technology to take care of this issue!

Joking aside, FormFields is a particularly scary change because it will involve some major overhaul of a few primitive components, namely:

  • Checkbox
  • Radio
  • Inputs (and its type variants)

These components will have a dramatically different (see, more streamlined API) that matches their regular vanilla HTML counterparts.

To add labels, error messages and the likes to these components, we can choose to wrap them inside the FormField component.

Positioning issue for Tooltip and Dropdown

Description

Tooltip and Dropdown don't recalculate their position when a DOM change repositions them on the page.

Expected behavior

When their position changes, so should the tooltip and dropdown menu.

Actual behavior

They keep their original position and appear disconnected from their triggering element.

Steps to reproduce the problem

Make a dropdown element to add an item above it. The dropdown menu won't follow its dropdown button.

Specifications

  • Affected component(s): Tooltip, Dropdown (and everything using page positioning like popovers)
  • Versions: 1.6.0
  • Browser: Chrome
  • Device: Macbook Pro
  • Operating System: Mac OS

Flame next major

Description

Tracking issue on what's coming for the next major version of Flame packages.

@lightspeed/flame

Deprecated

  • FlameFonts component from @lightspeed/flame/Core will be removed. Instead, use the link tag to load fonts. Problem is Next.js Head component does not play nice with it and actually removes the link after client-side takes over. Fonts won't be changing very frequently so its usefulness is very limited.
  • Group will either be moved to a separate package @lightspeed/flame-group or remain undocumented but kept as an hidden feature in the codebase. See #2.

@lightspeed/flame-tokens

Deprecated

  • Root level css and sass files will be removed, prefer going through the appropriate namespaced folder to get your utility files. See #56.
  • The cr- namespace will be removed in favour of the fl- namespace. See #56.

Remove Sass from Storybook

Description

Remove all Sass references and usage of it from our stories.

Since we want to promote the usage of emotion, it might make more sense to build custom components using emotion + our theme values than pulling stuff from our legacy generated Sass values.

This will also enable us to remove some rather pointless plugins to bundle css and sass into the final storybook build.

This is so incredible 🔥

Congratulations on finally open sourcing the library.

I'm still making my way through the storybook to examine all the api choices you've made and I'm just blown away at the quality.

I kind of want to start using this now :D

Disabled states in radio and checkboxes should affect labels

Hi,
Like it currently is with buttons, disabled states in radio and checkboxes should also affect their respective labels.

The visual cue that indicates the component is disabled becomes more reliable when it is applied to the element as a whole.

Attached is an example of the current and expected behaviour.

@ls-timothee-clain is going to submit a PR on this issue
Reviewed the case with @maartenafink .
Thanks!

Slice

Allow dropdown to also support "top" related positions

Description

Currently the DropdownContainer is pretty opinionated on the position of the dropdown, while I feel like this constraint should be put on the consumer side and not on the library's end. In some situations when placing a dropdown at the bottom of the page/screen or within a limited height container, it might not always be possible to display a menu that's dropping down, but it should show above it instead.

This css makes the component very opinionated on the position of the dropdown (as well as the animation when opening):

Design question: Should the chevron be up or down in this case?

Design/Examples

image

Use react-select v3

Description

React-Select v3 has the latest version of emotion, which will give us not only better perf, but also better integration with our ecosystem + SSR.

Updating to the latest version should be simple, but like all major version bumps, there can be issues along the way.

Requirements

  • React-Select is on the latest version
  • Tests and Percy snapshots are good/unchanged

Modal body is separated from the footer

Description

When the body exceeds the screen height, a space is created with the footer

Good / Normal
image

Bug
image

Expected behavior

The footer should be attached to the body at time and the body should be scrollable if it exceeds the window height

Steps to reproduce the problem

https://codesandbox.io/s/optimistic-cookies-06yx7

add a few elements to the modal body if you can't see it

Specifications

  • Affected component(s): Modal
  • Versions: Latest

Leverage spritemaps for Flags

Currently, Flags has the same implementation/behaviour as Icon, in which loading the base component <Flag> will cause all svgs to be loaded as a chunk. This is normal behaviour, however it's somewhat problematic in this use case since when we're using flags, we usually want all of them loaded at the same time.

What we should be doing is instead of loading all SVGs for Flags, would be to leverage an svg spritemap instead.

eslint-ordering configuration updated

Description

we should be using ["builtin", "external", "internal", "parent", "sibling", "index"] instead of the airbnb defaults as the current setup is a bit too loose in how to order imports.

We will need to:

  • add 'import/order': ['error', { groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'] }] to the .eslintrc.js rules object
  • fix any potential errors that will arise (just run yarn lint --fix)

Add more standardized menu for dropdown

Description

Currently the dropdown components (and sub components) make it possible to render anything within the "popped out" box, but this gives us consumers a lot of freedom. I would like to see some more guidance in how to render these dropdown lists.

How about a DropdownList or DropdownMenu component that is just a styled ul and li list?

Requirements

  • Don't narrow down the API of the dropdown component itself, people should still be allowed to render things above or below the list.
  • Standardise the way we create context menus

Design/Examples

Currently within the Lightspeed products, we've seen some context menus being used within the sidebar:

image

But also in our some other places:

image

Both of these designs already show and proof that the implementations are going all over the place, while they're pretty similar.

Make Input id as required (in TS typings)

Description

The id for an Input should probably be marked as required by it's TS typings. If not, its label will not have labelFor set.

Expected behavior

Spit out a TS error when id is not present.

Actual behavior

Not having an id is not flagged as an error, while the docs state that id should be set.

image

Steps to reproduce the problem

  1. Create an Input and don't set the id prop
  2. No TS errors/warnings

Specifications

  • Affected component(s): Input
  • Versions: latest

Simplify Button component

Description

Dumbify a bit the Button Component.

Split between <LinkButton> & <Button>

Typing issues caused by dynamically swapping button -> anchor is problematic.

Simply split those components in two. Meaning the <LinkButton /> will have the href tag.

Or use the render prop pattern

Also consider looking into using a render prop for the container element (HTML element like button, a or even a React element like Link):

https://blog.andrewbran.ch/polymorphic-react-components/#an-alternative-approach

Button will no longer auto resize based on Icons

The Button does some fun wacky wrapping of components and automatic resizing based on the presence or not of an Icon

This has got to go, as we're relying on cirrusName to do some funky manipulation. Instead, simply manually resize the content as needed.

// old
<Button>Some Action <Icon /></Button>
<Button><Icon /></Button>

// new
<Button>Some Action <Icon ml={1}/></Button>
<Button><Icon ma={1} /></Button>

Use deepmerge themes when overriding

Description

Provide a high-level summary of your issue.

return <ThemeProvider theme={{ ...selectedTheme, ...themeOverrides }}>{children}</ThemeProvider>;

Rather than spreading both objects together, use deepmerge so that a new theme may extend the ThemeUI without fully overriding the original theme.

What do you think should have happened?

The color would be deepmerged. Instead the color is overwritten by the ThemeOverride

Steps to reproduce the problem

const existingTheme = {col:{blue:'blue'}};
const newTheme = {col:{red:'red'}};
const mergedTheme = {...existingTheme, ...newTheme};
console.log(mergedTheme);
:rip:

Specifications

  • Affected component(s): Core / FlameTheme

Add children to all component interfaces where the prop is used

Description

While attempting to import the <Dropdown> component from Flame in the new insights app, we ran into a Typescript issue where the app wouldn't compile because children is not a valid prop in the Dropdown interface.

The insights app is using React 18 and in that version React.FC no longer includes children by default.

So any Flame components that

  • use React.FC
  • include a children prop
  • don't type their props to include children or extend a type that does so (e.g. Box)

will probably need to be updated to be compatible with React 18 and TS.

Requirements

Dependencies

<Dropdown> and other similar components that take children can be successfully used in a React 18 / Typescript project, like lighthouse-insights.

Required before signoff

n/a

Design/Examples

n/a

Better mobile-friendliness

Description

Supporting mobile devices is an important feature we would like to have.

Being mobile friendly is more than just simply resizing things to fit on a smaller screen. It's understanding that the overall UX is different. Buttons that are perfectly fine on desktop, might need a slightly bigger click area on mobile.

In order to make the Mobile version work better, we'll be revising, tinkering and tweaking a few things here and there.

There shouldn't be any substantial API changes, but instead its mostly a tweak of overall usability for smaller devices.

RFC: Styling API consolidation and a just more fun to use component API system

Background

As a consumer, having too many ways of doing things can lead to having some messy code base.

While Flame has some neat features, it still feels kinda awkward to use when it comes to deviating from whatever has been pre-established. Even with the inclusion of style-props, we still can't hit the "100%" fits all solution. That's just a limitation of the style-prop itself, you can only modify 1 css style per prop. Currently, should we want to handle advanced use cases that are not planned, we would need to:

  • Add more props
  • Extend using either styled or the css prop jsx pragma

Both solutions kinda suck, as we're:

  • Further increasing prop api complexity
  • Diverting some core functionalities that the library should handle to the underlying implementation (aka, we let emotion do it's thang)

Requirements

In order to have a better API and a just more fun to use component system we need to limit the amount of "back and forth" between various ways to extend and have the component system handle pretty much all the base styling needs.

  • A user should not have to extend a component via styled to get overrides.
  • A component API should not explode when trying to do overrides.
  • A user should not have to install yet another babel plugin.
  • A user can easily do responsive css

Proposal

There's a few things we can do. Some changes can be had immediately, while others might take some time.

The first thing we can do is create our own home grown css prop that is baked into our components.
see https://github.com/rebassjs/rebass/blob/master/packages/reflexbox/src/index.js#L37 for implementation details. Essentially, rebass has 2 props, css and sx, that are baked directly into rebass components. We can do something similar, except we will not have a sx prop and instead just use css that is automatically hooked into the theme values. Only having css prop can cause conflicts with the jsx pragma of props. Easiest solution: Use rebass and re-export only the components we want.

By doing this we avoid adding yet more styled-system props and grant you full access to ALL theme values as well as just regular old css in a single prop.

The second thing is we're adding back classnames on some components (tbd). This might seem like the funkiest thing ever, but this will enable us to target specific portions of a component easily via a top level css prop. Basically, the classnames are only there to serve as markers so we can quickly do edits without having to go through the whole render slot approach of jamming a component inside a prop.

Last but not least, we're gonna cleanup the theme file just a bit. Namely collapsing some properties together (like shadows) and renaming some values, as they are kinda long winded to write down

Out of Scope

Fixes relating to CSS specificity or stuff like that. That's for another time.

Risks

There may be a collision between our css prop and the jsx css pragma prop. If that happens, we'll need to do like rebass and split our styling into two props css for regular non themed css and sx for the magical augmented css

Alternatives

¯\_(ツ)_/¯

Resolution

Expect a PR in a couple of phases.

We'll start by adding this functionality to Box, Flex and Text as those are our fundamental components. From there, we're gonna modify existing components to use the new fundamental components and have a way to easily override sub-components.

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.