@dust-tt/sparkle 0.2.481-rc2 → 0.2.481-rc4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"InteractiveImage.d.ts","sourceRoot":"","sources":["../../../src/components/InteractiveImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,UAAU,qBAAqB;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAiB,EACjB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,qBAAqB,qBAsCvB"}
1
+ {"version":3,"file":"InteractiveImage.d.ts","sourceRoot":"","sources":["../../../src/components/InteractiveImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAqD1B,UAAU,qBAAqB;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAiB,EACjB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,qBAAqB,qBAsDvB"}
@@ -3,9 +3,41 @@ import React from "react";
3
3
  import { Dialog, DialogContent, DialogTrigger, IconButton, Spinner, } from "../components";
4
4
  import { ArrowDownOnSquareIcon } from "../icons/app";
5
5
  import { cn } from "../lib/utils";
6
+ function DownloadButton(_a) {
7
+ var _this = this;
8
+ var className = _a.className, _b = _a.size, size = _b === void 0 ? "xs" : _b, src = _a.src, title = _a.title;
9
+ var handleDownload = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
10
+ var link;
11
+ return __generator(this, function (_a) {
12
+ if (!src) {
13
+ return [2 /*return*/];
14
+ }
15
+ link = document.createElement("a");
16
+ link.href = src;
17
+ link.download = title;
18
+ document.body.appendChild(link);
19
+ link.click();
20
+ document.body.removeChild(link);
21
+ return [2 /*return*/];
22
+ });
23
+ }); }, [src, title]);
24
+ return (React.createElement(IconButton, { icon: ArrowDownOnSquareIcon, className: cn("s-text-white", className), tooltip: "Download", size: size, onClick: function (e) { return __awaiter(_this, void 0, void 0, function () {
25
+ return __generator(this, function (_a) {
26
+ switch (_a.label) {
27
+ case 0:
28
+ e.stopPropagation(); // Prevent image zoom.
29
+ return [4 /*yield*/, handleDownload()];
30
+ case 1:
31
+ _a.sent();
32
+ return [2 /*return*/];
33
+ }
34
+ });
35
+ }); } }));
36
+ }
6
37
  export function InteractiveImage(_a) {
7
38
  var alt = _a.alt, _b = _a.isLoading, isLoading = _b === void 0 ? false : _b, src = _a.src, props = __rest(_a, ["alt", "isLoading", "src"]);
8
39
  var _c = __read(React.useState(false), 2), isZoomed = _c[0], setIsZoomed = _c[1];
40
+ var _d = __read(React.useState(false), 2), imageLoaded = _d[0], setImageLoaded = _d[1];
9
41
  var handleZoomToggle = React.useCallback(function () {
10
42
  setIsZoomed(!isZoomed);
11
43
  }, [isZoomed]);
@@ -20,46 +52,22 @@ export function InteractiveImage(_a) {
20
52
  }
21
53
  handleZoomToggle();
22
54
  }, src: src }, props)))),
23
- React.createElement(DialogContent, { className: cn("s-w-auto s-max-w-none s-border-0 s-outline-none s-ring-0", "focus:s-outline-none focus:s-ring-0"), size: "xl" },
24
- React.createElement("img", { src: src, alt: alt, className: "s-object-contain" }))));
55
+ React.createElement(DialogContent, { className: cn("s-w-auto s-max-w-none s-border-0 s-outline-none s-ring-0", "focus:s-outline-none focus:s-ring-0", "s-rounded-none s-bg-transparent s-shadow-none"), size: "xl" },
56
+ React.createElement("div", { className: "s-flex s-flex-col" },
57
+ React.createElement("div", { className: "s-flex s-justify-end" }, imageLoaded && (React.createElement(DownloadButton, { src: src, title: props.title, size: "sm" }))),
58
+ React.createElement("div", { className: "s-relative s-w-full" },
59
+ React.createElement("img", { src: src, alt: alt, className: "s-w-full s-object-contain", onLoad: function () { return setImageLoaded(true); } }))))));
25
60
  }
26
61
  function LoadingImage() {
27
62
  return (React.createElement("div", { className: "s-flex s-h-full s-w-full s-items-center s-justify-center" },
28
- React.createElement(Spinner, { variant: "dark", size: "sm" })));
63
+ React.createElement(Spinner, { variant: "dark", size: "md" })));
29
64
  }
30
65
  function ImagePreview(_a) {
31
- var _this = this;
32
66
  var isLoading = _a.isLoading, onClick = _a.onClick, alt = _a.alt, src = _a.src, title = _a.title;
33
- var handleDownload = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
34
- var link;
35
- return __generator(this, function (_a) {
36
- if (!src) {
37
- return [2 /*return*/];
38
- }
39
- link = document.createElement("a");
40
- link.href = src;
41
- link.download = title;
42
- document.body.appendChild(link);
43
- link.click();
44
- document.body.removeChild(link);
45
- return [2 /*return*/];
46
- });
47
- }); }, [src, title]);
48
- return (React.createElement("div", { onClick: onClick, className: cn("s-group/preview s-relative s-h-full s-w-full s-overflow-hidden s-rounded-2xl s-bg-muted-background dark:s-bg-muted-background-night", !isLoading && "s-cursor-pointer") }, isLoading ? (React.createElement(LoadingImage, null)) : (React.createElement(React.Fragment, null,
67
+ return (React.createElement("div", { onClick: onClick, className: cn("s-group/preview s-relative s-h-full s-w-full s-overflow-hidden s-rounded-2xl", "s-bg-muted-background dark:s-bg-muted-background-night", !isLoading && "s-cursor-pointer") }, isLoading ? (React.createElement(LoadingImage, null)) : (React.createElement(React.Fragment, null,
49
68
  React.createElement("img", { src: src, alt: alt, className: "s-h-full s-w-full s-rounded-2xl s-object-cover" }),
50
- React.createElement("div", { className: "s-absolute s-inset-0 s-bg-black s-opacity-0 s-transition-opacity s-duration-200 group-hover/preview:s-opacity-40" }),
51
- React.createElement("div", { className: "s-absolute s-right-3 s-top-3 s-z-10 s-flex s-opacity-0 s-transition-opacity s-duration-200 group-hover/preview:s-opacity-100" },
52
- React.createElement(IconButton, { icon: ArrowDownOnSquareIcon, className: "s-text-white", tooltip: "Download", size: "xs", onClick: function (e) { return __awaiter(_this, void 0, void 0, function () {
53
- return __generator(this, function (_a) {
54
- switch (_a.label) {
55
- case 0:
56
- e.stopPropagation(); // Prevent image zoom.
57
- return [4 /*yield*/, handleDownload()];
58
- case 1:
59
- _a.sent();
60
- return [2 /*return*/];
61
- }
62
- });
63
- }); } }))))));
69
+ React.createElement("div", { className: cn("s-absolute s-inset-0 s-bg-gradient-to-b", "s-from-black/40 s-via-transparent s-to-black/40", "s-opacity-0 s-transition-opacity s-duration-200", "group-hover/preview:s-opacity-100") }),
70
+ React.createElement("div", { className: cn("s-absolute s-right-3 s-top-3 s-z-10 s-flex", "s-opacity-0 s-transition-opacity s-duration-200", "group-hover/preview:s-opacity-100") },
71
+ React.createElement(DownloadButton, { src: src, title: title, size: "xs" }))))));
64
72
  }
65
73
  //# sourceMappingURL=InteractiveImage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InteractiveImage.js","sourceRoot":"","sources":["../../../src/components/InteractiveImage.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InteractiveImage.js","sourceRoot":"","sources":["../../../src/components/InteractiveImage.tsx"],"names":[],"mappings":"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"}
package/dist/sparkle.css CHANGED
@@ -2311,6 +2311,10 @@ select {
2311
2311
  border-radius: 0.375rem;
2312
2312
  }
2313
2313
 
2314
+ .s-rounded-none {
2315
+ border-radius: 0px;
2316
+ }
2317
+
2314
2318
  .s-rounded-sm {
2315
2319
  border-radius: 0.125rem;
2316
2320
  }
@@ -2674,11 +2678,6 @@ select {
2674
2678
  background-color: rgb(255 255 255 / 0.8);
2675
2679
  }
2676
2680
 
2677
- .s-bg-black {
2678
- --tw-bg-opacity: 1;
2679
- background-color: rgb(0 0 0 / var(--tw-bg-opacity));
2680
- }
2681
-
2682
2681
  .s-bg-blue-100 {
2683
2682
  --tw-bg-opacity: 1;
2684
2683
  background-color: rgb(202 235 255 / var(--tw-bg-opacity));
@@ -3563,6 +3562,10 @@ select {
3563
3562
  background-color: rgb(169 184 169 / var(--tw-bg-opacity));
3564
3563
  }
3565
3564
 
3565
+ .s-bg-transparent {
3566
+ background-color: transparent;
3567
+ }
3568
+
3566
3569
  .s-bg-violet-100 {
3567
3570
  --tw-bg-opacity: 1;
3568
3571
  background-color: rgb(237 233 254 / var(--tw-bg-opacity));
@@ -3697,6 +3700,10 @@ select {
3697
3700
  background-color: rgb(254 240 138 / var(--tw-bg-opacity));
3698
3701
  }
3699
3702
 
3703
+ .s-bg-gradient-to-b {
3704
+ background-image: linear-gradient(to bottom, var(--tw-gradient-stops));
3705
+ }
3706
+
3700
3707
  .s-bg-gradient-to-r {
3701
3708
  background-image: linear-gradient(to right, var(--tw-gradient-stops));
3702
3709
  }
@@ -3709,6 +3716,12 @@ select {
3709
3716
  background-image: linear-gradient(90deg, #7AC6FF, #1C91FF, #a855f7, #4BABFF, #0A6CC6);
3710
3717
  }
3711
3718
 
3719
+ .s-from-black\/40 {
3720
+ --tw-gradient-from: rgb(0 0 0 / 0.4) var(--tw-gradient-from-position);
3721
+ --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);
3722
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
3723
+ }
3724
+
3712
3725
  .s-from-cyan-500 {
3713
3726
  --tw-gradient-from: #06b6d4 var(--tw-gradient-from-position);
3714
3727
  --tw-gradient-to: rgb(6 182 212 / 0) var(--tw-gradient-to-position);
@@ -3826,6 +3839,11 @@ select {
3826
3839
  --tw-gradient-stops: var(--tw-gradient-from), #04140A var(--tw-gradient-via-position), var(--tw-gradient-to);
3827
3840
  }
3828
3841
 
3842
+ .s-via-transparent {
3843
+ --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);
3844
+ --tw-gradient-stops: var(--tw-gradient-from), transparent var(--tw-gradient-via-position), var(--tw-gradient-to);
3845
+ }
3846
+
3829
3847
  .s-via-warning-950 {
3830
3848
  --tw-gradient-to: rgb(34 10 4 / 0) var(--tw-gradient-to-position);
3831
3849
  --tw-gradient-stops: var(--tw-gradient-from), #220A04 var(--tw-gradient-via-position), var(--tw-gradient-to);
@@ -3835,6 +3853,10 @@ select {
3835
3853
  --tw-gradient-via-position: 50%;
3836
3854
  }
3837
3855
 
3856
+ .s-to-black\/40 {
3857
+ --tw-gradient-to: rgb(0 0 0 / 0.4) var(--tw-gradient-to-position);
3858
+ }
3859
+
3838
3860
  .s-to-blue-500 {
3839
3861
  --tw-gradient-to: #1C91FF var(--tw-gradient-to-position);
3840
3862
  }
@@ -4899,6 +4921,12 @@ select {
4899
4921
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
4900
4922
  }
4901
4923
 
4924
+ .s-shadow-none {
4925
+ --tw-shadow: 0 0 #0000;
4926
+ --tw-shadow-colored: 0 0 #0000;
4927
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
4928
+ }
4929
+
4902
4930
  .s-shadow-sm {
4903
4931
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
4904
4932
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
@@ -5811,10 +5839,6 @@ select {
5811
5839
  opacity: 1;
5812
5840
  }
5813
5841
 
5814
- .s-group\/preview:hover .group-hover\/preview\:s-opacity-40 {
5815
- opacity: 0.4;
5816
- }
5817
-
5818
5842
  .s-group\/tree:hover .group-hover\/tree\:s-opacity-100 {
5819
5843
  opacity: 1;
5820
5844
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dust-tt/sparkle",
3
- "version": "0.2.481-rc2",
3
+ "version": "0.2.481-rc4",
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",
@@ -10,6 +10,47 @@ import {
10
10
  import { ArrowDownOnSquareIcon } from "@sparkle/icons/app";
11
11
  import { cn } from "@sparkle/lib/utils";
12
12
 
13
+ interface DownloadButtonProps {
14
+ className?: string;
15
+ size?: "xs" | "sm";
16
+ src?: string;
17
+ title: string;
18
+ }
19
+
20
+ function DownloadButton({
21
+ className,
22
+ size = "xs",
23
+ src,
24
+ title,
25
+ }: DownloadButtonProps) {
26
+ const handleDownload = React.useCallback(async () => {
27
+ if (!src) {
28
+ return;
29
+ }
30
+
31
+ // Create a hidden link and click it.
32
+ const link = document.createElement("a");
33
+ link.href = src;
34
+ link.download = title;
35
+ document.body.appendChild(link);
36
+ link.click();
37
+ document.body.removeChild(link);
38
+ }, [src, title]);
39
+
40
+ return (
41
+ <IconButton
42
+ icon={ArrowDownOnSquareIcon}
43
+ className={cn("s-text-white", className)}
44
+ tooltip="Download"
45
+ size={size}
46
+ onClick={async (e) => {
47
+ e.stopPropagation(); // Prevent image zoom.
48
+ await handleDownload();
49
+ }}
50
+ />
51
+ );
52
+ }
53
+
13
54
  interface InteractiveImageProps {
14
55
  alt: string;
15
56
  isLoading?: boolean;
@@ -24,6 +65,7 @@ export function InteractiveImage({
24
65
  ...props
25
66
  }: InteractiveImageProps) {
26
67
  const [isZoomed, setIsZoomed] = React.useState(false);
68
+ const [imageLoaded, setImageLoaded] = React.useState(false);
27
69
 
28
70
  const handleZoomToggle = React.useCallback(() => {
29
71
  setIsZoomed(!isZoomed);
@@ -52,11 +94,26 @@ export function InteractiveImage({
52
94
  <DialogContent
53
95
  className={cn(
54
96
  "s-w-auto s-max-w-none s-border-0 s-outline-none s-ring-0",
55
- "focus:s-outline-none focus:s-ring-0"
97
+ "focus:s-outline-none focus:s-ring-0",
98
+ "s-rounded-none s-bg-transparent s-shadow-none"
56
99
  )}
57
100
  size="xl"
58
101
  >
59
- <img src={src} alt={alt} className="s-object-contain" />
102
+ <div className="s-flex s-flex-col">
103
+ <div className="s-flex s-justify-end">
104
+ {imageLoaded && (
105
+ <DownloadButton src={src} title={props.title} size="sm" />
106
+ )}
107
+ </div>
108
+ <div className="s-relative s-w-full">
109
+ <img
110
+ src={src}
111
+ alt={alt}
112
+ className="s-w-full s-object-contain"
113
+ onLoad={() => setImageLoaded(true)}
114
+ />
115
+ </div>
116
+ </div>
60
117
  </DialogContent>
61
118
  </Dialog>
62
119
  );
@@ -65,7 +122,7 @@ export function InteractiveImage({
65
122
  function LoadingImage() {
66
123
  return (
67
124
  <div className="s-flex s-h-full s-w-full s-items-center s-justify-center">
68
- <Spinner variant="dark" size="sm" />
125
+ <Spinner variant="dark" size="md" />
69
126
  </div>
70
127
  );
71
128
  }
@@ -81,25 +138,12 @@ function ImagePreview({
81
138
  src,
82
139
  title,
83
140
  }: ImagePreviewProps) {
84
- const handleDownload = React.useCallback(async () => {
85
- if (!src) {
86
- return;
87
- }
88
-
89
- // Create a hidden link and click it.
90
- const link = document.createElement("a");
91
- link.href = src;
92
- link.download = title;
93
- document.body.appendChild(link);
94
- link.click();
95
- document.body.removeChild(link);
96
- }, [src, title]);
97
-
98
141
  return (
99
142
  <div
100
143
  onClick={onClick}
101
144
  className={cn(
102
- "s-group/preview s-relative s-h-full s-w-full s-overflow-hidden s-rounded-2xl s-bg-muted-background dark:s-bg-muted-background-night",
145
+ "s-group/preview s-relative s-h-full s-w-full s-overflow-hidden s-rounded-2xl",
146
+ "s-bg-muted-background dark:s-bg-muted-background-night",
103
147
  !isLoading && "s-cursor-pointer"
104
148
  )}
105
149
  >
@@ -113,19 +157,23 @@ function ImagePreview({
113
157
  className="s-h-full s-w-full s-rounded-2xl s-object-cover"
114
158
  />
115
159
  {/* Dark overlay on hover */}
116
- <div className="s-absolute s-inset-0 s-bg-black s-opacity-0 s-transition-opacity s-duration-200 group-hover/preview:s-opacity-40" />
160
+ <div
161
+ className={cn(
162
+ "s-absolute s-inset-0 s-bg-gradient-to-b",
163
+ "s-from-black/40 s-via-transparent s-to-black/40",
164
+ "s-opacity-0 s-transition-opacity s-duration-200",
165
+ "group-hover/preview:s-opacity-100"
166
+ )}
167
+ />
117
168
  {/* Icon container - only visible on hover */}
118
- <div className="s-absolute s-right-3 s-top-3 s-z-10 s-flex s-opacity-0 s-transition-opacity s-duration-200 group-hover/preview:s-opacity-100">
119
- <IconButton
120
- icon={ArrowDownOnSquareIcon}
121
- className="s-text-white"
122
- tooltip="Download"
123
- size="xs"
124
- onClick={async (e) => {
125
- e.stopPropagation(); // Prevent image zoom.
126
- await handleDownload();
127
- }}
128
- />
169
+ <div
170
+ className={cn(
171
+ "s-absolute s-right-3 s-top-3 s-z-10 s-flex",
172
+ "s-opacity-0 s-transition-opacity s-duration-200",
173
+ "group-hover/preview:s-opacity-100"
174
+ )}
175
+ >
176
+ <DownloadButton src={src} title={title} size="xs" />
129
177
  </div>
130
178
  </>
131
179
  )}