@dropins/storefront-pdp 1.3.1 → 1.4.0-alpha001
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/fetch-graphql/fetch-graphql.d.ts +1 -1
- package/api.js +1 -1
- package/chunks/GiftCardOptions2.js +4 -0
- package/chunks/GiftCardOptions2.js.map +1 -0
- package/chunks/Zoom.js +1 -1
- package/chunks/Zoom.js.map +1 -1
- package/chunks/fetchProductData.js +47 -0
- package/chunks/fetchProductData.js.map +1 -0
- package/chunks/isProductConfigurationValid.js +1 -44
- package/chunks/isProductConfigurationValid.js.map +1 -1
- package/components/GiftCardOptions/GiftCardOptions.d.ts +13 -0
- package/components/GiftCardOptions/index.d.ts +18 -0
- package/components/Product/Product.d.ts +1 -0
- package/components/index.d.ts +1 -0
- package/containers/ProductAttributes.js +1 -1
- package/containers/ProductAttributes.js.map +1 -1
- package/containers/ProductDetails/ProductDetails.d.ts +4 -0
- package/containers/ProductDetails.js +1 -1
- package/containers/ProductDetails.js.map +1 -1
- package/containers/ProductGallery.js +1 -1
- package/containers/ProductGallery.js.map +1 -1
- package/containers/ProductGiftCardOptions/ProductGiftCardOptions.d.ts +9 -0
- package/containers/ProductGiftCardOptions/index.d.ts +18 -0
- package/containers/ProductGiftCardOptions.d.ts +3 -0
- package/containers/ProductGiftCardOptions.js +4 -0
- package/containers/ProductGiftCardOptions.js.map +1 -0
- package/containers/ProductHeader.js +1 -1
- package/containers/ProductHeader.js.map +1 -1
- package/containers/ProductOptions.js +1 -1
- package/containers/ProductOptions.js.map +1 -1
- package/containers/ProductPrice.js +1 -1
- package/containers/ProductPrice.js.map +1 -1
- package/containers/ProductQuantity.js +1 -1
- package/containers/ProductQuantity.js.map +1 -1
- package/containers/index.d.ts +1 -0
- package/data/models/product-model.d.ts +1 -0
- package/data/models/values-model.d.ts +23 -0
- package/i18n/en_US.json.d.ts +32 -0
- package/package.json +1 -1
- package/render.js +3 -2
- package/render.js.map +1 -1
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* is strictly forbidden unless prior written permission is obtained
|
|
14
14
|
* from Adobe.
|
|
15
15
|
*/
|
|
16
|
-
export declare const setEndpoint: (endpoint: string) => void, setFetchGraphQlHeader: (key: string, value: string | null) => void, removeFetchGraphQlHeader: (key: string) => void, setFetchGraphQlHeaders: (header: import('@adobe-commerce/fetch-graphql').Header | ((prev: import('@adobe-commerce/fetch-graphql').Header) => import('@adobe-commerce/fetch-graphql').Header)) => void, fetchGraphQl: <T = any>(query: string, options?: import('@adobe-commerce/fetch-graphql').FetchOptions | undefined) => Promise<{
|
|
16
|
+
export declare const setEndpoint: (endpoint: string) => void, setFetchGraphQlHeader: (key: string, value: string | null) => void, removeFetchGraphQlHeader: (key: string) => void, setFetchGraphQlHeaders: (header: import('@adobe-commerce/fetch-graphql').Header | ((prev: import('@adobe-commerce/fetch-graphql').Header) => import('@adobe-commerce/fetch-graphql').Header)) => void, getFetchGraphQlHeader: (key: string) => string | null | undefined, fetchGraphQl: <T = any>(query: string, options?: import('@adobe-commerce/fetch-graphql').FetchOptions | undefined) => Promise<{
|
|
17
17
|
errors?: import('@adobe-commerce/fetch-graphql').FetchQueryError | undefined;
|
|
18
18
|
data: T;
|
|
19
19
|
}>, getConfig: () => {
|
package/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2025 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{c as i,f as d,
|
|
3
|
+
import{c as i,f as d,j as c,d as g,g as n,e as u,h as f,i as h,r as p,s as l,a as m,b as P}from"./chunks/fetchProductData.js";import{g as F,i as G,a as Q,s as H}from"./chunks/isProductConfigurationValid.js";import{g as x}from"./chunks/getFetchedProductData.js";import"@dropins/tools/lib.js";import"@dropins/tools/event-bus.js";import"./fragments.js";import"@dropins/tools/fetch-graphql.js";export{i as config,d as fetchGraphQl,c as fetchProductData,g as getConfig,n as getFetchGraphQlHeader,x as getFetchedProductData,F as getProductConfigurationValues,u as getProductData,f as getRefinedProduct,h as initialize,G as isProductConfigurationValid,p as removeFetchGraphQlHeader,l as setEndpoint,m as setFetchGraphQlHeader,P as setFetchGraphQlHeaders,Q as setProductConfigurationValid,H as setProductConfigurationValues};
|
|
4
4
|
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/*! Copyright 2025 Adobe
|
|
2
|
+
All Rights Reserved. */
|
|
3
|
+
import{jsxs as P,jsx as h}from"@dropins/tools/preact-jsx-runtime.js";import{useState as y,useCallback as I,useMemo as M,useEffect as A}from"@dropins/tools/preact-hooks.js";import{Field as B,TextArea as V,Picker as j,Input as $}from"@dropins/tools/components.js";import{classes as z}from"@dropins/tools/lib.js";/* empty css */import{useText as u}from"@dropins/tools/i18n.js";const H=c=>{switch(c){case"number":return"number";case"email":return"email";default:return"text"}},J=c=>c.name==="giftcard/giftcard_message"?"textarea":c.name==="giftcard/giftcard_amount"?"picker":"input",K=(c,a,i)=>[{text:a,value:"0",disabled:!1},...c.map(l=>({text:l.toString(),value:l.toString(),disabled:!1})),{text:i,value:"other",disabled:!1}],x=(c,a,i)=>{const{validationRule:t}=c;if(c.name==="giftcard/giftcard_amount"){if(t.required&&(a==="0"||!a||a.trim()==="")||a==="0")return i.RequiredFieldError;if(a==="other")return""}else if(t.required&&(!a||a.trim()===""))return i.RequiredFieldError;if(!a||a.trim()==="")return"";switch(t.type){case"email":{if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(a))return i.EmailError;break}case"number":{const l=Number(a);if(isNaN(l))return i.NumberError;if(t.min!==void 0&&l<t.min)return i.MinError.replace("{min}",t.min.toString());if(t.max!==void 0&&l>t.max)return i.MaxError.replace("{max}",t.max.toString());if(t.values&&!t.values.some(g=>typeof g=="number"?g===l:g===a))return i.InvalidValueError.replace("{values}",t.values.join(", "));break}case"string":{const l=a.length;if(t.minLength!==void 0&&l<t.minLength)return i.MinLengthError.replace("{min_length}",t.minLength.toString());if(t.maxLength!==void 0&&l>t.maxLength)return i.MaxLengthError.replace("{max_length}",t.maxLength.toString());break}}return""},rr=({options:c,currency:a,optionValues:i,onOptionChange:t,onValidationChange:l})=>{const v=u("PDP.Product.GiftCardOptions.ChooseAmount.label").label,g=u("PDP.Product.GiftCardOptions.OtherAmount.label").label,C=u("PDP.Product.GiftCardOptions.RequiredFieldError.label").label,w=u("PDP.Product.GiftCardOptions.NumberError.label").label,N=u("PDP.Product.GiftCardOptions.MinError.label").label,O=u("PDP.Product.GiftCardOptions.MaxError.label").label,G=u("PDP.Product.GiftCardOptions.MinLengthError.label").label,L=u("PDP.Product.GiftCardOptions.MaxLengthError.label").label,S=u("PDP.Product.GiftCardOptions.EmailError.label").label,D=u("PDP.Product.GiftCardOptions.InvalidValueError.label").label,[q,R]=y({}),[_,F]=y(!1),n=I(r=>c.find(e=>e.name===r),[c]),p=M(()=>({RequiredFieldError:C,NumberError:w,MinError:N,MaxError:O,MinLengthError:G,MaxLengthError:L,EmailError:S,InvalidValueError:D}),[C,w,N,O,G,L,S,D]);A(()=>{const r=c.every(e=>{if(e.name==="giftcard/custom_giftcard_amount"&&!_)return!0;const d=i.find(f=>f.id===e.uid),s=(d==null?void 0:d.value)||"";return x(e,s,p)===""});l(r)},[c,i,l,p,_]),A(()=>{const r=n("giftcard/giftcard_amount"),e=n("giftcard/custom_giftcard_amount"),d=i.find(o=>o.id===(r==null?void 0:r.uid)),s=(d==null?void 0:d.value)||"",f=_,b=s==="other";F(b),f&&!b&&e&&t(e.uid,"")},[i,n,_,t]);const E=(r,e)=>{const d=x(r,e,p);R(s=>({...s,[r.uid]:d})),t(r.uid,e)},k=(r,e)=>{const d=x(r,e,p);R(s=>({...s,[r.uid]:d}))},T=(r,e)=>{const d=e.target.value;E(r,d)},m=r=>{const e=i.find(o=>o.id===r.uid),d=e==null?void 0:e.value,s=q[r.uid],f=J(r);let b=r.label;return r.name==="giftcard/custom_giftcard_amount"&&a&&(b=`${r.label} ${a}`),h(B,{label:b,className:z(["pdp-gift-card-options__option-field",f==="textarea"&&"pdp-gift-card-options__option-field--full-width"]),error:s,children:f==="textarea"?h(V,{value:d,label:r.label,onChange:o=>E(r,o.target.value),onBlur:o=>k(r,o.target.value),"aria-invalid":!!s}):f==="picker"?h(j,{"aria-label":r.label,label:r.label,handleSelect:o=>T(r,o),options:K(r.validationRule.values||[],v,g),value:d,"aria-invalid":!!s}):h($,{type:H(r.validationRule.type),value:d,onChange:o=>E(r,o.target.value),onBlur:o=>k(r,o.target.value),"aria-invalid":!!s})},r.uid)};return P("div",{className:"pdp-gift-card-options__grid",children:[P("div",{className:"pdp-gift-card-options__row",children:[n("giftcard/giftcard_amount")&&m(n("giftcard/giftcard_amount")),n("giftcard/custom_giftcard_amount")&&_&&m(n("giftcard/custom_giftcard_amount"))]}),P("div",{className:"pdp-gift-card-options__row",children:[n("giftcard/giftcard_sender_name")&&m(n("giftcard/giftcard_sender_name")),n("giftcard/giftcard_sender_email")&&m(n("giftcard/giftcard_sender_email"))]}),P("div",{className:"pdp-gift-card-options__row",children:[n("giftcard/giftcard_recipient_name")&&m(n("giftcard/giftcard_recipient_name")),n("giftcard/giftcard_recipient_email")&&m(n("giftcard/giftcard_recipient_email"))]}),h("div",{className:"pdp-gift-card-options__row",children:n("giftcard/giftcard_message")&&m(n("giftcard/giftcard_message"))})]})};export{rr as G};
|
|
4
|
+
//# sourceMappingURL=GiftCardOptions2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GiftCardOptions2.js","sources":["/@dropins/storefront-pdp/src/components/GiftCardOptions/GiftCardOptions.tsx"],"sourcesContent":["import { FunctionComponent } from 'preact';\nimport { useState, useEffect, useMemo, useCallback } from 'preact/hooks';\nimport { HTMLAttributes } from 'preact/compat';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n Field,\n Input,\n TextArea,\n Picker,\n PickerOption,\n} from '@adobe-commerce/elsie/components';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { Option, OptionField } from '@/pdp/data/models/values-model';\nimport './GiftCardOptions.css';\n\nenum ComponentType {\n INPUT = 'input',\n TEXTAREA = 'textarea',\n PICKER = 'picker',\n}\n\nexport interface GiftCardOptionsProps extends HTMLAttributes<HTMLDivElement> {\n options: Option[];\n currency?: string;\n optionValues: OptionField[];\n onOptionChange: (uid: string, value: string) => void;\n onValidationChange: (valid: boolean) => void;\n}\n\n// Utility functions\nconst getInputType = (validationType: string): string => {\n switch (validationType) {\n case 'number':\n return 'number';\n case 'email':\n return 'email';\n default:\n return 'text';\n }\n};\n\nconst getComponentType = (option: Option): ComponentType => {\n if (option.name === 'giftcard/giftcard_message') {\n return ComponentType.TEXTAREA;\n }\n\n if (option.name === 'giftcard/giftcard_amount') {\n return ComponentType.PICKER;\n }\n\n return ComponentType.INPUT;\n};\n\nconst mapToPickerOptions = (\n values: (string | number)[],\n chooseAmountText: string,\n otherAmountText: string\n): PickerOption[] => {\n const options: PickerOption[] = [\n {\n text: chooseAmountText,\n value: '0',\n disabled: false,\n },\n ...values.map((value) => ({\n text: value.toString(),\n value: value.toString(),\n disabled: false,\n })),\n {\n text: otherAmountText,\n value: 'other',\n disabled: false,\n },\n ];\n return options;\n};\n\nconst validate = (\n option: Option,\n value: string,\n errorMessages: {\n RequiredFieldError: string;\n NumberError: string;\n MinError: string;\n MaxError: string;\n MinLengthError: string;\n MaxLengthError: string;\n EmailError: string;\n InvalidValueError: string;\n }\n) => {\n const { validationRule } = option;\n\n if (option.name === 'giftcard/giftcard_amount') {\n if (\n validationRule.required &&\n (value === '0' || !value || value.trim() === '')\n ) {\n return errorMessages.RequiredFieldError;\n }\n if (value === '0') {\n return errorMessages.RequiredFieldError;\n }\n if (value === 'other') {\n return '';\n }\n } else if (validationRule.required && (!value || value.trim() === '')) {\n return errorMessages.RequiredFieldError;\n }\n\n if (!value || value.trim() === '') {\n return '';\n }\n\n switch (validationRule.type) {\n case 'email': {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n return errorMessages.EmailError;\n }\n break;\n }\n\n case 'number': {\n const num = Number(value);\n if (isNaN(num)) {\n return errorMessages.NumberError;\n }\n\n // Check min value\n if (validationRule.min !== undefined && num < validationRule.min) {\n return errorMessages.MinError.replace(\n '{min}',\n validationRule.min.toString()\n );\n }\n\n // Check max value\n if (validationRule.max !== undefined && num > validationRule.max) {\n return errorMessages.MaxError.replace(\n '{max}',\n validationRule.max.toString()\n );\n }\n\n // Check allowed values\n if (validationRule.values) {\n const isValidValue = validationRule.values.some((val) =>\n typeof val === 'number' ? val === num : val === value\n );\n if (!isValidValue) {\n return errorMessages.InvalidValueError.replace(\n '{values}',\n validationRule.values.join(', ')\n );\n }\n }\n break;\n }\n\n case 'string': {\n const length = value.length;\n\n // Check min length\n if (\n validationRule.minLength !== undefined &&\n length < validationRule.minLength\n ) {\n return errorMessages.MinLengthError.replace(\n '{min_length}',\n validationRule.minLength.toString()\n );\n }\n\n // Check max length\n if (\n validationRule.maxLength !== undefined &&\n length > validationRule.maxLength\n ) {\n return errorMessages.MaxLengthError.replace(\n '{max_length}',\n validationRule.maxLength.toString()\n );\n }\n break;\n }\n }\n\n return '';\n};\n\nexport const GiftCardOptions: FunctionComponent<GiftCardOptionsProps> = ({\n options,\n currency,\n optionValues,\n onOptionChange,\n onValidationChange,\n}) => {\n const ChooseAmount = useText(\n 'PDP.Product.GiftCardOptions.ChooseAmount.label'\n ).label;\n const OtherAmount = useText(\n 'PDP.Product.GiftCardOptions.OtherAmount.label'\n ).label;\n const RequiredFieldError = useText(\n 'PDP.Product.GiftCardOptions.RequiredFieldError.label'\n ).label;\n const NumberError = useText(\n 'PDP.Product.GiftCardOptions.NumberError.label'\n ).label;\n const MinError = useText('PDP.Product.GiftCardOptions.MinError.label').label;\n const MaxError = useText('PDP.Product.GiftCardOptions.MaxError.label').label;\n const MinLengthError = useText(\n 'PDP.Product.GiftCardOptions.MinLengthError.label'\n ).label;\n const MaxLengthError = useText(\n 'PDP.Product.GiftCardOptions.MaxLengthError.label'\n ).label;\n const EmailError = useText(\n 'PDP.Product.GiftCardOptions.EmailError.label'\n ).label;\n const InvalidValueError = useText(\n 'PDP.Product.GiftCardOptions.InvalidValueError.label'\n ).label;\n\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [showCustomAmount, setShowCustomAmount] = useState(false);\n\n // Helper function to find option by name\n const findOptionByName = useCallback(\n (name: string): Option | undefined => {\n return options.find((option) => option.name === name);\n },\n [options]\n );\n\n // Memoize error messages to avoid recreating them on every render\n const errorMessages = useMemo(\n () => ({\n RequiredFieldError,\n NumberError,\n MinError,\n MaxError,\n MinLengthError,\n MaxLengthError,\n EmailError,\n InvalidValueError,\n }),\n [\n RequiredFieldError,\n NumberError,\n MinError,\n MaxError,\n MinLengthError,\n MaxLengthError,\n EmailError,\n InvalidValueError,\n ]\n );\n\n // Run initial validation only when options or optionValues change\n useEffect(() => {\n const valid = options.every((option) => {\n // Skip validation for custom gift card amount when it's not shown\n if (\n option.name === 'giftcard/custom_giftcard_amount' &&\n !showCustomAmount\n ) {\n return true;\n }\n\n const field = optionValues.find((f) => f.id === option.uid);\n const value = field?.value || '';\n return validate(option, value, errorMessages) === '';\n });\n\n onValidationChange(valid);\n }, [\n options,\n optionValues,\n onValidationChange,\n errorMessages,\n showCustomAmount,\n ]);\n\n useEffect(() => {\n const giftCardAmountOption = findOptionByName('giftcard/giftcard_amount');\n const customAmountOption = findOptionByName(\n 'giftcard/custom_giftcard_amount'\n );\n\n const giftCardAmountField = optionValues.find(\n (f) => f.id === giftCardAmountOption?.uid\n );\n\n const selectedValue = giftCardAmountField?.value || '';\n const wasShowingCustomAmount = showCustomAmount;\n const willShowCustomAmount = selectedValue === 'other';\n\n setShowCustomAmount(willShowCustomAmount);\n\n // Reset custom amount value when switching away from \"other\"\n if (wasShowingCustomAmount && !willShowCustomAmount && customAmountOption) {\n onOptionChange(customAmountOption.uid, '');\n }\n }, [optionValues, findOptionByName, showCustomAmount, onOptionChange]);\n\n const handleChange = (option: Option, value: string) => {\n const error = validate(option, value, errorMessages);\n setErrors((prev: Record<string, string>) => ({\n ...prev,\n [option.uid]: error,\n }));\n\n onOptionChange(option.uid, value);\n };\n\n const handleBlur = (option: Option, value: string) => {\n const error = validate(option, value, errorMessages);\n setErrors((prev: Record<string, string>) => ({\n ...prev,\n [option.uid]: error,\n }));\n };\n\n const handlePickerSelect = (option: Option, event: any) => {\n const selectedValue = event.target.value;\n handleChange(option, selectedValue);\n };\n\n const renderField = (option: Option) => {\n const field = optionValues.find((f) => f.id === option.uid);\n const value = field?.value;\n const error = errors[option.uid];\n const componentType = getComponentType(option);\n\n // Add currency to custom gift card amount label\n let label = option.label;\n if (option.name === 'giftcard/custom_giftcard_amount' && currency) {\n label = `${option.label} ${currency}`;\n }\n\n return (\n <Field\n key={option.uid}\n label={label}\n className={classes([\n 'pdp-gift-card-options__option-field',\n componentType === ComponentType.TEXTAREA &&\n 'pdp-gift-card-options__option-field--full-width',\n ])}\n error={error}\n >\n {(() => {\n if (componentType === ComponentType.TEXTAREA) {\n return (\n <TextArea\n value={value}\n label={option.label}\n onChange={(e: any) =>\n handleChange(option, (e.target as HTMLTextAreaElement).value)\n }\n onBlur={(e: any) =>\n handleBlur(option, (e.target as HTMLTextAreaElement).value)\n }\n aria-invalid={!!error}\n />\n );\n }\n\n if (componentType === ComponentType.PICKER) {\n return (\n <Picker\n aria-label={option.label}\n label={option.label}\n handleSelect={(event) => handlePickerSelect(option, event)}\n options={mapToPickerOptions(\n option.validationRule.values || [],\n ChooseAmount,\n OtherAmount\n )}\n value={value}\n aria-invalid={!!error}\n />\n );\n }\n\n return (\n <Input\n type={getInputType(option.validationRule.type)}\n value={value}\n onChange={(e) =>\n handleChange(option, (e.target as HTMLInputElement).value)\n }\n onBlur={(e) =>\n handleBlur(option, (e.target as HTMLInputElement).value)\n }\n aria-invalid={!!error}\n />\n );\n })()}\n </Field>\n );\n };\n\n return (\n <div className=\"pdp-gift-card-options__grid\">\n {/* Row 1: Gift card amount and custom amount */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_amount') &&\n renderField(findOptionByName('giftcard/giftcard_amount')!)}\n {findOptionByName('giftcard/custom_giftcard_amount') &&\n showCustomAmount &&\n renderField(findOptionByName('giftcard/custom_giftcard_amount')!)}\n </div>\n\n {/* Row 2: Sender name and email */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_sender_name') &&\n renderField(findOptionByName('giftcard/giftcard_sender_name')!)}\n {findOptionByName('giftcard/giftcard_sender_email') &&\n renderField(findOptionByName('giftcard/giftcard_sender_email')!)}\n </div>\n\n {/* Row 3: Recipient name and email */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_recipient_name') &&\n renderField(findOptionByName('giftcard/giftcard_recipient_name')!)}\n {findOptionByName('giftcard/giftcard_recipient_email') &&\n renderField(findOptionByName('giftcard/giftcard_recipient_email')!)}\n </div>\n\n {/* Row 4: Gift card message */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_message') &&\n renderField(findOptionByName('giftcard/giftcard_message')!)}\n </div>\n </div>\n );\n};\n"],"names":["getInputType","validationType","getComponentType","option","mapToPickerOptions","values","chooseAmountText","otherAmountText","value","validate","errorMessages","validationRule","num","val","length","GiftCardOptions","options","currency","optionValues","onOptionChange","onValidationChange","ChooseAmount","useText","OtherAmount","RequiredFieldError","NumberError","MinError","MaxError","MinLengthError","MaxLengthError","EmailError","InvalidValueError","errors","setErrors","useState","showCustomAmount","setShowCustomAmount","findOptionByName","useCallback","name","useMemo","useEffect","valid","field","giftCardAmountOption","customAmountOption","giftCardAmountField","f","selectedValue","wasShowingCustomAmount","willShowCustomAmount","handleChange","error","prev","handleBlur","handlePickerSelect","event","renderField","componentType","label","jsx","Field","classes","TextArea","e","Picker","Input","jsxs"],"mappings":"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"}
|
package/chunks/Zoom.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*! Copyright 2025 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
import{jsxs as U,jsx as M,Fragment as be}from"@dropins/tools/preact-jsx-runtime.js";import*as le from"@dropins/tools/preact-compat.js";import{useState as $,Children as I,useRef as A,useMemo as ve,useEffect as R,useCallback as re,useLayoutEffect as De}from"@dropins/tools/preact-compat.js";import{debounce as ye,classes as P}from"@dropins/tools/lib.js";import{Button as pe,Icon as We}from"@dropins/tools/components.js";/* empty css */import{useText as q}from"@dropins/tools/i18n.js";import{cloneElement as ke}from"@dropins/tools/preact.js";const Ae=i=>le.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...i},le.createElement("path",{d:"M7.74512 9.87701L12.0001 14.132L16.2551 9.87701",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"square",strokeLinejoin:"round"})),Ce=i=>le.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...i},le.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M18.3599 5.64001L5.62988 18.37",stroke:"currentColor"}),le.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M18.3599 18.37L5.62988 5.64001",stroke:"currentColor"})),Re=24,we=16,Se="32";var Me=(i=>(i[i.small=16]="small",i[i.medium=24]="medium",i[i.large=64]="large",i))(Me||{});const Fe=({show:i=1,scrollbar:p=!1,peak:y=!1,arrows:l=!1,controls:o="dots",arrowsOnMainImage:S=!1,loop:c=!1,gap:w=null,direction:L="horizontal",width:D="100%",height:ne="100%",defaultIndex:X=0,className:ie,children:W,thumbnails:J=null,isZoomed:Y,...O})=>{const Z=q("PDP.Carousel.label").label,ce=q("PDP.Carousel.Slide.label").label,x=q("PDP.Carousel.Previous.label").label,oe=q("PDP.Carousel.Next.label").label,j=q("PDP.Carousel.Controls.label").label,H=q("PDP.Carousel.Controls.Button.label").label,[d,ue]=$(()=>Le(i)),v=Math.ceil(I.count(W)/d),C=y?Re:0,Q=w?Me[w]:0,K=I.count(W)%d,[f,fe]=$(c?k()?X-1:X+1:X),G=A([]),[E,he]=$(0),[ee,de]=$(0),se=ve(()=>I.toArray(J),[J]),t=ve(()=>{const e=I.toArray(W).reduce((r,s,n)=>n%d===0?[...r,[s]]:[...r.slice(0,-1),[...r[r.length-1],s]],[]);return!c||e.length===1?e:c&&I.count(W)%d===0?[e[v-1]].concat(e).concat([e[0],e[1]]):[I.toArray(W).slice(-d)].concat(e).concat([e[0],e[1]])},[W,d,v,c]),g=A(null),h=A(null),a=o==="thumbnailsRow"||o==="thumbnailsColumn";R(()=>{const e=g.current;if(!e)return;const r=ye(()=>{he(e.offsetWidth??0),de(e.offsetHeight??0);const n=window.innerWidth,u=Le(i,n);u!==d&&ue(u)},50),s=new ResizeObserver(r);return s.observe(e),()=>{s.unobserve(e)}},[d,i]);const b=re(e=>{const r=c?e-1:e,s=G==null?void 0:G.current[0],n=(s==null?void 0:s.offsetWidth)+we,u=(s==null?void 0:s.offsetHeight)+we,_=h.current,te=o==="thumbnailsRow",ae=o==="thumbnailsColumn",F=te?_==null?void 0:_.offsetWidth:_==null?void 0:_.offsetHeight,N=te?n:u;if((te||ae)&&F){const Ee=Math.floor((te?_.clientWidth:_.clientHeight)/N),Ne=Math.floor(Ee/2),me=(r-Ne)*N;_.style.scrollBehavior="smooth",te?_.scrollLeft=k()?-(_.scrollWidth-_.clientWidth-me):me:_.scrollTop=me}},[o,c]);R(()=>{b(f)},[f,b]);const m=re((e,r,s)=>{a&&b(e);const n=g.current,u=C?n.offsetWidth-C:n.offsetWidth-C+Q;if(!Array.from(n.querySelectorAll("[data-index]")).filter(F=>{const N=Number(F.getAttribute("data-index"));return!isNaN(N)&&N>-1})[e])return;if(s){const F=e===0?v:0,N=u*(v+(K||d)/d);if(k()){if(n.scrollLeft<=0&&n.scrollLeft>-(u-5)){m(1,!0);return}if(n.scrollLeft<u-N&&n.scrollLeft>=-N){m(v,!0);return}n.style.scrollBehavior="auto",n.scrollLeft=F===0?0:-N,m(F===0?1:v,!0)}else{if(n.scrollLeft>=0&&n.scrollLeft<u-5){m(1,!0);return}if(n.scrollLeft>N-u&&n.scrollLeft<=N){m(v,!0);return}n.style.scrollBehavior="auto",n.scrollLeft=F===0?0:N,m(F===0?1:v,!0);return}}const ae=(n.offsetWidth-Q)/d*t[e].length-C;n.style.scrollBehavior=r?"smooth":"auto",n.scrollLeft=k()?-(t[e].length===d?u*e:u*(e-1)-ae):t[e].length===d?u*e:u*(e-1)+ae},[Q,v,C,d,K,t,b,o]),B=re(()=>{if(c){const r=f-1;m(r,!0,k()?f===v-1:f===1);return}const e=f<=0?0:f-1;m(e,!0)},[f,m,c]),z=re(()=>{const e=t.length-1;if(c){const s=f+1;m(s,!0,k()?f===0:f===v);return}const r=f>=e?e:f+1;m(r,!0)},[t.length,c,f,m,v]);R(()=>{const e=r=>{r.key==="ArrowLeft"&&(r.preventDefault(),k()?z():B()),r.key==="ArrowRight"&&(r.preventDefault(),k()?B():z())};return window.addEventListener("keydown",e),()=>{window.removeEventListener("keydown",e)}},[z,B]),De(()=>{m(c?X+1:X,!1)},[X,m,c,E]);const V=ye(()=>{const e=g.current,r=C?e.offsetWidth-C:e.offsetWidth-C+Q,s=Math.abs(e.scrollLeft)/r,n=Math.abs(Math.round(s)-s<1?Math.round(s):Math.ceil(s));if(a&&b(n),c){const u=r*(v+(K||d)/d),_=k()?-e.scrollLeft:e.scrollLeft;if(Math.ceil(Math.abs(_))>=Math.ceil(u)-5){e.style.scrollBehavior="auto",e.scrollLeft=k()?-e.offsetWidth+(Math.ceil(_)-Math.ceil(u)-C):e.offsetWidth+(Math.ceil(_)-Math.ceil(u)-C);return}if(Math.abs(_)===0){e.style.scrollBehavior="auto",e.scrollLeft=k()?-(u-e.offsetWidth+C):u-e.offsetWidth+C;return}}f!==n&&fe(n)},100);R(()=>{const e=g.current;return e==null||e.addEventListener("scroll",V),()=>{e==null||e.removeEventListener("scroll",V)}},[V]);const T=(e,r,s)=>M(pe,{className:P([["pdp-carousel__button",!e],[`pdp-carousel__button--${r}`,!e],[`pdp-carousel__button--${o}`,e]]),style:{"--height":`${ee}px`},variant:"tertiary","aria-label":r==="next"?oe:x,onClick:s,disabled:c?!1:r==="next"?f>=t.length-1:f<1,children:M(We,{className:P([["pdp-carousel__button__icon",!e],[`pdp-carousel__button__icon--${r}`,!e],[`pdp-carousel__button__icon--${o}--${r}`,e]]),size:Se,source:Ae})}),ge=l&&t.length!=1&&T(a,"prev",B),_e=l&&t.length!=1&&T(a,"next",z),Pe=l&&t.length!=1&&T(!1,"prev",B),xe=l&&t.length!=1&&T(!1,"next",z);return U("div",{role:"region","aria-roledescription":Z,className:P(["pdp-carousel",["pdp-carousel--main-image-controls",S],["pdp-carousel--arrows",l&&!a],[`pdp-carousel--${o}`,a],ie]),style:{"--flex-carousel":o==="thumbnailsColumn"?"row-reverse":"column","--gap":a?"0":"var(--spacing-small)","--width":D},...O,children:[M("div",{ref:g,className:P(["pdp-carousel__wrapper",`pdp-carousel__wrapper--${L}`,["pdp-carousel__wrapper--scrollbar",p],["pdp-carousel__wrapper--peak",y]]),style:{"--total-width":o==="thumbnailsColumn"?"81.6%":"100%","--height":o==="thumbnailsColumn"?"auto":ne,"--gap":w?`var(--spacing-${w})`:"0px","--per-page":d},tabIndex:0,children:t.map((e,r)=>{const s=e.length<d;return M("div",{role:"group","aria-roledescription":ce,"data-index":r,className:P(["pdp-carousel__slide",`pdp-carousel__slide--${L}`,["pdp-carousel__slide--active",f===r],["pdp-carousel__slide--orphan",s],["pdp-carousel__slide--hidden",E===0]]),style:{"--length":e.length},children:e},r)})}),!a&&U(be,{children:[ge,_e]}),a&&S&&U(be,{children:[Pe,xe]}),o&&t.length!=1&&U("div",{className:P([[`pdp-carousel__controls__container--${o}`,a],["pdp-carousel__controls__container--no-arrows",!l||S]]),style:{"--width":o==="thumbnailsRow"?`${E}px`:D,"--height":`${ee}px`,"--nr-thumbnails":se.length},children:[(a||Y)&&!S&&ge,M("div",{ref:h,className:P([[`pdp-carousel__controls__wrapper--${o}`,a],["pdp-carousel__controls__wrapper",a]]),children:M("div",{role:"group","aria-label":j,className:P(["pdp-carousel__controls",[`pdp-carousel__controls--${o}`,a]]),children:(c?t.slice(0,v):t).map((e,r)=>{const s=c?v:t.length,n=c?f-1===r:f===r;return a?U("label",{className:P(["pdp-carousel__thumbnail__container"]),ref:u=>{u&&(G.current[r]=u)},children:[M("input",{type:"radio",name:"carousel-thumbnails","aria-label":H.replace("{key}",String(r+1)).replace("{total}",String(s)),checked:n&&E!==0,onChange:()=>{m(c?r+1:r,!0)},...O,className:P(["pdp-carousel__thumbnail",["pdp-carousel__thumbnail--selected",n&&E!==0]])}),M("span",{className:P(["pdp-carousel__thumbnail__span"]),children:se[r]})]},r):M("button",{"aria-label":H.replace("{key}",String(r+1)).replace("{total}",String(s)),onClick:()=>{m(c?r+1:r,!0)},className:P(["pdp-carousel__controls__button",["pdp-carousel__controls__button--active",n]])},r)})})}),(a||Y)&&!S&&_e]})]})};function Le(i,p=0){if(typeof i=="number")return i;const{small:y,medium:l,large:o}=i,c=[{breakpoint:1024,value:o},{breakpoint:786,value:l},{breakpoint:0,value:y}].find(({breakpoint:w})=>p>w);return c?c.value:y}function k(){return document.documentElement.dir==="rtl"}const qe=({centered:i,onClose:p,className:y,children:l,...o})=>{const S=q("PDP.Overlay.Close.label").label,c=A(null),w=re(()=>{p==null||p()},[p]);return R(()=>{const L=D=>{D.key==="Escape"&&w()};return document.addEventListener("keydown",L),()=>{document.removeEventListener("keydown",L)}},[w]),R(()=>{const L=c.current;L==null||L.focus();const D=document.scrollingElement,ne=D.style.overflow;return D.style.overflow="hidden",()=>{D.style.overflow=ne}},[]),U("div",{...o,className:P(["pdp-overlay",["pdp-overlay--centered",i],y]),ref:c,role:"dialog","aria-describedby":"overlay-content",tabindex:0,children:[M("div",{className:"pdp-overlay__content",id:"overlay-content",children:l}),M(pe,{"aria-label":S,variant:"tertiary",className:"pdp-overlay__close-button",onClick:w,icon:M(Ce,{})})]})},Oe=({children:i,scale:p=2,closeButton:y=!0})=>{var se;const[l,o]=$(!1),[S,c]=$("pdp-zoom"),[w,L]=$(!1),[D,ne]=$({x:0,y:0}),[X,ie]=$({x:0,y:0}),[W,J]=$({x:0,y:0}),Y=A(null),O=A(null),Z=A(null),ce=A("none"),x=A(null),oe=A(!1),j=A(null),H=re(t=>{const g=()=>{var T;let h;O.current&&Y.current?h=O.current:Y.current?(h=Y.current.getBoundingClientRect(),O.current=h):h=(T=t.currentTarget)==null?void 0:T.getBoundingClientRect();const a=(100-100/p)/2;let b=null;if("touches"in t)if(t.touches.length>0)b=t.touches[0],j.current={clientX:b.clientX,clientY:b.clientY};else if(t.type==="touchend"&&x.current)b={clientX:x.current.x,clientY:x.current.y};else if(j.current)b=j.current;else return;else if(t instanceof MouseEvent)b=t;else return;const m=(b.clientX-h.left)/h.width*100,B=(b.clientY-h.top)/h.height*100,z=(50-m)*(p-1)/p,V=(50-B)*(p-1)/p;J({x:Math.max(-a,Math.min(z,a))||0,y:Math.max(-a,Math.min(V,a))||0})};Z.current&&cancelAnimationFrame(Z.current),Z.current=requestAnimationFrame(g)},[p]);R(()=>{O.current=null},[l]);const d=t=>{!l||t.type!=="touchstart"||(ne({x:t.touches[0].clientX,y:t.touches[0].clientY}),ie({x:W.x,y:W.y}),L(!0))},ue=t=>{var T;if(!w||t.type!=="touchmove")return;const g=(T=t.currentTarget)==null?void 0:T.getBoundingClientRect(),h=(100-100/p)/2,a=t.touches[0].clientX-D.x,b=t.touches[0].clientY-D.y,m=a*100/(g.width*p),B=b*100/(g.height*p),z=X.x+m,V=X.y+B;J({x:Math.max(-h,Math.min(z,h))||0,y:Math.max(-h,Math.min(V,h))||0}),t.preventDefault()},v=t=>{if(y)x.current={x:t.touches[0].clientX,y:t.touches[0].clientY,time:Date.now()},j.current={clientX:t.touches[0].clientX,clientY:t.touches[0].clientY},oe.current=!1,l&&d(t);else{if(w)return;!l&&H(t),o(!l),t.preventDefault()}},C=t=>{if(t.touches.length!==0){if(j.current={clientX:t.touches[0].clientX,clientY:t.touches[0].clientY},y){if(!x.current)return;if(w){ue(t);return}const g=t.touches[0].clientX,h=t.touches[0].clientY,a=Math.abs(g-x.current.x),b=Math.abs(h-x.current.y);(a>10||b>10)&&(oe.current=!0)}l&&H(t)}},Q=t=>{if(y){if(!x.current)return;const g=Date.now()-x.current.time;!oe.current&&g<300&&!w&&(o(!0),H(t),t.preventDefault()),L(!1),x.current=null}else o(!1)},K=t=>{"touches"in t||w||(l?!y&&o(!1):(o(!0),H(t)),t.preventDefault())},f=t=>{"touches"in t||l&&H(t)},fe=t=>{if(!("touches"in t)){if(y){L(!1);return}o(!1)}},G=t=>{o(!1),t.stopPropagation()},E=l?`scale(${p}) translateX(${W.x}%) translateY(${W.y}%)`:"none",he=q("PDP.Zoom.Close.label").label,ee=I.only(i);R(()=>{const t=()=>{l&&(o(!1),J({x:0,y:0}),L(!1))},g=document.querySelector("#gallery");if(g)return g.addEventListener("click",t),()=>g.removeEventListener("click",t)},[l]);const de=ke(ee,{...ee.props,draggable:!1,style:{...(se=ee.props)==null?void 0:se.style,"--transform":E}});return R(()=>{c(l?`pdp-zoom ${y?"pdp-zoom--no-effects":"pdp-zoom--zoomed"}`:"pdp-zoom")},[l,y]),R(()=>{if(ce.current===E)return;ce.current=E,requestAnimationFrame(()=>{if(!Y.current)return;Y.current.querySelectorAll("img").forEach(h=>{l&&E!=="none"?h.style.setProperty("transform",E,"important"):h.style.removeProperty("transform")})})},[E,l]),R(()=>()=>{Z.current&&cancelAnimationFrame(Z.current)},[]),U("figure",{ref:Y,className:S,onClick:K,onMouseMove:f,onMouseLeave:fe,onTouchStart:v,onTouchMove:C,onTouchEnd:Q,children:[de,y&&l&&M(pe,{"aria-label":he,variant:"tertiary",className:"pdp-zoom__close-button",icon:M(Ce,{}),onClick:G})]})};export{Fe as C,qe as O,Oe as Z};
|
|
3
|
+
import{jsxs as U,jsx as M,Fragment as be}from"@dropins/tools/preact-jsx-runtime.js";import*as le from"@dropins/tools/preact-compat.js";import{useState as $,Children as I,useRef as A,useMemo as ve,useEffect as R,useCallback as re,useLayoutEffect as We}from"@dropins/tools/preact-compat.js";import{debounce as ye,classes as P}from"@dropins/tools/lib.js";import{Button as pe,Icon as ke}from"@dropins/tools/components.js";/* empty css */import{useText as q}from"@dropins/tools/i18n.js";import{cloneElement as De}from"@dropins/tools/preact.js";const Ae=i=>le.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...i},le.createElement("path",{d:"M7.74512 9.87701L12.0001 14.132L16.2551 9.87701",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"square",strokeLinejoin:"round"})),Ce=i=>le.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...i},le.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M18.3599 5.64001L5.62988 18.37",stroke:"currentColor"}),le.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M18.3599 18.37L5.62988 5.64001",stroke:"currentColor"})),Re=24,we=16,Se="32";var Me=(i=>(i[i.small=16]="small",i[i.medium=24]="medium",i[i.large=64]="large",i))(Me||{});const Fe=({show:i=1,scrollbar:p=!1,peak:y=!1,arrows:l=!1,controls:o="dots",arrowsOnMainImage:S=!1,loop:c=!1,gap:w=null,direction:L="horizontal",width:W="100%",height:ne="100%",defaultIndex:X=0,className:ie,children:k,thumbnails:J=null,isZoomed:Y,...O})=>{const Z=q("PDP.Carousel.label").label,ce=q("PDP.Carousel.Slide.label").label,x=q("PDP.Carousel.Previous.label").label,oe=q("PDP.Carousel.Next.label").label,j=q("PDP.Carousel.Controls.label").label,H=q("PDP.Carousel.Controls.Button.label").label,[d,ue]=$(()=>Le(i)),v=Math.ceil(I.count(k)/d),C=y?Re:0,Q=w?Me[w]:0,K=I.count(k)%d,[f,fe]=$(c?D()?X-1:X+1:X),G=A([]),[E,he]=$(0),[ee,de]=$(0),se=ve(()=>I.toArray(J),[J]),t=ve(()=>{const e=I.toArray(k).reduce((r,s,n)=>n%d===0?[...r,[s]]:[...r.slice(0,-1),[...r[r.length-1],s]],[]);return!c||e.length===1?e:c&&I.count(k)%d===0?[e[v-1]].concat(e).concat([e[0],e[1]]):[I.toArray(k).slice(-d)].concat(e).concat([e[0],e[1]])},[k,d,v,c]),g=A(null),h=A(null),a=o==="thumbnailsRow"||o==="thumbnailsColumn";R(()=>{const e=g.current;if(!e)return;const r=ye(()=>{he(e.offsetWidth??0),de(e.offsetHeight??0);const n=window.innerWidth,u=Le(i,n);u!==d&&ue(u)},50),s=new ResizeObserver(r);return s.observe(e),()=>{s.unobserve(e)}},[d,i]);const b=re(e=>{const r=c?e-1:e,s=G==null?void 0:G.current[0],n=(s==null?void 0:s.offsetWidth)+we,u=(s==null?void 0:s.offsetHeight)+we,_=h.current,te=o==="thumbnailsRow",ae=o==="thumbnailsColumn",F=te?_==null?void 0:_.offsetWidth:_==null?void 0:_.offsetHeight,N=te?n:u;if((te||ae)&&F){const Ee=Math.floor((te?_.clientWidth:_.clientHeight)/N),Ne=Math.floor(Ee/2),me=(r-Ne)*N;_.style.scrollBehavior="smooth",te?_.scrollLeft=D()?-(_.scrollWidth-_.clientWidth-me):me:_.scrollTop=me}},[o,c]);R(()=>{b(f)},[f,b]);const m=re((e,r,s)=>{a&&b(e);const n=g.current,u=C?n.offsetWidth-C:n.offsetWidth-C+Q;if(!Array.from(n.querySelectorAll("[data-index]")).filter(F=>{const N=Number(F.getAttribute("data-index"));return!isNaN(N)&&N>-1})[e])return;if(s){const F=e===0?v:0,N=u*(v+(K||d)/d);if(D()){if(n.scrollLeft<=0&&n.scrollLeft>-(u-5)){m(1,!0);return}if(n.scrollLeft<u-N&&n.scrollLeft>=-N){m(v,!0);return}n.style.scrollBehavior="auto",n.scrollLeft=F===0?0:-N,m(F===0?1:v,!0)}else{if(n.scrollLeft>=0&&n.scrollLeft<u-5){m(1,!0);return}if(n.scrollLeft>N-u&&n.scrollLeft<=N){m(v,!0);return}n.style.scrollBehavior="auto",n.scrollLeft=F===0?0:N,m(F===0?1:v,!0);return}}const ae=(n.offsetWidth-Q)/d*t[e].length-C;n.style.scrollBehavior=r?"smooth":"auto",n.scrollLeft=D()?-(t[e].length===d?u*e:u*(e-1)-ae):t[e].length===d?u*e:u*(e-1)+ae},[Q,v,C,d,K,t,b,o]),B=re(()=>{if(c){const r=f-1;m(r,!0,D()?f===v-1:f===1);return}const e=f<=0?0:f-1;m(e,!0)},[f,m,c]),z=re(()=>{const e=t.length-1;if(c){const s=f+1;m(s,!0,D()?f===0:f===v);return}const r=f>=e?e:f+1;m(r,!0)},[t.length,c,f,m,v]);R(()=>{const e=r=>{r.key==="ArrowLeft"&&(D()?z():B()),r.key==="ArrowRight"&&(D()?B():z())};return window.addEventListener("keydown",e),()=>{window.removeEventListener("keydown",e)}},[z,B]),We(()=>{m(c?X+1:X,!1)},[X,m,c,E]);const V=ye(()=>{const e=g.current,r=C?e.offsetWidth-C:e.offsetWidth-C+Q,s=Math.abs(e.scrollLeft)/r,n=Math.abs(Math.round(s)-s<1?Math.round(s):Math.ceil(s));if(a&&b(n),c){const u=r*(v+(K||d)/d),_=D()?-e.scrollLeft:e.scrollLeft;if(Math.ceil(Math.abs(_))>=Math.ceil(u)-5){e.style.scrollBehavior="auto",e.scrollLeft=D()?-e.offsetWidth+(Math.ceil(_)-Math.ceil(u)-C):e.offsetWidth+(Math.ceil(_)-Math.ceil(u)-C);return}if(Math.abs(_)===0){e.style.scrollBehavior="auto",e.scrollLeft=D()?-(u-e.offsetWidth+C):u-e.offsetWidth+C;return}}f!==n&&fe(n)},100);R(()=>{const e=g.current;return e==null||e.addEventListener("scroll",V),()=>{e==null||e.removeEventListener("scroll",V)}},[V]);const T=(e,r,s)=>M(pe,{className:P([["pdp-carousel__button",!e],[`pdp-carousel__button--${r}`,!e],[`pdp-carousel__button--${o}`,e]]),style:{"--height":`${ee}px`},variant:"tertiary","aria-label":r==="next"?oe:x,onClick:s,disabled:c?!1:r==="next"?f>=t.length-1:f<1,children:M(ke,{className:P([["pdp-carousel__button__icon",!e],[`pdp-carousel__button__icon--${r}`,!e],[`pdp-carousel__button__icon--${o}--${r}`,e]]),size:Se,source:Ae})}),ge=l&&t.length!=1&&T(a,"prev",B),_e=l&&t.length!=1&&T(a,"next",z),Pe=l&&t.length!=1&&T(!1,"prev",B),xe=l&&t.length!=1&&T(!1,"next",z);return U("div",{role:"region","aria-roledescription":Z,className:P(["pdp-carousel",["pdp-carousel--main-image-controls",S],["pdp-carousel--arrows",l&&!a],[`pdp-carousel--${o}`,a],ie]),style:{"--flex-carousel":o==="thumbnailsColumn"?"row-reverse":"column","--gap":a?"0":"var(--spacing-small)","--width":W},...O,children:[M("div",{ref:g,className:P(["pdp-carousel__wrapper",`pdp-carousel__wrapper--${L}`,["pdp-carousel__wrapper--scrollbar",p],["pdp-carousel__wrapper--peak",y]]),style:{"--total-width":o==="thumbnailsColumn"?"81.6%":"100%","--height":o==="thumbnailsColumn"?"auto":ne,"--gap":w?`var(--spacing-${w})`:"0px","--per-page":d},tabIndex:0,children:t.map((e,r)=>{const s=e.length<d;return M("div",{role:"group","aria-roledescription":ce,"data-index":r,className:P(["pdp-carousel__slide",`pdp-carousel__slide--${L}`,["pdp-carousel__slide--active",f===r],["pdp-carousel__slide--orphan",s],["pdp-carousel__slide--hidden",E===0]]),style:{"--length":e.length},children:e},r)})}),!a&&U(be,{children:[ge,_e]}),a&&S&&U(be,{children:[Pe,xe]}),o&&t.length!=1&&U("div",{className:P([[`pdp-carousel__controls__container--${o}`,a],["pdp-carousel__controls__container--no-arrows",!l||S]]),style:{"--width":o==="thumbnailsRow"?`${E}px`:W,"--height":`${ee}px`,"--nr-thumbnails":se.length},children:[(a||Y)&&!S&&ge,M("div",{ref:h,className:P([[`pdp-carousel__controls__wrapper--${o}`,a],["pdp-carousel__controls__wrapper",a]]),children:M("div",{role:"group","aria-label":j,className:P(["pdp-carousel__controls",[`pdp-carousel__controls--${o}`,a]]),children:(c?t.slice(0,v):t).map((e,r)=>{const s=c?v:t.length,n=c?f-1===r:f===r;return a?U("label",{className:P(["pdp-carousel__thumbnail__container"]),ref:u=>{u&&(G.current[r]=u)},children:[M("input",{type:"radio",name:"carousel-thumbnails","aria-label":H.replace("{key}",String(r+1)).replace("{total}",String(s)),checked:n&&E!==0,onChange:()=>{m(c?r+1:r,!0)},...O,className:P(["pdp-carousel__thumbnail",["pdp-carousel__thumbnail--selected",n&&E!==0]])}),M("span",{className:P(["pdp-carousel__thumbnail__span"]),children:se[r]})]},r):M("button",{"aria-label":H.replace("{key}",String(r+1)).replace("{total}",String(s)),onClick:()=>{m(c?r+1:r,!0)},className:P(["pdp-carousel__controls__button",["pdp-carousel__controls__button--active",n]])},r)})})}),(a||Y)&&!S&&_e]})]})};function Le(i,p=0){if(typeof i=="number")return i;const{small:y,medium:l,large:o}=i,c=[{breakpoint:1024,value:o},{breakpoint:786,value:l},{breakpoint:0,value:y}].find(({breakpoint:w})=>p>w);return c?c.value:y}function D(){return document.documentElement.dir==="rtl"}const qe=({centered:i,onClose:p,className:y,children:l,...o})=>{const S=q("PDP.Overlay.Close.label").label,c=A(null),w=re(()=>{p==null||p()},[p]);return R(()=>{const L=W=>{W.key==="Escape"&&w()};return document.addEventListener("keydown",L),()=>{document.removeEventListener("keydown",L)}},[w]),R(()=>{const L=c.current;L==null||L.focus();const W=document.scrollingElement,ne=W.style.overflow;return W.style.overflow="hidden",()=>{W.style.overflow=ne}},[]),U("div",{...o,className:P(["pdp-overlay",["pdp-overlay--centered",i],y]),ref:c,role:"dialog","aria-describedby":"overlay-content",tabindex:0,children:[M("div",{className:"pdp-overlay__content",id:"overlay-content",children:l}),M(pe,{"aria-label":S,variant:"tertiary",className:"pdp-overlay__close-button",onClick:w,icon:M(Ce,{})})]})},Oe=({children:i,scale:p=2,closeButton:y=!0})=>{var se;const[l,o]=$(!1),[S,c]=$("pdp-zoom"),[w,L]=$(!1),[W,ne]=$({x:0,y:0}),[X,ie]=$({x:0,y:0}),[k,J]=$({x:0,y:0}),Y=A(null),O=A(null),Z=A(null),ce=A("none"),x=A(null),oe=A(!1),j=A(null),H=re(t=>{const g=()=>{var T;let h;O.current&&Y.current?h=O.current:Y.current?(h=Y.current.getBoundingClientRect(),O.current=h):h=(T=t.currentTarget)==null?void 0:T.getBoundingClientRect();const a=(100-100/p)/2;let b=null;if("touches"in t)if(t.touches.length>0)b=t.touches[0],j.current={clientX:b.clientX,clientY:b.clientY};else if(t.type==="touchend"&&x.current)b={clientX:x.current.x,clientY:x.current.y};else if(j.current)b=j.current;else return;else if(t instanceof MouseEvent)b=t;else return;const m=(b.clientX-h.left)/h.width*100,B=(b.clientY-h.top)/h.height*100,z=(50-m)*(p-1)/p,V=(50-B)*(p-1)/p;J({x:Math.max(-a,Math.min(z,a))||0,y:Math.max(-a,Math.min(V,a))||0})};Z.current&&cancelAnimationFrame(Z.current),Z.current=requestAnimationFrame(g)},[p]);R(()=>{O.current=null},[l]);const d=t=>{!l||t.type!=="touchstart"||(ne({x:t.touches[0].clientX,y:t.touches[0].clientY}),ie({x:k.x,y:k.y}),L(!0))},ue=t=>{var T;if(!w||t.type!=="touchmove")return;const g=(T=t.currentTarget)==null?void 0:T.getBoundingClientRect(),h=(100-100/p)/2,a=t.touches[0].clientX-W.x,b=t.touches[0].clientY-W.y,m=a*100/(g.width*p),B=b*100/(g.height*p),z=X.x+m,V=X.y+B;J({x:Math.max(-h,Math.min(z,h))||0,y:Math.max(-h,Math.min(V,h))||0}),t.preventDefault()},v=t=>{if(y)x.current={x:t.touches[0].clientX,y:t.touches[0].clientY,time:Date.now()},j.current={clientX:t.touches[0].clientX,clientY:t.touches[0].clientY},oe.current=!1,l&&d(t);else{if(w)return;!l&&H(t),o(!l),t.preventDefault()}},C=t=>{if(t.touches.length!==0){if(j.current={clientX:t.touches[0].clientX,clientY:t.touches[0].clientY},y){if(!x.current)return;if(w){ue(t);return}const g=t.touches[0].clientX,h=t.touches[0].clientY,a=Math.abs(g-x.current.x),b=Math.abs(h-x.current.y);(a>10||b>10)&&(oe.current=!0)}l&&H(t)}},Q=t=>{if(y){if(!x.current)return;const g=Date.now()-x.current.time;!oe.current&&g<300&&!w&&(o(!0),H(t),t.preventDefault()),L(!1),x.current=null}else o(!1)},K=t=>{"touches"in t||w||(l?!y&&o(!1):(o(!0),H(t)),t.preventDefault())},f=t=>{"touches"in t||l&&H(t)},fe=t=>{if(!("touches"in t)){if(y){L(!1);return}o(!1)}},G=t=>{o(!1),t.stopPropagation()},E=l?`scale(${p}) translateX(${k.x}%) translateY(${k.y}%)`:"none",he=q("PDP.Zoom.Close.label").label,ee=I.only(i);R(()=>{const t=()=>{l&&(o(!1),J({x:0,y:0}),L(!1))},g=document.querySelector("#gallery");if(g)return g.addEventListener("click",t),()=>g.removeEventListener("click",t)},[l]);const de=De(ee,{...ee.props,draggable:!1,style:{...(se=ee.props)==null?void 0:se.style,"--transform":E}});return R(()=>{c(l?`pdp-zoom ${y?"pdp-zoom--no-effects":"pdp-zoom--zoomed"}`:"pdp-zoom")},[l,y]),R(()=>{if(ce.current===E)return;ce.current=E,requestAnimationFrame(()=>{if(!Y.current)return;Y.current.querySelectorAll("img").forEach(h=>{l&&E!=="none"?h.style.setProperty("transform",E,"important"):h.style.removeProperty("transform")})})},[E,l]),R(()=>()=>{Z.current&&cancelAnimationFrame(Z.current)},[]),U("figure",{ref:Y,className:S,onClick:K,onMouseMove:f,onMouseLeave:fe,onTouchStart:v,onTouchMove:C,onTouchEnd:Q,children:[de,y&&l&&M(pe,{"aria-label":he,variant:"tertiary",className:"pdp-zoom__close-button",icon:M(Ce,{}),onClick:G})]})};export{Fe as C,qe as O,Oe as Z};
|
|
4
4
|
//# sourceMappingURL=Zoom.js.map
|
package/chunks/Zoom.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Zoom.js","sources":["../../node_modules/@adobe-commerce/elsie/src/icons/ChevronDown.svg","../../node_modules/@adobe-commerce/elsie/src/icons/Close.svg","/@dropins/storefront-pdp/src/components/Carousel/Carousel.tsx","/@dropins/storefront-pdp/src/components/Overlay/Overlay.tsx","/@dropins/storefront-pdp/src/components/Zoom/Zoom.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgChevronDown = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M7.74512 9.87701L12.0001 14.132L16.2551 9.87701\", stroke: \"currentColor\", strokeWidth: 1.5, strokeLinecap: \"square\", strokeLinejoin: \"round\" }));\nexport default SvgChevronDown;\n","import * as React from \"react\";\nconst SvgClose = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 5.64001L5.62988 18.37\", stroke: \"currentColor\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 18.37L5.62988 5.64001\", stroke: \"currentColor\" }));\nexport default SvgClose;\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 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 { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n Children,\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useLayoutEffect,\n} from 'preact/compat';\nimport { classes, debounce } from '@adobe-commerce/elsie/lib';\nimport { Button, Icon } from '@adobe-commerce/elsie/components';\nimport { ChevronDown } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport '@/pdp/components/Carousel/Carousel.css';\n\ntype Show = number;\n\nconst PEAK_WIDTH = 24;\nconst THUMB_GAP = 16;\nconst ICON_SIZE = '32';\n\nenum GapSize {\n small = 16,\n medium = 24,\n large = 64,\n}\n\nexport interface CarouselProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'controls'> {\n children: VNode[] | VNode;\n thumbnails?: VNode[] | VNode;\n show?: Show | { small: Show; medium: Show; large: Show };\n gap?: 'small' | 'medium' | 'large' | null;\n scrollbar?: boolean;\n peak?: boolean;\n arrows?: boolean;\n controls?: 'thumbnailsRow' | 'thumbnailsColumn' | 'dots' | null;\n arrowsOnMainImage?: boolean;\n loop?: boolean;\n direction?: 'horizontal';\n style?: Record<string, string | number>;\n width?: string;\n height?: string;\n defaultIndex?: number;\n infinite?: boolean;\n isZoomed?: boolean;\n}\n\nexport const Carousel: FunctionComponent<CarouselProps> = ({\n show = 1,\n scrollbar = false,\n peak = false,\n arrows = false,\n controls = 'dots',\n arrowsOnMainImage = false,\n loop = false,\n gap = null,\n direction = 'horizontal',\n width = '100%',\n height = '100%',\n defaultIndex = 0,\n className,\n children,\n thumbnails = null,\n isZoomed,\n ...props\n}) => {\n // i18n\n const Label = useText('PDP.Carousel.label').label;\n const SlideLabel = useText('PDP.Carousel.Slide.label').label;\n const PreviousLabel = useText('PDP.Carousel.Previous.label').label;\n const NextLabel = useText('PDP.Carousel.Next.label').label;\n const ControlsLabel = useText('PDP.Carousel.Controls.label').label;\n const ControlsBtnLabel = useText('PDP.Carousel.Controls.Button.label').label;\n\n // States\n const [perPage, setPerPage] = useState(() => getPerPageFromBreakpoint(show));\n\n // Constants\n const length = Math.ceil(Children.count(children) / perPage);\n\n const peakWidth = peak ? PEAK_WIDTH : 0;\n const gapWidth = gap ? GapSize[gap] : 0;\n const rest = Children.count(children) % perPage;\n\n // States\n const [current, setCurrent] = useState(\n loop ? (isRTL() ? defaultIndex - 1 : defaultIndex + 1) : defaultIndex\n );\n\n // Thumbnails (refs for each thumbnail item)\n const thumbnailsRefs = useRef<HTMLLabelElement[]>([]);\n const [thumbWidth, setThumbWidth] = useState(0);\n const [thumbHeight, setThumbHeight] = useState(0);\n\n // VNodes\n const thumbnailSlides = useMemo<VNode[]>(() => {\n return Children.toArray(thumbnails);\n }, [thumbnails]);\n\n // Slides\n const slides = useMemo<VNode[][]>(() => {\n const returnValue = Children.toArray(children).reduce((acc, child, i) => {\n if (i % perPage === 0) {\n return [...acc, [child]];\n }\n\n return [...acc.slice(0, -1), [...acc[acc.length - 1], child]];\n }, [] as VNode[][]);\n\n if (!loop || returnValue.length === 1) {\n return returnValue;\n }\n\n if (loop && !(Children.count(children) % perPage !== 0)) {\n return [returnValue[length - 1]]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }\n\n return [Children.toArray(children).slice(-perPage)]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }, [children, perPage, length, loop]);\n\n // Wrapper\n const wrapperRef = useRef<HTMLDivElement>(null);\n const thumbnailsWrapperRef = useRef<HTMLDivElement>(null);\n\n const thumbnailControls =\n controls === 'thumbnailsRow' || controls === 'thumbnailsColumn';\n\n // Observe Resize (responsive)\n useEffect(() => {\n const wrapper = wrapperRef.current;\n\n if (!wrapper) return; // Guard clause in case the ref is not set yet\n\n const handleResize = debounce(() => {\n setThumbWidth(wrapper.offsetWidth ?? 0);\n setThumbHeight(wrapper.offsetHeight ?? 0);\n const width = window.innerWidth;\n const newPerPage = getPerPageFromBreakpoint(show, width);\n\n if (newPerPage !== perPage) {\n setPerPage(newPerPage);\n }\n }, 50);\n\n const observer = new ResizeObserver(handleResize);\n observer.observe(wrapper);\n\n return () => {\n observer.unobserve(wrapper);\n };\n }, [perPage, show]);\n\n // Scrolling logic controls\n const handleThumbnailsScroll = useCallback(\n (nextSlideIndex: number) => {\n const nextItem = loop ? nextSlideIndex - 1 : nextSlideIndex;\n const thumbnailRef = thumbnailsRefs?.current[0];\n const oneItemWidth = thumbnailRef?.offsetWidth + THUMB_GAP;\n const oneItemHeight = thumbnailRef?.offsetHeight + THUMB_GAP;\n const thumbnailsWrapper = thumbnailsWrapperRef.current!;\n\n const isRow = controls === 'thumbnailsRow';\n const isColumn = controls === 'thumbnailsColumn';\n const offset = isRow\n ? thumbnailsWrapper?.offsetWidth\n : thumbnailsWrapper?.offsetHeight;\n const oneItemSize = isRow ? oneItemWidth : oneItemHeight;\n\n if ((isRow || isColumn) && offset) {\n const visibleThumbnails = Math.floor(\n (isRow\n ? thumbnailsWrapper.clientWidth\n : thumbnailsWrapper.clientHeight) / oneItemSize\n );\n const centerOffset = Math.floor(visibleThumbnails / 2);\n const targetScrollPosition = (nextItem - centerOffset) * oneItemSize;\n thumbnailsWrapper.style.scrollBehavior = 'smooth';\n\n if (isRow) {\n thumbnailsWrapper.scrollLeft = isRTL()\n ? -(\n thumbnailsWrapper.scrollWidth -\n thumbnailsWrapper.clientWidth -\n targetScrollPosition\n )\n : targetScrollPosition;\n } else {\n thumbnailsWrapper.scrollTop = targetScrollPosition;\n }\n }\n },\n [controls, loop]\n );\n\n useEffect(() => {\n handleThumbnailsScroll(current);\n }, [current, handleThumbnailsScroll]);\n\n // Navigation\n const handleScrollTo = useCallback(\n (nextSlideIndex: number, smooth?: boolean, reset?: boolean) => {\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const items = Array.from(wrapper.querySelectorAll('[data-index]')).filter(\n (element) => {\n const dataIndex = Number(element.getAttribute('data-index')!);\n return !isNaN(dataIndex) && dataIndex > -1;\n }\n );\n\n const item = items[nextSlideIndex];\n\n if (!item) {\n return;\n }\n\n if (reset) {\n const futureIndex = nextSlideIndex === 0 ? length : 0;\n const scrollWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n\n if (isRTL()) {\n if (\n wrapper.scrollLeft <= 0 &&\n wrapper.scrollLeft > -(realWidth - 5)\n ) {\n handleScrollTo(1, true);\n return;\n }\n if (\n wrapper.scrollLeft < realWidth - scrollWidth &&\n wrapper.scrollLeft >= -scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : -scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n } else {\n if (wrapper.scrollLeft >= 0 && wrapper.scrollLeft < realWidth - 5) {\n handleScrollTo(1, true);\n return;\n }\n\n if (\n wrapper.scrollLeft > scrollWidth - realWidth &&\n wrapper.scrollLeft <= scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n return;\n }\n }\n\n const diff =\n ((wrapper.offsetWidth - gapWidth) / perPage) *\n slides[nextSlideIndex].length -\n peakWidth;\n\n wrapper.style.scrollBehavior = smooth ? 'smooth' : 'auto';\n wrapper.scrollLeft = isRTL()\n ? -(slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) - diff)\n : slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) + diff;\n return;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n gapWidth,\n length,\n peakWidth,\n perPage,\n rest,\n slides,\n handleThumbnailsScroll,\n controls,\n ]\n );\n\n const handleGoToPrev = useCallback(() => {\n if (loop) {\n const nextSlideIndex = current - 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === length - 1 : current === 1\n );\n return;\n }\n\n const nextSlideIndex = current <= 0 ? 0 : current - 1;\n handleScrollTo(nextSlideIndex, true);\n }, [current, handleScrollTo, loop]); //eslint-disable-line react-hooks/exhaustive-deps\n\n const handleGoToNext = useCallback(() => {\n const lastSlideIndex = slides.length - 1;\n\n if (loop) {\n const nextSlideIndex = current + 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === 0 : current === length\n );\n return;\n }\n\n const nextSlideIndex =\n current >= lastSlideIndex ? lastSlideIndex : current + 1;\n\n handleScrollTo(nextSlideIndex, true);\n }, [slides.length, loop, current, handleScrollTo, length]);\n\n // Navigate with keyboard\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n isRTL() ? handleGoToNext() : handleGoToPrev();\n }\n\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n isRTL() ? handleGoToPrev() : handleGoToNext();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleGoToNext, handleGoToPrev]);\n\n // Set default index\n useLayoutEffect(() => {\n handleScrollTo(loop ? defaultIndex + 1 : defaultIndex, false);\n }, [defaultIndex, handleScrollTo, loop, thumbWidth]);\n\n // Track scrolling (swipes)\n const handleOnScroll = debounce(() => {\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const dividing = Math.abs(wrapper.scrollLeft) / realWidth;\n const nextSlideIndex = Math.abs(\n Math.round(dividing) - dividing < 1\n ? Math.round(dividing)\n : Math.ceil(dividing)\n );\n\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n if (loop) {\n const totalWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n const scrollOffset = isRTL() ? -wrapper.scrollLeft : wrapper.scrollLeft;\n\n if (Math.ceil(Math.abs(scrollOffset)) >= Math.ceil(totalWidth) - 5) {\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = isRTL()\n ? -wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth)\n : wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth);\n return;\n }\n\n if (Math.abs(scrollOffset) === 0) {\n wrapper.style.scrollBehavior = 'auto';\n\n wrapper.scrollLeft = isRTL()\n ? -(totalWidth - wrapper.offsetWidth + peakWidth)\n : totalWidth - wrapper.offsetWidth + peakWidth;\n return;\n }\n }\n\n if (current !== nextSlideIndex) {\n setCurrent(nextSlideIndex);\n }\n }, 100);\n\n useEffect(() => {\n const wrapper = wrapperRef.current;\n wrapper?.addEventListener('scroll', handleOnScroll);\n\n return () => {\n wrapper?.removeEventListener('scroll', handleOnScroll);\n };\n }, [handleOnScroll]);\n\n // thumbnails is column -> container is row reverse, controls is column\n // thumbnails is row -> container is column, controls is row\n const getArrow = (\n forThumbnails: boolean,\n direction: string,\n callback: () => void\n ) => {\n return (\n <Button\n className={classes([\n ['pdp-carousel__button', !forThumbnails],\n [`pdp-carousel__button--${direction}`, !forThumbnails],\n [`pdp-carousel__button--${controls}`, forThumbnails],\n ])}\n style={{\n '--height': `${thumbHeight}px`,\n }}\n variant=\"tertiary\"\n aria-label={direction === 'next' ? NextLabel : PreviousLabel}\n onClick={callback}\n disabled={\n loop\n ? false\n : direction === 'next'\n ? current >= slides.length - 1\n : current < 1\n }\n >\n <Icon\n className={classes([\n ['pdp-carousel__button__icon', !forThumbnails],\n [`pdp-carousel__button__icon--${direction}`, !forThumbnails],\n [\n `pdp-carousel__button__icon--${controls}--${direction}`,\n forThumbnails,\n ],\n ])}\n size={ICON_SIZE}\n source={ChevronDown}\n />\n </Button>\n );\n };\n\n const prevArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'prev', handleGoToPrev);\n\n const nextArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'next', handleGoToNext);\n\n const prevArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'prev', handleGoToPrev);\n\n const nextArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'next', handleGoToNext);\n\n return (\n <div\n role=\"region\"\n aria-roledescription={Label}\n className={classes([\n 'pdp-carousel',\n ['pdp-carousel--main-image-controls', arrowsOnMainImage],\n ['pdp-carousel--arrows', arrows && !thumbnailControls],\n [`pdp-carousel--${controls}`, thumbnailControls],\n className,\n ])}\n style={{\n '--flex-carousel':\n controls === 'thumbnailsColumn' ? 'row-reverse' : 'column',\n '--gap': thumbnailControls ? '0' : 'var(--spacing-small)',\n '--width': width,\n }}\n {...props}\n >\n {/* Slideshow */}\n <div\n ref={wrapperRef}\n className={classes([\n 'pdp-carousel__wrapper',\n `pdp-carousel__wrapper--${direction}`,\n ['pdp-carousel__wrapper--scrollbar', scrollbar],\n ['pdp-carousel__wrapper--peak', peak],\n ])}\n style={{\n '--total-width': controls === 'thumbnailsColumn' ? `81.6%` : `100%`,\n '--height': controls === 'thumbnailsColumn' ? 'auto' : height,\n '--gap': gap ? `var(--spacing-${gap})` : '0px',\n '--per-page': perPage,\n }}\n tabIndex={0}\n >\n {slides.map((page, index) => {\n const orphan = page.length < perPage;\n\n return (\n <div\n key={index}\n role=\"group\"\n aria-roledescription={SlideLabel}\n data-index={index}\n className={classes([\n 'pdp-carousel__slide',\n `pdp-carousel__slide--${direction}`,\n ['pdp-carousel__slide--active', current === index],\n ['pdp-carousel__slide--orphan', orphan],\n ['pdp-carousel__slide--hidden', thumbWidth === 0],\n ])}\n style={{\n '--length': page.length,\n }}\n >\n {page}\n </div>\n );\n })}\n </div>\n\n {/* Previous and next arrows for Carousel without thumbnails */}\n {!thumbnailControls && (\n <>\n {prevArrow}\n {nextArrow}\n </>\n )}\n\n {thumbnailControls && arrowsOnMainImage && (\n <>\n {prevArrowMainImage}\n {nextArrowMainImage}\n </>\n )}\n\n {/* Controls */}\n {controls && slides.length != 1 && (\n <div\n className={classes([\n [\n `pdp-carousel__controls__container--${controls}`,\n thumbnailControls,\n ],\n [\n 'pdp-carousel__controls__container--no-arrows',\n !arrows || arrowsOnMainImage,\n ],\n ])}\n style={{\n '--width': controls === 'thumbnailsRow' ? `${thumbWidth}px` : width,\n '--height': `${thumbHeight}px`,\n '--nr-thumbnails': thumbnailSlides.length,\n }}\n >\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && prevArrow}\n\n <div\n ref={thumbnailsWrapperRef}\n className={classes([\n [\n `pdp-carousel__controls__wrapper--${controls}`,\n thumbnailControls,\n ],\n [`pdp-carousel__controls__wrapper`, thumbnailControls],\n ])}\n >\n <div\n role=\"group\"\n aria-label={ControlsLabel}\n className={classes([\n 'pdp-carousel__controls',\n [`pdp-carousel__controls--${controls}`, thumbnailControls],\n ])}\n >\n {(loop ? slides.slice(0, length) : slides).map((_, key) => {\n const buttonsLength = loop ? length : slides.length;\n const active = loop ? current - 1 === key : current === key;\n\n if (!thumbnailControls) {\n return (\n <button\n key={key}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n onClick={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n className={classes([\n 'pdp-carousel__controls__button',\n ['pdp-carousel__controls__button--active', active],\n ])}\n />\n );\n }\n return (\n <label\n className={classes(['pdp-carousel__thumbnail__container'])}\n key={key}\n ref={(el: HTMLLabelElement | null) => {\n if (el) {\n thumbnailsRefs.current[key] = el;\n }\n }}\n >\n <input\n type=\"radio\"\n name={'carousel-thumbnails'}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n checked={active && thumbWidth !== 0}\n onChange={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n {...props}\n className={classes([\n 'pdp-carousel__thumbnail',\n [\n 'pdp-carousel__thumbnail--selected',\n active && thumbWidth !== 0,\n ],\n ])}\n />\n\n <span\n className={classes(['pdp-carousel__thumbnail__span'])}\n >\n {thumbnailSlides[key]}\n </span>\n </label>\n );\n })}\n </div>\n </div>\n\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && nextArrow}\n </div>\n )}\n </div>\n );\n};\n\n// Utilities\nfunction getPerPageFromBreakpoint(\n breakpoints: { small: number; medium: number; large: number } | number,\n width = 0\n) {\n if (typeof breakpoints === 'number') return breakpoints;\n\n const { small, medium, large } = breakpoints;\n const breakpointsMap = [\n { breakpoint: 1024, value: large },\n { breakpoint: 786, value: medium },\n { breakpoint: 0, value: small },\n ];\n\n const matchingBreakpoint = breakpointsMap.find(\n ({ breakpoint }) => width > breakpoint\n );\n\n return matchingBreakpoint ? matchingBreakpoint.value : small;\n}\n\nfunction isRTL() {\n return document.documentElement.dir === 'rtl';\n}\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 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 { FunctionComponent } from 'preact';\nimport { HTMLAttributes, useCallback, useEffect, useRef } from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { Button } from '@adobe-commerce/elsie/components';\n\nimport '@/pdp/components/Overlay/Overlay.css';\n\nexport interface OverlayProps extends HTMLAttributes<HTMLDivElement> {\n centered?: boolean;\n onClose?: () => void;\n}\n\nexport const Overlay: FunctionComponent<OverlayProps> = ({\n centered,\n onClose,\n className,\n children,\n ...props\n}) => {\n // i18n\n const CloseLabel = useText('PDP.Overlay.Close.label').label;\n const overlayRef = useRef<HTMLInputElement>(null);\n const handleOnClose = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n // Close on ESC\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handleOnClose();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleOnClose]);\n\n // Prevent document scrolling\n useEffect(() => {\n const input = overlayRef.current;\n input?.focus();\n\n const scrollingElement = document.scrollingElement as HTMLElement;\n\n const defaultOverflowValue = scrollingElement.style.overflow;\n\n scrollingElement.style.overflow = 'hidden';\n\n return () => {\n scrollingElement.style.overflow = defaultOverflowValue;\n };\n }, []);\n\n return (\n <div\n {...props}\n className={classes([\n 'pdp-overlay',\n ['pdp-overlay--centered', centered],\n className,\n ])}\n ref={overlayRef}\n role=\"dialog\"\n aria-describedby=\"overlay-content\"\n tabindex={0}\n >\n <div className=\"pdp-overlay__content\" id=\"overlay-content\">\n {children}\n </div>\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-overlay__close-button\"\n onClick={handleOnClose}\n icon={<CloseSVG />}\n />\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 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 */\nimport { cloneElement, FunctionComponent, VNode } from 'preact';\nimport {\n Children,\n useEffect,\n useState,\n useRef,\n useCallback,\n} from 'preact/compat';\n\nimport '@/pdp/components/Zoom/Zoom.css';\nimport { Button } from '@adobe-commerce/elsie/components';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nexport interface ZoomProps {\n children: VNode[] | VNode;\n scale?: number;\n closeButton?: boolean;\n}\n\nexport const Zoom: FunctionComponent<ZoomProps> = ({\n children,\n scale = 2.0,\n closeButton = true,\n}) => {\n const [zoomed, setZoomed] = useState(false);\n const [figureClassName, setFigureClassName] = useState('pdp-zoom');\n const [drag, setDrag] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 });\n const [position, setPosition] = useState({ x: 0, y: 0 });\n\n const containerRef = useRef<HTMLElement>(null);\n const cachedBoundsRef = useRef<DOMRect | null>(null);\n const animationFrameRef = useRef<number | null>(null);\n const lastTransformRef = useRef<string>('none');\n\n const touchStartRef = useRef<{ x: number; y: number; time: number } | null>(\n null\n );\n const isSwipingRef = useRef<boolean>(false);\n const lastValidTouchRef = useRef<{ clientX: number; clientY: number } | null>(\n null\n );\n\n const updatePosition = useCallback(\n (event: MouseEvent | TouchEvent) => {\n const updatePositionLogic = () => {\n let zoomer: DOMRect;\n\n if (cachedBoundsRef.current && containerRef.current) {\n zoomer = cachedBoundsRef.current;\n } else if (containerRef.current) {\n zoomer = containerRef.current.getBoundingClientRect();\n cachedBoundsRef.current = zoomer;\n } else {\n zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n }\n\n const overlap = (100 - 100 / scale) / 2;\n let coordinates: { clientX: number; clientY: number } | null = null;\n\n if ('touches' in event) {\n if (event.touches.length > 0) {\n coordinates = event.touches[0];\n lastValidTouchRef.current = {\n clientX: coordinates.clientX,\n clientY: coordinates.clientY,\n };\n } else if (event.type === 'touchend' && touchStartRef.current) {\n coordinates = {\n clientX: touchStartRef.current.x,\n clientY: touchStartRef.current.y,\n };\n } else if (lastValidTouchRef.current) {\n coordinates = lastValidTouchRef.current;\n } else {\n return;\n }\n } else if (event instanceof MouseEvent) {\n coordinates = event;\n } else {\n return;\n }\n\n const relativeX =\n ((coordinates.clientX - zoomer.left) / zoomer.width) * 100;\n const relativeY =\n ((coordinates.clientY - zoomer.top) / zoomer.height) * 100;\n\n const x = ((50 - relativeX) * (scale - 1)) / scale;\n const y = ((50 - relativeY) * (scale - 1)) / scale;\n\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n };\n\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') {\n updatePositionLogic();\n } else {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n animationFrameRef.current = requestAnimationFrame(updatePositionLogic);\n }\n },\n [scale]\n );\n\n useEffect(() => {\n cachedBoundsRef.current = null;\n }, [zoomed]);\n\n const startDrag = (event: TouchEvent) => {\n if (!zoomed || event.type !== 'touchstart') return;\n setDragStart({ x: event.touches[0].clientX, y: event.touches[0].clientY });\n setDragStartPosition({ x: position.x, y: position.y });\n setDrag(true);\n };\n\n const dragMove = (event: TouchEvent) => {\n if (!drag || event.type !== 'touchmove') return;\n const zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n const overlap = (100 - 100 / scale) / 2;\n const movedX = event.touches[0].clientX - dragStart.x;\n const movedY = event.touches[0].clientY - dragStart.y;\n const movedXPercent = (movedX * 100) / (zoomer.width * scale);\n const movedYPercent = (movedY * 100) / (zoomer.height * scale);\n const x = dragStartPosition.x + movedXPercent;\n const y = dragStartPosition.y + movedYPercent;\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n event.preventDefault();\n };\n\n const handleTouchStart = (event: TouchEvent) => {\n if (closeButton) {\n touchStartRef.current = {\n x: event.touches[0].clientX,\n y: event.touches[0].clientY,\n time: Date.now(),\n };\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n isSwipingRef.current = false;\n\n if (zoomed) {\n startDrag(event);\n }\n } else {\n if (drag) return;\n\n !zoomed && updatePosition(event);\n\n setZoomed(!zoomed);\n\n event.preventDefault();\n }\n };\n\n const handleTouchMove = (event: TouchEvent) => {\n if (event.touches.length === 0) return;\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n if (drag) {\n dragMove(event);\n return;\n }\n\n const touchX = event.touches[0].clientX;\n const touchY = event.touches[0].clientY;\n const deltaX = Math.abs(touchX - touchStartRef.current.x);\n const deltaY = Math.abs(touchY - touchStartRef.current.y);\n\n if (deltaX > 10 || deltaY > 10) {\n isSwipingRef.current = true;\n }\n }\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleTouchEnd = (event: TouchEvent) => {\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n const tapDuration = Date.now() - touchStartRef.current.time;\n\n if (!isSwipingRef.current && tapDuration < 300 && !drag) {\n setZoomed(true);\n updatePosition(event);\n event.preventDefault();\n }\n\n setDrag(false);\n touchStartRef.current = null;\n } else {\n setZoomed(false);\n }\n };\n\n const handleClick = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (drag) return;\n\n if (zoomed) {\n !closeButton && setZoomed(false);\n } else {\n setZoomed(true);\n updatePosition(event);\n }\n event.preventDefault();\n };\n\n const handleMove = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleLeave = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (closeButton) {\n setDrag(false);\n return;\n }\n setZoomed(false);\n };\n\n const closeButtonClick = (event: MouseEvent | TouchEvent) => {\n setZoomed(false);\n event.stopPropagation();\n };\n\n const transformStyle = zoomed\n ? `scale(${scale}) translateX(${position.x}%) translateY(${position.y}%)`\n : 'none';\n\n const CloseLabel = useText('PDP.Zoom.Close.label').label;\n const child = Children.only(children) as any;\n\n useEffect(() => {\n const handleGalleryChange = () => {\n if (zoomed) {\n setZoomed(false);\n setPosition({ x: 0, y: 0 });\n setDrag(false);\n }\n };\n\n const gallery = document.querySelector('#gallery');\n if (gallery) {\n gallery.addEventListener('click', handleGalleryChange);\n return () => gallery.removeEventListener('click', handleGalleryChange);\n }\n }, [zoomed]);\n\n const ImageClone = cloneElement(child, {\n ...child.props,\n draggable: false,\n style: {\n ...child.props?.style,\n '--transform': transformStyle,\n },\n });\n\n useEffect(() => {\n const className = zoomed\n ? `pdp-zoom ${closeButton ? 'pdp-zoom--no-effects' : 'pdp-zoom--zoomed'}`\n : 'pdp-zoom';\n setFigureClassName(className);\n }, [zoomed, closeButton]);\n\n useEffect(() => {\n if (lastTransformRef.current === transformStyle) return;\n lastTransformRef.current = transformStyle;\n\n const updateTransforms = () => {\n if (!containerRef.current) return;\n\n const images = containerRef.current.querySelectorAll('img');\n images.forEach((img) => {\n if (zoomed && transformStyle !== 'none') {\n img.style.setProperty('transform', transformStyle, 'important');\n } else {\n img.style.removeProperty('transform');\n }\n });\n };\n\n requestAnimationFrame(updateTransforms);\n }, [transformStyle, zoomed]);\n\n useEffect(() => {\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n };\n }, []);\n\n return (\n <figure\n ref={containerRef}\n className={figureClassName}\n onClick={handleClick}\n onMouseMove={handleMove}\n onMouseLeave={handleLeave}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {ImageClone}\n {closeButton && zoomed && (\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-zoom__close-button\"\n icon={<CloseSVG />}\n onClick={closeButtonClick}\n />\n )}\n </figure>\n );\n};\n"],"names":["SvgChevronDown","props","React","SvgClose","PEAK_WIDTH","THUMB_GAP","ICON_SIZE","GapSize","Carousel","show","scrollbar","peak","arrows","controls","arrowsOnMainImage","loop","gap","direction","width","height","defaultIndex","className","children","thumbnails","isZoomed","Label","useText","SlideLabel","PreviousLabel","NextLabel","ControlsLabel","ControlsBtnLabel","perPage","setPerPage","useState","getPerPageFromBreakpoint","length","Children","peakWidth","gapWidth","rest","current","setCurrent","isRTL","thumbnailsRefs","useRef","thumbWidth","setThumbWidth","thumbHeight","setThumbHeight","thumbnailSlides","useMemo","slides","returnValue","acc","child","i","wrapperRef","thumbnailsWrapperRef","thumbnailControls","useEffect","wrapper","handleResize","debounce","newPerPage","observer","handleThumbnailsScroll","useCallback","nextSlideIndex","nextItem","thumbnailRef","oneItemWidth","oneItemHeight","thumbnailsWrapper","isRow","isColumn","offset","oneItemSize","visibleThumbnails","centerOffset","targetScrollPosition","handleScrollTo","smooth","reset","realWidth","element","dataIndex","futureIndex","scrollWidth","diff","handleGoToPrev","handleGoToNext","lastSlideIndex","handleKeyDown","event","useLayoutEffect","handleOnScroll","dividing","totalWidth","scrollOffset","getArrow","forThumbnails","callback","jsx","Button","classes","Icon","ChevronDown","prevArrow","nextArrow","prevArrowMainImage","nextArrowMainImage","jsxs","page","index","orphan","Fragment","_","key","buttonsLength","active","el","breakpoints","small","medium","large","matchingBreakpoint","breakpoint","Overlay","centered","onClose","CloseLabel","overlayRef","handleOnClose","input","scrollingElement","defaultOverflowValue","CloseSVG","Zoom","scale","closeButton","zoomed","setZoomed","figureClassName","setFigureClassName","drag","setDrag","dragStart","setDragStart","dragStartPosition","setDragStartPosition","position","setPosition","containerRef","cachedBoundsRef","animationFrameRef","lastTransformRef","touchStartRef","isSwipingRef","lastValidTouchRef","updatePosition","updatePositionLogic","zoomer","_a","overlap","coordinates","relativeX","relativeY","x","y","startDrag","dragMove","movedX","movedY","movedXPercent","movedYPercent","handleTouchStart","handleTouchMove","touchX","touchY","deltaX","deltaY","handleTouchEnd","tapDuration","handleClick","handleMove","handleLeave","closeButtonClick","transformStyle","handleGalleryChange","gallery","ImageClone","cloneElement","img"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"Zoom.js","sources":["../../node_modules/@adobe-commerce/elsie/src/icons/ChevronDown.svg","../../node_modules/@adobe-commerce/elsie/src/icons/Close.svg","/@dropins/storefront-pdp/src/components/Carousel/Carousel.tsx","/@dropins/storefront-pdp/src/components/Overlay/Overlay.tsx","/@dropins/storefront-pdp/src/components/Zoom/Zoom.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgChevronDown = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M7.74512 9.87701L12.0001 14.132L16.2551 9.87701\", stroke: \"currentColor\", strokeWidth: 1.5, strokeLinecap: \"square\", strokeLinejoin: \"round\" }));\nexport default SvgChevronDown;\n","import * as React from \"react\";\nconst SvgClose = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 5.64001L5.62988 18.37\", stroke: \"currentColor\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 18.37L5.62988 5.64001\", stroke: \"currentColor\" }));\nexport default SvgClose;\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 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 { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n Children,\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useLayoutEffect,\n} from 'preact/compat';\nimport { classes, debounce } from '@adobe-commerce/elsie/lib';\nimport { Button, Icon } from '@adobe-commerce/elsie/components';\nimport { ChevronDown } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport '@/pdp/components/Carousel/Carousel.css';\n\ntype Show = number;\n\nconst PEAK_WIDTH = 24;\nconst THUMB_GAP = 16;\nconst ICON_SIZE = '32';\n\nenum GapSize {\n small = 16,\n medium = 24,\n large = 64,\n}\n\nexport interface CarouselProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'controls'> {\n children: VNode[] | VNode;\n thumbnails?: VNode[] | VNode;\n show?: Show | { small: Show; medium: Show; large: Show };\n gap?: 'small' | 'medium' | 'large' | null;\n scrollbar?: boolean;\n peak?: boolean;\n arrows?: boolean;\n controls?: 'thumbnailsRow' | 'thumbnailsColumn' | 'dots' | null;\n arrowsOnMainImage?: boolean;\n loop?: boolean;\n direction?: 'horizontal';\n style?: Record<string, string | number>;\n width?: string;\n height?: string;\n defaultIndex?: number;\n infinite?: boolean;\n isZoomed?: boolean;\n}\n\nexport const Carousel: FunctionComponent<CarouselProps> = ({\n show = 1,\n scrollbar = false,\n peak = false,\n arrows = false,\n controls = 'dots',\n arrowsOnMainImage = false,\n loop = false,\n gap = null,\n direction = 'horizontal',\n width = '100%',\n height = '100%',\n defaultIndex = 0,\n className,\n children,\n thumbnails = null,\n isZoomed,\n ...props\n}) => {\n // i18n\n const Label = useText('PDP.Carousel.label').label;\n const SlideLabel = useText('PDP.Carousel.Slide.label').label;\n const PreviousLabel = useText('PDP.Carousel.Previous.label').label;\n const NextLabel = useText('PDP.Carousel.Next.label').label;\n const ControlsLabel = useText('PDP.Carousel.Controls.label').label;\n const ControlsBtnLabel = useText('PDP.Carousel.Controls.Button.label').label;\n\n // States\n const [perPage, setPerPage] = useState(() => getPerPageFromBreakpoint(show));\n\n // Constants\n const length = Math.ceil(Children.count(children) / perPage);\n\n const peakWidth = peak ? PEAK_WIDTH : 0;\n const gapWidth = gap ? GapSize[gap] : 0;\n const rest = Children.count(children) % perPage;\n\n // States\n const [current, setCurrent] = useState(\n loop ? (isRTL() ? defaultIndex - 1 : defaultIndex + 1) : defaultIndex\n );\n\n // Thumbnails (refs for each thumbnail item)\n const thumbnailsRefs = useRef<HTMLLabelElement[]>([]);\n const [thumbWidth, setThumbWidth] = useState(0);\n const [thumbHeight, setThumbHeight] = useState(0);\n\n // VNodes\n const thumbnailSlides = useMemo<VNode[]>(() => {\n return Children.toArray(thumbnails);\n }, [thumbnails]);\n\n // Slides\n const slides = useMemo<VNode[][]>(() => {\n const returnValue = Children.toArray(children).reduce((acc, child, i) => {\n if (i % perPage === 0) {\n return [...acc, [child]];\n }\n\n return [...acc.slice(0, -1), [...acc[acc.length - 1], child]];\n }, [] as VNode[][]);\n\n if (!loop || returnValue.length === 1) {\n return returnValue;\n }\n\n if (loop && !(Children.count(children) % perPage !== 0)) {\n return [returnValue[length - 1]]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }\n\n return [Children.toArray(children).slice(-perPage)]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }, [children, perPage, length, loop]);\n\n // Wrapper\n const wrapperRef = useRef<HTMLDivElement>(null);\n const thumbnailsWrapperRef = useRef<HTMLDivElement>(null);\n\n const thumbnailControls =\n controls === 'thumbnailsRow' || controls === 'thumbnailsColumn';\n\n // Observe Resize (responsive)\n useEffect(() => {\n const wrapper = wrapperRef.current;\n\n if (!wrapper) return; // Guard clause in case the ref is not set yet\n\n const handleResize = debounce(() => {\n setThumbWidth(wrapper.offsetWidth ?? 0);\n setThumbHeight(wrapper.offsetHeight ?? 0);\n const width = window.innerWidth;\n const newPerPage = getPerPageFromBreakpoint(show, width);\n\n if (newPerPage !== perPage) {\n setPerPage(newPerPage);\n }\n }, 50);\n\n const observer = new ResizeObserver(handleResize);\n observer.observe(wrapper);\n\n return () => {\n observer.unobserve(wrapper);\n };\n }, [perPage, show]);\n\n // Scrolling logic controls\n const handleThumbnailsScroll = useCallback(\n (nextSlideIndex: number) => {\n const nextItem = loop ? nextSlideIndex - 1 : nextSlideIndex;\n const thumbnailRef = thumbnailsRefs?.current[0];\n const oneItemWidth = thumbnailRef?.offsetWidth + THUMB_GAP;\n const oneItemHeight = thumbnailRef?.offsetHeight + THUMB_GAP;\n const thumbnailsWrapper = thumbnailsWrapperRef.current!;\n\n const isRow = controls === 'thumbnailsRow';\n const isColumn = controls === 'thumbnailsColumn';\n const offset = isRow\n ? thumbnailsWrapper?.offsetWidth\n : thumbnailsWrapper?.offsetHeight;\n const oneItemSize = isRow ? oneItemWidth : oneItemHeight;\n\n if ((isRow || isColumn) && offset) {\n const visibleThumbnails = Math.floor(\n (isRow\n ? thumbnailsWrapper.clientWidth\n : thumbnailsWrapper.clientHeight) / oneItemSize\n );\n const centerOffset = Math.floor(visibleThumbnails / 2);\n const targetScrollPosition = (nextItem - centerOffset) * oneItemSize;\n thumbnailsWrapper.style.scrollBehavior = 'smooth';\n\n if (isRow) {\n thumbnailsWrapper.scrollLeft = isRTL()\n ? -(\n thumbnailsWrapper.scrollWidth -\n thumbnailsWrapper.clientWidth -\n targetScrollPosition\n )\n : targetScrollPosition;\n } else {\n thumbnailsWrapper.scrollTop = targetScrollPosition;\n }\n }\n },\n [controls, loop]\n );\n\n useEffect(() => {\n handleThumbnailsScroll(current);\n }, [current, handleThumbnailsScroll]);\n\n // Navigation\n const handleScrollTo = useCallback(\n (nextSlideIndex: number, smooth?: boolean, reset?: boolean) => {\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const items = Array.from(wrapper.querySelectorAll('[data-index]')).filter(\n (element) => {\n const dataIndex = Number(element.getAttribute('data-index')!);\n return !isNaN(dataIndex) && dataIndex > -1;\n }\n );\n\n const item = items[nextSlideIndex];\n\n if (!item) {\n return;\n }\n\n if (reset) {\n const futureIndex = nextSlideIndex === 0 ? length : 0;\n const scrollWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n\n if (isRTL()) {\n if (\n wrapper.scrollLeft <= 0 &&\n wrapper.scrollLeft > -(realWidth - 5)\n ) {\n handleScrollTo(1, true);\n return;\n }\n if (\n wrapper.scrollLeft < realWidth - scrollWidth &&\n wrapper.scrollLeft >= -scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : -scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n } else {\n if (wrapper.scrollLeft >= 0 && wrapper.scrollLeft < realWidth - 5) {\n handleScrollTo(1, true);\n return;\n }\n\n if (\n wrapper.scrollLeft > scrollWidth - realWidth &&\n wrapper.scrollLeft <= scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n return;\n }\n }\n\n const diff =\n ((wrapper.offsetWidth - gapWidth) / perPage) *\n slides[nextSlideIndex].length -\n peakWidth;\n\n wrapper.style.scrollBehavior = smooth ? 'smooth' : 'auto';\n wrapper.scrollLeft = isRTL()\n ? -(slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) - diff)\n : slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) + diff;\n return;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n gapWidth,\n length,\n peakWidth,\n perPage,\n rest,\n slides,\n handleThumbnailsScroll,\n controls,\n ]\n );\n\n const handleGoToPrev = useCallback(() => {\n if (loop) {\n const nextSlideIndex = current - 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === length - 1 : current === 1\n );\n return;\n }\n\n const nextSlideIndex = current <= 0 ? 0 : current - 1;\n handleScrollTo(nextSlideIndex, true);\n }, [current, handleScrollTo, loop]); //eslint-disable-line react-hooks/exhaustive-deps\n\n const handleGoToNext = useCallback(() => {\n const lastSlideIndex = slides.length - 1;\n\n if (loop) {\n const nextSlideIndex = current + 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === 0 : current === length\n );\n return;\n }\n\n const nextSlideIndex =\n current >= lastSlideIndex ? lastSlideIndex : current + 1;\n\n handleScrollTo(nextSlideIndex, true);\n }, [slides.length, loop, current, handleScrollTo, length]);\n\n // Navigate with keyboard\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowLeft') {\n isRTL() ? handleGoToNext() : handleGoToPrev();\n }\n\n if (event.key === 'ArrowRight') {\n isRTL() ? handleGoToPrev() : handleGoToNext();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleGoToNext, handleGoToPrev]);\n\n // Set default index\n useLayoutEffect(() => {\n handleScrollTo(loop ? defaultIndex + 1 : defaultIndex, false);\n }, [defaultIndex, handleScrollTo, loop, thumbWidth]);\n\n // Track scrolling (swipes)\n const handleOnScroll = debounce(() => {\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const dividing = Math.abs(wrapper.scrollLeft) / realWidth;\n const nextSlideIndex = Math.abs(\n Math.round(dividing) - dividing < 1\n ? Math.round(dividing)\n : Math.ceil(dividing)\n );\n\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n if (loop) {\n const totalWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n const scrollOffset = isRTL() ? -wrapper.scrollLeft : wrapper.scrollLeft;\n\n if (Math.ceil(Math.abs(scrollOffset)) >= Math.ceil(totalWidth) - 5) {\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = isRTL()\n ? -wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth)\n : wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth);\n return;\n }\n\n if (Math.abs(scrollOffset) === 0) {\n wrapper.style.scrollBehavior = 'auto';\n\n wrapper.scrollLeft = isRTL()\n ? -(totalWidth - wrapper.offsetWidth + peakWidth)\n : totalWidth - wrapper.offsetWidth + peakWidth;\n return;\n }\n }\n\n if (current !== nextSlideIndex) {\n setCurrent(nextSlideIndex);\n }\n }, 100);\n\n useEffect(() => {\n const wrapper = wrapperRef.current;\n wrapper?.addEventListener('scroll', handleOnScroll);\n\n return () => {\n wrapper?.removeEventListener('scroll', handleOnScroll);\n };\n }, [handleOnScroll]);\n\n // thumbnails is column -> container is row reverse, controls is column\n // thumbnails is row -> container is column, controls is row\n const getArrow = (\n forThumbnails: boolean,\n direction: string,\n callback: () => void\n ) => {\n return (\n <Button\n className={classes([\n ['pdp-carousel__button', !forThumbnails],\n [`pdp-carousel__button--${direction}`, !forThumbnails],\n [`pdp-carousel__button--${controls}`, forThumbnails],\n ])}\n style={{\n '--height': `${thumbHeight}px`,\n }}\n variant=\"tertiary\"\n aria-label={direction === 'next' ? NextLabel : PreviousLabel}\n onClick={callback}\n disabled={\n loop\n ? false\n : direction === 'next'\n ? current >= slides.length - 1\n : current < 1\n }\n >\n <Icon\n className={classes([\n ['pdp-carousel__button__icon', !forThumbnails],\n [`pdp-carousel__button__icon--${direction}`, !forThumbnails],\n [\n `pdp-carousel__button__icon--${controls}--${direction}`,\n forThumbnails,\n ],\n ])}\n size={ICON_SIZE}\n source={ChevronDown}\n />\n </Button>\n );\n };\n\n const prevArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'prev', handleGoToPrev);\n\n const nextArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'next', handleGoToNext);\n\n const prevArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'prev', handleGoToPrev);\n\n const nextArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'next', handleGoToNext);\n\n return (\n <div\n role=\"region\"\n aria-roledescription={Label}\n className={classes([\n 'pdp-carousel',\n ['pdp-carousel--main-image-controls', arrowsOnMainImage],\n ['pdp-carousel--arrows', arrows && !thumbnailControls],\n [`pdp-carousel--${controls}`, thumbnailControls],\n className,\n ])}\n style={{\n '--flex-carousel':\n controls === 'thumbnailsColumn' ? 'row-reverse' : 'column',\n '--gap': thumbnailControls ? '0' : 'var(--spacing-small)',\n '--width': width,\n }}\n {...props}\n >\n {/* Slideshow */}\n <div\n ref={wrapperRef}\n className={classes([\n 'pdp-carousel__wrapper',\n `pdp-carousel__wrapper--${direction}`,\n ['pdp-carousel__wrapper--scrollbar', scrollbar],\n ['pdp-carousel__wrapper--peak', peak],\n ])}\n style={{\n '--total-width': controls === 'thumbnailsColumn' ? `81.6%` : `100%`,\n '--height': controls === 'thumbnailsColumn' ? 'auto' : height,\n '--gap': gap ? `var(--spacing-${gap})` : '0px',\n '--per-page': perPage,\n }}\n tabIndex={0}\n >\n {slides.map((page, index) => {\n const orphan = page.length < perPage;\n\n return (\n <div\n key={index}\n role=\"group\"\n aria-roledescription={SlideLabel}\n data-index={index}\n className={classes([\n 'pdp-carousel__slide',\n `pdp-carousel__slide--${direction}`,\n ['pdp-carousel__slide--active', current === index],\n ['pdp-carousel__slide--orphan', orphan],\n ['pdp-carousel__slide--hidden', thumbWidth === 0],\n ])}\n style={{\n '--length': page.length,\n }}\n >\n {page}\n </div>\n );\n })}\n </div>\n\n {/* Previous and next arrows for Carousel without thumbnails */}\n {!thumbnailControls && (\n <>\n {prevArrow}\n {nextArrow}\n </>\n )}\n\n {thumbnailControls && arrowsOnMainImage && (\n <>\n {prevArrowMainImage}\n {nextArrowMainImage}\n </>\n )}\n\n {/* Controls */}\n {controls && slides.length != 1 && (\n <div\n className={classes([\n [\n `pdp-carousel__controls__container--${controls}`,\n thumbnailControls,\n ],\n [\n 'pdp-carousel__controls__container--no-arrows',\n !arrows || arrowsOnMainImage,\n ],\n ])}\n style={{\n '--width': controls === 'thumbnailsRow' ? `${thumbWidth}px` : width,\n '--height': `${thumbHeight}px`,\n '--nr-thumbnails': thumbnailSlides.length,\n }}\n >\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && prevArrow}\n\n <div\n ref={thumbnailsWrapperRef}\n className={classes([\n [\n `pdp-carousel__controls__wrapper--${controls}`,\n thumbnailControls,\n ],\n [`pdp-carousel__controls__wrapper`, thumbnailControls],\n ])}\n >\n <div\n role=\"group\"\n aria-label={ControlsLabel}\n className={classes([\n 'pdp-carousel__controls',\n [`pdp-carousel__controls--${controls}`, thumbnailControls],\n ])}\n >\n {(loop ? slides.slice(0, length) : slides).map((_, key) => {\n const buttonsLength = loop ? length : slides.length;\n const active = loop ? current - 1 === key : current === key;\n\n if (!thumbnailControls) {\n return (\n <button\n key={key}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n onClick={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n className={classes([\n 'pdp-carousel__controls__button',\n ['pdp-carousel__controls__button--active', active],\n ])}\n />\n );\n }\n return (\n <label\n className={classes(['pdp-carousel__thumbnail__container'])}\n key={key}\n ref={(el: HTMLLabelElement | null) => {\n if (el) {\n thumbnailsRefs.current[key] = el;\n }\n }}\n >\n <input\n type=\"radio\"\n name={'carousel-thumbnails'}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n checked={active && thumbWidth !== 0}\n onChange={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n {...props}\n className={classes([\n 'pdp-carousel__thumbnail',\n [\n 'pdp-carousel__thumbnail--selected',\n active && thumbWidth !== 0,\n ],\n ])}\n />\n\n <span\n className={classes(['pdp-carousel__thumbnail__span'])}\n >\n {thumbnailSlides[key]}\n </span>\n </label>\n );\n })}\n </div>\n </div>\n\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && nextArrow}\n </div>\n )}\n </div>\n );\n};\n\n// Utilities\nfunction getPerPageFromBreakpoint(\n breakpoints: { small: number; medium: number; large: number } | number,\n width = 0\n) {\n if (typeof breakpoints === 'number') return breakpoints;\n\n const { small, medium, large } = breakpoints;\n const breakpointsMap = [\n { breakpoint: 1024, value: large },\n { breakpoint: 786, value: medium },\n { breakpoint: 0, value: small },\n ];\n\n const matchingBreakpoint = breakpointsMap.find(\n ({ breakpoint }) => width > breakpoint\n );\n\n return matchingBreakpoint ? matchingBreakpoint.value : small;\n}\n\nfunction isRTL() {\n return document.documentElement.dir === 'rtl';\n}\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 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 { FunctionComponent } from 'preact';\nimport { HTMLAttributes, useCallback, useEffect, useRef } from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { Button } from '@adobe-commerce/elsie/components';\n\nimport '@/pdp/components/Overlay/Overlay.css';\n\nexport interface OverlayProps extends HTMLAttributes<HTMLDivElement> {\n centered?: boolean;\n onClose?: () => void;\n}\n\nexport const Overlay: FunctionComponent<OverlayProps> = ({\n centered,\n onClose,\n className,\n children,\n ...props\n}) => {\n // i18n\n const CloseLabel = useText('PDP.Overlay.Close.label').label;\n const overlayRef = useRef<HTMLInputElement>(null);\n const handleOnClose = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n // Close on ESC\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handleOnClose();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleOnClose]);\n\n // Prevent document scrolling\n useEffect(() => {\n const input = overlayRef.current;\n input?.focus();\n\n const scrollingElement = document.scrollingElement as HTMLElement;\n\n const defaultOverflowValue = scrollingElement.style.overflow;\n\n scrollingElement.style.overflow = 'hidden';\n\n return () => {\n scrollingElement.style.overflow = defaultOverflowValue;\n };\n }, []);\n\n return (\n <div\n {...props}\n className={classes([\n 'pdp-overlay',\n ['pdp-overlay--centered', centered],\n className,\n ])}\n ref={overlayRef}\n role=\"dialog\"\n aria-describedby=\"overlay-content\"\n tabindex={0}\n >\n <div className=\"pdp-overlay__content\" id=\"overlay-content\">\n {children}\n </div>\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-overlay__close-button\"\n onClick={handleOnClose}\n icon={<CloseSVG />}\n />\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 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 */\nimport { cloneElement, FunctionComponent, VNode } from 'preact';\nimport {\n Children,\n useEffect,\n useState,\n useRef,\n useCallback,\n} from 'preact/compat';\n\nimport '@/pdp/components/Zoom/Zoom.css';\nimport { Button } from '@adobe-commerce/elsie/components';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nexport interface ZoomProps {\n children: VNode[] | VNode;\n scale?: number;\n closeButton?: boolean;\n}\n\nexport const Zoom: FunctionComponent<ZoomProps> = ({\n children,\n scale = 2.0,\n closeButton = true,\n}) => {\n const [zoomed, setZoomed] = useState(false);\n const [figureClassName, setFigureClassName] = useState('pdp-zoom');\n const [drag, setDrag] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 });\n const [position, setPosition] = useState({ x: 0, y: 0 });\n\n const containerRef = useRef<HTMLElement>(null);\n const cachedBoundsRef = useRef<DOMRect | null>(null);\n const animationFrameRef = useRef<number | null>(null);\n const lastTransformRef = useRef<string>('none');\n\n const touchStartRef = useRef<{ x: number; y: number; time: number } | null>(\n null\n );\n const isSwipingRef = useRef<boolean>(false);\n const lastValidTouchRef = useRef<{ clientX: number; clientY: number } | null>(\n null\n );\n\n const updatePosition = useCallback(\n (event: MouseEvent | TouchEvent) => {\n const updatePositionLogic = () => {\n let zoomer: DOMRect;\n\n if (cachedBoundsRef.current && containerRef.current) {\n zoomer = cachedBoundsRef.current;\n } else if (containerRef.current) {\n zoomer = containerRef.current.getBoundingClientRect();\n cachedBoundsRef.current = zoomer;\n } else {\n zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n }\n\n const overlap = (100 - 100 / scale) / 2;\n let coordinates: { clientX: number; clientY: number } | null = null;\n\n if ('touches' in event) {\n if (event.touches.length > 0) {\n coordinates = event.touches[0];\n lastValidTouchRef.current = {\n clientX: coordinates.clientX,\n clientY: coordinates.clientY,\n };\n } else if (event.type === 'touchend' && touchStartRef.current) {\n coordinates = {\n clientX: touchStartRef.current.x,\n clientY: touchStartRef.current.y,\n };\n } else if (lastValidTouchRef.current) {\n coordinates = lastValidTouchRef.current;\n } else {\n return;\n }\n } else if (event instanceof MouseEvent) {\n coordinates = event;\n } else {\n return;\n }\n\n const relativeX =\n ((coordinates.clientX - zoomer.left) / zoomer.width) * 100;\n const relativeY =\n ((coordinates.clientY - zoomer.top) / zoomer.height) * 100;\n\n const x = ((50 - relativeX) * (scale - 1)) / scale;\n const y = ((50 - relativeY) * (scale - 1)) / scale;\n\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n };\n\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') {\n updatePositionLogic();\n } else {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n animationFrameRef.current = requestAnimationFrame(updatePositionLogic);\n }\n },\n [scale]\n );\n\n useEffect(() => {\n cachedBoundsRef.current = null;\n }, [zoomed]);\n\n const startDrag = (event: TouchEvent) => {\n if (!zoomed || event.type !== 'touchstart') return;\n setDragStart({ x: event.touches[0].clientX, y: event.touches[0].clientY });\n setDragStartPosition({ x: position.x, y: position.y });\n setDrag(true);\n };\n\n const dragMove = (event: TouchEvent) => {\n if (!drag || event.type !== 'touchmove') return;\n const zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n const overlap = (100 - 100 / scale) / 2;\n const movedX = event.touches[0].clientX - dragStart.x;\n const movedY = event.touches[0].clientY - dragStart.y;\n const movedXPercent = (movedX * 100) / (zoomer.width * scale);\n const movedYPercent = (movedY * 100) / (zoomer.height * scale);\n const x = dragStartPosition.x + movedXPercent;\n const y = dragStartPosition.y + movedYPercent;\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n event.preventDefault();\n };\n\n const handleTouchStart = (event: TouchEvent) => {\n if (closeButton) {\n touchStartRef.current = {\n x: event.touches[0].clientX,\n y: event.touches[0].clientY,\n time: Date.now(),\n };\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n isSwipingRef.current = false;\n\n if (zoomed) {\n startDrag(event);\n }\n } else {\n if (drag) return;\n\n !zoomed && updatePosition(event);\n\n setZoomed(!zoomed);\n\n event.preventDefault();\n }\n };\n\n const handleTouchMove = (event: TouchEvent) => {\n if (event.touches.length === 0) return;\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n if (drag) {\n dragMove(event);\n return;\n }\n\n const touchX = event.touches[0].clientX;\n const touchY = event.touches[0].clientY;\n const deltaX = Math.abs(touchX - touchStartRef.current.x);\n const deltaY = Math.abs(touchY - touchStartRef.current.y);\n\n if (deltaX > 10 || deltaY > 10) {\n isSwipingRef.current = true;\n }\n }\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleTouchEnd = (event: TouchEvent) => {\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n const tapDuration = Date.now() - touchStartRef.current.time;\n\n if (!isSwipingRef.current && tapDuration < 300 && !drag) {\n setZoomed(true);\n updatePosition(event);\n event.preventDefault();\n }\n\n setDrag(false);\n touchStartRef.current = null;\n } else {\n setZoomed(false);\n }\n };\n\n const handleClick = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (drag) return;\n\n if (zoomed) {\n !closeButton && setZoomed(false);\n } else {\n setZoomed(true);\n updatePosition(event);\n }\n event.preventDefault();\n };\n\n const handleMove = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleLeave = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (closeButton) {\n setDrag(false);\n return;\n }\n setZoomed(false);\n };\n\n const closeButtonClick = (event: MouseEvent | TouchEvent) => {\n setZoomed(false);\n event.stopPropagation();\n };\n\n const transformStyle = zoomed\n ? `scale(${scale}) translateX(${position.x}%) translateY(${position.y}%)`\n : 'none';\n\n const CloseLabel = useText('PDP.Zoom.Close.label').label;\n const child = Children.only(children) as any;\n\n useEffect(() => {\n const handleGalleryChange = () => {\n if (zoomed) {\n setZoomed(false);\n setPosition({ x: 0, y: 0 });\n setDrag(false);\n }\n };\n\n const gallery = document.querySelector('#gallery');\n if (gallery) {\n gallery.addEventListener('click', handleGalleryChange);\n return () => gallery.removeEventListener('click', handleGalleryChange);\n }\n }, [zoomed]);\n\n const ImageClone = cloneElement(child, {\n ...child.props,\n draggable: false,\n style: {\n ...child.props?.style,\n '--transform': transformStyle,\n },\n });\n\n useEffect(() => {\n const className = zoomed\n ? `pdp-zoom ${closeButton ? 'pdp-zoom--no-effects' : 'pdp-zoom--zoomed'}`\n : 'pdp-zoom';\n setFigureClassName(className);\n }, [zoomed, closeButton]);\n\n useEffect(() => {\n if (lastTransformRef.current === transformStyle) return;\n lastTransformRef.current = transformStyle;\n\n const updateTransforms = () => {\n if (!containerRef.current) return;\n\n const images = containerRef.current.querySelectorAll('img');\n images.forEach((img) => {\n if (zoomed && transformStyle !== 'none') {\n img.style.setProperty('transform', transformStyle, 'important');\n } else {\n img.style.removeProperty('transform');\n }\n });\n };\n\n requestAnimationFrame(updateTransforms);\n }, [transformStyle, zoomed]);\n\n useEffect(() => {\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n };\n }, []);\n\n return (\n <figure\n ref={containerRef}\n className={figureClassName}\n onClick={handleClick}\n onMouseMove={handleMove}\n onMouseLeave={handleLeave}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {ImageClone}\n {closeButton && zoomed && (\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-zoom__close-button\"\n icon={<CloseSVG />}\n onClick={closeButtonClick}\n />\n )}\n </figure>\n );\n};\n"],"names":["SvgChevronDown","props","React","SvgClose","PEAK_WIDTH","THUMB_GAP","ICON_SIZE","GapSize","Carousel","show","scrollbar","peak","arrows","controls","arrowsOnMainImage","loop","gap","direction","width","height","defaultIndex","className","children","thumbnails","isZoomed","Label","useText","SlideLabel","PreviousLabel","NextLabel","ControlsLabel","ControlsBtnLabel","perPage","setPerPage","useState","getPerPageFromBreakpoint","length","Children","peakWidth","gapWidth","rest","current","setCurrent","isRTL","thumbnailsRefs","useRef","thumbWidth","setThumbWidth","thumbHeight","setThumbHeight","thumbnailSlides","useMemo","slides","returnValue","acc","child","i","wrapperRef","thumbnailsWrapperRef","thumbnailControls","useEffect","wrapper","handleResize","debounce","newPerPage","observer","handleThumbnailsScroll","useCallback","nextSlideIndex","nextItem","thumbnailRef","oneItemWidth","oneItemHeight","thumbnailsWrapper","isRow","isColumn","offset","oneItemSize","visibleThumbnails","centerOffset","targetScrollPosition","handleScrollTo","smooth","reset","realWidth","element","dataIndex","futureIndex","scrollWidth","diff","handleGoToPrev","handleGoToNext","lastSlideIndex","handleKeyDown","event","useLayoutEffect","handleOnScroll","dividing","totalWidth","scrollOffset","getArrow","forThumbnails","callback","jsx","Button","classes","Icon","ChevronDown","prevArrow","nextArrow","prevArrowMainImage","nextArrowMainImage","jsxs","page","index","orphan","Fragment","_","key","buttonsLength","active","el","breakpoints","small","medium","large","matchingBreakpoint","breakpoint","Overlay","centered","onClose","CloseLabel","overlayRef","handleOnClose","input","scrollingElement","defaultOverflowValue","CloseSVG","Zoom","scale","closeButton","zoomed","setZoomed","figureClassName","setFigureClassName","drag","setDrag","dragStart","setDragStart","dragStartPosition","setDragStartPosition","position","setPosition","containerRef","cachedBoundsRef","animationFrameRef","lastTransformRef","touchStartRef","isSwipingRef","lastValidTouchRef","updatePosition","updatePositionLogic","zoomer","_a","overlap","coordinates","relativeX","relativeY","x","y","startDrag","dragMove","movedX","movedY","movedXPercent","movedYPercent","handleTouchStart","handleTouchMove","touchX","touchY","deltaX","deltaY","handleTouchEnd","tapDuration","handleClick","handleMove","handleLeave","closeButtonClick","transformStyle","handleGalleryChange","gallery","ImageClone","cloneElement","img"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*! Copyright 2025 Adobe
|
|
2
|
+
All Rights Reserved. */
|
|
3
|
+
import{merge as ce,Initializer as fe}from"@dropins/tools/lib.js";import{events as H}from"@dropins/tools/event-bus.js";import{PRODUCT_FRAGMENT as ie}from"../fragments.js";import{FetchGraphQL as Pe}from"@dropins/tools/fetch-graphql.js";import{s as de,a as he}from"./isProductConfigurationValid.js";function Xe(e){const r=new URLSearchParams(window.location.search);Object.entries(e).forEach(([n,t])=>{t===null?r.delete(n):r.set(n,String(t))});let i=window.location.pathname;i+=`?${r.toString()}`,i+=window.location.hash,window.history.replaceState({},"",i)}function se(){const e=new URLSearchParams(window.location.search),r={};return e.forEach((i,n)=>{r[n]=i}),r}function ye(e=1){const i=(se()||{}).quantity;if(i){const n=parseInt(i,10);if(!isNaN(n)&&Number.isInteger(n)&&n>0)return n}return e}function ge(e){var r,i,n,t,s,a,l,o,m,u,c,f;return{productId:Number(e==null?void 0:e.externalId),name:e==null?void 0:e.name,sku:(e==null?void 0:e.variantSku)||(e==null?void 0:e.sku),topLevelSku:e==null?void 0:e.sku,specialToDate:void 0,specialFromDate:void 0,newToDate:void 0,newFromDate:void 0,createdAt:void 0,updatedAt:void 0,manufacturer:void 0,countryOfManufacture:void 0,categories:void 0,productType:e==null?void 0:e.productType,pricing:{regularPrice:((i=(r=e==null?void 0:e.prices)==null?void 0:r.regular)==null?void 0:i.amount)||0,minimalPrice:(t=(n=e==null?void 0:e.prices)==null?void 0:n.final)==null?void 0:t.minimumAmount,maximalPrice:(a=(s=e==null?void 0:e.prices)==null?void 0:s.final)==null?void 0:a.maximumAmount,specialPrice:(o=(l=e==null?void 0:e.prices)==null?void 0:l.final)==null?void 0:o.amount,tierPricing:void 0,currencyCode:((u=(m=e==null?void 0:e.prices)==null?void 0:m.final)==null?void 0:u.currency)||"USD"},canonicalUrl:e==null?void 0:e.url,mainImageUrl:(f=(c=e==null?void 0:e.images)==null?void 0:c[0])==null?void 0:f.url}}const ae={PRODUCT_CONTEXT:"productContext",CHANNEL_CONTEXT:"channelContext"},we={PRODUCT_PAGE_VIEW:"product-page-view"};function oe(){return window.adobeDataLayer=window.adobeDataLayer||[],window.adobeDataLayer}function Ce(){return{_id:"https://ns.adobe.com/xdm/channels/web",_type:"https://ns.adobe.com/xdm/channel-types/web"}}function ue(e,r){const i=oe();i.push({[e]:null}),i.push({[e]:r})}function xe(){typeof window>"u"||ue(ae.CHANNEL_CONTEXT,Ce())}function De(e,r){oe().push(n=>{const t=n.getState?n.getState():{};n.push({event:e,eventInfo:{...t,...r}})})}function Te(e){const r=ge(e);ue(ae.PRODUCT_CONTEXT,r),xe(),De(we.PRODUCT_PAGE_VIEW)}var X=(e=>(e.ComplexProduct="complex",e.SimpleProduct="simple",e))(X||{}),le=(e=>(e.ComplexProductView="ComplexProductView",e.SimpleProductView="SimpleProductView",e))(le||{});function K(e,r){var a,l,o,m,u,c,f,d,h,g,P,_;const i=((m=(o=(l=(a=e==null?void 0:e.options)==null?void 0:a[0])==null?void 0:l.values)==null?void 0:o[0])==null?void 0:m.__typename)==="ProductViewOptionValueProduct",n=Ae(e,i,r==null?void 0:r.preselectFirstOption),t=(e==null?void 0:e.__typename)===le.SimpleProductView?X.SimpleProduct:X.ComplexProduct,s=e?{name:e.name,sku:e.sku,isBundle:i,addToCartAllowed:e.addToCartAllowed,inStock:e.inStock,shortDescription:e.shortDescription,metaDescription:e.metaDescription,metaKeyword:e.metaKeyword,metaTitle:e.metaTitle,description:e.description,images:Oe(e),prices:ke(e,i,n),attributes:Ee(e),options:Se(e,i),optionUIDs:n,url:e.url,urlKey:e.urlKey,externalId:e.externalId,externalParentId:e.externalParentId,variantSku:e.variantSku,productType:t}:null;return ce(s,((d=(f=(c=(u=p.getConfig())==null?void 0:u.models)==null?void 0:c.ProductDetails)==null?void 0:f.transformer)==null?void 0:d.call(f,e))??((_=(P=(g=(h=p.getConfig())==null?void 0:h.models)==null?void 0:g.ProductDetails)==null?void 0:P.transform)==null?void 0:_.call(P,e)))}function Oe(e){var r,i;return(i=(r=e.images)==null?void 0:r.filter(n=>{var t;return!((t=n.roles)!=null&&t.includes("hide_from_pdp"))}))==null?void 0:i.map(n=>(n.url=n.url.replace(/^https?:/,""),n))}function Ee(e){var r,i;return(i=(r=e.attributes)==null?void 0:r.filter(({roles:n})=>(n==null?void 0:n.indexOf("visible_in_pdp"))!==-1))==null?void 0:i.map(({label:n,value:t,name:s})=>{if(s==="ac_giftcard")try{const a=JSON.parse(t.toString()),l=j(a);return{id:s,label:n,value:JSON.stringify(l)}}catch{return{id:s,label:n,value:t.toString().split(",").join(", ")}}return{id:s,label:n,value:t.toString().split(",").join(", ")}})}function j(e){if(Array.isArray(e))return e.map(j);if(e!==null&&typeof e=="object"){const r={};for(const[i,n]of Object.entries(e)){let t=i;i==="validation_rule"?t="validationRule":i==="min_length"?t="minLength":i==="max_length"&&(t="maxLength"),r[t]=j(n)}return r}return e}function Se(e,r){const{options:i,optionUIDs:n}=e;return i==null?void 0:i.map(({id:t,title:s,required:a,multi:l,values:o})=>{var c;const m=(c=o==null?void 0:o[0])==null?void 0:c.__typename;let u=o==null?void 0:o[0].type;return u?u=u.replace("COLOR_HEX","color").replace("TEXT","text").replace("IMAGE","image"):u="dropdown",{id:t,type:u,typename:m,label:s,required:a,multiple:l,items:r?pe(o,n):_e(o,n,u)}})}function pe(e,r){return e==null?void 0:e.filter(({enabled:i})=>typeof i>"u"||i).map(({id:i,title:n,inStock:t,isDefault:s,product:a})=>({id:i,inStock:t,label:n,selected:(r==null?void 0:r.indexOf(i))>-1||s,value:i,product:a}))}function _e(e,r,i){return e==null?void 0:e.map(({id:n,title:t,inStock:s,value:a})=>({id:n,inStock:s,label:t,selected:(r==null?void 0:r.indexOf(n))>-1,value:(i==null?void 0:i.toLowerCase())==="dropdown"?n:a==null?void 0:a.replace(/^https?:/,"")}))}function ke(e,r,i){var P,_,B,z,J;const{price:n,priceRange:t,options:s,optionUIDs:a=i}=e;let{__typename:l}=e;function o(){var D;const C=n==null?void 0:n.regular.amount.value,y=((D=n==null?void 0:n.final)==null?void 0:D.amount.value)??(n==null?void 0:n.regular.amount.value),x=(n==null?void 0:n.regular.amount.currency)==="NONE"?"USD":n==null?void 0:n.regular.amount.currency;return[C,y,y,x]}function m(){var O,E,k,A,b,U,N,I,v,F,V,L;const C=(O=t==null?void 0:t.minimum)==null?void 0:O.final.amount.value,y=(E=t==null?void 0:t.maximum)==null?void 0:E.final.amount.value;let x;((A=(k=t==null?void 0:t.minimum)==null?void 0:k.regular)==null?void 0:A.amount.value)===((U=(b=t==null?void 0:t.maximum)==null?void 0:b.regular)==null?void 0:U.amount.value)&&(x=(I=(N=t==null?void 0:t.minimum)==null?void 0:N.regular)==null?void 0:I.amount.value);const D=((F=(v=t==null?void 0:t.minimum)==null?void 0:v.final)==null?void 0:F.amount.currency)==="NONE"?"USD":(L=(V=t==null?void 0:t.minimum)==null?void 0:V.final)==null?void 0:L.amount.currency;return[x,C,y,D]}function u(){var k,A,b,U,N,I,v,F,V,L,W,Y,Z;let C=0,y=0;s==null||s.forEach(S=>{var R;const Q=S==null?void 0:S.values;if(Q&&Array.isArray(Q)){const T=Q.map(w=>{var G,M,ee,te;return(te=(ee=(M=(G=w==null?void 0:w.product)==null?void 0:G.price)==null?void 0:M.regular)==null?void 0:ee.amount)==null?void 0:te.value}).filter(w=>w!==void 0),$=T.length>0?Math.max(...T):0;C+=$}(R=S==null?void 0:S.values)==null||R.forEach(T=>{var $,w,G,M;a!=null&&a.includes(T.id)&&(y+=(M=(G=(w=($=T==null?void 0:T.product)==null?void 0:$.price)==null?void 0:w.final)==null?void 0:G.amount)==null?void 0:M.value)})});const x=(k=t==null?void 0:t.minimum)==null?void 0:k.final.amount.value,D=(A=t==null?void 0:t.maximum)==null?void 0:A.final.amount.value;let O;((U=(b=t==null?void 0:t.minimum)==null?void 0:b.regular)==null?void 0:U.amount.value)===((I=(N=t==null?void 0:t.maximum)==null?void 0:N.regular)==null?void 0:I.amount.value)&&(O=(F=(v=t==null?void 0:t.minimum)==null?void 0:v.regular)==null?void 0:F.amount.value);const E=((L=(V=t==null?void 0:t.minimum)==null?void 0:V.final)==null?void 0:L.amount.currency)==="NONE"?"USD":(Y=(W=t==null?void 0:t.minimum)==null?void 0:W.final)==null?void 0:Y.amount.currency;return r&&(a==null?void 0:a.length)<1?[O,x,D,E]:C===((Z=t==null?void 0:t.maximum)==null?void 0:Z.regular.amount.value)?[y,y,y,E]:[O,x,D,E]}const[c,f,d,h]=l==="SimpleProductView"?o():r?u():m(),g=l==="SimpleProductView"?(P=n==null?void 0:n.roles)==null?void 0:P.includes("visible"):((B=(_=t==null?void 0:t.maximum)==null?void 0:_.roles)==null?void 0:B.includes("visible"))&&((J=(z=t==null?void 0:t.minimum)==null?void 0:z.roles)==null?void 0:J.includes("visible"));return d&&f===d?{regular:{amount:c,currency:h,variant:c&&f!==c?"strikethrough":"default"},final:{amount:d,currency:h,variant:"default"},visible:g}:{final:{minimumAmount:f,maximumAmount:d,currency:h},visible:g}}function Ae(e,r,i){var n;return r?((n=e==null?void 0:e.options)==null?void 0:n.map(({values:s})=>{var o;const a=((o=s==null?void 0:s.find(({isDefault:m})=>m))==null?void 0:o.id)??null,l=i?s[0].id:null;return a||l})).filter(s=>s!==null):e==null?void 0:e.optionUIDs}const q=new fe({init:async e=>{var l,o,m;const r=(o=(l=e==null?void 0:e.models)==null?void 0:l.ProductDetails)==null?void 0:o.initialData,n=((m=(se()||{}).optionsUIDs)==null?void 0:m.split(","))||(r==null?void 0:r.optionsUIDs),t=ye(1),a={...{defaultLocale:"en-US",persistURLParams:!1,acdl:!1,optionsUIDs:n},...e};if(q.config.setConfig({...a}),a!=null&&a.sku){const u=r?K(r):await re(a.sku,{preselectFirstOption:a.preselectFirstOption});H.emit("pdp/data",u,{scope:a.scope});const c={sku:a.sku,quantity:t,optionsUIDs:u==null?void 0:u.optionUIDs};de(()=>({...c}),{scope:a.scope}),he(()=>{var f;return u!=null&&u.options?u.options.length===((f=u==null?void 0:u.optionUIDs)==null?void 0:f.length):!0},{scope:a.scope}),a.acdl&&u&&Te(u)}},listeners:()=>[H.on("locale",async()=>{const{sku:e,scope:r}=q.config.getConfig();if(e){const i=await re(e);H.emit("pdp/data",i,{scope:r})}})]}),p=q.config,{setEndpoint:je,setFetchGraphQlHeader:qe,removeFetchGraphQlHeader:Ke,setFetchGraphQlHeaders:Be,getFetchGraphQlHeader:ze,fetchGraphQl:me,getConfig:Je}=new Pe().getMethods(),be=`
|
|
4
|
+
query GET_PRODUCT_DATA($skus: [String]) {
|
|
5
|
+
products(skus: $skus) {
|
|
6
|
+
...PRODUCT_FRAGMENT
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
${ie}
|
|
11
|
+
`,Ue=async(e,r,i)=>{var s;const{data:n}=await me(be,{method:"GET",variables:{skus:[e]}}),t=(s=n==null?void 0:n.products)==null?void 0:s[0];return r!=null&&r.optionsUIDs&&(t.optionUIDs=r.optionsUIDs),t?i?t:K(t,{preselectFirstOption:r==null?void 0:r.preselectFirstOption}):null},Ne=`
|
|
12
|
+
query REFINE_PRODUCT_QUERY(
|
|
13
|
+
$optionIds: [String!]!
|
|
14
|
+
$sku: String!
|
|
15
|
+
) {
|
|
16
|
+
# Refined Product
|
|
17
|
+
refineProduct(
|
|
18
|
+
optionIds: $optionIds
|
|
19
|
+
sku: $sku
|
|
20
|
+
) {
|
|
21
|
+
...PRODUCT_FRAGMENT
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Parent Product
|
|
25
|
+
products(skus: [$sku]) {
|
|
26
|
+
...PRODUCT_FRAGMENT
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
# %extendedPlaceholder%
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
${ie}
|
|
33
|
+
`;async function ne(e,r){const i=ve(r),n=Fe(i,e),t=Ne.replace("# %extendedPlaceholder%",n),{data:s}=await me(t,{method:"GET",variables:{optionIds:r,sku:e}});return s}const Ie=async(e,r,i,n)=>{var d,h,g;const t=await ne(e,r);if(!t)return null;let{products:s,refineProduct:a,...l}=t;const o=s==null?void 0:s[0],m=Ve(Object.values(l),o.options,i);if(i!=null&&i.length&&a===null){r=Le(m,r,i);const P=await ne(e,r);a=P==null?void 0:P.refineProduct}const u={...a||o,sku:o.sku,name:o.name,externalParentId:o==null?void 0:o.externalId,options:m,optionUIDs:r,variantSku:(a==null?void 0:a.__typename)==="SimpleProductView"?a==null?void 0:a.sku:void 0},c=n?u:K(u),f=(g=(h=(d=p==null?void 0:p.getConfig())==null?void 0:d.models)==null?void 0:h.ProductDetails)==null?void 0:g.fallbackData;return f?f(o,c):c};function ve(e){if(e.length<2)return[e];const r=[];return e.forEach(i=>{const n=[];e.forEach(t=>{i!==t&&n.push(t)}),r.push(n)}),r}function Fe(e,r){return e.map((i,n)=>`
|
|
34
|
+
ProductOption${n}: refineProduct(
|
|
35
|
+
optionIds: [
|
|
36
|
+
${i.map(t=>`"${t}"`).join(", ")}
|
|
37
|
+
]
|
|
38
|
+
sku: "${r}"
|
|
39
|
+
) {
|
|
40
|
+
... on ComplexProductView {
|
|
41
|
+
options {
|
|
42
|
+
...PRODUCT_OPTION_FRAGMENT
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
`).join("")}function Ve(e,r=[],i){const n=Object.values(e).filter(s=>!!s).reduce((s,a)=>a.options?[...s,...a.options]:[...s],[]),t=new Map(r.map(s=>[s.id,s]));return n.forEach(s=>{i!=null&&i.includes(s.id)||t.set(s.id,s)}),[...t.values()]}function Le(e,r,i){const n=[];let t;return e.forEach(s=>{var a,l,o,m;i.includes(s.id)?t=((l=(a=s.values)==null?void 0:a.find(u=>r.includes(u==null?void 0:u.id)))==null?void 0:l.id)||((o=s.values[0])==null?void 0:o.id):t=(m=s.values[0])==null?void 0:m.id,n.push(t)}),n}const re=async(e,r)=>{const{anchors:i,optionsUIDs:n}=p.getConfig(),{optionsUIDs:t=n,anchors:s=i,preselectFirstOption:a,isBundle:l,skipTransform:o}=r??{};return!l&&t?await Ie(e,t,s,o):await Ue(e,{preselectFirstOption:a,optionsUIDs:t},o)};export{qe as a,Be as b,p as c,Je as d,Ue as e,me as f,ze as g,Ie as h,q as i,re as j,ye as k,Xe as l,Te as p,Ke as r,je as s,K as t};
|
|
47
|
+
//# sourceMappingURL=fetchProductData.js.map
|