@dust-tt/sparkle 0.2.571 → 0.2.573

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 (40) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/esm/components/AnnouncementCard.d.ts +14 -0
  3. package/dist/esm/components/AnnouncementCard.d.ts.map +1 -0
  4. package/dist/esm/components/AnnouncementCard.js +25 -0
  5. package/dist/esm/components/AnnouncementCard.js.map +1 -0
  6. package/dist/esm/components/ContentMessage.d.ts +12 -2
  7. package/dist/esm/components/ContentMessage.d.ts.map +1 -1
  8. package/dist/esm/components/ContentMessage.js +52 -13
  9. package/dist/esm/components/ContentMessage.js.map +1 -1
  10. package/dist/esm/components/Dialog.js +1 -1
  11. package/dist/esm/components/MessageCard.d.ts +14 -0
  12. package/dist/esm/components/MessageCard.d.ts.map +1 -0
  13. package/dist/esm/components/MessageCard.js +25 -0
  14. package/dist/esm/components/MessageCard.js.map +1 -0
  15. package/dist/esm/components/index.d.ts +2 -1
  16. package/dist/esm/components/index.d.ts.map +1 -1
  17. package/dist/esm/components/index.js +2 -1
  18. package/dist/esm/components/index.js.map +1 -1
  19. package/dist/esm/stories/AnnouncementCard.stories.d.ts +8 -0
  20. package/dist/esm/stories/AnnouncementCard.stories.d.ts.map +1 -0
  21. package/dist/esm/stories/AnnouncementCard.stories.js +60 -0
  22. package/dist/esm/stories/AnnouncementCard.stories.js.map +1 -0
  23. package/dist/esm/stories/ContentMessage.stories.d.ts +6 -0
  24. package/dist/esm/stories/ContentMessage.stories.d.ts.map +1 -1
  25. package/dist/esm/stories/ContentMessage.stories.js +36 -1
  26. package/dist/esm/stories/ContentMessage.stories.js.map +1 -1
  27. package/dist/esm/stories/MessageCard.stories.d.ts +8 -0
  28. package/dist/esm/stories/MessageCard.stories.d.ts.map +1 -0
  29. package/dist/esm/stories/MessageCard.stories.js +60 -0
  30. package/dist/esm/stories/MessageCard.stories.js.map +1 -0
  31. package/dist/sparkle.css +9 -0
  32. package/package.json +1 -1
  33. package/src/components/AnnouncementCard.tsx +90 -0
  34. package/src/components/ContentMessage.tsx +90 -18
  35. package/src/components/Dialog.tsx +1 -1
  36. package/src/components/MessageCard.tsx +93 -0
  37. package/src/components/index.ts +6 -1
  38. package/src/stories/AnnouncementCard.stories.tsx +68 -0
  39. package/src/stories/ContentMessage.stories.tsx +86 -0
  40. package/src/stories/MessageCard.stories.tsx +68 -0
package/dist/sparkle.css CHANGED
@@ -2426,6 +2426,11 @@ select {
2426
2426
  border-bottom-right-radius: 0px;
2427
2427
  }
2428
2428
 
2429
+ .s-rounded-t-2xl {
2430
+ border-top-left-radius: 1rem;
2431
+ border-top-right-radius: 1rem;
2432
+ }
2433
+
2429
2434
  .s-border {
2430
2435
  border-width: 1px;
2431
2436
  }
@@ -4457,6 +4462,10 @@ select {
4457
4462
  line-height: 1.625;
4458
4463
  }
4459
4464
 
4465
+ .s-leading-tight {
4466
+ line-height: 1.25;
4467
+ }
4468
+
4460
4469
  .s-tracking-widest {
4461
4470
  letter-spacing: 0.1em;
4462
4471
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dust-tt/sparkle",
3
- "version": "0.2.571",
3
+ "version": "0.2.573",
4
4
  "scripts": {
5
5
  "build": "rm -rf dist && npm run tailwind && npm run build:esm && npm run build:cjs",
6
6
  "tailwind": "tailwindcss -i ./src/styles/tailwind.css -o dist/sparkle.css",
@@ -0,0 +1,90 @@
1
+ import React from "react";
2
+
3
+ import { Button } from "@sparkle/components/Button";
4
+ import { cn } from "@sparkle/lib/utils";
5
+
6
+ export interface MessageCardProps {
7
+ className?: string;
8
+ haveImage?: boolean;
9
+ imageSrc?: string;
10
+ announcementTitle?: string;
11
+ announcementMessage: string;
12
+ learnMoreHref?: string;
13
+ onLearnMore?: () => void;
14
+ onDismiss?: () => void;
15
+ dismissible?: boolean;
16
+ }
17
+
18
+ export const MessageCard = React.forwardRef<HTMLDivElement, MessageCardProps>(
19
+ (
20
+ {
21
+ className,
22
+ haveImage = false,
23
+ imageSrc,
24
+ announcementTitle = "New on Dust",
25
+ announcementMessage,
26
+ learnMoreHref,
27
+ onLearnMore,
28
+ onDismiss,
29
+ dismissible = true,
30
+ ...props
31
+ },
32
+ ref
33
+ ) => {
34
+ const handleLearnMore = () => {
35
+ if (onLearnMore) {
36
+ onLearnMore();
37
+ } else if (learnMoreHref) {
38
+ window.open(learnMoreHref, "_blank", "noopener,noreferrer");
39
+ }
40
+ };
41
+
42
+ return (
43
+ <div
44
+ ref={ref}
45
+ className={cn(
46
+ "s-flex s-flex-col s-overflow-hidden",
47
+ "s-bg-white dark:s-bg-black",
48
+ "s-rounded-2xl s-shadow-md",
49
+ "s-border s-border-border/0 dark:s-border-border-night/0",
50
+ className
51
+ )}
52
+ {...props}
53
+ >
54
+ {haveImage && imageSrc && (
55
+ <div
56
+ className="s-relative s-h-48 s-overflow-hidden s-rounded-t-2xl s-bg-cover s-bg-center s-bg-no-repeat"
57
+ style={{ backgroundImage: `url(${imageSrc})` }}
58
+ />
59
+ )}
60
+
61
+ <div className="s-p-4">
62
+ <div className="s-mb-2 s-text-sm s-font-medium s-text-primary dark:s-text-primary-night">
63
+ {announcementTitle}
64
+ </div>
65
+ <h4 className="s-mb-4 s-text-lg s-font-medium s-leading-tight s-text-foreground dark:s-text-foreground-night">
66
+ {announcementMessage}
67
+ </h4>
68
+ <div className="s-flex s-items-center s-justify-between">
69
+ <Button
70
+ variant="highlight"
71
+ size="sm"
72
+ onClick={handleLearnMore}
73
+ label="Learn more"
74
+ />
75
+ {dismissible && onDismiss && (
76
+ <Button
77
+ variant="ghost"
78
+ size="sm"
79
+ onClick={onDismiss}
80
+ label="Dismiss"
81
+ />
82
+ )}
83
+ </div>
84
+ </div>
85
+ </div>
86
+ );
87
+ }
88
+ );
89
+
90
+ MessageCard.displayName = "MessageCard";
@@ -1,6 +1,7 @@
1
1
  import { cva } from "class-variance-authority";
2
2
  import React, { ComponentType } from "react";
3
3
 
4
+ import { Button, ButtonProps } from "@sparkle/components/Button";
4
5
  import { Icon } from "@sparkle/components/Icon";
5
6
  import { cn } from "@sparkle/lib/utils";
6
7
 
@@ -23,27 +24,26 @@ const CONTENT_MESSAGE_SIZES = ["sm", "md", "lg"] as const;
23
24
 
24
25
  type ContentMessageSizeType = (typeof CONTENT_MESSAGE_SIZES)[number];
25
26
 
27
+ const sharedVariantStyles = {
28
+ primary:
29
+ "s-bg-muted-background dark:s-bg-muted-background-night s-border-border dark:s-border-border-night",
30
+ success: "s-bg-success-100 dark:s-bg-success-100-night s-border-transparent",
31
+ warning: "s-bg-warning-100 dark:s-bg-warning-100-night s-border-transparent",
32
+ highlight:
33
+ "s-bg-highlight-100 dark:s-bg-highlight-100-night s-border-transparent",
34
+ info: "s-bg-info-100 dark:s-bg-info-100-night s-border-transparent",
35
+ green: "s-bg-green-100 dark:s-bg-green-100-night s-border-transparent",
36
+ blue: "s-bg-blue-100 dark:s-bg-blue-100-night s-border-transparent",
37
+ rose: "s-bg-rose-100 dark:s-bg-rose-100-night s-border-transparent",
38
+ golden: "s-bg-golden-100 dark:s-bg-golden-100-night s-border-transparent",
39
+ outline: "s-bg-transparent s-border-border dark:s-border-border-night",
40
+ };
41
+
26
42
  const contentMessageVariants = cva(
27
43
  "s-flex s-flex-col s-gap-1 s-rounded-xl s-py-4 s-px-5 s-border",
28
44
  {
29
45
  variants: {
30
- variant: {
31
- primary:
32
- "s-bg-muted-background dark:s-bg-muted-background-night s-border-border dark:s-border-border-night",
33
- success:
34
- "s-bg-success-100 dark:s-bg-success-100-night s-border-transparent",
35
- warning:
36
- "s-bg-warning-100 dark:s-bg-warning-100-night s-border-transparent",
37
- highlight:
38
- "s-bg-highlight-100 dark:s-bg-highlight-100-night s-border-transparent",
39
- info: "s-bg-info-100 dark:s-bg-info-100-night s-border-transparent",
40
- green: "s-bg-green-100 dark:s-bg-green-100-night s-border-transparent",
41
- blue: "s-bg-blue-100 dark:s-bg-blue-100-night s-border-transparent",
42
- rose: "s-bg-rose-100 dark:s-bg-rose-100-night s-border-transparent",
43
- golden:
44
- "s-bg-golden-100 dark:s-bg-golden-100-night s-border-transparent",
45
- outline: "s-bg-transparent s-border-border dark:s-border-border-night",
46
- },
46
+ variant: sharedVariantStyles,
47
47
  size: {
48
48
  lg: "",
49
49
  md: "s-max-w-[500px]",
@@ -57,6 +57,18 @@ const contentMessageVariants = cva(
57
57
  }
58
58
  );
59
59
 
60
+ const contentMessageInlineVariants = cva(
61
+ "s-flex s-items-center s-gap-3 s-rounded-lg s-py-3 s-px-4 s-border",
62
+ {
63
+ variants: {
64
+ variant: sharedVariantStyles,
65
+ },
66
+ defaultVariants: {
67
+ variant: "info",
68
+ },
69
+ }
70
+ );
71
+
60
72
  const iconVariants = cva("s-shrink-0", {
61
73
  variants: {
62
74
  variant: {
@@ -117,7 +129,7 @@ export interface ContentMessageProps {
117
129
  icon?: ComponentType;
118
130
  }
119
131
 
120
- export function ContentMessage({
132
+ function ContentMessage({
121
133
  title,
122
134
  variant = "info",
123
135
  children,
@@ -140,6 +152,66 @@ export function ContentMessage({
140
152
  </div>
141
153
  )}
142
154
  {children && <div className={textVariants({ variant })}>{children}</div>}
155
+ {/* TODO(2025-08-13 aubin): Allow passing a ContentMessageAction here. */}
156
+ </div>
157
+ );
158
+ }
159
+
160
+ function ContentMessageAction(props: ButtonProps) {
161
+ return (
162
+ <Button
163
+ size="xs"
164
+ className={cn("s-shrink-0", props.className)}
165
+ {...props}
166
+ />
167
+ );
168
+ }
169
+
170
+ export interface ContentMessageInlineProps {
171
+ title?: string;
172
+ className?: string;
173
+ children?: React.ReactNode;
174
+ variant?: ContentMessageVariantType;
175
+ icon?: ComponentType;
176
+ }
177
+
178
+ function ContentMessageInline({
179
+ title,
180
+ variant = "info",
181
+ children,
182
+ className = "",
183
+ icon,
184
+ }: ContentMessageInlineProps) {
185
+ const childrenArray = React.Children.toArray(children);
186
+
187
+ const { actionChilds, contentChildren } = childrenArray.reduce(
188
+ ({ actionChilds, contentChildren }, child) => {
189
+ if (React.isValidElement(child) && child.type === ContentMessageAction) {
190
+ actionChilds.push(child);
191
+ } else {
192
+ contentChildren.push(child);
193
+ }
194
+ return { actionChilds, contentChildren };
195
+ },
196
+ {
197
+ actionChilds: [] as React.ReactNode[],
198
+ contentChildren: [] as React.ReactNode[],
199
+ }
200
+ );
201
+
202
+ return (
203
+ <div className={cn(contentMessageInlineVariants({ variant }), className)}>
204
+ {icon && (
205
+ <Icon size="xs" visual={icon} className={iconVariants({ variant })} />
206
+ )}
207
+ <div className={cn("s-flex-1", textVariants({ variant }))}>
208
+ {title && <span className={titleVariants({ variant })}>{title}</span>}
209
+ {title && contentChildren.length > 0 && ": "}
210
+ {contentChildren}
211
+ </div>
212
+ {actionChilds}
143
213
  </div>
144
214
  );
145
215
  }
216
+
217
+ export { ContentMessage, ContentMessageAction, ContentMessageInline };
@@ -174,7 +174,7 @@ const DialogFooter = ({
174
174
  <div className="s-flex s-flex-none s-flex-col s-gap-0">
175
175
  <div
176
176
  className={cn(
177
- "s-flex s-flex-none s-flex-row s-justify-end s-gap-2 s-px-3 s-py-3",
177
+ "s-flex s-flex-none s-flex-row s-justify-end s-gap-2 s-px-3 s-pb-3",
178
178
  className
179
179
  )}
180
180
  {...props}
@@ -0,0 +1,93 @@
1
+ import React from "react";
2
+
3
+ import { Button } from "@sparkle/components/Button";
4
+ import { cn } from "@sparkle/lib/utils";
5
+
6
+ export interface MessageCardProps {
7
+ className?: string;
8
+ haveImage?: boolean;
9
+ imageSrc?: string;
10
+ announcementTitle?: string;
11
+ announcementMessage: string;
12
+ learnMoreHref?: string;
13
+ onLearnMore?: () => void;
14
+ onDismiss?: () => void;
15
+ dismissible?: boolean;
16
+ }
17
+
18
+ export const MessageCard = React.forwardRef<
19
+ HTMLDivElement,
20
+ MessageCardProps
21
+ >(
22
+ (
23
+ {
24
+ className,
25
+ haveImage = false,
26
+ imageSrc,
27
+ announcementTitle = "New on Dust",
28
+ announcementMessage,
29
+ learnMoreHref,
30
+ onLearnMore,
31
+ onDismiss,
32
+ dismissible = true,
33
+ ...props
34
+ },
35
+ ref
36
+ ) => {
37
+ const handleLearnMore = () => {
38
+ if (onLearnMore) {
39
+ onLearnMore();
40
+ } else if (learnMoreHref) {
41
+ window.open(learnMoreHref, "_blank", "noopener,noreferrer");
42
+ }
43
+ };
44
+
45
+ return (
46
+ <div
47
+ ref={ref}
48
+ className={cn(
49
+ "s-flex s-flex-col s-overflow-hidden",
50
+ "s-bg-white dark:s-bg-black",
51
+ "s-rounded-2xl s-shadow-md",
52
+ "s-border s-border-border/0 dark:s-border-border-night/0",
53
+ className
54
+ )}
55
+ {...props}
56
+ >
57
+ {haveImage && imageSrc && (
58
+ <div
59
+ className="s-relative s-h-48 s-overflow-hidden s-rounded-t-2xl s-bg-cover s-bg-center s-bg-no-repeat"
60
+ style={{ backgroundImage: `url(${imageSrc})` }}
61
+ />
62
+ )}
63
+
64
+ <div className="s-p-4">
65
+ <div className="s-mb-2 s-text-sm s-font-medium s-text-primary dark:s-text-primary-night">
66
+ {announcementTitle}
67
+ </div>
68
+ <h4 className="s-mb-4 s-text-lg s-font-medium s-leading-tight s-text-foreground dark:s-text-foreground-night">
69
+ {announcementMessage}
70
+ </h4>
71
+ <div className="s-flex s-items-center s-justify-between">
72
+ <Button
73
+ variant="highlight"
74
+ size="sm"
75
+ onClick={handleLearnMore}
76
+ label="Learn more"
77
+ />
78
+ {dismissible && onDismiss && (
79
+ <Button
80
+ variant="ghost"
81
+ size="sm"
82
+ onClick={onDismiss}
83
+ label="Dismiss"
84
+ />
85
+ )}
86
+ </div>
87
+ </div>
88
+ </div>
89
+ );
90
+ }
91
+ );
92
+
93
+ MessageCard.displayName = "MessageCard";
@@ -35,7 +35,11 @@ export {
35
35
  } from "./Collapsible";
36
36
  export { default as ConfettiBackground } from "./ConfettiBackground";
37
37
  export { Container } from "./Container";
38
- export { ContentMessage } from "./ContentMessage";
38
+ export {
39
+ ContentMessage,
40
+ ContentMessageAction,
41
+ ContentMessageInline,
42
+ } from "./ContentMessage";
39
43
  export { ContextItem } from "./ContextItem";
40
44
  export {
41
45
  ConversationContainer,
@@ -102,6 +106,7 @@ export { LinkWrapper } from "./LinkWrapper";
102
106
  export { LoadingBlock } from "./LoadingBlock";
103
107
  export * from "./markdown";
104
108
  export { markdownStyles } from "./markdown/styles";
109
+ export { MessageCard } from "./MessageCard";
105
110
  export type {
106
111
  MultiPageDialogFooterProps,
107
112
  MultiPageDialogPage,
@@ -0,0 +1,68 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+
3
+ import { MessageCard } from "../components/MessageCard";
4
+
5
+ const meta: Meta<typeof MessageCard> = {
6
+ title: "Components/MessageCard",
7
+ component: MessageCard,
8
+ parameters: {
9
+ layout: "centered",
10
+ docs: {
11
+ description: {
12
+ component:
13
+ "A dismissible message card component designed for sidebar usage, featuring an optional image section and a new feature announcement section.",
14
+ },
15
+ },
16
+ },
17
+ argTypes: {
18
+ haveImage: {
19
+ control: { type: "boolean" },
20
+ description: "Whether to show an image in the top section",
21
+ },
22
+ imageSrc: {
23
+ control: { type: "text" },
24
+ description: "URL of the image to display in the top section",
25
+ if: { arg: "haveImage", truthy: true },
26
+ },
27
+ announcementTitle: {
28
+ control: { type: "text" },
29
+ description: "Title for the announcement section",
30
+ },
31
+ announcementMessage: {
32
+ control: { type: "text" },
33
+ description: "The main announcement message",
34
+ },
35
+ dismissible: {
36
+ control: { type: "boolean" },
37
+ description: "Whether the card can be dismissed",
38
+ },
39
+ onDismiss: {
40
+ description: "Callback when dismiss button is clicked",
41
+ },
42
+ },
43
+ args: {
44
+ haveImage: true,
45
+ imageSrc:
46
+ "https://blog.dust.tt/content/images/size/w2000/2025/05/cover.jpg",
47
+ announcementTitle: "New on Dust",
48
+ announcementMessage: "Create interactive content with Dust Shareables",
49
+ dismissible: true,
50
+ onDismiss: () => {
51
+ alert("Dismiss clicked!");
52
+ },
53
+ },
54
+ };
55
+
56
+ export default meta;
57
+ type Story = StoryObj<typeof meta>;
58
+
59
+ export const Default: Story = {
60
+ args: {},
61
+ };
62
+
63
+ export const WithoutImage: Story = {
64
+ args: {
65
+ haveImage: false,
66
+ imageSrc: undefined,
67
+ },
68
+ };
@@ -4,6 +4,8 @@ import React from "react";
4
4
  import {
5
5
  ChatBubbleBottomCenterTextIcon,
6
6
  ContentMessage,
7
+ ContentMessageAction,
8
+ ContentMessageInline,
7
9
  HeartIcon,
8
10
  InformationCircleIcon,
9
11
  } from "../index_with_tw_base";
@@ -68,6 +70,15 @@ export const Basic: Story = {
68
70
  },
69
71
  };
70
72
 
73
+ export const WithIcon: Story = {
74
+ args: {
75
+ title: "This is a title",
76
+ icon: InformationCircleIcon,
77
+ children: "This is a message. It can be multiple lines long.",
78
+ size: "md",
79
+ },
80
+ };
81
+
71
82
  export const WithList: Story = {
72
83
  args: {
73
84
  title: "Agent Thoughts",
@@ -146,3 +157,78 @@ export const ColorVariants: Story = {
146
157
  </div>
147
158
  ),
148
159
  };
160
+
161
+ export const InlineBasic: Story = {
162
+ render: () => (
163
+ <ContentMessageInline icon={InformationCircleIcon} variant="info">
164
+ This is an inline message. It can be used to display a short message.
165
+ </ContentMessageInline>
166
+ ),
167
+ };
168
+
169
+ export const InlineWithAction: Story = {
170
+ render: () => (
171
+ <ContentMessageInline icon={InformationCircleIcon} variant="info">
172
+ This is an inline message. It can be used to display a short message.
173
+ <ContentMessageAction variant="primary" label="Button" />
174
+ </ContentMessageInline>
175
+ ),
176
+ };
177
+
178
+ export const InlineWithTwoActions: Story = {
179
+ render: () => (
180
+ <ContentMessageInline icon={InformationCircleIcon} variant="info">
181
+ This is an inline message. It can be used to display a short message.
182
+ <ContentMessageAction variant="primary" label="Button" />
183
+ <ContentMessageAction variant="highlight" label="Button" />
184
+ </ContentMessageInline>
185
+ ),
186
+ };
187
+
188
+ export const InlineWithTitle: Story = {
189
+ render: () => (
190
+ <div className="s-flex s-flex-col s-gap-4">
191
+ <ContentMessageInline
192
+ title="Status"
193
+ icon={InformationCircleIcon}
194
+ variant="info"
195
+ >
196
+ This is an inline message.
197
+ <ContentMessageAction variant="primary" label="Button" />
198
+ </ContentMessageInline>
199
+ <ContentMessageInline
200
+ title="Alert"
201
+ icon={InformationCircleIcon}
202
+ variant="warning"
203
+ />
204
+ </div>
205
+ ),
206
+ };
207
+
208
+ export const InlineVariants: Story = {
209
+ render: () => (
210
+ <div className="s-flex s-flex-col s-gap-4">
211
+ {["primary", "warning", "success", "highlight", "info"].map((variant) => (
212
+ <ContentMessageInline
213
+ key={variant}
214
+ icon={InformationCircleIcon}
215
+ variant={
216
+ variant as
217
+ | "primary"
218
+ | "warning"
219
+ | "success"
220
+ | "highlight"
221
+ | "info"
222
+ | "green"
223
+ | "blue"
224
+ | "rose"
225
+ | "golden"
226
+ }
227
+ >
228
+ {variant.charAt(0).toUpperCase() + variant.slice(1)} inline message
229
+ <ContentMessageAction variant="primary" label="Action" />
230
+ </ContentMessageInline>
231
+ ))}
232
+ </div>
233
+ ),
234
+ };
@@ -0,0 +1,68 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+
3
+ import { MessageCard } from "../components/MessageCard";
4
+
5
+ const meta: Meta<typeof MessageCard> = {
6
+ title: "Components/MessageCard",
7
+ component: MessageCard,
8
+ parameters: {
9
+ layout: "centered",
10
+ docs: {
11
+ description: {
12
+ component:
13
+ "A dismissible message card component designed for sidebar usage, featuring an optional image section and a new feature announcement section.",
14
+ },
15
+ },
16
+ },
17
+ argTypes: {
18
+ haveImage: {
19
+ control: { type: "boolean" },
20
+ description: "Whether to show an image in the top section",
21
+ },
22
+ imageSrc: {
23
+ control: { type: "text" },
24
+ description: "URL of the image to display in the top section",
25
+ if: { arg: "haveImage", truthy: true },
26
+ },
27
+ announcementTitle: {
28
+ control: { type: "text" },
29
+ description: "Title for the announcement section",
30
+ },
31
+ announcementMessage: {
32
+ control: { type: "text" },
33
+ description: "The main announcement message",
34
+ },
35
+ dismissible: {
36
+ control: { type: "boolean" },
37
+ description: "Whether the card can be dismissed",
38
+ },
39
+ onDismiss: {
40
+ description: "Callback when dismiss button is clicked",
41
+ },
42
+ },
43
+ args: {
44
+ haveImage: true,
45
+ imageSrc:
46
+ "https://blog.dust.tt/content/images/size/w2000/2025/05/cover.jpg",
47
+ announcementTitle: "New on Dust",
48
+ announcementMessage: "Create interactive content with Dust Shareables",
49
+ dismissible: true,
50
+ onDismiss: () => {
51
+ alert("Dismiss clicked!");
52
+ },
53
+ },
54
+ };
55
+
56
+ export default meta;
57
+ type Story = StoryObj<typeof meta>;
58
+
59
+ export const Default: Story = {
60
+ args: {},
61
+ };
62
+
63
+ export const WithoutImage: Story = {
64
+ args: {
65
+ haveImage: false,
66
+ imageSrc: undefined,
67
+ },
68
+ };