@sonordev/site-kit 7.1.2 → 7.2.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.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +51 -0
- package/README.md +9 -8
- package/agent-manifest.json +12 -4
- package/dist/{AnalyticsProvider-ZB33W6MC.js → AnalyticsProvider-SLFFBRPE.js} +4 -4
- package/dist/{ArticleViewTracker-GMHYLLLZ.js → ArticleViewTracker-TM5AMGN2.js} +3 -3
- package/dist/{BlocksPopup-EA6LYL25.js → BlocksPopup-YJNJIVPO.js} +5 -5
- package/dist/ChatWidget-XKOSH66S.js +17 -0
- package/dist/{FileField-QKA3JB2Q.js → FileField-CI4UL5SH.js} +3 -3
- package/dist/{FormSpotlight-AQTIA5TP.js → FormSpotlight-F2AAEGBN.js} +20 -6
- package/dist/{FormStage-FDTLTP3B.js → FormStage-BI5R5CNC.js} +27 -7
- package/dist/ManagedForm-G6COGHXL.js +16 -0
- package/dist/{ManagedNewsletterForm-J6QSAGGP.js → ManagedNewsletterForm-BO3WCGXX.js} +7 -5
- package/dist/{SignalCore-JZNXOLNT.js → SignalCore-ZA6WHKBR.js} +3 -3
- package/dist/SiteChat-YJADDTKG.js +5 -0
- package/dist/{SiteDesignReporter-W4EJUSTE.js → SiteDesignReporter-5YAW36AQ.js} +5 -5
- package/dist/SitePopups-ST5PMKZE.js +10 -0
- package/dist/SitemapSync-RJTEBINX.js +8 -0
- package/dist/_client/booking-widget.js +5 -5
- package/dist/affiliates/index.js +3 -3
- package/dist/analytics/index.js +4 -4
- package/dist/analytics/send-gate.d.ts +1 -1
- package/dist/articles/index.js +2 -2
- package/dist/articles/server-ui.js +3 -2
- package/dist/articles/server.js +2 -1
- package/dist/{engage → chat}/ChatWidget.d.ts +7 -6
- package/dist/{engage → chat}/EchoUiActions.d.ts +1 -1
- package/dist/chat/SiteChat.d.ts +25 -0
- package/dist/{engage → chat}/brand-color.d.ts +1 -1
- package/dist/{engage → chat}/chat-messages.d.ts +1 -1
- package/dist/{engage → chat}/echo-config.d.ts +1 -1
- package/dist/chat/index.d.ts +10 -6
- package/dist/chat/index.js +14 -8
- package/dist/{engage → chat}/launcher-placement.d.ts +1 -7
- package/dist/{engage → chat}/socket-loader.d.ts +2 -2
- package/dist/chat/types.d.ts +136 -0
- package/dist/chunk-27FISYK4.js +4 -0
- package/dist/{chunk-LUXVWITO.js → chunk-4NTBQNHA.js} +247 -78
- package/dist/{chunk-V3PUVBME.js → chunk-5V2V5C3Y.js} +2 -4
- package/dist/{chunk-Q4W23JYM.js → chunk-5YCEMV2L.js} +1 -1
- package/dist/{chunk-RHNWA34F.js → chunk-64DKGVEI.js} +41 -7
- package/dist/{chunk-GLHQ3LRO.js → chunk-6U3VLV2C.js} +1 -1
- package/dist/{chunk-WWSHFRDL.js → chunk-BC4Y3S3D.js} +1 -1
- package/dist/{chunk-JSZN6LDZ.js → chunk-BF7TZYC3.js} +38 -31
- package/dist/{chunk-M3YEPKP7.js → chunk-BKY2ZNM7.js} +1 -1
- package/dist/{chunk-AQSNPZY4.js → chunk-C2FZBUSS.js} +80 -1
- package/dist/{chunk-NK4CSJNP.js → chunk-CF5QNFYU.js} +2 -2
- package/dist/{chunk-D5EC5KVO.js → chunk-D5DCBD4Y.js} +2 -2
- package/dist/{chunk-3SDOQUUF.js → chunk-D6ZC7XKZ.js} +2 -2
- package/dist/chunk-EJVQJCG5.js +370 -0
- package/dist/{chunk-AH5Q262S.js → chunk-F24FNCTK.js} +1 -1
- package/dist/{chunk-V6FDQLR7.js → chunk-FR6BYFPC.js} +53 -21
- package/dist/{chunk-UXOGCKL6.js → chunk-GEXT7BTE.js} +1 -1
- package/dist/{chunk-JTU2GOM4.js → chunk-GGORNBSC.js} +18 -6
- package/dist/{chunk-ERXXITG4.js → chunk-HGFAEDG3.js} +1 -1
- package/dist/chunk-HODO5BX5.js +28 -0
- package/dist/chunk-HW7B43E5.js +14 -0
- package/dist/{chunk-CSTQDNGK.js → chunk-IAM3D3RL.js} +43 -24
- package/dist/{chunk-PGMVL4AB.js → chunk-JJ3DELUL.js} +2 -2
- package/dist/{chunk-ILU5I6RW.js → chunk-JMLK6MH7.js} +1 -1
- package/dist/{chunk-YEMPUQVU.js → chunk-JWTQS5F5.js} +2 -2
- package/dist/{chunk-VDF5DFWT.js → chunk-K4ZHAURD.js} +1 -1
- package/dist/chunk-NV72HZ4W.js +45 -0
- package/dist/{chunk-4Y5FWDPM.js → chunk-NZ4RXN3G.js} +55 -7
- package/dist/chunk-OWZ7ATLZ.js +187 -0
- package/dist/{chunk-TXBAOEKG.js → chunk-PKGN32AU.js} +5 -4
- package/dist/chunk-Q6E4OPGG.js +40 -0
- package/dist/{chunk-QEDHRBAT.js → chunk-QL6XNPSD.js} +2 -2
- package/dist/{chunk-JBE46QJZ.js → chunk-R46IQIGK.js} +1 -1
- package/dist/{chunk-6WIQCXOO.js → chunk-RPZ7OQGD.js} +1 -1
- package/dist/{chunk-PHYMNUJU.js → chunk-S54ECQGY.js} +1 -1
- package/dist/{chunk-VGH4MDTU.js → chunk-VHKEF5ZB.js} +1 -1
- package/dist/{chunk-HF57LG73.js → chunk-VO3JYRT5.js} +43 -29
- package/dist/chunk-VWWITFWM.js +300 -0
- package/dist/{chunk-CIG5UL2S.js → chunk-ZTLMPUO6.js} +3 -2
- package/dist/client/index.js +3 -3
- package/dist/commerce/index.js +4 -4
- package/dist/contracts/color.d.ts +1 -1
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/contracts/error-page.d.ts +183 -0
- package/dist/contracts/llms.d.ts +1 -0
- package/dist/contracts/proposal-sitemap.d.ts +130 -0
- package/dist/contracts/schema-placeholders.d.ts +87 -0
- package/dist/engage/EngageWidget.d.ts +13 -12
- package/dist/engage/index.d.ts +10 -9
- package/dist/engage/index.js +31 -35
- package/dist/engage/types.d.ts +19 -244
- package/dist/fleet/FleetHeartbeat.d.ts +1 -1
- package/dist/fleet/index.js +4 -4
- package/dist/forms/FormEnhancer.d.ts +25 -12
- package/dist/forms/ServerForm.d.ts +11 -10
- package/dist/forms/StaticForm.d.ts +3 -1
- package/dist/forms/field-autocomplete.d.ts +28 -0
- package/dist/forms/form-dom-values.d.ts +42 -0
- package/dist/forms/index.js +11 -9
- package/dist/forms/server.js +6 -4
- package/dist/forms/static.js +3 -2
- package/dist/forms/submitForm.d.ts +8 -1
- package/dist/forms/types.d.ts +41 -2
- package/dist/forms/useForm.d.ts +21 -4
- package/dist/forms/webmcp.d.ts +38 -0
- package/dist/images/index.js +4 -4
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/layout/SiteKitClientProviders.d.ts +3 -3
- package/dist/layout/SiteKitLayout.d.ts +4 -4
- package/dist/layout/client.d.ts +3 -3
- package/dist/layout/client.js +7 -7
- package/dist/layout/index.js +8 -8
- package/dist/layout/types.d.ts +5 -4
- package/dist/llms/contract.js +1 -1
- package/dist/llms/index.js +6 -6
- package/dist/maps/index.js +3 -3
- package/dist/mcp/index.js +2 -14
- package/dist/mcp/sonor.js +14 -11
- package/dist/revalidate/index.js +2 -2
- package/dist/seo/client.js +4 -4
- package/dist/seo/index.js +15 -8
- package/dist/seo/llms/contract.js +1 -1
- package/dist/seo/llms.js +6 -6
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/sitemap.js +4 -4
- package/dist/server/index.js +2 -2
- package/dist/shared/dialog.d.ts +27 -0
- package/dist/shared/identity.d.ts +1 -1
- package/dist/shared/layers.d.ts +7 -0
- package/dist/shared/mid-form.d.ts +53 -0
- package/dist/shared/reporting-gate.d.ts +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/visual-viewport-gap.d.ts +1 -1
- package/dist/signal/index.js +2 -2
- package/dist/signal/types.d.ts +1 -1
- package/dist/sitemap/index.js +4 -4
- package/dist/{socket-loader-R24ZSRSQ.js → socket-loader-CGIPEG74.js} +1 -1
- package/dist/sync/index.js +5 -5
- package/dist/types.d.ts +3 -1
- package/dist/{web-vitals.attribution-GD6LGLVF.js → web-vitals.attribution-N2PCCF4Q.js} +1 -1
- package/dist/website/BlocksPopup.d.ts +1 -1
- package/dist/website/PopupBlocks.d.ts +5 -2
- package/dist/website/SitePopups.d.ts +25 -0
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +6 -6
- package/dist/website/popup-rules.d.ts +46 -0
- package/dist/website/popup-types.d.ts +113 -0
- package/dist/website/popups.d.ts +2 -6
- package/dist/website/popups.js +6 -14
- package/dist/{writeLLMsTxt-G3JBNBC5.js → writeLLMsTxt-OV24LQVL.js} +3 -3
- package/docs/MIGRATING-TO-7.md +41 -9
- package/docs.json +2 -1
- package/package.json +2 -2
- package/src/analytics/README.md +2 -2
- package/src/articles/README.md +4 -1
- package/src/{engage → chat}/README.md +63 -62
- package/src/forms/README.md +49 -3
- package/src/layout/README.md +8 -5
- package/src/seo/README.md +3 -1
- package/src/sync/README.md +10 -0
- package/src/website/README.md +133 -0
- package/dist/ChatWidget-UCDWMWCW.js +0 -15
- package/dist/EngageWidget-7ZYSK4GE.js +0 -11
- package/dist/ManagedForm-H7BVAH2W.js +0 -14
- package/dist/SitemapSync-XBANGKHZ.js +0 -8
- package/dist/chunk-NDF4A5JM.js +0 -37
- package/dist/chunk-VLARKWZU.js +0 -100
- package/dist/chunk-YCJT4JJG.js +0 -837
- package/dist/engage/DesignRenderer.d.ts +0 -57
- package/dist/engage/element-rules.d.ts +0 -38
package/dist/engage/types.d.ts
CHANGED
|
@@ -1,254 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @sonordev/site-kit/engage
|
|
2
|
+
* @sonordev/site-kit/engage types: deprecated, kept through 7.x so old
|
|
3
|
+
* imports compile. Engage was retired in Sonor. Chat types live in
|
|
4
|
+
* `@sonordev/site-kit/chat`, popup types in `@sonordev/site-kit/website/popups`.
|
|
5
|
+
* Nothing here has runtime code. Removed in 8.0.
|
|
3
6
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
updated_at: string;
|
|
19
|
-
/**
|
|
20
|
-
* Website → Popups & Banners: the popup as blocks, drawn in the site's own
|
|
21
|
-
* design by PopupBlocks. Sent alongside design_json, which older site-kits
|
|
22
|
-
* still draw; a site-kit that knows blocks prefers them.
|
|
23
|
-
*/
|
|
24
|
-
blocks?: PopupBlock[];
|
|
25
|
-
/**
|
|
26
|
-
* Where a blocks popup sits. `type`/`config` describe it for older kits
|
|
27
|
-
* (which can't pin a bar to the bottom); this says what it actually is.
|
|
28
|
-
*/
|
|
29
|
-
layout?: {
|
|
30
|
-
placement: 'popup' | 'bar' | 'slide-in';
|
|
31
|
-
edge?: 'top' | 'bottom';
|
|
32
|
-
corner?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
33
|
-
/** The popup's own accent, over the site's. */
|
|
34
|
-
accent?: string;
|
|
35
|
-
};
|
|
36
|
-
design_json?: DesignDocument;
|
|
37
|
-
compiled_bundle_url?: string;
|
|
38
|
-
status?: 'draft' | 'published' | 'archived' | 'paused';
|
|
39
|
-
}
|
|
40
|
-
export interface WidgetConfig {
|
|
41
|
-
/** Visual style */
|
|
42
|
-
theme?: 'light' | 'dark' | 'custom';
|
|
43
|
-
position?: 'center' | 'top' | 'bottom' | 'left' | 'right' | 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
44
|
-
/** Content */
|
|
45
|
-
title?: string;
|
|
46
|
-
message?: string;
|
|
47
|
-
imageUrl?: string;
|
|
48
|
-
/** CTA */
|
|
49
|
-
ctaText?: string;
|
|
50
|
-
ctaUrl?: string;
|
|
51
|
-
ctaAction?: 'link' | 'close' | 'form' | 'chat';
|
|
52
|
-
/** Form (if ctaAction is 'form') */
|
|
53
|
-
formId?: string;
|
|
54
|
-
/** Styling */
|
|
55
|
-
backgroundColor?: string;
|
|
56
|
-
textColor?: string;
|
|
57
|
-
ctaBackgroundColor?: string;
|
|
58
|
-
ctaTextColor?: string;
|
|
59
|
-
borderRadius?: number;
|
|
60
|
-
/** Behavior */
|
|
61
|
-
closable?: boolean;
|
|
62
|
-
showOverlay?: boolean;
|
|
63
|
-
overlayOpacity?: number;
|
|
64
|
-
}
|
|
65
|
-
export interface TargetingRules {
|
|
66
|
-
/** Page targeting */
|
|
67
|
-
pages?: {
|
|
68
|
-
include?: string[];
|
|
69
|
-
exclude?: string[];
|
|
70
|
-
};
|
|
71
|
-
/** Device targeting */
|
|
72
|
-
devices?: ('desktop' | 'mobile' | 'tablet')[];
|
|
73
|
-
/** Visitor targeting */
|
|
74
|
-
visitor?: {
|
|
75
|
-
type?: 'new' | 'returning' | 'all';
|
|
76
|
-
minSessions?: number;
|
|
77
|
-
maxSessions?: number;
|
|
78
|
-
};
|
|
79
|
-
/** Source targeting */
|
|
80
|
-
source?: {
|
|
81
|
-
utm_source?: string[];
|
|
82
|
-
utm_medium?: string[];
|
|
83
|
-
utm_campaign?: string[];
|
|
84
|
-
referrer?: string[];
|
|
85
|
-
};
|
|
86
|
-
/** Time targeting */
|
|
87
|
-
schedule?: {
|
|
88
|
-
startDate?: string;
|
|
89
|
-
endDate?: string;
|
|
90
|
-
daysOfWeek?: number[];
|
|
91
|
-
startTime?: string;
|
|
92
|
-
endTime?: string;
|
|
93
|
-
timezone?: string;
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
export interface TriggerConfig {
|
|
97
|
-
type: 'immediate' | 'delay' | 'scroll' | 'exit-intent' | 'click' | 'custom';
|
|
98
|
-
/** Delay in seconds (for 'delay' type) */
|
|
99
|
-
delay?: number;
|
|
100
|
-
/** Scroll percentage (for 'scroll' type) */
|
|
101
|
-
scrollPercentage?: number;
|
|
102
|
-
/** CSS selector (for 'click' type) */
|
|
103
|
-
clickSelector?: string;
|
|
104
|
-
/** Custom event name (for 'custom' type) */
|
|
105
|
-
customEvent?: string;
|
|
106
|
-
/** Frequency capping */
|
|
107
|
-
frequency?: {
|
|
108
|
-
type: 'always' | 'once' | 'once-per-session' | 'every-n-days';
|
|
109
|
-
days?: number;
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/** The corner the Echo chat launcher sits in. */
|
|
113
|
-
export type ChatLauncherPosition = 'bottom-right' | 'bottom-left';
|
|
114
|
-
/**
|
|
115
|
-
* Where the Echo chat launcher sits, including the layer it stacks on. The
|
|
116
|
-
* single definition of launcher placement: EngageConfig (here and in
|
|
117
|
-
* `@sonordev/site-kit/layout`), EngageWidget's props and ChatConfig all
|
|
118
|
-
* extend it, so a new placement option is added once. ChatWidget turns it
|
|
119
|
-
* into styles through `chatLauncherStyles` (./launcher-placement).
|
|
120
|
-
*/
|
|
121
|
-
export interface ChatLauncherPlacement {
|
|
122
|
-
/** Corner. Default: 'bottom-right' */
|
|
123
|
-
position?: ChatLauncherPosition;
|
|
124
|
-
/**
|
|
125
|
-
* Distance from the bottom of the viewport to the launcher, as any CSS
|
|
126
|
-
* length (`'88px'`, `'5.5rem'`, `'calc(4rem + 8px)'`). A number is pixels.
|
|
127
|
-
* Default: `'20px'`.
|
|
128
|
-
*
|
|
129
|
-
* The device's safe-area inset is added on top, so pass the clearance you
|
|
130
|
-
* want above your own UI, not the inset. The chat popup opens above the
|
|
131
|
-
* launcher wherever this puts it.
|
|
132
|
-
*
|
|
133
|
-
* A `--sk-echo-offset-bottom` custom property set anywhere above the
|
|
134
|
-
* launcher (`:root`, `body`, a media query, a `:has()` rule) wins over this
|
|
135
|
-
* value. Use that when the offset depends on the page or the breakpoint,
|
|
136
|
-
* such as clearing a sticky bar that only some pages render.
|
|
137
|
-
*/
|
|
138
|
-
offsetBottom?: string | number;
|
|
139
|
-
/**
|
|
140
|
-
* Stacking layer. The launcher sits on it and the chat popup one layer
|
|
141
|
-
* beneath. Default: 9999.
|
|
142
|
-
*
|
|
143
|
-
* On EngageConfig and EngageWidget the same number also stacks popups,
|
|
144
|
-
* nudges and bars, so everything Engage renders shares one layer. Lower it
|
|
145
|
-
* when the site's own fixed UI (a mobile menu, a cookie banner) has to
|
|
146
|
-
* cover the chat.
|
|
147
|
-
*/
|
|
148
|
-
zIndex?: number;
|
|
149
|
-
}
|
|
150
|
-
export interface ChatConfig extends ChatLauncherPlacement {
|
|
151
|
-
/** Widget position */
|
|
152
|
-
position: ChatLauncherPosition;
|
|
153
|
-
/** Widget appearance */
|
|
154
|
-
buttonIcon?: 'chat' | 'help' | 'custom';
|
|
155
|
-
buttonColor?: string;
|
|
156
|
-
buttonText?: string;
|
|
157
|
-
/** Brand primary color */
|
|
158
|
-
brandPrimary?: string;
|
|
159
|
-
/** Welcome message */
|
|
160
|
-
welcomeMessage?: string;
|
|
161
|
-
/** Operating hours */
|
|
162
|
-
operatingHours?: {
|
|
163
|
-
enabled: boolean;
|
|
164
|
-
timezone: string;
|
|
165
|
-
hours: {
|
|
166
|
-
[day: number]: {
|
|
167
|
-
start: string;
|
|
168
|
-
end: string;
|
|
169
|
-
} | null;
|
|
170
|
-
};
|
|
171
|
-
};
|
|
172
|
-
/** AI vs Live Chat */
|
|
173
|
-
mode: 'ai' | 'live' | 'hybrid';
|
|
174
|
-
/** AI settings (if mode is 'ai' or 'hybrid') */
|
|
175
|
-
aiSettings?: {
|
|
176
|
-
skillId?: string;
|
|
177
|
-
handoffToLive?: boolean;
|
|
178
|
-
handoffKeywords?: string[];
|
|
179
|
-
/** When AI should suggest handoff based on sentiment or keywords */
|
|
180
|
-
handoffTriggers?: {
|
|
181
|
-
negativesentiment?: boolean;
|
|
182
|
-
keywords?: string[];
|
|
183
|
-
afterMessages?: number;
|
|
184
|
-
};
|
|
185
|
-
};
|
|
186
|
-
/** Offline mode settings (when no agents available) */
|
|
187
|
-
offlineMode?: 'form' | 'ai' | 'message';
|
|
188
|
-
/** Form slug to show when offline (defaults to 'contact') */
|
|
189
|
-
offlineFormSlug?: string;
|
|
190
|
-
/** AI fallback when no agents online (hybrid mode) */
|
|
191
|
-
aiFallbackEnabled?: boolean;
|
|
192
|
-
/** Custom offline message */
|
|
193
|
-
offlineMessage?: string;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* UI actions the visitor Echo endpoint (POST /echo/public/chat) may return on
|
|
197
|
-
* the JSON response alongside `content` / `conversationId`. The chat widget
|
|
198
|
-
* renders each as an inline card or chip beneath the assistant message.
|
|
199
|
-
*
|
|
200
|
-
* This mirrors the shape Echo's endpoint sends. It is a LOCAL contract on
|
|
201
|
-
* purpose: the kit never imports from the API.
|
|
202
|
-
*
|
|
203
|
-
* - `show_form` → data.formSlug (+ optional data.prefill) — offer the managed form inline.
|
|
204
|
-
* - `suggest_action` → data.action + data.message — clickable chip (send message or navigate).
|
|
205
|
-
* - `show_portfolio_item` → data.slug — the generic widget ignores it (a site's own chat UI handles it).
|
|
206
|
-
*/
|
|
207
|
-
export type UiActionType = 'show_form' | 'suggest_action' | 'show_portfolio_item';
|
|
208
|
-
export interface UiAction {
|
|
209
|
-
type: UiActionType | string;
|
|
210
|
-
data: Record<string, unknown>;
|
|
211
|
-
}
|
|
212
|
-
export interface ChatMessage {
|
|
213
|
-
id: string;
|
|
214
|
-
conversation_id: string;
|
|
215
|
-
role: 'user' | 'assistant' | 'agent' | 'system';
|
|
216
|
-
content: string;
|
|
217
|
-
metadata?: Record<string, unknown>;
|
|
218
|
-
created_at: string;
|
|
219
|
-
/** Name of the agent (for agent messages) */
|
|
220
|
-
sender_name?: string;
|
|
221
|
-
/** Avatar URL of the agent */
|
|
222
|
-
sender_avatar?: string;
|
|
223
|
-
}
|
|
224
|
-
export interface ChatConversation {
|
|
225
|
-
id: string;
|
|
226
|
-
project_id: string;
|
|
227
|
-
visitor_id: string;
|
|
228
|
-
status: 'active' | 'ai' | 'pending_handoff' | 'human' | 'closed';
|
|
229
|
-
assigned_to?: string;
|
|
230
|
-
last_message_at: string;
|
|
231
|
-
created_at: string;
|
|
232
|
-
/** AI summary of the conversation */
|
|
233
|
-
ai_summary?: string;
|
|
234
|
-
/** Visitor info */
|
|
235
|
-
visitor_name?: string;
|
|
236
|
-
visitor_email?: string;
|
|
237
|
-
}
|
|
238
|
-
/** Availability status returned by the widget API */
|
|
239
|
-
export interface ChatAvailability {
|
|
240
|
-
available: boolean;
|
|
241
|
-
mode: 'live' | 'ai' | 'offline';
|
|
242
|
-
agentsOnline: number;
|
|
243
|
-
operatingHoursActive: boolean;
|
|
244
|
-
}
|
|
7
|
+
import type { ChatLauncherPlacement } from '../chat/types';
|
|
8
|
+
export type { ChatAvailability, ChatConfig, ChatConversation, ChatLauncherPlacement, ChatLauncherPosition, ChatMessage, UiAction, UiActionType, } from '../chat/types';
|
|
9
|
+
import type { SitePopup, SitePopupConfig, SitePopupTargeting, SitePopupTrigger, SitePopupType } from '../website/popup-types';
|
|
10
|
+
/** @deprecated Use `SitePopup` from `@sonordev/site-kit/website/popups`. */
|
|
11
|
+
export type EngageElement = SitePopup;
|
|
12
|
+
/** @deprecated Use `SitePopupType` from `@sonordev/site-kit/website/popups`. */
|
|
13
|
+
export type WidgetType = SitePopupType;
|
|
14
|
+
/** @deprecated Use `SitePopupConfig` from `@sonordev/site-kit/website/popups`. */
|
|
15
|
+
export type WidgetConfig = SitePopupConfig;
|
|
16
|
+
/** @deprecated Use `SitePopupTargeting` from `@sonordev/site-kit/website/popups`. */
|
|
17
|
+
export type TargetingRules = SitePopupTargeting;
|
|
18
|
+
/** @deprecated Use `SitePopupTrigger` from `@sonordev/site-kit/website/popups`. */
|
|
19
|
+
export type TriggerConfig = SitePopupTrigger;
|
|
20
|
+
/** @deprecated Use SiteKitLayout's `chat` and `popups` props. */
|
|
245
21
|
export interface EngageConfig extends ChatLauncherPlacement {
|
|
246
22
|
projectId: string;
|
|
247
|
-
/** Enable chat */
|
|
248
23
|
chatEnabled?: boolean;
|
|
249
|
-
/** Debug mode */
|
|
250
24
|
debug?: boolean;
|
|
251
25
|
}
|
|
26
|
+
/** @deprecated Unused since Engage was retired. */
|
|
252
27
|
export interface EngageAnalytics {
|
|
253
28
|
element_id: string;
|
|
254
29
|
event_type: 'impression' | 'click' | 'close' | 'submit' | 'dismiss';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* It is mounted as a deferred, CHILDLESS SIBLING — never a wrapper — by
|
|
11
11
|
* SiteKitClientProviders, behind the same idle/first-interaction gate as
|
|
12
|
-
* Analytics and
|
|
12
|
+
* Analytics and chat, so it never enters the critical hydration path (the
|
|
13
13
|
* page must server-render). It renders null and carries no
|
|
14
14
|
* visitor data.
|
|
15
15
|
*/
|
package/dist/fleet/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-
|
|
2
|
+
export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-CF5QNFYU.js';
|
|
3
3
|
export { FLEET_CONTRACT_VERSION, FLEET_MODULES, FLEET_MODULES_MAX, FLEET_SITE_MAX_LENGTH, FLEET_VERSION_MAX_LENGTH, FLEET_VERSION_PATTERN, buildFleetHeartbeatPayload, isFleetModule, normalizeFleetModules, normalizeFleetSite, sanitizeFleetVersion } from '../chunk-ZTZQPYP6.js';
|
|
4
4
|
import '../chunk-YC7ELZS3.js';
|
|
5
5
|
import '../chunk-43OCZ3JA.js';
|
|
6
6
|
import '../chunk-EKBEOXTH.js';
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-
|
|
9
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-D6ZC7XKZ.js';
|
|
8
|
+
import '../chunk-K4ZHAURD.js';
|
|
9
|
+
import '../chunk-F24FNCTK.js';
|
|
10
10
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -2,23 +2,36 @@
|
|
|
2
2
|
* FormEnhancer — the only client code a managed form needs up front.
|
|
3
3
|
*
|
|
4
4
|
* Renders the server-rendered shell (<StaticForm>, passed as `children`) until
|
|
5
|
-
* an idle/first-interaction gate fires, then
|
|
6
|
-
*
|
|
5
|
+
* an idle/first-interaction gate fires, then imports the interactive form and
|
|
6
|
+
* swaps it in. Everything expensive — validation, conditional logic,
|
|
7
7
|
* spotlight/stage, celebration, momentum — lives behind that dynamic import,
|
|
8
8
|
* so a page ships this boundary and nothing else in its initial chunk set.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* the
|
|
10
|
+
* Since 6.3.2 there is no no-JavaScript submit (the native POST door was a
|
|
11
|
+
* bot magnet and took no real leads), so the shell is a real form a visitor
|
|
12
|
+
* can read and type into, but only the enhancement sends it. The progression:
|
|
12
13
|
*
|
|
13
|
-
* no JS at all -> shell
|
|
14
|
-
*
|
|
15
|
-
* JS,
|
|
16
|
-
*
|
|
14
|
+
* no JS at all -> shell; its Send button stays disabled. Nothing is
|
|
15
|
+
* lost to a POST that goes nowhere.
|
|
16
|
+
* JS, pre-swap -> shell. A submit is caught here and replayed by the
|
|
17
|
+
* interactive form the moment it mounts.
|
|
18
|
+
* JS, post-swap -> enhanced form, submits over JSON, with delight.
|
|
19
|
+
* chunk 404s -> shell stays. (Never left blank.)
|
|
17
20
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
21
|
+
* Two rules keep the swap from losing anything (7.2.0):
|
|
22
|
+
*
|
|
23
|
+
* - The shell stays mounted, untouched, until the interactive form's code
|
|
24
|
+
* has loaded. The old version re-mounted the shell inside a Suspense
|
|
25
|
+
* fallback the moment the gate fired, which reset every control and
|
|
26
|
+
* dropped focus mid-click.
|
|
27
|
+
* - What's in the shell's controls at the moment of the swap is carried
|
|
28
|
+
* into the interactive form (form-dom-values.ts), including a date typed
|
|
29
|
+
* into the plain date input. Typing into the shell, or a browser agent
|
|
30
|
+
* filling it, also starts the swap at once instead of waiting for idle.
|
|
31
|
+
*
|
|
32
|
+
* The invariant to protect: the shell is only removed once the enhancement
|
|
33
|
+
* has actually rendered. Do not "hide the shell then load" — a CDN hiccup
|
|
34
|
+
* would leave a visitor staring at an empty box where the form used to be.
|
|
22
35
|
*
|
|
23
36
|
* ── Entrance animation ──────────────────────────────────────────────────
|
|
24
37
|
*
|
|
@@ -17,13 +17,14 @@
|
|
|
17
17
|
* What each layer is for:
|
|
18
18
|
*
|
|
19
19
|
* getFormConfig — server fetch, ISR-cached. No client round trip.
|
|
20
|
-
* StaticForm — real HTML form:
|
|
21
|
-
*
|
|
22
|
-
* FormEnhancer — ~1 KB client boundary.
|
|
23
|
-
*
|
|
20
|
+
* StaticForm — real HTML form: every field and the honeypot, readable
|
|
21
|
+
* by people and crawlers before any script runs.
|
|
22
|
+
* FormEnhancer — ~1 KB client boundary. Loads the interactive form at idle
|
|
23
|
+
* (or as soon as someone types into the shell) and swaps it
|
|
24
|
+
* in, carrying over anything already typed.
|
|
24
25
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
26
|
+
* Since 6.3.2 only the enhancement can send a managed form (the no-JavaScript
|
|
27
|
+
* POST was removed), so every ServerForm enhances.
|
|
27
28
|
*
|
|
28
29
|
* The client `ManagedForm` from `@sonordev/site-kit/forms` still exists and
|
|
29
30
|
* still works; reach for it only when the form must live inside an existing
|
|
@@ -44,9 +45,9 @@ export interface ServerFormProps {
|
|
|
44
45
|
/** Entrance animation for the idle upgrade. See FormEnhancer. */
|
|
45
46
|
enter?: FormEnterAnimation;
|
|
46
47
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
48
|
+
* @deprecated Ignored since 7.2.0. There is no no-JavaScript submit (6.3.2
|
|
49
|
+
* removed it), so a form that never loads its script can't send, and
|
|
50
|
+
* `false` only ever produced a form that silently went nowhere.
|
|
50
51
|
*/
|
|
51
52
|
enhance?: boolean;
|
|
52
53
|
/**
|
|
@@ -65,4 +66,4 @@ export interface ServerFormProps {
|
|
|
65
66
|
/** Passed through to getFormConfig (api key / url / revalidate). */
|
|
66
67
|
configOptions?: GetFormConfigOptions;
|
|
67
68
|
}
|
|
68
|
-
export declare function ServerForm({ formId, className, experience, enter,
|
|
69
|
+
export declare function ServerForm({ formId, className, experience, enter, defer, initialConfig, configOptions, defaultValues, }: ServerFormProps): Promise<React.JSX.Element>;
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* (/api/public/forms/submit-native, a signed token in the page HTML) took
|
|
9
9
|
* 10,500 bot submissions across the fleet and not one real lead, because a bot
|
|
10
10
|
* only had to download the page to borrow the token. `method="post"` stays so
|
|
11
|
-
*
|
|
11
|
+
* nothing typed can end up in a URL, and since 7.2.0 the Send button renders
|
|
12
|
+
* disabled until FormEnhancer is ready to catch the submit, so a click before
|
|
13
|
+
* hydration no longer posts the page to itself and throws the input away.
|
|
12
14
|
*
|
|
13
15
|
* ── Why this exists ─────────────────────────────────────────────────────
|
|
14
16
|
*
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/forms - autocomplete tokens for managed form fields
|
|
3
|
+
*
|
|
4
|
+
* Browser autofill, password managers and AI agents filling a form for
|
|
5
|
+
* someone all read a field's `autocomplete` token to know what it wants.
|
|
6
|
+
* Without one they guess from the label, and a guess is how a phone number
|
|
7
|
+
* ends up in the company field. Managed forms shipped no tokens at all before
|
|
8
|
+
* 7.2.0.
|
|
9
|
+
*
|
|
10
|
+
* Single source of truth for which token a managed field gets. FormField is
|
|
11
|
+
* the only caller; every experience (classic, spotlight, stage, the static
|
|
12
|
+
* shell) renders its controls through FormField.
|
|
13
|
+
*
|
|
14
|
+
* Precedence: the field's CRM destination (`destination_field`, set in
|
|
15
|
+
* Sonor) > its input type > its slug > its label. When nothing matches the
|
|
16
|
+
* attribute is omitted. A wrong token is worse than none, so matching is
|
|
17
|
+
* deliberately narrow: exact keys only, plus Sonor's random slug suffixes
|
|
18
|
+
* (`email_k3x9pq2m`).
|
|
19
|
+
*/
|
|
20
|
+
import type { FormField } from './types';
|
|
21
|
+
/**
|
|
22
|
+
* The `autocomplete` token for one managed field, or undefined to omit it.
|
|
23
|
+
* Only text-like inputs and selects get one; a message box, a date or a
|
|
24
|
+
* checkbox never does.
|
|
25
|
+
*/
|
|
26
|
+
export declare function autocompleteFor(field: Pick<FormField, 'field_type' | 'slug' | 'label'> & {
|
|
27
|
+
destination_field?: string;
|
|
28
|
+
}): string | undefined;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/forms - reading a managed form's values out of the DOM
|
|
3
|
+
*
|
|
4
|
+
* Two moments need what is actually in the controls rather than what React
|
|
5
|
+
* last heard about:
|
|
6
|
+
*
|
|
7
|
+
* 1. The enhancement swap. The server-rendered shell is plain HTML, so
|
|
8
|
+
* whatever a visitor (or an agent) typed before the interactive form
|
|
9
|
+
* loaded lives only in the DOM. FormEnhancer reads it here and seeds the
|
|
10
|
+
* interactive form with it. Before 7.2.0 the swap threw it away.
|
|
11
|
+
* 2. A submit. A browser agent can set a control's value without the input
|
|
12
|
+
* event React listens for. FormClient compares the DOM with its state
|
|
13
|
+
* at submit time and adopts anything it missed, instead of rejecting a
|
|
14
|
+
* filled form as empty.
|
|
15
|
+
*
|
|
16
|
+
* Single source of truth for turning form controls back into field values,
|
|
17
|
+
* typed the way FormClient stores them (checkbox groups and multi-selects as
|
|
18
|
+
* arrays, a lone checkbox as a boolean, ratings and sliders as numbers).
|
|
19
|
+
*/
|
|
20
|
+
import type { FormField } from './types';
|
|
21
|
+
/**
|
|
22
|
+
* Nothing worth seeding or adopting: an empty value (field-rules.ts), an
|
|
23
|
+
* unticked lone checkbox, or whitespace.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isBlank(value: unknown): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The value of every answerable field, read from the form's controls.
|
|
28
|
+
* Fields with no control in the DOM (another step, conditionally hidden) and
|
|
29
|
+
* blank fields are left out, as is the honeypot.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readFormControlValues(form: HTMLFormElement | null | undefined, fields: FormField[] | undefined, honeypotName: string): Record<string, unknown>;
|
|
32
|
+
/**
|
|
33
|
+
* What the shell holds beyond each field's configured default: the part of
|
|
34
|
+
* the shell worth carrying into the interactive form.
|
|
35
|
+
*/
|
|
36
|
+
export declare function shellValuesToCarry(form: HTMLFormElement | null | undefined, fields: FormField[] | undefined, honeypotName: string): Record<string, unknown>;
|
|
37
|
+
/**
|
|
38
|
+
* Values present in the DOM that React state doesn't have: a control set
|
|
39
|
+
* without an input event. Only fills a blank state value; never overrides
|
|
40
|
+
* something the visitor typed through React.
|
|
41
|
+
*/
|
|
42
|
+
export declare function unseenControlValues(form: HTMLFormElement | null | undefined, fields: FormField[] | undefined, honeypotName: string, state: Record<string, unknown>): Record<string, unknown>;
|
package/dist/forms/index.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
export { FormCelebration } from '../chunk-YGGDU6C3.js';
|
|
3
|
-
export { FormClient, ManagedForm } from '../chunk-
|
|
4
|
-
import '../chunk-
|
|
3
|
+
export { FormClient, ManagedForm } from '../chunk-IAM3D3RL.js';
|
|
4
|
+
import '../chunk-D5DCBD4Y.js';
|
|
5
5
|
export { DatePicker } from '../chunk-SOD2F6C2.js';
|
|
6
|
-
export { FormEnhancer } from '../chunk-
|
|
6
|
+
export { FormEnhancer } from '../chunk-OWZ7ATLZ.js';
|
|
7
7
|
import '../chunk-YC7ELZS3.js';
|
|
8
8
|
import '../chunk-DXO6SBMD.js';
|
|
9
|
-
export { FormField as FormFieldComponent } from '../chunk-
|
|
10
|
-
export { useForm, useFormTracking } from '../chunk-
|
|
11
|
-
import '../chunk-
|
|
9
|
+
export { FormField as FormFieldComponent } from '../chunk-4NTBQNHA.js';
|
|
10
|
+
export { useForm, useFormTracking } from '../chunk-FR6BYFPC.js';
|
|
11
|
+
import '../chunk-Q6E4OPGG.js';
|
|
12
|
+
import '../chunk-C2FZBUSS.js';
|
|
12
13
|
export { DEFAULT_FORM_SUCCESS_MESSAGE } from '../chunk-5SQK3D53.js';
|
|
14
|
+
import '../chunk-HW7B43E5.js';
|
|
13
15
|
import '../chunk-NJCTQH2P.js';
|
|
14
16
|
import '../chunk-L2V5PUFN.js';
|
|
15
17
|
import '../chunk-GJWI74ZZ.js';
|
|
16
|
-
import { sonorFetch } from '../chunk-
|
|
17
|
-
import '../chunk-
|
|
18
|
-
import '../chunk-
|
|
18
|
+
import { sonorFetch } from '../chunk-D6ZC7XKZ.js';
|
|
19
|
+
import '../chunk-K4ZHAURD.js';
|
|
20
|
+
import '../chunk-F24FNCTK.js';
|
|
19
21
|
import '../chunk-PKBMQBKP.js';
|
|
20
22
|
|
|
21
23
|
// src/forms/formsApi.ts
|
package/dist/forms/server.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
export { ServerForm, getFormConfig } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { ServerForm, getFormConfig } from '../chunk-5V2V5C3Y.js';
|
|
2
|
+
import '../chunk-OWZ7ATLZ.js';
|
|
3
3
|
import '../chunk-YC7ELZS3.js';
|
|
4
|
-
export { StaticForm } from '../chunk-
|
|
4
|
+
export { StaticForm } from '../chunk-ZTLMPUO6.js';
|
|
5
5
|
import '../chunk-DXO6SBMD.js';
|
|
6
|
-
import '../chunk-
|
|
6
|
+
import '../chunk-4NTBQNHA.js';
|
|
7
7
|
import '../chunk-X6F6SO4S.js';
|
|
8
8
|
import '../chunk-MH2DSGC6.js';
|
|
9
|
+
import '../chunk-C2FZBUSS.js';
|
|
9
10
|
import '../chunk-5SQK3D53.js';
|
|
11
|
+
import '../chunk-HW7B43E5.js';
|
|
10
12
|
import '../chunk-NJCTQH2P.js';
|
|
11
13
|
import '../chunk-PKBMQBKP.js';
|
package/dist/forms/static.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { StaticForm } from '../chunk-
|
|
1
|
+
export { StaticForm } from '../chunk-ZTLMPUO6.js';
|
|
2
2
|
import '../chunk-DXO6SBMD.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-4NTBQNHA.js';
|
|
4
4
|
import '../chunk-5SQK3D53.js';
|
|
5
|
+
import '../chunk-HW7B43E5.js';
|
|
5
6
|
import '../chunk-NJCTQH2P.js';
|
|
6
7
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -24,13 +24,20 @@ export interface SubmitFormArgs {
|
|
|
24
24
|
honeypotValue: string;
|
|
25
25
|
/** Timestamp (ms) the form was first rendered — a weak anti-bot timing signal. */
|
|
26
26
|
formLoadedAt: number;
|
|
27
|
+
/**
|
|
28
|
+
* The browser reported that an AI agent pressed submit (WebMCP's
|
|
29
|
+
* `SubmitEvent.agentInvoked`). Sent so Sonor can tag the lead for the
|
|
30
|
+
* business; it is the browser's word, so it never changes how the
|
|
31
|
+
* submission is checked.
|
|
32
|
+
*/
|
|
33
|
+
agentInvoked?: boolean;
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* Submit a managed form. Throws on failure (network, timeout, or a non-2xx
|
|
30
37
|
* response) with a human-readable message; resolves with the parsed API
|
|
31
38
|
* response on success.
|
|
32
39
|
*/
|
|
33
|
-
export declare function submitForm({ config, values, honeypotValue, formLoadedAt, }: SubmitFormArgs): Promise<FormSubmitResult>;
|
|
40
|
+
export declare function submitForm({ config, values, honeypotValue, formLoadedAt, agentInvoked, }: SubmitFormArgs): Promise<FormSubmitResult>;
|
|
34
41
|
/**
|
|
35
42
|
* The receipt Sonor returns plus the values that were sent. `onSuccess`
|
|
36
43
|
* callers need the values (free-audit reads the website and email back), and
|
package/dist/forms/types.d.ts
CHANGED
|
@@ -127,6 +127,45 @@ export interface ConditionalLogic {
|
|
|
127
127
|
* on purpose (a bot must not learn it was caught), so nothing here says
|
|
128
128
|
* whether the lead was accepted, routed or scored.
|
|
129
129
|
*/
|
|
130
|
+
/**
|
|
131
|
+
* Options for a managed form's `submit()`. All optional; `submit()` with no
|
|
132
|
+
* argument behaves exactly as it always has.
|
|
133
|
+
*/
|
|
134
|
+
export interface FormSubmitOptions {
|
|
135
|
+
/**
|
|
136
|
+
* The browser reported that an AI agent pressed submit (WebMCP's
|
|
137
|
+
* `SubmitEvent.agentInvoked`). Sonor tags the lead so the business can see
|
|
138
|
+
* how agent-sent leads compare; it changes nothing else about the submit.
|
|
139
|
+
*/
|
|
140
|
+
agentInvoked?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Values found in the form's controls that React state never received (a
|
|
143
|
+
* control set without an input event). Merged over blank state values
|
|
144
|
+
* before validating. See form-dom-values.ts.
|
|
145
|
+
*/
|
|
146
|
+
domFills?: Record<string, unknown>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* What `submit()` resolves with. Callers that ignore it keep working; an
|
|
150
|
+
* agent that submitted through WebMCP is handed this as its result.
|
|
151
|
+
*/
|
|
152
|
+
export type FormSubmitOutcome = {
|
|
153
|
+
status: 'sent';
|
|
154
|
+
message: string;
|
|
155
|
+
submissionId?: string;
|
|
156
|
+
} | {
|
|
157
|
+
status: 'invalid';
|
|
158
|
+
errors: Record<string, string>;
|
|
159
|
+
} | {
|
|
160
|
+
status: 'failed';
|
|
161
|
+
message: string;
|
|
162
|
+
} | {
|
|
163
|
+
status: 'busy';
|
|
164
|
+
} | {
|
|
165
|
+
status: 'next_step';
|
|
166
|
+
step: number;
|
|
167
|
+
totalSteps: number;
|
|
168
|
+
};
|
|
130
169
|
export interface FormSubmitResult {
|
|
131
170
|
success: boolean;
|
|
132
171
|
/** The form_submissions row id (same as submissionId). */
|
|
@@ -197,7 +236,7 @@ export interface ExperienceRenderProps {
|
|
|
197
236
|
isFieldVisible: (field: FormField) => boolean;
|
|
198
237
|
fieldIsComplete: (field: FormField) => boolean;
|
|
199
238
|
applyFieldError: (slug: string, error: string) => void;
|
|
200
|
-
submit: () => Promise<
|
|
239
|
+
submit: (options?: FormSubmitOptions) => Promise<FormSubmitOutcome>;
|
|
201
240
|
trackStepChange: (step: number) => void;
|
|
202
241
|
/** Pass to each FormField's onFocus/onBlur (field_interactions). */
|
|
203
242
|
trackFieldFocus: (slug: string) => void;
|
|
@@ -269,7 +308,7 @@ export interface FormRenderProps {
|
|
|
269
308
|
/** Go to specific step */
|
|
270
309
|
goToStep: (step: number) => void;
|
|
271
310
|
/** Submit the form */
|
|
272
|
-
submit: () => Promise<
|
|
311
|
+
submit: (options?: FormSubmitOptions) => Promise<FormSubmitOutcome>;
|
|
273
312
|
/** Set field value */
|
|
274
313
|
setFieldValue: (key: string, value: unknown) => void;
|
|
275
314
|
/** Check if field should be visible (conditional logic) */
|