@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,1369 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __objRest = (source, exclude) => {
26
+ var target = {};
27
+ for (var prop in source)
28
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
29
+ target[prop] = source[prop];
30
+ if (source != null && __getOwnPropSymbols)
31
+ for (var prop of __getOwnPropSymbols(source)) {
32
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
33
+ target[prop] = source[prop];
34
+ }
35
+ return target;
36
+ };
37
+ var __export = (target, all) => {
38
+ for (var name in all)
39
+ __defProp(target, name, { get: all[name], enumerable: true });
40
+ };
41
+ var __copyProps = (to, from, except, desc) => {
42
+ if (from && typeof from === "object" || typeof from === "function") {
43
+ for (let key of __getOwnPropNames(from))
44
+ if (!__hasOwnProp.call(to, key) && key !== except)
45
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
46
+ }
47
+ return to;
48
+ };
49
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
50
+ // If the importer is in node compatibility mode or this is not an ESM
51
+ // file that has been converted to a CommonJS file using a Babel-
52
+ // compatible transform (i.e. "__esModule" has not been set), then set
53
+ // "default" to the CommonJS "module.exports" for node compatibility.
54
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
55
+ mod
56
+ ));
57
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
58
+
59
+ // src/components/ProductImagePreview/index.tsx
60
+ var ProductImagePreview_exports = {};
61
+ __export(ProductImagePreview_exports, {
62
+ ProductImagePreview: () => ProductImagePreview
63
+ });
64
+ module.exports = __toCommonJS(ProductImagePreview_exports);
65
+
66
+ // src/components/ImagePlaceholder.tsx
67
+ var import_react = require("react");
68
+ var import_jsx_runtime = require("react/jsx-runtime");
69
+ function ImagePlaceholder(props) {
70
+ const clipId = (0, import_react.useId)();
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
72
+ "svg",
73
+ __spreadProps(__spreadValues({
74
+ xmlns: "http://www.w3.org/2000/svg",
75
+ width: 242,
76
+ height: 243,
77
+ fill: "none"
78
+ }, props), {
79
+ children: [
80
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: props.width, height: props.width, fill: "#F7F7F7", rx: 2 }) }),
81
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("clipPath", { id: clipId, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: props.width, height: props.width, fill: "#fff", rx: 2 }) }) })
82
+ ]
83
+ })
84
+ );
85
+ }
86
+
87
+ // src/components/ProductImagePreview/Thumbnail.tsx
88
+ var import_jsx_runtime2 = require("react/jsx-runtime");
89
+ function Thumbnail({
90
+ width,
91
+ height,
92
+ src,
93
+ alt,
94
+ isActive,
95
+ onClick,
96
+ isPlaceholder = false
97
+ }) {
98
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
99
+ "button",
100
+ {
101
+ type: "button",
102
+ onClick,
103
+ className: [
104
+ "cursor-pointer relative overflow-hidden rounded aspect-square w-full",
105
+ // base radius, square when no explicit size
106
+ "focus:outline-none",
107
+ isActive && !isPlaceholder && "ring-[3px] ring-offset-1 ring-border-action-normal ring-offset-white opacity-70"
108
+ ].join(" "),
109
+ style: { maxWidth: width, maxHeight: height, aspectRatio: "1 / 1" },
110
+ "aria-pressed": isActive && !isPlaceholder ? "true" : "false",
111
+ children: isPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ImagePlaceholder, { width: 115, height: 115 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
112
+ "img",
113
+ {
114
+ src,
115
+ alt,
116
+ className: "object-cover w-full h-full select-none",
117
+ draggable: false,
118
+ loading: "lazy"
119
+ }
120
+ )
121
+ }
122
+ );
123
+ }
124
+
125
+ // src/components/Stack.tsx
126
+ var import_clsx2 = __toESM(require("clsx"), 1);
127
+
128
+ // src/classNames.ts
129
+ var import_clsx = __toESM(require("clsx"), 1);
130
+ var typography = {
131
+ display1: (0, import_clsx.default)(
132
+ "font-sans font-semibold",
133
+ "text-display-1-mobile desktop:text-display-1-desktop compact:text-display-1-desktop-compact",
134
+ "leading-display-1-mobile desktop:leading-display-1-desktop"
135
+ ),
136
+ display2: (0, import_clsx.default)(
137
+ "font-sans font-bold",
138
+ "text-display-2-mobile desktop:text-display-2-desktop compact:text-display-2-desktop-compact",
139
+ "leading-display-2-mobile desktop:leading-display-2-desktop"
140
+ ),
141
+ heading1: (0, import_clsx.default)(
142
+ "font-sans font-semibold",
143
+ "text-heading-1-mobile desktop:text-heading-1-desktop compact:text-heading-1-desktop-compact",
144
+ "leading-heading-1-mobile desktop:leading-heading-1-desktop"
145
+ ),
146
+ heading2: (0, import_clsx.default)(
147
+ "font-sans font-normal",
148
+ "text-heading-2-mobile desktop:text-heading-2-desktop compact:text-heading-2-desktop-compact",
149
+ "leading-heading-2-mobile desktop:leading-heading-2-desktop"
150
+ ),
151
+ heading3: (0, import_clsx.default)(
152
+ "font-sans font-semibold",
153
+ "text-heading-3-mobile desktop:text-heading-3-desktop compact:text-heading-3-desktop-compact",
154
+ "leading-heading-3-mobile desktop:leading-heading-3-desktop"
155
+ ),
156
+ subheader: (0, import_clsx.default)(
157
+ "font-sans font-semibold",
158
+ "text-subheader-mobile desktop:text-subheader-desktop compact:text-subheader-desktop-compact",
159
+ "leading-subheader-mobile desktop:leading-subheader-desktop"
160
+ ),
161
+ link: (0, import_clsx.default)(
162
+ "font-sans font-normal",
163
+ "text-link-mobile desktop:text-link-desktop compact:text-link-desktop-compact",
164
+ "leading-link-mobile desktop:leading-link-desktop"
165
+ ),
166
+ buttonLabel: (0, import_clsx.default)(
167
+ "font-sans font-semibold",
168
+ "text-label-mobile desktop:text-label-desktop compact:text-label-desktop-compact",
169
+ "leading-label-mobile desktop:leading-label-desktop"
170
+ ),
171
+ label: (0, import_clsx.default)(
172
+ "font-sans font-semibold",
173
+ "text-label-mobile desktop:text-label-desktop compact:text-label-desktop-compact",
174
+ "leading-label-mobile desktop:leading-label-desktop"
175
+ ),
176
+ paragraph: (0, import_clsx.default)(
177
+ "font-sans font-normal",
178
+ "text-paragraph-mobile desktop:text-paragraph-desktop compact:text-paragraph-desktop-compact",
179
+ "leading-paragraph-mobile desktop:leading-paragraph-desktop"
180
+ ),
181
+ caption: (0, import_clsx.default)(
182
+ "font-sans font-normal",
183
+ "text-caption-mobile desktop:text-caption-desktop compact:text-caption-desktop-compact",
184
+ "leading-caption-mobile desktop:leading-caption-desktop"
185
+ ),
186
+ breadcrumb: (0, import_clsx.default)(
187
+ "font-sans font-normal",
188
+ "text-paragraph-mobile desktop:text-paragraph-desktop compact:text-paragraph-desktop-compact",
189
+ "leading-mobile-breadcrumb desktop:leading-desktop-breadcrumb"
190
+ )
191
+ };
192
+ var baseTransition = (0, import_clsx.default)(
193
+ "transition-colors duration-100 ease-in-out"
194
+ );
195
+ var componentGap = (0, import_clsx.default)(
196
+ "gap-mobile-component-gap desktop:gap-desktop-component-gap compact:gap-desktop-compact-component-gap"
197
+ );
198
+ var paddingUsingComponentGap = (0, import_clsx.default)(
199
+ "p-mobile-component-gap desktop:p-desktop-component-gap compact:p-desktop-compact-component-gap"
200
+ );
201
+ var paddingXUsingLayoutGroupGap = (0, import_clsx.default)(
202
+ "px-mobile-layout-group-gap desktop:px-desktop-layout-group-gap compact:px-desktop-compact-layout-group-gap"
203
+ );
204
+ var paddingYUsingLayoutGroupGap = (0, import_clsx.default)(
205
+ "py-mobile-layout-group-gap desktop:py-desktop-layout-group-gap compact:py-desktop-compact-layout-group-gap"
206
+ );
207
+ var componentPadding = (0, import_clsx.default)(
208
+ "p-mobile-component-padding desktop:p-desktop-component-padding compact:p-desktop-compact-component-padding"
209
+ );
210
+ var componentPaddingBottom = (0, import_clsx.default)(
211
+ "pb-mobile-component-padding desktop:pb-desktop-component-padding compact:pb-desktop-compact-component-padding"
212
+ );
213
+ var componentPaddingX = (0, import_clsx.default)(
214
+ "px-mobile-component-padding desktop:px-desktop-component-padding compact:px-desktop-compact-component-padding"
215
+ );
216
+ var componentPaddingY = (0, import_clsx.default)(
217
+ "py-mobile-component-padding desktop:py-desktop-component-padding compact:py-desktop-compact-component-padding"
218
+ );
219
+ var componentPaddingXUsingComponentGap = (0, import_clsx.default)(
220
+ "px-mobile-component-gap desktop:px-desktop-component-gap compact:px-desktop-compact-component-gap"
221
+ );
222
+ var componentPaddingYUsingComponentGap = (0, import_clsx.default)(
223
+ "py-mobile-component-gap desktop:py-desktop-component-gap compact:py-desktop-compact-component-gap"
224
+ );
225
+ var componentPaddingMinusBorder = (0, import_clsx.default)(
226
+ "p-[calc(var(--spacing-mobile-component-padding)_-_1px)] desktop:p-[calc(var(--spacing-desktop-component-padding)_-_1px)] compact:p-[calc(var(--spacing-desktop-compact-component-padding)_-_1px)]"
227
+ );
228
+ var componentPaddingMinus2pxBorder = (0, import_clsx.default)(
229
+ "p-[calc(var(--spacing-mobile-component-padding)_-_2px)] desktop:p-[calc(var(--spacing-desktop-component-padding)_-_2px)] compact:p-[calc(var(--spacing-desktop-compact-component-padding)_-_2px)]"
230
+ );
231
+ var layoutPaddding = (0, import_clsx.default)(
232
+ "p-mobile-layout-padding desktop:p-desktop-layout-padding compact:p-desktop-compact-layout-padding"
233
+ );
234
+ var layoutPaddingBottom = (0, import_clsx.default)(
235
+ "pb-mobile-layout-padding desktop:pb-desktop-layout-padding compact:pb-desktop-compact-layout-padding"
236
+ );
237
+ var layoutPaddingY = (0, import_clsx.default)(
238
+ "py-mobile-layout-padding desktop:py-desktop-layout-padding compact:py-desktop-compact-layout-padding"
239
+ );
240
+ var containerPaddingX = (0, import_clsx.default)(
241
+ "px-mobile-container-padding desktop:px-desktop-container-padding compact:px-desktop-compact-container-padding"
242
+ );
243
+ var containerPaddingY = (0, import_clsx.default)(
244
+ "py-mobile-container-padding desktop:py-desktop-container-padding compact:py-desktop-compact-container-padding"
245
+ );
246
+ var layoutGroupGapPaddingY = (0, import_clsx.default)(
247
+ "py-mobile-layout-group-gap desktop:py-desktop-layout-group-gap compact:py-desktop-compact-layout-group-gap"
248
+ );
249
+ var layoutGroupGap = (0, import_clsx.default)(
250
+ "gap-mobile-layout-group-gap desktop:gap-desktop-layout-group-gap compact:gap-desktop-compact-layout-group-gap"
251
+ );
252
+ var layoutGap = (0, import_clsx.default)(
253
+ "gap-mobile-layout-gap desktop:gap-desktop-layout-gap compact:gap-desktop-compact-layout-gap"
254
+ );
255
+ var gapUsingContainerPadding = (0, import_clsx.default)(
256
+ "gap-mobile-container-padding desktop:gap-desktop-container-padding compact:gap-desktop-compact-container-padding"
257
+ );
258
+
259
+ // src/components/Stack.tsx
260
+ var import_jsx_runtime3 = require("react/jsx-runtime");
261
+ var getFlexClassNames = ({ items, justify, grow }) => (0, import_clsx2.default)(
262
+ "flex",
263
+ items === "start" && "items-start",
264
+ grow && "grow",
265
+ items === "start" && "items-start",
266
+ items === "center" && "items-center",
267
+ items === "end" && "items-end",
268
+ items === "start-center" && "items-start desktop:items-center",
269
+ justify === "start" && "justify-start",
270
+ justify === "center" && "justify-center",
271
+ justify === "end" && "justify-end",
272
+ justify === "end" && "justify-end",
273
+ justify === "between" && "justify-between",
274
+ justify === "around" && "justify-around"
275
+ );
276
+ var useGapClassNames = (sizing) => {
277
+ return (0, import_clsx2.default)(
278
+ sizing === "layout-group" && "gap-mobile-layout-group-gap desktop:gap-desktop-layout-group-gap compact:gap-compact-layout-group-gap",
279
+ sizing === "layout" && "gap-mobile-layout-gap desktop:gap-desktop-layout-gap compact:gap-compact-layout-gap",
280
+ sizing === "container" && "gap-mobile-container-gap desktop:gap-desktop-container-gap compact:gap-compact-container-gap",
281
+ sizing === "component" && "gap-mobile-component-gap desktop:gap-desktop-component-gap compact:gap-compact-component-gap"
282
+ );
283
+ };
284
+ var Stack = (_a) => {
285
+ var _b = _a, {
286
+ children,
287
+ items,
288
+ justify,
289
+ grow,
290
+ padding,
291
+ paddingX,
292
+ paddingY,
293
+ margin,
294
+ marginX,
295
+ marginY,
296
+ horizontal,
297
+ horizontalMobile,
298
+ elevation = 0,
299
+ rounded,
300
+ centered,
301
+ width,
302
+ minHeight,
303
+ maxWidth,
304
+ minWidth,
305
+ height,
306
+ maxHeight,
307
+ borderColor,
308
+ backgroundColor,
309
+ sizing = "none",
310
+ overflowY = "inherit",
311
+ overflowX = "inherit",
312
+ flexShrink,
313
+ flexGrow,
314
+ position,
315
+ top,
316
+ left,
317
+ id,
318
+ noGap,
319
+ marginTop,
320
+ marginBottom,
321
+ testid,
322
+ bottom,
323
+ zIndex
324
+ } = _b, props = __objRest(_b, [
325
+ "children",
326
+ "items",
327
+ "justify",
328
+ "grow",
329
+ "padding",
330
+ "paddingX",
331
+ "paddingY",
332
+ "margin",
333
+ "marginX",
334
+ "marginY",
335
+ "horizontal",
336
+ "horizontalMobile",
337
+ "elevation",
338
+ "rounded",
339
+ "centered",
340
+ "width",
341
+ "minHeight",
342
+ "maxWidth",
343
+ "minWidth",
344
+ "height",
345
+ "maxHeight",
346
+ "borderColor",
347
+ "backgroundColor",
348
+ "sizing",
349
+ "overflowY",
350
+ "overflowX",
351
+ "flexShrink",
352
+ "flexGrow",
353
+ "position",
354
+ "top",
355
+ "left",
356
+ "id",
357
+ "noGap",
358
+ "marginTop",
359
+ "marginBottom",
360
+ "testid",
361
+ "bottom",
362
+ "zIndex"
363
+ ]);
364
+ var _a2, _b2, _c, _d, _e;
365
+ const flexClassNames = getFlexClassNames({ items, justify, grow });
366
+ const gapClassNames = useGapClassNames(sizing);
367
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
368
+ "div",
369
+ __spreadProps(__spreadValues({
370
+ id,
371
+ "data-testid": testid
372
+ }, props), {
373
+ style: {
374
+ height: height === "full" ? "100%" : height !== void 0 ? `${height}px` : void 0,
375
+ maxHeight: maxHeight !== void 0 ? isNaN(+maxHeight) ? maxHeight : `${maxHeight}px` : (_a2 = props.style) == null ? void 0 : _a2.maxHeight,
376
+ maxWidth: maxWidth !== void 0 ? isNaN(+maxWidth) ? maxWidth : `${maxWidth}px` : (_b2 = props.style) == null ? void 0 : _b2.maxWidth,
377
+ minHeight: minHeight !== void 0 ? isNaN(+minHeight) ? minHeight : `${minHeight}px` : (_c = props.style) == null ? void 0 : _c.minHeight,
378
+ width: width !== void 0 && typeof width === "number" ? `${width}px` : void 0,
379
+ minWidth: minWidth !== void 0 ? `${minWidth}px` : void 0,
380
+ border: borderColor ? `1px solid var(--color-${borderColor})` : void 0,
381
+ backgroundColor: backgroundColor ? `var(--color-${backgroundColor})` : void 0,
382
+ flexGrow: flexGrow !== void 0 ? flexGrow : void 0,
383
+ flexShrink: flexShrink !== void 0 ? flexShrink : void 0,
384
+ position: position !== void 0 ? position : void 0,
385
+ top: top !== void 0 ? `${top}px` : void 0,
386
+ bottom: bottom !== void 0 ? `${bottom}px` : void 0,
387
+ left: left !== void 0 ? `${left}px` : void 0,
388
+ borderBlock: (_d = props.style) == null ? void 0 : _d.borderBlock,
389
+ marginInline: (_e = props.style) == null ? void 0 : _e.marginInline,
390
+ zIndex: zIndex !== void 0 ? zIndex : void 0
391
+ },
392
+ className: (0, import_clsx2.default)(
393
+ "scrollbar-thin",
394
+ "max-w-screen",
395
+ width !== "fit" && "w-full",
396
+ width === "full" && "w-full",
397
+ width === "max" && "w-max",
398
+ centered && "mx-auto",
399
+ overflowY == "auto" && "overflow-y-auto",
400
+ overflowY == "hidden" && "overflow-y-hidden",
401
+ overflowY == "scroll" && "overflow-y-scroll",
402
+ overflowX == "auto" && "overflow-x-auto",
403
+ overflowX == "hidden" && "overflow-x-hidden",
404
+ overflowX == "scroll" && "overflow-x-scroll",
405
+ padding && sizing === "container" && "p-mobile-container-padding desktop:p-desktop-container-padding compact:p-desktop-compact-container-padding",
406
+ padding && sizing === "layout" && "p-mobile-layout-padding desktop:p-desktop-layout-padding compact:p-desktop-compact-layout-padding",
407
+ padding && sizing === "layout-group" && "p-mobile-layout-group-padding desktop:p-desktop-layout-group-padding compact:p-desktop-compact-layout-group-padding",
408
+ padding && sizing === "component" && "p-mobile-component-padding desktop:p-desktop-component-padding compact:p-desktop-compact-component-padding",
409
+ paddingX && sizing === "container" && "px-mobile-container-padding desktop:px-desktop-container-padding compact:px-desktop-compact-container-padding",
410
+ paddingX && sizing === "layout" && "px-mobile-layout-padding desktop:px-desktop-layout-padding compact:px-desktop-compact-layout-padding",
411
+ paddingX && sizing === "layout-group" && "px-mobile-layout-group-padding desktop:px-desktop-layout-group-padding compact:px-desktop-compact-layout-group-padding",
412
+ paddingX && sizing === "component" && "px-mobile-component-padding desktop:px-desktop-component-padding compact:px-desktop-compact-component-padding",
413
+ paddingY && sizing === "container" && "py-mobile-container-padding desktop:py-desktop-container-padding compact:py-desktop-compact-container-padding",
414
+ paddingY && sizing === "layout" && "py-mobile-layout-padding desktop:py-desktop-layout-padding compact:py-desktop-compact-layout-padding",
415
+ paddingY && sizing === "layout-group" && paddingYUsingLayoutGroupGap,
416
+ paddingY && sizing === "component" && "py-mobile-component-padding desktop:py-desktop-component-padding compact:py-desktop-compact-component-padding",
417
+ margin && sizing === "container" && "m-mobile-container-padding desktop:m-desktop-container-padding compact:m-compact-container-padding",
418
+ marginX && sizing === "container" && "mx-mobile-container-padding desktop:mx-desktop-container-padding compact:mx-compact-container-padding",
419
+ marginTop && sizing === "container" && "mt-mobile-container-padding desktop:mt-desktop-container-padding compact:mt-compact-container-padding",
420
+ marginBottom && sizing === "container" && "mb-mobile-container-padding desktop:mb-desktop-container-padding compact:mb-compact-container-padding",
421
+ marginY && sizing === "container" && "my-mobile-container-padding desktop:my-desktop-container-padding compact:my-compact-container-padding",
422
+ horizontal ? "desktop:flex-row" : "desktop:flex-col",
423
+ horizontalMobile ? "flex-row" : "flex-col",
424
+ flexClassNames,
425
+ !noGap && gapClassNames,
426
+ elevation === 0 && "shadow-none",
427
+ elevation === 2 && "shadow-2",
428
+ elevation === 4 && "shadow-4",
429
+ elevation === 16 && "shadow-16",
430
+ rounded && "rounded"
431
+ ),
432
+ children
433
+ })
434
+ );
435
+ };
436
+
437
+ // src/components/Grid.tsx
438
+ var import_react2 = require("react");
439
+ var import_clsx3 = __toESM(require("clsx"), 1);
440
+ var import_jsx_runtime4 = require("react/jsx-runtime");
441
+ var COLUMNS_WITH_SIDE_MENU_MAP = {
442
+ 1: "grid-cols-1",
443
+ 2: "sm:grid-cols-2",
444
+ 3: "sm:grid-cols-2 md:grid-cols-3",
445
+ 4: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4",
446
+ 5: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4",
447
+ 6: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4",
448
+ 7: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6",
449
+ 8: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6",
450
+ 9: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6",
451
+ 10: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6",
452
+ 11: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-8",
453
+ 12: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-8"
454
+ };
455
+ var COLUMNS_WITHOUT_SIDE_MENU_MAP = {
456
+ 1: "grid-cols-1",
457
+ 2: "sm:grid-cols-2",
458
+ 3: "sm:grid-cols-2 md:grid-cols-3",
459
+ 4: "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4",
460
+ 5: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5",
461
+ 6: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6",
462
+ 7: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-7",
463
+ 8: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-8",
464
+ 9: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-9",
465
+ 10: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-8 2xl:grid-cols-10",
466
+ 11: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-8 2xl:grid-cols-11",
467
+ 12: "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-8 2xl:grid-cols-12"
468
+ };
469
+ var getChildCountBasedClasses = (childCount, hasSideMenu) => {
470
+ if (hasSideMenu) {
471
+ if (childCount <= 1) return "grid-cols-1";
472
+ if (childCount <= 2) return "sm:grid-cols-2";
473
+ if (childCount === 3) return "sm:grid-cols-2 md:grid-cols-3";
474
+ if (childCount <= 5) return "sm:grid-cols-2 md:grid-cols-3";
475
+ return "sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6";
476
+ }
477
+ if (childCount <= 1) return "grid-cols-1";
478
+ if (childCount <= 2) return "sm:grid-cols-2";
479
+ if (childCount === 3) return "sm:grid-cols-2 md:grid-cols-3";
480
+ if (childCount <= 5) return "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4";
481
+ if (childCount <= 6)
482
+ return "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6";
483
+ if (childCount === 7)
484
+ return "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6";
485
+ if (childCount <= 11)
486
+ return "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-8";
487
+ return "sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-8 2xl:grid-cols-12";
488
+ };
489
+ var getGridClasses = (childCount, hasSideMenu, columns) => {
490
+ var _a;
491
+ if (columns) {
492
+ const map = hasSideMenu ? COLUMNS_WITH_SIDE_MENU_MAP : COLUMNS_WITHOUT_SIDE_MENU_MAP;
493
+ return (_a = map[columns]) != null ? _a : map[12];
494
+ }
495
+ return getChildCountBasedClasses(childCount, hasSideMenu != null ? hasSideMenu : false);
496
+ };
497
+ var Grid = ({
498
+ children,
499
+ sizing = "container",
500
+ padding,
501
+ hasSideMenu = false,
502
+ columns,
503
+ id,
504
+ testid,
505
+ style
506
+ }) => {
507
+ const childCount = import_react2.Children.count(children);
508
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
509
+ "div",
510
+ {
511
+ id,
512
+ "data-testid": testid,
513
+ className: (0, import_clsx3.default)(
514
+ padding && sizing === "container" && "p-mobile-container-padding desktop:p-desktop-container-padding compact:p-desktop-compact-container-padding",
515
+ padding && sizing === "layout" && "p-mobile-layout-padding desktop:p-desktop-layout-padding compact:p-desktop-compact-layout-padding",
516
+ padding && sizing === "layout-group" && "p-mobile-layout-group-padding desktop:p-desktop-layout-group-padding compact:p-desktop-compact-layout-group-padding",
517
+ padding && sizing === "component" && "p-mobile-component-padding desktop:p-desktop-component-padding compact:p-desktop-compact-component-padding",
518
+ sizing === "layout-group" && "gap-mobile-layout-group-gap desktop:gap-desktop-layout-group-gap compact:gap-compact-layout-group-gap",
519
+ sizing === "layout" && "gap-mobile-layout-gap desktop:gap-desktop-layout-gap compact:gap-compact-layout-gap",
520
+ sizing === "container" && "gap-mobile-container-gap desktop:gap-desktop-container-gap compact:gap-compact-container-gap",
521
+ sizing === "component" && "gap-mobile-component-gap desktop:gap-desktop-component-gap compact:gap-compact-component-gap",
522
+ "w-full grid",
523
+ getGridClasses(childCount, hasSideMenu, columns)
524
+ ),
525
+ style,
526
+ children
527
+ }
528
+ );
529
+ };
530
+
531
+ // src/components/ProductImagePreview/ProductPrimaryImage.tsx
532
+ var import_react3 = require("react");
533
+
534
+ // src/components/Spinner.tsx
535
+ var import_jsx_runtime5 = require("react/jsx-runtime");
536
+ var Spinner = ({ size = "small", testid }) => {
537
+ const dimension = size === "large" ? 48 : 24;
538
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
539
+ "svg",
540
+ {
541
+ "data-testid": testid,
542
+ width: dimension,
543
+ height: dimension,
544
+ viewBox: "0 0 24 24",
545
+ xmlns: "http://www.w3.org/2000/svg",
546
+ fill: "#1D1E1E",
547
+ className: "spinner",
548
+ "aria-label": "Loading",
549
+ children: [
550
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "4", r: "2", opacity: "1" }),
551
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "17.666", cy: "6.334", r: "2", opacity: "0.125" }),
552
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "20", cy: "12", r: "2", opacity: "0.25" }),
553
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "17.666", cy: "17.666", r: "2", opacity: "0.375" }),
554
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "20", r: "2", opacity: "0.5" }),
555
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "6.334", cy: "17.666", r: "2", opacity: "0.625" }),
556
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "4", cy: "12", r: "2", opacity: "0.75" }),
557
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "6.334", cy: "6.334", r: "2", opacity: "0.875" })
558
+ ]
559
+ }
560
+ );
561
+ };
562
+ Spinner.displayName = "Spinner";
563
+
564
+ // src/components/ProductImagePreview/ProductPrimaryImage.tsx
565
+ var import_jsx_runtime6 = require("react/jsx-runtime");
566
+ function ProductPrimaryImage({
567
+ image,
568
+ width,
569
+ height,
570
+ zoomEnabled = false,
571
+ zoomLensSize = 140,
572
+ scrollToZoomEnabled = false,
573
+ className = "",
574
+ isPlaceholder = false,
575
+ onZoomPositionChange,
576
+ onScrollZoom
577
+ }) {
578
+ const containerRef = (0, import_react3.useRef)(null);
579
+ const lastPointRef = (0, import_react3.useRef)(null);
580
+ const rafRef = (0, import_react3.useRef)(null);
581
+ const [active, setActive] = (0, import_react3.useState)(false);
582
+ const [, forceRerender] = (0, import_react3.useState)(0);
583
+ const [imageLoading, setImageLoading] = (0, import_react3.useState)(true);
584
+ const [imageError, setImageError] = (0, import_react3.useState)(false);
585
+ const imageSrc = (0, import_react3.useMemo)(() => image == null ? void 0 : image.src, [image == null ? void 0 : image.src]);
586
+ const schedule = () => {
587
+ if (rafRef.current != null) return;
588
+ rafRef.current = requestAnimationFrame(() => {
589
+ rafRef.current = null;
590
+ forceRerender((n) => n + 1);
591
+ });
592
+ };
593
+ const handlePointerEnter = (0, import_react3.useCallback)(() => {
594
+ if (!zoomEnabled) return;
595
+ setActive(true);
596
+ const el = containerRef.current;
597
+ if (el) {
598
+ const r = el.getBoundingClientRect();
599
+ const pt2 = lastPointRef.current;
600
+ onZoomPositionChange == null ? void 0 : onZoomPositionChange(
601
+ pt2 ? __spreadProps(__spreadValues({}, pt2), { w: r.width, h: r.height, lensSize: zoomLensSize }) : null,
602
+ true
603
+ );
604
+ }
605
+ }, [zoomEnabled, onZoomPositionChange, zoomLensSize]);
606
+ const handlePointerLeave = (0, import_react3.useCallback)(() => {
607
+ if (!zoomEnabled) return;
608
+ setActive(false);
609
+ lastPointRef.current = null;
610
+ onZoomPositionChange == null ? void 0 : onZoomPositionChange(null, false);
611
+ }, [zoomEnabled, onZoomPositionChange]);
612
+ const handlePointerMove = (0, import_react3.useCallback)(
613
+ (e) => {
614
+ if (!zoomEnabled || !active) return;
615
+ if (e.pointerType === "touch") return;
616
+ const el = containerRef.current;
617
+ if (!el) return;
618
+ const rect = el.getBoundingClientRect();
619
+ const rawX = (e.clientX - rect.left) / rect.width;
620
+ const rawY = (e.clientY - rect.top) / rect.height;
621
+ const size = zoomLensSize != null ? zoomLensSize : 140;
622
+ const left = Math.max(
623
+ 0,
624
+ Math.min(rect.width - size, rawX * rect.width - size / 2)
625
+ );
626
+ const top = Math.max(
627
+ 0,
628
+ Math.min(rect.height - size, rawY * rect.height - size / 2)
629
+ );
630
+ const centerXNorm = (left + size / 2) / rect.width;
631
+ const centerYNorm = (top + size / 2) / rect.height;
632
+ lastPointRef.current = {
633
+ x: centerXNorm,
634
+ y: centerYNorm
635
+ };
636
+ schedule();
637
+ onZoomPositionChange == null ? void 0 : onZoomPositionChange(
638
+ lastPointRef.current ? __spreadProps(__spreadValues({}, lastPointRef.current), {
639
+ w: rect.width,
640
+ h: rect.height,
641
+ lensSize: zoomLensSize
642
+ }) : null,
643
+ true
644
+ );
645
+ },
646
+ [zoomEnabled, active, onZoomPositionChange, zoomLensSize]
647
+ );
648
+ (0, import_react3.useEffect)(() => {
649
+ const container = containerRef.current;
650
+ if (!container || !scrollToZoomEnabled) return;
651
+ const handleNativeWheel = (e) => {
652
+ e.preventDefault();
653
+ e.stopPropagation();
654
+ if (!zoomEnabled || !active) return;
655
+ const delta = e.deltaY > 0 ? -0.2 : 0.2;
656
+ onScrollZoom == null ? void 0 : onScrollZoom(delta);
657
+ };
658
+ container.addEventListener("wheel", handleNativeWheel, { passive: false });
659
+ return () => {
660
+ container.removeEventListener("wheel", handleNativeWheel);
661
+ };
662
+ }, [scrollToZoomEnabled, zoomEnabled, active, onScrollZoom]);
663
+ if (!image && !isPlaceholder) return null;
664
+ const pt = lastPointRef.current;
665
+ let lensStyle;
666
+ if (pt && active && zoomEnabled) {
667
+ const size = zoomLensSize;
668
+ const leftRaw = pt.x * width - size / 2;
669
+ const topRaw = pt.y * height - size / 2;
670
+ lensStyle = {
671
+ width: size,
672
+ height: size,
673
+ left: Math.max(0, Math.min(width - size, leftRaw)),
674
+ top: Math.max(0, Math.min(height - size, topRaw))
675
+ };
676
+ }
677
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
678
+ "div",
679
+ {
680
+ ref: containerRef,
681
+ className: [
682
+ "relative overflow-hidden bg-white rounded flex items-center justify-center select-none",
683
+ zoomEnabled ? "cursor-crosshair" : "",
684
+ className
685
+ ].join(" "),
686
+ style: { maxWidth: width, maxHeight: height, aspectRatio: "1 / 1" },
687
+ onPointerEnter: handlePointerEnter,
688
+ onPointerLeave: handlePointerLeave,
689
+ onPointerMove: handlePointerMove,
690
+ children: [
691
+ imageLoading && !imageError && !isPlaceholder && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-neutral-50", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Spinner, { size: "small" }) }),
692
+ isPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ImagePlaceholder, { width, height }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
693
+ "img",
694
+ {
695
+ src: imageSrc,
696
+ alt: (image == null ? void 0 : image.alt) || "Product image",
697
+ className: "object-cover w-full h-full select-none",
698
+ draggable: false,
699
+ loading: "lazy",
700
+ onLoad: () => setImageLoading(false),
701
+ onError: () => {
702
+ setImageLoading(false);
703
+ setImageError(true);
704
+ }
705
+ },
706
+ imageSrc
707
+ ),
708
+ zoomEnabled && active && lensStyle && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
709
+ "div",
710
+ {
711
+ "aria-hidden": true,
712
+ className: "absolute pointer-events-none border border-white/70 shadow-[0_0_0_1px_rgba(0,0,0,0.15)] rounded-md bg-white/10 backdrop-blur-[1px]",
713
+ style: lensStyle
714
+ }
715
+ )
716
+ ]
717
+ }
718
+ );
719
+ }
720
+
721
+ // src/components/ProductImagePreview/ZoomWindow.tsx
722
+ var import_react4 = require("react");
723
+
724
+ // src/components/Surface.tsx
725
+ var import_clsx4 = __toESM(require("clsx"), 1);
726
+ var import_jsx_runtime7 = require("react/jsx-runtime");
727
+ var Surface = (_a) => {
728
+ var _b = _a, {
729
+ children,
730
+ className,
731
+ elevation = 0,
732
+ id
733
+ } = _b, props = __objRest(_b, [
734
+ "children",
735
+ "className",
736
+ "elevation",
737
+ "id"
738
+ ]);
739
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
740
+ "div",
741
+ __spreadProps(__spreadValues({
742
+ id,
743
+ className: (0, import_clsx4.default)(
744
+ "rounded-base",
745
+ {
746
+ "shadow-2": elevation === 2,
747
+ "shadow-4": elevation === 4,
748
+ "shadow-16": elevation === 16
749
+ },
750
+ className
751
+ )
752
+ }, props), {
753
+ children
754
+ })
755
+ );
756
+ };
757
+ Surface.displayName = "Surface";
758
+
759
+ // src/components/ProductImagePreview/ZoomWindow.tsx
760
+ var import_jsx_runtime8 = require("react/jsx-runtime");
761
+ function ZoomWindow({
762
+ image,
763
+ width,
764
+ height,
765
+ pointer,
766
+ active,
767
+ zoomFactor = 2,
768
+ scaleFactor = 2,
769
+ primaryImagePosition,
770
+ offset = 10,
771
+ className = ""
772
+ }) {
773
+ const imageSrc = (0, import_react4.useMemo)(() => image == null ? void 0 : image.src, [image == null ? void 0 : image.src]);
774
+ if (!image || !active || !pointer) return null;
775
+ const zoomWindowSize = pointer.lensSize * scaleFactor;
776
+ const baseW = pointer.w || width;
777
+ const baseH = pointer.h || height;
778
+ const scaledW = baseW * zoomFactor;
779
+ const scaledH = baseH * zoomFactor;
780
+ const centerX = pointer.x * baseW * zoomFactor;
781
+ const centerY = pointer.y * baseH * zoomFactor;
782
+ const imageOffsetX = zoomWindowSize / 2 - centerX;
783
+ const imageOffsetY = zoomWindowSize / 2 - centerY;
784
+ const calculatePosition = () => {
785
+ if (!primaryImagePosition) {
786
+ return {
787
+ position: "fixed",
788
+ zIndex: 999,
789
+ top: "50%",
790
+ left: "50%",
791
+ transform: "translate(-50%, -50%)"
792
+ };
793
+ }
794
+ const lensLeft = primaryImagePosition.left + pointer.x * primaryImagePosition.width - pointer.lensSize / 2;
795
+ const lensTop = primaryImagePosition.top + pointer.y * primaryImagePosition.height - pointer.lensSize / 2;
796
+ let left = lensLeft + pointer.lensSize + offset;
797
+ let top = lensTop;
798
+ const { innerWidth, innerHeight } = window;
799
+ if (left + zoomWindowSize > innerWidth) {
800
+ left = lensLeft - zoomWindowSize - offset;
801
+ }
802
+ if (top + zoomWindowSize > innerHeight) {
803
+ top = lensTop + pointer.lensSize - zoomWindowSize;
804
+ }
805
+ if (top < 0) {
806
+ top = lensTop;
807
+ }
808
+ if (left < 0) {
809
+ left = lensLeft + pointer.lensSize + offset;
810
+ }
811
+ return {
812
+ position: "fixed",
813
+ zIndex: 999,
814
+ left,
815
+ top
816
+ };
817
+ };
818
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
819
+ Surface,
820
+ {
821
+ elevation: 16,
822
+ className,
823
+ style: __spreadValues({
824
+ width: zoomWindowSize,
825
+ height: zoomWindowSize,
826
+ position: "fixed",
827
+ zIndex: 999,
828
+ overflow: "hidden",
829
+ pointerEvents: "none",
830
+ userSelect: "none"
831
+ }, calculatePosition()),
832
+ "aria-hidden": true,
833
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
834
+ "img",
835
+ {
836
+ src: imageSrc,
837
+ alt: "",
838
+ className: "pointer-events-none select-none max-w-none object-cover",
839
+ style: {
840
+ width: scaledW,
841
+ height: scaledH,
842
+ transform: `translate(${imageOffsetX}px, ${imageOffsetY}px)`
843
+ },
844
+ draggable: false,
845
+ loading: "lazy"
846
+ },
847
+ imageSrc
848
+ )
849
+ }
850
+ );
851
+ }
852
+
853
+ // src/components/ProductImagePreview/CarouselPagination.tsx
854
+ var import_clsx5 = require("clsx");
855
+ var import_jsx_runtime9 = require("react/jsx-runtime");
856
+ function CarouselPagination({
857
+ images,
858
+ currentIndex,
859
+ onSelect,
860
+ className
861
+ }) {
862
+ if (!(images == null ? void 0 : images.length)) return null;
863
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
864
+ "div",
865
+ {
866
+ className: (0, import_clsx5.clsx)(
867
+ "flex items-center justify-center w-full px-4 md:hidden",
868
+ className
869
+ ),
870
+ "aria-label": "Image navigation",
871
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
872
+ "div",
873
+ {
874
+ className: "grid gap-2 place-items-center",
875
+ style: {
876
+ gridTemplateColumns: `repeat(${Math.min(images.length, 8)}, 1fr)`
877
+ },
878
+ role: "tablist",
879
+ children: images.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
880
+ "button",
881
+ {
882
+ type: "button",
883
+ onClick: () => onSelect(index),
884
+ className: (0, import_clsx5.clsx)(
885
+ "w-4 h-4 transition-all duration-200 focus:outline-none",
886
+ index === currentIndex ? "ring-2 ring-brand-400" : "ring ring-neutral-300"
887
+ ),
888
+ "aria-label": `Go to image ${index + 1}`,
889
+ role: "tab",
890
+ "aria-selected": index === currentIndex,
891
+ tabIndex: index === currentIndex ? 0 : -1
892
+ },
893
+ index
894
+ ))
895
+ }
896
+ )
897
+ }
898
+ );
899
+ }
900
+
901
+ // src/components/ProductImagePreview/MobileImageCarousel.tsx
902
+ var import_react5 = require("react");
903
+ var import_jsx_runtime10 = require("react/jsx-runtime");
904
+ function MobileImageCarousel({
905
+ images,
906
+ currentIndex,
907
+ width = 483,
908
+ height = 483,
909
+ onChangeIndex,
910
+ className = ""
911
+ }) {
912
+ const containerRef = (0, import_react5.useRef)(null);
913
+ const [isDragging, setIsDragging] = (0, import_react5.useState)(false);
914
+ const [startX, setStartX] = (0, import_react5.useState)(0);
915
+ const [currentTranslate, setCurrentTranslate] = (0, import_react5.useState)(0);
916
+ const [prevTranslate, setPrevTranslate] = (0, import_react5.useState)(0);
917
+ const [containerWidth, setContainerWidth] = (0, import_react5.useState)(width);
918
+ const imageSize = Math.min(containerWidth * 0.6, height * 0.6);
919
+ const gap = 16;
920
+ const getTranslateX = (0, import_react5.useCallback)(
921
+ (index) => {
922
+ const containerCenter = containerWidth / 2;
923
+ const imageCenter = imageSize / 2;
924
+ const totalOffset = index * (imageSize + gap);
925
+ return containerCenter - imageCenter - totalOffset;
926
+ },
927
+ [containerWidth, imageSize, gap]
928
+ );
929
+ (0, import_react5.useEffect)(() => {
930
+ const translateX = getTranslateX(currentIndex);
931
+ setCurrentTranslate(translateX);
932
+ setPrevTranslate(translateX);
933
+ }, [currentIndex, getTranslateX]);
934
+ (0, import_react5.useEffect)(() => {
935
+ const updateContainerWidth = () => {
936
+ if (containerRef.current) {
937
+ const rect = containerRef.current.getBoundingClientRect();
938
+ setContainerWidth(rect.width);
939
+ }
940
+ };
941
+ updateContainerWidth();
942
+ const resizeObserver = new ResizeObserver(updateContainerWidth);
943
+ if (containerRef.current) {
944
+ resizeObserver.observe(containerRef.current);
945
+ }
946
+ return () => resizeObserver.disconnect();
947
+ }, []);
948
+ const handleStart = (0, import_react5.useCallback)((clientX) => {
949
+ setIsDragging(true);
950
+ setStartX(clientX);
951
+ }, []);
952
+ const handleMove = (0, import_react5.useCallback)(
953
+ (clientX) => {
954
+ if (!isDragging) return;
955
+ const currentPosition = clientX;
956
+ const diff = currentPosition - startX;
957
+ setCurrentTranslate(prevTranslate + diff);
958
+ },
959
+ [isDragging, startX, prevTranslate]
960
+ );
961
+ const handleEnd = (0, import_react5.useCallback)(() => {
962
+ if (!isDragging) return;
963
+ setIsDragging(false);
964
+ const moved = currentTranslate - prevTranslate;
965
+ const threshold = imageSize / 3;
966
+ let newIndex = currentIndex;
967
+ if (moved > threshold && currentIndex > 0) {
968
+ newIndex = currentIndex - 1;
969
+ } else if (moved < -threshold && currentIndex < images.length - 1) {
970
+ newIndex = currentIndex + 1;
971
+ }
972
+ if (newIndex !== currentIndex) {
973
+ onChangeIndex(newIndex);
974
+ } else {
975
+ setCurrentTranslate(prevTranslate);
976
+ }
977
+ }, [
978
+ isDragging,
979
+ currentTranslate,
980
+ prevTranslate,
981
+ currentIndex,
982
+ imageSize,
983
+ images.length,
984
+ onChangeIndex
985
+ ]);
986
+ const handleMouseDown = (e) => {
987
+ e.preventDefault();
988
+ handleStart(e.clientX);
989
+ };
990
+ const handleMouseMove = (e) => {
991
+ e.preventDefault();
992
+ handleMove(e.clientX);
993
+ };
994
+ const handleMouseUp = () => {
995
+ handleEnd();
996
+ };
997
+ const handleMouseLeave = () => {
998
+ handleEnd();
999
+ };
1000
+ const handleTouchStart = (e) => {
1001
+ handleStart(e.touches[0].clientX);
1002
+ };
1003
+ const handleTouchMove = (e) => {
1004
+ handleMove(e.touches[0].clientX);
1005
+ };
1006
+ const handleTouchEnd = () => {
1007
+ handleEnd();
1008
+ };
1009
+ const handleImageClick = (0, import_react5.useCallback)(
1010
+ (index) => {
1011
+ if (!isDragging && index !== currentIndex) {
1012
+ onChangeIndex(index);
1013
+ }
1014
+ },
1015
+ [isDragging, currentIndex, onChangeIndex]
1016
+ );
1017
+ if (!images.length) return null;
1018
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `md:hidden w-full ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1019
+ "div",
1020
+ {
1021
+ ref: containerRef,
1022
+ className: "relative overflow-hidden cursor-grab active:cursor-grabbing select-none w-full",
1023
+ style: {
1024
+ height: imageSize
1025
+ },
1026
+ onMouseDown: handleMouseDown,
1027
+ onMouseMove: handleMouseMove,
1028
+ onMouseUp: handleMouseUp,
1029
+ onMouseLeave: handleMouseLeave,
1030
+ onTouchStart: handleTouchStart,
1031
+ onTouchMove: handleTouchMove,
1032
+ onTouchEnd: handleTouchEnd,
1033
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1034
+ "div",
1035
+ {
1036
+ className: "flex items-center",
1037
+ style: {
1038
+ transform: `translateX(${currentTranslate}px)`,
1039
+ transition: isDragging ? "none" : "transform 0.3s ease-out",
1040
+ gap: `${gap}px`
1041
+ },
1042
+ children: images.map((image, index) => {
1043
+ const isActive = index === currentIndex;
1044
+ const distance = Math.abs(index - currentIndex);
1045
+ const shouldRender = distance <= 2;
1046
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1047
+ "div",
1048
+ {
1049
+ className: "flex-shrink-0 transition-opacity duration-300",
1050
+ style: {
1051
+ width: imageSize,
1052
+ height: imageSize,
1053
+ opacity: isActive ? 1 : Math.max(0.3, 1 - distance * 0.3)
1054
+ },
1055
+ onClick: () => handleImageClick(index),
1056
+ children: shouldRender ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1057
+ "img",
1058
+ {
1059
+ src: image.src,
1060
+ alt: image.alt || `Product image ${index + 1}`,
1061
+ className: "w-full h-full object-cover",
1062
+ draggable: false,
1063
+ loading: distance <= 1 ? "eager" : "lazy",
1064
+ style: {
1065
+ aspectRatio: "1 / 1"
1066
+ }
1067
+ }
1068
+ ) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1069
+ "div",
1070
+ {
1071
+ className: "w-full h-full bg-neutral-100 rounded-md border border-gray-200",
1072
+ style: {
1073
+ aspectRatio: "1 / 1"
1074
+ },
1075
+ "aria-hidden": "true"
1076
+ }
1077
+ )
1078
+ },
1079
+ image.src + index
1080
+ );
1081
+ })
1082
+ }
1083
+ )
1084
+ }
1085
+ ) });
1086
+ }
1087
+
1088
+ // src/hooks/useKeydown.ts
1089
+ var import_react6 = require("react");
1090
+
1091
+ // src/hooks/useInfiniteScroll.tsx
1092
+ var import_react7 = require("react");
1093
+
1094
+ // src/hooks/useMatchesMedia.ts
1095
+ var import_react8 = require("react");
1096
+ var useMatchesMedia = (query) => {
1097
+ const [matches, setMatches] = (0, import_react8.useState)();
1098
+ (0, import_react8.useLayoutEffect)(() => {
1099
+ const mediaQueryList = window.matchMedia(query);
1100
+ const listener = () => setMatches(mediaQueryList.matches);
1101
+ listener();
1102
+ mediaQueryList.addEventListener("change", listener);
1103
+ return () => mediaQueryList.removeEventListener("change", listener);
1104
+ }, [query]);
1105
+ return matches;
1106
+ };
1107
+ var useMatchesMobile = () => useMatchesMedia("(width < 48rem)");
1108
+
1109
+ // src/hooks/useTableLayout.ts
1110
+ var import_react9 = require("react");
1111
+
1112
+ // src/components/ProductImagePreview/useProductImagePreview.ts
1113
+ var import_react10 = require("react");
1114
+ function useProductImagePreview(props) {
1115
+ const {
1116
+ images,
1117
+ currentIndex,
1118
+ zoomEnabled = false,
1119
+ zoomFactor = 2,
1120
+ scrollToZoomEnabled = false,
1121
+ onChangeIndex,
1122
+ isMobile = false
1123
+ } = props;
1124
+ const hasImages = !!(images == null ? void 0 : images.length);
1125
+ const safeIndex = hasImages && currentIndex >= 0 && currentIndex < images.length ? currentIndex : 0;
1126
+ const active = (0, import_react10.useMemo)(() => {
1127
+ return hasImages ? images[safeIndex] : void 0;
1128
+ }, [hasImages, images, safeIndex]);
1129
+ const [zoomPoint, setZoomPoint] = (0, import_react10.useState)(null);
1130
+ const [zoomActive, setZoomActive] = (0, import_react10.useState)(false);
1131
+ const [currentZoomFactor, setCurrentZoomFactor] = (0, import_react10.useState)(zoomFactor);
1132
+ const [primaryImagePosition, setPrimaryImagePosition] = (0, import_react10.useState)(null);
1133
+ const primaryImageRef = (0, import_react10.useRef)(null);
1134
+ const cleanupRef = (0, import_react10.useRef)(null);
1135
+ const effectiveZoomEnabled = zoomEnabled && !isMobile;
1136
+ const effectiveScrollToZoomEnabled = scrollToZoomEnabled && !isMobile;
1137
+ (0, import_react10.useEffect)(() => {
1138
+ if (!effectiveZoomEnabled) return;
1139
+ const setupTracking = () => {
1140
+ const element = primaryImageRef.current;
1141
+ if (!element) return;
1142
+ const updatePosition = () => {
1143
+ if (element) {
1144
+ setPrimaryImagePosition(element.getBoundingClientRect());
1145
+ }
1146
+ };
1147
+ updatePosition();
1148
+ const resizeObserver = new ResizeObserver(updatePosition);
1149
+ resizeObserver.observe(element);
1150
+ window.addEventListener("scroll", updatePosition);
1151
+ window.addEventListener("resize", updatePosition);
1152
+ cleanupRef.current = () => {
1153
+ resizeObserver.disconnect();
1154
+ window.removeEventListener("scroll", updatePosition);
1155
+ window.removeEventListener("resize", updatePosition);
1156
+ };
1157
+ };
1158
+ if (primaryImageRef.current) {
1159
+ setupTracking();
1160
+ } else {
1161
+ const frameId = requestAnimationFrame(setupTracking);
1162
+ return () => cancelAnimationFrame(frameId);
1163
+ }
1164
+ return () => {
1165
+ if (cleanupRef.current) {
1166
+ cleanupRef.current();
1167
+ cleanupRef.current = null;
1168
+ }
1169
+ };
1170
+ }, [effectiveZoomEnabled]);
1171
+ const handleSelect = (0, import_react10.useCallback)(
1172
+ (idx) => {
1173
+ if (idx === safeIndex) return;
1174
+ onChangeIndex(idx);
1175
+ },
1176
+ [safeIndex, onChangeIndex]
1177
+ );
1178
+ const handleNext = (0, import_react10.useCallback)(() => {
1179
+ if (!hasImages) return;
1180
+ const nextIndex = (safeIndex + 1) % images.length;
1181
+ onChangeIndex(nextIndex);
1182
+ }, [hasImages, safeIndex, images.length, onChangeIndex]);
1183
+ const handlePrevious = (0, import_react10.useCallback)(() => {
1184
+ if (!hasImages) return;
1185
+ const previousIndex = safeIndex === 0 ? images.length - 1 : safeIndex - 1;
1186
+ onChangeIndex(previousIndex);
1187
+ }, [hasImages, safeIndex, images.length, onChangeIndex]);
1188
+ const handleZoomPositionChange = (0, import_react10.useCallback)(
1189
+ (p, active2) => {
1190
+ if (isMobile) return;
1191
+ setZoomPoint(p);
1192
+ setZoomActive(active2);
1193
+ },
1194
+ [isMobile]
1195
+ );
1196
+ const handleScrollZoom = (0, import_react10.useCallback)(
1197
+ (delta) => {
1198
+ if (!effectiveScrollToZoomEnabled) return;
1199
+ const newZoomFactor = Math.max(1, Math.min(5, currentZoomFactor + delta));
1200
+ setCurrentZoomFactor(newZoomFactor);
1201
+ },
1202
+ [effectiveScrollToZoomEnabled, currentZoomFactor]
1203
+ );
1204
+ (0, import_react10.useEffect)(() => {
1205
+ setCurrentZoomFactor(zoomFactor);
1206
+ }, [zoomFactor]);
1207
+ return {
1208
+ // State
1209
+ zoomPoint,
1210
+ zoomActive,
1211
+ currentZoomFactor,
1212
+ primaryImagePosition,
1213
+ hasImages,
1214
+ safeIndex,
1215
+ active,
1216
+ // Refs
1217
+ primaryImageRef,
1218
+ // Handlers
1219
+ handleSelect,
1220
+ handleZoomPositionChange,
1221
+ handleScrollZoom,
1222
+ handleNext,
1223
+ handlePrevious
1224
+ };
1225
+ }
1226
+
1227
+ // src/components/ProductImagePreview/index.tsx
1228
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1229
+ var PLACEHOLDER_IMAGES = [
1230
+ { src: "", alt: "placeholder" },
1231
+ { src: "", alt: "placeholder" }
1232
+ ];
1233
+ function ProductImagePreview(props) {
1234
+ const {
1235
+ width = 483,
1236
+ height = 483,
1237
+ thumbsPerRow = 4,
1238
+ zoomEnabled = false,
1239
+ scrollToZoomEnabled = false,
1240
+ images,
1241
+ currentIndex,
1242
+ onChangeIndex,
1243
+ zoomLensSize,
1244
+ zoomFactor = 2,
1245
+ zoomWindowScaleFactor = 2.5,
1246
+ zoomWindowOffset = 10
1247
+ } = props;
1248
+ const isMobile = useMatchesMobile();
1249
+ const {
1250
+ zoomPoint,
1251
+ zoomActive,
1252
+ currentZoomFactor,
1253
+ primaryImagePosition,
1254
+ safeIndex,
1255
+ active,
1256
+ primaryImageRef,
1257
+ handleSelect,
1258
+ handleZoomPositionChange,
1259
+ handleScrollZoom
1260
+ } = useProductImagePreview({
1261
+ images,
1262
+ currentIndex,
1263
+ zoomEnabled,
1264
+ zoomFactor,
1265
+ scrollToZoomEnabled,
1266
+ onChangeIndex,
1267
+ isMobile
1268
+ });
1269
+ if (typeof isMobile === "undefined") return null;
1270
+ const effectiveZoomEnabled = zoomEnabled && !isMobile;
1271
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Stack, { sizing: "layout", style: { width, position: "relative" }, children: [
1272
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hidden md:block", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-4 items-start", children: [
1273
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: primaryImageRef, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1274
+ ProductPrimaryImage,
1275
+ {
1276
+ image: active,
1277
+ width,
1278
+ height,
1279
+ zoomEnabled: effectiveZoomEnabled,
1280
+ zoomLensSize,
1281
+ scrollToZoomEnabled: scrollToZoomEnabled && !isMobile,
1282
+ onZoomPositionChange: handleZoomPositionChange,
1283
+ onScrollZoom: handleScrollZoom,
1284
+ isPlaceholder: images.length === 0
1285
+ }
1286
+ ) }),
1287
+ effectiveZoomEnabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1288
+ ZoomWindow,
1289
+ {
1290
+ image: active,
1291
+ width,
1292
+ height,
1293
+ pointer: zoomPoint,
1294
+ active: zoomActive,
1295
+ zoomFactor: currentZoomFactor,
1296
+ scaleFactor: zoomWindowScaleFactor,
1297
+ primaryImagePosition,
1298
+ offset: zoomWindowOffset
1299
+ }
1300
+ )
1301
+ ] }) }),
1302
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1303
+ MobileImageCarousel,
1304
+ {
1305
+ images,
1306
+ currentIndex: safeIndex,
1307
+ width,
1308
+ height,
1309
+ onChangeIndex: handleSelect
1310
+ }
1311
+ ),
1312
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hidden md:block", children: images.length <= 3 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1313
+ "div",
1314
+ {
1315
+ className: "flex justify-center gap-4",
1316
+ style: { width: "100%", maxWidth: width },
1317
+ "aria-label": "Product image thumbnails",
1318
+ children: (images.length === 0 ? PLACEHOLDER_IMAGES : images).map(
1319
+ (img, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { maxWidth: "115px" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1320
+ Thumbnail,
1321
+ {
1322
+ src: img.src,
1323
+ alt: img.alt || `Thumbnail ${i + 1}`,
1324
+ isActive: i === safeIndex,
1325
+ onClick: () => handleSelect(i),
1326
+ isPlaceholder: images.length === 0
1327
+ }
1328
+ ) }, img.src + i)
1329
+ )
1330
+ }
1331
+ ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1332
+ Grid,
1333
+ {
1334
+ sizing: "layout-group",
1335
+ "aria-label": "Product image thumbnails",
1336
+ style: {
1337
+ width: "100%",
1338
+ maxWidth: width
1339
+ },
1340
+ columns: thumbsPerRow > 12 ? 12 : thumbsPerRow < 1 ? 1 : thumbsPerRow,
1341
+ children: (images.length === 0 ? PLACEHOLDER_IMAGES : images).map(
1342
+ (img, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1343
+ Thumbnail,
1344
+ {
1345
+ src: img.src,
1346
+ alt: img.alt || `Thumbnail ${i + 1}`,
1347
+ isActive: i === safeIndex,
1348
+ onClick: () => handleSelect(i),
1349
+ isPlaceholder: images.length === 0
1350
+ },
1351
+ img.src + i
1352
+ )
1353
+ )
1354
+ }
1355
+ ) }),
1356
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1357
+ CarouselPagination,
1358
+ {
1359
+ images,
1360
+ currentIndex: safeIndex,
1361
+ onSelect: handleSelect
1362
+ }
1363
+ )
1364
+ ] });
1365
+ }
1366
+ // Annotate the CommonJS export names for ESM import in node:
1367
+ 0 && (module.exports = {
1368
+ ProductImagePreview
1369
+ });