Skip to content

Commit f147099

Browse files
Merge pull request #14 from jeffreylauwers/feature/no-placeholder-by-default
refactor(storybook): geen placeholder by default in invulvelden
2 parents 2c22994 + 8722374 commit f147099

14 files changed

Lines changed: 171 additions & 88 deletions

packages/storybook/src/EmailInput.docs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ De EmailInput component is een gespecialiseerd invoerveld voor e-mailadressen. H
2020

2121
## Best practices
2222

23-
- **Gebruik een duidelijke placeholder.** Geef een voorbeeld e-mailadres (bijv. `naam@voorbeeld.nl`).
23+
- **Gebruik FormFieldDescription voor formaathints.** Als het e-mailadresformaat toelichting behoeft, gebruik dan [FormFieldDescription](/docs/components-formfielddescription--docs) — niet een placeholder. Placeholder tekst verdwijnt bij typen en is daarna niet meer zichtbaar.
2424
- **Laat browser-autocomplete aan.** De standaard `autocomplete="email"` helpt gebruikers snel invullen. Zet alleen op `off` als daar een goede reden voor is.
2525
- **Combineer met FormField.** Gebruik altijd een label via `FormField` of `FormFieldLabel` voor toegankelijkheid.
2626
- **Geef validatie feedback.** Gebruik de `invalid` prop in combinatie met `aria-invalid` en een `FormFieldErrorMessage`.

packages/storybook/src/EmailInput.stories.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ const meta: Meta<typeof EmailInput> = {
2929
},
3030
},
3131
args: {
32-
placeholder: 'naam@voorbeeld.nl',
3332
disabled: false,
3433
readOnly: false,
3534
invalid: false,
@@ -55,6 +54,11 @@ export const WithValue: Story = {
5554
args: { defaultValue: 'jan@voorbeeld.nl' },
5655
};
5756

57+
export const WithPlaceholder: Story = {
58+
name: 'With placeholder',
59+
args: { placeholder: 'naam@voorbeeld.nl' },
60+
};
61+
5862
export const Disabled: Story = {
5963
args: { disabled: true, value: 'jan@voorbeeld.nl' },
6064
};
@@ -71,13 +75,21 @@ export const Invalid: Story = {
7175
export const Widths: Story = {
7276
name: 'Width variants',
7377
render: () => (
74-
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
75-
<EmailInput width="xs" placeholder="xs" />
76-
<EmailInput width="sm" placeholder="sm" />
77-
<EmailInput width="md" placeholder="md" />
78-
<EmailInput width="lg" placeholder="lg" />
79-
<EmailInput width="xl" placeholder="xl" />
80-
<EmailInput width="full" placeholder="full" />
78+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
79+
{(['xs', 'sm', 'md', 'lg', 'xl', 'full'] as const).map((w) => (
80+
<div key={w}>
81+
<p
82+
style={{
83+
margin: '0 0 0.25rem',
84+
fontWeight: 'bold',
85+
fontSize: '0.875rem',
86+
}}
87+
>
88+
{w}
89+
</p>
90+
<EmailInput width={w} />
91+
</div>
92+
))}
8193
</div>
8294
),
8395
};
@@ -107,7 +119,7 @@ export const AllStates: Story = {
107119
>
108120
Default
109121
</label>
110-
<EmailInput placeholder="naam@voorbeeld.nl" />
122+
<EmailInput />
111123
</div>
112124
<div>
113125
<label

packages/storybook/src/FormField.stories.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const Default: Story = {
5151
},
5252
render: (args) => (
5353
<FormField {...args}>
54-
<TextInput id="input-1" placeholder={TEKST} />
54+
<TextInput id="input-1" />
5555
</FormField>
5656
),
5757
};
@@ -60,7 +60,7 @@ export const WithDescription: Story = {
6060
name: 'With description',
6161
render: (args) => (
6262
<FormField {...args} label={TEKST} htmlFor="input-desc" description={TEKST}>
63-
<TextInput id="input-desc" placeholder={TEKST} />
63+
<TextInput id="input-desc" />
6464
</FormField>
6565
),
6666
};
@@ -69,7 +69,7 @@ export const WithError: Story = {
6969
name: 'With error',
7070
render: (args) => (
7171
<FormField {...args} label={TEKST} htmlFor="input-err" error={TEKST}>
72-
<TextInput id="input-err" invalid placeholder={TEKST} />
72+
<TextInput id="input-err" invalid />
7373
</FormField>
7474
),
7575
};
@@ -78,7 +78,7 @@ export const WithStatus: Story = {
7878
name: 'With status',
7979
render: (args) => (
8080
<FormField {...args} label={TEKST} htmlFor="input-status" status={TEKST}>
81-
<TextInput id="input-status" placeholder={TEKST} />
81+
<TextInput id="input-status" />
8282
</FormField>
8383
),
8484
};
@@ -90,25 +90,25 @@ export const AllStates: Story = {
9090
<div>
9191
<h3 style={{ marginBlockEnd: '0.5rem' }}>Basic</h3>
9292
<FormField label={TEKST} htmlFor="s1">
93-
<TextInput id="s1" placeholder={TEKST} />
93+
<TextInput id="s1" />
9494
</FormField>
9595
</div>
9696
<div>
9797
<h3 style={{ marginBlockEnd: '0.5rem' }}>With description</h3>
9898
<FormField label={TEKST} htmlFor="s2" description={TEKST}>
99-
<TextInput id="s2" placeholder={TEKST} />
99+
<TextInput id="s2" />
100100
</FormField>
101101
</div>
102102
<div>
103103
<h3 style={{ marginBlockEnd: '0.5rem' }}>With optional suffix</h3>
104104
<FormField label={TEKST} htmlFor="s3" labelSuffix="(niet verplicht)">
105-
<TextInput id="s3" placeholder={TEKST} />
105+
<TextInput id="s3" />
106106
</FormField>
107107
</div>
108108
<div>
109109
<h3 style={{ marginBlockEnd: '0.5rem' }}>With error</h3>
110110
<FormField label={TEKST} htmlFor="s4" error={TEKST}>
111-
<TextInput id="s4" invalid placeholder={TEKST} />
111+
<TextInput id="s4" invalid />
112112
</FormField>
113113
</div>
114114
<div>
@@ -119,7 +119,7 @@ export const AllStates: Story = {
119119
status={TEKST}
120120
statusVariant="positive"
121121
>
122-
<TextInput id="s5" placeholder={TEKST} />
122+
<TextInput id="s5" />
123123
</FormField>
124124
</div>
125125
<div>
@@ -130,13 +130,13 @@ export const AllStates: Story = {
130130
status={TEKST}
131131
statusVariant="warning"
132132
>
133-
<TextInput id="s6" placeholder={TEKST} />
133+
<TextInput id="s6" />
134134
</FormField>
135135
</div>
136136
<div>
137137
<h3 style={{ marginBlockEnd: '0.5rem' }}>With TextArea</h3>
138138
<FormField label={TEKST} htmlFor="s7" description={TEKST}>
139-
<TextArea id="s7" rows={4} placeholder={TEKST} />
139+
<TextArea id="s7" rows={4} />
140140
</FormField>
141141
</div>
142142
<div>

packages/storybook/src/NumberInput.docs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ De NumberInput component is een gespecialiseerd invoerveld voor het invoeren van
2121

2222
## Best practices
2323

24-
- **Gebruik een duidelijke placeholder.** Geef aan wat de verwachte invoer is (bijv. `0` voor gehele getallen, `0,00` voor bedragen).
24+
- **Gebruik FormFieldDescription voor formaathints.** Als je wilt toelichten wat de verwachte invoer is (bijv. "Voer een bedrag in, gebruik een komma voor decimalen"), gebruik dan [FormFieldDescription](/docs/components-formfielddescription--docs) — niet een placeholder. Placeholder tekst verdwijnt bij typen en is daarna niet meer zichtbaar.
2525
- **Gebruik `allowDecimals` voor bedragen.** Dit schakelt `inputmode="decimal"` in zodat ook een kommatoets beschikbaar is op mobiel.
2626
- **Combineer met FormField.** Gebruik altijd een label via `FormField` of `FormFieldLabel` voor toegankelijkheid.
2727
- **Geef validatie feedback.** Gebruik de `invalid` prop in combinatie met `aria-invalid` en een `FormFieldErrorMessage`.

packages/storybook/src/NumberInput.stories.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ const meta: Meta<typeof NumberInput> = {
2424
},
2525
},
2626
args: {
27-
placeholder: '0',
2827
disabled: false,
2928
readOnly: false,
3029
invalid: false,
@@ -50,11 +49,15 @@ export const WithDecimals: Story = {
5049
name: 'With decimals (allowDecimals)',
5150
args: {
5251
allowDecimals: true,
53-
placeholder: '0,00',
5452
defaultValue: '1234',
5553
},
5654
};
5755

56+
export const WithPlaceholder: Story = {
57+
name: 'With placeholder',
58+
args: { placeholder: '0' },
59+
};
60+
5861
export const WithValue: Story = {
5962
name: 'With value',
6063
args: { defaultValue: '42' },
@@ -76,13 +79,21 @@ export const Invalid: Story = {
7679
export const Widths: Story = {
7780
name: 'Width variants',
7881
render: () => (
79-
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
80-
<NumberInput width="xs" placeholder="xs" />
81-
<NumberInput width="sm" placeholder="sm" />
82-
<NumberInput width="md" placeholder="md" />
83-
<NumberInput width="lg" placeholder="lg" />
84-
<NumberInput width="xl" placeholder="xl" />
85-
<NumberInput width="full" placeholder="full" />
82+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
83+
{(['xs', 'sm', 'md', 'lg', 'xl', 'full'] as const).map((w) => (
84+
<div key={w}>
85+
<p
86+
style={{
87+
margin: '0 0 0.25rem',
88+
fontWeight: 'bold',
89+
fontSize: '0.875rem',
90+
}}
91+
>
92+
{w}
93+
</p>
94+
<NumberInput width={w} />
95+
</div>
96+
))}
8697
</div>
8798
),
8899
};
@@ -112,7 +123,7 @@ export const AllStates: Story = {
112123
>
113124
Default
114125
</label>
115-
<NumberInput placeholder="0" />
126+
<NumberInput />
116127
</div>
117128
<div>
118129
<label

packages/storybook/src/PasswordInput.stories.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ const meta: Meta<typeof PasswordInput> = {
2727
},
2828
},
2929
args: {
30-
placeholder: 'Wachtwoord',
3130
disabled: false,
3231
readOnly: false,
3332
invalid: false,
@@ -53,10 +52,14 @@ export const NewPassword: Story = {
5352
name: 'New password (registratie)',
5453
args: {
5554
passwordAutocomplete: 'new-password',
56-
placeholder: 'Nieuw wachtwoord',
5755
},
5856
};
5957

58+
export const WithPlaceholder: Story = {
59+
name: 'With placeholder',
60+
args: { placeholder: 'Wachtwoord' },
61+
};
62+
6063
export const Disabled: Story = {
6164
args: { disabled: true, value: 'geheim123' },
6265
};
@@ -73,13 +76,21 @@ export const Invalid: Story = {
7376
export const Widths: Story = {
7477
name: 'Width variants',
7578
render: () => (
76-
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
77-
<PasswordInput width="xs" placeholder="xs" />
78-
<PasswordInput width="sm" placeholder="sm" />
79-
<PasswordInput width="md" placeholder="md" />
80-
<PasswordInput width="lg" placeholder="lg" />
81-
<PasswordInput width="xl" placeholder="xl" />
82-
<PasswordInput width="full" placeholder="full" />
79+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
80+
{(['xs', 'sm', 'md', 'lg', 'xl', 'full'] as const).map((w) => (
81+
<div key={w}>
82+
<p
83+
style={{
84+
margin: '0 0 0.25rem',
85+
fontWeight: 'bold',
86+
fontSize: '0.875rem',
87+
}}
88+
>
89+
{w}
90+
</p>
91+
<PasswordInput width={w} />
92+
</div>
93+
))}
8394
</div>
8495
),
8596
};
@@ -109,7 +120,7 @@ export const AllStates: Story = {
109120
>
110121
Default
111122
</label>
112-
<PasswordInput placeholder="Wachtwoord" />
123+
<PasswordInput />
113124
</div>
114125
<div>
115126
<label

packages/storybook/src/SearchInput.docs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ De SearchInput component is een gespecialiseerd invoerveld voor zoekfunctionalit
2121

2222
## Best practices
2323

24-
- **Gebruik een duidelijke placeholder.** Geef aan wat gebruikers kunnen zoeken (bijv. `Zoek producten...`, `Zoek in artikelen...`).
24+
- **Gebruik een zichtbaar label of `aria-label`.** Voeg altijd een label toe via `FormField` of `FormFieldLabel`, of gebruik `aria-label` als het visuele design geen zichtbaar label toestaat (bijv. een zoekveld in de siteheader). Een placeholder is niet verplicht en verdwijnt bij typen — gebruik het optioneel alleen als extra context over de zoekscope nuttig is (bijv. `Zoek in producten...`).
2525
- **Gebruik `role="search"` op een wrapper element.** Dit helpt screen readers de zoekfunctionaliteit te identificeren.
2626
- **Implementeer live search of debouncing.** Update resultaten tijdens het typen, maar niet bij elke toetsaanslag.
2727
- **Geef feedback bij geen resultaten.** Toon een melding als er geen resultaten zijn gevonden.

packages/storybook/src/SearchInput.stories.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ const meta: Meta<typeof SearchInput> = {
3030
},
3131
},
3232
args: {
33-
placeholder: 'Zoeken...',
3433
disabled: false,
3534
readOnly: false,
3635
invalid: false,
@@ -56,6 +55,11 @@ export const WithValue: Story = {
5655
args: { defaultValue: TEKST },
5756
};
5857

58+
export const WithPlaceholder: Story = {
59+
name: 'With placeholder',
60+
args: { placeholder: 'Zoeken...' },
61+
};
62+
5963
export const Disabled: Story = {
6064
args: { disabled: true, value: TEKST },
6165
};
@@ -72,13 +76,21 @@ export const Invalid: Story = {
7276
export const Widths: Story = {
7377
name: 'Width variants',
7478
render: () => (
75-
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
76-
<SearchInput width="xs" placeholder="xs" />
77-
<SearchInput width="sm" placeholder="sm" />
78-
<SearchInput width="md" placeholder="md" />
79-
<SearchInput width="lg" placeholder="lg" />
80-
<SearchInput width="xl" placeholder="xl" />
81-
<SearchInput width="full" placeholder="full" />
79+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
80+
{(['xs', 'sm', 'md', 'lg', 'xl', 'full'] as const).map((w) => (
81+
<div key={w}>
82+
<p
83+
style={{
84+
margin: '0 0 0.25rem',
85+
fontWeight: 'bold',
86+
fontSize: '0.875rem',
87+
}}
88+
>
89+
{w}
90+
</p>
91+
<SearchInput width={w} />
92+
</div>
93+
))}
8294
</div>
8395
),
8496
};
@@ -108,7 +120,7 @@ export const AllStates: Story = {
108120
>
109121
Default
110122
</label>
111-
<SearchInput placeholder="Zoeken..." />
123+
<SearchInput />
112124
</div>
113125
<div>
114126
<label

packages/storybook/src/TelephoneInput.docs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ De TelephoneInput component is een gespecialiseerd invoerveld voor telefoonnumme
2020

2121
## Best practices
2222

23-
- **Gebruik een duidelijke placeholder.** Geef een voorbeeld in het verwachte formaat (bijv. `06 12345678` of `+31 6 12345678`).
23+
- **Gebruik FormFieldDescription voor formaathints.** Als je het verwachte formaat wilt toelichten (bijv. `06 12345678` of `+31 6 12345678`), gebruik dan [FormFieldDescription](/docs/components-formfielddescription--docs) — niet een placeholder. Placeholder tekst verdwijnt bij typen en is daarna niet meer zichtbaar.
2424
- **Dwing geen specifiek formaat af.** Gebruikers typen telefoonnummers op verschillende manieren. Valideer lengte en tekens, maar accepteer variaties in opmaak.
2525
- **Laat browser-autocomplete aan.** De standaard `autocomplete="tel"` helpt gebruikers snel invullen.
2626
- **Combineer met FormField.** Gebruik altijd een label via `FormField` of `FormFieldLabel` voor toegankelijkheid.

0 commit comments

Comments
 (0)