@lockerverse/react 0.2.163 → 0.2.165
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/MIGRATIONS.md +14 -0
- package/dist/custom-fields.d.ts.map +1 -1
- package/dist/custom-fields.js +1 -1
- package/dist/custom-fields.js.map +1 -1
- package/dist/select-control.css +68 -0
- package/dist/signup.css +0 -4
- package/guides/auctions.md +1 -1
- package/guides/events.md +1 -1
- package/guides/integration.md +1 -1
- package/guides/payment-widgets.md +1 -1
- package/guides/signup.md +1 -1
- package/package.json +2 -2
package/MIGRATIONS.md
CHANGED
|
@@ -36,6 +36,20 @@ If it cannot be found, report that limit and use the baseline review below. Do n
|
|
|
36
36
|
claim that every historical migration was applied. Read this file even if the
|
|
37
37
|
version already matches: a previous upgrade may have missed host adoption steps.
|
|
38
38
|
|
|
39
|
+
## 0.2.165 — multi-select custom fields
|
|
40
|
+
|
|
41
|
+
- **Affected:** React signup and payment forms with `multi_select` custom fields.
|
|
42
|
+
The field now opens a dropdown with multiple choices instead of a native listbox.
|
|
43
|
+
Accessible dropdown support adds Base UI Select to the signup bundle. The packed
|
|
44
|
+
signup consumer measures 111.80 kB brotli, about 32 kB above its former 80 kB
|
|
45
|
+
budget; hosts should account for this increase in initial JavaScript.
|
|
46
|
+
- **Required:** upgrade the matching SDK/React packages and deploy the host with
|
|
47
|
+
its existing signup or payment stylesheet. No host code or saved field changes
|
|
48
|
+
are required. Selected option IDs remain arrays; single-select fields are unchanged.
|
|
49
|
+
- **Check:** open the dropdown, select and remove multiple options, and confirm
|
|
50
|
+
keyboard navigation, Escape, and required-field feedback. Do not submit a live
|
|
51
|
+
signup or payment for this check.
|
|
52
|
+
|
|
39
53
|
## Existing integration baseline through 0.2.161
|
|
40
54
|
|
|
41
55
|
This guide starts with the current integration baseline. It is not a complete
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-fields.d.ts","names":[],"sources":["../src/custom-fields.tsx"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"custom-fields.d.ts","names":[],"sources":["../src/custom-fields.tsx"],"mappings":";;KAsBY,oBAAoB;iBAEhB,wBACd,SAAS,oBACT,gBAAgB,4BAAyB;;iBAW3B,wBACd,QAAQ,0BACR,gBAAe,oBACd;iBAca,2BACd,QAAQ,0BACR,QAAQ,oBAAiB;iBA2DX,wBACd,QAAQ,0BACR,QAAQ,oBACP;iBAgBa,qBACd,QAAQ,0BACR,QAAQ,oBAAiB;iBA6BX,eACd,iBACA,gBACA,QACA,QACA,UACA,UACA;EAEA;EACA;EACA,SAAS;EACT,QAAQ;EACR;EACA,WAAW,QAAQ;EACnB,QAAQ;oBACT,IAAA;KAeW;EACV;EACA;EACA;EACA,OAAO;EACP;EACA,WAAW;EACX;;iBAGc,cACd,iBACA,mBACG,SACF,mCAAgB,IAAA"}
|
package/dist/custom-fields.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{f as e,m as t,p as n,u as r}from"./phone-field.js";import{useId as i}from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";import{array as
|
|
1
|
+
import{f as e,m as t,p as n,u as r}from"./phone-field.js";import{useId as i}from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";import{Select as s}from"@base-ui/react/select";import{array as c,minLength as l,nonEmpty as u,pipe as d,safeParse as f,string as p,trim as m}from"valibot";function h(e,t){let n=new Set(t.map(e=>e.productId));return e.widget.customFields.filter(e=>!e.paymentOptionIds?.length||e.paymentOptionIds.some(e=>n.has(e)))}function g(e,t={}){return Object.fromEntries(e.map(e=>[e.id,v(e,Object.hasOwn(t,e.id)?t[e.id]:void 0)]))}function _(e,t){let n={};for(let r of e){let e=t[r.id];n[r.id]=v(r,e)}return Object.keys(t).length===e.length&&e.every(e=>{let r=t[e.id],i=n[e.id];return Object.hasOwn(t,e.id)&&y(r,i)})?t:n}function v(e,t){if(e.type===`checkbox`)return t===!0;if(e.type===`checkboxes`||e.type===`multi_select`){let n=new Set(e.options.map(e=>e.id));return Array.isArray(t)?t.filter(e=>n.has(e)):[]}let n=b(t);return e.type===`radio`||e.type===`select`?e.options.some(e=>e.id===n)?n:``:n}function y(e,t){return Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e===t}function b(e){let t=f(p(),e);return t.success?t.output:``}function x(e,t){return e.map(e=>{let n=t[e.id];return e.type===`checkbox`?{fieldId:e.id,value:n===!0}:e.type===`checkboxes`||e.type===`multi_select`?{fieldId:e.id,value:Array.isArray(n)?n:[]}:{fieldId:e.id,value:b(n)}})}function S(e,t){let n={};for(let r of e){if(!r.required)continue;let e=`${r.label} is required.`,i=t[r.id];if(r.type===`checkbox`){i!==!0&&(n[r.id]=e);continue}let a=r.type===`checkboxes`||r.type===`multi_select`?f(d(c(p()),l(1,e)),i??[]):f(d(p(),m(),u(e)),b(i));a.success||(n[r.id]=a.issues[0]?.message??e)}return n}function C({choiceClassName:e=`lockerverse-payment__check-row`,errorClassName:t=`lockerverse-payment__field-message`,errors:n={},fields:r,idPrefix:i,onChange:o,values:s}){return r.map(r=>a(w,{choiceClassName:e,error:n[r.id],errorClassName:t,field:r,idPrefix:i,onChange:e=>o({...s,[r.id]:e}),value:s[r.id]},r.id))}function w({choiceClassName:e=`lockerverse-payment__check-row`,errorClassName:t=`lockerverse-payment__field-message`,...n}){let r=i(),{field:o,idPrefix:s=`lockerverse-${r}`}=n,c=`${s}-custom-${o.id}`,l=`${c}-error`,u={...n,choiceClassName:e,controlId:c,errorClassName:t,errorId:l};switch(o.type){case`checkbox`:return a(T,{...u,field:o});case`text`:case`textarea`:return a(E,{...u,field:o});case`select`:return a(O,{...u,field:o});case`multi_select`:return a(D,{...u,field:o});case`radio`:case`checkboxes`:return a(k,{...u,field:o});default:return null}}function T({choiceClassName:t,controlId:n,error:i,errorClassName:s,errorId:c,field:l,onChange:u,value:d}){return o(`label`,{className:t,htmlFor:n,children:[a(r,{"aria-describedby":i?c:void 0,"aria-invalid":i?`true`:void 0,checked:d===!0,id:n,name:`custom:${l.id}`,onChange:e=>u(e.currentTarget.checked),required:l.required}),a(`span`,{children:l.label}),a(e,{className:s,error:i,id:c})]})}function E({controlId:e,error:r,errorId:i,field:o,onChange:s,value:c}){let l={"aria-describedby":r?i:void 0,"aria-invalid":r?`true`:void 0,id:e,name:`custom:${o.id}`,onChange:e=>s(e.currentTarget.value),required:o.required,value:b(c)};return o.type===`textarea`?a(n,{error:r,errorId:i,id:e,label:o.label,children:a(`textarea`,{...l,className:`lockerverse-form__control`})}):a(t,{...l,error:r,errorId:i,label:o.label})}function D({controlId:e,error:t,errorId:r,field:i,onChange:c,value:l}){return a(n,{error:t,errorId:r,id:e,label:i.label,children:o(s.Root,{id:e,items:i.options.map(e=>({label:e.label,value:e.id})),modal:!1,multiple:!0,name:`custom:${i.id}`,onValueChange:c,required:i.required,value:Array.isArray(l)?l:[],children:[o(s.Trigger,{"aria-describedby":t?r:void 0,"aria-invalid":t?`true`:void 0,className:`lockerverse-form__control lockerverse-multi-select__trigger`,id:e,name:`custom:${i.id}`,type:`button`,children:[a(s.Value,{placeholder:`Select…`}),a(s.Icon,{className:`lockerverse-multi-select__icon`,children:null})]}),a(s.Positioner,{align:`start`,alignItemWithTrigger:!1,className:`lockerverse-multi-select__positioner`,sideOffset:6,children:a(s.Popup,{className:`lockerverse-multi-select__popup`,children:a(s.List,{className:`lockerverse-multi-select__list`,children:i.options.map(e=>o(s.Item,{className:`lockerverse-multi-select__item`,value:e.id,children:[a(`span`,{"aria-hidden":`true`,className:`lockerverse-multi-select__check`,children:a(s.ItemIndicator,{children:`✓`})}),a(s.ItemText,{children:e.label})]},e.id))})})})]})})}function O({controlId:e,error:t,errorId:r,field:i,onChange:s,value:c}){return a(n,{error:t,errorId:r,id:e,label:i.label,children:o(`select`,{"aria-describedby":t?r:void 0,"aria-invalid":t?`true`:void 0,className:`lockerverse-form__control`,id:e,name:`custom:${i.id}`,onChange:e=>s(e.currentTarget.value),required:i.required,value:b(c),children:[a(`option`,{value:``,children:`Select…`}),i.options.map(e=>a(`option`,{value:e.id,children:e.label},e.id))]})})}function k({choiceClassName:t,controlId:n,error:r,errorClassName:i,errorId:s,field:c,onChange:l,value:u}){let d=Array.isArray(u)?u:[];return o(`fieldset`,{"aria-describedby":r?s:void 0,"aria-invalid":r?`true`:void 0,children:[a(`legend`,{children:c.label}),c.options.map((e,r)=>o(`label`,{className:t,children:[a(`input`,{checked:Array.isArray(u)?u.includes(e.id):u===e.id,className:c.type===`checkboxes`?`lockerverse-form__checkbox`:void 0,id:`${n}-${r}`,name:`custom:${c.id}`,onChange:t=>{if(c.type===`radio`){l(e.id);return}l(t.currentTarget.checked?[...d,e.id]:d.filter(t=>t!==e.id))},required:c.required&&c.type===`radio`,type:c.type===`radio`?`radio`:`checkbox`,value:e.id}),a(`span`,{children:e.label})]},e.id)),a(e,{className:i,error:r,id:s})]})}export{h as a,g as i,C as n,_ as o,x as r,S as s,w as t};
|
|
2
2
|
//# sourceMappingURL=custom-fields.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-fields.js","names":[],"sources":["../src/custom-fields.tsx"],"sourcesContent":["import type {\n LockerverseBooleanCustomField,\n LockerverseCatalog,\n LockerverseCheckoutItem,\n LockerverseCustomField,\n LockerverseCustomFieldAnswer,\n LockerverseMultiOptionCustomField,\n LockerverseSingleOptionCustomField,\n} from \"@lockerverse/sdk/checkout\";\nimport { useId } from \"react\";\nimport {\n array,\n minLength,\n nonEmpty,\n pipe,\n safeParse,\n string,\n trim,\n} from \"valibot\";\nimport { Checkbox, FieldError, FormField, TextField } from \"./form-field.tsx\";\n\nexport type CustomFieldValues = Record<string, boolean | string | string[]>;\n\nexport function getCheckoutCustomFields(\n catalog: LockerverseCatalog,\n items: readonly LockerverseCheckoutItem[]\n) {\n const selectedOptionIds = new Set(items.map((item) => item.productId));\n return catalog.widget.customFields.filter(\n (field) =>\n !field.paymentOptionIds?.length ||\n field.paymentOptionIds.some((id) => selectedOptionIds.has(id))\n );\n}\n\n/** Normalize initial values against configured fields; unknown fields and options are discarded. */\nexport function createCustomFieldValues(\n fields: LockerverseCustomField[],\n initialValues: CustomFieldValues = {}\n): CustomFieldValues {\n return Object.fromEntries(\n fields.map((field) => [\n field.id,\n reconcileCustomFieldValue(\n field,\n Object.hasOwn(initialValues, field.id)\n ? initialValues[field.id]\n : undefined\n ),\n ])\n );\n}\n\nexport function reconcileCustomFieldValues(\n fields: LockerverseCustomField[],\n values: CustomFieldValues\n) {\n const next: CustomFieldValues = {};\n for (const field of fields) {\n const value = values[field.id];\n next[field.id] = reconcileCustomFieldValue(field, value);\n }\n const oldKeys = Object.keys(values);\n if (\n oldKeys.length === fields.length &&\n fields.every((field) => {\n const before = values[field.id];\n const after = next[field.id];\n return (\n Object.hasOwn(values, field.id) && sameCustomFieldValue(before, after)\n );\n })\n ) {\n return values;\n }\n return next;\n}\n\nfunction reconcileCustomFieldValue(\n field: LockerverseCustomField,\n value: CustomFieldValues[string] | undefined\n) {\n if (field.type === \"checkbox\") {\n return value === true;\n }\n if (field.type === \"checkboxes\" || field.type === \"multi_select\") {\n const optionIds = new Set(field.options.map((option) => option.id));\n return Array.isArray(value) ? value.filter((id) => optionIds.has(id)) : [];\n }\n const text = getStringValue(value);\n if (field.type === \"radio\" || field.type === \"select\") {\n return field.options.some((option) => option.id === text) ? text : \"\";\n }\n return text;\n}\n\nfunction sameCustomFieldValue(\n before: CustomFieldValues[string] | undefined,\n after: CustomFieldValues[string] | undefined\n) {\n if (Array.isArray(before) && Array.isArray(after)) {\n return (\n before.length === after.length &&\n before.every((id, index) => id === after[index])\n );\n }\n return before === after;\n}\n\nfunction getStringValue(value: CustomFieldValues[string] | undefined) {\n const result = safeParse(string(), value);\n return result.success ? result.output : \"\";\n}\n\nexport function buildCustomFieldAnswers(\n fields: LockerverseCustomField[],\n values: CustomFieldValues\n): LockerverseCustomFieldAnswer[] {\n return fields.map((field): LockerverseCustomFieldAnswer => {\n const value = values[field.id];\n if (field.type === \"checkbox\") {\n return { fieldId: field.id, value: value === true };\n }\n if (field.type === \"checkboxes\" || field.type === \"multi_select\") {\n return { fieldId: field.id, value: Array.isArray(value) ? value : [] };\n }\n return {\n fieldId: field.id,\n value: getStringValue(value),\n };\n });\n}\n\nexport function validateCustomFields(\n fields: LockerverseCustomField[],\n values: CustomFieldValues\n) {\n const errors: Record<string, string> = {};\n for (const field of fields) {\n if (!field.required) {\n continue;\n }\n const message = `${field.label} is required.`;\n const value = values[field.id];\n if (field.type === \"checkbox\") {\n if (value !== true) {\n errors[field.id] = message;\n }\n continue;\n }\n const result =\n field.type === \"checkboxes\" || field.type === \"multi_select\"\n ? safeParse(pipe(array(string()), minLength(1, message)), value ?? [])\n : safeParse(\n pipe(string(), trim(), nonEmpty(message)),\n getStringValue(value)\n );\n if (!result.success) {\n errors[field.id] = result.issues[0]?.message ?? message;\n }\n }\n return errors;\n}\n\nexport function CustomFields({\n choiceClassName = \"lockerverse-payment__check-row\",\n errorClassName = \"lockerverse-payment__field-message\",\n errors = {},\n fields,\n idPrefix,\n onChange,\n values,\n}: {\n choiceClassName?: string;\n errorClassName?: string;\n errors?: Record<string, string>;\n fields: LockerverseCustomField[];\n idPrefix?: string | undefined;\n onChange: (values: CustomFieldValues) => void;\n values: CustomFieldValues;\n}) {\n return fields.map((field) => (\n <CustomField\n choiceClassName={choiceClassName}\n error={errors[field.id]}\n errorClassName={errorClassName}\n field={field}\n idPrefix={idPrefix}\n key={field.id}\n onChange={(value) => onChange({ ...values, [field.id]: value })}\n value={values[field.id]}\n />\n ));\n}\n\nexport type CustomFieldProps = {\n choiceClassName?: string;\n error?: string | undefined;\n errorClassName?: string;\n field: LockerverseCustomField;\n idPrefix?: string | undefined;\n onChange: (value: boolean | string | string[]) => void;\n value: boolean | string | string[] | undefined;\n};\n\nexport function CustomField({\n choiceClassName = \"lockerverse-payment__check-row\",\n errorClassName = \"lockerverse-payment__field-message\",\n ...props\n}: CustomFieldProps) {\n const generatedId = useId();\n const { field, idPrefix = `lockerverse-${generatedId}` } = props;\n const controlId = `${idPrefix}-custom-${field.id}`;\n const errorId = `${controlId}-error`;\n const controlProps = {\n ...props,\n choiceClassName,\n controlId,\n errorClassName,\n errorId,\n };\n switch (field.type) {\n case \"checkbox\":\n return <BooleanCustomField {...controlProps} field={field} />;\n case \"text\":\n case \"textarea\":\n return <TextCustomField {...controlProps} field={field} />;\n case \"select\":\n case \"multi_select\":\n return <SelectCustomField {...controlProps} field={field} />;\n case \"radio\":\n case \"checkboxes\":\n return <ChoiceCustomField {...controlProps} field={field} />;\n default:\n return null;\n }\n}\n\nfunction BooleanCustomField({\n choiceClassName,\n controlId,\n error,\n errorClassName,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & { field: LockerverseBooleanCustomField }) {\n return (\n <label className={choiceClassName} htmlFor={controlId}>\n <Checkbox\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n checked={value === true}\n id={controlId}\n name={`custom:${field.id}`}\n onChange={(event) => onChange(event.currentTarget.checked)}\n required={field.required}\n />\n <span>{field.label}</span>\n <FieldError className={errorClassName} error={error} id={errorId} />\n </label>\n );\n}\n\ntype ControlProps = CustomFieldProps & {\n choiceClassName: string;\n errorClassName: string;\n controlId: string;\n errorId: string;\n};\n\nfunction TextCustomField({\n controlId,\n error,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & {\n field: Extract<LockerverseCustomField, { type: \"text\" | \"textarea\" }>;\n}) {\n const commonProps = {\n \"aria-describedby\": error ? errorId : undefined,\n \"aria-invalid\": error ? (\"true\" as const) : undefined,\n id: controlId,\n name: `custom:${field.id}`,\n onChange: (\n event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => onChange(event.currentTarget.value),\n required: field.required,\n value: getStringValue(value),\n };\n return field.type === \"textarea\" ? (\n <FormField\n error={error}\n errorId={errorId}\n id={controlId}\n label={field.label}\n >\n <textarea {...commonProps} className=\"lockerverse-form__control\" />\n </FormField>\n ) : (\n <TextField\n {...commonProps}\n error={error}\n errorId={errorId}\n label={field.label}\n />\n );\n}\n\nfunction SelectCustomField({\n controlId,\n error,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & {\n field: LockerverseMultiOptionCustomField | LockerverseSingleOptionCustomField;\n}) {\n return (\n <FormField\n error={error}\n errorId={errorId}\n id={controlId}\n label={field.label}\n >\n <select\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n className=\"lockerverse-form__control\"\n id={controlId}\n multiple={field.type === \"multi_select\"}\n name={`custom:${field.id}`}\n onChange={(event) =>\n onChange(\n field.type === \"multi_select\"\n ? [...event.currentTarget.selectedOptions].map(\n (option) => option.value\n )\n : event.currentTarget.value\n )\n }\n required={field.required}\n value={\n value === true || value === false\n ? \"\"\n : (value ?? (field.type === \"multi_select\" ? [] : \"\"))\n }\n >\n {field.type === \"select\" ? <option value=\"\">Select…</option> : null}\n {field.options.map((option) => (\n <option key={option.id} value={option.id}>\n {option.label}\n </option>\n ))}\n </select>\n </FormField>\n );\n}\n\nfunction ChoiceCustomField({\n choiceClassName,\n controlId,\n error,\n errorClassName,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & {\n field: LockerverseMultiOptionCustomField | LockerverseSingleOptionCustomField;\n}) {\n const selectedValues = Array.isArray(value) ? value : [];\n return (\n <fieldset\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n >\n <legend>{field.label}</legend>\n {field.options.map((option, index) => (\n <label className={choiceClassName} key={option.id}>\n <input\n checked={\n Array.isArray(value)\n ? value.includes(option.id)\n : value === option.id\n }\n className={\n field.type === \"checkboxes\"\n ? \"lockerverse-form__checkbox\"\n : undefined\n }\n id={`${controlId}-${index}`}\n name={`custom:${field.id}`}\n onChange={(event) => {\n if (field.type === \"radio\") {\n onChange(option.id);\n return;\n }\n onChange(\n event.currentTarget.checked\n ? [...selectedValues, option.id]\n : selectedValues.filter((id) => id !== option.id)\n );\n }}\n required={field.required && field.type === \"radio\"}\n type={field.type === \"radio\" ? \"radio\" : \"checkbox\"}\n value={option.id}\n />\n <span>{option.label}</span>\n </label>\n ))}\n <FieldError className={errorClassName} error={error} id={errorId} />\n </fieldset>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"custom-fields.js","names":[],"sources":["../src/custom-fields.tsx"],"sourcesContent":["import { Select } from \"@base-ui/react/select\";\nimport type {\n LockerverseBooleanCustomField,\n LockerverseCatalog,\n LockerverseCheckoutItem,\n LockerverseCustomField,\n LockerverseCustomFieldAnswer,\n LockerverseMultiOptionCustomField,\n LockerverseSingleOptionCustomField,\n} from \"@lockerverse/sdk/checkout\";\nimport { useId } from \"react\";\nimport {\n array,\n minLength,\n nonEmpty,\n pipe,\n safeParse,\n string,\n trim,\n} from \"valibot\";\nimport { Checkbox, FieldError, FormField, TextField } from \"./form-field.tsx\";\n\nexport type CustomFieldValues = Record<string, boolean | string | string[]>;\n\nexport function getCheckoutCustomFields(\n catalog: LockerverseCatalog,\n items: readonly LockerverseCheckoutItem[]\n) {\n const selectedOptionIds = new Set(items.map((item) => item.productId));\n return catalog.widget.customFields.filter(\n (field) =>\n !field.paymentOptionIds?.length ||\n field.paymentOptionIds.some((id) => selectedOptionIds.has(id))\n );\n}\n\n/** Normalize initial values against configured fields; unknown fields and options are discarded. */\nexport function createCustomFieldValues(\n fields: LockerverseCustomField[],\n initialValues: CustomFieldValues = {}\n): CustomFieldValues {\n return Object.fromEntries(\n fields.map((field) => [\n field.id,\n reconcileCustomFieldValue(\n field,\n Object.hasOwn(initialValues, field.id)\n ? initialValues[field.id]\n : undefined\n ),\n ])\n );\n}\n\nexport function reconcileCustomFieldValues(\n fields: LockerverseCustomField[],\n values: CustomFieldValues\n) {\n const next: CustomFieldValues = {};\n for (const field of fields) {\n const value = values[field.id];\n next[field.id] = reconcileCustomFieldValue(field, value);\n }\n const oldKeys = Object.keys(values);\n if (\n oldKeys.length === fields.length &&\n fields.every((field) => {\n const before = values[field.id];\n const after = next[field.id];\n return (\n Object.hasOwn(values, field.id) && sameCustomFieldValue(before, after)\n );\n })\n ) {\n return values;\n }\n return next;\n}\n\nfunction reconcileCustomFieldValue(\n field: LockerverseCustomField,\n value: CustomFieldValues[string] | undefined\n) {\n if (field.type === \"checkbox\") {\n return value === true;\n }\n if (field.type === \"checkboxes\" || field.type === \"multi_select\") {\n const optionIds = new Set(field.options.map((option) => option.id));\n return Array.isArray(value) ? value.filter((id) => optionIds.has(id)) : [];\n }\n const text = getStringValue(value);\n if (field.type === \"radio\" || field.type === \"select\") {\n return field.options.some((option) => option.id === text) ? text : \"\";\n }\n return text;\n}\n\nfunction sameCustomFieldValue(\n before: CustomFieldValues[string] | undefined,\n after: CustomFieldValues[string] | undefined\n) {\n if (Array.isArray(before) && Array.isArray(after)) {\n return (\n before.length === after.length &&\n before.every((id, index) => id === after[index])\n );\n }\n return before === after;\n}\n\nfunction getStringValue(value: CustomFieldValues[string] | undefined) {\n const result = safeParse(string(), value);\n return result.success ? result.output : \"\";\n}\n\nexport function buildCustomFieldAnswers(\n fields: LockerverseCustomField[],\n values: CustomFieldValues\n): LockerverseCustomFieldAnswer[] {\n return fields.map((field): LockerverseCustomFieldAnswer => {\n const value = values[field.id];\n if (field.type === \"checkbox\") {\n return { fieldId: field.id, value: value === true };\n }\n if (field.type === \"checkboxes\" || field.type === \"multi_select\") {\n return { fieldId: field.id, value: Array.isArray(value) ? value : [] };\n }\n return {\n fieldId: field.id,\n value: getStringValue(value),\n };\n });\n}\n\nexport function validateCustomFields(\n fields: LockerverseCustomField[],\n values: CustomFieldValues\n) {\n const errors: Record<string, string> = {};\n for (const field of fields) {\n if (!field.required) {\n continue;\n }\n const message = `${field.label} is required.`;\n const value = values[field.id];\n if (field.type === \"checkbox\") {\n if (value !== true) {\n errors[field.id] = message;\n }\n continue;\n }\n const result =\n field.type === \"checkboxes\" || field.type === \"multi_select\"\n ? safeParse(pipe(array(string()), minLength(1, message)), value ?? [])\n : safeParse(\n pipe(string(), trim(), nonEmpty(message)),\n getStringValue(value)\n );\n if (!result.success) {\n errors[field.id] = result.issues[0]?.message ?? message;\n }\n }\n return errors;\n}\n\nexport function CustomFields({\n choiceClassName = \"lockerverse-payment__check-row\",\n errorClassName = \"lockerverse-payment__field-message\",\n errors = {},\n fields,\n idPrefix,\n onChange,\n values,\n}: {\n choiceClassName?: string;\n errorClassName?: string;\n errors?: Record<string, string>;\n fields: LockerverseCustomField[];\n idPrefix?: string | undefined;\n onChange: (values: CustomFieldValues) => void;\n values: CustomFieldValues;\n}) {\n return fields.map((field) => (\n <CustomField\n choiceClassName={choiceClassName}\n error={errors[field.id]}\n errorClassName={errorClassName}\n field={field}\n idPrefix={idPrefix}\n key={field.id}\n onChange={(value) => onChange({ ...values, [field.id]: value })}\n value={values[field.id]}\n />\n ));\n}\n\nexport type CustomFieldProps = {\n choiceClassName?: string;\n error?: string | undefined;\n errorClassName?: string;\n field: LockerverseCustomField;\n idPrefix?: string | undefined;\n onChange: (value: boolean | string | string[]) => void;\n value: boolean | string | string[] | undefined;\n};\n\nexport function CustomField({\n choiceClassName = \"lockerverse-payment__check-row\",\n errorClassName = \"lockerverse-payment__field-message\",\n ...props\n}: CustomFieldProps) {\n const generatedId = useId();\n const { field, idPrefix = `lockerverse-${generatedId}` } = props;\n const controlId = `${idPrefix}-custom-${field.id}`;\n const errorId = `${controlId}-error`;\n const controlProps = {\n ...props,\n choiceClassName,\n controlId,\n errorClassName,\n errorId,\n };\n switch (field.type) {\n case \"checkbox\":\n return <BooleanCustomField {...controlProps} field={field} />;\n case \"text\":\n case \"textarea\":\n return <TextCustomField {...controlProps} field={field} />;\n case \"select\":\n return <SelectCustomField {...controlProps} field={field} />;\n case \"multi_select\":\n return <MultiSelectCustomField {...controlProps} field={field} />;\n case \"radio\":\n case \"checkboxes\":\n return <ChoiceCustomField {...controlProps} field={field} />;\n default:\n return null;\n }\n}\n\nfunction BooleanCustomField({\n choiceClassName,\n controlId,\n error,\n errorClassName,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & { field: LockerverseBooleanCustomField }) {\n return (\n <label className={choiceClassName} htmlFor={controlId}>\n <Checkbox\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n checked={value === true}\n id={controlId}\n name={`custom:${field.id}`}\n onChange={(event) => onChange(event.currentTarget.checked)}\n required={field.required}\n />\n <span>{field.label}</span>\n <FieldError className={errorClassName} error={error} id={errorId} />\n </label>\n );\n}\n\ntype ControlProps = CustomFieldProps & {\n choiceClassName: string;\n errorClassName: string;\n controlId: string;\n errorId: string;\n};\n\nfunction TextCustomField({\n controlId,\n error,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & {\n field: Extract<LockerverseCustomField, { type: \"text\" | \"textarea\" }>;\n}) {\n const commonProps = {\n \"aria-describedby\": error ? errorId : undefined,\n \"aria-invalid\": error ? (\"true\" as const) : undefined,\n id: controlId,\n name: `custom:${field.id}`,\n onChange: (\n event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => onChange(event.currentTarget.value),\n required: field.required,\n value: getStringValue(value),\n };\n return field.type === \"textarea\" ? (\n <FormField\n error={error}\n errorId={errorId}\n id={controlId}\n label={field.label}\n >\n <textarea {...commonProps} className=\"lockerverse-form__control\" />\n </FormField>\n ) : (\n <TextField\n {...commonProps}\n error={error}\n errorId={errorId}\n label={field.label}\n />\n );\n}\n\nfunction MultiSelectCustomField({\n controlId,\n error,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & { field: LockerverseMultiOptionCustomField }) {\n return (\n <FormField\n error={error}\n errorId={errorId}\n id={controlId}\n label={field.label}\n >\n <Select.Root\n id={controlId}\n items={field.options.map((option) => ({\n label: option.label,\n value: option.id,\n }))}\n modal={false}\n multiple\n name={`custom:${field.id}`}\n onValueChange={onChange}\n required={field.required}\n value={Array.isArray(value) ? value : []}\n >\n <Select.Trigger\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n className=\"lockerverse-form__control lockerverse-multi-select__trigger\"\n id={controlId}\n name={`custom:${field.id}`}\n type=\"button\"\n >\n <Select.Value placeholder=\"Select…\" />\n <Select.Icon className=\"lockerverse-multi-select__icon\">\n {null}\n </Select.Icon>\n </Select.Trigger>\n <Select.Positioner\n align=\"start\"\n alignItemWithTrigger={false}\n className=\"lockerverse-multi-select__positioner\"\n sideOffset={6}\n >\n <Select.Popup className=\"lockerverse-multi-select__popup\">\n <Select.List className=\"lockerverse-multi-select__list\">\n {field.options.map((option) => (\n <Select.Item\n className=\"lockerverse-multi-select__item\"\n key={option.id}\n value={option.id}\n >\n <span\n aria-hidden=\"true\"\n className=\"lockerverse-multi-select__check\"\n >\n <Select.ItemIndicator>✓</Select.ItemIndicator>\n </span>\n <Select.ItemText>{option.label}</Select.ItemText>\n </Select.Item>\n ))}\n </Select.List>\n </Select.Popup>\n </Select.Positioner>\n </Select.Root>\n </FormField>\n );\n}\n\nfunction SelectCustomField({\n controlId,\n error,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & {\n field: LockerverseSingleOptionCustomField;\n}) {\n return (\n <FormField\n error={error}\n errorId={errorId}\n id={controlId}\n label={field.label}\n >\n <select\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n className=\"lockerverse-form__control\"\n id={controlId}\n name={`custom:${field.id}`}\n onChange={(event) => onChange(event.currentTarget.value)}\n required={field.required}\n value={getStringValue(value)}\n >\n <option value=\"\">Select…</option>\n {field.options.map((option) => (\n <option key={option.id} value={option.id}>\n {option.label}\n </option>\n ))}\n </select>\n </FormField>\n );\n}\n\nfunction ChoiceCustomField({\n choiceClassName,\n controlId,\n error,\n errorClassName,\n errorId,\n field,\n onChange,\n value,\n}: ControlProps & {\n field: LockerverseMultiOptionCustomField | LockerverseSingleOptionCustomField;\n}) {\n const selectedValues = Array.isArray(value) ? value : [];\n return (\n <fieldset\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n >\n <legend>{field.label}</legend>\n {field.options.map((option, index) => (\n <label className={choiceClassName} key={option.id}>\n <input\n checked={\n Array.isArray(value)\n ? value.includes(option.id)\n : value === option.id\n }\n className={\n field.type === \"checkboxes\"\n ? \"lockerverse-form__checkbox\"\n : undefined\n }\n id={`${controlId}-${index}`}\n name={`custom:${field.id}`}\n onChange={(event) => {\n if (field.type === \"radio\") {\n onChange(option.id);\n return;\n }\n onChange(\n event.currentTarget.checked\n ? [...selectedValues, option.id]\n : selectedValues.filter((id) => id !== option.id)\n );\n }}\n required={field.required && field.type === \"radio\"}\n type={field.type === \"radio\" ? \"radio\" : \"checkbox\"}\n value={option.id}\n />\n <span>{option.label}</span>\n </label>\n ))}\n <FieldError className={errorClassName} error={error} id={errorId} />\n </fieldset>\n );\n}\n"],"mappings":"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"}
|
package/dist/select-control.css
CHANGED
|
@@ -16,3 +16,71 @@ select.lockerverse-form__control:not([multiple]) {
|
|
|
16
16
|
select.lockerverse-form__control[multiple] {
|
|
17
17
|
background-image: none;
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
.lockerverse-multi-select__trigger {
|
|
21
|
+
display: flex;
|
|
22
|
+
gap: 12px;
|
|
23
|
+
align-items: center;
|
|
24
|
+
justify-content: space-between;
|
|
25
|
+
text-align: left;
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
}
|
|
28
|
+
.lockerverse-multi-select__icon {
|
|
29
|
+
flex: 0 0 auto;
|
|
30
|
+
width: 8px;
|
|
31
|
+
height: 8px;
|
|
32
|
+
margin: -4px 3px 0;
|
|
33
|
+
border-right: 2px solid currentcolor;
|
|
34
|
+
border-bottom: 2px solid currentcolor;
|
|
35
|
+
transform: rotate(45deg);
|
|
36
|
+
}
|
|
37
|
+
.lockerverse-multi-select__positioner {
|
|
38
|
+
z-index: 100;
|
|
39
|
+
width: var(--anchor-width);
|
|
40
|
+
max-width: var(--available-width);
|
|
41
|
+
}
|
|
42
|
+
.lockerverse-multi-select__popup {
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
color: var(--lockerverse-text);
|
|
45
|
+
background: var(--lockerverse-control, var(--lockerverse-bg));
|
|
46
|
+
border: 1px solid var(--lockerverse-border);
|
|
47
|
+
border-radius: var(--lockerverse-radius, 10px);
|
|
48
|
+
box-shadow: 0 8px 24px #0003;
|
|
49
|
+
}
|
|
50
|
+
.lockerverse-multi-select__list {
|
|
51
|
+
box-sizing: border-box;
|
|
52
|
+
max-height: min(280px, var(--available-height));
|
|
53
|
+
padding: 4px;
|
|
54
|
+
overflow-y: auto;
|
|
55
|
+
outline: none;
|
|
56
|
+
}
|
|
57
|
+
.lockerverse-multi-select__item {
|
|
58
|
+
display: flex;
|
|
59
|
+
gap: 10px;
|
|
60
|
+
align-items: center;
|
|
61
|
+
min-height: 44px;
|
|
62
|
+
padding: 8px 10px;
|
|
63
|
+
font: inherit;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
user-select: none;
|
|
66
|
+
outline: none;
|
|
67
|
+
border-radius: calc(var(--lockerverse-radius, 10px) / 2);
|
|
68
|
+
}
|
|
69
|
+
.lockerverse-multi-select__item[data-highlighted] {
|
|
70
|
+
background: color-mix(in srgb, var(--lockerverse-text) 10%, transparent);
|
|
71
|
+
}
|
|
72
|
+
.lockerverse-multi-select__check {
|
|
73
|
+
display: grid;
|
|
74
|
+
flex: 0 0 auto;
|
|
75
|
+
place-items: center;
|
|
76
|
+
width: 18px;
|
|
77
|
+
height: 18px;
|
|
78
|
+
border: 1px solid var(--lockerverse-border);
|
|
79
|
+
border-radius: 4px;
|
|
80
|
+
}
|
|
81
|
+
.lockerverse-multi-select__item[data-selected]
|
|
82
|
+
.lockerverse-multi-select__check {
|
|
83
|
+
color: var(--lockerverse-accent-contrast, #000);
|
|
84
|
+
background: var(--lockerverse-accent);
|
|
85
|
+
border-color: var(--lockerverse-accent);
|
|
86
|
+
}
|
package/dist/signup.css
CHANGED
|
@@ -134,10 +134,6 @@
|
|
|
134
134
|
color-mix(in srgb, var(--lockerverse-text) 8%, transparent);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
.lockerverse-signup select[multiple] {
|
|
138
|
-
min-height: 128px;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
137
|
.lockerverse-signup [aria-invalid="true"] {
|
|
142
138
|
border-color: var(--lockerverse-danger);
|
|
143
139
|
}
|
package/guides/auctions.md
CHANGED
package/guides/events.md
CHANGED
package/guides/integration.md
CHANGED
package/guides/signup.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lockerverse/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.165",
|
|
4
4
|
"description": "Tree-shakable React payment and signup UI for Lockerverse",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"embla-carousel-react": "8.6.0",
|
|
137
137
|
"lucide-react": "0.536.0",
|
|
138
138
|
"valibot": "1.4.2",
|
|
139
|
-
"@lockerverse/sdk": "0.2.
|
|
139
|
+
"@lockerverse/sdk": "0.2.165"
|
|
140
140
|
},
|
|
141
141
|
"devDependencies": {
|
|
142
142
|
"@size-limit/file": "13.0.3",
|