@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/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, XCircle, CheckCircle, Lock, Check, Plus, Circle, Minus, CaretLeft, CaretRight, CaretDoubleLeft, CaretDoubleRight, CaretUp, CaretDown, X, MagnifyingGlass, ArrowUp, ArrowDown, ArrowsDownUp, Clock } from "@phosphor-icons/react";
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 = "event",
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
- "img",
774
+ BannerMedia,
655
775
  {
656
- alt: variant === "news" ? "news banner" : "event banner",
657
- className: "pointer-events-none absolute inset-0 size-full object-cover",
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