-
-
Notifications
You must be signed in to change notification settings - Fork 390
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add additional docs for Lit (#878)
* chore: pulling * feat: add quickstart and guide for lit docs * feat: add lit arrays docs * feat: add lit arrays docs * feat: add basic concepts docs * chore: pulling * feat: add lit docs * docs: get PR to stable place --------- Co-authored-by: Corbin Crutchley <[email protected]>
- Loading branch information
1 parent
d5e06c7
commit 78be5bd
Showing
9 changed files
with
346 additions
and
35 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
--- | ||
id: arrays | ||
title: Arrays | ||
--- | ||
|
||
TanStack Form supports arrays as values in a form, including sub-object values inside of an array. | ||
|
||
# Basic Usage | ||
|
||
To use an array, you can use `field.state.value` on an array value, as in: | ||
|
||
```ts | ||
export class TestForm extends LitElement { | ||
#form = new TanStackFormController(this, { | ||
defaultValues: { | ||
people: [] as Array<{ name: string; age: string }>, | ||
}, | ||
}) | ||
render() { | ||
return html` | ||
<form | ||
id="form" | ||
@submit=${(e: Event) => { | ||
e.preventDefault() | ||
}} | ||
> | ||
<h1>Please enter your details</h1> | ||
${this.#form.field( | ||
{ | ||
name: `people`, | ||
}, | ||
(peopleField) => { | ||
return html`${repeat( | ||
peopleField.state.value, | ||
(_, index) => index, | ||
(_, index) => { | ||
return html` // ... ` | ||
}, | ||
)} ` | ||
}, | ||
)} | ||
</form> | ||
` | ||
} | ||
} | ||
``` | ||
|
||
This will generate the mapped HTML every time you run pushValue on the field: | ||
|
||
|
||
```html | ||
<div class="container"> | ||
<button | ||
type="button" | ||
@click=${() => { | ||
peopleField.pushValue({name: "",age: ""}) | ||
}}> | ||
Add Person | ||
</button> | ||
</div> | ||
``` | ||
|
||
Finally, you can use a subfield like so: | ||
|
||
```ts | ||
return html` | ||
${this.#form.field( | ||
{ | ||
name: `people[${index}].name`, | ||
}, | ||
(field) => { | ||
return html` | ||
<input | ||
type="text" | ||
placeholder="Name" | ||
.value="${field.state.value}" | ||
@input="${(e: Event) => { | ||
const target = e.target as HTMLInputElement; | ||
field.handleChange(target.value); | ||
}}" | ||
/> | ||
`; | ||
}, | ||
)} | ||
` | ||
``` | ||
|
||
|
||
## Full Example | ||
|
||
|
||
```typescript | ||
export class TestForm extends LitElement { | ||
#form = new TanStackFormController(this, { | ||
defaultValues: { | ||
people: [] as Array<{ name: string}>, | ||
}, | ||
}); | ||
render() { | ||
return html` | ||
<form | ||
id="form" | ||
@submit=${(e: Event) => { | ||
e.preventDefault(); | ||
}} | ||
> | ||
<h1>Please enter your details</h1> | ||
${this.#form.field( | ||
{ | ||
name: `people`, | ||
}, | ||
(peopleField) => { | ||
return html`${repeat( | ||
peopleField.state.value, | ||
(_, index) => index, | ||
(_, index) => { | ||
return html` | ||
${this.#form.field( | ||
{ | ||
name: `people[${index}].name`, | ||
}, | ||
(field) => { | ||
return html` <div> | ||
<div class="container"> | ||
<label>Name</label> | ||
<input | ||
type="text" | ||
placeholder="Name" | ||
.value="${field.state.value}" | ||
@input="${(e: Event) => { | ||
const target = e.target as HTMLInputElement; | ||
field.handleChange(target.value); | ||
}}" | ||
/> | ||
</div> | ||
</div>`; | ||
} | ||
)} | ||
`; | ||
} | ||
)} | ||
<div class="container"> | ||
<button | ||
type="button" | ||
@click=${() => { | ||
peopleField.pushValue({ | ||
name: "", | ||
}); | ||
}} | ||
> | ||
Add Person | ||
</button> | ||
</div> `; | ||
} | ||
)} | ||
<div class="container"> | ||
<button type="submit" ?disabled=${this.#form.api.state.isSubmitting}> | ||
${this.#form.api.state.isSubmitting ? html` Submitting` : "Submit"} | ||
</button> | ||
<button | ||
type="button" | ||
id="reset" | ||
@click=${() => { | ||
this.#form.api.reset(); | ||
}} | ||
> | ||
Reset | ||
</button> | ||
</div> | ||
</form> | ||
`; | ||
} | ||
|
||
declare global { | ||
interface HTMLElementTagNameMap { | ||
"test-form": TestForm; | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
--- | ||
id: basic-concepts | ||
title: Basic Concepts and Terminology | ||
--- | ||
|
||
This page introduces the basic concepts and terminology used in the `@tanstack/lit-form` library. Familiarizing yourself with these concepts will help you better understand and work with the library and its usage with Lit. | ||
|
||
## Form Options | ||
|
||
You can create options for your form so that it can be shared between multiple forms by using the `formOptions` function. | ||
|
||
For Example: | ||
|
||
```tsx | ||
const formOpts = formOptions({ | ||
defaultValues: { | ||
firstName: '', | ||
lastName: '', | ||
employed: false, | ||
jobTitle: '', | ||
} as Employee, | ||
}) | ||
``` | ||
|
||
## Form Instance | ||
|
||
A Form Instance is an object that represents an individual form and provides methods and properties for working with the form. You create a form instance using the `TanStackFormController` interface provided by `@tanstack/lit-form`. The `TanStackFormController` is instantiated with the current form's (`this`) class and some default form options. It initializes the form state, handles form submission, and provides methods to manage form fields and their validation. | ||
|
||
```tsx | ||
#form = new TanStackFormController(this, { | ||
defaultValues: { | ||
firstName: '', | ||
lastName: '', | ||
employed: false, | ||
jobTitle: '', | ||
} as Employee, | ||
}) | ||
``` | ||
|
||
You may also create a form instance without using `formOptions` by using the standalone `TanStackFormController` API: | ||
|
||
```tsx | ||
#form = new TanStackFormController(this, { | ||
...formOpts, | ||
}) | ||
``` | ||
|
||
## Field | ||
|
||
A Field represents a single form input element, such as a text input or a checkbox. Fields are created using the `field(FieldOptions, callback)` provided by the form instance. The component accepts a `FieldOptions` object and a callback function that receives a `FieldApi` object. This object provides methods to get the current value of the field, handle input changes, and handle blur events. | ||
|
||
For Example: | ||
|
||
```ts | ||
${this.#form.field( | ||
{ | ||
name: `firstName`, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.length < 3 ? "Not long enough" : undefined, | ||
}, | ||
}, | ||
(field: FieldApi<Employee, "firstName">) => { | ||
return html` <div> | ||
<label class="first-name-label">First Name</label> | ||
<input | ||
id="firstName" | ||
type="text" | ||
class="first-name-input" | ||
placeholder="First Name" | ||
@blur="${() => field.handleBlur()}" | ||
.value="${field.state.value}" | ||
@input="${(event: InputEvent) => { | ||
if (event.currentTarget) { | ||
const newValue = (event.currentTarget as HTMLInputElement).value; | ||
field.handleChange(newValue); | ||
} | ||
}}" | ||
/> | ||
</div>`; | ||
}, | ||
)} | ||
``` | ||
|
||
## Field State | ||
|
||
Each field has its own state, which includes its current value, validation status, error messages, and other metadata. You can access a field's state using its `field.state` property. | ||
|
||
```tsx | ||
const { value, meta: { errors, isValidating } } = field.state | ||
``` | ||
|
||
There are three field states can be very useful to see how the user interacts with a field. A field is _"touched"_ when the user clicks/tabs into it, _"pristine"_ until the user changes value in it, and _"dirty"_ after the value has been changed. You can check these states via the `isTouched`, `isPristine` and `isDirty` flags, as seen below. | ||
|
||
```tsx | ||
const { isTouched, isPristine, isDirty } = field.state.meta | ||
``` | ||
|
||
 |
Oops, something went wrong.