@ebitex/forms-sdk 0.6.133 → 0.6.135
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/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lookup.d.ts +16 -0
- package/dist/lookup.d.ts.map +1 -0
- package/dist/lookup.js +34 -0
- package/dist/lookup.js.map +1 -0
- package/dist/nodes.d.ts +8 -0
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +20 -0
- package/dist/nodes.js.map +1 -1
- package/dist/react/EbitexForm.d.ts +8 -2
- package/dist/react/EbitexForm.d.ts.map +1 -1
- package/dist/react/EbitexForm.js +12 -9
- package/dist/react/EbitexForm.js.map +1 -1
- package/dist/react/LookupField.d.ts +19 -0
- package/dist/react/LookupField.d.ts.map +1 -0
- package/dist/react/LookupField.js +207 -0
- package/dist/react/LookupField.js.map +1 -0
- package/dist/react/NodeList.d.ts +4 -2
- package/dist/react/NodeList.d.ts.map +1 -1
- package/dist/react/NodeList.js +7 -5
- package/dist/react/NodeList.js.map +1 -1
- package/dist/react/fields.d.ts +15 -3
- package/dist/react/fields.d.ts.map +1 -1
- package/dist/react/fields.js +6 -1
- package/dist/react/fields.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/styles.css +136 -0
- package/dist/types.d.ts +31 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -1
- package/dist/types.js.map +1 -1
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +22 -1
- package/dist/validators.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export { createFormsClient, FormsApiError, type FormsClient, type FormsClientOpt
|
|
|
11
11
|
export { validateSubmission, type ValidateOptions } from './validators.js';
|
|
12
12
|
export { isAllOfSatisfied, isFieldComparisonSatisfied, isSatisfied } from './predicates.js';
|
|
13
13
|
export { deriveDarkVariant } from './theme.js';
|
|
14
|
-
export { adjacentVisibleStepSlot, collectDataFields, defaultChoiceValues, isDataField, isFormField, resolveSteps, resolveVariant, resolveVisibleStepSlot, } from './nodes.js';
|
|
15
|
-
export { type AllOfPredicate, type ButtonField, type ButtonType, type ChoiceField, type ChoiceOption, type ChoiceType, type FieldComparisonOperator, type FieldComparisonPredicate, type FieldsetNode, type FormField, type FormNode, type FormStep, type InputField, type InputVariant, type NumberField, type RowNode, type SdkForm, type SubmissionData, type TextareaField, type ValidationErrors, type VariantBranch, type VariantNode, type VariantPredicate, } from './types.js';
|
|
14
|
+
export { adjacentVisibleStepSlot, collectDataFields, defaultChoiceValues, isDataField, collectSubmissionKeys, isFormField, resolveSteps, resolveVariant, resolveVisibleStepSlot, } from './nodes.js';
|
|
15
|
+
export { type AllOfPredicate, type ButtonField, type ButtonType, type ChoiceField, type ChoiceOption, type ChoiceType, type FieldComparisonOperator, type FieldComparisonPredicate, type FieldsetNode, type FormField, type FormNode, type FormStep, type InputField, type InputVariant, type LookupSource, type NumberField, type RowNode, type SdkForm, type SubmissionData, type TextareaField, type ValidationErrors, type VariantBranch, type VariantNode, type VariantPredicate, } from './types.js';
|
|
16
|
+
export { LOOKUP_COMPANION_SUFFIX, MAX_LOOKUP_VALUE_LENGTH } from './types.js';
|
|
17
|
+
export { createPublicLookupSource, lookupUrlFromSubmissionUrl } from './lookup.js';
|
|
16
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAE7E,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,8 @@ export { createFormsClient, FormsApiError, } from './client.js';
|
|
|
11
11
|
export { validateSubmission } from './validators.js';
|
|
12
12
|
export { isAllOfSatisfied, isFieldComparisonSatisfied, isSatisfied } from './predicates.js';
|
|
13
13
|
export { deriveDarkVariant } from './theme.js';
|
|
14
|
-
export { adjacentVisibleStepSlot, collectDataFields, defaultChoiceValues, isDataField, isFormField, resolveSteps, resolveVariant, resolveVisibleStepSlot, } from './nodes.js';
|
|
14
|
+
export { adjacentVisibleStepSlot, collectDataFields, defaultChoiceValues, isDataField, collectSubmissionKeys, isFormField, resolveSteps, resolveVariant, resolveVisibleStepSlot, } from './nodes.js';
|
|
15
15
|
export {} from './types.js';
|
|
16
|
+
export { LOOKUP_COMPANION_SUFFIX, MAX_LOOKUP_VALUE_LENGTH } from './types.js';
|
|
17
|
+
export { createPublicLookupSource, lookupUrlFromSubmissionUrl } from './lookup.js';
|
|
16
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,iBAAiB,EACjB,aAAa,GAGd,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,kBAAkB,EAAwB,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAA;AAEnB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,iBAAiB,EACjB,aAAa,GAGd,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,kBAAkB,EAAwB,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAyBN,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAE7E,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/lookup.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LookupSource } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A `LookupSource` that searches through a form's public lookup endpoint: a `POST` of the field's key and
|
|
4
|
+
* what was typed, answered with `{ options: [{ value, label }] }`. A `POST` for the reason the submission
|
|
5
|
+
* is one: a respondent's text does not belong in a URL, a log line or a `Referer` header.
|
|
6
|
+
*
|
|
7
|
+
* Needs no API key and runs in a browser. It rejects when the request is refused or fails, which is how a
|
|
8
|
+
* `Lookup` field learns to fall back to a plain text input; it never returns a partial answer.
|
|
9
|
+
*
|
|
10
|
+
* @param url The lookup endpoint. For a form fetched with this package it is `submissionUrl` with
|
|
11
|
+
* `/submissions` replaced by `/lookup`; see {@link lookupUrlFromSubmissionUrl}.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createPublicLookupSource(url: string, doFetch?: typeof globalThis.fetch): LookupSource;
|
|
14
|
+
/** The lookup endpoint that sits beside a form's public submission endpoint, or `undefined` for an address of another shape. */
|
|
15
|
+
export declare function lookupUrlFromSubmissionUrl(submissionUrl: string): string | undefined;
|
|
16
|
+
//# sourceMappingURL=lookup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../src/lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,YAAY,EAAE,MAAM,YAAY,CAAA;AAE5D;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,OAAO,UAAU,CAAC,KAAwB,GAAG,YAAY,CAevH;AAED,gIAAgI;AAChI,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGpF"}
|
package/dist/lookup.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A `LookupSource` that searches through a form's public lookup endpoint: a `POST` of the field's key and
|
|
3
|
+
* what was typed, answered with `{ options: [{ value, label }] }`. A `POST` for the reason the submission
|
|
4
|
+
* is one: a respondent's text does not belong in a URL, a log line or a `Referer` header.
|
|
5
|
+
*
|
|
6
|
+
* Needs no API key and runs in a browser. It rejects when the request is refused or fails, which is how a
|
|
7
|
+
* `Lookup` field learns to fall back to a plain text input; it never returns a partial answer.
|
|
8
|
+
*
|
|
9
|
+
* @param url The lookup endpoint. For a form fetched with this package it is `submissionUrl` with
|
|
10
|
+
* `/submissions` replaced by `/lookup`; see {@link lookupUrlFromSubmissionUrl}.
|
|
11
|
+
*/
|
|
12
|
+
export function createPublicLookupSource(url, doFetch = globalThis.fetch) {
|
|
13
|
+
return {
|
|
14
|
+
async search(field, query, signal) {
|
|
15
|
+
const response = await doFetch(url, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
headers: { 'Content-Type': 'application/json' },
|
|
18
|
+
body: JSON.stringify({ field, query }),
|
|
19
|
+
signal,
|
|
20
|
+
});
|
|
21
|
+
// A refusal (a limit, a missing field) is not an answer: reject, so the field becomes a plain input.
|
|
22
|
+
if (!response.ok)
|
|
23
|
+
throw new Error(`Lookup failed with ${response.status}.`);
|
|
24
|
+
const body = (await response.json());
|
|
25
|
+
return Array.isArray(body.options) ? body.options : [];
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** The lookup endpoint that sits beside a form's public submission endpoint, or `undefined` for an address of another shape. */
|
|
30
|
+
export function lookupUrlFromSubmissionUrl(submissionUrl) {
|
|
31
|
+
const suffix = '/submissions';
|
|
32
|
+
return submissionUrl.endsWith(suffix) ? `${submissionUrl.slice(0, -suffix.length)}/lookup` : undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../src/lookup.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAW,EAAE,UAAmC,UAAU,CAAC,KAAK;IACvG,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM;YAC/B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;gBAClC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;gBACtC,MAAM;aACP,CAAC,CAAA;YACF,qGAAqG;YACrG,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;YAC3E,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAiC,CAAA;YACpE,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;QACxD,CAAC;KACF,CAAA;AACH,CAAC;AAED,gIAAgI;AAChI,MAAM,UAAU,0BAA0B,CAAC,aAAqB;IAC9D,MAAM,MAAM,GAAG,cAAc,CAAA;IAC7B,OAAO,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;AACxG,CAAC"}
|
package/dist/nodes.d.ts
CHANGED
|
@@ -21,6 +21,14 @@ export declare function resolveVariant(variant: VariantNode, data: SubmissionDat
|
|
|
21
21
|
* resolve as if nothing had been answered, which is only sometimes what a caller wants).
|
|
22
22
|
*/
|
|
23
23
|
export declare function collectDataFields(nodes: FormNode[], data: SubmissionData): (InputField | TextareaField | NumberField | ChoiceField)[];
|
|
24
|
+
/**
|
|
25
|
+
* Every key a respondent's current view of `nodes` may submit: each visible field's own key, plus, for a
|
|
26
|
+
* `Lookup`, its `<key>-existing` companion. Use this, not the keys of `collectDataFields` alone, wherever
|
|
27
|
+
* a payload is pruned to what is visible or a validation error is scoped to a step: the companion is not a
|
|
28
|
+
* field, so a list built from fields alone would quietly drop it and the server would never learn whether
|
|
29
|
+
* the answer was picked or typed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function collectSubmissionKeys(nodes: FormNode[], data: SubmissionData): Set<string>;
|
|
24
32
|
/**
|
|
25
33
|
* Which of `steps` the respondent currently sees, given their answers so far — the Step-level
|
|
26
34
|
* counterpart to `resolveVariant`. A step's own `when` may
|
package/dist/nodes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAA;AAEnB,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,IAAI,SAAS,CAE7D;AAED,wGAAwG;AACxG,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,GACb,IAAI,IAAI,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAEhE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,GAAG,QAAQ,EAAE,CAQrF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,EAAE,EACjB,IAAI,EAAE,cAAc,GACnB,CAAC,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC,EAAE,CAc5D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAW1F;AAMD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,QAAQ,EAAE,CAEhF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQpG;AAED,yHAAyH;AACzH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAKxH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,cAAc,CAcrE"}
|
package/dist/nodes.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isSatisfied } from './predicates.js';
|
|
2
|
+
import { LOOKUP_COMPANION_SUFFIX } from './types.js';
|
|
2
3
|
export function isFormField(node) {
|
|
3
4
|
return node.nodeType === 'Field';
|
|
4
5
|
}
|
|
@@ -46,6 +47,25 @@ export function collectDataFields(nodes, data) {
|
|
|
46
47
|
}
|
|
47
48
|
return result;
|
|
48
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Every key a respondent's current view of `nodes` may submit: each visible field's own key, plus, for a
|
|
52
|
+
* `Lookup`, its `<key>-existing` companion. Use this, not the keys of `collectDataFields` alone, wherever
|
|
53
|
+
* a payload is pruned to what is visible or a validation error is scoped to a step: the companion is not a
|
|
54
|
+
* field, so a list built from fields alone would quietly drop it and the server would never learn whether
|
|
55
|
+
* the answer was picked or typed.
|
|
56
|
+
*/
|
|
57
|
+
export function collectSubmissionKeys(nodes, data) {
|
|
58
|
+
const keys = new Set();
|
|
59
|
+
for (const field of collectDataFields(nodes, data)) {
|
|
60
|
+
if (field.submissionKey === undefined)
|
|
61
|
+
continue;
|
|
62
|
+
keys.add(field.submissionKey);
|
|
63
|
+
if (field.fieldType === 'Choice' && field.choiceType === 'Lookup') {
|
|
64
|
+
keys.add(`${field.submissionKey}${LOOKUP_COMPANION_SUFFIX}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return keys;
|
|
68
|
+
}
|
|
49
69
|
function isStepVisible(step, data) {
|
|
50
70
|
return step.when === undefined || isSatisfied(step.when, data);
|
|
51
71
|
}
|
package/dist/nodes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.js","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"nodes.js","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CSSProperties } from 'react';
|
|
2
|
-
import type { SdkForm, SubmissionData } from '../types.js';
|
|
2
|
+
import type { LookupSource, SdkForm, SubmissionData } from '../types.js';
|
|
3
3
|
import type { FieldComponents } from './fields.js';
|
|
4
4
|
export interface EbitexFormProps {
|
|
5
5
|
/** A form definition from `createFormsClient(...).getForm(...)`, fetched on your server. */
|
|
@@ -16,6 +16,12 @@ export interface EbitexFormProps {
|
|
|
16
16
|
* `Input` alone and your Choice fields still render normally.
|
|
17
17
|
*/
|
|
18
18
|
fieldComponents?: FieldComponents;
|
|
19
|
+
/**
|
|
20
|
+
* Where a `Lookup` field searches its options. Defaults to the form's own public lookup endpoint,
|
|
21
|
+
* derived from `submissionUrl`, so an embedded form needs nothing here; pass one to route searches
|
|
22
|
+
* through your own server or to fake them in a test.
|
|
23
|
+
*/
|
|
24
|
+
lookup?: LookupSource;
|
|
19
25
|
/** Injectable for tests and non-standard runtimes. */
|
|
20
26
|
fetch?: typeof globalThis.fetch;
|
|
21
27
|
}
|
|
@@ -32,5 +38,5 @@ export interface EbitexFormProps {
|
|
|
32
38
|
* isn't lost — matching the behaviour of ebitex's own renderer rather than a simplified
|
|
33
39
|
* client-only notion of steps.
|
|
34
40
|
*/
|
|
35
|
-
export declare function EbitexForm({ form, onSubmitted, onError, className, style, fieldComponents, fetch: injectedFetch, }: EbitexFormProps): import("react").JSX.Element | null;
|
|
41
|
+
export declare function EbitexForm({ form, onSubmitted, onError, className, style, fieldComponents, lookup, fetch: injectedFetch, }: EbitexFormProps): import("react").JSX.Element | null;
|
|
36
42
|
//# sourceMappingURL=EbitexForm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EbitexForm.d.ts","sourceRoot":"","sources":["../../src/react/EbitexForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"EbitexForm.d.ts","sourceRoot":"","sources":["../../src/react/EbitexForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,OAAO,CAAA;AAGpE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAA;AAE1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIlD,MAAM,WAAW,eAAe;IAC9B,4FAA4F;IAC5F,IAAI,EAAE,OAAO,CAAA;IAEb,kDAAkD;IAClD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAA;IAE5C,wGAAwG;IACxG,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAElC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;IAErB;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;IAEjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAA;IAErB,sDAAsD;IACtD,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAChC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,WAAW,EACX,OAAO,EACP,SAAS,EACT,KAAK,EACL,eAAe,EACf,MAAM,EACN,KAAK,EAAE,aAAa,GACrB,EAAE,eAAe,sCA6NjB"}
|
package/dist/react/EbitexForm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useId, useMemo, useState } from 'react';
|
|
3
|
-
import { adjacentVisibleStepSlot,
|
|
3
|
+
import { adjacentVisibleStepSlot, collectSubmissionKeys, defaultChoiceValues, resolveSteps, resolveVisibleStepSlot } from '../nodes.js';
|
|
4
|
+
import { createPublicLookupSource, lookupUrlFromSubmissionUrl } from '../lookup.js';
|
|
4
5
|
import { validateSubmission } from '../validators.js';
|
|
5
6
|
import { ActionButtons, NodeList, joinClassNames } from './NodeList.js';
|
|
6
7
|
import { getOrCreateVisitorId } from './visitorId.js';
|
|
@@ -17,9 +18,15 @@ import { getOrCreateVisitorId } from './visitorId.js';
|
|
|
17
18
|
* isn't lost — matching the behaviour of ebitex's own renderer rather than a simplified
|
|
18
19
|
* client-only notion of steps.
|
|
19
20
|
*/
|
|
20
|
-
export function EbitexForm({ form, onSubmitted, onError, className, style, fieldComponents, fetch: injectedFetch, }) {
|
|
21
|
+
export function EbitexForm({ form, onSubmitted, onError, className, style, fieldComponents, lookup, fetch: injectedFetch, }) {
|
|
21
22
|
const baseId = useId();
|
|
22
23
|
const doFetch = injectedFetch ?? globalThis.fetch;
|
|
24
|
+
const lookupSource = useMemo(() => {
|
|
25
|
+
if (lookup)
|
|
26
|
+
return lookup;
|
|
27
|
+
const url = lookupUrlFromSubmissionUrl(form.submissionUrl);
|
|
28
|
+
return url === undefined ? undefined : createPublicLookupSource(url, doFetch);
|
|
29
|
+
}, [lookup, form.submissionUrl, doFetch]);
|
|
23
30
|
// An index into the *original*, unfiltered `steps` array (a "slot"), not into the answers-aware
|
|
24
31
|
// visible-step list — a step's visibility can flip as `data` changes (spec 116-conditional-steps),
|
|
25
32
|
// and a slot stays a stable reference to "the step the respondent is conceptually at" across that
|
|
@@ -51,9 +58,7 @@ export function EbitexForm({ form, onSubmitted, onError, className, style, field
|
|
|
51
58
|
* report errors for fields the respondent hasn't reached yet.
|
|
52
59
|
*/
|
|
53
60
|
function validateCurrentStep(requireAll) {
|
|
54
|
-
const stepKeys =
|
|
55
|
-
.map((field) => field.submissionKey)
|
|
56
|
-
.filter((key) => key !== undefined));
|
|
61
|
+
const stepKeys = collectSubmissionKeys(step.nodes, data);
|
|
57
62
|
const all = validateSubmission(form, visiblePayload(), { requireAll });
|
|
58
63
|
return Object.fromEntries(Object.entries(all).filter(([key]) => stepKeys.has(key)));
|
|
59
64
|
}
|
|
@@ -76,9 +81,7 @@ export function EbitexForm({ form, onSubmitted, onError, className, style, field
|
|
|
76
81
|
// itself still holds them — the same retain-but-suppress posture this function already gives
|
|
77
82
|
// hidden Variant branches, one level up.
|
|
78
83
|
const allNodes = resolveSteps(steps, data).flatMap((s) => s.nodes);
|
|
79
|
-
const visibleKeys =
|
|
80
|
-
.map((field) => field.submissionKey)
|
|
81
|
-
.filter((key) => key !== undefined));
|
|
84
|
+
const visibleKeys = collectSubmissionKeys(allNodes, data);
|
|
82
85
|
return Object.fromEntries(Object.entries(data).filter(([key]) => visibleKeys.has(key)));
|
|
83
86
|
}
|
|
84
87
|
async function save(complete) {
|
|
@@ -148,7 +151,7 @@ export function EbitexForm({ form, onSubmitted, onError, className, style, field
|
|
|
148
151
|
else {
|
|
149
152
|
void advance();
|
|
150
153
|
}
|
|
151
|
-
}, children: [visibleSteps.length > 1 ? (_jsxs("p", { className: "ebitex-forms__step-indicator", role: "status", children: ["Step ", visibleStepPosition + 1, " of ", visibleSteps.length, step.label ? `: ${step.label}` : ''] })) : null, _jsx(NodeList, { nodes: step.nodes, baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, onChange: setValue }), _jsxs("div", { className: "ebitex-forms__actions", children: [hasPreviousStep ? (_jsx("button", { type: "button", className: "ebitex-forms__button ebitex-forms__button--secondary", disabled: submitting,
|
|
154
|
+
}, children: [visibleSteps.length > 1 ? (_jsxs("p", { className: "ebitex-forms__step-indicator", role: "status", children: ["Step ", visibleStepPosition + 1, " of ", visibleSteps.length, step.label ? `: ${step.label}` : ''] })) : null, _jsx(NodeList, { nodes: step.nodes, baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, lookup: lookupSource, onChange: setValue }), _jsxs("div", { className: "ebitex-forms__actions", children: [hasPreviousStep ? (_jsx("button", { type: "button", className: "ebitex-forms__button ebitex-forms__button--secondary", disabled: submitting,
|
|
152
155
|
// Deliberately does not re-save: going back is navigation, not a change.
|
|
153
156
|
onClick: () => {
|
|
154
157
|
const previous = adjacentVisibleStepSlot(steps, data, currentSlot, -1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EbitexForm.js","sourceRoot":"","sources":["../../src/react/EbitexForm.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAsB,MAAM,OAAO,CAAA;AACpE,OAAO,EAAE,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"EbitexForm.js","sourceRoot":"","sources":["../../src/react/EbitexForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ChoiceFieldComponentProps } from './fields.js';
|
|
2
|
+
/**
|
|
3
|
+
* The `Lookup` choice: a type-ahead over a source that is searched as the respondent types, with a
|
|
4
|
+
* "use what I typed" row for an answer the source does not have.
|
|
5
|
+
*
|
|
6
|
+
* It follows the ARIA 1.2 combobox pattern (an input with `role="combobox"` controlling a `listbox`,
|
|
7
|
+
* focus staying in the input and `aria-activedescendant` naming the highlighted option) and announces
|
|
8
|
+
* the result count through a polite live region.
|
|
9
|
+
*
|
|
10
|
+
* **It is always a usable text input.** With no `lookup` source (server rendering, a consumer who passes
|
|
11
|
+
* none) it is just an `<input name=…>`, and so is it when a search fails; the form still submits what was
|
|
12
|
+
* typed. Nothing here touches `window` while rendering, so it renders on a server and hydrates cleanly.
|
|
13
|
+
*
|
|
14
|
+
* What the form receives: the answer itself (the option's `value` when one was picked, otherwise the typed
|
|
15
|
+
* text) and `onExistingChange(true | false | null)` for the companion key (`true` picked, `false` typed,
|
|
16
|
+
* `null` empty). The latter is also written as a hidden input, so a native form submission carries it too.
|
|
17
|
+
*/
|
|
18
|
+
export declare function LookupFieldControl({ field, id, name, value, onChange, error, disabled, lookup, existing, onExistingChange, }: ChoiceFieldComponentProps): import("react").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=LookupField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LookupField.d.ts","sourceRoot":"","sources":["../../src/react/LookupField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAU5D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,EAAE,EACF,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAe,EACf,gBAAgB,GACjB,EAAE,yBAAyB,+BA4R3B"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
const DEBOUNCE_MS = 200;
|
|
4
|
+
const DEFAULT_MIN_QUERY_LENGTH = 2;
|
|
5
|
+
/**
|
|
6
|
+
* The `Lookup` choice: a type-ahead over a source that is searched as the respondent types, with a
|
|
7
|
+
* "use what I typed" row for an answer the source does not have.
|
|
8
|
+
*
|
|
9
|
+
* It follows the ARIA 1.2 combobox pattern (an input with `role="combobox"` controlling a `listbox`,
|
|
10
|
+
* focus staying in the input and `aria-activedescendant` naming the highlighted option) and announces
|
|
11
|
+
* the result count through a polite live region.
|
|
12
|
+
*
|
|
13
|
+
* **It is always a usable text input.** With no `lookup` source (server rendering, a consumer who passes
|
|
14
|
+
* none) it is just an `<input name=…>`, and so is it when a search fails; the form still submits what was
|
|
15
|
+
* typed. Nothing here touches `window` while rendering, so it renders on a server and hydrates cleanly.
|
|
16
|
+
*
|
|
17
|
+
* What the form receives: the answer itself (the option's `value` when one was picked, otherwise the typed
|
|
18
|
+
* text) and `onExistingChange(true | false | null)` for the companion key (`true` picked, `false` typed,
|
|
19
|
+
* `null` empty). The latter is also written as a hidden input, so a native form submission carries it too.
|
|
20
|
+
*/
|
|
21
|
+
export function LookupFieldControl({ field, id, name, value, onChange, error, disabled, lookup, existing = null, onExistingChange, }) {
|
|
22
|
+
const text = typeof value === 'string' ? value : '';
|
|
23
|
+
const listboxId = `${id}-listbox`;
|
|
24
|
+
const statusId = `${id}-status`;
|
|
25
|
+
const describedBy = [error !== null ? `${id}-error` : undefined, statusId].filter(Boolean).join(' ');
|
|
26
|
+
const minLength = Math.max(1, field.minQueryLength ?? DEFAULT_MIN_QUERY_LENGTH);
|
|
27
|
+
const [search, setSearch] = useState({ status: 'idle' });
|
|
28
|
+
const [open, setOpen] = useState(false);
|
|
29
|
+
const [active, setActive] = useState(0);
|
|
30
|
+
const [unavailable, setUnavailable] = useState(false);
|
|
31
|
+
// Whether the respondent chose the "use what I typed" row: shows the answer as a settled chip, like a picked one.
|
|
32
|
+
const [committedNew, setCommittedNew] = useState(false);
|
|
33
|
+
// The label of the option picked in this session (the answer itself is its `value`); lost across a reload, when the value shows instead.
|
|
34
|
+
const [pickedLabel, setPickedLabel] = useState(null);
|
|
35
|
+
const inputRef = useRef(null);
|
|
36
|
+
const changeRef = useRef(null);
|
|
37
|
+
const requestCount = useRef(0);
|
|
38
|
+
const abort = useRef(null);
|
|
39
|
+
// False on the server and on the very first client render, so what React hydrates is exactly what was
|
|
40
|
+
// server-rendered: a plain input. Attributes that differ are NOT patched up by hydration, so setting the
|
|
41
|
+
// combobox role and ARIA state on that first render would leave them off for good, and a screen reader
|
|
42
|
+
// would announce an ordinary text box. One effect later the control becomes the combobox.
|
|
43
|
+
const [hydrated, setHydrated] = useState(false);
|
|
44
|
+
useEffect(() => setHydrated(true), []);
|
|
45
|
+
const searchable = hydrated && lookup !== undefined && !unavailable && !disabled;
|
|
46
|
+
const settled = text !== '' && (existing === true || committedNew);
|
|
47
|
+
// Search shortly after typing stops. Superseded and unmounted searches are aborted, and a response
|
|
48
|
+
// from an earlier keystroke is never allowed to replace a later one.
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (lookup === undefined || !searchable || settled)
|
|
51
|
+
return undefined;
|
|
52
|
+
const query = text.trim();
|
|
53
|
+
if (query.length < minLength) {
|
|
54
|
+
abort.current?.abort();
|
|
55
|
+
setSearch({ status: 'idle' });
|
|
56
|
+
setOpen(false);
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const timer = setTimeout(() => {
|
|
60
|
+
abort.current?.abort();
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
abort.current = controller;
|
|
63
|
+
const mine = ++requestCount.current;
|
|
64
|
+
setSearch({ status: 'loading' });
|
|
65
|
+
lookup.search(name, query, controller.signal).then((options) => {
|
|
66
|
+
if (mine !== requestCount.current)
|
|
67
|
+
return;
|
|
68
|
+
const capped = options.slice(0, field.maxResults ?? options.length);
|
|
69
|
+
setSearch({ status: 'done', query, options: capped });
|
|
70
|
+
setActive(0);
|
|
71
|
+
setOpen(true);
|
|
72
|
+
}, (failure) => {
|
|
73
|
+
if (mine !== requestCount.current || (failure instanceof DOMException && failure.name === 'AbortError'))
|
|
74
|
+
return;
|
|
75
|
+
// The source is not answering: stop asking, and leave a plain text input to answer with.
|
|
76
|
+
setUnavailable(true);
|
|
77
|
+
setSearch({ status: 'idle' });
|
|
78
|
+
setOpen(false);
|
|
79
|
+
});
|
|
80
|
+
}, DEBOUNCE_MS);
|
|
81
|
+
return () => clearTimeout(timer);
|
|
82
|
+
// `lookup` is intentionally read, not depended on: a new function identity must not restart the search.
|
|
83
|
+
}, [text, searchable, settled, minLength, name, field.maxResults]);
|
|
84
|
+
useEffect(() => () => abort.current?.abort(), []);
|
|
85
|
+
const matches = search.status === 'done' ? search.options : [];
|
|
86
|
+
// One extra row after the matches for what was typed. It exists only while there is something typed to offer.
|
|
87
|
+
const newRowIndex = matches.length;
|
|
88
|
+
const rowCount = matches.length + 1;
|
|
89
|
+
const listVisible = open && search.status === 'done' && searchable && !settled;
|
|
90
|
+
function typed(next) {
|
|
91
|
+
setCommittedNew(false);
|
|
92
|
+
setPickedLabel(null);
|
|
93
|
+
onChange(next);
|
|
94
|
+
// Typing over a picked answer makes it the respondent's own text again. While suggestions are being
|
|
95
|
+
// offered the answer is still being decided, so the companion waits for a commit (a pick, the
|
|
96
|
+
// use-what-I-typed row, or leaving the field): reporting "typed" on the first keystroke would reveal
|
|
97
|
+
// the questions meant for a new entry, and shove the page down under the list, while the respondent is
|
|
98
|
+
// still looking for the existing one. With nothing to search it is simply the respondent's own text.
|
|
99
|
+
onExistingChange?.(next.trim() === '' ? null : searchable ? null : false);
|
|
100
|
+
}
|
|
101
|
+
function commitTyped() {
|
|
102
|
+
setOpen(false);
|
|
103
|
+
// Leaving the field with text that was not picked is the respondent's own answer.
|
|
104
|
+
if (searchable && text.trim() !== '' && existing === null)
|
|
105
|
+
onExistingChange?.(false);
|
|
106
|
+
}
|
|
107
|
+
function pick(index) {
|
|
108
|
+
if (index === newRowIndex) {
|
|
109
|
+
setCommittedNew(true);
|
|
110
|
+
setPickedLabel(null);
|
|
111
|
+
onExistingChange?.(false);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
const option = matches[index];
|
|
115
|
+
if (option === undefined)
|
|
116
|
+
return;
|
|
117
|
+
setCommittedNew(false);
|
|
118
|
+
setPickedLabel(option.label);
|
|
119
|
+
onChange(option.value);
|
|
120
|
+
onExistingChange?.(true);
|
|
121
|
+
}
|
|
122
|
+
setOpen(false);
|
|
123
|
+
// Focus moves to the control that now holds the answer, so a keyboard respondent is not left on a removed input.
|
|
124
|
+
queueMicrotask(() => changeRef.current?.focus());
|
|
125
|
+
}
|
|
126
|
+
function clear() {
|
|
127
|
+
setCommittedNew(false);
|
|
128
|
+
setPickedLabel(null);
|
|
129
|
+
onChange('');
|
|
130
|
+
onExistingChange?.(null);
|
|
131
|
+
setSearch({ status: 'idle' });
|
|
132
|
+
queueMicrotask(() => inputRef.current?.focus());
|
|
133
|
+
}
|
|
134
|
+
function onKeyDown(event) {
|
|
135
|
+
if (!listVisible)
|
|
136
|
+
return;
|
|
137
|
+
switch (event.key) {
|
|
138
|
+
case 'ArrowDown':
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
setActive((index) => (index + 1) % rowCount);
|
|
141
|
+
break;
|
|
142
|
+
case 'ArrowUp':
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
setActive((index) => (index - 1 + rowCount) % rowCount);
|
|
145
|
+
break;
|
|
146
|
+
case 'Home':
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
setActive(0);
|
|
149
|
+
break;
|
|
150
|
+
case 'End':
|
|
151
|
+
event.preventDefault();
|
|
152
|
+
setActive(rowCount - 1);
|
|
153
|
+
break;
|
|
154
|
+
case 'Enter':
|
|
155
|
+
event.preventDefault();
|
|
156
|
+
pick(active);
|
|
157
|
+
break;
|
|
158
|
+
case 'Escape':
|
|
159
|
+
event.preventDefault();
|
|
160
|
+
setOpen(false);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const announcement = unavailable
|
|
165
|
+
? 'Suggestions are not available right now. Type your answer and continue.'
|
|
166
|
+
: search.status === 'loading'
|
|
167
|
+
? 'Searching.'
|
|
168
|
+
: listVisible
|
|
169
|
+
? `${matches.length} ${matches.length === 1 ? 'match' : 'matches'}, plus the option to use what you typed.`
|
|
170
|
+
: '';
|
|
171
|
+
const hiddenExisting = existing === null ? null : _jsx("input", { type: "hidden", name: `${name}-existing`, value: existing ? 'true' : 'false' });
|
|
172
|
+
return (_jsxs("div", { className: "ebitex-forms__field ebitex-forms__lookup", children: [_jsxs("label", { className: "ebitex-forms__label", htmlFor: id, children: [field.label, field.required ? (_jsxs("span", { className: "ebitex-forms__required", "aria-hidden": "true", children: [' ', "*"] })) : null] }), settled ? (_jsxs("div", { className: joinLookupClasses('ebitex-forms__lookup-chip', existing === true ? undefined : 'ebitex-forms__lookup-chip--new'), children: [_jsxs("div", { children: [_jsx("strong", { id: id, children: pickedLabel ?? text }), _jsx("span", { className: "ebitex-forms__lookup-chip-note", children: existing === true ? 'Found in our records' : 'New entry' })] }), _jsx("button", { type: "button", ref: changeRef, className: "ebitex-forms__button ebitex-forms__button--secondary", disabled: disabled, "aria-describedby": id, onClick: clear, children: "Change" }), _jsx("input", { type: "hidden", name: name, value: text })] })) : (_jsxs("div", { className: "ebitex-forms__lookup-box", children: [_jsx("input", { ref: inputRef, className: "ebitex-forms__control", id: id, name: name, type: "text", autoComplete: "off", spellCheck: false, value: text, required: field.required, "aria-required": field.required, "aria-invalid": error !== null, "aria-describedby": describedBy, disabled: disabled, ...(searchable
|
|
173
|
+
? {
|
|
174
|
+
role: 'combobox',
|
|
175
|
+
'aria-autocomplete': 'list',
|
|
176
|
+
'aria-expanded': listVisible,
|
|
177
|
+
'aria-controls': listboxId,
|
|
178
|
+
'aria-activedescendant': listVisible ? `${id}-option-${active}` : undefined,
|
|
179
|
+
}
|
|
180
|
+
: {}), onChange: (event) => typed(event.target.value), onKeyDown: onKeyDown, onBlur: commitTyped }), search.status === 'loading' ? _jsx("span", { className: "ebitex-forms__lookup-spinner", "aria-hidden": "true" }) : null, listVisible ? (_jsxs("ul", { id: listboxId, role: "listbox", "aria-label": field.label, className: "ebitex-forms__lookup-list", children: [matches.map((option, index) => (_jsx("li", { id: `${id}-option-${index}`, role: "option", "aria-selected": index === active, className: "ebitex-forms__lookup-option",
|
|
181
|
+
// mousedown, not click: the input's blur would close the list before a click could land.
|
|
182
|
+
onMouseDown: (event) => {
|
|
183
|
+
event.preventDefault();
|
|
184
|
+
pick(index);
|
|
185
|
+
}, onMouseMove: () => setActive(index), children: highlight(option.label, search.status === 'done' ? search.query : '') }, `${option.value}-${index}`))), _jsx("li", { id: `${id}-option-${newRowIndex}`, role: "option", "aria-selected": newRowIndex === active, className: "ebitex-forms__lookup-option ebitex-forms__lookup-option--new", onMouseDown: (event) => {
|
|
186
|
+
event.preventDefault();
|
|
187
|
+
pick(newRowIndex);
|
|
188
|
+
}, onMouseMove: () => setActive(newRowIndex), children: `Use "${text.trim()}" as a new entry` })] })) : null] })), unavailable ? (_jsx("p", { className: "ebitex-forms__lookup-notice", children: "Suggestions are not available right now. Type your answer and continue." })) : null, _jsx("div", { id: statusId, className: "ebitex-forms__visually-hidden", role: "status", "aria-live": "polite", children: announcement }), hiddenExisting, error !== null ? (_jsx("p", { className: "ebitex-forms__error", id: `${id}-error`, role: "alert", children: error })) : null] }));
|
|
189
|
+
}
|
|
190
|
+
function joinLookupClasses(...values) {
|
|
191
|
+
return values.filter(Boolean).join(' ');
|
|
192
|
+
}
|
|
193
|
+
/** Marks the typed start of a word, so the respondent sees why each row matched. Plain text elsewhere. */
|
|
194
|
+
function highlight(label, query) {
|
|
195
|
+
const lastWord = query.split(/[^\p{L}\p{N}]+/u).filter(Boolean).pop();
|
|
196
|
+
if (lastWord === undefined)
|
|
197
|
+
return label;
|
|
198
|
+
const match = new RegExp(`(^|[^\\p{L}\\p{N}])(${escapeRegExp(lastWord)})`, 'iu').exec(label);
|
|
199
|
+
if (match === null)
|
|
200
|
+
return label;
|
|
201
|
+
const start = match.index + match[1].length;
|
|
202
|
+
return (_jsxs(_Fragment, { children: [label.slice(0, start), _jsx("mark", { children: label.slice(start, start + lastWord.length) }), label.slice(start + lastWord.length)] }));
|
|
203
|
+
}
|
|
204
|
+
function escapeRegExp(value) {
|
|
205
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=LookupField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LookupField.js","sourceRoot":"","sources":["../../src/react/LookupField.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAInD,MAAM,WAAW,GAAG,GAAG,CAAA;AACvB,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAOlC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,KAAK,EACL,EAAE,EACF,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,GAAG,IAAI,EACf,gBAAgB,GACU;IAC1B,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;IACnD,MAAM,SAAS,GAAG,GAAG,EAAE,UAAU,CAAA;IACjC,MAAM,QAAQ,GAAG,GAAG,EAAE,SAAS,CAAA;IAC/B,MAAM,WAAW,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACpG,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,cAAc,IAAI,wBAAwB,CAAC,CAAA;IAE/E,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAChE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACvC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACrD,kHAAkH;IAClH,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvD,yIAAyI;IACzI,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IAEnE,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IACjD,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAyB,IAAI,CAAC,CAAA;IAElD,sGAAsG;IACtG,yGAAyG;IACzG,uGAAuG;IACvG,0FAA0F;IAC1F,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/C,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAEtC,MAAM,UAAU,GAAG,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAA;IAChF,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,YAAY,CAAC,CAAA;IAElE,mGAAmG;IACnG,qEAAqE;IACrE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,UAAU,IAAI,OAAO;YAAE,OAAO,SAAS,CAAA;QAEpE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QACzB,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAC7B,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;YACtB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;YAC7B,OAAO,CAAC,KAAK,CAAC,CAAA;YACd,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;YACtB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YACxC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAA;YAC1B,MAAM,IAAI,GAAG,EAAE,YAAY,CAAC,OAAO,CAAA;YACnC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;YAEhC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAChD,CAAC,OAAO,EAAE,EAAE;gBACV,IAAI,IAAI,KAAK,YAAY,CAAC,OAAO;oBAAE,OAAM;gBACzC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;gBACnE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;gBACrD,SAAS,CAAC,CAAC,CAAC,CAAA;gBACZ,OAAO,CAAC,IAAI,CAAC,CAAA;YACf,CAAC,EACD,CAAC,OAAgB,EAAE,EAAE;gBACnB,IAAI,IAAI,KAAK,YAAY,CAAC,OAAO,IAAI,CAAC,OAAO,YAAY,YAAY,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC;oBAAE,OAAM;gBAC/G,yFAAyF;gBACzF,cAAc,CAAC,IAAI,CAAC,CAAA;gBACpB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;gBAC7B,OAAO,CAAC,KAAK,CAAC,CAAA;YAChB,CAAC,CACF,CAAA;QACH,CAAC,EAAE,WAAW,CAAC,CAAA;QAEf,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAChC,wGAAwG;IAC1G,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;IAElE,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;IAEjD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9D,8GAA8G;IAC9G,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAA;IAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAA;IACnC,MAAM,WAAW,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,UAAU,IAAI,CAAC,OAAO,CAAA;IAE9E,SAAS,KAAK,CAAC,IAAY;QACzB,eAAe,CAAC,KAAK,CAAC,CAAA;QACtB,cAAc,CAAC,IAAI,CAAC,CAAA;QACpB,QAAQ,CAAC,IAAI,CAAC,CAAA;QACd,oGAAoG;QACpG,8FAA8F;QAC9F,qGAAqG;QACrG,uGAAuG;QACvG,qGAAqG;QACrG,gBAAgB,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IAC3E,CAAC;IAED,SAAS,WAAW;QAClB,OAAO,CAAC,KAAK,CAAC,CAAA;QACd,kFAAkF;QAClF,IAAI,UAAU,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,QAAQ,KAAK,IAAI;YAAE,gBAAgB,EAAE,CAAC,KAAK,CAAC,CAAA;IACtF,CAAC;IAED,SAAS,IAAI,CAAC,KAAa;QACzB,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;YAC1B,eAAe,CAAC,IAAI,CAAC,CAAA;YACrB,cAAc,CAAC,IAAI,CAAC,CAAA;YACpB,gBAAgB,EAAE,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;YAC7B,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAM;YAChC,eAAe,CAAC,KAAK,CAAC,CAAA;YACtB,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAC5B,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACtB,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAA;QAC1B,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,CAAA;QACd,iHAAiH;QACjH,cAAc,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,SAAS,KAAK;QACZ,eAAe,CAAC,KAAK,CAAC,CAAA;QACtB,cAAc,CAAC,IAAI,CAAC,CAAA;QACpB,QAAQ,CAAC,EAAE,CAAC,CAAA;QACZ,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAA;QACxB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QAC7B,cAAc,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IACjD,CAAC;IAED,SAAS,SAAS,CAAC,KAA4C;QAC7D,IAAI,CAAC,WAAW;YAAE,OAAM;QACxB,QAAQ,KAAK,CAAC,GAAG,EAAE,CAAC;YAClB,KAAK,WAAW;gBACd,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAA;gBAC5C,MAAK;YACP,KAAK,SAAS;gBACZ,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAA;gBACvD,MAAK;YACP,KAAK,MAAM;gBACT,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,SAAS,CAAC,CAAC,CAAC,CAAA;gBACZ,MAAK;YACP,KAAK,KAAK;gBACR,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAA;gBACvB,MAAK;YACP,KAAK,OAAO;gBACV,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,IAAI,CAAC,MAAM,CAAC,CAAA;gBACZ,MAAK;YACP,KAAK,QAAQ;gBACX,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,OAAO,CAAC,KAAK,CAAC,CAAA;gBACd,MAAK;QACT,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAChB,WAAW;QACT,CAAC,CAAC,yEAAyE;QAC3E,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS;YAC3B,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,WAAW;gBACX,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,0CAA0C;gBAC3G,CAAC,CAAC,EAAE,CAAA;IAEZ,MAAM,cAAc,GAClB,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAO,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAE,GAAG,IAAI,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,GAAI,CAAA;IAElH,OAAO,CACL,eAAK,SAAS,EAAC,0CAA0C,aACvD,iBAAO,SAAS,EAAC,qBAAqB,EAAC,OAAO,EAAE,EAAE,aAC/C,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAChB,gBAAM,SAAS,EAAC,wBAAwB,iBAAa,MAAM,aACxD,GAAG,SAEC,CACR,CAAC,CAAC,CAAC,IAAI,IACF,EAEP,OAAO,CAAC,CAAC,CAAC,CACT,eAAK,SAAS,EAAE,iBAAiB,CAAC,2BAA2B,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gCAAgC,CAAC,aAC9H,0BACE,iBAAQ,EAAE,EAAE,EAAE,YAAG,WAAW,IAAI,IAAI,GAAU,EAC9C,eAAM,SAAS,EAAC,gCAAgC,YAC7C,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,WAAW,GACpD,IACH,EACN,iBACE,IAAI,EAAC,QAAQ,EACb,GAAG,EAAE,SAAS,EACd,SAAS,EAAC,sDAAsD,EAChE,QAAQ,EAAE,QAAQ,sBACA,EAAE,EACpB,OAAO,EAAE,KAAK,uBAGP,EACT,gBAAO,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAI,IAC5C,CACP,CAAC,CAAC,CAAC,CACF,eAAK,SAAS,EAAC,0BAA0B,aACvC,gBACE,GAAG,EAAE,QAAQ,EACb,SAAS,EAAC,uBAAuB,EACjC,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,IAAI,EACV,IAAI,EAAC,MAAM,EACX,YAAY,EAAC,KAAK,EAClB,UAAU,EAAE,KAAK,EACjB,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,KAAK,CAAC,QAAQ,mBACT,KAAK,CAAC,QAAQ,kBACf,KAAK,KAAK,IAAI,sBACV,WAAW,EAC7B,QAAQ,EAAE,QAAQ,KACd,CAAC,UAAU;4BACb,CAAC,CAAC;gCACE,IAAI,EAAE,UAAmB;gCACzB,mBAAmB,EAAE,MAAe;gCACpC,eAAe,EAAE,WAAW;gCAC5B,eAAe,EAAE,SAAS;gCAC1B,uBAAuB,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;6BAC5E;4BACH,CAAC,CAAC,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAC9C,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,WAAW,GACnB,EACD,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,8BAA8B,iBAAa,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAEzG,WAAW,CAAC,CAAC,CAAC,CACb,cAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAC,SAAS,gBAAa,KAAK,CAAC,KAAK,EAAE,SAAS,EAAC,2BAA2B,aAC7F,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9B,aAEE,EAAE,EAAE,GAAG,EAAE,WAAW,KAAK,EAAE,EAC3B,IAAI,EAAC,QAAQ,mBACE,KAAK,KAAK,MAAM,EAC/B,SAAS,EAAC,6BAA6B;gCACvC,yFAAyF;gCACzF,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;oCACrB,KAAK,CAAC,cAAc,EAAE,CAAA;oCACtB,IAAI,CAAC,KAAK,CAAC,CAAA;gCACb,CAAC,EACD,WAAW,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,YAElC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAZjE,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE,CAa5B,CACN,CAAC,EACF,aACE,EAAE,EAAE,GAAG,EAAE,WAAW,WAAW,EAAE,EACjC,IAAI,EAAC,QAAQ,mBACE,WAAW,KAAK,MAAM,EACrC,SAAS,EAAC,8DAA8D,EACxE,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;oCACrB,KAAK,CAAC,cAAc,EAAE,CAAA;oCACtB,IAAI,CAAC,WAAW,CAAC,CAAA;gCACnB,CAAC,EACD,WAAW,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,YAExC,QAAQ,IAAI,CAAC,IAAI,EAAE,kBAAkB,GACnC,IACF,CACN,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,EAEA,WAAW,CAAC,CAAC,CAAC,CACb,YAAG,SAAS,EAAC,6BAA6B,wFAA4E,CACvH,CAAC,CAAC,CAAC,IAAI,EAER,cAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAC,+BAA+B,EAAC,IAAI,EAAC,QAAQ,eAAW,QAAQ,YAC1F,YAAY,GACT,EACL,cAAc,EACd,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAChB,YAAG,SAAS,EAAC,qBAAqB,EAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAC,OAAO,YAC/D,KAAK,GACJ,CACL,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAA;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAG,MAA8B;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACzC,CAAC;AAED,0GAA0G;AAC1G,SAAS,SAAS,CAAC,KAAa,EAAE,KAAa;IAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAA;IACrE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IACxC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,uBAAuB,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5F,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IAC3C,OAAO,CACL,8BACG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EACtB,yBAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAQ,EACzD,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IACpC,CACJ,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;AACrD,CAAC"}
|
package/dist/react/NodeList.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FormNode, type LookupSource, type SubmissionData, type ValidationErrors } from '../types.js';
|
|
2
2
|
import { type FieldComponents } from './fields.js';
|
|
3
3
|
/**
|
|
4
4
|
* The recursive Fieldset/Row/Variant/field-dispatch tree walk shared by every renderer this package
|
|
@@ -7,13 +7,15 @@ import { type FieldComponents } from './fields.js';
|
|
|
7
7
|
* `fetch`-driven submit state machine but needs this exact tree walk to avoid a second/third
|
|
8
8
|
* implementation of it. Extracted here specifically so it's importable without `EbitexForm` itself.
|
|
9
9
|
*/
|
|
10
|
-
export declare function NodeList({ nodes, baseId, data, errors, disabled, fieldComponents, onChange, }: {
|
|
10
|
+
export declare function NodeList({ nodes, baseId, data, errors, disabled, fieldComponents, lookup, onChange, }: {
|
|
11
11
|
nodes: FormNode[];
|
|
12
12
|
baseId: string;
|
|
13
13
|
data: SubmissionData;
|
|
14
14
|
errors: ValidationErrors;
|
|
15
15
|
disabled: boolean;
|
|
16
16
|
fieldComponents?: FieldComponents;
|
|
17
|
+
/** Searches the options of a `Lookup` field as the respondent types; without one such a field is a plain text input. */
|
|
18
|
+
lookup?: LookupSource;
|
|
17
19
|
onChange: (key: string, value: SubmissionData[string]) => void;
|
|
18
20
|
}): import("react").JSX.Element;
|
|
19
21
|
/** The Form's own configured Submit/Reset controls, shown on the final step. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeList.d.ts","sourceRoot":"","sources":["../../src/react/NodeList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"NodeList.d.ts","sourceRoot":"","sources":["../../src/react/NodeList.tsx"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnI,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAA;AAEpB;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,MAAM,EACN,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,eAAe,EACf,MAAM,EACN,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,cAAc,CAAA;IACpB,MAAM,EAAE,gBAAgB,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,wHAAwH;IACxH,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;CAC/D,+BAgHA;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,+BA8B1F;AAED,wBAAgB,cAAc,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM,CAExE"}
|
package/dist/react/NodeList.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { resolveVariant } from '../nodes.js';
|
|
3
|
+
import { LOOKUP_COMPANION_SUFFIX } from '../types.js';
|
|
3
4
|
import { ChoiceFieldControl, InputFieldControl, NumberFieldControl, TextareaFieldControl, } from './fields.js';
|
|
4
5
|
/**
|
|
5
6
|
* The recursive Fieldset/Row/Variant/field-dispatch tree walk shared by every renderer this package
|
|
@@ -8,21 +9,21 @@ import { ChoiceFieldControl, InputFieldControl, NumberFieldControl, TextareaFiel
|
|
|
8
9
|
* `fetch`-driven submit state machine but needs this exact tree walk to avoid a second/third
|
|
9
10
|
* implementation of it. Extracted here specifically so it's importable without `EbitexForm` itself.
|
|
10
11
|
*/
|
|
11
|
-
export function NodeList({ nodes, baseId, data, errors, disabled, fieldComponents, onChange, }) {
|
|
12
|
+
export function NodeList({ nodes, baseId, data, errors, disabled, fieldComponents, lookup, onChange, }) {
|
|
12
13
|
return (_jsx(_Fragment, { children: nodes.map((node, index) => {
|
|
13
14
|
if (node.nodeType === 'Fieldset') {
|
|
14
|
-
return (_jsxs("fieldset", { className: "ebitex-forms__fieldset", children: [_jsx("legend", { children: node.legend }), _jsx(NodeList, { nodes: node.nodes, baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, onChange: onChange })] }, `fieldset-${index}`));
|
|
15
|
+
return (_jsxs("fieldset", { className: "ebitex-forms__fieldset", children: [_jsx("legend", { children: node.legend }), _jsx(NodeList, { nodes: node.nodes, baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, lookup: lookup, onChange: onChange })] }, `fieldset-${index}`));
|
|
15
16
|
}
|
|
16
17
|
if (node.nodeType === 'Row') {
|
|
17
18
|
// Horizontal on wide viewports, single column on narrow — see styles.css.
|
|
18
|
-
return (_jsx("div", { className: "ebitex-forms__row", children: _jsx(NodeList, { nodes: node.nodes, baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, onChange: onChange }) }, `row-${index}`));
|
|
19
|
+
return (_jsx("div", { className: "ebitex-forms__row", children: _jsx(NodeList, { nodes: node.nodes, baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, lookup: lookup, onChange: onChange }) }, `row-${index}`));
|
|
19
20
|
}
|
|
20
21
|
if (node.nodeType === 'Variant') {
|
|
21
22
|
// Re-evaluated on every render as `data` changes, so the visible branch updates live as
|
|
22
23
|
// the respondent answers the controlling field (spec 111-conditional-fields). The chosen
|
|
23
24
|
// branch's/fallback's own node list (spec 113-variant-branch-refinements) may be empty —
|
|
24
25
|
// NodeList over an empty array renders nothing, same as the old `null` case did.
|
|
25
|
-
return (_jsx(NodeList, { nodes: resolveVariant(node, data), baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, onChange: onChange }, `variant-${index}`));
|
|
26
|
+
return (_jsx(NodeList, { nodes: resolveVariant(node, data), baseId: baseId, data: data, errors: errors, disabled: disabled, fieldComponents: fieldComponents, lookup: lookup, onChange: onChange }, `variant-${index}`));
|
|
26
27
|
}
|
|
27
28
|
if (node.fieldType === 'Button') {
|
|
28
29
|
// Buttons inside a step's tree are the Form's own Actions, rendered by ActionButtons.
|
|
@@ -56,7 +57,8 @@ export function NodeList({ nodes, baseId, data, errors, disabled, fieldComponent
|
|
|
56
57
|
}
|
|
57
58
|
case 'Choice': {
|
|
58
59
|
const Component = fieldComponents?.Choice ?? ChoiceFieldControl;
|
|
59
|
-
|
|
60
|
+
const companion = data[`${key}${LOOKUP_COMPANION_SUFFIX}`];
|
|
61
|
+
return (_jsx(Component, { field: node, ...shared, lookup: lookup, existing: companion === 'true' ? true : companion === 'false' ? false : null, onExistingChange: (existing) => onChange(`${key}${LOOKUP_COMPANION_SUFFIX}`, existing === null ? null : String(existing)) }, key));
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
}) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeList.js","sourceRoot":"","sources":["../../src/react/NodeList.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"NodeList.js","sourceRoot":"","sources":["../../src/react/NodeList.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/fields.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChoiceField, InputField, NumberField, SubmissionData, TextareaField } from '../types.js';
|
|
1
|
+
import type { ChoiceField, InputField, LookupSource, NumberField, SubmissionData, TextareaField } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* What every field component receives. A consumer overriding one via `fieldComponents` implements
|
|
4
4
|
* this same contract, so an override is a drop-in rather than a fork of the surrounding form.
|
|
@@ -20,14 +20,26 @@ export interface FieldComponentProps<TField> {
|
|
|
20
20
|
error: string | null;
|
|
21
21
|
disabled: boolean;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* What a `Choice` component receives: everything every field gets, plus what a `Lookup` needs. A component
|
|
25
|
+
* written against `FieldComponentProps<ChoiceField>` alone is still a valid override; it simply ignores these.
|
|
26
|
+
*/
|
|
27
|
+
export interface ChoiceFieldComponentProps extends FieldComponentProps<ChoiceField> {
|
|
28
|
+
/** Searches a `Lookup`'s options as the respondent types. Absent: the field is a plain text input. */
|
|
29
|
+
lookup?: LookupSource;
|
|
30
|
+
/** A `Lookup`'s companion answer: `true` picked from the options, `false` typed, `null` not answered. */
|
|
31
|
+
existing?: boolean | null;
|
|
32
|
+
/** Report the companion answer; the form stores it as `<key>-existing`. */
|
|
33
|
+
onExistingChange?: (existing: boolean | null) => void;
|
|
34
|
+
}
|
|
23
35
|
export interface FieldComponents {
|
|
24
36
|
Input?: React.ComponentType<FieldComponentProps<InputField>>;
|
|
25
37
|
Textarea?: React.ComponentType<FieldComponentProps<TextareaField>>;
|
|
26
38
|
Number?: React.ComponentType<FieldComponentProps<NumberField>>;
|
|
27
|
-
Choice?: React.ComponentType<
|
|
39
|
+
Choice?: React.ComponentType<ChoiceFieldComponentProps>;
|
|
28
40
|
}
|
|
29
41
|
export declare function InputFieldControl({ field, id, name, value, onChange, error, disabled }: FieldComponentProps<InputField>): import("react").JSX.Element;
|
|
30
42
|
export declare function TextareaFieldControl({ field, id, name, value, onChange, error, disabled }: FieldComponentProps<TextareaField>): import("react").JSX.Element;
|
|
31
43
|
export declare function NumberFieldControl({ field, id, name, value, onChange, error, disabled }: FieldComponentProps<NumberField>): import("react").JSX.Element;
|
|
32
|
-
export declare function ChoiceFieldControl(
|
|
44
|
+
export declare function ChoiceFieldControl(props: ChoiceFieldComponentProps): import("react").JSX.Element;
|
|
33
45
|
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/react/fields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/react/fields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAA;AAGpB;;;GAGG;AACH,MAAM,WAAW,mBAAmB,CAAC,MAAM;IACzC,KAAK,EAAE,MAAM,CAAA;IACb,iGAAiG;IACjG,EAAE,EAAE,MAAM,CAAA;IACV;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;IACjD,yGAAyG;IACzG,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB,CAAC,WAAW,CAAC;IACjF,sGAAsG;IACtG,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACzB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAA;CACtD;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAA;IAC5D,QAAQ,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAA;IAClE,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAA;IAC9D,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAA;CACxD;AAuCD,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,CAAC,UAAU,CAAC,+BAuBvH;AAED,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,CAAC,aAAa,CAAC,+BAuB7H;AAED,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,CAAC,WAAW,CAAC,+BA4BzH;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,yBAAyB,+BAgGlE"}
|
package/dist/react/fields.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { LookupFieldControl } from './LookupField.js';
|
|
2
3
|
const INPUT_TYPES = {
|
|
3
4
|
Text: 'text',
|
|
4
5
|
Email: 'email',
|
|
@@ -31,8 +32,12 @@ export function NumberFieldControl({ field, id, name, value, onChange, error, di
|
|
|
31
32
|
// coercing would turn a half-typed "-" or "1." into NaN mid-keystroke.
|
|
32
33
|
onChange: (event) => onChange(event.target.value) }), _jsx(ErrorMessage, { id: id, error: error })] }));
|
|
33
34
|
}
|
|
34
|
-
export function ChoiceFieldControl(
|
|
35
|
+
export function ChoiceFieldControl(props) {
|
|
36
|
+
const { field, id, name, value, onChange, error, disabled } = props;
|
|
35
37
|
const describedBy = error !== null ? `${id}-error` : undefined;
|
|
38
|
+
if (field.choiceType === 'Lookup') {
|
|
39
|
+
return _jsx(LookupFieldControl, { ...props });
|
|
40
|
+
}
|
|
36
41
|
if (field.choiceType === 'Select') {
|
|
37
42
|
return (_jsxs("div", { className: "ebitex-forms__field", children: [_jsx(Label, { id: id, required: field.required, children: field.label }), _jsxs("select", { className: "ebitex-forms__control", id: id, name: name, value: typeof value === 'string' ? value : '', required: field.required, "aria-required": field.required, "aria-invalid": error !== null, "aria-describedby": describedBy, disabled: disabled, onChange: (event) => onChange(event.target.value), children: [_jsx("option", { value: "", children: "Select\u2026" }), field.options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] }), _jsx(ErrorMessage, { id: id, error: error })] }));
|
|
38
43
|
}
|
package/dist/react/fields.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/react/fields.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/react/fields.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* `createFormsClient` from the root entry point and pass the result to `<EbitexForm />`.
|
|
7
7
|
*/
|
|
8
8
|
export { EbitexForm, type EbitexFormProps } from './EbitexForm.js';
|
|
9
|
-
export { ChoiceFieldControl, InputFieldControl, NumberFieldControl, TextareaFieldControl, type FieldComponentProps, type FieldComponents, } from './fields.js';
|
|
9
|
+
export { ChoiceFieldControl, InputFieldControl, NumberFieldControl, TextareaFieldControl, type ChoiceFieldComponentProps, type FieldComponentProps, type FieldComponents, } from './fields.js';
|
|
10
|
+
export { LookupFieldControl } from './LookupField.js';
|
|
10
11
|
/**
|
|
11
12
|
* The recursive Fieldset/Row/Variant/field-dispatch tree walk `EbitexForm` itself renders through —
|
|
12
13
|
* exported so a host that needs the same field-tree rendering without `EbitexForm`'s own
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAA;AAEpB;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAErD;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/react/index.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export { EbitexForm } from './EbitexForm.js';
|
|
9
9
|
export { ChoiceFieldControl, InputFieldControl, NumberFieldControl, TextareaFieldControl, } from './fields.js';
|
|
10
|
+
export { LookupFieldControl } from './LookupField.js';
|
|
10
11
|
/**
|
|
11
12
|
* The recursive Fieldset/Row/Variant/field-dispatch tree walk `EbitexForm` itself renders through —
|
|
12
13
|
* exported so a host that needs the same field-tree rendering without `EbitexForm`'s own
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA;AAElE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA;AAElE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,GAIrB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAErD;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/react/styles.css
CHANGED
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
--ebitex-forms-muted: #6b7280;
|
|
24
24
|
--ebitex-forms-border: #d1d5db;
|
|
25
25
|
--ebitex-forms-error: #dc2626;
|
|
26
|
+
/* An opaque background for the lookup suggestion list: `--ebitex-forms-surface` is transparent by default, which would let the form show through it. */
|
|
27
|
+
--ebitex-forms-listbox-bg: #ffffff;
|
|
28
|
+
--ebitex-forms-listbox-active: #dbeafe;
|
|
29
|
+
--ebitex-forms-mark: #fef08a;
|
|
26
30
|
--ebitex-forms-surface: transparent;
|
|
27
31
|
--ebitex-forms-radius: 0.375rem;
|
|
28
32
|
--ebitex-forms-gap: 1rem;
|
|
@@ -62,6 +66,9 @@
|
|
|
62
66
|
--ebitex-forms-muted: #9ca3af;
|
|
63
67
|
--ebitex-forms-border: #4b5563;
|
|
64
68
|
--ebitex-forms-error: #f87171;
|
|
69
|
+
--ebitex-forms-listbox-bg: #1f2937;
|
|
70
|
+
--ebitex-forms-listbox-active: #1e3a5f;
|
|
71
|
+
--ebitex-forms-mark: #854d0e;
|
|
65
72
|
}
|
|
66
73
|
}
|
|
67
74
|
|
|
@@ -72,6 +79,9 @@
|
|
|
72
79
|
--ebitex-forms-muted: #9ca3af;
|
|
73
80
|
--ebitex-forms-border: #4b5563;
|
|
74
81
|
--ebitex-forms-error: #f87171;
|
|
82
|
+
--ebitex-forms-listbox-bg: #1f2937;
|
|
83
|
+
--ebitex-forms-listbox-active: #1e3a5f;
|
|
84
|
+
--ebitex-forms-mark: #854d0e;
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
/*
|
|
@@ -183,6 +193,132 @@
|
|
|
183
193
|
margin: 0;
|
|
184
194
|
}
|
|
185
195
|
|
|
196
|
+
/*
|
|
197
|
+
* The `Lookup` choice: a type-ahead with a suggestion list under the input. The list is positioned
|
|
198
|
+
* against `.ebitex-forms__lookup-box` (the input and its list only), not the whole field, so it opens
|
|
199
|
+
* directly under the input whatever sits after it. It sits above following controls but is part of the
|
|
200
|
+
* normal flow of the page's stacking, never a viewport-fixed layer, so a form inside an iframe or a
|
|
201
|
+
* scrolled container keeps it attached to its input.
|
|
202
|
+
*/
|
|
203
|
+
.ebitex-forms__lookup-box {
|
|
204
|
+
position: relative;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.ebitex-forms__lookup-list {
|
|
208
|
+
position: absolute;
|
|
209
|
+
inset-inline: 0;
|
|
210
|
+
top: calc(100% + 0.25rem);
|
|
211
|
+
z-index: 10;
|
|
212
|
+
margin: 0;
|
|
213
|
+
padding: 0.25rem;
|
|
214
|
+
list-style: none;
|
|
215
|
+
max-height: 20rem;
|
|
216
|
+
overflow-y: auto;
|
|
217
|
+
color: var(--ebitex-forms-text);
|
|
218
|
+
/*
|
|
219
|
+
* An opaque base, with the form's own surface painted over it. The surface is `transparent` by default
|
|
220
|
+
* (and in the built-in theme), which on its own would let the fields behind the list show through it, so it
|
|
221
|
+
* cannot be the list's only background; layered over a base, a theme that picks a real surface colour still
|
|
222
|
+
* gets it, and one that does not gets the base.
|
|
223
|
+
*/
|
|
224
|
+
background-color: var(--ebitex-forms-listbox-bg);
|
|
225
|
+
background-image: linear-gradient(var(--ebitex-forms-surface), var(--ebitex-forms-surface));
|
|
226
|
+
border: 1px solid var(--ebitex-forms-border);
|
|
227
|
+
border-radius: var(--ebitex-forms-radius);
|
|
228
|
+
box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 0.15);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.ebitex-forms__lookup-option {
|
|
232
|
+
padding: 0.625rem;
|
|
233
|
+
border-radius: calc(var(--ebitex-forms-radius) - 0.125rem);
|
|
234
|
+
cursor: pointer;
|
|
235
|
+
/* A comfortable touch target. */
|
|
236
|
+
min-height: 2.5rem;
|
|
237
|
+
box-sizing: border-box;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.ebitex-forms__lookup-option[aria-selected='true'] {
|
|
241
|
+
background: var(--ebitex-forms-listbox-active);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.ebitex-forms__lookup-option--new {
|
|
245
|
+
margin-top: 0.25rem;
|
|
246
|
+
border-top: 1px solid var(--ebitex-forms-border);
|
|
247
|
+
border-radius: 0 0 calc(var(--ebitex-forms-radius) - 0.125rem) calc(var(--ebitex-forms-radius) - 0.125rem);
|
|
248
|
+
font-weight: 600;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.ebitex-forms__lookup-option mark {
|
|
252
|
+
background: var(--ebitex-forms-mark);
|
|
253
|
+
color: inherit;
|
|
254
|
+
border-radius: 0.125rem;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.ebitex-forms__lookup-spinner {
|
|
258
|
+
position: absolute;
|
|
259
|
+
inset-inline-end: 0.75rem;
|
|
260
|
+
top: 0.75rem;
|
|
261
|
+
width: 1rem;
|
|
262
|
+
height: 1rem;
|
|
263
|
+
border: 2px solid var(--ebitex-forms-border);
|
|
264
|
+
border-top-color: var(--ebitex-forms-accent);
|
|
265
|
+
border-radius: 50%;
|
|
266
|
+
animation: ebitex-forms-lookup-spin 0.7s linear infinite;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@keyframes ebitex-forms-lookup-spin {
|
|
270
|
+
to {
|
|
271
|
+
transform: rotate(360deg);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
@media (prefers-reduced-motion: reduce) {
|
|
276
|
+
.ebitex-forms__lookup-spinner {
|
|
277
|
+
animation: none;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.ebitex-forms__lookup-chip {
|
|
282
|
+
display: flex;
|
|
283
|
+
align-items: center;
|
|
284
|
+
justify-content: space-between;
|
|
285
|
+
gap: 0.75rem;
|
|
286
|
+
padding: 0.625rem 0.75rem;
|
|
287
|
+
border: 1px solid var(--ebitex-forms-border);
|
|
288
|
+
border-radius: var(--ebitex-forms-radius);
|
|
289
|
+
background: color-mix(in srgb, var(--ebitex-forms-accent) 12%, transparent);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.ebitex-forms__lookup-chip--new {
|
|
293
|
+
background: color-mix(in srgb, var(--ebitex-forms-muted) 14%, transparent);
|
|
294
|
+
border-style: dashed;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.ebitex-forms__lookup-chip-note {
|
|
298
|
+
display: block;
|
|
299
|
+
font-size: 0.8125rem;
|
|
300
|
+
color: var(--ebitex-forms-muted);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.ebitex-forms__lookup-notice {
|
|
304
|
+
margin: 0;
|
|
305
|
+
font-size: 0.8125rem;
|
|
306
|
+
color: var(--ebitex-forms-muted);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* Present for assistive technology (the live region) and invisible to everyone else. */
|
|
310
|
+
.ebitex-forms__visually-hidden {
|
|
311
|
+
position: absolute;
|
|
312
|
+
width: 1px;
|
|
313
|
+
height: 1px;
|
|
314
|
+
margin: -1px;
|
|
315
|
+
padding: 0;
|
|
316
|
+
overflow: hidden;
|
|
317
|
+
clip: rect(0 0 0 0);
|
|
318
|
+
white-space: nowrap;
|
|
319
|
+
border: 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
186
322
|
.ebitex-forms__notice,
|
|
187
323
|
.ebitex-forms__step-indicator {
|
|
188
324
|
color: var(--ebitex-forms-muted);
|
package/dist/types.d.ts
CHANGED
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
* describe what genuinely arrives rather than what was intended to.
|
|
7
7
|
*/
|
|
8
8
|
export type InputVariant = 'Text' | 'Email' | 'Tel' | 'Url' | 'Password';
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* `Lookup` is a type-ahead: the options are not listed up front but searched as the respondent types
|
|
11
|
+
* (see `LookupSource`), and any text is accepted, not only an offered option. Renderers older than the
|
|
12
|
+
* version that added it do not know it and show nothing for the field, so a form using one needs this
|
|
13
|
+
* package, or a custom `Choice` component, to be current.
|
|
14
|
+
*/
|
|
15
|
+
export type ChoiceType = 'Select' | 'Radio' | 'Checkbox' | 'Lookup';
|
|
10
16
|
export type ButtonType = 'Submit' | 'Reset' | 'Button';
|
|
11
17
|
export interface ChoiceOption {
|
|
12
18
|
value: string;
|
|
@@ -58,9 +64,32 @@ export interface ChoiceField extends FieldBase {
|
|
|
58
64
|
name: string;
|
|
59
65
|
required: boolean;
|
|
60
66
|
choiceType: ChoiceType;
|
|
61
|
-
/** Always a plain array — the server resolves data-set- and plugin-backed options before sending. */
|
|
67
|
+
/** Always a plain array — the server resolves data-set- and plugin-backed options before sending. Empty for a `Lookup`, whose options are searched instead. */
|
|
62
68
|
options: ChoiceOption[];
|
|
69
|
+
/** `Lookup` only: how many characters to type before searching. Absent means 2. */
|
|
70
|
+
minQueryLength?: number;
|
|
71
|
+
/** `Lookup` only: the most options one search shows. Absent means 8. */
|
|
72
|
+
maxResults?: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Where a `Lookup` field's options come from while the respondent types. `EbitexForm` supplies one
|
|
76
|
+
* that calls the form's own public endpoint, so an embedded form needs nothing from you; pass your own
|
|
77
|
+
* as the `lookup` prop to route searches elsewhere (a proxy of yours, or a fake in a test).
|
|
78
|
+
*
|
|
79
|
+
* Reject (or throw) when the search cannot be made: the field then falls back to a plain text input,
|
|
80
|
+
* which is always a usable way to answer. Honour `signal`: it fires when the respondent keeps typing.
|
|
81
|
+
*/
|
|
82
|
+
export interface LookupSource {
|
|
83
|
+
search(field: string, query: string, signal: AbortSignal): Promise<ChoiceOption[]>;
|
|
63
84
|
}
|
|
85
|
+
/** The most characters a `Lookup` answer may have. The same limit the server enforces. */
|
|
86
|
+
export declare const MAX_LOOKUP_VALUE_LENGTH = 200;
|
|
87
|
+
/**
|
|
88
|
+
* A `Lookup` also submits `<its key>-existing`: `"true"` when the respondent picked one of the
|
|
89
|
+
* offered options, `"false"` when they typed their own. A later field's condition may compare it, which
|
|
90
|
+
* is how extra questions appear only for an answer that is not in the list.
|
|
91
|
+
*/
|
|
92
|
+
export declare const LOOKUP_COMPANION_SUFFIX = "-existing";
|
|
64
93
|
export interface ButtonField extends FieldBase {
|
|
65
94
|
fieldType: 'Button';
|
|
66
95
|
buttonType: ButtonType;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,UAAU,CAAA;AAExE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -5,7 +5,14 @@
|
|
|
5
5
|
* its resolved node tree through the same converter its persistence layer uses, so these types
|
|
6
6
|
* describe what genuinely arrives rather than what was intended to.
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
/** The most characters a `Lookup` answer may have. The same limit the server enforces. */
|
|
9
|
+
export const MAX_LOOKUP_VALUE_LENGTH = 200;
|
|
10
|
+
/**
|
|
11
|
+
* A `Lookup` also submits `<its key>-existing`: `"true"` when the respondent picked one of the
|
|
12
|
+
* offered options, `"false"` when they typed their own. A later field's condition may compare it, which
|
|
13
|
+
* is how extra questions appear only for an answer that is not in the list.
|
|
14
|
+
*/
|
|
15
|
+
export const LOOKUP_COMPANION_SUFFIX = '-existing';
|
|
9
16
|
// `isFormField`/`isDataField`/`collectDataFields`/`resolveVariant` live in `./nodes.js`, not here —
|
|
10
17
|
// `resolveVariant` needs `isFieldComparisonSatisfied` from `./predicates.js`, which itself imports
|
|
11
18
|
// types from this file, so keeping tree-walking logic out of `types.ts` avoids a circular import
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAyFH,0FAA0F;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAE1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAA;AAkHlD,oGAAoG;AACpG,mGAAmG;AACnG,iGAAiG;AACjG,mBAAmB"}
|
package/dist/validators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAE3E,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,eAAe,GACvB,gBAAgB,CAgDlB"}
|
package/dist/validators.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { collectDataFields } from './nodes.js';
|
|
2
|
+
import { LOOKUP_COMPANION_SUFFIX, MAX_LOOKUP_VALUE_LENGTH } from './types.js';
|
|
2
3
|
/**
|
|
3
4
|
* A client-side port of the server's own submission validation, for immediate feedback before a
|
|
4
5
|
* step advances or a form submits.
|
|
@@ -40,7 +41,18 @@ export function validateSubmission(form, data, options) {
|
|
|
40
41
|
// remarks on why that's an acceptable simplification client-side.
|
|
41
42
|
for (const key of Object.keys(data)) {
|
|
42
43
|
if (!fields.has(key)) {
|
|
43
|
-
|
|
44
|
+
// A lookup's companion key is legal, but only beside a lookup that is itself present.
|
|
45
|
+
const lookupKey = key.endsWith(LOOKUP_COMPANION_SUFFIX) ? key.slice(0, -LOOKUP_COMPANION_SUFFIX.length) : null;
|
|
46
|
+
const lookup = lookupKey === null ? undefined : fields.get(lookupKey);
|
|
47
|
+
if (lookup?.fieldType === 'Choice' && lookup.choiceType === 'Lookup') {
|
|
48
|
+
const companion = data[key];
|
|
49
|
+
if (companion !== 'true' && companion !== 'false') {
|
|
50
|
+
errors[key] = 'Value must be "true" or "false".';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
errors[key] = 'Unknown field.';
|
|
55
|
+
}
|
|
44
56
|
}
|
|
45
57
|
}
|
|
46
58
|
for (const [key, field] of fields) {
|
|
@@ -67,6 +79,15 @@ function validateShape(field, value) {
|
|
|
67
79
|
case 'Number':
|
|
68
80
|
return validateNumber(field.min ?? null, field.max ?? null, value);
|
|
69
81
|
case 'Choice':
|
|
82
|
+
// A lookup takes any text: "not in the list" is the point. Not checked against a source, which
|
|
83
|
+
// would put a network call on the submit path.
|
|
84
|
+
if (field.choiceType === 'Lookup') {
|
|
85
|
+
if (typeof value !== 'string')
|
|
86
|
+
return 'Value must be text.';
|
|
87
|
+
return value.length > MAX_LOOKUP_VALUE_LENGTH
|
|
88
|
+
? `Value must be ${MAX_LOOKUP_VALUE_LENGTH} characters or fewer.`
|
|
89
|
+
: null;
|
|
90
|
+
}
|
|
70
91
|
return validateChoice(field.options.map((option) => option.value), value);
|
|
71
92
|
case 'Input':
|
|
72
93
|
case 'Textarea':
|
package/dist/validators.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED