@dmsi/wedgekit-react 0.0.369 → 0.0.371

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 (205) hide show
  1. package/dist/{chunk-RLLQRVM7.js → chunk-2H35FETR.js} +18 -10
  2. package/dist/chunk-2IKT6IHB.js +190 -0
  3. package/dist/chunk-4UNWXB4A.js +89 -0
  4. package/dist/chunk-5IFPG6TS.js +17 -0
  5. package/dist/{chunk-6GAYJCFE.js → chunk-6DPFKSCT.js} +1 -1
  6. package/dist/{chunk-ZFOANBWG.js → chunk-AG43RS4Q.js} +2 -1
  7. package/dist/chunk-AJ5M6MVX.js +7 -0
  8. package/dist/chunk-AT4AWD6B.js +44 -0
  9. package/dist/chunk-BQNPOGD5.js +105 -0
  10. package/dist/chunk-CQFPNZTN.js +172 -0
  11. package/dist/chunk-EJSPFQCY.js +29 -0
  12. package/dist/chunk-ER6RCOH3.js +97 -0
  13. package/dist/{chunk-4VER5OEU.js → chunk-FBE2HGEF.js} +35 -11
  14. package/dist/chunk-HPQWEZJL.js +45 -0
  15. package/dist/{chunk-URCLLHO5.js → chunk-IBX6DVHU.js} +376 -102
  16. package/dist/{chunk-I3WFZOFY.js → chunk-J5V2JRIK.js} +1 -1
  17. package/dist/chunk-JGJUVJKD.js +283 -0
  18. package/dist/chunk-KEMCFN4U.js +78 -0
  19. package/dist/chunk-M6TSTDNZ.js +22 -0
  20. package/dist/chunk-M7INAUAJ.js +140 -0
  21. package/dist/chunk-MBZ55T2D.js +51 -0
  22. package/dist/chunk-N6PNLLNS.js +77 -0
  23. package/dist/{chunk-ZA5E7ZYM.js → chunk-NXGUDYRR.js} +1 -1
  24. package/dist/chunk-P36QKH26.js +143 -0
  25. package/dist/chunk-PTRZHGHA.js +89 -0
  26. package/dist/chunk-QVWYTQKL.js +29 -0
  27. package/dist/{chunk-6CPGOW6J.js → chunk-T36HX6QY.js} +6 -4
  28. package/dist/chunk-U6PUOGG4.js +114 -0
  29. package/dist/{chunk-NQXZBWDZ.js → chunk-V6U7LU6M.js} +15 -6
  30. package/dist/chunk-VJVY6NPF.js +32 -0
  31. package/dist/chunk-VVXPGI2P.js +61 -0
  32. package/dist/{chunk-ARQBSR3I.js → chunk-YCKRVNJ3.js} +4 -4
  33. package/dist/chunk-YYHQLQDQ.js +68 -0
  34. package/dist/components/Accordion.cjs +47 -14
  35. package/dist/components/Accordion.js +2 -2
  36. package/dist/components/CalendarRange.cjs +700 -46
  37. package/dist/components/CalendarRange.css +186 -3
  38. package/dist/components/CalendarRange.js +43 -11
  39. package/dist/components/CompactImagesPreview.cjs +485 -0
  40. package/dist/components/CompactImagesPreview.js +13 -0
  41. package/dist/components/ContentTabs.cjs +3 -2
  42. package/dist/components/ContentTabs.js +3 -2
  43. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.cjs +4687 -0
  44. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.css +5051 -0
  45. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.js +62 -0
  46. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.cjs +4687 -0
  47. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.css +5051 -0
  48. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.js +62 -0
  49. package/dist/components/DataGrid/PinnedColumns.cjs +4687 -0
  50. package/dist/components/DataGrid/PinnedColumns.css +5051 -0
  51. package/dist/components/DataGrid/PinnedColumns.js +62 -0
  52. package/dist/components/DataGrid/TableBody/LoadingCell.cjs +4689 -0
  53. package/dist/components/DataGrid/TableBody/LoadingCell.css +5051 -0
  54. package/dist/components/DataGrid/TableBody/LoadingCell.js +62 -0
  55. package/dist/components/DataGrid/TableBody/TableBodyRow.cjs +4689 -0
  56. package/dist/components/DataGrid/TableBody/TableBodyRow.css +5051 -0
  57. package/dist/components/DataGrid/TableBody/TableBodyRow.js +62 -0
  58. package/dist/components/DataGrid/TableBody/index.cjs +4689 -0
  59. package/dist/components/DataGrid/TableBody/index.css +5051 -0
  60. package/dist/components/DataGrid/TableBody/index.js +62 -0
  61. package/dist/components/DataGrid/index.cjs +4692 -0
  62. package/dist/components/DataGrid/index.css +5051 -0
  63. package/dist/components/DataGrid/index.js +65 -0
  64. package/dist/components/DataGrid/utils.cjs +4687 -0
  65. package/dist/components/DataGrid/utils.css +5051 -0
  66. package/dist/components/DataGrid/utils.js +62 -0
  67. package/dist/components/DataGridCell.js +6 -6
  68. package/dist/components/DateInput.cjs +721 -67
  69. package/dist/components/DateInput.css +186 -3
  70. package/dist/components/DateInput.js +45 -13
  71. package/dist/components/DateRangeInput.cjs +721 -67
  72. package/dist/components/DateRangeInput.css +186 -3
  73. package/dist/components/DateRangeInput.js +45 -13
  74. package/dist/components/FilterGroup.js +3 -3
  75. package/dist/components/Grid.cjs +3 -1
  76. package/dist/components/Grid.js +3 -92
  77. package/dist/components/ImagePlaceholder.cjs +65 -0
  78. package/dist/components/ImagePlaceholder.js +7 -0
  79. package/dist/components/Input.js +2 -2
  80. package/dist/components/MenuOption.js +2 -2
  81. package/dist/components/MobileDataGrid/ColumnList.cjs +845 -0
  82. package/dist/components/MobileDataGrid/ColumnList.js +17 -0
  83. package/dist/components/MobileDataGrid/ColumnSelector/index.cjs +4797 -0
  84. package/dist/components/MobileDataGrid/ColumnSelector/index.css +5051 -0
  85. package/dist/components/MobileDataGrid/ColumnSelector/index.js +62 -0
  86. package/dist/components/MobileDataGrid/GridContextProvider/GridContext.cjs +31 -0
  87. package/dist/components/MobileDataGrid/GridContextProvider/GridContext.js +7 -0
  88. package/dist/components/MobileDataGrid/GridContextProvider/index.cjs +177 -0
  89. package/dist/components/MobileDataGrid/GridContextProvider/index.js +8 -0
  90. package/dist/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.cjs +269 -0
  91. package/dist/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.js +9 -0
  92. package/dist/components/MobileDataGrid/MobileDataGridCard/index.cjs +790 -0
  93. package/dist/components/MobileDataGrid/MobileDataGridCard/index.js +16 -0
  94. package/dist/components/MobileDataGrid/MobileDataGridHeader.cjs +5059 -0
  95. package/dist/components/MobileDataGrid/MobileDataGridHeader.css +5051 -0
  96. package/dist/components/MobileDataGrid/MobileDataGridHeader.js +62 -0
  97. package/dist/components/MobileDataGrid/RowDetailModalProvider/ModalContent.cjs +509 -0
  98. package/dist/components/MobileDataGrid/RowDetailModalProvider/ModalContent.js +13 -0
  99. package/dist/components/MobileDataGrid/RowDetailModalProvider/index.cjs +1261 -0
  100. package/dist/components/MobileDataGrid/RowDetailModalProvider/index.js +27 -0
  101. package/dist/components/MobileDataGrid/index.cjs +5521 -0
  102. package/dist/components/MobileDataGrid/index.css +5051 -0
  103. package/dist/components/MobileDataGrid/index.js +62 -0
  104. package/dist/components/Modal.cjs +24 -13
  105. package/dist/components/Modal.js +3 -3
  106. package/dist/components/ModalHeader.cjs +6 -4
  107. package/dist/components/ModalHeader.js +1 -1
  108. package/dist/components/ModalScrim.cjs +2 -1
  109. package/dist/components/ModalScrim.js +1 -1
  110. package/dist/components/NestedMenu.js +4 -4
  111. package/dist/components/Notification.cjs +15 -6
  112. package/dist/components/Notification.js +1 -1
  113. package/dist/components/PDFViewer/DownloadIcon.cjs +394 -0
  114. package/dist/components/PDFViewer/DownloadIcon.js +10 -0
  115. package/dist/components/PDFViewer/PDFElement.cjs +515 -0
  116. package/dist/components/PDFViewer/PDFElement.js +11 -0
  117. package/dist/components/{MobileDataGrid.cjs → PDFViewer/PDFNavigation.cjs} +318 -402
  118. package/dist/components/PDFViewer/PDFNavigation.js +13 -0
  119. package/dist/components/PDFViewer/PDFPage.cjs +56 -0
  120. package/dist/components/PDFViewer/PDFPage.js +7 -0
  121. package/dist/components/{PDFViewer.cjs → PDFViewer/index.cjs} +290 -202
  122. package/dist/components/PDFViewer/index.js +29 -0
  123. package/dist/components/Password.js +2 -2
  124. package/dist/components/ProductImagePreview/CarouselPagination.cjs +75 -0
  125. package/dist/components/ProductImagePreview/CarouselPagination.js +7 -0
  126. package/dist/components/ProductImagePreview/MobileImageCarousel.cjs +214 -0
  127. package/dist/components/ProductImagePreview/MobileImageCarousel.js +7 -0
  128. package/dist/components/ProductImagePreview/ProductPrimaryImage.cjs +255 -0
  129. package/dist/components/ProductImagePreview/ProductPrimaryImage.js +9 -0
  130. package/dist/components/ProductImagePreview/Thumbnail.cjs +105 -0
  131. package/dist/components/ProductImagePreview/Thumbnail.js +8 -0
  132. package/dist/components/ProductImagePreview/ZoomWindow.cjs +198 -0
  133. package/dist/components/ProductImagePreview/ZoomWindow.js +8 -0
  134. package/dist/components/ProductImagePreview/index.cjs +1369 -0
  135. package/dist/components/ProductImagePreview/index.js +22 -0
  136. package/dist/components/Search.js +3 -3
  137. package/dist/components/Select.js +3 -3
  138. package/dist/components/SideMenuGroup.cjs +15 -6
  139. package/dist/components/SideMenuGroup.js +1 -1
  140. package/dist/components/SideMenuItem.cjs +15 -6
  141. package/dist/components/SideMenuItem.js +1 -1
  142. package/dist/components/SkeletonParagraph.cjs +33 -0
  143. package/dist/components/SkeletonParagraph.js +10 -0
  144. package/dist/components/Stack.cjs +15 -6
  145. package/dist/components/Stack.js +1 -1
  146. package/dist/components/Stepper.cjs +61 -53
  147. package/dist/components/Stepper.js +63 -55
  148. package/dist/components/Surface.js +3 -39
  149. package/dist/components/Swatch.cjs +15 -6
  150. package/dist/components/Swatch.js +4 -4
  151. package/dist/components/Time.cjs +15 -6
  152. package/dist/components/Time.js +5 -5
  153. package/dist/components/Upload.cjs +15 -6
  154. package/dist/components/Upload.js +1 -1
  155. package/dist/components/index.cjs +2559 -14
  156. package/dist/components/index.css +186 -3
  157. package/dist/components/index.js +57 -14
  158. package/dist/index.css +186 -3
  159. package/package.json +1 -1
  160. package/src/components/Accordion.tsx +23 -4
  161. package/src/components/CompactImagesPreview.tsx +99 -0
  162. package/src/components/ContentTabs.tsx +3 -1
  163. package/src/components/DataGrid/types.ts +5 -0
  164. package/src/components/Grid.tsx +2 -0
  165. package/src/components/ImagePlaceholder.tsx +22 -0
  166. package/src/components/MobileDataGrid/ColumnList.tsx +66 -0
  167. package/src/components/MobileDataGrid/ColumnSelector/index.tsx +97 -0
  168. package/src/components/MobileDataGrid/GridContextProvider/GridContext.tsx +25 -0
  169. package/src/components/MobileDataGrid/GridContextProvider/index.tsx +132 -0
  170. package/src/components/MobileDataGrid/GridContextProvider/useGridContext.ts +10 -0
  171. package/src/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.tsx +20 -0
  172. package/src/components/MobileDataGrid/MobileDataGridCard/index.tsx +129 -0
  173. package/src/components/MobileDataGrid/MobileDataGridHeader.tsx +80 -0
  174. package/src/components/MobileDataGrid/RowDetailModalProvider/ModalContent.tsx +42 -0
  175. package/src/components/MobileDataGrid/RowDetailModalProvider/index.tsx +68 -0
  176. package/src/components/MobileDataGrid/dataGridReducer.ts +55 -0
  177. package/src/components/MobileDataGrid/index.tsx +92 -0
  178. package/src/components/MobileDataGrid/types.ts +4 -0
  179. package/src/components/Modal.tsx +31 -12
  180. package/src/components/ModalButtons.tsx +1 -1
  181. package/src/components/ModalHeader.tsx +5 -2
  182. package/src/components/ModalScrim.tsx +3 -2
  183. package/src/components/PDFViewer/DownloadIcon.tsx +22 -0
  184. package/src/components/PDFViewer/PDFElement.tsx +90 -0
  185. package/src/components/PDFViewer/PDFNavigation.tsx +68 -0
  186. package/src/components/PDFViewer/PDFPage.tsx +34 -0
  187. package/src/components/PDFViewer/index.tsx +128 -0
  188. package/src/components/ProductImagePreview/CarouselPagination.tsx +54 -0
  189. package/src/components/ProductImagePreview/MobileImageCarousel.tsx +226 -0
  190. package/src/components/ProductImagePreview/ProductPrimaryImage.tsx +218 -0
  191. package/src/components/ProductImagePreview/Thumbnail.tsx +49 -0
  192. package/src/components/ProductImagePreview/ZoomWindow.tsx +136 -0
  193. package/src/components/ProductImagePreview/index.tsx +182 -0
  194. package/src/components/ProductImagePreview/useProductImagePreview.ts +211 -0
  195. package/src/components/SkeletonParagraph.tsx +5 -0
  196. package/src/components/Stack.tsx +29 -6
  197. package/src/components/Stepper.tsx +5 -1
  198. package/src/components/index.ts +4 -0
  199. package/src/types.ts +2 -1
  200. package/dist/components/MobileDataGrid.js +0 -150
  201. package/dist/components/PDFViewer.js +0 -250
  202. package/src/components/MobileDataGrid.tsx +0 -163
  203. package/src/components/PDFViewer.tsx +0 -264
  204. package/dist/{chunk-OXSBIBGT.js → chunk-CKQNJNU3.js} +3 -3
  205. package/dist/{chunk-RJUN52HJ.js → chunk-ZL5X7KP6.js} +3 -3
@@ -0,0 +1,182 @@
1
+ import { Thumbnail } from "./Thumbnail";
2
+ import { Stack } from "../Stack";
3
+ import { Grid } from "../Grid";
4
+ import { ProductPrimaryImage } from "./ProductPrimaryImage";
5
+ import { ZoomWindow } from "./ZoomWindow";
6
+ import { CarouselPagination } from "./CarouselPagination";
7
+ import { MobileImageCarousel } from "./MobileImageCarousel";
8
+ import { useMatchesMobile } from "../../hooks";
9
+ import { useProductImagePreview } from "./useProductImagePreview";
10
+
11
+ export type ProductPreviewImage = {
12
+ src: string;
13
+ alt?: string;
14
+ };
15
+
16
+ export type ProductImagePreviewProps = {
17
+ width?: number;
18
+ height?: number;
19
+ images: ProductPreviewImage[];
20
+ currentIndex: number;
21
+ zoomEnabled?: boolean;
22
+ zoomLensSize?: number;
23
+ zoomFactor?: number;
24
+ zoomWindowScaleFactor?: number;
25
+ zoomWindowOffset?: number;
26
+ scrollToZoomEnabled?: boolean;
27
+ thumbsPerRow?: 8 | 5 | 2 | 4 | 1 | 3 | 6 | 7 | 9 | 10 | 11 | 12;
28
+ isMobile?: boolean; // Must be used for functionality only
29
+ onChangeIndex: (next: number) => void;
30
+ };
31
+
32
+ const PLACEHOLDER_IMAGES = [
33
+ { src: "", alt: "placeholder" },
34
+ { src: "", alt: "placeholder" },
35
+ ];
36
+ /** Product image gallery with primary image display, thumbnail navigation, and optional zoom functionality */
37
+ export function ProductImagePreview(props: ProductImagePreviewProps) {
38
+ const {
39
+ width = 483,
40
+ height = 483,
41
+ thumbsPerRow = 4,
42
+ zoomEnabled = false,
43
+ scrollToZoomEnabled = false,
44
+ images,
45
+ currentIndex,
46
+ onChangeIndex,
47
+ zoomLensSize,
48
+ zoomFactor = 2,
49
+ zoomWindowScaleFactor = 2.5,
50
+ zoomWindowOffset = 10,
51
+ } = props;
52
+
53
+ const isMobile = useMatchesMobile();
54
+
55
+ const {
56
+ zoomPoint,
57
+ zoomActive,
58
+ currentZoomFactor,
59
+ primaryImagePosition,
60
+ safeIndex,
61
+ active,
62
+ primaryImageRef,
63
+ handleSelect,
64
+ handleZoomPositionChange,
65
+ handleScrollZoom,
66
+ } = useProductImagePreview({
67
+ images,
68
+ currentIndex,
69
+ zoomEnabled,
70
+ zoomFactor,
71
+ scrollToZoomEnabled,
72
+ onChangeIndex,
73
+ isMobile,
74
+ });
75
+
76
+ if (typeof isMobile === "undefined") return null;
77
+
78
+ // Disable zoom on mobile
79
+ const effectiveZoomEnabled = zoomEnabled && !isMobile;
80
+
81
+ return (
82
+ <Stack sizing="layout" style={{ width, position: "relative" }}>
83
+ {/* Desktop layout - hidden on mobile */}
84
+ <div className="hidden md:block">
85
+ <div className="flex gap-4 items-start">
86
+ <div ref={primaryImageRef}>
87
+ <ProductPrimaryImage
88
+ image={active}
89
+ width={width}
90
+ height={height}
91
+ zoomEnabled={effectiveZoomEnabled}
92
+ zoomLensSize={zoomLensSize}
93
+ scrollToZoomEnabled={scrollToZoomEnabled && !isMobile}
94
+ onZoomPositionChange={handleZoomPositionChange}
95
+ onScrollZoom={handleScrollZoom}
96
+ isPlaceholder={images.length === 0}
97
+ />
98
+ </div>
99
+ {effectiveZoomEnabled && (
100
+ <ZoomWindow
101
+ image={active}
102
+ width={width}
103
+ height={height}
104
+ pointer={zoomPoint}
105
+ active={zoomActive}
106
+ zoomFactor={currentZoomFactor}
107
+ scaleFactor={zoomWindowScaleFactor}
108
+ primaryImagePosition={primaryImagePosition}
109
+ offset={zoomWindowOffset}
110
+ />
111
+ )}
112
+ </div>
113
+ </div>
114
+
115
+ {/* Mobile carousel - only visible on mobile */}
116
+ <MobileImageCarousel
117
+ images={images}
118
+ currentIndex={safeIndex}
119
+ width={width}
120
+ height={height}
121
+ onChangeIndex={handleSelect}
122
+ />
123
+
124
+ {/* Desktop thumbnail grid - hidden on mobile */}
125
+ <div className="hidden md:block">
126
+ {images.length <= 3 ? (
127
+ <div
128
+ className="flex justify-center gap-4"
129
+ style={{ width: "100%", maxWidth: width }}
130
+ aria-label="Product image thumbnails"
131
+ >
132
+ {(images.length === 0 ? PLACEHOLDER_IMAGES : images).map(
133
+ (img, i) => (
134
+ <div key={img.src + i} style={{ maxWidth: "115px" }}>
135
+ <Thumbnail
136
+ src={img.src}
137
+ alt={img.alt || `Thumbnail ${i + 1}`}
138
+ isActive={i === safeIndex}
139
+ onClick={() => handleSelect(i)}
140
+ isPlaceholder={images.length === 0}
141
+ />
142
+ </div>
143
+ ),
144
+ )}
145
+ </div>
146
+ ) : (
147
+ <Grid
148
+ sizing="layout-group"
149
+ aria-label="Product image thumbnails"
150
+ style={{
151
+ width: "100%",
152
+ maxWidth: width,
153
+ }}
154
+ columns={
155
+ thumbsPerRow > 12 ? 12 : thumbsPerRow < 1 ? 1 : thumbsPerRow
156
+ }
157
+ >
158
+ {(images.length === 0 ? PLACEHOLDER_IMAGES : images).map(
159
+ (img, i) => (
160
+ <Thumbnail
161
+ key={img.src + i}
162
+ src={img.src}
163
+ alt={img.alt || `Thumbnail ${i + 1}`}
164
+ isActive={i === safeIndex}
165
+ onClick={() => handleSelect(i)}
166
+ isPlaceholder={images.length === 0}
167
+ />
168
+ ),
169
+ )}
170
+ </Grid>
171
+ )}
172
+ </div>
173
+
174
+ {/* Mobile carousel pagination - only visible on mobile */}
175
+ <CarouselPagination
176
+ images={images}
177
+ currentIndex={safeIndex}
178
+ onSelect={handleSelect}
179
+ />
180
+ </Stack>
181
+ );
182
+ }
@@ -0,0 +1,211 @@
1
+ import { useCallback, useEffect, useRef, useState, useMemo } from "react";
2
+ import type { ProductPreviewImage } from ".";
3
+
4
+ export type UseProductImagePreviewProps = {
5
+ images: ProductPreviewImage[];
6
+ currentIndex: number;
7
+ zoomEnabled?: boolean;
8
+ zoomFactor?: number;
9
+ scrollToZoomEnabled?: boolean;
10
+ onChangeIndex: (next: number) => void;
11
+ isMobile?: boolean;
12
+ };
13
+
14
+ export type UseProductImagePreviewReturn = {
15
+ // State
16
+ zoomPoint: {
17
+ x: number;
18
+ y: number;
19
+ w: number;
20
+ h: number;
21
+ lensSize: number;
22
+ } | null;
23
+ zoomActive: boolean;
24
+ currentZoomFactor: number;
25
+ primaryImagePosition: DOMRect | null;
26
+ hasImages: boolean;
27
+ safeIndex: number;
28
+ active: ProductPreviewImage | undefined;
29
+
30
+ // Refs
31
+ primaryImageRef: React.RefObject<HTMLDivElement | null>;
32
+
33
+ // Handlers
34
+ handleSelect: (idx: number) => void;
35
+ handleZoomPositionChange: (
36
+ p: {
37
+ x: number;
38
+ y: number;
39
+ w: number;
40
+ h: number;
41
+ lensSize: number;
42
+ } | null,
43
+ active: boolean,
44
+ ) => void;
45
+ handleScrollZoom: (delta: number) => void;
46
+ handleNext: () => void;
47
+ handlePrevious: () => void;
48
+ };
49
+
50
+ /**
51
+ * Custom hook for managing product image preview logic including zoom, navigation, and mobile behavior
52
+ */
53
+ export function useProductImagePreview(
54
+ props: UseProductImagePreviewProps,
55
+ ): UseProductImagePreviewReturn {
56
+ const {
57
+ images,
58
+ currentIndex,
59
+ zoomEnabled = false,
60
+ zoomFactor = 2,
61
+ scrollToZoomEnabled = false,
62
+ onChangeIndex,
63
+ isMobile = false,
64
+ } = props;
65
+
66
+ // Derived state
67
+ const hasImages = !!images?.length;
68
+ const safeIndex =
69
+ hasImages && currentIndex >= 0 && currentIndex < images.length
70
+ ? currentIndex
71
+ : 0;
72
+
73
+ // Memoize active image to prevent unnecessary re-renders
74
+ const active = useMemo(() => {
75
+ return hasImages ? images[safeIndex] : undefined;
76
+ }, [hasImages, images, safeIndex]);
77
+
78
+ // Zoom state
79
+ const [zoomPoint, setZoomPoint] = useState<{
80
+ x: number;
81
+ y: number;
82
+ w: number;
83
+ h: number;
84
+ lensSize: number;
85
+ } | null>(null);
86
+ const [zoomActive, setZoomActive] = useState(false);
87
+ const [currentZoomFactor, setCurrentZoomFactor] = useState(zoomFactor);
88
+ const [primaryImagePosition, setPrimaryImagePosition] =
89
+ useState<DOMRect | null>(null);
90
+
91
+ // Refs
92
+ const primaryImageRef = useRef<HTMLDivElement>(null);
93
+ const cleanupRef = useRef<(() => void) | null>(null);
94
+
95
+ // Disable zoom functionality on mobile
96
+ const effectiveZoomEnabled = zoomEnabled && !isMobile;
97
+ const effectiveScrollToZoomEnabled = scrollToZoomEnabled && !isMobile;
98
+
99
+ // Track primary image position for zoom window
100
+ useEffect(() => {
101
+ if (!effectiveZoomEnabled) return;
102
+
103
+ const setupTracking = () => {
104
+ const element = primaryImageRef.current;
105
+ if (!element) return;
106
+
107
+ const updatePosition = () => {
108
+ if (element) {
109
+ setPrimaryImagePosition(element.getBoundingClientRect());
110
+ }
111
+ };
112
+
113
+ updatePosition();
114
+
115
+ const resizeObserver = new ResizeObserver(updatePosition);
116
+ resizeObserver.observe(element);
117
+
118
+ window.addEventListener("scroll", updatePosition);
119
+ window.addEventListener("resize", updatePosition);
120
+
121
+ cleanupRef.current = () => {
122
+ resizeObserver.disconnect();
123
+ window.removeEventListener("scroll", updatePosition);
124
+ window.removeEventListener("resize", updatePosition);
125
+ };
126
+ };
127
+
128
+ if (primaryImageRef.current) {
129
+ setupTracking();
130
+ } else {
131
+ const frameId = requestAnimationFrame(setupTracking);
132
+ return () => cancelAnimationFrame(frameId);
133
+ }
134
+
135
+ return () => {
136
+ if (cleanupRef.current) {
137
+ cleanupRef.current();
138
+ cleanupRef.current = null;
139
+ }
140
+ };
141
+ }, [effectiveZoomEnabled]);
142
+
143
+ // Navigation handlers
144
+ const handleSelect = useCallback(
145
+ (idx: number) => {
146
+ if (idx === safeIndex) return;
147
+ onChangeIndex(idx);
148
+ },
149
+ [safeIndex, onChangeIndex],
150
+ );
151
+
152
+ const handleNext = useCallback(() => {
153
+ if (!hasImages) return;
154
+ const nextIndex = (safeIndex + 1) % images.length;
155
+ onChangeIndex(nextIndex);
156
+ }, [hasImages, safeIndex, images.length, onChangeIndex]);
157
+
158
+ const handlePrevious = useCallback(() => {
159
+ if (!hasImages) return;
160
+ const previousIndex = safeIndex === 0 ? images.length - 1 : safeIndex - 1;
161
+ onChangeIndex(previousIndex);
162
+ }, [hasImages, safeIndex, images.length, onChangeIndex]);
163
+
164
+ // Zoom handlers
165
+ const handleZoomPositionChange = useCallback(
166
+ (p: typeof zoomPoint, active: boolean) => {
167
+ // Only allow zoom on non-mobile devices
168
+ if (isMobile) return;
169
+ setZoomPoint(p);
170
+ setZoomActive(active);
171
+ },
172
+ [isMobile],
173
+ );
174
+
175
+ const handleScrollZoom = useCallback(
176
+ (delta: number) => {
177
+ if (!effectiveScrollToZoomEnabled) return;
178
+
179
+ // Calculate new zoom factor with bounds (1x to 5x)
180
+ const newZoomFactor = Math.max(1, Math.min(5, currentZoomFactor + delta));
181
+ setCurrentZoomFactor(newZoomFactor);
182
+ },
183
+ [effectiveScrollToZoomEnabled, currentZoomFactor],
184
+ );
185
+
186
+ // Reset zoom factor when base zoom factor changes
187
+ useEffect(() => {
188
+ setCurrentZoomFactor(zoomFactor);
189
+ }, [zoomFactor]);
190
+
191
+ return {
192
+ // State
193
+ zoomPoint,
194
+ zoomActive,
195
+ currentZoomFactor,
196
+ primaryImagePosition,
197
+ hasImages,
198
+ safeIndex,
199
+ active,
200
+
201
+ // Refs
202
+ primaryImageRef,
203
+
204
+ // Handlers
205
+ handleSelect,
206
+ handleZoomPositionChange,
207
+ handleScrollZoom,
208
+ handleNext,
209
+ handlePrevious,
210
+ };
211
+ }
@@ -0,0 +1,5 @@
1
+ export function SkeletonParagraph() {
2
+ return (
3
+ <div className="h-[24px] bg-gradient-to-r from-neutral-100 to-[#f7f7f7] w-full rounded-xs min-w-32 "></div>
4
+ );
5
+ }
@@ -27,11 +27,11 @@ type StackProps = {
27
27
  rounded?: boolean;
28
28
  centered?: boolean;
29
29
  width?: number | "full" | "fit" | "max";
30
- maxWidth?: number;
30
+ maxWidth?: number | string;
31
31
  minWidth?: number;
32
32
  height?: string | number | "full";
33
- minHeight?: number;
34
- maxHeight?: number;
33
+ minHeight?: number | string;
34
+ maxHeight?: number | string;
35
35
  borderColor?: BorderColorTokens;
36
36
  backgroundColor?: BackgroundColorTokens;
37
37
  overflowY?: "hidden" | "scroll" | "auto" | "inherit";
@@ -39,6 +39,7 @@ type StackProps = {
39
39
  zIndex?: number;
40
40
  position?: CSSProperties["position"];
41
41
  top?: number;
42
+ bottom?: number;
42
43
  left?: number;
43
44
  id?: string;
44
45
  testid?: string;
@@ -123,6 +124,8 @@ export const Stack = ({
123
124
  marginTop,
124
125
  marginBottom,
125
126
  testid,
127
+ bottom,
128
+ zIndex,
126
129
  ...props
127
130
  }: StackProps) => {
128
131
  const flexClassNames = getFlexClassNames({ items, justify, grow });
@@ -140,9 +143,25 @@ export const Stack = ({
140
143
  : height !== undefined
141
144
  ? `${height}px`
142
145
  : undefined,
143
- maxHeight: maxHeight !== undefined ? `${maxHeight}px` : undefined,
144
- minHeight: minHeight !== undefined ? `${minHeight}px` : undefined,
145
- maxWidth: maxWidth !== undefined ? `${maxWidth}px` : undefined,
146
+ maxHeight:
147
+ maxHeight !== undefined
148
+ ? isNaN(+maxHeight)
149
+ ? maxHeight
150
+ : `${maxHeight}px`
151
+ : props.style?.maxHeight,
152
+ maxWidth:
153
+ maxWidth !== undefined
154
+ ? isNaN(+maxWidth)
155
+ ? maxWidth
156
+ : `${maxWidth}px`
157
+ : props.style?.maxWidth,
158
+ minHeight:
159
+ minHeight !== undefined
160
+ ? isNaN(+minHeight)
161
+ ? minHeight
162
+ : `${minHeight}px`
163
+ : props.style?.minHeight,
164
+
146
165
  width:
147
166
  width !== undefined && typeof width === "number"
148
167
  ? `${width}px`
@@ -158,7 +177,11 @@ export const Stack = ({
158
177
  flexShrink: flexShrink !== undefined ? flexShrink : undefined,
159
178
  position: position !== undefined ? position : undefined,
160
179
  top: top !== undefined ? `${top}px` : undefined,
180
+ bottom: bottom !== undefined ? `${bottom}px` : undefined,
161
181
  left: left !== undefined ? `${left}px` : undefined,
182
+ borderBlock: props.style?.borderBlock,
183
+ marginInline: props.style?.marginInline,
184
+ zIndex: zIndex !== undefined ? zIndex : undefined,
162
185
  }}
163
186
  className={clsx(
164
187
  "scrollbar-thin",
@@ -38,7 +38,11 @@ export const Stepper = ({
38
38
  }
39
39
 
40
40
  return (
41
- <div id={id} data-testid={testid} className={clsx("flex items-center", componentGap)}>
41
+ <div
42
+ id={id}
43
+ data-testid={testid}
44
+ className={clsx("flex items-center", componentGap)}
45
+ >
42
46
  <Button
43
47
  id={id ? `${id}-decrease-button` : undefined}
44
48
  testid={testid ? `${testid}-decrease-button` : undefined}
@@ -20,3 +20,7 @@ export { Tooltip } from "./Tooltip";
20
20
  export { Input } from "./Input";
21
21
  export { Accordion } from "./Accordion";
22
22
  export { Card } from "./Card";
23
+ export { MobileDataGrid } from "./MobileDataGrid";
24
+ export { ProductImagePreview } from "./ProductImagePreview";
25
+ export { CompactImagesPreview } from "./CompactImagesPreview";
26
+ export { PDFViewer } from "./PDFViewer";
package/src/types.ts CHANGED
@@ -126,7 +126,8 @@ export type BackgroundColorTokens =
126
126
  | "background-action-critical-secondary-normal"
127
127
  | "background-action-critical-secondary-hover"
128
128
  | "background-action-critical-secondary-active"
129
- | "background-action-critical-secondary-disabled";
129
+ | "background-action-critical-secondary-disabled"
130
+ | "background-brand-normal";
130
131
 
131
132
  export type TextAttributes = {
132
133
  color?: TextColorTokens;
@@ -1,150 +0,0 @@
1
- import {
2
- Theme
3
- } from "../chunk-EWGHVZL5.js";
4
- import {
5
- Heading3
6
- } from "../chunk-EU73QPW7.js";
7
- import {
8
- Stack
9
- } from "../chunk-NQXZBWDZ.js";
10
- import {
11
- Paragraph
12
- } from "../chunk-OGIFIPKH.js";
13
- import {
14
- Icon
15
- } from "../chunk-NKUETCDA.js";
16
- import {
17
- Button
18
- } from "../chunk-WWAPK5PH.js";
19
- import "../chunk-6CTCHYIS.js";
20
- import "../chunk-ORMEWXMH.js";
21
-
22
- // src/components/MobileDataGrid.tsx
23
- import clsx from "clsx";
24
- import { jsx, jsxs } from "react/jsx-runtime";
25
- function MobileDataGrid({
26
- columns,
27
- data,
28
- header,
29
- getId,
30
- renderLink,
31
- renderChevron,
32
- id,
33
- testid
34
- }) {
35
- return /* @__PURE__ */ jsxs(
36
- "div",
37
- {
38
- id,
39
- "data-testid": testid,
40
- className: clsx(
41
- "rounded",
42
- "overflow-hidden",
43
- "divide-y divide-border-primary-normal",
44
- "border border-border-primary-normal",
45
- "overflow-y-scroll scrollbar-thin"
46
- ),
47
- children: [
48
- /* @__PURE__ */ jsx(
49
- MobileDataGridHeader,
50
- {
51
- id: id ? `${id}-header` : void 0,
52
- testid: testid ? `${testid}-header` : void 0,
53
- header
54
- }
55
- ),
56
- data.map((item) => /* @__PURE__ */ jsx(
57
- MobileDataGridCard,
58
- {
59
- id: id ? `${id}-card-${getId(item)}` : void 0,
60
- testid: testid ? `${testid}-card-${getId(item)}` : void 0,
61
- data: item,
62
- columns,
63
- renderLink,
64
- renderChevron
65
- },
66
- getId(item)
67
- ))
68
- ]
69
- }
70
- );
71
- }
72
- function MobileDataGridHeader({
73
- header,
74
- id,
75
- testid
76
- }) {
77
- return /* @__PURE__ */ jsx("div", { id, "data-testid": testid, className: "sticky top-0", children: /* @__PURE__ */ jsx(Theme, { theme: "brand", children: /* @__PURE__ */ jsx(
78
- Stack,
79
- {
80
- horizontal: true,
81
- items: "start",
82
- justify: "center",
83
- backgroundColor: "background-primary-normal",
84
- padding: true,
85
- sizing: "component",
86
- children: /* @__PURE__ */ jsx(Heading3, { as: "span", color: "text-primary-normal", children: header })
87
- }
88
- ) }) });
89
- }
90
- function MobileDataGridCard({
91
- data,
92
- columns,
93
- renderLink,
94
- renderChevron,
95
- id,
96
- testid
97
- }) {
98
- return /* @__PURE__ */ jsxs("div", { id, "data-testid": testid, children: [
99
- /* @__PURE__ */ jsxs(Stack, { sizing: "component", padding: true, children: [
100
- /* @__PURE__ */ jsxs(Stack, { horizontal: true, horizontalMobile: true, items: "center", justify: "between", children: [
101
- renderLink && renderLink(data),
102
- /* @__PURE__ */ jsxs(Stack, { horizontal: true, horizontalMobile: true, items: "center", justify: "end", children: [
103
- /* @__PURE__ */ jsx(
104
- Button,
105
- {
106
- id: id ? `${id}-docs-button` : void 0,
107
- testid: testid ? `${testid}-docs-button` : void 0,
108
- iconOnly: true,
109
- variant: "tertiary",
110
- onClick: () => {
111
- },
112
- leftIcon: /* @__PURE__ */ jsx(Icon, { name: "docs" })
113
- }
114
- ),
115
- /* @__PURE__ */ jsx(
116
- Button,
117
- {
118
- id: id ? `${id}-swap-button` : void 0,
119
- testid: testid ? `${testid}-swap-button` : void 0,
120
- iconOnly: true,
121
- variant: "tertiary",
122
- onClick: () => {
123
- },
124
- leftIcon: /* @__PURE__ */ jsx(Icon, { name: "swap_vert" })
125
- }
126
- )
127
- ] })
128
- ] }),
129
- columns.filter((x) => x.show).map((column) => /* @__PURE__ */ jsxs(
130
- "div",
131
- {
132
- className: "mb-2 grid grid-cols-2",
133
- children: [
134
- /* @__PURE__ */ jsxs(Paragraph, { color: "text-secondary-normal", className: "text-left", children: [
135
- column.header,
136
- ":"
137
- ] }),
138
- " ",
139
- column.cell ? column.cell({ row: data }) : String(data[column.accessorKey])
140
- ]
141
- },
142
- String(column.accessorKey)
143
- ))
144
- ] }),
145
- renderChevron && /* @__PURE__ */ jsx(Stack, { items: "center", justify: "center", horizontal: true, horizontalMobile: true, children: renderChevron(data) })
146
- ] });
147
- }
148
- export {
149
- MobileDataGrid
150
- };