@samline/forms 2.7.1 → 2.8.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/CHANGELOG.md +302 -0
- package/README.md +110 -122
- package/dist/browser/global.d.ts +1 -13
- package/dist/browser/global.global.js +12 -6179
- package/dist/browser/global.global.js.map +1 -1
- package/dist/browser/index.cjs +125 -56
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/{chunk-MMHX34WB.js → chunk-23VZAYA3.js} +126 -57
- package/dist/chunk-23VZAYA3.js.map +1 -0
- package/dist/index.cjs +125 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +35 -7
- package/dist/chunk-MMHX34WB.js.map +0 -1
- package/docs/api/add-cleanup.md +0 -52
- package/docs/api/append.md +0 -96
- package/docs/api/auto-submit.md +0 -91
- package/docs/api/clear-errors.md +0 -69
- package/docs/api/destroy.md +0 -80
- package/docs/api/disable-auto-submit.md +0 -65
- package/docs/api/element.md +0 -78
- package/docs/api/form.md +0 -156
- package/docs/api/format.md +0 -270
- package/docs/api/get-data.md +0 -90
- package/docs/api/get-field.md +0 -87
- package/docs/api/get-state.md +0 -111
- package/docs/api/get-value.md +0 -114
- package/docs/api/index.md +0 -55
- package/docs/api/observe.md +0 -126
- package/docs/api/on-submit.md +0 -94
- package/docs/api/parse-form-data.md +0 -94
- package/docs/api/prefill.md +0 -89
- package/docs/api/regex.md +0 -155
- package/docs/api/reset.md +0 -61
- package/docs/api/revalidate.md +0 -52
- package/docs/api/set-errors.md +0 -97
- package/docs/api/set-value.md +0 -120
- package/docs/api/subscribe.md +0 -107
- package/docs/api/unwatch.md +0 -74
- package/docs/api/validate-field-value.md +0 -144
- package/docs/api/validate-values.md +0 -103
- package/docs/api/validate.md +0 -102
- package/docs/api/watch.md +0 -117
- package/docs/browser.md +0 -156
- package/docs/css-styling.md +0 -191
- package/docs/getting-started.md +0 -222
- package/docs/options.md +0 -326
- package/docs/recipes.md +0 -531
- package/docs/typescript.md +0 -615
- package/docs/vanilla.md +0 -12
- /package/{LICENSE → LICENSE.md} +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@samline/forms` are documented in this file. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [2.8.0] - 2026-11-06
|
|
8
|
+
|
|
9
|
+
No breaking API changes. The behavior changes below fix incorrect or surprising results; review them if your code relied on the old behavior.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `prefill()` writes a repeated query key (`?tags[]=a&tags[]=b`) once as an array instead of keeping only the last value, and auto-submit runs once after the whole prefill instead of once per field.
|
|
14
|
+
- A native `<button type="reset">` or a direct `form.reset()` now clears errors, `css-filled`, `css-error` and `aria-invalid` and restores formatted mirrors, like `reset()`. A canceled `reset` event is respected.
|
|
15
|
+
- The form's `MutationObserver` ignores markup that contains no form controls, so a subscriber that renders messages or a summary into the form no longer re-enters validation in an endless loop.
|
|
16
|
+
- An invalid submit started by auto-submit no longer moves focus away from the field being edited.
|
|
17
|
+
- After a failed submit, focus goes to the first invalid control in document order instead of the first field declared in `validators`.
|
|
18
|
+
- Formatting no longer moves the selection of an input that does not have focus (initial values, `setValue()`, `reset()`), which could also focus it in Safari.
|
|
19
|
+
- After `destroy()`, mutating methods (`setValue`, `setErrors`, `clearErrors`, `validate`, `revalidate`, `reset`, `prefill`, `append`, `autoSubmit`) and new registrations (`subscribe`, `observe`, `watch`, `onSubmit`) are no-ops, so an async handler that settles late cannot repaint a form now owned by another controller. `validate()` returns `{ isValid: true, errors: {} }`.
|
|
20
|
+
- `window.Forms` from the standalone script has exactly `form`, `newForm`, `destroyForm` and `available`; it no longer includes a `default` key.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- `reset()` and native resets call `watch()`/`observe()` callbacks with the restored values.
|
|
25
|
+
- A rejected promise returned by an `onSubmit()` handler is reported with `console.error('[forms] submit handler failed', reason)` instead of being swallowed. `isSubmitting` still settles.
|
|
26
|
+
- The standalone `dist/browser/global.global.js` is minified (about 188 KB instead of 343 KB before compression); module builds are unchanged.
|
|
27
|
+
- State reads index the form's controls once per snapshot instead of once per field name.
|
|
28
|
+
- Raised the optional `@samline/formatter` peer and development dependency to `^2.1.0` (released 2026-11-06). The standalone script now bundles it, including its fixes for `regex.numeral`, `regex.password`, case-insensitive phone countries and decorated `general` masks.
|
|
29
|
+
- Documentation moved to the website at <https://samline.github.io/forms/docs/>. The npm tarball now ships `dist`, `README.md`, `LICENSE.md` and `CHANGELOG.md`; the Markdown `docs/` folder is no longer published. Old Starlight URLs redirect to their new pages.
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- A landing page, twelve live examples with copyable HTML / CDN and Package / ESM files, framework guides and an AI agent skill at `skills/forms/SKILL.md`.
|
|
34
|
+
|
|
35
|
+
## [2.7.2] - 2026-09-23
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- Raised the optional `@samline/formatter` peer and development dependency minimum to `^2.0.3`, ensuring consumers receive the latest formatter fixes for empty date/time delimiters, suffix stripping, and parametric password validation.
|
|
40
|
+
- Updated the npm-bundled and Starlight documentation examples to reference `@samline/forms@2.7.2`.
|
|
41
|
+
|
|
42
|
+
## [2.7.1] - 2026-09-23
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Interpreted user input and rebind values as display-order data while retaining automatic detection for canonical mirrors and initial server values.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- Synchronized the internal and Starlight formatter-integration documentation.
|
|
51
|
+
- Removed duplicated implementation narratives and obsolete comments without changing the public API.
|
|
52
|
+
|
|
53
|
+
## [2.7.0] - 2026-09-22
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- Added explicit `dependsOn` metadata for reactive custom cross-field validation with transitive, cycle-safe dependency traversal.
|
|
58
|
+
- Added per-member `each` validation with element-specific `css-error` and `aria-invalid` state for repeated controls while preserving the public `FormErrors` string-array shape.
|
|
59
|
+
- Added strict decimal `numeric`, inclusive `min`, and inclusive `max` validation rules.
|
|
60
|
+
- Added promise-aware submit tracking through `FormStateSnapshot.isSubmitting`, including concurrent and rejected handler promises.
|
|
61
|
+
- Added `addCleanup()` for controller-owned integration teardown.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- Synchronized initial and reset `css-filled` state independently from `autoValidate`, without activating validation.
|
|
66
|
+
- Resolved per-input visual validation state for repeated `name="foo[]"` controls ([#1](https://github.com/samline/forms/issues/1)).
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
|
|
70
|
+
- Updated GitHub Actions, Astro, Starlight, and documentation tooling to their reviewed supported releases, including the Node and Astro compatibility floors required by those updates.
|
|
71
|
+
- Synchronized the npm-bundled and Starlight documentation with every new public type, rule, method, and state transition.
|
|
72
|
+
|
|
73
|
+
## [2.6.0] - 2026-09-21
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- Added the declarative `sameAs` validation rule for password confirmations and other fields that must contain equal non-empty values, with custom messages through `RuleConfig<string>`.
|
|
78
|
+
- Added automatic dependent-field revalidation for `sameAs`, including transitive dependencies, cycle-safe deduplication, `setValue()` updates, and activation after manual validation.
|
|
79
|
+
- Added regression coverage for matching strings, ordered arrays, empty values, source-field changes, reciprocal cycles, and transitive dependencies.
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- Expanded the npm-bundled and Starlight documentation with `sameAs` recipes, exact equality semantics, empty-value behavior, file identity rules, cycle guarantees, and guidance to place mismatch errors on confirmation fields only.
|
|
84
|
+
|
|
85
|
+
## [2.5.1] - 2026-09-20
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
|
|
89
|
+
- Corrected documentation for exact validator names, radio and collection values, subscriber notification points, destroyed-controller behavior, shared browser registries, formatter mirrors, and optional-peer behavior.
|
|
90
|
+
|
|
91
|
+
### Added
|
|
92
|
+
|
|
93
|
+
- Added focused Starlight guides for accessible validation and input formatting, plus references for native control behavior and package entrypoints.
|
|
94
|
+
|
|
95
|
+
### Changed
|
|
96
|
+
|
|
97
|
+
- Reorganized the documentation sidebar, expanded the API lifecycle contracts, improved accessible examples, and synchronized the npm-bundled and hosted documentation surfaces.
|
|
98
|
+
|
|
99
|
+
## [2.5.0] - 2026-09-19
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
|
|
103
|
+
- Corrected the browser IIFE so `Forms.form`, `Forms.newForm`, `Forms.destroyForm`, and `Forms.available` are exposed directly instead of under `Forms.default`.
|
|
104
|
+
- Fixed duplicate field processing, formatted-field reset state, submitter serialization, duplicate browser controllers, stateful regular expressions, external associated controls, multiple selects, reserved field names, escaped class names, pending auto-submit cancellation, and async formatter teardown.
|
|
105
|
+
- Added `aria-invalid` synchronization and focus management for invalid submissions.
|
|
106
|
+
|
|
107
|
+
### Added
|
|
108
|
+
|
|
109
|
+
- Added ESM/CJS browser entrypoints, package artifact smoke tests, CJS/ESM type-consumer tests, coverage thresholds, pull-request CI, dependency auditing, and Dependabot configuration.
|
|
110
|
+
- Added regression coverage for the corrected DOM, validation, serialization, formatting, and registry behavior.
|
|
111
|
+
|
|
112
|
+
### Changed
|
|
113
|
+
|
|
114
|
+
- Added `docs/` to the npm package, corrected conditional type exports, exported `FormDataPrimitive` and `FormFieldWatcher`, and made multi-field formatter configuration reject a shared `displayField` without mutating the form.
|
|
115
|
+
- Updated root and documentation-site dependencies to audited versions and synchronized both documentation surfaces.
|
|
116
|
+
|
|
117
|
+
## [2.4.0] - 2026-07-19
|
|
118
|
+
|
|
119
|
+
### Fixed
|
|
120
|
+
|
|
121
|
+
- `applyFormat` phase 2 and the capture-phase input handler now override `interpretInputAs` to `'auto'` for the initial value pass and for input events whose source is the hidden raw mirror, so a server pre-fill of the canonical raw (e.g. a Blade re-render with `value="{{ old('birthday') }}"` carrying `"19901212"` for a `d/m/Y` display + `Ymd` raw combo) is correctly converted to the display form on mount. Without the override, `@samline/formatter` v1.2.0+ — which changed `interpretInputAs` to default to `'display'` — mis-segmented the raw digits and the visible ended up showing the scrambled value (e.g. `"19/09/1212"`) instead of `"12/12/1990"`. As of `@samline/formatter@2.0.0`, the default is `'auto'` (which handles the same case via the formatter's own heuristic), so the override is now a defensive explicit declaration of intent rather than strictly required. It still serves two purposes: (1) it documents the controller's context awareness in code, and (2) it protects against a future formatter change that flips the default again. Live keystrokes on the visible input keep the formatter's default because what the user types is in display order. An explicit `interpretInputAs` in `config.options` is always respected, never overridden — pass `'display'` if you pre-render the visible in display order from the server, or `'raw'` if you want the legacy pre-1.2.0 round-trip semantics for the initial pass.
|
|
122
|
+
|
|
123
|
+
### Added
|
|
124
|
+
|
|
125
|
+
- Five regression tests under `test/api/format.test.ts`: the easytrip / Blade `old()` case (raw initial value → display form on mount), the live keystroke path (no `interpretInputAs` override applied to user typing), `setValue('field', raw)` writes the canonical raw with the `'auto'` interpretation forced, the explicit `interpretInputAs: 'display'` opt-in is preserved, and the re-bind path forwards the caller's options verbatim.
|
|
126
|
+
|
|
127
|
+
### Changed
|
|
128
|
+
|
|
129
|
+
- `docs/api/format.md` adds an "Initial value interpretation (server pre-fill)" section that documents the override and the four contexts (initial pass, mirror-source events, live keystrokes, re-bind) with the explicit opt-in caveat. With the formatter v2.0.0 default flip, the prose now notes that the override is defensive rather than strictly required.
|
|
130
|
+
- `example/src/content/docs/reference/api.md` (Starlight mirror) gains a "Server pre-fill" note in the `format()` summary so the npm-bundled docs and the live site stay in sync.
|
|
131
|
+
- `example/src/content/docs/reference/typescript.md` notes the `interpretInputAs` override in the `FieldFormatConfig` prose so consumers reading the type signature know the initial pass is the special case.
|
|
132
|
+
- The peer dependency `@samline/formatter` is now `^2.0.0` (was `^1.0.1`). The `^1.x` range no longer receives the v2.0.0 fix, so consumers on the previous major must pin explicitly or upgrade.
|
|
133
|
+
|
|
134
|
+
## [2.3.4] - 2026-07-16
|
|
135
|
+
|
|
136
|
+
### Fixed
|
|
137
|
+
|
|
138
|
+
- `readFieldValue` and `writeFieldValue` now respect the `name="foo[]"` convention for multi-value inputs. Previously, `getValue` returned only the first matching input's value and `setValue` wrote the same string to every matching input, breaking custom validators that check `Array.isArray(value)` on fields like `docusign_email[]`. The `[]` suffix is the de facto HTML pattern for array inputs (PHP, Rails, Express, Spring); the controller now treats it as the explicit signal for "collect all values as an array".
|
|
139
|
+
|
|
140
|
+
### Added
|
|
141
|
+
|
|
142
|
+
- Eleven regression tests under `test/api/array-syntax.test.ts` covering `getValue` / `setValue` with `name="foo[]"` for text, email, checkbox, and file inputs (the last via a hand-built `FileList`), plus guards that `name="foo"` (no brackets) keeps the original first-value / broadcast semantics and that custom validators keyed on the bracketed name now receive the full array.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- `docs/api/get-value.md` and `docs/api/set-value.md` document the `name="foo[]"` behaviour in the per-field-type tables, with a new example for each direction and a dedicated edge-case bullet describing the explicit opt-in. `example/src/content/docs/reference/api.md` mirrors the note in the Starlight reference so the npm-bundled docs and the live site stay in sync.
|
|
147
|
+
|
|
148
|
+
## [2.3.3] - 2026-07-16
|
|
149
|
+
|
|
150
|
+
### Fixed
|
|
151
|
+
|
|
152
|
+
- `syncVisualState` was routing `css-filled` and `css-error` to the **visible** input only on the user-typing path (`handleDelegatedEvent`). Every other path — `validate()`, `revalidate()`, `setErrors()`, `clearErrors()` with a name list, the initial mount, and the `MutationObserver`-driven re-sync — still wrote the attribute to the hidden raw mirror. For formatted fields the project label never matched `:has([css-error])` and the error indicator was invisible. The fix centralises the canonical→display name resolution inside `syncVisualState` itself, so all five call sites are fixed at once and the visual attribute contract documented in `api/format.ts` is honoured by every public entrypoint.
|
|
153
|
+
|
|
154
|
+
### Added
|
|
155
|
+
|
|
156
|
+
- Seven regression tests under `test/api/format.test.ts`: `validate()` (no-arg and with an explicit name list), `revalidate()`, `setErrors()` (array and map form), `clearErrors()` with a name list, and the initial-mount path with a pre-populated hidden mirror.
|
|
157
|
+
|
|
158
|
+
### Changed
|
|
159
|
+
|
|
160
|
+
- `docs/css-styling.md` adds a callout after the `:has()` recipe explaining that the hidden mirror created by `format()` lives outside any label and that the controller always targets the visible.
|
|
161
|
+
- `docs/recipes.md` adds a one-liner to the mirror-convention section cross-referencing the styling page.
|
|
162
|
+
|
|
163
|
+
## [2.3.2] - 2026-07-16
|
|
164
|
+
|
|
165
|
+
### Fixed
|
|
166
|
+
|
|
167
|
+
- `css-filled` and `css-error` were being written to the hidden raw mirror for fields wired through `format()`, so the `:has([css-filled])` selector on the project label parent never matched and the label text stayed invisible. `handleDelegatedEvent` now resolves the event target to the display name and calls `syncVisualState([displayName])` so visual attributes land on the element the user sees. The data path (validation, errors, raw mirror) is unchanged.
|
|
168
|
+
|
|
169
|
+
### Added
|
|
170
|
+
|
|
171
|
+
- Three regression tests for the user-typing path: `css-filled` on the visible after a keystroke, `css-filled` on the visible when `setValue` writes the canonical, and a guard for non-formatted fields.
|
|
172
|
+
|
|
173
|
+
## [2.3.1] - 2026-07-15
|
|
174
|
+
|
|
175
|
+
### Fixed
|
|
176
|
+
|
|
177
|
+
- When `format()` was called multiple times in the same tick (e.g. `format(phone)` + `format(date)` + `format(general)` at form init), the first `applyFormat` to resume from `await loadFormatter()` would bind every entry in the bucket with the first call's config; the subsequent calls short-circuited on the "already bound" check. The easytrip registration form hit this: phone formatter ran for all three fields, so date and tag_number output was phone-style instead of date / general. Phase 2 of `applyFormat` is now scoped to the entries the current call touched (via a local `phase1Entries` array) instead of iterating the whole bucket.
|
|
178
|
+
|
|
179
|
+
### Added
|
|
180
|
+
|
|
181
|
+
- Regression test covers the three-sequential-`format()` case end-to-end.
|
|
182
|
+
|
|
183
|
+
## [2.3.0] - 2026-07-15
|
|
184
|
+
|
|
185
|
+
### Changed
|
|
186
|
+
|
|
187
|
+
- **`format()` mirror convention inverted.** The canonical name (`<field>`) now carries the raw value on a hidden input appended to the form; the visible input is renamed to `<field>_displayed` (or whatever `displayField` resolves to). Both names are first-class in the controller's API: `getValue('phone')` returns the raw, `getValue('phone_displayed')` returns the formatted, `watch('phone', cb)` fires with the raw, etc. `rawField` config renamed to `displayField`.
|
|
188
|
+
- `format()` runs in two phases: phase 1 (sync) renames the visible and creates/reuses the hidden mirror; phase 2 (async) loads the formatter peer and binds the input listener. The sync phase rolls back on a missing peer so the DOM is left exactly as the developer authored it.
|
|
189
|
+
- `state.listeners` tracks `capture?` to match `addEventListener` (`exactOptionalPropertyTypes: true`).
|
|
190
|
+
- `destroy()` restores the visible's name to the canonical form and detaches every capture-phase listener added by `format()`.
|
|
191
|
+
|
|
192
|
+
### Notes
|
|
193
|
+
|
|
194
|
+
- No peer changes — options are still forwarded to `@samline/formatter` as before, so `datePattern`, `dateRawPattern`, `rawPrefix`, `rawSuffix`, `prefixMode`, `suffixMode`, etc. all keep working identically.
|
|
195
|
+
|
|
196
|
+
## [2.2.3] - 2026-07-14
|
|
197
|
+
|
|
198
|
+
### Fixed
|
|
199
|
+
|
|
200
|
+
- Cursor jumped past digits when backspacing adjacent to a delimiter. `applyFormattedValue` ignored `InputEvent.inputType` and `computeCursorPosition` counted non-format characters to the left of the caret without ever pulling the cursor back past a re-inserted delimiter. After a `deleteContentBackward` / `deleteWordBackward` the caret could land with a format character immediately on its left, so the next backspace removed the delimiter instead of the digit the user expected to delete.
|
|
201
|
+
- `applyFormattedValue` now threads `InputEvent.inputType` from `buildHandler` and applies cleave.js' `postDelimiterBackspace` scan in **both** branches of the function (early-return and full `computeCursorPosition`), so the contract holds whether or not the formatter rewrites the visible value.
|
|
202
|
+
|
|
203
|
+
### Added
|
|
204
|
+
|
|
205
|
+
- Four vitest cases under `test/api/format.test.ts` covering the `postDelimiterBackspace` contract for `deleteContentBackward` adjacent to a delimiter, deletion of a delimiter itself, `deleteWordBackward` in the middle of a formatted value, and a DD/MM/YYYY date field with the caret parked after the first slash.
|
|
206
|
+
|
|
207
|
+
## [2.2.2] - 2026-07-10
|
|
208
|
+
|
|
209
|
+
### Fixed
|
|
210
|
+
|
|
211
|
+
- `@samline/formatter` peer was being silently left as a bare specifier in the IIFE bundle, so `format()` / `formatAll()` did not run in Vite / Rollup production builds. The dynamic import carried a `/* @vite-ignore */` hint, which told Rollup to leave the literal `'@samline/formatter'` in the bundle.
|
|
212
|
+
- The IIFE build now bundles the peer; ESM and CJS still externalize it. Consumers that need to ship the formatter separately can do so via a bundler-level externals configuration.
|
|
213
|
+
|
|
214
|
+
## [2.2.1] - 2026-06-30
|
|
215
|
+
|
|
216
|
+
### Changed
|
|
217
|
+
|
|
218
|
+
- Documentation references aligned to 2.2.1 (CDN URLs in `README.md` and `docs/browser.md`).
|
|
219
|
+
|
|
220
|
+
## [2.2.0] - 2026-06-30
|
|
221
|
+
|
|
222
|
+
### Added
|
|
223
|
+
|
|
224
|
+
- `browser` singleton export for bundler usage — the same `{ form, newForm, destroyForm, available }` surface as the IIFE, but as a module-level singleton, so bundler consumers can use the registry helpers without opting into the IIFE `globalThis` side-effect.
|
|
225
|
+
|
|
226
|
+
### Fixed
|
|
227
|
+
|
|
228
|
+
- `format()` integration tests: raw mirror handling on `setValue` writing the display name (the visible's `.value` was being clobbered by the canonical write path).
|
|
229
|
+
|
|
230
|
+
## [2.1.0] - 2026-06-30
|
|
231
|
+
|
|
232
|
+
> Not tagged at the time. The version was bumped and published; this entry is reconstructed from the commit log between v1.0.3 and v2.2.0.
|
|
233
|
+
|
|
234
|
+
### Added
|
|
235
|
+
|
|
236
|
+
- `@samline/formatter` peer dependency. The controller reads the peer at runtime via a dynamic import; a missing peer is non-fatal — a single `console.error` is logged and `format()` becomes a no-op so the rest of the form keeps working.
|
|
237
|
+
- `format()` / `formatAll()` / `format` options API: `type`, `field` (string or `string[]`), `options` forwarded to the peer, `displayField` for the visible's name.
|
|
238
|
+
- `onSubmit`, `watch`, `observe`, `unwatch`, `subscribe`, `prefill`, `append`, `setErrors`, `clearErrors`, `setValue`, `getValue`, `getField`, `getData`, `getState`, `reset`, `autoSubmit`, `disableAutoSubmit`, `validate`, `revalidate`, `destroy` — the per-method api/ factories.
|
|
239
|
+
|
|
240
|
+
### Changed
|
|
241
|
+
|
|
242
|
+
- **Package focus narrowed to vanilla JS and direct browser usage.** Framework-specific variants and docs were removed (`refactor: remove framework-specific variants and docs, simplify package structure`). The README was rewritten to reflect the new focus.
|
|
243
|
+
- Browser global renamed to `Forms` and a registry helper added: `Forms.newForm({ id, options })` stores the controller under `Forms.available[id]`, `Forms.destroyForm(id)` calls `destroy()` and removes the entry.
|
|
244
|
+
- `watch()` and `observe()` callbacks now receive the field element(s) as an additional argument, so consumers can read attributes (`css-filled`, `css-error`, `aria-*`, …) without doing their own DOM lookup.
|
|
245
|
+
- "API at a glance" section added to the README and browser usage clarified.
|
|
246
|
+
- Installation instructions updated to use `bun`.
|
|
247
|
+
- Deployment branch for the GitHub Pages docs site changed to `v2`.
|
|
248
|
+
- Accessibility skill and patterns documented.
|
|
249
|
+
|
|
250
|
+
## [1.0.3] - 2026-05-31
|
|
251
|
+
|
|
252
|
+
### Fixed
|
|
253
|
+
|
|
254
|
+
- Manual errors were not cleared when the affected field changed. The controller now deletes the entry from `state.manualErrors[canonical]` on the next `input` / `change` event of the affected field, unless `clearManualErrorsOnChange: false` is passed via `FormControllerOptions`.
|
|
255
|
+
|
|
256
|
+
## [1.0.2] - 2026-03-24
|
|
257
|
+
|
|
258
|
+
### Fixed
|
|
259
|
+
|
|
260
|
+
- `npm publish` workflow was failing in CI; auth check fixed.
|
|
261
|
+
|
|
262
|
+
## [1.0.1] - 2026-03-24
|
|
263
|
+
|
|
264
|
+
### Fixed
|
|
265
|
+
|
|
266
|
+
- First stable patch on the 1.x line (release plumbing).
|
|
267
|
+
|
|
268
|
+
## [1.0.0] - 2026-03-24
|
|
269
|
+
|
|
270
|
+
### Fixed
|
|
271
|
+
|
|
272
|
+
- `npm publish` workflow: npm auth check on the publish job.
|
|
273
|
+
|
|
274
|
+
## [0.1.0] - 2026-03-24
|
|
275
|
+
|
|
276
|
+
### Added
|
|
277
|
+
|
|
278
|
+
- Initial release of `@samline/forms`. Vanilla JS form controller with framework-specific variants (React, Vue, Svelte) initially included; bundled `.local/` agent docs at the repo root.
|
|
279
|
+
|
|
280
|
+
[Unreleased]: https://github.com/samline/forms/compare/v2.8.0...HEAD
|
|
281
|
+
[2.8.0]: https://github.com/samline/forms/compare/v2.7.2...v2.8.0
|
|
282
|
+
[2.7.2]: https://github.com/samline/forms/compare/v2.7.1...v2.7.2
|
|
283
|
+
[2.7.1]: https://github.com/samline/forms/compare/v2.7.0...v2.7.1
|
|
284
|
+
[2.7.0]: https://github.com/samline/forms/compare/v2.6.0...v2.7.0
|
|
285
|
+
[2.6.0]: https://github.com/samline/forms/compare/v2.5.1...v2.6.0
|
|
286
|
+
[2.5.1]: https://github.com/samline/forms/compare/v2.5.0...v2.5.1
|
|
287
|
+
[2.5.0]: https://github.com/samline/forms/compare/v2.4.0...v2.5.0
|
|
288
|
+
[2.4.0]: https://github.com/samline/forms/compare/v2.3.4...v2.4.0
|
|
289
|
+
[2.3.4]: https://github.com/samline/forms/compare/v2.3.3...v2.3.4
|
|
290
|
+
[2.3.3]: https://github.com/samline/forms/compare/v2.3.2...v2.3.3
|
|
291
|
+
[2.3.2]: https://github.com/samline/forms/compare/v2.3.1...v2.3.2
|
|
292
|
+
[2.3.1]: https://github.com/samline/forms/compare/v2.3.0...v2.3.1
|
|
293
|
+
[2.3.0]: https://github.com/samline/forms/compare/v2.2.3...v2.3.0
|
|
294
|
+
[2.2.3]: https://github.com/samline/forms/compare/v2.2.2...v2.2.3
|
|
295
|
+
[2.2.2]: https://github.com/samline/forms/compare/v2.2.1...v2.2.2
|
|
296
|
+
[2.2.1]: https://github.com/samline/forms/compare/v2.2.0...v2.2.1
|
|
297
|
+
[2.2.0]: https://github.com/samline/forms/compare/v1.0.3...v2.2.0
|
|
298
|
+
[1.0.3]: https://github.com/samline/forms/compare/v1.0.2...v1.0.3
|
|
299
|
+
[1.0.2]: https://github.com/samline/forms/compare/v1.0.1...v1.0.2
|
|
300
|
+
[1.0.1]: https://github.com/samline/forms/compare/v1.0.0...v1.0.1
|
|
301
|
+
[1.0.0]: https://github.com/samline/forms/compare/v0.1.0...v1.0.0
|
|
302
|
+
[0.1.0]: https://github.com/samline/forms/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -1,183 +1,171 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @samline/forms
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Validation, reactive state, serialization and auto-submit for native HTML forms, with a typed, framework-free API for JavaScript and TypeScript.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[Demo](https://samline.github.io/forms/) · [Examples](https://samline.github.io/forms/examples/) · [Documentation](https://samline.github.io/forms/docs/) · [Changelog](CHANGELOG.md)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## Table of Contents
|
|
7
|
+
## Table of contents
|
|
10
8
|
|
|
11
9
|
- [Installation](#installation)
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [API at a Glance](#api-at-a-glance)
|
|
10
|
+
- [Quick start](#quick-start)
|
|
11
|
+
- [HTML / CDN](#html--cdn)
|
|
12
|
+
- [Capabilities](#capabilities)
|
|
13
|
+
- [API at a glance](#api-at-a-glance)
|
|
17
14
|
- [Documentation](#documentation)
|
|
15
|
+
- [Changelog](#changelog)
|
|
16
|
+
- [AI agent skill](#ai-agent-skill)
|
|
18
17
|
- [License](#license)
|
|
19
18
|
|
|
20
|
-
---
|
|
21
|
-
|
|
22
19
|
## Installation
|
|
23
20
|
|
|
24
|
-
```
|
|
21
|
+
```sh
|
|
25
22
|
npm install @samline/forms
|
|
26
23
|
```
|
|
27
24
|
|
|
28
|
-
```
|
|
25
|
+
```sh
|
|
29
26
|
pnpm add @samline/forms
|
|
30
27
|
```
|
|
31
28
|
|
|
32
|
-
```
|
|
29
|
+
```sh
|
|
33
30
|
bun add @samline/forms
|
|
34
31
|
```
|
|
35
32
|
|
|
36
|
-
Requires Node 20+ when bundling
|
|
37
|
-
|
|
38
|
-
---
|
|
33
|
+
Requires Node 20+ when bundling; the runtime targets ES2020 browsers. Formatting needs the optional peer `@samline/formatter` (`npm install @samline/formatter`); validation, state and serialization do not.
|
|
39
34
|
|
|
40
|
-
##
|
|
35
|
+
## Quick start
|
|
41
36
|
|
|
42
|
-
|
|
37
|
+
Keep a native form with named fields. `novalidate` lets the controller's rules replace the browser's bubbles.
|
|
43
38
|
|
|
44
39
|
```html
|
|
45
|
-
<
|
|
40
|
+
<form id="signup" novalidate>
|
|
41
|
+
<label for="email">Email</label>
|
|
42
|
+
<input id="email" name="email" type="email" autocomplete="email" aria-describedby="email-error" />
|
|
43
|
+
<p id="email-error" data-error-for="email" aria-live="polite"></p>
|
|
44
|
+
<button type="submit">Sign up</button>
|
|
45
|
+
</form>
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
The browser bundle exposes a single global: `window.Forms`.
|
|
48
|
+
```js
|
|
49
|
+
import { form } from '@samline/forms'
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
const signup = form('signup', {
|
|
52
|
+
autoValidate: false,
|
|
53
|
+
validators: {
|
|
54
|
+
email: {
|
|
55
|
+
required: { value: true, message: 'Enter your email.' },
|
|
56
|
+
pattern: { value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: 'Use a valid email.' },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
})
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
signup.subscribe(state => {
|
|
62
|
+
document.querySelector('#email-error').textContent = state.errors.email?.[0] ?? ''
|
|
63
|
+
})
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
signup.onSubmit(async (_element, _data, formData) => {
|
|
66
|
+
await fetch('/api/signup', { method: 'POST', body: formData })
|
|
67
|
+
signup.reset()
|
|
68
|
+
})
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
// When the form goes away (route change, component unmount):
|
|
71
|
+
// signup.destroy()
|
|
68
72
|
```
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
Invalid submits are always prevented and focus moves to the first invalid field. Valid submits reach every `onSubmit()` handler with a plain object, a fresh `FormData` and a state snapshot.
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
## HTML / CDN
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
The standalone build defines `window.Forms` and already includes `@samline/formatter`. Pin the version.
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
```html
|
|
81
|
+
<script src="https://unpkg.com/@samline/forms@2.8.0/dist/browser/global.global.js"></script>
|
|
82
|
+
<script>
|
|
83
|
+
const signup = window.Forms.form('signup', {
|
|
84
|
+
validators: { email: { required: true, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ } },
|
|
85
|
+
})
|
|
86
|
+
</script>
|
|
87
|
+
```
|
|
83
88
|
|
|
84
|
-
|
|
89
|
+
`window.Forms` has `form`, `newForm({ id, options })`, `destroyForm(id)` and the `available` registry. See [Browser global and CDN](https://samline.github.io/forms/docs/reference/browser/).
|
|
85
90
|
|
|
86
|
-
|
|
91
|
+
## Capabilities
|
|
87
92
|
|
|
88
|
-
|
|
93
|
+
- **Validation rules:** `required`, `minLength`, `maxLength`, `pattern`, `numeric`, `min`, `max`, `sameAs`, `dependsOn`, per-row `each` and custom validators that read every value.
|
|
94
|
+
- **Accessible state:** invalid controls get `aria-invalid` and `css-error`, filled ones `css-filled`; a failed submit focuses the first invalid control in document order.
|
|
95
|
+
- **Reactive state:** `subscribe()` for the whole form, `observe()`/`watch()` for one field.
|
|
96
|
+
- **Submission:** promise-aware `onSubmit()`, `autoSubmit()` with debounce, `setErrors()` for server responses, `prefill()` from the URL and `reset()`.
|
|
97
|
+
- **Native controls:** checkbox groups, radios, multiple selects, files, repeated `name[]` inputs and controls linked with `form="id"`, including fields added later.
|
|
98
|
+
- **Formatting:** `format()`, `formatAll()` and the `formats` option format phones, cards, dates, times and amounts while a hidden field submits the raw value.
|
|
99
|
+
- **DOM-free helpers:** `validateValues()` and `validateFieldValue()` run the same rules on the server; `parseFormData()` serializes any form.
|
|
89
100
|
|
|
90
|
-
|
|
91
|
-
import { form } from '@samline/forms'
|
|
101
|
+
### Lifecycle
|
|
92
102
|
|
|
93
|
-
|
|
94
|
-
validators: {
|
|
95
|
-
email: {
|
|
96
|
-
required: true,
|
|
97
|
-
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
})
|
|
103
|
+
One controller owns one form's listeners, `MutationObserver` and auto-submit timer. Create it once the form exists and call `destroy()` when it goes away. `addCleanup()` ties your own teardown to the same lifetime. After `destroy()`, writes and new registrations are no-ops.
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
console.log('email is now:', value)
|
|
104
|
-
})
|
|
105
|
+
## API at a glance
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
107
|
+
| Export | Purpose |
|
|
108
|
+
| ------------------------------------------ | ------------------------------------------------------------------- |
|
|
109
|
+
| `form(target, options?)` | Create a controller for an id, `HTMLFormElement` or `{ current }`. |
|
|
110
|
+
| `createFormController(target, options?)` | The same factory under its descriptive name. |
|
|
111
|
+
| `browser` | `{ form, newForm, destroyForm, available }` registry singleton. |
|
|
112
|
+
| `parseFormData(form, submitter?)` | Serialize a form into `{ data, formData }`. |
|
|
113
|
+
| `validateValues(values, schema)` | Validate a plain values object against a `ValidationSchema`. |
|
|
114
|
+
| `validateFieldValue(field, value, rules, values)` | Validate one value. |
|
|
115
|
+
| `@samline/forms/browser` | The registry as a module namespace; also sets `globalThis.Forms`. |
|
|
116
|
+
| `@samline/forms/browser/global` | The standalone IIFE that defines `window.Forms`. |
|
|
110
117
|
|
|
111
|
-
|
|
118
|
+
### Controller methods
|
|
112
119
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
| Group | Methods |
|
|
121
|
+
| ------------- | ---------------------------------------------------------------------------------- |
|
|
122
|
+
| Submission | `onSubmit`, `autoSubmit`, `disableAutoSubmit` |
|
|
123
|
+
| Validation | `validate`, `revalidate`, `setErrors`, `clearErrors` |
|
|
124
|
+
| State | `subscribe`, `observe`, `watch`, `unwatch`, `getState` |
|
|
125
|
+
| Values | `setValue`, `getValue`, `getField`, `getData`, `prefill`, `reset` |
|
|
126
|
+
| Formatting | `format`, `formatAll` |
|
|
127
|
+
| Lifecycle | `element`, `f`, `options`, `append`, `addCleanup`, `destroy` |
|
|
117
128
|
|
|
118
|
-
|
|
129
|
+
### Options
|
|
119
130
|
|
|
120
|
-
|
|
131
|
+
`validators`, `autoValidate` (default `true`), `autoSubmit`, `clearErrorsOnSubmit` (default `true`), `clearManualErrorsOnChange` (default `true`), `attributes` (default `{ filled: 'css-filled', error: 'css-error' }`) and `formats`. Every option is described in [Configuration options](https://samline.github.io/forms/docs/reference/configuration/); every type is exported, see the [TypeScript reference](https://samline.github.io/forms/docs/reference/typescript/).
|
|
121
132
|
|
|
122
|
-
|
|
123
|
-
- Forms that submit with `fetch` while keeping native `FormData` payloads.
|
|
124
|
-
- Autosave / autosubmit flows with optional debounce.
|
|
125
|
-
- Visual feedback driven by `css-filled` and `css-error` attributes.
|
|
126
|
-
- Progressive enhancement on top of any existing HTML form.
|
|
127
|
-
- Forms rendered server-side (Blade, Twig, ERB) that still want client-side validation.
|
|
133
|
+
## Documentation
|
|
128
134
|
|
|
129
|
-
|
|
135
|
+
| Guide | What it covers |
|
|
136
|
+
| ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
|
|
137
|
+
| [Get started](https://samline.github.io/forms/docs/getting-started/) | Installation, the first form, CDN use and cleanup. |
|
|
138
|
+
| [Examples](https://samline.github.io/forms/docs/guides/examples/) | Twelve live forms with their code. |
|
|
139
|
+
| [Validation and errors](https://samline.github.io/forms/docs/guides/validation/) | Every rule, cross-field checks and accessible messages. |
|
|
140
|
+
| [State and submission](https://samline.github.io/forms/docs/guides/state-and-submission/) | Subscribers, async submits, auto-submit, prefill and reset. |
|
|
141
|
+
| [Formatting fields](https://samline.github.io/forms/docs/guides/formatting/) | The optional formatter and the hidden raw mirror. |
|
|
142
|
+
| [Framework integrations](https://samline.github.io/forms/docs/guides/frameworks/) | React, Vue, Svelte, Astro, Shopify and WordPress. |
|
|
143
|
+
| [API reference](https://samline.github.io/forms/docs/reference/api/) | Every method, grouped by task, with one page per method. |
|
|
130
144
|
|
|
131
|
-
##
|
|
145
|
+
## Changelog
|
|
132
146
|
|
|
133
|
-
|
|
147
|
+
Read [CHANGELOG.md](CHANGELOG.md) or the [published changelog](https://samline.github.io/forms/docs/changelog/) for release history and explicitly marked behavior changes.
|
|
134
148
|
|
|
135
|
-
|
|
136
|
-
| --- | --- |
|
|
137
|
-
| Lifecycle | [`form`](docs/api/form.md) · [`addCleanup`](docs/api/add-cleanup.md) · [`destroy`](docs/api/destroy.md) · [`reset`](docs/api/reset.md) |
|
|
138
|
-
| Registry (vanilla) | [`browser`](docs/getting-started.md#browser-registry-helpers) — bundler-friendly `{ form, newForm, destroyForm, available }` singleton. |
|
|
139
|
-
| Properties | [`element`](docs/api/element.md) · [`options`](docs/options.md) |
|
|
140
|
-
| Submission | [`onSubmit`](docs/api/on-submit.md) · [`autoSubmit`](docs/api/auto-submit.md) · [`disableAutoSubmit`](docs/api/disable-auto-submit.md) |
|
|
141
|
-
| Field observation | [`watch`](docs/api/watch.md) · [`observe`](docs/api/observe.md) · [`unwatch`](docs/api/unwatch.md) · [`subscribe`](docs/api/subscribe.md) |
|
|
142
|
-
| Field values | [`setValue`](docs/api/set-value.md) · [`getValue`](docs/api/get-value.md) · [`getField`](docs/api/get-field.md) · [`prefill`](docs/api/prefill.md) · [`format`](docs/api/format.md) · [`formatAll`](docs/api/format.md) |
|
|
143
|
-
| Validation | [`validate`](docs/api/validate.md) · [`revalidate`](docs/api/revalidate.md) · [`setErrors`](docs/api/set-errors.md) · [`clearErrors`](docs/api/clear-errors.md) |
|
|
144
|
-
| State and data | [`getData`](docs/api/get-data.md) · [`getState`](docs/api/get-state.md) · [`append`](docs/api/append.md) |
|
|
145
|
-
| Pure helpers | [`parseFormData`](docs/api/parse-form-data.md) · [`validateValues`](docs/api/validate-values.md) · [`validateFieldValue`](docs/api/validate-field-value.md) |
|
|
149
|
+
### Upgrading to 2.8
|
|
146
150
|
|
|
147
|
-
|
|
151
|
+
2.8.0 removes no API. Review these behavior fixes before upgrading: `prefill()` writes repeated query keys as arrays and auto-submits once; native reset buttons now clear errors and attributes; `reset()` calls watchers; failed submits focus the first invalid control in document order and automatic submits never move focus; methods called after `destroy()` no longer change the form; rejected async submit handlers are logged. The Markdown `docs/` folder is no longer published to npm; the documentation lives on the website. The optional `@samline/formatter` peer now requires `^2.1.0`, which the standalone script bundles. Read the [2.8.0 notes](CHANGELOG.md).
|
|
148
152
|
|
|
149
|
-
|
|
153
|
+
## AI agent skill
|
|
150
154
|
|
|
151
|
-
|
|
155
|
+
<a id="agent-integration"></a>
|
|
152
156
|
|
|
153
|
-
|
|
157
|
+
The [Forms skill](https://samline.github.io/forms/skills/forms/SKILL.md) describes 2.8 integration: loading modes, validation rules and accessible messages, state and submission, formatting and host ownership. Pass it to an agent or install it using a skills-compatible tool. Verify the installed package version before applying its guidance.
|
|
154
158
|
|
|
155
|
-
[
|
|
159
|
+
Download [SKILL.md](https://samline.github.io/forms/skills/forms/SKILL.md) into a `forms/` folder in your agent's supported skill directory. For agents that discover project skills from `.agents/skills/`:
|
|
156
160
|
|
|
157
|
-
```
|
|
158
|
-
|
|
161
|
+
```sh
|
|
162
|
+
mkdir -p .agents/skills/forms
|
|
163
|
+
curl --fail --location https://samline.github.io/forms/skills/forms/SKILL.md \
|
|
164
|
+
--output .agents/skills/forms/SKILL.md
|
|
159
165
|
```
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Documentation
|
|
166
|
-
|
|
167
|
-
Full API reference, guides, and examples are available at **[samline.github.io/forms](https://samline.github.io/forms)**.
|
|
168
|
-
|
|
169
|
-
| Doc | Purpose |
|
|
170
|
-
| --- | --- |
|
|
171
|
-
| [docs/getting-started.md](docs/getting-started.md) | Concepts, observable contract, lifecycle, and side-effect overview. |
|
|
172
|
-
| [docs/options.md](docs/options.md) | Full `FormControllerOptions` reference. |
|
|
173
|
-
| [docs/css-styling.md](docs/css-styling.md) | `css-filled` and `css-error` styling recipes. |
|
|
174
|
-
| [docs/typescript.md](docs/typescript.md) | Every exported TypeScript type, with examples. |
|
|
175
|
-
| [docs/api/index.md](docs/api/index.md) | One page per public method. |
|
|
176
|
-
| [docs/recipes.md](docs/recipes.md) | End-to-end patterns: fetch submit, server errors, autosave, multi-step, etc. |
|
|
177
|
-
| [docs/browser.md](docs/browser.md) | Browser global (`window.Forms`) usage. |
|
|
178
|
-
|
|
179
|
-
---
|
|
167
|
+
When working from this repository, copy `skills/forms/SKILL.md` instead. Keep the filename `SKILL.md`; discovery paths and invocation syntax depend on the agent.
|
|
180
168
|
|
|
181
169
|
## License
|
|
182
170
|
|
|
183
|
-
MIT
|
|
171
|
+
MIT — [LICENSE.md](LICENSE.md)
|
package/dist/browser/global.d.ts
CHANGED
|
@@ -153,22 +153,10 @@ interface NewFormInput {
|
|
|
153
153
|
interface FormsAvailable {
|
|
154
154
|
[id: string]: FormController;
|
|
155
155
|
}
|
|
156
|
-
interface FormsApi {
|
|
157
|
-
form: (target: FormTarget, options?: FormControllerOptions) => FormController;
|
|
158
|
-
newForm: (input: NewFormInput) => FormController | undefined;
|
|
159
|
-
destroyForm: (id: string) => void;
|
|
160
|
-
available: FormsAvailable;
|
|
161
|
-
}
|
|
162
156
|
|
|
163
|
-
declare const Forms: FormsApi;
|
|
164
157
|
declare const form: (target: FormTarget, options?: FormControllerOptions) => FormController;
|
|
165
158
|
declare const newForm: (input: NewFormInput) => FormController | undefined;
|
|
166
159
|
declare const destroyForm: (id: string) => void;
|
|
167
160
|
declare const available: FormsAvailable;
|
|
168
|
-
declare global {
|
|
169
|
-
interface Window {
|
|
170
|
-
Forms: FormsApi;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
161
|
|
|
174
|
-
export { available,
|
|
162
|
+
export { available, destroyForm, form, newForm };
|