@syscore/ui-library 1.27.3 → 2.0.0-beta-publish-workflow-beta.2

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.
Files changed (169) hide show
  1. package/client/App.tsx +0 -2
  2. package/client/assets/alert/icon-clear.svg +4 -0
  3. package/client/assets/alert/icon-done.svg +3 -0
  4. package/client/assets/avatar-identity/photo.png +0 -0
  5. package/client/assets/avatar-identity/placeholder-icon.svg +8 -0
  6. package/client/assets/breadcrumb/icon-ellipsis.svg +5 -0
  7. package/client/assets/breadcrumb/icon-home.svg +3 -0
  8. package/client/assets/breadcrumb/icon-separator.svg +3 -0
  9. package/client/assets/button-v01/icon-back.svg +4 -0
  10. package/client/assets/button-v01/icon-check.svg +3 -0
  11. package/client/assets/button-v01/icon-close.svg +4 -0
  12. package/client/assets/button-v01/icon-delete.svg +3 -0
  13. package/client/assets/button-v01/icon-device.svg +3 -0
  14. package/client/assets/dropdown/icon-carrot-contract.svg +3 -0
  15. package/client/assets/dropdown/icon-carrot-expand.svg +3 -0
  16. package/client/assets/dropdown/icon-clear.svg +4 -0
  17. package/client/assets/dropdown/icon-enter.svg +3 -0
  18. package/client/components/icons/UtilityChangeType.tsx +21 -0
  19. package/client/components/ui/alert-dialog-panel.tsx +246 -0
  20. package/client/components/ui/alert-v02.tsx +214 -0
  21. package/client/components/ui/app-bar.tsx +299 -0
  22. package/client/components/ui/avatar-identity.tsx +122 -0
  23. package/client/components/ui/banner.tsx +108 -0
  24. package/client/components/ui/bottom-navigation.tsx +223 -0
  25. package/client/components/ui/breadcrumb-trail.tsx +170 -0
  26. package/client/components/ui/button-v01.tsx +238 -0
  27. package/client/components/ui/button.tsx +2 -0
  28. package/client/components/ui/card.tsx +108 -26
  29. package/client/components/ui/code-badge.tsx +62 -0
  30. package/client/components/ui/date-picker.tsx +188 -0
  31. package/client/components/ui/dropdown.tsx +448 -0
  32. package/client/components/ui/empty-state.tsx +197 -0
  33. package/client/components/ui/file-upload.tsx +214 -0
  34. package/client/components/ui/footer.tsx +179 -0
  35. package/client/components/ui/layout.tsx +1182 -0
  36. package/client/components/ui/pagination-v01.tsx +157 -0
  37. package/client/components/ui/password-field-v01.tsx +67 -0
  38. package/client/components/ui/search-field-v01.tsx +192 -0
  39. package/client/components/ui/section-heading.tsx +49 -0
  40. package/client/components/ui/sidebar.tsx +2 -3
  41. package/client/components/ui/standard-navigation.tsx +8 -2
  42. package/client/components/ui/stepper.tsx +148 -0
  43. package/client/components/ui/switch-v01.tsx +71 -0
  44. package/client/components/ui/system-bar.tsx +119 -0
  45. package/client/components/ui/table-v01.tsx +230 -0
  46. package/client/components/ui/tabs-v01.tsx +99 -0
  47. package/client/components/ui/tag-v02.tsx +113 -0
  48. package/client/components/ui/text-area-v01.tsx +33 -0
  49. package/client/components/ui/text-field-v01.tsx +108 -0
  50. package/client/components/ui/timeline.tsx +181 -0
  51. package/client/components/ui/toast-v01.tsx +206 -0
  52. package/client/components/ui/tooltip.tsx +264 -71
  53. package/client/global.css +9565 -4378
  54. package/client/storybook.css +125 -0
  55. package/client/ui/Accordion.stories.tsx +1 -1
  56. package/client/ui/AlertDialogPanel/AlertDialogPanel.stories.tsx +150 -0
  57. package/client/ui/AlertV02/AlertV02.stories.tsx +188 -0
  58. package/client/ui/AppBar/app-bar.stories.tsx +280 -0
  59. package/client/ui/AspectRatio.stories.tsx +1 -1
  60. package/client/ui/AvatarIdentity/AvatarIdentity.stories.tsx +77 -0
  61. package/client/ui/Banner/banner.stories.tsx +238 -0
  62. package/client/ui/BottomNavigation/bottom-navigation.stories.tsx +285 -0
  63. package/client/ui/BreadcrumbTrail/BreadcrumbTrail.stories.tsx +232 -0
  64. package/client/ui/Button.stories.tsx +1 -1
  65. package/client/ui/ButtonV01/ButtonV01.stories.tsx +417 -0
  66. package/client/ui/Calendar/Calendar.stories.tsx +1 -1
  67. package/client/ui/Card.stories.tsx +285 -168
  68. package/client/ui/Carousel/Carousel.stories.tsx +1 -1
  69. package/client/ui/Chart/Chart.stories.tsx +1 -1
  70. package/client/ui/Checkbox.stories.tsx +1 -1
  71. package/client/ui/Collapsible/Collapsible.stories.tsx +1 -1
  72. package/client/ui/Colors.stories.tsx +1 -1
  73. package/client/ui/Command/Command.stories.tsx +1 -1
  74. package/client/ui/ContextMenu/ContextMenu.stories.tsx +1 -1
  75. package/client/ui/DatePicker/DatePicker.stories.tsx +293 -0
  76. package/client/ui/Dialog.stories.tsx +1 -1
  77. package/client/ui/Drawer/Drawer.stories.tsx +1 -1
  78. package/client/ui/Dropdown/Dropdown.stories.tsx +205 -0
  79. package/client/ui/EmptyState/empty-state.stories.tsx +251 -0
  80. package/client/ui/FileUpload/FileUpload.stories.tsx +218 -0
  81. package/client/ui/Footer/footer.stories.tsx +194 -0
  82. package/client/ui/Form/Form.stories.tsx +1 -1
  83. package/client/ui/Hero.stories.tsx +1 -1
  84. package/client/ui/HoverCard/HoverCard.stories.tsx +1 -1
  85. package/client/ui/Icons.stories.tsx +1 -1
  86. package/client/ui/Input.stories.tsx +1 -1
  87. package/client/ui/InputOTP/InputOTP.stories.tsx +1 -1
  88. package/client/ui/Label.stories.tsx +1 -1
  89. package/client/ui/Layout/Center.stories.tsx +100 -0
  90. package/client/ui/Layout/Columns.stories.tsx +136 -0
  91. package/client/ui/Layout/Container.stories.tsx +104 -0
  92. package/client/ui/Layout/FormLayout.stories.tsx +144 -0
  93. package/client/ui/Layout/Grid.stories.tsx +158 -0
  94. package/client/ui/Layout/GridSpan.stories.tsx +75 -0
  95. package/client/ui/Layout/HStack.stories.tsx +128 -0
  96. package/client/ui/Layout/Layout.stories.tsx +287 -0
  97. package/client/ui/Layout/LayoutContent.stories.tsx +91 -0
  98. package/client/ui/Layout/LayoutFooter.stories.tsx +77 -0
  99. package/client/ui/Layout/LayoutHeader.stories.tsx +104 -0
  100. package/client/ui/Layout/LayoutPanel.stories.tsx +143 -0
  101. package/client/ui/Layout/Positioned.stories.tsx +113 -0
  102. package/client/ui/Layout/Section.stories.tsx +84 -0
  103. package/client/ui/Layout/ShowHide.stories.tsx +99 -0
  104. package/client/ui/Layout/Spacer.stories.tsx +149 -0
  105. package/client/ui/Layout/Stack.stories.tsx +69 -0
  106. package/client/ui/Layout/StackItem.stories.tsx +124 -0
  107. package/client/ui/Layout/VStack.stories.tsx +101 -0
  108. package/client/ui/Layout/controls.ts +33 -0
  109. package/client/ui/Layout/demo.tsx +37 -0
  110. package/client/ui/Menubar/Menubar.stories.tsx +1 -1
  111. package/client/ui/MobileNav.stories.tsx +1 -1
  112. package/client/ui/Navigation.stories.tsx +1 -1
  113. package/client/ui/NavigationMenu/NavigationMenu.stories.tsx +1 -1
  114. package/client/ui/PageHeader.stories.tsx +13 -13
  115. package/client/ui/Pagination/Pagination.stories.tsx +178 -98
  116. package/client/ui/Pagination/PaginationLegacy.stories.tsx +121 -0
  117. package/client/ui/Panel.stories.tsx +1 -1
  118. package/client/ui/Popover/Popover.stories.tsx +1 -1
  119. package/client/ui/Progress/Progress.stories.tsx +1 -1
  120. package/client/ui/RadioGroup/RadioGroup.stories.tsx +1 -1
  121. package/client/ui/Resizable/Resizable.stories.tsx +1 -1
  122. package/client/ui/ScrollArea/ScrollArea.stories.tsx +1 -1
  123. package/client/ui/SearchField/SearchField.stories.tsx +153 -0
  124. package/client/ui/{SearchField.stories.tsx → SearchField/SearchFieldLegacy.stories.tsx} +2 -2
  125. package/client/ui/SectionBadge.stories.tsx +1 -1
  126. package/client/ui/Select.stories.tsx +1 -1
  127. package/client/ui/Separator/Separator.stories.tsx +1 -1
  128. package/client/ui/Sheet/Sheet.stories.tsx +1 -1
  129. package/client/ui/Sidebar/Sidebar.stories.tsx +57 -8
  130. package/client/ui/Skeleton/Skeleton.stories.tsx +1 -1
  131. package/client/ui/Slider/Slider.stories.tsx +1 -1
  132. package/client/ui/StandardNavigation.stories.tsx +1 -1
  133. package/client/ui/Stepper/Stepper.stories.tsx +344 -0
  134. package/client/ui/Switch.stories.tsx +1 -1
  135. package/client/ui/SwitchV01/SwitchV01.stories.tsx +152 -0
  136. package/client/ui/SystemBar/system-bar.stories.tsx +179 -0
  137. package/client/ui/Table/TableV01.stories.tsx +256 -0
  138. package/client/ui/Tabs.stories.tsx +1 -1
  139. package/client/ui/TabsV01/TabsV01.stories.tsx +144 -0
  140. package/client/ui/Tag.stories.tsx +1 -1
  141. package/client/ui/TagV02/TagStatusV02.stories.tsx +132 -0
  142. package/client/ui/TagV02/TagV02.stories.tsx +142 -0
  143. package/client/ui/TextAreaV01/TextAreaV01.stories.tsx +146 -0
  144. package/client/ui/TextFieldV01/PasswordFieldV01.stories.tsx +161 -0
  145. package/client/ui/TextFieldV01/TextFieldV01.stories.tsx +160 -0
  146. package/client/ui/Textarea.stories.tsx +1 -1
  147. package/client/ui/Timeline/timeline.stories.tsx +404 -0
  148. package/client/ui/Toast/Toast.stories.tsx +1 -1
  149. package/client/ui/ToastV01/ToastV01.stories.tsx +201 -0
  150. package/client/ui/Toaster/Toaster.stories.tsx +1 -1
  151. package/client/ui/Toggle.stories.tsx +1 -1
  152. package/client/ui/Tooltip.stories.tsx +287 -114
  153. package/client/ui/Typography.stories.tsx +1 -1
  154. package/dist/index.cjs.js +1 -1
  155. package/dist/index.d.ts +649 -13
  156. package/dist/index.es.js +4405 -653
  157. package/package.json +1 -1
  158. package/client/components/ui/badge.tsx +0 -33
  159. package/client/components/ui/sonner.tsx +0 -26
  160. package/client/components/ui/toggle-group.tsx +0 -76
  161. package/client/ui/Alert/Alert.stories.tsx +0 -82
  162. package/client/ui/AlertDialog/AlertDialog.stories.tsx +0 -106
  163. package/client/ui/Avatar/Avatar.stories.tsx +0 -94
  164. package/client/ui/Badge/Badge.stories.tsx +0 -60
  165. package/client/ui/Breadcrumb/Breadcrumb.stories.tsx +0 -97
  166. package/client/ui/DropdownMenu/DropdownMenu.stories.tsx +0 -139
  167. package/client/ui/Sonner/Sonner.stories.tsx +0 -48
  168. package/client/ui/Table/Table.stories.tsx +0 -135
  169. package/client/ui/ToggleGroup/ToggleGroup.stories.tsx +0 -88
@@ -0,0 +1,108 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@/lib/utils";
4
+
5
+ export interface TextFieldV01Props
6
+ extends Omit<React.ComponentProps<"input">, "size"> {
7
+ label?: React.ReactNode;
8
+ helperText?: React.ReactNode;
9
+ error?: boolean;
10
+ warning?: boolean;
11
+ typeahead?: string;
12
+ focused?: boolean;
13
+ action?: React.ReactNode;
14
+ }
15
+
16
+ const TextFieldV01 = React.forwardRef<HTMLInputElement, TextFieldV01Props>(
17
+ (
18
+ {
19
+ className,
20
+ label,
21
+ helperText,
22
+ error = false,
23
+ warning = false,
24
+ typeahead,
25
+ focused,
26
+ action,
27
+ disabled,
28
+ readOnly,
29
+ value,
30
+ defaultValue,
31
+ placeholder = "Placeholder",
32
+ onChange,
33
+ id,
34
+ ...props
35
+ },
36
+ ref,
37
+ ) => {
38
+ const generated = React.useId();
39
+ const inputId = id ?? generated;
40
+
41
+ const isControlled = value !== undefined;
42
+ const [internal, setInternal] = React.useState(
43
+ () => (defaultValue as string) ?? "",
44
+ );
45
+ const current = isControlled ? String(value ?? "") : internal;
46
+
47
+ const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
48
+ if (!isControlled) setInternal(event.target.value);
49
+ onChange?.(event);
50
+ };
51
+
52
+ return (
53
+ <div
54
+ className={cn("text-field-v01 font-mazzardSoft", className)}
55
+ data-filled={current !== "" ? "true" : undefined}
56
+ data-error={error ? "true" : undefined}
57
+ data-warning={warning && !error ? "true" : undefined}
58
+ data-disabled={disabled ? "true" : undefined}
59
+ data-readonly={readOnly ? "true" : undefined}
60
+ data-focus={focused ? "true" : undefined}
61
+ data-typeahead={typeahead ? "true" : undefined}
62
+ >
63
+ {label != null && label !== "" ? (
64
+ <div className="text-field-v01-label">
65
+ <span className="text-field-v01-label-text overline-medium">
66
+ {label}
67
+ </span>
68
+ </div>
69
+ ) : null}
70
+
71
+ <div className="text-field-v01-cell">
72
+ {focused && current === "" ? (
73
+ <span className="text-field-v01-caret" aria-hidden />
74
+ ) : null}
75
+ <input
76
+ ref={ref}
77
+ id={inputId}
78
+ className="text-field-v01-input"
79
+ disabled={disabled}
80
+ readOnly={readOnly}
81
+ placeholder={placeholder}
82
+ value={isControlled ? value : internal}
83
+ onChange={handleChange}
84
+ aria-invalid={error || undefined}
85
+ aria-describedby={helperText ? `${inputId}-helper` : undefined}
86
+ {...props}
87
+ />
88
+ {focused && current !== "" ? (
89
+ <span className="text-field-v01-caret" aria-hidden />
90
+ ) : null}
91
+ {typeahead ? (
92
+ <span className="text-field-v01-typeahead">{typeahead}</span>
93
+ ) : null}
94
+ {action}
95
+ </div>
96
+
97
+ {helperText != null && helperText !== "" ? (
98
+ <div className="text-field-v01-helper" id={`${inputId}-helper`}>
99
+ {helperText}
100
+ </div>
101
+ ) : null}
102
+ </div>
103
+ );
104
+ },
105
+ );
106
+ TextFieldV01.displayName = "TextFieldV01";
107
+
108
+ export { TextFieldV01 };
@@ -0,0 +1,181 @@
1
+ import * as React from "react";
2
+ import { cn } from "@/lib/utils";
3
+
4
+ // ─── Context ──────────────────────────────────────────────────────────────────
5
+
6
+ interface TimelineContextValue {
7
+ direction: "vertical" | "horizontal";
8
+ side: "start" | "end" | "alternate";
9
+ align: "center" | "start";
10
+ density: "default" | "compact";
11
+ }
12
+
13
+ const TimelineContext = React.createContext<TimelineContextValue>({
14
+ direction: "vertical",
15
+ side: "alternate",
16
+ align: "center",
17
+ density: "default",
18
+ });
19
+
20
+ // ─── Timeline Root ────────────────────────────────────────────────────────────
21
+
22
+ export interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {
23
+ /**
24
+ * Layout direction.
25
+ * - "vertical" → items stack top-to-bottom (default)
26
+ * - "horizontal" → items flow left-to-right
27
+ */
28
+ direction?: "vertical" | "horizontal";
29
+ /**
30
+ * Which side content renders on relative to the stem.
31
+ * - "alternate" → alternates left / right (default)
32
+ * - "end" → all content on the right (vertical) or below (horizontal)
33
+ * - "start" → all content on the left (vertical) or above (horizontal)
34
+ */
35
+ side?: "start" | "end" | "alternate";
36
+ /**
37
+ * Vertical alignment of content inside each item.
38
+ * - "center" → content is centered on the dot (default)
39
+ * - "start" → content aligns to the top of the dot
40
+ */
41
+ align?: "center" | "start";
42
+ /**
43
+ * Reduces spacing between items.
44
+ */
45
+ density?: "default" | "compact";
46
+ }
47
+
48
+ const Timeline = React.forwardRef<HTMLDivElement, TimelineProps>(
49
+ (
50
+ {
51
+ className,
52
+ children,
53
+ direction = "vertical",
54
+ side = "alternate",
55
+ align = "center",
56
+ density = "default",
57
+ ...props
58
+ },
59
+ ref
60
+ ) => (
61
+ <TimelineContext.Provider value={{ direction, side, align, density }}>
62
+ <div
63
+ ref={ref}
64
+ className={cn(
65
+ "timeline",
66
+ direction === "horizontal" && "timeline--horizontal",
67
+ `timeline--side-${side}`,
68
+ `timeline--align-${align}`,
69
+ density === "compact" && "timeline--compact",
70
+ className
71
+ )}
72
+ {...props}
73
+ >
74
+ {children}
75
+ </div>
76
+ </TimelineContext.Provider>
77
+ )
78
+ );
79
+ Timeline.displayName = "Timeline";
80
+
81
+ // ─── TimelineItem ─────────────────────────────────────────────────────────────
82
+
83
+ export interface TimelineItemProps extends React.HTMLAttributes<HTMLDivElement> {
84
+ /**
85
+ * Background color of the dot — any CSS color or var() token.
86
+ */
87
+ dotColor?: string;
88
+ /**
89
+ * Size of the dot.
90
+ * - "x-small" → 12px
91
+ * - "small" → 16px (default)
92
+ * - "default" → 24px
93
+ * - "large" → 32px
94
+ * - "x-large" → 40px
95
+ */
96
+ size?: "x-small" | "small" | "default" | "large" | "x-large";
97
+ /**
98
+ * When true the dot background is filled with `dotColor`
99
+ * (instead of just a border ring).
100
+ */
101
+ fillDot?: boolean;
102
+ /**
103
+ * Completely hides the dot and stem connector.
104
+ */
105
+ hideDot?: boolean;
106
+ /**
107
+ * Icon rendered inside the dot. Pass any React node.
108
+ * For best results use with size="large" or size="x-large".
109
+ */
110
+ icon?: React.ReactNode;
111
+ /**
112
+ * Content rendered on the opposite side of the stem from the main content.
113
+ * Equivalent to Vuetify's v-slot:opposite.
114
+ */
115
+ opposite?: React.ReactNode;
116
+ }
117
+
118
+ const TimelineItem = React.forwardRef<HTMLDivElement, TimelineItemProps>(
119
+ (
120
+ {
121
+ className,
122
+ children,
123
+ dotColor,
124
+ size = "small",
125
+ fillDot = false,
126
+ hideDot = false,
127
+ icon,
128
+ opposite,
129
+ ...props
130
+ },
131
+ ref
132
+ ) => {
133
+ const { align } = React.useContext(TimelineContext);
134
+
135
+ return (
136
+ <div
137
+ ref={ref}
138
+ className={cn(
139
+ "timeline-item",
140
+ `timeline-item--size-${size}`,
141
+ fillDot && "timeline-item--fill-dot",
142
+ hideDot && "timeline-item--hide-dot",
143
+ align === "start" && "timeline-item--align-start",
144
+ className
145
+ )}
146
+ {...props}
147
+ >
148
+ {/* Opposite slot */}
149
+ <div className="timeline-item-opposite">
150
+ {opposite}
151
+ </div>
152
+
153
+ {/* Stem + dot column */}
154
+ <div className="timeline-item-stem">
155
+ <div className="timeline-item-stem-line timeline-item-stem-line--before" />
156
+ {!hideDot && (
157
+ <div
158
+ className="timeline-item-dot"
159
+ style={dotColor ? { backgroundColor: dotColor, borderColor: dotColor } : undefined}
160
+ >
161
+ {icon && (
162
+ <span className="timeline-item-dot-icon">{icon}</span>
163
+ )}
164
+ </div>
165
+ )}
166
+ <div className="timeline-item-stem-line timeline-item-stem-line--after" />
167
+ </div>
168
+
169
+ {/* Main content */}
170
+ <div className="timeline-item-body">
171
+ {children}
172
+ </div>
173
+ </div>
174
+ );
175
+ }
176
+ );
177
+ TimelineItem.displayName = "TimelineItem";
178
+
179
+ // ─── Exports ──────────────────────────────────────────────────────────────────
180
+
181
+ export { Timeline, TimelineItem };
@@ -0,0 +1,206 @@
1
+ import * as React from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+
4
+ import { cn } from "@/lib/utils";
5
+ import { ButtonV01 } from "@/components/ui/button-v01";
6
+ import { AvatarIdentity } from "@/components/ui/avatar-identity";
7
+ import iconDone from "@/assets/alert/icon-done.svg";
8
+ import iconClear from "@/assets/alert/icon-clear.svg";
9
+
10
+ const toastV01Variants = cva("toast-v01 font-mazzardSoft", {
11
+ variants: {
12
+ variant: {
13
+ solid: "toast-v01--solid",
14
+ subtle: "toast-v01--subtle",
15
+ outline: "toast-v01--outline",
16
+ },
17
+ size: {
18
+ large: "toast-v01--large",
19
+ small: "toast-v01--small",
20
+ },
21
+ color: {
22
+ default: "toast-v01--default",
23
+ success: "toast-v01--success",
24
+ error: "toast-v01--error",
25
+ },
26
+ },
27
+ defaultVariants: {
28
+ variant: "solid",
29
+ size: "large",
30
+ color: "default",
31
+ },
32
+ });
33
+
34
+ export type ToastV01Variant = NonNullable<
35
+ VariantProps<typeof toastV01Variants>["variant"]
36
+ >;
37
+ export type ToastV01Size = NonNullable<
38
+ VariantProps<typeof toastV01Variants>["size"]
39
+ >;
40
+ export type ToastV01Color = NonNullable<
41
+ VariantProps<typeof toastV01Variants>["color"]
42
+ >;
43
+ export type ToastV01Indicator = "icon" | "avatar";
44
+
45
+ function MaskIcon({ src, className }: { src: string; className?: string }) {
46
+ return (
47
+ <span
48
+ className={cn("toast-v01-mask-icon", className)}
49
+ style={{
50
+ WebkitMaskImage: `url("${src}")`,
51
+ maskImage: `url("${src}")`,
52
+ }}
53
+ aria-hidden
54
+ />
55
+ );
56
+ }
57
+
58
+ export interface ToastV01Props
59
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, "color" | "title">,
60
+ VariantProps<typeof toastV01Variants> {
61
+ indicator?: ToastV01Indicator;
62
+ action?: boolean;
63
+ title?: React.ReactNode;
64
+ description?: React.ReactNode;
65
+ confirmLabel?: React.ReactNode;
66
+ cancelLabel?: React.ReactNode;
67
+ onConfirm?: () => void;
68
+ onCancel?: () => void;
69
+ onDismiss?: () => void;
70
+ icon?: React.ReactNode;
71
+ avatar?: React.ReactNode;
72
+ avatarSrc?: string;
73
+ avatarAlt?: string;
74
+ }
75
+
76
+ const ToastV01 = React.forwardRef<HTMLDivElement, ToastV01Props>(
77
+ (
78
+ {
79
+ className,
80
+ variant = "solid",
81
+ size = "large",
82
+ color = "default",
83
+ indicator = "icon",
84
+ action = true,
85
+ title,
86
+ description,
87
+ confirmLabel = "Confirm",
88
+ cancelLabel = "Cancel",
89
+ onConfirm,
90
+ onCancel,
91
+ onDismiss,
92
+ icon,
93
+ avatar,
94
+ avatarSrc,
95
+ avatarAlt,
96
+ children,
97
+ ...props
98
+ },
99
+ ref,
100
+ ) => {
101
+ const isLarge = size !== "small";
102
+ const showDescription =
103
+ isLarge && description != null && description !== "";
104
+ const showCancel = isLarge && action;
105
+ const heading = title ?? children;
106
+
107
+ const indicatorNode =
108
+ indicator === "avatar"
109
+ ? (avatar ?? (
110
+ <AvatarIdentity
111
+ className="toast-v01-avatar"
112
+ size="medium"
113
+ variant={avatarSrc ? "image" : "placeholder"}
114
+ src={avatarSrc}
115
+ alt={avatarAlt}
116
+ showText={false}
117
+ />
118
+ ))
119
+ : (icon ?? (
120
+ <span className="toast-v01-indicator">
121
+ <MaskIcon src={iconDone} className="toast-v01-icon-done" />
122
+ </span>
123
+ ));
124
+
125
+ const dismissButton = (
126
+ <button
127
+ type="button"
128
+ className="toast-v01-dismiss"
129
+ aria-label="Dismiss"
130
+ onClick={onDismiss}
131
+ >
132
+ <MaskIcon src={iconClear} className="toast-v01-icon-clear" />
133
+ </button>
134
+ );
135
+
136
+ const confirmButton = (
137
+ <ButtonV01
138
+ type="button"
139
+ size="small"
140
+ typeVariant="utility"
141
+ hierarchy="primary"
142
+ appearance="solid"
143
+ context="general"
144
+ className="toast-v01-button"
145
+ onClick={onConfirm}
146
+ >
147
+ {confirmLabel}
148
+ </ButtonV01>
149
+ );
150
+
151
+ const cancelButton = (
152
+ <ButtonV01
153
+ type="button"
154
+ size="small"
155
+ typeVariant="utility"
156
+ hierarchy="tertiary"
157
+ appearance="stroke"
158
+ theme="light"
159
+ context="general"
160
+ className="toast-v01-button toast-v01-button--cancel"
161
+ onClick={onCancel}
162
+ >
163
+ {cancelLabel}
164
+ </ButtonV01>
165
+ );
166
+
167
+ return (
168
+ <div
169
+ ref={ref}
170
+ role="status"
171
+ aria-live="polite"
172
+ className={cn(toastV01Variants({ variant, size, color }), className)}
173
+ {...props}
174
+ >
175
+ {indicatorNode}
176
+
177
+ {isLarge ? (
178
+ <div className="toast-v01-content">
179
+ <div className="toast-v01-heading">
180
+ <h5 className="toast-v01-title">{heading}</h5>
181
+ {dismissButton}
182
+ </div>
183
+ {showDescription ? (
184
+ <div className="toast-v01-description">{description}</div>
185
+ ) : null}
186
+ {action ? (
187
+ <div className="toast-v01-actions">
188
+ {confirmButton}
189
+ {showCancel ? cancelButton : null}
190
+ </div>
191
+ ) : null}
192
+ </div>
193
+ ) : (
194
+ <>
195
+ <h5 className="toast-v01-title">{heading}</h5>
196
+ {action ? confirmButton : null}
197
+ {dismissButton}
198
+ </>
199
+ )}
200
+ </div>
201
+ );
202
+ },
203
+ );
204
+ ToastV01.displayName = "ToastV01";
205
+
206
+ export { ToastV01, toastV01Variants };