Skip to content

Commit 3f71240

Browse files
committed
feat(components): pass attributes to HTML elements
BREAKING CHANGE: requires svelte >= 3.20.0 Closes #164
1 parent 8bcc410 commit 3f71240

File tree

12 files changed

+110
-110
lines changed

12 files changed

+110
-110
lines changed

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,18 @@ $ yarn add sveltejs-forms
126126
let:isSubmitting
127127
let:isValid
128128
>
129-
<Input name="user.email" label="Email" placeholder="e.g. user@example.com" /> <!-- nested field -->
129+
<Input
130+
name="user.email" <!-- nested field -->
131+
label="Email Address"
132+
value="test@user.com" <!-- initial value -->
133+
placeholder="e.g. user@example.com" />
130134
<Input name="password" type="password" placeholder="Password" />
131135
<Select name="language" options={langOptions} />
132-
<Choice name="os" options={osOptions} multiple />
133-
136+
<Choice
137+
name="os"
138+
options={osOptions}
139+
disabled
140+
multiple />
134141
<button type="reset">Reset</button>
135142
<button type="submit" disabled={isSubmitting}>Sign in</button>
136143
The form is valid: {isValid}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@
4444
"rollup-plugin-terser": "~5.2.0",
4545
"semantic-release": "~17.0.4",
4646
"sirv-cli": "~0.4.5",
47-
"svelte": "~3.19.2",
47+
"svelte": "~3.20.0",
4848
"svelte-preprocess": "~3.4.0",
4949
"yup": "~0.28.2"
5050
},
5151
"peerDependencies": {
52+
"svelte": "~3.20.0",
5253
"yup": "~0.28.2"
5354
},
5455
"dependencies": {

src/App.svelte

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,20 @@
8282
<Input
8383
name="user.email"
8484
label="Email Address"
85+
value="test@user.com"
8586
placeholder="e.g. user@example.com" />
86-
<Input
87-
name="user.password"
88-
type="password"
89-
placeholder="Password"
90-
multiline />
91-
<Select name="user.language" label="Language" options={langOptions} />
92-
<Choice name="user.os" options={osOptions} multiple />
87+
<Input name="user.password" type="password" placeholder="Password" />
88+
<Select
89+
name="user.language"
90+
label="Language"
91+
options={langOptions}
92+
value={langOptions[2].id} />
93+
<Choice
94+
name="user.os"
95+
options={osOptions}
96+
value={['linux', 'windows']}
97+
disabled
98+
multiple />
9399

94100
<button type="reset">Reset</button>
95101
<button type="submit" disabled={isSubmitting}>Sign in</button>

src/components/Choice.svelte

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
export let name;
99
export let options;
1010
export let multiple = false;
11+
export let value;
1112
1213
const { touchField, values, errors, touched, validateOnChange } = getContext(
1314
FORM
@@ -26,6 +27,12 @@
2627
function onBlur() {
2728
touchField(name);
2829
}
30+
31+
if (value) {
32+
setTimeout(() => {
33+
choice.set(value);
34+
}, 0);
35+
}
2936
</script>
3037

3138
<div class="field" class:error={get($touched, name) && get($errors, name)}>
@@ -38,7 +45,8 @@
3845
on:change={onChange}
3946
on:blur={onBlur}
4047
bind:group={$choice}
41-
value={option.id} />
48+
value={option.id}
49+
{...$$restProps} />
4250
{:else}
4351
<input
4452
id={option.id}
@@ -47,7 +55,8 @@
4755
on:change={onChange}
4856
on:blur={onBlur}
4957
bind:group={$choice}
50-
value={option.id} />
58+
value={option.id}
59+
{...$$restProps} />
5160
{/if}
5261
{#if option.title}
5362
<label for={option.id}>{option.title}</label>

src/components/Form.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,11 @@
9696
}
9797
}
9898
99-
function setValue(path, value) {
99+
function setValue(path, value, validateForm = true) {
100100
$values = set($values, path, value);
101101
$touched = set($touched, path, true);
102102
103-
if (validateOnChange) {
103+
if (validateForm && validateOnChange) {
104104
validate();
105105
}
106106
}

src/components/Input.svelte

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
export let name;
77
export let label = '';
88
export let type = 'text';
9-
export let placeholder = '';
109
export let multiline = false;
1110
1211
const { touchField, setValue, values, errors, touched } = getContext(FORM);
@@ -18,6 +17,10 @@
1817
function onBlur() {
1918
touchField(name);
2019
}
20+
21+
if (Object.keys($$restProps).includes('value')) {
22+
setTimeout(() => setValue(name, $$restProps.value, false), 0);
23+
}
2124
</script>
2225

2326
<div class="field" class:error={get($touched, name) && get($errors, name)}>
@@ -27,20 +30,20 @@
2730
{#if multiline}
2831
<textarea
2932
{name}
30-
{placeholder}
3133
id={name}
3234
value={get($values, name)}
3335
on:blur={onBlur}
34-
on:change={onChange} />
36+
on:change={onChange}
37+
{...$$restProps} />
3538
{:else}
3639
<input
3740
{name}
3841
{type}
39-
{placeholder}
4042
id={name}
4143
value={get($values, name)}
4244
on:blur={onBlur}
43-
on:change={onChange} />
45+
on:change={onChange}
46+
{...$$restProps} />
4447
{/if}
4548
{#if get($touched, name) && get($errors, name)}
4649
<div class="message">{get($errors, name)}</div>

src/components/Select.svelte

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
function onBlur() {
1717
touchField(name);
1818
}
19+
20+
if (Object.keys($$restProps).includes('value')) {
21+
setTimeout(() => setValue(name, $$restProps.value, false), 0);
22+
}
1923
</script>
2024

2125
<div class="field" class:error={get($touched, name) && get($errors, name)}>
@@ -27,10 +31,13 @@
2731
id={name}
2832
value={get($values, name)}
2933
on:change={onChange}
30-
on:blur={onBlur}>
34+
on:blur={onBlur}
35+
{...$$restProps}>
3136
<option value="" />
3237
{#each options as option}
33-
<option value={option.id}>{option.title}</option>
38+
<option value={option.id} selected={get($values, name) === option.id}>
39+
{option.title}
40+
</option>
3441
{/each}
3542
</select>
3643
{#if get($touched, name) && get($errors, name)}

tests/Form/__snapshots__/Form.spec.js.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,19 @@ exports[`Form matches snapshot 1`] = `
3333
value="svelte"
3434
>
3535
Svelte
36+
3637
</option>
3738
<option
3839
value="react"
3940
>
4041
React
42+
4143
</option>
4244
<option
4345
value="angular"
4446
>
4547
Angular
48+
4649
</option>
4750
</select>
4851
@@ -55,7 +58,6 @@ exports[`Form matches snapshot 1`] = `
5558
id="macos"
5659
name="os"
5760
type="checkbox"
58-
value="macos"
5961
/>
6062
6163
<label
@@ -68,7 +70,6 @@ exports[`Form matches snapshot 1`] = `
6870
id="linux"
6971
name="os"
7072
type="checkbox"
71-
value="linux"
7273
/>
7374
7475
<label
@@ -81,7 +82,6 @@ exports[`Form matches snapshot 1`] = `
8182
id="windows"
8283
name="os"
8384
type="checkbox"
84-
value="windows"
8585
/>
8686
8787
<label
@@ -200,16 +200,19 @@ exports[`Form shows error message when schema is defined 1`] = `
200200
value="svelte"
201201
>
202202
Svelte
203+
203204
</option>
204205
<option
205206
value="react"
206207
>
207208
React
209+
208210
</option>
209211
<option
210212
value="angular"
211213
>
212214
Angular
215+
213216
</option>
214217
</select>
215218
@@ -222,7 +225,6 @@ exports[`Form shows error message when schema is defined 1`] = `
222225
id="macos"
223226
name="os"
224227
type="checkbox"
225-
value="macos"
226228
/>
227229
228230
<label
@@ -235,7 +237,6 @@ exports[`Form shows error message when schema is defined 1`] = `
235237
id="linux"
236238
name="os"
237239
type="checkbox"
238-
value="linux"
239240
/>
240241
241242
<label
@@ -248,7 +249,6 @@ exports[`Form shows error message when schema is defined 1`] = `
248249
id="windows"
249250
name="os"
250251
type="checkbox"
251-
value="windows"
252252
/>
253253
254254
<label

tests/Input/Input.spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ describe('Input', () => {
1414
expect(container.firstChild).toMatchSnapshot();
1515
});
1616

17+
it('passes props to input', async () => {
18+
const { container } = await render(App, { props: { disabled: true } });
19+
expect(container.firstChild).toMatchSnapshot();
20+
});
21+
1722
it('updates form value on change', async () => {
1823
const { component, getByPlaceholderText } = await render(App);
1924

tests/Input/TestApp.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
export let form = null;
1010
export let multiline = false;
1111
export let label = '';
12+
export let disabled = false;
1213
</script>
1314

1415
<Form
@@ -19,7 +20,7 @@
1920
on:submit={onSubmit}
2021
let:isSubmitting
2122
bind:this={form}>
22-
<Input name="email" {label} placeholder="Email" {multiline} />
23+
<Input name="email" {label} placeholder="Email" {multiline} {disabled} />
2324

2425
<button type="submit" disabled={isSubmitting}>Sign in</button>
2526
</Form>

tests/Input/__snapshots__/Input.spec.js.snap

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,34 @@ exports[`Input matches snapshot 1`] = `
2727
</div>
2828
`;
2929

30+
exports[`Input passes props 1`] = `
31+
<div>
32+
<form
33+
class="sveltejs-forms"
34+
>
35+
<div
36+
class="field"
37+
>
38+
39+
<input
40+
disabled=""
41+
id="email"
42+
name="email"
43+
placeholder="Email"
44+
type="text"
45+
/>
46+
47+
</div>
48+
49+
<button
50+
type="submit"
51+
>
52+
Sign in
53+
</button>
54+
</form>
55+
</div>
56+
`;
57+
3058
exports[`Input renders label 1`] = `
3159
<div>
3260
<form

0 commit comments

Comments
 (0)