Headless UI online editor

Write, Run & Share Headless UI code online using OneCompiler's Headless UI online editor for free. It's one of the robust, feature-rich online editors for Headless UI. Getting started with the OneCompiler's Headless UI online editor is really simple and pretty fast. The editor shows sample boilerplate code when you choose language as 'Headless UI' and start writing code to learn and test online without worrying about tedious process of installation.

About Headless UI

Headless UI gives you the behavior and accessibility of common widgets like menus, dialogs, switches, and comboboxes, with no styling attached. You bring the look, usually with Tailwind CSS. Each component manages keyboard navigation, focus, and ARIA roles for you, and exposes its state so you can style the open, selected, or checked variants. The playground loads the Tailwind runtime, so utility classes work right away.

Syntax help

Switch

Switch is a toggle. Track its state with checked and onChange, and use the state to swap classes.

import { Switch } from '@headlessui/react';
import { useState } from 'react';

function Toggle() {
  const [on, setOn] = useState(true);
  return (
    <Switch
      checked={on}
      onChange={setOn}
      className={`${on ? 'bg-indigo-600' : 'bg-gray-300'} relative inline-flex h-6 w-11 items-center rounded-full`}
    >
      <span className={`${on ? 'translate-x-6' : 'translate-x-1'} inline-block h-4 w-4 rounded-full bg-white transition`} />
    </Switch>
  );
}

Menu

Menu builds an accessible dropdown. The parts (Menu.Button, Menu.Items, Menu.Item) wire up focus and keyboard support.

import { Menu } from '@headlessui/react';

<Menu>
  <Menu.Button className="rounded bg-slate-800 px-3 py-2 text-white">Options</Menu.Button>
  <Menu.Items className="mt-2 rounded border bg-white shadow">
    <Menu.Item>
      {({ active }) => (
        <a href="#edit" className={`block px-4 py-2 ${active ? 'bg-slate-100' : ''}`}>Edit</a>
      )}
    </Menu.Item>
    <Menu.Item>
      {({ active }) => (
        <a href="#delete" className={`block px-4 py-2 ${active ? 'bg-slate-100' : ''}`}>Delete</a>
      )}
    </Menu.Item>
  </Menu.Items>
</Menu>

Dialog

Dialog is a modal that traps focus while open. You control its visibility with React state.

import { Dialog } from '@headlessui/react';
import { useState } from 'react';

function Demo() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={() => setOpen(true)}>Open</button>
      <Dialog open={open} onClose={() => setOpen(false)} className="relative z-10">
        <div className="fixed inset-0 bg-black/30" aria-hidden="true" />
        <div className="fixed inset-0 flex items-center justify-center p-4">
          <Dialog.Panel className="rounded bg-white p-6">
            <Dialog.Title className="font-semibold">Confirm</Dialog.Title>
            <button onClick={() => setOpen(false)}>Got it</button>
          </Dialog.Panel>
        </div>
      </Dialog>
    </>
  );
}

Listbox

Listbox is a styled-by-you select. It keeps the selected value and handles keyboard choice.

import { Listbox } from '@headlessui/react';
import { useState } from 'react';

const people = ['Ada', 'Alan', 'Grace'];

function Picker() {
  const [selected, setSelected] = useState(people[0]);
  return (
    <Listbox value={selected} onChange={setSelected}>
      <Listbox.Button className="rounded border px-3 py-2">{selected}</Listbox.Button>
      <Listbox.Options className="mt-1 rounded border bg-white">
        {people.map((p) => (
          <Listbox.Option key={p} value={p} className="px-4 py-2">{p}</Listbox.Option>
        ))}
      </Listbox.Options>
    </Listbox>
  );
}

Styling by state

Components pass their state to render-prop children (active, checked, selected, open), so you apply different classes per state. Newer versions also expose data- attributes you can target with Tailwind variants.

<Menu.Item>
  {({ active }) => (
    <span className={active ? 'bg-slate-100 text-black' : 'text-slate-700'}>Item</span>
  )}
</Menu.Item>