Skip to content
This repository was archived by the owner on Feb 14, 2022. It is now read-only.

Commit eedafee

Browse files
committed
Draft Headless UI v1.4 post
1 parent 0d741cc commit eedafee

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"printWidth": 80,
3+
"singleQuote": true,
4+
"semi": false
5+
}

src/pages/headless-ui-v1-4/card.jpg

41.2 KB
Loading

src/pages/headless-ui-v1-4/index.mdx

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import { adamwathan, robinmalfait } from '@/authors'
2+
import card from './card.jpg'
3+
4+
export const meta = {
5+
title: 'Headless UI v1.4: The One With Tabs',
6+
description: `We just released Headless UI v1.4, which includes a brand new \`Tab\` component, and new APIs for manually closing \`Popover\` and \`Disclosure\` components more easily.`,
7+
date: '2021-07-29T12:00:00.000Z',
8+
authors: [adamwathan, robinmalfait],
9+
image: card,
10+
footer: `
11+
<p>
12+
Ready to try it out?
13+
<a href="https://headlessui.dev" class="font-medium text-teal-600 hover:text-teal-700">
14+
Visit the Headless UI website →
15+
</a>
16+
</p>
17+
`,
18+
}
19+
20+
We just released Headless UI v1.4, which includes a brand new `Tab` component, and new APIs for manually closing `Popover` and `Disclosure` components more easily.
21+
22+
<!--more-->
23+
24+
<a href="https://headlessui.dev">
25+
<img src={card} alt="Headless UI" />
26+
</a>
27+
28+
## Tabs
29+
30+
Earlier this year we started working on [Tailwind UI Ecommerce](https://tailwindui.com/ecommerce), and we realized pretty quickly we were going to need to support tabs in Headless UI to be able to build the new interfaces we were designing.
31+
32+
<!-- Image of ecommerce design that includes tabs -->
33+
34+
Here's what we ended up with:
35+
36+
```jsx
37+
import { Tab } from '@headlessui/react'
38+
39+
function MyTabs() {
40+
return (
41+
<Tab.Group>
42+
<Tab.List>
43+
<Tab
44+
className={({ selected }) =>
45+
selected ? 'bg-blue-500 text-white' : 'bg-white text-black'
46+
}
47+
>
48+
Tab 1
49+
</Tab>
50+
51+
{/* ... */}
52+
</Tab.List>
53+
<Tab.Panels>
54+
<Tab.Panel>Content 1</Tab.Panel>
55+
{/* ... */}
56+
</Tab.Panels>
57+
</Tab.Group>
58+
)
59+
}
60+
```
61+
62+
Like all Headless UI components, this totally abstracts away stuff like keyboard navigation for you so you can create custom tabs in a completely declarative way, without having to think about any of the tricky accessibility details.
63+
64+
[Check out the documentation](https://headlessui.dev/react/tabs) to play with a working example.
65+
66+
### Closing Disclosures and Popovers
67+
68+
Up until now, there was no way to close a `Disclosure` without clicking the actual button used to open it. For typical disclosure use cases this isn't a big deal, but it often makes sense to use disclosures for things like mobile navigation, where you want to close it when someone clicks a link _inside_ of it.
69+
70+
Now you can use `Disclosure.Button` or (`DisclosureButton` in Vue) within your disclosure panel to close the panel, making it easy to wrap up things like links or other buttons so the panel doesn't stay open:
71+
72+
```html
73+
<template>
74+
<Disclosure>
75+
<DisclosureButton>Open mobile menu</DisclosureButton>
76+
<DisclosurePanel>
77+
<DisclosureButton :as="MyLink" href="/home">Home</DisclosureButton>
78+
<!-- ... -->
79+
</DisclosurePanel>
80+
</Disclosure>
81+
</template>
82+
83+
<script>
84+
import {
85+
Disclosure,
86+
DisclosureButton,
87+
DisclosurePanel,
88+
} from '@headlessui/vue'
89+
import MyLink from './MyLink'
90+
91+
export default {
92+
components: { Disclosure, DisclosureButton, DisclosurePanel, MyLink },
93+
}
94+
</script>
95+
```
96+
97+
The same thing works with `Popover` components, too:
98+
99+
```jsx
100+
import { Popover } from '@headlessui/react'
101+
import MyLink from './MyLink'
102+
103+
function MyPopover() {
104+
return (
105+
<Popover>
106+
<Popover.Button>Solutions</Popover.Button>
107+
<Popover.Panel>
108+
<Popover.Button as={MyLink} href="/insights">
109+
Insights
110+
</Popover.Button>
111+
{/* ... */}
112+
</Popover.Panel>
113+
</Popover>
114+
)
115+
}
116+
```
117+
118+
If you need finer control, we also pass a `close` function via the render prop/scoped slot, so you can imperatively close the panel when you need to:
119+
120+
```jsx
121+
import { Popover } from '@headlessui/react'
122+
123+
function MyPopover() {
124+
return (
125+
<Popover>
126+
<Popover.Button>Terms</Popover.Button>
127+
<Popover.Panel>
128+
{({ close }) => (
129+
<button
130+
onClick={async () => {
131+
await fetch('/accept-terms', { method: 'POST' })
132+
close()
133+
}}
134+
>
135+
Read and accept
136+
</button>
137+
)}
138+
</Popover.Panel>
139+
</Popover>
140+
)
141+
}
142+
```
143+
144+
For more details, check out the updated [Popover](https://headlessui.dev/react/popover#closing-popovers-manually) and [Disclosure](https://headlessui.dev/react/disclosure#closing-disclosures-manually) documentation.
145+
146+
## Try it out
147+
148+
Headless UI v1.4 is a minor update so there are no breaking changes. To upgrade, just install the latest version via npm:
149+
150+
```shell
151+
# For React
152+
npm install @headlessui/react
153+
154+
# For Vue
155+
npm install @headlessui/vue
156+
```
157+
158+
Check out [the official website](https://headlessui.dev) for the latest documentation, and check out [Tailwind UI](https://tailwindui.com) if you want to play tons of styled examples.

0 commit comments

Comments
 (0)