@akinon/pz-similar-products 1.92.0-rc.21 → 1.92.0-rc.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +25 -1
- package/package.json +1 -1
- package/src/hooks/use-similar-products.ts +9 -0
- package/src/types/index.ts +13 -0
- package/src/views/filters.tsx +32 -6
- package/src/views/main.tsx +11 -3
- package/src/views/results.tsx +7 -5
- package/src/views/search-modal.tsx +4 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -272,6 +272,18 @@ interface SimilarProductsSettings {
|
|
|
272
272
|
mobileActiveFilters?: string;
|
|
273
273
|
mobileActiveFilterTag?: string;
|
|
274
274
|
mobileClearAllButton?: string;
|
|
275
|
+
|
|
276
|
+
// New crop-related custom styles
|
|
277
|
+
cropComponent?: string;
|
|
278
|
+
cropImage?: string;
|
|
279
|
+
cropImageActive?: string;
|
|
280
|
+
cropImageNonCropping?: string;
|
|
281
|
+
cropImageContainer?: string;
|
|
282
|
+
cropOverlay?: string;
|
|
283
|
+
cropSelection?: string;
|
|
284
|
+
cropSelectionBorder?: string;
|
|
285
|
+
cropOverlayBackground?: string;
|
|
286
|
+
cropSelectionHighlight?: string;
|
|
275
287
|
};
|
|
276
288
|
|
|
277
289
|
// 25+ render functions for granular control
|
|
@@ -557,7 +569,18 @@ const settings = {
|
|
|
557
569
|
productItem: 'hover:scale-105 transition-all duration-300 shadow-lg',
|
|
558
570
|
filterSidebar: 'bg-gradient-to-b from-gray-50 to-white',
|
|
559
571
|
paginationButton: 'rounded-full px-4 py-2 bg-blue-600 text-white',
|
|
560
|
-
activeFilterTag: 'bg-blue-100 text-blue-800 px-3 py-1 rounded-full'
|
|
572
|
+
activeFilterTag: 'bg-blue-100 text-blue-800 px-3 py-1 rounded-full',
|
|
573
|
+
|
|
574
|
+
// Advanced crop styling
|
|
575
|
+
cropComponent: 'border-2 border-dashed border-blue-300 rounded-lg',
|
|
576
|
+
cropImage: 'rounded-lg shadow-md',
|
|
577
|
+
cropImageActive: 'brightness-110 contrast-110',
|
|
578
|
+
cropImageNonCropping: 'hover:scale-105 transition-transform',
|
|
579
|
+
cropImageContainer: 'bg-gray-50 rounded-lg p-2',
|
|
580
|
+
cropOverlay: 'backdrop-blur-sm',
|
|
581
|
+
cropOverlayBackground: 'bg-black/60',
|
|
582
|
+
cropSelection: 'border-4 border-blue-500',
|
|
583
|
+
cropSelectionHighlight: 'shadow-2xl shadow-blue-500/50'
|
|
561
584
|
}
|
|
562
585
|
};
|
|
563
586
|
```
|
|
@@ -1490,6 +1513,7 @@ const hybridAdvancedSettings = {
|
|
|
1490
1513
|
- `filterSidebar`, `filterSidebarMobileHeader`, `filterGroup`, `filterGroupTitle`, `filterGroupContent`
|
|
1491
1514
|
- `filterItem`, `filterItemInput`, `filterItemLabel`, `filterItemCount`
|
|
1492
1515
|
- `imageSection`, `imageContainer`, `imageWrapper`, `cropButton`, `tickButton`, `uploadButton`, `resetButton`, `errorMessage`, `cropControls`
|
|
1516
|
+
- `cropComponent`, `cropImage`, `cropImageActive`, `cropImageNonCropping`, `cropImageContainer`, `cropOverlay`, `cropSelection`, `cropSelectionBorder`, `cropOverlayBackground`, `cropSelectionHighlight`
|
|
1493
1517
|
- `mobileActiveFilters`, `mobileActiveFilterTag`, `mobileClearAllButton`
|
|
1494
1518
|
|
|
1495
1519
|
**Products & Results:**
|
package/package.json
CHANGED
|
@@ -874,6 +874,14 @@ export function useSimilarProducts(product: Product) {
|
|
|
874
874
|
setFileError('');
|
|
875
875
|
}, []);
|
|
876
876
|
|
|
877
|
+
const clearResults = useCallback(() => {
|
|
878
|
+
setSearchResults(null);
|
|
879
|
+
setResultsKey(0);
|
|
880
|
+
setLastProductIds([]);
|
|
881
|
+
setAllLoadedProducts([]);
|
|
882
|
+
setLoadedPages(new Set([1]));
|
|
883
|
+
}, []);
|
|
884
|
+
|
|
877
885
|
const clearFileInput = useCallback(
|
|
878
886
|
(fileInputRef: React.RefObject<HTMLInputElement>) => {
|
|
879
887
|
if (fileInputRef.current) {
|
|
@@ -940,6 +948,7 @@ export function useSimilarProducts(product: Product) {
|
|
|
940
948
|
loadedPages: Array.from(loadedPages),
|
|
941
949
|
allLoadedProducts,
|
|
942
950
|
clearError,
|
|
951
|
+
clearResults,
|
|
943
952
|
clearFileInput
|
|
944
953
|
};
|
|
945
954
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -357,6 +357,19 @@ export interface SimilarProductsSettings {
|
|
|
357
357
|
errorMessage?: string;
|
|
358
358
|
cropControls?: string;
|
|
359
359
|
|
|
360
|
+
// Detailed crop styling
|
|
361
|
+
cropComponent?: string;
|
|
362
|
+
cropImage?: string;
|
|
363
|
+
cropImageActive?: string;
|
|
364
|
+
cropOverlay?: string;
|
|
365
|
+
cropSelection?: string;
|
|
366
|
+
cropSelectionBorder?: string;
|
|
367
|
+
cropImageNonCropping?: string;
|
|
368
|
+
cropImageContainer?: string;
|
|
369
|
+
cropImageWrapper?: string;
|
|
370
|
+
cropOverlayBackground?: string;
|
|
371
|
+
cropSelectionHighlight?: string;
|
|
372
|
+
|
|
360
373
|
resultsContainer?: string;
|
|
361
374
|
gridContainer?: string;
|
|
362
375
|
productItem?: string;
|
package/src/views/filters.tsx
CHANGED
|
@@ -445,7 +445,10 @@ export function SimilarProductsFilterSidebar({
|
|
|
445
445
|
onDragEnd={() => {}}
|
|
446
446
|
ruleOfThirds={false}
|
|
447
447
|
aspect={settings?.cropAspectRatio}
|
|
448
|
-
className=
|
|
448
|
+
className={twMerge(
|
|
449
|
+
'slider-crop',
|
|
450
|
+
settings?.customStyles?.cropComponent
|
|
451
|
+
)}
|
|
449
452
|
disabled={isLoading}
|
|
450
453
|
keepSelection={true}
|
|
451
454
|
>
|
|
@@ -453,22 +456,45 @@ export function SimilarProductsFilterSidebar({
|
|
|
453
456
|
ref={imageRef}
|
|
454
457
|
src={currentImageUrl || ''}
|
|
455
458
|
alt={product?.name || 'Product image'}
|
|
456
|
-
className=
|
|
459
|
+
className={twMerge(
|
|
460
|
+
'max-w-full max-h-[200px] md:max-h-[280px]',
|
|
461
|
+
settings?.customStyles?.cropImage,
|
|
462
|
+
settings?.customStyles?.cropImageActive
|
|
463
|
+
)}
|
|
457
464
|
style={{ transform: `scale(1) rotate(0deg)` }}
|
|
458
465
|
/>
|
|
459
466
|
</ReactCrop>
|
|
460
467
|
) : (
|
|
461
|
-
<div
|
|
468
|
+
<div
|
|
469
|
+
className={twMerge(
|
|
470
|
+
'relative w-full h-full flex items-center justify-center',
|
|
471
|
+
settings?.customStyles?.cropImageContainer
|
|
472
|
+
)}
|
|
473
|
+
>
|
|
462
474
|
<img
|
|
463
475
|
ref={imageRef}
|
|
464
476
|
src={currentImageUrl || ''}
|
|
465
477
|
alt={product?.name || 'Product image'}
|
|
466
|
-
className=
|
|
478
|
+
className={twMerge(
|
|
479
|
+
'max-w-full max-h-[200px] md:max-h-[280px] object-contain',
|
|
480
|
+
settings?.customStyles?.cropImage,
|
|
481
|
+
settings?.customStyles?.cropImageNonCropping
|
|
482
|
+
)}
|
|
467
483
|
/>
|
|
468
484
|
{!isCropping && completedCrop && (
|
|
469
|
-
<div
|
|
485
|
+
<div
|
|
486
|
+
className={twMerge(
|
|
487
|
+
'hidden md:block absolute inset-0 bg-black bg-opacity-50 transition-opacity duration-300 ease-in-out',
|
|
488
|
+
settings?.customStyles?.cropOverlay,
|
|
489
|
+
settings?.customStyles?.cropOverlayBackground
|
|
490
|
+
)}
|
|
491
|
+
>
|
|
470
492
|
<div
|
|
471
|
-
className=
|
|
493
|
+
className={twMerge(
|
|
494
|
+
'absolute transition-all duration-300 ease-in-out',
|
|
495
|
+
settings?.customStyles?.cropSelection,
|
|
496
|
+
settings?.customStyles?.cropSelectionHighlight
|
|
497
|
+
)}
|
|
472
498
|
style={{
|
|
473
499
|
width: `${completedCrop.width}px`,
|
|
474
500
|
height: `${completedCrop.height}px`,
|
package/src/views/main.tsx
CHANGED
|
@@ -56,7 +56,8 @@ export function SimilarProductsPlugin({
|
|
|
56
56
|
loadedPages,
|
|
57
57
|
fetchSimilarProductsByImageUrl,
|
|
58
58
|
fetchSimilarProductsByImageCrop,
|
|
59
|
-
clearError
|
|
59
|
+
clearError,
|
|
60
|
+
clearResults
|
|
60
61
|
} = useSimilarProducts(product);
|
|
61
62
|
|
|
62
63
|
const {
|
|
@@ -108,6 +109,7 @@ export function SimilarProductsPlugin({
|
|
|
108
109
|
if (!isOpen) {
|
|
109
110
|
setHasInitialSearchDone(false);
|
|
110
111
|
clearError();
|
|
112
|
+
clearResults();
|
|
111
113
|
}
|
|
112
114
|
}, [
|
|
113
115
|
isOpen,
|
|
@@ -115,7 +117,8 @@ export function SimilarProductsPlugin({
|
|
|
115
117
|
activeIndex,
|
|
116
118
|
hasUploadedImage,
|
|
117
119
|
hasInitialSearchDone,
|
|
118
|
-
clearError
|
|
120
|
+
clearError,
|
|
121
|
+
clearResults
|
|
119
122
|
]);
|
|
120
123
|
|
|
121
124
|
useEffect(() => {
|
|
@@ -142,6 +145,11 @@ export function SimilarProductsPlugin({
|
|
|
142
145
|
}
|
|
143
146
|
};
|
|
144
147
|
|
|
148
|
+
const handleModalClose = () => {
|
|
149
|
+
resetCrop();
|
|
150
|
+
onClose();
|
|
151
|
+
};
|
|
152
|
+
|
|
145
153
|
const ModalComponent =
|
|
146
154
|
settings.customRenderers?.Modal || SimilarProductsModal;
|
|
147
155
|
const ImageSearchModalComponent =
|
|
@@ -151,7 +159,7 @@ export function SimilarProductsPlugin({
|
|
|
151
159
|
<>
|
|
152
160
|
<ModalComponent
|
|
153
161
|
isOpen={isOpen}
|
|
154
|
-
onClose={
|
|
162
|
+
onClose={handleModalClose}
|
|
155
163
|
searchResults={searchResults}
|
|
156
164
|
resultsKey={resultsKey}
|
|
157
165
|
isLoading={isLoading}
|
package/src/views/results.tsx
CHANGED
|
@@ -526,10 +526,14 @@ export function SimilarProductsResultsGrid({
|
|
|
526
526
|
);
|
|
527
527
|
};
|
|
528
528
|
|
|
529
|
-
if (isLoading && (!searchResults || !searchResults.products)) {
|
|
529
|
+
if (isLoading && (!searchResults || !searchResults.products?.length)) {
|
|
530
530
|
return renderLoadingState();
|
|
531
531
|
}
|
|
532
532
|
|
|
533
|
+
if (!isLoading && searchResults && searchResults.products?.length === 0) {
|
|
534
|
+
return renderEmptyState();
|
|
535
|
+
}
|
|
536
|
+
|
|
533
537
|
const renderLoadingOverlay = () => {
|
|
534
538
|
if (settings?.customRenderers?.render?.resultsGrid?.renderLoadingOverlay) {
|
|
535
539
|
return settings.customRenderers.render.resultsGrid.renderLoadingOverlay();
|
|
@@ -585,16 +589,14 @@ export function SimilarProductsResultsGrid({
|
|
|
585
589
|
<div className={gridClassName}>
|
|
586
590
|
{isLoading &&
|
|
587
591
|
searchResults &&
|
|
588
|
-
searchResults.products &&
|
|
592
|
+
searchResults.products?.length > 0 &&
|
|
589
593
|
renderLoadingOverlay()}
|
|
590
594
|
|
|
591
|
-
{searchResults && searchResults.products?.length > 0
|
|
595
|
+
{searchResults && searchResults.products?.length > 0 && (
|
|
592
596
|
<div className={resultsContainerClassName}>
|
|
593
597
|
{renderGridContainer()}
|
|
594
598
|
{renderPagination()}
|
|
595
599
|
</div>
|
|
596
|
-
) : (
|
|
597
|
-
renderEmptyState()
|
|
598
600
|
)}
|
|
599
601
|
</div>
|
|
600
602
|
);
|
|
@@ -326,6 +326,10 @@ export function SimilarProductsModal({
|
|
|
326
326
|
};
|
|
327
327
|
|
|
328
328
|
const renderSortDropdown = () => {
|
|
329
|
+
if (!searchResults?.products?.length || !searchResults?.sorters?.length) {
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
|
|
329
333
|
if (settings?.customRenderers?.render?.modal?.renderSortDropdown) {
|
|
330
334
|
return settings.customRenderers.render.modal.renderSortDropdown({
|
|
331
335
|
sorters: searchResults?.sorters || [],
|