@dust-tt/sparkle 0.5.13 → 0.5.15

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 (43) hide show
  1. package/dist/cjs/index.js +6 -6
  2. package/dist/cjs/index.js.map +3 -3
  3. package/dist/esm/components/AttachmentChip.d.ts +0 -2
  4. package/dist/esm/components/AttachmentChip.d.ts.map +1 -1
  5. package/dist/esm/components/AttachmentChip.js +1 -1
  6. package/dist/esm/components/AttachmentChip.js.map +1 -1
  7. package/dist/esm/components/Chip.d.ts.map +1 -1
  8. package/dist/esm/components/Chip.js +1 -0
  9. package/dist/esm/components/Chip.js.map +1 -1
  10. package/dist/esm/components/Dropdown.d.ts +21 -1
  11. package/dist/esm/components/Dropdown.d.ts.map +1 -1
  12. package/dist/esm/components/Dropdown.js +23 -1
  13. package/dist/esm/components/Dropdown.js.map +1 -1
  14. package/dist/esm/components/index.d.ts +2 -2
  15. package/dist/esm/components/index.d.ts.map +1 -1
  16. package/dist/esm/components/index.js +1 -1
  17. package/dist/esm/components/index.js.map +1 -1
  18. package/dist/esm/lottie/collapseBar.d.ts +21 -21
  19. package/dist/esm/lottie/dragArea.d.ts +37 -37
  20. package/dist/esm/lottie/spinnerColor.d.ts +64 -64
  21. package/dist/esm/lottie/spinnerDark.d.ts +64 -64
  22. package/dist/esm/lottie/spinnerDarkLG.d.ts +134 -134
  23. package/dist/esm/lottie/spinnerLightLG.d.ts +134 -134
  24. package/dist/esm/lottie/spinnerLightXS.d.ts +38 -38
  25. package/dist/esm/stories/AttachmentChip.stories.d.ts.map +1 -1
  26. package/dist/esm/stories/AttachmentChip.stories.js +1 -0
  27. package/dist/esm/stories/AttachmentChip.stories.js.map +1 -1
  28. package/dist/esm/stories/Chip.stories.d.ts.map +1 -1
  29. package/dist/esm/stories/Chip.stories.js +1 -1
  30. package/dist/esm/stories/Chip.stories.js.map +1 -1
  31. package/dist/esm/stories/Dropdown.stories.d.ts +1 -0
  32. package/dist/esm/stories/Dropdown.stories.d.ts.map +1 -1
  33. package/dist/esm/stories/Dropdown.stories.js +41 -1
  34. package/dist/esm/stories/Dropdown.stories.js.map +1 -1
  35. package/dist/sparkle.css +30 -0
  36. package/package.json +1 -1
  37. package/src/components/AttachmentChip.tsx +2 -3
  38. package/src/components/Chip.tsx +1 -0
  39. package/src/components/Dropdown.tsx +104 -7
  40. package/src/components/index.ts +3 -0
  41. package/src/stories/AttachmentChip.stories.tsx +1 -0
  42. package/src/stories/Chip.stories.tsx +1 -0
  43. package/src/stories/Dropdown.stories.tsx +112 -0
@@ -1,4 +1,5 @@
1
1
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
2
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
2
3
  import { cva } from "class-variance-authority";
3
4
  import * as React from "react";
4
5
  import { useRef } from "react";
@@ -242,9 +243,8 @@ const DropdownMenuSubContent = React.forwardRef<
242
243
  DropdownMenuSubContent.displayName =
243
244
  DropdownMenuPrimitive.SubContent.displayName;
244
245
 
245
- interface DropdownMenuContentProps extends React.ComponentPropsWithoutRef<
246
- typeof DropdownMenuPrimitive.Content
247
- > {
246
+ interface DropdownMenuContentProps
247
+ extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> {
248
248
  mountPortal?: boolean;
249
249
  mountPortalContainer?: HTMLElement;
250
250
  dropdownHeaders?: React.ReactNode;
@@ -487,10 +487,8 @@ const DropdownMenuRadioItem = React.forwardRef<
487
487
  ));
488
488
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
489
489
 
490
- interface DropdownMenuTagItemProps extends Omit<
491
- DropdownMenuItemProps,
492
- "label" | "icon" | "onClick"
493
- > {
490
+ interface DropdownMenuTagItemProps
491
+ extends Omit<DropdownMenuItemProps, "label" | "icon" | "onClick"> {
494
492
  label: string;
495
493
  size?: React.ComponentProps<typeof Chip>["size"];
496
494
  color?: React.ComponentProps<typeof Chip>["color"];
@@ -727,6 +725,104 @@ const DropdownMenuFilters = React.forwardRef<
727
725
 
728
726
  DropdownMenuFilters.displayName = "DropdownMenuFilters";
729
727
 
728
+ // DropdownTooltip: Simple tooltip with consistent layout: optional media at top, description below.
729
+ export interface DropdownTooltipProps {
730
+ description: string;
731
+ media?: React.ReactNode;
732
+ }
733
+
734
+ const DropdownTooltip = ({ description, media }: DropdownTooltipProps) => (
735
+ <div className="s-space-y-4">
736
+ {/* Media at top */}
737
+ {media && <div className="s-rounded-sm">{media}</div>}
738
+
739
+ {/* Description */}
740
+ <p className="text-foreground dark:text-foreground-night s-text-sm s-font-normal">
741
+ {description}
742
+ </p>
743
+ </div>
744
+ );
745
+
746
+ DropdownTooltip.displayName = "DropdownTooltip";
747
+
748
+ export interface DropdownTooltipTriggerProps {
749
+ children: React.ReactElement;
750
+ className?: string;
751
+ description: string;
752
+ media?: React.ReactNode;
753
+ mountPortal?: boolean;
754
+ mountPortalContainer?: HTMLElement;
755
+ onVisibilityChange?: (visible: boolean) => void;
756
+ side?: "left" | "right" | "top" | "bottom";
757
+ sideOffset?: number;
758
+ }
759
+
760
+ const DropdownTooltipTrigger = React.forwardRef<
761
+ React.ElementRef<typeof TooltipPrimitive.Trigger>,
762
+ DropdownTooltipTriggerProps
763
+ >(
764
+ (
765
+ {
766
+ children,
767
+ className,
768
+ description,
769
+ media,
770
+ mountPortal = true,
771
+ mountPortalContainer,
772
+ onVisibilityChange,
773
+ side = "right",
774
+ sideOffset = 8,
775
+ },
776
+ ref
777
+ ) => {
778
+ const tooltipContent = (
779
+ <TooltipPrimitive.Content
780
+ side={side}
781
+ sideOffset={sideOffset}
782
+ className={cn(
783
+ menuStyleClasses.container,
784
+ "s-w-48 s-max-w-sm s-p-2 s-shadow-lg"
785
+ )}
786
+ >
787
+ <DropdownTooltip description={description} media={media} />
788
+ </TooltipPrimitive.Content>
789
+ );
790
+
791
+ const [container, setContainer] = React.useState<Element | undefined>(
792
+ mountPortalContainer
793
+ );
794
+
795
+ React.useEffect(() => {
796
+ if (mountPortal && !container) {
797
+ const dialogElements = document.querySelectorAll(
798
+ ".s-sheet[role=dialog][data-state=open]"
799
+ );
800
+ const defaultContainer = dialogElements[dialogElements.length - 1];
801
+ setContainer(defaultContainer);
802
+ }
803
+ }, [mountPortal, container]);
804
+
805
+ return (
806
+ <TooltipPrimitive.Provider delayDuration={300}>
807
+ <TooltipPrimitive.Root onOpenChange={onVisibilityChange}>
808
+ <TooltipPrimitive.Trigger asChild className={className} ref={ref}>
809
+ {children}
810
+ </TooltipPrimitive.Trigger>
811
+ {mountPortal ? (
812
+ <TooltipPrimitive.Portal container={container}>
813
+ {tooltipContent}
814
+ </TooltipPrimitive.Portal>
815
+ ) : (
816
+ tooltipContent
817
+ )}
818
+ </TooltipPrimitive.Root>
819
+ </TooltipPrimitive.Provider>
820
+ );
821
+ }
822
+ );
823
+
824
+ DropdownTooltipTrigger.displayName = "DropdownTooltipTrigger";
825
+
730
826
  interface DropdownMenuStaticItemProps {
731
827
  label: string;
732
828
  value?: string;
@@ -783,4 +879,5 @@ export {
783
879
  DropdownMenuTagItem,
784
880
  DropdownMenuTagList,
785
881
  DropdownMenuTrigger,
882
+ DropdownTooltipTrigger,
786
883
  };
@@ -79,6 +79,8 @@ export {
79
79
  export type {
80
80
  DropdownMenuFilterOption,
81
81
  DropdownMenuItemProps,
82
+ DropdownTooltipProps,
83
+ DropdownTooltipTriggerProps,
82
84
  } from "./Dropdown";
83
85
  export {
84
86
  DropdownMenu,
@@ -100,6 +102,7 @@ export {
100
102
  DropdownMenuTagItem,
101
103
  DropdownMenuTagList,
102
104
  DropdownMenuTrigger,
105
+ DropdownTooltipTrigger,
103
106
  } from "./Dropdown";
104
107
  export { default as DropzoneOverlay } from "./DropzoneOverlay";
105
108
  export type { EmojiMartData } from "./EmojiPicker";
@@ -106,6 +106,7 @@ export const WithDoubleIconAndLink: Story = {
106
106
  },
107
107
  href: "https://notion.so",
108
108
  target: "_blank",
109
+ onRemove: () => console.log("Ciao"),
109
110
  },
110
111
  decorators: [
111
112
  (Story) => (
@@ -91,6 +91,7 @@ export const RemovableChip: Story = {
91
91
  size="mini"
92
92
  color="golden"
93
93
  label="Remove me"
94
+ href="https://notion.so"
94
95
  onRemove={() => alert("Removed")}
95
96
  />
96
97
  <Chip
@@ -23,6 +23,7 @@ import {
23
23
  DropdownMenuTagItem,
24
24
  DropdownMenuTagList,
25
25
  DropdownMenuTrigger,
26
+ DropdownTooltipTrigger,
26
27
  } from "@sparkle/components/Dropdown";
27
28
  import {
28
29
  AnthropicLogo,
@@ -927,3 +928,114 @@ export const WithFilters: Story = {
927
928
  );
928
929
  },
929
930
  };
931
+
932
+ export const WithTooltips: Story = {
933
+ render: () => {
934
+ return (
935
+ <div className="s-flex s-flex-col s-gap-8 s-p-8">
936
+ <h3 className="s-text-lg s-font-semibold">
937
+ Dropdown with Rich Tooltips
938
+ </h3>
939
+
940
+ <div className="s-flex s-gap-4">
941
+ {/* Knowledge Attachment Example */}
942
+ <DropdownMenu>
943
+ <DropdownMenuTrigger asChild>
944
+ <Button label="Skill Builder Actions" variant="outline" />
945
+ </DropdownMenuTrigger>
946
+ <DropdownMenuContent className="s-w-64">
947
+ <DropdownMenuItem label="Configure Settings" />
948
+ <DropdownTooltipTrigger
949
+ description="Use company knowledge for context."
950
+ media={
951
+ <img
952
+ src="/static/landing/product/Knowledge_Tooltips.jpg"
953
+ alt="Knowledge Search Interface"
954
+ className="s-aspect-[4/3] s-w-full s-rounded s-object-cover"
955
+ />
956
+ }
957
+ side="right"
958
+ sideOffset={8}
959
+ >
960
+ <DropdownMenuItem icon={AttachmentIcon} label="Add Knowledge" />
961
+ </DropdownTooltipTrigger>
962
+ <DropdownMenuItem label="Save Draft" />
963
+ </DropdownMenuContent>
964
+ </DropdownMenu>
965
+
966
+ {/* Data Export Example */}
967
+ <DropdownMenu>
968
+ <DropdownMenuTrigger asChild>
969
+ <Button label="Data Actions" variant="outline" />
970
+ </DropdownMenuTrigger>
971
+ <DropdownMenuContent className="s-w-64">
972
+ <DropdownMenuItem label="View Report" />
973
+ <DropdownTooltipTrigger
974
+ description="Export your data in various formats. Choose from CSV, JSON, or PDF depending on your needs."
975
+ media={
976
+ <div className="s-flex s-items-center s-gap-3">
977
+ <div className="s-flex s-h-10 s-w-10 s-items-center s-justify-center s-rounded-full s-bg-green-100">
978
+ <CloudArrowDownIcon className="s-h-5 s-w-5 s-text-green-600" />
979
+ </div>
980
+ <div>
981
+ <h4 className="s-text-sm s-font-medium s-text-green-800">
982
+ Export Status
983
+ </h4>
984
+ <p className="s-text-xs s-text-green-600">
985
+ Ready to export
986
+ </p>
987
+ </div>
988
+ </div>
989
+ }
990
+ side="right"
991
+ sideOffset={8}
992
+ >
993
+ <DropdownMenuItem
994
+ icon={CloudArrowDownIcon}
995
+ label="Export Data"
996
+ />
997
+ </DropdownTooltipTrigger>
998
+ <DropdownMenuItem label="Share Report" />
999
+ </DropdownMenuContent>
1000
+ </DropdownMenu>
1001
+
1002
+ {/* Left-side tooltip example */}
1003
+ <div className="s-ml-auto">
1004
+ <DropdownMenu>
1005
+ <DropdownMenuTrigger asChild>
1006
+ <Button label="Right Side Menu" variant="outline" />
1007
+ </DropdownMenuTrigger>
1008
+ <DropdownMenuContent className="s-w-56">
1009
+ <DropdownMenuItem label="Regular Item" />
1010
+ <DropdownTooltipTrigger
1011
+ description="This tooltip appears on the left side when the dropdown is positioned on the right side of the screen."
1012
+ media={
1013
+ <div className="s-text-center">
1014
+ <div className="s-mb-2 s-text-2xl">⬅️</div>
1015
+ <p className="s-text-sm s-font-medium s-text-orange-800">
1016
+ Positioned Left
1017
+ </p>
1018
+ <p className="s-mt-1 s-text-xs s-text-orange-600">
1019
+ Perfect for right-side menus
1020
+ </p>
1021
+ </div>
1022
+ }
1023
+ side="left"
1024
+ sideOffset={8}
1025
+ >
1026
+ <DropdownMenuItem icon={MagicIcon} label="Help Item" />
1027
+ </DropdownTooltipTrigger>
1028
+ </DropdownMenuContent>
1029
+ </DropdownMenu>
1030
+ </div>
1031
+ </div>
1032
+
1033
+ <p className="s-max-w-lg s-text-sm s-text-gray-600">
1034
+ Hover over menu items with icons to see rich tooltips that provide
1035
+ contextual information and step-by-step instructions. The tooltip
1036
+ positioning automatically adapts based on available space.
1037
+ </p>
1038
+ </div>
1039
+ );
1040
+ },
1041
+ };