Revery: Improve default styles and provide theming options

Created on 16 Feb 2019  路  3Comments  路  Source: revery-ui/revery

The default look of revery element should be good enough for developers not following a specific design.

The elements should all feel like they belong to the same library, the styles should respect accessibility standards, look modern and fresh.

API

To decide on the best API, we can have a look at how other libraries solve the problem.

Android

Android has the concept of per-widget styles and themes. When creating a new project, a default Material Design theme is applied.

Themes are versioned. Changes in theme are only made when a new version of android is released, so developers need manually verify and update the compatibility list, to ensure their app styles don't break with this newer version.

A developer can either extend the default styles:

<style name="GreenText" parent="@android:style/TextAppearance">
    <item name="android:textColor">#00FF00</item>
</style>

Create custom styles from scratch and the apply them to a single element:

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    ... />

Or apply a style to all elements, defining a new theme:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item>
    ...
</style>

Official documentation.

Flutter

The developer can define a ThemeData class, which describes the looks of the widgets.

 theme: Theme.of(context).copyWith(
  primaryColor: Colors.amber,
  textTheme: Theme.of(context).textTheme.copyWith(
    body1: new TextStyle(color: Colors.red),
    body2: new TextStyle(color: Colors.pink, fontSize: 24.0),
  ),
),

Overall, the library feels quite opinionated and limited in terms of theming. I might be missing something as I don't have direct experience with Futter.

Official documentation.

React-Select

Wait what? Why is a React component library in this list?

Well, I think it might be the best fit for Revery, and I think it's the correct mix of powerful, customizable and easy to completely skip.

Every component corresponds to a key in a styles object. Every key is a function receiving the provided styles as first argument and the state of that component as second argument. The return values are the applied styles.

const customStyles = {
  option: (provided, state) => ({
    ...provided,
    borderBottom: '1px dotted pink',
    color: state.isSelected ? 'red' : 'blue',
    padding: 20,
  }),
  control: () => ({
    // none of react-select's styles are passed to <Control />
    width: 200,
  }),
  singleValue: (provided, state) => {
    const opacity = state.isDisabled ? 0.5 : 1;
    const transition = 'opacity 300ms';

    return { ...provided, opacity, transition };
  }
}

  const App = () => (
    <Select
      styles={customStyles}
      options={...}
    />
  );
  • The developer can easily ignore the default styles
  • The developer can easily _extend_ the default styles
  • The styles can be changed depending on the state of the element

Official documentation.

Look and feel

Possible inspiration for the look and feel can be found in:

  • Material UI: for being extremely popular
  • Evergreen: Really well done
  • Semantic UI: Another incredibly well done UI library, possibly more flexible in style than the previous options
A-components enhancement

Most helpful comment

I played around with something super basic as well:

image

image

Coming from a web-development background I personally appreciate if the default styles don't do too much, but instead are easily overrideable

All 3 comments

What about a Cupertino and Material library a la flutter?

I began fiddling around a little bit with some UI and noticed that there are some inconsistencies in how elements are styled. In my opinion, I think it might be easier to begin with merging styles (as is done in a few places already).

e.g.

// A.re
<Button style=Style.[backgroundColor(Colors.red)]>Hello</Button>

// Button.re
let createElement = (
  style=Style.emptyViewStyle
) => {
  let defaultButtonStyle = Style.[/* some styles */];

  <View style=Style.(merge(~source=defaultButtonStyle, ~target=style))>
  // ...
  </View>
}

I played around with something super basic as well:

image

image

Coming from a web-development background I personally appreciate if the default styles don't do too much, but instead are easily overrideable

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bryphe picture bryphe  路  6Comments

SamuelTrew picture SamuelTrew  路  4Comments

bryphe picture bryphe  路  4Comments

broerjuang picture broerjuang  路  4Comments

bryphe picture bryphe  路  6Comments