@dust-tt/sparkle 0.5.0 → 0.5.2-rc-1

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 (104) hide show
  1. package/dist/cjs/index.js +10 -10
  2. package/dist/cjs/index.js.map +3 -3
  3. package/dist/esm/components/Avatar.d.ts +2 -1
  4. package/dist/esm/components/Avatar.d.ts.map +1 -1
  5. package/dist/esm/components/Avatar.js +34 -10
  6. package/dist/esm/components/Avatar.js.map +1 -1
  7. package/dist/esm/components/Button.d.ts.map +1 -1
  8. package/dist/esm/components/Button.js.map +1 -1
  9. package/dist/esm/components/ButtonGroup.d.ts.map +1 -1
  10. package/dist/esm/components/ButtonGroup.js.map +1 -1
  11. package/dist/esm/components/ButtonsSwitch.d.ts.map +1 -1
  12. package/dist/esm/components/ButtonsSwitch.js.map +1 -1
  13. package/dist/esm/components/Card.d.ts.map +1 -1
  14. package/dist/esm/components/Card.js.map +1 -1
  15. package/dist/esm/components/Checkbox.d.ts.map +1 -1
  16. package/dist/esm/components/Checkbox.js.map +1 -1
  17. package/dist/esm/components/Citation.d.ts.map +1 -1
  18. package/dist/esm/components/Citation.js.map +1 -1
  19. package/dist/esm/components/Collapsible.d.ts.map +1 -1
  20. package/dist/esm/components/Collapsible.js.map +1 -1
  21. package/dist/esm/components/ConversationMessage.d.ts.map +1 -1
  22. package/dist/esm/components/ConversationMessage.js.map +1 -1
  23. package/dist/esm/components/Counter.d.ts.map +1 -1
  24. package/dist/esm/components/Counter.js.map +1 -1
  25. package/dist/esm/components/DataTable.d.ts.map +1 -1
  26. package/dist/esm/components/DataTable.js.map +1 -1
  27. package/dist/esm/components/Dialog.d.ts.map +1 -1
  28. package/dist/esm/components/Dialog.js.map +1 -1
  29. package/dist/esm/components/Dropdown.d.ts.map +1 -1
  30. package/dist/esm/components/Dropdown.js.map +1 -1
  31. package/dist/esm/components/Hoverable.d.ts.map +1 -1
  32. package/dist/esm/components/Hoverable.js.map +1 -1
  33. package/dist/esm/components/IconButton.d.ts.map +1 -1
  34. package/dist/esm/components/IconButton.js.map +1 -1
  35. package/dist/esm/components/Input.d.ts.map +1 -1
  36. package/dist/esm/components/Input.js.map +1 -1
  37. package/dist/esm/components/Label.d.ts.map +1 -1
  38. package/dist/esm/components/Label.js.map +1 -1
  39. package/dist/esm/components/MultiPageDialog.d.ts.map +1 -1
  40. package/dist/esm/components/MultiPageDialog.js.map +1 -1
  41. package/dist/esm/components/MultiPageSheet.d.ts.map +1 -1
  42. package/dist/esm/components/MultiPageSheet.js.map +1 -1
  43. package/dist/esm/components/NavigationList.d.ts +18 -1
  44. package/dist/esm/components/NavigationList.d.ts.map +1 -1
  45. package/dist/esm/components/NavigationList.js +34 -5
  46. package/dist/esm/components/NavigationList.js.map +1 -1
  47. package/dist/esm/components/Popover.d.ts.map +1 -1
  48. package/dist/esm/components/Popover.js.map +1 -1
  49. package/dist/esm/components/RadioGroup.d.ts.map +1 -1
  50. package/dist/esm/components/RadioGroup.js.map +1 -1
  51. package/dist/esm/components/ScrollArea.d.ts.map +1 -1
  52. package/dist/esm/components/ScrollArea.js.map +1 -1
  53. package/dist/esm/components/Sheet.d.ts.map +1 -1
  54. package/dist/esm/components/Sheet.js.map +1 -1
  55. package/dist/esm/components/TextArea.d.ts.map +1 -1
  56. package/dist/esm/components/TextArea.js.map +1 -1
  57. package/dist/esm/components/Timeline.d.ts.map +1 -1
  58. package/dist/esm/components/Timeline.js.map +1 -1
  59. package/dist/esm/components/Tooltip.d.ts.map +1 -1
  60. package/dist/esm/components/Tooltip.js.map +1 -1
  61. package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.d.ts.map +1 -1
  62. package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.js +9 -4
  63. package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.js.map +1 -1
  64. package/dist/esm/stories/Avatar.stories.d.ts.map +1 -1
  65. package/dist/esm/stories/Avatar.stories.js +56 -0
  66. package/dist/esm/stories/Avatar.stories.js.map +1 -1
  67. package/dist/esm/stories/NavigationList.stories.d.ts +1 -0
  68. package/dist/esm/stories/NavigationList.stories.d.ts.map +1 -1
  69. package/dist/esm/stories/NavigationList.stories.js +70 -1
  70. package/dist/esm/stories/NavigationList.stories.js.map +1 -1
  71. package/dist/esm/styles/global.css +2 -1
  72. package/dist/sparkle.css +33 -0
  73. package/package.json +35 -15
  74. package/src/components/Avatar.tsx +45 -9
  75. package/src/components/Button.tsx +2 -1
  76. package/src/components/ButtonGroup.tsx +2 -1
  77. package/src/components/ButtonsSwitch.tsx +6 -3
  78. package/src/components/Card.tsx +3 -6
  79. package/src/components/Checkbox.tsx +2 -1
  80. package/src/components/Citation.tsx +2 -4
  81. package/src/components/Collapsible.tsx +4 -2
  82. package/src/components/ConversationMessage.tsx +4 -5
  83. package/src/components/Counter.tsx +2 -1
  84. package/src/components/DataTable.tsx +4 -4
  85. package/src/components/Dialog.tsx +3 -2
  86. package/src/components/Dropdown.tsx +7 -4
  87. package/src/components/Hoverable.tsx +2 -4
  88. package/src/components/IconButton.tsx +4 -5
  89. package/src/components/Input.tsx +4 -2
  90. package/src/components/Label.tsx +2 -1
  91. package/src/components/MultiPageDialog.tsx +1 -2
  92. package/src/components/MultiPageSheet.tsx +1 -2
  93. package/src/components/NavigationList.tsx +151 -15
  94. package/src/components/Popover.tsx +3 -2
  95. package/src/components/RadioGroup.tsx +4 -2
  96. package/src/components/ScrollArea.tsx +6 -6
  97. package/src/components/Sheet.tsx +6 -4
  98. package/src/components/TextArea.tsx +1 -2
  99. package/src/components/Timeline.tsx +2 -1
  100. package/src/components/Tooltip.tsx +3 -2
  101. package/src/components/markdown/CodeBlockWithExtendedSupport.tsx +12 -4
  102. package/src/stories/Avatar.stories.tsx +79 -0
  103. package/src/stories/NavigationList.stories.tsx +148 -0
  104. package/src/styles/global.css +2 -1
@@ -4,8 +4,9 @@ import { useMemo } from "react";
4
4
 
5
5
  import { cn } from "@sparkle/lib/utils";
6
6
 
7
- interface ScrollAreaProps
8
- extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
7
+ interface ScrollAreaProps extends React.ComponentPropsWithoutRef<
8
+ typeof ScrollAreaPrimitive.Root
9
+ > {
9
10
  hideScrollBar?: boolean;
10
11
  orientation?: "vertical" | "horizontal";
11
12
  scrollBarClassName?: string;
@@ -128,10 +129,9 @@ const scrollBarSizes = {
128
129
 
129
130
  type ScrollBarSize = keyof typeof scrollBarSizes;
130
131
 
131
- interface ScrollBarProps
132
- extends React.ComponentPropsWithoutRef<
133
- typeof ScrollAreaPrimitive.ScrollAreaScrollbar
134
- > {
132
+ interface ScrollBarProps extends React.ComponentPropsWithoutRef<
133
+ typeof ScrollAreaPrimitive.ScrollAreaScrollbar
134
+ > {
135
135
  size?: ScrollBarSize;
136
136
  }
137
137
 
@@ -82,8 +82,9 @@ const sheetVariants = cva(
82
82
  }
83
83
  );
84
84
 
85
- interface SheetContentProps
86
- extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content> {
85
+ interface SheetContentProps extends React.ComponentPropsWithoutRef<
86
+ typeof SheetPrimitive.Content
87
+ > {
87
88
  size?: SheetSizeType;
88
89
  trapFocusScope?: boolean;
89
90
  side?: SheetSideType;
@@ -300,8 +301,9 @@ const SheetFooter = ({
300
301
  };
301
302
  SheetFooter.displayName = "SheetFooter";
302
303
 
303
- interface SheetTitleProps
304
- extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title> {
304
+ interface SheetTitleProps extends React.ComponentPropsWithoutRef<
305
+ typeof SheetPrimitive.Title
306
+ > {
305
307
  icon?: React.ComponentType;
306
308
  }
307
309
 
@@ -7,8 +7,7 @@ const RESIZE_DIRECTIONS = ["none", "vertical", "horizontal", "both"] as const;
7
7
 
8
8
  type ResizeDirectionType = (typeof RESIZE_DIRECTIONS)[number];
9
9
 
10
- export interface TextareaProps
11
- extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
10
+ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
12
11
  resize?: ResizeDirectionType;
13
12
  error?: string | null;
14
13
  showErrorLabel?: boolean;
@@ -82,7 +82,8 @@ function Timeline({
82
82
  }
83
83
 
84
84
  export interface TimelineItemProps
85
- extends React.HTMLAttributes<HTMLDivElement>,
85
+ extends
86
+ React.HTMLAttributes<HTMLDivElement>,
86
87
  VariantProps<typeof markerVariants> {
87
88
  title?: string;
88
89
  description?: React.ReactNode;
@@ -11,8 +11,9 @@ const TooltipPortal = TooltipPrimitive.Portal;
11
11
 
12
12
  const TooltipTrigger = TooltipPrimitive.Trigger;
13
13
 
14
- interface TooltipContentProps
15
- extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {
14
+ interface TooltipContentProps extends React.ComponentPropsWithoutRef<
15
+ typeof TooltipPrimitive.Content
16
+ > {
16
17
  mountPortal?: boolean;
17
18
  mountPortalContainer?: HTMLElement;
18
19
  }
@@ -1,4 +1,3 @@
1
- import mermaid from "mermaid";
2
1
  import React, { useContext, useEffect, useRef, useState } from "react";
3
2
  import {
4
3
  amber,
@@ -176,7 +175,13 @@ const MermaidGraph: React.FC<{ chart: string }> = ({ chart }) => {
176
175
  const graphRef = useRef<HTMLDivElement | null>(null);
177
176
 
178
177
  useEffect(() => {
179
- if (graphRef.current) {
178
+ const renderMermaid = async () => {
179
+ if (!graphRef.current) {
180
+ return;
181
+ }
182
+
183
+ const mermaid = (await import("mermaid")).default;
184
+
180
185
  mermaid.initialize({
181
186
  startOnLoad: false,
182
187
  theme: "base",
@@ -278,8 +283,10 @@ const MermaidGraph: React.FC<{ chart: string }> = ({ chart }) => {
278
283
  });
279
284
 
280
285
  graphRef.current.textContent = chart;
281
- void mermaid.run(undefined);
282
- }
286
+ await mermaid.run(undefined);
287
+ };
288
+
289
+ void renderMermaid();
283
290
  }, [chart]);
284
291
 
285
292
  return (
@@ -352,6 +359,7 @@ export function CodeBlockWithExtendedSupport({
352
359
  if (language === "mermaid") {
353
360
  const checkValidMermaid = async () => {
354
361
  try {
362
+ const mermaid = (await import("mermaid")).default;
355
363
  await mermaid.parse(validChildrenContent);
356
364
  setIsValidMermaid(true);
357
365
  setShowMermaid(true);
@@ -425,6 +425,85 @@ export const AvatarStackExample: Story = {
425
425
  ]}
426
426
  />
427
427
  </div>
428
+
429
+ <div className="s-mt-8 s-text-lg s-font-semibold">
430
+ Vertical Orientation
431
+ </div>
432
+ <div className="s-flex s-flex-row s-items-start s-gap-4">
433
+ <Avatar.Stack
434
+ size="xs"
435
+ nbVisibleItems={3}
436
+ isRounded
437
+ orientation="vertical"
438
+ avatars={[
439
+ {
440
+ name: "Isabelle Doe",
441
+ visual: "https://dust.tt/static/droidavatar/Droid_Lime_3.jpg",
442
+ },
443
+ {
444
+ name: "Rafael Doe",
445
+ visual: "https://dust.tt/static/droidavatar/Droid_Yellow_3.jpg",
446
+ },
447
+ {
448
+ name: "Aria Doe",
449
+ visual: "https://dust.tt/static/droidavatar/Droid_Red_3.jpg",
450
+ },
451
+ {
452
+ name: "Omar Doe",
453
+ visual: "https://dust.tt/static/droidavatar/Droid_Pink_3.jpg",
454
+ },
455
+ ]}
456
+ />
457
+
458
+ <Avatar.Stack
459
+ size="sm"
460
+ nbVisibleItems={4}
461
+ isRounded
462
+ orientation="vertical"
463
+ avatars={[
464
+ {
465
+ name: "Isabelle Doe",
466
+ visual: "https://dust.tt/static/droidavatar/Droid_Lime_3.jpg",
467
+ },
468
+ {
469
+ name: "Rafael Doe",
470
+ visual: "https://dust.tt/static/droidavatar/Droid_Yellow_3.jpg",
471
+ },
472
+ {
473
+ name: "Aria Doe",
474
+ visual: "https://dust.tt/static/droidavatar/Droid_Red_3.jpg",
475
+ },
476
+ {
477
+ name: "Omar Doe",
478
+ visual: "https://dust.tt/static/droidavatar/Droid_Pink_3.jpg",
479
+ },
480
+ ]}
481
+ />
482
+
483
+ <Avatar.Stack
484
+ nbVisibleItems={3}
485
+ size="md"
486
+ orientation="vertical"
487
+ avatars={[
488
+ {
489
+ name: "Isabelle Doe",
490
+ visual: "https://dust.tt/static/droidavatar/Droid_Lime_3.jpg",
491
+ },
492
+ {
493
+ name: "Rafael Doe",
494
+ visual: "https://dust.tt/static/droidavatar/Droid_Yellow_3.jpg",
495
+ },
496
+ {
497
+ name: "Aria Doe",
498
+ visual: "https://dust.tt/static/droidavatar/Droid_Red_3.jpg",
499
+ },
500
+ {
501
+ name: "Omar Doe",
502
+ visual: "https://dust.tt/static/droidavatar/Droid_Pink_3.jpg",
503
+ },
504
+ ]}
505
+ />
506
+ </div>
428
507
  </div>
429
508
  ),
430
509
  };
@@ -9,9 +9,12 @@ import {
9
9
  NavigationList,
10
10
  NavigationListItem,
11
11
  NavigationListItemAction,
12
+ NavigationListCollapsibleSection,
12
13
  NavigationListLabel,
14
+ NavigationListLabelButton,
13
15
  PencilSquareIcon,
14
16
  TrashIcon,
17
+ MoreIcon,
15
18
  } from "../index_with_tw_base";
16
19
 
17
20
  const meta = {
@@ -155,6 +158,151 @@ export const Demo = () => {
155
158
  );
156
159
  };
157
160
 
161
+ export const CollapsibleSection = () => {
162
+ const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
163
+ const [conversationTitles, setConversationTitles] = useState<
164
+ { label: string; items: string[] }[]
165
+ >([]);
166
+
167
+ useEffect(() => {
168
+ setConversationTitles([
169
+ { label: "Today", items: getRandomTitles(5) },
170
+ { label: "Yesterday", items: getRandomTitles(10) },
171
+ { label: "Last Week", items: getRandomTitles(8) },
172
+ ]);
173
+ }, []);
174
+
175
+ const allItems = conversationTitles.flatMap((section) => section.items);
176
+
177
+ const getMoreMenu = (title: string) => (
178
+ <DropdownMenu>
179
+ <DropdownMenuTrigger asChild>
180
+ <NavigationListItemAction />
181
+ </DropdownMenuTrigger>
182
+ <DropdownMenuContent>
183
+ <DropdownMenuItem
184
+ label={`Rename ${title}`}
185
+ icon={PencilSquareIcon}
186
+ onClick={(e) => {
187
+ e.preventDefault();
188
+ e.stopPropagation();
189
+ }}
190
+ />
191
+ <DropdownMenuItem
192
+ label="Delete"
193
+ icon={TrashIcon}
194
+ variant="warning"
195
+ onClick={(e) => {
196
+ e.preventDefault();
197
+ e.stopPropagation();
198
+ }}
199
+ />
200
+ </DropdownMenuContent>
201
+ </DropdownMenu>
202
+ );
203
+
204
+ return (
205
+ <div className="s-flex s-h-[500px] s-w-full s-flex-row s-gap-12 s-bg-muted">
206
+ <div className="s-h-[500px] s-w-[240px]">
207
+ <NavigationList className="s-relative s-h-full s-w-full s-px-3 dark:s-bg-muted-background-night">
208
+ {conversationTitles.map((section, sectionIndex) => (
209
+ <>
210
+ <NavigationListLabel label="Hello" key={0} />
211
+ <NavigationListCollapsibleSection
212
+ key={sectionIndex}
213
+ label={section.label}
214
+ defaultOpen={sectionIndex === 0}
215
+ >
216
+ {section.items.map((title, index) => {
217
+ const itemIndex = allItems.indexOf(title);
218
+ const getStatus = (idx: number) => {
219
+ if (idx % 5 === 0) {
220
+ return "unread";
221
+ }
222
+ if (idx % 3 === 0) {
223
+ return "blocked";
224
+ }
225
+ return "idle";
226
+ };
227
+ return (
228
+ <NavigationListItem
229
+ key={index}
230
+ href={index % 2 === 0 ? "#" : undefined}
231
+ selected={itemIndex === selectedIndex}
232
+ onClick={(e) => {
233
+ if (!e.defaultPrevented) {
234
+ e.preventDefault();
235
+ setSelectedIndex(itemIndex);
236
+ }
237
+ }}
238
+ label={title}
239
+ className="s-w-full"
240
+ moreMenu={getMoreMenu(title)}
241
+ status={getStatus(index)}
242
+ />
243
+ );
244
+ })}
245
+ </NavigationListCollapsibleSection>
246
+ </>
247
+ ))}
248
+ </NavigationList>
249
+ </div>
250
+ <div className="s-h-[500px] s-w-[240px]">
251
+ <NavigationList className="s-relative s-h-full s-w-full s-px-3 dark:s-bg-muted-background-night">
252
+ {conversationTitles.map((section, sectionIndex) => (
253
+ <NavigationListCollapsibleSection
254
+ key={sectionIndex}
255
+ label={section.label}
256
+ defaultOpen={sectionIndex === 0}
257
+ action={
258
+ <NavigationListLabelButton
259
+ icon={MoreIcon}
260
+ aria-label="Add new item"
261
+ onClick={(e) => {
262
+ e.preventDefault();
263
+ e.stopPropagation();
264
+ // Add action logic here
265
+ }}
266
+ />
267
+ }
268
+ >
269
+ {section.items.map((title, index) => {
270
+ const itemIndex = allItems.indexOf(title);
271
+ const getStatus = (idx: number) => {
272
+ if (idx % 5 === 0) {
273
+ return "unread";
274
+ }
275
+ if (idx % 3 === 0) {
276
+ return "blocked";
277
+ }
278
+ return "idle";
279
+ };
280
+ return (
281
+ <NavigationListItem
282
+ key={index}
283
+ href={index % 2 === 0 ? "#" : undefined}
284
+ selected={itemIndex === selectedIndex}
285
+ onClick={(e) => {
286
+ if (!e.defaultPrevented) {
287
+ e.preventDefault();
288
+ setSelectedIndex(itemIndex);
289
+ }
290
+ }}
291
+ label={title}
292
+ className="s-w-full"
293
+ moreMenu={getMoreMenu(title)}
294
+ status={getStatus(index)}
295
+ />
296
+ );
297
+ })}
298
+ </NavigationListCollapsibleSection>
299
+ ))}
300
+ </NavigationList>
301
+ </div>
302
+ </div>
303
+ );
304
+ };
305
+
158
306
  const fakeTitles = [
159
307
  "Project Kickoff Meeting",
160
308
  "Budget Review Discussion",
@@ -24,7 +24,8 @@
24
24
 
25
25
  @layer utilities {
26
26
  .s-checkerboard {
27
- background-image: linear-gradient(
27
+ background-image:
28
+ linear-gradient(
28
29
  45deg,
29
30
  var(--tw-checker-color) 25%,
30
31
  transparent 25%,