@lockerverse/react 0.2.154-dev.1 → 0.2.156

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +74 -0
  2. package/dist/auction-catalog.css +3 -1
  3. package/dist/auction-item-layout.css +3 -0
  4. package/dist/auction-item.d.ts +2 -0
  5. package/dist/auction-item.d.ts.map +1 -1
  6. package/dist/auction-item.js +1 -1
  7. package/dist/auction-item.js.map +1 -1
  8. package/dist/custom-fields.d.ts +31 -0
  9. package/dist/custom-fields.d.ts.map +1 -0
  10. package/dist/custom-fields.js +2 -0
  11. package/dist/custom-fields.js.map +1 -0
  12. package/dist/form-skeleton.js +1 -1
  13. package/dist/form-skeleton.js.map +1 -1
  14. package/dist/host-callback.js +1 -1
  15. package/dist/host-callback.js.map +1 -1
  16. package/dist/index.d.ts +2 -1
  17. package/dist/lockerverse-auction-item-card.d.ts +5 -1
  18. package/dist/lockerverse-auction-item-card.d.ts.map +1 -1
  19. package/dist/lockerverse-auction.js +1 -1
  20. package/dist/lockerverse-auction.js.map +1 -1
  21. package/dist/lockerverse-payment.js +1 -1
  22. package/dist/lockerverse-payment.js.map +1 -1
  23. package/dist/payment-form.d.ts +2 -2
  24. package/dist/payment-form.d.ts.map +1 -1
  25. package/dist/payment-primitives.d.ts +113 -0
  26. package/dist/payment-primitives.d.ts.map +1 -0
  27. package/dist/payment-primitives.js +1 -0
  28. package/dist/payment-summary.js +2 -0
  29. package/dist/payment-summary.js.map +1 -0
  30. package/dist/payment.d.ts +2 -1
  31. package/dist/phone-field.js +2 -0
  32. package/dist/phone-field.js.map +1 -0
  33. package/dist/signup.js +1 -1
  34. package/dist/signup.js.map +1 -1
  35. package/dist/stripe-loader.js +1 -1
  36. package/dist/stripe-loader.js.map +1 -1
  37. package/dist/types.d.ts +3 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/use-auction-boundary.js +1 -1
  40. package/dist/use-auction-boundary.js.map +1 -1
  41. package/package.json +7 -2
@@ -1 +1 @@
1
- {"version":3,"file":"stripe-loader.js","names":["normalizeContactPhone"],"sources":["../src/payment-validation.ts","../src/stripe-appearance.ts","../src/stripe-loader.ts"],"sourcesContent":["import { object, safeParse } from \"valibot\";\nimport {\n normalizePhone as normalizeContactPhone,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\n\nexport function normalizePhone(input: string) {\n return normalizeContactPhone(input);\n}\n\nexport type ContactErrors = {\n email?: string;\n phone?: string;\n};\n\nexport function validateContact(\n input: { email: string; phone: string },\n requiresPhone: boolean\n) {\n const normalizedInput = requiresPhone\n ? { ...input, phone: normalizePhone(input.phone) }\n : input;\n const schema = requiresPhone\n ? object({ email: requiredEmailSchema, phone: requiredPhoneSchema })\n : object({ email: requiredEmailSchema });\n const result = safeParse(schema, normalizedInput);\n\n if (result.success) {\n const errors: ContactErrors = {};\n return { errors, value: result.output } as const;\n }\n\n const errors: ContactErrors = {};\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n if ((field === \"email\" || field === \"phone\") && !errors[field]) {\n errors[field] = issue.message;\n }\n }\n return { errors, value: null } as const;\n}\n","import type { Appearance } from \"@stripe/stripe-js\";\nimport { type RefObject, useEffect, useRef, useState } from \"react\";\nimport type { LockerverseStyle, LockerverseTheme } from \"./theme.ts\";\n\nconst DEFAULT_FONT_FAMILY =\n 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\n\nconst CONTEXTUAL_CSS = /var\\(|currentcolor|inherit|initial|unset|revert/i;\n\nfunction resolveToken(\n root: HTMLElement,\n probe: HTMLElement,\n property: string,\n token: string,\n fallback: string\n) {\n const view = root.ownerDocument.defaultView;\n if (!view) {\n return fallback;\n }\n const tokenValue = view\n .getComputedStyle(root)\n .getPropertyValue(`--lockerverse-${token}`)\n .trim();\n if (!tokenValue) {\n return fallback;\n }\n if (!view.CSS?.supports(property, tokenValue)) {\n return fallback;\n }\n if (!CONTEXTUAL_CSS.test(tokenValue)) {\n return tokenValue;\n }\n probe.style.removeProperty(property);\n probe.style.setProperty(property, tokenValue, \"important\");\n return (\n view.getComputedStyle(probe).getPropertyValue(property).trim() || fallback\n );\n}\n\n/** Resolve host CSS in the host document. Stripe's iframe cannot inherit it. */\nfunction resolveAppearance(\n root: HTMLElement | null,\n theme: LockerverseTheme,\n accent?: string\n): Appearance {\n const light = theme === \"light\";\n const variables: NonNullable<Appearance[\"variables\"]> = {\n borderRadius: \"10px\",\n colorBackground: light ? \"#f5f6f7\" : \"#121212\",\n colorDanger: light ? \"#c52b3e\" : \"#f08a98\",\n colorPrimary: accent ?? \"#38d77a\",\n colorText: light ? \"#121416\" : \"#ffffff\",\n colorTextPlaceholder: light ? \"#72767d\" : \"#6b6b6b\",\n colorTextSecondary: light ? \"#62666d\" : \"#a1a1aa\",\n focusBoxShadow: \"none\",\n focusOutline: \"none\",\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSizeBase: \"16px\",\n };\n const view = root?.ownerDocument.defaultView;\n if (root?.isConnected && view) {\n variables.fontFamily =\n view.getComputedStyle(root).fontFamily || DEFAULT_FONT_FAMILY;\n const probe = root.ownerDocument.createElement(\"span\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.style.cssText =\n \"position:absolute;visibility:hidden;pointer-events:none;width:0;height:0;overflow:hidden\";\n root.append(probe);\n try {\n const tokens = [\n [\"borderRadius\", \"radius\", \"border-radius\"],\n [\"colorBackground\", \"control\", \"color\"],\n [\"colorDanger\", \"danger\", \"color\"],\n [\"colorPrimary\", \"accent\", \"color\"],\n [\"colorText\", \"text\", \"color\"],\n [\"colorTextPlaceholder\", \"placeholder\", \"color\"],\n [\"colorTextSecondary\", \"muted\", \"color\"],\n ] as const;\n for (const [variable, token, property] of tokens) {\n variables[variable] = resolveToken(\n root,\n probe,\n property,\n token,\n variables[variable] ?? \"\"\n );\n }\n } finally {\n probe.remove();\n }\n }\n return {\n rules: {\n \".Input:focus\": {\n borderColor: variables.colorPrimary ?? \"#38d77a\",\n boxShadow: `0 0 0 1px ${variables.colorPrimary}`,\n outline: \"none\",\n },\n },\n theme: light ? \"stripe\" : \"night\",\n variables,\n };\n}\n\n/** Keep the current Elements appearance while a payment or recovery is active. */\nexport function useStripeAppearance(\n root: RefObject<HTMLElement | null>,\n theme: LockerverseTheme | undefined,\n style: LockerverseStyle | undefined,\n locked: boolean,\n accent?: string\n) {\n const [appearance, setAppearance] = useState<Appearance | null>(null);\n const resolved = useRef<Appearance | null>(null);\n useEffect(() => {\n if (locked && resolved.current) {\n return;\n }\n const next = resolveAppearance(root.current, theme ?? \"dark\", accent);\n if (JSON.stringify(resolved.current) !== JSON.stringify(next)) {\n resolved.current = next;\n setAppearance(next);\n }\n }, [root, theme, style, locked, accent]);\n return appearance;\n}\n","import { loadStripe } from \"@stripe/stripe-js/pure\";\nimport type { LockerverseStripeLoader } from \"./types.ts\";\n\nconst stripeLoads = new Map<\n string,\n Map<string | null, ReturnType<LockerverseStripeLoader>>\n>();\n\nexport const defaultLockerverseStripeLoader: LockerverseStripeLoader = (\n publishableKey,\n options\n) => {\n const connectedAccountId = options?.stripeAccount ?? null;\n let accountLoads = stripeLoads.get(publishableKey);\n if (!accountLoads) {\n accountLoads = new Map();\n stripeLoads.set(publishableKey, accountLoads);\n }\n\n const existingLoad = accountLoads.get(connectedAccountId);\n if (existingLoad) {\n return existingLoad;\n }\n\n const stripeLoad = loadStripe(publishableKey, options)\n .catch(() => null)\n .then((stripe) => {\n if (stripe) {\n return stripe;\n }\n if (accountLoads?.get(connectedAccountId) === stripeLoad) {\n accountLoads.delete(connectedAccountId);\n if (accountLoads.size === 0) {\n stripeLoads.delete(publishableKey);\n }\n }\n return null;\n });\n accountLoads.set(connectedAccountId, stripeLoad);\n return stripeLoad;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"stripe-loader.js","names":["normalizeContactPhone"],"sources":["../src/payment-validation.ts","../src/stripe-appearance.ts","../src/stripe-loader.ts"],"sourcesContent":["import { object, safeParse } from \"valibot\";\nimport {\n normalizePhone as normalizeContactPhone,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\n\nexport function normalizePhone(input: string) {\n return normalizeContactPhone(input);\n}\n\nexport type ContactErrors = {\n email?: string;\n phone?: string;\n};\n\nexport function validateContact(\n input: { email: string; phone: string },\n requiresPhone: boolean\n) {\n const normalizedInput = requiresPhone\n ? { ...input, phone: normalizePhone(input.phone) }\n : input;\n const schema = requiresPhone\n ? object({ email: requiredEmailSchema, phone: requiredPhoneSchema })\n : object({ email: requiredEmailSchema });\n const result = safeParse(schema, normalizedInput);\n\n if (result.success) {\n const errors: ContactErrors = {};\n return { errors, value: result.output } as const;\n }\n\n const errors: ContactErrors = {};\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n if ((field === \"email\" || field === \"phone\") && !errors[field]) {\n errors[field] = issue.message;\n }\n }\n return { errors, value: null } as const;\n}\n","import type { Appearance } from \"@stripe/stripe-js\";\nimport { type RefObject, useEffect, useRef, useState } from \"react\";\nimport type { LockerverseStyle, LockerverseTheme } from \"./theme.ts\";\n\nconst DEFAULT_FONT_FAMILY =\n 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\n\nconst CONTEXTUAL_CSS = /var\\(|currentcolor|inherit|initial|unset|revert/i;\n\nfunction resolveToken(\n root: HTMLElement,\n probe: HTMLElement,\n property: string,\n token: string,\n fallback: string\n) {\n const view = root.ownerDocument.defaultView;\n if (!view) {\n return fallback;\n }\n const tokenValue = view\n .getComputedStyle(root)\n .getPropertyValue(`--lockerverse-${token}`)\n .trim();\n if (!tokenValue) {\n return fallback;\n }\n if (!view.CSS?.supports(property, tokenValue)) {\n return fallback;\n }\n if (!CONTEXTUAL_CSS.test(tokenValue)) {\n return tokenValue;\n }\n probe.style.removeProperty(property);\n probe.style.setProperty(property, tokenValue, \"important\");\n return (\n view.getComputedStyle(probe).getPropertyValue(property).trim() || fallback\n );\n}\n\n/** Resolve host CSS in the host document. Stripe's iframe cannot inherit it. */\nfunction resolveAppearance(\n root: HTMLElement | null,\n theme: LockerverseTheme,\n accent?: string\n): Appearance {\n const light = theme === \"light\";\n const variables: NonNullable<Appearance[\"variables\"]> = {\n borderRadius: \"10px\",\n colorBackground: light ? \"#f5f6f7\" : \"#121212\",\n colorDanger: light ? \"#c52b3e\" : \"#f08a98\",\n colorPrimary: accent ?? \"#38d77a\",\n colorText: light ? \"#121416\" : \"#ffffff\",\n colorTextPlaceholder: light ? \"#72767d\" : \"#6b6b6b\",\n colorTextSecondary: light ? \"#62666d\" : \"#a1a1aa\",\n focusBoxShadow: \"none\",\n focusOutline: \"none\",\n fontFamily: DEFAULT_FONT_FAMILY,\n fontSizeBase: \"16px\",\n };\n const view = root?.ownerDocument.defaultView;\n if (root?.isConnected && view) {\n variables.fontFamily =\n view.getComputedStyle(root).fontFamily || DEFAULT_FONT_FAMILY;\n const probe = root.ownerDocument.createElement(\"span\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.style.cssText =\n \"position:absolute;visibility:hidden;pointer-events:none;width:0;height:0;overflow:hidden\";\n root.append(probe);\n try {\n const tokens = [\n [\"borderRadius\", \"radius\", \"border-radius\"],\n [\"colorBackground\", \"control\", \"color\"],\n [\"colorDanger\", \"danger\", \"color\"],\n [\"colorPrimary\", \"accent\", \"color\"],\n [\"colorText\", \"text\", \"color\"],\n [\"colorTextPlaceholder\", \"placeholder\", \"color\"],\n [\"colorTextSecondary\", \"muted\", \"color\"],\n ] as const;\n for (const [variable, token, property] of tokens) {\n variables[variable] = resolveToken(\n root,\n probe,\n property,\n token,\n variables[variable] ?? \"\"\n );\n }\n } finally {\n probe.remove();\n }\n }\n return {\n rules: {\n \".Input:focus\": {\n borderColor: variables.colorPrimary ?? \"#38d77a\",\n boxShadow: `0 0 0 1px ${variables.colorPrimary}`,\n outline: \"none\",\n },\n },\n theme: light ? \"stripe\" : \"night\",\n variables,\n };\n}\n\n/** Keep the current Elements appearance while a payment or recovery is active. */\nexport function useStripeAppearance(\n root: RefObject<HTMLElement | null>,\n theme: LockerverseTheme | undefined,\n style: LockerverseStyle | undefined,\n locked: boolean,\n accent?: string\n) {\n const [appearance, setAppearance] = useState<Appearance | null>(null);\n const resolved = useRef<Appearance | null>(null);\n useEffect(() => {\n if (locked && resolved.current) {\n return;\n }\n const next = resolveAppearance(root.current, theme ?? \"dark\", accent);\n if (JSON.stringify(resolved.current) !== JSON.stringify(next)) {\n resolved.current = next;\n setAppearance(next);\n }\n }, [root, theme, style, locked, accent]);\n return appearance;\n}\n","import { loadStripe } from \"@stripe/stripe-js/pure\";\nimport type { LockerverseStripeLoader } from \"./types.ts\";\n\nconst stripeLoads = new Map<\n string,\n Map<string | null, ReturnType<LockerverseStripeLoader>>\n>();\n\nexport const defaultLockerverseStripeLoader: LockerverseStripeLoader = (\n publishableKey,\n options\n) => {\n const connectedAccountId = options?.stripeAccount ?? null;\n let accountLoads = stripeLoads.get(publishableKey);\n if (!accountLoads) {\n accountLoads = new Map();\n stripeLoads.set(publishableKey, accountLoads);\n }\n\n const existingLoad = accountLoads.get(connectedAccountId);\n if (existingLoad) {\n return existingLoad;\n }\n\n const stripeLoad = loadStripe(publishableKey, options)\n .catch(() => null)\n .then((stripe) => {\n if (stripe) {\n return stripe;\n }\n if (accountLoads?.get(connectedAccountId) === stripeLoad) {\n accountLoads.delete(connectedAccountId);\n if (accountLoads.size === 0) {\n stripeLoads.delete(publishableKey);\n }\n }\n return null;\n });\n accountLoads.set(connectedAccountId, stripeLoad);\n return stripeLoad;\n};\n"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { n as LockerverseTheme, t as LockerverseStyle } from "./theme.js";
2
+ import { n as CustomFieldValues } from "./custom-fields.js";
2
3
  import { n as UseLockerverseWidgetResult } from "./use-lockerverse-widget.js";
3
4
  import { ComponentPropsWithoutRef } from "react";
4
5
  import { LockerversePaymentCompletion } from "@lockerverse/sdk/checkout";
@@ -31,6 +32,8 @@ type LockerversePaymentRecovery = {
31
32
  type LockerverseStripeLoader = (...args: Parameters<typeof loadStripe>) => ReturnType<typeof loadStripe>;
32
33
  type LockerversePaymentViewProps = Omit<ComponentPropsWithoutRef<"section">, "children" | "onError"> & {
33
34
  branding?: LockerversePaymentBranding;
35
+ /** Initial values for configured custom fields. Buyers can edit them. Read once per checkout form. */
36
+ initialCustomFieldValues?: CustomFieldValues;
34
37
  metadata?: Record<string, string>;
35
38
  onPaymentComplete?: (payment: LockerversePaymentCompletion) => void;
36
39
  onPaymentRecoveryChange?: (recovery: LockerversePaymentRecovery | null) => void;
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;KAOY;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;;EAEX,2BAA2B;EAC3B,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,2 +1,2 @@
1
- import{t as e}from"./format-money.js";import{useCallback as t,useEffect as n,useRef as r,useState as i,useSyncExternalStore as a}from"react";import{jsx as o}from"react/jsx-runtime";const s=/<\/?(?:p|br|strong|em|u|s|ul|ol|li|blockquote|pre|code|hr|h[1-6]|a)(?:\s|\/?>)/i;function c(e){return s.test(e)?e:e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/\r\n|\r|\n/g,`<br>`)}function l({description:e,className:t,id:n}){return o(`div`,{className:[`lockerverse-auctions__description`,t].filter(Boolean).join(` `),dangerouslySetInnerHTML:{__html:c(e)},id:n})}function u(e,t=e.status,n){let r=t===`draft`,i=n??p(e),a=r?i?.startAt??e.startAt:(t===`finished`?n?.finishedAt:void 0)??n?.endAt??e.endAt,o=new Date(a);if(!Number.isFinite(o.getTime()))return``;let s=(r?i?.startAt:n?.endAt)?!0:(r?e.configuration.startTimeEnabled:e.configuration.endTimeEnabled)??!0,c=new Intl.DateTimeFormat(`en-US`,{day:`numeric`,month:`short`,timeZone:`America/New_York`,year:`numeric`}).format(o);return s?`${c} at ${new Intl.DateTimeFormat(`en-US`,{hour:`numeric`,minute:`2-digit`,timeZone:`America/New_York`,timeZoneName:`short`}).format(o)}`:c}function d(t){return e(t,0)}function f(e,t){if(e.status===`finished`||t?.status===`finished`)return`finished`;if(t&&!(t.startAt&&t.endAt)&&(t.status===`draft`||e.status===`draft`))return`draft`;let n=Date.now();if(Date.parse(t?.endAt??e.endAt)<=n)return`finished`;if(Date.parse(t?.startAt??e.startAt)>n)return`draft`;if(t)return`active`;if(e.items.length){let t=e.items.map(t=>f(e,t));return t.includes(`active`)?`active`:t.includes(`draft`)?`draft`:`finished`}return e.status}function p(e){let t=Date.now();return e.items.filter(n=>n.status!==`finished`&&Date.parse(n.startAt??e.startAt)>t).sort((t,n)=>Date.parse(t.startAt??e.startAt)-Date.parse(n.startAt??e.startAt))[0]}function m(e){return e.isSoldOut||e.saleMode===`buy_now`&&e.availableQuantity===0}function h(){let e=r(null),[t,a]=i(!1);return n(()=>{let t=e.current;if(!(t&&`IntersectionObserver`in window))return;let n=!1,r=()=>a(n&&!document.hidden),i=new IntersectionObserver(([e])=>{n=!!(e?.isIntersecting&&e.intersectionRatio>0),r()});return i.observe(t),document.addEventListener(`visibilitychange`,r),()=>{i.disconnect(),document.removeEventListener(`visibilitychange`,r)}},[]),{ref:e,visible:t}}const g=new Map;let _,v=0;function y(){clearTimeout(_),_=void 0;let e=Date.now(),t=1/0;for(let n of g.values())for(let r of n)r>e&&(t=Math.min(t,r));Number.isFinite(t)&&(_=setTimeout(b,Math.min(t-e+1,2147483647)))}function b(){v+=1;for(let e of g.keys())e();y()}function x(){document.hidden||b()}const S=()=>v,C=()=>0;function w(e,n,r=[]){let i=[e,n,...r.flatMap(t=>[t.startAt??e,t.endAt??n])].join(`,`),o=t(e=>(g.size||document.addEventListener(`visibilitychange`,x),g.set(e,i.split(`,`).map(Date.parse)),y(),()=>{g.delete(e),y(),g.size||document.removeEventListener(`visibilitychange`,x)}),[i]);a(o,S,C)}export{f as a,l as c,d as i,h as n,p as o,u as r,m as s,w as t};
1
+ import{t as e}from"./format-money.js";import{useCallback as t,useEffect as n,useRef as r,useState as i,useSyncExternalStore as a}from"react";import{jsx as o}from"react/jsx-runtime";function s({href:e,onBack:t,className:n,children:r,elementRef:i}){return e?o(`a`,{className:n,href:e,onClick:e=>{t&&e.button===0&&!e.metaKey&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&(e.preventDefault(),t())},ref:i,children:r}):t?o(`button`,{className:n,onClick:t,ref:i,type:`button`,children:r}):null}const c=/<\/?(?:p|br|strong|em|u|s|ul|ol|li|blockquote|pre|code|hr|h[1-6]|a)(?:\s|\/?>)/i;function l(e){return c.test(e)?e:e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/\r\n|\r|\n/g,`<br>`)}function u({description:e,className:t,id:n}){return o(`div`,{className:[`lockerverse-auctions__description`,t].filter(Boolean).join(` `),dangerouslySetInnerHTML:{__html:l(e)},id:n})}function d(e,t=e.status,n){let r=t===`draft`,i=n??m(e),a=r?i?.startAt??e.startAt:(t===`finished`?n?.finishedAt:void 0)??n?.endAt??e.endAt,o=new Date(a);if(!Number.isFinite(o.getTime()))return``;let s=(r?i?.startAt:n?.endAt)?!0:(r?e.configuration.startTimeEnabled:e.configuration.endTimeEnabled)??!0,c=new Intl.DateTimeFormat(`en-US`,{day:`numeric`,month:`short`,timeZone:`America/New_York`,year:`numeric`}).format(o);return s?`${c} at ${new Intl.DateTimeFormat(`en-US`,{hour:`numeric`,minute:`2-digit`,timeZone:`America/New_York`,timeZoneName:`short`}).format(o)}`:c}function f(t){return e(t,0)}function p(e,t){if(e.status===`finished`||t?.status===`finished`)return`finished`;if(t&&!(t.startAt&&t.endAt)&&(t.status===`draft`||e.status===`draft`))return`draft`;let n=Date.now();if(Date.parse(t?.endAt??e.endAt)<=n)return`finished`;if(Date.parse(t?.startAt??e.startAt)>n)return`draft`;if(t)return`active`;if(e.items.length){let t=e.items.map(t=>p(e,t));return t.includes(`active`)?`active`:t.includes(`draft`)?`draft`:`finished`}return e.status}function m(e){let t=Date.now();return e.items.filter(n=>n.status!==`finished`&&Date.parse(n.startAt??e.startAt)>t).sort((t,n)=>Date.parse(t.startAt??e.startAt)-Date.parse(n.startAt??e.startAt))[0]}function h(e){return e.isSoldOut||e.saleMode===`buy_now`&&e.availableQuantity===0}function g(){let e=r(null),[t,a]=i(!1);return n(()=>{let t=e.current;if(!(t&&`IntersectionObserver`in window))return;let n=!1,r=()=>a(n&&!document.hidden),i=new IntersectionObserver(([e])=>{n=!!(e?.isIntersecting&&e.intersectionRatio>0),r()});return i.observe(t),document.addEventListener(`visibilitychange`,r),()=>{i.disconnect(),document.removeEventListener(`visibilitychange`,r)}},[]),{ref:e,visible:t}}const _=new Map;let v,y=0;function b(){clearTimeout(v),v=void 0;let e=Date.now(),t=1/0;for(let n of _.values())for(let r of n)r>e&&(t=Math.min(t,r));Number.isFinite(t)&&(v=setTimeout(x,Math.min(t-e+1,2147483647)))}function x(){y+=1;for(let e of _.keys())e();b()}function S(){document.hidden||x()}const C=()=>y,w=()=>0;function T(e,n,r=[]){let i=[e,n,...r.flatMap(t=>[t.startAt??e,t.endAt??n])].join(`,`),o=t(e=>(_.size||document.addEventListener(`visibilitychange`,S),_.set(e,i.split(`,`).map(Date.parse)),b(),()=>{_.delete(e),b(),_.size||document.removeEventListener(`visibilitychange`,S)}),[i]);a(o,C,w)}export{p as a,u as c,f as i,s as l,g as n,m as o,d as r,h as s,T as t};
2
2
  //# sourceMappingURL=use-auction-boundary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-auction-boundary.js","names":[],"sources":["../src/auction-description-html.ts","../src/auction-description.tsx","../src/auction-display.ts","../src/use-auction-visibility.ts","../src/use-auction-boundary.ts"],"sourcesContent":["const richDescriptionPattern =\n /<\\/?(?:p|br|strong|em|u|s|ul|ol|li|blockquote|pre|code|hr|h[1-6]|a)(?:\\s|\\/?>)/i;\n\nexport function auctionDescriptionHtml(description: string): string {\n if (!richDescriptionPattern.test(description)) {\n return description\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\\r\\n|\\r|\\n/g, \"<br>\");\n }\n\n return description;\n}\n","import { auctionDescriptionHtml } from \"./auction-description-html.ts\";\n\nexport function AuctionDescription({\n description,\n className,\n id,\n}: {\n description: string;\n className?: string | undefined;\n id?: string | undefined;\n}) {\n return (\n <div\n className={[\"lockerverse-auctions__description\", className]\n .filter(Boolean)\n .join(\" \")}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: Auction description HTML is trusted content supplied by the backend; the SDK renders it unchanged.\n dangerouslySetInnerHTML={{\n __html: auctionDescriptionHtml(description),\n }}\n id={id}\n />\n );\n}\n","import type {\n LockerverseAuction,\n LockerverseAuctionItem,\n LockerverseAuctionStatus,\n} from \"@lockerverse/sdk/auctions\";\nimport { formatMoney } from \"./format-money.ts\";\n\n// Match the public web app. Keep display policy here for all SDK auction surfaces.\nexport function formatAuctionBoundary(\n auction: LockerverseAuction,\n status: LockerverseAuctionStatus = auction.status,\n item?: LockerverseAuctionItem\n) {\n const starts = status === \"draft\";\n const nextItem = item ?? getNextAuctionItem(auction);\n const value = starts\n ? (nextItem?.startAt ?? auction.startAt)\n : ((status === \"finished\" ? item?.finishedAt : undefined) ??\n item?.endAt ??\n auction.endAt);\n const date = new Date(value);\n if (!Number.isFinite(date.getTime())) {\n return \"\";\n }\n const explicitBoundary = starts ? nextItem?.startAt : item?.endAt;\n const showTime = explicitBoundary\n ? true\n : ((starts\n ? auction.configuration.startTimeEnabled\n : auction.configuration.endTimeEnabled) ?? true);\n const dateLabel = new Intl.DateTimeFormat(\"en-US\", {\n day: \"numeric\",\n month: \"short\",\n timeZone: \"America/New_York\",\n year: \"numeric\",\n }).format(date);\n if (!showTime) {\n return dateLabel;\n }\n const timeLabel = new Intl.DateTimeFormat(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n timeZone: \"America/New_York\",\n timeZoneName: \"short\",\n }).format(date);\n return `${dateLabel} at ${timeLabel}`;\n}\n\nexport function formatAuctionMoney(cents: number) {\n return formatMoney(cents, 0);\n}\n\nexport function getAuctionDisplayStatus(\n auction: LockerverseAuction,\n item?: LockerverseAuctionItem\n): LockerverseAuctionStatus {\n if (auction.status === \"finished\" || item?.status === \"finished\") {\n return \"finished\";\n }\n // Preserve legacy draft responses until both item boundaries are available.\n if (\n item &&\n !(item.startAt && item.endAt) &&\n (item.status === \"draft\" || auction.status === \"draft\")\n ) {\n return \"draft\";\n }\n const now = Date.now();\n if (Date.parse(item?.endAt ?? auction.endAt) <= now) {\n return \"finished\";\n }\n if (Date.parse(item?.startAt ?? auction.startAt) > now) {\n return \"draft\";\n }\n if (item) {\n return \"active\";\n }\n if (auction.items.length) {\n const statuses = auction.items.map((entry) =>\n getAuctionDisplayStatus(auction, entry)\n );\n if (statuses.includes(\"active\")) {\n return \"active\";\n }\n return statuses.includes(\"draft\") ? \"draft\" : \"finished\";\n }\n return auction.status;\n}\n\n/** The next scheduled item, including a gap between groups of items. */\nexport function getNextAuctionItem(auction: LockerverseAuction) {\n const now = Date.now();\n return auction.items\n .filter(\n (item) =>\n item.status !== \"finished\" &&\n Date.parse(item.startAt ?? auction.startAt) > now\n )\n .sort(\n (left, right) =>\n Date.parse(left.startAt ?? auction.startAt) -\n Date.parse(right.startAt ?? auction.startAt)\n )[0];\n}\n\nexport function isAuctionItemSoldOut(item: LockerverseAuctionItem) {\n return (\n item.isSoldOut ||\n (item.saleMode === \"buy_now\" && item.availableQuantity === 0)\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\n\n/** Automatic motion stays off during SSR and in browsers without observation.\n * Manual gallery navigation remains available in those environments. */\nexport function useAuctionVisibility<ElementType extends HTMLElement>() {\n const ref = useRef<ElementType>(null);\n const [visible, setVisible] = useState(false);\n useEffect(() => {\n const element = ref.current;\n // biome-ignore lint/suspicious/noUnnecessaryConditions: React assigns this ref after rendering.\n if (!(element && \"IntersectionObserver\" in window)) {\n return;\n }\n let intersecting = false;\n const update = () => setVisible(intersecting && !document.hidden);\n const observer = new IntersectionObserver(([entry]) => {\n intersecting = Boolean(\n entry?.isIntersecting && entry.intersectionRatio > 0\n );\n update();\n });\n observer.observe(element);\n document.addEventListener(\"visibilitychange\", update);\n return () => {\n observer.disconnect();\n document.removeEventListener(\"visibilitychange\", update);\n };\n }, []);\n return { ref, visible };\n}\n","import { useCallback, useSyncExternalStore } from \"react\";\n\n// One timer serves every mounted auction surface, including standalone cards.\nconst subscriptions = new Map<() => void, readonly number[]>();\nlet timer: ReturnType<typeof setTimeout> | undefined;\nlet revision = 0;\nconst MAX_DELAY = 2_147_483_647;\n\nfunction schedule() {\n clearTimeout(timer);\n timer = undefined;\n const now = Date.now();\n let next = Number.POSITIVE_INFINITY;\n for (const boundaries of subscriptions.values()) {\n for (const boundary of boundaries) {\n if (boundary > now) {\n next = Math.min(next, boundary);\n }\n }\n }\n if (Number.isFinite(next)) {\n timer = setTimeout(notify, Math.min(next - now + 1, MAX_DELAY));\n }\n}\nfunction notify() {\n revision += 1;\n for (const listener of subscriptions.keys()) {\n listener();\n }\n schedule();\n}\nfunction onVisibilityChange() {\n if (!document.hidden) {\n notify();\n }\n}\nconst getSnapshot = () => revision;\nconst getServerSnapshot = () => 0;\n\n/** Re-render at known boundaries without polling or changing server status. */\nexport function useAuctionBoundary(\n startAt: string,\n endAt: string,\n items: readonly {\n startAt?: string | null | undefined;\n endAt?: string | null | undefined;\n }[] = []\n) {\n const boundaryKey = [\n startAt,\n endAt,\n ...items.flatMap((item) => [item.startAt ?? startAt, item.endAt ?? endAt]),\n ].join(\",\");\n const subscribe = useCallback(\n (listener: () => void) => {\n if (!subscriptions.size) {\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n }\n subscriptions.set(listener, boundaryKey.split(\",\").map(Date.parse));\n schedule();\n return () => {\n subscriptions.delete(listener);\n schedule();\n if (!subscriptions.size) {\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n }\n };\n },\n [boundaryKey]\n );\n useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-auction-boundary.js","names":[],"sources":["../src/auction-back-action.tsx","../src/auction-description-html.ts","../src/auction-description.tsx","../src/auction-display.ts","../src/use-auction-visibility.ts","../src/use-auction-boundary.ts"],"sourcesContent":["import type { ReactNode, RefCallback } from \"react\";\n\n/** Native route navigation; an optional host callback handles plain clicks. */\nexport function AuctionBackAction({\n href,\n onBack,\n className,\n children,\n elementRef,\n}: {\n href?: string | undefined;\n onBack?: (() => void) | undefined;\n className?: string;\n children: ReactNode;\n elementRef?: RefCallback<HTMLAnchorElement | HTMLButtonElement>;\n}) {\n if (href) {\n return (\n <a\n className={className}\n href={href}\n onClick={(event) => {\n if (\n onBack &&\n event.button === 0 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.shiftKey &&\n !event.altKey\n ) {\n event.preventDefault();\n onBack();\n }\n }}\n ref={elementRef}\n >\n {children}\n </a>\n );\n }\n return onBack ? (\n <button\n className={className}\n onClick={onBack}\n ref={elementRef}\n type=\"button\"\n >\n {children}\n </button>\n ) : null;\n}\n","const richDescriptionPattern =\n /<\\/?(?:p|br|strong|em|u|s|ul|ol|li|blockquote|pre|code|hr|h[1-6]|a)(?:\\s|\\/?>)/i;\n\nexport function auctionDescriptionHtml(description: string): string {\n if (!richDescriptionPattern.test(description)) {\n return description\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\\r\\n|\\r|\\n/g, \"<br>\");\n }\n\n return description;\n}\n","import { auctionDescriptionHtml } from \"./auction-description-html.ts\";\n\nexport function AuctionDescription({\n description,\n className,\n id,\n}: {\n description: string;\n className?: string | undefined;\n id?: string | undefined;\n}) {\n return (\n <div\n className={[\"lockerverse-auctions__description\", className]\n .filter(Boolean)\n .join(\" \")}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: Auction description HTML is trusted content supplied by the backend; the SDK renders it unchanged.\n dangerouslySetInnerHTML={{\n __html: auctionDescriptionHtml(description),\n }}\n id={id}\n />\n );\n}\n","import type {\n LockerverseAuction,\n LockerverseAuctionItem,\n LockerverseAuctionStatus,\n} from \"@lockerverse/sdk/auctions\";\nimport { formatMoney } from \"./format-money.ts\";\n\n// Match the public web app. Keep display policy here for all SDK auction surfaces.\nexport function formatAuctionBoundary(\n auction: LockerverseAuction,\n status: LockerverseAuctionStatus = auction.status,\n item?: LockerverseAuctionItem\n) {\n const starts = status === \"draft\";\n const nextItem = item ?? getNextAuctionItem(auction);\n const value = starts\n ? (nextItem?.startAt ?? auction.startAt)\n : ((status === \"finished\" ? item?.finishedAt : undefined) ??\n item?.endAt ??\n auction.endAt);\n const date = new Date(value);\n if (!Number.isFinite(date.getTime())) {\n return \"\";\n }\n const explicitBoundary = starts ? nextItem?.startAt : item?.endAt;\n const showTime = explicitBoundary\n ? true\n : ((starts\n ? auction.configuration.startTimeEnabled\n : auction.configuration.endTimeEnabled) ?? true);\n const dateLabel = new Intl.DateTimeFormat(\"en-US\", {\n day: \"numeric\",\n month: \"short\",\n timeZone: \"America/New_York\",\n year: \"numeric\",\n }).format(date);\n if (!showTime) {\n return dateLabel;\n }\n const timeLabel = new Intl.DateTimeFormat(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n timeZone: \"America/New_York\",\n timeZoneName: \"short\",\n }).format(date);\n return `${dateLabel} at ${timeLabel}`;\n}\n\nexport function formatAuctionMoney(cents: number) {\n return formatMoney(cents, 0);\n}\n\nexport function getAuctionDisplayStatus(\n auction: LockerverseAuction,\n item?: LockerverseAuctionItem\n): LockerverseAuctionStatus {\n if (auction.status === \"finished\" || item?.status === \"finished\") {\n return \"finished\";\n }\n // Preserve legacy draft responses until both item boundaries are available.\n if (\n item &&\n !(item.startAt && item.endAt) &&\n (item.status === \"draft\" || auction.status === \"draft\")\n ) {\n return \"draft\";\n }\n const now = Date.now();\n if (Date.parse(item?.endAt ?? auction.endAt) <= now) {\n return \"finished\";\n }\n if (Date.parse(item?.startAt ?? auction.startAt) > now) {\n return \"draft\";\n }\n if (item) {\n return \"active\";\n }\n if (auction.items.length) {\n const statuses = auction.items.map((entry) =>\n getAuctionDisplayStatus(auction, entry)\n );\n if (statuses.includes(\"active\")) {\n return \"active\";\n }\n return statuses.includes(\"draft\") ? \"draft\" : \"finished\";\n }\n return auction.status;\n}\n\n/** The next scheduled item, including a gap between groups of items. */\nexport function getNextAuctionItem(auction: LockerverseAuction) {\n const now = Date.now();\n return auction.items\n .filter(\n (item) =>\n item.status !== \"finished\" &&\n Date.parse(item.startAt ?? auction.startAt) > now\n )\n .sort(\n (left, right) =>\n Date.parse(left.startAt ?? auction.startAt) -\n Date.parse(right.startAt ?? auction.startAt)\n )[0];\n}\n\nexport function isAuctionItemSoldOut(item: LockerverseAuctionItem) {\n return (\n item.isSoldOut ||\n (item.saleMode === \"buy_now\" && item.availableQuantity === 0)\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\n\n/** Automatic motion stays off during SSR and in browsers without observation.\n * Manual gallery navigation remains available in those environments. */\nexport function useAuctionVisibility<ElementType extends HTMLElement>() {\n const ref = useRef<ElementType>(null);\n const [visible, setVisible] = useState(false);\n useEffect(() => {\n const element = ref.current;\n // biome-ignore lint/suspicious/noUnnecessaryConditions: React assigns this ref after rendering.\n if (!(element && \"IntersectionObserver\" in window)) {\n return;\n }\n let intersecting = false;\n const update = () => setVisible(intersecting && !document.hidden);\n const observer = new IntersectionObserver(([entry]) => {\n intersecting = Boolean(\n entry?.isIntersecting && entry.intersectionRatio > 0\n );\n update();\n });\n observer.observe(element);\n document.addEventListener(\"visibilitychange\", update);\n return () => {\n observer.disconnect();\n document.removeEventListener(\"visibilitychange\", update);\n };\n }, []);\n return { ref, visible };\n}\n","import { useCallback, useSyncExternalStore } from \"react\";\n\n// One timer serves every mounted auction surface, including standalone cards.\nconst subscriptions = new Map<() => void, readonly number[]>();\nlet timer: ReturnType<typeof setTimeout> | undefined;\nlet revision = 0;\nconst MAX_DELAY = 2_147_483_647;\n\nfunction schedule() {\n clearTimeout(timer);\n timer = undefined;\n const now = Date.now();\n let next = Number.POSITIVE_INFINITY;\n for (const boundaries of subscriptions.values()) {\n for (const boundary of boundaries) {\n if (boundary > now) {\n next = Math.min(next, boundary);\n }\n }\n }\n if (Number.isFinite(next)) {\n timer = setTimeout(notify, Math.min(next - now + 1, MAX_DELAY));\n }\n}\nfunction notify() {\n revision += 1;\n for (const listener of subscriptions.keys()) {\n listener();\n }\n schedule();\n}\nfunction onVisibilityChange() {\n if (!document.hidden) {\n notify();\n }\n}\nconst getSnapshot = () => revision;\nconst getServerSnapshot = () => 0;\n\n/** Re-render at known boundaries without polling or changing server status. */\nexport function useAuctionBoundary(\n startAt: string,\n endAt: string,\n items: readonly {\n startAt?: string | null | undefined;\n endAt?: string | null | undefined;\n }[] = []\n) {\n const boundaryKey = [\n startAt,\n endAt,\n ...items.flatMap((item) => [item.startAt ?? startAt, item.endAt ?? endAt]),\n ].join(\",\");\n const subscribe = useCallback(\n (listener: () => void) => {\n if (!subscriptions.size) {\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n }\n subscriptions.set(listener, boundaryKey.split(\",\").map(Date.parse));\n schedule();\n return () => {\n subscriptions.delete(listener);\n schedule();\n if (!subscriptions.size) {\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n }\n };\n },\n [boundaryKey]\n );\n useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lockerverse/react",
3
- "version": "0.2.154-dev.1",
3
+ "version": "0.2.156",
4
4
  "description": "Tree-shakable React payment and signup UI for Lockerverse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -113,6 +113,11 @@
113
113
  "./auction-result.css": {
114
114
  "types": "./dist/styles.d.ts",
115
115
  "default": "./dist/auction-result.css"
116
+ },
117
+ "./payment-primitives": {
118
+ "types": "./dist/payment-primitives.d.ts",
119
+ "import": "./dist/payment-primitives.js",
120
+ "default": "./dist/payment-primitives.js"
116
121
  }
117
122
  },
118
123
  "module": "./dist/index.js",
@@ -127,7 +132,7 @@
127
132
  "embla-carousel-react": "8.6.0",
128
133
  "lucide-react": "0.536.0",
129
134
  "valibot": "1.4.2",
130
- "@lockerverse/sdk": "0.2.154-dev.1"
135
+ "@lockerverse/sdk": "0.2.156"
131
136
  },
132
137
  "devDependencies": {
133
138
  "@size-limit/file": "13.0.3",