@vectoriox/iox-ui 4.27.0 → 4.29.0

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.
@@ -202,5 +202,45 @@ declare function collectFormSpec(node: FormNodeLike | null | undefined): FormSpe
202
202
  /** Every Field in this subtree, in document order, not descending into a nested Form. */
203
203
  declare function collectFieldNodes(nodes: readonly FormNodeLike[]): FormNodeLike[];
204
204
 
205
- export { ControlType, DEFAULT_EN_MESSAGES, FIELD_NODE_TYPE, FORM_ERROR_KEYS, FORM_NODE_TYPE, FeedbackTiming, IMPLIED_PATTERN, MESSAGE_NAMESPACE, MULTI_VALUE_CONTROLS, PATTERN_MESSAGE_KEYS, PATTERN_PRESETS, PatternPreset, RULE_MESSAGE_KEYS, RuleName, STORE_ACTION, collectFieldNodes, collectFormSpec, deriveFieldName, firstInvalidField, uniqueFieldName, validateField, validateForm };
206
- export type { FieldError, FieldOption, FieldOptionSource, FieldResult, FieldSpec, FormNodeLike, FormResult, FormSpec, SubmitAction, ValidationRule };
205
+ /** Everything the runtime needs to remember. Immutable — each transition returns a new state. */
206
+ interface FormRuntimeState {
207
+ /** Field names the visitor has left (blurred) at least once. */
208
+ touched: ReadonlySet<string>;
209
+ /** True once a submit has been attempted — after that, every error is fair game. */
210
+ submitted: boolean;
211
+ /** The current errors, whether or not they are being shown. */
212
+ errors: Readonly<Record<string, FieldError>>;
213
+ /** In flight — the submit button shows its loading label and the form is aria-busy. */
214
+ submitting: boolean;
215
+ }
216
+ declare const INITIAL_FORM_STATE: FormRuntimeState;
217
+ /**
218
+ * Should this field's error be on screen right now?
219
+ *
220
+ * - `Submit` — only after a submit attempt. Quietest; nothing moves while typing.
221
+ * - `Live` — as soon as it is invalid. Loudest; shouts at a half-typed email address.
222
+ * - `Smart` — the default, and the reason the author gets one dropdown instead of a decision per
223
+ * field: stay quiet until the visitor has either left the field or tried to submit.
224
+ * After that, correct live, so fixing an error clears it as they type.
225
+ */
226
+ declare function shouldShowError(fieldName: string, state: FormRuntimeState, timing?: FeedbackTiming | string): boolean;
227
+ /**
228
+ * Re-validate one field after a change. Only that field is re-checked, EXCEPT that a `matches` rule
229
+ * makes another field's validity depend on this one — so a confirm-email field stops being wrong
230
+ * the moment you fix the address it points at, rather than waiting for its own blur.
231
+ */
232
+ declare function onFieldChange(state: FormRuntimeState, fieldName: string, values: Record<string, unknown>, spec: FormSpec): FormRuntimeState;
233
+ /** Mark a field touched (on blur) and re-check it, so Smart timing can start showing its error. */
234
+ declare function onFieldBlur(state: FormRuntimeState, fieldName: string, values: Record<string, unknown>, spec: FormSpec): FormRuntimeState;
235
+ /**
236
+ * A submit attempt. Validates everything and flips `submitted`, so from here on every error shows
237
+ * whatever the timing setting is — a visitor who pressed the button is owed the full picture.
238
+ */
239
+ declare function onSubmitAttempt(state: FormRuntimeState, values: Record<string, unknown>, spec: FormSpec): FormRuntimeState;
240
+ /** Server-side rejection: adopt the server's errors verbatim. It is the authority, not the client. */
241
+ declare function applyServerErrors(state: FormRuntimeState, errors: Record<string, FieldError>): FormRuntimeState;
242
+ /** A clean slate after a successful submit, for a form configured to clear itself. */
243
+ declare function resetFormState(): FormRuntimeState;
244
+
245
+ export { ControlType, DEFAULT_EN_MESSAGES, FIELD_NODE_TYPE, FORM_ERROR_KEYS, FORM_NODE_TYPE, FeedbackTiming, IMPLIED_PATTERN, INITIAL_FORM_STATE, MESSAGE_NAMESPACE, MULTI_VALUE_CONTROLS, PATTERN_MESSAGE_KEYS, PATTERN_PRESETS, PatternPreset, RULE_MESSAGE_KEYS, RuleName, STORE_ACTION, applyServerErrors, collectFieldNodes, collectFormSpec, deriveFieldName, firstInvalidField, onFieldBlur, onFieldChange, onSubmitAttempt, resetFormState, shouldShowError, uniqueFieldName, validateField, validateForm };
246
+ export type { FieldError, FieldOption, FieldOptionSource, FieldResult, FieldSpec, FormNodeLike, FormResult, FormRuntimeState, FormSpec, SubmitAction, ValidationRule };
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { AfterViewInit, EventEmitter, ElementRef, SimpleChanges, OnDestroy, OnInit, Renderer2, ModuleWithProviders, InjectionToken, ChangeDetectorRef, ViewContainerRef, Type, ComponentRef } from '@angular/core';
2
+ import { AfterViewInit, EventEmitter, ElementRef, SimpleChanges, OnDestroy, OnInit, Renderer2, ModuleWithProviders, InjectionToken, ChangeDetectorRef, ViewContainerRef, OnChanges, Type, ComponentRef } from '@angular/core';
3
3
  import { AnimationPlayer, AnimationBuilder } from '@angular/animations';
4
4
  import { Observable, Subject } from 'rxjs';
5
5
  import * as i3 from '@angular/platform-browser/animations';
@@ -875,9 +875,377 @@ declare class ClientGalleryComponent implements AfterViewInit, OnDestroy {
875
875
  static ɵcmp: i0.ɵɵComponentDeclaration<ClientGalleryComponent, "iox-gallery", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "effect": { "alias": "effect"; "required": false; }; "autoStart": { "alias": "autoStart"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "images": { "alias": "images"; "required": false; }; "showDuration": { "alias": "showDuration"; "required": false; }; "fadeDuration": { "alias": "fadeDuration"; "required": false; }; }, {}, never, never, false, never>;
876
876
  }
877
877
 
878
+ /** What the visitor actually types into. Chosen by a trait; it also implies a validation rule. */
879
+ declare enum ControlType {
880
+ Text = "text",
881
+ Email = "email",
882
+ Tel = "tel",
883
+ Url = "url",
884
+ Number = "number",
885
+ Password = "password",
886
+ Textarea = "textarea",
887
+ Select = "select",
888
+ Checkbox = "checkbox",
889
+ Radio = "radio",
890
+ Date = "date",
891
+ Time = "time",
892
+ File = "file",
893
+ /** Not shown; carries a constant or a bound value (campaign, source page, …). */
894
+ Hidden = "hidden"
895
+ }
896
+ /** The v1 rule grammar. Phase 3's conditional logic reuses these same names for its conditions. */
897
+ declare enum RuleName {
898
+ Required = "required",
899
+ MinLength = "minLength",
900
+ MaxLength = "maxLength",
901
+ Min = "min",
902
+ Max = "max",
903
+ Pattern = "pattern",
904
+ /** Cross-field: this value must equal another field's (confirm email / password). */
905
+ Matches = "matches",
906
+ /** A checkbox that must be ticked — terms, consent. */
907
+ Accepted = "accepted",
908
+ FileType = "fileType",
909
+ FileSize = "fileSize"
910
+ }
911
+ interface ValidationRule {
912
+ name: RuleName;
913
+ /** `{ n }` for lengths/bounds · `{ preset } | { regex }` for pattern · `{ field }` for matches. */
914
+ params?: Record<string, any>;
915
+ /** Author's override. Absent → the shared message catalog supplies a translated key. */
916
+ message?: string;
917
+ }
918
+ interface FieldOption {
919
+ label: string;
920
+ value: string;
921
+ }
922
+ /** Options pulled from a data source instead of typed by hand (a Select of CMS categories). */
923
+ interface FieldOptionSource {
924
+ source: string;
925
+ sourcePath?: string;
926
+ valuePath: string;
927
+ labelPath: string;
928
+ }
929
+ interface FieldSpec {
930
+ /** The submitted key. Derived from the label, unique within the form, editable. */
931
+ name: string;
932
+ control: ControlType;
933
+ label: string;
934
+ /** Surfaced as its own switch in the panel rather than buried in the rule list. */
935
+ required?: boolean;
936
+ rules?: ValidationRule[];
937
+ options?: FieldOption[];
938
+ optionsSource?: FieldOptionSource;
939
+ defaultValue?: any;
940
+ }
941
+ /** When a field is validated, once the author has stopped deciding it per field. */
942
+ declare enum FeedbackTiming {
943
+ /** Validate on submit, then live per-field once that field has been touched or has failed. */
944
+ Smart = "smart",
945
+ Submit = "submit",
946
+ Live = "live"
947
+ }
948
+ /** What happens to a submission, in order. Card #1 (`store`) is always present. */
949
+ interface SubmitAction {
950
+ type: string;
951
+ config?: Record<string, any>;
952
+ /** `retry` (default) · `fail` · `ignore`. */
953
+ onFailure?: 'retry' | 'fail' | 'ignore';
954
+ }
955
+ interface FormSpec {
956
+ formId: string;
957
+ /** Author-facing name — the submissions inbox groups by it. */
958
+ name: string;
959
+ feedback: FeedbackTiming;
960
+ fields: FieldSpec[];
961
+ actions: SubmitAction[];
962
+ antiSpam: {
963
+ honeypot: boolean;
964
+ minFillMs: number;
965
+ turnstile?: boolean;
966
+ };
967
+ retention?: {
968
+ days: number;
969
+ };
970
+ }
971
+
972
+ interface FieldError {
973
+ /** i18n key, or the author's own override string when they set one. */
974
+ messageKey: string;
975
+ /** Interpolation values (`{ n: 8 }`, `{ field: 'Email' }`). */
976
+ params?: Record<string, any>;
977
+ }
978
+
979
+ /** Everything the runtime needs to remember. Immutable — each transition returns a new state. */
980
+ interface FormRuntimeState {
981
+ /** Field names the visitor has left (blurred) at least once. */
982
+ touched: ReadonlySet<string>;
983
+ /** True once a submit has been attempted — after that, every error is fair game. */
984
+ submitted: boolean;
985
+ /** The current errors, whether or not they are being shown. */
986
+ errors: Readonly<Record<string, FieldError>>;
987
+ /** In flight — the submit button shows its loading label and the form is aria-busy. */
988
+ submitting: boolean;
989
+ }
990
+
991
+ /**
992
+ * How a message KEY becomes text a visitor reads.
993
+ *
994
+ * Translation belongs to the consumer, not the library: the CMS client has ngx-translate, the SSR
995
+ * engine has the page's locale bundle. Providing this token is how each one plugs its own in. The
996
+ * default below interpolates the built-in English strings, so a consumer that provides nothing
997
+ * still shows real sentences rather than raw keys.
998
+ */
999
+ type FormMessageResolver = (key: string, params?: Record<string, any>) => string;
1000
+ /**
1001
+ * Per-form runtime. **Provided by `IoxFormComponent`**, so every Field created into that form's
1002
+ * `childrenHost` resolves THIS instance through its element injector — which is exactly how a field
1003
+ * finds its form without a form-id, matching the ancestry rule (decision D1). A Field outside any
1004
+ * form injects nothing and simply renders.
1005
+ *
1006
+ * All the decisions live in the pure `forms-core` runtime; this class only holds the mutable state,
1007
+ * the registered fields and the Angular-shaped API. Nothing here decides *when* an error shows.
1008
+ */
1009
+ declare class FormRuntimeService {
1010
+ /** Registered fields, in DOM order — the order the spec and focus-first-invalid depend on. */
1011
+ private readonly fields;
1012
+ private _state;
1013
+ private _spec;
1014
+ private _timing;
1015
+ get state(): FormRuntimeState;
1016
+ get submitting(): boolean;
1017
+ /** Set by the Form from its own traits. */
1018
+ configure(spec: FormSpec, timing: FeedbackTiming | string): void;
1019
+ /**
1020
+ * A Field announces itself here on init. It passes FUNCTIONS rather than values so the runtime
1021
+ * always reads the field's current spec and value — a trait edited on the canvas takes effect
1022
+ * without re-registering anything.
1023
+ */
1024
+ register(field: {
1025
+ spec: () => FieldSpec;
1026
+ getValue: () => any;
1027
+ }): () => void;
1028
+ /** The live spec, derived from what is registered right now. */
1029
+ specNow(): FormSpec;
1030
+ /** Current values, keyed by submitted field name. */
1031
+ values(): Record<string, any>;
1032
+ onChange(name: string): void;
1033
+ onBlur(name: string): void;
1034
+ /** Validate everything. Returns whether the submission may proceed. */
1035
+ validateAll(): boolean;
1036
+ setSubmitting(submitting: boolean): void;
1037
+ /** The server rejected it — its verdict replaces ours. */
1038
+ applyErrors(errors: Record<string, FieldError>): void;
1039
+ reset(): void;
1040
+ /** Whether this field's error is allowed on screen right now. */
1041
+ showsError(name: string): boolean;
1042
+ errorFor(name: string): FieldError | undefined;
1043
+ /** The first invalid field in registration (DOM) order — what submit should focus. */
1044
+ firstInvalidName(): string | null;
1045
+ static ɵfac: i0.ɵɵFactoryDeclaration<FormRuntimeService, never>;
1046
+ static ɵprov: i0.ɵɵInjectableDeclaration<FormRuntimeService>;
1047
+ }
1048
+
1049
+ /** Which of the form's four states the canvas / runtime is showing. */
1050
+ declare enum FormRenderState {
1051
+ Idle = "idle",
1052
+ Submitting = "submitting",
1053
+ Success = "success",
1054
+ Error = "error"
1055
+ }
1056
+ /**
1057
+ * Directive-host Form: the real `<form>` IS the host — no wrapper, no inner/outer split. Children
1058
+ * (fields, layout, the submit button, and the two state blocks) render into it via `childrenHost`.
1059
+ *
1060
+ * Scope is ANCESTRY, not naming (decision D1): a Field belongs to its nearest ancestor Form, so
1061
+ * there is no form-id to pick and nothing to mis-wire. The runtime finds its fields by walking the
1062
+ * DOM it owns.
1063
+ *
1064
+ * `renderState` drives which children are visible. In the builder it is set by the canvas state
1065
+ * switcher so an author can DESIGN the success and error blocks; at runtime the same input is
1066
+ * driven by the submit lifecycle. One mechanism, two drivers — the author designs exactly what a
1067
+ * visitor will see.
1068
+ *
1069
+ * ⚠️ `novalidate` is deliberate: the browser's native bubbles would pre-empt our own messages,
1070
+ * which are styleable, translated and announced. Validation still runs — ours does it.
1071
+ */
1072
+ declare class IoxFormComponent implements OnChanges {
1073
+ private readonly runtime;
1074
+ private readonly host;
1075
+ nodeId: string;
1076
+ /** Stable id the submit endpoint resolves the saved spec by. */
1077
+ formId: string;
1078
+ /** Author-facing name — what the submissions inbox groups by. */
1079
+ name: string;
1080
+ renderState: FormRenderState | string;
1081
+ feedback: FeedbackTiming | string;
1082
+ /**
1083
+ * Emitted ONLY when client-side validation passes, carrying the collected values. The host
1084
+ * (builder canvas or engine runtime) owns the transport — posting, retries and the server's
1085
+ * verdict — so the same component serves both renderers.
1086
+ */
1087
+ formSubmit: EventEmitter<{
1088
+ values: Record<string, any>;
1089
+ event: Event;
1090
+ }>;
1091
+ /** Emitted when a submit attempt was refused locally, so a host can react (analytics, focus). */
1092
+ validationFailed: EventEmitter<Record<string, any>>;
1093
+ childrenHost: ViewContainerRef;
1094
+ /**
1095
+ * Constructor injection rather than `inject()`, for the same reason as Field: this library's
1096
+ * specs construct components directly. `runtime` is provided by THIS component (see
1097
+ * `providers`), so every Field created into `childrenHost` resolves this instance by ancestry.
1098
+ */
1099
+ constructor(runtime: FormRuntimeService, host: ElementRef<HTMLElement>);
1100
+ ngOnChanges(): void;
1101
+ onSubmit(event: Event): void;
1102
+ private focusFirstInvalid;
1103
+ static ɵfac: i0.ɵɵFactoryDeclaration<IoxFormComponent, never>;
1104
+ static ɵcmp: i0.ɵɵComponentDeclaration<IoxFormComponent, "form[iox-form]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "formId": { "alias": "formId"; "required": false; }; "name": { "alias": "name"; "required": false; }; "renderState": { "alias": "renderState"; "required": false; }; "feedback": { "alias": "feedback"; "required": false; }; }, { "formSubmit": "formSubmit"; "validationFailed": "validationFailed"; }, never, never, false, never>;
1105
+ }
1106
+
1107
+ /**
1108
+ * The compound Field: label + control + help + error + required mark, as ONE node (decision D2).
1109
+ *
1110
+ * This is the biggest divergence from Webflow, and it is deliberate. There, a form field is four
1111
+ * loose elements an author can delete — and they do delete the label, which breaks the
1112
+ * `for`/`id` pairing and with it screen-reader support. Here the structure is fixed and
1113
+ * accessibility is guaranteed by construction: the label can be visually hidden, never removed.
1114
+ *
1115
+ * The PARTS are styled through the virtual-trait mechanism (`__labelStyles`, `__errorStyles`, …)
1116
+ * that already compiles `::marker` rules for List — so per-part styling invents no new concept in
1117
+ * the style engine. Each part carries a stable class the compiler targets.
1118
+ *
1119
+ * ⚠️ Control type is a TRAIT, not a component per type (decision D4) — one component, one config,
1120
+ * and choosing `email` also chooses email validation.
1121
+ */
1122
+ declare class IoxFieldComponent implements OnInit, OnDestroy {
1123
+ private readonly runtime;
1124
+ private readonly resolveMessage;
1125
+ nodeId: string;
1126
+ /** The submitted key. Blank means "derive it from the label" — authors never invent keys. */
1127
+ name: string;
1128
+ label: string;
1129
+ control: ControlType | string;
1130
+ placeholder: string;
1131
+ help: string;
1132
+ required: boolean;
1133
+ disabled: boolean;
1134
+ labelHidden: boolean;
1135
+ requiredMark: string;
1136
+ rows: number;
1137
+ accept: string;
1138
+ options: FieldOption[];
1139
+ value: any;
1140
+ /** Rules beyond `required` — carried on the node, interpreted by forms-core. */
1141
+ rules: ValidationRule[];
1142
+ /**
1143
+ * Forces the error appearance without a real failure — how the builder lets an author DESIGN
1144
+ * the error state (decision D5). At runtime the state comes from the runtime service instead.
1145
+ */
1146
+ forceInvalid: boolean;
1147
+ /** Placeholder shown while designing the error state, so the block has something to style. */
1148
+ designErrorText: string;
1149
+ /** Only after a successful check — never on an untouched field. */
1150
+ showValid: boolean;
1151
+ valueChange: EventEmitter<any>;
1152
+ touched: EventEmitter<void>;
1153
+ /** Stable per instance so `for`/`id` and `aria-describedby` always pair up. */
1154
+ readonly controlId: string;
1155
+ private unregister?;
1156
+ /**
1157
+ * Classic constructor injection, not `inject()`: this library's specs construct components
1158
+ * directly (its vitest setup cannot run `TestBed.createComponent`), and a field initializer
1159
+ * calling `inject()` throws NG0203 outside an injection context.
1160
+ *
1161
+ * `runtime` is optional because a Field dropped OUTSIDE any Form must still render — it simply
1162
+ * has nothing to submit to. That is the same ancestry rule from the other side.
1163
+ */
1164
+ constructor(runtime: FormRuntimeService | null, resolveMessage: FormMessageResolver);
1165
+ ngOnInit(): void;
1166
+ ngOnDestroy(): void;
1167
+ /** The submitted key: the author's override, else derived from the label. */
1168
+ get fieldName(): string;
1169
+ /** Failing AND allowed to say so — or forced, while an author designs the state. */
1170
+ get invalid(): boolean;
1171
+ /** The message a visitor reads. Translation is the consumer's, via IOX_FORM_MESSAGES. */
1172
+ get errorText(): string;
1173
+ private toSpec;
1174
+ /** `file`, `date`, `number`… map straight through; everything else is a text input. */
1175
+ get inputType(): string;
1176
+ /** Help and error are BOTH announced, in that order, when both are present. */
1177
+ get describedBy(): string | null;
1178
+ emit(value: any): void;
1179
+ touch(): void;
1180
+ static ɵfac: i0.ɵɵFactoryDeclaration<IoxFieldComponent, [{ optional: true; }, null]>;
1181
+ static ɵcmp: i0.ɵɵComponentDeclaration<IoxFieldComponent, "div[iox-field]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "name": { "alias": "name"; "required": false; }; "label": { "alias": "label"; "required": false; }; "control": { "alias": "control"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "help": { "alias": "help"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "labelHidden": { "alias": "labelHidden"; "required": false; }; "requiredMark": { "alias": "requiredMark"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "accept": { "alias": "accept"; "required": false; }; "options": { "alias": "options"; "required": false; }; "value": { "alias": "value"; "required": false; }; "rules": { "alias": "rules"; "required": false; }; "forceInvalid": { "alias": "forceInvalid"; "required": false; }; "designErrorText": { "alias": "designErrorText"; "required": false; }; "showValid": { "alias": "showValid"; "required": false; }; }, { "valueChange": "valueChange"; "touched": "touched"; }, never, never, false, never>;
1182
+ }
1183
+
1184
+ /**
1185
+ * Directive-host SubmitButton: the real `<button type="submit">` IS the host.
1186
+ *
1187
+ * It carries no destination configuration of its own — "what happens with the data" is an ordered
1188
+ * action list on the FORM (decision D9), so there is nothing here to wire and nothing to get out of
1189
+ * sync. The button owns only its own appearance and its busy state.
1190
+ *
1191
+ * While submitting it shows `loadingLabel` and is disabled, which is the whole double-submit
1192
+ * defence on the client side (the server's rate limit is the real one).
1193
+ */
1194
+ declare class IoxSubmitButtonComponent {
1195
+ nodeId: string;
1196
+ label: string;
1197
+ loadingLabel: string;
1198
+ disableWhileSubmitting: boolean;
1199
+ /** Driven by the form's lifecycle, not by the author. */
1200
+ submitting: boolean;
1201
+ static ɵfac: i0.ɵɵFactoryDeclaration<IoxSubmitButtonComponent, never>;
1202
+ static ɵcmp: i0.ɵɵComponentDeclaration<IoxSubmitButtonComponent, "button[iox-submit]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "label": { "alias": "label"; "required": false; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; }; "disableWhileSubmitting": { "alias": "disableWhileSubmitting"; "required": false; }; "submitting": { "alias": "submitting"; "required": false; }; }, {}, never, never, false, never>;
1203
+ }
1204
+
1205
+ /**
1206
+ * The Success and Error blocks — real, fully styleable container nodes that the Form auto-creates
1207
+ * and the author cannot delete (decision D7). Hiding one is allowed; removing it is not, because
1208
+ * "the author deleted the success block and the form went quiet" is Webflow's commonest form
1209
+ * failure and we designed it out.
1210
+ *
1211
+ * ⚠️ VISIBILITY IS NOT AN INPUT. Which block shows is decided by CSS keyed on the parent form's
1212
+ * `data-iox-state` attribute (see `iox-form-states.css` / the engine's `styles.scss`):
1213
+ *
1214
+ * .iox-form-success { display: none }
1215
+ * .iox-form[data-iox-state="success"] .iox-form-success { display: block }
1216
+ *
1217
+ * That is deliberate. It means the builder's state switcher and the runtime's submit lifecycle
1218
+ * drive the SAME mechanism through one attribute, with no input plumbing down the tree and no
1219
+ * chance of the canvas and the live site disagreeing about what a visitor sees. The selector
1220
+ * out-specifies `.iox-node-{id}`, so the state machine owns visibility and the author owns
1221
+ * everything else about the block.
1222
+ */
1223
+ declare class IoxFormSuccessComponent {
1224
+ nodeId: string;
1225
+ childrenHost: ViewContainerRef;
1226
+ static ɵfac: i0.ɵɵFactoryDeclaration<IoxFormSuccessComponent, never>;
1227
+ static ɵcmp: i0.ɵɵComponentDeclaration<IoxFormSuccessComponent, "div[iox-form-success]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; }, {}, never, never, false, never>;
1228
+ }
1229
+ /**
1230
+ * The Error block. One design, five reasons: the renderer writes the resolved reason text into
1231
+ * `message`, so an author designs the block once and every failure mode (network, rejected, spam,
1232
+ * rate-limited, server) renders through it.
1233
+ *
1234
+ * `role="alert"` rather than `status`: a failed submit must interrupt, because the visitor is
1235
+ * about to walk away believing they sent it.
1236
+ */
1237
+ declare class IoxFormErrorComponent {
1238
+ nodeId: string;
1239
+ /** Already-translated reason. Resolving the key is the host's job. */
1240
+ message: string;
1241
+ childrenHost: ViewContainerRef;
1242
+ static ɵfac: i0.ɵɵFactoryDeclaration<IoxFormErrorComponent, never>;
1243
+ static ɵcmp: i0.ɵɵComponentDeclaration<IoxFormErrorComponent, "div[iox-form-error]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "message": { "alias": "message"; "required": false; }; }, {}, never, never, false, never>;
1244
+ }
1245
+
878
1246
  declare class IoxBuilderComponentsModule {
879
1247
  static ɵfac: i0.ɵɵFactoryDeclaration<IoxBuilderComponentsModule, never>;
880
- static ɵmod: i0.ɵɵNgModuleDeclaration<IoxBuilderComponentsModule, [typeof BuilderImageComponent, typeof BuilderSpacerComponent, typeof CardComponent, typeof BuilderDividerComponent, typeof BuilderIconComponent, typeof BuilderLinkComponent, typeof BuilderButtonComponent, typeof BuilderHeadingComponent, typeof TextBlockComponent, typeof SectionComponent, typeof ContainerComponent, typeof LinkedContainerComponent, typeof ClientRepeaterComponent, typeof ButtonBlockComponent, typeof ClientSliderContainerComponent, typeof ClientSliderSlideComponent, typeof ClientListComponent, typeof ClientListItemComponent, typeof ClientGalleryComponent], [typeof i2.CommonModule], [typeof BuilderImageComponent, typeof BuilderSpacerComponent, typeof CardComponent, typeof BuilderDividerComponent, typeof BuilderIconComponent, typeof BuilderLinkComponent, typeof BuilderButtonComponent, typeof BuilderHeadingComponent, typeof TextBlockComponent, typeof SectionComponent, typeof ContainerComponent, typeof LinkedContainerComponent, typeof ClientRepeaterComponent, typeof ButtonBlockComponent, typeof ClientSliderContainerComponent, typeof ClientSliderSlideComponent, typeof ClientListComponent, typeof ClientListItemComponent, typeof ClientGalleryComponent]>;
1248
+ static ɵmod: i0.ɵɵNgModuleDeclaration<IoxBuilderComponentsModule, [typeof BuilderImageComponent, typeof BuilderSpacerComponent, typeof CardComponent, typeof BuilderDividerComponent, typeof BuilderIconComponent, typeof BuilderLinkComponent, typeof BuilderButtonComponent, typeof BuilderHeadingComponent, typeof TextBlockComponent, typeof SectionComponent, typeof ContainerComponent, typeof LinkedContainerComponent, typeof ClientRepeaterComponent, typeof ButtonBlockComponent, typeof ClientSliderContainerComponent, typeof ClientSliderSlideComponent, typeof ClientListComponent, typeof ClientListItemComponent, typeof ClientGalleryComponent, typeof IoxFormComponent, typeof IoxFieldComponent, typeof IoxSubmitButtonComponent, typeof IoxFormSuccessComponent, typeof IoxFormErrorComponent], [typeof i2.CommonModule], [typeof BuilderImageComponent, typeof BuilderSpacerComponent, typeof CardComponent, typeof BuilderDividerComponent, typeof BuilderIconComponent, typeof BuilderLinkComponent, typeof BuilderButtonComponent, typeof BuilderHeadingComponent, typeof TextBlockComponent, typeof SectionComponent, typeof ContainerComponent, typeof LinkedContainerComponent, typeof ClientRepeaterComponent, typeof ButtonBlockComponent, typeof ClientSliderContainerComponent, typeof ClientSliderSlideComponent, typeof ClientListComponent, typeof ClientListItemComponent, typeof ClientGalleryComponent, typeof IoxFormComponent, typeof IoxFieldComponent, typeof IoxSubmitButtonComponent, typeof IoxFormSuccessComponent, typeof IoxFormErrorComponent]>;
881
1249
  static ɵinj: i0.ɵɵInjectorDeclaration<IoxBuilderComponentsModule>;
882
1250
  }
883
1251
 
@@ -2002,5 +2370,5 @@ declare class GalleryLoop {
2002
2370
  private emit;
2003
2371
  }
2004
2372
 
2005
- export { AOSService, AnalyticsService, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, ENVIRONMENT, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, IOX_BUILDER_EVENTS, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxPageComponent, IoxPageModule, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, effectiveTransitionId, excludeSelf, feelFor, getByPath, initialSlotValues, isActionEnabled, isContextAction, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, parentBreakpoint, parseUrlList, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, stateNamesIn, stripSuppressedProps, styleKeyToKebab, variableAliases, variableItemsFrom, withContextSlots, wrapInBreakpointQuery, wrapInMediaQuery };
2373
+ export { AOSService, AnalyticsService, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, ENVIRONMENT, FormRenderState, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, IOX_BUILDER_EVENTS, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, effectiveTransitionId, excludeSelf, feelFor, getByPath, initialSlotValues, isActionEnabled, isContextAction, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, parentBreakpoint, parseUrlList, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, stateNamesIn, stripSuppressedProps, styleKeyToKebab, variableAliases, variableItemsFrom, withContextSlots, wrapInBreakpointQuery, wrapInMediaQuery };
2006
2374
  export type { BreakpointDef, BuildRelatedFilterOptions, ContextActionEffect, ContextActionLike, ContextItemRef, ContextSlotDefault, ContextValueSpec, ContextWriteScope, DataSourceDomain, DataSourceEndpoints, DataSourceMode, DataSourcePlan, DataSourceQueryFilter, DataSourceRequest, DataSourceRequestSpec, DataSourceRouteFilter, DataSourceSpec, GalleryBoundSource, GalleryDurations, GalleryEffect, GalleryEffectDescriptor, GalleryImage, GalleryLoopOptions, GalleryLoopScheduler, GalleryLoopState, GallerySlideState, IBuilderEventEmitter, InputMap, IoxContextSlot, IoxPipe, OverrideBreakpoint, PageTransitionCategory, PageTransitionCategoryMeta, PageTransitionOptions, PageTransitionPreset, PipeArgSpec, PipeContext, PipeDescriptor, RelativeInputs, RelativeSourceKind, RelativeSourceSpec, ResolveSiblingsOptions, ResolvedPageTransition, ResponsiveLayer, ResponsiveOverrides, ResponsiveRuleSet, RouteContext, SetContextParams, SiblingsResult, StateStyleMap, StyleMap, StyleTreeNode, SwiperBreakpointMap, ToggleableAction, TransitionFeel, TransitionPhase, TransitionTimelineInput, ValueSource, VirtualTraitGroup };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectoriox/iox-ui",
3
- "version": "4.27.0",
3
+ "version": "4.29.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=20.0.0",
6
6
  "@angular/core": ">=20.0.0",