@snowcone-app/ui 0.1.43 → 0.2.0
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 +26 -0
- package/README.md +18 -4
- package/package.json +9 -5
- package/src/components/CanvasIsolationBoundary.tsx +202 -0
- package/src/components/LoadingOverlayPrism.tsx +251 -0
- package/src/composed/AddToCart.tsx +229 -0
- package/src/composed/ArtAlignment.tsx +703 -0
- package/src/composed/ArtSelector.tsx +290 -0
- package/src/composed/ArtworkCustomizer.tsx +212 -0
- package/src/composed/CanvasEditor.tsx +79 -0
- package/src/composed/ColorPicker.tsx +111 -0
- package/src/composed/CurrentSelectionDisplay.tsx +86 -0
- package/src/composed/HeroProductImage.tsx +1071 -0
- package/src/composed/Lightbox.index.ts +2 -0
- package/src/composed/Lightbox.tsx +230 -0
- package/src/composed/PlacementClipShapeSelector.tsx +88 -0
- package/src/composed/PlacementTabs.tsx +179 -0
- package/src/composed/ProductCard.tsx +298 -0
- package/src/composed/ProductGallery.tsx +54 -0
- package/src/composed/ProductImage.tsx +129 -0
- package/src/composed/ProductList.tsx +147 -0
- package/src/composed/ProductOptions.tsx +305 -0
- package/src/composed/RealtimeMockup.tsx +121 -0
- package/src/composed/TileCount.tsx +348 -0
- package/src/composed/carousels/HeroCarousel.tsx +240 -0
- package/src/composed/carousels/MobileProductCarousel.tsx +1002 -0
- package/src/composed/carousels/index.ts +11 -0
- package/src/composed/carousels/types.ts +58 -0
- package/src/composed/grids/MasonryGrid.tsx +238 -0
- package/src/composed/grids/index.ts +9 -0
- package/src/composed/search/CurrentRefinements.tsx +80 -0
- package/src/composed/search/Filters.tsx +49 -0
- package/src/composed/search/FiltersButton.tsx +57 -0
- package/src/composed/search/FiltersDrawer.tsx +375 -0
- package/src/composed/search/ProductGrid.tsx +118 -0
- package/src/composed/search/ProductHit.tsx +56 -0
- package/src/composed/search/SearchBox.tsx +109 -0
- package/src/composed/search/SearchProvider.tsx +136 -0
- package/src/composed/search/facetConfig.ts +16 -0
- package/src/composed/search/index.ts +22 -0
- package/src/composed/search/meilisearchAdapter.ts +20 -0
- package/src/composed/search/types.ts +22 -0
- package/src/composed/zoom/EnhancedImageViewer.tsx +505 -0
- package/src/composed/zoom/ResponsiveZoom.tsx +134 -0
- package/src/composed/zoom/ZoomOverlay.tsx +194 -0
- package/src/composed/zoom/index.ts +12 -0
- package/src/composed/zoom/types.ts +12 -0
- package/src/design-system/ColorPalette.tsx +126 -0
- package/src/design-system/ColorSwatch.tsx +49 -0
- package/src/design-system/DesignSystemPage.tsx +130 -0
- package/src/design-system/ThemeSwitcher.tsx +181 -0
- package/src/design-system/TypographyScale.tsx +106 -0
- package/src/design-system/index.ts +5 -0
- package/src/ecommerce/stories/HeroProductImage.stories.tsx +66 -0
- package/src/ecommerce/stories/PDPHeroGallery.stories.tsx +105 -0
- package/src/ecommerce/stories/PDPInfoPanel.stories.tsx +472 -0
- package/src/ecommerce/stories/PDPLayout.stories.tsx +365 -0
- package/src/hooks/useBrand.ts +41 -0
- package/src/hooks/useCanvasContext.ts +127 -0
- package/src/hooks/useDeviceDetection.ts +64 -0
- package/src/hooks/useFocusTrap.ts +70 -0
- package/src/hooks/useImagePreloader.ts +268 -0
- package/src/hooks/useImageTransition.ts +608 -0
- package/src/hooks/usePlacementsProcessor.ts +74 -0
- package/src/hooks/useProductGallery.ts +193 -0
- package/src/hooks/useProductPage.ts +467 -0
- package/src/hooks/useRenderGuard.ts +96 -0
- package/src/hooks/useScrollDirection.ts +196 -0
- package/src/hooks/viewport/index.ts +25 -0
- package/src/hooks/viewport/useContainerWidth.ts +59 -0
- package/src/hooks/viewport/useMediaQuery.ts +52 -0
- package/src/hooks/viewport/useResponsiveImageCap.ts +149 -0
- package/src/hooks/viewport/useViewportDimensions.ts +135 -0
- package/src/hooks/viewport/useWideMonitorMode.ts +150 -0
- package/src/hooks/visibility/index.ts +15 -0
- package/src/hooks/visibility/observerPool.ts +150 -0
- package/src/index.ts +240 -0
- package/src/layouts/hero-zoom/HeroShrinkLayout.tsx +209 -0
- package/src/layouts/hero-zoom/HeroZoomLayout.tsx +351 -0
- package/src/layouts/hero-zoom/index.ts +30 -0
- package/src/layouts/hero-zoom/stories/HeroZoomLayout.stories.tsx +350 -0
- package/src/layouts/hero-zoom/types.ts +113 -0
- package/src/layouts/hero-zoom/useHeroZoomScales.ts +156 -0
- package/src/layouts/index.ts +9 -0
- package/src/layouts/pdp/EdgeBlurBox.tsx +210 -0
- package/src/layouts/pdp/ImageBlurExtension.tsx +215 -0
- package/src/layouts/pdp/ImageEdgeBlur.tsx +215 -0
- package/src/layouts/pdp/PDPLayout.tsx +246 -0
- package/src/layouts/pdp/SimpleImageBlur.tsx +140 -0
- package/src/layouts/pdp/index.ts +40 -0
- package/src/lib/env.ts +15 -0
- package/src/lib/locale.ts +167 -0
- package/src/lib/router.tsx +46 -0
- package/src/lib/utils.ts +6 -0
- package/src/lightbox/README.md +77 -0
- package/src/next/index.tsx +26 -0
- package/src/patterns/MockupPriorityProvider.tsx +1014 -0
- package/src/patterns/Product.tsx +850 -0
- package/src/patterns/ProductPageProvider.tsx +224 -0
- package/src/patterns/RealtimeProvider.tsx +1162 -0
- package/src/patterns/ShopProvider.tsx +603 -0
- package/src/personalization/PersonalizationBridge.tsx +235 -0
- package/src/personalization/PersonalizationContext.ts +29 -0
- package/src/personalization/PersonalizationInputs.tsx +110 -0
- package/src/personalization/PersonalizationProvider.tsx +407 -0
- package/src/personalization/canvas-stub.d.ts +22 -0
- package/src/personalization/index.ts +43 -0
- package/src/personalization/types.ts +48 -0
- package/src/personalization/usePersonalization.ts +32 -0
- package/src/personalization/usePersonalizationShimmer.ts +159 -0
- package/src/personalization/utils.ts +59 -0
- package/src/primitives/BrandLogo.tsx +65 -0
- package/src/primitives/BrandName.tsx +51 -0
- package/src/primitives/Button.tsx +123 -0
- package/src/primitives/ColorSwatch.tsx +221 -0
- package/src/primitives/DragHintAnimation.tsx +190 -0
- package/src/primitives/EdgeSwipeGuards.tsx +60 -0
- package/src/primitives/FloatingActionGroup.tsx +176 -0
- package/src/primitives/ProductPrice.tsx +171 -0
- package/src/primitives/ProgressiveBlur.tsx +295 -0
- package/src/primitives/ThemeToggle.tsx +125 -0
- package/src/primitives/__tests__/story-coverage.test.ts +98 -0
- package/src/primitives/accordion.tsx +280 -0
- package/src/primitives/badge.tsx +137 -0
- package/src/primitives/card.tsx +61 -0
- package/src/primitives/checkbox.tsx +56 -0
- package/src/primitives/collapsible.tsx +51 -0
- package/src/primitives/drawer.tsx +828 -0
- package/src/primitives/dropdown-menu.tsx +197 -0
- package/src/primitives/fieldset.tsx +73 -0
- package/src/primitives/index.ts +138 -0
- package/src/primitives/input.tsx +91 -0
- package/src/primitives/kbd.tsx +130 -0
- package/src/primitives/label.tsx +20 -0
- package/src/primitives/link.tsx +182 -0
- package/src/primitives/popover.tsx +80 -0
- package/src/primitives/radio-group.tsx +79 -0
- package/src/primitives/scroll-fade.tsx +159 -0
- package/src/primitives/select.tsx +170 -0
- package/src/primitives/separator.tsx +25 -0
- package/src/primitives/slider.tsx +221 -0
- package/src/primitives/spinner.tsx +72 -0
- package/src/primitives/stories/Accordion.stories.tsx +121 -0
- package/src/primitives/stories/Badge.stories.tsx +221 -0
- package/src/primitives/stories/Button.stories.tsx +185 -0
- package/src/primitives/stories/Card.stories.tsx +171 -0
- package/src/primitives/stories/Checkbox.stories.tsx +214 -0
- package/src/primitives/stories/Collapsible.stories.tsx +230 -0
- package/src/primitives/stories/Drawer.stories.tsx +378 -0
- package/src/primitives/stories/DropdownMenu.stories.tsx +182 -0
- package/src/primitives/stories/Fieldset.stories.tsx +212 -0
- package/src/primitives/stories/Input.stories.tsx +172 -0
- package/src/primitives/stories/Kbd.stories.tsx +183 -0
- package/src/primitives/stories/Label.stories.tsx +98 -0
- package/src/primitives/stories/Link.stories.tsx +260 -0
- package/src/primitives/stories/Popover.stories.tsx +178 -0
- package/src/primitives/stories/RadioGroup.stories.tsx +205 -0
- package/src/primitives/stories/Select.stories.tsx +222 -0
- package/src/primitives/stories/Separator.stories.tsx +134 -0
- package/src/primitives/stories/Slider.stories.tsx +203 -0
- package/src/primitives/stories/Spinner.stories.tsx +142 -0
- package/src/primitives/stories/Surface.stories.tsx +257 -0
- package/src/primitives/stories/Switch.stories.tsx +131 -0
- package/src/primitives/stories/Tabs.stories.tsx +275 -0
- package/src/primitives/stories/TextField.stories.tsx +139 -0
- package/src/primitives/stories/Textarea.stories.tsx +148 -0
- package/src/primitives/stories/Tooltip.stories.tsx +119 -0
- package/src/primitives/surface.tsx +86 -0
- package/src/primitives/switch.tsx +35 -0
- package/src/primitives/tabs.tsx +206 -0
- package/src/primitives/text-field.tsx +84 -0
- package/src/primitives/textarea.tsx +50 -0
- package/src/primitives/tooltip.tsx +58 -0
- package/src/services/CanvasExportService.ts +518 -0
- package/src/styles/base.css +380 -0
- package/src/styles/defaults.css +280 -0
- package/src/styles/globals.css +1242 -0
- package/src/styles/index.css +17 -0
- package/src/styles/ne-themes.css +4740 -0
- package/src/styles/tailwind.css +11 -0
- package/src/styles/tokens.css +117 -0
- package/src/styles/utilities.css +188 -0
- package/src/themes/apply-theme.ts +449 -0
- package/src/themes/getThemeStyles.ts +454 -0
- package/src/themes/index.ts +48 -0
- package/src/themes/oklch-theme.ts +283 -0
- package/src/themes/presets.ts +989 -0
- package/src/themes/types.ts +386 -0
- package/src/themes/useTheme.tsx +450 -0
- package/src/utils/dev-warnings.ts +161 -0
- package/src/utils/devWarnings.ts +153 -0
- package/dist/styles.css +0 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { InstantSearch, Configure, useSearchBox } from "react-instantsearch";
|
|
4
|
+
import { searchClient } from "./meilisearchAdapter";
|
|
5
|
+
import { useEffect } from "react";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Component that triggers an initial search on mount
|
|
9
|
+
*/
|
|
10
|
+
function InitialSearchTrigger() {
|
|
11
|
+
const { refine } = useSearchBox();
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
// Trigger search with empty query to load all products
|
|
15
|
+
refine("");
|
|
16
|
+
}, [refine]);
|
|
17
|
+
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SearchProviderProps {
|
|
22
|
+
/**
|
|
23
|
+
* The index name in Meilisearch (defaults to "snowcone")
|
|
24
|
+
*/
|
|
25
|
+
indexName?: string;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Number of results per page
|
|
29
|
+
*/
|
|
30
|
+
hitsPerPage?: number;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Filters to apply to the search
|
|
34
|
+
*/
|
|
35
|
+
filters?: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Facets to retrieve
|
|
39
|
+
*/
|
|
40
|
+
facets?: string[];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Attributes to retrieve from search results
|
|
44
|
+
*/
|
|
45
|
+
attributesToRetrieve?: string[];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Children components that need access to InstantSearch context
|
|
49
|
+
*/
|
|
50
|
+
children: React.ReactNode;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* SearchProvider - Wraps InstantSearch context for composable search UI
|
|
55
|
+
*
|
|
56
|
+
* This component provides the search context that other search components need.
|
|
57
|
+
* Use this as a wrapper when you want to compose your own search UI layout.
|
|
58
|
+
*
|
|
59
|
+
* Must be used within a Shop context. ProductGrid will get artwork automatically.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* <Shop>
|
|
64
|
+
* <ArtSelector artworks={artworks} />
|
|
65
|
+
* <SearchProvider>
|
|
66
|
+
* <div className="flex gap-2">
|
|
67
|
+
* <SearchBox />
|
|
68
|
+
* <Filters />
|
|
69
|
+
* </div>
|
|
70
|
+
* <CurrentRefinements />
|
|
71
|
+
* <ProductGrid />
|
|
72
|
+
* </SearchProvider>
|
|
73
|
+
* </Shop>
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export function SearchProvider({
|
|
77
|
+
indexName = "snowcone",
|
|
78
|
+
hitsPerPage = 100,
|
|
79
|
+
filters = "mockups IS NOT EMPTY",
|
|
80
|
+
facets = ["*"],
|
|
81
|
+
attributesToRetrieve = [
|
|
82
|
+
"id",
|
|
83
|
+
"objectID",
|
|
84
|
+
"name",
|
|
85
|
+
"tags",
|
|
86
|
+
"price",
|
|
87
|
+
"mockups",
|
|
88
|
+
"placements",
|
|
89
|
+
"options",
|
|
90
|
+
"variants",
|
|
91
|
+
"sizes",
|
|
92
|
+
],
|
|
93
|
+
children,
|
|
94
|
+
}: SearchProviderProps) {
|
|
95
|
+
return (
|
|
96
|
+
<InstantSearch
|
|
97
|
+
// @ts-expect-error - InstantMeiliSearchInstance type incompatibility with react-instantsearch
|
|
98
|
+
searchClient={searchClient}
|
|
99
|
+
indexName={indexName}
|
|
100
|
+
future={{
|
|
101
|
+
preserveSharedStateOnUnmount: true,
|
|
102
|
+
}}
|
|
103
|
+
routing={{
|
|
104
|
+
stateMapping: {
|
|
105
|
+
// Map URL state to InstantSearch state
|
|
106
|
+
stateToRoute(uiState) {
|
|
107
|
+
const indexUiState = uiState[indexName] || {};
|
|
108
|
+
return {
|
|
109
|
+
q: indexUiState.query,
|
|
110
|
+
} as any;
|
|
111
|
+
},
|
|
112
|
+
// Map route to InstantSearch state - default to empty query to show all products
|
|
113
|
+
routeToState(routeState) {
|
|
114
|
+
return {
|
|
115
|
+
[indexName]: {
|
|
116
|
+
query: (routeState as any).q || "",
|
|
117
|
+
},
|
|
118
|
+
} as any;
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
<Configure
|
|
124
|
+
hitsPerPage={hitsPerPage}
|
|
125
|
+
filters={filters}
|
|
126
|
+
facets={facets}
|
|
127
|
+
attributesToRetrieve={attributesToRetrieve}
|
|
128
|
+
/>
|
|
129
|
+
<InitialSearchTrigger />
|
|
130
|
+
{/* Two @types/react versions in the tree (18.3.28 alongside whatever
|
|
131
|
+
* react-instantsearch resolves). Cross-version ReactNode mismatch is
|
|
132
|
+
* cosmetic — same runtime shape, different declaration site. */}
|
|
133
|
+
{children as any}
|
|
134
|
+
</InstantSearch>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FacetSection } from "./types";
|
|
2
|
+
|
|
3
|
+
export const FACET_SECTIONS: FacetSection[] = [
|
|
4
|
+
{
|
|
5
|
+
id: "tags",
|
|
6
|
+
title: "Tags",
|
|
7
|
+
attribute: "tags",
|
|
8
|
+
facetType: "customTags",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: "price",
|
|
12
|
+
title: "Price",
|
|
13
|
+
attribute: "price",
|
|
14
|
+
facetType: "range",
|
|
15
|
+
},
|
|
16
|
+
];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Composable search components for InstantSearch + Meilisearch
|
|
2
|
+
export { SearchProvider } from "./SearchProvider";
|
|
3
|
+
export { SearchBox } from "./SearchBox";
|
|
4
|
+
export { ProductGrid } from "./ProductGrid";
|
|
5
|
+
export { Filters } from "./Filters";
|
|
6
|
+
export { FiltersButton } from "./FiltersButton";
|
|
7
|
+
export { FiltersDrawer } from "./FiltersDrawer";
|
|
8
|
+
export { CurrentRefinements } from "./CurrentRefinements";
|
|
9
|
+
|
|
10
|
+
// ProductHit component (Next.js specific)
|
|
11
|
+
export { ProductHitComponent } from "./ProductHit";
|
|
12
|
+
|
|
13
|
+
// Utilities
|
|
14
|
+
export { searchClient } from "./meilisearchAdapter";
|
|
15
|
+
export { FACET_SECTIONS } from "./facetConfig";
|
|
16
|
+
|
|
17
|
+
// Types
|
|
18
|
+
export type { FacetSection, ProductHit, FacetType } from "./types";
|
|
19
|
+
export type { SearchProviderProps } from "./SearchProvider";
|
|
20
|
+
export type { ProductGridProps } from "./ProductGrid";
|
|
21
|
+
export type { FiltersProps } from "./Filters";
|
|
22
|
+
export type { FiltersButtonProps } from "./FiltersButton";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { instantMeiliSearch } from "@meilisearch/instant-meilisearch";
|
|
2
|
+
import { readEnv } from "../../lib/env";
|
|
3
|
+
|
|
4
|
+
const MEILISEARCH_HOST =
|
|
5
|
+
readEnv("NEXT_PUBLIC_MEILISEARCH_HOST") ||
|
|
6
|
+
"https://ms-e5d999b2eaca-15654.sfo.meilisearch.io";
|
|
7
|
+
const MEILISEARCH_API_KEY =
|
|
8
|
+
readEnv("NEXT_PUBLIC_MEILISEARCH_API_KEY") ||
|
|
9
|
+
"eee819b849798ad9091228c486ec05d0931e5292";
|
|
10
|
+
|
|
11
|
+
const { searchClient } = instantMeiliSearch(
|
|
12
|
+
MEILISEARCH_HOST,
|
|
13
|
+
MEILISEARCH_API_KEY,
|
|
14
|
+
{
|
|
15
|
+
primaryKey: "id",
|
|
16
|
+
finitePagination: true,
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export { searchClient };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CatalogProduct } from "@snowcone-app/sdk";
|
|
2
|
+
|
|
3
|
+
export type FacetType =
|
|
4
|
+
| "refinementList"
|
|
5
|
+
| "range"
|
|
6
|
+
| "hierarchical"
|
|
7
|
+
| "customTags"
|
|
8
|
+
| "customSizes";
|
|
9
|
+
|
|
10
|
+
export interface FacetSection {
|
|
11
|
+
id: string;
|
|
12
|
+
title: string;
|
|
13
|
+
attribute: string;
|
|
14
|
+
facetType: FacetType;
|
|
15
|
+
attributes?: string[];
|
|
16
|
+
showCheckbox?: boolean;
|
|
17
|
+
transformLabel?: (label: string) => string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ProductHit extends CatalogProduct {
|
|
21
|
+
objectID: string;
|
|
22
|
+
}
|