@volter/world-ui 0.1.0 → 0.1.1

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.
@@ -9,6 +9,8 @@ export type PaymentField = {
9
9
  /** a field that formats itself as it is typed, as payment vendors' card fields do: `card-expiry` reads the digits
10
10
  * `1230` as `12 / 30` (FORMAT_SCRIPT). The page still posts without a script; the pack reads what is posted. */
11
11
  format?: 'card-expiry';
12
+ /** a value the vendor already knows and the customer cannot change here (an email on file): shown, posted, not editable */
13
+ readOnly?: boolean;
12
14
  };
13
15
 
14
16
  export type PaymentProps = {
@@ -79,7 +81,7 @@ export function Payment(props: PaymentProps) {
79
81
  <span>{f.label}</span>
80
82
  {f.options
81
83
  ? <select id={f.id} name={f.id} defaultValue={f.value}>{f.options.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}</select>
82
- : <input id={f.id} name={f.id} type={f.type ?? 'text'} placeholder={f.placeholder} autoComplete={f.autoComplete} defaultValue={f.value} {...(f.format ? { 'data-format': f.format, inputMode: 'numeric' as const } : {})} />}
84
+ : <input id={f.id} name={f.id} type={f.type ?? 'text'} placeholder={f.placeholder} autoComplete={f.autoComplete} defaultValue={f.value} {...(f.format ? { 'data-format': f.format, inputMode: 'numeric' as const } : {})} {...(f.readOnly ? { readOnly: true } : {})} />}
83
85
  </label>
84
86
  ))}
85
87
  </fieldset>
@@ -116,6 +118,7 @@ body { margin: 0; font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-seri
116
118
  .pay-field { display: block; margin-bottom: 12px; }
117
119
  .pay-field span { display: block; font-size: 13px; margin-bottom: 4px; }
118
120
  .pay-field input, .pay-field select { box-sizing: border-box; width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid; font: inherit; }
121
+ .pay-field input[readonly] { opacity: 0.7; }
119
122
  .pay-error { margin: 0 0 12px; }
120
123
  .pay-submit { width: 100%; padding: 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer; }
121
124
  `;
@@ -33,7 +33,7 @@ React keys must be passed directly to JSX without using spread:
33
33
  yy = yy.length === 4 ? yy.slice(2) : yy.slice(0, 2);
34
34
  el.value = mm.length < 2 || (deleting && !yy && raw.slice(-2) !== '/ ') ? mm : mm + ' / ' + yy;
35
35
  });
36
- });`;function cG(W){return $.jsxDEV("div",{className:"pay",children:[$.jsxDEV("section",{className:"pay-summary",children:[W.back?$.jsxDEV("a",{className:"pay-back",href:W.back.href,children:W.back.label},void 0,!1,void 0,this):null,$.jsxDEV("div",{className:"pay-merchant",children:W.merchant},void 0,!1,void 0,this),W.total?$.jsxDEV("div",{className:"pay-total-lead",children:[$.jsxDEV("span",{children:W.total.label},void 0,!1,void 0,this),$.jsxDEV("strong",{children:W.total.amount},void 0,!1,void 0,this),W.total.detail?$.jsxDEV("small",{className:"pay-total-detail",children:W.total.detail},void 0,!1,void 0,this):null]},void 0,!0,void 0,this):null,$.jsxDEV("ul",{className:"pay-lines",children:W.lines.map((J,L)=>$.jsxDEV("li",{className:"pay-line",children:[$.jsxDEV("span",{className:"pay-line-name",children:[J.name,J.detail?$.jsxDEV("small",{children:J.detail},void 0,!1,void 0,this):null]},void 0,!0,void 0,this),$.jsxDEV("span",{className:"pay-line-amount",children:J.amount},void 0,!1,void 0,this)]},`${J.name}:${L}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.jsxDEV("main",{className:"pay-form",children:[$.jsxDEV("form",{method:"post",action:W.action,children:[W.sections.map((J)=>$.jsxDEV("fieldset",{className:"pay-section",children:[$.jsxDEV("legend",{children:J.heading},void 0,!1,void 0,this),J.fields.map((L)=>$.jsxDEV("label",{className:"pay-field",htmlFor:L.id,children:[$.jsxDEV("span",{children:L.label},void 0,!1,void 0,this),L.options?$.jsxDEV("select",{id:L.id,name:L.id,defaultValue:L.value,children:L.options.map((F)=>$.jsxDEV("option",{value:F.value,children:F.label},F.value,!1,void 0,this))},void 0,!1,void 0,this):$.jsxDEV("input",{id:L.id,name:L.id,type:L.type??"text",placeholder:L.placeholder,autoComplete:L.autoComplete,defaultValue:L.value,...L.format?{"data-format":L.format,inputMode:"numeric"}:{}},void 0,!1,void 0,this)]},L.id,!0,void 0,this))]},J.heading,!0,void 0,this)),W.error?$.jsxDEV("p",{className:"pay-error",role:"alert",children:W.error},void 0,!1,void 0,this):null,$.jsxDEV("button",{type:"submit",className:"pay-submit SubmitButton","data-testid":W.submit.testId,children:W.submit.label},void 0,!1,void 0,this),W.note?$.jsxDEV("p",{className:"pay-note",children:W.note},void 0,!1,void 0,this):null]},void 0,!0,void 0,this),W.sections.some((J)=>J.fields.some((L)=>L.format))?$.jsxDEV("script",{dangerouslySetInnerHTML:{__html:`document.querySelectorAll('input[data-format="card-expiry"]').forEach(function (el) {
36
+ });`;function cG(W){return $.jsxDEV("div",{className:"pay",children:[$.jsxDEV("section",{className:"pay-summary",children:[W.back?$.jsxDEV("a",{className:"pay-back",href:W.back.href,children:W.back.label},void 0,!1,void 0,this):null,$.jsxDEV("div",{className:"pay-merchant",children:W.merchant},void 0,!1,void 0,this),W.total?$.jsxDEV("div",{className:"pay-total-lead",children:[$.jsxDEV("span",{children:W.total.label},void 0,!1,void 0,this),$.jsxDEV("strong",{children:W.total.amount},void 0,!1,void 0,this),W.total.detail?$.jsxDEV("small",{className:"pay-total-detail",children:W.total.detail},void 0,!1,void 0,this):null]},void 0,!0,void 0,this):null,$.jsxDEV("ul",{className:"pay-lines",children:W.lines.map((J,L)=>$.jsxDEV("li",{className:"pay-line",children:[$.jsxDEV("span",{className:"pay-line-name",children:[J.name,J.detail?$.jsxDEV("small",{children:J.detail},void 0,!1,void 0,this):null]},void 0,!0,void 0,this),$.jsxDEV("span",{className:"pay-line-amount",children:J.amount},void 0,!1,void 0,this)]},`${J.name}:${L}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.jsxDEV("main",{className:"pay-form",children:[$.jsxDEV("form",{method:"post",action:W.action,children:[W.sections.map((J)=>$.jsxDEV("fieldset",{className:"pay-section",children:[$.jsxDEV("legend",{children:J.heading},void 0,!1,void 0,this),J.fields.map((L)=>$.jsxDEV("label",{className:"pay-field",htmlFor:L.id,children:[$.jsxDEV("span",{children:L.label},void 0,!1,void 0,this),L.options?$.jsxDEV("select",{id:L.id,name:L.id,defaultValue:L.value,children:L.options.map((F)=>$.jsxDEV("option",{value:F.value,children:F.label},F.value,!1,void 0,this))},void 0,!1,void 0,this):$.jsxDEV("input",{id:L.id,name:L.id,type:L.type??"text",placeholder:L.placeholder,autoComplete:L.autoComplete,defaultValue:L.value,...L.format?{"data-format":L.format,inputMode:"numeric"}:{},...L.readOnly?{readOnly:!0}:{}},void 0,!1,void 0,this)]},L.id,!0,void 0,this))]},J.heading,!0,void 0,this)),W.error?$.jsxDEV("p",{className:"pay-error",role:"alert",children:W.error},void 0,!1,void 0,this):null,$.jsxDEV("button",{type:"submit",className:"pay-submit SubmitButton","data-testid":W.submit.testId,children:W.submit.label},void 0,!1,void 0,this),W.note?$.jsxDEV("p",{className:"pay-note",children:W.note},void 0,!1,void 0,this):null]},void 0,!0,void 0,this),W.sections.some((J)=>J.fields.some((L)=>L.format))?$.jsxDEV("script",{dangerouslySetInnerHTML:{__html:`document.querySelectorAll('input[data-format="card-expiry"]').forEach(function (el) {
37
37
  el.addEventListener('input', function (e) {
38
38
  var raw = el.value, deleting = typeof e.inputType === 'string' && e.inputType.indexOf('delete') === 0, mm, yy;
39
39
  var cut = raw.indexOf('/');
@@ -72,6 +72,7 @@ body { margin: 0; font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-seri
72
72
  .pay-field { display: block; margin-bottom: 12px; }
73
73
  .pay-field span { display: block; font-size: 13px; margin-bottom: 4px; }
74
74
  .pay-field input, .pay-field select { box-sizing: border-box; width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid; font: inherit; }
75
+ .pay-field input[readonly] { opacity: 0.7; }
75
76
  .pay-error { margin: 0 0 12px; }
76
77
  .pay-submit { width: 100%; padding: 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer; }
77
78
  `;export{cG as Payment,pG as PAYMENT_CSS,yG as FORMAT_SCRIPT};
@@ -12,6 +12,8 @@ export type PaymentField = {
12
12
  /** a field that formats itself as it is typed, as payment vendors' card fields do: `card-expiry` reads the digits
13
13
  * `1230` as `12 / 30` (FORMAT_SCRIPT). The page still posts without a script; the pack reads what is posted. */
14
14
  format?: 'card-expiry';
15
+ /** a value the vendor already knows and the customer cannot change here (an email on file): shown, posted, not editable */
16
+ readOnly?: boolean;
15
17
  };
16
18
  export type PaymentProps = {
17
19
  merchant: string;
@@ -54,4 +56,4 @@ export type PaymentProps = {
54
56
  export declare const FORMAT_SCRIPT = "document.querySelectorAll('input[data-format=\"card-expiry\"]').forEach(function (el) {\n el.addEventListener('input', function (e) {\n var raw = el.value, deleting = typeof e.inputType === 'string' && e.inputType.indexOf('delete') === 0, mm, yy;\n var cut = raw.indexOf('/');\n if (cut >= 0) {\n mm = raw.slice(0, cut).replace(/\\D/g, '').slice(0, 2);\n yy = raw.slice(cut + 1).replace(/\\D/g, '');\n if (mm.length === 1 && mm !== '0') mm = '0' + mm;\n } else {\n var d = raw.replace(/\\D/g, '');\n if (d.length === 6 && d.slice(2, 4) === '20') d = d.slice(0, 2) + d.slice(4);\n if (d.length >= 1 && d.charAt(0) > '1') d = '0' + d;\n mm = d.slice(0, 2);\n yy = d.slice(2);\n }\n yy = yy.length === 4 ? yy.slice(2) : yy.slice(0, 2);\n el.value = mm.length < 2 || (deleting && !yy && raw.slice(-2) !== '/ ') ? mm : mm + ' / ' + yy;\n });\n});";
55
57
  export declare function Payment(props: PaymentProps): import("react").JSX.Element;
56
58
  /** The payment page's layout; a pack's skin sets the colours and type over it. */
57
- export declare const PAYMENT_CSS = "\nbody { margin: 0; font: 14px/1.5 system-ui, -apple-system, \"Segoe UI\", sans-serif; }\n.pay { display: grid; grid-template-columns: 1fr 1fr; min-height: 100vh; }\n@media (max-width: 800px) { .pay { grid-template-columns: 1fr; } }\n.pay-summary { padding: 48px 48px 24px; }\n.pay-back { display: inline-block; margin-bottom: 24px; text-decoration: none; }\n.pay-merchant { font-weight: 500; margin-bottom: 16px; }\n.pay-total-lead span { display: block; }\n.pay-total-lead strong { display: block; font-size: 36px; font-weight: 600; }\n.pay-total-lead { margin-bottom: 24px; }\n.pay-total-detail { display: block; }\n.pay-note { margin: 12px 0 0; font-size: 13px; text-align: center; }\n.pay-lines { list-style: none; padding: 0; margin: 0; }\n.pay-line { display: flex; justify-content: space-between; padding: 8px 0; }\n.pay-line small { display: block; }\n.pay-form { padding: 48px; }\n.pay-section { border: 0; padding: 0; margin: 0 0 24px; }\n.pay-section legend { font-weight: 500; margin-bottom: 8px; }\n.pay-field { display: block; margin-bottom: 12px; }\n.pay-field span { display: block; font-size: 13px; margin-bottom: 4px; }\n.pay-field input, .pay-field select { box-sizing: border-box; width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid; font: inherit; }\n.pay-error { margin: 0 0 12px; }\n.pay-submit { width: 100%; padding: 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer; }\n";
59
+ export declare const PAYMENT_CSS = "\nbody { margin: 0; font: 14px/1.5 system-ui, -apple-system, \"Segoe UI\", sans-serif; }\n.pay { display: grid; grid-template-columns: 1fr 1fr; min-height: 100vh; }\n@media (max-width: 800px) { .pay { grid-template-columns: 1fr; } }\n.pay-summary { padding: 48px 48px 24px; }\n.pay-back { display: inline-block; margin-bottom: 24px; text-decoration: none; }\n.pay-merchant { font-weight: 500; margin-bottom: 16px; }\n.pay-total-lead span { display: block; }\n.pay-total-lead strong { display: block; font-size: 36px; font-weight: 600; }\n.pay-total-lead { margin-bottom: 24px; }\n.pay-total-detail { display: block; }\n.pay-note { margin: 12px 0 0; font-size: 13px; text-align: center; }\n.pay-lines { list-style: none; padding: 0; margin: 0; }\n.pay-line { display: flex; justify-content: space-between; padding: 8px 0; }\n.pay-line small { display: block; }\n.pay-form { padding: 48px; }\n.pay-section { border: 0; padding: 0; margin: 0 0 24px; }\n.pay-section legend { font-weight: 500; margin-bottom: 8px; }\n.pay-field { display: block; margin-bottom: 12px; }\n.pay-field span { display: block; font-size: 13px; margin-bottom: 4px; }\n.pay-field input, .pay-field select { box-sizing: border-box; width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid; font: inherit; }\n.pay-field input[readonly] { opacity: 0.7; }\n.pay-error { margin: 0 0 12px; }\n.pay-submit { width: 100%; padding: 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer; }\n";
@@ -26,7 +26,7 @@ export const FORMAT_SCRIPT = `document.querySelectorAll('input[data-format="card
26
26
  export function Payment(props) {
27
27
  return (_jsxs("div", { className: "pay", children: [_jsxs("section", { className: "pay-summary", children: [props.back ? _jsx("a", { className: "pay-back", href: props.back.href, children: props.back.label }) : null, _jsx("div", { className: "pay-merchant", children: props.merchant }), props.total ? _jsxs("div", { className: "pay-total-lead", children: [_jsx("span", { children: props.total.label }), _jsx("strong", { children: props.total.amount }), props.total.detail ? _jsx("small", { className: "pay-total-detail", children: props.total.detail }) : null] }) : null, _jsx("ul", { className: "pay-lines", children: props.lines.map((l, i) => (_jsxs("li", { className: "pay-line", children: [_jsxs("span", { className: "pay-line-name", children: [l.name, l.detail ? _jsx("small", { children: l.detail }) : null] }), _jsx("span", { className: "pay-line-amount", children: l.amount })] }, `${l.name}:${i}`))) })] }), _jsxs("main", { className: "pay-form", children: [_jsxs("form", { method: "post", action: props.action, children: [props.sections.map((s) => (_jsxs("fieldset", { className: "pay-section", children: [_jsx("legend", { children: s.heading }), s.fields.map((f) => (_jsxs("label", { className: "pay-field", htmlFor: f.id, children: [_jsx("span", { children: f.label }), f.options
28
28
  ? _jsx("select", { id: f.id, name: f.id, defaultValue: f.value, children: f.options.map((o) => _jsx("option", { value: o.value, children: o.label }, o.value)) })
29
- : _jsx("input", { id: f.id, name: f.id, type: f.type ?? 'text', placeholder: f.placeholder, autoComplete: f.autoComplete, defaultValue: f.value, ...(f.format ? { 'data-format': f.format, inputMode: 'numeric' } : {}) })] }, f.id)))] }, s.heading))), props.error ? _jsx("p", { className: "pay-error", role: "alert", children: props.error }) : null, _jsx("button", { type: "submit", className: "pay-submit SubmitButton", "data-testid": props.submit.testId, children: props.submit.label }), props.note ? _jsx("p", { className: "pay-note", children: props.note }) : null] }), props.sections.some((s) => s.fields.some((f) => f.format)) ? _jsx("script", { dangerouslySetInnerHTML: { __html: FORMAT_SCRIPT } }) : null] })] }));
29
+ : _jsx("input", { id: f.id, name: f.id, type: f.type ?? 'text', placeholder: f.placeholder, autoComplete: f.autoComplete, defaultValue: f.value, ...(f.format ? { 'data-format': f.format, inputMode: 'numeric' } : {}), ...(f.readOnly ? { readOnly: true } : {}) })] }, f.id)))] }, s.heading))), props.error ? _jsx("p", { className: "pay-error", role: "alert", children: props.error }) : null, _jsx("button", { type: "submit", className: "pay-submit SubmitButton", "data-testid": props.submit.testId, children: props.submit.label }), props.note ? _jsx("p", { className: "pay-note", children: props.note }) : null] }), props.sections.some((s) => s.fields.some((f) => f.format)) ? _jsx("script", { dangerouslySetInnerHTML: { __html: FORMAT_SCRIPT } }) : null] })] }));
30
30
  }
31
31
  /** The payment page's layout; a pack's skin sets the colours and type over it. */
32
32
  export const PAYMENT_CSS = `
@@ -50,6 +50,7 @@ body { margin: 0; font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-seri
50
50
  .pay-field { display: block; margin-bottom: 12px; }
51
51
  .pay-field span { display: block; font-size: 13px; margin-bottom: 4px; }
52
52
  .pay-field input, .pay-field select { box-sizing: border-box; width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid; font: inherit; }
53
+ .pay-field input[readonly] { opacity: 0.7; }
53
54
  .pay-error { margin: 0 0 12px; }
54
55
  .pay-submit { width: 100%; padding: 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer; }
55
56
  `;
@@ -9,6 +9,8 @@ export type PaymentField = {
9
9
  /** a field that formats itself as it is typed, as payment vendors' card fields do: `card-expiry` reads the digits
10
10
  * `1230` as `12 / 30` (FORMAT_SCRIPT). The page still posts without a script; the pack reads what is posted. */
11
11
  format?: 'card-expiry';
12
+ /** a value the vendor already knows and the customer cannot change here (an email on file): shown, posted, not editable */
13
+ readOnly?: boolean;
12
14
  };
13
15
 
14
16
  export type PaymentProps = {
@@ -79,7 +81,7 @@ export function Payment(props: PaymentProps) {
79
81
  <span>{f.label}</span>
80
82
  {f.options
81
83
  ? <select id={f.id} name={f.id} defaultValue={f.value}>{f.options.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}</select>
82
- : <input id={f.id} name={f.id} type={f.type ?? 'text'} placeholder={f.placeholder} autoComplete={f.autoComplete} defaultValue={f.value} {...(f.format ? { 'data-format': f.format, inputMode: 'numeric' as const } : {})} />}
84
+ : <input id={f.id} name={f.id} type={f.type ?? 'text'} placeholder={f.placeholder} autoComplete={f.autoComplete} defaultValue={f.value} {...(f.format ? { 'data-format': f.format, inputMode: 'numeric' as const } : {})} {...(f.readOnly ? { readOnly: true } : {})} />}
83
85
  </label>
84
86
  ))}
85
87
  </fieldset>
@@ -116,6 +118,7 @@ body { margin: 0; font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-seri
116
118
  .pay-field { display: block; margin-bottom: 12px; }
117
119
  .pay-field span { display: block; font-size: 13px; margin-bottom: 4px; }
118
120
  .pay-field input, .pay-field select { box-sizing: border-box; width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid; font: inherit; }
121
+ .pay-field input[readonly] { opacity: 0.7; }
119
122
  .pay-error { margin: 0 0 12px; }
120
123
  .pay-submit { width: 100%; padding: 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer; }
121
124
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/world-ui",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Shared pieces and serving for derived packs' screens (hosted flows and workspaces), through each pack's own API; see docs/contributing/architecture.md, Screens.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Volter (https://github.com/volter-ai)",
@@ -29,7 +29,7 @@
29
29
  "dist"
30
30
  ],
31
31
  "peerDependencies": {
32
- "@volter/world-core": "2.0.0",
32
+ "@volter/world-core": "2.0.1",
33
33
  "react": "^19.2.7",
34
34
  "react-dom": "^19.2.7"
35
35
  },