Skip to content

Package

@remix-run/ui

Headless, accessible UI primitives and animation utilities for Remix components.

Installation

@remix-run/ui is currently unstable and versioned independently. It is not available through the remix package.

npm i remix @remix-run/ui

Usage

Compose behavioral primitives with your own markup and styles:

import { css, on } from 'remix/component'
import type { Handle } from 'remix/component'
import * as popover from '@remix-run/ui/popover'

let triggerCss = css({
  border: '1px solid #d1d5db',
  borderRadius: '6px',
  padding: '6px 10px',
})

let surfaceCss = css({
  background: 'white',
  border: '1px solid #d1d5db',
  borderRadius: '6px',
  padding: '8px',
})

function ViewOptions(handle: Handle) {
  let open = false

  return () => (
    <popover.Context>
      <button
        mix={[
          triggerCss,
          popover.anchor({ placement: 'bottom-end' }),
          popover.focusOnHide(),
          on('click', () => {
            open = true
            handle.update()
          }),
        ]}
        type="button"
      >
        View options
      </button>
      <div
        mix={[
          surfaceCss,
          popover.surface({
            open,
            onHide() {
              open = false
              handle.update()
            },
          }),
        ]}
      >
        Panel content
      </div>
    </popover.Context>
  )
}

Primitives

Animation

Use the animation utilities for entrance, exit, layout, spring, and tween animation:

import { animateEntrance, animateExit, spring } from '@remix-run/ui/animation'

function Toast() {
  return () => (
    <div
      mix={[
        animateEntrance({ opacity: 0, ...spring('snappy') }),
        animateExit({ opacity: 0, ...spring('snappy') }),
      ]}
    >
      Saved
    </div>
  )
}

See the animation module README for layout animation, CSS transitions, Web Animations API options, and imperative animation.

License

See LICENSE.