Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

op-ent/unstyled-ui

Repository files navigation

Banner

@op-ent/unstyled-ui

npm version npm downloads Github Actions bundle Codecov MIT License

@op-ent/unstyled-ui is an headless react library.

Motivation

When it comes to components libaries, there are two main approaches:

  • Styled components: The library provides a set of components with a default style. The user can override the style by providing a custom class or style. Examples of such approach are Bootstrap and Material UI. Those libraries offer customization options, but they are limited and require a lot of work to achieve a custom look and feel. In most cases, it feels like fighting against the library (using !important in CSS for example). Using these libraries will result in a library style, not your brand style.
  • Headless (unstyled) components: The library provides a set of components without any style but fully functional and accessible. The user is responsible for providing the style. Examples of such approach are Headless UI, Radix Primitives or even specialized libraries like React table. It solves some of the problems raised by the use of libraries in the first approach. On the other hand, it requires a compositional implementation (i.e. wrappers) for each project, and it is not possible to style globally, like in a config file.

So here comes unstyled-ui, whose purpose is to conciliate both approaches :

  • Use only headless components
  • Do not recreate components libraries for each project, since unstyled-ui is a kind of interface
  • Provide all components of a design system. For example, Headless UI provides only a few specific components, but not buttons which is a classic component but is never developed in headless libraries
  • Be able to configure the whole theme at the global level. It's easier because it allows to centralize everything, to share between different projects and to avoid composition problems. Moreover, no decision is taken (about colors for example), it's up to the designers to define them. For instance, the color prop is only of type string by default, but can be changed via TypeScript module augmentation to 'primary' | 'secondary'.

Usage

Install package:

# npm
npm install @op-ent/unstyled-ui

# yarn
yarn install @op-ent/unstyled-ui

# pnpm
pnpm install @op-ent/unstyled-ui

Import example:

// ESM
import { Button } from '@op-ent/unstyled-ui'

// CommonJS
const { Button } = require('@op-ent/unstyled-ui')

Create a config

// lib/config.ts
import { createConfig } from '@op-ent/unstyled-ui'

declare module '@op-ent/unstyled-ui' {
    interface CustomizableComponentsPropsOverride {
        button: {
            variant: 'primary' | 'secondary'
        }
    }
}

export const { config, extendConfig } = createConfig({
    components: {
        button: {
            defaultProps: {
                variant: 'secondary',
            },
            customProps: ['variant'],
        },
    },
})

Use the config

import { ConfigProvider } from '@op-ent/unstyled-ui'
import { config } from '~/lib/config'

function App() {
    return (
        <ConfigProvider config={config}>
            <Button variant="primary">Hello world</Button>
        </ConfigProvider>
    )
}

Styling

Using CSS data parts:

.uui-button[data-part='root'] {
}
.uui-button[data-part='loader'] {
}
.uui-button[data-part='left-icon'] {
}
.uui-button[data-part='right-icon'] {
}
.uui-button[data-part='children'] {
}
.uui-button[data-part='loading-text'] {
}

Planned components & features

WARNING: This is a work in progress.

  • This list is not complete and may change at any time.
  • Names may change in the future.
  • 🚧 ConfigProvider
    • 🚧 Behavior
      • useMemo ?
    • ❌ Docs
    • ❌ Tests
    • ❌ Example theme
  • 🚧 Button
    • 🚧 Behavior
    • ❌ Docs
    • ❌ Tests
    • ❌ Example theme
  • 🚧 ButtonGroup
    • 🚧 Behavior
    • ❌ Docs
    • ❌ Tests
    • ❌ Example theme
  • 🚧 IconButton
    • 🚧 Behavior
    • ❌ Docs
    • ❌ Tests
    • ❌ Example theme
  • ❌ Badge
  • ❌ Heading
  • ❌ Paragraph
  • ❌ Input
  • ❌ Modal
  • ❌ Switch

API Reference

TBD

💻 Development

  • Clone this repository
  • Install dependencies using yarn install
  • Watch files in development using yarn dev
  • Run interactive tests using yarn test

Inspiration

License

Published under MIT License.

Made with ❤️ by Florian LEFEBVRE in France.


Sponsors
Netlify banner Cleavr banner