@lockerverse/react 0.2.77 → 0.2.78

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
@@ -244,19 +244,29 @@ const widget = useLockerverseWidget({
244
244
 
245
245
  ## Styling
246
246
 
247
- Use `theme="dark"` or `theme="light"`. Lockerverse applies the community branding returned by the widget API. Override it with `branding`, or override individual CSS variables through `style` or a scoped stylesheet.
247
+ Use `theme="dark"` or `theme="light"`. Lockerverse applies the community branding returned by the widget API. Pass the same `LockerverseStyle` object to payment, signup, and donate launcher components.
248
248
 
249
249
  ```tsx
250
+ import type { LockerverseStyle } from "@lockerverse/react";
251
+
252
+ const lockerverseStyle = {
253
+ "--lockerverse-accent": "#ff6b35",
254
+ "--lockerverse-bg": "#fffaf0",
255
+ "--lockerverse-control": "#f5eddf",
256
+ "--lockerverse-radius": "14px",
257
+ "--lockerverse-text": "#211c17",
258
+ } satisfies LockerverseStyle;
259
+
250
260
  <LockerversePayment
251
261
  selection={selection}
252
- style={{
253
- "--lockerverse-accent": "#ff6b35",
254
- "--lockerverse-radius": "14px",
255
- }}
262
+ style={lockerverseStyle}
256
263
  widget={widget}
257
264
  />
258
265
  ```
259
266
 
267
+ The canonical `--lockerverse-*` tokens control every component. Existing
268
+ `--lockerverse-signup-*` tokens remain supported as signup-only aliases.
269
+
260
270
  The package keeps React, React DOM, and Stripe's React libraries as peer dependencies so it does not ship duplicate framework code. `LockerversePayment` leaves product selection to its host. `LockerverseDonateLauncher` provides selection from the existing widget catalog. Neither component depends on Lockerverse's Next.js application components.
261
271
 
262
272
  ## Payment outcomes
@@ -1,3 +1,4 @@
1
+ import { n as LockerverseTheme, t as LockerverseStyle } from "./theme.js";
1
2
  import { n as LockerverseDonateLauncherProps, t as LockerverseDonateLauncherPosition } from "./types.js";
2
3
  import { t as LockerverseDonateLauncher } from "./lockerverse-donate-launcher.js";
3
- export { LockerverseDonateLauncher, type LockerverseDonateLauncherPosition, type LockerverseDonateLauncherProps };
4
+ export { LockerverseDonateLauncher, type LockerverseDonateLauncherPosition, type LockerverseDonateLauncherProps, type LockerverseStyle, type LockerverseTheme };
package/dist/form-ui.css CHANGED
@@ -10,17 +10,6 @@
10
10
  --lockerverse-form-text: var(--lockerverse-text);
11
11
  }
12
12
 
13
- .lockerverse-signup {
14
- --lockerverse-form-accent: var(--lockerverse-signup-accent);
15
- --lockerverse-form-border: var(--lockerverse-signup-border);
16
- --lockerverse-form-control: var(--lockerverse-signup-control);
17
- --lockerverse-form-muted: var(--lockerverse-signup-muted);
18
- --lockerverse-form-placeholder: var(--lockerverse-signup-placeholder);
19
- --lockerverse-form-radius: var(--lockerverse-signup-radius);
20
- --lockerverse-form-subtle: var(--lockerverse-signup-subtle);
21
- --lockerverse-form-text: var(--lockerverse-signup-text);
22
- }
23
-
24
13
  :is(.lockerverse-payment, .lockerverse-signup)
25
14
  label:not(.lockerverse-payment__check-row),
26
15
  :is(.lockerverse-payment, .lockerverse-signup) .lockerverse-payment__field,
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import { n as LockerverseTheme, t as LockerverseStyle } from "./theme.js";
1
2
  import { n as useLockerverseWidget, t as UseLockerverseWidgetResult } from "./use-lockerverse-widget.js";
2
3
  import { a as LockerversePaymentRecovery, c as LockerversePaymentTheme, i as LockerversePaymentProps, l as LockerversePaymentUncertain, n as LockerverseDonateLauncherProps, o as LockerversePaymentSelectionItem, r as LockerversePaymentBranding, s as LockerversePaymentStyle, t as LockerverseDonateLauncherPosition, u as LockerverseStripeLoader } from "./types.js";
3
4
  import { t as LockerverseDonateLauncher } from "./lockerverse-donate-launcher.js";
4
5
  import { t as LockerversePayment } from "./lockerverse-payment.js";
5
- export { LockerverseDonateLauncher, type LockerverseDonateLauncherPosition, type LockerverseDonateLauncherProps, LockerversePayment, type LockerversePaymentBranding, type LockerversePaymentProps, type LockerversePaymentRecovery, type LockerversePaymentSelectionItem, type LockerversePaymentStyle, type LockerversePaymentTheme, type LockerversePaymentUncertain, type LockerverseStripeLoader, type UseLockerverseWidgetResult, useLockerverseWidget };
6
+ export { LockerverseDonateLauncher, type LockerverseDonateLauncherPosition, type LockerverseDonateLauncherProps, LockerversePayment, type LockerversePaymentBranding, type LockerversePaymentProps, type LockerversePaymentRecovery, type LockerversePaymentSelectionItem, type LockerversePaymentStyle, type LockerversePaymentTheme, type LockerversePaymentUncertain, type LockerverseStripeLoader, type LockerverseStyle, type LockerverseTheme, type UseLockerverseWidgetResult, useLockerverseWidget };
@@ -1 +1 @@
1
- {"version":3,"file":"lockerverse-donate-launcher.d.ts","names":[],"sources":["../src/lockerverse-donate-launcher.tsx"],"mappings":";;iBA0jBgB,4BACd,aACA,UACA,WACG,gBACF,iDAA8B,IAAA"}
1
+ {"version":3,"file":"lockerverse-donate-launcher.d.ts","names":[],"sources":["../src/lockerverse-donate-launcher.tsx"],"mappings":";;iBA2jBgB,4BACd,aACA,UACA,WACG,gBACF,iDAA8B,IAAA"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./lockerverse-payment.js";import{Dialog as t}from"@base-ui/react/dialog";import{createElement as n,useState as r}from"react";import{Fragment as i,jsx as a,jsxs as o}from"react/jsx-runtime";const s=new Intl.NumberFormat(`en-US`,{currency:`USD`,style:`currency`}),c=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/,l=[1e3,2500,5e3,1e4];function u(e){if(!c.test(e))return null;let t=Math.round(Number(e)*100);return Number.isSafeInteger(t)&&t>0?t:null}function d(e,t){let n=``;return t===`monthly`&&(n=`/month`),t===`annually`&&(n=`/year`),`${s.format(e/100)}${n}`}function f({customAmounts:e,product:t,quantities:n,recurringProductId:r,setCustomAmounts:i,setQuantities:c,setRecurringProductId:l}){let u=n[t.id]??0;if(t.pricingMode===`fixed`&&t.paymentOption===`one-time`){let e=Math.min(t.maximumQuantity??1/0,t.inventoryQuantity??1/0);return o(`span`,{className:`lockerverse-launcher__quantity`,children:[a(`button`,{"aria-label":`Decrease ${t.name} quantity`,disabled:u===0,onClick:()=>{l(null),c(e=>{let n=e[t.id]??0,r=t.minimumQuantity??1;return{...e,[t.id]:n<=r?0:n-1}})},type:`button`,children:`−`}),a(`output`,{"aria-label":`${t.name} quantity`,children:u}),a(`button`,{"aria-label":`Increase ${t.name} quantity`,disabled:u>=e,onClick:()=>{l(null),c(e=>{let n=e[t.id]??0;return{...e,[t.id]:n===0?t.minimumQuantity??1:n+1}})},type:`button`,children:`+`})]})}return t.pricingMode===`custom`&&t.paymentOption===`one-time`?o(`span`,{className:`lockerverse-launcher__custom-amount`,children:[a(`span`,{"aria-hidden":`true`,children:`$`}),a(`input`,{"aria-label":`${t.name} amount`,min:(t.minimumAmountCents??1)/100,name:`amount-${t.slug}`,onChange:e=>{l(null),i(n=>({...n,[t.id]:e.target.value}))},placeholder:`0.00`,step:`0.01`,type:`number`,value:e[t.id]??``}),t.minimumAmountCents===null?null:o(`small`,{children:[`Minimum `,s.format(t.minimumAmountCents/100)]})]}):a(`button`,{"aria-label":`Select ${t.name}`,"aria-pressed":r===t.id,className:`lockerverse-launcher__select`,onClick:()=>{c({}),i({}),l(e=>e===t.id?null:t.id)},type:`button`,children:`Select`})}function p({variant:e=`default`,...t}){let{customAmounts:n,product:r,quantities:i,recurringProductId:s}=t,c=u(n[r.id]??``),l=s===r.id||r.paymentOption===`one-time`&&(r.pricingMode===`fixed`&&(i[r.id]??0)>0||r.pricingMode===`custom`&&c!==null&&(r.minimumAmountCents===null||c>=r.minimumAmountCents));return o(`article`,{className:`lockerverse-launcher__product lockerverse-launcher__product--${e}`,"data-selected":l||void 0,children:[o(`span`,{className:`lockerverse-launcher__product-copy`,children:[a(`strong`,{className:`lockerverse-launcher__product-name`,children:r.name}),r.description?a(`small`,{children:r.description}):null,r.amountCents===null?null:a(`span`,{className:`lockerverse-launcher__product-price`,children:d(r.amountCents,r.paymentOption)})]}),a(f,{...t})]})}function m({customAmounts:e,product:t,setCustomAmounts:n,setRecurringProductId:r}){let i=e[t.id]??``,c=u(i),d=l.filter(e=>t.minimumAmountCents===null||e>=t.minimumAmountCents),f=d.includes(c??0),p=e=>{r(null),n(n=>({...n,[t.id]:e}))};return a(`div`,{className:`lockerverse-launcher__donation-option`,children:o(`fieldset`,{className:`lockerverse-launcher__donation-choices`,children:[o(`legend`,{className:`lockerverse-launcher__sr-only`,children:[t.name,` amount`]}),a(`button`,{"aria-pressed":i===``,onClick:()=>p(``),type:`button`,children:`No thanks`}),d.map(e=>a(`button`,{"aria-pressed":c===e,onClick:()=>p(String(e/100)),type:`button`,children:s.format(e/100).replace(`.00`,``)},e)),a(`label`,{className:`lockerverse-launcher__donation-other`,"data-selected":i!==``&&!f||void 0,children:a(`input`,{"aria-label":`${t.name} amount`,min:(t.minimumAmountCents??1)/100,name:`amount-${t.slug}`,onChange:e=>p(e.target.value),placeholder:`Other $`,step:`0.01`,type:`number`,value:f?``:i})})]})})}function h({products:e,variant:t=`default`,...r}){return a(`div`,{className:`lockerverse-launcher__product-list`,children:e.map(e=>t===`donation`?n(m,{...r,key:e.id,product:e}):n(p,{...r,key:e.id,product:e,variant:t}))})}function g(e,t){let n=0,r=0;for(let i of t){let t=e.products.find(e=>e.slug===i.productSlug);if(t){if(`quantity`in i){n+=i.quantity,r+=(t.amountCents??0)*i.quantity;continue}n+=1,r+=`amountCents`in i?i.amountCents:t.amountCents??0}}return{amountCents:r,itemCount:n}}function _(){return a(`div`,{"aria-label":`Loading donation options`,className:`lockerverse-launcher__loading`,role:`status`,children:[0,1,2].map(e=>a(`span`,{"aria-hidden":`true`,className:`lockerverse-launcher__loading-row`},e))})}function v(e,t,n,r){if(r){let t=e.products.find(e=>e.id===r&&e.paymentOption!==`one-time`);return t?[{productSlug:t.slug}]:[]}return e.products.flatMap(e=>{let r=t[e.id]??0;if(e.pricingMode===`fixed`&&e.paymentOption===`one-time`&&r>0)return[{productSlug:e.slug,quantity:r}];let i=u(n[e.id]??``);return e.pricingMode===`custom`&&e.paymentOption===`one-time`&&i!==null&&(e.minimumAmountCents===null||i>=e.minimumAmountCents)?[{amountCents:i,productSlug:e.slug}]:[]})}function y({catalog:e,onContinue:t,...n}){let r=v(e,n.quantities,n.customAmounts,n.recurringProductId),i=g(e,r),c=e.products.filter(e=>e.paymentOption===`one-time`&&e.pricingMode===`custom`),l=e.products.filter(e=>!c.includes(e));return o(`form`,{className:`lockerverse-launcher__products`,onSubmit:e=>{e.preventDefault(),r.length>0&&t(r)},children:[l.length>0?a(`section`,{className:`lockerverse-launcher__section`,children:a(h,{...n,products:l})}):null,c.length>0?o(`section`,{className:`lockerverse-launcher__donation`,children:[o(`header`,{className:`lockerverse-launcher__section-header`,children:[a(`h3`,{children:`Add a donation`}),a(`p`,{children:`Choose an amount to add to this order.`})]}),a(h,{...n,products:c,variant:`donation`})]}):null,e.products.length>0?o(`footer`,{className:`lockerverse-launcher__footer`,children:[o(`p`,{"aria-live":`polite`,className:`lockerverse-launcher__summary`,children:[a(`span`,{children:i.itemCount===0?`No items selected`:`${i.itemCount} ${i.itemCount===1?`item`:`items`} selected`}),i.itemCount===0?null:a(`strong`,{children:s.format(i.amountCents/100)})]}),a(`button`,{className:`lockerverse-launcher__continue`,disabled:r.length===0,type:`submit`,children:`Continue`})]}):null]})}function b({onEdit:t,paymentProps:n,selection:r,style:i,widget:s}){return o(`div`,{className:`lockerverse-launcher__checkout`,children:[a(`header`,{className:`lockerverse-launcher__checkout-toolbar`,children:a(`button`,{className:`lockerverse-launcher__back`,onClick:t,type:`button`,children:`Edit order`})}),a(e,{...n,selection:r,style:i,widget:s})]})}function x({catalog:e,checkout:n}){return n?o(i,{children:[a(t.Title,{className:`lockerverse-launcher__sr-only`,children:`Checkout`}),a(t.Description,{className:`lockerverse-launcher__sr-only`,children:`Review the order and complete payment.`})]}):e?o(`header`,{className:`lockerverse-launcher__header`,children:[e.community?o(`div`,{className:`lockerverse-launcher__brand`,children:[e.community.imageUrl?a(`img`,{alt:`${e.community.name} logo`,height:`28`,src:e.community.imageUrl,width:`28`}):null,a(`span`,{children:e.community.name})]}):null,a(t.Title,{className:`lockerverse-launcher__title`,children:e.widget.title??e.widget.name}),a(t.Description,{className:`lockerverse-launcher__description`,children:e.widget.description??`Choose your options, then continue to checkout.`})]}):o(`header`,{className:`lockerverse-launcher__header`,children:[a(t.Title,{className:`lockerverse-launcher__title`,children:`Donate`}),a(t.Description,{className:`lockerverse-launcher__description`,children:`Choose your options, then continue to checkout.`})]})}function S({buttonLabel:e=`Donate`,position:n=`inline`,widget:i,...s}){let[c,l]=r(null),[u,d]=r({}),[f,p]=r({}),[m,h]=r(null),{catalog:g,error:v,loading:S}=i,C={...g?.community?{"--lockerverse-accent":g.community.accentColor}:{},...s.style},w;return w=S?a(_,{}):v?o(`div`,{role:`alert`,children:[a(`p`,{children:`Unable to load donation options.`}),a(`button`,{onClick:i.refresh,type:`button`,children:`Retry`})]}):g?a(y,{catalog:g,customAmounts:u,onContinue:l,quantities:f,recurringProductId:m,setCustomAmounts:d,setQuantities:p,setRecurringProductId:h}):a(_,{}),!(S||v)&&c&&g&&(w=a(b,{onEdit:()=>l(null),paymentProps:s,selection:c,style:C,widget:i})),o(t.Root,{children:[a(t.Trigger,{className:`lockerverse-launcher lockerverse-launcher--${n}`,"data-lockerverse-theme":s.theme??`dark`,style:C,children:e}),o(t.Portal,{children:[a(t.Backdrop,{className:`lockerverse-launcher__backdrop`}),a(t.Viewport,{className:`lockerverse-launcher__viewport`,children:o(t.Popup,{className:`lockerverse-launcher__dialog`,"data-lockerverse-theme":s.theme??`dark`,style:C,children:[a(x,{catalog:g,checkout:c!==null}),a(t.Close,{"aria-label":`Close donation dialog`,className:`lockerverse-launcher__close`,children:a(`span`,{"aria-hidden":`true`,children:`×`})}),w]})})]})]})}export{S as t};
1
+ import{d as e,f as t}from"./contact-validation.js";import{t as n}from"./lockerverse-payment.js";import{Dialog as r}from"@base-ui/react/dialog";import{createElement as i,useState as a}from"react";import{Fragment as o,jsx as s,jsxs as c}from"react/jsx-runtime";const l=new Intl.NumberFormat(`en-US`,{currency:`USD`,style:`currency`}),u=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/,d=[1e3,2500,5e3,1e4];function f(e){if(!u.test(e))return null;let t=Math.round(Number(e)*100);return Number.isSafeInteger(t)&&t>0?t:null}function p(e,t){let n=``;return t===`monthly`&&(n=`/month`),t===`annually`&&(n=`/year`),`${l.format(e/100)}${n}`}function m({customAmounts:e,product:t,quantities:n,recurringProductId:r,setCustomAmounts:i,setQuantities:a,setRecurringProductId:o}){let u=n[t.id]??0;if(t.pricingMode===`fixed`&&t.paymentOption===`one-time`){let e=Math.min(t.maximumQuantity??1/0,t.inventoryQuantity??1/0);return c(`span`,{className:`lockerverse-launcher__quantity`,children:[s(`button`,{"aria-label":`Decrease ${t.name} quantity`,disabled:u===0,onClick:()=>{o(null),a(e=>{let n=e[t.id]??0,r=t.minimumQuantity??1;return{...e,[t.id]:n<=r?0:n-1}})},type:`button`,children:`−`}),s(`output`,{"aria-label":`${t.name} quantity`,children:u}),s(`button`,{"aria-label":`Increase ${t.name} quantity`,disabled:u>=e,onClick:()=>{o(null),a(e=>{let n=e[t.id]??0;return{...e,[t.id]:n===0?t.minimumQuantity??1:n+1}})},type:`button`,children:`+`})]})}return t.pricingMode===`custom`&&t.paymentOption===`one-time`?c(`span`,{className:`lockerverse-launcher__custom-amount`,children:[s(`span`,{"aria-hidden":`true`,children:`$`}),s(`input`,{"aria-label":`${t.name} amount`,min:(t.minimumAmountCents??1)/100,name:`amount-${t.slug}`,onChange:e=>{o(null),i(n=>({...n,[t.id]:e.target.value}))},placeholder:`0.00`,step:`0.01`,type:`number`,value:e[t.id]??``}),t.minimumAmountCents===null?null:c(`small`,{children:[`Minimum `,l.format(t.minimumAmountCents/100)]})]}):s(`button`,{"aria-label":`Select ${t.name}`,"aria-pressed":r===t.id,className:`lockerverse-launcher__select`,onClick:()=>{a({}),i({}),o(e=>e===t.id?null:t.id)},type:`button`,children:`Select`})}function h({variant:e=`default`,...t}){let{customAmounts:n,product:r,quantities:i,recurringProductId:a}=t,o=f(n[r.id]??``),l=a===r.id||r.paymentOption===`one-time`&&(r.pricingMode===`fixed`&&(i[r.id]??0)>0||r.pricingMode===`custom`&&o!==null&&(r.minimumAmountCents===null||o>=r.minimumAmountCents));return c(`article`,{className:`lockerverse-launcher__product lockerverse-launcher__product--${e}`,"data-selected":l||void 0,children:[c(`span`,{className:`lockerverse-launcher__product-copy`,children:[s(`strong`,{className:`lockerverse-launcher__product-name`,children:r.name}),r.description?s(`small`,{children:r.description}):null,r.amountCents===null?null:s(`span`,{className:`lockerverse-launcher__product-price`,children:p(r.amountCents,r.paymentOption)})]}),s(m,{...t})]})}function g({customAmounts:e,product:t,setCustomAmounts:n,setRecurringProductId:r}){let i=e[t.id]??``,a=f(i),o=d.filter(e=>t.minimumAmountCents===null||e>=t.minimumAmountCents),u=o.includes(a??0),p=e=>{r(null),n(n=>({...n,[t.id]:e}))};return s(`div`,{className:`lockerverse-launcher__donation-option`,children:c(`fieldset`,{className:`lockerverse-launcher__donation-choices`,children:[c(`legend`,{className:`lockerverse-launcher__sr-only`,children:[t.name,` amount`]}),s(`button`,{"aria-pressed":i===``,onClick:()=>p(``),type:`button`,children:`No thanks`}),o.map(e=>s(`button`,{"aria-pressed":a===e,onClick:()=>p(String(e/100)),type:`button`,children:l.format(e/100).replace(`.00`,``)},e)),s(`label`,{className:`lockerverse-launcher__donation-other`,"data-selected":i!==``&&!u||void 0,children:s(`input`,{"aria-label":`${t.name} amount`,min:(t.minimumAmountCents??1)/100,name:`amount-${t.slug}`,onChange:e=>p(e.target.value),placeholder:`Other $`,step:`0.01`,type:`number`,value:u?``:i})})]})})}function _({products:e,variant:t=`default`,...n}){return s(`div`,{className:`lockerverse-launcher__product-list`,children:e.map(e=>t===`donation`?i(g,{...n,key:e.id,product:e}):i(h,{...n,key:e.id,product:e,variant:t}))})}function v(e,t){let n=0,r=0;for(let i of t){let t=e.products.find(e=>e.slug===i.productSlug);if(t){if(`quantity`in i){n+=i.quantity,r+=(t.amountCents??0)*i.quantity;continue}n+=1,r+=`amountCents`in i?i.amountCents:t.amountCents??0}}return{amountCents:r,itemCount:n}}function y(){return s(`div`,{"aria-label":`Loading donation options`,className:`lockerverse-launcher__loading`,role:`status`,children:[0,1,2].map(e=>s(`span`,{"aria-hidden":`true`,className:`lockerverse-launcher__loading-row`},e))})}function b(e,t,n,r){if(r){let t=e.products.find(e=>e.id===r&&e.paymentOption!==`one-time`);return t?[{productSlug:t.slug}]:[]}return e.products.flatMap(e=>{let r=t[e.id]??0;if(e.pricingMode===`fixed`&&e.paymentOption===`one-time`&&r>0)return[{productSlug:e.slug,quantity:r}];let i=f(n[e.id]??``);return e.pricingMode===`custom`&&e.paymentOption===`one-time`&&i!==null&&(e.minimumAmountCents===null||i>=e.minimumAmountCents)?[{amountCents:i,productSlug:e.slug}]:[]})}function x({catalog:e,onContinue:t,...n}){let r=b(e,n.quantities,n.customAmounts,n.recurringProductId),i=v(e,r),a=e.products.filter(e=>e.paymentOption===`one-time`&&e.pricingMode===`custom`),o=e.products.filter(e=>!a.includes(e));return c(`form`,{className:`lockerverse-launcher__products`,onSubmit:e=>{e.preventDefault(),r.length>0&&t(r)},children:[o.length>0?s(`section`,{className:`lockerverse-launcher__section`,children:s(_,{...n,products:o})}):null,a.length>0?c(`section`,{className:`lockerverse-launcher__donation`,children:[c(`header`,{className:`lockerverse-launcher__section-header`,children:[s(`h3`,{children:`Add a donation`}),s(`p`,{children:`Choose an amount to add to this order.`})]}),s(_,{...n,products:a,variant:`donation`})]}):null,e.products.length>0?c(`footer`,{className:`lockerverse-launcher__footer`,children:[c(`p`,{"aria-live":`polite`,className:`lockerverse-launcher__summary`,children:[s(`span`,{children:i.itemCount===0?`No items selected`:`${i.itemCount} ${i.itemCount===1?`item`:`items`} selected`}),i.itemCount===0?null:s(`strong`,{children:l.format(i.amountCents/100)})]}),s(`button`,{className:`lockerverse-launcher__continue`,disabled:r.length===0,type:`submit`,children:`Continue`})]}):null]})}function S({onEdit:e,paymentProps:t,selection:r,style:i,widget:a}){return c(`div`,{className:`lockerverse-launcher__checkout`,children:[s(`header`,{className:`lockerverse-launcher__checkout-toolbar`,children:s(`button`,{className:`lockerverse-launcher__back`,onClick:e,type:`button`,children:`Edit order`})}),s(n,{...t,selection:r,style:i,widget:a})]})}function C({catalog:e,checkout:t}){return t?c(o,{children:[s(r.Title,{className:`lockerverse-launcher__sr-only`,children:`Checkout`}),s(r.Description,{className:`lockerverse-launcher__sr-only`,children:`Review the order and complete payment.`})]}):e?c(`header`,{className:`lockerverse-launcher__header`,children:[e.community?c(`div`,{className:`lockerverse-launcher__brand`,children:[e.community.imageUrl?s(`img`,{alt:`${e.community.name} logo`,height:`28`,src:e.community.imageUrl,width:`28`}):null,s(`span`,{children:e.community.name})]}):null,s(r.Title,{className:`lockerverse-launcher__title`,children:e.widget.title??e.widget.name}),s(r.Description,{className:`lockerverse-launcher__description`,children:e.widget.description??`Choose your options, then continue to checkout.`})]}):c(`header`,{className:`lockerverse-launcher__header`,children:[s(r.Title,{className:`lockerverse-launcher__title`,children:`Donate`}),s(r.Description,{className:`lockerverse-launcher__description`,children:`Choose your options, then continue to checkout.`})]})}function w({buttonLabel:n=`Donate`,position:i=`inline`,widget:o,...l}){let[u,d]=a(null),[f,p]=a({}),[m,h]=a({}),[g,_]=a(null),{catalog:v,error:b,loading:w}=o,T=t(l.style?.[`--lockerverse-accent`]??v?.community?.accentColor??`#38d77a`),E=e(T),D={...l.style,...l.style?.[`--lockerverse-accent`]!==void 0||v?.community?.accentColor?{"--lockerverse-accent":T}:{},...E&&l.style?.[`--lockerverse-accent-contrast`]===void 0?{"--lockerverse-accent-contrast":E}:{}},O;return O=w?s(y,{}):b?c(`div`,{role:`alert`,children:[s(`p`,{children:`Unable to load donation options.`}),s(`button`,{onClick:o.refresh,type:`button`,children:`Retry`})]}):v?s(x,{catalog:v,customAmounts:f,onContinue:d,quantities:m,recurringProductId:g,setCustomAmounts:p,setQuantities:h,setRecurringProductId:_}):s(y,{}),!(w||b)&&u&&v&&(O=s(S,{onEdit:()=>d(null),paymentProps:l,selection:u,style:D,widget:o})),c(r.Root,{children:[s(r.Trigger,{className:`lockerverse-launcher lockerverse-launcher--${i}`,"data-lockerverse-theme":l.theme??`dark`,style:D,children:n}),c(r.Portal,{children:[s(r.Backdrop,{className:`lockerverse-launcher__backdrop`}),s(r.Viewport,{className:`lockerverse-launcher__viewport`,children:c(r.Popup,{className:`lockerverse-launcher__dialog`,"data-lockerverse-theme":l.theme??`dark`,style:D,children:[s(C,{catalog:v,checkout:u!==null}),s(r.Close,{"aria-label":`Close donation dialog`,className:`lockerverse-launcher__close`,children:s(`span`,{"aria-hidden":`true`,children:`×`})}),O]})})]})]})}export{w as t};
2
2
  //# sourceMappingURL=lockerverse-donate-launcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lockerverse-donate-launcher.js","names":[],"sources":["../src/lockerverse-donate-launcher.tsx"],"sourcesContent":["import { Dialog } from \"@base-ui/react/dialog\";\nimport type {\n LockerverseCatalog,\n LockerverseProduct,\n} from \"@lockerverse/sdk/checkout\";\nimport {\n type Dispatch,\n type ReactNode,\n type SetStateAction,\n useState,\n} from \"react\";\nimport { LockerversePayment } from \"./lockerverse-payment.tsx\";\nimport type {\n LockerverseDonateLauncherProps,\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n LockerversePaymentStyle,\n} from \"./types.ts\";\nimport type { UseLockerverseWidgetResult } from \"./use-lockerverse-widget.ts\";\n\nconst usd = new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n});\nconst decimalAmountPattern = /^(?:0|[1-9]\\d*)(?:\\.\\d{1,2})?$/;\nconst suggestedDonationAmountsCents = [1000, 2500, 5000, 10_000];\n\nfunction parseAmountCents(value: string) {\n if (!decimalAmountPattern.test(value)) {\n return null;\n }\n const amountCents = Math.round(Number(value) * 100);\n return Number.isSafeInteger(amountCents) && amountCents > 0\n ? amountCents\n : null;\n}\n\nfunction formatProductPrice(\n amountCents: number,\n paymentOption: \"one-time\" | \"monthly\" | \"annually\"\n) {\n let cadence = \"\";\n if (paymentOption === \"monthly\") {\n cadence = \"/month\";\n }\n if (paymentOption === \"annually\") {\n cadence = \"/year\";\n }\n return `${usd.format(amountCents / 100)}${cadence}`;\n}\n\ntype LauncherProductControlProps = {\n customAmounts: Record<string, string>;\n product: LockerverseProduct;\n quantities: Record<string, number>;\n recurringProductId: string | null;\n setCustomAmounts: Dispatch<SetStateAction<Record<string, string>>>;\n setQuantities: Dispatch<SetStateAction<Record<string, number>>>;\n setRecurringProductId: Dispatch<SetStateAction<string | null>>;\n};\n\nfunction LauncherProductControl({\n customAmounts,\n product,\n quantities,\n recurringProductId,\n setCustomAmounts,\n setQuantities,\n setRecurringProductId,\n}: LauncherProductControlProps) {\n const quantity = quantities[product.id] ?? 0;\n if (product.pricingMode === \"fixed\" && product.paymentOption === \"one-time\") {\n const maximum = Math.min(\n product.maximumQuantity ?? Number.POSITIVE_INFINITY,\n product.inventoryQuantity ?? Number.POSITIVE_INFINITY\n );\n return (\n <span className=\"lockerverse-launcher__quantity\">\n <button\n aria-label={`Decrease ${product.name} quantity`}\n disabled={quantity === 0}\n onClick={() => {\n setRecurringProductId(null);\n setQuantities((current) => {\n const currentQuantity = current[product.id] ?? 0;\n const minimum = product.minimumQuantity ?? 1;\n return {\n ...current,\n [product.id]:\n currentQuantity <= minimum ? 0 : currentQuantity - 1,\n };\n });\n }}\n type=\"button\"\n >\n −\n </button>\n <output aria-label={`${product.name} quantity`}>{quantity}</output>\n <button\n aria-label={`Increase ${product.name} quantity`}\n disabled={quantity >= maximum}\n onClick={() => {\n setRecurringProductId(null);\n setQuantities((current) => {\n const currentQuantity = current[product.id] ?? 0;\n return {\n ...current,\n [product.id]:\n currentQuantity === 0\n ? (product.minimumQuantity ?? 1)\n : currentQuantity + 1,\n };\n });\n }}\n type=\"button\"\n >\n +\n </button>\n </span>\n );\n }\n\n if (\n product.pricingMode === \"custom\" &&\n product.paymentOption === \"one-time\"\n ) {\n return (\n <span className=\"lockerverse-launcher__custom-amount\">\n <span aria-hidden=\"true\">$</span>\n <input\n aria-label={`${product.name} amount`}\n min={(product.minimumAmountCents ?? 1) / 100}\n name={`amount-${product.slug}`}\n onChange={(event) => {\n setRecurringProductId(null);\n setCustomAmounts((current) => ({\n ...current,\n [product.id]: event.target.value,\n }));\n }}\n placeholder=\"0.00\"\n step=\"0.01\"\n type=\"number\"\n value={customAmounts[product.id] ?? \"\"}\n />\n {product.minimumAmountCents === null ? null : (\n <small>Minimum {usd.format(product.minimumAmountCents / 100)}</small>\n )}\n </span>\n );\n }\n\n return (\n <button\n aria-label={`Select ${product.name}`}\n aria-pressed={recurringProductId === product.id}\n className=\"lockerverse-launcher__select\"\n onClick={() => {\n setQuantities({});\n setCustomAmounts({});\n setRecurringProductId((current) =>\n current === product.id ? null : product.id\n );\n }}\n type=\"button\"\n >\n Select\n </button>\n );\n}\n\ntype LauncherProductOptionProps = LauncherProductControlProps & {\n variant?: \"default\" | \"donation\";\n};\n\nfunction LauncherProductOption({\n variant = \"default\",\n ...props\n}: LauncherProductOptionProps) {\n const { customAmounts, product, quantities, recurringProductId } = props;\n const customAmount = parseAmountCents(customAmounts[product.id] ?? \"\");\n const isSelected =\n recurringProductId === product.id ||\n (product.paymentOption === \"one-time\" &&\n ((product.pricingMode === \"fixed\" && (quantities[product.id] ?? 0) > 0) ||\n (product.pricingMode === \"custom\" &&\n customAmount !== null &&\n (product.minimumAmountCents === null ||\n customAmount >= product.minimumAmountCents))));\n return (\n <article\n className={`lockerverse-launcher__product lockerverse-launcher__product--${variant}`}\n data-selected={isSelected || undefined}\n >\n <span className=\"lockerverse-launcher__product-copy\">\n <strong className=\"lockerverse-launcher__product-name\">\n {product.name}\n </strong>\n {product.description ? <small>{product.description}</small> : null}\n {product.amountCents === null ? null : (\n <span className=\"lockerverse-launcher__product-price\">\n {formatProductPrice(product.amountCents, product.paymentOption)}\n </span>\n )}\n </span>\n <LauncherProductControl {...props} />\n </article>\n );\n}\n\nfunction LauncherDonationOption({\n customAmounts,\n product,\n setCustomAmounts,\n setRecurringProductId,\n}: LauncherProductControlProps) {\n const amount = customAmounts[product.id] ?? \"\";\n const amountCents = parseAmountCents(amount);\n const suggestions = suggestedDonationAmountsCents.filter(\n (suggestion) =>\n product.minimumAmountCents === null ||\n suggestion >= product.minimumAmountCents\n );\n const isSuggestedAmount = suggestions.includes(amountCents ?? 0);\n const setAmount = (value: string) => {\n setRecurringProductId(null);\n setCustomAmounts((current) => ({\n ...current,\n [product.id]: value,\n }));\n };\n\n return (\n <div className=\"lockerverse-launcher__donation-option\">\n <fieldset className=\"lockerverse-launcher__donation-choices\">\n <legend className=\"lockerverse-launcher__sr-only\">\n {product.name} amount\n </legend>\n <button\n aria-pressed={amount === \"\"}\n onClick={() => setAmount(\"\")}\n type=\"button\"\n >\n No thanks\n </button>\n {suggestions.map((suggestion) => (\n <button\n aria-pressed={amountCents === suggestion}\n key={suggestion}\n onClick={() => setAmount(String(suggestion / 100))}\n type=\"button\"\n >\n {usd.format(suggestion / 100).replace(\".00\", \"\")}\n </button>\n ))}\n <label\n className=\"lockerverse-launcher__donation-other\"\n data-selected={amount !== \"\" && !isSuggestedAmount ? true : undefined}\n >\n <input\n aria-label={`${product.name} amount`}\n min={(product.minimumAmountCents ?? 1) / 100}\n name={`amount-${product.slug}`}\n onChange={(event) => setAmount(event.target.value)}\n placeholder=\"Other $\"\n step=\"0.01\"\n type=\"number\"\n value={isSuggestedAmount ? \"\" : amount}\n />\n </label>\n </fieldset>\n </div>\n );\n}\n\ntype LauncherProductListProps = Omit<LauncherProductControlProps, \"product\"> & {\n products: LockerverseProduct[];\n variant?: LauncherProductOptionProps[\"variant\"];\n};\n\nfunction LauncherProductList({\n products,\n variant = \"default\",\n ...controlProps\n}: LauncherProductListProps) {\n return (\n <div className=\"lockerverse-launcher__product-list\">\n {products.map((product) =>\n variant === \"donation\" ? (\n <LauncherDonationOption\n {...controlProps}\n key={product.id}\n product={product}\n />\n ) : (\n <LauncherProductOption\n {...controlProps}\n key={product.id}\n product={product}\n variant={variant}\n />\n )\n )}\n </div>\n );\n}\n\nfunction getSelectionSummary(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n) {\n let itemCount = 0;\n let amountCents = 0;\n for (const item of selection) {\n const product = catalog.products.find(\n (candidate) => candidate.slug === item.productSlug\n );\n if (!product) {\n continue;\n }\n if (\"quantity\" in item) {\n itemCount += item.quantity;\n amountCents += (product.amountCents ?? 0) * item.quantity;\n continue;\n }\n itemCount += 1;\n amountCents +=\n \"amountCents\" in item ? item.amountCents : (product.amountCents ?? 0);\n }\n return { amountCents, itemCount };\n}\n\nfunction LauncherLoading() {\n return (\n <div\n aria-label=\"Loading donation options\"\n className=\"lockerverse-launcher__loading\"\n role=\"status\"\n >\n {[0, 1, 2].map((item) => (\n <span\n aria-hidden=\"true\"\n className=\"lockerverse-launcher__loading-row\"\n key={item}\n />\n ))}\n </div>\n );\n}\n\nfunction createLauncherSelection(\n catalog: LockerverseCatalog,\n quantities: Record<string, number>,\n customAmounts: Record<string, string>,\n recurringProductId: string | null\n): LockerversePaymentSelectionItem[] {\n if (recurringProductId) {\n const product = catalog.products.find(\n (candidate) =>\n candidate.id === recurringProductId &&\n candidate.paymentOption !== \"one-time\"\n );\n return product ? [{ productSlug: product.slug }] : [];\n }\n\n return catalog.products.flatMap(\n (product): LockerversePaymentSelectionItem[] => {\n const quantity = quantities[product.id] ?? 0;\n if (\n product.pricingMode === \"fixed\" &&\n product.paymentOption === \"one-time\" &&\n quantity > 0\n ) {\n return [{ productSlug: product.slug, quantity }];\n }\n const amountCents = parseAmountCents(customAmounts[product.id] ?? \"\");\n if (\n product.pricingMode === \"custom\" &&\n product.paymentOption === \"one-time\" &&\n amountCents !== null &&\n (product.minimumAmountCents === null ||\n amountCents >= product.minimumAmountCents)\n ) {\n return [{ amountCents, productSlug: product.slug }];\n }\n return [];\n }\n );\n}\n\ntype LauncherSelectionStateProps = Omit<LauncherProductControlProps, \"product\">;\n\ntype LauncherCatalogProps = LauncherSelectionStateProps & {\n catalog: LockerverseCatalog;\n onContinue: (selection: LockerversePaymentSelectionItem[]) => void;\n};\n\nfunction LauncherCatalog({\n catalog,\n onContinue,\n ...selectionState\n}: LauncherCatalogProps) {\n const draftSelection = createLauncherSelection(\n catalog,\n selectionState.quantities,\n selectionState.customAmounts,\n selectionState.recurringProductId\n );\n const summary = getSelectionSummary(catalog, draftSelection);\n const donationProducts = catalog.products.filter(\n (product) =>\n product.paymentOption === \"one-time\" && product.pricingMode === \"custom\"\n );\n const orderProducts = catalog.products.filter(\n (product) => !donationProducts.includes(product)\n );\n\n return (\n <form\n className=\"lockerverse-launcher__products\"\n onSubmit={(event) => {\n event.preventDefault();\n if (draftSelection.length > 0) {\n onContinue(draftSelection);\n }\n }}\n >\n {orderProducts.length > 0 ? (\n <section className=\"lockerverse-launcher__section\">\n <LauncherProductList {...selectionState} products={orderProducts} />\n </section>\n ) : null}\n {donationProducts.length > 0 ? (\n <section className=\"lockerverse-launcher__donation\">\n <header className=\"lockerverse-launcher__section-header\">\n <h3>Add a donation</h3>\n <p>Choose an amount to add to this order.</p>\n </header>\n <LauncherProductList\n {...selectionState}\n products={donationProducts}\n variant=\"donation\"\n />\n </section>\n ) : null}\n {catalog.products.length > 0 ? (\n <footer className=\"lockerverse-launcher__footer\">\n <p aria-live=\"polite\" className=\"lockerverse-launcher__summary\">\n <span>\n {summary.itemCount === 0\n ? \"No items selected\"\n : `${summary.itemCount} ${summary.itemCount === 1 ? \"item\" : \"items\"} selected`}\n </span>\n {summary.itemCount === 0 ? null : (\n <strong>{usd.format(summary.amountCents / 100)}</strong>\n )}\n </p>\n <button\n className=\"lockerverse-launcher__continue\"\n disabled={draftSelection.length === 0}\n type=\"submit\"\n >\n Continue\n </button>\n </footer>\n ) : null}\n </form>\n );\n}\n\ntype LauncherPaymentProps = Omit<\n LockerversePaymentProps,\n \"selection\" | \"widget\"\n>;\n\ntype LauncherCheckoutProps = {\n onEdit: () => void;\n paymentProps: LauncherPaymentProps;\n selection: LockerversePaymentSelectionItem[];\n style: LockerversePaymentStyle;\n widget: UseLockerverseWidgetResult;\n};\n\nfunction LauncherCheckout({\n onEdit,\n paymentProps,\n selection,\n style,\n widget,\n}: LauncherCheckoutProps) {\n return (\n <div className=\"lockerverse-launcher__checkout\">\n <header className=\"lockerverse-launcher__checkout-toolbar\">\n <button\n className=\"lockerverse-launcher__back\"\n onClick={onEdit}\n type=\"button\"\n >\n Edit order\n </button>\n </header>\n <LockerversePayment\n {...paymentProps}\n selection={selection}\n style={style}\n widget={widget}\n />\n </div>\n );\n}\n\nfunction LauncherDialogHeading({\n catalog,\n checkout,\n}: {\n catalog: LockerverseCatalog | null;\n checkout: boolean;\n}) {\n if (checkout) {\n return (\n <>\n <Dialog.Title className=\"lockerverse-launcher__sr-only\">\n Checkout\n </Dialog.Title>\n <Dialog.Description className=\"lockerverse-launcher__sr-only\">\n Review the order and complete payment.\n </Dialog.Description>\n </>\n );\n }\n\n if (!catalog) {\n return (\n <header className=\"lockerverse-launcher__header\">\n <Dialog.Title className=\"lockerverse-launcher__title\">\n Donate\n </Dialog.Title>\n <Dialog.Description className=\"lockerverse-launcher__description\">\n Choose your options, then continue to checkout.\n </Dialog.Description>\n </header>\n );\n }\n\n return (\n <header className=\"lockerverse-launcher__header\">\n {catalog.community ? (\n <div className=\"lockerverse-launcher__brand\">\n {catalog.community.imageUrl ? (\n <img\n alt={`${catalog.community.name} logo`}\n height=\"28\"\n src={catalog.community.imageUrl}\n width=\"28\"\n />\n ) : null}\n <span>{catalog.community.name}</span>\n </div>\n ) : null}\n <Dialog.Title className=\"lockerverse-launcher__title\">\n {catalog.widget.title ?? catalog.widget.name}\n </Dialog.Title>\n <Dialog.Description className=\"lockerverse-launcher__description\">\n {catalog.widget.description ??\n \"Choose your options, then continue to checkout.\"}\n </Dialog.Description>\n </header>\n );\n}\n\nexport function LockerverseDonateLauncher({\n buttonLabel = \"Donate\",\n position = \"inline\",\n widget,\n ...paymentProps\n}: LockerverseDonateLauncherProps) {\n const [selection, setSelection] = useState<\n LockerversePaymentSelectionItem[] | null\n >(null);\n const [customAmounts, setCustomAmounts] = useState<Record<string, string>>(\n {}\n );\n const [quantities, setQuantities] = useState<Record<string, number>>({});\n const [recurringProductId, setRecurringProductId] = useState<string | null>(\n null\n );\n const { catalog, error, loading } = widget;\n const launcherStyle: LockerversePaymentStyle = {\n ...(catalog?.community\n ? { \"--lockerverse-accent\": catalog.community.accentColor }\n : {}),\n ...paymentProps.style,\n };\n\n let content: ReactNode;\n if (loading) {\n content = <LauncherLoading />;\n } else if (error) {\n content = (\n <div role=\"alert\">\n <p>Unable to load donation options.</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </div>\n );\n } else if (catalog) {\n content = (\n <LauncherCatalog\n catalog={catalog}\n customAmounts={customAmounts}\n onContinue={setSelection}\n quantities={quantities}\n recurringProductId={recurringProductId}\n setCustomAmounts={setCustomAmounts}\n setQuantities={setQuantities}\n setRecurringProductId={setRecurringProductId}\n />\n );\n } else {\n content = <LauncherLoading />;\n }\n if (!(loading || error) && selection && catalog) {\n content = (\n <LauncherCheckout\n onEdit={() => setSelection(null)}\n paymentProps={paymentProps}\n selection={selection}\n style={launcherStyle}\n widget={widget}\n />\n );\n }\n\n return (\n <Dialog.Root>\n <Dialog.Trigger\n className={`lockerverse-launcher lockerverse-launcher--${position}`}\n data-lockerverse-theme={paymentProps.theme ?? \"dark\"}\n style={launcherStyle}\n >\n {buttonLabel}\n </Dialog.Trigger>\n <Dialog.Portal>\n <Dialog.Backdrop className=\"lockerverse-launcher__backdrop\" />\n <Dialog.Viewport className=\"lockerverse-launcher__viewport\">\n <Dialog.Popup\n className=\"lockerverse-launcher__dialog\"\n data-lockerverse-theme={paymentProps.theme ?? \"dark\"}\n style={launcherStyle}\n >\n <LauncherDialogHeading\n catalog={catalog}\n checkout={selection !== null}\n />\n <Dialog.Close\n aria-label=\"Close donation dialog\"\n className=\"lockerverse-launcher__close\"\n >\n <span aria-hidden=\"true\">×</span>\n </Dialog.Close>\n {content}\n </Dialog.Popup>\n </Dialog.Viewport>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n"],"mappings":"gNAoBA,MAAM,EAAM,IAAI,KAAK,aAAa,QAAS,CACzC,SAAU,MACV,MAAO,UACT,CAAC,EACK,EAAuB,iCACvB,EAAgC,CAAC,IAAM,KAAM,IAAM,GAAM,EAE/D,SAAS,EAAiB,EAAe,CACvC,GAAI,CAAC,EAAqB,KAAK,CAAK,EAClC,OAAO,KAET,IAAM,EAAc,KAAK,MAAM,OAAO,CAAK,EAAI,GAAG,EAClD,OAAO,OAAO,cAAc,CAAW,GAAK,EAAc,EACtD,EACA,IACN,CAEA,SAAS,EACP,EACA,EACA,CACA,IAAI,EAAU,GAOd,OANI,IAAkB,YACpB,EAAU,UAER,IAAkB,aACpB,EAAU,SAEL,GAAG,EAAI,OAAO,EAAc,GAAG,IAAI,GAC5C,CAYA,SAAS,EAAuB,CAC9B,gBACA,UACA,aACA,qBACA,mBACA,gBACA,yBAC8B,CAC9B,IAAM,EAAW,EAAW,EAAQ,KAAO,EAC3C,GAAI,EAAQ,cAAgB,SAAW,EAAQ,gBAAkB,WAAY,CAC3E,IAAM,EAAU,KAAK,IACnB,EAAQ,iBAAmB,IAC3B,EAAQ,mBAAqB,GAC/B,EACA,OACE,EAAC,OAAD,CAAM,UAAU,iCAAhB,SAAA,CACE,EAAC,SAAD,CACE,aAAY,YAAY,EAAQ,KAAK,WACrC,SAAU,IAAa,EACvB,YAAe,CACb,EAAsB,IAAI,EAC1B,EAAe,GAAY,CACzB,IAAM,EAAkB,EAAQ,EAAQ,KAAO,EACzC,EAAU,EAAQ,iBAAmB,EAC3C,MAAO,CACL,GAAG,GACF,EAAQ,IACP,GAAmB,EAAU,EAAI,EAAkB,CACvD,CACF,CAAC,CACH,EACA,KAAK,SACN,SAAA,GAEO,CAAA,EACR,EAAC,SAAD,CAAQ,aAAY,GAAG,EAAQ,KAAK,WAAa,SAAA,CAAiB,CAAA,EAClE,EAAC,SAAD,CACE,aAAY,YAAY,EAAQ,KAAK,WACrC,SAAU,GAAY,EACtB,YAAe,CACb,EAAsB,IAAI,EAC1B,EAAe,GAAY,CACzB,IAAM,EAAkB,EAAQ,EAAQ,KAAO,EAC/C,MAAO,CACL,GAAG,GACF,EAAQ,IACP,IAAoB,EACf,EAAQ,iBAAmB,EAC5B,EAAkB,CAC1B,CACF,CAAC,CACH,EACA,KAAK,SACN,SAAA,GAEO,CAAA,CACJ,GAEV,CAgCA,OA7BE,EAAQ,cAAgB,UACxB,EAAQ,gBAAkB,WAGxB,EAAC,OAAD,CAAM,UAAU,sCAAhB,SAAA,CACE,EAAC,OAAD,CAAM,cAAY,OAAO,SAAA,GAAO,CAAA,EAChC,EAAC,QAAD,CACE,aAAY,GAAG,EAAQ,KAAK,SAC5B,KAAM,EAAQ,oBAAsB,GAAK,IACzC,KAAM,UAAU,EAAQ,OACxB,SAAW,GAAU,CACnB,EAAsB,IAAI,EAC1B,EAAkB,IAAa,CAC7B,GAAG,GACF,EAAQ,IAAK,EAAM,OAAO,KAC7B,EAAE,CACJ,EACA,YAAY,OACZ,KAAK,OACL,KAAK,SACL,MAAO,EAAc,EAAQ,KAAO,EACrC,CAAA,EACA,EAAQ,qBAAuB,KAAO,KACrC,EAAC,QAAD,CAAA,SAAA,CAAO,WAAS,EAAI,OAAO,EAAQ,mBAAqB,GAAG,CAAS,CAAA,CAAA,CAElE,IAKR,EAAC,SAAD,CACE,aAAY,UAAU,EAAQ,OAC9B,eAAc,IAAuB,EAAQ,GAC7C,UAAU,+BACV,YAAe,CACb,EAAc,CAAC,CAAC,EAChB,EAAiB,CAAC,CAAC,EACnB,EAAuB,GACrB,IAAY,EAAQ,GAAK,KAAO,EAAQ,EAC1C,CACF,EACA,KAAK,SACN,SAAA,QAEO,CAAA,CAEZ,CAMA,SAAS,EAAsB,CAC7B,UAAU,UACV,GAAG,GAC0B,CAC7B,GAAM,CAAE,gBAAe,UAAS,aAAY,sBAAuB,EAC7D,EAAe,EAAiB,EAAc,EAAQ,KAAO,EAAE,EAC/D,EACJ,IAAuB,EAAQ,IAC9B,EAAQ,gBAAkB,aACvB,EAAQ,cAAgB,UAAY,EAAW,EAAQ,KAAO,GAAK,GAClE,EAAQ,cAAgB,UACvB,IAAiB,OAChB,EAAQ,qBAAuB,MAC9B,GAAgB,EAAQ,qBAClC,OACE,EAAC,UAAD,CACE,UAAW,gEAAgE,IAC3E,gBAAe,GAAc,IAAA,GAF/B,SAAA,CAIE,EAAC,OAAD,CAAM,UAAU,qCAAhB,SAAA,CACE,EAAC,SAAD,CAAQ,UAAU,qCACf,SAAA,EAAQ,IACH,CAAA,EACP,EAAQ,YAAc,EAAC,QAAD,CAAA,SAAQ,EAAQ,WAAmB,CAAA,EAAI,KAC7D,EAAQ,cAAgB,KAAO,KAC9B,EAAC,OAAD,CAAM,UAAU,sCACb,SAAA,EAAmB,EAAQ,YAAa,EAAQ,aAAa,CAC1D,CAAA,CAEJ,CACN,CAAA,EAAA,EAAC,EAAD,CAAwB,GAAI,CAAQ,CAAA,CAC7B,GAEb,CAEA,SAAS,EAAuB,CAC9B,gBACA,UACA,mBACA,yBAC8B,CAC9B,IAAM,EAAS,EAAc,EAAQ,KAAO,GACtC,EAAc,EAAiB,CAAM,EACrC,EAAc,EAA8B,OAC/C,GACC,EAAQ,qBAAuB,MAC/B,GAAc,EAAQ,kBAC1B,EACM,EAAoB,EAAY,SAAS,GAAe,CAAC,EACzD,EAAa,GAAkB,CACnC,EAAsB,IAAI,EAC1B,EAAkB,IAAa,CAC7B,GAAG,GACF,EAAQ,IAAK,CAChB,EAAE,CACJ,EAEA,OACE,EAAC,MAAD,CAAK,UAAU,wCACb,SAAA,EAAC,WAAD,CAAU,UAAU,yCAApB,SAAA,CACE,EAAC,SAAD,CAAQ,UAAU,gCAAlB,SAAA,CACG,EAAQ,KAAK,SACR,IACR,EAAC,SAAD,CACE,eAAc,IAAW,GACzB,YAAe,EAAU,EAAE,EAC3B,KAAK,SACN,SAAA,WAEO,CAAA,EACP,EAAY,IAAK,GAChB,EAAC,SAAD,CACE,eAAc,IAAgB,EAE9B,YAAe,EAAU,OAAO,EAAa,GAAG,CAAC,EACjD,KAAK,SAEJ,SAAA,EAAI,OAAO,EAAa,GAAG,CAAC,CAAC,QAAQ,MAAO,EAAE,CACzC,EALD,CAKC,CACT,EACD,EAAC,QAAD,CACE,UAAU,uCACV,gBAAe,IAAW,IAAM,CAAC,GAA2B,IAAA,GAE5D,SAAA,EAAC,QAAD,CACE,aAAY,GAAG,EAAQ,KAAK,SAC5B,KAAM,EAAQ,oBAAsB,GAAK,IACzC,KAAM,UAAU,EAAQ,OACxB,SAAW,GAAU,EAAU,EAAM,OAAO,KAAK,EACjD,YAAY,UACZ,KAAK,OACL,KAAK,SACL,MAAO,EAAoB,GAAK,CACjC,CAAA,CACI,CAAA,CACC,GACP,CAAA,CAET,CAOA,SAAS,EAAoB,CAC3B,WACA,UAAU,UACV,GAAG,GACwB,CAC3B,OACE,EAAC,MAAD,CAAK,UAAU,qCACZ,SAAA,EAAS,IAAK,GACb,IAAY,WACV,EAAC,EAAD,CACE,GAAI,EACJ,IAAK,EAAQ,GACJ,SACV,CAAA,EAED,EAAC,EAAD,CACE,GAAI,EACJ,IAAK,EAAQ,GACJ,UACA,SACV,CAAA,CAEL,CACG,CAAA,CAET,CAEA,SAAS,EACP,EACA,EACA,CACA,IAAI,EAAY,EACZ,EAAc,EAClB,IAAK,IAAM,KAAQ,EAAW,CAC5B,IAAM,EAAU,EAAQ,SAAS,KAC9B,GAAc,EAAU,OAAS,EAAK,WACzC,EACK,KAGL,IAAI,aAAc,EAAM,CACtB,GAAa,EAAK,SAClB,IAAgB,EAAQ,aAAe,GAAK,EAAK,SACjD,QACF,CACA,GAAa,EACb,GACE,gBAAiB,EAAO,EAAK,YAAe,EAAQ,aAAe,CAHrE,CAIF,CACA,MAAO,CAAE,cAAa,WAAU,CAClC,CAEA,SAAS,GAAkB,CACzB,OACE,EAAC,MAAD,CACE,aAAW,2BACX,UAAU,gCACV,KAAK,SAEJ,SAAA,CAAC,EAAG,EAAG,CAAC,CAAC,CAAC,IAAK,GACd,EAAC,OAAD,CACE,cAAY,OACZ,UAAU,mCAEX,EADM,CACN,CACF,CACE,CAAA,CAET,CAEA,SAAS,EACP,EACA,EACA,EACA,EACmC,CACnC,GAAI,EAAoB,CACtB,IAAM,EAAU,EAAQ,SAAS,KAC9B,GACC,EAAU,KAAO,GACjB,EAAU,gBAAkB,UAChC,EACA,OAAO,EAAU,CAAC,CAAE,YAAa,EAAQ,IAAK,CAAC,EAAI,CAAC,CACtD,CAEA,OAAO,EAAQ,SAAS,QACrB,GAA+C,CAC9C,IAAM,EAAW,EAAW,EAAQ,KAAO,EAC3C,GACE,EAAQ,cAAgB,SACxB,EAAQ,gBAAkB,YAC1B,EAAW,EAEX,MAAO,CAAC,CAAE,YAAa,EAAQ,KAAM,UAAS,CAAC,EAEjD,IAAM,EAAc,EAAiB,EAAc,EAAQ,KAAO,EAAE,EAUpE,OARE,EAAQ,cAAgB,UACxB,EAAQ,gBAAkB,YAC1B,IAAgB,OACf,EAAQ,qBAAuB,MAC9B,GAAe,EAAQ,oBAElB,CAAC,CAAE,cAAa,YAAa,EAAQ,IAAK,CAAC,EAE7C,CAAC,CACV,CACF,CACF,CASA,SAAS,EAAgB,CACvB,UACA,aACA,GAAG,GACoB,CACvB,IAAM,EAAiB,EACrB,EACA,EAAe,WACf,EAAe,cACf,EAAe,kBACjB,EACM,EAAU,EAAoB,EAAS,CAAc,EACrD,EAAmB,EAAQ,SAAS,OACvC,GACC,EAAQ,gBAAkB,YAAc,EAAQ,cAAgB,QACpE,EACM,EAAgB,EAAQ,SAAS,OACpC,GAAY,CAAC,EAAiB,SAAS,CAAO,CACjD,EAEA,OACE,EAAC,OAAD,CACE,UAAU,iCACV,SAAW,GAAU,CACnB,EAAM,eAAe,EACjB,EAAe,OAAS,GAC1B,EAAW,CAAc,CAE7B,EAPF,SAAA,CASG,EAAc,OAAS,EACtB,EAAC,UAAD,CAAS,UAAU,gCACjB,SAAA,EAAC,EAAD,CAAqB,GAAI,EAAgB,SAAU,CAAgB,CAAA,CAC5D,CAAA,EACP,KACH,EAAiB,OAAS,EACzB,EAAC,UAAD,CAAS,UAAU,iCAAnB,SAAA,CACE,EAAC,SAAD,CAAQ,UAAU,uCAAlB,SAAA,CACE,EAAC,KAAD,CAAA,SAAI,gBAAkB,CAAA,EACtB,EAAC,IAAD,CAAA,SAAG,wCAAyC,CAAA,CACtC,CACR,CAAA,EAAA,EAAC,EAAD,CACE,GAAI,EACJ,SAAU,EACV,QAAQ,UACT,CAAA,CACM,CACP,CAAA,EAAA,KACH,EAAQ,SAAS,OAAS,EACzB,EAAC,SAAD,CAAQ,UAAU,+BAAlB,SAAA,CACE,EAAC,IAAD,CAAG,YAAU,SAAS,UAAU,gCAAhC,SAAA,CACE,EAAC,OAAD,CAAA,SACG,EAAQ,YAAc,EACnB,oBACA,GAAG,EAAQ,UAAU,GAAG,EAAQ,YAAc,EAAI,OAAS,QAAQ,UACnE,CAAA,EACL,EAAQ,YAAc,EAAI,KACzB,EAAC,SAAD,CAAA,SAAS,EAAI,OAAO,EAAQ,YAAc,GAAG,CAAU,CAAA,CAExD,CACH,CAAA,EAAA,EAAC,SAAD,CACE,UAAU,iCACV,SAAU,EAAe,SAAW,EACpC,KAAK,SACN,SAAA,UAEO,CAAA,CACF,CACN,CAAA,EAAA,IACA,GAEV,CAeA,SAAS,EAAiB,CACxB,SACA,eACA,YACA,QACA,UACwB,CACxB,OACE,EAAC,MAAD,CAAK,UAAU,iCAAf,SAAA,CACE,EAAC,SAAD,CAAQ,UAAU,yCAChB,SAAA,EAAC,SAAD,CACE,UAAU,6BACV,QAAS,EACT,KAAK,SACN,SAAA,YAEO,CAAA,CACF,CAAA,EACR,EAAC,EAAD,CACE,GAAI,EACO,YACJ,QACC,QACT,CAAA,CACE,GAET,CAEA,SAAS,EAAsB,CAC7B,UACA,YAIC,CA2BD,OA1BI,EAEA,EAAA,EAAA,CAAA,SAAA,CACE,EAAC,EAAO,MAAR,CAAc,UAAU,gCAAgC,SAAA,UAE1C,CAAA,EACd,EAAC,EAAO,YAAR,CAAoB,UAAU,gCAAgC,SAAA,wCAE1C,CAAA,CACpB,CAAA,CAAA,EAID,EAcH,EAAC,SAAD,CAAQ,UAAU,+BAAlB,SAAA,CACG,EAAQ,UACP,EAAC,MAAD,CAAK,UAAU,8BAAf,SAAA,CACG,EAAQ,UAAU,SACjB,EAAC,MAAD,CACE,IAAK,GAAG,EAAQ,UAAU,KAAK,OAC/B,OAAO,KACP,IAAK,EAAQ,UAAU,SACvB,MAAM,IACP,CAAA,EACC,KACJ,EAAC,OAAD,CAAA,SAAO,EAAQ,UAAU,IAAW,CAAA,CACjC,CACH,CAAA,EAAA,KACJ,EAAC,EAAO,MAAR,CAAc,UAAU,8BACrB,SAAA,EAAQ,OAAO,OAAS,EAAQ,OAAO,IAC5B,CAAA,EACd,EAAC,EAAO,YAAR,CAAoB,UAAU,oCAC3B,SAAA,EAAQ,OAAO,aACd,iDACgB,CAAA,CACd,IAjCN,EAAC,SAAD,CAAQ,UAAU,+BAAlB,SAAA,CACE,EAAC,EAAO,MAAR,CAAc,UAAU,8BAA8B,SAAA,QAExC,CAAA,EACd,EAAC,EAAO,YAAR,CAAoB,UAAU,oCAAoC,SAAA,iDAE9C,CAAA,CACd,GA4Bd,CAEA,SAAgB,EAA0B,CACxC,cAAc,SACd,WAAW,SACX,SACA,GAAG,GAC8B,CACjC,GAAM,CAAC,EAAW,GAAgB,EAEhC,IAAI,EACA,CAAC,EAAe,GAAoB,EACxC,CAAC,CACH,EACM,CAAC,EAAY,GAAiB,EAAiC,CAAC,CAAC,EACjE,CAAC,EAAoB,GAAyB,EAClD,IACF,EACM,CAAE,UAAS,QAAO,WAAY,EAC9B,EAAyC,CAC7C,GAAI,GAAS,UACT,CAAE,uBAAwB,EAAQ,UAAU,WAAY,EACxD,CAAC,EACL,GAAG,EAAa,KAClB,EAEI,EAwCJ,MAvCA,CAyBE,EAzBE,EACQ,EAAC,EAAD,CAAkB,CAAA,EACnB,EAEP,EAAC,MAAD,CAAK,KAAK,QAAV,SAAA,CACE,EAAC,IAAD,CAAA,SAAG,kCAAmC,CAAA,EACtC,EAAC,SAAD,CAAQ,QAAS,EAAO,QAAS,KAAK,SAAS,SAAA,OAEvC,CAAA,CACL,IAEE,EAEP,EAAC,EAAD,CACW,UACM,gBACf,WAAY,EACA,aACQ,qBACF,mBACH,gBACQ,uBACxB,CAAA,EAGO,EAAC,EAAD,CAAkB,CAAA,EAE1B,EAAE,GAAW,IAAU,GAAa,IACtC,EACE,EAAC,EAAD,CACE,WAAc,EAAa,IAAI,EACjB,eACH,YACX,MAAO,EACC,QACT,CAAA,GAKH,EAAC,EAAO,KAAR,CAAA,SAAA,CACE,EAAC,EAAO,QAAR,CACE,UAAW,8CAA8C,IACzD,yBAAwB,EAAa,OAAS,OAC9C,MAAO,EAEN,SAAA,CACa,CAAA,EAChB,EAAC,EAAO,OAAR,CAAA,SAAA,CACE,EAAC,EAAO,SAAR,CAAiB,UAAU,gCAAkC,CAAA,EAC7D,EAAC,EAAO,SAAR,CAAiB,UAAU,iCACzB,SAAA,EAAC,EAAO,MAAR,CACE,UAAU,+BACV,yBAAwB,EAAa,OAAS,OAC9C,MAAO,EAHT,SAAA,CAKE,EAAC,EAAD,CACW,UACT,SAAU,IAAc,IACzB,CAAA,EACD,EAAC,EAAO,MAAR,CACE,aAAW,wBACX,UAAU,8BAEV,SAAA,EAAC,OAAD,CAAM,cAAY,OAAO,SAAA,GAAO,CAAA,CACpB,CAAA,EACb,CACW,GACC,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,CAAA,CAEjB"}
1
+ {"version":3,"file":"lockerverse-donate-launcher.js","names":[],"sources":["../src/lockerverse-donate-launcher.tsx"],"sourcesContent":["import { Dialog } from \"@base-ui/react/dialog\";\nimport type {\n LockerverseCatalog,\n LockerverseProduct,\n} from \"@lockerverse/sdk/checkout\";\nimport {\n type Dispatch,\n type ReactNode,\n type SetStateAction,\n useState,\n} from \"react\";\nimport { getAccentContrast, normalizeAccentColor } from \"./accent-contrast.ts\";\nimport { LockerversePayment } from \"./lockerverse-payment.tsx\";\nimport type {\n LockerverseDonateLauncherProps,\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n LockerversePaymentStyle,\n} from \"./types.ts\";\nimport type { UseLockerverseWidgetResult } from \"./use-lockerverse-widget.ts\";\n\nconst usd = new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n});\nconst decimalAmountPattern = /^(?:0|[1-9]\\d*)(?:\\.\\d{1,2})?$/;\nconst suggestedDonationAmountsCents = [1000, 2500, 5000, 10_000];\n\nfunction parseAmountCents(value: string) {\n if (!decimalAmountPattern.test(value)) {\n return null;\n }\n const amountCents = Math.round(Number(value) * 100);\n return Number.isSafeInteger(amountCents) && amountCents > 0\n ? amountCents\n : null;\n}\n\nfunction formatProductPrice(\n amountCents: number,\n paymentOption: \"one-time\" | \"monthly\" | \"annually\"\n) {\n let cadence = \"\";\n if (paymentOption === \"monthly\") {\n cadence = \"/month\";\n }\n if (paymentOption === \"annually\") {\n cadence = \"/year\";\n }\n return `${usd.format(amountCents / 100)}${cadence}`;\n}\n\ntype LauncherProductControlProps = {\n customAmounts: Record<string, string>;\n product: LockerverseProduct;\n quantities: Record<string, number>;\n recurringProductId: string | null;\n setCustomAmounts: Dispatch<SetStateAction<Record<string, string>>>;\n setQuantities: Dispatch<SetStateAction<Record<string, number>>>;\n setRecurringProductId: Dispatch<SetStateAction<string | null>>;\n};\n\nfunction LauncherProductControl({\n customAmounts,\n product,\n quantities,\n recurringProductId,\n setCustomAmounts,\n setQuantities,\n setRecurringProductId,\n}: LauncherProductControlProps) {\n const quantity = quantities[product.id] ?? 0;\n if (product.pricingMode === \"fixed\" && product.paymentOption === \"one-time\") {\n const maximum = Math.min(\n product.maximumQuantity ?? Number.POSITIVE_INFINITY,\n product.inventoryQuantity ?? Number.POSITIVE_INFINITY\n );\n return (\n <span className=\"lockerverse-launcher__quantity\">\n <button\n aria-label={`Decrease ${product.name} quantity`}\n disabled={quantity === 0}\n onClick={() => {\n setRecurringProductId(null);\n setQuantities((current) => {\n const currentQuantity = current[product.id] ?? 0;\n const minimum = product.minimumQuantity ?? 1;\n return {\n ...current,\n [product.id]:\n currentQuantity <= minimum ? 0 : currentQuantity - 1,\n };\n });\n }}\n type=\"button\"\n >\n −\n </button>\n <output aria-label={`${product.name} quantity`}>{quantity}</output>\n <button\n aria-label={`Increase ${product.name} quantity`}\n disabled={quantity >= maximum}\n onClick={() => {\n setRecurringProductId(null);\n setQuantities((current) => {\n const currentQuantity = current[product.id] ?? 0;\n return {\n ...current,\n [product.id]:\n currentQuantity === 0\n ? (product.minimumQuantity ?? 1)\n : currentQuantity + 1,\n };\n });\n }}\n type=\"button\"\n >\n +\n </button>\n </span>\n );\n }\n\n if (\n product.pricingMode === \"custom\" &&\n product.paymentOption === \"one-time\"\n ) {\n return (\n <span className=\"lockerverse-launcher__custom-amount\">\n <span aria-hidden=\"true\">$</span>\n <input\n aria-label={`${product.name} amount`}\n min={(product.minimumAmountCents ?? 1) / 100}\n name={`amount-${product.slug}`}\n onChange={(event) => {\n setRecurringProductId(null);\n setCustomAmounts((current) => ({\n ...current,\n [product.id]: event.target.value,\n }));\n }}\n placeholder=\"0.00\"\n step=\"0.01\"\n type=\"number\"\n value={customAmounts[product.id] ?? \"\"}\n />\n {product.minimumAmountCents === null ? null : (\n <small>Minimum {usd.format(product.minimumAmountCents / 100)}</small>\n )}\n </span>\n );\n }\n\n return (\n <button\n aria-label={`Select ${product.name}`}\n aria-pressed={recurringProductId === product.id}\n className=\"lockerverse-launcher__select\"\n onClick={() => {\n setQuantities({});\n setCustomAmounts({});\n setRecurringProductId((current) =>\n current === product.id ? null : product.id\n );\n }}\n type=\"button\"\n >\n Select\n </button>\n );\n}\n\ntype LauncherProductOptionProps = LauncherProductControlProps & {\n variant?: \"default\" | \"donation\";\n};\n\nfunction LauncherProductOption({\n variant = \"default\",\n ...props\n}: LauncherProductOptionProps) {\n const { customAmounts, product, quantities, recurringProductId } = props;\n const customAmount = parseAmountCents(customAmounts[product.id] ?? \"\");\n const isSelected =\n recurringProductId === product.id ||\n (product.paymentOption === \"one-time\" &&\n ((product.pricingMode === \"fixed\" && (quantities[product.id] ?? 0) > 0) ||\n (product.pricingMode === \"custom\" &&\n customAmount !== null &&\n (product.minimumAmountCents === null ||\n customAmount >= product.minimumAmountCents))));\n return (\n <article\n className={`lockerverse-launcher__product lockerverse-launcher__product--${variant}`}\n data-selected={isSelected || undefined}\n >\n <span className=\"lockerverse-launcher__product-copy\">\n <strong className=\"lockerverse-launcher__product-name\">\n {product.name}\n </strong>\n {product.description ? <small>{product.description}</small> : null}\n {product.amountCents === null ? null : (\n <span className=\"lockerverse-launcher__product-price\">\n {formatProductPrice(product.amountCents, product.paymentOption)}\n </span>\n )}\n </span>\n <LauncherProductControl {...props} />\n </article>\n );\n}\n\nfunction LauncherDonationOption({\n customAmounts,\n product,\n setCustomAmounts,\n setRecurringProductId,\n}: LauncherProductControlProps) {\n const amount = customAmounts[product.id] ?? \"\";\n const amountCents = parseAmountCents(amount);\n const suggestions = suggestedDonationAmountsCents.filter(\n (suggestion) =>\n product.minimumAmountCents === null ||\n suggestion >= product.minimumAmountCents\n );\n const isSuggestedAmount = suggestions.includes(amountCents ?? 0);\n const setAmount = (value: string) => {\n setRecurringProductId(null);\n setCustomAmounts((current) => ({\n ...current,\n [product.id]: value,\n }));\n };\n\n return (\n <div className=\"lockerverse-launcher__donation-option\">\n <fieldset className=\"lockerverse-launcher__donation-choices\">\n <legend className=\"lockerverse-launcher__sr-only\">\n {product.name} amount\n </legend>\n <button\n aria-pressed={amount === \"\"}\n onClick={() => setAmount(\"\")}\n type=\"button\"\n >\n No thanks\n </button>\n {suggestions.map((suggestion) => (\n <button\n aria-pressed={amountCents === suggestion}\n key={suggestion}\n onClick={() => setAmount(String(suggestion / 100))}\n type=\"button\"\n >\n {usd.format(suggestion / 100).replace(\".00\", \"\")}\n </button>\n ))}\n <label\n className=\"lockerverse-launcher__donation-other\"\n data-selected={amount !== \"\" && !isSuggestedAmount ? true : undefined}\n >\n <input\n aria-label={`${product.name} amount`}\n min={(product.minimumAmountCents ?? 1) / 100}\n name={`amount-${product.slug}`}\n onChange={(event) => setAmount(event.target.value)}\n placeholder=\"Other $\"\n step=\"0.01\"\n type=\"number\"\n value={isSuggestedAmount ? \"\" : amount}\n />\n </label>\n </fieldset>\n </div>\n );\n}\n\ntype LauncherProductListProps = Omit<LauncherProductControlProps, \"product\"> & {\n products: LockerverseProduct[];\n variant?: LauncherProductOptionProps[\"variant\"];\n};\n\nfunction LauncherProductList({\n products,\n variant = \"default\",\n ...controlProps\n}: LauncherProductListProps) {\n return (\n <div className=\"lockerverse-launcher__product-list\">\n {products.map((product) =>\n variant === \"donation\" ? (\n <LauncherDonationOption\n {...controlProps}\n key={product.id}\n product={product}\n />\n ) : (\n <LauncherProductOption\n {...controlProps}\n key={product.id}\n product={product}\n variant={variant}\n />\n )\n )}\n </div>\n );\n}\n\nfunction getSelectionSummary(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n) {\n let itemCount = 0;\n let amountCents = 0;\n for (const item of selection) {\n const product = catalog.products.find(\n (candidate) => candidate.slug === item.productSlug\n );\n if (!product) {\n continue;\n }\n if (\"quantity\" in item) {\n itemCount += item.quantity;\n amountCents += (product.amountCents ?? 0) * item.quantity;\n continue;\n }\n itemCount += 1;\n amountCents +=\n \"amountCents\" in item ? item.amountCents : (product.amountCents ?? 0);\n }\n return { amountCents, itemCount };\n}\n\nfunction LauncherLoading() {\n return (\n <div\n aria-label=\"Loading donation options\"\n className=\"lockerverse-launcher__loading\"\n role=\"status\"\n >\n {[0, 1, 2].map((item) => (\n <span\n aria-hidden=\"true\"\n className=\"lockerverse-launcher__loading-row\"\n key={item}\n />\n ))}\n </div>\n );\n}\n\nfunction createLauncherSelection(\n catalog: LockerverseCatalog,\n quantities: Record<string, number>,\n customAmounts: Record<string, string>,\n recurringProductId: string | null\n): LockerversePaymentSelectionItem[] {\n if (recurringProductId) {\n const product = catalog.products.find(\n (candidate) =>\n candidate.id === recurringProductId &&\n candidate.paymentOption !== \"one-time\"\n );\n return product ? [{ productSlug: product.slug }] : [];\n }\n\n return catalog.products.flatMap(\n (product): LockerversePaymentSelectionItem[] => {\n const quantity = quantities[product.id] ?? 0;\n if (\n product.pricingMode === \"fixed\" &&\n product.paymentOption === \"one-time\" &&\n quantity > 0\n ) {\n return [{ productSlug: product.slug, quantity }];\n }\n const amountCents = parseAmountCents(customAmounts[product.id] ?? \"\");\n if (\n product.pricingMode === \"custom\" &&\n product.paymentOption === \"one-time\" &&\n amountCents !== null &&\n (product.minimumAmountCents === null ||\n amountCents >= product.minimumAmountCents)\n ) {\n return [{ amountCents, productSlug: product.slug }];\n }\n return [];\n }\n );\n}\n\ntype LauncherSelectionStateProps = Omit<LauncherProductControlProps, \"product\">;\n\ntype LauncherCatalogProps = LauncherSelectionStateProps & {\n catalog: LockerverseCatalog;\n onContinue: (selection: LockerversePaymentSelectionItem[]) => void;\n};\n\nfunction LauncherCatalog({\n catalog,\n onContinue,\n ...selectionState\n}: LauncherCatalogProps) {\n const draftSelection = createLauncherSelection(\n catalog,\n selectionState.quantities,\n selectionState.customAmounts,\n selectionState.recurringProductId\n );\n const summary = getSelectionSummary(catalog, draftSelection);\n const donationProducts = catalog.products.filter(\n (product) =>\n product.paymentOption === \"one-time\" && product.pricingMode === \"custom\"\n );\n const orderProducts = catalog.products.filter(\n (product) => !donationProducts.includes(product)\n );\n\n return (\n <form\n className=\"lockerverse-launcher__products\"\n onSubmit={(event) => {\n event.preventDefault();\n if (draftSelection.length > 0) {\n onContinue(draftSelection);\n }\n }}\n >\n {orderProducts.length > 0 ? (\n <section className=\"lockerverse-launcher__section\">\n <LauncherProductList {...selectionState} products={orderProducts} />\n </section>\n ) : null}\n {donationProducts.length > 0 ? (\n <section className=\"lockerverse-launcher__donation\">\n <header className=\"lockerverse-launcher__section-header\">\n <h3>Add a donation</h3>\n <p>Choose an amount to add to this order.</p>\n </header>\n <LauncherProductList\n {...selectionState}\n products={donationProducts}\n variant=\"donation\"\n />\n </section>\n ) : null}\n {catalog.products.length > 0 ? (\n <footer className=\"lockerverse-launcher__footer\">\n <p aria-live=\"polite\" className=\"lockerverse-launcher__summary\">\n <span>\n {summary.itemCount === 0\n ? \"No items selected\"\n : `${summary.itemCount} ${summary.itemCount === 1 ? \"item\" : \"items\"} selected`}\n </span>\n {summary.itemCount === 0 ? null : (\n <strong>{usd.format(summary.amountCents / 100)}</strong>\n )}\n </p>\n <button\n className=\"lockerverse-launcher__continue\"\n disabled={draftSelection.length === 0}\n type=\"submit\"\n >\n Continue\n </button>\n </footer>\n ) : null}\n </form>\n );\n}\n\ntype LauncherPaymentProps = Omit<\n LockerversePaymentProps,\n \"selection\" | \"widget\"\n>;\n\ntype LauncherCheckoutProps = {\n onEdit: () => void;\n paymentProps: LauncherPaymentProps;\n selection: LockerversePaymentSelectionItem[];\n style: LockerversePaymentStyle;\n widget: UseLockerverseWidgetResult;\n};\n\nfunction LauncherCheckout({\n onEdit,\n paymentProps,\n selection,\n style,\n widget,\n}: LauncherCheckoutProps) {\n return (\n <div className=\"lockerverse-launcher__checkout\">\n <header className=\"lockerverse-launcher__checkout-toolbar\">\n <button\n className=\"lockerverse-launcher__back\"\n onClick={onEdit}\n type=\"button\"\n >\n Edit order\n </button>\n </header>\n <LockerversePayment\n {...paymentProps}\n selection={selection}\n style={style}\n widget={widget}\n />\n </div>\n );\n}\n\nfunction LauncherDialogHeading({\n catalog,\n checkout,\n}: {\n catalog: LockerverseCatalog | null;\n checkout: boolean;\n}) {\n if (checkout) {\n return (\n <>\n <Dialog.Title className=\"lockerverse-launcher__sr-only\">\n Checkout\n </Dialog.Title>\n <Dialog.Description className=\"lockerverse-launcher__sr-only\">\n Review the order and complete payment.\n </Dialog.Description>\n </>\n );\n }\n\n if (!catalog) {\n return (\n <header className=\"lockerverse-launcher__header\">\n <Dialog.Title className=\"lockerverse-launcher__title\">\n Donate\n </Dialog.Title>\n <Dialog.Description className=\"lockerverse-launcher__description\">\n Choose your options, then continue to checkout.\n </Dialog.Description>\n </header>\n );\n }\n\n return (\n <header className=\"lockerverse-launcher__header\">\n {catalog.community ? (\n <div className=\"lockerverse-launcher__brand\">\n {catalog.community.imageUrl ? (\n <img\n alt={`${catalog.community.name} logo`}\n height=\"28\"\n src={catalog.community.imageUrl}\n width=\"28\"\n />\n ) : null}\n <span>{catalog.community.name}</span>\n </div>\n ) : null}\n <Dialog.Title className=\"lockerverse-launcher__title\">\n {catalog.widget.title ?? catalog.widget.name}\n </Dialog.Title>\n <Dialog.Description className=\"lockerverse-launcher__description\">\n {catalog.widget.description ??\n \"Choose your options, then continue to checkout.\"}\n </Dialog.Description>\n </header>\n );\n}\n\nexport function LockerverseDonateLauncher({\n buttonLabel = \"Donate\",\n position = \"inline\",\n widget,\n ...paymentProps\n}: LockerverseDonateLauncherProps) {\n const [selection, setSelection] = useState<\n LockerversePaymentSelectionItem[] | null\n >(null);\n const [customAmounts, setCustomAmounts] = useState<Record<string, string>>(\n {}\n );\n const [quantities, setQuantities] = useState<Record<string, number>>({});\n const [recurringProductId, setRecurringProductId] = useState<string | null>(\n null\n );\n const { catalog, error, loading } = widget;\n const accent = normalizeAccentColor(\n paymentProps.style?.[\"--lockerverse-accent\"] ??\n catalog?.community?.accentColor ??\n \"#38d77a\"\n );\n const accentContrast = getAccentContrast(accent);\n const launcherStyle: LockerversePaymentStyle = {\n ...paymentProps.style,\n ...(paymentProps.style?.[\"--lockerverse-accent\"] !== undefined ||\n catalog?.community?.accentColor\n ? { \"--lockerverse-accent\": accent }\n : {}),\n ...(accentContrast &&\n paymentProps.style?.[\"--lockerverse-accent-contrast\"] === undefined\n ? { \"--lockerverse-accent-contrast\": accentContrast }\n : {}),\n };\n\n let content: ReactNode;\n if (loading) {\n content = <LauncherLoading />;\n } else if (error) {\n content = (\n <div role=\"alert\">\n <p>Unable to load donation options.</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </div>\n );\n } else if (catalog) {\n content = (\n <LauncherCatalog\n catalog={catalog}\n customAmounts={customAmounts}\n onContinue={setSelection}\n quantities={quantities}\n recurringProductId={recurringProductId}\n setCustomAmounts={setCustomAmounts}\n setQuantities={setQuantities}\n setRecurringProductId={setRecurringProductId}\n />\n );\n } else {\n content = <LauncherLoading />;\n }\n if (!(loading || error) && selection && catalog) {\n content = (\n <LauncherCheckout\n onEdit={() => setSelection(null)}\n paymentProps={paymentProps}\n selection={selection}\n style={launcherStyle}\n widget={widget}\n />\n );\n }\n\n return (\n <Dialog.Root>\n <Dialog.Trigger\n className={`lockerverse-launcher lockerverse-launcher--${position}`}\n data-lockerverse-theme={paymentProps.theme ?? \"dark\"}\n style={launcherStyle}\n >\n {buttonLabel}\n </Dialog.Trigger>\n <Dialog.Portal>\n <Dialog.Backdrop className=\"lockerverse-launcher__backdrop\" />\n <Dialog.Viewport className=\"lockerverse-launcher__viewport\">\n <Dialog.Popup\n className=\"lockerverse-launcher__dialog\"\n data-lockerverse-theme={paymentProps.theme ?? \"dark\"}\n style={launcherStyle}\n >\n <LauncherDialogHeading\n catalog={catalog}\n checkout={selection !== null}\n />\n <Dialog.Close\n aria-label=\"Close donation dialog\"\n className=\"lockerverse-launcher__close\"\n >\n <span aria-hidden=\"true\">×</span>\n </Dialog.Close>\n {content}\n </Dialog.Popup>\n </Dialog.Viewport>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n"],"mappings":"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"}
package/dist/payment.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { n as LockerverseTheme, t as LockerverseStyle } from "./theme.js";
1
2
  import { a as LockerversePaymentRecovery, c as LockerversePaymentTheme, i as LockerversePaymentProps, l as LockerversePaymentUncertain, o as LockerversePaymentSelectionItem, r as LockerversePaymentBranding, s as LockerversePaymentStyle, u as LockerverseStripeLoader } from "./types.js";
2
3
  import { t as LockerversePayment } from "./lockerverse-payment.js";
3
- export { LockerversePayment, type LockerversePaymentBranding, type LockerversePaymentProps, type LockerversePaymentRecovery, type LockerversePaymentSelectionItem, type LockerversePaymentStyle, type LockerversePaymentTheme, type LockerversePaymentUncertain, type LockerverseStripeLoader };
4
+ export { LockerversePayment, type LockerversePaymentBranding, type LockerversePaymentProps, type LockerversePaymentRecovery, type LockerversePaymentSelectionItem, type LockerversePaymentStyle, type LockerversePaymentTheme, type LockerversePaymentUncertain, type LockerverseStripeLoader, type LockerverseStyle, type LockerverseTheme };
package/dist/signup.css CHANGED
@@ -1,41 +1,59 @@
1
1
  @import "./form-ui.css";
2
2
 
3
3
  .lockerverse-signup {
4
- --lockerverse-signup-accent: #5751f2;
5
- --lockerverse-signup-accent-contrast: #fff;
6
- --lockerverse-signup-bg: #080808;
7
- --lockerverse-signup-border: rgb(255 255 255 / 12%);
8
- --lockerverse-signup-control: #101010;
9
- --lockerverse-signup-danger: #f4a0ab;
10
- --lockerverse-signup-font-family:
11
- ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
12
- sans-serif;
13
- --lockerverse-signup-muted: rgb(255 255 255 / 66%);
14
- --lockerverse-signup-placeholder: rgb(255 255 255 / 34%);
15
- --lockerverse-signup-radius: 10px;
16
- --lockerverse-signup-subtle: rgb(255 255 255 / 8%);
17
- --lockerverse-signup-text: #fff;
4
+ --lockerverse-accent: var(--lockerverse-signup-accent, #5751f2);
5
+ --lockerverse-accent-contrast: var(
6
+ --lockerverse-signup-accent-contrast,
7
+ #fff
8
+ );
9
+ --lockerverse-bg: var(--lockerverse-signup-bg, #080808);
10
+ --lockerverse-border: var(
11
+ --lockerverse-signup-border,
12
+ rgb(255 255 255 / 12%)
13
+ );
14
+ --lockerverse-control: var(--lockerverse-signup-control, #101010);
15
+ --lockerverse-danger: var(--lockerverse-signup-danger, #f4a0ab);
16
+ --lockerverse-font-family: var(
17
+ --lockerverse-signup-font-family,
18
+ ui-sans-serif,
19
+ system-ui,
20
+ -apple-system,
21
+ BlinkMacSystemFont,
22
+ "Segoe UI",
23
+ sans-serif
24
+ );
25
+ --lockerverse-muted: var(--lockerverse-signup-muted, rgb(255 255 255 / 66%));
26
+ --lockerverse-placeholder: var(
27
+ --lockerverse-signup-placeholder,
28
+ rgb(255 255 255 / 34%)
29
+ );
30
+ --lockerverse-radius: var(--lockerverse-signup-radius, 10px);
31
+ --lockerverse-subtle: var(--lockerverse-signup-subtle, rgb(255 255 255 / 8%));
32
+ --lockerverse-text: var(--lockerverse-signup-text, #fff);
18
33
  box-sizing: border-box;
19
34
  width: 100%;
20
35
  max-width: 480px;
21
36
  padding: clamp(16px, 4.2%, 20px);
22
- font-family: var(--lockerverse-signup-font-family);
37
+ font-family: var(--lockerverse-font-family);
23
38
  font-size: 15px;
24
39
  line-height: 1.4;
25
- color: var(--lockerverse-signup-text);
26
- background: var(--lockerverse-signup-bg);
27
- border-radius: var(--lockerverse-signup-radius);
40
+ color: var(--lockerverse-text);
41
+ background: var(--lockerverse-bg);
42
+ border-radius: var(--lockerverse-radius);
28
43
  }
29
44
 
30
45
  .lockerverse-signup[data-lockerverse-theme="light"] {
31
- --lockerverse-signup-bg: #fff;
32
- --lockerverse-signup-border: rgb(18 20 22 / 14%);
33
- --lockerverse-signup-control: #f5f6f7;
34
- --lockerverse-signup-danger: #c52b3e;
35
- --lockerverse-signup-muted: rgb(18 20 22 / 64%);
36
- --lockerverse-signup-placeholder: rgb(18 20 22 / 38%);
37
- --lockerverse-signup-subtle: rgb(18 20 22 / 8%);
38
- --lockerverse-signup-text: #121416;
46
+ --lockerverse-bg: var(--lockerverse-signup-bg, #fff);
47
+ --lockerverse-border: var(--lockerverse-signup-border, rgb(18 20 22 / 14%));
48
+ --lockerverse-control: var(--lockerverse-signup-control, #f5f6f7);
49
+ --lockerverse-danger: var(--lockerverse-signup-danger, #c52b3e);
50
+ --lockerverse-muted: var(--lockerverse-signup-muted, rgb(18 20 22 / 64%));
51
+ --lockerverse-placeholder: var(
52
+ --lockerverse-signup-placeholder,
53
+ rgb(18 20 22 / 38%)
54
+ );
55
+ --lockerverse-subtle: var(--lockerverse-signup-subtle, rgb(18 20 22 / 8%));
56
+ --lockerverse-text: var(--lockerverse-signup-text, #121416);
39
57
  box-shadow: 0 18px 55px rgb(20 25 32 / 10%);
40
58
  }
41
59
 
@@ -56,8 +74,8 @@
56
74
  height: 192px;
57
75
  margin-bottom: 16px;
58
76
  object-fit: cover;
59
- border: 1px solid var(--lockerverse-signup-border);
60
- border-radius: var(--lockerverse-signup-radius);
77
+ border: 1px solid var(--lockerverse-border);
78
+ border-radius: var(--lockerverse-radius);
61
79
  }
62
80
 
63
81
  .lockerverse-signup__branding {
@@ -73,8 +91,8 @@
73
91
  width: 48px;
74
92
  height: 48px;
75
93
  object-fit: cover;
76
- border: 1px solid var(--lockerverse-signup-border);
77
- border-radius: var(--lockerverse-signup-radius);
94
+ border: 1px solid var(--lockerverse-border);
95
+ border-radius: var(--lockerverse-radius);
78
96
  }
79
97
 
80
98
  .lockerverse-signup__branding strong {
@@ -96,7 +114,7 @@
96
114
  .lockerverse-signup header p,
97
115
  .lockerverse-signup__status > p {
98
116
  margin-top: 12px;
99
- color: var(--lockerverse-signup-muted);
117
+ color: var(--lockerverse-muted);
100
118
  white-space: pre-line;
101
119
  }
102
120
 
@@ -114,7 +132,7 @@
114
132
  .lockerverse-signup__fields {
115
133
  padding-top: 14px;
116
134
  border-top: 1px solid
117
- color-mix(in srgb, var(--lockerverse-signup-text) 8%, transparent);
135
+ color-mix(in srgb, var(--lockerverse-text) 8%, transparent);
118
136
  }
119
137
 
120
138
  .lockerverse-signup select[multiple] {
@@ -122,7 +140,7 @@
122
140
  }
123
141
 
124
142
  .lockerverse-signup [aria-invalid="true"] {
125
- border-color: var(--lockerverse-signup-danger);
143
+ border-color: var(--lockerverse-danger);
126
144
  }
127
145
 
128
146
  .lockerverse-signup__choice {
@@ -138,25 +156,21 @@
138
156
  width: 19px;
139
157
  height: 19px;
140
158
  margin: 0;
141
- accent-color: var(--lockerverse-signup-accent);
159
+ accent-color: var(--lockerverse-accent);
142
160
  }
143
161
 
144
162
  .lockerverse-signup__field-error,
145
163
  .lockerverse-signup__submit-error {
146
164
  font-size: 13px;
147
- color: var(--lockerverse-signup-danger);
165
+ color: var(--lockerverse-danger);
148
166
  }
149
167
 
150
168
  .lockerverse-signup__submit-error {
151
169
  padding: 10px 12px;
152
- background: color-mix(
153
- in srgb,
154
- var(--lockerverse-signup-danger) 10%,
155
- transparent
156
- );
170
+ background: color-mix(in srgb, var(--lockerverse-danger) 10%, transparent);
157
171
  border: 1px solid
158
- color-mix(in srgb, var(--lockerverse-signup-danger) 40%, transparent);
159
- border-radius: var(--lockerverse-signup-radius);
172
+ color-mix(in srgb, var(--lockerverse-danger) 40%, transparent);
173
+ border-radius: var(--lockerverse-radius);
160
174
  }
161
175
 
162
176
  .lockerverse-signup__submit,
@@ -165,11 +179,11 @@
165
179
  padding: 11px 16px;
166
180
  font: inherit;
167
181
  font-weight: 600;
168
- color: var(--lockerverse-signup-accent-contrast);
182
+ color: var(--lockerverse-accent-contrast);
169
183
  cursor: pointer;
170
- background: var(--lockerverse-signup-accent);
184
+ background: var(--lockerverse-accent);
171
185
  border: 1px solid transparent;
172
- border-radius: var(--lockerverse-signup-radius);
186
+ border-radius: var(--lockerverse-radius);
173
187
  }
174
188
 
175
189
  .lockerverse-signup__submit:disabled {
@@ -206,7 +220,7 @@
206
220
  top: 15px;
207
221
  right: 12px;
208
222
  font-size: 12px;
209
- color: var(--lockerverse-signup-muted);
223
+ color: var(--lockerverse-muted);
210
224
  }
211
225
 
212
226
  .lockerverse-signup__address-suggestions {
@@ -218,9 +232,9 @@
218
232
  max-height: 240px;
219
233
  padding: 4px;
220
234
  overflow-y: auto;
221
- background: var(--lockerverse-signup-control);
222
- border: 1px solid var(--lockerverse-signup-border);
223
- border-radius: var(--lockerverse-signup-radius);
235
+ background: var(--lockerverse-control);
236
+ border: 1px solid var(--lockerverse-border);
237
+ border-radius: var(--lockerverse-radius);
224
238
  box-shadow: 0 18px 48px rgb(0 0 0 / 48%);
225
239
  }
226
240
 
@@ -230,7 +244,7 @@
230
244
  width: 100%;
231
245
  padding: 9px 10px;
232
246
  font: inherit;
233
- color: var(--lockerverse-signup-text);
247
+ color: var(--lockerverse-text);
234
248
  text-align: left;
235
249
  cursor: pointer;
236
250
  background: transparent;
@@ -239,16 +253,12 @@
239
253
  }
240
254
 
241
255
  .lockerverse-signup__address-suggestions button:hover {
242
- background: color-mix(
243
- in srgb,
244
- var(--lockerverse-signup-text) 8%,
245
- transparent
246
- );
256
+ background: color-mix(in srgb, var(--lockerverse-text) 8%, transparent);
247
257
  }
248
258
 
249
259
  .lockerverse-signup .lockerverse-signup__address-suggestions span {
250
260
  font-size: 12px;
251
- color: var(--lockerverse-signup-muted);
261
+ color: var(--lockerverse-muted);
252
262
  }
253
263
 
254
264
  .lockerverse-signup__status {
@@ -271,8 +281,8 @@
271
281
  margin-bottom: 20px;
272
282
  font-size: 28px;
273
283
  font-weight: 700;
274
- color: var(--lockerverse-signup-accent-contrast);
275
- background: var(--lockerverse-signup-accent);
284
+ color: var(--lockerverse-accent-contrast);
285
+ background: var(--lockerverse-accent);
276
286
  border-radius: 50%;
277
287
  }
278
288
 
package/dist/signup.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { CSSProperties, ComponentPropsWithoutRef } from "react";
1
+ import { n as LockerverseTheme, t as LockerverseStyle } from "./theme.js";
2
+ import { ComponentPropsWithoutRef } from "react";
2
3
  import { CreateLockerverseSignupOptions, LockerverseSdkError, LockerverseSignup as LockerverseSignup$1, LockerverseSignupClient, LockerverseSignupSubmissionResult } from "@lockerverse/sdk/signup";
3
4
  //#region src/use-lockerverse-signup.d.ts
4
5
  type UseLockerverseSignupResult = {
@@ -11,14 +12,15 @@ type UseLockerverseSignupResult = {
11
12
  declare function useLockerverseSignup(options: CreateLockerverseSignupOptions): UseLockerverseSignupResult;
12
13
  //#endregion
13
14
  //#region src/signup-types.d.ts
14
- type LockerverseSignupTheme = "dark" | "light";
15
+ type LockerverseSignupTheme = LockerverseTheme;
15
16
  type LockerverseSignupBranding = {
16
17
  accentColor?: string;
17
18
  imageUrl?: string | null;
18
19
  name: string;
19
20
  };
20
- type LockerverseSignupStyle = CSSProperties & {
21
+ type LockerverseSignupStyle = LockerverseStyle & {
21
22
  "--lockerverse-signup-accent"?: string;
23
+ "--lockerverse-signup-accent-contrast"?: string;
22
24
  "--lockerverse-signup-bg"?: string;
23
25
  "--lockerverse-signup-border"?: string;
24
26
  "--lockerverse-signup-control"?: string;
@@ -44,5 +46,5 @@ type LockerverseSignupProps = LockerverseSignupViewProps & {
44
46
  //#region src/lockerverse-signup.d.ts
45
47
  declare function LockerverseSignup({ widget, ...viewProps }: LockerverseSignupProps): import("react").JSX.Element;
46
48
  //#endregion
47
- export { LockerverseSignup, type LockerverseSignupBranding, type LockerverseSignupProps, type LockerverseSignupStyle, type LockerverseSignupTheme, type UseLockerverseSignupResult, useLockerverseSignup };
49
+ export { LockerverseSignup, type LockerverseSignupBranding, type LockerverseSignupProps, type LockerverseSignupStyle, type LockerverseSignupTheme, type LockerverseStyle, type LockerverseTheme, type UseLockerverseSignupResult, useLockerverseSignup };
48
50
  //# sourceMappingURL=signup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signup.d.ts","names":[],"sources":["../src/use-lockerverse-signup.ts","../src/signup-types.ts","../src/lockerverse-signup.tsx"],"mappings":";;;KAeY;EACV,QAAQ;EACR,OAAO;EACP;EACA;EACA,QAAQ;;iBAGM,qBACd,SAAS,iCACR;;;KCrBS;KAEA;EACV;EACA;EACA;;KAGU,yBAAyB;EACnC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGG,6BAA6B,KAChC;EAGA,WAAW;EACX;EACA,oBAAoB,YAAY;EAChC,QAAQ;EACR,QAAQ;;KAGE,yBAAyB;EACnC,QAAQ;;;;iBC0ZM,oBACd,WACG,aACF,yCAAsB,IAAA"}
1
+ {"version":3,"file":"signup.d.ts","names":[],"sources":["../src/use-lockerverse-signup.ts","../src/signup-types.ts","../src/lockerverse-signup.tsx"],"mappings":";;;;KAeY;EACV,QAAQ;EACR,OAAO;EACP;EACA;EACA,QAAQ;;iBAGM,qBACd,SAAS,iCACR;;;KCpBS,yBAAyB;KAEzB;EACV;EACA;EACA;;KAGU,yBAAyB;EACnC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGG,6BAA6B,KAChC;EAGA,WAAW;EACX;EACA,oBAAoB,YAAY;EAChC,QAAQ;EACR,QAAQ;;KAGE,yBAAyB;EACnC,QAAQ;;;;iBCoaM,oBACd,WACG,aACF,yCAAsB,IAAA"}
package/dist/signup.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,u}from"./contact-validation.js";import{t as d}from"./immutable-resource-identity.js";import{useCallback as f,useEffect as p,useId as m,useRef as h,useState as g}from"react";import{check as _,nonEmpty as v,nullable as y,object as b,pipe as x,regex as S,safeParse as C,string as w,transform as T,trim as E}from"valibot";import{jsx as D,jsxs as O}from"react/jsx-runtime";import{createLockerverseSignupClient as k}from"@lockerverse/sdk/signup";const A=`lockerverse-signup-google-places`,j=[`premise`,`subpremise`,`street_address`,`route`];let M=null;function N(e){let t=window;if(t.google?.maps?.importLibrary)return;t.google||={};let n=t.google;n.maps||={};let r=n.maps,i=null;r.importLibrary=n=>(i||=new Promise((t,i)=>{let a=document.getElementById(A);if(r.__lockerverseSignupReady=t,a){a.addEventListener(`error`,()=>i(Error(`Unable to load Google Places.`)),{once:!0});return}let o=document.createElement(`script`),s=new URLSearchParams({callback:`google.maps.__lockerverseSignupReady`,key:e,libraries:n,v:`weekly`});o.async=!0,o.id=A,o.src=`https://maps.googleapis.com/maps/api/js?${s}`,o.onerror=()=>i(Error(`Unable to load Google Places.`)),document.head.append(o)}),i.then(()=>t.google?.maps?.importLibrary?.(n)).catch(e=>{throw i=null,document.getElementById(A)?.remove(),e}))}function P(e){return M||=(async()=>{try{return N(e),await window.google?.maps?.importLibrary?.(`places`)}catch(e){throw M=null,e}})(),M}function F(e,t,n=`longText`){return e.find(e=>e.types.includes(t))?.[n]??``}function I(e,t){let n=t.addressComponents??[],r=[F(n,`street_number`),F(n,`route`)].filter(Boolean).join(` `);return{...e,city:F(n,`locality`)||F(n,`postal_town`)||F(n,`sublocality_level_1`),country:F(n,`country`,`shortText`)||`US`,line1:r||t.formattedAddress?.split(`,`)[0]||``,line2:F(n,`subpremise`),postalCode:[F(n,`postal_code`),F(n,`postal_code_suffix`)].filter(Boolean).join(`-`),state:F(n,`administrative_area_level_1`,`shortText`)}}function L({apiKey:e,errorId:t,invalid:n,onChange:r,required:i,value:a}){let o=m(),s=`${o}-suggestions`,[c,l]=g(-1),[u,d]=g(!1),[f,_]=g(!1),[v,y]=g([]),b=h(0),x=h(null);p(()=>{let t=b.current+1;b.current=t;let n=a.line1.trim();if(l(-1),_(!1),!(e&&u&&n.length>=3)){y([]);return}let r=window.setTimeout(async()=>{if(t===b.current){_(!0);try{let{AutocompleteSessionToken:r,AutocompleteSuggestion:i}=await P(e);x.current??=new r;let a=await i.fetchAutocompleteSuggestions({includedPrimaryTypes:j,includedRegionCodes:[`US`],input:n,region:`US`,sessionToken:x.current});t===b.current&&y(a.suggestions.flatMap(({placePrediction:e})=>e?[{id:e.placeId,label:e.mainText?.text??e.text.text,prediction:e,secondaryLabel:e.secondaryText?.text??``}]:[]))}catch{t===b.current&&y([])}finally{t===b.current&&_(!1)}}},250);return()=>{window.clearTimeout(r)}},[e,u,a.line1]);let S=e=>r({...a,...e}),C=async e=>{let t=e.prediction.toPlace();try{await t.fetchFields({fields:[`addressComponents`,`formattedAddress`]}),r(I(a,t)),x.current=null,y([]),l(-1),d(!1)}catch{y([]),l(-1)}};return O(`fieldset`,{"aria-describedby":n?t:void 0,"aria-invalid":n?`true`:void 0,className:`lockerverse-signup__address`,children:[D(`legend`,{children:`Address`}),O(`label`,{htmlFor:`${o}-line1`,children:[D(`span`,{children:`Street address`}),O(`div`,{className:`lockerverse-signup__address-search`,children:[D(`input`,{"aria-activedescendant":c>=0?`${o}-suggestion-${c}`:void 0,"aria-autocomplete":`list`,"aria-controls":s,"aria-describedby":n?t:void 0,"aria-expanded":u&&v.length>0,"aria-invalid":n?`true`:void 0,autoComplete:`street-address`,id:`${o}-line1`,name:`address.line1`,onBlur:()=>window.setTimeout(()=>d(!1),120),onChange:e=>S({line1:e.currentTarget.value}),onFocus:()=>d(!0),onKeyDown:e=>{if(e.key===`Escape`){e.preventDefault(),y([]),l(-1);return}if(v.length===0)return;if(e.key===`ArrowDown`){e.preventDefault(),l(e=>e<v.length-1?e+1:0);return}if(e.key===`ArrowUp`){e.preventDefault(),l(e=>e>0?e-1:v.length-1);return}let t=v[c];e.key===`Enter`&&t&&(e.preventDefault(),C(t).catch(()=>void 0))},required:i,role:`combobox`,value:a.line1}),f?D(`span`,{className:`lockerverse-signup__address-loading`,children:`Searching…`}):null,v.length>0?D(`div`,{className:`lockerverse-signup__address-suggestions`,id:s,role:`listbox`,children:v.map((e,t)=>O(`button`,{"aria-selected":c===t,id:`${o}-suggestion-${t}`,onMouseDown:t=>{t.preventDefault(),C(e).catch(()=>void 0)},role:`option`,type:`button`,children:[D(`strong`,{children:e.label}),e.secondaryLabel?D(`span`,{children:e.secondaryLabel}):null]},e.id))}):null]})]}),O(`label`,{htmlFor:`${o}-line2`,children:[D(`span`,{children:`Apartment, suite, or unit`}),D(`input`,{autoComplete:`address-line2`,id:`${o}-line2`,onChange:e=>S({line2:e.currentTarget.value}),placeholder:`Optional`,value:a.line2??``})]}),O(`div`,{className:`lockerverse-signup__address-row`,children:[O(`label`,{htmlFor:`${o}-city`,children:[D(`span`,{children:`City`}),D(`input`,{autoComplete:`address-level2`,id:`${o}-city`,onChange:e=>S({city:e.currentTarget.value}),required:i,value:a.city})]}),O(`label`,{htmlFor:`${o}-state`,children:[D(`span`,{children:`State`}),D(`input`,{autoComplete:`address-level1`,id:`${o}-state`,onChange:e=>S({state:e.currentTarget.value}),required:i,value:a.state})]})]}),O(`div`,{className:`lockerverse-signup__address-row`,children:[O(`label`,{htmlFor:`${o}-postal`,children:[D(`span`,{children:`Postal code`}),D(`input`,{autoComplete:`postal-code`,id:`${o}-postal`,onChange:e=>S({postalCode:e.currentTarget.value}),required:i,value:a.postalCode})]}),O(`label`,{htmlFor:`${o}-country`,children:[D(`span`,{children:`Country`}),D(`input`,{autoComplete:`country`,id:`${o}-country`,maxLength:2,onChange:e=>S({country:e.currentTarget.value.toUpperCase()}),required:i,value:a.country})]})]})]})}const ee=/^[1-9]\d*$/,te=/^(?:$|[1-9]\d*)$/,R=x(w(),E(),v(`Name is required.`)),z=x(w(),E(),S(te,`Guest count must be a positive whole number.`),T(e=>e?Number(e):null),_(e=>e===null||Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),B=x(w(),E(),v(`Guest count is required.`),S(ee,`Guest count must be a positive whole number.`),T(Number),_(e=>Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),V=b({city:w(),country:w(),line1:w(),line2:y(w()),postalCode:w(),state:w()}),H=x(V,_(K,`Complete the address.`)),U={city:``,country:`US`,line1:``,line2:null,postalCode:``,state:``},W=x(V,_(e=>G(e)||K(e),`Complete the address or leave it blank.`));function G(e){return![e.city,e.line1,e.line2,e.postalCode,e.state].some(e=>e?.trim())}function K(e){return[e.city,e.country,e.line1,e.postalCode,e.state].every(e=>e.trim())}function q(t,n){let r={...n,address:t.fields.address.enabled?n.address:U,email:t.fields.email.enabled?n.email:``,participantCount:t.fields.participantCount.enabled?n.participantCount:``,phone:t.fields.phone.enabled?n.phone:``},a=b({address:t.fields.address.enabled&&t.fields.address.required?H:W,email:t.fields.email.enabled&&t.fields.email.required?i:o,name:R,participantCount:t.fields.participantCount.enabled&&t.fields.participantCount.required?B:z,phone:t.fields.phone.enabled&&t.fields.phone.required?e:c}),s=C(a,r),l=u(t.customFields,n.customFields);if(!s.success)for(let e of s.issues){let t=e.path?.[0]?.key;typeof t==`string`&&!l[t]&&(l[t]=e.message)}return s.success?{errors:l,value:{...n,...s.output}}:{errors:l,value:null}}const J={city:``,country:`US`,line1:``,line2:``,postalCode:``,state:``};function Y(e){return{address:J,customFields:a(e.customFields),email:``,honeypot:``,name:``,participantCount:``,phone:``}}function X({error:e,id:t}){return e?D(`span`,{className:`lockerverse-signup__field-error`,id:t,role:`alert`,children:e}):null}function Z(e,t){let n=e.elements.namedItem(t);if(n instanceof HTMLElement)return!n.matches(`:disabled`)&&(n.focus(),!0);if(n instanceof RadioNodeList){let e=Array.from(n).find(e=>e instanceof HTMLElement&&!e.matches(`:disabled`));return e?.focus(),!!e}return!1}function ne(e,t){let n=[[`name`,`name`],[`email`,`email`],[`phone`,`phone`],[`participantCount`,`participantCount`],[`address`,`address.line1`]];for(let[r,i]of n)if(t[r]&&Z(e,i))return;let r=new Set(n.map(([e])=>e)),i=Object.keys(t).find(e=>!r.has(e));i&&Z(e,`custom:${i}`)}function Q({children:e,loading:t=!1,status:i=!1,viewProps:a}){let{branding:o,className:s,googlePlacesApiKey:c,onSignupComplete:l,style:u,theme:d=`dark`,...f}=a,p=r(o?.accentColor??`#5751f2`),m={"--lockerverse-signup-accent":p,"--lockerverse-signup-accent-contrast":n(p),...u};return D(`section`,{...f,...t?{"aria-busy":!0}:{},className:[`lockerverse-signup`,i?`lockerverse-signup__status`:null,s].filter(Boolean).join(` `),"data-lockerverse-theme":d,style:m,children:e})}function re({client:e,signup:n,...r}){let{branding:i,googlePlacesApiKey:a,onSignupComplete:o}=r,s=m(),c=h(!0),u=h(!1),[d,f]=g({phase:`idle`}),[_,v]=g(()=>Y(n)),[y,b]=g({}),[x,S]=g();if(p(()=>(c.current=!0,()=>{c.current=!1}),[]),!n.isActive)return O(Q,{status:!0,viewProps:r,children:[D(`h1`,{children:`Signup closed`}),D(`p`,{children:`This signup is not accepting submissions.`})]});if(d.phase===`submitted`)return O(Q,{status:!0,viewProps:r,children:[i?D($,{branding:i}):null,D(`span`,{"aria-hidden":`true`,className:`lockerverse-signup__success`,children:`✓`}),D(`h1`,{children:`Thank you`}),D(`p`,{children:`Your signup has been received.`})]});let C=e=>v({..._,...e}),w=d.phase===`submitting`,T=d.phase===`submit_error`?d.error.message:void 0;return O(Q,{viewProps:r,children:[n.coverImageUrl?D(`img`,{alt:``,className:`lockerverse-signup__cover`,height:192,src:n.coverImageUrl,width:440}):null,i?D($,{branding:i}):null,O(`header`,{children:[n.title?.trim()?D(`h1`,{children:n.title}):null,n.description?D(`p`,{children:n.description}):null]}),O(`form`,{noValidate:!0,onSubmit:async r=>{if(r.preventDefault(),u.current)return;let i=q(n,_);if(b(i.errors),Object.keys(i.errors).length>0||!i.value){let e=r.currentTarget;queueMicrotask(()=>ne(e,i.errors));return}let a=i.value,s={address:n.fields.address.enabled&&!G(a.address)?a.address:null,answers:t(n.customFields,a.customFields),email:n.fields.email.enabled&&a.email||null,honeypot:a.honeypot,name:a.name,participantCount:n.fields.participantCount.enabled?a.participantCount:null,phone:n.fields.phone.enabled&&a.phone||null},l=JSON.stringify(s),d=x?.payloadKey===l?x.reference:globalThis.crypto.randomUUID(),p;u.current=!0,f({phase:`submitting`});try{p=await e.submit(s,{submissionReference:d})}catch(e){if(!c.current)return;let t=e;f({error:t,phase:`submit_error`}),t.recoveryRecommended?S({payloadKey:l,reference:d}):S(void 0);return}finally{u.current=!1}c.current&&(S(void 0),f({phase:`submitted`}),o?.(p))},children:[D(`input`,{"aria-hidden":`true`,autoComplete:`off`,className:`lockerverse-signup__honeypot`,onChange:e=>C({honeypot:e.currentTarget.value}),tabIndex:-1,value:_.honeypot}),O(`div`,{className:`lockerverse-signup__fields`,children:[O(`label`,{htmlFor:`${s}-name`,children:[D(`span`,{children:`Name`}),D(`input`,{"aria-describedby":y.name?`${s}-name-error`:void 0,"aria-invalid":y.name?`true`:void 0,autoComplete:`name`,id:`${s}-name`,name:`name`,onChange:e=>C({name:e.currentTarget.value}),required:!0,value:_.name}),D(X,{error:y.name,id:`${s}-name-error`})]}),n.fields.email.enabled?O(`label`,{htmlFor:`${s}-email`,children:[D(`span`,{children:`Email`}),D(`input`,{"aria-describedby":y.email?`${s}-email-error`:void 0,"aria-invalid":y.email?`true`:void 0,autoComplete:`email`,id:`${s}-email`,name:`email`,onChange:e=>C({email:e.currentTarget.value}),required:n.fields.email.required,type:`email`,value:_.email}),D(X,{error:y.email,id:`${s}-email-error`})]}):null,n.fields.phone.enabled?O(`label`,{htmlFor:`${s}-phone`,children:[D(`span`,{children:`Phone`}),D(`input`,{"aria-describedby":y.phone?`${s}-phone-error`:void 0,"aria-invalid":y.phone?`true`:void 0,autoComplete:`tel`,id:`${s}-phone`,name:`phone`,onChange:e=>C({phone:e.currentTarget.value}),placeholder:`+1 555 555 0123`,required:n.fields.phone.required,type:`tel`,value:_.phone}),D(X,{error:y.phone,id:`${s}-phone-error`})]}):null,n.fields.participantCount.enabled?O(`label`,{htmlFor:`${s}-participant-count`,children:[D(`span`,{children:`Guest count`}),D(`input`,{"aria-describedby":y.participantCount?`${s}-participant-count-error`:void 0,"aria-invalid":y.participantCount?`true`:void 0,id:`${s}-participant-count`,min:1,name:`participantCount`,onChange:e=>C({participantCount:e.currentTarget.value}),required:n.fields.participantCount.required,type:`number`,value:_.participantCount}),D(X,{error:y.participantCount,id:`${s}-participant-count-error`})]}):null,n.fields.address.enabled?O(`div`,{className:`lockerverse-signup__field-group`,children:[D(L,{apiKey:a,errorId:y.address?`${s}-address-error`:void 0,invalid:!!y.address,onChange:e=>C({address:e}),required:n.fields.address.required,value:_.address}),D(X,{error:y.address,id:`${s}-address-error`})]}):null,D(l,{choiceClassName:`lockerverse-signup__choice`,errorClassName:`lockerverse-signup__field-error`,errors:y,fields:n.customFields,idPrefix:s,onChange:e=>C({customFields:e}),values:_.customFields})]}),T?O(`p`,{className:`lockerverse-signup__submit-error`,role:`alert`,children:[T,` Try again.`]}):null,D(`button`,{className:`lockerverse-signup__submit`,disabled:w,type:`submit`,children:w?`Submitting…`:`Submit`})]})]})}function ie({widget:e,...t}){return e.error?O(Q,{status:!0,viewProps:t,children:[D(`h1`,{children:`Signup unavailable`}),D(`p`,{role:`alert`,children:e.error.message}),D(`button`,{onClick:e.refresh,type:`button`,children:`Retry`})]}):e.loading||!e.signup?D(Q,{loading:!0,viewProps:t,children:D(s,{fieldCount:4,label:`Loading signup…`})}):D(re,{client:e.client,signup:e.signup,...t})}function $({branding:e}){return O(`div`,{className:`lockerverse-signup__branding`,children:[e.imageUrl?D(`img`,{alt:``,height:48,src:e.imageUrl,width:48}):null,D(`strong`,{children:e.name})]})}function ae(e){let{onError:t}=e;d(`signup`,{apiBaseUrl:e.apiBaseUrl,communitySlug:e.communitySlug,environment:e.environment,slug:e.signupSlug});let n=h(t);n.current=t;let[r]=g(()=>k({...e,onError:e=>n.current?.(e)})),[i,a]=g(0),[o,s]=g({error:null,signup:null});p(()=>{let e=!0;return r.load().then(t=>{e&&s({error:null,signup:t})},t=>{e&&s({error:t,signup:null})}),()=>{e=!1}},[r,i]);let c=f(()=>{s({error:null,signup:null}),a(e=>e+1)},[]);return{client:r,error:o.error,loading:o.signup===null&&o.error===null,refresh:c,signup:o.signup}}export{ie as LockerverseSignup,ae as useLockerverseSignup};
1
+ import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,u}from"./contact-validation.js";import{t as d}from"./immutable-resource-identity.js";import{useCallback as f,useEffect as p,useId as m,useRef as h,useState as g}from"react";import{check as _,nonEmpty as v,nullable as y,object as b,pipe as x,regex as S,safeParse as C,string as w,transform as T,trim as E}from"valibot";import{jsx as D,jsxs as O}from"react/jsx-runtime";import{createLockerverseSignupClient as k}from"@lockerverse/sdk/signup";const A=`lockerverse-signup-google-places`,j=[`premise`,`subpremise`,`street_address`,`route`];let M=null;function N(e){let t=window;if(t.google?.maps?.importLibrary)return;t.google||={};let n=t.google;n.maps||={};let r=n.maps,i=null;r.importLibrary=n=>(i||=new Promise((t,i)=>{let a=document.getElementById(A);if(r.__lockerverseSignupReady=t,a){a.addEventListener(`error`,()=>i(Error(`Unable to load Google Places.`)),{once:!0});return}let o=document.createElement(`script`),s=new URLSearchParams({callback:`google.maps.__lockerverseSignupReady`,key:e,libraries:n,v:`weekly`});o.async=!0,o.id=A,o.src=`https://maps.googleapis.com/maps/api/js?${s}`,o.onerror=()=>i(Error(`Unable to load Google Places.`)),document.head.append(o)}),i.then(()=>t.google?.maps?.importLibrary?.(n)).catch(e=>{throw i=null,document.getElementById(A)?.remove(),e}))}function P(e){return M||=(async()=>{try{return N(e),await window.google?.maps?.importLibrary?.(`places`)}catch(e){throw M=null,e}})(),M}function F(e,t,n=`longText`){return e.find(e=>e.types.includes(t))?.[n]??``}function I(e,t){let n=t.addressComponents??[],r=[F(n,`street_number`),F(n,`route`)].filter(Boolean).join(` `);return{...e,city:F(n,`locality`)||F(n,`postal_town`)||F(n,`sublocality_level_1`),country:F(n,`country`,`shortText`)||`US`,line1:r||t.formattedAddress?.split(`,`)[0]||``,line2:F(n,`subpremise`),postalCode:[F(n,`postal_code`),F(n,`postal_code_suffix`)].filter(Boolean).join(`-`),state:F(n,`administrative_area_level_1`,`shortText`)}}function L({apiKey:e,errorId:t,invalid:n,onChange:r,required:i,value:a}){let o=m(),s=`${o}-suggestions`,[c,l]=g(-1),[u,d]=g(!1),[f,_]=g(!1),[v,y]=g([]),b=h(0),x=h(null);p(()=>{let t=b.current+1;b.current=t;let n=a.line1.trim();if(l(-1),_(!1),!(e&&u&&n.length>=3)){y([]);return}let r=window.setTimeout(async()=>{if(t===b.current){_(!0);try{let{AutocompleteSessionToken:r,AutocompleteSuggestion:i}=await P(e);x.current??=new r;let a=await i.fetchAutocompleteSuggestions({includedPrimaryTypes:j,includedRegionCodes:[`US`],input:n,region:`US`,sessionToken:x.current});t===b.current&&y(a.suggestions.flatMap(({placePrediction:e})=>e?[{id:e.placeId,label:e.mainText?.text??e.text.text,prediction:e,secondaryLabel:e.secondaryText?.text??``}]:[]))}catch{t===b.current&&y([])}finally{t===b.current&&_(!1)}}},250);return()=>{window.clearTimeout(r)}},[e,u,a.line1]);let S=e=>r({...a,...e}),C=async e=>{let t=e.prediction.toPlace();try{await t.fetchFields({fields:[`addressComponents`,`formattedAddress`]}),r(I(a,t)),x.current=null,y([]),l(-1),d(!1)}catch{y([]),l(-1)}};return O(`fieldset`,{"aria-describedby":n?t:void 0,"aria-invalid":n?`true`:void 0,className:`lockerverse-signup__address`,children:[D(`legend`,{children:`Address`}),O(`label`,{htmlFor:`${o}-line1`,children:[D(`span`,{children:`Street address`}),O(`div`,{className:`lockerverse-signup__address-search`,children:[D(`input`,{"aria-activedescendant":c>=0?`${o}-suggestion-${c}`:void 0,"aria-autocomplete":`list`,"aria-controls":s,"aria-describedby":n?t:void 0,"aria-expanded":u&&v.length>0,"aria-invalid":n?`true`:void 0,autoComplete:`street-address`,id:`${o}-line1`,name:`address.line1`,onBlur:()=>window.setTimeout(()=>d(!1),120),onChange:e=>S({line1:e.currentTarget.value}),onFocus:()=>d(!0),onKeyDown:e=>{if(e.key===`Escape`){e.preventDefault(),y([]),l(-1);return}if(v.length===0)return;if(e.key===`ArrowDown`){e.preventDefault(),l(e=>e<v.length-1?e+1:0);return}if(e.key===`ArrowUp`){e.preventDefault(),l(e=>e>0?e-1:v.length-1);return}let t=v[c];e.key===`Enter`&&t&&(e.preventDefault(),C(t).catch(()=>void 0))},required:i,role:`combobox`,value:a.line1}),f?D(`span`,{className:`lockerverse-signup__address-loading`,children:`Searching…`}):null,v.length>0?D(`div`,{className:`lockerverse-signup__address-suggestions`,id:s,role:`listbox`,children:v.map((e,t)=>O(`button`,{"aria-selected":c===t,id:`${o}-suggestion-${t}`,onMouseDown:t=>{t.preventDefault(),C(e).catch(()=>void 0)},role:`option`,type:`button`,children:[D(`strong`,{children:e.label}),e.secondaryLabel?D(`span`,{children:e.secondaryLabel}):null]},e.id))}):null]})]}),O(`label`,{htmlFor:`${o}-line2`,children:[D(`span`,{children:`Apartment, suite, or unit`}),D(`input`,{autoComplete:`address-line2`,id:`${o}-line2`,onChange:e=>S({line2:e.currentTarget.value}),placeholder:`Optional`,value:a.line2??``})]}),O(`div`,{className:`lockerverse-signup__address-row`,children:[O(`label`,{htmlFor:`${o}-city`,children:[D(`span`,{children:`City`}),D(`input`,{autoComplete:`address-level2`,id:`${o}-city`,onChange:e=>S({city:e.currentTarget.value}),required:i,value:a.city})]}),O(`label`,{htmlFor:`${o}-state`,children:[D(`span`,{children:`State`}),D(`input`,{autoComplete:`address-level1`,id:`${o}-state`,onChange:e=>S({state:e.currentTarget.value}),required:i,value:a.state})]})]}),O(`div`,{className:`lockerverse-signup__address-row`,children:[O(`label`,{htmlFor:`${o}-postal`,children:[D(`span`,{children:`Postal code`}),D(`input`,{autoComplete:`postal-code`,id:`${o}-postal`,onChange:e=>S({postalCode:e.currentTarget.value}),required:i,value:a.postalCode})]}),O(`label`,{htmlFor:`${o}-country`,children:[D(`span`,{children:`Country`}),D(`input`,{autoComplete:`country`,id:`${o}-country`,maxLength:2,onChange:e=>S({country:e.currentTarget.value.toUpperCase()}),required:i,value:a.country})]})]})]})}const ee=/^[1-9]\d*$/,te=/^(?:$|[1-9]\d*)$/,R=x(w(),E(),v(`Name is required.`)),z=x(w(),E(),S(te,`Guest count must be a positive whole number.`),T(e=>e?Number(e):null),_(e=>e===null||Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),B=x(w(),E(),v(`Guest count is required.`),S(ee,`Guest count must be a positive whole number.`),T(Number),_(e=>Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),V=b({city:w(),country:w(),line1:w(),line2:y(w()),postalCode:w(),state:w()}),H=x(V,_(K,`Complete the address.`)),U={city:``,country:`US`,line1:``,line2:null,postalCode:``,state:``},W=x(V,_(e=>G(e)||K(e),`Complete the address or leave it blank.`));function G(e){return![e.city,e.line1,e.line2,e.postalCode,e.state].some(e=>e?.trim())}function K(e){return[e.city,e.country,e.line1,e.postalCode,e.state].every(e=>e.trim())}function q(t,n){let r={...n,address:t.fields.address.enabled?n.address:U,email:t.fields.email.enabled?n.email:``,participantCount:t.fields.participantCount.enabled?n.participantCount:``,phone:t.fields.phone.enabled?n.phone:``},a=b({address:t.fields.address.enabled&&t.fields.address.required?H:W,email:t.fields.email.enabled&&t.fields.email.required?i:o,name:R,participantCount:t.fields.participantCount.enabled&&t.fields.participantCount.required?B:z,phone:t.fields.phone.enabled&&t.fields.phone.required?e:c}),s=C(a,r),l=u(t.customFields,n.customFields);if(!s.success)for(let e of s.issues){let t=e.path?.[0]?.key;typeof t==`string`&&!l[t]&&(l[t]=e.message)}return s.success?{errors:l,value:{...n,...s.output}}:{errors:l,value:null}}const J={city:``,country:`US`,line1:``,line2:``,postalCode:``,state:``};function Y(e){return{address:J,customFields:a(e.customFields),email:``,honeypot:``,name:``,participantCount:``,phone:``}}function X({error:e,id:t}){return e?D(`span`,{className:`lockerverse-signup__field-error`,id:t,role:`alert`,children:e}):null}function Z(e,t){let n=e.elements.namedItem(t);if(n instanceof HTMLElement)return!n.matches(`:disabled`)&&(n.focus(),!0);if(n instanceof RadioNodeList){let e=Array.from(n).find(e=>e instanceof HTMLElement&&!e.matches(`:disabled`));return e?.focus(),!!e}return!1}function ne(e,t){let n=[[`name`,`name`],[`email`,`email`],[`phone`,`phone`],[`participantCount`,`participantCount`],[`address`,`address.line1`]];for(let[r,i]of n)if(t[r]&&Z(e,i))return;let r=new Set(n.map(([e])=>e)),i=Object.keys(t).find(e=>!r.has(e));i&&Z(e,`custom:${i}`)}function Q({children:e,loading:t=!1,status:i=!1,viewProps:a}){let{branding:o,className:s,googlePlacesApiKey:c,onSignupComplete:l,style:u,theme:d=`dark`,...f}=a,p=r(u?.[`--lockerverse-accent`]??u?.[`--lockerverse-signup-accent`]??o?.accentColor??`#5751f2`),m={...u,...u?.[`--lockerverse-accent`]!==void 0||u?.[`--lockerverse-signup-accent`]!==void 0||o?.accentColor?{"--lockerverse-accent":p}:{},...u?.[`--lockerverse-accent-contrast`]===void 0&&u?.[`--lockerverse-signup-accent-contrast`]===void 0?{"--lockerverse-accent-contrast":n(p)}:{}};return D(`section`,{...f,...t?{"aria-busy":!0}:{},className:[`lockerverse-signup`,i?`lockerverse-signup__status`:null,s].filter(Boolean).join(` `),"data-lockerverse-theme":d,style:m,children:e})}function re({client:e,signup:n,...r}){let{branding:i,googlePlacesApiKey:a,onSignupComplete:o}=r,s=m(),c=h(!0),u=h(!1),[d,f]=g({phase:`idle`}),[_,v]=g(()=>Y(n)),[y,b]=g({}),[x,S]=g();if(p(()=>(c.current=!0,()=>{c.current=!1}),[]),!n.isActive)return O(Q,{status:!0,viewProps:r,children:[D(`h1`,{children:`Signup closed`}),D(`p`,{children:`This signup is not accepting submissions.`})]});if(d.phase===`submitted`)return O(Q,{status:!0,viewProps:r,children:[i?D($,{branding:i}):null,D(`span`,{"aria-hidden":`true`,className:`lockerverse-signup__success`,children:`✓`}),D(`h1`,{children:`Thank you`}),D(`p`,{children:`Your signup has been received.`})]});let C=e=>v({..._,...e}),w=d.phase===`submitting`,T=d.phase===`submit_error`?d.error.message:void 0;return O(Q,{viewProps:r,children:[n.coverImageUrl?D(`img`,{alt:``,className:`lockerverse-signup__cover`,height:192,src:n.coverImageUrl,width:440}):null,i?D($,{branding:i}):null,O(`header`,{children:[n.title?.trim()?D(`h1`,{children:n.title}):null,n.description?D(`p`,{children:n.description}):null]}),O(`form`,{noValidate:!0,onSubmit:async r=>{if(r.preventDefault(),u.current)return;let i=q(n,_);if(b(i.errors),Object.keys(i.errors).length>0||!i.value){let e=r.currentTarget;queueMicrotask(()=>ne(e,i.errors));return}let a=i.value,s={address:n.fields.address.enabled&&!G(a.address)?a.address:null,answers:t(n.customFields,a.customFields),email:n.fields.email.enabled&&a.email||null,honeypot:a.honeypot,name:a.name,participantCount:n.fields.participantCount.enabled?a.participantCount:null,phone:n.fields.phone.enabled&&a.phone||null},l=JSON.stringify(s),d=x?.payloadKey===l?x.reference:globalThis.crypto.randomUUID(),p;u.current=!0,f({phase:`submitting`});try{p=await e.submit(s,{submissionReference:d})}catch(e){if(!c.current)return;let t=e;f({error:t,phase:`submit_error`}),t.recoveryRecommended?S({payloadKey:l,reference:d}):S(void 0);return}finally{u.current=!1}c.current&&(S(void 0),f({phase:`submitted`}),o?.(p))},children:[D(`input`,{"aria-hidden":`true`,autoComplete:`off`,className:`lockerverse-signup__honeypot`,onChange:e=>C({honeypot:e.currentTarget.value}),tabIndex:-1,value:_.honeypot}),O(`div`,{className:`lockerverse-signup__fields`,children:[O(`label`,{htmlFor:`${s}-name`,children:[D(`span`,{children:`Name`}),D(`input`,{"aria-describedby":y.name?`${s}-name-error`:void 0,"aria-invalid":y.name?`true`:void 0,autoComplete:`name`,id:`${s}-name`,name:`name`,onChange:e=>C({name:e.currentTarget.value}),required:!0,value:_.name}),D(X,{error:y.name,id:`${s}-name-error`})]}),n.fields.email.enabled?O(`label`,{htmlFor:`${s}-email`,children:[D(`span`,{children:`Email`}),D(`input`,{"aria-describedby":y.email?`${s}-email-error`:void 0,"aria-invalid":y.email?`true`:void 0,autoComplete:`email`,id:`${s}-email`,name:`email`,onChange:e=>C({email:e.currentTarget.value}),required:n.fields.email.required,type:`email`,value:_.email}),D(X,{error:y.email,id:`${s}-email-error`})]}):null,n.fields.phone.enabled?O(`label`,{htmlFor:`${s}-phone`,children:[D(`span`,{children:`Phone`}),D(`input`,{"aria-describedby":y.phone?`${s}-phone-error`:void 0,"aria-invalid":y.phone?`true`:void 0,autoComplete:`tel`,id:`${s}-phone`,name:`phone`,onChange:e=>C({phone:e.currentTarget.value}),placeholder:`+1 555 555 0123`,required:n.fields.phone.required,type:`tel`,value:_.phone}),D(X,{error:y.phone,id:`${s}-phone-error`})]}):null,n.fields.participantCount.enabled?O(`label`,{htmlFor:`${s}-participant-count`,children:[D(`span`,{children:`Guest count`}),D(`input`,{"aria-describedby":y.participantCount?`${s}-participant-count-error`:void 0,"aria-invalid":y.participantCount?`true`:void 0,id:`${s}-participant-count`,min:1,name:`participantCount`,onChange:e=>C({participantCount:e.currentTarget.value}),required:n.fields.participantCount.required,type:`number`,value:_.participantCount}),D(X,{error:y.participantCount,id:`${s}-participant-count-error`})]}):null,n.fields.address.enabled?O(`div`,{className:`lockerverse-signup__field-group`,children:[D(L,{apiKey:a,errorId:y.address?`${s}-address-error`:void 0,invalid:!!y.address,onChange:e=>C({address:e}),required:n.fields.address.required,value:_.address}),D(X,{error:y.address,id:`${s}-address-error`})]}):null,D(l,{choiceClassName:`lockerverse-signup__choice`,errorClassName:`lockerverse-signup__field-error`,errors:y,fields:n.customFields,idPrefix:s,onChange:e=>C({customFields:e}),values:_.customFields})]}),T?O(`p`,{className:`lockerverse-signup__submit-error`,role:`alert`,children:[T,` Try again.`]}):null,D(`button`,{className:`lockerverse-signup__submit`,disabled:w,type:`submit`,children:w?`Submitting…`:`Submit`})]})]})}function ie({widget:e,...t}){return e.error?O(Q,{status:!0,viewProps:t,children:[D(`h1`,{children:`Signup unavailable`}),D(`p`,{role:`alert`,children:e.error.message}),D(`button`,{onClick:e.refresh,type:`button`,children:`Retry`})]}):e.loading||!e.signup?D(Q,{loading:!0,viewProps:t,children:D(s,{fieldCount:4,label:`Loading signup…`})}):D(re,{client:e.client,signup:e.signup,...t})}function $({branding:e}){return O(`div`,{className:`lockerverse-signup__branding`,children:[e.imageUrl?D(`img`,{alt:``,height:48,src:e.imageUrl,width:48}):null,D(`strong`,{children:e.name})]})}function ae(e){let{onError:t}=e;d(`signup`,{apiBaseUrl:e.apiBaseUrl,communitySlug:e.communitySlug,environment:e.environment,slug:e.signupSlug});let n=h(t);n.current=t;let[r]=g(()=>k({...e,onError:e=>n.current?.(e)})),[i,a]=g(0),[o,s]=g({error:null,signup:null});p(()=>{let e=!0;return r.load().then(t=>{e&&s({error:null,signup:t})},t=>{e&&s({error:t,signup:null})}),()=>{e=!1}},[r,i]);let c=f(()=>{s({error:null,signup:null}),a(e=>e+1)},[]);return{client:r,error:o.error,loading:o.signup===null&&o.error===null,refresh:c,signup:o.signup}}export{ie as LockerverseSignup,ae as useLockerverseSignup};
2
2
  //# sourceMappingURL=signup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signup.js","names":["googleWindow"],"sources":["../src/signup-address-field.tsx","../src/signup-validation.ts","../src/lockerverse-signup.tsx","../src/use-lockerverse-signup.ts"],"sourcesContent":["import { type KeyboardEvent, useEffect, useId, useRef, useState } from \"react\";\nimport type { SignupAddressValues } from \"./signup-validation.ts\";\n\ntype GoogleAddressComponent = {\n longText?: string;\n shortText?: string;\n types: string[];\n};\n\ntype GooglePlace = {\n addressComponents?: GoogleAddressComponent[];\n formattedAddress?: string;\n fetchFields: (options: { fields: string[] }) => Promise<void>;\n};\n\ntype GooglePlacePrediction = {\n placeId: string;\n mainText?: { text: string };\n secondaryText?: { text: string };\n text: { text: string };\n toPlace: () => GooglePlace;\n};\n\ntype GooglePlacesLibrary = {\n AutocompleteSessionToken: new () => unknown;\n AutocompleteSuggestion: {\n fetchAutocompleteSuggestions: (options: {\n input: string;\n includedPrimaryTypes: string[];\n includedRegionCodes: string[];\n region: string;\n sessionToken: unknown;\n }) => Promise<{\n suggestions: { placePrediction?: GooglePlacePrediction }[];\n }>;\n };\n};\n\ntype GoogleMapsWindow = Window & {\n google?: {\n maps?: {\n __lockerverseSignupReady?: () => void;\n importLibrary?: (libraryName: string) => Promise<unknown>;\n };\n };\n};\n\ntype AddressSuggestion = {\n id: string;\n label: string;\n secondaryLabel: string;\n prediction: GooglePlacePrediction;\n};\n\nconst GOOGLE_MAPS_SCRIPT_ID = \"lockerverse-signup-google-places\";\nconst GOOGLE_ADDRESS_TYPES = [\n \"premise\",\n \"subpremise\",\n \"street_address\",\n \"route\",\n];\nlet googlePlacesLoader: Promise<GooglePlacesLibrary> | null = null;\n\nfunction installGoogleMaps(apiKey: string) {\n const googleWindow = window as GoogleMapsWindow;\n if (googleWindow.google?.maps?.importLibrary) {\n return;\n }\n googleWindow.google ||= {};\n const googleObject = googleWindow.google;\n googleObject.maps ||= {};\n const mapsObject = googleObject.maps;\n let scriptPromise: Promise<void> | null = null;\n mapsObject.importLibrary = (libraryName: string) => {\n scriptPromise ||= new Promise((resolve, reject) => {\n const existingScript = document.getElementById(GOOGLE_MAPS_SCRIPT_ID);\n mapsObject.__lockerverseSignupReady = resolve;\n if (existingScript) {\n existingScript.addEventListener(\n \"error\",\n () => reject(new Error(\"Unable to load Google Places.\")),\n { once: true }\n );\n return;\n }\n const script = document.createElement(\"script\");\n const parameters = new URLSearchParams({\n callback: \"google.maps.__lockerverseSignupReady\",\n key: apiKey,\n libraries: libraryName,\n v: \"weekly\",\n });\n script.async = true;\n script.id = GOOGLE_MAPS_SCRIPT_ID;\n script.src = `https://maps.googleapis.com/maps/api/js?${parameters}`;\n script.onerror = () => reject(new Error(\"Unable to load Google Places.\"));\n document.head.append(script);\n });\n return scriptPromise\n .then(() => googleWindow.google?.maps?.importLibrary?.(libraryName))\n .catch((error) => {\n scriptPromise = null;\n document.getElementById(GOOGLE_MAPS_SCRIPT_ID)?.remove();\n throw error;\n });\n };\n}\n\nfunction loadGooglePlaces(apiKey: string) {\n googlePlacesLoader ||= (async () => {\n try {\n installGoogleMaps(apiKey);\n const googleWindow = window as GoogleMapsWindow;\n return (await googleWindow.google?.maps?.importLibrary?.(\n \"places\"\n )) as GooglePlacesLibrary;\n } catch (error) {\n googlePlacesLoader = null;\n throw error;\n }\n })();\n return googlePlacesLoader;\n}\n\nfunction getAddressPart(\n components: GoogleAddressComponent[],\n type: string,\n key: \"longText\" | \"shortText\" = \"longText\"\n) {\n return (\n components.find((component) => component.types.includes(type))?.[key] ?? \"\"\n );\n}\n\nfunction parseAddress(current: SignupAddressValues, place: GooglePlace) {\n const components = place.addressComponents ?? [];\n const street = [\n getAddressPart(components, \"street_number\"),\n getAddressPart(components, \"route\"),\n ]\n .filter(Boolean)\n .join(\" \");\n return {\n ...current,\n city:\n getAddressPart(components, \"locality\") ||\n getAddressPart(components, \"postal_town\") ||\n getAddressPart(components, \"sublocality_level_1\"),\n country: getAddressPart(components, \"country\", \"shortText\") || \"US\",\n line1: street || place.formattedAddress?.split(\",\")[0] || \"\",\n line2: getAddressPart(components, \"subpremise\"),\n postalCode: [\n getAddressPart(components, \"postal_code\"),\n getAddressPart(components, \"postal_code_suffix\"),\n ]\n .filter(Boolean)\n .join(\"-\"),\n state: getAddressPart(\n components,\n \"administrative_area_level_1\",\n \"shortText\"\n ),\n } satisfies SignupAddressValues;\n}\n\nexport function SignupAddressField({\n apiKey,\n errorId,\n invalid,\n onChange,\n required,\n value,\n}: {\n apiKey: string | undefined;\n errorId: string | undefined;\n invalid: boolean;\n onChange: (address: SignupAddressValues) => void;\n required: boolean;\n value: SignupAddressValues;\n}) {\n const id = useId();\n const listboxId = `${id}-suggestions`;\n const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(-1);\n const [focused, setFocused] = useState(false);\n const [loading, setLoading] = useState(false);\n const [suggestions, setSuggestions] = useState<AddressSuggestion[]>([]);\n const searchGeneration = useRef(0);\n const sessionToken = useRef<unknown>(null);\n\n useEffect(() => {\n const generation = searchGeneration.current + 1;\n searchGeneration.current = generation;\n const query = value.line1.trim();\n setActiveSuggestionIndex(-1);\n setLoading(false);\n if (!(apiKey && focused && query.length >= 3)) {\n setSuggestions([]);\n return;\n }\n const timeout = window.setTimeout(async () => {\n if (generation !== searchGeneration.current) {\n return;\n }\n setLoading(true);\n try {\n const { AutocompleteSessionToken, AutocompleteSuggestion } =\n await loadGooglePlaces(apiKey);\n sessionToken.current ??= new AutocompleteSessionToken();\n const response =\n await AutocompleteSuggestion.fetchAutocompleteSuggestions({\n includedPrimaryTypes: GOOGLE_ADDRESS_TYPES,\n includedRegionCodes: [\"US\"],\n input: query,\n region: \"US\",\n sessionToken: sessionToken.current,\n });\n if (generation === searchGeneration.current) {\n setSuggestions(\n response.suggestions.flatMap(({ placePrediction }) =>\n placePrediction\n ? [\n {\n id: placePrediction.placeId,\n label:\n placePrediction.mainText?.text ??\n placePrediction.text.text,\n prediction: placePrediction,\n secondaryLabel: placePrediction.secondaryText?.text ?? \"\",\n },\n ]\n : []\n )\n );\n }\n } catch {\n if (generation === searchGeneration.current) {\n setSuggestions([]);\n }\n } finally {\n if (generation === searchGeneration.current) {\n setLoading(false);\n }\n }\n }, 250);\n return () => {\n window.clearTimeout(timeout);\n };\n }, [apiKey, focused, value.line1]);\n\n const update = (patch: Partial<SignupAddressValues>) =>\n onChange({ ...value, ...patch });\n\n const selectSuggestion = async (suggestion: AddressSuggestion) => {\n const place = suggestion.prediction.toPlace();\n try {\n await place.fetchFields({\n fields: [\"addressComponents\", \"formattedAddress\"],\n });\n onChange(parseAddress(value, place));\n sessionToken.current = null;\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n setFocused(false);\n } catch {\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n }\n };\n\n const handleAddressKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n return;\n }\n if (suggestions.length === 0) {\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current < suggestions.length - 1 ? current + 1 : 0\n );\n return;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current > 0 ? current - 1 : suggestions.length - 1\n );\n return;\n }\n const suggestion = suggestions[activeSuggestionIndex];\n if (event.key === \"Enter\" && suggestion) {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }\n };\n\n return (\n <fieldset\n aria-describedby={invalid ? errorId : undefined}\n aria-invalid={invalid ? \"true\" : undefined}\n className=\"lockerverse-signup__address\"\n >\n <legend>Address</legend>\n <label htmlFor={`${id}-line1`}>\n <span>Street address</span>\n <div className=\"lockerverse-signup__address-search\">\n <input\n aria-activedescendant={\n activeSuggestionIndex >= 0\n ? `${id}-suggestion-${activeSuggestionIndex}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-describedby={invalid ? errorId : undefined}\n aria-expanded={focused && suggestions.length > 0}\n aria-invalid={invalid ? \"true\" : undefined}\n autoComplete=\"street-address\"\n id={`${id}-line1`}\n name=\"address.line1\"\n onBlur={() => window.setTimeout(() => setFocused(false), 120)}\n onChange={(event) => update({ line1: event.currentTarget.value })}\n onFocus={() => setFocused(true)}\n onKeyDown={handleAddressKeyDown}\n required={required}\n role=\"combobox\"\n value={value.line1}\n />\n {loading ? (\n <span className=\"lockerverse-signup__address-loading\">\n Searching…\n </span>\n ) : null}\n {suggestions.length > 0 ? (\n <div\n className=\"lockerverse-signup__address-suggestions\"\n id={listboxId}\n role=\"listbox\"\n >\n {suggestions.map((suggestion, index) => (\n <button\n aria-selected={activeSuggestionIndex === index}\n id={`${id}-suggestion-${index}`}\n key={suggestion.id}\n onMouseDown={(event) => {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }}\n role=\"option\"\n type=\"button\"\n >\n <strong>{suggestion.label}</strong>\n {suggestion.secondaryLabel ? (\n <span>{suggestion.secondaryLabel}</span>\n ) : null}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n </label>\n <label htmlFor={`${id}-line2`}>\n <span>Apartment, suite, or unit</span>\n <input\n autoComplete=\"address-line2\"\n id={`${id}-line2`}\n onChange={(event) => update({ line2: event.currentTarget.value })}\n placeholder=\"Optional\"\n value={value.line2 ?? \"\"}\n />\n </label>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-city`}>\n <span>City</span>\n <input\n autoComplete=\"address-level2\"\n id={`${id}-city`}\n onChange={(event) => update({ city: event.currentTarget.value })}\n required={required}\n value={value.city}\n />\n </label>\n <label htmlFor={`${id}-state`}>\n <span>State</span>\n <input\n autoComplete=\"address-level1\"\n id={`${id}-state`}\n onChange={(event) => update({ state: event.currentTarget.value })}\n required={required}\n value={value.state}\n />\n </label>\n </div>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-postal`}>\n <span>Postal code</span>\n <input\n autoComplete=\"postal-code\"\n id={`${id}-postal`}\n onChange={(event) =>\n update({ postalCode: event.currentTarget.value })\n }\n required={required}\n value={value.postalCode}\n />\n </label>\n <label htmlFor={`${id}-country`}>\n <span>Country</span>\n <input\n autoComplete=\"country\"\n id={`${id}-country`}\n maxLength={2}\n onChange={(event) =>\n update({ country: event.currentTarget.value.toUpperCase() })\n }\n required={required}\n value={value.country}\n />\n </label>\n </div>\n </fieldset>\n );\n}\n","import type {\n LockerverseSignup,\n LockerverseSignupAddress,\n} from \"@lockerverse/sdk/signup\";\nimport {\n check,\n nonEmpty,\n nullable,\n object,\n pipe,\n regex,\n safeParse,\n string,\n transform,\n trim,\n} from \"valibot\";\nimport {\n optionalEmailSchema,\n optionalPhoneSchema,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\nimport { validateCustomFields } from \"./custom-fields.tsx\";\n\nconst POSITIVE_INTEGER_PATTERN = /^[1-9]\\d*$/;\nconst OPTIONAL_POSITIVE_INTEGER_PATTERN = /^(?:$|[1-9]\\d*)$/;\n\nexport type SignupAddressValues = Omit<LockerverseSignupAddress, \"line2\"> & {\n line2: string | null;\n};\n\nexport type SignupFormValues = {\n address: SignupAddressValues;\n customFields: Record<string, string | string[]>;\n email: string;\n honeypot: string;\n name: string;\n participantCount: string;\n phone: string;\n};\n\nconst nameSchema = pipe(string(), trim(), nonEmpty(\"Name is required.\"));\nconst optionalParticipantCountSchema = pipe(\n string(),\n trim(),\n regex(\n OPTIONAL_POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform((value) => (value ? Number(value) : null)),\n check(\n (value) => value === null || Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst requiredParticipantCountSchema = pipe(\n string(),\n trim(),\n nonEmpty(\"Guest count is required.\"),\n regex(\n POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform(Number),\n check(\n (value) => Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst addressShape = object({\n city: string(),\n country: string(),\n line1: string(),\n line2: nullable(string()),\n postalCode: string(),\n state: string(),\n});\nconst requiredAddressSchema = pipe(\n addressShape,\n check(isAddressComplete, \"Complete the address.\")\n);\n\nconst EMPTY_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: null,\n postalCode: \"\",\n state: \"\",\n};\nconst optionalAddressSchema = pipe(\n addressShape,\n check(\n (address) => isAddressEmpty(address) || isAddressComplete(address),\n \"Complete the address or leave it blank.\"\n )\n);\n\nexport function isAddressEmpty(address: SignupAddressValues) {\n return ![\n address.city,\n address.line1,\n address.line2,\n address.postalCode,\n address.state,\n ].some((value) => value?.trim());\n}\n\nfunction isAddressComplete(address: SignupAddressValues) {\n return [\n address.city,\n address.country,\n address.line1,\n address.postalCode,\n address.state,\n ].every((value) => value.trim());\n}\n\nexport function validateSignupForm(\n signup: LockerverseSignup,\n values: SignupFormValues\n) {\n const normalizedValues = {\n ...values,\n address: signup.fields.address.enabled ? values.address : EMPTY_ADDRESS,\n email: signup.fields.email.enabled ? values.email : \"\",\n participantCount: signup.fields.participantCount.enabled\n ? values.participantCount\n : \"\",\n phone: signup.fields.phone.enabled ? values.phone : \"\",\n };\n const schema = object({\n address:\n signup.fields.address.enabled && signup.fields.address.required\n ? requiredAddressSchema\n : optionalAddressSchema,\n email:\n signup.fields.email.enabled && signup.fields.email.required\n ? requiredEmailSchema\n : optionalEmailSchema,\n name: nameSchema,\n participantCount:\n signup.fields.participantCount.enabled &&\n signup.fields.participantCount.required\n ? requiredParticipantCountSchema\n : optionalParticipantCountSchema,\n phone:\n signup.fields.phone.enabled && signup.fields.phone.required\n ? requiredPhoneSchema\n : optionalPhoneSchema,\n });\n const result = safeParse(schema, normalizedValues);\n const errors = validateCustomFields(signup.customFields, values.customFields);\n if (!result.success) {\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n if (typeof field === \"string\" && !errors[field]) {\n errors[field] = issue.message;\n }\n }\n }\n return result.success\n ? { errors, value: { ...values, ...result.output } }\n : { errors, value: null };\n}\n","import type {\n LockerverseSdkError,\n LockerverseSignupClient,\n LockerverseSignup as LockerverseSignupDefinition,\n LockerverseSignupSubmissionResult,\n} from \"@lockerverse/sdk/signup\";\nimport {\n type FormEvent,\n type ReactNode,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { getAccentContrast, normalizeAccentColor } from \"./accent-contrast.ts\";\nimport {\n buildCustomFieldAnswers,\n CustomFields,\n createCustomFieldValues,\n} from \"./custom-fields.tsx\";\nimport { FormSkeleton } from \"./form-skeleton.tsx\";\nimport { SignupAddressField } from \"./signup-address-field.tsx\";\nimport type { LockerverseSignupProps } from \"./signup-types.ts\";\nimport {\n type SignupFormValues as FormValues,\n isAddressEmpty,\n type SignupAddressValues,\n validateSignupForm,\n} from \"./signup-validation.ts\";\n\nconst DEFAULT_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: \"\",\n postalCode: \"\",\n state: \"\",\n};\n\nconst DEFAULT_ACCENT = \"#5751f2\";\n\nfunction createInitialValues(signup: LockerverseSignupDefinition): FormValues {\n return {\n address: DEFAULT_ADDRESS,\n customFields: createCustomFieldValues(signup.customFields),\n email: \"\",\n honeypot: \"\",\n name: \"\",\n participantCount: \"\",\n phone: \"\",\n };\n}\n\nfunction FieldError({ error, id }: { error: string | undefined; id: string }) {\n return error ? (\n <span className=\"lockerverse-signup__field-error\" id={id} role=\"alert\">\n {error}\n </span>\n ) : null;\n}\n\nfunction focusNamedControl(form: HTMLFormElement, name: string) {\n const control = form.elements.namedItem(name);\n if (control instanceof HTMLElement) {\n if (!control.matches(\":disabled\")) {\n control.focus();\n return true;\n }\n return false;\n }\n if (control instanceof RadioNodeList) {\n const focusable = Array.from(control).find(\n (item) => item instanceof HTMLElement && !item.matches(\":disabled\")\n );\n focusable?.focus();\n return Boolean(focusable);\n }\n return false;\n}\n\nfunction focusFirstSignupValidationError(\n form: HTMLFormElement,\n errors: Record<string, string>\n) {\n const builtInFields: [string, string][] = [\n [\"name\", \"name\"],\n [\"email\", \"email\"],\n [\"phone\", \"phone\"],\n [\"participantCount\", \"participantCount\"],\n [\"address\", \"address.line1\"],\n ];\n for (const [errorKey, controlName] of builtInFields) {\n if (errors[errorKey] && focusNamedControl(form, controlName)) {\n return;\n }\n }\n const builtInKeys = new Set(builtInFields.map(([errorKey]) => errorKey));\n const customFieldId = Object.keys(errors).find(\n (errorKey) => !builtInKeys.has(errorKey)\n );\n if (customFieldId) {\n focusNamedControl(form, `custom:${customFieldId}`);\n }\n}\n\ntype SignupViewProps = Omit<LockerverseSignupProps, \"widget\">;\n\nfunction SignupShell({\n children,\n loading = false,\n status = false,\n viewProps,\n}: {\n children: ReactNode;\n loading?: boolean;\n status?: boolean;\n viewProps: SignupViewProps;\n}) {\n const {\n branding,\n className,\n googlePlacesApiKey: _googlePlacesApiKey,\n onSignupComplete: _onSignupComplete,\n style,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const accent = normalizeAccentColor(branding?.accentColor ?? DEFAULT_ACCENT);\n const signupStyle = {\n \"--lockerverse-signup-accent\": accent,\n \"--lockerverse-signup-accent-contrast\": getAccentContrast(accent),\n ...style,\n } as React.CSSProperties;\n return (\n <section\n {...sectionProps}\n {...(loading ? { \"aria-busy\": true } : {})}\n className={[\n \"lockerverse-signup\",\n status ? \"lockerverse-signup__status\" : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n data-lockerverse-theme={theme}\n style={signupStyle}\n >\n {children}\n </section>\n );\n}\n\ntype SignupWorkflowState =\n | { phase: \"idle\" }\n | { phase: \"submitting\" }\n | {\n error: LockerverseSdkError;\n phase: \"submit_error\";\n }\n | {\n phase: \"submitted\";\n };\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: The component renders server-defined field branches in one public form boundary.\nfunction SignupForm({\n client,\n signup,\n ...viewProps\n}: SignupViewProps & {\n client: LockerverseSignupClient;\n signup: LockerverseSignupDefinition;\n}) {\n const { branding, googlePlacesApiKey, onSignupComplete } = viewProps;\n const idPrefix = useId();\n const mountedRef = useRef(true);\n const submittingRef = useRef(false);\n const [state, setState] = useState<SignupWorkflowState>({ phase: \"idle\" });\n const [values, setValues] = useState<FormValues>(() =>\n createInitialValues(signup)\n );\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [submissionRetry, setSubmissionRetry] = useState<{\n payloadKey: string;\n reference: string;\n }>();\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n if (!signup.isActive) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup closed</h1>\n <p>This signup is not accepting submissions.</p>\n </SignupShell>\n );\n }\n\n if (state.phase === \"submitted\") {\n return (\n <SignupShell status viewProps={viewProps}>\n {branding ? <Branding branding={branding} /> : null}\n <span aria-hidden=\"true\" className=\"lockerverse-signup__success\">\n ✓\n </span>\n <h1>Thank you</h1>\n <p>Your signup has been received.</p>\n </SignupShell>\n );\n }\n\n const update = (patch: Partial<FormValues>) =>\n setValues({ ...values, ...patch });\n const submitting = state.phase === \"submitting\";\n const submitError =\n state.phase === \"submit_error\" ? state.error.message : undefined;\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Submission maps the enabled server-defined fields to one SDK request.\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref blocks a second submit before React commits the submitting state.\n if (submittingRef.current) {\n return;\n }\n const validation = validateSignupForm(signup, values);\n setErrors(validation.errors);\n if (Object.keys(validation.errors).length > 0 || !validation.value) {\n const form = event.currentTarget;\n queueMicrotask(() =>\n focusFirstSignupValidationError(form, validation.errors)\n );\n return;\n }\n const validatedValues = validation.value;\n const submission = {\n address:\n signup.fields.address.enabled &&\n !isAddressEmpty(validatedValues.address)\n ? validatedValues.address\n : null,\n answers: buildCustomFieldAnswers(\n signup.customFields,\n validatedValues.customFields\n ),\n email: signup.fields.email.enabled ? validatedValues.email || null : null,\n honeypot: validatedValues.honeypot,\n name: validatedValues.name,\n participantCount: signup.fields.participantCount.enabled\n ? validatedValues.participantCount\n : null,\n phone: signup.fields.phone.enabled ? validatedValues.phone || null : null,\n };\n const payloadKey = JSON.stringify(submission);\n const submissionReference =\n submissionRetry?.payloadKey === payloadKey\n ? submissionRetry.reference\n : globalThis.crypto.randomUUID();\n let result: LockerverseSignupSubmissionResult;\n submittingRef.current = true;\n setState({ phase: \"submitting\" });\n try {\n result = await client.submit(submission, { submissionReference });\n } catch (error) {\n if (!mountedRef.current) {\n return;\n }\n const sdkError = error as LockerverseSdkError;\n setState({ error: sdkError, phase: \"submit_error\" });\n if (sdkError.recoveryRecommended) {\n setSubmissionRetry({\n payloadKey,\n reference: submissionReference,\n });\n } else {\n setSubmissionRetry(undefined);\n }\n return;\n } finally {\n submittingRef.current = false;\n }\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref changes during unmount while this request is pending.\n if (!mountedRef.current) {\n return;\n }\n setSubmissionRetry(undefined);\n setState({ phase: \"submitted\" });\n onSignupComplete?.(result);\n };\n\n return (\n <SignupShell viewProps={viewProps}>\n {signup.coverImageUrl ? (\n <img\n alt=\"\"\n className=\"lockerverse-signup__cover\"\n height={192}\n src={signup.coverImageUrl}\n width={440}\n />\n ) : null}\n {branding ? <Branding branding={branding} /> : null}\n <header>\n {signup.title?.trim() ? <h1>{signup.title}</h1> : null}\n {signup.description ? <p>{signup.description}</p> : null}\n </header>\n <form noValidate onSubmit={handleSubmit}>\n <input\n aria-hidden=\"true\"\n autoComplete=\"off\"\n className=\"lockerverse-signup__honeypot\"\n onChange={(event) => update({ honeypot: event.currentTarget.value })}\n tabIndex={-1}\n value={values.honeypot}\n />\n <div className=\"lockerverse-signup__fields\">\n <label htmlFor={`${idPrefix}-name`}>\n <span>Name</span>\n <input\n aria-describedby={\n errors.name ? `${idPrefix}-name-error` : undefined\n }\n aria-invalid={errors.name ? \"true\" : undefined}\n autoComplete=\"name\"\n id={`${idPrefix}-name`}\n name=\"name\"\n onChange={(event) => update({ name: event.currentTarget.value })}\n required\n value={values.name}\n />\n <FieldError error={errors.name} id={`${idPrefix}-name-error`} />\n </label>\n {signup.fields.email.enabled ? (\n <label htmlFor={`${idPrefix}-email`}>\n <span>Email</span>\n <input\n aria-describedby={\n errors.email ? `${idPrefix}-email-error` : undefined\n }\n aria-invalid={errors.email ? \"true\" : undefined}\n autoComplete=\"email\"\n id={`${idPrefix}-email`}\n name=\"email\"\n onChange={(event) =>\n update({ email: event.currentTarget.value })\n }\n required={signup.fields.email.required}\n type=\"email\"\n value={values.email}\n />\n <FieldError error={errors.email} id={`${idPrefix}-email-error`} />\n </label>\n ) : null}\n {signup.fields.phone.enabled ? (\n <label htmlFor={`${idPrefix}-phone`}>\n <span>Phone</span>\n <input\n aria-describedby={\n errors.phone ? `${idPrefix}-phone-error` : undefined\n }\n aria-invalid={errors.phone ? \"true\" : undefined}\n autoComplete=\"tel\"\n id={`${idPrefix}-phone`}\n name=\"phone\"\n onChange={(event) =>\n update({ phone: event.currentTarget.value })\n }\n placeholder=\"+1 555 555 0123\"\n required={signup.fields.phone.required}\n type=\"tel\"\n value={values.phone}\n />\n <FieldError error={errors.phone} id={`${idPrefix}-phone-error`} />\n </label>\n ) : null}\n {signup.fields.participantCount.enabled ? (\n <label htmlFor={`${idPrefix}-participant-count`}>\n <span>Guest count</span>\n <input\n aria-describedby={\n errors.participantCount\n ? `${idPrefix}-participant-count-error`\n : undefined\n }\n aria-invalid={errors.participantCount ? \"true\" : undefined}\n id={`${idPrefix}-participant-count`}\n min={1}\n name=\"participantCount\"\n onChange={(event) =>\n update({ participantCount: event.currentTarget.value })\n }\n required={signup.fields.participantCount.required}\n type=\"number\"\n value={values.participantCount}\n />\n <FieldError\n error={errors.participantCount}\n id={`${idPrefix}-participant-count-error`}\n />\n </label>\n ) : null}\n {signup.fields.address.enabled ? (\n <div className=\"lockerverse-signup__field-group\">\n <SignupAddressField\n apiKey={googlePlacesApiKey}\n errorId={\n errors.address ? `${idPrefix}-address-error` : undefined\n }\n invalid={Boolean(errors.address)}\n onChange={(address) => update({ address })}\n required={signup.fields.address.required}\n value={values.address}\n />\n <FieldError\n error={errors.address}\n id={`${idPrefix}-address-error`}\n />\n </div>\n ) : null}\n <CustomFields\n choiceClassName=\"lockerverse-signup__choice\"\n errorClassName=\"lockerverse-signup__field-error\"\n errors={errors}\n fields={signup.customFields}\n idPrefix={idPrefix}\n onChange={(customFields) => update({ customFields })}\n values={values.customFields}\n />\n </div>\n {submitError ? (\n <p className=\"lockerverse-signup__submit-error\" role=\"alert\">\n {submitError} Try again.\n </p>\n ) : null}\n <button\n className=\"lockerverse-signup__submit\"\n disabled={submitting}\n type=\"submit\"\n >\n {submitting ? \"Submitting…\" : \"Submit\"}\n </button>\n </form>\n </SignupShell>\n );\n}\n\nexport function LockerverseSignup({\n widget,\n ...viewProps\n}: LockerverseSignupProps) {\n if (widget.error) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup unavailable</h1>\n <p role=\"alert\">{widget.error.message}</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </SignupShell>\n );\n }\n if (widget.loading || !widget.signup) {\n return (\n <SignupShell loading viewProps={viewProps}>\n <FormSkeleton fieldCount={4} label=\"Loading signup…\" />\n </SignupShell>\n );\n }\n return (\n <SignupForm client={widget.client} signup={widget.signup} {...viewProps} />\n );\n}\n\nfunction Branding({\n branding,\n}: {\n branding: NonNullable<LockerverseSignupProps[\"branding\"]>;\n}) {\n return (\n <div className=\"lockerverse-signup__branding\">\n {branding.imageUrl ? (\n <img alt=\"\" height={48} src={branding.imageUrl} width={48} />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n );\n}\n","import {\n type CreateLockerverseSignupOptions,\n createLockerverseSignupClient,\n type LockerverseSdkError,\n type LockerverseSignup,\n type LockerverseSignupClient,\n} from \"@lockerverse/sdk/signup\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useImmutableResourceIdentity } from \"./immutable-resource-identity.ts\";\n\ntype SignupLoadState = {\n error: LockerverseSdkError | null;\n signup: LockerverseSignup | null;\n};\n\nexport type UseLockerverseSignupResult = {\n client: LockerverseSignupClient;\n error: LockerverseSdkError | null;\n loading: boolean;\n refresh: () => void;\n signup: LockerverseSignup | null;\n};\n\nexport function useLockerverseSignup(\n options: CreateLockerverseSignupOptions\n): UseLockerverseSignupResult {\n const { onError } = options;\n useImmutableResourceIdentity(\"signup\", {\n apiBaseUrl: options.apiBaseUrl,\n communitySlug: options.communitySlug,\n environment: options.environment,\n slug: options.signupSlug,\n });\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const [client] = useState(() =>\n createLockerverseSignupClient({\n ...options,\n onError: (error) => onErrorRef.current?.(error),\n } as CreateLockerverseSignupOptions)\n );\n const [revision, setRevision] = useState(0);\n const [state, setState] = useState<SignupLoadState>({\n error: null,\n signup: null,\n });\n\n useEffect(() => {\n let active = true;\n client.load().then(\n (signup) => {\n if (active) {\n setState({\n error: null,\n signup,\n });\n }\n },\n (error: LockerverseSdkError) => {\n if (active) {\n setState({\n error,\n signup: null,\n });\n }\n }\n );\n return () => {\n active = false;\n };\n }, [client, revision]);\n\n const refresh = useCallback(() => {\n setState({\n error: null,\n signup: null,\n });\n setRevision((value) => value + 1);\n }, []);\n\n return {\n client,\n error: state.error,\n loading: state.signup === null && state.error === null,\n refresh,\n signup: state.signup,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"signup.js","names":["googleWindow"],"sources":["../src/signup-address-field.tsx","../src/signup-validation.ts","../src/lockerverse-signup.tsx","../src/use-lockerverse-signup.ts"],"sourcesContent":["import { type KeyboardEvent, useEffect, useId, useRef, useState } from \"react\";\nimport type { SignupAddressValues } from \"./signup-validation.ts\";\n\ntype GoogleAddressComponent = {\n longText?: string;\n shortText?: string;\n types: string[];\n};\n\ntype GooglePlace = {\n addressComponents?: GoogleAddressComponent[];\n formattedAddress?: string;\n fetchFields: (options: { fields: string[] }) => Promise<void>;\n};\n\ntype GooglePlacePrediction = {\n placeId: string;\n mainText?: { text: string };\n secondaryText?: { text: string };\n text: { text: string };\n toPlace: () => GooglePlace;\n};\n\ntype GooglePlacesLibrary = {\n AutocompleteSessionToken: new () => unknown;\n AutocompleteSuggestion: {\n fetchAutocompleteSuggestions: (options: {\n input: string;\n includedPrimaryTypes: string[];\n includedRegionCodes: string[];\n region: string;\n sessionToken: unknown;\n }) => Promise<{\n suggestions: { placePrediction?: GooglePlacePrediction }[];\n }>;\n };\n};\n\ntype GoogleMapsWindow = Window & {\n google?: {\n maps?: {\n __lockerverseSignupReady?: () => void;\n importLibrary?: (libraryName: string) => Promise<unknown>;\n };\n };\n};\n\ntype AddressSuggestion = {\n id: string;\n label: string;\n secondaryLabel: string;\n prediction: GooglePlacePrediction;\n};\n\nconst GOOGLE_MAPS_SCRIPT_ID = \"lockerverse-signup-google-places\";\nconst GOOGLE_ADDRESS_TYPES = [\n \"premise\",\n \"subpremise\",\n \"street_address\",\n \"route\",\n];\nlet googlePlacesLoader: Promise<GooglePlacesLibrary> | null = null;\n\nfunction installGoogleMaps(apiKey: string) {\n const googleWindow = window as GoogleMapsWindow;\n if (googleWindow.google?.maps?.importLibrary) {\n return;\n }\n googleWindow.google ||= {};\n const googleObject = googleWindow.google;\n googleObject.maps ||= {};\n const mapsObject = googleObject.maps;\n let scriptPromise: Promise<void> | null = null;\n mapsObject.importLibrary = (libraryName: string) => {\n scriptPromise ||= new Promise((resolve, reject) => {\n const existingScript = document.getElementById(GOOGLE_MAPS_SCRIPT_ID);\n mapsObject.__lockerverseSignupReady = resolve;\n if (existingScript) {\n existingScript.addEventListener(\n \"error\",\n () => reject(new Error(\"Unable to load Google Places.\")),\n { once: true }\n );\n return;\n }\n const script = document.createElement(\"script\");\n const parameters = new URLSearchParams({\n callback: \"google.maps.__lockerverseSignupReady\",\n key: apiKey,\n libraries: libraryName,\n v: \"weekly\",\n });\n script.async = true;\n script.id = GOOGLE_MAPS_SCRIPT_ID;\n script.src = `https://maps.googleapis.com/maps/api/js?${parameters}`;\n script.onerror = () => reject(new Error(\"Unable to load Google Places.\"));\n document.head.append(script);\n });\n return scriptPromise\n .then(() => googleWindow.google?.maps?.importLibrary?.(libraryName))\n .catch((error) => {\n scriptPromise = null;\n document.getElementById(GOOGLE_MAPS_SCRIPT_ID)?.remove();\n throw error;\n });\n };\n}\n\nfunction loadGooglePlaces(apiKey: string) {\n googlePlacesLoader ||= (async () => {\n try {\n installGoogleMaps(apiKey);\n const googleWindow = window as GoogleMapsWindow;\n return (await googleWindow.google?.maps?.importLibrary?.(\n \"places\"\n )) as GooglePlacesLibrary;\n } catch (error) {\n googlePlacesLoader = null;\n throw error;\n }\n })();\n return googlePlacesLoader;\n}\n\nfunction getAddressPart(\n components: GoogleAddressComponent[],\n type: string,\n key: \"longText\" | \"shortText\" = \"longText\"\n) {\n return (\n components.find((component) => component.types.includes(type))?.[key] ?? \"\"\n );\n}\n\nfunction parseAddress(current: SignupAddressValues, place: GooglePlace) {\n const components = place.addressComponents ?? [];\n const street = [\n getAddressPart(components, \"street_number\"),\n getAddressPart(components, \"route\"),\n ]\n .filter(Boolean)\n .join(\" \");\n return {\n ...current,\n city:\n getAddressPart(components, \"locality\") ||\n getAddressPart(components, \"postal_town\") ||\n getAddressPart(components, \"sublocality_level_1\"),\n country: getAddressPart(components, \"country\", \"shortText\") || \"US\",\n line1: street || place.formattedAddress?.split(\",\")[0] || \"\",\n line2: getAddressPart(components, \"subpremise\"),\n postalCode: [\n getAddressPart(components, \"postal_code\"),\n getAddressPart(components, \"postal_code_suffix\"),\n ]\n .filter(Boolean)\n .join(\"-\"),\n state: getAddressPart(\n components,\n \"administrative_area_level_1\",\n \"shortText\"\n ),\n } satisfies SignupAddressValues;\n}\n\nexport function SignupAddressField({\n apiKey,\n errorId,\n invalid,\n onChange,\n required,\n value,\n}: {\n apiKey: string | undefined;\n errorId: string | undefined;\n invalid: boolean;\n onChange: (address: SignupAddressValues) => void;\n required: boolean;\n value: SignupAddressValues;\n}) {\n const id = useId();\n const listboxId = `${id}-suggestions`;\n const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(-1);\n const [focused, setFocused] = useState(false);\n const [loading, setLoading] = useState(false);\n const [suggestions, setSuggestions] = useState<AddressSuggestion[]>([]);\n const searchGeneration = useRef(0);\n const sessionToken = useRef<unknown>(null);\n\n useEffect(() => {\n const generation = searchGeneration.current + 1;\n searchGeneration.current = generation;\n const query = value.line1.trim();\n setActiveSuggestionIndex(-1);\n setLoading(false);\n if (!(apiKey && focused && query.length >= 3)) {\n setSuggestions([]);\n return;\n }\n const timeout = window.setTimeout(async () => {\n if (generation !== searchGeneration.current) {\n return;\n }\n setLoading(true);\n try {\n const { AutocompleteSessionToken, AutocompleteSuggestion } =\n await loadGooglePlaces(apiKey);\n sessionToken.current ??= new AutocompleteSessionToken();\n const response =\n await AutocompleteSuggestion.fetchAutocompleteSuggestions({\n includedPrimaryTypes: GOOGLE_ADDRESS_TYPES,\n includedRegionCodes: [\"US\"],\n input: query,\n region: \"US\",\n sessionToken: sessionToken.current,\n });\n if (generation === searchGeneration.current) {\n setSuggestions(\n response.suggestions.flatMap(({ placePrediction }) =>\n placePrediction\n ? [\n {\n id: placePrediction.placeId,\n label:\n placePrediction.mainText?.text ??\n placePrediction.text.text,\n prediction: placePrediction,\n secondaryLabel: placePrediction.secondaryText?.text ?? \"\",\n },\n ]\n : []\n )\n );\n }\n } catch {\n if (generation === searchGeneration.current) {\n setSuggestions([]);\n }\n } finally {\n if (generation === searchGeneration.current) {\n setLoading(false);\n }\n }\n }, 250);\n return () => {\n window.clearTimeout(timeout);\n };\n }, [apiKey, focused, value.line1]);\n\n const update = (patch: Partial<SignupAddressValues>) =>\n onChange({ ...value, ...patch });\n\n const selectSuggestion = async (suggestion: AddressSuggestion) => {\n const place = suggestion.prediction.toPlace();\n try {\n await place.fetchFields({\n fields: [\"addressComponents\", \"formattedAddress\"],\n });\n onChange(parseAddress(value, place));\n sessionToken.current = null;\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n setFocused(false);\n } catch {\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n }\n };\n\n const handleAddressKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n return;\n }\n if (suggestions.length === 0) {\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current < suggestions.length - 1 ? current + 1 : 0\n );\n return;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current > 0 ? current - 1 : suggestions.length - 1\n );\n return;\n }\n const suggestion = suggestions[activeSuggestionIndex];\n if (event.key === \"Enter\" && suggestion) {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }\n };\n\n return (\n <fieldset\n aria-describedby={invalid ? errorId : undefined}\n aria-invalid={invalid ? \"true\" : undefined}\n className=\"lockerverse-signup__address\"\n >\n <legend>Address</legend>\n <label htmlFor={`${id}-line1`}>\n <span>Street address</span>\n <div className=\"lockerverse-signup__address-search\">\n <input\n aria-activedescendant={\n activeSuggestionIndex >= 0\n ? `${id}-suggestion-${activeSuggestionIndex}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-describedby={invalid ? errorId : undefined}\n aria-expanded={focused && suggestions.length > 0}\n aria-invalid={invalid ? \"true\" : undefined}\n autoComplete=\"street-address\"\n id={`${id}-line1`}\n name=\"address.line1\"\n onBlur={() => window.setTimeout(() => setFocused(false), 120)}\n onChange={(event) => update({ line1: event.currentTarget.value })}\n onFocus={() => setFocused(true)}\n onKeyDown={handleAddressKeyDown}\n required={required}\n role=\"combobox\"\n value={value.line1}\n />\n {loading ? (\n <span className=\"lockerverse-signup__address-loading\">\n Searching…\n </span>\n ) : null}\n {suggestions.length > 0 ? (\n <div\n className=\"lockerverse-signup__address-suggestions\"\n id={listboxId}\n role=\"listbox\"\n >\n {suggestions.map((suggestion, index) => (\n <button\n aria-selected={activeSuggestionIndex === index}\n id={`${id}-suggestion-${index}`}\n key={suggestion.id}\n onMouseDown={(event) => {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }}\n role=\"option\"\n type=\"button\"\n >\n <strong>{suggestion.label}</strong>\n {suggestion.secondaryLabel ? (\n <span>{suggestion.secondaryLabel}</span>\n ) : null}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n </label>\n <label htmlFor={`${id}-line2`}>\n <span>Apartment, suite, or unit</span>\n <input\n autoComplete=\"address-line2\"\n id={`${id}-line2`}\n onChange={(event) => update({ line2: event.currentTarget.value })}\n placeholder=\"Optional\"\n value={value.line2 ?? \"\"}\n />\n </label>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-city`}>\n <span>City</span>\n <input\n autoComplete=\"address-level2\"\n id={`${id}-city`}\n onChange={(event) => update({ city: event.currentTarget.value })}\n required={required}\n value={value.city}\n />\n </label>\n <label htmlFor={`${id}-state`}>\n <span>State</span>\n <input\n autoComplete=\"address-level1\"\n id={`${id}-state`}\n onChange={(event) => update({ state: event.currentTarget.value })}\n required={required}\n value={value.state}\n />\n </label>\n </div>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-postal`}>\n <span>Postal code</span>\n <input\n autoComplete=\"postal-code\"\n id={`${id}-postal`}\n onChange={(event) =>\n update({ postalCode: event.currentTarget.value })\n }\n required={required}\n value={value.postalCode}\n />\n </label>\n <label htmlFor={`${id}-country`}>\n <span>Country</span>\n <input\n autoComplete=\"country\"\n id={`${id}-country`}\n maxLength={2}\n onChange={(event) =>\n update({ country: event.currentTarget.value.toUpperCase() })\n }\n required={required}\n value={value.country}\n />\n </label>\n </div>\n </fieldset>\n );\n}\n","import type {\n LockerverseSignup,\n LockerverseSignupAddress,\n} from \"@lockerverse/sdk/signup\";\nimport {\n check,\n nonEmpty,\n nullable,\n object,\n pipe,\n regex,\n safeParse,\n string,\n transform,\n trim,\n} from \"valibot\";\nimport {\n optionalEmailSchema,\n optionalPhoneSchema,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\nimport { validateCustomFields } from \"./custom-fields.tsx\";\n\nconst POSITIVE_INTEGER_PATTERN = /^[1-9]\\d*$/;\nconst OPTIONAL_POSITIVE_INTEGER_PATTERN = /^(?:$|[1-9]\\d*)$/;\n\nexport type SignupAddressValues = Omit<LockerverseSignupAddress, \"line2\"> & {\n line2: string | null;\n};\n\nexport type SignupFormValues = {\n address: SignupAddressValues;\n customFields: Record<string, string | string[]>;\n email: string;\n honeypot: string;\n name: string;\n participantCount: string;\n phone: string;\n};\n\nconst nameSchema = pipe(string(), trim(), nonEmpty(\"Name is required.\"));\nconst optionalParticipantCountSchema = pipe(\n string(),\n trim(),\n regex(\n OPTIONAL_POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform((value) => (value ? Number(value) : null)),\n check(\n (value) => value === null || Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst requiredParticipantCountSchema = pipe(\n string(),\n trim(),\n nonEmpty(\"Guest count is required.\"),\n regex(\n POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform(Number),\n check(\n (value) => Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst addressShape = object({\n city: string(),\n country: string(),\n line1: string(),\n line2: nullable(string()),\n postalCode: string(),\n state: string(),\n});\nconst requiredAddressSchema = pipe(\n addressShape,\n check(isAddressComplete, \"Complete the address.\")\n);\n\nconst EMPTY_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: null,\n postalCode: \"\",\n state: \"\",\n};\nconst optionalAddressSchema = pipe(\n addressShape,\n check(\n (address) => isAddressEmpty(address) || isAddressComplete(address),\n \"Complete the address or leave it blank.\"\n )\n);\n\nexport function isAddressEmpty(address: SignupAddressValues) {\n return ![\n address.city,\n address.line1,\n address.line2,\n address.postalCode,\n address.state,\n ].some((value) => value?.trim());\n}\n\nfunction isAddressComplete(address: SignupAddressValues) {\n return [\n address.city,\n address.country,\n address.line1,\n address.postalCode,\n address.state,\n ].every((value) => value.trim());\n}\n\nexport function validateSignupForm(\n signup: LockerverseSignup,\n values: SignupFormValues\n) {\n const normalizedValues = {\n ...values,\n address: signup.fields.address.enabled ? values.address : EMPTY_ADDRESS,\n email: signup.fields.email.enabled ? values.email : \"\",\n participantCount: signup.fields.participantCount.enabled\n ? values.participantCount\n : \"\",\n phone: signup.fields.phone.enabled ? values.phone : \"\",\n };\n const schema = object({\n address:\n signup.fields.address.enabled && signup.fields.address.required\n ? requiredAddressSchema\n : optionalAddressSchema,\n email:\n signup.fields.email.enabled && signup.fields.email.required\n ? requiredEmailSchema\n : optionalEmailSchema,\n name: nameSchema,\n participantCount:\n signup.fields.participantCount.enabled &&\n signup.fields.participantCount.required\n ? requiredParticipantCountSchema\n : optionalParticipantCountSchema,\n phone:\n signup.fields.phone.enabled && signup.fields.phone.required\n ? requiredPhoneSchema\n : optionalPhoneSchema,\n });\n const result = safeParse(schema, normalizedValues);\n const errors = validateCustomFields(signup.customFields, values.customFields);\n if (!result.success) {\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n if (typeof field === \"string\" && !errors[field]) {\n errors[field] = issue.message;\n }\n }\n }\n return result.success\n ? { errors, value: { ...values, ...result.output } }\n : { errors, value: null };\n}\n","import type {\n LockerverseSdkError,\n LockerverseSignupClient,\n LockerverseSignup as LockerverseSignupDefinition,\n LockerverseSignupSubmissionResult,\n} from \"@lockerverse/sdk/signup\";\nimport {\n type FormEvent,\n type ReactNode,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { getAccentContrast, normalizeAccentColor } from \"./accent-contrast.ts\";\nimport {\n buildCustomFieldAnswers,\n CustomFields,\n createCustomFieldValues,\n} from \"./custom-fields.tsx\";\nimport { FormSkeleton } from \"./form-skeleton.tsx\";\nimport { SignupAddressField } from \"./signup-address-field.tsx\";\nimport type { LockerverseSignupProps } from \"./signup-types.ts\";\nimport {\n type SignupFormValues as FormValues,\n isAddressEmpty,\n type SignupAddressValues,\n validateSignupForm,\n} from \"./signup-validation.ts\";\n\nconst DEFAULT_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: \"\",\n postalCode: \"\",\n state: \"\",\n};\n\nconst DEFAULT_ACCENT = \"#5751f2\";\n\nfunction createInitialValues(signup: LockerverseSignupDefinition): FormValues {\n return {\n address: DEFAULT_ADDRESS,\n customFields: createCustomFieldValues(signup.customFields),\n email: \"\",\n honeypot: \"\",\n name: \"\",\n participantCount: \"\",\n phone: \"\",\n };\n}\n\nfunction FieldError({ error, id }: { error: string | undefined; id: string }) {\n return error ? (\n <span className=\"lockerverse-signup__field-error\" id={id} role=\"alert\">\n {error}\n </span>\n ) : null;\n}\n\nfunction focusNamedControl(form: HTMLFormElement, name: string) {\n const control = form.elements.namedItem(name);\n if (control instanceof HTMLElement) {\n if (!control.matches(\":disabled\")) {\n control.focus();\n return true;\n }\n return false;\n }\n if (control instanceof RadioNodeList) {\n const focusable = Array.from(control).find(\n (item) => item instanceof HTMLElement && !item.matches(\":disabled\")\n );\n focusable?.focus();\n return Boolean(focusable);\n }\n return false;\n}\n\nfunction focusFirstSignupValidationError(\n form: HTMLFormElement,\n errors: Record<string, string>\n) {\n const builtInFields: [string, string][] = [\n [\"name\", \"name\"],\n [\"email\", \"email\"],\n [\"phone\", \"phone\"],\n [\"participantCount\", \"participantCount\"],\n [\"address\", \"address.line1\"],\n ];\n for (const [errorKey, controlName] of builtInFields) {\n if (errors[errorKey] && focusNamedControl(form, controlName)) {\n return;\n }\n }\n const builtInKeys = new Set(builtInFields.map(([errorKey]) => errorKey));\n const customFieldId = Object.keys(errors).find(\n (errorKey) => !builtInKeys.has(errorKey)\n );\n if (customFieldId) {\n focusNamedControl(form, `custom:${customFieldId}`);\n }\n}\n\ntype SignupViewProps = Omit<LockerverseSignupProps, \"widget\">;\n\nfunction SignupShell({\n children,\n loading = false,\n status = false,\n viewProps,\n}: {\n children: ReactNode;\n loading?: boolean;\n status?: boolean;\n viewProps: SignupViewProps;\n}) {\n const {\n branding,\n className,\n googlePlacesApiKey: _googlePlacesApiKey,\n onSignupComplete: _onSignupComplete,\n style,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const accent = normalizeAccentColor(\n style?.[\"--lockerverse-accent\"] ??\n style?.[\"--lockerverse-signup-accent\"] ??\n branding?.accentColor ??\n DEFAULT_ACCENT\n );\n const signupStyle = {\n ...style,\n ...(style?.[\"--lockerverse-accent\"] !== undefined ||\n style?.[\"--lockerverse-signup-accent\"] !== undefined ||\n branding?.accentColor\n ? { \"--lockerverse-accent\": accent }\n : {}),\n ...(style?.[\"--lockerverse-accent-contrast\"] === undefined &&\n style?.[\"--lockerverse-signup-accent-contrast\"] === undefined\n ? { \"--lockerverse-accent-contrast\": getAccentContrast(accent) }\n : {}),\n } as React.CSSProperties;\n return (\n <section\n {...sectionProps}\n {...(loading ? { \"aria-busy\": true } : {})}\n className={[\n \"lockerverse-signup\",\n status ? \"lockerverse-signup__status\" : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n data-lockerverse-theme={theme}\n style={signupStyle}\n >\n {children}\n </section>\n );\n}\n\ntype SignupWorkflowState =\n | { phase: \"idle\" }\n | { phase: \"submitting\" }\n | {\n error: LockerverseSdkError;\n phase: \"submit_error\";\n }\n | {\n phase: \"submitted\";\n };\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: The component renders server-defined field branches in one public form boundary.\nfunction SignupForm({\n client,\n signup,\n ...viewProps\n}: SignupViewProps & {\n client: LockerverseSignupClient;\n signup: LockerverseSignupDefinition;\n}) {\n const { branding, googlePlacesApiKey, onSignupComplete } = viewProps;\n const idPrefix = useId();\n const mountedRef = useRef(true);\n const submittingRef = useRef(false);\n const [state, setState] = useState<SignupWorkflowState>({ phase: \"idle\" });\n const [values, setValues] = useState<FormValues>(() =>\n createInitialValues(signup)\n );\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [submissionRetry, setSubmissionRetry] = useState<{\n payloadKey: string;\n reference: string;\n }>();\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n if (!signup.isActive) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup closed</h1>\n <p>This signup is not accepting submissions.</p>\n </SignupShell>\n );\n }\n\n if (state.phase === \"submitted\") {\n return (\n <SignupShell status viewProps={viewProps}>\n {branding ? <Branding branding={branding} /> : null}\n <span aria-hidden=\"true\" className=\"lockerverse-signup__success\">\n ✓\n </span>\n <h1>Thank you</h1>\n <p>Your signup has been received.</p>\n </SignupShell>\n );\n }\n\n const update = (patch: Partial<FormValues>) =>\n setValues({ ...values, ...patch });\n const submitting = state.phase === \"submitting\";\n const submitError =\n state.phase === \"submit_error\" ? state.error.message : undefined;\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Submission maps the enabled server-defined fields to one SDK request.\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref blocks a second submit before React commits the submitting state.\n if (submittingRef.current) {\n return;\n }\n const validation = validateSignupForm(signup, values);\n setErrors(validation.errors);\n if (Object.keys(validation.errors).length > 0 || !validation.value) {\n const form = event.currentTarget;\n queueMicrotask(() =>\n focusFirstSignupValidationError(form, validation.errors)\n );\n return;\n }\n const validatedValues = validation.value;\n const submission = {\n address:\n signup.fields.address.enabled &&\n !isAddressEmpty(validatedValues.address)\n ? validatedValues.address\n : null,\n answers: buildCustomFieldAnswers(\n signup.customFields,\n validatedValues.customFields\n ),\n email: signup.fields.email.enabled ? validatedValues.email || null : null,\n honeypot: validatedValues.honeypot,\n name: validatedValues.name,\n participantCount: signup.fields.participantCount.enabled\n ? validatedValues.participantCount\n : null,\n phone: signup.fields.phone.enabled ? validatedValues.phone || null : null,\n };\n const payloadKey = JSON.stringify(submission);\n const submissionReference =\n submissionRetry?.payloadKey === payloadKey\n ? submissionRetry.reference\n : globalThis.crypto.randomUUID();\n let result: LockerverseSignupSubmissionResult;\n submittingRef.current = true;\n setState({ phase: \"submitting\" });\n try {\n result = await client.submit(submission, { submissionReference });\n } catch (error) {\n if (!mountedRef.current) {\n return;\n }\n const sdkError = error as LockerverseSdkError;\n setState({ error: sdkError, phase: \"submit_error\" });\n if (sdkError.recoveryRecommended) {\n setSubmissionRetry({\n payloadKey,\n reference: submissionReference,\n });\n } else {\n setSubmissionRetry(undefined);\n }\n return;\n } finally {\n submittingRef.current = false;\n }\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref changes during unmount while this request is pending.\n if (!mountedRef.current) {\n return;\n }\n setSubmissionRetry(undefined);\n setState({ phase: \"submitted\" });\n onSignupComplete?.(result);\n };\n\n return (\n <SignupShell viewProps={viewProps}>\n {signup.coverImageUrl ? (\n <img\n alt=\"\"\n className=\"lockerverse-signup__cover\"\n height={192}\n src={signup.coverImageUrl}\n width={440}\n />\n ) : null}\n {branding ? <Branding branding={branding} /> : null}\n <header>\n {signup.title?.trim() ? <h1>{signup.title}</h1> : null}\n {signup.description ? <p>{signup.description}</p> : null}\n </header>\n <form noValidate onSubmit={handleSubmit}>\n <input\n aria-hidden=\"true\"\n autoComplete=\"off\"\n className=\"lockerverse-signup__honeypot\"\n onChange={(event) => update({ honeypot: event.currentTarget.value })}\n tabIndex={-1}\n value={values.honeypot}\n />\n <div className=\"lockerverse-signup__fields\">\n <label htmlFor={`${idPrefix}-name`}>\n <span>Name</span>\n <input\n aria-describedby={\n errors.name ? `${idPrefix}-name-error` : undefined\n }\n aria-invalid={errors.name ? \"true\" : undefined}\n autoComplete=\"name\"\n id={`${idPrefix}-name`}\n name=\"name\"\n onChange={(event) => update({ name: event.currentTarget.value })}\n required\n value={values.name}\n />\n <FieldError error={errors.name} id={`${idPrefix}-name-error`} />\n </label>\n {signup.fields.email.enabled ? (\n <label htmlFor={`${idPrefix}-email`}>\n <span>Email</span>\n <input\n aria-describedby={\n errors.email ? `${idPrefix}-email-error` : undefined\n }\n aria-invalid={errors.email ? \"true\" : undefined}\n autoComplete=\"email\"\n id={`${idPrefix}-email`}\n name=\"email\"\n onChange={(event) =>\n update({ email: event.currentTarget.value })\n }\n required={signup.fields.email.required}\n type=\"email\"\n value={values.email}\n />\n <FieldError error={errors.email} id={`${idPrefix}-email-error`} />\n </label>\n ) : null}\n {signup.fields.phone.enabled ? (\n <label htmlFor={`${idPrefix}-phone`}>\n <span>Phone</span>\n <input\n aria-describedby={\n errors.phone ? `${idPrefix}-phone-error` : undefined\n }\n aria-invalid={errors.phone ? \"true\" : undefined}\n autoComplete=\"tel\"\n id={`${idPrefix}-phone`}\n name=\"phone\"\n onChange={(event) =>\n update({ phone: event.currentTarget.value })\n }\n placeholder=\"+1 555 555 0123\"\n required={signup.fields.phone.required}\n type=\"tel\"\n value={values.phone}\n />\n <FieldError error={errors.phone} id={`${idPrefix}-phone-error`} />\n </label>\n ) : null}\n {signup.fields.participantCount.enabled ? (\n <label htmlFor={`${idPrefix}-participant-count`}>\n <span>Guest count</span>\n <input\n aria-describedby={\n errors.participantCount\n ? `${idPrefix}-participant-count-error`\n : undefined\n }\n aria-invalid={errors.participantCount ? \"true\" : undefined}\n id={`${idPrefix}-participant-count`}\n min={1}\n name=\"participantCount\"\n onChange={(event) =>\n update({ participantCount: event.currentTarget.value })\n }\n required={signup.fields.participantCount.required}\n type=\"number\"\n value={values.participantCount}\n />\n <FieldError\n error={errors.participantCount}\n id={`${idPrefix}-participant-count-error`}\n />\n </label>\n ) : null}\n {signup.fields.address.enabled ? (\n <div className=\"lockerverse-signup__field-group\">\n <SignupAddressField\n apiKey={googlePlacesApiKey}\n errorId={\n errors.address ? `${idPrefix}-address-error` : undefined\n }\n invalid={Boolean(errors.address)}\n onChange={(address) => update({ address })}\n required={signup.fields.address.required}\n value={values.address}\n />\n <FieldError\n error={errors.address}\n id={`${idPrefix}-address-error`}\n />\n </div>\n ) : null}\n <CustomFields\n choiceClassName=\"lockerverse-signup__choice\"\n errorClassName=\"lockerverse-signup__field-error\"\n errors={errors}\n fields={signup.customFields}\n idPrefix={idPrefix}\n onChange={(customFields) => update({ customFields })}\n values={values.customFields}\n />\n </div>\n {submitError ? (\n <p className=\"lockerverse-signup__submit-error\" role=\"alert\">\n {submitError} Try again.\n </p>\n ) : null}\n <button\n className=\"lockerverse-signup__submit\"\n disabled={submitting}\n type=\"submit\"\n >\n {submitting ? \"Submitting…\" : \"Submit\"}\n </button>\n </form>\n </SignupShell>\n );\n}\n\nexport function LockerverseSignup({\n widget,\n ...viewProps\n}: LockerverseSignupProps) {\n if (widget.error) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup unavailable</h1>\n <p role=\"alert\">{widget.error.message}</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </SignupShell>\n );\n }\n if (widget.loading || !widget.signup) {\n return (\n <SignupShell loading viewProps={viewProps}>\n <FormSkeleton fieldCount={4} label=\"Loading signup…\" />\n </SignupShell>\n );\n }\n return (\n <SignupForm client={widget.client} signup={widget.signup} {...viewProps} />\n );\n}\n\nfunction Branding({\n branding,\n}: {\n branding: NonNullable<LockerverseSignupProps[\"branding\"]>;\n}) {\n return (\n <div className=\"lockerverse-signup__branding\">\n {branding.imageUrl ? (\n <img alt=\"\" height={48} src={branding.imageUrl} width={48} />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n );\n}\n","import {\n type CreateLockerverseSignupOptions,\n createLockerverseSignupClient,\n type LockerverseSdkError,\n type LockerverseSignup,\n type LockerverseSignupClient,\n} from \"@lockerverse/sdk/signup\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useImmutableResourceIdentity } from \"./immutable-resource-identity.ts\";\n\ntype SignupLoadState = {\n error: LockerverseSdkError | null;\n signup: LockerverseSignup | null;\n};\n\nexport type UseLockerverseSignupResult = {\n client: LockerverseSignupClient;\n error: LockerverseSdkError | null;\n loading: boolean;\n refresh: () => void;\n signup: LockerverseSignup | null;\n};\n\nexport function useLockerverseSignup(\n options: CreateLockerverseSignupOptions\n): UseLockerverseSignupResult {\n const { onError } = options;\n useImmutableResourceIdentity(\"signup\", {\n apiBaseUrl: options.apiBaseUrl,\n communitySlug: options.communitySlug,\n environment: options.environment,\n slug: options.signupSlug,\n });\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const [client] = useState(() =>\n createLockerverseSignupClient({\n ...options,\n onError: (error) => onErrorRef.current?.(error),\n } as CreateLockerverseSignupOptions)\n );\n const [revision, setRevision] = useState(0);\n const [state, setState] = useState<SignupLoadState>({\n error: null,\n signup: null,\n });\n\n useEffect(() => {\n let active = true;\n client.load().then(\n (signup) => {\n if (active) {\n setState({\n error: null,\n signup,\n });\n }\n },\n (error: LockerverseSdkError) => {\n if (active) {\n setState({\n error,\n signup: null,\n });\n }\n }\n );\n return () => {\n active = false;\n };\n }, [client, revision]);\n\n const refresh = useCallback(() => {\n setState({\n error: null,\n signup: null,\n });\n setRevision((value) => value + 1);\n }, []);\n\n return {\n client,\n error: state.error,\n loading: state.signup === null && state.error === null,\n refresh,\n signup: state.signup,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { CSSProperties } from "react";
2
+ //#region src/theme.d.ts
3
+ type LockerverseTheme = "dark" | "light";
4
+ type LockerverseStyle = CSSProperties & {
5
+ "--lockerverse-accent"?: string;
6
+ "--lockerverse-accent-contrast"?: string;
7
+ "--lockerverse-bg"?: string;
8
+ "--lockerverse-border"?: string;
9
+ "--lockerverse-control"?: string;
10
+ "--lockerverse-danger"?: string;
11
+ "--lockerverse-danger-border"?: string;
12
+ "--lockerverse-font-family"?: string;
13
+ "--lockerverse-muted"?: string;
14
+ "--lockerverse-placeholder"?: string;
15
+ "--lockerverse-radius"?: string;
16
+ "--lockerverse-subtle"?: string;
17
+ "--lockerverse-text"?: string;
18
+ };
19
+ //#endregion
20
+ export { LockerverseTheme as n, LockerverseStyle as t };
21
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","names":[],"sources":["../src/theme.ts"],"mappings":";;KAEY;KAEA,mBAAmB;EAC7B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import { n as LockerverseTheme, t as LockerverseStyle } from "./theme.js";
1
2
  import { t as UseLockerverseWidgetResult } from "./use-lockerverse-widget.js";
2
- import { CSSProperties, ComponentPropsWithoutRef } from "react";
3
+ import { ComponentPropsWithoutRef } from "react";
3
4
  import { loadStripe } from "@stripe/stripe-js";
4
5
  import { LockerversePaymentResult } from "@lockerverse/sdk/checkout";
5
6
  //#region src/types.d.ts
@@ -12,27 +13,13 @@ type LockerversePaymentSelectionItem = {
12
13
  } | {
13
14
  productSlug: string;
14
15
  };
15
- type LockerversePaymentTheme = "dark" | "light";
16
+ type LockerversePaymentTheme = LockerverseTheme;
16
17
  type LockerversePaymentBranding = {
17
18
  accentColor?: string;
18
19
  imageUrl?: string | null;
19
20
  name: string;
20
21
  };
21
- type LockerversePaymentStyle = CSSProperties & {
22
- "--lockerverse-accent"?: string;
23
- "--lockerverse-accent-contrast"?: string;
24
- "--lockerverse-bg"?: string;
25
- "--lockerverse-border"?: string;
26
- "--lockerverse-control"?: string;
27
- "--lockerverse-danger"?: string;
28
- "--lockerverse-danger-border"?: string;
29
- "--lockerverse-font-family"?: string;
30
- "--lockerverse-muted"?: string;
31
- "--lockerverse-placeholder"?: string;
32
- "--lockerverse-radius"?: string;
33
- "--lockerverse-subtle"?: string;
34
- "--lockerverse-text"?: string;
35
- };
22
+ type LockerversePaymentStyle = LockerverseStyle;
36
23
  type LockerversePaymentUncertain = {
37
24
  paymentReference: string;
38
25
  reason: "action_required" | "pending" | "recovery_failed";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;KAKY;EACN;EAAqB;;EACrB;EAAqB;;EACrB;;KAEM;KAEA;EACV;EACA;EACA;;KAGU,0BAA0B;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU;EACV;EACA;;KAGU;EACV;EACA;;KAGU,8BACP,MAAM,kBAAkB,gBACxB,kBAAkB;KAElB,8BAA8B,KACjC;EAGA,WAAW;EACX,WAAW;EACX,qBAAqB,SAAS;EAC9B,2BACE,UAAU;EAEZ,sBAAsB,SAAS;EAC/B,gBAAgB;EAChB,WAAW;EACX,eAAe;EACf,QAAQ;EACR,QAAQ;;KAGE,0BAA0B;EACpC,QAAQ;;KAGE;KAKA,iCAAiC,KAC3C;EAGA;EACA,WAAW"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;KAMY;EACN;EAAqB;;EACrB;EAAqB;;EACrB;;KAEM,0BAA0B;KAE1B;EACV;EACA;EACA;;KAGU,0BAA0B;KAE1B;EACV;EACA;;KAGU;EACV;EACA;;KAGU,8BACP,MAAM,kBAAkB,gBACxB,kBAAkB;KAElB,8BAA8B,KACjC;EAGA,WAAW;EACX,WAAW;EACX,qBAAqB,SAAS;EAC9B,2BACE,UAAU;EAEZ,sBAAsB,SAAS;EAC/B,gBAAgB;EAChB,WAAW;EACX,eAAe;EACf,QAAQ;EACR,QAAQ;;KAGE,0BAA0B;EACpC,QAAQ;;KAGE;KAKA,iCAAiC,KAC3C;EAGA;EACA,WAAW"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lockerverse/react",
3
- "version": "0.2.77",
3
+ "version": "0.2.78",
4
4
  "description": "Tree-shakable React payment and signup UI for Lockerverse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -61,7 +61,7 @@
61
61
  "dependencies": {
62
62
  "@base-ui/react": "1.6.0",
63
63
  "valibot": "1.4.2",
64
- "@lockerverse/sdk": "0.2.77"
64
+ "@lockerverse/sdk": "0.2.78"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@size-limit/file": "13.0.3",