@snowcone-app/ui 0.1.42 → 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.
Files changed (192) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +18 -4
  3. package/package.json +9 -5
  4. package/src/components/CanvasIsolationBoundary.tsx +202 -0
  5. package/src/components/LoadingOverlayPrism.tsx +251 -0
  6. package/src/composed/AddToCart.tsx +229 -0
  7. package/src/composed/ArtAlignment.tsx +703 -0
  8. package/src/composed/ArtSelector.tsx +290 -0
  9. package/src/composed/ArtworkCustomizer.tsx +212 -0
  10. package/src/composed/CanvasEditor.tsx +79 -0
  11. package/src/composed/ColorPicker.tsx +111 -0
  12. package/src/composed/CurrentSelectionDisplay.tsx +86 -0
  13. package/src/composed/HeroProductImage.tsx +1071 -0
  14. package/src/composed/Lightbox.index.ts +2 -0
  15. package/src/composed/Lightbox.tsx +230 -0
  16. package/src/composed/PlacementClipShapeSelector.tsx +88 -0
  17. package/src/composed/PlacementTabs.tsx +179 -0
  18. package/src/composed/ProductCard.tsx +298 -0
  19. package/src/composed/ProductGallery.tsx +54 -0
  20. package/src/composed/ProductImage.tsx +129 -0
  21. package/src/composed/ProductList.tsx +147 -0
  22. package/src/composed/ProductOptions.tsx +305 -0
  23. package/src/composed/RealtimeMockup.tsx +121 -0
  24. package/src/composed/TileCount.tsx +348 -0
  25. package/src/composed/carousels/HeroCarousel.tsx +240 -0
  26. package/src/composed/carousels/MobileProductCarousel.tsx +1002 -0
  27. package/src/composed/carousels/index.ts +11 -0
  28. package/src/composed/carousels/types.ts +58 -0
  29. package/src/composed/grids/MasonryGrid.tsx +238 -0
  30. package/src/composed/grids/index.ts +9 -0
  31. package/src/composed/search/CurrentRefinements.tsx +80 -0
  32. package/src/composed/search/Filters.tsx +49 -0
  33. package/src/composed/search/FiltersButton.tsx +57 -0
  34. package/src/composed/search/FiltersDrawer.tsx +375 -0
  35. package/src/composed/search/ProductGrid.tsx +118 -0
  36. package/src/composed/search/ProductHit.tsx +56 -0
  37. package/src/composed/search/SearchBox.tsx +109 -0
  38. package/src/composed/search/SearchProvider.tsx +136 -0
  39. package/src/composed/search/facetConfig.ts +16 -0
  40. package/src/composed/search/index.ts +22 -0
  41. package/src/composed/search/meilisearchAdapter.ts +20 -0
  42. package/src/composed/search/types.ts +22 -0
  43. package/src/composed/zoom/EnhancedImageViewer.tsx +505 -0
  44. package/src/composed/zoom/ResponsiveZoom.tsx +134 -0
  45. package/src/composed/zoom/ZoomOverlay.tsx +194 -0
  46. package/src/composed/zoom/index.ts +12 -0
  47. package/src/composed/zoom/types.ts +12 -0
  48. package/src/design-system/ColorPalette.tsx +126 -0
  49. package/src/design-system/ColorSwatch.tsx +49 -0
  50. package/src/design-system/DesignSystemPage.tsx +130 -0
  51. package/src/design-system/ThemeSwitcher.tsx +181 -0
  52. package/src/design-system/TypographyScale.tsx +106 -0
  53. package/src/design-system/index.ts +5 -0
  54. package/src/ecommerce/stories/HeroProductImage.stories.tsx +66 -0
  55. package/src/ecommerce/stories/PDPHeroGallery.stories.tsx +105 -0
  56. package/src/ecommerce/stories/PDPInfoPanel.stories.tsx +472 -0
  57. package/src/ecommerce/stories/PDPLayout.stories.tsx +365 -0
  58. package/src/hooks/useBrand.ts +41 -0
  59. package/src/hooks/useCanvasContext.ts +127 -0
  60. package/src/hooks/useDeviceDetection.ts +64 -0
  61. package/src/hooks/useFocusTrap.ts +70 -0
  62. package/src/hooks/useImagePreloader.ts +268 -0
  63. package/src/hooks/useImageTransition.ts +608 -0
  64. package/src/hooks/usePlacementsProcessor.ts +74 -0
  65. package/src/hooks/useProductGallery.ts +193 -0
  66. package/src/hooks/useProductPage.ts +467 -0
  67. package/src/hooks/useRenderGuard.ts +96 -0
  68. package/src/hooks/useScrollDirection.ts +196 -0
  69. package/src/hooks/viewport/index.ts +25 -0
  70. package/src/hooks/viewport/useContainerWidth.ts +59 -0
  71. package/src/hooks/viewport/useMediaQuery.ts +52 -0
  72. package/src/hooks/viewport/useResponsiveImageCap.ts +149 -0
  73. package/src/hooks/viewport/useViewportDimensions.ts +135 -0
  74. package/src/hooks/viewport/useWideMonitorMode.ts +150 -0
  75. package/src/hooks/visibility/index.ts +15 -0
  76. package/src/hooks/visibility/observerPool.ts +150 -0
  77. package/src/index.ts +240 -0
  78. package/src/layouts/hero-zoom/HeroShrinkLayout.tsx +209 -0
  79. package/src/layouts/hero-zoom/HeroZoomLayout.tsx +351 -0
  80. package/src/layouts/hero-zoom/index.ts +30 -0
  81. package/src/layouts/hero-zoom/stories/HeroZoomLayout.stories.tsx +350 -0
  82. package/src/layouts/hero-zoom/types.ts +113 -0
  83. package/src/layouts/hero-zoom/useHeroZoomScales.ts +156 -0
  84. package/src/layouts/index.ts +9 -0
  85. package/src/layouts/pdp/EdgeBlurBox.tsx +210 -0
  86. package/src/layouts/pdp/ImageBlurExtension.tsx +215 -0
  87. package/src/layouts/pdp/ImageEdgeBlur.tsx +215 -0
  88. package/src/layouts/pdp/PDPLayout.tsx +246 -0
  89. package/src/layouts/pdp/SimpleImageBlur.tsx +140 -0
  90. package/src/layouts/pdp/index.ts +40 -0
  91. package/src/lib/env.ts +15 -0
  92. package/src/lib/locale.ts +167 -0
  93. package/src/lib/router.tsx +46 -0
  94. package/src/lib/utils.ts +6 -0
  95. package/src/lightbox/README.md +77 -0
  96. package/src/next/index.tsx +26 -0
  97. package/src/patterns/MockupPriorityProvider.tsx +1014 -0
  98. package/src/patterns/Product.tsx +850 -0
  99. package/src/patterns/ProductPageProvider.tsx +224 -0
  100. package/src/patterns/RealtimeProvider.tsx +1162 -0
  101. package/src/patterns/ShopProvider.tsx +603 -0
  102. package/src/personalization/PersonalizationBridge.tsx +235 -0
  103. package/src/personalization/PersonalizationContext.ts +29 -0
  104. package/src/personalization/PersonalizationInputs.tsx +110 -0
  105. package/src/personalization/PersonalizationProvider.tsx +407 -0
  106. package/src/personalization/canvas-stub.d.ts +22 -0
  107. package/src/personalization/index.ts +43 -0
  108. package/src/personalization/types.ts +48 -0
  109. package/src/personalization/usePersonalization.ts +32 -0
  110. package/src/personalization/usePersonalizationShimmer.ts +159 -0
  111. package/src/personalization/utils.ts +59 -0
  112. package/src/primitives/BrandLogo.tsx +65 -0
  113. package/src/primitives/BrandName.tsx +51 -0
  114. package/src/primitives/Button.tsx +123 -0
  115. package/src/primitives/ColorSwatch.tsx +221 -0
  116. package/src/primitives/DragHintAnimation.tsx +190 -0
  117. package/src/primitives/EdgeSwipeGuards.tsx +60 -0
  118. package/src/primitives/FloatingActionGroup.tsx +176 -0
  119. package/src/primitives/ProductPrice.tsx +171 -0
  120. package/src/primitives/ProgressiveBlur.tsx +295 -0
  121. package/src/primitives/ThemeToggle.tsx +125 -0
  122. package/src/primitives/__tests__/story-coverage.test.ts +98 -0
  123. package/src/primitives/accordion.tsx +280 -0
  124. package/src/primitives/badge.tsx +137 -0
  125. package/src/primitives/card.tsx +61 -0
  126. package/src/primitives/checkbox.tsx +56 -0
  127. package/src/primitives/collapsible.tsx +51 -0
  128. package/src/primitives/drawer.tsx +828 -0
  129. package/src/primitives/dropdown-menu.tsx +197 -0
  130. package/src/primitives/fieldset.tsx +73 -0
  131. package/src/primitives/index.ts +138 -0
  132. package/src/primitives/input.tsx +91 -0
  133. package/src/primitives/kbd.tsx +130 -0
  134. package/src/primitives/label.tsx +20 -0
  135. package/src/primitives/link.tsx +182 -0
  136. package/src/primitives/popover.tsx +80 -0
  137. package/src/primitives/radio-group.tsx +79 -0
  138. package/src/primitives/scroll-fade.tsx +159 -0
  139. package/src/primitives/select.tsx +170 -0
  140. package/src/primitives/separator.tsx +25 -0
  141. package/src/primitives/slider.tsx +221 -0
  142. package/src/primitives/spinner.tsx +72 -0
  143. package/src/primitives/stories/Accordion.stories.tsx +121 -0
  144. package/src/primitives/stories/Badge.stories.tsx +221 -0
  145. package/src/primitives/stories/Button.stories.tsx +185 -0
  146. package/src/primitives/stories/Card.stories.tsx +171 -0
  147. package/src/primitives/stories/Checkbox.stories.tsx +214 -0
  148. package/src/primitives/stories/Collapsible.stories.tsx +230 -0
  149. package/src/primitives/stories/Drawer.stories.tsx +378 -0
  150. package/src/primitives/stories/DropdownMenu.stories.tsx +182 -0
  151. package/src/primitives/stories/Fieldset.stories.tsx +212 -0
  152. package/src/primitives/stories/Input.stories.tsx +172 -0
  153. package/src/primitives/stories/Kbd.stories.tsx +183 -0
  154. package/src/primitives/stories/Label.stories.tsx +98 -0
  155. package/src/primitives/stories/Link.stories.tsx +260 -0
  156. package/src/primitives/stories/Popover.stories.tsx +178 -0
  157. package/src/primitives/stories/RadioGroup.stories.tsx +205 -0
  158. package/src/primitives/stories/Select.stories.tsx +222 -0
  159. package/src/primitives/stories/Separator.stories.tsx +134 -0
  160. package/src/primitives/stories/Slider.stories.tsx +203 -0
  161. package/src/primitives/stories/Spinner.stories.tsx +142 -0
  162. package/src/primitives/stories/Surface.stories.tsx +257 -0
  163. package/src/primitives/stories/Switch.stories.tsx +131 -0
  164. package/src/primitives/stories/Tabs.stories.tsx +275 -0
  165. package/src/primitives/stories/TextField.stories.tsx +139 -0
  166. package/src/primitives/stories/Textarea.stories.tsx +148 -0
  167. package/src/primitives/stories/Tooltip.stories.tsx +119 -0
  168. package/src/primitives/surface.tsx +86 -0
  169. package/src/primitives/switch.tsx +35 -0
  170. package/src/primitives/tabs.tsx +206 -0
  171. package/src/primitives/text-field.tsx +84 -0
  172. package/src/primitives/textarea.tsx +50 -0
  173. package/src/primitives/tooltip.tsx +58 -0
  174. package/src/services/CanvasExportService.ts +518 -0
  175. package/src/styles/base.css +380 -0
  176. package/src/styles/defaults.css +280 -0
  177. package/src/styles/globals.css +1242 -0
  178. package/src/styles/index.css +17 -0
  179. package/src/styles/ne-themes.css +4740 -0
  180. package/src/styles/tailwind.css +11 -0
  181. package/src/styles/tokens.css +117 -0
  182. package/src/styles/utilities.css +188 -0
  183. package/src/themes/apply-theme.ts +449 -0
  184. package/src/themes/getThemeStyles.ts +454 -0
  185. package/src/themes/index.ts +48 -0
  186. package/src/themes/oklch-theme.ts +283 -0
  187. package/src/themes/presets.ts +989 -0
  188. package/src/themes/types.ts +386 -0
  189. package/src/themes/useTheme.tsx +450 -0
  190. package/src/utils/dev-warnings.ts +161 -0
  191. package/src/utils/devWarnings.ts +153 -0
  192. 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
+ }