@sarunyu/system-one 4.3.1 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -0
- package/README.md +7 -0
- package/dist/index.cjs +448 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +450 -39
- package/dist/index.js.map +1 -1
- package/dist/src/components/alert.d.ts +9 -0
- package/dist/src/components/alert.d.ts.map +1 -0
- package/dist/src/components/badge.d.ts +23 -0
- package/dist/src/components/badge.d.ts.map +1 -0
- package/dist/src/components/card.d.ts +1 -1
- package/dist/src/components/card.d.ts.map +1 -1
- package/dist/src/components/notification.d.ts +47 -0
- package/dist/src/components/notification.d.ts.map +1 -0
- package/dist/src/components/toast.d.ts +25 -0
- package/dist/src/components/toast.d.ts.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/llms.txt +160 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import React__default, { forwardRef, useState, useRef, useEffect, useCallback, useId, useMemo, useLayoutEffect, useContext, createContext } from "react";
|
|
5
5
|
import { clsx } from "clsx";
|
|
6
6
|
import { twMerge } from "tailwind-merge";
|
|
7
|
-
import { BookmarkSimpleIcon, BroadcastIcon, CalendarBlank, MapPin, Users,
|
|
7
|
+
import { BellSimple, FunnelSimple, CheckCircle, Warning, XCircle, Info, BookmarkSimpleIcon, BroadcastIcon as BroadcastIcon$1, CalendarBlank, MapPin, Users, Lock, Check, Plus, Circle, Minus, CaretLeft, CaretRight, CaretDoubleLeft, CaretDoubleRight, CaretUp, CaretDown, X, ImageSquare, MegaphoneSimple, GearSix, MagnifyingGlass, ArrowUp, ArrowDown, ArrowsDownUp, Clock } from "@phosphor-icons/react";
|
|
8
8
|
import { DayPicker, useNavigation } from "react-day-picker";
|
|
9
9
|
import * as Popover from "@radix-ui/react-popover";
|
|
10
10
|
import { Drawer as Drawer$1 } from "vaul";
|
|
@@ -228,6 +228,154 @@ const Button = forwardRef(function Button2({
|
|
|
228
228
|
);
|
|
229
229
|
});
|
|
230
230
|
Button.displayName = "Button";
|
|
231
|
+
function formatCount(count, maxCount) {
|
|
232
|
+
if (count > maxCount) return `${maxCount}+`;
|
|
233
|
+
return String(count);
|
|
234
|
+
}
|
|
235
|
+
function Badge({
|
|
236
|
+
variant = "button",
|
|
237
|
+
count = 0,
|
|
238
|
+
maxCount = 99,
|
|
239
|
+
label = "Filter",
|
|
240
|
+
iconOnly = false,
|
|
241
|
+
icon,
|
|
242
|
+
notificationState,
|
|
243
|
+
className,
|
|
244
|
+
...props
|
|
245
|
+
}) {
|
|
246
|
+
const hasCount = count > 0;
|
|
247
|
+
const isActive = hasCount;
|
|
248
|
+
const resolvedNotificationState = notificationState ?? (hasCount ? "noti" : "default");
|
|
249
|
+
const notificationIsFilled = resolvedNotificationState === "active" || resolvedNotificationState === "noti";
|
|
250
|
+
const showNotificationDot = resolvedNotificationState === "noti" && hasCount;
|
|
251
|
+
const visualIcon = variant === "notification" ? notificationIsFilled ? /* @__PURE__ */ jsx(BellSimple, { size: 19, weight: "fill" }) : /* @__PURE__ */ jsx(BellSimple, { size: 19, weight: "regular" }) : icon ?? /* @__PURE__ */ jsx(FunnelSimple, { size: 18, weight: "regular" });
|
|
252
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex", className), children: [
|
|
253
|
+
variant === "notification" ? /* @__PURE__ */ jsx(
|
|
254
|
+
Button,
|
|
255
|
+
{
|
|
256
|
+
"aria-label": "Notification",
|
|
257
|
+
size: "icon-xs",
|
|
258
|
+
variant: "plain-black",
|
|
259
|
+
className: cn(
|
|
260
|
+
"text-subtle-text",
|
|
261
|
+
notificationIsFilled && "text-primary-action"
|
|
262
|
+
),
|
|
263
|
+
...props,
|
|
264
|
+
children: visualIcon
|
|
265
|
+
}
|
|
266
|
+
) : iconOnly ? /* @__PURE__ */ jsx(
|
|
267
|
+
Button,
|
|
268
|
+
{
|
|
269
|
+
"aria-label": label,
|
|
270
|
+
size: "icon-md",
|
|
271
|
+
variant: isActive ? "outline" : "outline-black",
|
|
272
|
+
className: cn(isActive && "bg-primary-action-light border-primary-action-light"),
|
|
273
|
+
...props,
|
|
274
|
+
children: visualIcon
|
|
275
|
+
}
|
|
276
|
+
) : /* @__PURE__ */ jsx(
|
|
277
|
+
Button,
|
|
278
|
+
{
|
|
279
|
+
size: "md",
|
|
280
|
+
leftIcon: visualIcon,
|
|
281
|
+
variant: isActive ? "outline" : "outline-black",
|
|
282
|
+
className: cn(isActive && "bg-primary-action-light border-primary-action-light"),
|
|
283
|
+
...props,
|
|
284
|
+
children: label
|
|
285
|
+
}
|
|
286
|
+
),
|
|
287
|
+
(variant === "notification" ? showNotificationDot : hasCount) && /* @__PURE__ */ jsx(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
className: cn(
|
|
291
|
+
"absolute flex items-center justify-center rounded-[60px] px-1",
|
|
292
|
+
variant === "notification" ? "-right-0.5 -top-0.5 h-[14px] min-w-[14px] bg-destructive" : "-right-1 -top-[7px] h-4 min-w-4 bg-primary-action"
|
|
293
|
+
),
|
|
294
|
+
children: /* @__PURE__ */ jsx("p", { className: "text-center text-xs leading-4 text-on-primary-action", children: formatCount(count, maxCount) })
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
] });
|
|
298
|
+
}
|
|
299
|
+
const alertStyles = {
|
|
300
|
+
normal: {
|
|
301
|
+
container: "bg-default-secondary",
|
|
302
|
+
text: "text-default-secondary",
|
|
303
|
+
icon: "text-default-secondary"
|
|
304
|
+
},
|
|
305
|
+
information: {
|
|
306
|
+
container: "bg-[var(--bg-info-light)]",
|
|
307
|
+
text: "text-[var(--text-info-primary)]",
|
|
308
|
+
icon: "text-[var(--icon-brand-primary)]"
|
|
309
|
+
},
|
|
310
|
+
success: {
|
|
311
|
+
container: "bg-[var(--bg-success-light)]",
|
|
312
|
+
text: "text-[var(--text-success-primary)]",
|
|
313
|
+
icon: "text-[var(--icon-success)]"
|
|
314
|
+
},
|
|
315
|
+
warning: {
|
|
316
|
+
container: "bg-[var(--bg-warning-soft)]",
|
|
317
|
+
text: "text-[var(--text-warning-primary)]",
|
|
318
|
+
icon: "text-[var(--icon-warning)]"
|
|
319
|
+
},
|
|
320
|
+
critical: {
|
|
321
|
+
container: "bg-[var(--bg-danger-light)]",
|
|
322
|
+
text: "text-[var(--text-danger-primary)]",
|
|
323
|
+
icon: "text-[var(--icon-danger)]"
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
function AlertStatusIcon({
|
|
327
|
+
status,
|
|
328
|
+
className
|
|
329
|
+
}) {
|
|
330
|
+
if (status === "success") return /* @__PURE__ */ jsx(CheckCircle, { size: 16, weight: "fill", className });
|
|
331
|
+
if (status === "warning") return /* @__PURE__ */ jsx(Warning, { size: 16, weight: "fill", className });
|
|
332
|
+
if (status === "critical") return /* @__PURE__ */ jsx(XCircle, { size: 16, weight: "fill", className });
|
|
333
|
+
return /* @__PURE__ */ jsx(Info, { size: 16, weight: "fill", className });
|
|
334
|
+
}
|
|
335
|
+
const Alert = forwardRef(function Alert2({ status = "normal", message, multiline = false, className }, ref) {
|
|
336
|
+
const style = alertStyles[status];
|
|
337
|
+
return /* @__PURE__ */ jsxs(
|
|
338
|
+
"div",
|
|
339
|
+
{
|
|
340
|
+
ref,
|
|
341
|
+
role: "status",
|
|
342
|
+
className: cn(
|
|
343
|
+
"flex w-full items-center gap-1.5 rounded px-2 py-1",
|
|
344
|
+
multiline && "items-start",
|
|
345
|
+
style.container,
|
|
346
|
+
className
|
|
347
|
+
),
|
|
348
|
+
children: [
|
|
349
|
+
/* @__PURE__ */ jsx(AlertStatusIcon, { status, className: cn("shrink-0", multiline && "mt-0.5", style.icon) }),
|
|
350
|
+
/* @__PURE__ */ jsx(
|
|
351
|
+
"p",
|
|
352
|
+
{
|
|
353
|
+
className: cn(
|
|
354
|
+
"min-w-0 flex-1 text-sm leading-5 font-normal",
|
|
355
|
+
multiline ? "line-clamp-2" : "truncate",
|
|
356
|
+
style.text
|
|
357
|
+
),
|
|
358
|
+
children: message
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
});
|
|
365
|
+
Alert.displayName = "Alert";
|
|
366
|
+
function BannerMedia({ src, alt }) {
|
|
367
|
+
if (!src) {
|
|
368
|
+
return /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "absolute inset-0 bg-muted" });
|
|
369
|
+
}
|
|
370
|
+
return /* @__PURE__ */ jsx(
|
|
371
|
+
"img",
|
|
372
|
+
{
|
|
373
|
+
alt,
|
|
374
|
+
className: "pointer-events-none absolute inset-0 size-full object-cover",
|
|
375
|
+
src
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
}
|
|
231
379
|
function DurationBadge({
|
|
232
380
|
duration,
|
|
233
381
|
size
|
|
@@ -241,7 +389,7 @@ function DurationBadge({
|
|
|
241
389
|
size === "lg" ? "bottom-[6px] right-[6px] h-[20px] px-[4px]" : "bottom-[4px] right-[4px] h-[16px] px-[2px]"
|
|
242
390
|
),
|
|
243
391
|
children: [
|
|
244
|
-
isUpcoming && /* @__PURE__ */ jsx(BroadcastIcon, { size: 14, className: "text-white" }),
|
|
392
|
+
isUpcoming && /* @__PURE__ */ jsx(BroadcastIcon$1, { size: 14, className: "text-white" }),
|
|
245
393
|
/* @__PURE__ */ jsx(
|
|
246
394
|
"p",
|
|
247
395
|
{
|
|
@@ -321,7 +469,7 @@ const tagConfig = {
|
|
|
321
469
|
}
|
|
322
470
|
};
|
|
323
471
|
const Card = forwardRef(function Card2({
|
|
324
|
-
variant = "
|
|
472
|
+
variant = "default",
|
|
325
473
|
size = "desktop",
|
|
326
474
|
children,
|
|
327
475
|
title,
|
|
@@ -435,14 +583,7 @@ const Card = forwardRef(function Card2({
|
|
|
435
583
|
}
|
|
436
584
|
)
|
|
437
585
|
] }),
|
|
438
|
-
/* @__PURE__ */ jsx("div", { className: "relative h-[84px] w-[149px] shrink-0 overflow-clip rounded-[6px]", children: /* @__PURE__ */ jsx(
|
|
439
|
-
"img",
|
|
440
|
-
{
|
|
441
|
-
alt: "social thumbnail",
|
|
442
|
-
className: "pointer-events-none absolute inset-0 size-full object-cover",
|
|
443
|
-
src: bannerSrc
|
|
444
|
-
}
|
|
445
|
-
) })
|
|
586
|
+
/* @__PURE__ */ jsx("div", { className: "relative h-[84px] w-[149px] shrink-0 overflow-clip rounded-[6px]", children: /* @__PURE__ */ jsx(BannerMedia, { src: bannerSrc, alt: "social thumbnail" }) })
|
|
446
587
|
] }),
|
|
447
588
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
448
589
|
isDesktop ? /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-[12px]", children: [
|
|
@@ -525,14 +666,7 @@ const Card = forwardRef(function Card2({
|
|
|
525
666
|
imgHeight
|
|
526
667
|
),
|
|
527
668
|
children: [
|
|
528
|
-
/* @__PURE__ */ jsx(
|
|
529
|
-
"img",
|
|
530
|
-
{
|
|
531
|
-
alt: "live thumbnail",
|
|
532
|
-
className: "pointer-events-none absolute inset-0 size-full object-cover",
|
|
533
|
-
src: bannerSrc
|
|
534
|
-
}
|
|
535
|
-
),
|
|
669
|
+
/* @__PURE__ */ jsx(BannerMedia, { src: bannerSrc, alt: "live thumbnail" }),
|
|
536
670
|
/* @__PURE__ */ jsxs(
|
|
537
671
|
"div",
|
|
538
672
|
{
|
|
@@ -569,14 +703,7 @@ const Card = forwardRef(function Card2({
|
|
|
569
703
|
),
|
|
570
704
|
children: [
|
|
571
705
|
/* @__PURE__ */ jsxs("div", { className: "relative h-[184px] w-full shrink-0 overflow-clip", children: [
|
|
572
|
-
/* @__PURE__ */ jsx(
|
|
573
|
-
"img",
|
|
574
|
-
{
|
|
575
|
-
alt: "news banner",
|
|
576
|
-
className: "pointer-events-none absolute inset-0 size-full object-cover",
|
|
577
|
-
src: bannerSrc
|
|
578
|
-
}
|
|
579
|
-
),
|
|
706
|
+
/* @__PURE__ */ jsx(BannerMedia, { src: bannerSrc, alt: "news banner" }),
|
|
580
707
|
locked && /* @__PURE__ */ jsx(LockBadge, {})
|
|
581
708
|
] }),
|
|
582
709
|
/* @__PURE__ */ jsx(
|
|
@@ -606,14 +733,7 @@ const Card = forwardRef(function Card2({
|
|
|
606
733
|
),
|
|
607
734
|
children: [
|
|
608
735
|
/* @__PURE__ */ jsxs("div", { className: "relative h-[114px] w-[171px] shrink-0 overflow-clip", children: [
|
|
609
|
-
/* @__PURE__ */ jsx(
|
|
610
|
-
"img",
|
|
611
|
-
{
|
|
612
|
-
alt: "news banner",
|
|
613
|
-
className: "pointer-events-none absolute inset-0 size-full object-cover",
|
|
614
|
-
src: bannerSrc
|
|
615
|
-
}
|
|
616
|
-
),
|
|
736
|
+
/* @__PURE__ */ jsx(BannerMedia, { src: bannerSrc, alt: "news banner" }),
|
|
617
737
|
locked && /* @__PURE__ */ jsx(LockBadge, {})
|
|
618
738
|
] }),
|
|
619
739
|
/* @__PURE__ */ jsx(
|
|
@@ -651,11 +771,10 @@ const Card = forwardRef(function Card2({
|
|
|
651
771
|
className: cn("relative w-full shrink-0 overflow-clip", bannerClass),
|
|
652
772
|
children: [
|
|
653
773
|
/* @__PURE__ */ jsx(
|
|
654
|
-
|
|
774
|
+
BannerMedia,
|
|
655
775
|
{
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
src: bannerSrc
|
|
776
|
+
src: bannerSrc,
|
|
777
|
+
alt: variant === "news" ? "news banner" : "event banner"
|
|
659
778
|
}
|
|
660
779
|
),
|
|
661
780
|
locked && /* @__PURE__ */ jsx(LockBadge, { size })
|
|
@@ -3737,6 +3856,293 @@ function ModalActions({
|
|
|
3737
3856
|
)
|
|
3738
3857
|
] });
|
|
3739
3858
|
}
|
|
3859
|
+
function NotificationDivider({ label }) {
|
|
3860
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 px-4 py-2", children: [
|
|
3861
|
+
/* @__PURE__ */ jsx("p", { className: "shrink-0 text-sm leading-5 text-subtle-text", children: label }),
|
|
3862
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "h-px min-w-0 flex-1 bg-divider" })
|
|
3863
|
+
] });
|
|
3864
|
+
}
|
|
3865
|
+
function NotificationRow({
|
|
3866
|
+
item,
|
|
3867
|
+
onItemClick
|
|
3868
|
+
}) {
|
|
3869
|
+
const rowType = item.type ?? "icon";
|
|
3870
|
+
const showImage = rowType === "image";
|
|
3871
|
+
const showUnread = Boolean(item.unread);
|
|
3872
|
+
return /* @__PURE__ */ jsxs(
|
|
3873
|
+
"div",
|
|
3874
|
+
{
|
|
3875
|
+
className: cn(
|
|
3876
|
+
"flex w-full items-start gap-3 px-4 py-3",
|
|
3877
|
+
showUnread ? "bg-primary-action-light/40" : "bg-background"
|
|
3878
|
+
),
|
|
3879
|
+
role: "button",
|
|
3880
|
+
tabIndex: 0,
|
|
3881
|
+
onClick: () => onItemClick == null ? void 0 : onItemClick(item),
|
|
3882
|
+
onKeyDown: (e) => {
|
|
3883
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3884
|
+
e.preventDefault();
|
|
3885
|
+
onItemClick == null ? void 0 : onItemClick(item);
|
|
3886
|
+
}
|
|
3887
|
+
},
|
|
3888
|
+
children: [
|
|
3889
|
+
/* @__PURE__ */ jsx("div", { className: "flex w-10 shrink-0 items-start justify-center py-0.5", children: showImage ? item.imageSrc ? /* @__PURE__ */ jsx(
|
|
3890
|
+
"img",
|
|
3891
|
+
{
|
|
3892
|
+
alt: "",
|
|
3893
|
+
className: "h-10 w-10 rounded object-cover",
|
|
3894
|
+
src: item.imageSrc
|
|
3895
|
+
}
|
|
3896
|
+
) : /* @__PURE__ */ jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded bg-disabled-bg text-disabled", children: /* @__PURE__ */ jsx(ImageSquare, { size: 20, weight: "regular" }) }) : /* @__PURE__ */ jsx("div", { className: "flex h-6 w-6 items-center justify-center text-subtle-text", children: item.icon ?? /* @__PURE__ */ jsx(Circle, { size: 20, weight: "regular" }) }) }),
|
|
3897
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
3898
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_auto] items-start gap-x-2", children: [
|
|
3899
|
+
/* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-base leading-6 font-bold text-foreground", children: item.title }),
|
|
3900
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
3901
|
+
showUnread && /* @__PURE__ */ jsx(
|
|
3902
|
+
"span",
|
|
3903
|
+
{
|
|
3904
|
+
"aria-hidden": "true",
|
|
3905
|
+
className: "h-2 w-2 rounded-full bg-primary-action"
|
|
3906
|
+
}
|
|
3907
|
+
),
|
|
3908
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs leading-4 text-muted-foreground", children: item.time })
|
|
3909
|
+
] }),
|
|
3910
|
+
/* @__PURE__ */ jsx("p", { className: "col-start-1 mt-1 line-clamp-2 text-sm leading-5 text-muted-foreground", children: item.description })
|
|
3911
|
+
] }),
|
|
3912
|
+
item.actionLabel && /* @__PURE__ */ jsx(
|
|
3913
|
+
Button,
|
|
3914
|
+
{
|
|
3915
|
+
className: "mt-2",
|
|
3916
|
+
size: "md",
|
|
3917
|
+
variant: "primary",
|
|
3918
|
+
onClick: (e) => {
|
|
3919
|
+
var _a;
|
|
3920
|
+
e.stopPropagation();
|
|
3921
|
+
(_a = item.onActionClick) == null ? void 0 : _a.call(item);
|
|
3922
|
+
},
|
|
3923
|
+
children: item.actionLabel
|
|
3924
|
+
}
|
|
3925
|
+
)
|
|
3926
|
+
] })
|
|
3927
|
+
]
|
|
3928
|
+
}
|
|
3929
|
+
);
|
|
3930
|
+
}
|
|
3931
|
+
const Notification = forwardRef(
|
|
3932
|
+
function Notification2({
|
|
3933
|
+
groups,
|
|
3934
|
+
badgeCount,
|
|
3935
|
+
panelWidth = 375,
|
|
3936
|
+
emptyText = "No notifications",
|
|
3937
|
+
clearBadgeOnOpen = true,
|
|
3938
|
+
open,
|
|
3939
|
+
defaultOpen,
|
|
3940
|
+
onOpenChange,
|
|
3941
|
+
onBadgeCleared,
|
|
3942
|
+
onItemClick,
|
|
3943
|
+
className,
|
|
3944
|
+
panelClassName
|
|
3945
|
+
}, ref) {
|
|
3946
|
+
const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);
|
|
3947
|
+
const [isBadgeCleared, setIsBadgeCleared] = useState(false);
|
|
3948
|
+
const controlled = open !== void 0;
|
|
3949
|
+
const resolvedOpen = controlled ? open : internalOpen;
|
|
3950
|
+
const unreadCount = useMemo(
|
|
3951
|
+
() => groups.reduce(
|
|
3952
|
+
(acc, group) => acc + group.items.filter((item) => Boolean(item.unread)).length,
|
|
3953
|
+
0
|
|
3954
|
+
),
|
|
3955
|
+
[groups]
|
|
3956
|
+
);
|
|
3957
|
+
const nextCount = badgeCount ?? unreadCount;
|
|
3958
|
+
const prevCountRef = useRef(nextCount);
|
|
3959
|
+
useEffect(() => {
|
|
3960
|
+
const prevCount = prevCountRef.current;
|
|
3961
|
+
if (nextCount <= 0 || nextCount > prevCount) {
|
|
3962
|
+
setIsBadgeCleared(false);
|
|
3963
|
+
}
|
|
3964
|
+
prevCountRef.current = nextCount;
|
|
3965
|
+
}, [nextCount]);
|
|
3966
|
+
const displayCount = clearBadgeOnOpen && isBadgeCleared ? 0 : nextCount;
|
|
3967
|
+
const hasItems = groups.some((group) => group.items.length > 0);
|
|
3968
|
+
const handleOpenChange = (next) => {
|
|
3969
|
+
if (next && clearBadgeOnOpen && nextCount > 0) {
|
|
3970
|
+
setIsBadgeCleared(true);
|
|
3971
|
+
onBadgeCleared == null ? void 0 : onBadgeCleared();
|
|
3972
|
+
}
|
|
3973
|
+
if (!controlled) setInternalOpen(next);
|
|
3974
|
+
onOpenChange == null ? void 0 : onOpenChange(next);
|
|
3975
|
+
};
|
|
3976
|
+
return /* @__PURE__ */ jsxs(Popover.Root, { open: resolvedOpen, onOpenChange: handleOpenChange, children: [
|
|
3977
|
+
/* @__PURE__ */ jsx("div", { ref, className: cn("inline-flex", className), children: /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
|
|
3978
|
+
Badge,
|
|
3979
|
+
{
|
|
3980
|
+
variant: "notification",
|
|
3981
|
+
count: displayCount,
|
|
3982
|
+
maxCount: 99,
|
|
3983
|
+
notificationState: displayCount > 0 ? "noti" : resolvedOpen ? "active" : "default",
|
|
3984
|
+
"aria-label": "Open notifications"
|
|
3985
|
+
}
|
|
3986
|
+
) }) }) }),
|
|
3987
|
+
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(
|
|
3988
|
+
Popover.Content,
|
|
3989
|
+
{
|
|
3990
|
+
align: "end",
|
|
3991
|
+
sideOffset: 10,
|
|
3992
|
+
className: cn(
|
|
3993
|
+
"z-50 overflow-hidden rounded-lg border border-border bg-background shadow-lg",
|
|
3994
|
+
panelClassName
|
|
3995
|
+
),
|
|
3996
|
+
style: { width: panelWidth },
|
|
3997
|
+
children: /* @__PURE__ */ jsxs("div", { className: "max-h-[480px] overflow-y-auto py-2", children: [
|
|
3998
|
+
!hasItems && /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center text-sm text-muted-foreground", children: emptyText }),
|
|
3999
|
+
groups.map((group) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
4000
|
+
/* @__PURE__ */ jsx(NotificationDivider, { label: group.label }),
|
|
4001
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-divider", children: group.items.map((item) => /* @__PURE__ */ jsx(
|
|
4002
|
+
NotificationRow,
|
|
4003
|
+
{
|
|
4004
|
+
item,
|
|
4005
|
+
onItemClick
|
|
4006
|
+
},
|
|
4007
|
+
item.id
|
|
4008
|
+
)) })
|
|
4009
|
+
] }, group.label))
|
|
4010
|
+
] })
|
|
4011
|
+
}
|
|
4012
|
+
) })
|
|
4013
|
+
] });
|
|
4014
|
+
}
|
|
4015
|
+
);
|
|
4016
|
+
Notification.displayName = "Notification";
|
|
4017
|
+
const statusStyles = {
|
|
4018
|
+
information: {
|
|
4019
|
+
bg: "bg-[var(--bg-info-light)]",
|
|
4020
|
+
text: "text-[var(--text-info-primary)]",
|
|
4021
|
+
icon: "text-[var(--icon-brand-primary)]",
|
|
4022
|
+
link: "text-[var(--text-brand-link-primary)]"
|
|
4023
|
+
},
|
|
4024
|
+
success: {
|
|
4025
|
+
bg: "bg-[var(--bg-success-light)]",
|
|
4026
|
+
text: "text-[var(--text-success-primary)]",
|
|
4027
|
+
icon: "text-[var(--icon-success)]",
|
|
4028
|
+
link: "text-[var(--text-success-link)]"
|
|
4029
|
+
},
|
|
4030
|
+
warning: {
|
|
4031
|
+
bg: "bg-[var(--bg-warning-soft)]",
|
|
4032
|
+
text: "text-[var(--text-warning-primary)]",
|
|
4033
|
+
icon: "text-[var(--icon-warning)]",
|
|
4034
|
+
link: "text-[var(--text-warning-link)]"
|
|
4035
|
+
},
|
|
4036
|
+
critical: {
|
|
4037
|
+
bg: "bg-[var(--bg-danger-light)]",
|
|
4038
|
+
text: "text-[var(--text-danger-primary)]",
|
|
4039
|
+
icon: "text-[var(--icon-danger)]",
|
|
4040
|
+
link: "text-[var(--text-danger-link)]"
|
|
4041
|
+
}
|
|
4042
|
+
};
|
|
4043
|
+
function DefaultIcon({
|
|
4044
|
+
status,
|
|
4045
|
+
className
|
|
4046
|
+
}) {
|
|
4047
|
+
if (status === "success") return /* @__PURE__ */ jsx(CheckCircle, { className, size: 24, weight: "fill" });
|
|
4048
|
+
if (status === "warning") return /* @__PURE__ */ jsx(Warning, { className, size: 24, weight: "fill" });
|
|
4049
|
+
if (status === "critical") return /* @__PURE__ */ jsx(XCircle, { className, size: 24, weight: "fill" });
|
|
4050
|
+
return /* @__PURE__ */ jsx(Info, { className, size: 24, weight: "fill" });
|
|
4051
|
+
}
|
|
4052
|
+
function BroadcastIcon({
|
|
4053
|
+
status,
|
|
4054
|
+
className
|
|
4055
|
+
}) {
|
|
4056
|
+
if (status === "information") {
|
|
4057
|
+
return /* @__PURE__ */ jsx(MegaphoneSimple, { className, size: 20, weight: "fill" });
|
|
4058
|
+
}
|
|
4059
|
+
return /* @__PURE__ */ jsx(GearSix, { className, size: 20, weight: "fill" });
|
|
4060
|
+
}
|
|
4061
|
+
function ToastCloseButton({
|
|
4062
|
+
colorClass,
|
|
4063
|
+
onClose
|
|
4064
|
+
}) {
|
|
4065
|
+
return /* @__PURE__ */ jsx(
|
|
4066
|
+
"button",
|
|
4067
|
+
{
|
|
4068
|
+
type: "button",
|
|
4069
|
+
"aria-label": "Close toast",
|
|
4070
|
+
className: cn(
|
|
4071
|
+
"inline-flex h-[18px] w-[18px] shrink-0 cursor-pointer items-center justify-center",
|
|
4072
|
+
colorClass
|
|
4073
|
+
),
|
|
4074
|
+
onClick: onClose,
|
|
4075
|
+
children: /* @__PURE__ */ jsx(X, { size: 12, weight: "bold" })
|
|
4076
|
+
}
|
|
4077
|
+
);
|
|
4078
|
+
}
|
|
4079
|
+
const Toast = forwardRef(function Toast2({
|
|
4080
|
+
variant = "default",
|
|
4081
|
+
status = "information",
|
|
4082
|
+
message,
|
|
4083
|
+
actionLabel,
|
|
4084
|
+
multiline = false,
|
|
4085
|
+
onActionClick,
|
|
4086
|
+
onClose,
|
|
4087
|
+
className
|
|
4088
|
+
}, ref) {
|
|
4089
|
+
const hasAction = Boolean(actionLabel);
|
|
4090
|
+
const effectiveStatus = variant === "broadcast" && status === "success" ? "information" : status;
|
|
4091
|
+
const effectiveStyle = statusStyles[effectiveStatus];
|
|
4092
|
+
const Icon = variant === "broadcast" ? BroadcastIcon : DefaultIcon;
|
|
4093
|
+
const showActions = variant === "default";
|
|
4094
|
+
return /* @__PURE__ */ jsxs(
|
|
4095
|
+
"div",
|
|
4096
|
+
{
|
|
4097
|
+
ref,
|
|
4098
|
+
role: "status",
|
|
4099
|
+
className: cn(
|
|
4100
|
+
"flex w-full p-3",
|
|
4101
|
+
variant === "default" ? "items-center gap-2 rounded-lg shadow-[0px_1px_2px_0px_rgba(0,0,0,0.10),0px_1px_3px_1px_rgba(0,0,0,0.05)]" : "items-center gap-2",
|
|
4102
|
+
multiline && "items-start",
|
|
4103
|
+
effectiveStyle.bg,
|
|
4104
|
+
className
|
|
4105
|
+
),
|
|
4106
|
+
children: [
|
|
4107
|
+
/* @__PURE__ */ jsxs(
|
|
4108
|
+
"div",
|
|
4109
|
+
{
|
|
4110
|
+
className: cn(
|
|
4111
|
+
"flex min-w-0 flex-1 gap-2",
|
|
4112
|
+
multiline ? "items-start" : "items-center",
|
|
4113
|
+
variant === "default" && !hasAction && "opacity-80"
|
|
4114
|
+
),
|
|
4115
|
+
children: [
|
|
4116
|
+
/* @__PURE__ */ jsx("div", { className: cn("shrink-0", multiline && "pt-0.5"), children: /* @__PURE__ */ jsx(Icon, { status: effectiveStatus, className: effectiveStyle.icon }) }),
|
|
4117
|
+
/* @__PURE__ */ jsx("p", { className: cn("min-w-0 flex-1 text-sm leading-5 font-normal", effectiveStyle.text), children: message })
|
|
4118
|
+
]
|
|
4119
|
+
}
|
|
4120
|
+
),
|
|
4121
|
+
showActions && hasAction ? /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [
|
|
4122
|
+
/* @__PURE__ */ jsx(
|
|
4123
|
+
"button",
|
|
4124
|
+
{
|
|
4125
|
+
type: "button",
|
|
4126
|
+
className: cn(
|
|
4127
|
+
"cursor-pointer text-sm leading-5 underline underline-offset-2",
|
|
4128
|
+
effectiveStyle.link
|
|
4129
|
+
),
|
|
4130
|
+
onClick: onActionClick,
|
|
4131
|
+
children: actionLabel
|
|
4132
|
+
}
|
|
4133
|
+
),
|
|
4134
|
+
/* @__PURE__ */ jsx(ToastCloseButton, { colorClass: effectiveStyle.icon, onClose })
|
|
4135
|
+
] }) : showActions ? /* @__PURE__ */ jsx(ToastCloseButton, { colorClass: effectiveStyle.icon, onClose }) : null
|
|
4136
|
+
]
|
|
4137
|
+
}
|
|
4138
|
+
);
|
|
4139
|
+
});
|
|
4140
|
+
Toast.displayName = "Toast";
|
|
4141
|
+
function ToastStack({ items, className, renderItem }) {
|
|
4142
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col gap-2", className), children: items.map(
|
|
4143
|
+
(item) => renderItem ? /* @__PURE__ */ jsx("div", { children: renderItem(item) }, item.id) : /* @__PURE__ */ jsx(Toast, { ...item }, item.id)
|
|
4144
|
+
) });
|
|
4145
|
+
}
|
|
3740
4146
|
const OptionList = forwardRef(
|
|
3741
4147
|
function OptionList2({
|
|
3742
4148
|
options,
|
|
@@ -5370,6 +5776,8 @@ const TimeInput = forwardRef(
|
|
|
5370
5776
|
);
|
|
5371
5777
|
TimeInput.displayName = "TimeInput";
|
|
5372
5778
|
export {
|
|
5779
|
+
Alert,
|
|
5780
|
+
Badge,
|
|
5373
5781
|
BottomSheet,
|
|
5374
5782
|
Button,
|
|
5375
5783
|
Card,
|
|
@@ -5380,6 +5788,7 @@ export {
|
|
|
5380
5788
|
DropdownMultiple,
|
|
5381
5789
|
Input,
|
|
5382
5790
|
Modal,
|
|
5791
|
+
Notification,
|
|
5383
5792
|
OptionList,
|
|
5384
5793
|
Radio,
|
|
5385
5794
|
SearchInput,
|
|
@@ -5393,6 +5802,8 @@ export {
|
|
|
5393
5802
|
Tag,
|
|
5394
5803
|
TextArea,
|
|
5395
5804
|
TimeInput,
|
|
5805
|
+
Toast,
|
|
5806
|
+
ToastStack,
|
|
5396
5807
|
Toggle,
|
|
5397
5808
|
cn,
|
|
5398
5809
|
useIsMobile
|