@viveksinghind/narrative-form-react 1.0.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.
@@ -0,0 +1,897 @@
1
+ import React from 'react';
2
+ import { NarrativeField, NarrativeFormConfig, NarrativeTheme, NarrativeTypewriter, NarrativeWelcome, NarrativeDone, NarrativeCallbacks, NarrativeRefHandle, NarrativeFieldValues, NarrativeI18n, NarrativeCrossFieldValidator, NarrativeMeta, FormStateSnapshot, FieldStatus, NarrativeErrorDisplay } from '@viveksinghind/narrative-form-core';
3
+ export { AsyncValidationHandle, FieldStatus, FormStateEngine, FormStateSnapshot, NarrativeCallbacks, NarrativeCrossFieldValidator, NarrativeDone, NarrativeErrorDisplay, NarrativeField, NarrativeFieldType, NarrativeFieldValues, NarrativeFormConfig, NarrativeI18n, NarrativeMeta, NarrativeRefHandle, NarrativeServerValidation, NarrativeTheme, NarrativeTypewriter, NarrativeValidation, NarrativeValidationRule, NarrativeWelcome, ValidationResult, ValidatorFn, clearValidators, defaultStrings, getRegisteredValidatorNames, getValidator, hasAsyncValidation, hasValidator, mergeStrings, registerBuiltinValidators, registerValidator, unregisterValidator, validateField, validateFieldAsync } from '@viveksinghind/narrative-form-core';
4
+
5
+ /**
6
+ * NarrativeForm — root component for narrative-form.
7
+ *
8
+ * @remarks
9
+ * Main entry point for consumers. Renders fields one by one with typewriter
10
+ * animations and manages the full lifecycle: welcome → fields → done.
11
+ *
12
+ * Supports: theming, dark mode, welcome/done screens, async validation,
13
+ * dynamic forms (fieldsUrl/formConfig), controlled mode, default values,
14
+ * field dependencies (showIf), step locking (lockPrevious), i18n/RTL,
15
+ * and cross-field validation.
16
+ *
17
+ * CSS classes: `ns-root`, `ns-letter`, `ns-root--complete`,
18
+ * `ns-root--dark`, `ns-root--submitting`, `ns-root--loading`, `ns-root--error`
19
+ */
20
+
21
+ /** Props for the NarrativeForm component. */
22
+ interface NarrativeFormProps {
23
+ /** Ordered list of field configurations (static mode). */
24
+ fields?: NarrativeField[];
25
+ /** URL to fetch form config from (dynamic mode). */
26
+ fieldsUrl?: string;
27
+ /** Headers for the fieldsUrl fetch request. */
28
+ fieldsUrlHeaders?: Record<string, string>;
29
+ /** Pre-fetched form config object (dynamic mode). */
30
+ formConfig?: NarrativeFormConfig;
31
+ /** Theme configuration — colours, typography, spacing. */
32
+ theme?: NarrativeTheme;
33
+ /** Typewriter animation settings. */
34
+ typewriter?: NarrativeTypewriter;
35
+ /** Welcome screen configuration. Pass `{ show: false }` to skip. */
36
+ welcome?: NarrativeWelcome;
37
+ /** Done screen configuration. Pass `{ show: false }` to skip. */
38
+ done?: NarrativeDone;
39
+ /** Whether confirmed fields show an edit icon. Default: true */
40
+ editable?: boolean;
41
+ /** Label for the edit button. Default: "Edit" */
42
+ editLabel?: string;
43
+ /** Additional CSS class added to the root element. */
44
+ className?: string;
45
+ /** Event callbacks for analytics and integration. */
46
+ callbacks?: NarrativeCallbacks;
47
+ /** Ref handle for imperative API (next, getValues, reset, focusField). */
48
+ formRef?: React.Ref<NarrativeRefHandle>;
49
+ /** Default values — pre-fill fields as already confirmed. */
50
+ defaultValues?: NarrativeFieldValues;
51
+ /** Controlled mode — external values source of truth. */
52
+ values?: NarrativeFieldValues;
53
+ /** i18n string overrides. */
54
+ strings?: Partial<NarrativeI18n>;
55
+ /** BCP 47 locale code. */
56
+ locale?: string;
57
+ /** Text direction. Auto-detected from locale if not set. */
58
+ direction?: "ltr" | "rtl";
59
+ /** Cross-field validation rules. */
60
+ crossFieldValidators?: NarrativeCrossFieldValidator[];
61
+ /** Custom loading component while fetching dynamic config. */
62
+ loadingComponent?: React.ReactNode;
63
+ /** Custom error component when config fetch fails. */
64
+ errorComponent?: React.ReactNode;
65
+ /** Callback when config fetch fails. */
66
+ onFetchError?: (error: Error) => void;
67
+ /** Label for the retry button on fetch error. */
68
+ retryLabel?: string;
69
+ /** Whether reduced motion should be forced. */
70
+ reducedMotion?: boolean;
71
+ }
72
+ /**
73
+ * The root narrative-form component.
74
+ *
75
+ * Renders fields one by one with typewriter animations. Each field follows
76
+ * the lifecycle: idle → typing → active → confirmed → editing.
77
+ *
78
+ * @param props - Form configuration
79
+ */
80
+ declare const NarrativeForm: React.FC<NarrativeFormProps>;
81
+
82
+ /**
83
+ * ThemeProvider — applies NarrativeTheme tokens as CSS custom properties.
84
+ *
85
+ * @remarks
86
+ * Converts theme token names (e.g., `background`, `textColor`) into CSS
87
+ * variable names (e.g., `--ns-bg`, `--ns-text`) and applies them as inline
88
+ * style on a wrapper element. This avoids any CSS-in-JS dependency.
89
+ *
90
+ * Supports dark mode via `theme.mode` (`'light'`, `'dark'`, `'auto'`).
91
+ * When `'auto'`, it uses `matchMedia('(prefers-color-scheme: dark)')`.
92
+ *
93
+ * CSS classes: none (uses ns-root--dark on root via className)
94
+ */
95
+
96
+ /** Resolved theme context value. */
97
+ interface ThemeContextValue {
98
+ /** The resolved theme tokens (merged with dark overrides if applicable). */
99
+ theme: NarrativeTheme;
100
+ /** Whether dark mode is currently active. */
101
+ isDark: boolean;
102
+ }
103
+ /**
104
+ * Hook to access the current theme context.
105
+ *
106
+ * @returns The resolved theme and dark mode state
107
+ */
108
+ declare function useTheme(): ThemeContextValue;
109
+ /** Props for the ThemeProvider component. */
110
+ interface ThemeProviderProps {
111
+ /** The theme configuration. */
112
+ theme?: NarrativeTheme;
113
+ /** Children to render. */
114
+ children: React.ReactNode;
115
+ }
116
+ /**
117
+ * Provides theme context and applies CSS custom properties.
118
+ *
119
+ * @param props - Theme provider configuration
120
+ */
121
+ declare const ThemeProvider: React.FC<ThemeProviderProps>;
122
+
123
+ /**
124
+ * WelcomeScreen — the opening screen of the narrative form.
125
+ *
126
+ * @remarks
127
+ * Displays a heading (with optional typewriter animation), supporting
128
+ * subtext, and a call-to-action button. Shown before any form fields.
129
+ *
130
+ * CSS classes: `ns-welcome`, `ns-welcome-heading`, `ns-welcome-subtext`,
131
+ * `ns-welcome-cta`
132
+ */
133
+
134
+ /** Props for the WelcomeScreen component. */
135
+ interface WelcomeScreenProps {
136
+ /** Welcome screen configuration. */
137
+ welcome: NarrativeWelcome;
138
+ /** Typewriter settings for the heading animation. */
139
+ typewriter?: NarrativeTypewriter;
140
+ /** Called when the CTA button is clicked to start the form. */
141
+ onStart: () => void;
142
+ /** Additional CSS class for the wrapper. */
143
+ className?: string;
144
+ }
145
+ /**
146
+ * Renders the welcome screen with an animated heading and CTA.
147
+ *
148
+ * @param props - Welcome screen configuration
149
+ */
150
+ declare const WelcomeScreen: React.FC<WelcomeScreenProps>;
151
+
152
+ /**
153
+ * DoneScreen — the completion screen shown after all fields are confirmed.
154
+ *
155
+ * @remarks
156
+ * Displays a personalised message (with template variable interpolation)
157
+ * and a submit CTA button. Supports `{key}` placeholders in the message
158
+ * string that are replaced with confirmed field values.
159
+ *
160
+ * Also supports a function-mode message: `(values) => string`.
161
+ *
162
+ * CSS classes: `ns-done`, `ns-done-message`, `ns-done-cta`,
163
+ * `ns-done-cta--loading`, `ns-done-cta--success`, `ns-done-cta--error`,
164
+ * `ns-done-error`
165
+ */
166
+
167
+ /** Props for the DoneScreen component. */
168
+ interface DoneScreenProps {
169
+ /** Done screen configuration. */
170
+ done: NarrativeDone;
171
+ /** All confirmed field values. */
172
+ values: NarrativeFieldValues;
173
+ /** Analytics metadata. */
174
+ meta: NarrativeMeta;
175
+ /** Typewriter settings for the message animation. */
176
+ typewriter?: NarrativeTypewriter;
177
+ /** Additional CSS class for the wrapper. */
178
+ className?: string;
179
+ }
180
+ /**
181
+ * Renders the done screen with a personalised message and submit button.
182
+ *
183
+ * @param props - Done screen configuration
184
+ */
185
+ declare const DoneScreen: React.FC<DoneScreenProps>;
186
+
187
+ /**
188
+ * Core typewriter animation hook for narrative-form.
189
+ *
190
+ * @remarks
191
+ * Animates a string character by character to create the "letter being written"
192
+ * effect. Cleans up the interval on unmount to prevent memory leaks.
193
+ * Respects `prefers-reduced-motion` — skips animation entirely if set.
194
+ *
195
+ * @example
196
+ * ```tsx
197
+ * const { displayedText, isTyping, isComplete } = useTypewriter({
198
+ * text: "My name is",
199
+ * speed: 38,
200
+ * });
201
+ * ```
202
+ */
203
+ /** Configuration options for the useTypewriter hook. */
204
+ interface UseTypewriterOptions {
205
+ /** The full text to type out. */
206
+ text: string;
207
+ /** Milliseconds per character. Default: 38 */
208
+ speed?: number;
209
+ /** Whether animation is enabled. Default: true */
210
+ enabled?: boolean;
211
+ /** Milliseconds to pause after typing completes before signalling done. Default: 100 */
212
+ pauseAfter?: number;
213
+ /** Callback fired when typing is fully complete (after pause). */
214
+ onComplete?: () => void;
215
+ }
216
+ /** Return value of the useTypewriter hook. */
217
+ interface UseTypewriterResult {
218
+ /** The currently visible portion of the text. */
219
+ displayedText: string;
220
+ /** Whether the typewriter is actively typing characters. */
221
+ isTyping: boolean;
222
+ /** Whether typing is fully complete (including the post-typing pause). */
223
+ isComplete: boolean;
224
+ }
225
+ /**
226
+ * React hook that animates text character by character.
227
+ *
228
+ * @param options - Typewriter configuration
229
+ * @returns Object with displayedText, isTyping, and isComplete
230
+ */
231
+ declare function useTypewriter(options: UseTypewriterOptions): UseTypewriterResult;
232
+
233
+ /**
234
+ * React hook wrapping the core FormStateEngine.
235
+ *
236
+ * @remarks
237
+ * Bridges the framework-agnostic FormStateEngine with React's
238
+ * state management. Each state mutation in the engine triggers
239
+ * a React re-render via `useSyncExternalStore`-like pattern.
240
+ */
241
+
242
+ /** Return value of the useFormState hook. */
243
+ interface UseFormStateResult {
244
+ /** Current snapshot of the form state. */
245
+ snapshot: FormStateSnapshot;
246
+ /** Start the typewriter animation for a field. */
247
+ startTyping: (key: string) => void;
248
+ /** Mark a field as active (typewriter done, input visible). */
249
+ activateField: (key: string) => void;
250
+ /** Confirm a field with a value. */
251
+ confirmField: (key: string, value: string | string[]) => void;
252
+ /** Reopen a confirmed field for editing. */
253
+ editField: (key: string) => void;
254
+ /** Re-confirm a field after editing. */
255
+ reconfirmField: (key: string, value: string | string[]) => void;
256
+ /** Move to the next field. */
257
+ next: () => void;
258
+ /** Focus a specific field by key. */
259
+ focusField: (key: string) => void;
260
+ /** Reset all form state. */
261
+ reset: () => void;
262
+ /** Get all confirmed values. */
263
+ getValues: () => NarrativeFieldValues;
264
+ /** Get analytics metadata. */
265
+ getMeta: (formId?: string, formVersion?: number) => NarrativeMeta;
266
+ }
267
+ /**
268
+ * React hook that manages the narrative form state.
269
+ *
270
+ * @param fields - Ordered array of field configurations
271
+ * @returns Form state and mutation methods
272
+ */
273
+ declare function useFormState(fields: readonly NarrativeField[]): UseFormStateResult;
274
+
275
+ /**
276
+ * Line — single sentence row orchestrator for narrative-form.
277
+ *
278
+ * @remarks
279
+ * Manages the full lifecycle of a single field within the form:
280
+ * `typing → active → confirmed → editing`.
281
+ *
282
+ * Composes: Prose + InlineInput (or FilledValue + EditIcon) + ErrorMessage.
283
+ * Runs validation on confirm — blocks confirmation if validation fails.
284
+ * Supports async validation with loading/success visual states.
285
+ * CSS classes: `ns-line`, `ns-line--active`, `ns-line--confirmed`,
286
+ * `ns-line--editing`, `ns-line--error`, `ns-line-[key]`
287
+ */
288
+
289
+ /** Props for the Line component. */
290
+ interface LineProps {
291
+ /** The field configuration for this line. */
292
+ field: NarrativeField;
293
+ /** Current lifecycle status of this field. */
294
+ status: FieldStatus;
295
+ /** The confirmed value (if any). */
296
+ value?: string | string[];
297
+ /** All confirmed values so far (for cross-field validation). */
298
+ allValues?: NarrativeFieldValues;
299
+ /** Typewriter configuration. */
300
+ typewriter?: NarrativeTypewriter;
301
+ /** Whether editing is enabled globally. Default: true */
302
+ editable?: boolean;
303
+ /** Whether this field is locked (lockPrevious). */
304
+ locked?: boolean;
305
+ /** Label for the edit button. */
306
+ editLabel?: string;
307
+ /** Called when typing animation completes — field should become active. */
308
+ onTypingComplete: (key: string) => void;
309
+ /** Called when the field value is confirmed (after validation passes). */
310
+ onConfirm: (key: string, value: string) => void;
311
+ /** Called when the edit icon is clicked. */
312
+ onEdit: (key: string) => void;
313
+ /** Called when validation fails. */
314
+ onError?: (key: string, message: string) => void;
315
+ /** Called on every keystroke. */
316
+ onChange?: (key: string, value: string) => void;
317
+ /** Called when input receives focus. */
318
+ onFocus?: (key: string) => void;
319
+ /** Called when input loses focus. */
320
+ onBlur?: (key: string, value: string) => void;
321
+ }
322
+ /**
323
+ * Renders a single sentence row — the core building block of the narrative form.
324
+ *
325
+ * Lifecycle:
326
+ * 1. `typing` — Prose types out the prefix text
327
+ * 2. `active` — Input appears for the user to fill
328
+ * 3. `confirmed` — Value is locked, shown as filled text with edit icon
329
+ * 4. `editing` — User clicked edit, input re-appears with current value
330
+ *
331
+ * Validation runs on confirm. If it fails, the field stays active and
332
+ * an error message is displayed below the input.
333
+ *
334
+ * @param props - Line configuration
335
+ */
336
+ declare const Line: React.FC<LineProps>;
337
+
338
+ /**
339
+ * Typewriter prose text component.
340
+ *
341
+ * @remarks
342
+ * Wraps the `useTypewriter` hook to render the sentence prefix
343
+ * (e.g., "My name is") character by character, followed by a blinking cursor.
344
+ * CSS classes: `ns-prose`, `ns-prose--typing`
345
+ */
346
+
347
+ /** Props for the Prose component. */
348
+ interface ProseProps {
349
+ /** The full sentence text to type out. */
350
+ text: string;
351
+ /** Whether typewriter animation is enabled. Default: true */
352
+ animate?: boolean;
353
+ /** Milliseconds per character. Default: 38 */
354
+ speed?: number;
355
+ /** Whether to show a blinking cursor while typing. Default: true */
356
+ cursor?: boolean;
357
+ /** Custom cursor character. Default: "|" */
358
+ cursorChar?: string;
359
+ /** Milliseconds to pause after typing before input appears. Default: 100 */
360
+ pauseAfter?: number;
361
+ /** Callback fired when typing is fully complete. */
362
+ onComplete?: () => void;
363
+ /** Additional CSS class name. */
364
+ className?: string;
365
+ }
366
+ /**
367
+ * Renders a sentence prefix with a typewriter animation.
368
+ *
369
+ * @param props - Prose configuration
370
+ */
371
+ declare const Prose: React.FC<ProseProps>;
372
+
373
+ /**
374
+ * Blinking cursor component for the typewriter effect.
375
+ *
376
+ * @remarks
377
+ * Renders a single character that blinks via CSS animation.
378
+ * Visible only while the typewriter is actively typing.
379
+ * CSS class: `ns-cursor`
380
+ */
381
+
382
+ /** Props for the Cursor component. */
383
+ interface CursorProps {
384
+ /** The character to display as the cursor. Default: "|" */
385
+ cursorChar?: string;
386
+ /** Additional CSS class name. */
387
+ className?: string;
388
+ }
389
+ /**
390
+ * A blinking cursor character displayed during typewriter animation.
391
+ *
392
+ * @param props - Cursor configuration
393
+ */
394
+ declare const Cursor: React.FC<CursorProps>;
395
+
396
+ /**
397
+ * Base inline input component for narrative-form.
398
+ *
399
+ * @remarks
400
+ * Renders an inline text input that appears after the typewriter finishes.
401
+ * Handles Enter key to confirm, Escape to cancel, and auto-focuses when it mounts.
402
+ * Supports sanitise function on input and paste events.
403
+ * CSS classes: `ns-input-wrap`, `ns-input`, `ns-input--[type]`, `ns-input--focused`
404
+ */
405
+
406
+ /** Props for the InlineInput component. */
407
+ interface InlineInputProps {
408
+ /** Unique field key used for identification. */
409
+ fieldKey: string;
410
+ /** HTML input type attribute. Default: "text" */
411
+ type?: string;
412
+ /** Placeholder text inside the input. */
413
+ placeholder?: string;
414
+ /** Initial value for the input. */
415
+ defaultValue?: string;
416
+ /** Suffix text displayed after the input. */
417
+ suffix?: string;
418
+ /** Sanitise function applied on input and paste. */
419
+ sanitise?: (value: string) => string;
420
+ /** Callback fired when the value is confirmed (Enter key or button). */
421
+ onConfirm: (value: string) => void;
422
+ /** Callback fired on every keystroke. */
423
+ onChange?: (value: string) => void;
424
+ /** Callback fired when input receives focus. */
425
+ onFocus?: () => void;
426
+ /** Callback fired when input loses focus. */
427
+ onBlur?: (value: string) => void;
428
+ /** Callback fired when Escape is pressed (cancel edit). */
429
+ onEscape?: () => void;
430
+ /** Additional CSS class for the input element. */
431
+ inputClassName?: string;
432
+ /** Additional CSS class for the wrapper. */
433
+ className?: string;
434
+ }
435
+ /**
436
+ * An inline input that lives within a sentence.
437
+ * Auto-focuses on mount and confirms on Enter key press.
438
+ *
439
+ * @param props - Input configuration
440
+ */
441
+ declare const InlineInput: React.FC<InlineInputProps>;
442
+
443
+ /**
444
+ * EnterButton — the ↵ confirm button displayed next to inline inputs.
445
+ *
446
+ * @remarks
447
+ * Triggers field confirmation when clicked.
448
+ * CSS class: `ns-enter-btn`
449
+ */
450
+
451
+ /** Props for the EnterButton component. */
452
+ interface EnterButtonProps {
453
+ /** Callback fired when the button is clicked. */
454
+ onConfirm: () => void;
455
+ /** Button label. Default: "↵" */
456
+ label?: string;
457
+ /** Additional CSS class name. */
458
+ className?: string;
459
+ }
460
+ /**
461
+ * A small inline button that confirms the current field value.
462
+ *
463
+ * @param props - Button configuration
464
+ */
465
+ declare const EnterButton: React.FC<EnterButtonProps>;
466
+
467
+ /**
468
+ * Confirmed/filled value display component.
469
+ *
470
+ * @remarks
471
+ * Renders the confirmed field value as styled italic text alongside
472
+ * an edit icon. Shown after a field is confirmed.
473
+ * CSS classes: `ns-filled-wrap`, `ns-filled-value`
474
+ */
475
+
476
+ /** Props for the FilledValue component. */
477
+ interface FilledValueProps {
478
+ /** The confirmed value to display. */
479
+ value: string;
480
+ /** Suffix text displayed after the value. */
481
+ suffix?: string;
482
+ /** Whether the edit icon should be shown. Default: true */
483
+ editable?: boolean;
484
+ /** Callback fired when the edit icon is clicked. */
485
+ onEdit?: () => void;
486
+ /** Label for the edit button. Default: "Edit" */
487
+ editLabel?: string;
488
+ /** Additional CSS class name. */
489
+ className?: string;
490
+ }
491
+ /**
492
+ * Displays a confirmed field value with an optional edit icon.
493
+ *
494
+ * @param props - FilledValue configuration
495
+ */
496
+ declare const FilledValue: React.FC<FilledValueProps>;
497
+
498
+ /**
499
+ * Pencil edit icon button for confirmed fields.
500
+ *
501
+ * @remarks
502
+ * Appears inline next to the filled value after a field is confirmed.
503
+ * Clicking it reopens the field for editing.
504
+ * CSS class: `ns-edit-btn`
505
+ */
506
+
507
+ /** Props for the EditIcon component. */
508
+ interface EditIconProps {
509
+ /** Callback fired when the edit icon is clicked. */
510
+ onEdit: () => void;
511
+ /** Accessible label for the button. Default: "Edit" */
512
+ label?: string;
513
+ /** Additional CSS class name. */
514
+ className?: string;
515
+ }
516
+ /**
517
+ * A small pencil icon button that triggers field editing.
518
+ *
519
+ * @param props - Edit icon configuration
520
+ */
521
+ declare const EditIcon: React.FC<EditIconProps>;
522
+
523
+ /**
524
+ * ErrorMessage — validation error display for narrative-form.
525
+ *
526
+ * @remarks
527
+ * Displays validation errors based on the configured mode (inline, tooltip).
528
+ * Supports animations (fadeUp, slideDown, shake) and optional icons.
529
+ *
530
+ * CSS classes:
531
+ * - `ns-error-wrap` (base)
532
+ * - `ns-error-wrap--tooltip` / `ns-error-wrap--inline`
533
+ * - `ns-error-wrap--above` / `ns-error-wrap--below`
534
+ * - `ns-error-text`
535
+ * - `ns-error-text--shake`
536
+ * - `ns-animate-fade-up` / `ns-animate-slide-down`
537
+ */
538
+
539
+ /** Props for the ErrorMessage component. */
540
+ interface ErrorMessageProps {
541
+ /** The error message to display. */
542
+ message: string;
543
+ /** Display configuration for the error. */
544
+ display?: NarrativeErrorDisplay;
545
+ /** Additional CSS class name. */
546
+ className?: string;
547
+ }
548
+ /**
549
+ * Renders a validation error message.
550
+ *
551
+ * @param props - Error message configuration
552
+ */
553
+ declare const ErrorMessage: React.FC<ErrorMessageProps>;
554
+
555
+ /**
556
+ * TextField — the default text input field type for narrative-form.
557
+ *
558
+ * @remarks
559
+ * Wraps InlineInput with text-specific defaults.
560
+ * This is the simplest field type — all other types build on this pattern.
561
+ * CSS class: `ns-input--text`
562
+ */
563
+
564
+ /** Props for the TextField component. */
565
+ interface TextFieldProps {
566
+ /** Unique field key. */
567
+ fieldKey: string;
568
+ /** Placeholder text. */
569
+ placeholder?: string;
570
+ /** Initial value (for edit mode). */
571
+ defaultValue?: string;
572
+ /** Suffix text after the input. */
573
+ suffix?: string;
574
+ /** Callback when the value is confirmed. */
575
+ onConfirm: (value: string) => void;
576
+ /** Callback on every keystroke. */
577
+ onChange?: (value: string) => void;
578
+ /** Callback when input receives focus. */
579
+ onFocus?: () => void;
580
+ /** Callback when input loses focus. */
581
+ onBlur?: (value: string) => void;
582
+ /** Additional CSS class for the input element. */
583
+ inputClassName?: string;
584
+ /** Additional CSS class for the wrapper. */
585
+ className?: string;
586
+ }
587
+ /**
588
+ * A text input field rendered inline within a sentence.
589
+ *
590
+ * @param props - TextField configuration
591
+ */
592
+ declare const TextField: React.FC<TextFieldProps>;
593
+
594
+ /**
595
+ * TelField — phone number input field for narrative-form.
596
+ *
597
+ * @remarks
598
+ * Renders an inline input with `type="tel"` for numeric keyboard on mobile.
599
+ * CSS class: `ns-input--tel`
600
+ */
601
+
602
+ /** Props for the TelField component. */
603
+ interface TelFieldProps {
604
+ /** Unique field key. */
605
+ fieldKey: string;
606
+ /** Placeholder text. */
607
+ placeholder?: string;
608
+ /** Initial value (for edit mode). */
609
+ defaultValue?: string;
610
+ /** Suffix text after the input. */
611
+ suffix?: string;
612
+ /** Callback when the value is confirmed. */
613
+ onConfirm: (value: string) => void;
614
+ /** Callback on every keystroke. */
615
+ onChange?: (value: string) => void;
616
+ /** Callback when input receives focus. */
617
+ onFocus?: () => void;
618
+ /** Callback when input loses focus. */
619
+ onBlur?: (value: string) => void;
620
+ /** Additional CSS class for the input element. */
621
+ inputClassName?: string;
622
+ /** Additional CSS class for the wrapper. */
623
+ className?: string;
624
+ }
625
+ /**
626
+ * A phone number input field rendered inline within a sentence.
627
+ *
628
+ * @param props - TelField configuration
629
+ */
630
+ declare const TelField: React.FC<TelFieldProps>;
631
+
632
+ /**
633
+ * EmailField — email input field for narrative-form.
634
+ *
635
+ * @remarks
636
+ * Renders an inline input with `type="email"` for email keyboard on mobile.
637
+ * CSS class: `ns-input--email`
638
+ */
639
+
640
+ /** Props for the EmailField component. */
641
+ interface EmailFieldProps {
642
+ /** Unique field key. */
643
+ fieldKey: string;
644
+ /** Placeholder text. */
645
+ placeholder?: string;
646
+ /** Initial value (for edit mode). */
647
+ defaultValue?: string;
648
+ /** Suffix text after the input. */
649
+ suffix?: string;
650
+ /** Callback when the value is confirmed. */
651
+ onConfirm: (value: string) => void;
652
+ /** Callback on every keystroke. */
653
+ onChange?: (value: string) => void;
654
+ /** Callback when input receives focus. */
655
+ onFocus?: () => void;
656
+ /** Callback when input loses focus. */
657
+ onBlur?: (value: string) => void;
658
+ /** Additional CSS class for the input element. */
659
+ inputClassName?: string;
660
+ /** Additional CSS class for the wrapper. */
661
+ className?: string;
662
+ }
663
+ /**
664
+ * An email input field rendered inline within a sentence.
665
+ *
666
+ * @param props - EmailField configuration
667
+ */
668
+ declare const EmailField: React.FC<EmailFieldProps>;
669
+
670
+ /**
671
+ * PasswordField — masked password input for narrative-form.
672
+ *
673
+ * @remarks
674
+ * Renders an inline input with `type="password"` and a show/hide toggle.
675
+ * CSS classes: `ns-input--password`, `ns-password-toggle`
676
+ */
677
+
678
+ /** Props for the PasswordField component. */
679
+ interface PasswordFieldProps {
680
+ /** Unique field key. */
681
+ fieldKey: string;
682
+ /** Placeholder text. */
683
+ placeholder?: string;
684
+ /** Initial value (for edit mode). */
685
+ defaultValue?: string;
686
+ /** Suffix text after the input. */
687
+ suffix?: string;
688
+ /** Callback when the value is confirmed. */
689
+ onConfirm: (value: string) => void;
690
+ /** Callback on every keystroke. */
691
+ onChange?: (value: string) => void;
692
+ /** Callback when input receives focus. */
693
+ onFocus?: () => void;
694
+ /** Callback when input loses focus. */
695
+ onBlur?: (value: string) => void;
696
+ /** Whether to show a show/hide toggle. Default: true */
697
+ showToggle?: boolean;
698
+ /** Additional CSS class for the input element. */
699
+ inputClassName?: string;
700
+ /** Additional CSS class for the wrapper. */
701
+ className?: string;
702
+ }
703
+ /**
704
+ * A masked password input field with optional show/hide toggle.
705
+ *
706
+ * @param props - PasswordField configuration
707
+ */
708
+ declare const PasswordField: React.FC<PasswordFieldProps>;
709
+
710
+ /**
711
+ * NumberField — numeric input field for narrative-form.
712
+ *
713
+ * @remarks
714
+ * Renders an inline input with `type="number"` for numeric entry.
715
+ * CSS class: `ns-input--number`
716
+ */
717
+
718
+ /** Props for the NumberField component. */
719
+ interface NumberFieldProps {
720
+ /** Unique field key. */
721
+ fieldKey: string;
722
+ /** Placeholder text. */
723
+ placeholder?: string;
724
+ /** Initial value (for edit mode). */
725
+ defaultValue?: string;
726
+ /** Suffix text after the input. */
727
+ suffix?: string;
728
+ /** Callback when the value is confirmed. */
729
+ onConfirm: (value: string) => void;
730
+ /** Callback on every keystroke. */
731
+ onChange?: (value: string) => void;
732
+ /** Callback when input receives focus. */
733
+ onFocus?: () => void;
734
+ /** Callback when input loses focus. */
735
+ onBlur?: (value: string) => void;
736
+ /** Additional CSS class for the input element. */
737
+ inputClassName?: string;
738
+ /** Additional CSS class for the wrapper. */
739
+ className?: string;
740
+ }
741
+ /**
742
+ * A numeric input field rendered inline within a sentence.
743
+ *
744
+ * @param props - NumberField configuration
745
+ */
746
+ declare const NumberField: React.FC<NumberFieldProps>;
747
+
748
+ /**
749
+ * ChipsField — tap to select one option for narrative-form.
750
+ *
751
+ * @remarks
752
+ * Renders a row of pill-shaped chips. User taps one to select it.
753
+ * Supports optional auto-advance, keyboard navigation (Arrow keys + Space),
754
+ * and RTL layout.
755
+ * CSS classes: `ns-chips-wrap`, `ns-chip`, `ns-chip--active`, `ns-chip--hover`
756
+ */
757
+
758
+ /** Props for the ChipsField component. */
759
+ interface ChipsFieldProps {
760
+ /** Unique field key. */
761
+ fieldKey: string;
762
+ /** Array of option labels. */
763
+ options: string[];
764
+ /** Currently selected value (for edit mode). */
765
+ defaultValue?: string;
766
+ /** Whether to auto-confirm on selection. Default: false */
767
+ autoAdvance?: boolean;
768
+ /** Callback when a value is confirmed. */
769
+ onConfirm: (value: string) => void;
770
+ /** Callback on selection change. */
771
+ onChange?: (value: string) => void;
772
+ /** Additional CSS class for the wrapper. */
773
+ className?: string;
774
+ }
775
+ /**
776
+ * A single-select chip field rendered inline within a sentence.
777
+ * Supports Arrow Left/Right keyboard navigation and Space to select.
778
+ *
779
+ * @param props - ChipsField configuration
780
+ */
781
+ declare const ChipsField: React.FC<ChipsFieldProps>;
782
+
783
+ /**
784
+ * MultiChipsField — tap to select multiple options for narrative-form.
785
+ *
786
+ * @remarks
787
+ * Renders a row of pill-shaped chips. User can tap multiple to select them.
788
+ * Confirmed value is an array of selected option strings.
789
+ * CSS classes: `ns-chips-wrap`, `ns-chip`, `ns-chip--active`, `ns-chip--hover`
790
+ */
791
+
792
+ /** Props for the MultiChipsField component. */
793
+ interface MultiChipsFieldProps {
794
+ /** Unique field key. */
795
+ fieldKey: string;
796
+ /** Array of option labels. */
797
+ options: string[];
798
+ /** Currently selected values (for edit mode). */
799
+ defaultValue?: string[];
800
+ /** Callback when values are confirmed. Receives comma-separated string. */
801
+ onConfirm: (value: string) => void;
802
+ /** Callback on selection change. */
803
+ onChange?: (value: string) => void;
804
+ /** Additional CSS class for the wrapper. */
805
+ className?: string;
806
+ }
807
+ /**
808
+ * A multi-select chip field rendered inline within a sentence.
809
+ *
810
+ * @param props - MultiChipsField configuration
811
+ */
812
+ declare const MultiChipsField: React.FC<MultiChipsFieldProps>;
813
+
814
+ /**
815
+ * SelectField — inline dropdown for narrative-form.
816
+ *
817
+ * @remarks
818
+ * Renders a native `<select>` element inline within a sentence.
819
+ * CSS classes: `ns-select-wrap`, `ns-select`
820
+ */
821
+
822
+ /** Props for the SelectField component. */
823
+ interface SelectFieldProps {
824
+ /** Unique field key. */
825
+ fieldKey: string;
826
+ /** Array of option labels. */
827
+ options: string[];
828
+ /** Placeholder text for the default empty option. */
829
+ placeholder?: string;
830
+ /** Currently selected value (for edit mode). */
831
+ defaultValue?: string;
832
+ /** Whether to auto-confirm on selection. Default: false */
833
+ autoAdvance?: boolean;
834
+ /** Callback when a value is confirmed. */
835
+ onConfirm: (value: string) => void;
836
+ /** Callback on selection change. */
837
+ onChange?: (value: string) => void;
838
+ /** Callback when input receives focus. */
839
+ onFocus?: () => void;
840
+ /** Callback when input loses focus. */
841
+ onBlur?: (value: string) => void;
842
+ /** Additional CSS class for the select element. */
843
+ inputClassName?: string;
844
+ /** Additional CSS class for the wrapper. */
845
+ className?: string;
846
+ }
847
+ /**
848
+ * An inline dropdown select field rendered within a sentence.
849
+ *
850
+ * @param props - SelectField configuration
851
+ */
852
+ declare const SelectField: React.FC<SelectFieldProps>;
853
+
854
+ /**
855
+ * OtpField — N-digit OTP input for narrative-form.
856
+ *
857
+ * @remarks
858
+ * Each digit is a separate focusable input. Auto-focuses the next box
859
+ * on digit entry, auto-focuses previous on backspace. Paste distributes
860
+ * across all boxes. Never logs or exposes the OTP value in console.
861
+ *
862
+ * CSS classes: `ns-otp-wrap`, `ns-otp-box`, `ns-otp-box--filled`,
863
+ * `ns-otp-box--active`, `ns-otp-box--error`, `ns-otp-resend`,
864
+ * `ns-otp-resend--disabled`, `ns-otp-timer`
865
+ */
866
+
867
+ /** Props for the OtpField component. */
868
+ interface OtpFieldProps {
869
+ /** Unique field key. */
870
+ fieldKey: string;
871
+ /** Number of OTP digit boxes. Default: 6 */
872
+ otpLength?: number;
873
+ /** Whether to auto-submit when all digits are filled. Default: true */
874
+ autoAdvance?: boolean;
875
+ /** Called when the OTP field first appears — triggers OTP send. */
876
+ onRequest?: () => void | Promise<void>;
877
+ /** Called when all digits are filled. */
878
+ onVerify?: (otp: string) => void | Promise<void>;
879
+ /** Callback when the full OTP is confirmed. */
880
+ onConfirm: (value: string) => void;
881
+ /** Callback on value change. */
882
+ onChange?: (value: string) => void;
883
+ /** Label for the resend link. Default: "Resend code" */
884
+ resendLabel?: string;
885
+ /** Seconds before resend is allowed. Default: 30 */
886
+ resendDelay?: number;
887
+ /** Additional CSS class for the wrapper. */
888
+ className?: string;
889
+ }
890
+ /**
891
+ * An N-digit OTP input with auto-focus, paste distribution, and resend timer.
892
+ *
893
+ * @param props - OtpField configuration
894
+ */
895
+ declare const OtpField: React.FC<OtpFieldProps>;
896
+
897
+ export { ChipsField, type ChipsFieldProps, Cursor, type CursorProps, DoneScreen, type DoneScreenProps, EditIcon, type EditIconProps, EmailField, type EmailFieldProps, EnterButton, type EnterButtonProps, ErrorMessage, type ErrorMessageProps, FilledValue, type FilledValueProps, InlineInput, type InlineInputProps, Line, type LineProps, MultiChipsField, type MultiChipsFieldProps, NarrativeForm, type NarrativeFormProps, NumberField, type NumberFieldProps, OtpField, type OtpFieldProps, PasswordField, type PasswordFieldProps, Prose, type ProseProps, SelectField, type SelectFieldProps, TelField, type TelFieldProps, TextField, type TextFieldProps, type ThemeContextValue, ThemeProvider, type ThemeProviderProps, type UseFormStateResult, type UseTypewriterOptions, type UseTypewriterResult, WelcomeScreen, type WelcomeScreenProps, useFormState, useTheme, useTypewriter };