See it in context
Preview
All primitives are available as Astro components.
The same API surface is available in React.
Copy a working example
Usage
Astro examples assume UIPrimitives is mounted once in your root layout. Do not add the runtime next to each component instance.
---
import { Tabs } from '@santi020k/lumen-astro'
---
<Tabs>
<div role="tablist" aria-label="Package targets">
<button id="ex-tab-astro" role="tab" aria-controls="ex-panel-astro" aria-selected="true">Astro</button>
<button id="ex-tab-react" role="tab" aria-controls="ex-panel-react">React</button>
</div>
<section id="ex-panel-astro" role="tabpanel" aria-labelledby="ex-tab-astro">
<p>All primitives are available as Astro components.</p>
</section>
<section id="ex-panel-react" role="tabpanel" aria-labelledby="ex-tab-react" hidden>
<p>The same API surface is available in React.</p>
</section>
</Tabs>---
import { Tabs } from '@santi020k/lumen-astro'
---
<Tabs>
<div role="tablist" aria-label="Package targets">
<button id="ex-tab-astro" role="tab" aria-controls="ex-panel-astro" aria-selected="true">Astro</button>
<button id="ex-tab-react" role="tab" aria-controls="ex-panel-react">React</button>
</div>
<section id="ex-panel-astro" role="tabpanel" aria-labelledby="ex-tab-astro">
<p>All primitives are available as Astro components.</p>
</section>
<section id="ex-panel-react" role="tabpanel" aria-labelledby="ex-tab-react" hidden>
<p>The same API surface is available in React.</p>
</section>
</Tabs>import { Tabs } from '@santi020k/lumen-react'
export const Example = () => (
<>
<Tabs>
<div role="tablist" aria-label="Package targets">
<button id="ex-tab-astro" role="tab" aria-controls="ex-panel-astro" aria-selected="true">Astro</button>
<button id="ex-tab-react" role="tab" aria-controls="ex-panel-react">React</button>
</div>
<section id="ex-panel-astro" role="tabpanel" aria-labelledby="ex-tab-astro">
<p>All primitives are available as Astro components.</p>
</section>
<section id="ex-panel-react" role="tabpanel" aria-labelledby="ex-tab-react" hidden>
<p>The same API surface is available in React.</p>
</section>
</Tabs>
</>
)import { Tabs } from '@santi020k/lumen-react'
export const Example = () => (
<>
<Tabs>
<div role="tablist" aria-label="Package targets">
<button id="ex-tab-astro" role="tab" aria-controls="ex-panel-astro" aria-selected="true">Astro</button>
<button id="ex-tab-react" role="tab" aria-controls="ex-panel-react">React</button>
</div>
<section id="ex-panel-astro" role="tabpanel" aria-labelledby="ex-tab-astro">
<p>All primitives are available as Astro components.</p>
</section>
<section id="ex-panel-react" role="tabpanel" aria-labelledby="ex-tab-react" hidden>
<p>The same API surface is available in React.</p>
</section>
</Tabs>
</>
)<script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<lumen-tabs>
<div role="tablist" aria-label="Package targets">
<button id="ex-tab-astro" role="tab" aria-controls="ex-panel-astro" aria-selected="true">Astro</button>
<button id="ex-tab-react" role="tab" aria-controls="ex-panel-react">React</button>
</div>
<section id="ex-panel-astro" role="tabpanel" aria-labelledby="ex-tab-astro">
<p>All primitives are available as Astro components.</p>
</section>
<section id="ex-panel-react" role="tabpanel" aria-labelledby="ex-tab-react" hidden>
<p>The same API surface is available in React.</p>
</section>
</lumen-tabs><script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<lumen-tabs>
<div role="tablist" aria-label="Package targets">
<button id="ex-tab-astro" role="tab" aria-controls="ex-panel-astro" aria-selected="true">Astro</button>
<button id="ex-tab-react" role="tab" aria-controls="ex-panel-react">React</button>
</div>
<section id="ex-panel-astro" role="tabpanel" aria-labelledby="ex-tab-astro">
<p>All primitives are available as Astro components.</p>
</section>
<section id="ex-panel-react" role="tabpanel" aria-labelledby="ex-tab-react" hidden>
<p>The same API surface is available in React.</p>
</section>
</lumen-tabs>Choose your target
Add this component
Choose the package for your runtime. All adapters share the Lumen stylesheet. Use the matching registry command when you want a local wrapper for that framework.
pnpm add @santi020k/lumen-astropnpm add @santi020k/lumen-astrolumen add Tabslumen add Tabspnpm add @santi020k/lumen-reactpnpm add @santi020k/lumen-reactlumen add Tabs --target reactlumen add Tabs --target reactpnpm add @santi020k/lumen-elementspnpm add @santi020k/lumen-elementslumen add Tabs --target elementslumen add Tabs --target elementsGlass
Add the glass prop to apply the shared blur, saturation, border, and highlight tokens. Glass reads best over vivid content, so place the surface above imagery or color.
---
import { Tabs } from '@santi020k/lumen-astro'
---
<div class="docs-glass-demo">
<Tabs glass>
<div role="tablist">
<button role="tab" aria-selected="true">Preview</button>
<button role="tab">Code</button>
<button role="tab">Tokens</button>
</div>
<section role="tabpanel">Glass tabs get a translucent tab list, and the selected tab reads as a raised sliver of glass.</section>
</Tabs>
</div>---
import { Tabs } from '@santi020k/lumen-astro'
---
<div class="docs-glass-demo">
<Tabs glass>
<div role="tablist">
<button role="tab" aria-selected="true">Preview</button>
<button role="tab">Code</button>
<button role="tab">Tokens</button>
</div>
<section role="tabpanel">Glass tabs get a translucent tab list, and the selected tab reads as a raised sliver of glass.</section>
</Tabs>
</div>import { Tabs } from '@santi020k/lumen-react'
export const Example = () => (
<>
<div className="docs-glass-demo">
<Tabs glass>
<div role="tablist">
<button role="tab" aria-selected="true">Preview</button>
<button role="tab">Code</button>
<button role="tab">Tokens</button>
</div>
<section role="tabpanel">Glass tabs get a translucent tab list, and the selected tab reads as a raised sliver of glass.</section>
</Tabs>
</div>
</>
)import { Tabs } from '@santi020k/lumen-react'
export const Example = () => (
<>
<div className="docs-glass-demo">
<Tabs glass>
<div role="tablist">
<button role="tab" aria-selected="true">Preview</button>
<button role="tab">Code</button>
<button role="tab">Tokens</button>
</div>
<section role="tabpanel">Glass tabs get a translucent tab list, and the selected tab reads as a raised sliver of glass.</section>
</Tabs>
</div>
</>
)<script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<div class="docs-glass-demo">
<lumen-tabs glass>
<div role="tablist">
<button role="tab" aria-selected="true">Preview</button>
<button role="tab">Code</button>
<button role="tab">Tokens</button>
</div>
<section role="tabpanel">Glass tabs get a translucent tab list, and the selected tab reads as a raised sliver of glass.</section>
</lumen-tabs>
</div><script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<div class="docs-glass-demo">
<lumen-tabs glass>
<div role="tablist">
<button role="tab" aria-selected="true">Preview</button>
<button role="tab">Code</button>
<button role="tab">Tokens</button>
</div>
<section role="tabpanel">Glass tabs get a translucent tab list, and the selected tab reads as a raised sliver of glass.</section>
</lumen-tabs>
</div>API reference
Lumen-specific props and runtime attributes for the Astro primitive. React props follow the same names; Elements use equivalent kebab-case attributes where custom elements expose them.
| Attribute | Values | Default | Description |
|---|---|---|---|
| glass | boolean | "subtle" | "strong" | false | Applies the tokenized liquid-glass surface treatment with backdrop-filter fallbacks; "subtle" and "strong" adjust the fill intensity. |
| class, className | string | "" | Merges custom classes with the generated ui-* root classes. |
| ...native attributes | HTML attributes | - | Forwards standard attributes to the root element unless the component consumes them. |
Keyboard interactions
Keyboard behavior provided by the Astro UIPrimitives runtime for this component.
| Key | Action |
|---|---|
| ArrowRight | Activate and focus the next tab, wrapping at the end. |
| ArrowLeft | Activate and focus the previous tab, wrapping at the start. |
| Home, End | Activate and focus the first or last tab. |