Toast
Cola de notificaciones breves.
- Navegadores
- Chrome 114+Firefox 125+Safari 17+
- Nivel
- 1
- Tamaño comprimido
- 2.41 kB
- Presupuesto de diseño forzado
- 0 ms
- Presupuesto de axe
- 0
- Compatible con SSR
- Sí
- Contrato publicado
- Entorno de pruebas
Zona de pruebas
Toast
Área visible
"use client";
import { Toast, useToast } from "@gunkin/uiify";
function ShowToast() {
const { toast } = useToast();
return (
<button className="" type="button" onClick={() => toast({ title: "Saved" })}>
Save
</button>
);
}
export default function Example() {
return (
<Toast.Provider>
<ShowToast />
<Toast.Viewport className="" />
</Toast.Provider>
);
}/* Toast — a fixed viewport stacking cards in the corner, promoted to the top
layer via [popover]. inset: auto overrides the UA popover default of
inset: 0 so the corner offsets below can apply; the top-layer stack is
ordered by show order, not z-index, so no manual z-index is needed. Cards
use `data-part="item"`. Cards enter, leave, and restack through React view
transitions (view-transition-class `uiify-toast`) with the shared presence
motion; the snapshots hang off the root, so they read root tokens only. */
@layer components {
[data-uiify-toast] [data-part="viewport"]:where(:not([popover]), :popover-open),
[data-uiify-toast][data-part="viewport"]:where(:not([popover]), :popover-open) {
display: flex;
}
[data-uiify-toast] [data-part="viewport"],
[data-uiify-toast][data-part="viewport"] {
position: fixed;
inset: auto;
inset-block-end: var(--space-lg);
inset-inline-end: var(--space-lg);
flex-direction: column;
gap: var(--space-sm);
inline-size: min(24rem, calc(100vw - 2 * var(--space-lg)));
margin: 0;
padding: 0;
/* Cancels the UA popover default (`border: solid` + Canvas background) —
the viewport is a transparent stacking container; cards carry their
own border and background. */
border: none;
background: none;
list-style: none;
}
[data-uiify-toast] [data-part="item"],
[data-uiify-toast][data-part="viewport"] [data-part="item"] {
display: flex;
flex-direction: column;
gap: var(--space-xs);
padding: var(--space-md) var(--space-lg);
border: var(--border-width) solid var(--border);
border-radius: var(--radius-lg);
corner-shape: squircle;
background-color: var(--popover);
color: var(--popover-foreground);
box-shadow: var(--shadow-popover);
margin: 0;
min-inline-size: 0;
}
[data-uiify-toast] [data-part="close"] {
align-self: flex-end;
min-block-size: 30px;
padding-block: 0;
padding-inline: var(--space-sm);
border: 0;
border-radius: var(--radius-md);
background: transparent;
color: var(--popover-foreground);
font: inherit;
cursor: pointer;
}
[data-uiify-toast] [data-part="close"]:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
[data-uiify-toast] [data-part="close"]:hover {
background-color: var(--accent);
color: var(--accent-foreground);
}
}
@media (prefers-reduced-motion: no-preference) {
::view-transition-group(.uiify-toast) {
animation-duration: var(--duration-fast);
animation-timing-function: var(--ease-out);
}
::view-transition-new(.uiify-toast):only-child {
animation: uiify-presence-in var(--duration-fast) var(--ease-out) both;
}
::view-transition-old(.uiify-toast):only-child {
animation: uiify-presence-out var(--duration-fast) var(--ease-out) both;
}
}
@keyframes uiify-presence-in {
from {
opacity: 0;
scale: var(--presence-scale);
}
}
@keyframes uiify-presence-out {
to {
opacity: 0;
scale: var(--presence-scale);
}
}
}"use client";
import { Toast, useToast } from "@gunkin/uiify";
function ShowToast() {
const { toast } = useToast();
return (
<button
className={
"focus-visible:[outline:none] focus-visible:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ri" +
"ng)_16%,_transparent)] [--uiify-button-rim:rgb(255_255_255_/_20%)] [--uiify-button-wash:light-dark(rgb(255_" +
"255_255_/_15%),_rgb(255_255_255_/_30%))] relative isolate inline-flex items-center justify-center [gap:0.37" +
"5rem] [min-block-size:44px] [min-inline-size:44px] py-0 [padding-inline:1.25rem] border-[length:var(--borde" +
"r-width)] border-solid border-transparent rounded-[var(--radius-full)] bg-foreground bg-clip-padding text-b" +
"ackground text-base font-[number:var(--weight-medium)] leading-6 no-underline cursor-pointer [transition:va" +
"r(--transition-colors)] before:content-[''] before:absolute before:inset-0 before:z-[-1] before:[border-rad" +
"ius:inherit] before:pointer-events-none after:content-[''] after:absolute after:inset-0 after:z-[-1] after:" +
"[border-radius:inherit] after:pointer-events-none before:[background-color:var(--uiify-button-wash)] before" +
":[filter:blur(10px)] before:[translate:0_-50%] before:[clip-path:inset(50%_0_-50%_0_round_var(--radius-full" +
"))] after:[padding:0.5px] after:[background-image:linear-gradient(to_bottom,_var(--uiify-button-rim),_trans" +
"parent_75%)] after:[mask:linear-gradient(#fff_0_0)_content-box_exclude,_linear-gradient(#fff_0_0)] [&:is([d" +
"ata-size=sm],[data-size=icon-sm])]:[min-block-size:32px] [&:is([data-size=sm],[data-size=icon-sm])]:[min-in" +
"line-size:32px] [&:is([data-size=sm],[data-size=icon-sm])]:[padding-inline:0.75rem] [&:is([data-size=sm],[d" +
"ata-size=icon-sm])]:[gap:0.25rem] [&:is([data-size=sm],[data-size=icon-sm])]:text-sm [&:is([data-size=sm],[" +
"data-size=icon-sm])]:leading-5 [&:is([data-size=lg],[data-size=icon-lg])]:[min-block-size:56px] [&:is([data" +
"-size=lg],[data-size=icon-lg])]:[min-inline-size:56px] [&:is([data-size=lg],[data-size=icon-lg])]:[padding-" +
"inline:1.75rem] [&:is([data-size=lg],[data-size=icon-lg])]:text-lg [&:is([data-size=lg],[data-size=icon-lg]" +
")]:leading-7 [&[data-size^=icon]]:px-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:hover:[&:not(:di" +
"sabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_90%,_var(--background))] a" +
"ctive:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_80%,_var(-" +
"-background))] disabled:opacity-50 disabled:cursor-not-allowed data-[disabled]:opacity-50 data-[disabled]:c" +
"ursor-not-allowed data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[ar" +
"ia-current=page]))]:[--uiify-button-rim:light-dark(rgb(0_0_0_/_5%),_rgb(255_255_255_/_10%))] data-[variant=" +
"secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-but" +
"ton-wash:light-dark(rgb(255_255_255_/_20%),_rgb(255_255_255_/_5%))] data-[variant=secondary]:[&:where(:not(" +
":checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[background-color:color-mix(in_oklch," +
"_var(--foreground)_10%,_transparent)] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[ar" +
"ia-pressed=true],[aria-current=page]))]:text-foreground data-[variant=outline]:[&:where(:not(:checked+*,[da" +
"ta-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-rim:color-mix(in_oklch,_var(--foreg" +
"round)_25%,_transparent)] data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=tru" +
"e],[aria-current=page]))]:[border-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] data-[vari" +
"ant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-transpa" +
"rent data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page" +
"]))]:text-foreground data-[variant=outline]:before:content-none data-[variant=outline]:after:[inset:calc(-1" +
"_*_var(--border-width))] data-[variant=outline]:after:[padding:var(--border-width)] data-[variant=outline]:" +
"[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled" +
",[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data-[variant" +
"=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-transparent " +
"data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:te" +
"xt-foreground data-[variant=ghost]:before:content-none data-[variant=ghost]:after:content-none data-[varian" +
"t=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(" +
":disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data" +
"-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:ac" +
"tive:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_26%,_transp" +
"arent)] data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-curre" +
"nt=page]))]:[--uiify-button-wash:rgb(255_255_255_/_15%)] data-[variant=destructive]:[&:where(:not(:checked+" +
"*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-destructive data-[variant=destructive]:text" +
"-destructive-foreground data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=t" +
"rue],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch," +
"_var(--destructive),_black_20%)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=outline]" +
":[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled" +
",[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] [@media_(any-" +
"hover:_hover)_and_(any-pointer:_fine)]:data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-" +
"pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(i" +
"n_oklch,_var(--foreground)_10%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[var" +
"iant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[" +
"&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)" +
"] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=destructive]:[&:where(:not(:checked+*,[" +
"data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[backgro" +
"und-color:color-mix(in_oklch,_var(--destructive),_black_12%)] [&:is([data-selected],[aria-pressed=true],[ar" +
"ia-current=page])]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [&:is([data-selected],[aria-pressed=true],[a" +
"ria-current=page])]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [&:is([data-selected],[aria-pressed=true]," +
"[aria-current=page])]:border-transparent [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:bg" +
"-primary [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:text-primary-foreground [:checked+" +
"&]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [:checked+&]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [:" +
"checked+&]:border-transparent [:checked+&]:bg-primary [:checked+&]:text-primary-foreground [@media_(any-hov" +
"er:_hover)_and_(any-pointer:_fine)]:[&:is([data-selected],[aria-pressed=true],[aria-current=page]):hover:no" +
"t(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreg" +
"round))] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[:checked:not(:disabled)+&:hover]:[background-" +
"color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] [:disabled+&]:opacity-50 [:disabl" +
"ed+&]:cursor-not-allowed [&[hidden]]:hidden data-[variant=link]:px-0 data-[variant=link]:border-0 data-[var" +
"iant=link]:border-current data-[variant=link]:border-none data-[variant=link]:rounded-none data-[variant=li" +
"nk]:bg-transparent data-[variant=link]:text-primary data-[variant=link]:underline data-[variant=link]:[text" +
"-underline-offset:0.2em] data-[variant=link]:active:px-0 data-[variant=link]:active:border-0 data-[variant=" +
"link]:active:border-current data-[variant=link]:active:border-none data-[variant=link]:active:rounded-none " +
"data-[variant=link]:active:bg-transparent data-[variant=link]:active:text-primary data-[variant=link]:activ" +
"e:underline data-[variant=link]:active:[text-underline-offset:0.2em] data-[variant=link]:[min-inline-size:0" +
"] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:px-0 [@media_(any-hover:_ho" +
"ver)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-0 [@media_(any-hover:_hover)_and_(any-pointe" +
"r:_fine)]:data-[variant=link]:hover:border-current [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data" +
"-[variant=link]:hover:border-none [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:h" +
"over:rounded-none [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:bg-transpar" +
"ent [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:text-primary [@media_(any" +
"-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:underline [@media_(any-hover:_hover)_and_" +
"(any-pointer:_fine)]:data-[variant=link]:hover:[text-underline-offset:0.2em] data-[variant=link]:before:con" +
"tent-none data-[variant=link]:after:content-none data-[variant=link]:focus-visible:[outline:2px_solid_var(-" +
"-ring)] data-[variant=link]:focus-visible:[outline-offset:3px] [[data-uiify-toggle]>input:focus-visible+&]:" +
"[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [[data-uiify-toggle-" +
"group]_[data-part=item]>input:focus-visible+&]:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(" +
"--ring)_16%,_transparent)] [[data-uiify-modal][data-part=close]&]:border-transparent [[data-uiify-modal][da" +
"ta-part=close]&]:[background-color:color-mix(in_oklch,_var(--foreground)_8%,_transparent)] [[data-uiify-mod" +
"al][data-part=close]&]:text-foreground [[data-uiify-modal][data-part=close]&:hover]:[background-color:color" +
"-mix(in_oklch,_var(--foreground)_14%,_transparent)] [[data-uiify-modal][data-part=close]&:active]:[backgrou" +
"nd-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] [[data-uiify-pagination]_span&:not([data-" +
"disabled])]:cursor-default [[data-uiify-input-group]>[data-part=addon]>&]:[min-inline-size:0] [[data-uiify-" +
"input-group]>[data-part=addon]>&]:[max-inline-size:100%] [[data-uiify-input-group]>[data-part=addon]>&]:whi" +
"tespace-normal [[data-uiify-input-group]>[data-part=addon]>&]:[overflow-wrap:anywhere] [[data-uiify-item-co" +
"ntent]>&]:[justify-self:start]"
}
type="button"
onClick={() => toast({ title: "Saved" })}
>
Save
</button>
);
}
export default function Example() {
return (
<Toast.Provider>
<ShowToast />
<Toast.Viewport
className="
fixed [inset:auto] [inset-block-end:var(--space-lg)] [inset-inline-end:var(--space-lg)] flex-col gap-sm
[inline-size:min(24rem,calc(100vw_-_2_*_var(--space-lg)))] m-0 p-0 border-0 border-none bg-transparent
list-none [&:where(:not([popover]),:popover-open)]:flex [&_[data-part=item]]:flex
[&_[data-part=item]]:flex-col [&_[data-part=item]]:gap-xs
[&_[data-part=item]]:[padding:var(--space-md)_var(--space-lg)]
[&_[data-part=item]]:border-[length:var(--border-width)] [&_[data-part=item]]:border-solid
[&_[data-part=item]]:border-border [&_[data-part=item]]:rounded-lg
[&_[data-part=item]]:[corner-shape:squircle] [&_[data-part=item]]:bg-popover
[&_[data-part=item]]:text-popover-foreground [&_[data-part=item]]:shadow-popover [&_[data-part=item]]:m-0
[&_[data-part=item]]:[min-inline-size:0] [&_[data-part=close]]:self-end
[&_[data-part=close]]:[min-block-size:30px] [&_[data-part=close]]:py-0 [&_[data-part=close]]:px-sm
[&_[data-part=close]]:border-0 [&_[data-part=close]]:border-none [&_[data-part=close]]:rounded-md
[&_[data-part=close]]:bg-transparent [&_[data-part=close]]:text-popover-foreground
[&_[data-part=close]]:cursor-pointer [&_[data-part=close]:focus-visible]:outline-2
[&_[data-part=close]:focus-visible]:outline-ring [&_[data-part=close]:focus-visible]:outline-offset-2
[@media_(hover:_hover)_and_(pointer:_fine)]:[&_[data-part=close]:hover]:bg-accent
[@media_(hover:_hover)_and_(pointer:_fine)]:[&_[data-part=close]:hover]:text-accent-foreground
"
/>
</Toast.Provider>
);
}/* app.css */
@layer reset, ui, app, tokens, base, demo, components, utilities, theme;
@import "@gunkin/uiify/styles/reset";
@import "@gunkin/uiify/components/behavior.css";
@import "@gunkin/uiify/styles/tokens";
@import "@gunkin/uiify/styles/tailwind";
@import "tailwindcss/utilities.css";
@theme { --spacing: 0.25rem; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; }
@source inline('focus-visible:[outline:none] focus-visible:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [--uiify-button-rim:rgb(255_255_255_/_20%)] [--uiify-button-wash:light-dark(rgb(255_255_255_/_15%),_rgb(255_255_255_/_30%))] relative isolate inline-flex items-center justify-center [gap:0.375rem] [min-block-size:44px] [min-inline-size:44px] py-0 [padding-inline:1.25rem] border-[length:var(--border-width)] border-solid border-transparent rounded-[var(--radius-full)] bg-foreground bg-clip-padding text-background text-base font-[number:var(--weight-medium)] leading-6 no-underline cursor-pointer [transition:var(--transition-colors)] before:absolute before:inset-0 before:z-[-1] before:[border-radius:inherit] before:pointer-events-none after:absolute after:inset-0 after:z-[-1] after:[border-radius:inherit] after:pointer-events-none before:[background-color:var(--uiify-button-wash)] before:[filter:blur(10px)] before:[translate:0_-50%] before:[clip-path:inset(50%_0_-50%_0_round_var(--radius-full))] after:[padding:0.5px] after:[background-image:linear-gradient(to_bottom,_var(--uiify-button-rim),_transparent_75%)] after:[mask:linear-gradient(#fff_0_0)_content-box_exclude,_linear-gradient(#fff_0_0)] [&:is([data-size=sm],[data-size=icon-sm])]:[min-block-size:32px] [&:is([data-size=sm],[data-size=icon-sm])]:[min-inline-size:32px] [&:is([data-size=sm],[data-size=icon-sm])]:[padding-inline:0.75rem] [&:is([data-size=sm],[data-size=icon-sm])]:[gap:0.25rem] [&:is([data-size=sm],[data-size=icon-sm])]:text-sm [&:is([data-size=sm],[data-size=icon-sm])]:leading-5 [&:is([data-size=lg],[data-size=icon-lg])]:[min-block-size:56px] [&:is([data-size=lg],[data-size=icon-lg])]:[min-inline-size:56px] [&:is([data-size=lg],[data-size=icon-lg])]:[padding-inline:1.75rem] [&:is([data-size=lg],[data-size=icon-lg])]:text-lg [&:is([data-size=lg],[data-size=icon-lg])]:leading-7 [&[data-size^=icon]]:px-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_90%,_var(--background))] active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_80%,_var(--background))] disabled:opacity-50 disabled:cursor-not-allowed data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-rim:light-dark(rgb(0_0_0_/_5%),_rgb(255_255_255_/_10%))] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-wash:light-dark(rgb(255_255_255_/_20%),_rgb(255_255_255_/_5%))] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-rim:color-mix(in_oklch,_var(--foreground)_25%,_transparent)] data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[border-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-transparent data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[variant=outline]:before:content-none data-[variant=outline]:after:[inset:calc(-1_*_var(--border-width))] data-[variant=outline]:after:[padding:var(--border-width)] data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-transparent data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[variant=ghost]:before:content-none data-[variant=ghost]:after:content-none data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_26%,_transparent)] data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-wash:rgb(255_255_255_/_15%)] data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-destructive data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--destructive),_black_20%)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--destructive),_black_12%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:border-transparent [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:bg-primary [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:text-primary-foreground [:checked+&]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [:checked+&]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [:checked+&]:border-transparent [:checked+&]:bg-primary [:checked+&]:text-primary-foreground [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[&:is([data-selected],[aria-pressed=true],[aria-current=page]):hover:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[:checked:not(:disabled)+&:hover]:[background-color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] [:disabled+&]:opacity-50 [:disabled+&]:cursor-not-allowed [&[hidden]]:hidden data-[variant=link]:px-0 data-[variant=link]:border-0 data-[variant=link]:border-current data-[variant=link]:border-none data-[variant=link]:rounded-none data-[variant=link]:bg-transparent data-[variant=link]:text-primary data-[variant=link]:underline data-[variant=link]:[text-underline-offset:0.2em] data-[variant=link]:active:px-0 data-[variant=link]:active:border-0 data-[variant=link]:active:border-current data-[variant=link]:active:border-none data-[variant=link]:active:rounded-none data-[variant=link]:active:bg-transparent data-[variant=link]:active:text-primary data-[variant=link]:active:underline data-[variant=link]:active:[text-underline-offset:0.2em] data-[variant=link]:[min-inline-size:0] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:px-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-current [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-none [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:rounded-none [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:bg-transparent [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:text-primary [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:underline [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:[text-underline-offset:0.2em] data-[variant=link]:before:content-none data-[variant=link]:after:content-none data-[variant=link]:focus-visible:[outline:2px_solid_var(--ring)] data-[variant=link]:focus-visible:[outline-offset:3px] [[data-uiify-toggle]>input:focus-visible+&]:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [[data-uiify-toggle-group]_[data-part=item]>input:focus-visible+&]:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [[data-uiify-modal][data-part=close]&]:border-transparent [[data-uiify-modal][data-part=close]&]:[background-color:color-mix(in_oklch,_var(--foreground)_8%,_transparent)] [[data-uiify-modal][data-part=close]&]:text-foreground [[data-uiify-modal][data-part=close]&:hover]:[background-color:color-mix(in_oklch,_var(--foreground)_14%,_transparent)] [[data-uiify-modal][data-part=close]&:active]:[background-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] [[data-uiify-pagination]_span&:not([data-disabled])]:cursor-default [[data-uiify-input-group]>[data-part=addon]>&]:[min-inline-size:0] [[data-uiify-input-group]>[data-part=addon]>&]:[max-inline-size:100%] [[data-uiify-input-group]>[data-part=addon]>&]:whitespace-normal [[data-uiify-input-group]>[data-part=addon]>&]:[overflow-wrap:anywhere] [[data-uiify-item-content]>&]:[justify-self:start] fixed [inset:auto] [inset-block-end:var(--space-lg)] [inset-inline-end:var(--space-lg)] flex-col gap-sm [inline-size:min(24rem,calc(100vw_-_2_*_var(--space-lg)))] m-0 p-0 border-0 border-none bg-transparent list-none [&:where(:not([popover]),:popover-open)]:flex [&_[data-part=item]]:flex [&_[data-part=item]]:flex-col [&_[data-part=item]]:gap-xs [&_[data-part=item]]:[padding:var(--space-md)_var(--space-lg)] [&_[data-part=item]]:border-[length:var(--border-width)] [&_[data-part=item]]:border-solid [&_[data-part=item]]:border-border [&_[data-part=item]]:rounded-lg [&_[data-part=item]]:[corner-shape:squircle] [&_[data-part=item]]:bg-popover [&_[data-part=item]]:text-popover-foreground [&_[data-part=item]]:shadow-popover [&_[data-part=item]]:m-0 [&_[data-part=item]]:[min-inline-size:0] [&_[data-part=close]]:self-end [&_[data-part=close]]:[min-block-size:30px] [&_[data-part=close]]:py-0 [&_[data-part=close]]:px-sm [&_[data-part=close]]:border-0 [&_[data-part=close]]:border-none [&_[data-part=close]]:rounded-md [&_[data-part=close]]:bg-transparent [&_[data-part=close]]:text-popover-foreground [&_[data-part=close]]:cursor-pointer [&_[data-part=close]:focus-visible]:outline-2 [&_[data-part=close]:focus-visible]:outline-ring [&_[data-part=close]:focus-visible]:outline-offset-2 [@media_(hover:_hover)_and_(pointer:_fine)]:[&_[data-part=close]:hover]:bg-accent [@media_(hover:_hover)_and_(pointer:_fine)]:[&_[data-part=close]:hover]:text-accent-foreground');
@source inline("before:content-[''] after:content-['']");
@layer base { :root { --uiify-control-text: var(--text-sm); } @media (pointer: coarse) { :root { --uiify-control-text: var(--text-base); } } }
/* Authored animation and registered properties used by the Tailwind skin.
* Visual rules belong in utility recipes; only at-rule definitions live here. */
@layer components {
@keyframes uiify-presence-in {
from {
opacity: 0;
scale: var(--presence-scale);
}
}
}
@layer components {
@keyframes uiify-presence-out {
to {
opacity: 0;
scale: var(--presence-scale);
}
}
}
@property --uiify-spinner-tail {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --uiify-spinner-length {
syntax: "<angle>";
inherits: false;
initial-value: 36deg;
}
@layer components {
@keyframes uiify-spinner-rotate {
to {
transform: rotate(360deg);
}
}
}
@layer components {
@keyframes uiify-spinner-orbit {
0% {
--uiify-spinner-tail: 0deg;
--uiify-spinner-length: 36deg;
}
50% {
--uiify-spinner-tail: 90deg;
--uiify-spinner-length: 324deg;
}
100% {
--uiify-spinner-tail: 360deg;
--uiify-spinner-length: 36deg;
}
}
}
@layer components {
@keyframes uiify-skeleton-pulse {
50% {
opacity: 0.45;
}
}
}
@layer components {
@keyframes uiify-skeleton-shimmer {
to {
background-position: -200% 0;
}
}
}
@layer components {
@keyframes uiify-skeleton-reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
@property --candle-body-height {
syntax: "<percentage>";
inherits: true;
initial-value: 0%;
}
@property --candle-body-top {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --candle-slot {
syntax: "<percentage>";
inherits: true;
initial-value: 100%;
}
@property --candle-wick-height {
syntax: "<percentage>";
inherits: true;
initial-value: 0%;
}
@property --candle-wick-top {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --candle-x {
syntax: "<percentage>";
inherits: true;
initial-value: 0%;
}
@property --candle-scale {
syntax: "<number>";
inherits: true;
initial-value: 1;
}
@property --line-y {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --line-prev-y {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --line-count {
syntax: "<integer>";
inherits: false;
initial-value: 1;
}
@property --line-scale {
syntax: "<number>";
inherits: true;
initial-value: 1;
}
@layer components {
@keyframes uiify-otp-input-caret-blink {
50% {
opacity: 0;
}
}
}API
Toast.Provider
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
limit | number | 3 | Número máximo de notificaciones en la cola; las más antiguas se descartan. |
children | ReactNode | — | Árbol que puede llamar a useToast y renderizar un área visible. |
Toast.Viewport
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
aria-label | string | — | Nombre accesible de la región que contiene las notificaciones en cola. |
className | string | — | Clase aplicada al elemento del área visible. |
popover | "manual" | — | Lo establece el área visible activa del cliente para que la cola renderizada ocupe la capa superior; la envoltura del servidor lo deja sin establecer. |
ref | Ref<HTMLElement> | — | Ref del elemento del área visible. |
children | ReactNode | — | Contenido adicional renderizado dentro del área visible junto a las notificaciones en cola. |
Toast.Root
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
toast* | ToastRecord | — | Registro en cola que se renderiza, con id, título, descripción, acción, duración y prioridad resueltos. |
Toast.Title
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
className | string | — | Clase aplicada al elemento del título. |
children | ReactNode | — | Contenido del título. |
Toast.Description
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
className | string | — | Clase aplicada al elemento de descripción. |
children | ReactNode | — | Contenido de la descripción. |
Toast.Action
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
className | string | — | Clase aplicada al botón de acción. |
onClick | (event: MouseEvent<HTMLButtonElement>) => void | — | Se llama al hacer clic en el botón de acción. |
children | ReactNode | — | Contenido del botón de acción. |
Toast.Close
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
className | string | — | Clase aplicada al botón de cierre. |
onClick | (event: MouseEvent<HTMLButtonElement>) => void | — | Se llama al hacer clic en el botón de cierre. |
children | ReactNode | — | Contenido del botón de cierre. |
useToast().toast(input)
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
title | ReactNode | — | Línea del título de la notificación. |
description | ReactNode | — | Línea de apoyo bajo el título. |
action | { label: ReactNode; onClick: () => void } | — | Etiqueta y manejador de un único botón de acción de la notificación. |
duration | number | 4000 | Milisegundos antes de que la notificación se cierre sola; cero o menos la mantiene hasta que se cierre. |
priority | "polite" | "assertive" | "polite" | Región dinámica que anuncia la notificación. |
id | string | — | Id de la notificación; se genera si se omite. |
Teclado
| Tecla | Acción |
|---|---|
| Tab | Dar el foco a los botones de acción dentro de la notificación |
| Escape | Cerrar cuando se permite |
Accesibilidad
Anuncios polite/assertive mediante una región dinámica; añadir a la cola no mueve el foco, y pasar el puntero o dar el foco pausa el cierre automático.
Puntos de estilo
data-statedata-part="item"data-part="title"data-part="description"data-part="action"data-part="close"