@dust-tt/sparkle 0.5.12 → 0.5.14
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.
- package/dist/cjs/index.js +8 -11
- package/dist/cjs/index.js.map +4 -4
- package/dist/esm/components/AnimatedText.d.ts +1 -1
- package/dist/esm/components/AnimatedText.d.ts.map +1 -1
- package/dist/esm/components/AnimatedText.js +3 -0
- package/dist/esm/components/AnimatedText.js.map +1 -1
- package/dist/esm/components/Chip.d.ts +1 -1
- package/dist/esm/components/Chip.d.ts.map +1 -1
- package/dist/esm/components/Chip.js +8 -3
- package/dist/esm/components/Chip.js.map +1 -1
- package/dist/esm/components/Citation.js +1 -1
- package/dist/esm/components/DataTable.d.ts.map +1 -1
- package/dist/esm/components/DataTable.js +1 -1
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/components/Dropdown.d.ts +21 -1
- package/dist/esm/components/Dropdown.d.ts.map +1 -1
- package/dist/esm/components/Dropdown.js +23 -1
- package/dist/esm/components/Dropdown.js.map +1 -1
- package/dist/esm/components/NavigationList.d.ts.map +1 -1
- package/dist/esm/components/NavigationList.js.map +1 -1
- package/dist/esm/components/index.d.ts +2 -2
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +1 -1
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/lottie/collapseBar.d.ts +21 -21
- package/dist/esm/lottie/dragArea.d.ts +31 -31
- package/dist/esm/lottie/spinnerColor.d.ts +73 -73
- package/dist/esm/lottie/spinnerDark.d.ts +73 -73
- package/dist/esm/lottie/spinnerDarkLG.d.ts +141 -141
- package/dist/esm/lottie/spinnerLightLG.d.ts +141 -141
- package/dist/esm/lottie/spinnerLightXS.d.ts +38 -38
- package/dist/esm/stories/Chip.stories.d.ts +1 -1
- package/dist/esm/stories/Dropdown.stories.d.ts +1 -0
- package/dist/esm/stories/Dropdown.stories.d.ts.map +1 -1
- package/dist/esm/stories/Dropdown.stories.js +41 -1
- package/dist/esm/stories/Dropdown.stories.js.map +1 -1
- package/dist/sparkle.css +1589 -1569
- package/package.json +8 -8
- package/src/components/AnimatedText.tsx +6 -0
- package/src/components/Chip.tsx +45 -11
- package/src/components/Citation.tsx +1 -1
- package/src/components/DataTable.tsx +5 -5
- package/src/components/Dropdown.tsx +104 -7
- package/src/components/NavigationList.tsx +6 -6
- package/src/components/index.ts +3 -0
- package/src/stories/Dropdown.stories.tsx +112 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dust-tt/sparkle",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.14",
|
|
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",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@babel/preset-react": "^7.22.5",
|
|
49
49
|
"@babel/preset-typescript": "^7.22.5",
|
|
50
50
|
"@chromatic-com/storybook": "^3.2.5",
|
|
51
|
+
"@radix-ui/react-focus-scope": "^1.0.3",
|
|
51
52
|
"@storybook/addon-essentials": "^8.6.4",
|
|
52
53
|
"@storybook/addon-interactions": "^8.6.4",
|
|
53
54
|
"@storybook/addon-links": "^8.6.4",
|
|
@@ -68,14 +69,12 @@
|
|
|
68
69
|
"@types/uuid": "^9.0.6",
|
|
69
70
|
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
70
71
|
"@typescript-eslint/parser": "^8.48.0",
|
|
71
|
-
"@typescript/native-preview": "^7.0.0-dev.
|
|
72
|
-
"
|
|
73
|
-
"@radix-ui/react-focus-scope": "^1.0.3",
|
|
74
|
-
"autoprefixer": "^10.4.14",
|
|
72
|
+
"@typescript/native-preview": "^7.0.0-dev.20260105.1",
|
|
73
|
+
"autoprefixer": "^10.4.23",
|
|
75
74
|
"babel-loader": "^9.1.3",
|
|
76
75
|
"babel-preset-react-app": "^10.0.1",
|
|
77
76
|
"copyfiles": "^2.4.1",
|
|
78
|
-
"esbuild": "^0.25.
|
|
77
|
+
"esbuild": "^0.25.12",
|
|
79
78
|
"esbuild-plugin-postcss2": "^0.1.2",
|
|
80
79
|
"eslint": "^9.18.0",
|
|
81
80
|
"eslint-config-prettier": "^9.1.0",
|
|
@@ -89,10 +88,10 @@
|
|
|
89
88
|
"react-dom": "^18.3.1",
|
|
90
89
|
"sass-loader": "^13.3.2",
|
|
91
90
|
"storybook": "^8.6.4",
|
|
92
|
-
"tailwindcss": "^3.
|
|
91
|
+
"tailwindcss": "^3.4.19",
|
|
93
92
|
"tailwindcss-animate": "^1.0.7",
|
|
94
93
|
"tsc-alias": "^1.8.10",
|
|
95
|
-
"typescript": "^5.
|
|
94
|
+
"typescript": "^5.9.3",
|
|
96
95
|
"typescript-eslint": "^8.48.0",
|
|
97
96
|
"typescript-transform-paths": "^3.4.7",
|
|
98
97
|
"uuid": "^9.0.1"
|
|
@@ -130,6 +129,7 @@
|
|
|
130
129
|
"@radix-ui/react-tabs": "^1.1.1",
|
|
131
130
|
"@radix-ui/react-tooltip": "^1.1.3",
|
|
132
131
|
"@tanstack/react-table": "^8.13.0",
|
|
132
|
+
"@tanstack/react-virtual": "^3.5.0",
|
|
133
133
|
"class-variance-authority": "^0.7.1",
|
|
134
134
|
"clsx": "^2.1.1",
|
|
135
135
|
"emoji-mart": "^5.5.2",
|
|
@@ -14,6 +14,7 @@ const ANIMATED_TEXT_VARIANTS = [
|
|
|
14
14
|
"blue",
|
|
15
15
|
"rose",
|
|
16
16
|
"golden",
|
|
17
|
+
"white",
|
|
17
18
|
] as const;
|
|
18
19
|
|
|
19
20
|
type AnimatedTextVariantType = (typeof ANIMATED_TEXT_VARIANTS)[number];
|
|
@@ -59,6 +60,10 @@ const animatedVariants: Record<AnimatedTextVariantType, string> = {
|
|
|
59
60
|
"s-from-golden-800 s-via-golden-950 s-via-50% s-to-golden-800",
|
|
60
61
|
"dark:s-from-golden-800-night dark:s-via-golden-950-night dark:s-via-50% dark:s-to-golden-800-night"
|
|
61
62
|
),
|
|
63
|
+
white: cn(
|
|
64
|
+
"s-from-primary-800 s-via-primary-950 s-via-50% s-to-primary-800",
|
|
65
|
+
"dark:s-from-primary-800-night dark:s-via-primary-950-night dark:s-via-50% dark:s-to-primary-800-night"
|
|
66
|
+
),
|
|
62
67
|
};
|
|
63
68
|
|
|
64
69
|
const animVariants = cva(
|
|
@@ -84,6 +89,7 @@ const animatedTextVariants: Record<AnimatedTextVariantType, string> = {
|
|
|
84
89
|
blue: "s-text-sky-800 dark:s-text-sky-800-night",
|
|
85
90
|
rose: "s-text-rose-800 dark:s-text-rose-800-night",
|
|
86
91
|
golden: "s-text-golden-800 dark:s-text-rose-golden-night",
|
|
92
|
+
white: "s-text-primary-800 dark:s-text-primary-800-night",
|
|
87
93
|
};
|
|
88
94
|
|
|
89
95
|
const textVariants = cva("s-absolute s-inset-0", {
|
package/src/components/Chip.tsx
CHANGED
|
@@ -25,6 +25,7 @@ export const CHIP_COLORS = [
|
|
|
25
25
|
"blue",
|
|
26
26
|
"rose",
|
|
27
27
|
"golden",
|
|
28
|
+
"white",
|
|
28
29
|
] as const;
|
|
29
30
|
|
|
30
31
|
type ChipColorType = (typeof CHIP_COLORS)[number];
|
|
@@ -91,6 +92,12 @@ const chipVariants = cva("s-inline-flex s-box-border s-items-center", {
|
|
|
91
92
|
"dark:s-bg-golden-100-night dark:s-border-golden-200-night",
|
|
92
93
|
"dark:s-text-golden-900-night"
|
|
93
94
|
),
|
|
95
|
+
white: cn(
|
|
96
|
+
"s-border s-bg-white s-border-border",
|
|
97
|
+
"s-text-primary-900",
|
|
98
|
+
"dark:s-bg-background-night dark:s-border-border-night",
|
|
99
|
+
"dark:s-text-primary-900-night"
|
|
100
|
+
),
|
|
94
101
|
},
|
|
95
102
|
},
|
|
96
103
|
defaultVariants: {
|
|
@@ -136,8 +143,40 @@ const closeIconVariants: Record<ChipColorType, string> = {
|
|
|
136
143
|
"s-text-golden-900 hover:s-text-golden-700 active:s-text-golden-950",
|
|
137
144
|
"dark:s-text-golden-900-night dark:hover:s-text-golden-700-night dark:active:s-text-golden-950-night"
|
|
138
145
|
),
|
|
146
|
+
white: cn(
|
|
147
|
+
"s-text-primary-700 hover:s-text-primary-500 active:s-text-primary-950",
|
|
148
|
+
"dark:s-text-primary-700-night dark:hover:s-text-primary-500-night dark:active:s-text-primary-950-night"
|
|
149
|
+
),
|
|
139
150
|
};
|
|
140
151
|
|
|
152
|
+
interface ChipInternalButtonProps {
|
|
153
|
+
icon: ComponentType;
|
|
154
|
+
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
155
|
+
className?: string;
|
|
156
|
+
size?: "xs" | "sm";
|
|
157
|
+
"aria-label"?: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const ChipButton = React.forwardRef<HTMLButtonElement, ChipInternalButtonProps>(
|
|
161
|
+
({ icon, onClick, className, size = "xs", "aria-label": ariaLabel }, ref) => (
|
|
162
|
+
<button
|
|
163
|
+
ref={ref}
|
|
164
|
+
type="button"
|
|
165
|
+
onClick={onClick}
|
|
166
|
+
aria-label={ariaLabel}
|
|
167
|
+
className={cn(
|
|
168
|
+
"s-rounded-md s-p-0.5",
|
|
169
|
+
"s-transition-colors s-duration-200",
|
|
170
|
+
"focus-visible:s-outline-none focus-visible:s-ring-2 focus-visible:s-ring-ring",
|
|
171
|
+
className
|
|
172
|
+
)}
|
|
173
|
+
>
|
|
174
|
+
<Icon visual={icon} size={size} />
|
|
175
|
+
</button>
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
ChipButton.displayName = "ChipButton";
|
|
179
|
+
|
|
141
180
|
type ChipBaseProps = {
|
|
142
181
|
size?: ChipSizeType;
|
|
143
182
|
color?: ChipColorType;
|
|
@@ -225,21 +264,16 @@ const Chip = React.forwardRef<HTMLDivElement, ChipProps>(
|
|
|
225
264
|
</span>
|
|
226
265
|
)}
|
|
227
266
|
{onRemove && (
|
|
228
|
-
<
|
|
267
|
+
<ChipButton
|
|
268
|
+
icon={XMarkIcon}
|
|
269
|
+
size={size === "mini" ? "xs" : "sm"}
|
|
270
|
+
className={cn("-s-mr-1", closeIconVariants[color || "primary"])}
|
|
271
|
+
aria-label="Remove"
|
|
229
272
|
onClick={(e) => {
|
|
230
273
|
e.stopPropagation();
|
|
231
274
|
onRemove();
|
|
232
275
|
}}
|
|
233
|
-
|
|
234
|
-
<Icon
|
|
235
|
-
visual={XMarkIcon}
|
|
236
|
-
size={size === "mini" ? "xs" : (size as IconProps["size"])}
|
|
237
|
-
className={cn(
|
|
238
|
-
"s-transition-color -s-mr-1 s-duration-200",
|
|
239
|
-
closeIconVariants[color || "primary"]
|
|
240
|
-
)}
|
|
241
|
-
/>
|
|
242
|
-
</button>
|
|
276
|
+
/>
|
|
243
277
|
)}
|
|
244
278
|
</div>
|
|
245
279
|
);
|
|
@@ -53,7 +53,7 @@ const Citation = React.forwardRef<HTMLDivElement, CitationProps>(
|
|
|
53
53
|
variant={variant}
|
|
54
54
|
size="sm"
|
|
55
55
|
className={cn(
|
|
56
|
-
"s-
|
|
56
|
+
"s-relative s-flex s-min-w-24 s-flex-none s-flex-col s-overflow-hidden",
|
|
57
57
|
// Use min() to maintain aspect ratio in grid mode (8% of width) while capping
|
|
58
58
|
// padding at 3 (0.75rem) for list mode to prevent excessive top padding on wide items.
|
|
59
59
|
"s-pt-[min(8%,theme(spacing.3))]",
|
|
@@ -333,8 +333,9 @@ export function DataTable<TData extends TBaseData>({
|
|
|
333
333
|
);
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
-
export interface ScrollableDataTableProps<
|
|
337
|
-
extends
|
|
336
|
+
export interface ScrollableDataTableProps<
|
|
337
|
+
TData extends TBaseData,
|
|
338
|
+
> extends DataTableProps<TData> {
|
|
338
339
|
maxHeight?: string | boolean;
|
|
339
340
|
onLoadMore?: () => void;
|
|
340
341
|
isLoading?: boolean;
|
|
@@ -871,8 +872,7 @@ interface BaseMenuItem {
|
|
|
871
872
|
}
|
|
872
873
|
|
|
873
874
|
interface RegularMenuItem
|
|
874
|
-
extends BaseMenuItem,
|
|
875
|
-
Omit<DropdownMenuItemProps, "children" | "label"> {
|
|
875
|
+
extends BaseMenuItem, Omit<DropdownMenuItemProps, "children" | "label"> {
|
|
876
876
|
kind: "item";
|
|
877
877
|
}
|
|
878
878
|
|
|
@@ -900,7 +900,7 @@ const renderSubmenuItem = (
|
|
|
900
900
|
<DropdownMenuPortal>
|
|
901
901
|
<DropdownMenuSubContent>
|
|
902
902
|
<ScrollArea
|
|
903
|
-
className="s-
|
|
903
|
+
className="s-flex s-max-h-72 s-min-w-24 s-flex-col"
|
|
904
904
|
hideScrollBar
|
|
905
905
|
>
|
|
906
906
|
{item.items.map((subItem) => (
|
|
@@ -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
|
|
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
|
|
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
|
};
|
|
@@ -69,7 +69,8 @@ const NavigationList = React.forwardRef<
|
|
|
69
69
|
NavigationList.displayName = "NavigationList";
|
|
70
70
|
|
|
71
71
|
interface NavigationListItemProps
|
|
72
|
-
extends
|
|
72
|
+
extends
|
|
73
|
+
React.HTMLAttributes<HTMLDivElement>,
|
|
73
74
|
Omit<LinkWrapperProps, "children" | "className"> {
|
|
74
75
|
selected?: boolean;
|
|
75
76
|
label?: string;
|
|
@@ -178,8 +179,7 @@ const NavigationListItem = React.forwardRef<
|
|
|
178
179
|
);
|
|
179
180
|
NavigationListItem.displayName = "NavigationListItem";
|
|
180
181
|
|
|
181
|
-
interface NavigationListItemActionProps
|
|
182
|
-
extends React.HTMLAttributes<HTMLDivElement> {
|
|
182
|
+
interface NavigationListItemActionProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
183
183
|
showOnHover?: boolean;
|
|
184
184
|
}
|
|
185
185
|
|
|
@@ -228,7 +228,8 @@ const labelStyles = cva(
|
|
|
228
228
|
);
|
|
229
229
|
|
|
230
230
|
interface NavigationListLabelProps
|
|
231
|
-
extends
|
|
231
|
+
extends
|
|
232
|
+
React.HTMLAttributes<HTMLDivElement>,
|
|
232
233
|
VariantProps<typeof variantStyles> {
|
|
233
234
|
label: string;
|
|
234
235
|
action?: React.ReactNode;
|
|
@@ -257,8 +258,7 @@ const NavigationListLabel = React.forwardRef<
|
|
|
257
258
|
|
|
258
259
|
NavigationListLabel.displayName = "NavigationListLabel";
|
|
259
260
|
|
|
260
|
-
interface NavigationListCollapsibleSectionProps
|
|
261
|
-
extends React.HTMLAttributes<HTMLDivElement> {
|
|
261
|
+
interface NavigationListCollapsibleSectionProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
262
262
|
label: string;
|
|
263
263
|
action?: React.ReactNode;
|
|
264
264
|
defaultOpen?: boolean;
|
package/src/components/index.ts
CHANGED
|
@@ -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";
|
|
@@ -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
|
+
};
|