Skip to content

Commit

Permalink
feat(components): pass attributes to HTML elements
Browse files Browse the repository at this point in the history
BREAKING CHANGE: requires svelte >= 3.20.0
Closes #164
  • Loading branch information
mdauner committed Apr 4, 2020
1 parent 8bcc410 commit 3f71240
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 110 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,18 @@ $ yarn add sveltejs-forms
let:isSubmitting
let:isValid
>
<Input name="user.email" label="Email" placeholder="e.g. user@example.com" /> <!-- nested field -->
<Input
name="user.email" <!-- nested field -->
label="Email Address"
value="test@user.com" <!-- initial value -->
placeholder="e.g. user@example.com" />
<Input name="password" type="password" placeholder="Password" />
<Select name="language" options={langOptions} />
<Choice name="os" options={osOptions} multiple />

<Choice
name="os"
options={osOptions}
disabled
multiple />
<button type="reset">Reset</button>
<button type="submit" disabled={isSubmitting}>Sign in</button>
The form is valid: {isValid}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@
"rollup-plugin-terser": "~5.2.0",
"semantic-release": "~17.0.4",
"sirv-cli": "~0.4.5",
"svelte": "~3.19.2",
"svelte": "~3.20.0",
"svelte-preprocess": "~3.4.0",
"yup": "~0.28.2"
},
"peerDependencies": {
"svelte": "~3.20.0",
"yup": "~0.28.2"
},
"dependencies": {
Expand Down
20 changes: 13 additions & 7 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,20 @@
<Input
name="user.email"
label="Email Address"
value="test@user.com"
placeholder="e.g. user@example.com" />
<Input
name="user.password"
type="password"
placeholder="Password"
multiline />
<Select name="user.language" label="Language" options={langOptions} />
<Choice name="user.os" options={osOptions} multiple />
<Input name="user.password" type="password" placeholder="Password" />
<Select
name="user.language"
label="Language"
options={langOptions}
value={langOptions[2].id} />
<Choice
name="user.os"
options={osOptions}
value={['linux', 'windows']}
disabled
multiple />

<button type="reset">Reset</button>
<button type="submit" disabled={isSubmitting}>Sign in</button>
Expand Down
13 changes: 11 additions & 2 deletions src/components/Choice.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
export let name;
export let options;
export let multiple = false;
export let value;
const { touchField, values, errors, touched, validateOnChange } = getContext(
FORM
Expand All @@ -26,6 +27,12 @@
function onBlur() {
touchField(name);
}
if (value) {
setTimeout(() => {
choice.set(value);
}, 0);
}
</script>

<div class="field" class:error={get($touched, name) && get($errors, name)}>
Expand All @@ -38,7 +45,8 @@
on:change={onChange}
on:blur={onBlur}
bind:group={$choice}
value={option.id} />
value={option.id}
{...$$restProps} />
{:else}
<input
id={option.id}
Expand All @@ -47,7 +55,8 @@
on:change={onChange}
on:blur={onBlur}
bind:group={$choice}
value={option.id} />
value={option.id}
{...$$restProps} />
{/if}
{#if option.title}
<label for={option.id}>{option.title}</label>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@
}
}
function setValue(path, value) {
function setValue(path, value, validateForm = true) {
$values = set($values, path, value);
$touched = set($touched, path, true);
if (validateOnChange) {
if (validateForm && validateOnChange) {
validate();
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/components/Input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
export let name;
export let label = '';
export let type = 'text';
export let placeholder = '';
export let multiline = false;
const { touchField, setValue, values, errors, touched } = getContext(FORM);
Expand All @@ -18,6 +17,10 @@
function onBlur() {
touchField(name);
}
if (Object.keys($$restProps).includes('value')) {
setTimeout(() => setValue(name, $$restProps.value, false), 0);
}
</script>

<div class="field" class:error={get($touched, name) && get($errors, name)}>
Expand All @@ -27,20 +30,20 @@
{#if multiline}
<textarea
{name}
{placeholder}
id={name}
value={get($values, name)}
on:blur={onBlur}
on:change={onChange} />
on:change={onChange}
{...$$restProps} />
{:else}
<input
{name}
{type}
{placeholder}
id={name}
value={get($values, name)}
on:blur={onBlur}
on:change={onChange} />
on:change={onChange}
{...$$restProps} />
{/if}
{#if get($touched, name) && get($errors, name)}
<div class="message">{get($errors, name)}</div>
Expand Down
11 changes: 9 additions & 2 deletions src/components/Select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
function onBlur() {
touchField(name);
}
if (Object.keys($$restProps).includes('value')) {
setTimeout(() => setValue(name, $$restProps.value, false), 0);
}
</script>

<div class="field" class:error={get($touched, name) && get($errors, name)}>
Expand All @@ -27,10 +31,13 @@
id={name}
value={get($values, name)}
on:change={onChange}
on:blur={onBlur}>
on:blur={onBlur}
{...$$restProps}>
<option value="" />
{#each options as option}
<option value={option.id}>{option.title}</option>
<option value={option.id} selected={get($values, name) === option.id}>
{option.title}
</option>
{/each}
</select>
{#if get($touched, name) && get($errors, name)}
Expand Down
12 changes: 6 additions & 6 deletions tests/Form/__snapshots__/Form.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@ exports[`Form matches snapshot 1`] = `
value="svelte"
>
Svelte
</option>
<option
value="react"
>
React
</option>
<option
value="angular"
>
Angular
</option>
</select>
Expand All @@ -55,7 +58,6 @@ exports[`Form matches snapshot 1`] = `
id="macos"
name="os"
type="checkbox"
value="macos"
/>
<label
Expand All @@ -68,7 +70,6 @@ exports[`Form matches snapshot 1`] = `
id="linux"
name="os"
type="checkbox"
value="linux"
/>
<label
Expand All @@ -81,7 +82,6 @@ exports[`Form matches snapshot 1`] = `
id="windows"
name="os"
type="checkbox"
value="windows"
/>
<label
Expand Down Expand Up @@ -200,16 +200,19 @@ exports[`Form shows error message when schema is defined 1`] = `
value="svelte"
>
Svelte
</option>
<option
value="react"
>
React
</option>
<option
value="angular"
>
Angular
</option>
</select>
Expand All @@ -222,7 +225,6 @@ exports[`Form shows error message when schema is defined 1`] = `
id="macos"
name="os"
type="checkbox"
value="macos"
/>
<label
Expand All @@ -235,7 +237,6 @@ exports[`Form shows error message when schema is defined 1`] = `
id="linux"
name="os"
type="checkbox"
value="linux"
/>
<label
Expand All @@ -248,7 +249,6 @@ exports[`Form shows error message when schema is defined 1`] = `
id="windows"
name="os"
type="checkbox"
value="windows"
/>
<label
Expand Down
5 changes: 5 additions & 0 deletions tests/Input/Input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ describe('Input', () => {
expect(container.firstChild).toMatchSnapshot();
});

it('passes props to input', async () => {
const { container } = await render(App, { props: { disabled: true } });
expect(container.firstChild).toMatchSnapshot();
});

it('updates form value on change', async () => {
const { component, getByPlaceholderText } = await render(App);

Expand Down
3 changes: 2 additions & 1 deletion tests/Input/TestApp.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
export let form = null;
export let multiline = false;
export let label = '';
export let disabled = false;
</script>

<Form
Expand All @@ -19,7 +20,7 @@
on:submit={onSubmit}
let:isSubmitting
bind:this={form}>
<Input name="email" {label} placeholder="Email" {multiline} />
<Input name="email" {label} placeholder="Email" {multiline} {disabled} />

<button type="submit" disabled={isSubmitting}>Sign in</button>
</Form>
28 changes: 28 additions & 0 deletions tests/Input/__snapshots__/Input.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,34 @@ exports[`Input matches snapshot 1`] = `
</div>
`;

exports[`Input passes props 1`] = `
<div>
<form
class="sveltejs-forms"
>
<div
class="field"
>
<input
disabled=""
id="email"
name="email"
placeholder="Email"
type="text"
/>
</div>
<button
type="submit"
>
Sign in
</button>
</form>
</div>
`;

exports[`Input renders label 1`] = `
<div>
<form
Expand Down

0 comments on commit 3f71240

Please sign in to comment.