@seekora-ai/ui-sdk-react 0.2.5 → 0.2.8

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 (104) hide show
  1. package/dist/components/SearchBarWithSuggestions.d.ts +2 -0
  2. package/dist/components/SearchBarWithSuggestions.d.ts.map +1 -1
  3. package/dist/components/SearchBarWithSuggestions.js +2 -2
  4. package/dist/components/primitives/ImageDisplay.d.ts +19 -0
  5. package/dist/components/primitives/ImageDisplay.d.ts.map +1 -0
  6. package/dist/components/primitives/ImageDisplay.js +74 -0
  7. package/dist/components/primitives/index.d.ts +2 -0
  8. package/dist/components/primitives/index.d.ts.map +1 -0
  9. package/dist/components/primitives/index.js +1 -0
  10. package/dist/components/product-page/ProductGallery.d.ts +19 -0
  11. package/dist/components/product-page/ProductGallery.d.ts.map +1 -0
  12. package/dist/components/product-page/ProductGallery.js +13 -0
  13. package/dist/components/product-page/ProductInfo.d.ts +21 -0
  14. package/dist/components/product-page/ProductInfo.d.ts.map +1 -0
  15. package/dist/components/product-page/ProductInfo.js +19 -0
  16. package/dist/components/product-page/ProductRecommendations.d.ts +21 -0
  17. package/dist/components/product-page/ProductRecommendations.d.ts.map +1 -0
  18. package/dist/components/product-page/ProductRecommendations.js +17 -0
  19. package/dist/components/product-page/index.d.ts +4 -0
  20. package/dist/components/product-page/index.d.ts.map +1 -0
  21. package/dist/components/product-page/index.js +3 -0
  22. package/dist/components/section-primitives/SectionError.d.ts +11 -0
  23. package/dist/components/section-primitives/SectionError.d.ts.map +1 -0
  24. package/dist/components/section-primitives/SectionError.js +13 -0
  25. package/dist/components/section-primitives/SectionItemGrid.d.ts +18 -0
  26. package/dist/components/section-primitives/SectionItemGrid.d.ts.map +1 -0
  27. package/dist/components/section-primitives/SectionItemGrid.js +16 -0
  28. package/dist/components/section-primitives/SectionLoading.d.ts +11 -0
  29. package/dist/components/section-primitives/SectionLoading.d.ts.map +1 -0
  30. package/dist/components/section-primitives/SectionLoading.js +11 -0
  31. package/dist/components/section-primitives/SectionSearchContext.d.ts +17 -0
  32. package/dist/components/section-primitives/SectionSearchContext.d.ts.map +1 -0
  33. package/dist/components/section-primitives/SectionSearchContext.js +17 -0
  34. package/dist/components/section-primitives/SectionSearchProvider.d.ts +23 -0
  35. package/dist/components/section-primitives/SectionSearchProvider.d.ts.map +1 -0
  36. package/dist/components/section-primitives/SectionSearchProvider.js +105 -0
  37. package/dist/components/section-primitives/index.d.ts +6 -0
  38. package/dist/components/section-primitives/index.d.ts.map +1 -0
  39. package/dist/components/section-primitives/index.js +5 -0
  40. package/dist/components/suggestions-primitives/CategoriesTabs.d.ts +13 -0
  41. package/dist/components/suggestions-primitives/CategoriesTabs.d.ts.map +1 -0
  42. package/dist/components/suggestions-primitives/CategoriesTabs.js +35 -0
  43. package/dist/components/suggestions-primitives/DropdownPanel.d.ts +24 -0
  44. package/dist/components/suggestions-primitives/DropdownPanel.d.ts.map +1 -0
  45. package/dist/components/suggestions-primitives/DropdownPanel.js +54 -0
  46. package/dist/components/suggestions-primitives/ItemCard.d.ts +39 -0
  47. package/dist/components/suggestions-primitives/ItemCard.d.ts.map +1 -0
  48. package/dist/components/suggestions-primitives/ItemCard.js +52 -0
  49. package/dist/components/suggestions-primitives/ItemGrid.d.ts +28 -0
  50. package/dist/components/suggestions-primitives/ItemGrid.d.ts.map +1 -0
  51. package/dist/components/suggestions-primitives/ItemGrid.js +42 -0
  52. package/dist/components/suggestions-primitives/ProductCard.d.ts +21 -0
  53. package/dist/components/suggestions-primitives/ProductCard.d.ts.map +1 -0
  54. package/dist/components/suggestions-primitives/ProductCard.js +46 -0
  55. package/dist/components/suggestions-primitives/ProductGrid.d.ts +17 -0
  56. package/dist/components/suggestions-primitives/ProductGrid.d.ts.map +1 -0
  57. package/dist/components/suggestions-primitives/ProductGrid.js +36 -0
  58. package/dist/components/suggestions-primitives/RecentSearchesList.d.ts +17 -0
  59. package/dist/components/suggestions-primitives/RecentSearchesList.d.ts.map +1 -0
  60. package/dist/components/suggestions-primitives/RecentSearchesList.js +39 -0
  61. package/dist/components/suggestions-primitives/SearchInput.d.ts +23 -0
  62. package/dist/components/suggestions-primitives/SearchInput.d.ts.map +1 -0
  63. package/dist/components/suggestions-primitives/SearchInput.js +95 -0
  64. package/dist/components/suggestions-primitives/SuggestionItem.d.ts +18 -0
  65. package/dist/components/suggestions-primitives/SuggestionItem.d.ts.map +1 -0
  66. package/dist/components/suggestions-primitives/SuggestionItem.js +34 -0
  67. package/dist/components/suggestions-primitives/SuggestionList.d.ts +15 -0
  68. package/dist/components/suggestions-primitives/SuggestionList.d.ts.map +1 -0
  69. package/dist/components/suggestions-primitives/SuggestionList.js +36 -0
  70. package/dist/components/suggestions-primitives/SuggestionsContext.d.ts +41 -0
  71. package/dist/components/suggestions-primitives/SuggestionsContext.d.ts.map +1 -0
  72. package/dist/components/suggestions-primitives/SuggestionsContext.js +18 -0
  73. package/dist/components/suggestions-primitives/SuggestionsDropdownComposition.d.ts +24 -0
  74. package/dist/components/suggestions-primitives/SuggestionsDropdownComposition.d.ts.map +1 -0
  75. package/dist/components/suggestions-primitives/SuggestionsDropdownComposition.js +32 -0
  76. package/dist/components/suggestions-primitives/SuggestionsError.d.ts +11 -0
  77. package/dist/components/suggestions-primitives/SuggestionsError.d.ts.map +1 -0
  78. package/dist/components/suggestions-primitives/SuggestionsError.js +19 -0
  79. package/dist/components/suggestions-primitives/SuggestionsLoading.d.ts +11 -0
  80. package/dist/components/suggestions-primitives/SuggestionsLoading.d.ts.map +1 -0
  81. package/dist/components/suggestions-primitives/SuggestionsLoading.js +17 -0
  82. package/dist/components/suggestions-primitives/SuggestionsProvider.d.ts +38 -0
  83. package/dist/components/suggestions-primitives/SuggestionsProvider.d.ts.map +1 -0
  84. package/dist/components/suggestions-primitives/SuggestionsProvider.js +222 -0
  85. package/dist/components/suggestions-primitives/TrendingList.d.ts +17 -0
  86. package/dist/components/suggestions-primitives/TrendingList.d.ts.map +1 -0
  87. package/dist/components/suggestions-primitives/TrendingList.js +41 -0
  88. package/dist/components/suggestions-primitives/index.d.ts +39 -0
  89. package/dist/components/suggestions-primitives/index.d.ts.map +1 -0
  90. package/dist/components/suggestions-primitives/index.js +24 -0
  91. package/dist/hooks/useQuerySuggestionsEnhanced.d.ts.map +1 -1
  92. package/dist/hooks/useQuerySuggestionsEnhanced.js +30 -8
  93. package/dist/hooks/useSuggestionsAnalytics.d.ts +6 -6
  94. package/dist/hooks/useSuggestionsAnalytics.js +6 -6
  95. package/dist/index.d.ts +9 -1
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +7 -0
  98. package/dist/index.umd.js +1 -1
  99. package/dist/src/index.d.ts +630 -130
  100. package/dist/src/index.esm.js +1110 -43
  101. package/dist/src/index.esm.js.map +1 -1
  102. package/dist/src/index.js +1134 -42
  103. package/dist/src/index.js.map +1 -1
  104. package/package.json +3 -3
@@ -35,6 +35,8 @@ export interface SearchBarWithSuggestionsProps {
35
35
  minQueryLength?: number;
36
36
  /** Max suggestions to show */
37
37
  maxSuggestions?: number;
38
+ /** Max products to show in dropdown (federated/rich) */
39
+ maxProducts?: number;
38
40
  /** Debounce delay (ms) */
39
41
  debounceMs?: number;
40
42
  /** Show recent searches */
@@ -1 +1 @@
1
- {"version":3,"file":"SearchBarWithSuggestions.d.ts","sourceRoot":"","sources":["../../src/components/SearchBarWithSuggestions.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SearchBarWithSuggestions.d.ts","sourceRoot":"","sources":["../../src/components/SearchBarWithSuggestions.tsx"],"names":[],"mappings":"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"}
@@ -92,7 +92,7 @@ const ClearIcon = () => (React.createElement("svg", { viewBox: "0 0 20 20", fill
92
92
  // Component
93
93
  // ============================================================================
94
94
  export const SearchBarWithSuggestions = forwardRef(function SearchBarWithSuggestions(props, ref) {
95
- const { variant = 'classic', placeholder = 'Search...', initialQuery = '', value, onQueryChange, onSearch, onSuggestionSelect, onProductClick, showSearchButton = false, searchButtonText = 'Search', showClearButton = true, autoFocus = false, minQueryLength = 1, maxSuggestions = 8, debounceMs = 200, showRecentSearches = true, showTrendingOnEmpty = true, includeDropdownRecommendations = false, filteredTabs, enableAnalytics = true, analyticsTags, includeFacets, includeCategories, dropdownWidth, dropdownMaxHeight, classNames = {}, style, inputStyle, ariaLabel = 'Search', } = props;
95
+ const { variant = 'classic', placeholder = 'Search...', initialQuery = '', value, onQueryChange, onSearch, onSuggestionSelect, onProductClick, showSearchButton = false, searchButtonText = 'Search', showClearButton = true, autoFocus = false, minQueryLength = 1, maxSuggestions = 8, maxProducts = 8, debounceMs = 200, showRecentSearches = true, showTrendingOnEmpty = true, includeDropdownRecommendations = false, filteredTabs, enableAnalytics = true, analyticsTags, includeFacets, includeCategories, dropdownWidth, dropdownMaxHeight, classNames = {}, style, inputStyle, ariaLabel = 'Search', } = props;
96
96
  const { client } = useSearchContext();
97
97
  const inputRef = useRef(null);
98
98
  const dropdownRef = useRef(null);
@@ -251,7 +251,7 @@ export const SearchBarWithSuggestions = forwardRef(function SearchBarWithSuggest
251
251
  case 'rich':
252
252
  return (React.createElement(RichQuerySuggestions, { ref: dropdownRef, ...commonProps, includeDropdownRecommendations: includeDropdownRecommendations, includeCategories: true, width: dropdownWidth || '100%', maxHeight: dropdownMaxHeight || '480px' }));
253
253
  case 'federated':
254
- return (React.createElement(FederatedDropdown, { ref: dropdownRef, ...commonProps, filteredTabs: filteredTabs, showProducts: true, showBrands: true, showFilteredTabs: !!filteredTabs, onProductClick: handleProductClick, width: dropdownWidth || '800px', maxHeight: dropdownMaxHeight || '600px', includeFacets: includeFacets, includeCategories: includeCategories, includeDropdownRecommendations: includeDropdownRecommendations }));
254
+ return (React.createElement(FederatedDropdown, { ref: dropdownRef, ...commonProps, maxProducts: maxProducts, filteredTabs: filteredTabs, showProducts: true, showBrands: true, showFilteredTabs: !!filteredTabs, onProductClick: handleProductClick, width: dropdownWidth || '800px', maxHeight: dropdownMaxHeight || '600px', includeFacets: includeFacets, includeCategories: includeCategories, includeDropdownRecommendations: includeDropdownRecommendations }));
255
255
  case 'compact':
256
256
  return (React.createElement(QuerySuggestionsDropdown, { ref: dropdownRef, ...commonProps, maxSuggestions: 5, showCounts: false, width: dropdownWidth || '100%' }));
257
257
  case 'classic':
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ImageDisplay – configurable multi-image display (primitive)
3
+ *
4
+ * Variants: single, carousel, hover, thumbStrip, thumbList. Use in ItemCard,
5
+ * ProductCard, ProductGallery. Overridable via className/style.
6
+ */
7
+ import React from 'react';
8
+ export type ImageDisplayVariant = 'single' | 'carousel' | 'hover' | 'thumbStrip' | 'thumbList';
9
+ export interface ImageDisplayProps {
10
+ images: string[];
11
+ variant?: ImageDisplayVariant;
12
+ alt?: string;
13
+ className?: string;
14
+ style?: React.CSSProperties;
15
+ carouselAutoplay?: boolean;
16
+ carouselIntervalMs?: number;
17
+ }
18
+ export declare function ImageDisplay({ images, variant, alt, className, style, carouselAutoplay, carouselIntervalMs, }: ImageDisplayProps): React.JSX.Element;
19
+ //# sourceMappingURL=ImageDisplay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageDisplay.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/ImageDisplay.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAgC,MAAM,OAAO,CAAC;AAGrD,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC;AAE/F,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAUD,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,OAAkB,EAClB,GAAQ,EACR,SAAS,EACT,KAAK,EACL,gBAAwB,EACxB,kBAAyB,GAC1B,EAAE,iBAAiB,qBAiFnB"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * ImageDisplay – configurable multi-image display (primitive)
3
+ *
4
+ * Variants: single, carousel, hover, thumbStrip, thumbList. Use in ItemCard,
5
+ * ProductCard, ProductGallery. Overridable via className/style.
6
+ */
7
+ import React, { useState } from 'react';
8
+ import { clsx } from 'clsx';
9
+ const imgBaseStyle = {
10
+ width: '100%',
11
+ aspectRatio: '1',
12
+ objectFit: 'cover',
13
+ borderRadius: 4,
14
+ backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
15
+ };
16
+ export function ImageDisplay({ images, variant = 'single', alt = '', className, style, carouselAutoplay = false, carouselIntervalMs = 4000, }) {
17
+ const [index, setIndex] = useState(0);
18
+ const [hovering, setHovering] = useState(false);
19
+ const safeImages = Array.isArray(images) ? images.filter(Boolean) : [];
20
+ const current = safeImages[index] ?? safeImages[0];
21
+ if (safeImages.length === 0) {
22
+ return React.createElement("div", { className: clsx('seekora-img-display', 'seekora-img-placeholder', className), style: { ...imgBaseStyle, ...style }, "aria-hidden": true });
23
+ }
24
+ if (variant === 'single') {
25
+ return (React.createElement("img", { src: safeImages[0], alt: alt, className: clsx('seekora-img-display', 'seekora-img-single', className), style: { ...imgBaseStyle, ...style }, loading: "lazy" }));
26
+ }
27
+ if (variant === 'hover') {
28
+ const showSecond = safeImages.length > 1 && hovering;
29
+ const src = showSecond ? safeImages[1] : safeImages[0];
30
+ return (React.createElement("div", { className: clsx('seekora-img-display', 'seekora-img-hover', className), style: { position: 'relative', ...style }, onMouseEnter: () => setHovering(true), onMouseLeave: () => setHovering(false) },
31
+ React.createElement("img", { src: src, alt: alt, className: "seekora-img-hover-img", style: imgBaseStyle, loading: "lazy" })));
32
+ }
33
+ if (variant === 'carousel') {
34
+ const go = (delta) => {
35
+ setIndex((i) => {
36
+ const next = i + delta;
37
+ if (next < 0)
38
+ return safeImages.length - 1;
39
+ if (next >= safeImages.length)
40
+ return 0;
41
+ return next;
42
+ });
43
+ };
44
+ return (React.createElement("div", { className: clsx('seekora-img-display', 'seekora-img-carousel', className), style: { position: 'relative', ...style } },
45
+ React.createElement("img", { src: current, alt: alt, className: "seekora-img-carousel-main", style: imgBaseStyle, loading: "lazy" }),
46
+ safeImages.length > 1 && (React.createElement(React.Fragment, null,
47
+ React.createElement("button", { type: "button", "aria-label": "Previous", className: "seekora-img-carousel-prev", style: arrowStyle(true), onMouseDown: () => go(-1) }),
48
+ React.createElement("button", { type: "button", "aria-label": "Next", className: "seekora-img-carousel-next", style: arrowStyle(false), onMouseDown: () => go(1) })))));
49
+ }
50
+ if (variant === 'thumbStrip' || variant === 'thumbList') {
51
+ return (React.createElement("div", { className: clsx('seekora-img-display', 'seekora-img-thumbstrip', className), style: { display: 'flex', flexDirection: 'column', gap: 8, ...style } },
52
+ React.createElement("img", { src: current, alt: alt, className: "seekora-img-thumb-main", style: imgBaseStyle, loading: "lazy" }),
53
+ React.createElement("div", { className: "seekora-img-thumbs", style: { display: 'flex', gap: 4, overflowX: 'auto', paddingBottom: 4 } }, safeImages.map((src, i) => (React.createElement("button", { type: "button", key: i, className: clsx('seekora-img-thumb', i === index && 'seekora-img-thumb--active'), style: { flexShrink: 0, width: 48, height: 48, padding: 0, border: i === index ? '2px solid var(--seekora-primary)' : '1px solid transparent', borderRadius: 4, overflow: 'hidden', cursor: 'pointer', background: 'none' }, onMouseDown: () => setIndex(i) },
54
+ React.createElement("img", { src: src, alt: "", style: { width: '100%', height: '100%', objectFit: 'cover' } })))))));
55
+ }
56
+ return React.createElement("img", { src: current, alt: alt, className: clsx('seekora-img-display', className), style: { ...imgBaseStyle, ...style }, loading: "lazy" });
57
+ }
58
+ function arrowStyle(left) {
59
+ return {
60
+ position: 'absolute',
61
+ top: '50%',
62
+ [left ? 'left' : 'right']: 8,
63
+ transform: 'translateY(-50%)',
64
+ width: 32,
65
+ height: 32,
66
+ borderRadius: '50%',
67
+ border: '1px solid var(--seekora-border-color)',
68
+ backgroundColor: 'var(--seekora-bg-surface)',
69
+ cursor: 'pointer',
70
+ display: 'flex',
71
+ alignItems: 'center',
72
+ justifyContent: 'center',
73
+ };
74
+ }
@@ -0,0 +1,2 @@
1
+ export { ImageDisplay, type ImageDisplayVariant, type ImageDisplayProps } from './ImageDisplay';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export { ImageDisplay } from './ImageDisplay';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ProductGallery – product detail image gallery (primitive)
3
+ *
4
+ * Uses ImageDisplay with configurable variant (carousel, thumbStrip, etc.).
5
+ * For use on individual product page.
6
+ */
7
+ import React from 'react';
8
+ import { type ImageDisplayVariant } from '../primitives/ImageDisplay';
9
+ export interface ProductGalleryProps {
10
+ images: string[];
11
+ variant?: ImageDisplayVariant;
12
+ alt?: string;
13
+ className?: string;
14
+ style?: React.CSSProperties;
15
+ carouselAutoplay?: boolean;
16
+ carouselIntervalMs?: number;
17
+ }
18
+ export declare function ProductGallery({ images, variant, alt, className, style, carouselAutoplay, carouselIntervalMs, }: ProductGalleryProps): React.JSX.Element;
19
+ //# sourceMappingURL=ProductGallery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductGallery.d.ts","sourceRoot":"","sources":["../../../src/components/product-page/ProductGallery.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEpF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,OAAsB,EACtB,GAAe,EACf,SAAS,EACT,KAAK,EACL,gBAAgB,EAChB,kBAAkB,GACnB,EAAE,mBAAmB,qBAYrB"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * ProductGallery – product detail image gallery (primitive)
3
+ *
4
+ * Uses ImageDisplay with configurable variant (carousel, thumbStrip, etc.).
5
+ * For use on individual product page.
6
+ */
7
+ import React from 'react';
8
+ import { clsx } from 'clsx';
9
+ import { ImageDisplay } from '../primitives/ImageDisplay';
10
+ export function ProductGallery({ images, variant = 'thumbStrip', alt = 'Product', className, style, carouselAutoplay, carouselIntervalMs, }) {
11
+ return (React.createElement("div", { className: clsx('seekora-product-gallery', className), style: style },
12
+ React.createElement(ImageDisplay, { images: images, variant: variant, alt: alt, carouselAutoplay: carouselAutoplay, carouselIntervalMs: carouselIntervalMs })));
13
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * ProductInfo – product detail block (primitive)
3
+ *
4
+ * Title, description, price, optional variant selector and CTA. Minimal layout;
5
+ * override with className/style. For use on individual product page.
6
+ */
7
+ import React from 'react';
8
+ export interface ProductInfoProps {
9
+ title: string;
10
+ description?: string;
11
+ price?: number | string;
12
+ currency?: string;
13
+ /** Optional variant selector (e.g. size/color) */
14
+ renderVariantSelector?: () => React.ReactNode;
15
+ /** Optional CTA (e.g. Add to cart) */
16
+ renderCTA?: () => React.ReactNode;
17
+ className?: string;
18
+ style?: React.CSSProperties;
19
+ }
20
+ export declare function ProductInfo({ title, description, price, currency, renderVariantSelector, renderCTA, className, style, }: ProductInfoProps): React.JSX.Element;
21
+ //# sourceMappingURL=ProductInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductInfo.d.ts","sourceRoot":"","sources":["../../../src/components/product-page/ProductInfo.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,qBAAqB,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IAC9C,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAc,EACd,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,KAAK,GACN,EAAE,gBAAgB,qBAsBlB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ProductInfo – product detail block (primitive)
3
+ *
4
+ * Title, description, price, optional variant selector and CTA. Minimal layout;
5
+ * override with className/style. For use on individual product page.
6
+ */
7
+ import React from 'react';
8
+ import { clsx } from 'clsx';
9
+ export function ProductInfo({ title, description, price, currency = '$', renderVariantSelector, renderCTA, className, style, }) {
10
+ const priceNum = price != null ? (typeof price === 'number' ? price : parseFloat(String(price))) : null;
11
+ return (React.createElement("div", { className: clsx('seekora-product-info', className), style: { display: 'flex', flexDirection: 'column', gap: 12, ...style } },
12
+ React.createElement("h1", { className: "seekora-product-info-title", style: { fontSize: '1.25rem', fontWeight: 600, margin: 0 } }, title),
13
+ priceNum != null && !Number.isNaN(priceNum) ? (React.createElement("span", { className: "seekora-product-info-price", style: { fontSize: '1.125rem', fontWeight: 600 } },
14
+ currency,
15
+ priceNum.toFixed(2))) : null,
16
+ description ? (React.createElement("p", { className: "seekora-product-info-description", style: { fontSize: '0.875rem', color: 'var(--seekora-text-secondary)', margin: 0, lineHeight: 1.5 } }, description)) : null,
17
+ renderVariantSelector?.(),
18
+ renderCTA?.()));
19
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * ProductRecommendations – related / frequently bought (primitive)
3
+ *
4
+ * Renders a section of recommended items (generic ItemGrid or product list).
5
+ * Pass items and onItemClick; or wrap SectionSearchProvider with preset query for "related".
6
+ * For use on individual product page.
7
+ */
8
+ import React from 'react';
9
+ import type { GenericItem } from '../suggestions-primitives/ItemCard';
10
+ export interface ProductRecommendationsProps {
11
+ title?: string;
12
+ items: GenericItem[] | unknown[];
13
+ onItemClick?: (item: unknown, index: number) => void;
14
+ maxItems?: number;
15
+ columns?: number;
16
+ className?: string;
17
+ style?: React.CSSProperties;
18
+ renderItem?: (item: unknown, index: number) => React.ReactNode;
19
+ }
20
+ export declare function ProductRecommendations({ title, items, onItemClick, maxItems, columns, className, style, renderItem, }: ProductRecommendationsProps): React.JSX.Element | null;
21
+ //# sourceMappingURL=ProductRecommendations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductRecommendations.d.ts","sourceRoot":"","sources":["../../../src/components/product-page/ProductRecommendations.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAEtE,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAChE;AAED,wBAAgB,sBAAsB,CAAC,EACrC,KAA2B,EAC3B,KAAK,EACL,WAAW,EACX,QAAY,EACZ,OAAW,EACX,SAAS,EACT,KAAK,EACL,UAAU,GACX,EAAE,2BAA2B,4BAiB7B"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * ProductRecommendations – related / frequently bought (primitive)
3
+ *
4
+ * Renders a section of recommended items (generic ItemGrid or product list).
5
+ * Pass items and onItemClick; or wrap SectionSearchProvider with preset query for "related".
6
+ * For use on individual product page.
7
+ */
8
+ import React from 'react';
9
+ import { clsx } from 'clsx';
10
+ import { ItemGrid } from '../suggestions-primitives/ItemGrid';
11
+ export function ProductRecommendations({ title = 'You may also like', items, onItemClick, maxItems = 6, columns = 3, className, style, renderItem, }) {
12
+ if (!items?.length)
13
+ return null;
14
+ return (React.createElement("div", { className: clsx('seekora-product-recommendations', className), style: style },
15
+ React.createElement("h2", { className: "seekora-product-recommendations-title", style: { fontSize: '1rem', fontWeight: 600, marginBottom: 12 } }, title),
16
+ React.createElement(ItemGrid, { items: items, maxItems: maxItems, columns: columns, onItemClick: onItemClick, renderItem: renderItem })));
17
+ }
@@ -0,0 +1,4 @@
1
+ export { ProductGallery, type ProductGalleryProps } from './ProductGallery';
2
+ export { ProductInfo, type ProductInfoProps } from './ProductInfo';
3
+ export { ProductRecommendations, type ProductRecommendationsProps } from './ProductRecommendations';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/product-page/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,2BAA2B,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ProductGallery } from './ProductGallery';
2
+ export { ProductInfo } from './ProductInfo';
3
+ export { ProductRecommendations } from './ProductRecommendations';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * SectionError – error state for section (primitive)
3
+ */
4
+ import React from 'react';
5
+ export interface SectionErrorProps {
6
+ className?: string;
7
+ style?: React.CSSProperties;
8
+ render?: (error: Error) => React.ReactNode;
9
+ }
10
+ export declare function SectionError({ className, style, render }: SectionErrorProps): React.JSX.Element | null;
11
+ //# sourceMappingURL=SectionError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionError.d.ts","sourceRoot":"","sources":["../../../src/components/section-primitives/SectionError.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,CAAC,SAAS,CAAC;CAC5C;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,iBAAiB,4BAS3E"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SectionError – error state for section (primitive)
3
+ */
4
+ import React from 'react';
5
+ import { useSectionSearchContext } from './SectionSearchContext';
6
+ export function SectionError({ className, style, render }) {
7
+ const { error } = useSectionSearchContext();
8
+ if (!error)
9
+ return null;
10
+ if (render)
11
+ return React.createElement(React.Fragment, null, render(error));
12
+ return (React.createElement("div", { className: className, style: { padding: 16, color: 'var(--seekora-error,#dc2626)', fontSize: '0.875rem', ...style } }, error.message));
13
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * SectionItemGrid – generic grid of items from SectionSearchProvider (primitive)
3
+ */
4
+ import React from 'react';
5
+ export interface SectionItemGridProps {
6
+ columns?: number;
7
+ maxItems?: number;
8
+ className?: string;
9
+ style?: React.CSSProperties;
10
+ getItemId?: (item: unknown) => string;
11
+ getItemTitle?: (item: unknown) => string;
12
+ getItemImage?: (item: unknown) => string | undefined;
13
+ getItemDescription?: (item: unknown) => string | undefined;
14
+ getItemUrl?: (item: unknown) => string | undefined;
15
+ renderItem?: (item: unknown, index: number) => React.ReactNode;
16
+ }
17
+ export declare function SectionItemGrid({ columns, maxItems, className, style, getItemId, getItemTitle, getItemImage, getItemDescription, getItemUrl, renderItem, }: SectionItemGridProps): React.JSX.Element;
18
+ //# sourceMappingURL=SectionItemGrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionItemGrid.d.ts","sourceRoot":"","sources":["../../../src/components/section-primitives/SectionItemGrid.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IACtC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IACzC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;IACrD,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;IAC3D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;IACnD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAChE;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAW,EACX,QAAa,EACb,SAAS,EACT,KAAK,EACL,SAA8E,EAC9E,YAAyE,EACzE,YAAmE,EACnE,kBAAqF,EACrF,UAA6D,EAC7D,UAAU,GACX,EAAE,oBAAoB,qBAsBtB"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * SectionItemGrid – generic grid of items from SectionSearchProvider (primitive)
3
+ */
4
+ import React from 'react';
5
+ import { useSectionSearchContext } from './SectionSearchContext';
6
+ import { ItemGrid } from '../suggestions-primitives/ItemGrid';
7
+ import { SectionLoading } from './SectionLoading';
8
+ import { SectionError } from './SectionError';
9
+ export function SectionItemGrid({ columns = 4, maxItems = 12, className, style, getItemId = (i) => i.id ?? String(i?.objectID ?? ''), getItemTitle = (i) => i.title ?? i?.title ?? '', getItemImage = (i) => i.image ?? i?.image, getItemDescription = (i) => i.description ?? i?.description, getItemUrl = (i) => i.url ?? i?.url, renderItem, }) {
10
+ const { items, loading, error, trackClick } = useSectionSearchContext();
11
+ if (loading)
12
+ return React.createElement(SectionLoading, { className: className, style: style });
13
+ if (error)
14
+ return React.createElement(SectionError, { className: className, style: style });
15
+ return (React.createElement(ItemGrid, { items: items, maxItems: maxItems, columns: columns, className: className, style: style, getItemId: getItemId, getItemTitle: getItemTitle, getItemImage: getItemImage, getItemDescription: getItemDescription, getItemUrl: getItemUrl, renderItem: renderItem, onItemClick: (item, index) => trackClick(item, index) }));
16
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * SectionLoading – loading state for section (primitive)
3
+ */
4
+ import React from 'react';
5
+ export interface SectionLoadingProps {
6
+ className?: string;
7
+ style?: React.CSSProperties;
8
+ text?: string;
9
+ }
10
+ export declare function SectionLoading({ className, style, text }: SectionLoadingProps): React.JSX.Element | null;
11
+ //# sourceMappingURL=SectionLoading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionLoading.d.ts","sourceRoot":"","sources":["../../../src/components/section-primitives/SectionLoading.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAmB,EAAE,EAAE,mBAAmB,4BAQ5F"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * SectionLoading – loading state for section (primitive)
3
+ */
4
+ import React from 'react';
5
+ import { useSectionSearchContext } from './SectionSearchContext';
6
+ export function SectionLoading({ className, style, text = 'Loading...' }) {
7
+ const { loading } = useSectionSearchContext();
8
+ if (!loading)
9
+ return null;
10
+ return (React.createElement("div", { className: className, style: { padding: 16, color: 'var(--seekora-text-secondary)', fontSize: '0.875rem', ...style } }, text));
11
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * SectionSearchContext – preset query/filter section state
3
+ *
4
+ * For menus, sidebar, front-page blocks. Independent of main search state.
5
+ */
6
+ import React from 'react';
7
+ export interface SectionSearchContextValue {
8
+ items: unknown[];
9
+ loading: boolean;
10
+ error: Error | null;
11
+ totalCount: number;
12
+ sectionId?: string;
13
+ trackClick: (item: unknown, position: number) => void;
14
+ }
15
+ export declare const SectionSearchContext: React.Context<SectionSearchContextValue | null>;
16
+ export declare function useSectionSearchContext(): SectionSearchContextValue;
17
+ //# sourceMappingURL=SectionSearchContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionSearchContext.d.ts","sourceRoot":"","sources":["../../../src/components/section-primitives/SectionSearchContext.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAoC,MAAM,OAAO,CAAC;AAGzD,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD;AAED,eAAO,MAAM,oBAAoB,iDAAwD,CAAC;AAE1F,wBAAgB,uBAAuB,IAAI,yBAAyB,CAQnE"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * SectionSearchContext – preset query/filter section state
3
+ *
4
+ * For menus, sidebar, front-page blocks. Independent of main search state.
5
+ */
6
+ import { createContext, useContext } from 'react';
7
+ import { log } from '@seekora-ai/ui-sdk-core';
8
+ export const SectionSearchContext = createContext(null);
9
+ export function useSectionSearchContext() {
10
+ const context = useContext(SectionSearchContext);
11
+ if (!context) {
12
+ const error = new Error('useSectionSearchContext must be used within a SectionSearchProvider');
13
+ log.error('SectionSearchContext: not available', { error: error.message });
14
+ throw error;
15
+ }
16
+ return context;
17
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * SectionSearchProvider – preset query + filter section
3
+ *
4
+ * Runs client.search(query, { refinements, hitsPerPage, sortBy }) on mount and when
5
+ * query/filters change. Does not use global SearchStateManager. Use for menus,
6
+ * sidebar, front-page blocks (e.g. "New arrivals", "On sale").
7
+ */
8
+ import React from 'react';
9
+ export interface RefinementInput {
10
+ field: string;
11
+ value: string;
12
+ }
13
+ export interface SectionSearchProviderProps {
14
+ children: React.ReactNode;
15
+ query: string;
16
+ refinements?: RefinementInput[];
17
+ maxItems?: number;
18
+ sortBy?: string;
19
+ enabled?: boolean;
20
+ sectionId?: string;
21
+ }
22
+ export declare function SectionSearchProvider({ children, query, refinements, maxItems, sortBy, enabled, sectionId, }: SectionSearchProviderProps): React.JSX.Element;
23
+ //# sourceMappingURL=SectionSearchProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionSearchProvider.d.ts","sourceRoot":"","sources":["../../../src/components/section-primitives/SectionSearchProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAoD,MAAM,OAAO,CAAC;AAIzE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,KAAK,EACL,WAAgB,EAChB,QAAa,EACb,MAAM,EACN,OAAc,EACd,SAAS,GACV,EAAE,0BAA0B,qBAgF5B"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * SectionSearchProvider – preset query + filter section
3
+ *
4
+ * Runs client.search(query, { refinements, hitsPerPage, sortBy }) on mount and when
5
+ * query/filters change. Does not use global SearchStateManager. Use for menus,
6
+ * sidebar, front-page blocks (e.g. "New arrivals", "On sale").
7
+ */
8
+ import React, { useState, useEffect, useCallback, useMemo } from 'react';
9
+ import { useSearchContext } from '../SearchProvider';
10
+ import { SectionSearchContext } from './SectionSearchContext';
11
+ function extractItems(response) {
12
+ if (!response)
13
+ return [];
14
+ if (Array.isArray(response.results))
15
+ return response.results;
16
+ if (Array.isArray(response.hits))
17
+ return response.hits;
18
+ const data = response.data;
19
+ if (data && Array.isArray(data.results))
20
+ return data.results;
21
+ if (data && Array.isArray(data.data))
22
+ return data.data;
23
+ return [];
24
+ }
25
+ function extractTotal(response) {
26
+ if (!response)
27
+ return 0;
28
+ const n = response.totalResults ?? response.total ?? response.total_results;
29
+ if (typeof n === 'number')
30
+ return n;
31
+ const data = response.data;
32
+ if (data?.total_results != null)
33
+ return Number(data.total_results);
34
+ if (data?.data?.total_results != null)
35
+ return Number(data.data.total_results);
36
+ return 0;
37
+ }
38
+ export function SectionSearchProvider({ children, query, refinements = [], maxItems = 12, sortBy, enabled = true, sectionId, }) {
39
+ const { client } = useSearchContext();
40
+ const [items, setItems] = useState([]);
41
+ const [loading, setLoading] = useState(true);
42
+ const [error, setError] = useState(null);
43
+ const [totalCount, setTotalCount] = useState(0);
44
+ useEffect(() => {
45
+ if (!enabled || !client?.search) {
46
+ setItems([]);
47
+ setLoading(false);
48
+ setError(null);
49
+ setTotalCount(0);
50
+ return;
51
+ }
52
+ let cancelled = false;
53
+ setLoading(true);
54
+ setError(null);
55
+ const options = {
56
+ per_page: maxItems,
57
+ page: 1,
58
+ };
59
+ if (sortBy)
60
+ options.sort_by = sortBy;
61
+ if (refinements.length > 0) {
62
+ options.filter_by = refinements.map((r) => `${r.field}:${r.value}`).join(',');
63
+ }
64
+ client
65
+ .search(query, options)
66
+ .then((response) => {
67
+ if (cancelled)
68
+ return;
69
+ setItems(extractItems(response));
70
+ setTotalCount(extractTotal(response));
71
+ setLoading(false);
72
+ })
73
+ .catch((err) => {
74
+ if (cancelled)
75
+ return;
76
+ setError(err instanceof Error ? err : new Error(String(err)));
77
+ setItems([]);
78
+ setLoading(false);
79
+ });
80
+ return () => {
81
+ cancelled = true;
82
+ };
83
+ }, [client, enabled, query, maxItems, sortBy, refinements]);
84
+ const trackClick = useCallback((item, position) => {
85
+ if (!client?.trackEvent)
86
+ return;
87
+ const id = item?.id ?? item?.objectID;
88
+ client.trackEvent({
89
+ event_name: 'section_result_click',
90
+ clicked_item_id: id,
91
+ position,
92
+ section: sectionId,
93
+ metadata: { section_id: sectionId },
94
+ }, undefined);
95
+ }, [client, sectionId]);
96
+ const value = useMemo(() => ({
97
+ items,
98
+ loading,
99
+ error,
100
+ totalCount,
101
+ sectionId,
102
+ trackClick,
103
+ }), [items, loading, error, totalCount, sectionId, trackClick]);
104
+ return React.createElement(SectionSearchContext.Provider, { value: value }, children);
105
+ }
@@ -0,0 +1,6 @@
1
+ export { SectionSearchProvider, type RefinementInput, type SectionSearchProviderProps } from './SectionSearchProvider';
2
+ export { SectionSearchContext, useSectionSearchContext, type SectionSearchContextValue } from './SectionSearchContext';
3
+ export { SectionItemGrid, type SectionItemGridProps } from './SectionItemGrid';
4
+ export { SectionLoading, type SectionLoadingProps } from './SectionLoading';
5
+ export { SectionError, type SectionErrorProps } from './SectionError';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/section-primitives/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,KAAK,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACvH,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { SectionSearchProvider } from './SectionSearchProvider';
2
+ export { SectionSearchContext, useSectionSearchContext } from './SectionSearchContext';
3
+ export { SectionItemGrid } from './SectionItemGrid';
4
+ export { SectionLoading } from './SectionLoading';
5
+ export { SectionError } from './SectionError';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * CategoriesTabs – horizontal tabs (e.g. filtered tabs) (primitive)
3
+ *
4
+ * Active tab from context; on select updates context and tracks analytics.
5
+ */
6
+ import React from 'react';
7
+ export interface CategoriesTabsProps {
8
+ className?: string;
9
+ style?: React.CSSProperties;
10
+ tabClassName?: string;
11
+ }
12
+ export declare function CategoriesTabs({ className, style, tabClassName }: CategoriesTabsProps): React.JSX.Element | null;
13
+ //# sourceMappingURL=CategoriesTabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CategoriesTabs.d.ts","sourceRoot":"","sources":["../../../src/components/suggestions-primitives/CategoriesTabs.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,mBAAmB,4BA+CrF"}