Skip to content

Commit 90a0835

Browse files
committed
chore: Update Documentation for the FormValidityObserver
Note: We technically have not yet updated the types for the JS framework integrations, so we aren't 100% sure that our docs in that area are correct yet. But we're pretty confident that the documentation should be correct. After reviewing these docs on GitHub and verifying that we didn't break any links, we'll follow up with the integration TypeScript changes (and any docs updates that should be done as a result).
1 parent 823a231 commit 90a0835

File tree

12 files changed

+156
-119
lines changed

12 files changed

+156
-119
lines changed

docs/extras/philosophy.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ The next natural step is to provide a way to validate an _entire form_. For that
318318

319319
If the developer opts out of accessible error messaging, the `setFieldError` and `clearFieldError` methods will fallback to `field.setCustomValidity()`, and `validateField({ focus: true })`/`validateFields({ focus: true })` will fallback to `field.reportValidity()`/`form.reportValidity()`.
320320

321-
As an added bonus, the `FormValidityObserver` exposes a [`configure`](../form-validity-observer/README.md#method-formvalidityobserverconfigureename-string-errormessages-validationerrorsm-e-void) method that enables developers to configure the error messages that should be displayed when a field fails validation. (Any unconfigured error messages will fallback to the `validationMessage` that the browser provides.) It also allows a custom validation function to be configured for the field.
321+
As an added bonus, the `FormValidityObserver` exposes a [`configure`](../form-validity-observer/README.md#method-formvalidityobserverconfigureename-string-errormessages-validationerrorsm-e-r-void) method that enables developers to configure the error messages that should be displayed when a field fails validation. (Any unconfigured error messages will fallback to the `validationMessage` that the browser provides.) It also allows a custom validation function to be configured for the field.
322322

323323
Seeing the big picture here? The `FormValidityObserver` is basically a wrapper for the browser's native features when accessible error messages aren't being used. When accessible error messages are needed, it functions as an _enhancement_ (not a replacement) of the browser's features to satisfy that need. As a bonus, it includes configurable scrolling/rendering functionality as well.
324324

docs/form-validity-observer/README.md

+25-13
Large diffs are not rendered by default.

docs/form-validity-observer/integrations/README.md

+51-35
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,14 @@ function createFormValidityObserver<
135135
T extends OneOrMany<EventType>,
136136
M = string,
137137
E extends ValidatableField = ValidatableField,
138-
>(types: T, options?: FormValidityObserverOptions<M, E>): SvelteFormValidityObserver<M> {
139-
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M>;
138+
R extends boolean = false,
139+
>(types: T, options?: FormValidityObserverOptions<M, E, R>): SvelteFormValidityObserver<M, R> {
140+
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M, R>;
140141
return observer;
141142
}
142143
143-
interface SvelteFormValidityObserver<M = string> extends Omit<FormValidityObserver<M>, "configure"> {}
144+
interface SvelteFormValidityObserver<M = string, R extends boolean = false>
145+
extends Omit<FormValidityObserver<M, R>, "configure"> {}
144146
```
145147
146148
Note: Since we will be augmenting the `FormValidityObserver.configure()` method, we are _not_ copying its type definition to the `SvelteFormValidityObserver` interface.
@@ -162,8 +164,9 @@ function createFormValidityObserver<
162164
T extends OneOrMany<EventType>,
163165
M = string,
164166
E extends ValidatableField = ValidatableField,
165-
>(types: T, options?: FormValidityObserverOptions<M, E>): SvelteFormValidityObserver<M> {
166-
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M>;
167+
R extends boolean = false,
168+
>(types: T, options?: FormValidityObserverOptions<M, E, R>): SvelteFormValidityObserver<M, R> {
169+
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M, R>;
167170
168171
/* ---------- Bindings ---------- */
169172
// Form Observer Methods
@@ -180,7 +183,8 @@ function createFormValidityObserver<
180183
return observer;
181184
}
182185
183-
interface SvelteFormValidityObserver<M = string> extends Omit<FormValidityObserver<M>, "configure"> {}
186+
interface SvelteFormValidityObserver<M = string, R extends boolean = false>
187+
extends Omit<FormValidityObserver<M, R>, "configure"> {}
184188
```
185189
186190
Note: Because we will be enhancing the `configure` method, we _have not_ attached it to the `observer` object that we return.
@@ -203,8 +207,9 @@ function createFormValidityObserver<
203207
T extends OneOrMany<EventType>,
204208
M = string,
205209
E extends ValidatableField = ValidatableField,
206-
>(types: T, options?: FormValidityObserverOptions<M, E>): SvelteFormValidityObserver<M> {
207-
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M>;
210+
R extends boolean = false,
211+
>(types: T, options?: FormValidityObserverOptions<M, E, R>): SvelteFormValidityObserver<M, R> {
212+
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M, R>;
208213
209214
/* ---------- Bindings ---------- */
210215
// Apply all bindings...
@@ -224,7 +229,8 @@ function createFormValidityObserver<
224229
return observer;
225230
}
226231
227-
interface SvelteFormValidityObserver<M = string> extends Omit<FormValidityObserver<M>, "configure"> {
232+
interface SvelteFormValidityObserver<M = string, R extends boolean = false>
233+
extends Omit<FormValidityObserver<M, R>, "configure"> {
228234
autoObserve(form: HTMLFormElement, novalidate?: boolean): ActionReturn;
229235
}
230236
```
@@ -311,9 +317,10 @@ import type { HTMLInputAttributes } from "svelte/elements";
311317
312318
// Definition of `createFormValidityObserver` ...
313319
314-
interface SvelteFormValidityObserver<M = string> extends Omit<FormValidityObserver<M>, "configure"> {
320+
interface SvelteFormValidityObserver<M = string, R extends boolean = false>
321+
extends Omit<FormValidityObserver<M, R>, "configure"> {
315322
// Augments `FormValidityObserver.configure()`
316-
configure<E extends ValidatableField>(name: string, errorMessages: SvelteValidationErrors<M, E>): SvelteFieldProps;
323+
configure<E extends ValidatableField>(name: string, errorMessages: SvelteValidationErrors<M, E, R>): SvelteFieldProps;
317324
autoObserve(form: HTMLFormElement, novalidate?: boolean): ActionReturn;
318325
}
319326
@@ -324,23 +331,30 @@ type SvelteFieldProps = Pick<
324331
>;
325332
326333
// Augments `ValidationErrors` type
327-
export interface SvelteValidationErrors<M, E extends ValidatableField = ValidatableField>
328-
extends Pick<ValidationErrors<M, E>, "badinput" | "validate"> {
329-
required?: SvelteErrorDetails<M, HTMLInputAttributes["required"], E> | ErrorMessage<string, E>;
330-
minlength?: SvelteErrorDetails<M, HTMLInputAttributes["minlength"], E>;
331-
min?: SvelteErrorDetails<M, HTMLInputAttributes["min"], E>;
332-
maxlength?: SvelteErrorDetails<M, HTMLInputAttributes["maxlength"], E>;
333-
max?: SvelteErrorDetails<M, HTMLInputAttributes["max"], E>;
334-
step?: SvelteErrorDetails<M, HTMLInputAttributes["step"], E>;
335-
type?: SvelteErrorDetails<M, HTMLInputAttributes["type"], E>;
336-
pattern?: SvelteErrorDetails<M, HTMLInputAttributes["pattern"], E>;
334+
export interface SvelteValidationErrors<M, E extends ValidatableField = ValidatableField, R extends boolean = false>
335+
extends Pick<ValidationErrors<M, E, R>, "badinput" | "validate"> {
336+
required?:
337+
| SvelteErrorDetails<M, HTMLInputAttributes["required"], E, R>
338+
| ErrorMessage<R extends true ? M : string, E>;
339+
minlength?: SvelteErrorDetails<M, HTMLInputAttributes["minlength"], E, R>;
340+
min?: SvelteErrorDetails<M, HTMLInputAttributes["min"], E, R>;
341+
maxlength?: SvelteErrorDetails<M, HTMLInputAttributes["maxlength"], E, R>;
342+
max?: SvelteErrorDetails<M, HTMLInputAttributes["max"], E, R>;
343+
step?: SvelteErrorDetails<M, HTMLInputAttributes["step"], E, R>;
344+
type?: SvelteErrorDetails<M, HTMLInputAttributes["type"], E, R>;
345+
pattern?: SvelteErrorDetails<M, HTMLInputAttributes["pattern"], E, R>;
337346
}
338347
339348
// Augments `ErrorDetails` type
340-
type SvelteErrorDetails<M, V, E extends ValidatableField = ValidatableField> =
349+
type SvelteErrorDetails<M, V, E extends ValidatableField = ValidatableField, R extends boolean = false> =
341350
| V
342-
| { render: true; message: ErrorMessage<M, E>; value: V }
343-
| { render?: false; message: ErrorMessage<string, E>; value: V };
351+
| R extends true
352+
?
353+
| { render?: true; message: ErrorMessage<M, E>; value: V }
354+
| { render: false; message: ErrorMessage<string, E>; value: V }
355+
:
356+
| { render: true; message: ErrorMessage<M, E>; value: V }
357+
| { render?: false; message: ErrorMessage<string, E>; value: V };
344358
```
345359
346360
You don't have to understand what these types do to use them. But if you're interested in understanding what's happening here, let's walk you through what we did.
@@ -349,7 +363,7 @@ You don't have to understand what these types do to use them. But if you're inte
349363
350364
Our `configure` method has changed the type of the `errorMessages` argument from `ValidationErrors` to `SvelteValidationErrors` so that we can configure a field's constraints and error messages simultaneously. The type that enables us to support this feature is `SvelteErrorDetails`.
351365
352-
`SvelteErrorDetails` is _almost_ the exact same type as [`ErrorDetails`](../types.md#errordetailsm-e). There are only two differences between `SvelteErrorDetail` and `ErrorDetails`:
366+
`SvelteErrorDetails` is _almost_ the exact same type as [`ErrorDetails`](../types.md#errordetailsm-e-r). There are only two differences between `SvelteErrorDetail` and `ErrorDetails`:
353367
354368
<ol>
355369
<li>
@@ -370,7 +384,7 @@ Our `configure` method has changed the type of the `errorMessages` argument from
370384
</li>
371385
</ol>
372386
373-
Just as the `ErrorDetails` type forms the foundation of the [`ValidationErrors`](../types.md#validationerrorsm-e) type, so the `SvelteErrorDetails` type forms the foundation of the `SvelteValidationErrors` type. The type definition for `SvelteValidationErrors` is _almost_ the exact same as the type definition for `ValidationErrors`. In fact, the `badinput` and `validate` properties are exactly the same between the 2.
387+
Just as the `ErrorDetails` type forms the foundation of the [`ValidationErrors`](../types.md#validationerrorsm-e-r) type, so the `SvelteErrorDetails` type forms the foundation of the `SvelteValidationErrors` type. The type definition for `SvelteValidationErrors` is _almost_ the exact same as the type definition for `ValidationErrors`. In fact, the `badinput` and `validate` properties are exactly the same between the 2.
374388
375389
The primary way in which the `SvelteValidationErrors` type differs from the `ValidationErrors` type is that it takes constraint values into account (with the help of `SvelteErrorDetails`). It determines the value types that each constraint supports by looking at `Svelte`'s type definition for the `input` field's props (i.e., `HTMLInputAttributes`). (**Note: If you're using a different JS framework, you should use _that_ framework's type definitions for the `input` field's props instead.**)
376390
@@ -390,8 +404,9 @@ type SvelteFieldProps = Pick<
390404
And we make _this_ the return type of `configure`:
391405
392406
```ts
393-
interface SvelteFormValidityObserver<M = string> extends Omit<FormValidityObserver<M>, "configure"> {
394-
configure<E extends ValidatableField>(name: string, errorMessages: SvelteValidationErrors<M, E>): SvelteFieldProps;
407+
interface SvelteFormValidityObserver<M = string, R extends boolean = false>
408+
extends Omit<FormValidityObserver<M, R>, "configure"> {
409+
configure<E extends ValidatableField>(name: string, errorMessages: SvelteValidationErrors<M, E, R>): SvelteFieldProps;
395410
autoObserve(form: HTMLFormElement, novalidate?: boolean): ActionReturn;
396411
}
397412
```
@@ -409,23 +424,24 @@ export default function createFormValidityObserver<
409424
T extends OneOrMany<EventType>,
410425
M = string,
411426
E extends ValidatableField = ValidatableField,
412-
>(types: T, options?: FormValidityObserverOptions<M, E>): SvelteFormValidityObserver<M> {
413-
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M>;
427+
R extends boolean = false,
428+
>(types: T, options?: FormValidityObserverOptions<M, E, R>): SvelteFormValidityObserver<M, R> {
429+
const observer = new FormValidityObserver(types, options) as unknown as SvelteFormValidityObserver<M, R>;
414430
415431
/* ---------- Bindings ---------- */
416432
// Apply bindings for exposed methods ...
417433
418434
/** **Private** reference to the original {@link FormValidityObserver.configure} method */
419-
const originalConfigure = observer.configure.bind(observer) as FormValidityObserver<M>["configure"];
435+
const originalConfigure = observer.configure.bind(observer) as FormValidityObserver<M, R>["configure"];
420436
421437
/* ---------- Enhancements ---------- */
422438
// Definition for `autoObserver` ...
423439
424440
// Enhanced `configure` method
425441
observer.configure = (name, errorMessages) => {
426-
const keys = Object.keys(errorMessages) as Array<keyof SvelteValidationErrors<M>>;
442+
const keys = Object.keys(errorMessages) as Array<keyof SvelteValidationErrors<M, R>>;
427443
const props = { name } as SvelteFieldProps;
428-
const config = {} as ValidationErrors<M>;
444+
const config = {} as ValidationErrors<M, ValidatableField, R>;
429445
430446
// Build `props` object and error `config` object from `errorMessages`
431447
for (let i = 0; i < keys.length; i++) {
@@ -516,9 +532,9 @@ If we want to keep our code readable, then the next best solution is to use `any
516532
517533
```ts
518534
observer.configure = (name, errorMessages) => {
519-
const keys = Object.keys(errorMessages) as Array<keyof SvelteValidationErrors<M>>;
535+
const keys = Object.keys(errorMessages) as Array<keyof SvelteValidationErrors<M, ValidatableField, R>>;
520536
const props = { name } as SvelteFieldProps;
521-
const config = {} as ValidationErrors<M>;
537+
const config = {} as ValidationErrors<M, ValidatableField, R>;
522538
523539
// Build `props` object and error `config` object from `errorMessages`
524540
for (let i = 0; i < keys.length; i++) {

docs/form-validity-observer/integrations/preact.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ A _convenience_ API for reducing code repetition in a [Preact](https://preactjs.
66

77
Creates an enhanced version of the `FormValidityObserver`, known as the `PreactFormValidityObserver`. It accepts the exact same arguments as the [`FormValidityObserver`'s constructor](../README.md#constructor-formvalidityobservertypes-options).
88

9-
### Return Type: `PreactFormValidityObserver<M>`
9+
### Return Type: `PreactFormValidityObserver<M, R>`
1010

11-
An enhanced version of the `FormValidityObserver`, designed specifically for Preact applications. It has the same Type Parameters as the `FormValidityObserver`. As with the `FormValidityObserver`, the type of `M` is derived from the [`renderer`](../README.md#form-validity-observer-options-renderer) option.
11+
An enhanced version of the `FormValidityObserver`, designed specifically for Preact applications. It has the same Type Parameters as the `FormValidityObserver`. As with the `FormValidityObserver`, the type of `M` is derived from the [`renderer`](../README.md#form-validity-observer-options-renderer) option, and the type of `R` is derived from the [`renderByDefault`](../README.md#form-validity-observer-options-render-by-default) option.
1212

1313
#### Copied Methods
1414

@@ -77,13 +77,13 @@ class MyFormClass extends Component {
7777

7878
Remember that `autoObserve` is simply a convenience utility for calling `observe` and `unobserve` automatically. You're free to setup and teardown the `FormValidityObserver` manually if you prefer.
7979

80-
#### Function: `configure<E>(name: string, errorMessages: PreactValidationErrors<M, E>): PreactFieldProps`
80+
#### Function: `configure<E>(name: string, errorMessages: PreactValidationErrors<M, E, R>): PreactFieldProps`
8181

82-
An enhanced version of [`FormValidityObserver.configure`](../README.md#method-formvalidityobserverconfigureename-string-errormessages-validationerrorsm-e-void) for `Preact`. In addition to configuring a field's error messages, it generates the props that should be applied to the field based on the provided arguments.
82+
An enhanced version of [`FormValidityObserver.configure`](../README.md#method-formvalidityobserverconfigureename-string-errormessages-validationerrorsm-e-r-void) for `Preact`. In addition to configuring a field's error messages, it generates the props that should be applied to the field based on the provided arguments.
8383

8484
> Note: If the field is _only_ using the configured [`defaultErrors`](../README.md#form-validity-observer-options-default-errors) and/or the browser's default error messages, it _does not_ need to be `configure`d.
8585
86-
The `PreactValidationErrors<M, E>` type is an enhanced version of the core [`ValidationErrors<M, E>`](../types.md#validationerrorsm-e) type. Here is how `PreactValidationErrors` compares to `ValidationErrors`.
86+
The `PreactValidationErrors<M, E, R>` type is an enhanced version of the core [`ValidationErrors<M, E, R>`](../types.md#validationerrorsm-e-r) type. Here is how `PreactValidationErrors` compares to `ValidationErrors`.
8787

8888
##### Properties That Mimic the `ValidationErrors` Properties
8989

@@ -139,7 +139,7 @@ All the other properties on the `PreactValidationErrors` type are enhancements o
139139

140140
The rules are as follows:
141141

142-
1&rpar; When a constraint is configured with an [`ErrorDetails`](../types.md#errordetailsm-e) object, the object must include a `value` property specifying the value of the constraint. In this scenario, both the field's constraint value _and_ its error message are configured.
142+
1&rpar; When a constraint is configured with an [`ErrorDetails`](../types.md#errordetailsm-e-r) object, the object must include a `value` property specifying the value of the constraint. In this scenario, both the field's constraint value _and_ its error message are configured.
143143

144144
```tsx
145145
import { createFormValidityObserver } from "@form-observer/preact";

0 commit comments

Comments
 (0)