Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
min-block-size: 0;
overflow: hidden;
border-radius: calc(var(--openbitfun-space-8) + var(--openbitfun-space-1));
background: color-mix(in srgb, var(--openbitfun-color-content-on-light) 80%, transparent);
background: var(--openbitfun-color-content-on-light);
color: var(--openbitfun-color-content-on-dark);
font-family: var(--openbitfun-type-body-lg-font-family);
font-size: var(--openbitfun-type-body-lg-font-size);
Expand All @@ -20,6 +20,15 @@
letter-spacing: var(--openbitfun-type-body-lg-letter-spacing);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
.root {
/* Figma live-call surface: 80% dark fill over a 10px backdrop blur. */
background: color-mix(in srgb, var(--openbitfun-color-content-on-light) 80%, transparent);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
}

.header {
display: flex;
flex: 0 0 auto;
Expand Down Expand Up @@ -142,11 +151,20 @@
}

@media (prefers-reduced-transparency: reduce) {
.root { background: var(--openbitfun-color-content-on-light); }
.root {
background: var(--openbitfun-color-content-on-light);
-webkit-backdrop-filter: none;
backdrop-filter: none;
}
}

@media (forced-colors: active) {
.root { background: Canvas; color: CanvasText; }
.root {
background: Canvas;
color: CanvasText;
-webkit-backdrop-filter: none;
backdrop-filter: none;
}
.user { border: 1px solid CanvasText; }
.root :is(.control, .back, .close) { border: 1px solid ButtonText; color: ButtonText; opacity: 1; }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
import { Button, Icon, OverflowText } from '@openbitfun/ui';
import { Button, Icon, IconButton, OverflowText } from '@openbitfun/ui';
import type { AnnouncementCard } from '../types';
import { useAnnouncementStore } from '../store/announcementStore';
import { useAnnouncementI18n } from '../hooks/useAnnouncementI18n';
Expand Down Expand Up @@ -69,32 +69,34 @@ const AnnouncementToastItem: React.FC<Props> = ({ card }) => {
aria-hidden={exiting}
{...(exiting ? { inert: '' } : {})}
>
{/* Row 1: title + close (with optional countdown ring) */}
{/* Row 1: title + close with optional countdown ring */}
<div className="announcement-toast__header">
<OverflowText as="div" lines={2} className="announcement-toast__title">{resolve(toast.title)}</OverflowText>
{toast.dismissible && (
<div className="announcement-toast__close-wrap">
{autoDismissMs && (
{autoDismissMs != null && autoDismissMs > 0 && (
<svg
className="announcement-toast__ring"
viewBox="0 0 28 28"
aria-hidden
aria-hidden="true"
focusable="false"
>
<circle cx="14" cy="14" r="11.5"
<circle cx="14" cy="14" r="13.25"
className="announcement-toast__ring-track" />
<circle cx="14" cy="14" r="11.5"
<circle cx="14" cy="14" r="13.25" pathLength="100"
className="announcement-toast__ring-fill"
style={{ animationDuration: `${autoDismissMs}ms` }} />
</svg>
)}
<button
type="button"
<IconButton
className="announcement-toast__close"
shape="circle"
size="xs"
variant="quiet"
icon={<Icon name="xmark" />}
onClick={handleDismiss}
aria-label={t('announcements.common.close')}
>
<Icon name="xmark" size="lg" />
</button>
/>
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ $toast-width: 320px;
overflow: hidden;
}

// ── Close button + countdown ring ────────────────────────────────────────
// The transparent close control and countdown share one circular footprint.
&__close-wrap {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 28px;
height: 28px;
Expand All @@ -133,63 +136,38 @@ $toast-width: 320px;

&__ring {
position: absolute;
z-index: 1;
inset: 0;
width: 100%;
height: 100%;
// Start arc from 12 o'clock
transform: rotate(-90deg);
pointer-events: none;
}

// Circumference = 2π × 11.5 ≈ 72.26
$ring-circumference: 72.26px;
&__ring-track,
&__ring-fill {
fill: none;
stroke-width: 1.5;
}

&__ring-track {
fill: none;
stroke: var(--openbitfun-color-border-default);
stroke-width: 1.5;
}

&__ring-fill {
fill: none;
stroke: var(--openbitfun-color-accent-default);
stroke-width: 1.5;
stroke-linecap: round;
stroke-dasharray: $ring-circumference;
stroke-dasharray: 100;
stroke-dashoffset: 0;
animation: openbitfun-announcement-ring-countdown linear both;
// Smooth opacity fade at the very end
transition: opacity 0.3s ease;
}

// Match the ring's hit area while retaining the shared small close glyph.
&__close {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: inline-flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
border-radius: 50%;
inline-size: 100%;
block-size: 100%;
flex-shrink: 0;
color: var(--openbitfun-color-content-muted);
cursor: pointer;
transition:
background-color var(--openbitfun-motion-duration-base) var(--openbitfun-motion-easing-standard),
color var(--openbitfun-motion-duration-base) var(--openbitfun-motion-easing-standard);

svg {
width: 13px;
height: 13px;
}

@media (hover: hover) and (pointer: fine) {
&:hover {
background: var(--openbitfun-color-surface-panel);
color: var(--openbitfun-color-content-primary);
}
}
}

// ── Description ──────────────────────────────────────────────────────────
Expand Down Expand Up @@ -221,11 +199,11 @@ $toast-width: 320px;
@keyframes openbitfun-announcement-toast-in {
from {
opacity: 0;
transform: translateX(-12px) scale(0.985);
transform: translateX(-12px);
}
to {
opacity: 1;
transform: translateX(0) scale(1);
transform: translateX(0);
}
}

Expand All @@ -242,7 +220,7 @@ $toast-width: 320px;

@keyframes openbitfun-announcement-ring-countdown {
from { stroke-dashoffset: 0; }
to { stroke-dashoffset: 72.26px; }
to { stroke-dashoffset: 100; }
}

@media (prefers-reduced-motion: reduce) {
Expand Down
Loading