@dust-tt/sparkle 0.5.9 → 0.5.11

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 (29) hide show
  1. package/dist/cjs/index.js +8 -8
  2. package/dist/cjs/index.js.map +4 -4
  3. package/dist/esm/components/AttachmentChip.d.ts +20 -9
  4. package/dist/esm/components/AttachmentChip.d.ts.map +1 -1
  5. package/dist/esm/components/AttachmentChip.js +2 -5
  6. package/dist/esm/components/AttachmentChip.js.map +1 -1
  7. package/dist/esm/components/ConversationMessage.d.ts +2 -20
  8. package/dist/esm/components/ConversationMessage.d.ts.map +1 -1
  9. package/dist/esm/components/ConversationMessage.js +2 -9
  10. package/dist/esm/components/ConversationMessage.js.map +1 -1
  11. package/dist/esm/components/ConversationMessages.d.ts +33 -0
  12. package/dist/esm/components/ConversationMessages.d.ts.map +1 -0
  13. package/dist/esm/components/ConversationMessages.js +59 -0
  14. package/dist/esm/components/ConversationMessages.js.map +1 -0
  15. package/dist/esm/components/index.d.ts +2 -2
  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/lottie/dragArea.d.ts +19 -19
  20. package/dist/esm/stories/AttachmentChip.stories.d.ts.map +1 -1
  21. package/dist/esm/stories/AttachmentChip.stories.js +6 -2
  22. package/dist/esm/stories/AttachmentChip.stories.js.map +1 -1
  23. package/dist/sparkle.css +16 -4
  24. package/package.json +1 -1
  25. package/src/components/AttachmentChip.tsx +22 -18
  26. package/src/components/ConversationMessage.tsx +9 -35
  27. package/src/components/ConversationMessages.tsx +180 -0
  28. package/src/components/index.ts +6 -3
  29. package/src/stories/AttachmentChip.stories.tsx +6 -2
@@ -12,38 +12,43 @@ const attachmentChipOverrides = cn(
12
12
  "dark:s-bg-background-night dark:s-text-foreground-night"
13
13
  );
14
14
 
15
- type AttachmentChipIconProps = IconProps | DoubleIconProps;
15
+ export type AttachmentChipIconProps = IconProps;
16
+ export type AttachmentChipDoubleIconProps = DoubleIconProps;
16
17
 
17
- function isDoubleIconProps(
18
- props: AttachmentChipIconProps
19
- ): props is DoubleIconProps {
20
- return "mainIcon" in props;
21
- }
18
+ type AttachmentChipIconOptions =
19
+ | { icon?: AttachmentChipIconProps; doubleIcon?: never }
20
+ | { icon?: never; doubleIcon?: AttachmentChipDoubleIconProps };
22
21
 
23
- interface AttachmentChipBaseProps {
22
+ export type AttachmentChipBaseProps = AttachmentChipIconOptions & {
24
23
  label: string;
25
- icon?: AttachmentChipIconProps;
26
24
  size?: (typeof CHIP_SIZES)[number];
27
25
  color?: (typeof CHIP_COLORS)[number];
28
26
  className?: string;
29
27
  isBusy?: boolean;
30
28
  onRemove?: () => void;
31
- onClick?: () => void;
32
- }
29
+ children?: never;
30
+ };
33
31
 
34
- type AttachmentChipButtonProps = AttachmentChipBaseProps & {
32
+ export type AttachmentChipButtonProps = AttachmentChipBaseProps & {
35
33
  href?: never;
34
+ onClick?: () => void;
36
35
  } & {
37
36
  [K in keyof Omit<LinkWrapperProps, "children">]?: never;
38
37
  };
39
38
 
40
- type AttachmentChipLinkProps = AttachmentChipBaseProps &
41
- Omit<LinkWrapperProps, "children">;
39
+ export type AttachmentChipLinkProps = AttachmentChipBaseProps &
40
+ Omit<LinkWrapperProps, "children" | "href"> & {
41
+ href: string;
42
+ onClick?: never;
43
+ };
42
44
 
43
- type AttachmentChipProps = AttachmentChipButtonProps | AttachmentChipLinkProps;
45
+ export type AttachmentChipProps =
46
+ | AttachmentChipButtonProps
47
+ | AttachmentChipLinkProps;
44
48
 
45
49
  export function AttachmentChip({
46
50
  icon,
51
+ doubleIcon,
47
52
  className,
48
53
  label,
49
54
  size,
@@ -53,14 +58,13 @@ export function AttachmentChip({
53
58
  onClick,
54
59
  ...linkProps
55
60
  }: AttachmentChipProps) {
56
- const iconElement = icon && (
61
+ const chipClassName = cn(attachmentChipOverrides, className);
62
+ const iconElement = (icon || doubleIcon) && (
57
63
  <div className="s-shrink-0">
58
- {isDoubleIconProps(icon) ? <DoubleIcon {...icon} /> : <Icon {...icon} />}
64
+ {doubleIcon ? <DoubleIcon {...doubleIcon} /> : <Icon {...icon} />}
59
65
  </div>
60
66
  );
61
67
 
62
- const chipClassName = cn(attachmentChipOverrides, className);
63
-
64
68
  if ("href" in linkProps && linkProps.href) {
65
69
  return (
66
70
  <Chip
@@ -1,7 +1,12 @@
1
1
  import { cva, VariantProps } from "class-variance-authority";
2
2
  import React from "react";
3
3
 
4
- import { Avatar, Button, CitationGrid, IconButton } from "@sparkle/components";
4
+ import {
5
+ Avatar,
6
+ Button,
7
+ ConversationMessageContent,
8
+ IconButton,
9
+ } from "@sparkle/components";
5
10
  import {
6
11
  DropdownMenu,
7
12
  DropdownMenuContent,
@@ -52,9 +57,9 @@ interface ConversationMessageProps
52
57
  type: ConversationMessageType;
53
58
  }
54
59
 
55
- export type ConversationMessageType = "user" | "agent";
60
+ type ConversationMessageType = "user" | "agent";
56
61
 
57
- export interface ConversationMessageAction {
62
+ interface ConversationMessageAction {
58
63
  icon: React.ComponentType | React.ReactNode;
59
64
  label: string;
60
65
  onClick: () => void;
@@ -142,37 +147,6 @@ export const ConversationMessage = React.forwardRef<
142
147
 
143
148
  ConversationMessage.displayName = "ConversationMessage";
144
149
 
145
- interface ConversationMessageContentProps extends React.HTMLAttributes<HTMLDivElement> {
146
- children: React.ReactNode;
147
- citations?: React.ReactElement[];
148
- type: ConversationMessageType;
149
- }
150
-
151
- export const ConversationMessageContent = React.forwardRef<
152
- HTMLDivElement,
153
- ConversationMessageContentProps
154
- >(({ children, citations, className, ...props }, ref) => {
155
- return (
156
- <div
157
- ref={ref}
158
- className={cn(
159
- "s-flex s-flex-col s-gap-3 @sm/conversation:s-gap-4",
160
- className
161
- )}
162
- {...props}
163
- >
164
- <div className="s-text-base s-text-foreground dark:s-text-foreground-night">
165
- {children}
166
- </div>
167
- {citations && citations.length > 0 && (
168
- <CitationGrid>{citations}</CitationGrid>
169
- )}
170
- </div>
171
- );
172
- });
173
-
174
- ConversationMessageContent.displayName = "ConversationMessageContent";
175
-
176
150
  interface ConversationMessageHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
177
151
  actions?: ConversationMessageAction[];
178
152
  avatarUrl?: string | React.ReactNode;
@@ -185,7 +159,7 @@ interface ConversationMessageHeaderProps extends React.HTMLAttributes<HTMLDivEle
185
159
  renderName: (name: string | null) => React.ReactNode;
186
160
  }
187
161
 
188
- export const ConversationMessageHeader = React.forwardRef<
162
+ const ConversationMessageHeader = React.forwardRef<
189
163
  HTMLDivElement,
190
164
  ConversationMessageHeaderProps
191
165
  >(
@@ -0,0 +1,180 @@
1
+ import { cva } from "class-variance-authority";
2
+ import React from "react";
3
+
4
+ import { Avatar, CitationGrid } from "@sparkle/components";
5
+ import { cn } from "@sparkle/lib/utils";
6
+
7
+ type ConversationMessageType = "user" | "agent";
8
+ type MessageType = "me" | "user" | "agent";
9
+
10
+ const wrapperVariants = cva("s-flex s-flex-col s-@container @sm:s-flex-row", {
11
+ variants: {
12
+ messageType: {
13
+ agent: "s-pr-0",
14
+ me: "s-pl-9",
15
+ user: "s-pr-9",
16
+ },
17
+ },
18
+ defaultVariants: {
19
+ messageType: "agent",
20
+ },
21
+ });
22
+ const messageVariants = cva("s-flex s-rounded-2xl s-max-w-full", {
23
+ variants: {
24
+ type: {
25
+ user: "s-bg-muted-background dark:s-bg-muted-background-night s-px-3 s-py-3 s-gap-2 s-w-fit",
26
+ agent: "s-w-full s-gap-3 s-p-4 @sm:s-flex-row s-flex-col",
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ type: "agent",
31
+ },
32
+ });
33
+
34
+ interface ConversationMessageContainerProps extends React.HTMLAttributes<HTMLDivElement> {
35
+ messageType: MessageType;
36
+ type: ConversationMessageType;
37
+ }
38
+
39
+ export const ConversationMessageContainer = React.forwardRef<
40
+ HTMLDivElement,
41
+ ConversationMessageContainerProps
42
+ >(({ children, className, messageType, type, ...props }, ref) => {
43
+ return (
44
+ <div ref={ref} className={cn(wrapperVariants({ messageType }))}>
45
+ <div className={cn(messageVariants({ type, className }))} {...props}>
46
+ {children}
47
+ </div>
48
+ </div>
49
+ );
50
+ });
51
+
52
+ ConversationMessageContainer.displayName = "ConversationMessageContainer";
53
+
54
+ interface ConversationMessageContentProps extends React.HTMLAttributes<HTMLDivElement> {
55
+ children: React.ReactNode;
56
+ citations?: React.ReactElement[];
57
+ type: ConversationMessageType;
58
+ infoChip?: React.ReactNode;
59
+ }
60
+
61
+ export const ConversationMessageContent = React.forwardRef<
62
+ HTMLDivElement,
63
+ ConversationMessageContentProps
64
+ >(({ children, citations, className, ...props }, ref) => {
65
+ return (
66
+ <div
67
+ ref={ref}
68
+ className={cn("s-flex s-min-w-0 s-flex-col s-gap-1", className)}
69
+ {...props}
70
+ >
71
+ <div className="s-text-base s-text-foreground dark:s-text-foreground-night">
72
+ {children}
73
+ </div>
74
+ {citations && citations.length > 0 && (
75
+ <CitationGrid>{citations}</CitationGrid>
76
+ )}
77
+ </div>
78
+ );
79
+ });
80
+
81
+ ConversationMessageContent.displayName = "ConversationMessageContent";
82
+
83
+ interface ConversationMessageAvatarProps extends React.HTMLAttributes<HTMLDivElement> {
84
+ avatarUrl?: string | React.ReactNode;
85
+ isBusy?: boolean;
86
+ isDisabled?: boolean;
87
+ name?: string;
88
+ type: ConversationMessageType;
89
+ }
90
+
91
+ export const ConversationMessageAvatar = React.forwardRef<
92
+ HTMLDivElement,
93
+ ConversationMessageAvatarProps
94
+ >(
95
+ (
96
+ { avatarUrl, isBusy, isDisabled, name = "", className, type, ...props },
97
+ ref
98
+ ) => {
99
+ return (
100
+ <div
101
+ ref={ref}
102
+ className={cn("conversation:s-p-0 s-flex s-gap-2", className)}
103
+ {...props}
104
+ >
105
+ <Avatar
106
+ className="@sm:s-hidden"
107
+ name={name}
108
+ visual={avatarUrl}
109
+ busy={isBusy}
110
+ disabled={isDisabled}
111
+ isRounded={type === "user"}
112
+ size="xs"
113
+ />
114
+ <Avatar
115
+ className="s-hidden @sm:s-flex"
116
+ name={name}
117
+ visual={avatarUrl}
118
+ busy={isBusy}
119
+ disabled={isDisabled}
120
+ isRounded={type === "user"}
121
+ size="sm"
122
+ />
123
+ </div>
124
+ );
125
+ }
126
+ );
127
+
128
+ ConversationMessageAvatar.displayName = "ConversationMessageAvatar";
129
+
130
+ interface ConversationMessageTitleProps extends React.HTMLAttributes<HTMLDivElement> {
131
+ name?: string;
132
+ timestamp?: string;
133
+ infoChip?: React.ReactNode;
134
+ completionStatus?: React.ReactNode;
135
+ renderName: (name: string | null) => React.ReactNode;
136
+ }
137
+
138
+ export const ConversationMessageTitle = React.forwardRef<
139
+ HTMLDivElement,
140
+ ConversationMessageTitleProps
141
+ >(
142
+ (
143
+ {
144
+ name = "",
145
+ timestamp,
146
+ infoChip,
147
+ completionStatus,
148
+ renderName,
149
+ className,
150
+ ...props
151
+ },
152
+ ref
153
+ ) => {
154
+ return (
155
+ <div
156
+ ref={ref}
157
+ className={cn(
158
+ "s-inline-flex s-flex-1 s-items-center s-justify-between s-gap-0.5",
159
+ className
160
+ )}
161
+ {...props}
162
+ >
163
+ <div className="s-inline-flex s-items-center s-gap-2 s-text-foreground dark:s-text-foreground-night">
164
+ <span className="s-heading-sm">{renderName(name)}</span>
165
+ <span className="s-heading-xs s-text-muted-foreground dark:s-text-muted-foreground-night">
166
+ {timestamp}
167
+ </span>
168
+ {infoChip && (
169
+ <div className="s-inline-flex s-items-center">{infoChip}</div>
170
+ )}
171
+ </div>
172
+ <div className="s-ml-1 s-inline-flex s-items-center">
173
+ {completionStatus ?? null}
174
+ </div>
175
+ </div>
176
+ );
177
+ }
178
+ );
179
+
180
+ ConversationMessageTitle.displayName = "ConversationMessageTitle";
@@ -45,13 +45,16 @@ export {
45
45
  ContentMessageInline,
46
46
  } from "./ContentMessage";
47
47
  export { ContextItem } from "./ContextItem";
48
- export type { ConversationMessageAction } from "./ConversationMessage";
49
48
  export {
50
49
  ConversationContainer,
51
50
  ConversationMessage,
52
- ConversationMessageContent,
53
- ConversationMessageHeader,
54
51
  } from "./ConversationMessage";
52
+ export {
53
+ ConversationMessageAvatar,
54
+ ConversationMessageContainer,
55
+ ConversationMessageContent,
56
+ ConversationMessageTitle,
57
+ } from "./ConversationMessages";
55
58
  export { Counter } from "./Counter";
56
59
  export type { DataTableMoreButtonProps, MenuItem } from "./DataTable";
57
60
  export {
@@ -85,7 +85,7 @@ export const LongLabel: Story = {
85
85
  export const WithDoubleIcon: Story = {
86
86
  args: {
87
87
  label: "My Drive Folder",
88
- icon: { mainIcon: FolderIcon, secondaryIcon: DriveLogo, size: "sm" },
88
+ doubleIcon: { mainIcon: FolderIcon, secondaryIcon: DriveLogo, size: "sm" },
89
89
  },
90
90
  decorators: [
91
91
  (Story) => (
@@ -99,7 +99,11 @@ export const WithDoubleIcon: Story = {
99
99
  export const WithDoubleIconAndLink: Story = {
100
100
  args: {
101
101
  label: "Notion Document",
102
- icon: { mainIcon: DocumentIcon, secondaryIcon: NotionLogo, size: "sm" },
102
+ doubleIcon: {
103
+ mainIcon: DocumentIcon,
104
+ secondaryIcon: NotionLogo,
105
+ size: "sm",
106
+ },
103
107
  href: "https://notion.so",
104
108
  target: "_blank",
105
109
  },