@dropins/storefront-product-discovery 3.1.1-beta2 → 3.1.1
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/api.js +4 -118
- package/api.js.map +1 -1
- package/containers/Facets.js +1 -1
- package/containers/Facets.js.map +1 -1
- package/containers/Pagination.js +1 -1
- package/containers/Pagination.js.map +1 -1
- package/containers/SearchResults.js +1 -1
- package/containers/SearchResults.js.map +1 -1
- package/containers/SortBy.js +1 -1
- package/containers/SortBy.js.map +1 -1
- package/fragments.js +115 -1
- package/fragments.js.map +1 -1
- package/package.json +1 -1
- package/render.js +1 -1
- package/render.js.map +1 -1
package/api.js
CHANGED
|
@@ -1,120 +1,6 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{events as h}from"@dropins/tools/event-bus.js";import{Initializer as fe,merge as
|
|
4
|
-
fragment Facet on Aggregation {
|
|
5
|
-
title
|
|
6
|
-
attribute
|
|
7
|
-
buckets {
|
|
8
|
-
title
|
|
9
|
-
__typename
|
|
10
|
-
... on CategoryView {
|
|
11
|
-
name
|
|
12
|
-
count
|
|
13
|
-
path
|
|
14
|
-
}
|
|
15
|
-
... on ScalarBucket {
|
|
16
|
-
count
|
|
17
|
-
}
|
|
18
|
-
... on RangeBucket {
|
|
19
|
-
from
|
|
20
|
-
to
|
|
21
|
-
count
|
|
22
|
-
}
|
|
23
|
-
... on StatsBucket {
|
|
24
|
-
min
|
|
25
|
-
max
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
`,ve=`
|
|
30
|
-
fragment ProductView on ProductSearchItem {
|
|
31
|
-
productView {
|
|
32
|
-
__typename
|
|
33
|
-
sku
|
|
34
|
-
name
|
|
35
|
-
inStock
|
|
36
|
-
url
|
|
37
|
-
urlKey
|
|
38
|
-
attributes(roles: []) {
|
|
39
|
-
name
|
|
40
|
-
label
|
|
41
|
-
value
|
|
42
|
-
roles
|
|
43
|
-
}
|
|
44
|
-
images {
|
|
45
|
-
label
|
|
46
|
-
url
|
|
47
|
-
roles
|
|
48
|
-
}
|
|
49
|
-
... on ComplexProductView {
|
|
50
|
-
priceRange {
|
|
51
|
-
maximum {
|
|
52
|
-
final {
|
|
53
|
-
amount {
|
|
54
|
-
value
|
|
55
|
-
currency
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
regular {
|
|
59
|
-
amount {
|
|
60
|
-
value
|
|
61
|
-
currency
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
minimum {
|
|
66
|
-
final {
|
|
67
|
-
amount {
|
|
68
|
-
value
|
|
69
|
-
currency
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
regular {
|
|
73
|
-
amount {
|
|
74
|
-
value
|
|
75
|
-
currency
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
options {
|
|
81
|
-
id
|
|
82
|
-
title
|
|
83
|
-
values {
|
|
84
|
-
title
|
|
85
|
-
... on ProductViewOptionValueSwatch {
|
|
86
|
-
id
|
|
87
|
-
inStock
|
|
88
|
-
type
|
|
89
|
-
value
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
... on SimpleProductView {
|
|
95
|
-
price {
|
|
96
|
-
final {
|
|
97
|
-
amount {
|
|
98
|
-
value
|
|
99
|
-
currency
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
regular {
|
|
103
|
-
amount {
|
|
104
|
-
value
|
|
105
|
-
currency
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
highlights {
|
|
112
|
-
attribute
|
|
113
|
-
value
|
|
114
|
-
matched_words
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
`,be=`
|
|
3
|
+
import{events as h}from"@dropins/tools/event-bus.js";import{Initializer as fe,merge as ue}from"@dropins/tools/lib.js";import{ProductView as me,Facet as he}from"./fragments.js";import{FetchGraphQL as ye}from"@dropins/tools/fetch-graphql.js";const ie=new fe({init:async e=>{const o={};ie.config.setConfig({...o,...e})},listeners:()=>[]}),le=ie.config,{setEndpoint:Me,setFetchGraphQlHeader:Xe,removeFetchGraphQlHeader:qe,setFetchGraphQlHeaders:We,getFetchGraphQlHeader:Ye,fetchGraphQl:Ce,getConfig:je}=new ye().getMethods(),y=e=>!e||!Intl.supportedValuesOf("currency").includes(e)?"USD":e,Re=e=>{var n,s,r,u,c,l,t,i,g,p,C,m,b,v,E,P,w,x,T,D,k,U,A,L,$,F,H,N,z,O,Q,G,K,M,X,q,W,Y,j,B,J,V,Z,a,d,ee,ne,re,I,oe;if(!e)return{id:"",name:"",sku:"",shortDescription:"",url:"",urlKey:"",metaTitle:"",metaKeywords:"",metaDescription:"",lowStock:!1,links:[],attributes:[],images:[],description:"",externalId:"",inputOptions:[],addToCartAllowed:!1,price:void 0,priceRange:void 0,inStock:!1,typename:""};const o={id:(e==null?void 0:e.id)||"",name:(e==null?void 0:e.name)||"",sku:(e==null?void 0:e.sku)||"",shortDescription:(e==null?void 0:e.shortDescription)||"",url:(e==null?void 0:e.url)||"",urlKey:(e==null?void 0:e.urlKey)||"",metaTitle:(e==null?void 0:e.metaTitle)||"",metaKeywords:(e==null?void 0:e.metaKeywords)||"",metaDescription:(e==null?void 0:e.metaDescription)||"",lowStock:(e==null?void 0:e.lowStock)||!1,links:(e==null?void 0:e.links)||[],attributes:((n=e==null?void 0:e.attributes)==null?void 0:n.map(f=>({label:f.label||"",name:f.name||"",roles:f.roles||[],value:f.value??null})))||[],images:((s=e==null?void 0:e.images)==null?void 0:s.map(f=>{var se;return{label:f.label||"",roles:f.roles||[],url:((se=f.url)==null?void 0:se.replace(/^https?:\/\//,"//"))||""}}))||[],description:(e==null?void 0:e.description)||"",externalId:(e==null?void 0:e.externalId)||"",inputOptions:(e==null?void 0:e.inputOptions)||[],addToCartAllowed:(e==null?void 0:e.addToCartAllowed)||!1,price:e.price?{final:{amount:{value:((c=(u=(r=e==null?void 0:e.price)==null?void 0:r.final)==null?void 0:u.amount)==null?void 0:c.value)||0,currency:y((i=(t=(l=e==null?void 0:e.price)==null?void 0:l.final)==null?void 0:t.amount)==null?void 0:i.currency)}},regular:{amount:{value:((C=(p=(g=e==null?void 0:e.price)==null?void 0:g.regular)==null?void 0:p.amount)==null?void 0:C.value)||0,currency:y((v=(b=(m=e==null?void 0:e.price)==null?void 0:m.regular)==null?void 0:b.amount)==null?void 0:v.currency)}},roles:((E=e==null?void 0:e.price)==null?void 0:E.roles)||[]}:void 0,priceRange:e!=null&&e.priceRange?{minimum:{final:{amount:{value:((T=(x=(w=(P=e==null?void 0:e.priceRange)==null?void 0:P.minimum)==null?void 0:w.final)==null?void 0:x.amount)==null?void 0:T.value)||0,currency:y((A=(U=(k=(D=e==null?void 0:e.priceRange)==null?void 0:D.minimum)==null?void 0:k.final)==null?void 0:U.amount)==null?void 0:A.currency)}},regular:{amount:{value:((H=(F=($=(L=e==null?void 0:e.priceRange)==null?void 0:L.minimum)==null?void 0:$.regular)==null?void 0:F.amount)==null?void 0:H.value)||0,currency:y((Q=(O=(z=(N=e==null?void 0:e.priceRange)==null?void 0:N.minimum)==null?void 0:z.regular)==null?void 0:O.amount)==null?void 0:Q.currency)}}},maximum:{final:{amount:{value:((X=(M=(K=(G=e==null?void 0:e.priceRange)==null?void 0:G.maximum)==null?void 0:K.final)==null?void 0:M.amount)==null?void 0:X.value)||0,currency:y((j=(Y=(W=(q=e==null?void 0:e.priceRange)==null?void 0:q.maximum)==null?void 0:W.final)==null?void 0:Y.amount)==null?void 0:j.currency)}},regular:{amount:{value:((Z=(V=(J=(B=e==null?void 0:e.priceRange)==null?void 0:B.maximum)==null?void 0:J.regular)==null?void 0:V.amount)==null?void 0:Z.value)||0,currency:y((ne=(ee=(d=(a=e==null?void 0:e.priceRange)==null?void 0:a.maximum)==null?void 0:d.regular)==null?void 0:ee.amount)==null?void 0:ne.currency)}}}}:void 0,inStock:(e==null?void 0:e.inStock)||!1,typename:(e==null?void 0:e.__typename)||""};return ue(o,(oe=(I=(re=le.getConfig().models)==null?void 0:re.Product)==null?void 0:I.transformer)==null?void 0:oe.call(I,e))};function _e(e,o){var r,u,c,l,t,i,g,p,C;const n=e==null?void 0:e.productSearch,s={facets:Se((n==null?void 0:n.facets)||[],o),items:(n==null?void 0:n.items.map(m=>Re(m==null?void 0:m.productView)))||[],pageInfo:{currentPage:((r=n==null?void 0:n.page_info)==null?void 0:r.current_page)||1,totalPages:((u=n==null?void 0:n.page_info)==null?void 0:u.total_pages)||1,totalItems:((c=n==null?void 0:n.page_info)==null?void 0:c.total_items)||0,pageSize:((l=n==null?void 0:n.page_info)==null?void 0:l.page_size)||10},totalCount:(n==null?void 0:n.total_count)||0,metadata:{filterableAttributes:((t=e==null?void 0:e.attributeMetadata)==null?void 0:t.filterableInSearch)||[],sortableAttributes:Ie(((i=e==null?void 0:e.attributeMetadata)==null?void 0:i.sortable)||[],o)}};return ue(s,(C=(p=(g=le.getConfig().models)==null?void 0:g.ProductSearchResult)==null?void 0:p.transformer)==null?void 0:C.call(p,e))}function Ie(e=[],o){return!e||e.length===0?[]:e.filter(n=>{var s;return n.attribute==="position"?(s=o==null?void 0:o.filter)==null?void 0:s.some(u=>u.attribute==="categoryPath"):!0}).map(n=>({...n,bidirectional:n.attribute==="price"}))}function Se(e=[],o){var s;return!e||e.length===0?[]:((s=o==null?void 0:o.filter)==null?void 0:s.some(r=>r.attribute==="categoryPath"))?e.filter(r=>r.attribute!=="categories"):e}const be=`
|
|
118
4
|
query productSearch(
|
|
119
5
|
$phrase: String!
|
|
120
6
|
$pageSize: Int
|
|
@@ -158,7 +44,7 @@ import{events as h}from"@dropins/tools/event-bus.js";import{Initializer as fe,me
|
|
|
158
44
|
}
|
|
159
45
|
}
|
|
160
46
|
}
|
|
161
|
-
${
|
|
162
|
-
${
|
|
163
|
-
`,
|
|
47
|
+
${me}
|
|
48
|
+
${he}
|
|
49
|
+
`,te="searchInputContext",ce="searchResultsContext",ve="livesearch-plp",Ee="livesearch-popover",Pe="search-product-click",we="search-request-sent",xe="search-response-received",Te="search-results-view",De="category-results-view",ke="channelContext";function R(){return window.adobeDataLayer=window.adobeDataLayer||[],window.adobeDataLayer}function pe(e){const o=R();return o.getState?o.getState(e):{}}function S(e,o){const n=R();n.push({[e]:null}),n.push({[e]:o})}function Ue(){return{_id:"https://ns.adobe.com/xdm/channels/web",_type:"https://ns.adobe.com/xdm/channel-types/web"}}function ge(){S(ke,Ue())}function _(e,o){R().push(s=>{const r=s.getState?s.getState():{};s.push({event:e,eventInfo:{...r,...o}})})}const Ae=e=>{ge(),_(we,{searchUnitId:e})},Le=e=>{ge(),_(xe,{searchUnitId:e})},Be=e=>{_(De,{searchUnitId:e})},Je=e=>{_(Te,{searchUnitId:e})},Ve=(e,o)=>{_(Pe,{sku:e,searchUnitId:o})},$e=(e,o,n,s,r,u,c)=>{if(!R)return;const t=pe(te)||{};t!=null&&t.units||(t.units=[]);const i={searchUnitId:e,searchRequestId:o,queryTypes:["products","suggestions"],phrase:n,pageSize:r,currentPage:u,filter:s,sort:c},g=t.units.findIndex(p=>p.searchUnitId===e);g<0?t.units.push(i):t.units[g]=i,S(te,t)},Fe=(e,o,n)=>{var l,t;if(!R)return;const r=pe(ce)||{};r!=null&&r.units||(r.units=[]);const u=r.units.findIndex(i=>i.searchUnitId===e),c={searchUnitId:e,searchRequestId:o,products:He(n.items),categories:[],suggestions:Ne(n.suggestions),page:((l=n==null?void 0:n.pageInfo)==null?void 0:l.currentPage)||1,perPage:((t=n==null?void 0:n.pageInfo)==null?void 0:t.pageSize)||20,facets:ze(n.facets)};u<0?r.units.push(c):r.units[u]=c,S(ce,r)},He=e=>e?e.map((n,s)=>{var r,u,c,l,t,i,g,p;return{name:n==null?void 0:n.name,sku:n==null?void 0:n.sku,url:(n==null?void 0:n.url)??"",imageUrl:((r=n==null?void 0:n.images[0])==null?void 0:r.url)??"",price:((l=(c=(u=n==null?void 0:n.price)==null?void 0:u.final)==null?void 0:c.amount)==null?void 0:l.value)??((p=(g=(i=(t=n==null?void 0:n.priceRange)==null?void 0:t.minimum)==null?void 0:i.regular)==null?void 0:g.amount)==null?void 0:p.value),rank:s}}):[],Ne=e=>e?e.map((n,s)=>({suggestion:n,rank:s})):[],ze=e=>e?e.map(n=>({attribute:n==null?void 0:n.attribute,title:n==null?void 0:n.title,type:(n==null?void 0:n.type)||"PINNED",buckets:n==null?void 0:n.buckets.map(s=>s)})):[],Ze=async(e,o={})=>{const n=o.scope==="search"?void 0:o.scope,s={request:e||{},result:{facets:[],pageInfo:{currentPage:0,totalPages:0,totalItems:0,pageSize:0},items:[],totalCount:0,suggestions:[],metadata:{filterableAttributes:[],sortableAttributes:[]}}};if(e===null)return h.emit("search/result",s,{scope:n}),s.result;h.emit("search/loading",!0,{scope:n});try{const r=n==="popover"?Ee:ve,u=window.crypto.randomUUID(),c={...e,phrase:e.phrase??"",currentPage:e.currentPage??1,sort:e.sort??[],filter:e.filter??[]};$e(r,u,c.phrase||"",c.filter||[],c.pageSize||0,c.currentPage||0,c.sort||[]),Ae(r);const{errors:l,data:t}=await Ce(be,{method:"GET",variables:{...c}});if(l&&!t)throw new Error("Error fetching product search");const i=_e(t,c);return Fe(r,u,i),Le(r),h.emit("search/result",{request:c,result:i},{scope:n}),i}catch(r){throw h.emit("search/error",r.message,{scope:n}),h.emit("search/result",s,{scope:n}),r}finally{h.emit("search/loading",!1,{scope:n})}};export{ve as P,Ee as S,Ve as a,Be as c,le as config,Ce as fetchGraphQl,je as getConfig,Ye as getFetchGraphQlHeader,ie as initialize,qe as removeFetchGraphQlHeader,Je as s,Ze as search,Me as setEndpoint,Xe as setFetchGraphQlHeader,We as setFetchGraphQlHeaders};
|
|
164
50
|
//# sourceMappingURL=api.js.map
|
package/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sources":["/@dropins/storefront-product-discovery/src/api/initialize/initialize.ts","/@dropins/storefront-product-discovery/src/api/fetch-graphql/fetch-graphql.ts","/@dropins/storefront-product-discovery/src/data/transforms/product.ts","/@dropins/storefront-product-discovery/src/data/transforms/api.ts","/@dropins/storefront-product-discovery/src/api/graphql/fragments.graphql.ts","/@dropins/storefront-product-discovery/src/api/search/graphql/search.graphql.ts","/@dropins/storefront-product-discovery/src/utils/acdlEvents.ts","/@dropins/storefront-product-discovery/src/api/search/search.ts"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { Initializer, Model } from '@adobe-commerce/elsie/lib';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { Product } from '@/plp/data/models/product';\nimport { ProductSearchResult } from '@/plp/data/models';\n\ntype ConfigProps = {\n langDefinitions?: Lang;\n\n models?: {\n Product?: Model<Product>\n ProductSearchResult?: Model<ProductSearchResult>\n }\n};\n\nexport const initialize = new Initializer<ConfigProps>({\n init: async (config) => {\n const defaultConfig = {};\n\n initialize.config.setConfig({ ...defaultConfig, ...config });\n },\n\n listeners: () => [],\n});\n\nexport const config = initialize.config;\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { FetchGraphQL } from '@adobe-commerce/fetch-graphql';\n\nexport const {\n setEndpoint,\n setFetchGraphQlHeader,\n removeFetchGraphQlHeader,\n setFetchGraphQlHeaders,\n getFetchGraphQlHeader,\n fetchGraphQl,\n getConfig,\n} = new FetchGraphQL().getMethods();\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\nimport { merge } from '@adobe-commerce/elsie/lib';\nimport { config } from '@/plp/api/initialize/initialize';\nimport { Product } from '../models/product';\n\nconst getCurrency = (currency?: string) => {\n if (!currency || !Intl.supportedValuesOf(\"currency\").includes(currency)) {\n return 'USD';\n }\n return currency;\n};\n\nexport const transformProduct = (data: any): Product | null => {\n // check if data is null or undefined, and if so return an empty object\n if (!data) {\n return {\n id: '',\n name: '',\n sku: '',\n shortDescription: '',\n url: '',\n urlKey: '',\n metaTitle: '',\n metaKeywords: '',\n metaDescription: '',\n lowStock: false,\n links: [],\n attributes: [],\n images: [],\n description: '',\n externalId: '',\n inputOptions: [],\n addToCartAllowed: false,\n price: undefined,\n priceRange: undefined,\n inStock: false,\n typename: '',\n };\n }\n\n const transformedProduct = {\n id: data?.id || '',\n name: data?.name || '',\n sku: data?.sku || '',\n shortDescription: data?.shortDescription || '',\n url: data?.url || '',\n urlKey: data?.urlKey || '',\n metaTitle: data?.metaTitle || '',\n metaKeywords: data?.metaKeywords || '',\n metaDescription: data?.metaDescription || '',\n lowStock: data?.lowStock || false,\n links: data?.links || [],\n attributes:\n data?.attributes?.map((attr: any) => ({\n label: attr.label || '',\n name: attr.name || '',\n roles: attr.roles || [],\n value: attr.value ?? null,\n })) || [],\n images:\n data?.images?.map((image: any) => ({\n label: image.label || '',\n roles: image.roles || [],\n url: image.url?.replace(/^https?:\\/\\//, '//') || '',\n })) || [],\n description: data?.description || '',\n externalId: data?.externalId || '',\n inputOptions: data?.inputOptions || [],\n addToCartAllowed: data?.addToCartAllowed || false,\n price: data.price\n ? {\n final: {\n amount: {\n value: data?.price?.final?.amount?.value || 0,\n currency: getCurrency(data?.price?.final?.amount?.currency),\n },\n },\n regular: {\n amount: {\n value: data?.price?.regular?.amount?.value || 0,\n currency: getCurrency(data?.price?.regular?.amount?.currency),\n },\n },\n roles: data?.price?.roles || [],\n }\n : undefined,\n priceRange: data?.priceRange\n ? {\n minimum: {\n final: {\n amount: {\n value: data?.priceRange?.minimum?.final?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.minimum?.final?.amount?.currency),\n },\n },\n regular: {\n amount: {\n value: data?.priceRange?.minimum?.regular?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.minimum?.regular?.amount?.currency),\n },\n },\n },\n maximum: {\n final: {\n amount: {\n value: data?.priceRange?.maximum?.final?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.maximum?.final?.amount?.currency),\n },\n },\n regular: {\n amount: {\n value: data?.priceRange?.maximum?.regular?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.maximum?.regular?.amount?.currency),\n },\n },\n },\n }\n : undefined,\n inStock: data?.inStock || false,\n typename: data?.__typename || '',\n };\n\n return merge(\n transformedProduct, // default transformer\n config.getConfig().models?.Product?.transformer?.(data), // custom transformer\n )\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\nimport { merge } from '@adobe-commerce/elsie/lib';\nimport { config } from '@/plp/api/initialize/initialize';\nimport { ProductSearchResult, SearchVariables } from '@/plp/data/models';\nimport { Product } from '@/plp/data/models/product';\n\nimport { transformProduct } from './product';\n\n\nexport function transformProductSearchResponse(data: any, searchVariables?: SearchVariables): ProductSearchResult {\n const productSearch = data?.productSearch;\n\n const transformedResponse: ProductSearchResult = {\n facets: transformFacets(productSearch?.facets || [], searchVariables),\n items: productSearch?.items.map((product: any) => transformProduct(product?.productView)) || [],\n pageInfo: {\n currentPage: productSearch?.page_info?.current_page || 1,\n totalPages: productSearch?.page_info?.total_pages || 1,\n totalItems: productSearch?.page_info?.total_items || 0,\n pageSize: productSearch?.page_info?.page_size || 10, //replace with default constant\n },\n totalCount: productSearch?.total_count || 0,\n metadata: {\n filterableAttributes: data?.attributeMetadata?.filterableInSearch || [],\n sortableAttributes: transformSortAttributes(data?.attributeMetadata?.sortable || [], searchVariables),\n }\n };\n return merge(\n transformedResponse, // default transformer\n config.getConfig().models?.ProductSearchResult?.transformer?.(data), // custom transformer\n );\n}\n\nexport const transformSearchResultProducts = (searchResponse: { productSearch: { items: any[] } }): Product[] =>\n searchResponse?.productSearch?.items?.reduce<Product[]>((returnedProductList, productItem) => {\n if (!productItem?.productView) return returnedProductList; // Skip if no productView and product is null\n\n const transformed = transformProduct(productItem.productView);\n if (transformed) {\n returnedProductList.push(transformed);\n }\n\n return returnedProductList;\n }, []) || [];\n\nfunction transformSortAttributes(sortableAttributes: any[] = [], searchVariables?: SearchVariables): any[] {\n if (!sortableAttributes || sortableAttributes.length === 0) {\n return [];\n }\n\n return sortableAttributes\n .filter((option) => {\n // Only include position attribute if there's a category filter\n if (option.attribute === 'position') {\n const hasCategoryFilter = searchVariables?.filter?.some(\n (filter) => filter.attribute === 'categoryPath'\n );\n return hasCategoryFilter;\n }\n\n // Include all other attributes\n return true;\n })\n .map((option) => ({\n ...option,\n bidirectional: option.attribute === 'price',\n }));\n}\n\nfunction transformFacets(facets: any[] = [], searchVariables?: SearchVariables): any[] {\n if (!facets || facets.length === 0) {\n return [];\n }\n\n const hasCategoryPathFilter = searchVariables?.filter?.some(\n (filter) => filter.attribute === 'categoryPath'\n );\n\n // if hasCategoryPathFilter, then we need to remove facets with attribute 'categories'\n if (hasCategoryPathFilter) {\n return facets.filter((facet) => facet.attribute !== 'categories');\n }\n\n return facets;\n}\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nconst Facet = /* GraphQL */ `\n fragment Facet on Aggregation {\n title\n attribute\n buckets {\n title\n __typename\n ... on CategoryView {\n name\n count\n path\n }\n ... on ScalarBucket {\n count\n }\n ... on RangeBucket {\n from\n to\n count\n }\n ... on StatsBucket {\n min\n max\n }\n }\n }\n`;\n\nconst ProductView = /* GraphQL */ `\n fragment ProductView on ProductSearchItem {\n productView {\n __typename\n sku\n name\n inStock\n url\n urlKey\n attributes(roles: []) {\n name\n label\n value\n roles\n }\n images {\n label\n url\n roles\n }\n ... on ComplexProductView {\n priceRange {\n maximum {\n final {\n amount {\n value\n currency\n }\n }\n regular {\n amount {\n value\n currency\n }\n }\n }\n minimum {\n final {\n amount {\n value\n currency\n }\n }\n regular {\n amount {\n value\n currency\n }\n }\n }\n }\n options {\n id\n title\n values {\n title\n ... on ProductViewOptionValueSwatch {\n id\n inStock\n type\n value\n }\n }\n }\n }\n ... on SimpleProductView {\n price {\n final {\n amount {\n value\n currency\n }\n }\n regular {\n amount {\n value\n currency\n }\n }\n }\n }\n }\n highlights {\n attribute\n value\n matched_words\n }\n }\n`;\n\nexport { Facet, ProductView };\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { Facet, ProductView } from '../../graphql/fragments.graphql';\n\nconst PRODUCT_SEARCH_QUERY = /* GraphQL */ `\n query productSearch(\n $phrase: String!\n $pageSize: Int\n $currentPage: Int = 1\n $filter: [SearchClauseInput!]\n $sort: [ProductSearchSortInput!]\n $context: QueryContextInput\n ) {\n attributeMetadata {\n sortable {\n label\n attribute\n numeric\n }\n filterableInSearch {\n label\n attribute\n numeric\n }\n }\n\n productSearch(\n phrase: $phrase\n page_size: $pageSize\n current_page: $currentPage\n filter: $filter\n sort: $sort\n context: $context\n ) {\n total_count\n items {\n ...ProductView\n }\n facets {\n ...Facet\n }\n page_info {\n current_page\n page_size\n total_pages\n }\n }\n }\n ${ProductView}\n ${Facet}\n`;\n\nexport { PRODUCT_SEARCH_QUERY };\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { ProductSearchResponse } from '@/plp/data/models/api';\nimport {\n SearchFilter,\n SearchInput,\n SearchInputUnit,\n SearchSort,\n SearchResults,\n SearchResultUnit,\n SearchResultSuggestion,\n SearchFacetContext,\n SearchBucket,\n SearchResultProduct,\n} from '@/plp/data/models/acdl';\n\nconst SEARCH_INPUT_CONTEXT = 'searchInputContext';\nconst SEARCH_RESULTS_CONTEXT = 'searchResultsContext';\nconst PLP_UNIT_ID = 'livesearch-plp';\nconst SEARCH_UNIT_ID = 'livesearch-popover';\n//const SEARCH_CATEGORY_CLICK = 'search-category-click';\nconst SEARCH_PRODUCT_CLICK = 'search-product-click';\nconst SEARCH_REQUEST_SENT = 'search-request-sent';\nconst SEARCH_RESPONSE_RECEIVED = 'search-response-received';\nconst SEARCH_RESULTS_VIEW = 'search-results-view';\nconst CATEGORY_RESULTS_VIEW = 'category-results-view';\nconst CHANNEL_CONTEXT = 'channelContext';\n\nfunction getAdobeDataLayer() {\n // @ts-ignore\n window.adobeDataLayer = window.adobeDataLayer || [];\n // @ts-ignore\n return window.adobeDataLayer;\n}\n\n// Get a context from ACDL\nfunction getContext<T>(name?: string): T {\n const adobeDataLayer = getAdobeDataLayer();\n return adobeDataLayer.getState ? adobeDataLayer.getState(name) : ({} as T);\n}\n\nfunction setContext(name: string, data: any) {\n const adobeDataLayer = getAdobeDataLayer();\n\n // Clear existing context\n adobeDataLayer.push({\n [name]: null,\n });\n\n // Set new context\n adobeDataLayer.push({\n [name]: data,\n });\n}\n\nfunction getChannelContext() {\n return {\n _id: \"https://ns.adobe.com/xdm/channels/web\",\n _type: \"https://ns.adobe.com/xdm/channel-types/web\",\n };\n}\n\nfunction setChannelContext() {\n setContext(CHANNEL_CONTEXT, getChannelContext());\n}\n\nfunction pushEvent(event: string, additionalContext?: any) {\n const adobeDataLayer = getAdobeDataLayer();\n\n adobeDataLayer.push((acdl: any) => {\n const state = acdl.getState ? acdl.getState() : {};\n\n acdl.push({\n event,\n eventInfo: {\n ...state,\n ...additionalContext,\n },\n });\n });\n}\n\nconst searchRequestSent = (searchUnitId: string) => {\n setChannelContext();\n pushEvent(SEARCH_REQUEST_SENT, { searchUnitId });\n};\n\nconst searchResponseReceived = (searchUnitId: string) => {\n setChannelContext();\n pushEvent(SEARCH_RESPONSE_RECEIVED, { searchUnitId });\n};\n\nconst categoryResultsView = (searchUnitId: string) => {\n pushEvent(CATEGORY_RESULTS_VIEW, { searchUnitId });\n};\n\nconst searchResultsView = (searchUnitId: string) => {\n pushEvent(SEARCH_RESULTS_VIEW, { searchUnitId });\n};\n\nconst searchProductClick = (sku: string, searchUnitId: string) => {\n pushEvent(SEARCH_PRODUCT_CLICK, { sku, searchUnitId });\n};\n\nconst updateSearchInputCtx = (\n searchUnitId: string,\n searchRequestId: string,\n phrase: string,\n filters: Array<SearchFilter>,\n pageSize: number,\n currentPage: number,\n sort: Array<SearchSort>,\n): void => {\n const acdl = getAdobeDataLayer;\n if (!acdl) {\n // don't break search if events are broken/not loading\n return;\n }\n\n const searchInputCtx: SearchInput = getContext(SEARCH_INPUT_CONTEXT) || {};\n if (!searchInputCtx?.units) {\n searchInputCtx.units = [];\n }\n\n // create search input unit\n const searchInputUnit: SearchInputUnit = {\n searchUnitId,\n searchRequestId,\n queryTypes: ['products', 'suggestions'],\n phrase,\n pageSize,\n currentPage,\n filter: filters,\n sort,\n };\n\n // find search input unit index\n const searchInputUnitIndex = searchInputCtx.units.findIndex((unit) => unit.searchUnitId === searchUnitId);\n\n // update search input unit\n if (searchInputUnitIndex < 0) {\n searchInputCtx.units.push(searchInputUnit);\n } else {\n searchInputCtx.units[searchInputUnitIndex] = searchInputUnit;\n }\n\n setContext(SEARCH_INPUT_CONTEXT, searchInputCtx);\n};\n\nconst updateSearchResultsCtx = (\n searchUnitId: string,\n searchRequestId: string,\n results: ProductSearchResponse['productSearch'],\n): void => {\n const acdl = getAdobeDataLayer;\n if (!acdl) {\n // don't break search if events are broken/not loading\n return;\n }\n const searchResultsCtx: SearchResults = getContext(SEARCH_RESULTS_CONTEXT) || {};\n if (!searchResultsCtx?.units) {\n searchResultsCtx.units = [];\n }\n\n // find search result unit index\n const searchResultUnitIndex = searchResultsCtx.units.findIndex((unit) => unit.searchUnitId === searchUnitId);\n\n // create search result unit\n const searchResultUnit: SearchResultUnit = {\n searchUnitId,\n searchRequestId,\n products: createProducts(results.items),\n categories: [],\n suggestions: createSuggestions(results.suggestions),\n page: results?.pageInfo?.currentPage || 1,\n perPage: results?.pageInfo?.pageSize || 20,\n facets: createFacets(results.facets as SearchFacetContext[]),\n };\n\n // update search result unit\n if (searchResultUnitIndex < 0) {\n searchResultsCtx.units.push(searchResultUnit);\n } else {\n searchResultsCtx.units[searchResultUnitIndex] = searchResultUnit;\n }\n\n setContext(SEARCH_RESULTS_CONTEXT, searchResultsCtx);\n};\n\nconst createProducts = (items: ProductSearchResponse['productSearch']['items']): SearchResultProduct[] => {\n if (!items) {\n return [];\n }\n\n const products: SearchResultProduct[] = items.map((item, index) => ({\n name: item?.name,\n sku: item?.sku,\n url: item?.url ?? '',\n imageUrl: item?.images[0]?.url ?? '',\n price: item?.price?.final?.amount?.value ?? item?.priceRange?.minimum?.regular?.amount?.value,\n rank: index,\n }));\n\n return products;\n};\n\nconst createSuggestions = (items: ProductSearchResponse['productSearch']['suggestions']): SearchResultSuggestion[] => {\n if (!items) {\n return [];\n }\n\n const suggestions: SearchResultSuggestion[] = items.map((suggestion, index) => ({\n suggestion,\n rank: index,\n }));\n\n return suggestions;\n};\n\nconst createFacets = (items: SearchFacetContext[]): SearchFacetContext[] => {\n if (!items) {\n return [];\n }\n\n const facets = items.map<SearchFacetContext>((item) => ({\n attribute: item?.attribute,\n title: item?.title,\n type: item?.type || 'PINNED',\n buckets: item?.buckets.map<SearchBucket>((bucket: any) => bucket),\n }));\n\n return facets;\n};\n\nexport {\n searchRequestSent,\n searchResponseReceived,\n categoryResultsView,\n searchResultsView,\n searchProductClick,\n updateSearchInputCtx,\n updateSearchResultsCtx,\n PLP_UNIT_ID,\n SEARCH_UNIT_ID,\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { ProductSearchResult, Scope, SearchVariables } from '@/plp/data/models';\nimport { fetchGraphQl } from '@/plp/api';\nimport { transformProductSearchResponse } from '@/plp/data/transforms';\nimport { events } from '@adobe-commerce/event-bus';\nimport { PRODUCT_SEARCH_QUERY } from './graphql/search.graphql';\nimport { \n searchRequestSent, \n searchResponseReceived, \n updateSearchInputCtx,\n updateSearchResultsCtx,\n SEARCH_UNIT_ID, \n PLP_UNIT_ID,\n} from '@/plp/utils/acdlEvents';\n\ntype SearchOptions = {\n scope?: Scope;\n};\n\nexport const search = async (\n request: SearchVariables | null,\n options: SearchOptions = {},\n): Promise<ProductSearchResult> => {\n const scope = options.scope === 'search' ? undefined : options.scope;\n // empty result\n const emptyResult = {\n request: request || {} ,\n result: {\n facets: [],\n pageInfo: { currentPage: 0, totalPages: 0, totalItems: 0, pageSize: 0 },\n items: [],\n totalCount: 0,\n suggestions: [],\n metadata: {\n filterableAttributes: [],\n sortableAttributes: []\n }\n }\n };\n\n // clear search results if no request are provided\n if (request === null) {\n events.emit('search/result', emptyResult, { scope });\n return emptyResult.result;\n }\n\n\n // Emit loading state\n events.emit('search/loading', true, { scope });\n\n try {\n const acdlUnitId = scope === 'popover' ? SEARCH_UNIT_ID : PLP_UNIT_ID;\n const searchRequestId = window.crypto.randomUUID();\n\n const resolvedRequest: SearchVariables = {\n ...request,\n phrase: request.phrase ?? '',\n currentPage: request.currentPage ?? 1,\n sort: request.sort ?? [],\n filter: request.filter ?? [],\n };\n\n updateSearchInputCtx(\n acdlUnitId,\n searchRequestId,\n resolvedRequest.phrase || '',\n resolvedRequest.filter || [],\n resolvedRequest.pageSize || 0,\n resolvedRequest.currentPage || 0,\n resolvedRequest.sort || [],\n );\n\n // Publish search request event to ACDL\n searchRequestSent(acdlUnitId);\n\n // Execute search with validated request\n const { errors, data } = await fetchGraphQl(PRODUCT_SEARCH_QUERY, {\n method: 'GET',\n variables: { ...resolvedRequest },\n });\n\n if (errors && !data) {\n throw new Error('Error fetching product search');\n }\n\n const result = transformProductSearchResponse(data, resolvedRequest);\n\n // Update search results context in ACDL\n updateSearchResultsCtx(acdlUnitId, searchRequestId, result);\n\n // Publish search response event to ACDL\n searchResponseReceived(acdlUnitId);\n\n // Emit single event with result and metadata\n events.emit('search/result', { request: resolvedRequest, result }, { scope });\n\n return result;\n\n } catch (error) {\n // Emit error event\n events.emit('search/error', (error as Error).message, { scope });\n\n // Emit result event with empty result\n events.emit('search/result', emptyResult, { scope });\n\n throw error;\n } finally {\n // Reset loading state\n events.emit('search/loading', false, { scope });\n }\n};"],"names":["initialize","Initializer","config","defaultConfig","setEndpoint","setFetchGraphQlHeader","removeFetchGraphQlHeader","setFetchGraphQlHeaders","getFetchGraphQlHeader","fetchGraphQl","getConfig","FetchGraphQL","getCurrency","currency","transformProduct","data","transformedProduct","_a","attr","_b","image","_e","_d","_c","_h","_g","_f","_k","_j","_i","_n","_m","_l","_o","_s","_r","_q","_p","_w","_v","_u","_t","_A","_z","_y","_x","_E","_D","_C","_B","_I","_H","_G","_F","_M","_L","_K","_J","_Q","_P","_O","_N","_U","_T","_S","_R","merge","_X","_W","_V","transformProductSearchResponse","searchVariables","productSearch","transformedResponse","transformFacets","product","transformSortAttributes","sortableAttributes","option","filter","facets","facet","Facet","ProductView","PRODUCT_SEARCH_QUERY","SEARCH_INPUT_CONTEXT","SEARCH_RESULTS_CONTEXT","PLP_UNIT_ID","SEARCH_UNIT_ID","SEARCH_PRODUCT_CLICK","SEARCH_REQUEST_SENT","SEARCH_RESPONSE_RECEIVED","SEARCH_RESULTS_VIEW","CATEGORY_RESULTS_VIEW","CHANNEL_CONTEXT","getAdobeDataLayer","getContext","name","adobeDataLayer","setContext","getChannelContext","setChannelContext","pushEvent","event","additionalContext","acdl","state","searchRequestSent","searchUnitId","searchResponseReceived","categoryResultsView","searchResultsView","searchProductClick","sku","updateSearchInputCtx","searchRequestId","phrase","filters","pageSize","currentPage","sort","searchInputCtx","searchInputUnit","searchInputUnitIndex","unit","updateSearchResultsCtx","results","searchResultsCtx","searchResultUnitIndex","searchResultUnit","createProducts","createSuggestions","createFacets","items","item","index","suggestion","bucket","search","request","options","scope","emptyResult","events","acdlUnitId","resolvedRequest","errors","result","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.js","sources":["/@dropins/storefront-product-discovery/src/api/initialize/initialize.ts","/@dropins/storefront-product-discovery/src/api/fetch-graphql/fetch-graphql.ts","/@dropins/storefront-product-discovery/src/data/transforms/product.ts","/@dropins/storefront-product-discovery/src/data/transforms/api.ts","/@dropins/storefront-product-discovery/src/api/search/graphql/search.graphql.ts","/@dropins/storefront-product-discovery/src/utils/acdlEvents.ts","/@dropins/storefront-product-discovery/src/api/search/search.ts"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { Initializer, Model } from '@adobe-commerce/elsie/lib';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { Product } from '@/plp/data/models/product';\nimport { ProductSearchResult } from '@/plp/data/models';\n\ntype ConfigProps = {\n langDefinitions?: Lang;\n\n models?: {\n Product?: Model<Product>\n ProductSearchResult?: Model<ProductSearchResult>\n }\n};\n\nexport const initialize = new Initializer<ConfigProps>({\n init: async (config) => {\n const defaultConfig = {};\n\n initialize.config.setConfig({ ...defaultConfig, ...config });\n },\n\n listeners: () => [],\n});\n\nexport const config = initialize.config;\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { FetchGraphQL } from '@adobe-commerce/fetch-graphql';\n\nexport const {\n setEndpoint,\n setFetchGraphQlHeader,\n removeFetchGraphQlHeader,\n setFetchGraphQlHeaders,\n getFetchGraphQlHeader,\n fetchGraphQl,\n getConfig,\n} = new FetchGraphQL().getMethods();\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\nimport { merge } from '@adobe-commerce/elsie/lib';\nimport { config } from '@/plp/api/initialize/initialize';\nimport { Product } from '../models/product';\n\nconst getCurrency = (currency?: string) => {\n if (!currency || !Intl.supportedValuesOf(\"currency\").includes(currency)) {\n return 'USD';\n }\n return currency;\n};\n\nexport const transformProduct = (data: any): Product | null => {\n // check if data is null or undefined, and if so return an empty object\n if (!data) {\n return {\n id: '',\n name: '',\n sku: '',\n shortDescription: '',\n url: '',\n urlKey: '',\n metaTitle: '',\n metaKeywords: '',\n metaDescription: '',\n lowStock: false,\n links: [],\n attributes: [],\n images: [],\n description: '',\n externalId: '',\n inputOptions: [],\n addToCartAllowed: false,\n price: undefined,\n priceRange: undefined,\n inStock: false,\n typename: '',\n };\n }\n\n const transformedProduct = {\n id: data?.id || '',\n name: data?.name || '',\n sku: data?.sku || '',\n shortDescription: data?.shortDescription || '',\n url: data?.url || '',\n urlKey: data?.urlKey || '',\n metaTitle: data?.metaTitle || '',\n metaKeywords: data?.metaKeywords || '',\n metaDescription: data?.metaDescription || '',\n lowStock: data?.lowStock || false,\n links: data?.links || [],\n attributes:\n data?.attributes?.map((attr: any) => ({\n label: attr.label || '',\n name: attr.name || '',\n roles: attr.roles || [],\n value: attr.value ?? null,\n })) || [],\n images:\n data?.images?.map((image: any) => ({\n label: image.label || '',\n roles: image.roles || [],\n url: image.url?.replace(/^https?:\\/\\//, '//') || '',\n })) || [],\n description: data?.description || '',\n externalId: data?.externalId || '',\n inputOptions: data?.inputOptions || [],\n addToCartAllowed: data?.addToCartAllowed || false,\n price: data.price\n ? {\n final: {\n amount: {\n value: data?.price?.final?.amount?.value || 0,\n currency: getCurrency(data?.price?.final?.amount?.currency),\n },\n },\n regular: {\n amount: {\n value: data?.price?.regular?.amount?.value || 0,\n currency: getCurrency(data?.price?.regular?.amount?.currency),\n },\n },\n roles: data?.price?.roles || [],\n }\n : undefined,\n priceRange: data?.priceRange\n ? {\n minimum: {\n final: {\n amount: {\n value: data?.priceRange?.minimum?.final?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.minimum?.final?.amount?.currency),\n },\n },\n regular: {\n amount: {\n value: data?.priceRange?.minimum?.regular?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.minimum?.regular?.amount?.currency),\n },\n },\n },\n maximum: {\n final: {\n amount: {\n value: data?.priceRange?.maximum?.final?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.maximum?.final?.amount?.currency),\n },\n },\n regular: {\n amount: {\n value: data?.priceRange?.maximum?.regular?.amount?.value || 0,\n currency: getCurrency(data?.priceRange?.maximum?.regular?.amount?.currency),\n },\n },\n },\n }\n : undefined,\n inStock: data?.inStock || false,\n typename: data?.__typename || '',\n };\n\n return merge(\n transformedProduct, // default transformer\n config.getConfig().models?.Product?.transformer?.(data), // custom transformer\n )\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\nimport { merge } from '@adobe-commerce/elsie/lib';\nimport { config } from '@/plp/api/initialize/initialize';\nimport { ProductSearchResult, SearchVariables } from '@/plp/data/models';\nimport { Product } from '@/plp/data/models/product';\n\nimport { transformProduct } from './product';\n\n\nexport function transformProductSearchResponse(data: any, searchVariables?: SearchVariables): ProductSearchResult {\n const productSearch = data?.productSearch;\n\n const transformedResponse: ProductSearchResult = {\n facets: transformFacets(productSearch?.facets || [], searchVariables),\n items: productSearch?.items.map((product: any) => transformProduct(product?.productView)) || [],\n pageInfo: {\n currentPage: productSearch?.page_info?.current_page || 1,\n totalPages: productSearch?.page_info?.total_pages || 1,\n totalItems: productSearch?.page_info?.total_items || 0,\n pageSize: productSearch?.page_info?.page_size || 10, //replace with default constant\n },\n totalCount: productSearch?.total_count || 0,\n metadata: {\n filterableAttributes: data?.attributeMetadata?.filterableInSearch || [],\n sortableAttributes: transformSortAttributes(data?.attributeMetadata?.sortable || [], searchVariables),\n }\n };\n return merge(\n transformedResponse, // default transformer\n config.getConfig().models?.ProductSearchResult?.transformer?.(data), // custom transformer\n );\n}\n\nexport const transformSearchResultProducts = (searchResponse: { productSearch: { items: any[] } }): Product[] =>\n searchResponse?.productSearch?.items?.reduce<Product[]>((returnedProductList, productItem) => {\n if (!productItem?.productView) return returnedProductList; // Skip if no productView and product is null\n\n const transformed = transformProduct(productItem.productView);\n if (transformed) {\n returnedProductList.push(transformed);\n }\n\n return returnedProductList;\n }, []) || [];\n\nfunction transformSortAttributes(sortableAttributes: any[] = [], searchVariables?: SearchVariables): any[] {\n if (!sortableAttributes || sortableAttributes.length === 0) {\n return [];\n }\n\n return sortableAttributes\n .filter((option) => {\n // Only include position attribute if there's a category filter\n if (option.attribute === 'position') {\n const hasCategoryFilter = searchVariables?.filter?.some(\n (filter) => filter.attribute === 'categoryPath'\n );\n return hasCategoryFilter;\n }\n\n // Include all other attributes\n return true;\n })\n .map((option) => ({\n ...option,\n bidirectional: option.attribute === 'price',\n }));\n}\n\nfunction transformFacets(facets: any[] = [], searchVariables?: SearchVariables): any[] {\n if (!facets || facets.length === 0) {\n return [];\n }\n\n const hasCategoryPathFilter = searchVariables?.filter?.some(\n (filter) => filter.attribute === 'categoryPath'\n );\n\n // if hasCategoryPathFilter, then we need to remove facets with attribute 'categories'\n if (hasCategoryPathFilter) {\n return facets.filter((facet) => facet.attribute !== 'categories');\n }\n\n return facets;\n}\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { Facet, ProductView } from '../../graphql/fragments.graphql';\n\nconst PRODUCT_SEARCH_QUERY = /* GraphQL */ `\n query productSearch(\n $phrase: String!\n $pageSize: Int\n $currentPage: Int = 1\n $filter: [SearchClauseInput!]\n $sort: [ProductSearchSortInput!]\n $context: QueryContextInput\n ) {\n attributeMetadata {\n sortable {\n label\n attribute\n numeric\n }\n filterableInSearch {\n label\n attribute\n numeric\n }\n }\n\n productSearch(\n phrase: $phrase\n page_size: $pageSize\n current_page: $currentPage\n filter: $filter\n sort: $sort\n context: $context\n ) {\n total_count\n items {\n ...ProductView\n }\n facets {\n ...Facet\n }\n page_info {\n current_page\n page_size\n total_pages\n }\n }\n }\n ${ProductView}\n ${Facet}\n`;\n\nexport { PRODUCT_SEARCH_QUERY };\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { ProductSearchResponse } from '@/plp/data/models/api';\nimport {\n SearchFilter,\n SearchInput,\n SearchInputUnit,\n SearchSort,\n SearchResults,\n SearchResultUnit,\n SearchResultSuggestion,\n SearchFacetContext,\n SearchBucket,\n SearchResultProduct,\n} from '@/plp/data/models/acdl';\n\nconst SEARCH_INPUT_CONTEXT = 'searchInputContext';\nconst SEARCH_RESULTS_CONTEXT = 'searchResultsContext';\nconst PLP_UNIT_ID = 'livesearch-plp';\nconst SEARCH_UNIT_ID = 'livesearch-popover';\n//const SEARCH_CATEGORY_CLICK = 'search-category-click';\nconst SEARCH_PRODUCT_CLICK = 'search-product-click';\nconst SEARCH_REQUEST_SENT = 'search-request-sent';\nconst SEARCH_RESPONSE_RECEIVED = 'search-response-received';\nconst SEARCH_RESULTS_VIEW = 'search-results-view';\nconst CATEGORY_RESULTS_VIEW = 'category-results-view';\nconst CHANNEL_CONTEXT = 'channelContext';\n\nfunction getAdobeDataLayer() {\n // @ts-ignore\n window.adobeDataLayer = window.adobeDataLayer || [];\n // @ts-ignore\n return window.adobeDataLayer;\n}\n\n// Get a context from ACDL\nfunction getContext<T>(name?: string): T {\n const adobeDataLayer = getAdobeDataLayer();\n return adobeDataLayer.getState ? adobeDataLayer.getState(name) : ({} as T);\n}\n\nfunction setContext(name: string, data: any) {\n const adobeDataLayer = getAdobeDataLayer();\n\n // Clear existing context\n adobeDataLayer.push({\n [name]: null,\n });\n\n // Set new context\n adobeDataLayer.push({\n [name]: data,\n });\n}\n\nfunction getChannelContext() {\n return {\n _id: \"https://ns.adobe.com/xdm/channels/web\",\n _type: \"https://ns.adobe.com/xdm/channel-types/web\",\n };\n}\n\nfunction setChannelContext() {\n setContext(CHANNEL_CONTEXT, getChannelContext());\n}\n\nfunction pushEvent(event: string, additionalContext?: any) {\n const adobeDataLayer = getAdobeDataLayer();\n\n adobeDataLayer.push((acdl: any) => {\n const state = acdl.getState ? acdl.getState() : {};\n\n acdl.push({\n event,\n eventInfo: {\n ...state,\n ...additionalContext,\n },\n });\n });\n}\n\nconst searchRequestSent = (searchUnitId: string) => {\n setChannelContext();\n pushEvent(SEARCH_REQUEST_SENT, { searchUnitId });\n};\n\nconst searchResponseReceived = (searchUnitId: string) => {\n setChannelContext();\n pushEvent(SEARCH_RESPONSE_RECEIVED, { searchUnitId });\n};\n\nconst categoryResultsView = (searchUnitId: string) => {\n pushEvent(CATEGORY_RESULTS_VIEW, { searchUnitId });\n};\n\nconst searchResultsView = (searchUnitId: string) => {\n pushEvent(SEARCH_RESULTS_VIEW, { searchUnitId });\n};\n\nconst searchProductClick = (sku: string, searchUnitId: string) => {\n pushEvent(SEARCH_PRODUCT_CLICK, { sku, searchUnitId });\n};\n\nconst updateSearchInputCtx = (\n searchUnitId: string,\n searchRequestId: string,\n phrase: string,\n filters: Array<SearchFilter>,\n pageSize: number,\n currentPage: number,\n sort: Array<SearchSort>,\n): void => {\n const acdl = getAdobeDataLayer;\n if (!acdl) {\n // don't break search if events are broken/not loading\n return;\n }\n\n const searchInputCtx: SearchInput = getContext(SEARCH_INPUT_CONTEXT) || {};\n if (!searchInputCtx?.units) {\n searchInputCtx.units = [];\n }\n\n // create search input unit\n const searchInputUnit: SearchInputUnit = {\n searchUnitId,\n searchRequestId,\n queryTypes: ['products', 'suggestions'],\n phrase,\n pageSize,\n currentPage,\n filter: filters,\n sort,\n };\n\n // find search input unit index\n const searchInputUnitIndex = searchInputCtx.units.findIndex((unit) => unit.searchUnitId === searchUnitId);\n\n // update search input unit\n if (searchInputUnitIndex < 0) {\n searchInputCtx.units.push(searchInputUnit);\n } else {\n searchInputCtx.units[searchInputUnitIndex] = searchInputUnit;\n }\n\n setContext(SEARCH_INPUT_CONTEXT, searchInputCtx);\n};\n\nconst updateSearchResultsCtx = (\n searchUnitId: string,\n searchRequestId: string,\n results: ProductSearchResponse['productSearch'],\n): void => {\n const acdl = getAdobeDataLayer;\n if (!acdl) {\n // don't break search if events are broken/not loading\n return;\n }\n const searchResultsCtx: SearchResults = getContext(SEARCH_RESULTS_CONTEXT) || {};\n if (!searchResultsCtx?.units) {\n searchResultsCtx.units = [];\n }\n\n // find search result unit index\n const searchResultUnitIndex = searchResultsCtx.units.findIndex((unit) => unit.searchUnitId === searchUnitId);\n\n // create search result unit\n const searchResultUnit: SearchResultUnit = {\n searchUnitId,\n searchRequestId,\n products: createProducts(results.items),\n categories: [],\n suggestions: createSuggestions(results.suggestions),\n page: results?.pageInfo?.currentPage || 1,\n perPage: results?.pageInfo?.pageSize || 20,\n facets: createFacets(results.facets as SearchFacetContext[]),\n };\n\n // update search result unit\n if (searchResultUnitIndex < 0) {\n searchResultsCtx.units.push(searchResultUnit);\n } else {\n searchResultsCtx.units[searchResultUnitIndex] = searchResultUnit;\n }\n\n setContext(SEARCH_RESULTS_CONTEXT, searchResultsCtx);\n};\n\nconst createProducts = (items: ProductSearchResponse['productSearch']['items']): SearchResultProduct[] => {\n if (!items) {\n return [];\n }\n\n const products: SearchResultProduct[] = items.map((item, index) => ({\n name: item?.name,\n sku: item?.sku,\n url: item?.url ?? '',\n imageUrl: item?.images[0]?.url ?? '',\n price: item?.price?.final?.amount?.value ?? item?.priceRange?.minimum?.regular?.amount?.value,\n rank: index,\n }));\n\n return products;\n};\n\nconst createSuggestions = (items: ProductSearchResponse['productSearch']['suggestions']): SearchResultSuggestion[] => {\n if (!items) {\n return [];\n }\n\n const suggestions: SearchResultSuggestion[] = items.map((suggestion, index) => ({\n suggestion,\n rank: index,\n }));\n\n return suggestions;\n};\n\nconst createFacets = (items: SearchFacetContext[]): SearchFacetContext[] => {\n if (!items) {\n return [];\n }\n\n const facets = items.map<SearchFacetContext>((item) => ({\n attribute: item?.attribute,\n title: item?.title,\n type: item?.type || 'PINNED',\n buckets: item?.buckets.map<SearchBucket>((bucket: any) => bucket),\n }));\n\n return facets;\n};\n\nexport {\n searchRequestSent,\n searchResponseReceived,\n categoryResultsView,\n searchResultsView,\n searchProductClick,\n updateSearchInputCtx,\n updateSearchResultsCtx,\n PLP_UNIT_ID,\n SEARCH_UNIT_ID,\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { ProductSearchResult, Scope, SearchVariables } from '@/plp/data/models';\nimport { fetchGraphQl } from '@/plp/api';\nimport { transformProductSearchResponse } from '@/plp/data/transforms';\nimport { events } from '@adobe-commerce/event-bus';\nimport { PRODUCT_SEARCH_QUERY } from './graphql/search.graphql';\nimport { \n searchRequestSent, \n searchResponseReceived, \n updateSearchInputCtx,\n updateSearchResultsCtx,\n SEARCH_UNIT_ID, \n PLP_UNIT_ID,\n} from '@/plp/utils/acdlEvents';\n\ntype SearchOptions = {\n scope?: Scope;\n};\n\nexport const search = async (\n request: SearchVariables | null,\n options: SearchOptions = {},\n): Promise<ProductSearchResult> => {\n const scope = options.scope === 'search' ? undefined : options.scope;\n // empty result\n const emptyResult = {\n request: request || {} ,\n result: {\n facets: [],\n pageInfo: { currentPage: 0, totalPages: 0, totalItems: 0, pageSize: 0 },\n items: [],\n totalCount: 0,\n suggestions: [],\n metadata: {\n filterableAttributes: [],\n sortableAttributes: []\n }\n }\n };\n\n // clear search results if no request are provided\n if (request === null) {\n events.emit('search/result', emptyResult, { scope });\n return emptyResult.result;\n }\n\n\n // Emit loading state\n events.emit('search/loading', true, { scope });\n\n try {\n const acdlUnitId = scope === 'popover' ? SEARCH_UNIT_ID : PLP_UNIT_ID;\n const searchRequestId = window.crypto.randomUUID();\n\n const resolvedRequest: SearchVariables = {\n ...request,\n phrase: request.phrase ?? '',\n currentPage: request.currentPage ?? 1,\n sort: request.sort ?? [],\n filter: request.filter ?? [],\n };\n\n updateSearchInputCtx(\n acdlUnitId,\n searchRequestId,\n resolvedRequest.phrase || '',\n resolvedRequest.filter || [],\n resolvedRequest.pageSize || 0,\n resolvedRequest.currentPage || 0,\n resolvedRequest.sort || [],\n );\n\n // Publish search request event to ACDL\n searchRequestSent(acdlUnitId);\n\n // Execute search with validated request\n const { errors, data } = await fetchGraphQl(PRODUCT_SEARCH_QUERY, {\n method: 'GET',\n variables: { ...resolvedRequest },\n });\n\n if (errors && !data) {\n throw new Error('Error fetching product search');\n }\n\n const result = transformProductSearchResponse(data, resolvedRequest);\n\n // Update search results context in ACDL\n updateSearchResultsCtx(acdlUnitId, searchRequestId, result);\n\n // Publish search response event to ACDL\n searchResponseReceived(acdlUnitId);\n\n // Emit single event with result and metadata\n events.emit('search/result', { request: resolvedRequest, result }, { scope });\n\n return result;\n\n } catch (error) {\n // Emit error event\n events.emit('search/error', (error as Error).message, { scope });\n\n // Emit result event with empty result\n events.emit('search/result', emptyResult, { scope });\n\n throw error;\n } finally {\n // Reset loading state\n events.emit('search/loading', false, { scope });\n }\n};"],"names":["initialize","Initializer","config","defaultConfig","setEndpoint","setFetchGraphQlHeader","removeFetchGraphQlHeader","setFetchGraphQlHeaders","getFetchGraphQlHeader","fetchGraphQl","getConfig","FetchGraphQL","getCurrency","currency","transformProduct","data","transformedProduct","_a","attr","_b","image","_e","_d","_c","_h","_g","_f","_k","_j","_i","_n","_m","_l","_o","_s","_r","_q","_p","_w","_v","_u","_t","_A","_z","_y","_x","_E","_D","_C","_B","_I","_H","_G","_F","_M","_L","_K","_J","_Q","_P","_O","_N","_U","_T","_S","_R","merge","_X","_W","_V","transformProductSearchResponse","searchVariables","productSearch","transformedResponse","transformFacets","product","transformSortAttributes","sortableAttributes","option","filter","facets","facet","PRODUCT_SEARCH_QUERY","ProductView","Facet","SEARCH_INPUT_CONTEXT","SEARCH_RESULTS_CONTEXT","PLP_UNIT_ID","SEARCH_UNIT_ID","SEARCH_PRODUCT_CLICK","SEARCH_REQUEST_SENT","SEARCH_RESPONSE_RECEIVED","SEARCH_RESULTS_VIEW","CATEGORY_RESULTS_VIEW","CHANNEL_CONTEXT","getAdobeDataLayer","getContext","name","adobeDataLayer","setContext","getChannelContext","setChannelContext","pushEvent","event","additionalContext","acdl","state","searchRequestSent","searchUnitId","searchResponseReceived","categoryResultsView","searchResultsView","searchProductClick","sku","updateSearchInputCtx","searchRequestId","phrase","filters","pageSize","currentPage","sort","searchInputCtx","searchInputUnit","searchInputUnitIndex","unit","updateSearchResultsCtx","results","searchResultsCtx","searchResultUnitIndex","searchResultUnit","createProducts","createSuggestions","createFacets","items","item","index","suggestion","bucket","search","request","options","scope","emptyResult","events","acdlUnitId","resolvedRequest","errors","result","error"],"mappings":"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"}
|
package/containers/Facets.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{jsxs as _,jsx as i,Fragment as N}from"@dropins/tools/preact-jsx-runtime.js";import{useState as w,useRef as W,useEffect as T}from"@dropins/tools/preact-compat.js";import{Slot as y}from"@dropins/tools/lib.js";import{PriceRange as A,Button as O,Icon as Y,Checkbox as G,RadioButton as H}from"@dropins/tools/components.js";import{F as J,a as K,b as M}from"../chunks/components.js";import{events as Q}from"@dropins/tools/event-bus.js";import{search as X}from"../api.js";import{useText as I}from"@dropins/tools/i18n.js";import"@dropins/tools/fetch-graphql.js";const ee="no",te="yes",re=n=>{const e=n.buckets.find(u=>u.selected);return e?{attribute:n.attribute,range:{from:e.from,to:e.to}}:null},ne=n=>{const e=n.buckets.reduce((u,g)=>(g.selected&&u.push(g.title),u),[]);return e.length===0?null:{attribute:n.attribute,in:e}},q=n=>{var e;switch((e=n.buckets[0])==null?void 0:e.__typename){case"RangeBucket":return re(n);case"ScalarBucket":case"CategoryView":return ne(n)}},ce=n=>{var u,g,
|
|
3
|
+
import{jsxs as _,jsx as i,Fragment as N}from"@dropins/tools/preact-jsx-runtime.js";import{useState as w,useRef as W,useEffect as T}from"@dropins/tools/preact-compat.js";import{Slot as y}from"@dropins/tools/lib.js";import{PriceRange as A,Button as O,Icon as Y,Checkbox as G,RadioButton as H}from"@dropins/tools/components.js";import{F as J,a as K,b as M}from"../chunks/components.js";import{events as Q}from"@dropins/tools/event-bus.js";import{search as X}from"../api.js";import{useText as I}from"@dropins/tools/i18n.js";import"../fragments.js";import"@dropins/tools/fetch-graphql.js";const ee="no",te="yes",re=n=>{const e=n.buckets.find(u=>u.selected);return e?{attribute:n.attribute,range:{from:e.from,to:e.to}}:null},ne=n=>{const e=n.buckets.reduce((u,g)=>(g.selected&&u.push(g.title),u),[]);return e.length===0?null:{attribute:n.attribute,in:e}},q=n=>{var e;switch((e=n.buckets[0])==null?void 0:e.__typename){case"RangeBucket":return re(n);case"ScalarBucket":case"CategoryView":return ne(n)}},ce=n=>{var u,g,F,R,x,p,C,b,B,f,L;const e=n[0];return(F=(g=(u=e==null?void 0:e.price)==null?void 0:u.regular)==null?void 0:g.amount)!=null&&F.currency?e.price.regular.amount.currency:(C=(p=(x=(R=e==null?void 0:e.priceRange)==null?void 0:R.minimum)==null?void 0:x.regular)==null?void 0:p.amount)!=null&&C.currency?(L=(f=(B=(b=e==null?void 0:e.priceRange)==null?void 0:b.minimum)==null?void 0:B.regular)==null?void 0:f.amount)==null?void 0:L.currency:"USD"},ae=(n,e,u)=>(e==null?void 0:e.attribute)==="price"?n.from===0?_("div",{style:"display:flex",children:[i(A,{amount:n.from,currency:u||"USD"}),i("span",{style:"padding: 0 2px",children:"-"}),i(A,{amount:n.to,currency:u||"USD"})]}):i(A,{minimumAmount:n.from,maximumAmount:n.to,currency:u||"USD",display:"dash"}):n.title,ie=(n,e)=>n.title===ee?`Not ${e.title}`:n.title===te?e.title:n.title,D=(n,e,u)=>{switch(n.__typename){case"RangeBucket":return ae(n,e,u);case"ScalarBucket":case"CategoryView":return ie(n,e)}},fe=({scope:n,slots:e})=>{const u=I({clearAll:"Search.Facet.clearAll"}),[g,F]=w([]),[R,x]=w(null),[p,C]=w(),[b,B]=w(null),f=W(null),L=r=>{const a=new Set(g.map(t=>t.attribute)),c=[...((p==null?void 0:p.filter)||[]).filter(t=>!a.has(t.attribute)),...r.filter||[]];X({...r,filter:c},{scope:n})},U=r=>{if(!r||!r.result.facets&&!r.result.items&&!r.request.filter){F([]);return}C(r.request);const{facets:a,items:s}=r.result;x(ce(s));const c=r.request.filter;if(a){const t=a.map(l=>{const m=l.buckets.map(h=>{const o=c==null?void 0:c.find(S=>S.attribute===l.attribute);if(o){const S=o.range;if(S&&h.from===S.from&&h.to===S.to)return{...h,selected:!0};if(o.in&&o.in.includes(h.title))return{...h,selected:!0}}return{...h,selected:!1}});return{...l,buckets:m}});F(t)}},z=r=>{F(a=>{const s=a.map(t=>{const l=r.find(m=>m.attribute===t.attribute);return l||t}),c=s.reduce((t,l)=>{const m=q(l);return m&&t.push(m),t},[]);return B(c),s})},E=(r,a)=>{const s=r.buckets.map(t=>t.title===a?{...t,selected:!1}:t),c={...r,buckets:s};z([c])},P=()=>{const r=g.map(a=>{const s=a.buckets.map(c=>({...c,selected:!1}));return{...a,buckets:s}});F(r),B([])},$=(r,a)=>{const s=r.target.value,c=r.target.checked;F(t=>{const l=t.find(d=>d.attribute===a);if(!l)return t;const m=l.buckets.map(d=>{var k;return((k=l.buckets[0])==null?void 0:k.__typename)==="RangeBucket"?d.title===s?{...d,selected:c}:{...d,selected:!1}:d.title===s?{...d,selected:c}:{...d}}),h={...l,buckets:m},o=t.map(d=>d.attribute===a?h:d),S=o.reduce((d,k)=>{const v=q(k);return v&&d.push(v),d},[]);return B(S),o})},V=(r,a)=>{const s=i("span",{children:r.title}),c=r.buckets.map(t=>{var h;const l=D(t,r,R),m=o=>_(y,{name:"FacetBucketLabel",slot:e==null?void 0:e.FacetBucketLabel,context:{data:t},children:[l," ",o?`(${o})`:""]});switch((h=r.buckets[0])==null?void 0:h.__typename){case"RangeBucket":return i(y,{name:"FacetBucket",slot:e==null?void 0:e.FacetBucket,context:{data:t},children:i(H,{"data-testid":`${t.title}-radio`,label:m(),name:r.attribute,value:t.title,checked:t.selected,onChange:o=>{$(o,r.attribute)}})});case"ScalarBucket":case"CategoryView":return i(y,{name:"FacetBucket",slot:e==null?void 0:e.FacetBucket,context:{data:t},children:i(G,{id:`${r.attribute}-${t.title.replace(/[^a-zA-Z0-9_-]/g,"")}`,"data-testid":`${t.title}-checkbox`,label:m(t.count),name:`${r.attribute}-${t.title.replace(/[^a-zA-Z0-9_-]/g,"")}`,value:t.title,checked:t.selected,onChange:o=>{$(o,r.attribute)}})});default:return null}}).filter(t=>t!==null);return i(M,{header:s,buckets:c,last:a===g.length-1})},j=()=>i(y,{name:"Facets",slot:e==null?void 0:e.Facets,context:{data:g},children:g.map((r,a)=>r.buckets.length>0?i(N,{children:i(y,{name:"Facet",slot:e==null?void 0:e.Facet,context:{data:r},children:V(r,a)})}):null)}),Z=()=>{const r=g.reduce((c,t)=>(t.buckets.filter(m=>m.selected).length>0&&c.push(t),c),[]),a=r.map(c=>c.buckets.map(t=>{if(t.selected){const l=D(t,c,R);return i(O,{"data-testid":`${t.title}-selected-btn`,"aria-label":`Remove ${c.title} filter: ${t.title}`,variant:"secondary",children:_(N,{children:[i("span",{children:l}),i(Y,{source:K,size:"16"})]}),onClick:()=>{E(c,t.title)}})}return null})),s=a.length>0?i(O,{variant:"secondary",onClick:()=>{P()},children:i("span",{children:u.clearAll})}):null;return _(y,{name:"SelectedFacets",slot:e==null?void 0:e.SelectedFacets,context:{data:r},children:[a,s]})};return T(()=>{const r=Q.on("search/result",U,{eager:!0,scope:n});return()=>{r==null||r.off()}},[]),T(()=>{if(b!==null)return f.current&&clearTimeout(f.current),f.current=setTimeout(()=>{p&&L({...p,filter:b,currentPage:1}),B(null)},150),()=>{f.current&&clearTimeout(f.current)}},[b,p]),i(J,{selectedFacets:Z(),facets:j()})};export{fe as Facets,fe as default};
|
|
4
4
|
//# sourceMappingURL=Facets.js.map
|
package/containers/Facets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Facets.js","sources":["/@dropins/storefront-product-discovery/src/containers/Facets/utils/facetUtils.tsx","/@dropins/storefront-product-discovery/src/containers/Facets/Facets.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { SearchFacet } from '@/plp/data/models/api';\nimport { Product } from '@/plp/data/models/product';\nimport { PriceRange } from '@adobe-commerce/elsie/components';\n\nconst BOOLEAN_NO = 'no';\nconst BOOLEAN_YES = 'yes';\n\nconst getRangeFacetFilter = (facet: SearchFacet) => {\n const selectedRange = facet.buckets.find((bucket) => bucket.selected);\n if (!selectedRange) {\n return null;\n }\n return {\n attribute: facet.attribute,\n range: {\n from: selectedRange.from,\n to: selectedRange.to,\n },\n };\n};\n\nconst getScalarFacetFilter = (facet: SearchFacet) => {\n const scalarSelections = facet.buckets.reduce((accu, curr) => {\n if (curr.selected) {\n accu.push(curr.title);\n }\n return accu;\n }, [] as string[]);\n if (scalarSelections.length === 0) {\n return null;\n }\n return {\n attribute: facet.attribute,\n in: scalarSelections,\n };\n};\n\nconst getFilterSelection = (facet: SearchFacet) => {\n switch (facet.buckets[0]?.__typename) {\n case 'RangeBucket':\n return getRangeFacetFilter(facet);\n case 'ScalarBucket':\n case 'CategoryView':\n return getScalarFacetFilter(facet);\n default:\n break;\n }\n};\n\nconst getCurrencyType = (items: Product[]) => {\n const firstItem = items[0];\n if (firstItem?.price?.regular?.amount?.currency) {\n return firstItem.price.regular.amount.currency;\n } else if (firstItem?.priceRange?.minimum?.regular?.amount?.currency) {\n return firstItem?.priceRange?.minimum?.regular?.amount?.currency;\n }\n return 'USD'; // Default currency if not found\n};\n\nconst getRangeBucketLabel = (bucket: any, facet: SearchFacet, currency: string | null) => {\n if (facet?.attribute === 'price') {\n //Temp fix for Price range not handling value when minumum is zero\n if (bucket.from === 0) {\n return (\n <div style={'display:flex'}>\n <PriceRange amount={bucket.from} currency={currency || 'USD'} />\n <span style={'padding: 0 2px'}>{'-'}</span>\n <PriceRange amount={bucket.to} currency={currency || 'USD'} />\n </div>\n );\n }\n return (\n <PriceRange minimumAmount={bucket.from} maximumAmount={bucket.to} currency={currency || 'USD'} display=\"dash\" />\n );\n }\n return bucket.title;\n};\n\nconst getScalarBucketLabel = (bucket: any, facet: SearchFacet) => {\n if (bucket.title === BOOLEAN_NO) {\n return `Not ${facet.title}`;\n } else if (bucket.title === BOOLEAN_YES) {\n return facet.title;\n }\n return bucket.title;\n};\n\nconst getBucketLabel = (bucket: any, facet: SearchFacet, currency: string | null) => {\n switch (bucket.__typename) {\n case 'RangeBucket':\n return getRangeBucketLabel(bucket, facet, currency);\n case 'ScalarBucket':\n case 'CategoryView':\n return getScalarBucketLabel(bucket, facet);\n default:\n break;\n }\n};\n\nexport { getBucketLabel, getCurrencyType, getFilterSelection };\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { HTMLAttributes, useEffect, useState, useRef } from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { ProductSearchResult, SearchFilter, SearchFacet, SearchVariables, FacetBucket, Scope } from '@/plp/data/models/api';\nimport { getBucketLabel, getCurrencyType, getFilterSelection } from './utils/facetUtils';\nimport FacetList from '@/plp/components/FacetList';\nimport { Button, Checkbox, Icon, RadioButton } from '@adobe-commerce/elsie/components';\nimport { Facet } from '@/plp/components';\nimport { VNode } from 'preact';\nimport { Close } from '@adobe-commerce/elsie/icons';\nimport { events } from '@adobe-commerce/event-bus';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { search } from '@/plp/api';\n\nexport interface FacetsProps extends HTMLAttributes<HTMLDivElement> {\n scope?: Scope;\n slots?: {\n Facet?: SlotProps<{ data: SearchFacet }>;\n SelectedFacets?: SlotProps<{ data: SearchFacet[] }>;\n Facets?: SlotProps<{ data: SearchFacet[] }>;\n FacetBucket?: SlotProps<{ data: FacetBucket }>;\n FacetBucketLabel?: SlotProps<{ data: FacetBucket }>;\n };\n}\n\nexport const Facets: Container<FacetsProps> = ({ scope, slots }) => {\n const labels = useText({\n clearAll: 'Search.Facet.clearAll',\n });\n\n const [facetList, setFacetList] = useState<SearchFacet[]>([]);\n const [currency, setCurrency] = useState<string | null>(null);\n const [currentSearchVariables, setCurrentSearchVariables] = useState<SearchVariables>();\n const [pendingFilters, setPendingFilters] = useState<SearchFilter[] | null>(null);\n const searchTimeoutRef = useRef<number | null>(null);\n\n const handleSearchRequest = (searchVariables: SearchVariables): void => {\n // Attributes that appear in the facet list are driven by user selection; all others\n // (visibility, etc.) are carried through so they are not lost when the user changes facets.\n const facetAttributes = new Set(facetList.map((f) => f.attribute));\n const baseFilters = (currentSearchVariables?.filter || []).filter(\n (f) => !facetAttributes.has(f.attribute)\n );\n const mergedFilter = [...baseFilters, ...(searchVariables.filter || [])];\n\n search({\n ...searchVariables,\n filter: mergedFilter,\n }, { scope });\n };\n\n const handleSearchResult = (payload: { result: ProductSearchResult; request: SearchVariables }): void => {\n if (!payload || (!payload.result.facets && !payload.result.items && !payload.request.filter)) {\n setFacetList([]);\n return;\n }\n\n setCurrentSearchVariables(payload.request);\n\n const { facets, items } = payload.result;\n\n setCurrency(getCurrencyType(items));\n\n const filterList = payload.request.filter;\n\n if (facets) {\n const facetsWithSelections = facets.map((facet: SearchFacet) => {\n const selectedBuckets = facet.buckets.map((bucket) => {\n const selectedFilter = filterList?.find((filter) => filter.attribute === facet.attribute);\n if (selectedFilter) {\n const selectedRange = selectedFilter.range;\n if (selectedRange && bucket.from === selectedRange.from && bucket.to === selectedRange.to) {\n return { ...bucket, selected: true };\n } else if (selectedFilter.in && selectedFilter.in.includes(bucket.title)) {\n return { ...bucket, selected: true };\n }\n }\n return { ...bucket, selected: false };\n });\n return { ...facet, buckets: selectedBuckets };\n });\n\n setFacetList(facetsWithSelections);\n }\n };\n\n const updateFacetSelections = (facets: SearchFacet[]): void => {\n // Use functional update to ensure we're working with latest state\n setFacetList(currentFacetList => {\n const updatedFacetList = currentFacetList.map((f) => {\n const newFacet = facets.find((facet) => facet.attribute === f.attribute);\n if (newFacet) {\n return newFacet;\n }\n return f;\n });\n \n // Calculate selectedFilterList from the updated facet list\n const selectedFilterList = updatedFacetList.reduce((accu: SearchFilter[], facet: SearchFacet) => {\n const selectedFilter = getFilterSelection(facet);\n if (selectedFilter) {\n accu.push(selectedFilter as SearchFilter);\n }\n return accu;\n }, [] as SearchFilter[]);\n \n // Queue the search request (will be debounced by useEffect)\n setPendingFilters(selectedFilterList);\n \n return updatedFacetList;\n });\n };\n\n const handleCancelSelection = (facet: SearchFacet, title: string): void => {\n const newBuckets = facet.buckets.map((bucket) => {\n if (bucket.title === title) {\n return { ...bucket, selected: false };\n }\n return bucket;\n });\n const newFacet = { ...facet, buckets: newBuckets };\n updateFacetSelections([newFacet]);\n };\n\n const clearAllSelections = (): void => {\n const updatedFacetList = facetList.map((facet) => {\n const updatedBuckets = facet.buckets.map((bucket) => {\n return { ...bucket, selected: false };\n });\n return { ...facet, buckets: updatedBuckets };\n });\n setFacetList(updatedFacetList);\n // Queue the search request with empty filters\n setPendingFilters([]);\n };\n\n const changeFilter = (event: any, facetAttribute: string): void => {\n const clickedValue = event.target.value;\n const isChecked = event.target.checked;\n \n // Use functional update to work with latest state\n setFacetList(currentFacetList => {\n const currentFacet = currentFacetList.find(f => f.attribute === facetAttribute);\n if (!currentFacet) {\n return currentFacetList;\n }\n \n const newBuckets = currentFacet.buckets.map((bucket) => {\n if (currentFacet.buckets[0]?.__typename === 'RangeBucket') {\n // For range buckets (radio buttons), only one can be selected\n if (bucket.title === clickedValue) {\n return { ...bucket, selected: isChecked };\n }\n return { ...bucket, selected: false };\n }\n // For scalar buckets (checkboxes), multiple can be selected\n if (bucket.title === clickedValue) {\n return { ...bucket, selected: isChecked };\n }\n // Keep other buckets as-is, but create new objects to maintain immutability\n return { ...bucket };\n });\n \n const newFacet = { ...currentFacet, buckets: newBuckets };\n \n // Update the facet list with the new facet\n const updatedFacetList = currentFacetList.map((f) => {\n if (f.attribute === facetAttribute) {\n return newFacet;\n }\n return f;\n });\n \n // Calculate selected filters - will trigger search via useEffect\n const selectedFilterList = updatedFacetList.reduce((accu: SearchFilter[], facet: SearchFacet) => {\n const selectedFilter = getFilterSelection(facet);\n if (selectedFilter) {\n accu.push(selectedFilter as SearchFilter);\n }\n return accu;\n }, [] as SearchFilter[]);\n \n // Queue the search request (will be debounced by useEffect)\n setPendingFilters(selectedFilterList);\n \n return updatedFacetList;\n });\n };\n\n const getFacetNode = (facet: SearchFacet, index: number): VNode => {\n const header = <span>{facet.title}</span>;\n const buckets = facet.buckets\n .map((bucket: FacetBucket) => {\n const bucketLabel = getBucketLabel(bucket, facet, currency);\n\n const renderedBucketLabel = (count?: number) => (\n <Slot name=\"FacetBucketLabel\"\n slot={slots?.FacetBucketLabel}\n context={{ data: bucket }}>\n {bucketLabel} {count ? `(${count})` : ''}\n </Slot>\n );\n switch (facet.buckets[0]?.__typename) {\n case 'RangeBucket':\n \n return (\n <Slot name=\"FacetBucket\" slot={slots?.FacetBucket} context={{ data: bucket }}>\n <RadioButton\n data-testid={`${bucket.title}-radio`}\n label={renderedBucketLabel()}\n name={facet.attribute}\n value={bucket.title}\n checked={bucket.selected}\n onChange={(event): void => {\n changeFilter(event, facet.attribute);\n }}\n />\n </Slot>\n ) as VNode;\n case 'ScalarBucket':\n case 'CategoryView':\n return (\n <Slot name=\"FacetBucket\" slot={slots?.FacetBucket} context={{ data: bucket }}>\n <Checkbox\n id={`${facet.attribute}-${bucket.title.replace(/[^a-zA-Z0-9_-]/g, '')}`}\n data-testid={`${bucket.title}-checkbox`}\n label={renderedBucketLabel(bucket.count)}\n name={`${facet.attribute}-${bucket.title.replace(/[^a-zA-Z0-9_-]/g, '')}`}\n value={bucket.title}\n checked={bucket.selected}\n onChange={(event): void => {\n changeFilter(event, facet.attribute);\n }}\n />\n </Slot>\n ) as VNode;\n default:\n return null;\n }\n })\n .filter((bucket) => bucket !== null);\n\n return <Facet header={header} buckets={buckets} last={index === facetList.length - 1} />\n };\n\n const getFacetsNode = (): VNode => {\n return (\n <Slot name=\"Facets\" slot={slots?.Facets} context={{ data: facetList }}>\n {facetList.map((facet, index) => {\n return facet.buckets.length > 0\n ? ((\n <>\n <Slot name=\"Facet\" slot={slots?.Facet} context={{ data: facet }}>\n {getFacetNode(facet, index)}\n </Slot>\n </>\n ) as VNode)\n : null;\n })}\n </Slot>\n );\n };\n\n const getSelectedFacetsNode = (): VNode => {\n const selectedFacets = facetList.reduce((accu, curr) => {\n const selected = curr.buckets.filter((bucket: FacetBucket) => bucket.selected);\n if (selected.length > 0) {\n accu.push(curr);\n }\n return accu;\n }, [] as SearchFacet[]);\n const selectedFilterBtns = selectedFacets.map((facet) => {\n return facet.buckets.map((bucket) => {\n if (bucket.selected) {\n const bucketTitle = getBucketLabel(bucket, facet, currency);\n return (\n <Button\n data-testid={`${bucket.title}-selected-btn`}\n aria-label={`Remove ${facet.title} filter: ${bucket.title}`}\n variant=\"secondary\"\n children={\n <>\n <span>{bucketTitle}</span>\n <Icon source={Close} size=\"16\" />\n </>\n }\n onClick={(): void => {\n handleCancelSelection(facet, bucket.title);\n }}\n />\n ) as VNode;\n }\n return null;\n });\n });\n\n const clearAllBtn =\n selectedFilterBtns.length > 0 ? (\n <Button\n variant=\"secondary\"\n onClick={(): void => {\n clearAllSelections();\n }}\n >\n <span>{labels.clearAll}</span>\n </Button>\n ) : null;\n return (\n <Slot name=\"SelectedFacets\" slot={slots?.SelectedFacets} context={{ data: selectedFacets }}>\n {selectedFilterBtns}\n {clearAllBtn}\n </Slot>\n );\n };\n\n useEffect(() => {\n const dataEvents = events.on('search/result', handleSearchResult, { eager: true, scope });\n\n return () => {\n dataEvents?.off();\n };\n }, []);\n\n // Handle search triggering with debouncing for better UX\n useEffect(() => {\n if (pendingFilters === null) {\n return;\n }\n\n // Clear any existing timeout\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n\n // Debounce search requests to avoid too many API calls\n searchTimeoutRef.current = setTimeout(() => {\n if (currentSearchVariables) {\n // Reset to first page when filters change\n handleSearchRequest({ ...currentSearchVariables, filter: pendingFilters, currentPage: 1 });\n }\n setPendingFilters(null);\n }, 150);\n\n return () => {\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n };\n }, [pendingFilters, currentSearchVariables]);\n\n return <FacetList selectedFacets={getSelectedFacetsNode()} facets={getFacetsNode()} />;\n};\n"],"names":["BOOLEAN_NO","BOOLEAN_YES","getRangeFacetFilter","facet","selectedRange","bucket","getScalarFacetFilter","scalarSelections","accu","curr","getFilterSelection","_a","getCurrencyType","items","firstItem","_c","_b","_g","_f","_e","_d","_k","_j","_i","_h","getRangeBucketLabel","currency","jsxs","jsx","PriceRange","getScalarBucketLabel","getBucketLabel","Facets","scope","slots","labels","useText","facetList","setFacetList","useState","setCurrency","currentSearchVariables","setCurrentSearchVariables","pendingFilters","setPendingFilters","searchTimeoutRef","useRef","handleSearchRequest","searchVariables","facetAttributes","f","mergedFilter","search","handleSearchResult","payload","facets","filterList","facetsWithSelections","selectedBuckets","selectedFilter","filter","updateFacetSelections","currentFacetList","updatedFacetList","newFacet","selectedFilterList","handleCancelSelection","title","newBuckets","clearAllSelections","updatedBuckets","changeFilter","event","facetAttribute","clickedValue","isChecked","currentFacet","getFacetNode","index","header","buckets","bucketLabel","renderedBucketLabel","count","Slot","RadioButton","Checkbox","Facet","getFacetsNode","getSelectedFacetsNode","selectedFacets","selectedFilterBtns","bucketTitle","Button","Fragment","Icon","Close","clearAllBtn","useEffect","dataEvents","events","FacetList"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Facets.js","sources":["/@dropins/storefront-product-discovery/src/containers/Facets/utils/facetUtils.tsx","/@dropins/storefront-product-discovery/src/containers/Facets/Facets.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { SearchFacet } from '@/plp/data/models/api';\nimport { Product } from '@/plp/data/models/product';\nimport { PriceRange } from '@adobe-commerce/elsie/components';\n\nconst BOOLEAN_NO = 'no';\nconst BOOLEAN_YES = 'yes';\n\nconst getRangeFacetFilter = (facet: SearchFacet) => {\n const selectedRange = facet.buckets.find((bucket) => bucket.selected);\n if (!selectedRange) {\n return null;\n }\n return {\n attribute: facet.attribute,\n range: {\n from: selectedRange.from,\n to: selectedRange.to,\n },\n };\n};\n\nconst getScalarFacetFilter = (facet: SearchFacet) => {\n const scalarSelections = facet.buckets.reduce((accu, curr) => {\n if (curr.selected) {\n accu.push(curr.title);\n }\n return accu;\n }, [] as string[]);\n if (scalarSelections.length === 0) {\n return null;\n }\n return {\n attribute: facet.attribute,\n in: scalarSelections,\n };\n};\n\nconst getFilterSelection = (facet: SearchFacet) => {\n switch (facet.buckets[0]?.__typename) {\n case 'RangeBucket':\n return getRangeFacetFilter(facet);\n case 'ScalarBucket':\n case 'CategoryView':\n return getScalarFacetFilter(facet);\n default:\n break;\n }\n};\n\nconst getCurrencyType = (items: Product[]) => {\n const firstItem = items[0];\n if (firstItem?.price?.regular?.amount?.currency) {\n return firstItem.price.regular.amount.currency;\n } else if (firstItem?.priceRange?.minimum?.regular?.amount?.currency) {\n return firstItem?.priceRange?.minimum?.regular?.amount?.currency;\n }\n return 'USD'; // Default currency if not found\n};\n\nconst getRangeBucketLabel = (bucket: any, facet: SearchFacet, currency: string | null) => {\n if (facet?.attribute === 'price') {\n //Temp fix for Price range not handling value when minumum is zero\n if (bucket.from === 0) {\n return (\n <div style={'display:flex'}>\n <PriceRange amount={bucket.from} currency={currency || 'USD'} />\n <span style={'padding: 0 2px'}>{'-'}</span>\n <PriceRange amount={bucket.to} currency={currency || 'USD'} />\n </div>\n );\n }\n return (\n <PriceRange minimumAmount={bucket.from} maximumAmount={bucket.to} currency={currency || 'USD'} display=\"dash\" />\n );\n }\n return bucket.title;\n};\n\nconst getScalarBucketLabel = (bucket: any, facet: SearchFacet) => {\n if (bucket.title === BOOLEAN_NO) {\n return `Not ${facet.title}`;\n } else if (bucket.title === BOOLEAN_YES) {\n return facet.title;\n }\n return bucket.title;\n};\n\nconst getBucketLabel = (bucket: any, facet: SearchFacet, currency: string | null) => {\n switch (bucket.__typename) {\n case 'RangeBucket':\n return getRangeBucketLabel(bucket, facet, currency);\n case 'ScalarBucket':\n case 'CategoryView':\n return getScalarBucketLabel(bucket, facet);\n default:\n break;\n }\n};\n\nexport { getBucketLabel, getCurrencyType, getFilterSelection };\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { HTMLAttributes, useEffect, useState, useRef } from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { ProductSearchResult, SearchFilter, SearchFacet, SearchVariables, FacetBucket, Scope } from '@/plp/data/models/api';\nimport { getBucketLabel, getCurrencyType, getFilterSelection } from './utils/facetUtils';\nimport FacetList from '@/plp/components/FacetList';\nimport { Button, Checkbox, Icon, RadioButton } from '@adobe-commerce/elsie/components';\nimport { Facet } from '@/plp/components';\nimport { VNode } from 'preact';\nimport { Close } from '@adobe-commerce/elsie/icons';\nimport { events } from '@adobe-commerce/event-bus';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { search } from '@/plp/api';\n\nexport interface FacetsProps extends HTMLAttributes<HTMLDivElement> {\n scope?: Scope;\n slots?: {\n Facet?: SlotProps<{ data: SearchFacet }>;\n SelectedFacets?: SlotProps<{ data: SearchFacet[] }>;\n Facets?: SlotProps<{ data: SearchFacet[] }>;\n FacetBucket?: SlotProps<{ data: FacetBucket }>;\n FacetBucketLabel?: SlotProps<{ data: FacetBucket }>;\n };\n}\n\nexport const Facets: Container<FacetsProps> = ({ scope, slots }) => {\n const labels = useText({\n clearAll: 'Search.Facet.clearAll',\n });\n\n const [facetList, setFacetList] = useState<SearchFacet[]>([]);\n const [currency, setCurrency] = useState<string | null>(null);\n const [currentSearchVariables, setCurrentSearchVariables] = useState<SearchVariables>();\n const [pendingFilters, setPendingFilters] = useState<SearchFilter[] | null>(null);\n const searchTimeoutRef = useRef<number | null>(null);\n\n const handleSearchRequest = (searchVariables: SearchVariables): void => {\n // Attributes that appear in the facet list are driven by user selection; all others\n // (visibility, etc.) are carried through so they are not lost when the user changes facets.\n const facetAttributes = new Set(facetList.map((f) => f.attribute));\n const baseFilters = (currentSearchVariables?.filter || []).filter(\n (f) => !facetAttributes.has(f.attribute)\n );\n const mergedFilter = [...baseFilters, ...(searchVariables.filter || [])];\n\n search({\n ...searchVariables,\n filter: mergedFilter,\n }, { scope });\n };\n\n const handleSearchResult = (payload: { result: ProductSearchResult; request: SearchVariables }): void => {\n if (!payload || (!payload.result.facets && !payload.result.items && !payload.request.filter)) {\n setFacetList([]);\n return;\n }\n\n setCurrentSearchVariables(payload.request);\n\n const { facets, items } = payload.result;\n\n setCurrency(getCurrencyType(items));\n\n const filterList = payload.request.filter;\n\n if (facets) {\n const facetsWithSelections = facets.map((facet: SearchFacet) => {\n const selectedBuckets = facet.buckets.map((bucket) => {\n const selectedFilter = filterList?.find((filter) => filter.attribute === facet.attribute);\n if (selectedFilter) {\n const selectedRange = selectedFilter.range;\n if (selectedRange && bucket.from === selectedRange.from && bucket.to === selectedRange.to) {\n return { ...bucket, selected: true };\n } else if (selectedFilter.in && selectedFilter.in.includes(bucket.title)) {\n return { ...bucket, selected: true };\n }\n }\n return { ...bucket, selected: false };\n });\n return { ...facet, buckets: selectedBuckets };\n });\n\n setFacetList(facetsWithSelections);\n }\n };\n\n const updateFacetSelections = (facets: SearchFacet[]): void => {\n // Use functional update to ensure we're working with latest state\n setFacetList(currentFacetList => {\n const updatedFacetList = currentFacetList.map((f) => {\n const newFacet = facets.find((facet) => facet.attribute === f.attribute);\n if (newFacet) {\n return newFacet;\n }\n return f;\n });\n \n // Calculate selectedFilterList from the updated facet list\n const selectedFilterList = updatedFacetList.reduce((accu: SearchFilter[], facet: SearchFacet) => {\n const selectedFilter = getFilterSelection(facet);\n if (selectedFilter) {\n accu.push(selectedFilter as SearchFilter);\n }\n return accu;\n }, [] as SearchFilter[]);\n \n // Queue the search request (will be debounced by useEffect)\n setPendingFilters(selectedFilterList);\n \n return updatedFacetList;\n });\n };\n\n const handleCancelSelection = (facet: SearchFacet, title: string): void => {\n const newBuckets = facet.buckets.map((bucket) => {\n if (bucket.title === title) {\n return { ...bucket, selected: false };\n }\n return bucket;\n });\n const newFacet = { ...facet, buckets: newBuckets };\n updateFacetSelections([newFacet]);\n };\n\n const clearAllSelections = (): void => {\n const updatedFacetList = facetList.map((facet) => {\n const updatedBuckets = facet.buckets.map((bucket) => {\n return { ...bucket, selected: false };\n });\n return { ...facet, buckets: updatedBuckets };\n });\n setFacetList(updatedFacetList);\n // Queue the search request with empty filters\n setPendingFilters([]);\n };\n\n const changeFilter = (event: any, facetAttribute: string): void => {\n const clickedValue = event.target.value;\n const isChecked = event.target.checked;\n \n // Use functional update to work with latest state\n setFacetList(currentFacetList => {\n const currentFacet = currentFacetList.find(f => f.attribute === facetAttribute);\n if (!currentFacet) {\n return currentFacetList;\n }\n \n const newBuckets = currentFacet.buckets.map((bucket) => {\n if (currentFacet.buckets[0]?.__typename === 'RangeBucket') {\n // For range buckets (radio buttons), only one can be selected\n if (bucket.title === clickedValue) {\n return { ...bucket, selected: isChecked };\n }\n return { ...bucket, selected: false };\n }\n // For scalar buckets (checkboxes), multiple can be selected\n if (bucket.title === clickedValue) {\n return { ...bucket, selected: isChecked };\n }\n // Keep other buckets as-is, but create new objects to maintain immutability\n return { ...bucket };\n });\n \n const newFacet = { ...currentFacet, buckets: newBuckets };\n \n // Update the facet list with the new facet\n const updatedFacetList = currentFacetList.map((f) => {\n if (f.attribute === facetAttribute) {\n return newFacet;\n }\n return f;\n });\n \n // Calculate selected filters - will trigger search via useEffect\n const selectedFilterList = updatedFacetList.reduce((accu: SearchFilter[], facet: SearchFacet) => {\n const selectedFilter = getFilterSelection(facet);\n if (selectedFilter) {\n accu.push(selectedFilter as SearchFilter);\n }\n return accu;\n }, [] as SearchFilter[]);\n \n // Queue the search request (will be debounced by useEffect)\n setPendingFilters(selectedFilterList);\n \n return updatedFacetList;\n });\n };\n\n const getFacetNode = (facet: SearchFacet, index: number): VNode => {\n const header = <span>{facet.title}</span>;\n const buckets = facet.buckets\n .map((bucket: FacetBucket) => {\n const bucketLabel = getBucketLabel(bucket, facet, currency);\n\n const renderedBucketLabel = (count?: number) => (\n <Slot name=\"FacetBucketLabel\"\n slot={slots?.FacetBucketLabel}\n context={{ data: bucket }}>\n {bucketLabel} {count ? `(${count})` : ''}\n </Slot>\n );\n switch (facet.buckets[0]?.__typename) {\n case 'RangeBucket':\n \n return (\n <Slot name=\"FacetBucket\" slot={slots?.FacetBucket} context={{ data: bucket }}>\n <RadioButton\n data-testid={`${bucket.title}-radio`}\n label={renderedBucketLabel()}\n name={facet.attribute}\n value={bucket.title}\n checked={bucket.selected}\n onChange={(event): void => {\n changeFilter(event, facet.attribute);\n }}\n />\n </Slot>\n ) as VNode;\n case 'ScalarBucket':\n case 'CategoryView':\n return (\n <Slot name=\"FacetBucket\" slot={slots?.FacetBucket} context={{ data: bucket }}>\n <Checkbox\n id={`${facet.attribute}-${bucket.title.replace(/[^a-zA-Z0-9_-]/g, '')}`}\n data-testid={`${bucket.title}-checkbox`}\n label={renderedBucketLabel(bucket.count)}\n name={`${facet.attribute}-${bucket.title.replace(/[^a-zA-Z0-9_-]/g, '')}`}\n value={bucket.title}\n checked={bucket.selected}\n onChange={(event): void => {\n changeFilter(event, facet.attribute);\n }}\n />\n </Slot>\n ) as VNode;\n default:\n return null;\n }\n })\n .filter((bucket) => bucket !== null);\n\n return <Facet header={header} buckets={buckets} last={index === facetList.length - 1} />\n };\n\n const getFacetsNode = (): VNode => {\n return (\n <Slot name=\"Facets\" slot={slots?.Facets} context={{ data: facetList }}>\n {facetList.map((facet, index) => {\n return facet.buckets.length > 0\n ? ((\n <>\n <Slot name=\"Facet\" slot={slots?.Facet} context={{ data: facet }}>\n {getFacetNode(facet, index)}\n </Slot>\n </>\n ) as VNode)\n : null;\n })}\n </Slot>\n );\n };\n\n const getSelectedFacetsNode = (): VNode => {\n const selectedFacets = facetList.reduce((accu, curr) => {\n const selected = curr.buckets.filter((bucket: FacetBucket) => bucket.selected);\n if (selected.length > 0) {\n accu.push(curr);\n }\n return accu;\n }, [] as SearchFacet[]);\n const selectedFilterBtns = selectedFacets.map((facet) => {\n return facet.buckets.map((bucket) => {\n if (bucket.selected) {\n const bucketTitle = getBucketLabel(bucket, facet, currency);\n return (\n <Button\n data-testid={`${bucket.title}-selected-btn`}\n aria-label={`Remove ${facet.title} filter: ${bucket.title}`}\n variant=\"secondary\"\n children={\n <>\n <span>{bucketTitle}</span>\n <Icon source={Close} size=\"16\" />\n </>\n }\n onClick={(): void => {\n handleCancelSelection(facet, bucket.title);\n }}\n />\n ) as VNode;\n }\n return null;\n });\n });\n\n const clearAllBtn =\n selectedFilterBtns.length > 0 ? (\n <Button\n variant=\"secondary\"\n onClick={(): void => {\n clearAllSelections();\n }}\n >\n <span>{labels.clearAll}</span>\n </Button>\n ) : null;\n return (\n <Slot name=\"SelectedFacets\" slot={slots?.SelectedFacets} context={{ data: selectedFacets }}>\n {selectedFilterBtns}\n {clearAllBtn}\n </Slot>\n );\n };\n\n useEffect(() => {\n const dataEvents = events.on('search/result', handleSearchResult, { eager: true, scope });\n\n return () => {\n dataEvents?.off();\n };\n }, []);\n\n // Handle search triggering with debouncing for better UX\n useEffect(() => {\n if (pendingFilters === null) {\n return;\n }\n\n // Clear any existing timeout\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n\n // Debounce search requests to avoid too many API calls\n searchTimeoutRef.current = setTimeout(() => {\n if (currentSearchVariables) {\n // Reset to first page when filters change\n handleSearchRequest({ ...currentSearchVariables, filter: pendingFilters, currentPage: 1 });\n }\n setPendingFilters(null);\n }, 150);\n\n return () => {\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n };\n }, [pendingFilters, currentSearchVariables]);\n\n return <FacetList selectedFacets={getSelectedFacetsNode()} facets={getFacetsNode()} />;\n};\n"],"names":["BOOLEAN_NO","BOOLEAN_YES","getRangeFacetFilter","facet","selectedRange","bucket","getScalarFacetFilter","scalarSelections","accu","curr","getFilterSelection","_a","getCurrencyType","items","firstItem","_c","_b","_g","_f","_e","_d","_k","_j","_i","_h","getRangeBucketLabel","currency","jsxs","jsx","PriceRange","getScalarBucketLabel","getBucketLabel","Facets","scope","slots","labels","useText","facetList","setFacetList","useState","setCurrency","currentSearchVariables","setCurrentSearchVariables","pendingFilters","setPendingFilters","searchTimeoutRef","useRef","handleSearchRequest","searchVariables","facetAttributes","f","mergedFilter","search","handleSearchResult","payload","facets","filterList","facetsWithSelections","selectedBuckets","selectedFilter","filter","updateFacetSelections","currentFacetList","updatedFacetList","newFacet","selectedFilterList","handleCancelSelection","title","newBuckets","clearAllSelections","updatedBuckets","changeFilter","event","facetAttribute","clickedValue","isChecked","currentFacet","getFacetNode","index","header","buckets","bucketLabel","renderedBucketLabel","count","Slot","RadioButton","Checkbox","Facet","getFacetsNode","getSelectedFacetsNode","selectedFacets","selectedFilterBtns","bucketTitle","Button","Fragment","Icon","Close","clearAllBtn","useEffect","dataEvents","events","FacetList"],"mappings":"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"}
|
package/containers/Pagination.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{jsx as S}from"@dropins/tools/preact-jsx-runtime.js";import{useState as s,useEffect as b}from"@dropins/tools/preact-compat.js";import{Pagination as h}from"@dropins/tools/components.js";import{events as x}from"@dropins/tools/event-bus.js";import{search as I}from"../api.js";import"@dropins/tools/lib.js";import"@dropins/tools/fetch-graphql.js";const
|
|
3
|
+
import{jsx as S}from"@dropins/tools/preact-jsx-runtime.js";import{useState as s,useEffect as b}from"@dropins/tools/preact-compat.js";import{Pagination as h}from"@dropins/tools/components.js";import{events as x}from"@dropins/tools/event-bus.js";import{search as I}from"../api.js";import"@dropins/tools/lib.js";import"../fragments.js";import"@dropins/tools/fetch-graphql.js";const w=({scope:o,onPageChange:r})=>{const[a,m]=s(),[n,l]=s(),[g,p]=s({});b(()=>{const t=x.on("search/result",e=>{var u,i,c,f;p(e.request),m((i=(u=e.result)==null?void 0:u.pageInfo)==null?void 0:i.currentPage),l((f=(c=e.result)==null?void 0:c.pageInfo)==null?void 0:f.totalPages)},{eager:!0,scope:o});return()=>{t==null||t.off()}},[]);const P=async t=>{r==null||r(t),I({...g,currentPage:t},{scope:o})};return!a||!n?null:S(h,{currentPage:a,totalPages:n,onChange:P})};export{w as Pagination,w as default};
|
|
4
4
|
//# sourceMappingURL=Pagination.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.js","sources":["/@dropins/storefront-product-discovery/src/containers/Pagination/Pagination.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n \nimport { HTMLAttributes, useState, useEffect } from 'preact/compat';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { Pagination as PaginationComponent } from '@adobe-commerce/elsie/components';\nimport { events } from '@adobe-commerce/event-bus';\nimport { Scope, SearchVariables } from '@/plp/data/models';\nimport { search } from '@/plp/api';\n\nexport interface PaginationProps extends HTMLAttributes<HTMLDivElement> {\n scope?: Scope;\n onPageChange?: (page: number) => void;\n }\n \nexport const Pagination: Container<PaginationProps> = ({ scope, onPageChange }) => {\n const [currentPage, setCurrentPage] = useState<number>();\n const [totalPages, setTotalPages] = useState<number>();\n const [currentSearchVariables, setCurrentSearchVariables] = useState<SearchVariables>({});\n\n useEffect(() => {\n const searchEvent = events.on('search/result', (payload) => {\n setCurrentSearchVariables(payload.request);\n setCurrentPage(payload.result?.pageInfo?.currentPage);\n setTotalPages(payload.result?.pageInfo?.totalPages);\n }, { eager: true, scope });\n\n return () => {\n searchEvent?.off();\n };\n }, []);\n\n const handlePageChange = async (page: number): Promise<void> => {\n onPageChange?.(page);\n\n search(\n { ...currentSearchVariables, currentPage: page },\n { scope }\n );\n };\n \n\n // Don't render if we don't have the variables\n if (!currentPage || !totalPages) {\n return null;\n }\n\n return (\n <PaginationComponent \n currentPage={currentPage}\n totalPages={totalPages}\n onChange={handlePageChange}\n />\n );\n};"],"names":["Pagination","scope","onPageChange","currentPage","setCurrentPage","useState","totalPages","setTotalPages","currentSearchVariables","setCurrentSearchVariables","useEffect","searchEvent","events","payload","_b","_a","_d","_c","handlePageChange","page","search","jsx","PaginationComponent"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Pagination.js","sources":["/@dropins/storefront-product-discovery/src/containers/Pagination/Pagination.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n \nimport { HTMLAttributes, useState, useEffect } from 'preact/compat';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { Pagination as PaginationComponent } from '@adobe-commerce/elsie/components';\nimport { events } from '@adobe-commerce/event-bus';\nimport { Scope, SearchVariables } from '@/plp/data/models';\nimport { search } from '@/plp/api';\n\nexport interface PaginationProps extends HTMLAttributes<HTMLDivElement> {\n scope?: Scope;\n onPageChange?: (page: number) => void;\n }\n \nexport const Pagination: Container<PaginationProps> = ({ scope, onPageChange }) => {\n const [currentPage, setCurrentPage] = useState<number>();\n const [totalPages, setTotalPages] = useState<number>();\n const [currentSearchVariables, setCurrentSearchVariables] = useState<SearchVariables>({});\n\n useEffect(() => {\n const searchEvent = events.on('search/result', (payload) => {\n setCurrentSearchVariables(payload.request);\n setCurrentPage(payload.result?.pageInfo?.currentPage);\n setTotalPages(payload.result?.pageInfo?.totalPages);\n }, { eager: true, scope });\n\n return () => {\n searchEvent?.off();\n };\n }, []);\n\n const handlePageChange = async (page: number): Promise<void> => {\n onPageChange?.(page);\n\n search(\n { ...currentSearchVariables, currentPage: page },\n { scope }\n );\n };\n \n\n // Don't render if we don't have the variables\n if (!currentPage || !totalPages) {\n return null;\n }\n\n return (\n <PaginationComponent \n currentPage={currentPage}\n totalPages={totalPages}\n onChange={handlePageChange}\n />\n );\n};"],"names":["Pagination","scope","onPageChange","currentPage","setCurrentPage","useState","totalPages","setTotalPages","currentSearchVariables","setCurrentSearchVariables","useEffect","searchEvent","events","payload","_b","_a","_d","_c","handlePageChange","page","search","jsx","PaginationComponent"],"mappings":"qXAqBO,MAAMA,EAAyC,CAAC,CAAE,MAAAC,EAAO,aAAAC,KAAmB,CACjF,KAAM,CAACC,EAAaC,CAAc,EAAIC,EAAA,EAChC,CAACC,EAAYC,CAAa,EAAIF,EAAA,EAC9B,CAACG,EAAwBC,CAAyB,EAAIJ,EAA0B,CAAA,CAAE,EAExFK,EAAU,IAAM,CACd,MAAMC,EAAcC,EAAO,GAAG,gBAAkBC,GAAY,aAC1DJ,EAA0BI,EAAQ,OAAO,EACzCT,GAAeU,GAAAC,EAAAF,EAAQ,SAAR,YAAAE,EAAgB,WAAhB,YAAAD,EAA0B,WAAW,EACpDP,GAAcS,GAAAC,EAAAJ,EAAQ,SAAR,YAAAI,EAAgB,WAAhB,YAAAD,EAA0B,UAAU,CACpD,EAAG,CAAE,MAAO,GAAM,MAAAf,EAAO,EAEzB,MAAO,IAAM,CACXU,GAAA,MAAAA,EAAa,KACf,CACF,EAAG,CAAA,CAAE,EAEL,MAAMO,EAAmB,MAAOC,GAAgC,CAC9DjB,GAAA,MAAAA,EAAeiB,GAEfC,EACE,CAAE,GAAGZ,EAAwB,YAAaW,CAAA,EAC1C,CAAE,MAAAlB,CAAA,CAAM,CAEZ,EAIA,MAAI,CAACE,GAAe,CAACG,EACZ,KAIPe,EAACC,EAAA,CACC,YAAAnB,EACA,WAAAG,EACA,SAAUY,CAAA,CAAA,CAGhB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{jsx as n,jsxs as E}from"@dropins/tools/preact-jsx-runtime.js";import{useState as L,useEffect as B}from"@dropins/tools/preact-compat.js";import{Slot as I}from"@dropins/tools/lib.js";import{events as D}from"@dropins/tools/event-bus.js";import{PriceRange as v,ProductItemCard as
|
|
3
|
+
import{jsx as n,jsxs as E}from"@dropins/tools/preact-jsx-runtime.js";import{useState as L,useEffect as B}from"@dropins/tools/preact-compat.js";import{Slot as I}from"@dropins/tools/lib.js";import{events as D}from"@dropins/tools/event-bus.js";import{PriceRange as v,ProductItemCard as F,Image as G}from"@dropins/tools/components.js";import{P as V,S as J}from"../chunks/components.js";import{s as K,c as Q,a as X,S as Y,P as Z}from"../api.js";import{useText as $}from"@dropins/tools/i18n.js";import"../fragments.js";import"@dropins/tools/fetch-graphql.js";const b=a=>new DOMParser().parseFromString(a,"text/html").documentElement.textContent,W=({product:a})=>{var d,P,l,f,m,S,s,x,R;let i=((l=(P=(d=a.price)==null?void 0:d.regular)==null?void 0:P.amount)==null?void 0:l.currency)??"USD";Intl.supportedValuesOf("currency").includes(i)||(i="USD");const r=(S=(m=(f=a.price)==null?void 0:f.final)==null?void 0:m.amount)==null?void 0:S.value,c=(R=(x=(s=a.price)==null?void 0:s.regular)==null?void 0:x.amount)==null?void 0:R.value;return r!==void 0&&c!==void 0&&r<c?E("div",{class:"product-price",children:[n("span",{class:"regular-price-normal",children:n(v,{amount:r,currency:i})}),n("span",{class:"special-price-crossed",children:n(v,{amount:c,currency:i})})]}):n(v,{amount:c,currency:i})},ee=({product:a})=>{var l,f,m,S,s,x,R,w,A,N,y,C;let i=((S=(m=(f=(l=a.priceRange)==null?void 0:l.minimum)==null?void 0:f.regular)==null?void 0:m.amount)==null?void 0:S.currency)??"USD";Intl.supportedValuesOf("currency").includes(i)||(i="USD");const r=(x=(s=a.priceRange)==null?void 0:s.minimum)==null?void 0:x.final.amount.value,c=(w=(R=a.priceRange)==null?void 0:R.minimum)==null?void 0:w.regular.amount.value,p=(N=(A=a.priceRange)==null?void 0:A.maximum)==null?void 0:N.final.amount.value,d=(C=(y=a.priceRange)==null?void 0:y.maximum)==null?void 0:C.regular.amount.value;return r<c||p<d?E("div",{class:"product-price",children:[n("span",{class:"regular-price-normal",children:n(v,{display:"from to",minimumAmount:r,maximumAmount:p,currency:i})}),n("span",{class:"special-price-crossed",children:n(v,{display:"from to",minimumAmount:c,maximumAmount:d,currency:i})})]}):n(v,{display:"from to",minimumAmount:c,maximumAmount:d,currency:i})},de=({routeProduct:a,scope:i,slots:r,imageWidth:c=400,imageHeight:p=450,skeletonCount:d=8,onSearchResult:P})=>{const l=i==="popover"?Y:Z,f=$({noResults:"Search.PLP.noResults",searchError:"Search.PLP.searchError"}),[m,S]=L(null),[s,x]=L([]),[R,w]=L(!1),[A,N]=L(null);B(()=>{const e=D.on("search/loading",w,{eager:!0,scope:i}),t=D.on("search/error",()=>{N(f.searchError)},{eager:!0,scope:i}),o=D.on("search/result",u=>{var h,g,U;N(((h=u.result)==null?void 0:h.items.length)<1?f.noResults:null),S(u.request),x((g=u.result)==null?void 0:g.items),P==null||P((U=u.result)==null?void 0:U.items),u.request.phrase?K(l):Q(l)},{eager:!0,scope:i});return()=>{e==null||e.off(),t==null||t.off(),o==null||o.off()}},[]);const y=(e,t)=>{var g;const o=(g=e.target)==null?void 0:g.closest("a");if(!o||!a)return;const u=new URL(o.href),h=new URL(a(t),window.location.origin);u.pathname===h.pathname&&u.hostname===h.hostname&&X(t.sku,l)},C=(e,t)=>{var g,U,k,_;const o={loading:t<8?"eager":"lazy",src:((U=(g=e.images)==null?void 0:g[0])==null?void 0:U.url)||"",alt:((_=(k=e.images)==null?void 0:k[0])==null?void 0:_.label)||"",width:c,height:p,params:{width:c}},u=e.name!==null?b(e.name):e.sku,h=n(G,{class:"product-discovery-product-item__image",...o,"aria-label":u||""});return n(I,{name:"ProductImage",slot:r==null?void 0:r.ProductImage,context:{product:e,defaultImageProps:o,variables:m},children:a?n("a",{href:a(e),children:h}):h})},z=e=>{const t=e.name!==null?b(e.name):"";return n(I,{name:"ProductName",slot:r==null?void 0:r.ProductName,context:{product:e,variables:m},children:a?n("a",{href:a(e),children:t}):t})},M=e=>{const t=e.typename==="ComplexProductView"?n(ee,{product:e}):n(W,{product:e});return n(I,{name:"ProductPrice",slot:r==null?void 0:r.ProductPrice,context:{product:e,variables:m},children:a?n("a",{href:a(e),children:t}):t})},O=e=>n(I,{name:"ProductActions",slot:r==null?void 0:r.ProductActions,context:{product:e,variables:m}}),T=()=>n(I,{name:"NoResults",slot:r==null?void 0:r.NoResults,context:{error:A,variables:m},children:A&&n(J,{alertMessage:A})}),j=()=>n(V,{imageWidth:c,imageHeight:p,productList:Array.from({length:d}).map((e,t)=>n(F,{initialized:!1},t))}),q=()=>n(I,{name:"Header",slot:r==null?void 0:r.Header,context:{products:s,variables:m}}),H=()=>n(I,{name:"Footer",slot:r==null?void 0:r.Footer,context:{products:s,variables:m}});return n("div",{children:R?j():A?T():n(V,{header:q(),footer:H(),imageWidth:c,imageHeight:p,productList:s.map((e,t)=>n(F,{image:C(e,t),titleNode:z(e),price:M(e),actionButton:r!=null&&r.ProductActions?O(e):void 0,onClick:o=>y(o,e),initialized:!0},e.id||e.sku||t))})})};export{de as SearchResults,de as default};
|
|
4
4
|
//# sourceMappingURL=SearchResults.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchResults.js","sources":["/@dropins/storefront-product-discovery/src/utils/htmlStringDecode.ts","/@dropins/storefront-product-discovery/src/containers/SearchResults/SimpleProductPrice.tsx","/@dropins/storefront-product-discovery/src/containers/SearchResults/ComplexProductPrice.tsx","/@dropins/storefront-product-discovery/src/containers/SearchResults/SearchResults.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nconst htmlStringDecode = (input: string): string | null => {\n const doc = new DOMParser().parseFromString(input, 'text/html');\n return doc.documentElement.textContent;\n};\n\nexport { htmlStringDecode };\n","import { PriceRange } from \"@adobe-commerce/elsie/components\";\nimport { Product } from \"@/plp/data/models/product\";\nimport '@/plp/components/ProductList/ProductList';\n\nexport const SimpleProductPrice = ({ product }: { product: Product }) => {\n let currency = product.price?.regular?.amount?.currency ?? \"USD\";\n\n if (!Intl.supportedValuesOf(\"currency\").includes(currency)) {\n currency = \"USD\";\n }\n\n\n const finalAmount = product.price?.final?.amount?.value;\n const regularAmount = product.price?.regular?.amount?.value;\n\n const hasSpecial =\n finalAmount !== undefined &&\n regularAmount !== undefined &&\n finalAmount < regularAmount;\n\n if (!hasSpecial) {\n return <PriceRange amount={regularAmount} currency={currency} />;\n }\n\n return (\n <div class=\"product-price\">\n <span class=\"regular-price-normal\">\n <PriceRange amount={finalAmount} currency={currency} />\n </span>\n <span class=\"special-price-crossed\">\n <PriceRange amount={regularAmount} currency={currency} />\n </span>\n </div>\n );\n};\n","import { PriceRange } from \"@adobe-commerce/elsie/components\";\nimport { Product } from \"@/plp/data/models/product\";\n\nexport const ComplexProductPrice = ({ product }: { product: Product }) => {\n let currency =\n product.priceRange?.minimum?.regular?.amount?.currency ?? \"USD\";\n\n if (!Intl.supportedValuesOf(\"currency\").includes(currency)) {\n currency = \"USD\";\n }\n\n const minFinal = product.priceRange?.minimum?.final.amount.value;\n const minRegular = product.priceRange?.minimum?.regular.amount.value;\n const maxFinal = product.priceRange?.maximum?.final.amount.value;\n const maxRegular = product.priceRange?.maximum?.regular.amount.value;\n\n const hasSpecial = minFinal < minRegular || maxFinal < maxRegular;\n\n if (!hasSpecial) {\n return (\n <PriceRange\n display=\"from to\"\n minimumAmount={minRegular}\n maximumAmount={maxRegular}\n currency={currency}\n />\n );\n }\n\n return (\n <div class=\"product-price\">\n <span class=\"regular-price-normal\">\n <PriceRange\n display=\"from to\"\n minimumAmount={minFinal}\n maximumAmount={maxFinal}\n currency={currency}\n />\n </span>\n\n <span class=\"special-price-crossed\">\n <PriceRange\n display=\"from to\"\n minimumAmount={minRegular}\n maximumAmount={maxRegular}\n currency={currency}\n />\n </span>\n </div>\n );\n};","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { HTMLAttributes, useEffect, useState } from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { events } from '@adobe-commerce/event-bus';\nimport { ImageProps, Image, ProductItemCard } from '@adobe-commerce/elsie/components';\nimport { htmlStringDecode } from '@/plp/utils/htmlStringDecode';\nimport { Scope, SearchVariables } from '@/plp/data/models';\nimport { Product } from '@/plp/data/models/product';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { SimpleProductPrice } from '@/plp/containers/SearchResults/SimpleProductPrice';\nimport { ComplexProductPrice } from \"@/plp/containers/SearchResults/ComplexProductPrice\";\nimport { ProductList, SearchAlertMessage } from '@/plp/components'\nimport {\n searchProductClick,\n searchResultsView,\n categoryResultsView,\n PLP_UNIT_ID,\n SEARCH_UNIT_ID\n} from '@/plp/utils/acdlEvents';\n\ntype SlotDefaultContext = {\n product: Product;\n variables: SearchVariables | null;\n}\n\nexport interface SearchResultsProps extends HTMLAttributes<HTMLDivElement> {\n routeProduct?: (product: Product) => string;\n scope?: Scope;\n imageWidth?: number;\n imageHeight?: number;\n skeletonCount?: number;\n onSearchResult?: (payload: Product[]) => void;\n slots?: {\n ProductActions?: SlotProps<SlotDefaultContext>;\n ProductPrice?: SlotProps<SlotDefaultContext>;\n ProductName?: SlotProps<SlotDefaultContext>;\n ProductImage?: SlotProps<SlotDefaultContext & { defaultImageProps: ImageProps }>;\n NoResults?: SlotProps<{ error: string | null; variables: SearchVariables | null }>;\n Header?: SlotProps<{ products: Product[]; variables: SearchVariables | null }>;\n Footer?: SlotProps<{ products: Product[]; variables: SearchVariables | null }>;\n },\n}\n\nexport const SearchResults: Container<SearchResultsProps> = ({\n routeProduct,\n scope,\n slots,\n imageWidth = 400,\n imageHeight = 450,\n skeletonCount = 8,\n onSearchResult,\n}) => {\n const acdlUnitId = scope === 'popover' ? SEARCH_UNIT_ID : PLP_UNIT_ID;\n\n const labels = useText({\n noResults: 'Search.PLP.noResults',\n searchError: 'Search.PLP.searchError',\n });\n\n const [variables, setVariables] = useState<SearchVariables | null>(null);\n const [items, setItems] = useState<any[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const loadingEvent = events.on('search/loading', setLoading, { eager: true, scope });\n\n const errorEvent = events.on('search/error', () => {\n setError(labels.searchError!);\n }, { eager: true, scope });\n\n const searchEvent = events.on('search/result', (payload) => {\n setError(payload.result?.items.length < 1 ? labels.noResults! : null);\n\n setVariables(payload.request);\n setItems(payload.result?.items);\n onSearchResult?.(payload.result?.items);\n\n // Publish search results view event to ACDL\n if (payload.request.phrase) {\n searchResultsView(acdlUnitId);\n } else {\n categoryResultsView(acdlUnitId);\n }\n }, { eager: true, scope });\n\n return () => {\n loadingEvent?.off();\n errorEvent?.off();\n searchEvent?.off();\n };\n }, []);\n\n const handleProductClick = (event: MouseEvent, product: Product): void => {\n const anchor = (event.target as HTMLElement)?.closest('a');\n\n if (!anchor || !routeProduct) return;\n\n const anchorUrl = new URL(anchor.href);\n const routeUrl = new URL(routeProduct(product), window.location.origin);\n\n // Compare both pathname and hostname to ensure same path under same host\n if (anchorUrl.pathname === routeUrl.pathname && anchorUrl.hostname === routeUrl.hostname) { \n searchProductClick(product.sku, acdlUnitId);\n }\n };\n\n const renderProductImageSlot = (product: Product, index: number) => {\n const defaultImageProps: ImageProps = {\n loading: index < 8 ? 'eager' : 'lazy',\n src: product.images?.[0]?.url || '',\n alt: product.images?.[0]?.label || '',\n width: imageWidth,\n height: imageHeight,\n params: { width: imageWidth },\n };\n const productName = product.name !== null ? htmlStringDecode(product.name) : product.sku;\n const imageComponent = (\n <Image class=\"product-discovery-product-item__image\" {...defaultImageProps} aria-label={productName || ''} />\n );\n\n return (\n <Slot name=\"ProductImage\" slot={slots?.ProductImage} context={{ product, defaultImageProps, variables }}>\n {routeProduct ? (\n <a href={routeProduct(product)}>\n {imageComponent}\n </a>\n ) : (\n imageComponent\n )}\n </Slot>\n );\n };\n\n const renderProductNameSlot = (product: Product) => {\n const productName = product.name !== null ? htmlStringDecode(product.name) : '';\n return (\n <Slot name=\"ProductName\" slot={slots?.ProductName} context={{ product, variables }}>\n {routeProduct ? (\n <a href={routeProduct(product)}>\n {productName}\n </a>\n ) : (\n productName\n )}\n </Slot>\n );\n };\n\n const renderProductPriceSlot = (product: Product) => {\n const PriceNode =\n product.typename === \"ComplexProductView\" ? (\n <ComplexProductPrice product={product} />\n ) : (\n <SimpleProductPrice product={product} />\n );\n \n return (\n <Slot name=\"ProductPrice\" slot={slots?.ProductPrice} context={{ product, variables }}>\n {routeProduct ? (\n <a href={routeProduct(product)}>{PriceNode}</a>\n ) : (\n PriceNode\n )}\n </Slot>\n );\n }; \n \n const renderActionsSlot = (product: Product) => {\n return <Slot name=\"ProductActions\" slot={slots?.ProductActions} context={{ product, variables }} />;\n };\n\n const renderAlertSlot = () => {\n return <Slot name=\"NoResults\" slot={slots?.NoResults} context={{ error, variables }}>\n {error && <SearchAlertMessage alertMessage={error} />}\n </Slot>;\n }\n\n const renderSkeleton = () => {\n return <ProductList\n imageWidth={imageWidth}\n imageHeight={imageHeight}\n productList={Array.from({ length: skeletonCount }).map((_, index) => (\n <ProductItemCard key={index} initialized={false} />\n ))}\n />\n }\n\n const renderHeader = () => {\n return <Slot name=\"Header\" slot={slots?.Header} context={{ products: items, variables }} />;\n }\n\n const renderFooter = () => {\n return <Slot name=\"Footer\" slot={slots?.Footer} context={{ products: items, variables }} />;\n }\n\n const renderResults = () => {\n if (error) return renderAlertSlot();\n\n return <ProductList\n header={renderHeader()}\n footer={renderFooter()}\n imageWidth={imageWidth}\n imageHeight={imageHeight}\n productList={items.map((product, index) => (\n <ProductItemCard key={product.id || product.sku || index}\n image={renderProductImageSlot(product, index)}\n titleNode={renderProductNameSlot(product)}\n price={renderProductPriceSlot(product)}\n actionButton={slots?.ProductActions ? renderActionsSlot(product) : undefined}\n onClick={(event) => handleProductClick(event, product)}\n initialized\n />\n ))}\n />\n }\n\n return (\n <div>\n {loading ? renderSkeleton() : renderResults()}\n </div>\n );\n};\n"],"names":["htmlStringDecode","input","SimpleProductPrice","product","currency","_c","_b","_a","finalAmount","_f","_e","_d","regularAmount","_i","_h","_g","jsxs","jsx","PriceRange","ComplexProductPrice","minFinal","minRegular","maxFinal","_j","maxRegular","_l","_k","SearchResults","routeProduct","scope","slots","imageWidth","imageHeight","skeletonCount","onSearchResult","acdlUnitId","SEARCH_UNIT_ID","PLP_UNIT_ID","labels","useText","variables","setVariables","useState","items","setItems","loading","setLoading","error","setError","useEffect","loadingEvent","events","errorEvent","searchEvent","payload","searchResultsView","categoryResultsView","handleProductClick","event","anchor","anchorUrl","routeUrl","searchProductClick","renderProductImageSlot","index","defaultImageProps","productName","imageComponent","Image","Slot","renderProductNameSlot","renderProductPriceSlot","PriceNode","renderActionsSlot","renderAlertSlot","SearchAlertMessage","renderSkeleton","ProductList","_","ProductItemCard","renderHeader","renderFooter"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SearchResults.js","sources":["/@dropins/storefront-product-discovery/src/utils/htmlStringDecode.ts","/@dropins/storefront-product-discovery/src/containers/SearchResults/SimpleProductPrice.tsx","/@dropins/storefront-product-discovery/src/containers/SearchResults/ComplexProductPrice.tsx","/@dropins/storefront-product-discovery/src/containers/SearchResults/SearchResults.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nconst htmlStringDecode = (input: string): string | null => {\n const doc = new DOMParser().parseFromString(input, 'text/html');\n return doc.documentElement.textContent;\n};\n\nexport { htmlStringDecode };\n","import { PriceRange } from \"@adobe-commerce/elsie/components\";\nimport { Product } from \"@/plp/data/models/product\";\nimport '@/plp/components/ProductList/ProductList';\n\nexport const SimpleProductPrice = ({ product }: { product: Product }) => {\n let currency = product.price?.regular?.amount?.currency ?? \"USD\";\n\n if (!Intl.supportedValuesOf(\"currency\").includes(currency)) {\n currency = \"USD\";\n }\n\n\n const finalAmount = product.price?.final?.amount?.value;\n const regularAmount = product.price?.regular?.amount?.value;\n\n const hasSpecial =\n finalAmount !== undefined &&\n regularAmount !== undefined &&\n finalAmount < regularAmount;\n\n if (!hasSpecial) {\n return <PriceRange amount={regularAmount} currency={currency} />;\n }\n\n return (\n <div class=\"product-price\">\n <span class=\"regular-price-normal\">\n <PriceRange amount={finalAmount} currency={currency} />\n </span>\n <span class=\"special-price-crossed\">\n <PriceRange amount={regularAmount} currency={currency} />\n </span>\n </div>\n );\n};\n","import { PriceRange } from \"@adobe-commerce/elsie/components\";\nimport { Product } from \"@/plp/data/models/product\";\n\nexport const ComplexProductPrice = ({ product }: { product: Product }) => {\n let currency =\n product.priceRange?.minimum?.regular?.amount?.currency ?? \"USD\";\n\n if (!Intl.supportedValuesOf(\"currency\").includes(currency)) {\n currency = \"USD\";\n }\n\n const minFinal = product.priceRange?.minimum?.final.amount.value;\n const minRegular = product.priceRange?.minimum?.regular.amount.value;\n const maxFinal = product.priceRange?.maximum?.final.amount.value;\n const maxRegular = product.priceRange?.maximum?.regular.amount.value;\n\n const hasSpecial = minFinal < minRegular || maxFinal < maxRegular;\n\n if (!hasSpecial) {\n return (\n <PriceRange\n display=\"from to\"\n minimumAmount={minRegular}\n maximumAmount={maxRegular}\n currency={currency}\n />\n );\n }\n\n return (\n <div class=\"product-price\">\n <span class=\"regular-price-normal\">\n <PriceRange\n display=\"from to\"\n minimumAmount={minFinal}\n maximumAmount={maxFinal}\n currency={currency}\n />\n </span>\n\n <span class=\"special-price-crossed\">\n <PriceRange\n display=\"from to\"\n minimumAmount={minRegular}\n maximumAmount={maxRegular}\n currency={currency}\n />\n </span>\n </div>\n );\n};","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { HTMLAttributes, useEffect, useState } from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { events } from '@adobe-commerce/event-bus';\nimport { ImageProps, Image, ProductItemCard } from '@adobe-commerce/elsie/components';\nimport { htmlStringDecode } from '@/plp/utils/htmlStringDecode';\nimport { Scope, SearchVariables } from '@/plp/data/models';\nimport { Product } from '@/plp/data/models/product';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { SimpleProductPrice } from '@/plp/containers/SearchResults/SimpleProductPrice';\nimport { ComplexProductPrice } from \"@/plp/containers/SearchResults/ComplexProductPrice\";\nimport { ProductList, SearchAlertMessage } from '@/plp/components'\nimport {\n searchProductClick,\n searchResultsView,\n categoryResultsView,\n PLP_UNIT_ID,\n SEARCH_UNIT_ID\n} from '@/plp/utils/acdlEvents';\n\ntype SlotDefaultContext = {\n product: Product;\n variables: SearchVariables | null;\n}\n\nexport interface SearchResultsProps extends HTMLAttributes<HTMLDivElement> {\n routeProduct?: (product: Product) => string;\n scope?: Scope;\n imageWidth?: number;\n imageHeight?: number;\n skeletonCount?: number;\n onSearchResult?: (payload: Product[]) => void;\n slots?: {\n ProductActions?: SlotProps<SlotDefaultContext>;\n ProductPrice?: SlotProps<SlotDefaultContext>;\n ProductName?: SlotProps<SlotDefaultContext>;\n ProductImage?: SlotProps<SlotDefaultContext & { defaultImageProps: ImageProps }>;\n NoResults?: SlotProps<{ error: string | null; variables: SearchVariables | null }>;\n Header?: SlotProps<{ products: Product[]; variables: SearchVariables | null }>;\n Footer?: SlotProps<{ products: Product[]; variables: SearchVariables | null }>;\n },\n}\n\nexport const SearchResults: Container<SearchResultsProps> = ({\n routeProduct,\n scope,\n slots,\n imageWidth = 400,\n imageHeight = 450,\n skeletonCount = 8,\n onSearchResult,\n}) => {\n const acdlUnitId = scope === 'popover' ? SEARCH_UNIT_ID : PLP_UNIT_ID;\n\n const labels = useText({\n noResults: 'Search.PLP.noResults',\n searchError: 'Search.PLP.searchError',\n });\n\n const [variables, setVariables] = useState<SearchVariables | null>(null);\n const [items, setItems] = useState<any[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const loadingEvent = events.on('search/loading', setLoading, { eager: true, scope });\n\n const errorEvent = events.on('search/error', () => {\n setError(labels.searchError!);\n }, { eager: true, scope });\n\n const searchEvent = events.on('search/result', (payload) => {\n setError(payload.result?.items.length < 1 ? labels.noResults! : null);\n\n setVariables(payload.request);\n setItems(payload.result?.items);\n onSearchResult?.(payload.result?.items);\n\n // Publish search results view event to ACDL\n if (payload.request.phrase) {\n searchResultsView(acdlUnitId);\n } else {\n categoryResultsView(acdlUnitId);\n }\n }, { eager: true, scope });\n\n return () => {\n loadingEvent?.off();\n errorEvent?.off();\n searchEvent?.off();\n };\n }, []);\n\n const handleProductClick = (event: MouseEvent, product: Product): void => {\n const anchor = (event.target as HTMLElement)?.closest('a');\n\n if (!anchor || !routeProduct) return;\n\n const anchorUrl = new URL(anchor.href);\n const routeUrl = new URL(routeProduct(product), window.location.origin);\n\n // Compare both pathname and hostname to ensure same path under same host\n if (anchorUrl.pathname === routeUrl.pathname && anchorUrl.hostname === routeUrl.hostname) { \n searchProductClick(product.sku, acdlUnitId);\n }\n };\n\n const renderProductImageSlot = (product: Product, index: number) => {\n const defaultImageProps: ImageProps = {\n loading: index < 8 ? 'eager' : 'lazy',\n src: product.images?.[0]?.url || '',\n alt: product.images?.[0]?.label || '',\n width: imageWidth,\n height: imageHeight,\n params: { width: imageWidth },\n };\n const productName = product.name !== null ? htmlStringDecode(product.name) : product.sku;\n const imageComponent = (\n <Image class=\"product-discovery-product-item__image\" {...defaultImageProps} aria-label={productName || ''} />\n );\n\n return (\n <Slot name=\"ProductImage\" slot={slots?.ProductImage} context={{ product, defaultImageProps, variables }}>\n {routeProduct ? (\n <a href={routeProduct(product)}>\n {imageComponent}\n </a>\n ) : (\n imageComponent\n )}\n </Slot>\n );\n };\n\n const renderProductNameSlot = (product: Product) => {\n const productName = product.name !== null ? htmlStringDecode(product.name) : '';\n return (\n <Slot name=\"ProductName\" slot={slots?.ProductName} context={{ product, variables }}>\n {routeProduct ? (\n <a href={routeProduct(product)}>\n {productName}\n </a>\n ) : (\n productName\n )}\n </Slot>\n );\n };\n\n const renderProductPriceSlot = (product: Product) => {\n const PriceNode =\n product.typename === \"ComplexProductView\" ? (\n <ComplexProductPrice product={product} />\n ) : (\n <SimpleProductPrice product={product} />\n );\n \n return (\n <Slot name=\"ProductPrice\" slot={slots?.ProductPrice} context={{ product, variables }}>\n {routeProduct ? (\n <a href={routeProduct(product)}>{PriceNode}</a>\n ) : (\n PriceNode\n )}\n </Slot>\n );\n }; \n \n const renderActionsSlot = (product: Product) => {\n return <Slot name=\"ProductActions\" slot={slots?.ProductActions} context={{ product, variables }} />;\n };\n\n const renderAlertSlot = () => {\n return <Slot name=\"NoResults\" slot={slots?.NoResults} context={{ error, variables }}>\n {error && <SearchAlertMessage alertMessage={error} />}\n </Slot>;\n }\n\n const renderSkeleton = () => {\n return <ProductList\n imageWidth={imageWidth}\n imageHeight={imageHeight}\n productList={Array.from({ length: skeletonCount }).map((_, index) => (\n <ProductItemCard key={index} initialized={false} />\n ))}\n />\n }\n\n const renderHeader = () => {\n return <Slot name=\"Header\" slot={slots?.Header} context={{ products: items, variables }} />;\n }\n\n const renderFooter = () => {\n return <Slot name=\"Footer\" slot={slots?.Footer} context={{ products: items, variables }} />;\n }\n\n const renderResults = () => {\n if (error) return renderAlertSlot();\n\n return <ProductList\n header={renderHeader()}\n footer={renderFooter()}\n imageWidth={imageWidth}\n imageHeight={imageHeight}\n productList={items.map((product, index) => (\n <ProductItemCard key={product.id || product.sku || index}\n image={renderProductImageSlot(product, index)}\n titleNode={renderProductNameSlot(product)}\n price={renderProductPriceSlot(product)}\n actionButton={slots?.ProductActions ? renderActionsSlot(product) : undefined}\n onClick={(event) => handleProductClick(event, product)}\n initialized\n />\n ))}\n />\n }\n\n return (\n <div>\n {loading ? renderSkeleton() : renderResults()}\n </div>\n );\n};\n"],"names":["htmlStringDecode","input","SimpleProductPrice","product","currency","_c","_b","_a","finalAmount","_f","_e","_d","regularAmount","_i","_h","_g","jsxs","jsx","PriceRange","ComplexProductPrice","minFinal","minRegular","maxFinal","_j","maxRegular","_l","_k","SearchResults","routeProduct","scope","slots","imageWidth","imageHeight","skeletonCount","onSearchResult","acdlUnitId","SEARCH_UNIT_ID","PLP_UNIT_ID","labels","useText","variables","setVariables","useState","items","setItems","loading","setLoading","error","setError","useEffect","loadingEvent","events","errorEvent","searchEvent","payload","searchResultsView","categoryResultsView","handleProductClick","event","anchor","anchorUrl","routeUrl","searchProductClick","renderProductImageSlot","index","defaultImageProps","productName","imageComponent","Image","Slot","renderProductNameSlot","renderProductPriceSlot","PriceNode","renderActionsSlot","renderAlertSlot","SearchAlertMessage","renderSkeleton","ProductList","_","ProductItemCard","renderHeader","renderFooter"],"mappings":"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"}
|
package/containers/SortBy.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{jsx as g}from"@dropins/tools/preact-jsx-runtime.js";import{useState as S,useEffect as p}from"@dropins/tools/preact-compat.js";import{Picker as v}from"@dropins/tools/components.js";import{events as $}from"@dropins/tools/event-bus.js";import{search as w}from"../api.js";import{useText as x}from"@dropins/tools/i18n.js";import"@dropins/tools/lib.js";import"@dropins/tools/fetch-graphql.js";const
|
|
3
|
+
import{jsx as g}from"@dropins/tools/preact-jsx-runtime.js";import{useState as S,useEffect as p}from"@dropins/tools/preact-compat.js";import{Picker as v}from"@dropins/tools/components.js";import{events as $}from"@dropins/tools/event-bus.js";import{search as w}from"../api.js";import{useText as x}from"@dropins/tools/i18n.js";import"@dropins/tools/lib.js";import"../fragments.js";import"@dropins/tools/fetch-graphql.js";const H=({scope:t,onSortChange:e})=>{const s=x({sortLabel:"Search.SortBy.title",lowToHigh:"Search.SortBy.lowToHigh",highToLow:"Search.SortBy.highToLow",relevance:"Search.SortBy.relevance",position:"Search.SortBy.position",name:"Search.SortBy.name",price:"Search.SortBy.price"}),[o,r]=S([]),[a,c]=S("relevance_DESC"),[f,m]=S({});p(()=>{const i=$.on("search/result",n=>{var u,l;if(m(n.request),(l=(u=n.result)==null?void 0:u.metadata)!=null&&l.sortableAttributes&&(r([...n.result.metadata.sortableAttributes]),n.request.sort)){const h=d(n.request.sort);h&&c(h)}},{eager:!0,scope:t});return()=>{i==null||i.off()}},[]);const b=async i=>{e==null||e(i[0]),w({...f,sort:i,currentPage:1},{scope:t})};return g(v,{required:!0,floatingLabel:s.sortLabel,...B(o,s),value:a,handleSelect:i=>{const{value:n}=i.target,u=L(n);b(u)}})};function B(t,e){const s={relevance:e.relevance,position:e.position,name:e.name,price:e.price},o=[];return t.forEach((r,a)=>{const c=s[r.attribute]||r.label;r.bidirectional?o.splice(a+o.length,0,{text:`${c}: ${e.lowToHigh}`,value:`${r.attribute}_ASC`},{text:`${c}: ${e.highToLow}`,value:`${r.attribute}_DESC`}):o.splice(a+o.length,0,{text:c,value:`${r.attribute}_DESC`})}),{options:o}}function L(t){const e=t.indexOf("_");return[{attribute:t.substring(0,e),direction:t.substring(e+1)==="ASC"?"ASC":"DESC"}]}function d(t){return t.length>0&&t[0]?`${t[0].attribute}_${t[0].direction}`:""}export{H as SortBy,H as default};
|
|
4
4
|
//# sourceMappingURL=SortBy.js.map
|
package/containers/SortBy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SortBy.js","sources":["/@dropins/storefront-product-discovery/src/containers/SortBy/SortBy.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { HTMLAttributes, useState, useEffect } from 'preact/compat';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { Picker } from '@adobe-commerce/elsie/components';\nimport { events } from '@adobe-commerce/event-bus';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Scope, SearchVariables, SortOrder } from '@/plp/data/models';\nimport { search } from '@/plp/api';\n\nexport interface SortByProps extends HTMLAttributes<HTMLDivElement> {\n scope?: Scope;\n onSortChange?: (value: SortOrder | null) => void;\n}\n\nexport const SortBy: Container<SortByProps> = ({ scope, onSortChange }) => {\n const labels = useText({\n sortLabel: 'Search.SortBy.title',\n lowToHigh: 'Search.SortBy.lowToHigh',\n highToLow: 'Search.SortBy.highToLow',\n relevance: 'Search.SortBy.relevance',\n position: 'Search.SortBy.position',\n name: 'Search.SortBy.name',\n price: 'Search.SortBy.price',\n });\n\n\n const [sortOptions, setSortOptions] = useState<any[]>([]);\n const [current, setCurrent] = useState('relevance_DESC');\n const [currentSearchVariables, setCurrentSearchVariables] = useState<SearchVariables>({});\n\n useEffect(() => {\n // Listen for search results\n const searchEvent = events.on('search/result', (payload) => {\n setCurrentSearchVariables(payload.request);\n\n // Configure sort options from metadata\n if (payload.result?.metadata?.sortableAttributes) {\n setSortOptions([...payload.result.metadata.sortableAttributes]);\n\n // Set current sort value from request\n if (payload.request.sort) {\n const sortValue = getSortValue(payload.request.sort);\n\n if (sortValue) {\n setCurrent(sortValue);\n }\n }\n }\n }, { eager: true, scope });\n\n return () => {\n searchEvent?.off();\n };\n }, []);\n\n const handleSortChange = async (value: SortOrder[]): Promise<void> => {\n onSortChange?.(value[0]!);\n\n search({ ...currentSearchVariables, sort: value, currentPage: 1 }, { scope });\n };\n\n return (\n <Picker\n required\n floatingLabel={labels.sortLabel}\n {...getSortOptions(sortOptions, labels)}\n value={current}\n handleSelect={(event) => {\n const { value } = event.target as HTMLSelectElement;\n const next = getSortSearchVariables(value);\n handleSortChange(next);\n }}\n />\n );\n};\n\n/** Utility functions */\n\nfunction getSortOptions(sortOptions: any, labels: any): any {\n const attributeLabels: Record<string, string> = {\n relevance: labels.relevance,\n position: labels.position,\n name: labels.name,\n price: labels.price,\n };\n\n const options: any[] = [];\n\n // if sortOption is bidirectional, then we need to add two options: lowToHigh and highToLow\n sortOptions.forEach((option: any, index: number) => {\n const displayLabel = attributeLabels[option.attribute] || option.label;\n\n if (option.bidirectional) {\n // Insert the two options at the current position\n options.splice(index + options.length, 0,\n { text: `${displayLabel}: ${labels.lowToHigh}`, value: `${option.attribute}_ASC` },\n { text: `${displayLabel}: ${labels.highToLow}`, value: `${option.attribute}_DESC` }\n );\n } else {\n // Add single option at the current position\n options.splice(index + options.length, 0,\n { text: displayLabel, value: `${option.attribute}_DESC` }\n );\n }\n });\n\n return { options };\n}\n\n\nfunction getSortSearchVariables(sortValue: string): SortOrder[] {\n const index = sortValue.indexOf('_');\n const newSort: SortOrder[] = [\n {\n attribute: sortValue.substring(0, index) as string,\n direction: sortValue.substring(index + 1) === 'ASC' ? 'ASC' : 'DESC',\n },\n ];\n return newSort;\n}\n\nfunction getSortValue(sort: SortOrder[]) {\n if (sort.length > 0 && sort[0]) {\n return `${sort[0].attribute}_${sort[0].direction}`;\n }\n return '';\n}\n"],"names":["SortBy","scope","onSortChange","labels","useText","sortOptions","setSortOptions","useState","current","setCurrent","currentSearchVariables","setCurrentSearchVariables","useEffect","searchEvent","events","payload","_b","_a","sortValue","getSortValue","handleSortChange","value","search","jsx","Picker","getSortOptions","event","next","getSortSearchVariables","attributeLabels","options","option","index","displayLabel","sort"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SortBy.js","sources":["/@dropins/storefront-product-discovery/src/containers/SortBy/SortBy.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { HTMLAttributes, useState, useEffect } from 'preact/compat';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { Picker } from '@adobe-commerce/elsie/components';\nimport { events } from '@adobe-commerce/event-bus';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Scope, SearchVariables, SortOrder } from '@/plp/data/models';\nimport { search } from '@/plp/api';\n\nexport interface SortByProps extends HTMLAttributes<HTMLDivElement> {\n scope?: Scope;\n onSortChange?: (value: SortOrder | null) => void;\n}\n\nexport const SortBy: Container<SortByProps> = ({ scope, onSortChange }) => {\n const labels = useText({\n sortLabel: 'Search.SortBy.title',\n lowToHigh: 'Search.SortBy.lowToHigh',\n highToLow: 'Search.SortBy.highToLow',\n relevance: 'Search.SortBy.relevance',\n position: 'Search.SortBy.position',\n name: 'Search.SortBy.name',\n price: 'Search.SortBy.price',\n });\n\n\n const [sortOptions, setSortOptions] = useState<any[]>([]);\n const [current, setCurrent] = useState('relevance_DESC');\n const [currentSearchVariables, setCurrentSearchVariables] = useState<SearchVariables>({});\n\n useEffect(() => {\n // Listen for search results\n const searchEvent = events.on('search/result', (payload) => {\n setCurrentSearchVariables(payload.request);\n\n // Configure sort options from metadata\n if (payload.result?.metadata?.sortableAttributes) {\n setSortOptions([...payload.result.metadata.sortableAttributes]);\n\n // Set current sort value from request\n if (payload.request.sort) {\n const sortValue = getSortValue(payload.request.sort);\n\n if (sortValue) {\n setCurrent(sortValue);\n }\n }\n }\n }, { eager: true, scope });\n\n return () => {\n searchEvent?.off();\n };\n }, []);\n\n const handleSortChange = async (value: SortOrder[]): Promise<void> => {\n onSortChange?.(value[0]!);\n\n search({ ...currentSearchVariables, sort: value, currentPage: 1 }, { scope });\n };\n\n return (\n <Picker\n required\n floatingLabel={labels.sortLabel}\n {...getSortOptions(sortOptions, labels)}\n value={current}\n handleSelect={(event) => {\n const { value } = event.target as HTMLSelectElement;\n const next = getSortSearchVariables(value);\n handleSortChange(next);\n }}\n />\n );\n};\n\n/** Utility functions */\n\nfunction getSortOptions(sortOptions: any, labels: any): any {\n const attributeLabels: Record<string, string> = {\n relevance: labels.relevance,\n position: labels.position,\n name: labels.name,\n price: labels.price,\n };\n\n const options: any[] = [];\n\n // if sortOption is bidirectional, then we need to add two options: lowToHigh and highToLow\n sortOptions.forEach((option: any, index: number) => {\n const displayLabel = attributeLabels[option.attribute] || option.label;\n\n if (option.bidirectional) {\n // Insert the two options at the current position\n options.splice(index + options.length, 0,\n { text: `${displayLabel}: ${labels.lowToHigh}`, value: `${option.attribute}_ASC` },\n { text: `${displayLabel}: ${labels.highToLow}`, value: `${option.attribute}_DESC` }\n );\n } else {\n // Add single option at the current position\n options.splice(index + options.length, 0,\n { text: displayLabel, value: `${option.attribute}_DESC` }\n );\n }\n });\n\n return { options };\n}\n\n\nfunction getSortSearchVariables(sortValue: string): SortOrder[] {\n const index = sortValue.indexOf('_');\n const newSort: SortOrder[] = [\n {\n attribute: sortValue.substring(0, index) as string,\n direction: sortValue.substring(index + 1) === 'ASC' ? 'ASC' : 'DESC',\n },\n ];\n return newSort;\n}\n\nfunction getSortValue(sort: SortOrder[]) {\n if (sort.length > 0 && sort[0]) {\n return `${sort[0].attribute}_${sort[0].direction}`;\n }\n return '';\n}\n"],"names":["SortBy","scope","onSortChange","labels","useText","sortOptions","setSortOptions","useState","current","setCurrent","currentSearchVariables","setCurrentSearchVariables","useEffect","searchEvent","events","payload","_b","_a","sortValue","getSortValue","handleSortChange","value","search","jsx","Picker","getSortOptions","event","next","getSortSearchVariables","attributeLabels","options","option","index","displayLabel","sort"],"mappings":"kaAsBO,MAAMA,EAAiC,CAAC,CAAE,MAAAC,EAAO,aAAAC,KAAmB,CACzE,MAAMC,EAASC,EAAQ,CACrB,UAAW,sBACX,UAAW,0BACX,UAAW,0BACX,UAAW,0BACX,SAAU,yBACV,KAAM,qBACN,MAAO,qBAAA,CACR,EAGK,CAACC,EAAaC,CAAc,EAAIC,EAAgB,CAAA,CAAE,EAClD,CAACC,EAASC,CAAU,EAAIF,EAAS,gBAAgB,EACjD,CAACG,EAAwBC,CAAyB,EAAIJ,EAA0B,CAAA,CAAE,EAExFK,EAAU,IAAM,CAEd,MAAMC,EAAcC,EAAO,GAAG,gBAAkBC,GAAY,SAI1D,GAHAJ,EAA0BI,EAAQ,OAAO,GAGrCC,GAAAC,EAAAF,EAAQ,SAAR,YAAAE,EAAgB,WAAhB,MAAAD,EAA0B,qBAC5BV,EAAe,CAAC,GAAGS,EAAQ,OAAO,SAAS,kBAAkB,CAAC,EAG1DA,EAAQ,QAAQ,MAAM,CACxB,MAAMG,EAAYC,EAAaJ,EAAQ,QAAQ,IAAI,EAE/CG,GACFT,EAAWS,CAAS,CAExB,CAEJ,EAAG,CAAE,MAAO,GAAM,MAAAjB,EAAO,EAEzB,MAAO,IAAM,CACXY,GAAA,MAAAA,EAAa,KACf,CACF,EAAG,CAAA,CAAE,EAEL,MAAMO,EAAmB,MAAOC,GAAsC,CACpEnB,GAAA,MAAAA,EAAemB,EAAM,CAAC,GAEtBC,EAAO,CAAE,GAAGZ,EAAwB,KAAMW,EAAO,YAAa,CAAA,EAAK,CAAE,MAAApB,EAAO,CAC9E,EAEA,OACEsB,EAACC,EAAA,CACC,SAAQ,GACR,cAAerB,EAAO,UACrB,GAAGsB,EAAepB,EAAaF,CAAM,EACtC,MAAOK,EACP,aAAekB,GAAU,CACvB,KAAM,CAAE,MAAAL,GAAUK,EAAM,OAClBC,EAAOC,EAAuBP,CAAK,EACzCD,EAAiBO,CAAI,CACvB,CAAA,CAAA,CAGN,EAIA,SAASF,EAAepB,EAAkBF,EAAkB,CAC1D,MAAM0B,EAA0C,CAC9C,UAAW1B,EAAO,UAClB,SAAUA,EAAO,SACjB,KAAMA,EAAO,KACb,MAAOA,EAAO,KAAA,EAGV2B,EAAiB,CAAA,EAGvB,OAAAzB,EAAY,QAAQ,CAAC0B,EAAaC,IAAkB,CAClD,MAAMC,EAAeJ,EAAgBE,EAAO,SAAS,GAAKA,EAAO,MAE7DA,EAAO,cAETD,EAAQ,OAAOE,EAAQF,EAAQ,OAAQ,EACrC,CAAE,KAAM,GAAGG,CAAY,KAAK9B,EAAO,SAAS,GAAI,MAAO,GAAG4B,EAAO,SAAS,MAAA,EAC1E,CAAE,KAAM,GAAGE,CAAY,KAAK9B,EAAO,SAAS,GAAI,MAAO,GAAG4B,EAAO,SAAS,OAAA,CAAQ,EAIpFD,EAAQ,OAAOE,EAAQF,EAAQ,OAAQ,EACrC,CAAE,KAAMG,EAAc,MAAO,GAAGF,EAAO,SAAS,OAAA,CAAQ,CAG9D,CAAC,EAEM,CAAE,QAAAD,CAAA,CACX,CAGA,SAASF,EAAuBV,EAAgC,CAC9D,MAAMc,EAAQd,EAAU,QAAQ,GAAG,EAOnC,MAN6B,CAC3B,CACE,UAAWA,EAAU,UAAU,EAAGc,CAAK,EACvC,UAAWd,EAAU,UAAUc,EAAQ,CAAC,IAAM,MAAQ,MAAQ,MAAA,CAChE,CAGJ,CAEA,SAASb,EAAae,EAAmB,CACvC,OAAIA,EAAK,OAAS,GAAKA,EAAK,CAAC,EACpB,GAAGA,EAAK,CAAC,EAAE,SAAS,IAAIA,EAAK,CAAC,EAAE,SAAS,GAE3C,EACT"}
|
package/fragments.js
CHANGED
|
@@ -1,4 +1,118 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
|
|
3
|
+
const e=`
|
|
4
|
+
fragment Facet on Aggregation {
|
|
5
|
+
title
|
|
6
|
+
attribute
|
|
7
|
+
buckets {
|
|
8
|
+
title
|
|
9
|
+
__typename
|
|
10
|
+
... on CategoryView {
|
|
11
|
+
name
|
|
12
|
+
count
|
|
13
|
+
path
|
|
14
|
+
}
|
|
15
|
+
... on ScalarBucket {
|
|
16
|
+
count
|
|
17
|
+
}
|
|
18
|
+
... on RangeBucket {
|
|
19
|
+
from
|
|
20
|
+
to
|
|
21
|
+
count
|
|
22
|
+
}
|
|
23
|
+
... on StatsBucket {
|
|
24
|
+
min
|
|
25
|
+
max
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`,t=`
|
|
30
|
+
fragment ProductView on ProductSearchItem {
|
|
31
|
+
productView {
|
|
32
|
+
__typename
|
|
33
|
+
sku
|
|
34
|
+
name
|
|
35
|
+
inStock
|
|
36
|
+
url
|
|
37
|
+
urlKey
|
|
38
|
+
attributes(roles: []) {
|
|
39
|
+
name
|
|
40
|
+
label
|
|
41
|
+
value
|
|
42
|
+
roles
|
|
43
|
+
}
|
|
44
|
+
images {
|
|
45
|
+
label
|
|
46
|
+
url
|
|
47
|
+
roles
|
|
48
|
+
}
|
|
49
|
+
... on ComplexProductView {
|
|
50
|
+
priceRange {
|
|
51
|
+
maximum {
|
|
52
|
+
final {
|
|
53
|
+
amount {
|
|
54
|
+
value
|
|
55
|
+
currency
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
regular {
|
|
59
|
+
amount {
|
|
60
|
+
value
|
|
61
|
+
currency
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
minimum {
|
|
66
|
+
final {
|
|
67
|
+
amount {
|
|
68
|
+
value
|
|
69
|
+
currency
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
regular {
|
|
73
|
+
amount {
|
|
74
|
+
value
|
|
75
|
+
currency
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
options {
|
|
81
|
+
id
|
|
82
|
+
title
|
|
83
|
+
values {
|
|
84
|
+
title
|
|
85
|
+
... on ProductViewOptionValueSwatch {
|
|
86
|
+
id
|
|
87
|
+
inStock
|
|
88
|
+
type
|
|
89
|
+
value
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
... on SimpleProductView {
|
|
95
|
+
price {
|
|
96
|
+
final {
|
|
97
|
+
amount {
|
|
98
|
+
value
|
|
99
|
+
currency
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
regular {
|
|
103
|
+
amount {
|
|
104
|
+
value
|
|
105
|
+
currency
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
highlights {
|
|
112
|
+
attribute
|
|
113
|
+
value
|
|
114
|
+
matched_words
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
`;export{e as Facet,t as ProductView};
|
|
4
118
|
//# sourceMappingURL=fragments.js.map
|
package/fragments.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fragments.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"fragments.js","sources":["/@dropins/storefront-product-discovery/src/api/graphql/fragments.graphql.ts"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nconst Facet = /* GraphQL */ `\n fragment Facet on Aggregation {\n title\n attribute\n buckets {\n title\n __typename\n ... on CategoryView {\n name\n count\n path\n }\n ... on ScalarBucket {\n count\n }\n ... on RangeBucket {\n from\n to\n count\n }\n ... on StatsBucket {\n min\n max\n }\n }\n }\n`;\n\nconst ProductView = /* GraphQL */ `\n fragment ProductView on ProductSearchItem {\n productView {\n __typename\n sku\n name\n inStock\n url\n urlKey\n attributes(roles: []) {\n name\n label\n value\n roles\n }\n images {\n label\n url\n roles\n }\n ... on ComplexProductView {\n priceRange {\n maximum {\n final {\n amount {\n value\n currency\n }\n }\n regular {\n amount {\n value\n currency\n }\n }\n }\n minimum {\n final {\n amount {\n value\n currency\n }\n }\n regular {\n amount {\n value\n currency\n }\n }\n }\n }\n options {\n id\n title\n values {\n title\n ... on ProductViewOptionValueSwatch {\n id\n inStock\n type\n value\n }\n }\n }\n }\n ... on SimpleProductView {\n price {\n final {\n amount {\n value\n currency\n }\n }\n regular {\n amount {\n value\n currency\n }\n }\n }\n }\n }\n highlights {\n attribute\n value\n matched_words\n }\n }\n`;\n\nexport { Facet, ProductView };\n"],"names":["Facet","ProductView"],"mappings":"AASA,MAAMA,EAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BtBC,EAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name": "@dropins/storefront-product-discovery", "version": "3.1.1
|
|
1
|
+
{"name": "@dropins/storefront-product-discovery", "version": "3.1.1", "@dropins/tools": "~1.9.0", "license": "SEE LICENSE IN LICENSE.md"}
|
package/render.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
3
|
(function(d,r){try{if(typeof document<"u"){const t=document.createElement("style"),o=r.styleId;for(const e in r.attributes)t.setAttribute(e,r.attributes[e]);t.setAttribute("data-dropin",o),t.appendChild(document.createTextNode(d));const i=document.querySelector('style[data-dropin="sdk"]');if(i)i.after(t);else{const e=document.querySelector('link[rel="stylesheet"], style');e?e.before(t):document.head.append(t)}}}catch(t){console.error("dropin-styles (injectCodeFunction)",t)}})(".product-discovery-product-list{container-type:inline-size;display:flex;flex-direction:column;width:100%}.product-discovery-product-list__container{display:flex;flex-direction:column;width:100%}.product-discovery-product-list__grid{display:grid;grid-template-columns:1fr;gap:var(--spacing-small)}.product-discovery-product-list__grid .dropin-product-item-card{margin:unset;width:100%}.product-discovery-product-list__grid .dropin-product-item-card img,.product-discovery-product-list__grid .dropin-product-item-card__skeleton__image{aspect-ratio:var(--imageWidth) / var(--imageHeight);max-height:unset;height:unset}.product-discovery-product-list .product-price{display:flex;gap:8px}.product-discovery-product-list .special-price-crossed{text-decoration:line-through;opacity:.5}@container (min-width: 600px){.product-discovery-product-list__grid{grid-template-columns:repeat(2,1fr)}}@container (min-width: 900px){.product-discovery-product-list__grid{grid-template-columns:repeat(3,1fr)}}@container (min-width: 1200px){.product-discovery-product-list__grid{grid-template-columns:repeat(4,1fr)}}.product-discovery-search-alert-message__wrapper{display:flex;flex-direction:column;justify-content:center;width:100%;min-height:300px}.product-discovery-search-alert-message__content{display:flex;justify-content:center}.product-discovery-facet{padding-block:var(--spacing-small)}.product-discovery-facet:not(.product-discovery-facet--last){border-bottom:1px solid var(--color-neutral-400)}.product-discovery-facet__header{display:block;margin-block-end:var(--spacing-xsmall)}.product-discovery-facet__bucket .dropin-price-range .dropin-price--small.dropin-price--bold{font:var(--type-body-2-default-font)}.product-discovery-facet__bucket .dropin-radio-button__label:before{margin-right:var(--spacing-xsmall)}.product-discovery-facet-list{display:flex;flex-direction:column;width:100%}.product-discovery-facet-list__selected-filters{display:flex;flex-direction:row;flex-wrap:wrap;row-gap:var(--spacing-xxsmall);padding:0 0 var(--spacing-xxsmall) 0}.product-discovery-facet-list__selected-filters button{padding:0 var(--spacing-xxsmall);margin:0 var(--spacing-xxsmall);border-radius:var(--shape-border-radius-2)}.product-discovery-facet-list__selected-filters .dropin-price-range .dropin-price--small.dropin-price--bold{font:var(--type-button-2-font)}.product-discovery-facet-list__facet-options{text-align:left}.product-discovery-facet-list__facet-options button{padding:0}.product-discovery-facet-list__facet-options .dropin-radio-button{padding:var(--spacing-xxsmall) 0}.product-discovery-facet-list__facet-options--hidden{display:none}.product-discovery-facet-list .dropin-divider{margin:var(--spacing-xsmall) 0 var(--spacing-xsmall) 0}",{styleId:"storefront-product-discovery"});
|
|
4
|
-
import{jsx as r}from"@dropins/tools/preact-jsx-runtime.js";import{deepmerge as l,Render as f}from"@dropins/tools/lib.js";import{useState as m,useEffect as g}from"@dropins/tools/preact-hooks.js";import{UIProvider as h}from"@dropins/tools/components.js";import{events as u}from"@dropins/tools/event-bus.js";import{config as p}from"./api.js";import"@dropins/tools/fetch-graphql.js";const d={PLP:{noResults:"Your search returned no results.",searchError:"An error occurred while searching."},Facet:{showMore:"Show more",showLess:"Show less",clearAll:"Clear all"},SortBy:{title:"Sort by",lowToHigh:"Low to High",highToLow:"High to Low",relevance:"Relevance",position:"Position",name:"Product Name",price:"Price"}},w={Search:d},S={default:w},L=({children:n})=>{var o;const[t,i]=m("en_US"),s=(o=p.getConfig())==null?void 0:o.langDefinitions;g(()=>{const e=u.on("locale",a=>{i(a)},{eager:!0});return()=>{e==null||e.off()}},[]);const c=l(S,s??{});return r(h,{lang:t,langDefinitions:c,children:n})},
|
|
4
|
+
import{jsx as r}from"@dropins/tools/preact-jsx-runtime.js";import{deepmerge as l,Render as f}from"@dropins/tools/lib.js";import{useState as m,useEffect as g}from"@dropins/tools/preact-hooks.js";import{UIProvider as h}from"@dropins/tools/components.js";import{events as u}from"@dropins/tools/event-bus.js";import{config as p}from"./api.js";import"./fragments.js";import"@dropins/tools/fetch-graphql.js";const d={PLP:{noResults:"Your search returned no results.",searchError:"An error occurred while searching."},Facet:{showMore:"Show more",showLess:"Show less",clearAll:"Clear all"},SortBy:{title:"Sort by",lowToHigh:"Low to High",highToLow:"High to Low",relevance:"Relevance",position:"Position",name:"Product Name",price:"Price"}},w={Search:d},S={default:w},L=({children:n})=>{var o;const[t,i]=m("en_US"),s=(o=p.getConfig())==null?void 0:o.langDefinitions;g(()=>{const e=u.on("locale",a=>{i(a)},{eager:!0});return()=>{e==null||e.off()}},[]);const c=l(S,s??{});return r(h,{lang:t,langDefinitions:c,children:n})},A=new f(r(L,{}));export{A as render};
|
|
5
5
|
//# sourceMappingURL=render.js.map
|
package/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sources":["/@dropins/storefront-product-discovery/src/render/Provider.tsx","/@dropins/storefront-product-discovery/src/render/render.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { FunctionComponent } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { UIProvider } from '@adobe-commerce/elsie/components';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { events } from '@adobe-commerce/event-bus';\nimport { deepmerge } from '@adobe-commerce/elsie/lib';\n\nimport en_US from '../i18n/en_US.json';\nimport { config } from '../api';\n\n// Langs\nconst langDefinitions = {\n default: en_US,\n};\n\ninterface CartProviderProps {\n children?: any;\n}\n\nexport const Provider: FunctionComponent<CartProviderProps> = ({ children }) => {\n const [lang, setLang] = useState<Lang>('en_US');\n\n const userLangDefinitions = config.getConfig()?.langDefinitions;\n\n\n // Events\n useEffect(() => {\n const localeEvent = events.on(\n 'locale',\n (locale: string) => {\n setLang(locale as Lang);\n },\n { eager: true },\n );\n return () => {\n localeEvent?.off();\n };\n }, []);\n\n // Merge language definitions with user language definitions\n const definitions = deepmerge(langDefinitions, userLangDefinitions ?? {});\n\n return (\n <UIProvider lang={lang} langDefinitions={definitions}>\n {children}\n </UIProvider>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { Render } from '@adobe-commerce/elsie/lib';\nimport { Provider } from './Provider';\n\nexport const render = new Render(<Provider />);\n"],"names":["langDefinitions","en_US","Provider","children","lang","setLang","useState","userLangDefinitions","_a","config","useEffect","localeEvent","events","locale","definitions","deepmerge","jsx","UIProvider","render","Render"],"mappings":"
|
|
1
|
+
{"version":3,"file":"render.js","sources":["/@dropins/storefront-product-discovery/src/render/Provider.tsx","/@dropins/storefront-product-discovery/src/render/render.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { FunctionComponent } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { UIProvider } from '@adobe-commerce/elsie/components';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { events } from '@adobe-commerce/event-bus';\nimport { deepmerge } from '@adobe-commerce/elsie/lib';\n\nimport en_US from '../i18n/en_US.json';\nimport { config } from '../api';\n\n// Langs\nconst langDefinitions = {\n default: en_US,\n};\n\ninterface CartProviderProps {\n children?: any;\n}\n\nexport const Provider: FunctionComponent<CartProviderProps> = ({ children }) => {\n const [lang, setLang] = useState<Lang>('en_US');\n\n const userLangDefinitions = config.getConfig()?.langDefinitions;\n\n\n // Events\n useEffect(() => {\n const localeEvent = events.on(\n 'locale',\n (locale: string) => {\n setLang(locale as Lang);\n },\n { eager: true },\n );\n return () => {\n localeEvent?.off();\n };\n }, []);\n\n // Merge language definitions with user language definitions\n const definitions = deepmerge(langDefinitions, userLangDefinitions ?? {});\n\n return (\n <UIProvider lang={lang} langDefinitions={definitions}>\n {children}\n </UIProvider>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { Render } from '@adobe-commerce/elsie/lib';\nimport { Provider } from './Provider';\n\nexport const render = new Render(<Provider />);\n"],"names":["langDefinitions","en_US","Provider","children","lang","setLang","useState","userLangDefinitions","_a","config","useEffect","localeEvent","events","locale","definitions","deepmerge","jsx","UIProvider","render","Render"],"mappings":"yuBAoBMA,EAAkB,CACtB,QAASC,CACX,EAMaC,EAAiD,CAAC,CAAE,SAAAC,KAAe,OAC9E,KAAM,CAACC,EAAMC,CAAO,EAAIC,EAAe,OAAO,EAExCC,GAAsBC,EAAAC,EAAO,UAAA,IAAP,YAAAD,EAAoB,gBAIhDE,EAAU,IAAM,CACd,MAAMC,EAAcC,EAAO,GACzB,SACCC,GAAmB,CAClBR,EAAQQ,CAAc,CACxB,EACA,CAAE,MAAO,EAAA,CAAK,EAEhB,MAAO,IAAM,CACXF,GAAA,MAAAA,EAAa,KACf,CACF,EAAG,CAAA,CAAE,EAGL,MAAMG,EAAcC,EAAUf,EAAiBO,GAAuB,CAAA,CAAE,EAExE,OACES,EAACC,EAAA,CAAW,KAAAb,EAAY,gBAAiBU,EACtC,SAAAX,EACH,CAEJ,EC5Cae,EAAS,IAAIC,EAAOH,EAACd,IAAS,CAAE"}
|