<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Ariakit]]></title><description><![CDATA[Receive monthly updates about Ariakit directly in your inbox.]]></description><link>https://newsletter.ariakit.com</link><image><url>https://substackcdn.com/image/fetch/$s_!y4DB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10c70c7a-0bd3-4a17-80ad-30d4a8fb847e_1000x1000.png</url><title>Ariakit</title><link>https://newsletter.ariakit.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 07 May 2026 19:56:14 GMT</lastBuildDate><atom:link href="https://newsletter.ariakit.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Haz]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[diegohaz@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[diegohaz@substack.com]]></itunes:email><itunes:name><![CDATA[Haz]]></itunes:name></itunes:owner><itunes:author><![CDATA[Haz]]></itunes:author><googleplay:owner><![CDATA[diegohaz@substack.com]]></googleplay:owner><googleplay:email><![CDATA[diegohaz@substack.com]]></googleplay:email><googleplay:author><![CDATA[Haz]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Performance, Tailwind v4, and more]]></title><description><![CDATA[Improved performance by 20-30% by working around useSyncExternalStore, new features, Black Friday discounts, and more.]]></description><link>https://newsletter.ariakit.com/p/performance-tailwind-v4-and-more</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/performance-tailwind-v4-and-more</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Tue, 26 Nov 2024 14:42:48 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/635858d9-fac0-4257-9be5-c2531418f21b_4032x3024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi folks,</p><p>In recent months, we've focused on improving the performance of composite widgets like <strong>Combobox</strong> and <strong>Select</strong>. In the latest version, we increased the rendering speed of these components by <strong>20-30%</strong> without any API changes. Additionally, we're working on new APIs and a built-in virtualization feature to enhance their performance even more.</p><h2>useSyncExternalStore</h2><p>In our measurements, we identified the performance bottleneck as the multiple uses of the <strong>useSyncExternalStore</strong> (<strong>uSES</strong>) React hook in composite item components. We even tested calling <strong>uSES</strong> with no-op stable subscribe and getSnapshot functions. However, React itself seems to perform extra work with each call to this hook compared to <strong>useState</strong> or <strong>useContext</strong>.</p><p>Each composite item component might call <strong>uSES</strong> over 10 times. When rendering more than 1,000 items, this could lead to thousands of hook calls. We improved this by <a href="https://github.com/ariakit/ariakit/blob/06c67ab6d6d8fc067949c07400d52260f3745134/packages/ariakit-react-core/src/select/select-item.tsx#L77-L97">consolidating them into a single </a><strong><a href="https://github.com/ariakit/ariakit/blob/06c67ab6d6d8fc067949c07400d52260f3745134/packages/ariakit-react-core/src/select/select-item.tsx#L77-L97">uSES</a></strong><a href="https://github.com/ariakit/ariakit/blob/06c67ab6d6d8fc067949c07400d52260f3745134/packages/ariakit-react-core/src/select/select-item.tsx#L77-L97"> call</a>.</p><p><em><strong>Important</strong>: this doesn&#8217;t mean you should avoid using <strong>uSES</strong> in your components. It&#8217;s just that, in our case, we&#8217;ve identified it as the issue, and only when rendering hundreds of items.</em></p><h2>offscreenBehavior</h2><p>In addition to working on implementation details, we've added two new experimental props, <strong>offscreenBehavior</strong> and <strong>offscreenRoot</strong>, to the <strong>CollectionItem</strong>, <strong>CompositeItem</strong>, <strong>ComboboxItem</strong>, and <strong>SelectItem</strong> components.</p><p>The <strong>offscreenBehavior</strong> prop determines how the item component behaves when offscreen:</p><ul><li><p><strong>active</strong> (default): No changes occur. The component is fully rendered even when offscreen.</p></li><li><p><strong>passive</strong>: The component is replaced by a super lightweight version when offscreen. Styles and content are rendered, eliminating the need to estimate size or absolutely position the items, while other React computations are skipped. The element is rendered to be accessible to assistive technologies.</p></li><li><p><strong>lazy</strong>: Similar to <strong>passive</strong>, but once the component becomes active, it remains active even when offscreen. You can think of it like the <strong><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/loading#lazy">loading="lazy"</a></strong> attribute on image elements.</p></li></ul><p>Currently, these props are available only when importing components from the experimental <strong>@ariakit/react-core</strong> package:</p><pre><code>import { <strong>SelectItem</strong> } from "<strong>@ariakit/react-core/select/select-item-offscreen</strong>";

&lt;SelectItem
  <strong>offscreenBehavior</strong>="lazy"
  <strong>offscreenRoot</strong>={ref}</code></pre><p>Unlike virtualization, <strong>offscreenBehavior</strong> requires no extra changes to component usage. It is designed to offer the best balance between developer experience and performance.</p><p>However, when rendering thousands of items, full virtualization is unmatched, particularly on low-end devices. That's why we are continually improving our experimental virtualization feature, which you can see in action with the <strong><a href="https://ariakit.org/examples/select-combobox-virtualized">select-combobox-virtualized</a></strong> example.</p><h2>Interaction to Next Paint (INP) numbers</h2><p>We tested rendering a <strong>Combobox</strong> component with 1,000 items on a MacBook Pro M1 with a 4x slowdown in production. Here are the results for different <em>compound</em> component libraries:</p><p><strong>Opening popup (less is better):</strong></p><ol><li><p>Ariakit (virtualized) &#8773; <strong>56 ms</strong></p></li><li><p>Headless UI (virtualized) &#8773; <strong>128 ms</strong></p></li><li><p>Ariakit (offscreenBehavior) &#8773; <strong>168 ms</strong></p></li><li><p>React Aria Components &#8773; <strong>368 ms</strong></p></li><li><p>Ariakit &#8773; <strong>464 ms</strong></p></li><li><p>Radix UI &#8773; <strong>568 ms</strong></p></li><li><p>Headless UI &#8773; <strong>2920 ms</strong></p></li></ol><p><strong>Closing popup (less is better):</strong></p><ol><li><p>Ariakit (virtualized) &#8773; <strong>24 ms</strong></p></li><li><p>Headless UI (virtualized) &#8773; <strong>40 ms</strong></p></li><li><p>Ariakit (offscreenBehavior) &#8773; <strong>48 ms</strong></p></li><li><p>Ariakit &#8773; <strong>120 ms</strong></p></li><li><p>Headless UI &#8773; <strong>128 ms</strong></p></li><li><p>React Aria Components &#8773; <strong>160 ms</strong></p></li><li><p>Radix UI &#8773; <strong>312 ms</strong></p></li></ol><p><strong>Opening, navigating 10 items with arrow keys, then closing (less is better):</strong></p><ol><li><p>Ariakit (virtualized) &#8773; <strong>400 ms</strong></p></li><li><p>Ariakit (offscreenBehavior) &#8773; <strong>536 ms</strong></p></li><li><p>Headless UI (virtualized) &#8773; <strong>568 ms</strong></p></li><li><p>Radix UI &#8773; <strong>880 ms</strong></p></li><li><p>Ariakit &#8773; <strong>984 ms</strong></p></li><li><p>React Aria Components &#8773; <strong>1808 ms</strong></p></li><li><p>Headless UI &#8773; <strong>4088 ms</strong></p></li></ol><h2>Tailwind v4 theme</h2><p>We&#8217;re working on a Tailwind v4 theme with the following features:</p><ul><li><p>Copy and paste</p></li><li><p>Beautiful, accessible, and fully customizable</p></li><li><p>Styles for buttons, dialogs, popover, form controls, and more</p></li><li><p>Autocomplete support similar to other Tailwind utilities</p></li><li><p>Use with any component library: Ariakit, Radix UI, Headless UI, or none at all</p></li><li><p>Use with any framework: React, Vue, Svelte, Solid, or none at all</p></li></ul><p>This will be included in <strong><a href="https://ariakit.org/plus">Ariakit Plus</a></strong>, so subscribing to <strong>Plus</strong> today will also grant you access to this product.</p><p>Stay tuned for upcoming announcements.</p><h2>Ariakit Plus Black Friday &#127881;</h2><p><strong>Ariakit Plus</strong> already has Black Friday discounts, which you can check out at <a href="https://ariakit.org/plus">ariakit.org/plus</a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ariakit.org/plus&quot;,&quot;text&quot;:&quot;Get Ariakit Plus&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ariakit.org/plus"><span>Get Ariakit Plus</span></a></p><p>With <strong>Plus</strong>, you gain access to a growing collection of exclusive examples, including all current and future ones. You'll also have access to the Tailwind v4 theme upon its release.</p><p>Ariakit Plus funds the open-source library and supports its ongoing improvement.</p><h2>We are on Bluesky</h2><p>A significant portion of the developer community is moving from Twitter/X to Bluesky, and we are too.</p><p>You can find us there:</p><ul><li><p><a href="https://bsky.app/profile/ariakit.org">@ariakit.org</a></p></li><li><p><a href="https://bsky.app/profile/haz.dev">@haz.dev</a></p></li><li><p><a href="https://bsky.app/profile/ben.ariakit.org">@ben.ariakit.org</a></p></li></ul><p>We'll keep sharing work in progress and updates about Ariakit there. While we're not leaving Twitter entirely, expect updates to be prioritized on Bluesky.</p><h2>Built with Ariakit</h2><ul><li><p><strong><a href="https://www.highlight.io/">Highlight.io</a></strong> (via email)</p></li><li><p><strong><a href="https://trigger.dev/">Trigger.dev</a></strong> (<a href="https://x.com/mattaitken/status/1787894708326334553">tweeted by Matt</a>)</p></li><li><p><strong><a href="https://www.kadoa.com/">Kadoa.com</a></strong> (<a href="https://x.com/vladstudio/status/1809659194259263630">tweeted by Vladstudio</a>)</p></li><li><p><strong><a href="https://todoist.com/">Todoist.com</a></strong> (<a href="https://x.com/gnapse/status/1796742643063394649">tweeted by Ernesto</a>)</p></li><li><p><strong><a href="https://drawingsalive.com/">DrawingsAlive.com</a></strong> (<a href="https://x.com/gvrizzo/status/1833124155761573961">tweeted by Guilherme</a>)</p></li><li><p><strong><a href="https://chromewebstore.google.com/detail/cleeve/hgeihiegomepfaafkmgglifdnkfehkfj?hl=en">Cleeve.app</a></strong> (<a href="https://x.com/_christian_o/status/1846480286353170823">tweeted by Christian</a>)</p></li></ul><p>If you've created something using Ariakit and want it featured in our next newsletter, just share your work on Bluesky mentioning <a href="https://bsky.app/profile/ariakit.org">@ariakit.org</a>, or reply to this email.</p><h2>More Ariakit</h2><ul><li><p>New releases:</p><p><strong><a href="https://ariakit.org/changelog">v0.4.6 &#8594; v0.4.14</a></strong></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Tabs everywhere]]></title><description><![CDATA[Tabs within Combobox and Select popovers, Tags with multi-selectable Combobox, LinkedIn, new Plus examples and releases.]]></description><link>https://newsletter.ariakit.com/p/tabs-everywhere</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/tabs-everywhere</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Mon, 29 Apr 2024 15:46:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello,</p><p>Over the past few months, we've been developing some thrilling new features for Ariakit. The most significant ones are the <strong><a href="https://twitter.com/diegohaz/status/1772245003609280557">Tag</a></strong><a href="https://twitter.com/diegohaz/status/1772245003609280557"> components</a> and the ability to render <strong>Tabs</strong> within <strong>Combobox</strong> and <strong>Select</strong> popovers.</p><p>In a future post, I'll delve into more details about <strong>Tag</strong> components, which are still in the experimental phase. But for today, let's reintroduce <strong>Tabs</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fRTt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fRTt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 424w, https://substackcdn.com/image/fetch/$s_!fRTt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 848w, https://substackcdn.com/image/fetch/$s_!fRTt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 1272w, https://substackcdn.com/image/fetch/$s_!fRTt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fRTt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png" width="1408" height="792" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a868486a-167c-4cda-b221-944d086137e0_1408x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:792,&quot;width&quot;:1408,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:72979,&quot;alt&quot;:&quot;Screenshot of a custom select widget with a combobox input and tabs inside&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Screenshot of a custom select widget with a combobox input and tabs inside" title="Screenshot of a custom select widget with a combobox input and tabs inside" srcset="https://substackcdn.com/image/fetch/$s_!fRTt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 424w, https://substackcdn.com/image/fetch/$s_!fRTt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 848w, https://substackcdn.com/image/fetch/$s_!fRTt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 1272w, https://substackcdn.com/image/fetch/$s_!fRTt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa868486a-167c-4cda-b221-944d086137e0_1408x792.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A custom Select widget with Combobox and Tabs inside</figcaption></figure></div><p>We've got a couple of new examples that demonstrate how to use <strong>Tabs</strong> in both <strong>Combobox</strong> and <strong>Select</strong> widgets:</p><ul><li><p><strong><a href="https://ariakit.org/examples/combobox-tabs">Combobox with Tabs</a></strong></p></li><li><p><strong><a href="https://ariakit.org/examples/select-combobox-tab">Select with Combobox and Tabs</a></strong></p></li></ul><p>In short, just render the <strong>Tab</strong> components inside a <strong>Combobox</strong> or <strong>Select</strong> popover, and Ariakit will automatically adjust roles and other ARIA attributes. This ensures the widget is accessible for mouse, touch, keyboard, and assistive technology users:</p><pre><code>&lt;ComboboxProvider&gt;
  &lt;Combobox /&gt;
  &lt;ComboboxPopover&gt;
    &lt;<strong>TabProvider</strong>&gt;
      &lt;<strong>TabList</strong>&gt;
        &lt;<strong>Tab</strong> /&gt;
      &lt;/<strong>TabList</strong>&gt;
      &lt;<strong>TabPanel</strong> unmountOnHide&gt;
        &lt;ComboboxList&gt;
          &lt;ComboboxItem /&gt;
        &lt;/ComboboxList&gt;
      &lt;/<strong>TabPanel</strong>&gt;
    &lt;/<strong>TabProvider</strong>&gt;
  &lt;/ComboboxPopover&gt;
&lt;/ComboboxProvider&gt;</code></pre><p>Ensure the <strong>TabPanel</strong> component is dynamically rendered. You can achieve this either by using the <strong><a href="https://ariakit.org/reference/tab-panel#unmountonhide">unmountOnHide</a></strong> prop or by <a href="https://ariakit.org/examples/tab-next-router#rendering-a-single-tabpanel">rendering a single </a><strong><a href="https://ariakit.org/examples/tab-next-router#rendering-a-single-tabpanel">TabPanel</a></strong> with dynamic content that changes according to the currently selected tab.</p><h2>We are on LinkedIn</h2><p>Ariakit is now also on LinkedIn: <a href="https://www.linkedin.com/company/ariakit/">https://www.linkedin.com/company/ariakit/</a></p><p>We'll share announcements, experiments, and ongoing projects there. If you're active on LinkedIn and this topic sparks your curiosity, we'd value your follow. Interacting with and liking our posts will help us spread the word. &#10084;&#65039;</p><h2>Built with Ariakit</h2><ul><li><p><strong><a href="https://relative-ci.com/">RelativeCI</a></strong> (<a href="https://twitter.com/vio/status/1768963250866053430">tweeted by Vio</a>)</p></li></ul><p>If you've created something using Ariakit and want it featured in our next newsletter, just share your work on Twitter mentioning <a href="https://twitter.com/ariakitjs">@ariakitjs</a>, or reply to this email.</p><h2>More Ariakit</h2><ul><li><p><strong>New</strong> examples:<strong><br><a href="https://ariakit.org/examples/select-next-router">Select with Next.js App Router</a> </strong>(<strong>Plus</strong>)<br><strong><a href="https://ariakit.org/examples/tab-panel-animated">Animated TabPanel</a></strong> (<strong>Plus</strong>)<br><strong><a href="https://ariakit.org/examples/disclosure-animated">Animated Disclosure</a></strong> (<strong>Plus</strong>)<br><strong><a href="https://ariakit.org/examples/select-combobox-tab">Select with Combobox and Tabs</a></strong> (<strong>Plus</strong>)</p></li><li><p>Improved examples:</p><p><strong><a href="https://ariakit.org/examples/combobox-animated">Animated Combobox</a><br><a href="https://ariakit.org/examples/dialog-animated">Animated Dialog</a><br><a href="https://ariakit.org/examples/select-animated">Animated Select</a><br><a href="https://ariakit.org/examples/combobox-tabs">Combobox with Tabs</a></strong> (<strong>Plus</strong>)</p></li><li><p>New releases:</p><p><strong><a href="https://ariakit.org/changelog">v0.4.1 &#8594; v0.4.6</a></strong></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Animation, Ariakit Plus, and more]]></title><description><![CDATA[Improved CSS transition and animation support, Ariakit Plus with lifetime access, Combobox with Tabs, Command Menu, and more.]]></description><link>https://newsletter.ariakit.com/p/animation-ariakit-plus-and-more</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/animation-ariakit-plus-and-more</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Mon, 05 Feb 2024 14:31:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/aa9ad63d-93cf-4822-ab91-c9fd4424bedb_740x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone,</p><p><strong><a href="https://ariakit.org/changelog#040">Ariakit v0.4.0</a></strong> has improved support for CSS transitions and animations. To animate <strong>Dialog</strong>, <strong>Popover</strong>, <strong>Menu</strong>, <strong>Tooltip</strong>, and other popup components, you can simply add CSS transitions or animations using the <strong>[data-open]</strong>, <strong>[data-enter]</strong>, and <strong>[data-leave]</strong> selectors.</p><p>If an animation is detected, the component will automatically wait for the exit animation to finish before hiding itself or removing it from the DOM:</p><pre><code>.dialog {
  opacity: 0;
  <strong>transition</strong>: opacity 0.3s;
}

.dialog<strong>[data-enter]</strong> {
  opacity: 1;
}</code></pre><p>This also works seamlessly with libraries like <a href="https://github.com/jamiebuilds/tailwindcss-animate">tailwindcss-animate</a>:</p><pre><code>&lt;Dialog className="
  <strong>data-[open]</strong>:animate-in
  <strong>data-[open]</strong>:fade-in
  <strong>data-[leave]</strong>:animate-out
  <strong>data-[leave]</strong>:fade-out
"&gt;</code></pre><p>Previously, we only supported CSS transitions (not animations), and it was necessary to explicitly pass an <strong>animated</strong> prop to the component provider or store to enable this behavior. They're both supported right out of the box now.</p><p>Check out the <a href="https://ariakit.org/changelog#040">release notes</a> to learn more.</p><h2>Ariakit Plus with lifetime access</h2><p><strong><a href="https://ariakit.org/plus">Ariakit Plus</a></strong> grants you access to exclusive content and features on the site.</p><p>In response to popular demand, it is now available as a <strong>one-time purchase</strong>. This includes <strong>free lifetime updates</strong>. Get access to all examples available today, as well as those planned for the future, which includes full-featured templates.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ariakit.org/plus&quot;,&quot;text&quot;:&quot;Get Ariakit Plus&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ariakit.org/plus"><span>Get Ariakit Plus</span></a></p><div><hr></div><h3>For existing subscribers</h3><p>If you're already a monthly or yearly subscriber, don&#8217;t worry, nothing has changed.</p><p>But if you're interested in getting <strong>Ariakit Plus</strong> with lifetime access, a discount awaits you. Simply visit <strong><a href="https://ariakit.org/plus">ariakit.org/plus</a></strong> and sign in with your account. The discount is applied automatically.</p><p>After you complete your purchase, there's no need for further action. Your subscription will automatically transition to lifetime access, and future charges will stop.</p><p>If you have any questions about <strong>Ariakit Plus</strong>, feel free to contact <strong><a href="mailto:support@ariakit.org">support@ariakit.org</a></strong></p><h2>Built with Ariakit</h2><ul><li><p><strong><a href="https://attio.com">Attio</a></strong> (<a href="https://twitter.com/alex_krasikau/status/1732368303316668757">tweeted by Alex Krasikau</a>)</p></li><li><p><strong><a href="https://www.flowapp.so">Flow</a></strong> (<a href="https://twitter.com/d2ac__/status/1736317986913575055">tweeted by Daniel</a>)</p></li></ul><p>If you've created something using Ariakit and want it featured in our next newsletter, just share your work on Twitter/X mentioning <a href="https://twitter.com/ariakitjs">@ariakitjs</a>, or reply to this email.</p><h2>More Ariakit</h2><ul><li><p><strong>New</strong> examples:<br><strong><a href="https://ariakit.org/examples/combobox-radix">Radix Combobox</a><br><a href="https://ariakit.org/examples/menu-nested-combobox">Submenu with Combobox</a> </strong>(<strong>Plus</strong>)<strong><br><a href="https://ariakit.org/examples/combobox-tabs">Combobox with Tabs</a> </strong>(<strong>Plus</strong>)<br><strong><a href="https://ariakit.org/examples/combobox-radix-select">Radix Select with Combobox</a><br><a href="https://ariakit.org/examples/dialog-combobox-command-menu">Command Menu</a> </strong>(<strong>Plus</strong>)</p></li><li><p>Improved examples:</p><p><strong><a href="https://ariakit.org/examples/combobox-multiple">Multi-selectable Combobox</a></strong></p></li><li><p>Improved docs:</p><p><strong><a href="https://ariakit.org/guide/composition#merging-the-rendered-element-props">Guide: Composition</a><br><a href="https://ariakit.org/guide/styling#data-user-value">Guide: Styling</a><br><a href="https://ariakit.org/reference#combobox">API Reference: Combobox</a></strong></p></li><li><p>New releases:</p><p><strong><a href="https://ariakit.org/changelog">v0.3.8 &#8594; v0.4.1</a></strong></p></li></ul><h2>More Dev</h2><ul><li><p><a href="https://twitter.com/diegohaz/status/1754051815249781174">Do you struggle to execute </a><strong><a href="https://twitter.com/diegohaz/status/1754051815249781174">long-term plans</a></strong><a href="https://twitter.com/diegohaz/status/1754051815249781174">?</a><br><em>What's the next little thing you can do today that will help you make even a slight progress towards your ultimate goal?</em></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Ariakit Plus]]></title><description><![CDATA[I'm excited to announce Ariakit Plus, a subscription program that provides additional benefits to anyone who interacts with Ariakit in any way.]]></description><link>https://newsletter.ariakit.com/p/ariakit-plus</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/ariakit-plus</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Wed, 29 Nov 2023 14:41:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!y4DB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10c70c7a-0bd3-4a17-80ad-30d4a8fb847e_1000x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone,</p><p>This month, I'm thrilled to announce <strong><a href="https://ariakit.org/plus">Ariakit Plus</a></strong>.</p><p><strong>Ariakit Plus</strong> is a subscription program that offers extra perks to those who engage with Ariakit in any way, be it through using the npm library, perusing the documentation, or simply drawing inspiration from the <a href="https://ariakit.org/examples">examples</a>.</p><p>As the name suggests, it's an enhancement to the abundant free resources already provided by Ariakit.</p><p>I've spent several months designing this model and only implemented it when I, as a project user myself, was completely convinced that I would sign up as a customer.</p><h2>What&#8217;s included</h2><h3>Access new examples</h3><p>The Ariakit website currently showcases <a href="https://ariakit.org/examples">48 examples</a> that demonstrate a wide array of use cases for all Ariakit components. We'll continue expanding this collection with common and advanced use cases. <strong>Ariakit Plus</strong> will help us in doing this sustainably, providing added motivation to create top-notch recipes with comprehensive instructions.</p><p>Several of the upcoming examples, particularly the advanced ones, will be exclusive to <strong>Plus</strong> members. As I write this newsletter, we already have three <strong>Plus</strong> examples ready for your enjoyment:</p><ul><li><p><strong><a href="https://ariakit.org/examples/menubar-navigation">Navigation Menubar</a><br></strong>Using <a href="https://ariakit.org/components/menubar">Menubar</a>, <a href="https://ariakit.org/components/menu">Menu</a>, and <a href="https://ariakit.org/components/portal">Portal</a> to create an accessible, tabbable navigation menu widget with links and menu buttons that expand on hover and focus.</p></li><li><p><strong><a href="https://ariakit.org/examples/combobox-filtering-integrated">Combobox with integrated filter</a></strong><br>Filtering options in a <a href="https://ariakit.org/components/combobox">Combobox</a> component through an abstracted implementation using React.useDeferredValue, resulting in a simple higher-level API.</p></li><li><p><strong><a href="https://ariakit.org/examples/dialog-hide-warning">Warning on Dialog hide</a></strong><br>Preventing users from accidentally closing a modal <a href="https://ariakit.org/components/dialog">Dialog</a> component with unsaved changes by displaying a nested confirmation dialog.</p></li></ul><p>If you're reading this newsletter at a later time, you can use the <strong><a href="https://ariakit.org/tags/new">New</a></strong> tag to see all <strong>Plus</strong> examples.</p><p>With <strong>Ariakit Plus</strong>, you can access the source code of these examples and detailed documentation that allows you to dive deeper into their specifics:</p><ul><li><p>Discover why and how we made the menubar items tabbable.</p></li><li><p>Understand how we used a single Menu popover element for multiple menu buttons to implement a plain CSS transition when changing between menus.</p></li><li><p>Learn the process of displaying menus on hover and focus.</p></li><li><p>Get insights on rendering the ComboboxItem component dynamically based on the search value.</p></li><li><p>Find out how to prevent a Dialog from closing when there are unsaved changes.</p></li><li><p>Learn to re-trigger the auto-focus behavior using the autoFocusOnShow prop.</p></li></ul><h3>And more</h3><ul><li><p><strong>Edit examples</strong><br>Edit examples in the browser using Vite and Next.js without having to install anything. Reproduce issues or quickly test something out using an existing example as a starting point.</p></li><li><p><strong>Preview API docs</strong><br>You can quickly preview detailed API documentation by hovering over site links. No more need to navigate away from the current page.</p></li></ul><h2>Do not worry</h2><p>If you decide to cancel your subscription, it won't automatically renew, but you'll still have access until the end of the current billing period.</p><p>If you have any problems during this process, feel free to reach out to me at hazdiego@gmail.com</p><h2>More Ariakit</h2><ul><li><p><strong><a href="https://twitter.com/diegohaz/status/1711064102515114452">Dialog</a></strong><a href="https://twitter.com/diegohaz/status/1711064102515114452"> has now an API that's similar to the native HTML dialog element</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1712955308132192540">50 bugs were reported and all of them had a </a><strong><a href="https://twitter.com/diegohaz/status/1712955308132192540">workaround</a></strong></p></li><li><p><a href="https://twitter.com/diegohaz/status/1727766643730784499">The </a><strong><a href="https://twitter.com/diegohaz/status/1727766643730784499">blurOnHoverEnd</a></strong><a href="https://twitter.com/diegohaz/status/1727766643730784499"> prop</a></p></li><li><p>Improved examples:</p><p><strong><a href="https://ariakit.org/examples/dialog-menu">Dialog with Menu</a></strong></p></li><li><p>Improved docs:</p><p><strong><a href="https://ariakit.org/examples/dialog-nested">Nested Dialog</a></strong></p></li><li><p>New releases:</p><p><strong><a href="https://github.com/ariakit/ariakit/blob/aaf9b01a7c6f0d229f2b962e5418705415cd01b9/packages/ariakit-react/CHANGELOG.md">v0.3.4 &#8594; v0.3.7</a></strong></p></li></ul><h2>More Dev</h2><ul><li><p><strong><a href="https://twitter.com/diegohaz/status/1718790616459489368">Server Actions</a></strong><a href="https://twitter.com/diegohaz/status/1718790616459489368"> can return server and client components</a></p></li><li><p><strong><a href="https://twitter.com/diegohaz/status/1725046677231304804">Safari</a></strong><a href="https://twitter.com/diegohaz/status/1725046677231304804"> is finally fixing combobox</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Component providers]]></title><description><![CDATA[Provide state to Ariakit components using a simple wrapper that supports controlled and uncontrolled props.]]></description><link>https://newsletter.ariakit.com/p/component-providers</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/component-providers</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Wed, 04 Oct 2023 14:48:08 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/88d129a5-df1d-4f26-8d78-7746ef8a5d82_784x588.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone,</p><p>This month, we're rolling out a new feature for Ariakit: <strong><a href="https://ariakit.org/guide/component-providers">Component providers</a></strong>.</p><p>Component providers are optional components that act as a higher-level API on top of <strong><a href="https://ariakit.org/guide/component-stores">component stores</a></strong>. They wrap Ariakit components and automatically provide a store to them.</p><p>You no longer need to manually create a store and pass it as a prop to the components. Instead, you can just wrap the components with a provider:</p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/951aa41b-1d4c-42ee-92da-2a0ed2843f72_742x848.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9546283e-ee34-41b9-b4e3-9868f77a1c5a_826x944.png&quot;}],&quot;caption&quot;:&quot;Component stores vs. component providers&quot;,&quot;alt&quot;:&quot;Two snippets of code: one using Ariakit component stores, where the useComboboxStore hook is used and the returned store object is passed to the Combobox and ComboboxPopover components; and another one using component providers, where the ComboboxProvider component is wrapping both Combobox and ComboboxPopover, and no explicit store prop must be passed.&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3ef6eb11-9a2f-44e7-8310-a804fc69e8db_1456x720.png&quot;}},&quot;isEditorNode&quot;:true}"></div><p>Component providers take the same props as component stores, allowing you to use them in the same manner with both <strong><a href="https://ariakit.org/guide/component-providers#controlled-state">controlled</a></strong> and <strong><a href="https://ariakit.org/guide/component-providers#default-state">uncontrolled</a></strong> APIs. </p><p>They also accept a <strong><a href="https://ariakit.org/guide/component-providers#passing-a-store">store</a></strong> prop, enabling you to use component stores and component providers in tandem.</p><p>It's important to note that component stores aren&#8217;t going anywhere, and you <strong>do not</strong> need to migrate your code. They will continue to serve as a fundamental lower-level API.</p><p>In addition to the providers, we're also introducing context hooks such as <strong><a href="https://ariakit.org/reference/use-combobox-context">useComboboxContext</a></strong>. This allows you to access the store from within components nested in providers and other top-level components like <strong><a href="https://ariakit.org/reference/combobox">Combobox</a></strong> and <strong><a href="https://ariakit.org/reference/combobox-popover">ComboboxPopover</a></strong>.</p><p>You can learn more about the work and the rationale behind this feature in the <strong><a href="https://github.com/ariakit/ariakit/issues/2658">Component providers RFC</a></strong>, authored by <a href="https://dio.la/">Dani Guardiola</a>.</p><h2>Built with Ariakit</h2><ul><li><p><strong><a href="https://nozzle.io">Nozzle</a></strong> (<a href="https://twitter.com/tannerlinsley/status/1708531703206293747">tweeted by Tanner Linsley</a>)</p></li><li><p><strong><a href="https://chrome.google.com/webstore/detail/rsc-devtools/jcejahepddjnppkhomnidalpnnnemomn">RSC Devtools</a> </strong>(<a href="https://twitter.com/alvarlagerlof/status/1692998609501864167">tweeted by Alvar Lagerl&#246;f</a>)</p></li><li><p><strong><a href="https://www.welcome-ui.com/">Welcome UI</a> </strong>(<a href="https://twitter.com/theomesnil/status/1697234192269005188">tweeted by Th&#233;o Mesnil</a>)</p></li></ul><p>If you've created something using Ariakit and want it featured in our next newsletter, just share your work on Twitter mentioning <a href="http://If you've created something using Ariakit and want it featured in our upcoming newsletter, just share your work on Twitter and tag @ariakitjs, or respond to this email.">@ariakitjs</a>, or reply to this email.</p><h2>More Ariakit</h2><ul><li><p><strong>New</strong> example: <strong><a href="https://ariakit.org/examples/dialog-hide-warning">Warning on Dialog hide</a><br></strong>Preventing users from accidentally closing a modal with unsaved changes by displaying a nested confirmation dialog.</p></li><li><p>Improved examples:</p><p><strong><a href="https://ariakit.org/examples/menu-nested">Submenu</a><br><a href="https://ariakit.org/examples/select-animated">Animated Select</a><br><a href="https://ariakit.org/examples/tab-react-router">Tab with React Router</a><br><a href="https://ariakit.org/examples/tab-next-router">Tab with Next.js App Router</a><br><a href="https://ariakit.org/examples/toolbar-select">Toolbar with Select</a></strong></p></li><li><p>Improved docs:</p><p><strong><a href="https://ariakit.org/reference/command">Command</a></strong></p></li><li><p>New releases:</p><p><strong><a href="https://github.com/ariakit/ariakit/blob/ca6a8ace3c0dcdb0e15782fd2c81099e71811fda/packages/ariakit-react/CHANGELOG.md">v0.2.17 &#8594; v0.3.3</a></strong></p></li></ul><h2>More Dev</h2><ul><li><p><a href="https://twitter.com/diegohaz/status/1691175190481211393">A better </a><strong><a href="https://twitter.com/diegohaz/status/1691175190481211393">setTimeout</a></strong></p></li><li><p><strong><a href="https://twitter.com/diegohaz/status/1691195240957239296">addGlobalEventListener</a></strong></p></li></ul>]]></content:encoded></item><item><title><![CDATA[All things]]></title><description><![CDATA[Ariakit now features tag pages where you can discover all content related to specific topics such as Combobox, Form controls, Dropdowns, Concurrent React, and more.]]></description><link>https://newsletter.ariakit.com/p/all-things</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/all-things</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Mon, 14 Aug 2023 14:07:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!y4DB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10c70c7a-0bd3-4a17-80ad-30d4a8fb847e_1000x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dear readers,</p><p>Have you ever felt overwhelmed while working on a specific component or page in your web app, constantly switching between numerous documentation pages?</p><p>Ariakit might have several related pages that are scattered. For example, we have separate <a href="https://ariakit.org/components/combobox">Component</a>, <a href="https://ariakit.org/examples#combobox">Examples</a>, and <a href="https://ariakit.org/reference#combobox">Reference</a> pages for the Combobox module alone. Some examples aren't even included in the Combobox section as they're part of different components, such as <a href="https://ariakit.org/examples/menu-combobox">Menu with Combobox</a> or <a href="https://ariakit.org/examples/select-combobox">Select with Combobox</a>. Finding exactly what you need can be a challenge.</p><p>To assist with this, Ariakit now features tag pages. If you're working with Combobox, you can access all related Combobox content from a single page: <strong><a href="https://ariakit.org/tags/combobox">All things Combobox</a></strong>.</p><p>Working with Framer Motion? Discover all related content on the <strong><a href="https://ariakit.org/tags/framer-motion">All things Framer Motion</a></strong> page.</p><p>Dealing with form controls? <strong><a href="https://ariakit.org/tags/form-controls">All things Form controls</a></strong> has you covered.</p><p>You'll find more tags at the top of each content page. If you notice any potentially useful ones missing, don't hesitate to suggest them by replying to this email or opening an issue.</p><h2>Code block links</h2><p>The Ariakit docs now include links to API reference pages within code blocks. If you're browsing the code examples on the site and want to explore a specific API further, simply click on the function, component, or property name to go to the API reference page.</p><h2>RFC: Component providers</h2><p>Ariakit has a new Request for Comments (RFC) for component providers. The proposal aims to simplify the use of component stores by abstracting them into higher-level provider components. This approach eliminates the need to explicitly instantiate component stores and pass them as props to components, <strong>without introducing any breaking changes</strong>.</p><p>If you believe this feature could assist in improving your code, we welcome your feedback on the <a href="https://github.com/ariakit/ariakit/issues/2658">RFC issue</a>.</p><h2>More Ariakit</h2><ul><li><p><strong>New</strong> guide: <strong><a href="https://ariakit.org/guide/coding-guidelines">Coding guidelines</a></strong></p><p>TypeScript <strong>type</strong> vs. <strong>interface</strong>, <strong>forwardRef</strong>, <strong>displayName</strong>, and more</p></li><li><p><strong>New</strong> example: <strong><a href="https://ariakit.org/examples/menu-tooltip">Menu with Tooltip</a></strong></p><p>With an abstracted API similar to the <a href="https://github.com/ariakit/ariakit/issues/2658">component providers RFC</a></p></li><li><p><strong>New</strong> example: <strong><a href="https://ariakit.org/examples/combobox-filtering">Combobox filtering</a></strong></p><p>Using React.startTransition</p></li><li><p>Improved examples:</p><p><strong><a href="https://ariakit.org/examples/combobox-links">Combobox with links</a></strong></p><p><strong><a href="https://ariakit.org/examples/combobox-multiple">Multi-selectable Combobox</a></strong></p><p><strong><a href="https://ariakit.org/examples/combobox-animated">Animated Combobox</a></strong></p><p><strong><a href="https://ariakit.org/examples/combobox-cancel">ComboboxCancel</a></strong></p><p><strong><a href="https://ariakit.org/examples/combobox-disclosure">ComboboxDisclosure</a></strong></p><p><strong><a href="https://ariakit.org/examples/combobox-group">ComboboxGroup</a></strong></p></li><li><p>Improved docs:</p><p><strong><a href="https://ariakit.org/guide/getting-started">Getting started</a></strong></p><p><strong><a href="https://ariakit.org/components/button">Button</a></strong></p><p><strong><a href="https://ariakit.org/components/checkbox">Checkbox</a></strong></p><p><strong><a href="https://ariakit.org/reference/focusable">Focusable</a></strong></p></li><li><p>New releases:</p><p><strong><a href="https://github.com/ariakit/ariakit/blob/2cb8de3245dc85d70eefa6ed2e3a01d0b420f33c/packages/ariakit-react/CHANGELOG.md">v0.2.13 &#8594; v0.2.16</a></strong></p></li></ul><h2>More Dev</h2><ul><li><p><strong><a href="https://twitter.com/diegohaz/status/1685159682187399168">URL pagination</a></strong><a href="https://twitter.com/diegohaz/status/1685159682187399168">: use links, not buttons</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1688922839582408704">Nice Tailwind </a><strong><a href="https://twitter.com/diegohaz/status/1688922839582408704">&lt;kbd&gt;</a></strong><a href="https://twitter.com/diegohaz/status/1688922839582408704"> styles</a></p><p>Here are the <a href="https://twitter.com/diegohaz/status/1688924154974937088">class names</a> for copy and paste</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Stable]]></title><description><![CDATA[Ariakit is now stable. If you have been waiting to integrate Ariakit into your project, I can finally recommend it for production use.]]></description><link>https://newsletter.ariakit.com/p/stable</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/stable</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Wed, 05 Jul 2023 13:34:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!y4DB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10c70c7a-0bd3-4a17-80ad-30d4a8fb847e_1000x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dear readers,</p><p>I&#8217;m delighted to announce that the <a href="https://www.npmjs.com/package/@ariakit/react">ariakit</a> npm package is now stable (<a href="https://gist.github.com/diegohaz/bc07491aee61a5f2469574b38c5c1aa0">What is Ariakit?</a>). If you&#8217;ve been eagerly awaiting the ideal opportunity to integrate Ariakit into your project, I can finally recommend it for production use. It&#8217;s already been successfully used by amazing projects such as <a href="https://wordpress.org">WordPress</a>, <a href="https://todoist.com">Todoist</a>, <a href="https://www.guide.co">Guide</a>, <a href="https://croct.com">Croct</a>, and <a href="https://github.com/ariakit/ariakit/discussions/1661">many others</a>.</p><p>This means that Ariakit now follows semantic versioning and will introduce fewer breaking changes. Whenever feasible, these changes will be preceded by soft deprecations, followed by deprecation warnings before the actual breaking change occurs.</p><h2>Ariakit is antifragile</h2><p>Over the past year, numerous bugs have been reported, and all of them could be resolved in userland before a fix was implemented in the library. By inspecting the <a href="https://github.com/ariakit/ariakit/issues?q=is%3Aissue+label%3A%22bug%22+is%3Aclosed+">closed bugs</a> in the repository, you will notice that each of them is labeled with &#8220;<strong>has workaround</strong>&#8221;.</p><p>This means that you don&#8217;t have to wait for a general solution to be proposed, discussed, implemented, tested, reviewed, merged, and published to npm in order to address your specific issue and move forward, delivering amazing features to your clients.</p><p>As both a maintainer and consumer of the project, I&#8217;m pleased that I can quickly fix any bug I encounter while using Ariakit in my apps without having to go through the entire process of figuring out a suitable solution. This not only saves time but also contributes to finding the proper fix.</p><p>When we address a bug report or feature request in the project, we create an example accessible in the browser and make sure it&#8217;s automatically tested on every commit to the library. This approach ensures that we don&#8217;t introduce any regressions in the future.</p><h2>This isn&#8217;t an official announcement yet</h2><p>The library is still being released as v0.x.x. This is because I intend to synchronize an official release with the launch of the <a href="https://ariakit.org">ariakit.org</a> website. Stay tuned!</p><h2>More Ariakit</h2><ul><li><p><strong><a href="https://twitter.com/diegohaz/status/1676187883781214209">ariakit.org</a></strong><a href="https://twitter.com/diegohaz/status/1676187883781214209"> now has searchable API docs</a></p></li><li><p><strong><a href="https://ariakit.org/examples/dialog-radix">New</a></strong><a href="https://ariakit.org/examples/dialog-radix"> example: Radix UI Dialog</a></p></li><li><p><strong><a href="https://ariakit.org/examples/dialog-backdrop-scrollable">New</a></strong><a href="https://ariakit.org/examples/dialog-backdrop-scrollable"> example: Dialog with a scrollable backdrop</a></p></li><li><p><a href="https://ariakit.org/examples/menu-item-checkbox">Updated example: MenuItemCheckbox</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1663435844324130822">Complex example: Menu and Select</a></p></li><li><p><a href="https://ariakit.org/guide/composition">Updated guide: Composition</a></p></li></ul><h2>More Dev</h2><ul><li><p><strong><a href="https://twitter.com/diegohaz/status/1662671157978447872">React</a></strong><a href="https://twitter.com/diegohaz/status/1662671157978447872"> effects, events, queueMicrotask, and requestAnimationFrame</a></p></li><li><p><strong><a href="https://twitter.com/diegohaz/status/1667197904006569991">TypeScript</a></strong><a href="https://twitter.com/diegohaz/status/1667197904006569991"> tip: an alternative to filter(Boolean)</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1673052314393772032">New experimental accessibility feature on Chrome DevTools</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Composition]]></title><description><![CDATA[Composition makes Ariakit components more versatile, allowing you to easily replace the default HTML element or enhance its features with custom components.]]></description><link>https://newsletter.ariakit.com/p/composition</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/composition</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Thu, 25 May 2023 15:45:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!y4DB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10c70c7a-0bd3-4a17-80ad-30d4a8fb847e_1000x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dear readers,</p><p>This month we&#8217;ve introduced a new <strong><a href="https://ariakit.org/guide/composition">Composition</a></strong> guide to the Ariakit documentation. This guide offers detailed explanations on using the polymorphic <strong><a href="https://ariakit.org/guide/composition#as">as</a></strong> prop and introduces the new <strong><a href="https://ariakit.org/guide/composition#render">render</a></strong> prop, which aims to simplify the abstraction and extension of Ariakit components with an explicit API:</p><pre><code>&lt;<strong>TooltipAnchor</strong>
  title="Open menu"
  <strong>render</strong>={(props) =&gt; &lt;<strong>MenuButton</strong> {...props} /&gt;}
&gt;
  Menu
&lt;/<strong>TooltipAnchor</strong>&gt;</code></pre><p>By leveraging the <strong>render</strong> prop, you can create higher-level APIs that provide the same level of flexibility as any Ariakit component, all without having to handle the intricacies of TypeScript and the <strong>as</strong> prop.</p><p>For a practical demonstration of the <strong>render</strong> prop in action, I encourage you to explore the <a href="https://ariakit.org/examples/tooltip-framer-motion">Tooltip with Framer Motion</a> example. This example demonstrates how the <strong>render</strong> prop enables rendering the tooltip anchor as a link.</p><p>Thank you for your continued support, and happy exploring!</p><h2>More Ariakit</h2><ul><li><p><strong><a href="https://ariakit.org/examples/dialog-nested">New</a></strong><a href="https://ariakit.org/examples/dialog-nested"> example: Nested modal dialogs</a></p></li><li><p><strong><a href="https://ariakit.org/examples/dialog-next-router">New</a></strong><a href="https://ariakit.org/examples/dialog-next-router"> example: Modal dialog with Next.js App Router</a></p></li><li><p><strong><a href="https://ariakit.org/examples/tab-next-router">New</a></strong><a href="https://ariakit.org/examples/tab-next-router"> example: Tabs with Next.js App Router</a></p></li><li><p><strong><a href="https://ariakit.org/examples/tooltip-framer-motion">New</a></strong><a href="https://ariakit.org/examples/tooltip-framer-motion"> example: Animated tooltip with Framer Motion</a></p></li><li><p><strong><a href="https://ariakit.org/examples/checkbox-custom">New</a></strong><a href="https://ariakit.org/examples/checkbox-custom"> example: Checkbox with custom styles</a></p></li><li><p><a href="https://ariakit.org/examples/menu-framer-motion">Updated example: Animated dropdown menu with Framer Motion</a></p></li><li><p><a href="https://ariakit.org/examples/tab-react-router">Updated example: Tabs with React Router</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1652648620330549248">Simple Dialog/Menu higher-level API</a></p></li><li><p><a href="https://ariakit.org/guide/component-stores#using-react-context">Using React Context with component stores</a></p></li></ul><h2>More Dev</h2><ul><li><p><a href="https://twitter.com/diegohaz/status/1650894386736119809">Vitest (alternative to Jest) supports importing CSS files</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1659075295524134912">Automated screen reader testing</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Component stores]]></title><description><![CDATA[Dear readers,]]></description><link>https://newsletter.ariakit.com/p/component-stores</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/component-stores</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Mon, 17 Apr 2023 11:42:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!y4DB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10c70c7a-0bd3-4a17-80ad-30d4a8fb847e_1000x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dear readers,</p><p>I&#8217;m excited to share with you the latest updates on Ariakit.</p><blockquote><p><em>As some of you may know, earlier this year, <a href="https://www.getrevue.co/">Revue was shut down</a>. I migrated this newsletter to <a href="https://newsletter.ariakit.org">Substack</a>. Please do let me know if you encounter any issues.</em></p></blockquote><p>In recent months, I posted a Request for Comments (RFC) on the Ariakit repository, proposing to replace state hooks like <code>useComboboxState</code> with component stores:</p><pre><code>import {
  <strong>useComboboxStore</strong>,
  Combobox,
  ComboboxPopover
} from "<strong>@ariakit/react</strong>"

function MyCombobox() {
  const combobox = <strong>useComboboxStore()</strong>
  return (
    &lt;&gt;
      &lt;Combobox <strong>store={combobox}</strong> /&gt;
      &lt;ComboboxPopover <strong>store={combobox}</strong>&gt;
        ...
      &lt;/ComboboxPopover&gt;
    &lt;/&gt;
  )
}</code></pre><p>This approach has numerous advantages over the old one, such as the ability to reuse state logic outside of React, prevent unnecessary re-renders, and better integration with React&#8217;s <code>useEffect</code>.</p><p>I&#8217;m thrilled to announce that this feature has finally landed. You can learn more about it on the <a href="https://github.com/ariakit/ariakit/issues/1875">RFC</a> or the dedicated <a href="https://ariakit.org/guide/component-stores">Component stores</a> page on <a href="https://ariakit.org">ariakit.org</a>.</p><h2>New package names</h2><p>As part of this update, we&#8217;ve also changed the npm packages to include the <code>@ariakit</code> scope. You can expect to see new packages, such as <code>@ariakit/dom</code> and <code>@ariakit/vue</code>, in the future.</p><p>Furthermore, we&#8217;ve changed the versioning system from <code>v2.0.0-beta.x</code> to <code>v0.x.x</code>. This change ensures that projects that don&#8217;t set the exact version of the dependency on <code>package.json</code> won&#8217;t experience unnecessary breakages due to breaking changes released between beta versions.</p><h2>More Ariakit</h2><ul><li><p><a href="https://twitter.com/ariakitjs/status/1547942602778877952">Ariakit has a new logo &#10024;</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1646337146444193795">Test files on Ariakit are now framework-agnostic</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1647198461262004229">Test Ariakit examples on Next.js directly from the site</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1536775509190778882">Contribute to Ariakit directly from the browser using Gitpod</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1545419735751335941">Building a multi-level sliding menu with Ariakit and CSS Scroll Snap</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1551476114027069441">Ariakit has workaround</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1553744035772235783">Fixing bad UX with Ariakit Hovercard</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1555599281523941376">Use the browser&#8217;s built-in search to focus on ComboboxItem</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1559913093773365248">Improved support for links on Ariakit comboboxes</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1564646984107048970">The unconventional navigation on ariakit.org</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1564999224969797635">Improved support for auto-select and inline auto-completion on Combobox</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1569680550452944896">API ideas for a vanilla JS version of Ariakit</a></p></li></ul><h2>More Dev</h2><ul><li><p><a href="https://twitter.com/diegohaz/status/1546112249147887616">Detect DOM element direction (ltr/rtl)</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1534888291732013058">Performance: Map vs. plain objects</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1542504728487088131">Easy way to detect if the focus is leaving an element</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1546833250043166720">Using the hover media query to improve touch UX</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1560257032422187009">The problem with the autoFocus prop on React</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1561036326849372163">The best fuzzy-search library</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1562097407013359616">Using Unicode regular expressions to match any language</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1590043504428077056">Render diagrams on GitHub using markdown</a> (my most popular tweet &#128561;)</p></li><li><p><a href="https://twitter.com/diegohaz/status/1591114210766831616">Render maps on GitHub using markdown</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1585879346350284801">Naming groups in regular expressions for better readability</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1591829631811846147">Always underline links within paragraphs</a> (I wish I could do this on Substack)</p></li><li><p><a href="https://twitter.com/diegohaz/status/1604834676945846274">Why you should use interface instead of type to document APIs in TypeScript</a></p></li></ul><p></p>]]></content:encoded></item><item><title><![CDATA[Virtualization]]></title><description><![CDATA[UPDATE: We're testing an experimental virtualization feature.]]></description><link>https://newsletter.ariakit.com/p/virtualization</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/virtualization</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Wed, 08 Jun 2022 13:44:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!TsBl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>UPDATE: We're testing an experimental virtualization feature. Feel free to use this unlisted example as a starting point: <a href="https://ariakit.org/examples/select-combobox-virtualized">select-combobox-virtualized</a>. I welcome you to try it and provide feedback. However, remember that the API is currently in the experimental phase and is likely to change soon.</em></p><p>Do you know what <code>Combobox</code>, <code>Menu</code>, <code>Radio</code>, <code>Select</code>, <code>Tab</code>, and <code>Toolbar</code> have in common? They all take advantage of the powerful <a href="https://ariakit.org/components/composite">Composite</a> component.</p><p>Those components may render multiple elements. Ariakit is already optimized to render hundreds of composite items. But, for those who need an extra performance boost, we&#8217;ve been working on a virtualization feature.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TsBl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TsBl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 424w, https://substackcdn.com/image/fetch/$s_!TsBl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 848w, https://substackcdn.com/image/fetch/$s_!TsBl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 1272w, https://substackcdn.com/image/fetch/$s_!TsBl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TsBl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png" width="1456" height="957" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:957,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3014322,&quot;alt&quot;:&quot;const select = useSelectState({   defaultItems: [     { id: \&quot;africa-abidjan\&quot;, value: \&quot;Africa/Abidjan\&quot; },     { id: \&quot;africa-accra\&quot;, value: \&quot;Africa/Accra\&quot; },     ...     { id: \&quot;us-samoa\&quot;, value: \&quot;US/Samoa\&quot; },   ], })  <Select state={select} /> <SelectPopover state={select}>   <SelectViewport>     {(item) => <SelectItem {...item} />}   </SelectViewport> </SelectPopover>&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="const select = useSelectState({   defaultItems: [     { id: &quot;africa-abidjan&quot;, value: &quot;Africa/Abidjan&quot; },     { id: &quot;africa-accra&quot;, value: &quot;Africa/Accra&quot; },     ...     { id: &quot;us-samoa&quot;, value: &quot;US/Samoa&quot; },   ], })  <Select state={select} /> <SelectPopover state={select}>   <SelectViewport>     {(item) => <SelectItem {...item} />}   </SelectViewport> </SelectPopover>" title="const select = useSelectState({   defaultItems: [     { id: &quot;africa-abidjan&quot;, value: &quot;Africa/Abidjan&quot; },     { id: &quot;africa-accra&quot;, value: &quot;Africa/Accra&quot; },     ...     { id: &quot;us-samoa&quot;, value: &quot;US/Samoa&quot; },   ], })  <Select state={select} /> <SelectPopover state={select}>   <SelectViewport>     {(item) => <SelectItem {...item} />}   </SelectViewport> </SelectPopover>" srcset="https://substackcdn.com/image/fetch/$s_!TsBl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 424w, https://substackcdn.com/image/fetch/$s_!TsBl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 848w, https://substackcdn.com/image/fetch/$s_!TsBl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 1272w, https://substackcdn.com/image/fetch/$s_!TsBl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8c5a7df-31b2-40b7-ad12-0f97ffc3fa76_3606x2370.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Virtualization means that, even if your list has thousands of items, only the elements in the viewport will be rendered.</p><p>On Ariakit, we have to consider arrow keys and typeahead navigation. We still need access to items outside of the viewport to move focus to them when necessary. That&#8217;s why we&#8217;re building this feature into a new optional <code>CompositeViewport</code> component.</p><p>All components powered by Composite will immediately benefit from this feature.</p><div><hr></div><h2>More Ariakit</h2><p><strong><a href="https://twitter.com/diegohaz/status/1517531116575600641">Testing with ariakit-test</a></strong></p><p>Example of how the <code>ariakit-test</code> package is used internally to test Ariakit components.</p><p><strong><a href="https://github.com/ariakit/ariakit/issues/1245#issuecomment-1100931606">Render props vs. asChild</a></strong></p><p>Thoughts on render props vs. the <code>asChild</code> prop.</p><p><strong><a href="https://twitter.com/diegohaz/status/1515348428372467713">GitHub-like Textarea with Combobox</a></strong></p><p>Using the Ariakit Combobox component to create a GitHub-like textarea widget.</p><p><strong><a href="https://twitter.com/diegohaz/status/1514902260526026766">Floating UI + Ariakit</a></strong></p><p>We&#8217;ve recently migrated from Popper.js to Floating UI on Ariakit popovers.</p><p><strong><a href="https://twitter.com/diegohaz/status/1510671317430939648">Context Menu built with Ariakit</a></strong></p><p>Context Menu component built with the Ariakit Menu.</p><p><strong><a href="https://twitter.com/diegohaz/status/1511511000511664129">Toolbar with Select</a></strong></p><p>Toolbar component with a custom Select.</p><p><strong><a href="https://twitter.com/diegohaz/status/1529702907238617088">Dialog with &lt;details&gt;&lt;summary&gt;</a></strong></p><p>Progressively enhanced Dialog component rendered as <code>&lt;details&gt;&lt;summary&gt;</code>, so it works before the JavaScript finishes loading.</p><p><strong><a href="https://twitter.com/diegohaz/status/1528423152295874560">Dialog with React Router</a></strong></p><p>Using React Router to control the state of the Ariakit Dialog. This is how you&#8217;d use the Dialog component in a Remix app.</p><p><strong><a href="https://twitter.com/diegohaz/status/1531167430109806595">Menu, Dialog, Form, and CSS transitions</a></strong></p><p>Example of multiple Ariakit components combined to create an animated UI.</p><div><hr></div><h2>More Dev</h2><p><strong><a href="https://twitter.com/diegohaz/status/1518689957778538496">How to test accessibility</a></strong></p><p>Thread on how you should test the accessibility of your site.</p><p><strong><a href="https://twitter.com/diegohaz/status/1524257274012876801">TypeScript string with autocomplete</a></strong></p><p>A little trick to accept any string but still provide an autocomplete with specific values.</p><p><strong><a href="https://twitter.com/diegohaz/status/1526874008049811461">Using the built-in browser validation API</a></strong></p><p>Example of how to use the built-in browser validation API with JavaScript. That&#8217;s the same technique used in the Ariakit Form component.</p><p><strong><a href="https://twitter.com/diegohaz/status/1529543787311144961">Scrollbars in dark mode</a></strong></p><p>Make the browser show dark scrollbars when your site has a dark theme using the <code>color-scheme</code> CSS property.</p><p><strong><a href="https://twitter.com/diegohaz/status/1530223691128311809">Accessible links</a></strong></p><p>Make links within paragraphs more accessible with the <code>text-decoration-thickness</code> CSS property.</p><p><strong><a href="https://twitter.com/diegohaz/status/1530662445240426496">queueMicrotask()</a></strong></p><p>Thread about the handy <code>queueMicrotask</code> function available on all modern browsers.</p>]]></content:encoded></item><item><title><![CDATA[Select components]]></title><description><![CDATA[While I&#8217;ve been receiving feedback from people who are testing the alpha, I noticed quite a few using the Menu component as a custom select widget, which is problematic. This was happening so frequently that we made the decision to work on a specific Select component before the final release.]]></description><link>https://newsletter.ariakit.com/p/select-components</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/select-components</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Thu, 31 Mar 2022 12:29:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friends,</p><p>This month I&#8217;d like to share one of the most requested components of Ariakit. We&#8217;ve been working on it for months, and now it&#8217;s finally available on the latest alpha version.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X4xC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X4xC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 424w, https://substackcdn.com/image/fetch/$s_!X4xC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 848w, https://substackcdn.com/image/fetch/$s_!X4xC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 1272w, https://substackcdn.com/image/fetch/$s_!X4xC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X4xC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png" width="1106" height="702" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:702,&quot;width&quot;:1106,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:51806,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!X4xC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 424w, https://substackcdn.com/image/fetch/$s_!X4xC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 848w, https://substackcdn.com/image/fetch/$s_!X4xC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 1272w, https://substackcdn.com/image/fetch/$s_!X4xC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3cf8490-6f40-4299-9b2a-c2ccbd01298f_1106x702.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>While I&#8217;ve been receiving feedback from people who are testing the alpha, I noticed quite a few using the Menu component as a custom select widget, <a href="https://twitter.com/diegohaz/status/1482447267474903045">which is problematic</a>. This was happening so frequently that we made the decision to work on a specific <strong>Select</strong> component before the final release.</p><p>The new Select component is now available on <code>v2.0.0-alpha.20</code>.</p><p>Here&#8217;s a list of examples you can use as a reference:</p><ul><li><p><a href="https://ariakit.org/components/select">Default Select</a></p></li><li><p><a href="https://ariakit.org/examples/select-combobox">Select with a search field</a></p></li><li><p><a href="https://ariakit.org/examples/select-grid">Select grid</a></p></li><li><p><a href="https://ariakit.org/examples/select-group">Select group</a></p></li><li><p><a href="https://ariakit.org/examples/select-item-custom">Select with custom items</a></p></li><li><p><a href="https://ariakit.org/examples/form-select">Select with Form</a></p></li><li><p><a href="https://ariakit.org/examples/select-multiple">Multi-select</a></p></li><li><p><a href="https://ariakit.org/examples/select-animated">Animated Select</a></p></li></ul><h2>Other stuff</h2><p>Select wasn&#8217;t the only thing that&#8217;s happened since our previous newsletter. Here&#8217;s a list of updates you may find interesting:</p><ul><li><p><a href="https://twitter.com/diegohaz/status/1489261735013863424">How is Ariakit different from library X?</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1494701538232655872">Annoying sub-menus and how to fix them</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1488037639278186496">Testing a multi-selectable combobox with a screen reader</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1492775239628967936">Hovercard component with keyboard support</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1488786190346170370">Replicating Twitter hovercard with keyboard support</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1491826618750451717">Building a simple dropdown menu with keyboard support</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1496849131846914051">Building a dropdown menu with a search field</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1492537569841754112">Experimenting with dropdown menus and tooltips</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1496157654997159938">Re-creating the macOS menu bar using Ariakit</a></p></li><li><p><a href="https://twitter.com/diegohaz/status/1494633886894243841">A higher-level API using Ariakit&#8217;s primitive components</a></p></li></ul><h2>What's next</h2><p>Right now, composite components such as <code>Menu</code>, <code>Combobox</code>, and <code>Select</code> may render hundreds of items without performance issues. We&#8217;re now working on a built-in <strong>virtualization</strong> feature with proper keyboard support (which is hard to handle with the existing libraries), so they will be able to render thousands of items even on low-end devices.</p><p>Hopefully, we&#8217;ll talk more about that in the next newsletter.</p><p>See you!</p>]]></content:encoded></item><item><title><![CDATA[Form components]]></title><description><![CDATA[This is not the regular Form library you&#8217;re used to. Ariakit will manage focus and apply aria attributes automatically.&#160;For example, submitting an invalid form will focus on the first invalid input. Adding or removing inputs in a dynamic field list will automatically handle focus.]]></description><link>https://newsletter.ariakit.com/p/form-components</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/form-components</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Tue, 25 Jan 2022 14:13:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friends,</p><p>This month I&#8217;d like to share one of the most critical components of Ariakit. It&#8217;s been tested since the very first versions of Reakit. And it will finally reach its stable <strong>form</strong> (!) in v2.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IeI5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IeI5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 424w, https://substackcdn.com/image/fetch/$s_!IeI5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 848w, https://substackcdn.com/image/fetch/$s_!IeI5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 1272w, https://substackcdn.com/image/fetch/$s_!IeI5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IeI5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png" width="1282" height="764" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:764,&quot;width&quot;:1282,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66870,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IeI5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 424w, https://substackcdn.com/image/fetch/$s_!IeI5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 848w, https://substackcdn.com/image/fetch/$s_!IeI5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 1272w, https://substackcdn.com/image/fetch/$s_!IeI5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a6b7de3-0e90-4efb-81e1-a0d4931a3aca_1282x764.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is not the regular Form library you&#8217;re used to. Ariakit will manage focus and apply aria attributes automatically.</p><p>For example, submitting an invalid form will focus on the first invalid input. Adding or removing inputs in a dynamic field list will automatically handle focus.</p><p>Besides that, the Ariakit Form takes full advantage of the native browser validation with built-in <a href="https://en.wikipedia.org/wiki/Internationalization_and_localization">i18n</a>. You can use native HTML props like <code>required</code>, <code>minLength</code>, <code>maxLength</code>, <code>min</code>, <code>max</code>, <code>type</code> and <code>pattern</code>. Unlike the native element, though, you will be able to customize the error messages with CSS.</p><p>See you!</p>]]></content:encoded></item><item><title><![CDATA[Reakit is now Ariakit]]></title><description><![CDATA[Reakit has evolved. We&#8217;ve been focusing more and more on accessibility. In the future, we&#8217;d like to provide more framework-agnostic utilities as well.]]></description><link>https://newsletter.ariakit.com/p/reakit-is-now-ariakit</link><guid isPermaLink="false">https://newsletter.ariakit.com/p/reakit-is-now-ariakit</guid><dc:creator><![CDATA[Haz]]></dc:creator><pubDate>Tue, 07 Dec 2021 19:56:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!y4DB!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10c70c7a-0bd3-4a17-80ad-30d4a8fb847e_1000x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friends,</p><p>For the past few months, I&#8217;ve been working hard on the next major release of <strong>Reakit</strong>. This includes a more convenient API, better screen reader support, and several <a href="https://twitter.com/diegohaz/status/1307299869200191490">performance improvements</a>.</p><p>Reakit has evolved. We&#8217;ve been focusing more and more on accessibility. In the future, we&#8217;d like to provide more framework-agnostic utilities as well.</p><p>Reakit stands for React Toolkit. <strong>Ariakit</strong> stands for Aria Toolkit, which is better aligned with these goals.</p><p>You can learn more about that change on <a href="https://gist.github.com/diegohaz/bc07491aee61a5f2469574b38c5c1aa0">What is Ariakit?</a></p><div><hr></div><h2>New docs</h2><p>A new documentation site is under development. You&#8217;ll be able to interact with multiple examples for each component and play with the code directly in the browser.</p><p>Ariakit will remain an unstyled component library, but you&#8217;ll be able to see and play with the example CSS. You can use it as a reference to write your own.</p>]]></content:encoded></item></channel></rss>