@lockerverse/react 0.2.22 → 0.2.24

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/README.md CHANGED
@@ -37,7 +37,10 @@ export function Checkout() {
37
37
 
38
38
  For development, provide both `environment="development"` and `apiBaseUrl`.
39
39
  The component supports dark and light themes, an accent color, CSS variables,
40
- and host CSS. It intentionally does not render Product selection.
40
+ and host CSS. It intentionally does not render Product selection. When enabled
41
+ by the widget, customers can change the tip and service-fee contribution in the
42
+ payment form; the displayed total is updated by the Lockerverse backend and
43
+ Stripe Checkout before confirmation.
41
44
 
42
45
  The package uses Stripe's React Checkout Elements directly. React, React DOM,
43
46
  and Stripe libraries are peer dependencies, so consuming applications do not
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CreateLockerverseWidgetOptions, LockerverseCatalog, LockerverseCustomFieldAnswer } from "@lockerverse/sdk/checkout";
1
+ import { CreateLockerverseWidgetOptions, LockerverseCatalog, LockerverseCheckoutSessionPricing, LockerverseCustomFieldAnswer } from "@lockerverse/sdk/checkout";
2
2
  import { loadStripe } from "@stripe/stripe-js/pure/index.js";
3
3
  import { CSSProperties, ComponentPropsWithoutRef, PropsWithChildren } from "react";
4
4
  //#region src/types.d.ts
@@ -25,9 +25,13 @@ type LockerversePaymentStyle = CSSProperties & {
25
25
  "--lockerverse-bg"?: string;
26
26
  "--lockerverse-border"?: string;
27
27
  "--lockerverse-control"?: string;
28
+ "--lockerverse-danger"?: string;
29
+ "--lockerverse-danger-border"?: string;
28
30
  "--lockerverse-font-family"?: string;
29
31
  "--lockerverse-muted"?: string;
32
+ "--lockerverse-placeholder"?: string;
30
33
  "--lockerverse-radius"?: string;
34
+ "--lockerverse-subtle"?: string;
31
35
  "--lockerverse-text"?: string;
32
36
  };
33
37
  type LockerversePaymentProps = CreateLockerverseWidgetOptions & Omit<ComponentPropsWithoutRef<"section">, "children" | "onError"> & {
@@ -63,13 +67,25 @@ type CheckoutContextValue = {
63
67
  memberId?: string;
64
68
  merchSize?: "XS" | "S" | "M" | "L" | "XL" | "XXL" | "XXXL";
65
69
  phone?: string;
70
+ shippingMatchesBilling?: boolean;
66
71
  }) => Promise<LockerversePaymentCompletion>;
67
72
  paymentReference: string;
73
+ pricing: {
74
+ includeServiceFee: boolean;
75
+ serviceFeeAmountCents: number;
76
+ subtotalCents: number;
77
+ tipCents: number;
78
+ };
68
79
  totalCents: number;
80
+ updatePricing: (input: {
81
+ includeServiceFee: boolean;
82
+ tipCents: number;
83
+ }) => Promise<LockerverseCheckoutSessionPricing>;
69
84
  };
70
85
  declare function LockerverseCheckoutSessionProvider(props: LockerverseCheckoutSessionProviderProps): import("react").JSX.Element;
71
86
  declare function useLockerverseCheckoutSession(): CheckoutContextValue;
72
- declare function LockerverseCheckoutSessionPaymentForm({ onComplete }: {
87
+ declare function LockerverseCheckoutSessionPaymentForm({ branding, onComplete }: {
88
+ branding?: LockerversePaymentBranding;
73
89
  onComplete?: (result: LockerversePaymentCompletion) => void;
74
90
  }): import("react").JSX.Element;
75
91
  declare function LockerversePayment(props: LockerversePaymentProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/checkout-session-payment.tsx"],"mappings":";;;;KAIY;EACN;EAAqB;;EACrB;EAAqB;;KAEf;KAEA;EACV;EACA;EACA;;KAGU;EACV;EACA;;KAGU,0BAA0B;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,0BAA0B,iCACpC,KAAK;EACH,WAAW;EACX;EACA,qBAAqB,QAAQ;EAC7B;EACA,WAAW;EACX,+BAA+B;EAC/B,QAAQ;EACR,QAAQ;EACR;;;;KCRC,qCAAqC;KAE9B,0CACV,iCACE;EACE;EACA;EACA;EACA;EACA,WAAW;EACX,wBAAwB;EACxB;EACA;;KAUD;EACH,iBAAiB,sBAAsB;EACvC,SAAS;EACT,UAAU;IACR,qBAAqB;IACrB;IACA;IACA;IACA;QACI,QAAQ;EACd;EACA;;iBAqHc,mCACd,OAAO,0DAAuC,IAAA;iBA8KhC,iCAA6B;iBAyI7B,wCACd;EAEA,cAAc,QAAQ;oBACvB,IAAA;iBAiMe,mBAAmB,OAAO,0CAAuB,IAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/checkout-session-payment.tsx"],"mappings":";;;;KAIY;EACN;EAAqB;;EACrB;EAAqB;;KAEf;KAEA;EACV;EACA;EACA;;KAGU;EACV;EACA;;KAGU,0BAA0B;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,0BAA0B,iCACpC,KAAK;EACH,WAAW;EACX;EACA,qBAAqB,QAAQ;EAC7B;EACA,WAAW;EACX,+BAA+B;EAC/B,QAAQ;EACR,QAAQ;EACR;;;;KCFC,qCAAqC;KAE9B,0CACV,iCACE;EACE;EACA;EACA;EACA;EACA,WAAW;EACX,wBAAwB;EACxB;EACA;;KAaD;EACH,iBAAiB,sBAAsB;EACvC,SAAS;EACT,UAAU;IACR,qBAAqB;IACrB;IACA;IACA;IACA;IACA;QACI,QAAQ;EACd;EACA;IACE;IACA;IACA;IACA;;EAEF;EACA,gBAAgB;IACd;IACA;QACI,QAAQ;;iBAyRA,mCACd,OAAO,0DAAuC,IAAA;iBAkJhC,iCAA6B;iBA6F7B,wCACd,UACA;EAEA,WAAW;EACX,cAAc,QAAQ;oBACvB,IAAA;iBAuSe,mBAAmB,OAAO,0CAAuB,IAAA"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{createLockerverseCheckoutClient as e}from"@lockerverse/sdk/checkout";import{BillingAddressElement as t,CheckoutElementsProvider as n,PaymentElement as r,ShippingAddressElement as i,useCheckoutElements as a}from"@stripe/react-stripe-js/checkout";import{loadStripe as o}from"@stripe/stripe-js/pure/index.js";import{createContext as s,useContext as c,useEffect as l,useMemo as u,useRef as d,useState as f}from"react";import{jsx as p,jsxs as m}from"react/jsx-runtime";const h=s(null);function g(e,t){if(!t.length)throw Error(`Select at least one Product before opening checkout.`);return t.map(t=>{let n=e.products.find(e=>e.slug===t.productSlug);if(!n)throw Error(`Product ${t.productSlug} is unavailable.`);return`amountCents`in t?{amountCents:t.amountCents,productId:n.id}:{productId:n.id,quantity:t.quantity}})}function _(e){let t={communitySlug:e.communitySlug,...e.fetch?{fetch:e.fetch}:{},...e.onError?{onError:e.onError}:{},...e.requestTimeoutMs===void 0?{}:{requestTimeoutMs:e.requestTimeoutMs},...e.sentryDsn===void 0?{}:{sentryDsn:e.sentryDsn},widgetSlug:e.widgetSlug};return e.apiBaseUrl?{...t,apiBaseUrl:e.apiBaseUrl,environment:e.environment}:{...t,environment:`production`}}function v({children:e,loaded:t}){let n=a();if(n.type===`loading`)return p(`div`,{role:`status`,children:`Loading secure payment form…`});if(n.type===`error`)return p(`div`,{role:`alert`,children:n.error.message});let{checkout:r}=n,i={async applyPromoCode(e){let n=await r.runServerUpdate(()=>t.client.updateSessionDiscount({paymentReference:t.session.paymentReference,...e.trim()?{promoCode:e.trim()}:{}}));return n.type===`error`?n.error.message:null},catalog:t.catalog,async confirm(e){let n=await r.runServerUpdate(()=>t.client.updateSessionDetails({...e.customFieldAnswers?{customFieldAnswers:e.customFieldAnswers}:{},email:e.email,...e.memberId?{memberId:e.memberId}:{},...e.merchSize?{merchSize:e.merchSize}:{},paymentReference:t.session.paymentReference,...e.phone?{phone:e.phone}:{}}));if(n.type===`error`)throw Error(n.error.message);let i=await x(r,e.email,e.phone??``);if(`error`in i)throw Error(i.error);let a=await r.confirm({email:i.email,...i.phone?{phoneNumber:i.phone}:{},redirect:`if_required`});if(a.type===`error`)throw Error(a.error.message);return{paymentReference:t.session.paymentReference,sessionId:t.session.sessionId}},paymentReference:t.session.paymentReference,totalCents:r.total.total.minorUnitsAmount};return p(h.Provider,{value:i,children:e})}function y(t){let[r,i]=f(null),[a,s]=f(null),[c,h]=f(0),y=d(null),b=JSON.stringify({email:t.email,includeServiceFee:t.includeServiceFee,returnUrl:t.returnUrl,selection:t.selection,tipCents:t.tipCents}),x=d({email:t.email,includeServiceFee:t.includeServiceFee,key:b,requestKey:globalThis.crypto.randomUUID(),returnUrl:t.returnUrl,selection:t.selection,tipCents:t.tipCents}),S=u(()=>_(t),[t.apiBaseUrl,t.communitySlug,t.environment,t.fetch,t.onError,t.requestTimeoutMs,t.sentryDsn,t.widgetSlug]);l(()=>{let t=!0;if(y.current?.clientOptions!==S||c>0){let t=e(S),n=x.current;y.current={clientOptions:S,promise:(async()=>{let e=await t.load(),r=g(e,n.selection),i=n.includeServiceFee??e.widget.fields.serviceFee,a=await t.createSession({...n.email?{email:n.email}:{},...e.widget.fields.serviceFee?{includeServiceFee:i}:{},items:r,requestKey:n.requestKey,returnUrl:n.returnUrl,...n.tipCents===void 0?{}:{tipCents:n.tipCents}});return{catalog:e,client:t,returnUrl:n.returnUrl,session:a}})()}}return i(null),s(null),y.current.promise.then(e=>{t&&i(e)}).catch(e=>{t&&s(e instanceof Error?e.message:`Unable to load checkout.`)}),()=>{t=!1}},[S,c]);let C=u(()=>r?(t.unstable_stripeLoader??o)(r.catalog.payment.publishableKey,{betas:[`custom_checkout_server_updates_1`],...r.session.connectedAccountId?{stripeAccount:r.session.connectedAccountId}:{}}):null,[r,t.unstable_stripeLoader]),w=u(()=>r?{clientSecret:r.session.clientSecret,elementsOptions:{appearance:{theme:t.theme===`light`?`stripe`:`night`,variables:{colorBackground:`transparent`,colorPrimary:t.accentColor??`#38d77a`}}}}:null,[r,t.accentColor,t.theme]);return b===x.current.key?a?m(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:[p(`p`,{children:a}),p(`button`,{onClick:()=>h(e=>e+1),type:`button`,children:`Try again`})]}):r&&w?p(n,{options:w,stripe:C,children:p(v,{loaded:r,children:t.children})}):m(`div`,{className:`lockerverse-payment__loading`,children:[p(`span`,{className:`lockerverse-payment__sr-only`,role:`status`,children:`Preparing secure checkout…`}),m(`div`,{"aria-hidden":`true`,className:`lockerverse-payment__skeleton`,children:[p(`div`,{className:`lockerverse-payment__skeleton-contact`,children:m(`div`,{className:`lockerverse-payment__skeleton-field`,children:[p(`span`,{className:`lockerverse-payment__skeleton-label`}),p(`span`,{className:`lockerverse-payment__skeleton-input`})]})}),m(`div`,{className:`lockerverse-payment__skeleton-loader-block`,children:[p(`span`,{className:`lockerverse-payment__skeleton-loader-label`}),p(`span`,{className:`lockerverse-payment__skeleton-loader-full`})]}),p(`div`,{className:`lockerverse-payment__skeleton-actions`,children:p(`span`,{className:`lockerverse-payment__skeleton-button`})})]})]}):p(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:`Checkout selection changed. Remount this payment component for the new selection.`})}function b(){let e=c(h);if(!e)throw Error(`useLockerverseCheckoutSession must be used inside LockerverseCheckoutSessionProvider.`);return e}async function x(e,t,n){let r=t.trim().toLowerCase();if(!r)return{error:`Email is required.`};let i=await e.updateEmail(r);if(i.type===`error`)return{error:i.error.message};let a=n.trim();if(a&&(await e.updatePhoneNumber(a)).type===`error`)return{error:`Phone number is invalid.`};let o=await e.validateElements();return o.type===`error`?{error:o.error.message}:{email:r,phone:a}}function S({fields:e,onChange:t,values:n}){return e.map(e=>{let r=n[e.id]??(e.type.includes(`multi`)||e.type===`checkboxes`?[]:``);if(e.type===`textarea`)return m(`label`,{children:[p(`span`,{children:e.label}),p(`textarea`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,value:String(r)})]},e.id);if(e.type===`select`)return m(`label`,{children:[p(`span`,{children:e.label}),m(`select`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,value:String(r),children:[p(`option`,{value:``,children:`Select…`}),e.options.map(e=>p(`option`,{value:e.id,children:e.label},e.id))]})]},e.id);if(e.type===`radio`||e.type===`checkboxes`||e.type===`multi_select`){let n=Array.isArray(r)?r:[r];return m(`fieldset`,{children:[p(`legend`,{children:e.label}),e.options.map(r=>{let i=n.includes(r.id);return m(`label`,{className:`lockerverse-payment__choice`,children:[p(`input`,{checked:i,name:e.id,onChange:()=>{if(e.type===`radio`){t(e.id,r.id);return}t(e.id,i?n.filter(e=>e!==r.id):[...n,r.id])},required:e.required&&n.length===0,type:e.type===`radio`?`radio`:`checkbox`,value:r.id}),p(`span`,{children:r.label})]},r.id)})]},e.id)}return m(`label`,{children:[p(`span`,{children:e.label}),p(`input`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,type:`text`,value:String(r)})]},e.id)})}function C({onComplete:e}){let{applyPromoCode:n,catalog:a,confirm:o,totalCents:s}=b(),[c,l]=f(``),[u,d]=f(``),[h,g]=f(``),[_,v]=f(``),[y,x]=f({}),[C,w]=f(``),[T,E]=f(null),[D,O]=f(!1);async function k(){O(!0),E(null);try{E(await n(C))}catch(e){E(e instanceof Error?e.message:`Unable to update checkout.`)}finally{O(!1)}}async function A(t){t.preventDefault(),O(!0),E(null);try{e?.(await o({customFieldAnswers:a.widget.customFields.map(e=>({fieldId:e.id,value:y[e.id]??null})),email:c,...h?{memberId:h}:{},..._?{merchSize:_}:{},...u?{phone:u}:{}}))}catch(e){E(e instanceof Error?e.message:`Unable to complete checkout.`)}finally{O(!1)}}return m(`form`,{className:`lockerverse-payment__form`,onSubmit:A,children:[m(`header`,{children:[p(`h1`,{children:a.widget.title??a.widget.name}),a.widget.description?p(`p`,{children:a.widget.description}):null]}),m(`div`,{className:`lockerverse-payment__contact`,children:[m(`label`,{children:[p(`span`,{children:`Email`}),p(`input`,{autoComplete:`email`,inputMode:`email`,name:`email`,onChange:e=>l(e.currentTarget.value),placeholder:`you@example.com`,required:!0,type:`email`,value:c})]}),a.widget.fields.phone?m(`label`,{children:[p(`span`,{children:`Phone`}),p(`input`,{autoComplete:`tel`,inputMode:`tel`,name:`phone`,onChange:e=>d(e.currentTarget.value),placeholder:`+1 555 555 5555`,required:!0,type:`tel`,value:u})]}):null,a.widget.fields.memberId?m(`label`,{children:[p(`span`,{children:`Member ID`}),p(`input`,{name:`memberId`,onChange:e=>g(e.currentTarget.value),required:!0,type:`text`,value:h})]}):null,a.widget.fields.merchSize?m(`label`,{children:[p(`span`,{children:`Merch size`}),m(`select`,{name:`merchSize`,onChange:e=>v(e.currentTarget.value),required:!0,value:_,children:[p(`option`,{value:``,children:`Select…`}),[`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`].map(e=>p(`option`,{value:e,children:e},e))]})]}):null]}),m(`div`,{className:`lockerverse-payment__address`,children:[p(`h2`,{children:`Billing information`}),p(t,{})]}),a.widget.fields.shipping?m(`div`,{className:`lockerverse-payment__shipping`,children:[p(`h2`,{children:`Shipping information`}),p(i,{})]}):null,m(`div`,{className:`lockerverse-payment__stripe-element`,hidden:s===0,children:[p(`h2`,{children:`Payment details`}),p(r,{})]}),a.widget.fields.promoCode?m(`div`,{className:`lockerverse-payment__additional-fields`,children:[m(`label`,{children:[p(`span`,{children:`Promo code`}),p(`input`,{name:`promoCode`,onChange:e=>w(e.currentTarget.value),placeholder:`Optional`,value:C})]}),p(`button`,{disabled:D,onClick:k,type:`button`,children:C.trim()?`Apply code`:`Remove code`})]}):null,a.widget.customFields.length?p(`div`,{className:`lockerverse-payment__custom-fields`,children:p(S,{fields:a.widget.customFields,onChange:(e,t)=>x(n=>({...n,[e]:t})),values:y})}):null,T?p(`div`,{role:`alert`,children:T}):null,p(`div`,{className:`lockerverse-payment__actions`,children:p(`button`,{disabled:D,type:`submit`,children:s===0?`Complete free order`:`Pay $${(s/100).toFixed(2)}`})})]})}function w(e){let{apiBaseUrl:t,branding:n,className:r,communitySlug:i,environment:a,fetch:o,includeServiceFee:s,onError:c,onPaymentComplete:l,requestTimeoutMs:u,returnUrl:d,selection:f,sentryDsn:h,unstable_stripeLoader:g,style:_,theme:v=`dark`,tipCents:b,widgetSlug:x,...S}=e,w=d??(globalThis.location===void 0?`https://lockerverse.com`:globalThis.location.href),T=[`lockerverse-payment`,r].filter(Boolean).join(` `),E=t?{apiBaseUrl:t,communitySlug:i,environment:a,widgetSlug:x}:{communitySlug:i,environment:`production`,widgetSlug:x},D=n?.accentColor?{..._,"--lockerverse-accent":n.accentColor}:_;return m(`section`,{...S,className:T,"data-lockerverse-theme":v,style:D,children:[n?m(`div`,{className:`lockerverse-payment__branding`,children:[n.imageUrl?p(`img`,{alt:``,height:`48`,src:n.imageUrl,width:`48`}):null,p(`strong`,{children:n.name})]}):null,p(y,{...E,...n?.accentColor?{accentColor:n.accentColor}:{},...o?{fetch:o}:{},...s===void 0?{}:{includeServiceFee:s},...c?{onError:c}:{},...u===void 0?{}:{requestTimeoutMs:u},returnUrl:w,selection:f,...h===void 0?{}:{sentryDsn:h},...g?{unstable_stripeLoader:g}:{},theme:v,...b===void 0?{}:{tipCents:b},children:p(C,{...l?{onComplete:l}:{}})})]})}export{C as LockerverseCheckoutSessionPaymentForm,y as LockerverseCheckoutSessionProvider,w as LockerversePayment,b as useLockerverseCheckoutSession};
1
+ import{createLockerverseCheckoutClient as e}from"@lockerverse/sdk/checkout";import{BillingAddressElement as t,CheckoutElementsProvider as n,PaymentElement as r,ShippingAddressElement as i,useCheckoutElements as a}from"@stripe/react-stripe-js/checkout";import{loadStripe as o}from"@stripe/stripe-js/pure/index.js";import{createContext as s,useContext as c,useEffect as l,useMemo as u,useRef as d,useState as f}from"react";import{pipe as p,regex as m,safeParse as h,string as g}from"valibot";import{Fragment as _,jsx as v,jsxs as y}from"react/jsx-runtime";const b=/^#([\da-f]{3}|[\da-f]{6})$/i;function x(e){let t=b.exec(e.trim());if(!t)return;let[,n]=t;if(!n)return;let r=n.length===3?Array.from(n,e=>`${e}${e}`).join(``):n;return[0,2,4].map(e=>Number.parseInt(r.slice(e,e+2),16))}function S([e,t,n]){let[r=0,i=0,a=0]=[e,t,n].map((e=0)=>{let t=e/255;return t<=.04045?t/12.92:((t+.055)/1.055)**2.4});return .2126*r+.7152*i+.0722*a}function C(e){let t=x(e);if(!t)return;let n=S(t);return(n+.05)/.05>=1.05/(n+.05)?`#000`:`#fff`}const w=[{callingCode:`+1`,label:`🇺🇸 +1`,value:`US`},{callingCode:`+52`,label:`🇲🇽 +52`,value:`MX`},{callingCode:`+380`,label:`🇺🇦 +380`,value:`UA`},{callingCode:`+48`,label:`🇵🇱 +48`,value:`PL`},{callingCode:`+1`,label:`🇨🇦 +1`,value:`CA`},{callingCode:`+49`,label:`🇩🇪 +49`,value:`DE`},{callingCode:`+44`,label:`🇬🇧 +44`,value:`GB`},{callingCode:`+46`,label:`🇸🇪 +46`,value:`SE`},{callingCode:`+358`,label:`🇫🇮 +358`,value:`FI`},{callingCode:`+1`,label:`🇵🇷 +1`,value:`PR`}],T=[{label:`15%`,percent:15,value:`15`},{label:`12%`,percent:12,value:`12`},{label:`10%`,percent:10,value:`10`},{label:`5%`,percent:5,value:`5`},{label:`Other`,percent:null,value:`custom`}];function E({label:e}){return y(`div`,{className:`lockerverse-payment__stripe-loader`,role:`status`,children:[v(`p`,{children:e}),y(`div`,{"aria-hidden":`true`,children:[v(`span`,{}),v(`span`,{}),v(`span`,{})]})]})}function ee({fields:e,onChange:t,values:n}){return e.map(e=>{let r=n[e.id]??(e.type.includes(`multi`)||e.type===`checkboxes`?[]:``);if(e.type===`textarea`)return y(`label`,{children:[v(`span`,{children:e.label}),v(`textarea`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,value:String(r)})]},e.id);if(e.type===`select`)return y(`label`,{children:[v(`span`,{children:e.label}),y(`select`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,value:String(r),children:[v(`option`,{value:``,children:`Select…`}),e.options.map(e=>v(`option`,{value:e.id,children:e.label},e.id))]})]},e.id);if(e.type===`radio`||e.type===`checkboxes`||e.type===`multi_select`){let n=Array.isArray(r)?r:[r];return y(`fieldset`,{children:[v(`legend`,{children:e.label}),e.options.map(r=>{let i=n.includes(r.id);return y(`label`,{className:`lockerverse-payment__choice`,children:[v(`input`,{checked:i,name:e.id,onChange:()=>{if(e.type===`radio`){t(e.id,r.id);return}t(e.id,i?n.filter(e=>e!==r.id):[...n,r.id])},required:e.required&&n.length===0,type:e.type===`radio`?`radio`:`checkbox`,value:r.id}),v(`span`,{children:r.label})]},r.id)})]},e.id)}return y(`label`,{children:[v(`span`,{children:e.label}),v(`input`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,type:`text`,value:String(r)})]},e.id)})}function te({busy:e,enabled:t,onCustomTipBlur:n,onCustomTipChange:r,onSelect:i,tipInput:a,tipOption:o}){return t?y(`div`,{className:`lockerverse-payment__tip`,children:[v(`strong`,{children:`Add a tip to support the Lockerverse platform`}),v(`div`,{"aria-label":`Tip amount`,role:`radiogroup`,children:T.map(t=>v(`button`,{"aria-pressed":o===t.value,disabled:e,onClick:()=>i(t),type:`button`,children:t.label},t.value))}),o===`custom`?y(`label`,{children:[v(`span`,{children:`Custom tip`}),y(`div`,{className:`lockerverse-payment__money-input`,children:[v(`span`,{"aria-hidden":`true`,children:`$`}),v(`input`,{inputMode:`decimal`,name:`customTip`,onBlur:n,onChange:e=>r(e.currentTarget.value),placeholder:`0.00`,value:a})]})]}):null]}):null}function D({email:e,fields:t,onEmailChange:n,onPhoneChange:r,onPhoneCountryChange:i,phone:a,phoneCountry:o}){return y(`div`,{className:`lockerverse-payment__contact`,children:[y(`label`,{children:[v(`span`,{children:`Email`}),v(`input`,{autoComplete:`email`,inputMode:`email`,name:`email`,onChange:e=>n(e.currentTarget.value),placeholder:`name@example.com`,required:!0,type:`email`,value:e})]}),t.phone?y(`label`,{children:[v(`span`,{children:`Phone`}),y(`div`,{className:`lockerverse-payment__phone-control`,children:[v(`select`,{"aria-label":`Phone country`,name:`phoneCountry`,onChange:e=>i(e.currentTarget.value),value:o,children:w.map(e=>v(`option`,{value:e.value,children:e.label},e.value))}),v(`input`,{autoComplete:`tel`,inputMode:`tel`,name:`phone`,onChange:e=>r(e.currentTarget.value),placeholder:`(201) 555-0123`,required:!0,type:`tel`,value:a})]})]}):null]})}function ne({fields:e,isBillingAddressReady:n,isPaymentReady:a,isShippingAddressReady:o,onBillingAddressReady:s,onPaymentReady:c,onShippingAddressReady:l,onShippingMatchesBillingChange:u,shippingMatchesBilling:d,totalCents:f}){return y(_,{children:[y(`div`,{className:`lockerverse-payment__stripe-element`,"data-ready":a,hidden:f===0,children:[a?null:v(E,{label:`Loading payment form...`}),v(`div`,{className:`lockerverse-payment__stripe-mount`,children:v(r,{onReady:c,options:{fields:{billingDetails:{address:`never`,email:`never`,name:`never`,phone:`never`}},layout:`tabs`,paymentMethodOrder:[`card`,`apple_pay`,`paypal`],terms:{applePay:`auto`,card:`always`,googlePay:`never`,paypal:`auto`,usBankAccount:`never`},wallets:{applePay:`auto`,googlePay:`never`}}})})]}),y(`div`,{className:`lockerverse-payment__address`,children:[v(`h2`,{children:`Billing address`}),y(`div`,{className:`lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address`,"data-ready":n,children:[n?null:v(E,{label:`Loading billing address...`}),v(`div`,{className:`lockerverse-payment__stripe-mount`,children:v(t,{onReady:s})})]})]}),e.shipping?y(`div`,{className:`lockerverse-payment__shipping`,children:[y(`label`,{className:`lockerverse-payment__check-row`,children:[v(`input`,{checked:d,name:`shippingMatchesBilling`,onChange:e=>u(e.currentTarget.checked),type:`checkbox`}),v(`span`,{children:`Shipping is same as billing information`})]}),d?null:y(`div`,{className:`lockerverse-payment__address`,children:[v(`h2`,{children:`Shipping address`}),y(`div`,{className:`lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address`,"data-ready":o,children:[o?null:v(E,{label:`Loading shipping address...`}),v(`div`,{className:`lockerverse-payment__stripe-mount`,children:v(i,{onReady:l})})]})]})]}):null]})}function re({fields:e,memberId:t,merchSize:n,onMemberIdChange:r,onMerchSizeChange:i}){return y(_,{children:[e.memberId?y(`label`,{children:[v(`span`,{children:`Member ID`}),v(`input`,{name:`memberId`,onChange:e=>r(e.currentTarget.value),required:!0,type:`text`,value:t})]}):null,e.merchSize?y(`label`,{children:[v(`span`,{children:`Size`}),v(`select`,{name:`merchSize`,onChange:e=>i(e.currentTarget.value),required:!0,value:n,children:[`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`].map(e=>v(`option`,{value:e,children:e},e))})]}):null]})}function O(){return y(`div`,{className:`lockerverse-payment__skeleton-loader-block`,children:[v(`span`,{className:`lockerverse-payment__skeleton-loader-label`}),y(`div`,{className:`lockerverse-payment__skeleton-loader-content`,children:[v(`span`,{className:`lockerverse-payment__skeleton-loader-full`}),y(`div`,{className:`lockerverse-payment__skeleton-loader-grid`,children:[v(`span`,{className:`lockerverse-payment__skeleton-loader-half`}),v(`span`,{className:`lockerverse-payment__skeleton-loader-half`})]})]})]})}function k(){return y(`div`,{className:`lockerverse-payment__loading`,children:[v(`span`,{className:`lockerverse-payment__sr-only`,role:`status`,children:`Preparing secure checkout…`}),y(`div`,{"aria-hidden":`true`,className:`lockerverse-payment__skeleton`,children:[y(`div`,{className:`lockerverse-payment__skeleton-branding`,children:[v(`span`,{className:`lockerverse-payment__skeleton-avatar`}),v(`span`,{className:`lockerverse-payment__skeleton-community`})]}),y(`div`,{className:`lockerverse-payment__skeleton-contact`,children:[y(`div`,{className:`lockerverse-payment__skeleton-field`,children:[v(`span`,{className:`lockerverse-payment__skeleton-label`}),v(`span`,{className:`lockerverse-payment__skeleton-input`})]}),y(`div`,{className:`lockerverse-payment__skeleton-field`,children:[v(`span`,{className:`lockerverse-payment__skeleton-label`}),v(`span`,{className:`lockerverse-payment__skeleton-input`})]})]}),v(O,{}),v(O,{}),y(`div`,{className:`lockerverse-payment__skeleton-actions`,children:[v(`span`,{className:`lockerverse-payment__skeleton-check-line`}),v(`span`,{className:`lockerverse-payment__skeleton-button`})]})]})]})}const A=s(null),j=p(g(),m(/^\d+(?:\.\d{1,2})?$/));function M(e){let t=e.trim();if(!t)return 0;let n=h(j,t);if(!n.success)return null;let[r=`0`,i=``]=n.output.split(`.`),a=BigInt(r)*100n+BigInt(i.padEnd(2,`0`));return a<=BigInt(2**53-1)?Number(a):null}function N(e){return new Intl.NumberFormat(`en-US`,{currency:`USD`,style:`currency`}).format(e/100)}function P(e,t){let n=e.trim(),r=n.replace(/\D/g,``);return n.startsWith(`+`)?`+${r}`:`${w.find(e=>e.value===t)?.callingCode??`+1`}${r}`}function F(e,t){if(!t.length)throw Error(`Select at least one Product before opening checkout.`);return t.map(t=>{let n=e.products.find(e=>e.slug===t.productSlug);if(!n)throw Error(`Product ${t.productSlug} is unavailable.`);return`amountCents`in t?{amountCents:t.amountCents,productId:n.id}:{productId:n.id,quantity:t.quantity}})}function I(e,t){return t.reduce((t,n)=>{if(`amountCents`in n)return t+n.amountCents;let r=e.products.find(e=>e.slug===n.productSlug);if(!r||r.amountCents===null)throw Error(`Product ${n.productSlug} has invalid pricing.`);return t+r.amountCents*n.quantity},0)}function L(e){let t={communitySlug:e.communitySlug,...e.fetch?{fetch:e.fetch}:{},...e.onError?{onError:e.onError}:{},...e.requestTimeoutMs===void 0?{}:{requestTimeoutMs:e.requestTimeoutMs},...e.sentryDsn===void 0?{}:{sentryDsn:e.sentryDsn},widgetSlug:e.widgetSlug};return e.apiBaseUrl?{...t,apiBaseUrl:e.apiBaseUrl,environment:e.environment}:{...t,environment:`production`}}function R(e,t,n){if(!e)return null;let r=t??`#38d77a`,i=n===`light`;return{clientSecret:e.session.clientSecret,elementsOptions:{appearance:{rules:{".Input:focus":{borderColor:r,boxShadow:`0 0 0 1px ${r}`,outline:`none`}},theme:i?`stripe`:`night`,variables:{borderRadius:`10px`,colorBackground:i?`#f5f6f7`:`#121212`,colorDanger:i?`#c52b3e`:`#f08a98`,colorPrimary:r,colorText:i?`#121416`:`#ffffff`,colorTextPlaceholder:i?`#72767d`:`#6b6b6b`,colorTextSecondary:i?`#62666d`:`#a1a1aa`,focusBoxShadow:`none`,focusOutline:`none`,fontSizeBase:`16px`}},syncAddressCheckbox:`none`}}}function z({children:e,loaded:t}){let n=a();return n.type===`loading`?v(k,{}):n.type===`error`?v(`div`,{role:`alert`,children:n.error.message}):v(V,{checkout:n.checkout,loaded:t,children:e})}function B(e){return{includeServiceFee:e.includeServiceFee,serviceFeeAmountCents:Math.round(e.subtotalCents*e.catalog.pricingPolicy.serviceFeeRateBasisPoints/1e4),subtotalCents:e.subtotalCents,tipCents:e.tipCents}}function V({checkout:e,children:t,loaded:n}){let[r,i]=f(()=>B(n));l(()=>{i(B(n))},[n]);let a={async applyPromoCode(t){let r=await e.runServerUpdate(()=>n.client.updateSessionDiscount({paymentReference:n.session.paymentReference,...t.trim()?{promoCode:t.trim()}:{}}));return r.type===`error`?r.error.message:null},catalog:n.catalog,async confirm(t){if(t.shippingMatchesBilling){if(!e.billingAddress)throw Error(`Billing address is required.`);let t=await e.updateShippingAddress(e.billingAddress);if(t.type===`error`)throw Error(t.error.message)}let r=await e.runServerUpdate(()=>n.client.updateSessionDetails({...t.customFieldAnswers?{customFieldAnswers:t.customFieldAnswers}:{},email:t.email,...t.memberId?{memberId:t.memberId}:{},...t.merchSize?{merchSize:t.merchSize}:{},paymentReference:n.session.paymentReference,...t.phone?{phone:t.phone}:{}}));if(r.type===`error`)throw Error(r.error.message);let i=await W(e,t.email,t.phone??``,e.total.total.minorUnitsAmount>0);if(`error`in i)throw Error(i.error);let a=await e.confirm({email:i.email,...i.phone?{phoneNumber:i.phone}:{},redirect:`if_required`});if(a.type===`error`)throw Error(a.error.message);return{paymentReference:n.session.paymentReference,sessionId:n.session.sessionId}},paymentReference:n.session.paymentReference,pricing:r,totalCents:e.total.total.minorUnitsAmount,async updatePricing(t){let r,a=await e.runServerUpdate(()=>n.client.updateSessionPricing({...t,paymentReference:n.session.paymentReference}).then(e=>(r=e,e)));if(a.type===`error`)throw Error(a.error.message);if(!r)throw Error(`Lockerverse returned no updated pricing.`);let o=r;return i(e=>({...e,includeServiceFee:o.includeServiceFee,tipCents:o.tipCents})),o}};return v(A.Provider,{value:a,children:t})}function H(t){let[r,i]=f(null),[a,s]=f(null),[c,p]=f(0),m=d(null),h=JSON.stringify({email:t.email,includeServiceFee:t.includeServiceFee,returnUrl:t.returnUrl,selection:t.selection,tipCents:t.tipCents}),g=d({email:t.email,includeServiceFee:t.includeServiceFee,key:h,requestKey:globalThis.crypto.randomUUID(),returnUrl:t.returnUrl,selection:t.selection,tipCents:t.tipCents}),_=u(()=>L(t),[t.apiBaseUrl,t.communitySlug,t.environment,t.fetch,t.onError,t.requestTimeoutMs,t.sentryDsn,t.widgetSlug]);l(()=>{let t=!0;if(m.current?.clientOptions!==_||c>0){let t=e(_),n=g.current;m.current={clientOptions:_,promise:(async()=>{let e=await t.load(),r=F(e,n.selection),i=I(e,n.selection),a=n.includeServiceFee??e.widget.fields.serviceFee,o=n.tipCents??(e.widget.fields.tipping?Math.round(i*.1):0),s=await t.createSession({...n.email?{email:n.email}:{},...e.widget.fields.serviceFee?{includeServiceFee:a}:{},items:r,requestKey:n.requestKey,returnUrl:n.returnUrl,...e.widget.fields.tipping?{tipCents:o}:{}});return{catalog:e,client:t,includeServiceFee:a,returnUrl:n.returnUrl,session:s,subtotalCents:i,tipCents:o}})()}}return i(null),s(null),m.current.promise.then(e=>{t&&i(e)}).catch(e=>{t&&s(e instanceof Error?e.message:`Unable to load checkout.`)}),()=>{t=!1}},[_,c]);let b=u(()=>r?(t.unstable_stripeLoader??o)(r.catalog.payment.publishableKey,{betas:[`custom_checkout_server_updates_1`],...r.session.connectedAccountId?{stripeAccount:r.session.connectedAccountId}:{}}):null,[r,t.unstable_stripeLoader]),x=u(()=>R(r,t.accentColor,t.theme),[r,t.accentColor,t.theme]);return h===g.current.key?a?y(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:[v(`p`,{children:a}),v(`button`,{onClick:()=>p(e=>e+1),type:`button`,children:`Try again`})]}):r&&x?v(n,{options:x,stripe:b,children:v(z,{loaded:r,children:t.children})}):v(k,{}):v(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:`Checkout selection changed. Remount this payment component for the new selection.`})}function U(){let e=c(A);if(!e)throw Error(`useLockerverseCheckoutSession must be used inside LockerverseCheckoutSessionProvider.`);return e}async function W(e,t,n,r){let i=t.trim().toLowerCase();if(!i)return{error:`Email is required.`};let a=await e.updateEmail(i);if(a.type===`error`)return{error:a.error.message};let o=n.trim();if(o&&(await e.updatePhoneNumber(o)).type===`error`)return{error:`Phone number is invalid.`};if(r){let t=await e.validateElements();if(t.type===`error`)return{error:t.error.message}}return{email:i,phone:o}}function ie(e,t){return e===0?`Complete free order`:t>0?`Process Payment ($${((e-t)/100).toFixed(2)}) + $${(t/100).toFixed(2)} tip`:`Process Payment ($${(e/100).toFixed(2)})`}function ae({catalog:e,customFieldValues:t,email:n,memberId:r,merchSize:i,phone:a,phoneCountry:o,shippingMatchesBilling:s}){return{customFieldAnswers:e.widget.customFields.map(e=>({fieldId:e.id,value:t[e.id]??null})),email:n,...r?{memberId:r}:{},...i?{merchSize:i}:{},...a?{phone:P(a,o)}:{},...e.widget.fields.shipping?{shippingMatchesBilling:s}:{}}}function G({branding:e,onComplete:t}){let{applyPromoCode:n,catalog:r,confirm:i,pricing:a,totalCents:o,updatePricing:s}=U(),[c,u]=f(``),[p,m]=f(``),[h,g]=f(`US`),[_,b]=f(``),[x,S]=f(`M`),[C,w]=f({}),[E,O]=f(``),[k,A]=f(null),[j,P]=f(!1),[F,I]=f(!1),[L,R]=f(!1),[z,B]=f(!1),[V,H]=f(!1),[W,G]=f(!0),K=T.find(e=>e.percent!==null&&Math.round(a.subtotalCents*e.percent/100)===a.tipCents)?.value??`custom`,[q,J]=f(K),[Y,X]=f(K===`custom`&&a.tipCents>0?(a.tipCents/100).toFixed(2):``),Z=d({includeServiceFee:a.includeServiceFee,tipCents:a.tipCents}),Q=d(Promise.resolve(!0));l(()=>{Z.current={includeServiceFee:a.includeServiceFee,tipCents:a.tipCents}},[a.includeServiceFee,a.tipCents]);function $(e){let t=(async()=>{I(!0),A(null);try{let t=await s(e);return Z.current={includeServiceFee:t.includeServiceFee,tipCents:t.tipCents},!0}catch(e){return A(e instanceof Error?e.message:`Unable to update checkout.`),!1}finally{I(!1)}})();return Q.current=t,t}async function oe(e){if(e.percent===null){J(e.value);return}let t=Math.round(a.subtotalCents*e.percent/100);await $({includeServiceFee:a.includeServiceFee,tipCents:t})&&(X(``),J(e.value))}function se(){let e=M(Y);if(e===null){A(`Enter a valid tip with no more than two decimal places.`);return}return $({includeServiceFee:a.includeServiceFee,tipCents:e})}async function ce(e){await $({includeServiceFee:e,tipCents:a.tipCents})}async function le(){P(!0),A(null);try{A(await n(E))}catch(e){A(e instanceof Error?e.message:`Unable to update checkout.`)}finally{P(!1)}}async function ue(){if(!await Q.current)return!1;if(q!==`custom`)return!0;let e=M(Y);return e===null?(A(`Enter a valid tip with no more than two decimal places.`),!1):e===Z.current.tipCents||$({includeServiceFee:Z.current.includeServiceFee,tipCents:e})}async function de(e){e.preventDefault(),P(!0),A(null);try{if(!await ue())return;let e=await i(ae({catalog:r,customFieldValues:C,email:c,memberId:_,merchSize:x,phone:p,phoneCountry:h,shippingMatchesBilling:W}));t?.(e)}catch(e){A(e instanceof Error?e.message:`Unable to complete checkout.`)}finally{P(!1)}}return y(`form`,{className:`lockerverse-payment__form`,onSubmit:de,children:[y(`header`,{children:[r.widget.showCommunityBranding&&e?y(`div`,{className:`lockerverse-payment__branding`,children:[e.imageUrl?v(`img`,{alt:e.name,height:`48`,src:e.imageUrl,width:`48`}):null,v(`strong`,{children:e.name})]}):null,v(`h1`,{children:r.widget.title??r.widget.name}),r.widget.description?v(`p`,{children:r.widget.description}):null]}),v(te,{busy:j||F,enabled:r.widget.fields.tipping,onCustomTipBlur:se,onCustomTipChange:X,onSelect:oe,tipInput:Y,tipOption:q}),v(D,{email:c,fields:r.widget.fields,onEmailChange:u,onPhoneChange:m,onPhoneCountryChange:g,phone:p,phoneCountry:h}),v(ne,{fields:r.widget.fields,isBillingAddressReady:L,isPaymentReady:z,isShippingAddressReady:V,onBillingAddressReady:()=>R(!0),onPaymentReady:()=>B(!0),onShippingAddressReady:()=>H(!0),onShippingMatchesBillingChange:e=>{G(e),e||H(!1)},shippingMatchesBilling:W,totalCents:o}),v(re,{fields:r.widget.fields,memberId:_,merchSize:x,onMemberIdChange:b,onMerchSizeChange:S}),r.widget.fields.promoCode?y(`div`,{className:`lockerverse-payment__additional-fields`,children:[y(`label`,{children:[v(`span`,{children:`Promo code`}),v(`input`,{name:`promoCode`,onChange:e=>O(e.currentTarget.value),placeholder:`Optional`,value:E})]}),v(`button`,{disabled:j,onClick:le,type:`button`,children:E.trim()?`Apply code`:`Remove code`})]}):null,r.widget.customFields.length?v(`div`,{className:`lockerverse-payment__custom-fields`,children:v(ee,{fields:r.widget.customFields,onChange:(e,t)=>w(n=>({...n,[e]:t})),values:C})}):null,k?v(`div`,{role:`alert`,children:k}):null,y(`div`,{className:`lockerverse-payment__actions`,children:[r.widget.fields.serviceFee?y(`label`,{className:`lockerverse-payment__check-row`,children:[v(`input`,{checked:a.includeServiceFee,disabled:j||F,name:`includeServiceFee`,onChange:e=>ce(e.currentTarget.checked),type:`checkbox`}),y(`span`,{children:[`Add `,N(a.serviceFeeAmountCents),` to help cover processing fees`]})]}):null,v(`button`,{disabled:j,type:`submit`,children:ie(o,a.tipCents)})]})]})}function K(e){let{apiBaseUrl:t,branding:n,className:r,communitySlug:i,environment:a,fetch:o,includeServiceFee:s,onError:c,onPaymentComplete:l,requestTimeoutMs:u,returnUrl:d,selection:f,sentryDsn:p,unstable_stripeLoader:m,style:h,theme:g=`dark`,tipCents:_,widgetSlug:y,...b}=e,x=d??(globalThis.location===void 0?`https://lockerverse.com`:globalThis.location.href),S=[`lockerverse-payment`,r].filter(Boolean).join(` `),w=t?{apiBaseUrl:t,communitySlug:i,environment:a,widgetSlug:y}:{communitySlug:i,environment:`production`,widgetSlug:y},T=n?.accentColor?{...h,"--lockerverse-accent":n.accentColor,"--lockerverse-accent-contrast":C(n.accentColor)??`#08110c`}:h;return v(`section`,{...b,className:S,"data-lockerverse-theme":g,style:T,children:v(H,{...w,...n?.accentColor?{accentColor:n.accentColor}:{},...o?{fetch:o}:{},...s===void 0?{}:{includeServiceFee:s},...c?{onError:c}:{},...u===void 0?{}:{requestTimeoutMs:u},returnUrl:x,selection:f,...p===void 0?{}:{sentryDsn:p},...m?{unstable_stripeLoader:m}:{},theme:g,..._===void 0?{}:{tipCents:_},children:v(G,{...n?{branding:n}:{},...l?{onComplete:l}:{}})})})}export{G as LockerverseCheckoutSessionPaymentForm,H as LockerverseCheckoutSessionProvider,K as LockerversePayment,U as useLockerverseCheckoutSession};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/checkout-session-payment.tsx"],"sourcesContent":["import type {\n CreateLockerverseWidgetOptions,\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutItem,\n LockerverseCheckoutSession,\n LockerverseCustomField,\n LockerverseCustomFieldAnswer,\n} from \"@lockerverse/sdk/checkout\";\nimport { createLockerverseCheckoutClient } from \"@lockerverse/sdk/checkout\";\nimport type { StripeCheckoutElementsValue } from \"@stripe/react-stripe-js/checkout\";\nimport {\n BillingAddressElement,\n CheckoutElementsProvider,\n PaymentElement,\n ShippingAddressElement,\n useCheckoutElements,\n} from \"@stripe/react-stripe-js/checkout\";\nimport { loadStripe } from \"@stripe/stripe-js/pure\";\nimport {\n createContext,\n type FormEvent,\n type PropsWithChildren,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LockerversePaymentCompletion,\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\ntype CheckoutSessionStripeLoader = typeof loadStripe;\n\nexport type LockerverseCheckoutSessionProviderProps =\n CreateLockerverseWidgetOptions &\n PropsWithChildren<{\n accentColor?: string;\n email?: string;\n includeServiceFee?: boolean;\n returnUrl: string;\n selection: LockerversePaymentSelectionItem[];\n unstable_stripeLoader?: CheckoutSessionStripeLoader;\n theme?: \"dark\" | \"light\";\n tipCents?: number;\n }>;\n\ntype LoadedCheckout = {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n returnUrl: string;\n session: LockerverseCheckoutSession;\n};\n\ntype CheckoutContextValue = {\n applyPromoCode: (promoCode: string) => Promise<string | null>;\n catalog: LockerverseCatalog;\n confirm: (contact: {\n customFieldAnswers?: LockerverseCustomFieldAnswer[];\n email: string;\n memberId?: string;\n merchSize?: \"XS\" | \"S\" | \"M\" | \"L\" | \"XL\" | \"XXL\" | \"XXXL\";\n phone?: string;\n }) => Promise<LockerversePaymentCompletion>;\n paymentReference: string;\n totalCents: number;\n};\n\nconst CheckoutContext = createContext<CheckoutContextValue | null>(null);\n\nfunction resolveItems(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n) {\n if (!selection.length) {\n throw new Error(\"Select at least one Product before opening checkout.\");\n }\n return selection.map((selected): LockerverseCheckoutItem => {\n const product = catalog.products.find(\n (candidate) => candidate.slug === selected.productSlug\n );\n if (!product) {\n throw new Error(`Product ${selected.productSlug} is unavailable.`);\n }\n return \"amountCents\" in selected\n ? { amountCents: selected.amountCents, productId: product.id }\n : { productId: product.id, quantity: selected.quantity };\n });\n}\n\nfunction createClientOptions(\n props: LockerverseCheckoutSessionProviderProps\n): CreateLockerverseWidgetOptions {\n const common = {\n communitySlug: props.communitySlug,\n ...(props.fetch ? { fetch: props.fetch } : {}),\n ...(props.onError ? { onError: props.onError } : {}),\n ...(props.requestTimeoutMs === undefined\n ? {}\n : { requestTimeoutMs: props.requestTimeoutMs }),\n ...(props.sentryDsn === undefined ? {} : { sentryDsn: props.sentryDsn }),\n widgetSlug: props.widgetSlug,\n };\n return props.apiBaseUrl\n ? {\n ...common,\n apiBaseUrl: props.apiBaseUrl,\n environment: props.environment,\n }\n : { ...common, environment: \"production\" };\n}\n\nfunction CheckoutBridge({\n children,\n loaded,\n}: PropsWithChildren<{ loaded: LoadedCheckout }>) {\n const result = useCheckoutElements();\n if (result.type === \"loading\") {\n return <div role=\"status\">Loading secure payment form…</div>;\n }\n if (result.type === \"error\") {\n return <div role=\"alert\">{result.error.message}</div>;\n }\n const { checkout } = result;\n const value: CheckoutContextValue = {\n async applyPromoCode(promoCode) {\n const update = await checkout.runServerUpdate(() =>\n loaded.client.updateSessionDiscount({\n paymentReference: loaded.session.paymentReference,\n ...(promoCode.trim() ? { promoCode: promoCode.trim() } : {}),\n })\n );\n return update.type === \"error\" ? update.error.message : null;\n },\n catalog: loaded.catalog,\n async confirm(contact) {\n const detailsUpdate = await checkout.runServerUpdate(() =>\n loaded.client.updateSessionDetails({\n ...(contact.customFieldAnswers\n ? { customFieldAnswers: contact.customFieldAnswers }\n : {}),\n email: contact.email,\n ...(contact.memberId ? { memberId: contact.memberId } : {}),\n ...(contact.merchSize ? { merchSize: contact.merchSize } : {}),\n paymentReference: loaded.session.paymentReference,\n ...(contact.phone ? { phone: contact.phone } : {}),\n })\n );\n if (detailsUpdate.type === \"error\") {\n throw new Error(detailsUpdate.error.message);\n }\n const prepared = await prepareCheckoutContact(\n checkout,\n contact.email,\n contact.phone ?? \"\"\n );\n if (\"error\" in prepared) {\n throw new Error(prepared.error);\n }\n const confirmation = await checkout.confirm({\n email: prepared.email,\n ...(prepared.phone ? { phoneNumber: prepared.phone } : {}),\n redirect: \"if_required\",\n });\n if (confirmation.type === \"error\") {\n throw new Error(confirmation.error.message);\n }\n return {\n paymentReference: loaded.session.paymentReference,\n sessionId: loaded.session.sessionId,\n };\n },\n paymentReference: loaded.session.paymentReference,\n totalCents: checkout.total.total.minorUnitsAmount,\n };\n return (\n <CheckoutContext.Provider value={value}>\n {children}\n </CheckoutContext.Provider>\n );\n}\n\nexport function LockerverseCheckoutSessionProvider(\n props: LockerverseCheckoutSessionProviderProps\n) {\n const [loaded, setLoaded] = useState<LoadedCheckout | null>(null);\n const [failure, setFailure] = useState<string | null>(null);\n const [revision, setRevision] = useState(0);\n const preparation = useRef<{\n clientOptions: CreateLockerverseWidgetOptions;\n promise: Promise<LoadedCheckout>;\n } | null>(null);\n const currentCheckoutKey = JSON.stringify({\n email: props.email,\n includeServiceFee: props.includeServiceFee,\n returnUrl: props.returnUrl,\n selection: props.selection,\n tipCents: props.tipCents,\n });\n const initialCheckout = useRef({\n email: props.email,\n includeServiceFee: props.includeServiceFee,\n key: currentCheckoutKey,\n requestKey: globalThis.crypto.randomUUID(),\n returnUrl: props.returnUrl,\n selection: props.selection,\n tipCents: props.tipCents,\n });\n const clientOptions = useMemo(\n () => createClientOptions(props),\n [\n props.apiBaseUrl,\n props.communitySlug,\n props.environment,\n props.fetch,\n props.onError,\n props.requestTimeoutMs,\n props.sentryDsn,\n props.widgetSlug,\n ]\n );\n\n useEffect(() => {\n let active = true;\n if (preparation.current?.clientOptions !== clientOptions || revision > 0) {\n const client = createLockerverseCheckoutClient(clientOptions);\n const checkoutInput = initialCheckout.current;\n preparation.current = {\n clientOptions,\n promise: (async () => {\n const catalog = await client.load();\n const items = resolveItems(catalog, checkoutInput.selection);\n const includeServiceFee =\n checkoutInput.includeServiceFee ?? catalog.widget.fields.serviceFee;\n const session = await client.createSession({\n ...(checkoutInput.email ? { email: checkoutInput.email } : {}),\n ...(catalog.widget.fields.serviceFee ? { includeServiceFee } : {}),\n items,\n requestKey: checkoutInput.requestKey,\n returnUrl: checkoutInput.returnUrl,\n ...(checkoutInput.tipCents === undefined\n ? {}\n : { tipCents: checkoutInput.tipCents }),\n });\n return {\n catalog,\n client,\n returnUrl: checkoutInput.returnUrl,\n session,\n };\n })(),\n };\n }\n setLoaded(null);\n setFailure(null);\n preparation.current.promise\n .then((next) => {\n if (active) {\n setLoaded(next);\n }\n })\n .catch((error: unknown) => {\n if (active) {\n setFailure(\n error instanceof Error ? error.message : \"Unable to load checkout.\"\n );\n }\n });\n return () => {\n active = false;\n };\n }, [clientOptions, revision]);\n\n const stripe = useMemo(() => {\n if (!loaded) {\n return null;\n }\n const stripeLoader = props.unstable_stripeLoader ?? loadStripe;\n return stripeLoader(loaded.catalog.payment.publishableKey, {\n betas: [\"custom_checkout_server_updates_1\"],\n ...(loaded.session.connectedAccountId\n ? { stripeAccount: loaded.session.connectedAccountId }\n : {}),\n });\n }, [loaded, props.unstable_stripeLoader]);\n const providerOptions = useMemo(\n () =>\n loaded\n ? {\n clientSecret: loaded.session.clientSecret,\n elementsOptions: {\n appearance: {\n theme:\n props.theme === \"light\"\n ? (\"stripe\" as const)\n : (\"night\" as const),\n variables: {\n colorBackground: \"transparent\",\n colorPrimary: props.accentColor ?? \"#38d77a\",\n },\n },\n },\n }\n : null,\n [loaded, props.accentColor, props.theme]\n );\n\n if (currentCheckoutKey !== initialCheckout.current.key) {\n return (\n <div className=\"lockerverse-payment__payment-status\" role=\"alert\">\n Checkout selection changed. Remount this payment component for the new\n selection.\n </div>\n );\n }\n if (failure) {\n return (\n <div className=\"lockerverse-payment__payment-status\" role=\"alert\">\n <p>{failure}</p>\n <button onClick={() => setRevision((value) => value + 1)} type=\"button\">\n Try again\n </button>\n </div>\n );\n }\n if (!(loaded && providerOptions)) {\n return (\n <div className=\"lockerverse-payment__loading\">\n <span className=\"lockerverse-payment__sr-only\" role=\"status\">\n Preparing secure checkout…\n </span>\n <div aria-hidden=\"true\" className=\"lockerverse-payment__skeleton\">\n <div className=\"lockerverse-payment__skeleton-contact\">\n <div className=\"lockerverse-payment__skeleton-field\">\n <span className=\"lockerverse-payment__skeleton-label\" />\n <span className=\"lockerverse-payment__skeleton-input\" />\n </div>\n </div>\n <div className=\"lockerverse-payment__skeleton-loader-block\">\n <span className=\"lockerverse-payment__skeleton-loader-label\" />\n <span className=\"lockerverse-payment__skeleton-loader-full\" />\n </div>\n <div className=\"lockerverse-payment__skeleton-actions\">\n <span className=\"lockerverse-payment__skeleton-button\" />\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <CheckoutElementsProvider options={providerOptions} stripe={stripe}>\n <CheckoutBridge loaded={loaded}>{props.children}</CheckoutBridge>\n </CheckoutElementsProvider>\n );\n}\n\nexport function useLockerverseCheckoutSession() {\n const value = useContext(CheckoutContext);\n if (!value) {\n throw new Error(\n \"useLockerverseCheckoutSession must be used inside LockerverseCheckoutSessionProvider.\"\n );\n }\n return value;\n}\n\nasync function prepareCheckoutContact(\n checkout: StripeCheckoutElementsValue,\n email: string,\n phone: string\n) {\n const normalizedEmail = email.trim().toLowerCase();\n if (!normalizedEmail) {\n return { error: \"Email is required.\" } as const;\n }\n const emailResult = await checkout.updateEmail(normalizedEmail);\n if (emailResult.type === \"error\") {\n return { error: emailResult.error.message } as const;\n }\n const normalizedPhone = phone.trim();\n if (normalizedPhone) {\n const phoneResult = await checkout.updatePhoneNumber(normalizedPhone);\n if (phoneResult.type === \"error\") {\n return { error: \"Phone number is invalid.\" } as const;\n }\n }\n const validation = await checkout.validateElements();\n if (validation.type === \"error\") {\n return { error: validation.error.message } as const;\n }\n return { email: normalizedEmail, phone: normalizedPhone } as const;\n}\n\nfunction LockerverseCustomFields({\n fields,\n onChange,\n values,\n}: {\n fields: LockerverseCustomField[];\n onChange: (fieldId: string, value: string | string[]) => void;\n values: Record<string, string | string[]>;\n}) {\n return fields.map((field) => {\n const value =\n values[field.id] ??\n (field.type.includes(\"multi\") || field.type === \"checkboxes\" ? [] : \"\");\n if (field.type === \"textarea\") {\n return (\n <label key={field.id}>\n <span>{field.label}</span>\n <textarea\n name={field.id}\n onChange={(event) => onChange(field.id, event.currentTarget.value)}\n required={field.required}\n value={String(value)}\n />\n </label>\n );\n }\n if (field.type === \"select\") {\n return (\n <label key={field.id}>\n <span>{field.label}</span>\n <select\n name={field.id}\n onChange={(event) => onChange(field.id, event.currentTarget.value)}\n required={field.required}\n value={String(value)}\n >\n <option value=\"\">Select…</option>\n {field.options.map((option) => (\n <option key={option.id} value={option.id}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n );\n }\n if (\n field.type === \"radio\" ||\n field.type === \"checkboxes\" ||\n field.type === \"multi_select\"\n ) {\n const selected = Array.isArray(value) ? value : [value];\n return (\n <fieldset key={field.id}>\n <legend>{field.label}</legend>\n {field.options.map((option) => {\n const checked = selected.includes(option.id);\n return (\n <label className=\"lockerverse-payment__choice\" key={option.id}>\n <input\n checked={checked}\n name={field.id}\n onChange={() => {\n if (field.type === \"radio\") {\n onChange(field.id, option.id);\n return;\n }\n onChange(\n field.id,\n checked\n ? selected.filter((id) => id !== option.id)\n : [...selected, option.id]\n );\n }}\n required={field.required && selected.length === 0}\n type={field.type === \"radio\" ? \"radio\" : \"checkbox\"}\n value={option.id}\n />\n <span>{option.label}</span>\n </label>\n );\n })}\n </fieldset>\n );\n }\n return (\n <label key={field.id}>\n <span>{field.label}</span>\n <input\n name={field.id}\n onChange={(event) => onChange(field.id, event.currentTarget.value)}\n required={field.required}\n type=\"text\"\n value={String(value)}\n />\n </label>\n );\n });\n}\n\nexport function LockerverseCheckoutSessionPaymentForm({\n onComplete,\n}: {\n onComplete?: (result: LockerversePaymentCompletion) => void;\n}) {\n const { applyPromoCode, catalog, confirm, totalCents } =\n useLockerverseCheckoutSession();\n const [email, setEmail] = useState(\"\");\n const [phone, setPhone] = useState(\"\");\n const [memberId, setMemberId] = useState(\"\");\n const [merchSize, setMerchSize] = useState(\"\");\n const [customFieldValues, setCustomFieldValues] = useState<\n Record<string, string | string[]>\n >({});\n const [promoCode, setPromoCode] = useState(\"\");\n const [message, setMessage] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n async function updateDiscount() {\n setBusy(true);\n setMessage(null);\n try {\n setMessage(await applyPromoCode(promoCode));\n } catch (error) {\n setMessage(\n error instanceof Error ? error.message : \"Unable to update checkout.\"\n );\n } finally {\n setBusy(false);\n }\n }\n\n async function submit(event: FormEvent) {\n event.preventDefault();\n setBusy(true);\n setMessage(null);\n try {\n onComplete?.(\n await confirm({\n customFieldAnswers: catalog.widget.customFields.map((field) => ({\n fieldId: field.id,\n value: customFieldValues[field.id] ?? null,\n })) as LockerverseCustomFieldAnswer[],\n email,\n ...(memberId ? { memberId } : {}),\n ...(merchSize\n ? {\n merchSize: merchSize as\n | \"XS\"\n | \"S\"\n | \"M\"\n | \"L\"\n | \"XL\"\n | \"XXL\"\n | \"XXXL\",\n }\n : {}),\n ...(phone ? { phone } : {}),\n })\n );\n } catch (error) {\n setMessage(\n error instanceof Error ? error.message : \"Unable to complete checkout.\"\n );\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <form className=\"lockerverse-payment__form\" onSubmit={submit}>\n <header>\n <h1>{catalog.widget.title ?? catalog.widget.name}</h1>\n {catalog.widget.description ? (\n <p>{catalog.widget.description}</p>\n ) : null}\n </header>\n <div className=\"lockerverse-payment__contact\">\n <label>\n <span>Email</span>\n <input\n autoComplete=\"email\"\n inputMode=\"email\"\n name=\"email\"\n onChange={(event) => setEmail(event.currentTarget.value)}\n placeholder=\"you@example.com\"\n required\n type=\"email\"\n value={email}\n />\n </label>\n {catalog.widget.fields.phone ? (\n <label>\n <span>Phone</span>\n <input\n autoComplete=\"tel\"\n inputMode=\"tel\"\n name=\"phone\"\n onChange={(event) => setPhone(event.currentTarget.value)}\n placeholder=\"+1 555 555 5555\"\n required\n type=\"tel\"\n value={phone}\n />\n </label>\n ) : null}\n {catalog.widget.fields.memberId ? (\n <label>\n <span>Member ID</span>\n <input\n name=\"memberId\"\n onChange={(event) => setMemberId(event.currentTarget.value)}\n required\n type=\"text\"\n value={memberId}\n />\n </label>\n ) : null}\n {catalog.widget.fields.merchSize ? (\n <label>\n <span>Merch size</span>\n <select\n name=\"merchSize\"\n onChange={(event) => setMerchSize(event.currentTarget.value)}\n required\n value={merchSize}\n >\n <option value=\"\">Select…</option>\n {([\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"] as const).map(\n (size) => (\n <option key={size} value={size}>\n {size}\n </option>\n )\n )}\n </select>\n </label>\n ) : null}\n </div>\n <div className=\"lockerverse-payment__address\">\n <h2>Billing information</h2>\n <BillingAddressElement />\n </div>\n {catalog.widget.fields.shipping ? (\n <div className=\"lockerverse-payment__shipping\">\n <h2>Shipping information</h2>\n <ShippingAddressElement />\n </div>\n ) : null}\n <div\n className=\"lockerverse-payment__stripe-element\"\n hidden={totalCents === 0}\n >\n <h2>Payment details</h2>\n <PaymentElement />\n </div>\n {catalog.widget.fields.promoCode ? (\n <div className=\"lockerverse-payment__additional-fields\">\n <label>\n <span>Promo code</span>\n <input\n name=\"promoCode\"\n onChange={(event) => setPromoCode(event.currentTarget.value)}\n placeholder=\"Optional\"\n value={promoCode}\n />\n </label>\n <button disabled={busy} onClick={updateDiscount} type=\"button\">\n {promoCode.trim() ? \"Apply code\" : \"Remove code\"}\n </button>\n </div>\n ) : null}\n {catalog.widget.customFields.length ? (\n <div className=\"lockerverse-payment__custom-fields\">\n <LockerverseCustomFields\n fields={catalog.widget.customFields}\n onChange={(fieldId, value) =>\n setCustomFieldValues((current) => ({\n ...current,\n [fieldId]: value,\n }))\n }\n values={customFieldValues}\n />\n </div>\n ) : null}\n {message ? <div role=\"alert\">{message}</div> : null}\n <div className=\"lockerverse-payment__actions\">\n <button disabled={busy} type=\"submit\">\n {totalCents === 0\n ? \"Complete free order\"\n : `Pay $${(totalCents / 100).toFixed(2)}`}\n </button>\n </div>\n </form>\n );\n}\n\nexport function LockerversePayment(props: LockerversePaymentProps) {\n const {\n apiBaseUrl,\n branding,\n className,\n communitySlug,\n environment,\n fetch,\n includeServiceFee,\n onError,\n onPaymentComplete,\n requestTimeoutMs,\n returnUrl,\n selection,\n sentryDsn,\n unstable_stripeLoader,\n style,\n theme = \"dark\",\n tipCents,\n widgetSlug,\n ...sectionProps\n } = props;\n const destination =\n returnUrl ??\n (typeof globalThis.location === \"undefined\"\n ? \"https://lockerverse.com\"\n : globalThis.location.href);\n const rootClassName = [\"lockerverse-payment\", className]\n .filter(Boolean)\n .join(\" \");\n const clientOptions = apiBaseUrl\n ? { apiBaseUrl, communitySlug, environment, widgetSlug }\n : { communitySlug, environment: \"production\" as const, widgetSlug };\n const rootStyle = branding?.accentColor\n ? ({ ...style, \"--lockerverse-accent\": branding.accentColor } as const)\n : style;\n\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n {branding ? (\n <div className=\"lockerverse-payment__branding\">\n {branding.imageUrl ? (\n <img alt=\"\" height=\"48\" src={branding.imageUrl} width=\"48\" />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n ) : null}\n <LockerverseCheckoutSessionProvider\n {...clientOptions}\n {...(branding?.accentColor\n ? { accentColor: branding.accentColor }\n : {})}\n {...(fetch ? { fetch } : {})}\n {...(includeServiceFee === undefined ? {} : { includeServiceFee })}\n {...(onError ? { onError } : {})}\n {...(requestTimeoutMs === undefined ? {} : { requestTimeoutMs })}\n returnUrl={destination}\n selection={selection}\n {...(sentryDsn === undefined ? {} : { sentryDsn })}\n {...(unstable_stripeLoader ? { unstable_stripeLoader } : {})}\n theme={theme}\n {...(tipCents === undefined ? {} : { tipCents })}\n >\n <LockerverseCheckoutSessionPaymentForm\n {...(onPaymentComplete ? { onComplete: onPaymentComplete } : {})}\n />\n </LockerverseCheckoutSessionProvider>\n </section>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/accent-contrast.ts","../src/checkout-session-form-fields.tsx","../src/checkout-session-loading.tsx","../src/checkout-session-payment.tsx"],"sourcesContent":["const HEX_COLOR = /^#([\\da-f]{3}|[\\da-f]{6})$/i;\n\nfunction parseHexColor(color: string) {\n const match = HEX_COLOR.exec(color.trim());\n if (!match) {\n return;\n }\n const [, value] = match;\n if (!value) {\n return;\n }\n const expanded =\n value.length === 3\n ? Array.from(value, (character) => `${character}${character}`).join(\"\")\n : value;\n return [0, 2, 4].map((offset) =>\n Number.parseInt(expanded.slice(offset, offset + 2), 16)\n );\n}\n\nfunction relativeLuminance([red, green, blue]: number[]) {\n const [linearRed = 0, linearGreen = 0, linearBlue = 0] = [\n red,\n green,\n blue,\n ].map((channel = 0) => {\n const normalized = channel / 255;\n return normalized <= 0.040_45\n ? normalized / 12.92\n : ((normalized + 0.055) / 1.055) ** 2.4;\n });\n return 0.2126 * linearRed + 0.7152 * linearGreen + 0.0722 * linearBlue;\n}\n\nexport function getAccentContrast(color: string) {\n const parsed = parseHexColor(color);\n if (!parsed) {\n return;\n }\n const luminance = relativeLuminance(parsed);\n const blackContrast = (luminance + 0.05) / 0.05;\n const whiteContrast = 1.05 / (luminance + 0.05);\n return blackContrast >= whiteContrast ? \"#000\" : \"#fff\";\n}\n","import type {\n LockerverseCatalog,\n LockerverseCustomField,\n} from \"@lockerverse/sdk/checkout\";\nimport {\n BillingAddressElement,\n PaymentElement,\n ShippingAddressElement,\n} from \"@stripe/react-stripe-js/checkout\";\n\nexport const PHONE_COUNTRIES = [\n { callingCode: \"+1\", label: \"🇺🇸 +1\", value: \"US\" },\n { callingCode: \"+52\", label: \"🇲🇽 +52\", value: \"MX\" },\n { callingCode: \"+380\", label: \"🇺🇦 +380\", value: \"UA\" },\n { callingCode: \"+48\", label: \"🇵🇱 +48\", value: \"PL\" },\n { callingCode: \"+1\", label: \"🇨🇦 +1\", value: \"CA\" },\n { callingCode: \"+49\", label: \"🇩🇪 +49\", value: \"DE\" },\n { callingCode: \"+44\", label: \"🇬🇧 +44\", value: \"GB\" },\n { callingCode: \"+46\", label: \"🇸🇪 +46\", value: \"SE\" },\n { callingCode: \"+358\", label: \"🇫🇮 +358\", value: \"FI\" },\n { callingCode: \"+1\", label: \"🇵🇷 +1\", value: \"PR\" },\n] as const;\n\nexport const TIP_OPTIONS = [\n { label: \"15%\", percent: 15, value: \"15\" },\n { label: \"12%\", percent: 12, value: \"12\" },\n { label: \"10%\", percent: 10, value: \"10\" },\n { label: \"5%\", percent: 5, value: \"5\" },\n { label: \"Other\", percent: null, value: \"custom\" },\n] as const;\n\nfunction StripeElementLoader({ label }: { label: string }) {\n return (\n <div className=\"lockerverse-payment__stripe-loader\" role=\"status\">\n <p>{label}</p>\n <div aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </div>\n </div>\n );\n}\n\nexport function LockerverseCustomFields({\n fields,\n onChange,\n values,\n}: {\n fields: LockerverseCustomField[];\n onChange: (fieldId: string, value: string | string[]) => void;\n values: Record<string, string | string[]>;\n}) {\n return fields.map((field) => {\n const value =\n values[field.id] ??\n (field.type.includes(\"multi\") || field.type === \"checkboxes\" ? [] : \"\");\n if (field.type === \"textarea\") {\n return (\n <label key={field.id}>\n <span>{field.label}</span>\n <textarea\n name={field.id}\n onChange={(event) => onChange(field.id, event.currentTarget.value)}\n required={field.required}\n value={String(value)}\n />\n </label>\n );\n }\n if (field.type === \"select\") {\n return (\n <label key={field.id}>\n <span>{field.label}</span>\n <select\n name={field.id}\n onChange={(event) => onChange(field.id, event.currentTarget.value)}\n required={field.required}\n value={String(value)}\n >\n <option value=\"\">Select…</option>\n {field.options.map((option) => (\n <option key={option.id} value={option.id}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n );\n }\n if (\n field.type === \"radio\" ||\n field.type === \"checkboxes\" ||\n field.type === \"multi_select\"\n ) {\n const selected = Array.isArray(value) ? value : [value];\n return (\n <fieldset key={field.id}>\n <legend>{field.label}</legend>\n {field.options.map((option) => {\n const checked = selected.includes(option.id);\n return (\n <label className=\"lockerverse-payment__choice\" key={option.id}>\n <input\n checked={checked}\n name={field.id}\n onChange={() => {\n if (field.type === \"radio\") {\n onChange(field.id, option.id);\n return;\n }\n onChange(\n field.id,\n checked\n ? selected.filter((id) => id !== option.id)\n : [...selected, option.id]\n );\n }}\n required={field.required && selected.length === 0}\n type={field.type === \"radio\" ? \"radio\" : \"checkbox\"}\n value={option.id}\n />\n <span>{option.label}</span>\n </label>\n );\n })}\n </fieldset>\n );\n }\n return (\n <label key={field.id}>\n <span>{field.label}</span>\n <input\n name={field.id}\n onChange={(event) => onChange(field.id, event.currentTarget.value)}\n required={field.required}\n type=\"text\"\n value={String(value)}\n />\n </label>\n );\n });\n}\n\nexport function TipSelector({\n busy,\n enabled,\n onCustomTipBlur,\n onCustomTipChange,\n onSelect,\n tipInput,\n tipOption,\n}: {\n busy: boolean;\n enabled: boolean;\n onCustomTipBlur: () => Promise<unknown> | undefined;\n onCustomTipChange: (value: string) => void;\n onSelect: (option: (typeof TIP_OPTIONS)[number]) => Promise<void>;\n tipInput: string;\n tipOption: string;\n}) {\n if (!enabled) {\n return null;\n }\n return (\n <div className=\"lockerverse-payment__tip\">\n <strong>Add a tip to support the Lockerverse platform</strong>\n <div aria-label=\"Tip amount\" role=\"radiogroup\">\n {TIP_OPTIONS.map((option) => (\n <button\n aria-pressed={tipOption === option.value}\n disabled={busy}\n key={option.value}\n onClick={() => onSelect(option)}\n type=\"button\"\n >\n {option.label}\n </button>\n ))}\n </div>\n {tipOption === \"custom\" ? (\n <label>\n <span>Custom tip</span>\n <div className=\"lockerverse-payment__money-input\">\n <span aria-hidden=\"true\">$</span>\n <input\n inputMode=\"decimal\"\n name=\"customTip\"\n onBlur={onCustomTipBlur}\n onChange={(event) => onCustomTipChange(event.currentTarget.value)}\n placeholder=\"0.00\"\n value={tipInput}\n />\n </div>\n </label>\n ) : null}\n </div>\n );\n}\n\nexport function ContactFields({\n email,\n fields,\n onEmailChange,\n onPhoneChange,\n onPhoneCountryChange,\n phone,\n phoneCountry,\n}: {\n email: string;\n fields: LockerverseCatalog[\"widget\"][\"fields\"];\n onEmailChange: (value: string) => void;\n onPhoneChange: (value: string) => void;\n onPhoneCountryChange: (value: string) => void;\n phone: string;\n phoneCountry: string;\n}) {\n return (\n <div className=\"lockerverse-payment__contact\">\n <label>\n <span>Email</span>\n <input\n autoComplete=\"email\"\n inputMode=\"email\"\n name=\"email\"\n onChange={(event) => onEmailChange(event.currentTarget.value)}\n placeholder=\"name@example.com\"\n required\n type=\"email\"\n value={email}\n />\n </label>\n {fields.phone ? (\n <label>\n <span>Phone</span>\n <div className=\"lockerverse-payment__phone-control\">\n <select\n aria-label=\"Phone country\"\n name=\"phoneCountry\"\n onChange={(event) =>\n onPhoneCountryChange(event.currentTarget.value)\n }\n value={phoneCountry}\n >\n {PHONE_COUNTRIES.map((country) => (\n <option key={country.value} value={country.value}>\n {country.label}\n </option>\n ))}\n </select>\n <input\n autoComplete=\"tel\"\n inputMode=\"tel\"\n name=\"phone\"\n onChange={(event) => onPhoneChange(event.currentTarget.value)}\n placeholder=\"(201) 555-0123\"\n required\n type=\"tel\"\n value={phone}\n />\n </div>\n </label>\n ) : null}\n </div>\n );\n}\n\nexport function StripeCheckoutFields({\n fields,\n isBillingAddressReady,\n isPaymentReady,\n isShippingAddressReady,\n onBillingAddressReady,\n onPaymentReady,\n onShippingAddressReady,\n onShippingMatchesBillingChange,\n shippingMatchesBilling,\n totalCents,\n}: {\n fields: LockerverseCatalog[\"widget\"][\"fields\"];\n isBillingAddressReady: boolean;\n isPaymentReady: boolean;\n isShippingAddressReady: boolean;\n onBillingAddressReady: () => void;\n onPaymentReady: () => void;\n onShippingAddressReady: () => void;\n onShippingMatchesBillingChange: (value: boolean) => void;\n shippingMatchesBilling: boolean;\n totalCents: number;\n}) {\n return (\n <>\n <div\n className=\"lockerverse-payment__stripe-element\"\n data-ready={isPaymentReady}\n hidden={totalCents === 0}\n >\n {isPaymentReady ? null : (\n <StripeElementLoader label=\"Loading payment form...\" />\n )}\n <div className=\"lockerverse-payment__stripe-mount\">\n <PaymentElement\n onReady={onPaymentReady}\n options={{\n fields: {\n billingDetails: {\n address: \"never\",\n email: \"never\",\n name: \"never\",\n phone: \"never\",\n },\n },\n layout: \"tabs\",\n paymentMethodOrder: [\"card\", \"apple_pay\", \"paypal\"],\n terms: {\n applePay: \"auto\",\n card: \"always\",\n googlePay: \"never\",\n paypal: \"auto\",\n usBankAccount: \"never\",\n },\n wallets: { applePay: \"auto\", googlePay: \"never\" },\n }}\n />\n </div>\n </div>\n <div className=\"lockerverse-payment__address\">\n <h2>Billing address</h2>\n <div\n className=\"lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address\"\n data-ready={isBillingAddressReady}\n >\n {isBillingAddressReady ? null : (\n <StripeElementLoader label=\"Loading billing address...\" />\n )}\n <div className=\"lockerverse-payment__stripe-mount\">\n <BillingAddressElement onReady={onBillingAddressReady} />\n </div>\n </div>\n </div>\n {fields.shipping ? (\n <div className=\"lockerverse-payment__shipping\">\n <label className=\"lockerverse-payment__check-row\">\n <input\n checked={shippingMatchesBilling}\n name=\"shippingMatchesBilling\"\n onChange={(event) =>\n onShippingMatchesBillingChange(event.currentTarget.checked)\n }\n type=\"checkbox\"\n />\n <span>Shipping is same as billing information</span>\n </label>\n {shippingMatchesBilling ? null : (\n <div className=\"lockerverse-payment__address\">\n <h2>Shipping address</h2>\n <div\n className=\"lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address\"\n data-ready={isShippingAddressReady}\n >\n {isShippingAddressReady ? null : (\n <StripeElementLoader label=\"Loading shipping address...\" />\n )}\n <div className=\"lockerverse-payment__stripe-mount\">\n <ShippingAddressElement onReady={onShippingAddressReady} />\n </div>\n </div>\n </div>\n )}\n </div>\n ) : null}\n </>\n );\n}\n\nexport function CustomerFields({\n fields,\n memberId,\n merchSize,\n onMemberIdChange,\n onMerchSizeChange,\n}: {\n fields: LockerverseCatalog[\"widget\"][\"fields\"];\n memberId: string;\n merchSize: string;\n onMemberIdChange: (value: string) => void;\n onMerchSizeChange: (value: string) => void;\n}) {\n return (\n <>\n {fields.memberId ? (\n <label>\n <span>Member ID</span>\n <input\n name=\"memberId\"\n onChange={(event) => onMemberIdChange(event.currentTarget.value)}\n required\n type=\"text\"\n value={memberId}\n />\n </label>\n ) : null}\n {fields.merchSize ? (\n <label>\n <span>Size</span>\n <select\n name=\"merchSize\"\n onChange={(event) => onMerchSizeChange(event.currentTarget.value)}\n required\n value={merchSize}\n >\n {([\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"] as const).map(\n (size) => (\n <option key={size} value={size}>\n {size}\n </option>\n )\n )}\n </select>\n </label>\n ) : null}\n </>\n );\n}\n","function SkeletonLoaderBlock() {\n return (\n <div className=\"lockerverse-payment__skeleton-loader-block\">\n <span className=\"lockerverse-payment__skeleton-loader-label\" />\n <div className=\"lockerverse-payment__skeleton-loader-content\">\n <span className=\"lockerverse-payment__skeleton-loader-full\" />\n <div className=\"lockerverse-payment__skeleton-loader-grid\">\n <span className=\"lockerverse-payment__skeleton-loader-half\" />\n <span className=\"lockerverse-payment__skeleton-loader-half\" />\n </div>\n </div>\n </div>\n );\n}\n\nexport function PaymentSkeleton() {\n return (\n <div className=\"lockerverse-payment__loading\">\n <span className=\"lockerverse-payment__sr-only\" role=\"status\">\n Preparing secure checkout…\n </span>\n <div aria-hidden=\"true\" className=\"lockerverse-payment__skeleton\">\n <div className=\"lockerverse-payment__skeleton-branding\">\n <span className=\"lockerverse-payment__skeleton-avatar\" />\n <span className=\"lockerverse-payment__skeleton-community\" />\n </div>\n <div className=\"lockerverse-payment__skeleton-contact\">\n <div className=\"lockerverse-payment__skeleton-field\">\n <span className=\"lockerverse-payment__skeleton-label\" />\n <span className=\"lockerverse-payment__skeleton-input\" />\n </div>\n <div className=\"lockerverse-payment__skeleton-field\">\n <span className=\"lockerverse-payment__skeleton-label\" />\n <span className=\"lockerverse-payment__skeleton-input\" />\n </div>\n </div>\n <SkeletonLoaderBlock />\n <SkeletonLoaderBlock />\n <div className=\"lockerverse-payment__skeleton-actions\">\n <span className=\"lockerverse-payment__skeleton-check-line\" />\n <span className=\"lockerverse-payment__skeleton-button\" />\n </div>\n </div>\n </div>\n );\n}\n","import type {\n CreateLockerverseWidgetOptions,\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutItem,\n LockerverseCheckoutSession,\n LockerverseCheckoutSessionPricing,\n LockerverseCustomFieldAnswer,\n} from \"@lockerverse/sdk/checkout\";\nimport { createLockerverseCheckoutClient } from \"@lockerverse/sdk/checkout\";\nimport type { StripeCheckoutElementsValue } from \"@stripe/react-stripe-js/checkout\";\nimport {\n CheckoutElementsProvider,\n useCheckoutElements,\n} from \"@stripe/react-stripe-js/checkout\";\nimport { loadStripe } from \"@stripe/stripe-js/pure\";\nimport {\n createContext,\n type FormEvent,\n type PropsWithChildren,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { pipe, regex, safeParse, string } from \"valibot\";\nimport { getAccentContrast } from \"./accent-contrast.ts\";\nimport {\n ContactFields,\n CustomerFields,\n LockerverseCustomFields,\n PHONE_COUNTRIES,\n StripeCheckoutFields,\n TIP_OPTIONS,\n TipSelector,\n} from \"./checkout-session-form-fields.tsx\";\nimport { PaymentSkeleton } from \"./checkout-session-loading.tsx\";\nimport type {\n LockerversePaymentBranding,\n LockerversePaymentCompletion,\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\ntype CheckoutSessionStripeLoader = typeof loadStripe;\n\nexport type LockerverseCheckoutSessionProviderProps =\n CreateLockerverseWidgetOptions &\n PropsWithChildren<{\n accentColor?: string;\n email?: string;\n includeServiceFee?: boolean;\n returnUrl: string;\n selection: LockerversePaymentSelectionItem[];\n unstable_stripeLoader?: CheckoutSessionStripeLoader;\n theme?: \"dark\" | \"light\";\n tipCents?: number;\n }>;\n\ntype LoadedCheckout = {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n includeServiceFee: boolean;\n returnUrl: string;\n session: LockerverseCheckoutSession;\n subtotalCents: number;\n tipCents: number;\n};\n\ntype CheckoutContextValue = {\n applyPromoCode: (promoCode: string) => Promise<string | null>;\n catalog: LockerverseCatalog;\n confirm: (contact: {\n customFieldAnswers?: LockerverseCustomFieldAnswer[];\n email: string;\n memberId?: string;\n merchSize?: \"XS\" | \"S\" | \"M\" | \"L\" | \"XL\" | \"XXL\" | \"XXXL\";\n phone?: string;\n shippingMatchesBilling?: boolean;\n }) => Promise<LockerversePaymentCompletion>;\n paymentReference: string;\n pricing: {\n includeServiceFee: boolean;\n serviceFeeAmountCents: number;\n subtotalCents: number;\n tipCents: number;\n };\n totalCents: number;\n updatePricing: (input: {\n includeServiceFee: boolean;\n tipCents: number;\n }) => Promise<LockerverseCheckoutSessionPricing>;\n};\n\nconst CheckoutContext = createContext<CheckoutContextValue | null>(null);\n\nconst customTipSchema = pipe(string(), regex(/^\\d+(?:\\.\\d{1,2})?$/));\n\nfunction parseCustomTipCents(value: string) {\n const normalized = value.trim();\n if (!normalized) {\n return 0;\n }\n const parsed = safeParse(customTipSchema, normalized);\n if (!parsed.success) {\n return null;\n }\n const [dollars = \"0\", cents = \"\"] = parsed.output.split(\".\");\n const amount = BigInt(dollars) * 100n + BigInt(cents.padEnd(2, \"0\"));\n return amount <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(amount) : null;\n}\n\nfunction formatMoney(amountCents: number) {\n return new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n }).format(amountCents / 100);\n}\n\nfunction getInternationalPhone(phone: string, country: string) {\n const normalized = phone.trim();\n const digits = normalized.replace(/\\D/g, \"\");\n if (normalized.startsWith(\"+\")) {\n return `+${digits}`;\n }\n const callingCode =\n PHONE_COUNTRIES.find((option) => option.value === country)?.callingCode ??\n \"+1\";\n return `${callingCode}${digits}`;\n}\n\nfunction resolveItems(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n) {\n if (!selection.length) {\n throw new Error(\"Select at least one Product before opening checkout.\");\n }\n return selection.map((selected): LockerverseCheckoutItem => {\n const product = catalog.products.find(\n (candidate) => candidate.slug === selected.productSlug\n );\n if (!product) {\n throw new Error(`Product ${selected.productSlug} is unavailable.`);\n }\n return \"amountCents\" in selected\n ? { amountCents: selected.amountCents, productId: product.id }\n : { productId: product.id, quantity: selected.quantity };\n });\n}\n\nfunction getSelectionSubtotalCents(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n) {\n return selection.reduce((total, selected) => {\n if (\"amountCents\" in selected) {\n return total + selected.amountCents;\n }\n const product = catalog.products.find(\n (candidate) => candidate.slug === selected.productSlug\n );\n if (!product || product.amountCents === null) {\n throw new Error(`Product ${selected.productSlug} has invalid pricing.`);\n }\n return total + product.amountCents * selected.quantity;\n }, 0);\n}\n\nfunction createClientOptions(\n props: LockerverseCheckoutSessionProviderProps\n): CreateLockerverseWidgetOptions {\n const common = {\n communitySlug: props.communitySlug,\n ...(props.fetch ? { fetch: props.fetch } : {}),\n ...(props.onError ? { onError: props.onError } : {}),\n ...(props.requestTimeoutMs === undefined\n ? {}\n : { requestTimeoutMs: props.requestTimeoutMs }),\n ...(props.sentryDsn === undefined ? {} : { sentryDsn: props.sentryDsn }),\n widgetSlug: props.widgetSlug,\n };\n return props.apiBaseUrl\n ? {\n ...common,\n apiBaseUrl: props.apiBaseUrl,\n environment: props.environment,\n }\n : { ...common, environment: \"production\" };\n}\n\nfunction createStripeProviderOptions(\n loaded: LoadedCheckout | null,\n accentColor: string | undefined,\n theme: \"dark\" | \"light\" | undefined\n) {\n if (!loaded) {\n return null;\n }\n const accent = accentColor ?? \"#38d77a\";\n const light = theme === \"light\";\n return {\n clientSecret: loaded.session.clientSecret,\n elementsOptions: {\n appearance: {\n rules: {\n \".Input:focus\": {\n borderColor: accent,\n boxShadow: `0 0 0 1px ${accent}`,\n outline: \"none\",\n },\n },\n theme: light ? (\"stripe\" as const) : (\"night\" as const),\n variables: {\n borderRadius: \"10px\",\n colorBackground: light ? \"#f5f6f7\" : \"#121212\",\n colorDanger: light ? \"#c52b3e\" : \"#f08a98\",\n colorPrimary: accent,\n colorText: light ? \"#121416\" : \"#ffffff\",\n colorTextPlaceholder: light ? \"#72767d\" : \"#6b6b6b\",\n colorTextSecondary: light ? \"#62666d\" : \"#a1a1aa\",\n focusBoxShadow: \"none\",\n focusOutline: \"none\",\n fontSizeBase: \"16px\",\n },\n },\n syncAddressCheckbox: \"none\" as const,\n },\n };\n}\n\nfunction CheckoutBridge({\n children,\n loaded,\n}: PropsWithChildren<{ loaded: LoadedCheckout }>) {\n const result = useCheckoutElements();\n if (result.type === \"loading\") {\n return <PaymentSkeleton />;\n }\n if (result.type === \"error\") {\n return <div role=\"alert\">{result.error.message}</div>;\n }\n return (\n <ReadyCheckoutBridge checkout={result.checkout} loaded={loaded}>\n {children}\n </ReadyCheckoutBridge>\n );\n}\n\nfunction initialPricing(loaded: LoadedCheckout) {\n return {\n includeServiceFee: loaded.includeServiceFee,\n serviceFeeAmountCents: Math.round(\n (loaded.subtotalCents *\n loaded.catalog.pricingPolicy.serviceFeeRateBasisPoints) /\n 10_000\n ),\n subtotalCents: loaded.subtotalCents,\n tipCents: loaded.tipCents,\n };\n}\n\nfunction ReadyCheckoutBridge({\n checkout,\n children,\n loaded,\n}: PropsWithChildren<{\n checkout: StripeCheckoutElementsValue;\n loaded: LoadedCheckout;\n}>) {\n const [pricing, setPricing] = useState(() => initialPricing(loaded));\n useEffect(() => {\n setPricing(initialPricing(loaded));\n }, [loaded]);\n const value: CheckoutContextValue = {\n async applyPromoCode(promoCode) {\n const update = await checkout.runServerUpdate(() =>\n loaded.client.updateSessionDiscount({\n paymentReference: loaded.session.paymentReference,\n ...(promoCode.trim() ? { promoCode: promoCode.trim() } : {}),\n })\n );\n return update.type === \"error\" ? update.error.message : null;\n },\n catalog: loaded.catalog,\n async confirm(contact) {\n if (contact.shippingMatchesBilling) {\n if (!checkout.billingAddress) {\n throw new Error(\"Billing address is required.\");\n }\n const addressUpdate = await checkout.updateShippingAddress(\n checkout.billingAddress\n );\n if (addressUpdate.type === \"error\") {\n throw new Error(addressUpdate.error.message);\n }\n }\n const detailsUpdate = await checkout.runServerUpdate(() =>\n loaded.client.updateSessionDetails({\n ...(contact.customFieldAnswers\n ? { customFieldAnswers: contact.customFieldAnswers }\n : {}),\n email: contact.email,\n ...(contact.memberId ? { memberId: contact.memberId } : {}),\n ...(contact.merchSize ? { merchSize: contact.merchSize } : {}),\n paymentReference: loaded.session.paymentReference,\n ...(contact.phone ? { phone: contact.phone } : {}),\n })\n );\n if (detailsUpdate.type === \"error\") {\n throw new Error(detailsUpdate.error.message);\n }\n const prepared = await prepareCheckoutContact(\n checkout,\n contact.email,\n contact.phone ?? \"\",\n checkout.total.total.minorUnitsAmount > 0\n );\n if (\"error\" in prepared) {\n throw new Error(prepared.error);\n }\n const confirmation = await checkout.confirm({\n email: prepared.email,\n ...(prepared.phone ? { phoneNumber: prepared.phone } : {}),\n redirect: \"if_required\",\n });\n if (confirmation.type === \"error\") {\n throw new Error(confirmation.error.message);\n }\n return {\n paymentReference: loaded.session.paymentReference,\n sessionId: loaded.session.sessionId,\n };\n },\n paymentReference: loaded.session.paymentReference,\n pricing,\n totalCents: checkout.total.total.minorUnitsAmount,\n async updatePricing(input) {\n let updatedPricing: LockerverseCheckoutSessionPricing | undefined;\n const update = await checkout.runServerUpdate(() =>\n loaded.client\n .updateSessionPricing({\n ...input,\n paymentReference: loaded.session.paymentReference,\n })\n .then((response) => {\n updatedPricing = response;\n return response;\n })\n );\n if (update.type === \"error\") {\n throw new Error(update.error.message);\n }\n if (!updatedPricing) {\n throw new Error(\"Lockerverse returned no updated pricing.\");\n }\n const nextPricing = updatedPricing;\n setPricing((current) => ({\n ...current,\n includeServiceFee: nextPricing.includeServiceFee,\n tipCents: nextPricing.tipCents,\n }));\n return nextPricing;\n },\n };\n return (\n <CheckoutContext.Provider value={value}>\n {children}\n </CheckoutContext.Provider>\n );\n}\n\nexport function LockerverseCheckoutSessionProvider(\n props: LockerverseCheckoutSessionProviderProps\n) {\n const [loaded, setLoaded] = useState<LoadedCheckout | null>(null);\n const [failure, setFailure] = useState<string | null>(null);\n const [revision, setRevision] = useState(0);\n const preparation = useRef<{\n clientOptions: CreateLockerverseWidgetOptions;\n promise: Promise<LoadedCheckout>;\n } | null>(null);\n const currentCheckoutKey = JSON.stringify({\n email: props.email,\n includeServiceFee: props.includeServiceFee,\n returnUrl: props.returnUrl,\n selection: props.selection,\n tipCents: props.tipCents,\n });\n const initialCheckout = useRef({\n email: props.email,\n includeServiceFee: props.includeServiceFee,\n key: currentCheckoutKey,\n requestKey: globalThis.crypto.randomUUID(),\n returnUrl: props.returnUrl,\n selection: props.selection,\n tipCents: props.tipCents,\n });\n const clientOptions = useMemo(\n () => createClientOptions(props),\n [\n props.apiBaseUrl,\n props.communitySlug,\n props.environment,\n props.fetch,\n props.onError,\n props.requestTimeoutMs,\n props.sentryDsn,\n props.widgetSlug,\n ]\n );\n\n useEffect(() => {\n let active = true;\n if (preparation.current?.clientOptions !== clientOptions || revision > 0) {\n const client = createLockerverseCheckoutClient(clientOptions);\n const checkoutInput = initialCheckout.current;\n preparation.current = {\n clientOptions,\n promise: (async () => {\n const catalog = await client.load();\n const items = resolveItems(catalog, checkoutInput.selection);\n const subtotalCents = getSelectionSubtotalCents(\n catalog,\n checkoutInput.selection\n );\n const includeServiceFee =\n checkoutInput.includeServiceFee ?? catalog.widget.fields.serviceFee;\n const tipCents =\n checkoutInput.tipCents ??\n (catalog.widget.fields.tipping\n ? Math.round(subtotalCents * 0.1)\n : 0);\n const session = await client.createSession({\n ...(checkoutInput.email ? { email: checkoutInput.email } : {}),\n ...(catalog.widget.fields.serviceFee ? { includeServiceFee } : {}),\n items,\n requestKey: checkoutInput.requestKey,\n returnUrl: checkoutInput.returnUrl,\n ...(catalog.widget.fields.tipping ? { tipCents } : {}),\n });\n return {\n catalog,\n client,\n includeServiceFee,\n returnUrl: checkoutInput.returnUrl,\n session,\n subtotalCents,\n tipCents,\n };\n })(),\n };\n }\n setLoaded(null);\n setFailure(null);\n preparation.current.promise\n .then((next) => {\n if (active) {\n setLoaded(next);\n }\n })\n .catch((error: unknown) => {\n if (active) {\n setFailure(\n error instanceof Error ? error.message : \"Unable to load checkout.\"\n );\n }\n });\n return () => {\n active = false;\n };\n }, [clientOptions, revision]);\n\n const stripe = useMemo(() => {\n if (!loaded) {\n return null;\n }\n const stripeLoader = props.unstable_stripeLoader ?? loadStripe;\n return stripeLoader(loaded.catalog.payment.publishableKey, {\n betas: [\"custom_checkout_server_updates_1\"],\n ...(loaded.session.connectedAccountId\n ? { stripeAccount: loaded.session.connectedAccountId }\n : {}),\n });\n }, [loaded, props.unstable_stripeLoader]);\n const providerOptions = useMemo(\n () => createStripeProviderOptions(loaded, props.accentColor, props.theme),\n [loaded, props.accentColor, props.theme]\n );\n\n if (currentCheckoutKey !== initialCheckout.current.key) {\n return (\n <div className=\"lockerverse-payment__payment-status\" role=\"alert\">\n Checkout selection changed. Remount this payment component for the new\n selection.\n </div>\n );\n }\n if (failure) {\n return (\n <div className=\"lockerverse-payment__payment-status\" role=\"alert\">\n <p>{failure}</p>\n <button onClick={() => setRevision((value) => value + 1)} type=\"button\">\n Try again\n </button>\n </div>\n );\n }\n if (!(loaded && providerOptions)) {\n return <PaymentSkeleton />;\n }\n\n return (\n <CheckoutElementsProvider options={providerOptions} stripe={stripe}>\n <CheckoutBridge loaded={loaded}>{props.children}</CheckoutBridge>\n </CheckoutElementsProvider>\n );\n}\n\nexport function useLockerverseCheckoutSession() {\n const value = useContext(CheckoutContext);\n if (!value) {\n throw new Error(\n \"useLockerverseCheckoutSession must be used inside LockerverseCheckoutSessionProvider.\"\n );\n }\n return value;\n}\n\nasync function prepareCheckoutContact(\n checkout: StripeCheckoutElementsValue,\n email: string,\n phone: string,\n requirePaymentDetails: boolean\n) {\n const normalizedEmail = email.trim().toLowerCase();\n if (!normalizedEmail) {\n return { error: \"Email is required.\" } as const;\n }\n const emailResult = await checkout.updateEmail(normalizedEmail);\n if (emailResult.type === \"error\") {\n return { error: emailResult.error.message } as const;\n }\n const normalizedPhone = phone.trim();\n if (normalizedPhone) {\n const phoneResult = await checkout.updatePhoneNumber(normalizedPhone);\n if (phoneResult.type === \"error\") {\n return { error: \"Phone number is invalid.\" } as const;\n }\n }\n if (requirePaymentDetails) {\n const validation = await checkout.validateElements();\n if (validation.type === \"error\") {\n return { error: validation.error.message } as const;\n }\n }\n return { email: normalizedEmail, phone: normalizedPhone } as const;\n}\n\nfunction getPaymentButtonLabel(totalCents: number, tipCents: number) {\n if (totalCents === 0) {\n return \"Complete free order\";\n }\n if (tipCents > 0) {\n return `Process Payment ($${((totalCents - tipCents) / 100).toFixed(2)}) + $${(tipCents / 100).toFixed(2)} tip`;\n }\n return `Process Payment ($${(totalCents / 100).toFixed(2)})`;\n}\n\nfunction buildCheckoutContact({\n catalog,\n customFieldValues,\n email,\n memberId,\n merchSize,\n phone,\n phoneCountry,\n shippingMatchesBilling,\n}: {\n catalog: LockerverseCatalog;\n customFieldValues: Record<string, string | string[]>;\n email: string;\n memberId: string;\n merchSize: string;\n phone: string;\n phoneCountry: string;\n shippingMatchesBilling: boolean;\n}): Parameters<CheckoutContextValue[\"confirm\"]>[0] {\n return {\n customFieldAnswers: catalog.widget.customFields.map((field) => ({\n fieldId: field.id,\n value: customFieldValues[field.id] ?? null,\n })) as LockerverseCustomFieldAnswer[],\n email,\n ...(memberId ? { memberId } : {}),\n ...(merchSize\n ? {\n merchSize: merchSize as\n | \"XS\"\n | \"S\"\n | \"M\"\n | \"L\"\n | \"XL\"\n | \"XXL\"\n | \"XXXL\",\n }\n : {}),\n ...(phone ? { phone: getInternationalPhone(phone, phoneCountry) } : {}),\n ...(catalog.widget.fields.shipping ? { shippingMatchesBilling } : {}),\n };\n}\n\nexport function LockerverseCheckoutSessionPaymentForm({\n branding,\n onComplete,\n}: {\n branding?: LockerversePaymentBranding;\n onComplete?: (result: LockerversePaymentCompletion) => void;\n}) {\n const {\n applyPromoCode,\n catalog,\n confirm,\n pricing,\n totalCents,\n updatePricing,\n } = useLockerverseCheckoutSession();\n const [email, setEmail] = useState(\"\");\n const [phone, setPhone] = useState(\"\");\n const [phoneCountry, setPhoneCountry] = useState(\"US\");\n const [memberId, setMemberId] = useState(\"\");\n const [merchSize, setMerchSize] = useState(\"M\");\n const [customFieldValues, setCustomFieldValues] = useState<\n Record<string, string | string[]>\n >({});\n const [promoCode, setPromoCode] = useState(\"\");\n const [message, setMessage] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n const [pricingBusy, setPricingBusy] = useState(false);\n const [isBillingAddressReady, setIsBillingAddressReady] = useState(false);\n const [isPaymentReady, setIsPaymentReady] = useState(false);\n const [isShippingAddressReady, setIsShippingAddressReady] = useState(false);\n const [shippingMatchesBilling, setShippingMatchesBilling] = useState(true);\n const initialTipOption =\n TIP_OPTIONS.find(\n (option) =>\n option.percent !== null &&\n Math.round((pricing.subtotalCents * option.percent) / 100) ===\n pricing.tipCents\n )?.value ?? \"custom\";\n const [tipOption, setTipOption] = useState(initialTipOption);\n const [tipInput, setTipInput] = useState(\n initialTipOption === \"custom\" && pricing.tipCents > 0\n ? (pricing.tipCents / 100).toFixed(2)\n : \"\"\n );\n const committedPricing = useRef({\n includeServiceFee: pricing.includeServiceFee,\n tipCents: pricing.tipCents,\n });\n const pendingPricing = useRef<Promise<boolean>>(Promise.resolve(true));\n useEffect(() => {\n committedPricing.current = {\n includeServiceFee: pricing.includeServiceFee,\n tipCents: pricing.tipCents,\n };\n }, [pricing.includeServiceFee, pricing.tipCents]);\n\n function savePricing(next: { includeServiceFee: boolean; tipCents: number }) {\n const operation = (async () => {\n setPricingBusy(true);\n setMessage(null);\n try {\n const updated = await updatePricing(next);\n committedPricing.current = {\n includeServiceFee: updated.includeServiceFee,\n tipCents: updated.tipCents,\n };\n return true;\n } catch (error) {\n setMessage(\n error instanceof Error ? error.message : \"Unable to update checkout.\"\n );\n return false;\n } finally {\n setPricingBusy(false);\n }\n })();\n pendingPricing.current = operation;\n return operation;\n }\n\n async function selectTip(option: (typeof TIP_OPTIONS)[number]) {\n if (option.percent === null) {\n setTipOption(option.value);\n return;\n }\n const nextTipCents = Math.round(\n (pricing.subtotalCents * option.percent) / 100\n );\n const updated = await savePricing({\n includeServiceFee: pricing.includeServiceFee,\n tipCents: nextTipCents,\n });\n if (updated) {\n setTipInput(\"\");\n setTipOption(option.value);\n }\n }\n\n function applyCustomTip() {\n const nextTipCents = parseCustomTipCents(tipInput);\n if (nextTipCents === null) {\n setMessage(\"Enter a valid tip with no more than two decimal places.\");\n return;\n }\n return savePricing({\n includeServiceFee: pricing.includeServiceFee,\n tipCents: nextTipCents,\n });\n }\n\n async function changeServiceFee(nextIncludeServiceFee: boolean) {\n await savePricing({\n includeServiceFee: nextIncludeServiceFee,\n tipCents: pricing.tipCents,\n });\n }\n async function updateDiscount() {\n setBusy(true);\n setMessage(null);\n try {\n setMessage(await applyPromoCode(promoCode));\n } catch (error) {\n setMessage(\n error instanceof Error ? error.message : \"Unable to update checkout.\"\n );\n } finally {\n setBusy(false);\n }\n }\n\n async function commitPricingBeforeSubmit() {\n if (!(await pendingPricing.current)) {\n return false;\n }\n if (tipOption !== \"custom\") {\n return true;\n }\n const nextTipCents = parseCustomTipCents(tipInput);\n if (nextTipCents === null) {\n setMessage(\"Enter a valid tip with no more than two decimal places.\");\n return false;\n }\n if (nextTipCents === committedPricing.current.tipCents) {\n return true;\n }\n return savePricing({\n includeServiceFee: committedPricing.current.includeServiceFee,\n tipCents: nextTipCents,\n });\n }\n\n async function submit(event: FormEvent) {\n event.preventDefault();\n setBusy(true);\n setMessage(null);\n try {\n if (!(await commitPricingBeforeSubmit())) {\n return;\n }\n const completion = await confirm(\n buildCheckoutContact({\n catalog,\n customFieldValues,\n email,\n memberId,\n merchSize,\n phone,\n phoneCountry,\n shippingMatchesBilling,\n })\n );\n onComplete?.(completion);\n } catch (error) {\n setMessage(\n error instanceof Error ? error.message : \"Unable to complete checkout.\"\n );\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <form className=\"lockerverse-payment__form\" onSubmit={submit}>\n <header>\n {catalog.widget.showCommunityBranding && branding ? (\n <div className=\"lockerverse-payment__branding\">\n {branding.imageUrl ? (\n <img\n alt={branding.name}\n height=\"48\"\n src={branding.imageUrl}\n width=\"48\"\n />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n ) : null}\n <h1>{catalog.widget.title ?? catalog.widget.name}</h1>\n {catalog.widget.description ? (\n <p>{catalog.widget.description}</p>\n ) : null}\n </header>\n <TipSelector\n busy={busy || pricingBusy}\n enabled={catalog.widget.fields.tipping}\n onCustomTipBlur={applyCustomTip}\n onCustomTipChange={setTipInput}\n onSelect={selectTip}\n tipInput={tipInput}\n tipOption={tipOption}\n />\n <ContactFields\n email={email}\n fields={catalog.widget.fields}\n onEmailChange={setEmail}\n onPhoneChange={setPhone}\n onPhoneCountryChange={setPhoneCountry}\n phone={phone}\n phoneCountry={phoneCountry}\n />\n <StripeCheckoutFields\n fields={catalog.widget.fields}\n isBillingAddressReady={isBillingAddressReady}\n isPaymentReady={isPaymentReady}\n isShippingAddressReady={isShippingAddressReady}\n onBillingAddressReady={() => setIsBillingAddressReady(true)}\n onPaymentReady={() => setIsPaymentReady(true)}\n onShippingAddressReady={() => setIsShippingAddressReady(true)}\n onShippingMatchesBillingChange={(value) => {\n setShippingMatchesBilling(value);\n if (!value) {\n setIsShippingAddressReady(false);\n }\n }}\n shippingMatchesBilling={shippingMatchesBilling}\n totalCents={totalCents}\n />\n <CustomerFields\n fields={catalog.widget.fields}\n memberId={memberId}\n merchSize={merchSize}\n onMemberIdChange={setMemberId}\n onMerchSizeChange={setMerchSize}\n />\n {catalog.widget.fields.promoCode ? (\n <div className=\"lockerverse-payment__additional-fields\">\n <label>\n <span>Promo code</span>\n <input\n name=\"promoCode\"\n onChange={(event) => setPromoCode(event.currentTarget.value)}\n placeholder=\"Optional\"\n value={promoCode}\n />\n </label>\n <button disabled={busy} onClick={updateDiscount} type=\"button\">\n {promoCode.trim() ? \"Apply code\" : \"Remove code\"}\n </button>\n </div>\n ) : null}\n {catalog.widget.customFields.length ? (\n <div className=\"lockerverse-payment__custom-fields\">\n <LockerverseCustomFields\n fields={catalog.widget.customFields}\n onChange={(fieldId, value) =>\n setCustomFieldValues((current) => ({\n ...current,\n [fieldId]: value,\n }))\n }\n values={customFieldValues}\n />\n </div>\n ) : null}\n {message ? <div role=\"alert\">{message}</div> : null}\n <div className=\"lockerverse-payment__actions\">\n {catalog.widget.fields.serviceFee ? (\n <label className=\"lockerverse-payment__check-row\">\n <input\n checked={pricing.includeServiceFee}\n disabled={busy || pricingBusy}\n name=\"includeServiceFee\"\n onChange={(event) =>\n changeServiceFee(event.currentTarget.checked)\n }\n type=\"checkbox\"\n />\n <span>\n Add {formatMoney(pricing.serviceFeeAmountCents)} to help cover\n processing fees\n </span>\n </label>\n ) : null}\n <button disabled={busy} type=\"submit\">\n {getPaymentButtonLabel(totalCents, pricing.tipCents)}\n </button>\n </div>\n </form>\n );\n}\n\nexport function LockerversePayment(props: LockerversePaymentProps) {\n const {\n apiBaseUrl,\n branding,\n className,\n communitySlug,\n environment,\n fetch,\n includeServiceFee,\n onError,\n onPaymentComplete,\n requestTimeoutMs,\n returnUrl,\n selection,\n sentryDsn,\n unstable_stripeLoader,\n style,\n theme = \"dark\",\n tipCents,\n widgetSlug,\n ...sectionProps\n } = props;\n const destination =\n returnUrl ??\n (typeof globalThis.location === \"undefined\"\n ? \"https://lockerverse.com\"\n : globalThis.location.href);\n const rootClassName = [\"lockerverse-payment\", className]\n .filter(Boolean)\n .join(\" \");\n const clientOptions = apiBaseUrl\n ? { apiBaseUrl, communitySlug, environment, widgetSlug }\n : { communitySlug, environment: \"production\" as const, widgetSlug };\n const rootStyle = branding?.accentColor\n ? ({\n ...style,\n \"--lockerverse-accent\": branding.accentColor,\n \"--lockerverse-accent-contrast\":\n getAccentContrast(branding.accentColor) ?? \"#08110c\",\n } as const)\n : style;\n\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n <LockerverseCheckoutSessionProvider\n {...clientOptions}\n {...(branding?.accentColor\n ? { accentColor: branding.accentColor }\n : {})}\n {...(fetch ? { fetch } : {})}\n {...(includeServiceFee === undefined ? {} : { includeServiceFee })}\n {...(onError ? { onError } : {})}\n {...(requestTimeoutMs === undefined ? {} : { requestTimeoutMs })}\n returnUrl={destination}\n selection={selection}\n {...(sentryDsn === undefined ? {} : { sentryDsn })}\n {...(unstable_stripeLoader ? { unstable_stripeLoader } : {})}\n theme={theme}\n {...(tipCents === undefined ? {} : { tipCents })}\n >\n <LockerverseCheckoutSessionPaymentForm\n {...(branding ? { branding } : {})}\n {...(onPaymentComplete ? { onComplete: onPaymentComplete } : {})}\n />\n </LockerverseCheckoutSessionProvider>\n </section>\n );\n}\n"],"mappings":"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"}
package/dist/styles.css CHANGED
@@ -1,21 +1,24 @@
1
1
  .lockerverse-payment {
2
2
  --lockerverse-accent: #38d77a;
3
- --lockerverse-accent-contrast: #08110c;
3
+ --lockerverse-accent-contrast: #000;
4
4
  --lockerverse-bg: #080808;
5
- --lockerverse-border: rgb(255 255 255 / 14%);
6
- --lockerverse-control: #151515;
5
+ --lockerverse-border: rgb(255 255 255 / 12%);
6
+ --lockerverse-control: #121212;
7
7
  --lockerverse-danger: #f08a98;
8
+ --lockerverse-danger-border: #8f3542;
8
9
  --lockerverse-font-family:
9
10
  ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
10
11
  sans-serif;
11
12
  --lockerverse-muted: rgb(255 255 255 / 64%);
12
- --lockerverse-placeholder: rgb(255 255 255 / 38%);
13
+ --lockerverse-placeholder: rgb(255 255 255 / 34%);
13
14
  --lockerverse-radius: 10px;
15
+ --lockerverse-subtle: rgb(255 255 255 / 8%);
14
16
  --lockerverse-text: #fff;
15
17
  box-sizing: border-box;
16
18
  width: 100%;
17
19
  max-width: 480px;
18
- padding: 20px;
20
+ padding: clamp(16px, 4.2%, 20px);
21
+ container-type: inline-size;
19
22
  font-family: var(--lockerverse-font-family);
20
23
  font-size: 15px;
21
24
  line-height: 1.4;
@@ -26,11 +29,13 @@
26
29
 
27
30
  .lockerverse-payment[data-lockerverse-theme="light"] {
28
31
  --lockerverse-bg: #fff;
29
- --lockerverse-border: rgb(18 20 22 / 15%);
30
- --lockerverse-control: #f4f5f6;
32
+ --lockerverse-border: rgb(18 20 22 / 14%);
33
+ --lockerverse-control: #f5f6f7;
31
34
  --lockerverse-danger: #c52b3e;
35
+ --lockerverse-danger-border: #b64656;
32
36
  --lockerverse-muted: rgb(18 20 22 / 64%);
33
- --lockerverse-placeholder: rgb(18 20 22 / 40%);
37
+ --lockerverse-placeholder: rgb(18 20 22 / 38%);
38
+ --lockerverse-subtle: rgb(18 20 22 / 8%);
34
39
  --lockerverse-text: #121416;
35
40
  box-shadow: 0 18px 55px rgb(20 25 32 / 10%);
36
41
  }
@@ -48,31 +53,24 @@
48
53
  }
49
54
 
50
55
  .lockerverse-payment header {
51
- margin-bottom: 4px;
56
+ margin-bottom: 20px;
52
57
  }
53
58
 
54
59
  .lockerverse-payment h1 {
55
60
  font-size: 24px;
56
61
  font-weight: 600;
57
- line-height: 1.33;
62
+ line-height: 1.333;
63
+ letter-spacing: 0;
58
64
  }
59
65
 
60
66
  .lockerverse-payment header p {
61
- margin-top: 10px;
67
+ margin-top: 12px;
62
68
  font-size: 14px;
63
69
  line-height: 1.55;
64
70
  color: var(--lockerverse-muted);
65
71
  white-space: pre-line;
66
72
  }
67
73
 
68
- .lockerverse-payment h2,
69
- .lockerverse-payment label > span {
70
- font-size: 14px;
71
- font-weight: 600;
72
- line-height: 1.45;
73
- color: var(--lockerverse-text);
74
- }
75
-
76
74
  .lockerverse-payment__branding {
77
75
  display: flex;
78
76
  gap: 12px;
@@ -80,24 +78,27 @@
80
78
  min-width: 0;
81
79
  margin-bottom: 16px;
82
80
  font-size: 18px;
81
+ line-height: 1.25;
83
82
  }
84
83
 
85
84
  .lockerverse-payment__branding img {
86
85
  width: 48px;
87
86
  height: 48px;
88
87
  object-fit: cover;
89
- border: 1px solid var(--lockerverse-border);
88
+ border: 1px solid var(--lockerverse-subtle);
90
89
  border-radius: var(--lockerverse-radius);
91
90
  }
92
91
 
93
92
  .lockerverse-payment__branding strong {
94
93
  overflow: hidden;
95
94
  text-overflow: ellipsis;
95
+ font-weight: 600;
96
96
  white-space: nowrap;
97
97
  }
98
98
 
99
99
  .lockerverse-payment__form,
100
100
  .lockerverse-payment__contact,
101
+ .lockerverse-payment__tip,
101
102
  .lockerverse-payment__additional-fields,
102
103
  .lockerverse-payment__custom-fields,
103
104
  .lockerverse-payment__address,
@@ -109,26 +110,103 @@
109
110
  }
110
111
 
111
112
  .lockerverse-payment__form {
112
- gap: 18px;
113
+ gap: 16px;
114
+ }
115
+
116
+ .lockerverse-payment__tip {
117
+ gap: 10px;
118
+ padding: 12px;
119
+ background: color-mix(in srgb, var(--lockerverse-control) 88%, transparent);
120
+ border: 1px solid var(--lockerverse-subtle);
121
+ border-radius: var(--lockerverse-radius);
122
+ }
123
+
124
+ .lockerverse-payment__tip > strong {
125
+ padding-bottom: 2px;
126
+ font-size: 15px;
127
+ font-weight: 600;
128
+ }
129
+
130
+ .lockerverse-payment__tip > div[role="radiogroup"] {
131
+ display: grid;
132
+ grid-template-columns: repeat(5, minmax(0, 1fr));
133
+ gap: 6px;
134
+ }
135
+
136
+ .lockerverse-payment__money-input {
137
+ position: relative;
138
+ }
139
+
140
+ .lockerverse-payment__money-input > span {
141
+ position: absolute;
142
+ top: 50%;
143
+ left: 13px;
144
+ z-index: 1;
145
+ color: var(--lockerverse-placeholder);
146
+ pointer-events: none;
147
+ transform: translateY(-50%);
148
+ }
149
+
150
+ .lockerverse-payment__money-input
151
+ input:not([type="checkbox"]):not([type="radio"]) {
152
+ padding-left: 28px;
153
+ }
154
+
155
+ .lockerverse-payment__contact {
156
+ gap: 8px;
157
+ padding-top: 14px;
158
+ border-top: 1px solid var(--lockerverse-subtle);
159
+ }
160
+
161
+ .lockerverse-payment__contact label:not(:first-child) {
162
+ margin-top: 4px;
113
163
  }
114
164
 
115
- .lockerverse-payment__contact,
116
165
  .lockerverse-payment__additional-fields,
117
166
  .lockerverse-payment__custom-fields,
118
167
  .lockerverse-payment__shipping,
119
168
  .lockerverse-payment__actions {
120
- gap: 14px;
169
+ gap: 16px;
121
170
  }
122
171
 
123
172
  .lockerverse-payment__address,
124
- .lockerverse-payment__stripe-element,
125
- .lockerverse-payment label {
173
+ .lockerverse-payment__stripe-element {
174
+ gap: 12px;
175
+ }
176
+
177
+ .lockerverse-payment label,
178
+ .lockerverse-payment fieldset {
126
179
  gap: 8px;
127
180
  }
128
181
 
129
- .lockerverse-payment__contact {
130
- padding-top: 16px;
131
- border-top: 1px solid var(--lockerverse-border);
182
+ .lockerverse-payment__actions {
183
+ padding: 4px 0;
184
+ margin-top: 4px;
185
+ }
186
+
187
+ .lockerverse-payment label > span,
188
+ .lockerverse-payment legend,
189
+ .lockerverse-payment h2 {
190
+ font-size: 14px;
191
+ font-weight: 500;
192
+ line-height: 1.45;
193
+ color: color-mix(in srgb, var(--lockerverse-text) 82%, transparent);
194
+ }
195
+
196
+ .lockerverse-payment h2 {
197
+ font-weight: 600;
198
+ color: var(--lockerverse-text);
199
+ }
200
+
201
+ .lockerverse-payment fieldset {
202
+ display: grid;
203
+ padding: 0;
204
+ margin: 0;
205
+ border: 0;
206
+ }
207
+
208
+ .lockerverse-payment legend {
209
+ margin-bottom: 8px;
132
210
  }
133
211
 
134
212
  .lockerverse-payment input:not([type="checkbox"]):not([type="radio"]),
@@ -141,32 +219,130 @@
141
219
  font-size: 16px;
142
220
  line-height: 1.5;
143
221
  color: var(--lockerverse-text);
222
+ appearance: none;
144
223
  outline: none;
145
- background: var(--lockerverse-control);
224
+ background-color: var(--lockerverse-control);
146
225
  border: 1px solid var(--lockerverse-border);
147
226
  border-radius: var(--lockerverse-radius);
227
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 4%);
148
228
  transition:
149
- border-color 120ms ease,
150
- box-shadow 120ms ease;
229
+ border-color 140ms ease,
230
+ box-shadow 140ms ease;
231
+ }
232
+
233
+ .lockerverse-payment select {
234
+ padding-right: 38px;
235
+ background-image:
236
+ linear-gradient(45deg, transparent 50%, currentcolor 50%),
237
+ linear-gradient(135deg, currentcolor 50%, transparent 50%);
238
+ background-repeat: no-repeat;
239
+ background-position:
240
+ calc(100% - 17px) calc(50% - 2px),
241
+ calc(100% - 12px) calc(50% - 2px);
242
+ background-size:
243
+ 5px 5px,
244
+ 5px 5px;
151
245
  }
152
246
 
153
247
  .lockerverse-payment textarea {
154
248
  min-height: 112px;
249
+ padding-top: 12px;
155
250
  resize: vertical;
156
251
  }
157
252
 
158
- .lockerverse-payment fieldset {
253
+ .lockerverse-payment input::placeholder,
254
+ .lockerverse-payment textarea::placeholder {
255
+ color: var(--lockerverse-placeholder);
256
+ opacity: 1;
257
+ }
258
+
259
+ .lockerverse-payment input:not([type="checkbox"]):not([type="radio"]):focus,
260
+ .lockerverse-payment select:focus,
261
+ .lockerverse-payment textarea:focus,
262
+ .lockerverse-payment button:focus {
263
+ outline: none;
264
+ border-color: var(--lockerverse-accent);
265
+ }
266
+
267
+ .lockerverse-payment input:not([type="checkbox"]):not([type="radio"]):focus,
268
+ .lockerverse-payment select:focus,
269
+ .lockerverse-payment textarea:focus {
270
+ box-shadow: 0 0 0 1px var(--lockerverse-accent);
271
+ }
272
+
273
+ .lockerverse-payment
274
+ input:not([type="checkbox"]):not([type="radio"]):focus-visible,
275
+ .lockerverse-payment select:focus-visible,
276
+ .lockerverse-payment textarea:focus-visible,
277
+ .lockerverse-payment button:focus-visible {
278
+ box-shadow: 0 0 0 2px
279
+ color-mix(in srgb, var(--lockerverse-accent) 24%, transparent);
280
+ }
281
+
282
+ .lockerverse-payment [aria-invalid="true"] {
283
+ border-color: var(--lockerverse-danger-border) !important;
284
+ }
285
+
286
+ .lockerverse-payment__phone-control {
159
287
  display: grid;
160
- gap: 8px;
161
- padding: 0;
162
- margin: 0;
288
+ grid-template-columns: 84px minmax(0, 1fr);
289
+ overflow: hidden;
290
+ background: var(--lockerverse-control);
291
+ border: 1px solid var(--lockerverse-border);
292
+ border-radius: var(--lockerverse-radius);
293
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 4%);
294
+ transition:
295
+ border-color 140ms ease,
296
+ box-shadow 140ms ease;
297
+ }
298
+
299
+ .lockerverse-payment__phone-control:focus-within {
300
+ border-color: var(--lockerverse-accent);
301
+ box-shadow:
302
+ inset 0 1px 0 rgb(255 255 255 / 4%),
303
+ 0 0 0 1px var(--lockerverse-accent);
304
+ }
305
+
306
+ .lockerverse-payment__phone-control:has(:focus-visible) {
307
+ box-shadow: 0 0 0 2px
308
+ color-mix(in srgb, var(--lockerverse-accent) 24%, transparent);
309
+ }
310
+
311
+ .lockerverse-payment__phone-control select,
312
+ .lockerverse-payment__phone-control
313
+ input:not([type="checkbox"]):not([type="radio"]) {
314
+ min-width: 0;
315
+ background-color: transparent;
163
316
  border: 0;
317
+ box-shadow: none;
164
318
  }
165
319
 
166
- .lockerverse-payment legend {
167
- margin-bottom: 8px;
168
- font-size: 14px;
169
- font-weight: 600;
320
+ .lockerverse-payment__phone-control select {
321
+ padding-right: 25px;
322
+ padding-left: 10px;
323
+ background-position:
324
+ calc(100% - 12px) calc(50% - 2px),
325
+ calc(100% - 7px) calc(50% - 2px);
326
+ border-right: 1px solid var(--lockerverse-border);
327
+ border-radius: var(--lockerverse-radius) 0 0 var(--lockerverse-radius);
328
+ }
329
+
330
+ .lockerverse-payment__phone-control
331
+ input:not([type="checkbox"]):not([type="radio"]) {
332
+ border-radius: 0 var(--lockerverse-radius) var(--lockerverse-radius) 0;
333
+ }
334
+
335
+ .lockerverse-payment__phone-control select:focus,
336
+ .lockerverse-payment__phone-control
337
+ input:not([type="checkbox"]):not([type="radio"]):focus,
338
+ .lockerverse-payment__phone-control select:focus-visible,
339
+ .lockerverse-payment__phone-control
340
+ input:not([type="checkbox"]):not([type="radio"]):focus-visible {
341
+ box-shadow: none;
342
+ }
343
+
344
+ .lockerverse-payment__phone-control:focus-within select {
345
+ border-right-color: var(--lockerverse-accent);
170
346
  }
171
347
 
172
348
  .lockerverse-payment__choice {
@@ -176,16 +352,69 @@
176
352
  align-items: center;
177
353
  }
178
354
 
179
- .lockerverse-payment input::placeholder {
180
- color: var(--lockerverse-placeholder);
355
+ .lockerverse-payment__choice input {
356
+ flex: 0 0 auto;
357
+ width: 20px;
358
+ height: 20px;
359
+ accent-color: var(--lockerverse-accent);
181
360
  }
182
361
 
183
- .lockerverse-payment input:focus-visible,
184
- .lockerverse-payment select:focus-visible,
185
- .lockerverse-payment textarea:focus-visible {
362
+ .lockerverse-payment__check-row {
363
+ display: flex;
364
+ grid-template-columns: none;
365
+ gap: 12px;
366
+ align-items: center;
367
+ min-height: 28px;
368
+ padding: 4px 2px;
369
+ font-size: 15px;
370
+ font-weight: 500;
371
+ line-height: 1.35;
372
+ color: color-mix(in srgb, var(--lockerverse-text) 86%, transparent);
373
+ }
374
+
375
+ .lockerverse-payment__check-row input {
376
+ display: grid;
377
+ flex: 0 0 auto;
378
+ place-content: center;
379
+ width: 20px;
380
+ height: 20px;
381
+ padding: 0;
382
+ margin: 0;
383
+ color: var(--lockerverse-accent-contrast);
384
+ appearance: none;
385
+ cursor: pointer;
386
+ background: transparent;
387
+ border: 1px solid color-mix(in srgb, var(--lockerverse-text) 25%, transparent);
388
+ border-radius: calc(var(--lockerverse-radius) / 2);
389
+ }
390
+
391
+ .lockerverse-payment__check-row input::before {
392
+ width: 11px;
393
+ height: 7px;
394
+ content: "";
395
+ border-bottom: 2.5px solid currentcolor;
396
+ border-left: 2.5px solid currentcolor;
397
+ opacity: 0;
398
+ transform: translateY(-1px) rotate(-45deg) scale(0.7);
399
+ transition:
400
+ opacity 100ms ease,
401
+ transform 100ms ease;
402
+ }
403
+
404
+ .lockerverse-payment__check-row input:checked {
405
+ background: var(--lockerverse-accent);
186
406
  border-color: var(--lockerverse-accent);
407
+ }
408
+
409
+ .lockerverse-payment__check-row input:checked::before {
410
+ opacity: 1;
411
+ transform: translateY(-1px) rotate(-45deg) scale(1);
412
+ }
413
+
414
+ .lockerverse-payment__check-row input:focus-visible {
415
+ outline: none;
187
416
  box-shadow: 0 0 0 2px
188
- color-mix(in srgb, var(--lockerverse-accent) 28%, transparent);
417
+ color-mix(in srgb, var(--lockerverse-accent) 24%, transparent);
189
418
  }
190
419
 
191
420
  .lockerverse-payment button {
@@ -200,14 +429,46 @@
200
429
  border-radius: var(--lockerverse-radius);
201
430
  }
202
431
 
203
- .lockerverse-payment button:focus-visible {
204
- outline: 2px solid var(--lockerverse-accent);
205
- outline-offset: 2px;
432
+ .lockerverse-payment button[type="submit"] {
433
+ width: 100%;
434
+ min-height: 48px;
435
+ padding: 12px;
436
+ font-size: 14px;
437
+ font-weight: 600;
438
+ line-height: 1.25;
439
+ box-shadow: 0 14px 34px rgb(0 0 0 / 34%);
440
+ transition:
441
+ filter 140ms ease,
442
+ transform 140ms ease;
443
+ }
444
+
445
+ .lockerverse-payment button[type="submit"]:hover {
446
+ filter: brightness(1.06);
447
+ }
448
+
449
+ .lockerverse-payment button[type="submit"]:active {
450
+ transform: translateY(1px);
206
451
  }
207
452
 
208
453
  .lockerverse-payment button:disabled {
209
454
  cursor: wait;
210
- opacity: 0.58;
455
+ opacity: 0.72;
456
+ }
457
+
458
+ .lockerverse-payment__tip > div[role="radiogroup"] button {
459
+ min-width: 0;
460
+ min-height: 38px;
461
+ padding: 8px 4px;
462
+ font-size: 14px;
463
+ color: var(--lockerverse-muted);
464
+ background: color-mix(in srgb, var(--lockerverse-bg) 68%, transparent);
465
+ border-color: var(--lockerverse-subtle);
466
+ }
467
+
468
+ .lockerverse-payment__tip > div[role="radiogroup"] button[aria-pressed="true"] {
469
+ color: var(--lockerverse-accent-contrast);
470
+ background: var(--lockerverse-accent);
471
+ border-color: var(--lockerverse-accent);
211
472
  }
212
473
 
213
474
  .lockerverse-payment__additional-fields button {
@@ -234,77 +495,183 @@
234
495
  clip-path: inset(50%);
235
496
  }
236
497
 
498
+ .lockerverse-payment__stripe-mount {
499
+ visibility: visible;
500
+ min-width: 0;
501
+ opacity: 1;
502
+ transition: opacity 120ms ease;
503
+ }
504
+
505
+ .lockerverse-payment__stripe-element[data-ready="false"] {
506
+ position: relative;
507
+ }
508
+
509
+ .lockerverse-payment__stripe-element[data-ready="false"]
510
+ > .lockerverse-payment__stripe-mount {
511
+ position: absolute;
512
+ inset: 0;
513
+ z-index: -1;
514
+ visibility: hidden;
515
+ pointer-events: none;
516
+ opacity: 0;
517
+ }
518
+
519
+ .lockerverse-payment__stripe-loader {
520
+ padding: 12px;
521
+ background: color-mix(in srgb, var(--lockerverse-text) 2.5%, transparent);
522
+ border: 1px solid var(--lockerverse-subtle);
523
+ border-radius: var(--lockerverse-radius);
524
+ }
525
+
526
+ .lockerverse-payment__stripe-loader > p {
527
+ font-size: 14px;
528
+ font-weight: 500;
529
+ color: color-mix(in srgb, var(--lockerverse-text) 72%, transparent);
530
+ }
531
+
532
+ .lockerverse-payment__stripe-loader > div {
533
+ display: grid;
534
+ grid-template-columns: repeat(2, minmax(0, 1fr));
535
+ gap: 8px;
536
+ margin-top: 12px;
537
+ }
538
+
539
+ .lockerverse-payment .lockerverse-payment__stripe-loader span {
540
+ height: 36px;
541
+ background: color-mix(in srgb, var(--lockerverse-text) 4.5%, transparent);
542
+ border-radius: 6px;
543
+ animation: lockerverse-pulse 1.5s ease-in-out infinite;
544
+ }
545
+
546
+ .lockerverse-payment__stripe-loader span:first-child {
547
+ grid-column: 1 / -1;
548
+ background: color-mix(in srgb, var(--lockerverse-text) 6%, transparent);
549
+ }
550
+
237
551
  .lockerverse-payment__loading {
238
- min-height: 344px;
552
+ min-height: 420px;
239
553
  }
240
554
 
241
555
  .lockerverse-payment__skeleton {
242
556
  display: grid;
243
- gap: 22px;
557
+ gap: 16px;
558
+ }
559
+
560
+ .lockerverse-payment__skeleton-branding {
561
+ display: flex;
562
+ gap: 14px;
563
+ align-items: center;
244
564
  }
245
565
 
246
566
  .lockerverse-payment__skeleton-contact,
247
567
  .lockerverse-payment__skeleton-field,
248
- .lockerverse-payment__skeleton-loader-block,
568
+ .lockerverse-payment__skeleton-loader-content,
249
569
  .lockerverse-payment__skeleton-actions {
250
570
  display: grid;
251
- gap: 9px;
252
571
  }
253
572
 
254
573
  .lockerverse-payment__skeleton-contact {
255
- padding-top: 16px;
256
- border-top: 1px solid var(--lockerverse-border);
574
+ gap: 12px;
575
+ padding-top: 14px;
576
+ border-top: 1px solid var(--lockerverse-subtle);
257
577
  }
258
578
 
579
+ .lockerverse-payment__skeleton-field {
580
+ gap: 8px;
581
+ }
582
+
583
+ .lockerverse-payment__skeleton-avatar,
584
+ .lockerverse-payment__skeleton-community,
259
585
  .lockerverse-payment__skeleton-label,
260
586
  .lockerverse-payment__skeleton-input,
261
587
  .lockerverse-payment__skeleton-loader-label,
262
588
  .lockerverse-payment__skeleton-loader-full,
589
+ .lockerverse-payment__skeleton-loader-half,
590
+ .lockerverse-payment__skeleton-check-line,
263
591
  .lockerverse-payment__skeleton-button {
264
592
  display: block;
265
- overflow: hidden;
266
- background: color-mix(in srgb, var(--lockerverse-text) 9%, transparent);
593
+ background: color-mix(in srgb, var(--lockerverse-text) 8%, transparent);
594
+ animation: lockerverse-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
267
595
  }
268
596
 
269
- .lockerverse-payment__skeleton-label,
270
- .lockerverse-payment__skeleton-loader-label {
271
- width: 31%;
272
- height: 14px;
273
- border-radius: 5px;
597
+ .lockerverse-payment__skeleton-avatar {
598
+ flex: none;
599
+ width: 48px;
600
+ height: 48px;
601
+ border-radius: var(--lockerverse-radius);
602
+ }
603
+
604
+ .lockerverse-payment__skeleton-community {
605
+ width: 176px;
606
+ height: 20px;
607
+ border-radius: 4px;
608
+ }
609
+
610
+ .lockerverse-payment__skeleton-label {
611
+ width: 48px;
612
+ height: 16px;
613
+ border-radius: 4px;
274
614
  }
275
615
 
276
616
  .lockerverse-payment__skeleton-input,
277
- .lockerverse-payment__skeleton-loader-full,
278
617
  .lockerverse-payment__skeleton-button {
618
+ width: 100%;
279
619
  height: 48px;
280
620
  border-radius: var(--lockerverse-radius);
281
621
  }
282
622
 
623
+ .lockerverse-payment__skeleton-input {
624
+ background: var(--lockerverse-control);
625
+ border: 1px solid var(--lockerverse-subtle);
626
+ }
627
+
628
+ .lockerverse-payment__skeleton-loader-block {
629
+ padding: 12px;
630
+ background: color-mix(in srgb, var(--lockerverse-text) 2.5%, transparent);
631
+ border: 1px solid var(--lockerverse-subtle);
632
+ border-radius: var(--lockerverse-radius);
633
+ }
634
+
635
+ .lockerverse-payment__skeleton-loader-label {
636
+ width: 144px;
637
+ height: 16px;
638
+ border-radius: 4px;
639
+ }
640
+
641
+ .lockerverse-payment__skeleton-loader-content {
642
+ grid-template-columns: repeat(2, minmax(0, 1fr));
643
+ gap: 8px;
644
+ margin-top: 12px;
645
+ }
646
+
647
+ .lockerverse-payment__skeleton-loader-full,
648
+ .lockerverse-payment__skeleton-loader-half {
649
+ height: 36px;
650
+ border-radius: 6px;
651
+ }
652
+
283
653
  .lockerverse-payment__skeleton-loader-full {
284
- height: 128px;
654
+ grid-column: 1 / -1;
655
+ background: color-mix(in srgb, var(--lockerverse-text) 6%, transparent);
285
656
  }
286
657
 
287
- .lockerverse-payment__skeleton-button {
288
- margin-top: 8px;
658
+ .lockerverse-payment__skeleton-loader-half {
659
+ background: color-mix(in srgb, var(--lockerverse-text) 4.5%, transparent);
289
660
  }
290
661
 
291
- .lockerverse-payment__skeleton-label::after,
292
- .lockerverse-payment__skeleton-input::after,
293
- .lockerverse-payment__skeleton-loader-label::after,
294
- .lockerverse-payment__skeleton-loader-full::after,
295
- .lockerverse-payment__skeleton-button::after {
296
- display: block;
297
- width: 100%;
298
- height: 100%;
299
- content: "";
300
- background: linear-gradient(
301
- 90deg,
302
- transparent,
303
- color-mix(in srgb, var(--lockerverse-text) 13%, transparent),
304
- transparent
305
- );
306
- transform: translateX(-100%);
307
- animation: lockerverse-skeleton-shimmer 1.25s ease-in-out infinite;
662
+ .lockerverse-payment__skeleton-actions {
663
+ gap: 16px;
664
+ padding: 20px 0 4px;
665
+ }
666
+
667
+ .lockerverse-payment__skeleton-check-line {
668
+ width: min(256px, 70%);
669
+ height: 20px;
670
+ border-radius: 4px;
671
+ }
672
+
673
+ .lockerverse-payment__skeleton-button {
674
+ background: color-mix(in srgb, var(--lockerverse-text) 12%, transparent);
308
675
  }
309
676
 
310
677
  .lockerverse-payment__sr-only {
@@ -319,18 +686,19 @@
319
686
  clip: rect(0, 0, 0, 0);
320
687
  }
321
688
 
322
- @keyframes lockerverse-skeleton-shimmer {
323
- to {
324
- transform: translateX(100%);
689
+ @keyframes lockerverse-pulse {
690
+ 50% {
691
+ opacity: 0.55;
325
692
  }
326
693
  }
327
694
 
328
695
  @media (prefers-reduced-motion: reduce) {
329
- .lockerverse-payment__skeleton-label::after,
330
- .lockerverse-payment__skeleton-input::after,
331
- .lockerverse-payment__skeleton-loader-label::after,
332
- .lockerverse-payment__skeleton-loader-full::after,
333
- .lockerverse-payment__skeleton-button::after {
334
- animation: none;
696
+ .lockerverse-payment *,
697
+ .lockerverse-payment *::before,
698
+ .lockerverse-payment *::after {
699
+ scroll-behavior: auto !important;
700
+ animation-duration: 0.01ms !important;
701
+ animation-iteration-count: 1 !important;
702
+ transition-duration: 0.01ms !important;
335
703
  }
336
704
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lockerverse/react",
3
- "version": "0.2.22",
3
+ "version": "0.2.24",
4
4
  "description": "React payment UI for Lockerverse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -29,7 +29,8 @@
29
29
  "README.md"
30
30
  ],
31
31
  "dependencies": {
32
- "@lockerverse/sdk": "0.2.21"
32
+ "valibot": "1.4.2",
33
+ "@lockerverse/sdk": "0.2.24"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@size-limit/file": "13.0.3",