headlessui-svelte
Unofficial Headless UI Svelte components. Very much a work in progress, use with caution.
npm install @mattjennings/headlessui-svelte
Usage
See Components for which are available.
The goal is to keep the API as close to @headlessui/react
as possible.
<script>
import { Switch } from "@mattjennings/headlessui-svelte";
let enabled = false;
</script>
<Switch.Group>
<div class="flex items-center">
<Switch.Label class="mr-4">Enable notifications</Switch.Label>
<Switch
bind:checked={enabled}
class={`${
enabled ? "bg-blue-600" : "bg-gray-200"
} relative inline-flex items-center h-6 rounded-full w-11 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500`}>
<span
class={`${
enabled ? "translate-x-6" : "translate-x-1"
} inline-block w-4 h-4 transform bg-white rounded-full transition-transform`} />
</Switch>
</div>
</Switch.Group>
For comparison, this is the @headlessui/react
version:
import { useState } from 'react'
import { Switch } from '@headlessui/react'
export default function CustomLabelExample() {
const [enabled, setEnabled] = useState(false)
return (
<Switch.Group>
<div className="flex items-center">
<Switch.Label className="mr-4">Enable notifications</Switch.Label>
<Switch
checked={enabled}
onChange={setEnabled}
className={`${
enabled ? 'bg-blue-600' : 'bg-gray-200'
} relative inline-flex items-center h-6 rounded-full w-11 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500`}
>
<span
className={`${
enabled ? 'translate-x-6' : 'translate-x-1'
} inline-block w-4 h-4 transform bg-white rounded-full transition-transform`}
/>
</Switch>
</div>
</Switch.Group>
)
}
Caveats
Event forwarding
Until the on:* syntax is supported in Svelte, each internal component will need to explicitly forward every possible event so that they can be used. The scope of this package is small enough that I could do that, but it would be annoying.
One idea is to go the React-way and use on-*
props for event listeners. This would not be the ideal API, but it would work.
For now, components will at least emit the following events:
click
focus
blur
keypress
keydown
keyup
Dynamic elements
Until dynamic elements are supported in Svelte, I'm using a modified internal version of svelte-elements to support the as
prop.
SvelteKit
You might get the following error (or similar) when running in development with SvelteKit:
Cannot read property 'default' of null
The fix is to restart the dev server. It only happens the first time svelte-kit dev
is run and I'm not sure why.
Components
- [x] Switch
- [ ] Menu
- [ ] Listbox
- [ ] Disclosure
- [ ] Dialog
- [ ] Popover
- [ ] Radio Group
- [ ] Transition