Toast
طابور إشعارات قصيرة الظهور.
- المتصفحات
- Chrome 114+, Firefox 125+, Safari 17+
- الفئة
- 1
- الحجم المضغوط
- 2.41 kB
- ميزانية التخطيط القسري
- 0 ms
- ميزانية axe
- 0
- متوافق مع SSR
- نعم
- العقد المنشور
- بيئة الاختبار
المختبر
Toast
إطار العرض
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
"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>
);
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
/* 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);
}
}
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
"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>
);
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
/* 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
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
limit | number | 3 | أقصى عدد إشعارات عابرة في الطابور؛ وتُحذف الأقدم. |
children | ReactNode | — | الشجرة التي يمكنها استدعاء useToast وعرض إطار عرض. |
Toast.Viewport
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
aria-label | string | — | اسم المنطقة التي تضم طابور الإشعارات العابرة للتقنيات المساعدة. |
className | string | — | الفئة المطبّقة على عنصر إطار العرض. |
popover | "manual" | — | يعيّنه إطار العرض الحي على العميل لوضع الطابور المعروض في الطبقة العليا؛ ويتركه هيكل الخادم دون تعيين. |
ref | Ref<HTMLElement> | — | مرجع إلى عنصر إطار العرض. |
children | ReactNode | — | محتوى إضافي يُعرض داخل إطار العرض مع الإشعارات العابرة في الطابور. |
Toast.Root
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
toast* | ToastRecord | — | السجل المطلوب عرضه من الطابور، مع معرّفه المحلول وعنوانه ووصفه وإجرائه ومدته وأولويته. |
Toast.Title
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
className | string | — | الفئة المطبّقة على عنصر العنوان. |
children | ReactNode | — | محتوى العنوان. |
Toast.Description
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
className | string | — | الفئة المطبّقة على عنصر الوصف. |
children | ReactNode | — | محتوى الوصف. |
Toast.Action
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
className | string | — | الفئة المطبّقة على زر الإجراء. |
onClick | (event: MouseEvent<HTMLButtonElement>) => void | — | تُستدعى عند النقر على زر الإجراء. |
children | ReactNode | — | محتوى زر الإجراء. |
Toast.Close
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
className | string | — | الفئة المطبّقة على زر الإغلاق. |
onClick | (event: MouseEvent<HTMLButtonElement>) => void | — | تُستدعى عند النقر على زر الإغلاق. |
children | ReactNode | — | محتوى زر الإغلاق. |
useToast().toast(input)
| الخاصية | النوع | افتراضي | الوصف |
|---|---|---|---|
title | ReactNode | — | سطر عنوان الإشعار العابر. |
description | ReactNode | — | سطر مساعد تحت العنوان. |
action | { label: ReactNode; onClick: () => void } | — | تسمية ومعالج لزر إجراء واحد على الإشعار العابر. |
duration | number | 4000 | المدة بالمللي ثانية قبل إغلاق الإشعار العابر تلقائيًا؛ وتبقيه قيمة صفر أو أقل حتى يُغلق. |
priority | "polite" | "assertive" | "polite" | المنطقة الحية التي تعلن الإشعار العابر. |
id | string | — | معرّف الإشعار العابر؛ يُولّد عند حذفه. |
لوحة المفاتيح
| المفتاح | الإجراء |
|---|---|
| Tab | تركيز أزرار الإجراءات داخل الإشعار العابر |
| Escape | الإغلاق حين يكون متاحًا |
إمكانية الوصول
إعلانات المنطقة الحية بنمط polite أو assertive؛ لا تنقل الإضافة إلى الطابور التركيز، ويوقف التحويم أو التركيز الإغلاق التلقائي مؤقتًا.
نقاط التنسيق
data-statedata-part="item"data-part="title"data-part="description"data-part="action"data-part="close"