@dust-tt/sparkle 0.2.491 → 0.2.492
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 +1 -1
- package/dist/esm/components/Dialog.d.ts +5 -3
- package/dist/esm/components/Dialog.d.ts.map +1 -1
- package/dist/esm/components/Dialog.js +5 -4
- package/dist/esm/components/Dialog.js.map +1 -1
- package/dist/esm/components/InteractiveImageGrid.d.ts +4 -1
- package/dist/esm/components/InteractiveImageGrid.d.ts.map +1 -1
- package/dist/esm/components/InteractiveImageGrid.js +53 -63
- package/dist/esm/components/InteractiveImageGrid.js.map +1 -1
- package/dist/esm/stories/InteractiveImageGrid.stories.d.ts.map +1 -1
- package/dist/esm/stories/InteractiveImageGrid.stories.js +7 -1
- package/dist/esm/stories/InteractiveImageGrid.stories.js.map +1 -1
- package/dist/esm/stories/TourGuide.stories.d.ts.map +1 -1
- package/dist/esm/stories/TourGuide.stories.js +73 -28
- package/dist/esm/stories/TourGuide.stories.js.map +1 -1
- package/dist/sparkle.css +91 -15
- package/package.json +1 -1
- package/src/components/Dialog.tsx +16 -3
- package/src/components/InteractiveImageGrid.tsx +67 -70
- package/src/stories/InteractiveImageGrid.stories.tsx +8 -0
- package/src/stories/TourGuide.stories.tsx +345 -40
package/dist/sparkle.css
CHANGED
|
@@ -969,8 +969,8 @@ select {
|
|
|
969
969
|
bottom: 0.25rem;
|
|
970
970
|
}
|
|
971
971
|
|
|
972
|
-
.s-bottom-
|
|
973
|
-
bottom:
|
|
972
|
+
.s-bottom-3 {
|
|
973
|
+
bottom: 0.75rem;
|
|
974
974
|
}
|
|
975
975
|
|
|
976
976
|
.s-bottom-6 {
|
|
@@ -1029,10 +1029,6 @@ select {
|
|
|
1029
1029
|
right: 0.75rem;
|
|
1030
1030
|
}
|
|
1031
1031
|
|
|
1032
|
-
.s-right-4 {
|
|
1033
|
-
right: 1rem;
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
1032
|
.s-right-6 {
|
|
1037
1033
|
right: 1.5rem;
|
|
1038
1034
|
}
|
|
@@ -1061,10 +1057,6 @@ select {
|
|
|
1061
1057
|
top: 0.75rem;
|
|
1062
1058
|
}
|
|
1063
1059
|
|
|
1064
|
-
.s-top-4 {
|
|
1065
|
-
top: 1rem;
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
1060
|
.s-top-6 {
|
|
1069
1061
|
top: 1.5rem;
|
|
1070
1062
|
}
|
|
@@ -1435,10 +1427,18 @@ select {
|
|
|
1435
1427
|
height: 200px;
|
|
1436
1428
|
}
|
|
1437
1429
|
|
|
1430
|
+
.s-h-\[240px\] {
|
|
1431
|
+
height: 240px;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1438
1434
|
.s-h-\[30\%\] {
|
|
1439
1435
|
height: 30%;
|
|
1440
1436
|
}
|
|
1441
1437
|
|
|
1438
|
+
.s-h-\[32px\] {
|
|
1439
|
+
height: 32px;
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
1442
|
.s-h-\[340px\] {
|
|
1443
1443
|
height: 340px;
|
|
1444
1444
|
}
|
|
@@ -1668,6 +1668,10 @@ select {
|
|
|
1668
1668
|
width: 250px;
|
|
1669
1669
|
}
|
|
1670
1670
|
|
|
1671
|
+
.s-w-\[300px\] {
|
|
1672
|
+
width: 300px;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1671
1675
|
.s-w-\[350px\] {
|
|
1672
1676
|
width: 350px;
|
|
1673
1677
|
}
|
|
@@ -1676,6 +1680,10 @@ select {
|
|
|
1676
1680
|
width: 380px;
|
|
1677
1681
|
}
|
|
1678
1682
|
|
|
1683
|
+
.s-w-\[3px\] {
|
|
1684
|
+
width: 3px;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1679
1687
|
.s-w-\[420px\] {
|
|
1680
1688
|
width: 420px;
|
|
1681
1689
|
}
|
|
@@ -1738,10 +1746,6 @@ select {
|
|
|
1738
1746
|
min-width: 0px;
|
|
1739
1747
|
}
|
|
1740
1748
|
|
|
1741
|
-
.s-min-w-\[1024px\] {
|
|
1742
|
-
min-width: 1024px;
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
1749
|
.s-min-w-\[20px\] {
|
|
1746
1750
|
min-width: 20px;
|
|
1747
1751
|
}
|
|
@@ -1916,6 +1920,28 @@ select {
|
|
|
1916
1920
|
animation: s-breathing 3s infinite ease-in-out;
|
|
1917
1921
|
}
|
|
1918
1922
|
|
|
1923
|
+
@keyframes s-cursor-blink {
|
|
1924
|
+
0% {
|
|
1925
|
+
opacity: 1;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
60% {
|
|
1929
|
+
opacity: 1;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
70% {
|
|
1933
|
+
opacity: 0;
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
100% {
|
|
1937
|
+
opacity: 0;
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
.s-animate-cursor-blink {
|
|
1942
|
+
animation: s-cursor-blink 0.9s infinite;;
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1919
1945
|
@keyframes s-pulse {
|
|
1920
1946
|
50% {
|
|
1921
1947
|
opacity: .5;
|
|
@@ -2040,6 +2066,10 @@ select {
|
|
|
2040
2066
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
2041
2067
|
}
|
|
2042
2068
|
|
|
2069
|
+
.s-grid-cols-6 {
|
|
2070
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2043
2073
|
.s-grid-cols-8 {
|
|
2044
2074
|
grid-template-columns: repeat(8, minmax(0, 1fr));
|
|
2045
2075
|
}
|
|
@@ -2368,6 +2398,10 @@ select {
|
|
|
2368
2398
|
border-radius: 0.375rem;
|
|
2369
2399
|
}
|
|
2370
2400
|
|
|
2401
|
+
.s-rounded-none {
|
|
2402
|
+
border-radius: 0px;
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2371
2405
|
.s-rounded-sm {
|
|
2372
2406
|
border-radius: 0.125rem;
|
|
2373
2407
|
}
|
|
@@ -2390,6 +2424,10 @@ select {
|
|
|
2390
2424
|
border-width: 1px;
|
|
2391
2425
|
}
|
|
2392
2426
|
|
|
2427
|
+
.s-border-0 {
|
|
2428
|
+
border-width: 0px;
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2393
2431
|
.s-border-b {
|
|
2394
2432
|
border-bottom-width: 1px;
|
|
2395
2433
|
}
|
|
@@ -2822,6 +2860,11 @@ select {
|
|
|
2822
2860
|
background-color: rgb(233 247 255 / var(--tw-bg-opacity));
|
|
2823
2861
|
}
|
|
2824
2862
|
|
|
2863
|
+
.s-bg-brand-support-golden {
|
|
2864
|
+
--tw-bg-opacity: 1;
|
|
2865
|
+
background-color: rgb(255 250 224 / var(--tw-bg-opacity));
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2825
2868
|
.s-bg-brand-support-green {
|
|
2826
2869
|
--tw-bg-opacity: 1;
|
|
2827
2870
|
background-color: rgb(254 255 240 / var(--tw-bg-opacity));
|
|
@@ -2892,6 +2935,11 @@ select {
|
|
|
2892
2935
|
background-color: rgb(4 20 10 / var(--tw-bg-opacity));
|
|
2893
2936
|
}
|
|
2894
2937
|
|
|
2938
|
+
.s-bg-foreground {
|
|
2939
|
+
--tw-bg-opacity: 1;
|
|
2940
|
+
background-color: rgb(17 20 24 / var(--tw-bg-opacity));
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2895
2943
|
.s-bg-golden-100 {
|
|
2896
2944
|
--tw-bg-opacity: 1;
|
|
2897
2945
|
background-color: rgb(255 239 168 / var(--tw-bg-opacity));
|
|
@@ -4251,6 +4299,10 @@ select {
|
|
|
4251
4299
|
padding-right: 0.75rem;
|
|
4252
4300
|
}
|
|
4253
4301
|
|
|
4302
|
+
.s-pr-5 {
|
|
4303
|
+
padding-right: 1.25rem;
|
|
4304
|
+
}
|
|
4305
|
+
|
|
4254
4306
|
.s-pr-8 {
|
|
4255
4307
|
padding-right: 2rem;
|
|
4256
4308
|
}
|
|
@@ -4990,6 +5042,12 @@ select {
|
|
|
4990
5042
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
4991
5043
|
}
|
|
4992
5044
|
|
|
5045
|
+
.s-shadow-none {
|
|
5046
|
+
--tw-shadow: 0 0 #0000;
|
|
5047
|
+
--tw-shadow-colored: 0 0 #0000;
|
|
5048
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
5049
|
+
}
|
|
5050
|
+
|
|
4993
5051
|
.s-shadow-sm {
|
|
4994
5052
|
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
4995
5053
|
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
|
@@ -5007,6 +5065,12 @@ select {
|
|
|
5007
5065
|
outline-offset: 2px;
|
|
5008
5066
|
}
|
|
5009
5067
|
|
|
5068
|
+
.s-ring-0 {
|
|
5069
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
5070
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
5071
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
5072
|
+
}
|
|
5073
|
+
|
|
5010
5074
|
.s-ring-2 {
|
|
5011
5075
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
5012
5076
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
@@ -5249,10 +5313,14 @@ select {
|
|
|
5249
5313
|
opacity: 1;
|
|
5250
5314
|
}
|
|
5251
5315
|
|
|
5252
|
-
|
|
5316
|
+
60% {
|
|
5253
5317
|
opacity: 1;
|
|
5254
5318
|
}
|
|
5255
5319
|
|
|
5320
|
+
70% {
|
|
5321
|
+
opacity: 0;
|
|
5322
|
+
}
|
|
5323
|
+
|
|
5256
5324
|
100% {
|
|
5257
5325
|
opacity: 0;
|
|
5258
5326
|
}
|
|
@@ -8597,10 +8665,18 @@ select {
|
|
|
8597
8665
|
}
|
|
8598
8666
|
|
|
8599
8667
|
@media (min-width: 640px) {
|
|
8668
|
+
.sm\:s-h-full {
|
|
8669
|
+
height: 100%;
|
|
8670
|
+
}
|
|
8671
|
+
|
|
8600
8672
|
.sm\:s-max-w-3xl {
|
|
8601
8673
|
max-width: 48rem;
|
|
8602
8674
|
}
|
|
8603
8675
|
|
|
8676
|
+
.sm\:s-max-w-full {
|
|
8677
|
+
max-width: 100%;
|
|
8678
|
+
}
|
|
8679
|
+
|
|
8604
8680
|
.sm\:s-max-w-md {
|
|
8605
8681
|
max-width: 28rem;
|
|
8606
8682
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,13 @@ import { FocusScope } from "@radix-ui/react-focus-scope";
|
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Button,
|
|
9
|
+
ButtonProps,
|
|
10
|
+
Checkbox,
|
|
11
|
+
Label,
|
|
12
|
+
ScrollArea,
|
|
13
|
+
} from "@sparkle/components";
|
|
8
14
|
import { XMarkIcon } from "@sparkle/icons/app";
|
|
9
15
|
import { cn } from "@sparkle/lib/utils";
|
|
10
16
|
|
|
@@ -29,13 +35,14 @@ const DialogOverlay = React.forwardRef<
|
|
|
29
35
|
));
|
|
30
36
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
31
37
|
|
|
32
|
-
const DIALOG_SIZES = ["md", "lg", "xl"] as const;
|
|
38
|
+
const DIALOG_SIZES = ["md", "lg", "xl", "full"] as const;
|
|
33
39
|
type DialogSizeType = (typeof DIALOG_SIZES)[number];
|
|
34
40
|
|
|
35
41
|
const sizeClasses: Record<DialogSizeType, string> = {
|
|
36
42
|
md: "sm:s-max-w-md",
|
|
37
43
|
lg: "sm:s-max-w-xl",
|
|
38
44
|
xl: "sm:s-max-w-3xl",
|
|
45
|
+
full: "sm:s-max-w-full sm:s-h-full",
|
|
39
46
|
};
|
|
40
47
|
|
|
41
48
|
const dialogVariants = cva(
|
|
@@ -90,12 +97,16 @@ const DialogContent = React.forwardRef<
|
|
|
90
97
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
91
98
|
|
|
92
99
|
interface NewDialogHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
100
|
+
buttonSize?: ButtonProps["size"];
|
|
101
|
+
buttonVariant?: ButtonProps["variant"];
|
|
93
102
|
hideButton?: boolean;
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
const DialogHeader = ({
|
|
97
106
|
className,
|
|
98
107
|
children,
|
|
108
|
+
buttonSize = "mini",
|
|
109
|
+
buttonVariant = "ghost",
|
|
99
110
|
hideButton = false,
|
|
100
111
|
...props
|
|
101
112
|
}: NewDialogHeaderProps) => (
|
|
@@ -108,7 +119,9 @@ const DialogHeader = ({
|
|
|
108
119
|
>
|
|
109
120
|
{children}
|
|
110
121
|
<DialogClose asChild className="s-absolute s-right-3 s-top-3">
|
|
111
|
-
{!hideButton &&
|
|
122
|
+
{!hideButton && (
|
|
123
|
+
<Button icon={XMarkIcon} variant={buttonVariant} size={buttonSize} />
|
|
124
|
+
)}
|
|
112
125
|
</DialogClose>
|
|
113
126
|
</div>
|
|
114
127
|
);
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Dialog,
|
|
6
|
+
DialogContent,
|
|
7
|
+
DialogHeader,
|
|
8
|
+
DialogTrigger,
|
|
9
|
+
Spinner,
|
|
10
|
+
} from "@sparkle/components/";
|
|
4
11
|
import {
|
|
5
12
|
ArrowDownOnSquareIcon,
|
|
6
13
|
ChevronLeftIcon,
|
|
7
14
|
ChevronRightIcon,
|
|
8
|
-
XMarkIcon,
|
|
9
15
|
} from "@sparkle/icons/app";
|
|
10
16
|
import { cn } from "@sparkle/lib/utils";
|
|
11
17
|
|
|
@@ -53,7 +59,7 @@ const ImagePreview = React.forwardRef<HTMLDivElement, ImagePreviewProps>(
|
|
|
53
59
|
ref={ref}
|
|
54
60
|
onClick={onClick}
|
|
55
61
|
className={cn(
|
|
56
|
-
"s-group/preview s-relative",
|
|
62
|
+
"s-group/preview s-relative s-aspect-square",
|
|
57
63
|
"s-cursor-pointer s-overflow-hidden s-rounded-2xl",
|
|
58
64
|
"s-bg-muted-background dark:s-bg-muted-background-night"
|
|
59
65
|
)}
|
|
@@ -113,14 +119,13 @@ interface InteractiveImageGridProps {
|
|
|
113
119
|
}[];
|
|
114
120
|
}
|
|
115
121
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
function InteractiveImageGrid({
|
|
123
|
+
className,
|
|
124
|
+
images,
|
|
125
|
+
}: InteractiveImageGridProps) {
|
|
120
126
|
const [currentImageIndex, setCurrentImageIndex] = React.useState<
|
|
121
127
|
number | null
|
|
122
128
|
>(null);
|
|
123
|
-
const [isZoomed, setIsZoomed] = React.useState(false);
|
|
124
129
|
const [imageLoaded, setImageLoaded] = React.useState(false);
|
|
125
130
|
|
|
126
131
|
const handleNext = React.useCallback(() => {
|
|
@@ -157,7 +162,7 @@ const InteractiveImageGrid = React.forwardRef<
|
|
|
157
162
|
);
|
|
158
163
|
|
|
159
164
|
React.useEffect(() => {
|
|
160
|
-
if (
|
|
165
|
+
if (currentImageIndex === null) {
|
|
161
166
|
return;
|
|
162
167
|
}
|
|
163
168
|
|
|
@@ -167,72 +172,64 @@ const InteractiveImageGrid = React.forwardRef<
|
|
|
167
172
|
handleNext();
|
|
168
173
|
} else if (e.key === "ArrowLeft") {
|
|
169
174
|
handlePrevious();
|
|
170
|
-
} else if (e.key === "Escape") {
|
|
171
|
-
setIsZoomed(false);
|
|
172
|
-
setCurrentImageIndex(null);
|
|
173
175
|
}
|
|
174
176
|
};
|
|
175
177
|
|
|
176
178
|
window.addEventListener("keydown", handleKeyDown);
|
|
177
179
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
178
|
-
}, [
|
|
180
|
+
}, [currentImageIndex, handleNext, handlePrevious]);
|
|
179
181
|
|
|
180
182
|
return (
|
|
181
|
-
<
|
|
182
|
-
{
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
e.stopPropagation();
|
|
192
|
-
await handleDownload(images[0].downloadUrl, images[0].title);
|
|
193
|
-
}}
|
|
194
|
-
/>
|
|
195
|
-
</div>
|
|
196
|
-
) : (
|
|
197
|
-
<div className="s-grid s-grid-cols-2 s-gap-2 @xxs:s-grid-cols-3 @xs:s-grid-cols-4">
|
|
198
|
-
{images.map((image, idx) => (
|
|
199
|
-
<ImagePreview
|
|
200
|
-
key={idx}
|
|
201
|
-
image={image}
|
|
202
|
-
onClick={() => {
|
|
203
|
-
setCurrentImageIndex(idx);
|
|
204
|
-
setIsZoomed(true);
|
|
205
|
-
}}
|
|
206
|
-
onDownload={async (e) => {
|
|
207
|
-
e.stopPropagation();
|
|
208
|
-
await handleDownload(image.downloadUrl, image.title);
|
|
209
|
-
}}
|
|
210
|
-
/>
|
|
211
|
-
))}
|
|
212
|
-
</div>
|
|
213
|
-
)}
|
|
214
|
-
|
|
215
|
-
{isZoomed && currentImageIndex !== null && (
|
|
216
|
-
<div
|
|
217
|
-
className={cn(
|
|
218
|
-
"s-fixed s-inset-0 s-z-50 s-flex s-items-center s-justify-center",
|
|
219
|
-
"s-bg-white/95 dark:s-bg-gray-900/95"
|
|
220
|
-
)}
|
|
221
|
-
>
|
|
222
|
-
<div className="s-relative s-flex s-h-full s-w-full s-flex-col">
|
|
223
|
-
{/* Top bar */}
|
|
224
|
-
<div className="s-absolute s-right-4 s-top-4 s-z-10 s-flex s-gap-2">
|
|
225
|
-
<Button
|
|
226
|
-
variant="outline"
|
|
227
|
-
size="md"
|
|
228
|
-
icon={XMarkIcon}
|
|
229
|
-
tooltip="Close"
|
|
183
|
+
<Dialog
|
|
184
|
+
open={currentImageIndex !== null}
|
|
185
|
+
onOpenChange={(open) => !open && setCurrentImageIndex(null)}
|
|
186
|
+
>
|
|
187
|
+
<DialogTrigger asChild>
|
|
188
|
+
<div className={cn("s-@container", className)}>
|
|
189
|
+
{images.length === 1 ? (
|
|
190
|
+
<div className="s-h-80 s-w-80">
|
|
191
|
+
<ImagePreview
|
|
192
|
+
image={images[0]}
|
|
230
193
|
onClick={() => {
|
|
231
|
-
|
|
232
|
-
|
|
194
|
+
setCurrentImageIndex(0);
|
|
195
|
+
}}
|
|
196
|
+
onDownload={async (e) => {
|
|
197
|
+
e.stopPropagation();
|
|
198
|
+
await handleDownload(images[0].downloadUrl, images[0].title);
|
|
233
199
|
}}
|
|
234
200
|
/>
|
|
235
201
|
</div>
|
|
202
|
+
) : (
|
|
203
|
+
<div className="s-grid s-grid-cols-2 s-gap-2 @xxs:s-grid-cols-3 @xs:s-grid-cols-4">
|
|
204
|
+
{images.map((image, idx) => (
|
|
205
|
+
<ImagePreview
|
|
206
|
+
key={idx}
|
|
207
|
+
image={image}
|
|
208
|
+
onClick={() => {
|
|
209
|
+
setCurrentImageIndex(idx);
|
|
210
|
+
}}
|
|
211
|
+
onDownload={async (e) => {
|
|
212
|
+
e.stopPropagation();
|
|
213
|
+
await handleDownload(image.downloadUrl, image.title);
|
|
214
|
+
}}
|
|
215
|
+
/>
|
|
216
|
+
))}
|
|
217
|
+
</div>
|
|
218
|
+
)}
|
|
219
|
+
</div>
|
|
220
|
+
</DialogTrigger>
|
|
221
|
+
<DialogContent
|
|
222
|
+
size="full"
|
|
223
|
+
className="s-rounded-none s-border-0 s-bg-white/95 s-p-0 s-shadow-none s-outline-none s-ring-0 dark:s-bg-gray-900/95"
|
|
224
|
+
>
|
|
225
|
+
{currentImageIndex !== null && (
|
|
226
|
+
<div className="s-relative s-flex s-h-full s-w-full s-flex-col">
|
|
227
|
+
{/* Top bar */}
|
|
228
|
+
<DialogHeader
|
|
229
|
+
buttonVariant="outline"
|
|
230
|
+
buttonSize="md"
|
|
231
|
+
className="s-h-6"
|
|
232
|
+
/>
|
|
236
233
|
|
|
237
234
|
{/* Main content */}
|
|
238
235
|
<div className="s-flex s-flex-1 s-items-center s-justify-center">
|
|
@@ -255,7 +252,7 @@ const InteractiveImageGrid = React.forwardRef<
|
|
|
255
252
|
src={images[currentImageIndex].imageUrl}
|
|
256
253
|
alt={images[currentImageIndex].alt}
|
|
257
254
|
className={cn(
|
|
258
|
-
"s-max-h-[90vh] s-min-h-[50vh] s-w-auto s-min-w-[
|
|
255
|
+
"s-max-h-[90vh] s-min-h-[50vh] s-w-auto s-min-w-[50vh]",
|
|
259
256
|
"s-checkerboard s-object-contain"
|
|
260
257
|
)}
|
|
261
258
|
onLoad={() => setImageLoaded(true)}
|
|
@@ -279,7 +276,7 @@ const InteractiveImageGrid = React.forwardRef<
|
|
|
279
276
|
{!images[currentImageIndex].isLoading && (
|
|
280
277
|
<>
|
|
281
278
|
{imageLoaded ? (
|
|
282
|
-
<div className="s-absolute s-bottom-
|
|
279
|
+
<div className="s-absolute s-bottom-3 s-right-3 s-z-10">
|
|
283
280
|
<Button
|
|
284
281
|
variant="outline"
|
|
285
282
|
size="md"
|
|
@@ -299,11 +296,11 @@ const InteractiveImageGrid = React.forwardRef<
|
|
|
299
296
|
</>
|
|
300
297
|
)}
|
|
301
298
|
</div>
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
</
|
|
299
|
+
)}
|
|
300
|
+
</DialogContent>
|
|
301
|
+
</Dialog>
|
|
305
302
|
);
|
|
306
|
-
}
|
|
303
|
+
}
|
|
307
304
|
|
|
308
305
|
InteractiveImageGrid.displayName = "InteractiveImageGrid";
|
|
309
306
|
|
|
@@ -62,9 +62,17 @@ export const InteractiveImageExample = () => (
|
|
|
62
62
|
<h2>Interactive Image Grid</h2>
|
|
63
63
|
<InteractiveImageGrid images={images} />
|
|
64
64
|
</div>
|
|
65
|
+
<div className="s-w-[300px]">
|
|
66
|
+
<h2>Interactive Image Grid with small width</h2>
|
|
67
|
+
<InteractiveImageGrid images={images} />
|
|
68
|
+
</div>
|
|
65
69
|
<div className="s-w-[700px]">
|
|
66
70
|
<h2>Interactive Image Grid with 1 image</h2>
|
|
67
71
|
<InteractiveImageGrid images={images.slice(1, 2)} />
|
|
68
72
|
</div>
|
|
73
|
+
<div className="s-w-[700px]">
|
|
74
|
+
<h2>Interactive Image Grid with 1 image (loading)</h2>
|
|
75
|
+
<InteractiveImageGrid images={images.slice(0, 1)} />
|
|
76
|
+
</div>
|
|
69
77
|
</div>
|
|
70
78
|
);
|