npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

rescript-headlessui

v0.1.2

Published

ReScript bindings to HeadlessUI React component library

Downloads

4

Readme

rescript-headlessui

npm

This library provides ReScript bindings for HeadlessUI React components.

Installation

npm install rescript-headlessui

Add it to bs-dependencies in your rescript.json:

{
  "bs-dependencies": ["rescript-headlessui"]
}

Usage

Props

To use ReactDOM.domProps in all components, it was necessary to remove collisions. This was achieved by maintaining a custom list of props that excludes most of the fields defined by HeadlessUI.

The only exception is for components with event handlers or names resembling event handlers (e.g., onChange). Instead of removing these properties globally, they were overridden in the specific modules where they are used. For example, <Combobox.Input onChange={...} /> should be written as <Combobox.Input onChangeHeadless={...} />, with the function defined as @as("onChange") onChangeHeadless?: ReactEvent.Form.t => unit.

If you need one of the properties listed below, please wrap the component in a native element.

{disabled, value, defaultValue, by, multiple, name, form, children, as_, type, checked, defaultChecked, order, role, autoFocus, open_}

Union type bindings

Many of the HeadlessUI bindings allow union types, which can be challenging to represent in ReScript. When the allowed values were well-defined, they were converted into variants:

// <Dialog role=#dialog ... />
role?: @string
[
  | #dialog
  | #alertdialog
],

// <Button type=#submit ... />
type_?: @string
[
  | #button
  | #submit
  | #reset
],

For cases where the allowed values were not explicitly defined, inferred types were used and are configured at compile time:

// Common props on every component
type common<'as_> = {
  ...domProps,
  @as("as") as_?: 'as_
}

The inferred type is applied wherever "T" appears in the HeadlessUI documentation. This approach works well when used correctly but will result in errors if an unsupported value is provided to HeadlessUI.

Attribute by exception

An exception was made when defining by?: ('value, 'value) => bool instead of by?: 'by or by?: string to enforce a modicum of type safety.

Tooltip

There was an undocumented tooltip component in the HeadlessUI package that is also bound here. It is untested and should be used accordingly.

module Tooltip = {
  type tooltipProps<'as_> = {
    ...Props.common<'as_>,
    showDelayMs?: int,
    hideDelay?: int,
    children?: React.element,
  }

  @module("@headlessui/react") @react.component(: tooltipProps<'as_>)
  external make: unit => React.element = "Tooltip"

  module Trigger = {
    type triggerState = {
      focus: bool,
      hover: bool,
      autoFocus: bool,
    }
    type triggerProps<'as_> = {
      ...Props.common<'as_>,
      disabled?: bool,
      autoFocus?: bool,
      children?: React.component<triggerState>,
    }

    @module("@headlessui/react") @react.component(: triggerProps<'as_>)
    external make: unit => React.element = "TooltipTrigger"
  }

  module Panel = {
    type panelProps<'as_, 'anchor> = {
      ...Props.common<'as_>,
      anchor?: 'anchor,
      static?: bool,
      unmount?: bool,
      children?: React.element,
    }

    @module("@headlessui/react") @react.component(: panelProps<'as_, 'anchor>)
    external make: unit => React.element = "TooltipPanel"
  }
}