Skip to content

Commit c682d2b

Browse files
committed
isNameRequired and isEmailRequired
1 parent 13aaf3c commit c682d2b

File tree

5 files changed

+76
-10
lines changed

5 files changed

+76
-10
lines changed

packages/feedback/src/widget/Dialog.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export function Dialog({
4545
showBranding,
4646
showName,
4747
showEmail,
48+
isNameRequired,
49+
isEmailRequired,
4850
colorScheme,
4951
isAnonymous,
5052
defaultName,
@@ -102,6 +104,8 @@ export function Dialog({
102104
showEmail,
103105
showName,
104106
isAnonymous,
107+
isEmailRequired,
108+
isNameRequired,
105109

106110
defaultName,
107111
defaultEmail,

packages/feedback/src/widget/Form.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export interface FormComponentProps
88
| 'showName'
99
| 'showEmail'
1010
| 'isAnonymous'
11+
| 'isNameRequired'
12+
| 'isEmailRequired'
1113
| Exclude<keyof FeedbackTextConfiguration, 'buttonLabel' | 'formTitle' | 'successMessageText'>
1214
> {
1315
/**
@@ -58,6 +60,8 @@ export function Form({
5860
showName,
5961
showEmail,
6062
isAnonymous,
63+
isNameRequired,
64+
isEmailRequired,
6165

6266
defaultName,
6367
defaultEmail,
@@ -110,19 +114,21 @@ export function Form({
110114

111115
const nameEl = createElement('input', {
112116
id: 'name',
113-
type: showName ? 'text' : 'hidden',
114-
['aria-hidden']: showName ? 'false' : 'true',
117+
type: showName || isNameRequired? 'text' : 'hidden',
118+
['aria-hidden']: showName || isNameRequired? 'false' : 'true',
115119
name: 'name',
120+
required: isNameRequired,
116121
className: 'form__input',
117122
placeholder: namePlaceholder,
118123
value: defaultName,
119124
});
120125

121126
const emailEl = createElement('input', {
122127
id: 'email',
123-
type: showEmail ? 'text' : 'hidden',
124-
['aria-hidden']: showEmail ? 'false' : 'true',
128+
type: showEmail || isEmailRequired? 'text' : 'hidden',
129+
['aria-hidden']: showEmail || isEmailRequired? 'false' : 'true',
125130
name: 'email',
131+
required: isEmailRequired,
126132
className: 'form__input',
127133
placeholder: emailPlaceholder,
128134
value: defaultEmail,
@@ -161,28 +167,46 @@ export function Form({
161167
errorEl,
162168

163169
!isAnonymous &&
164-
showName &&
170+
(showName || isNameRequired) &&
165171
createElement(
166172
'label',
167173
{
168174
htmlFor: 'name',
169175
className: 'form__label',
170176
},
177+
isNameRequired ? [
178+
createElement(
179+
'span',
180+
{ className: 'form__label__text' },
181+
nameLabel,
182+
createElement('span', { className: 'form__label__text--required' }, ' (required)'),
183+
),
184+
nameEl,
185+
] :
171186
[nameLabel, nameEl],
172187
),
173-
!isAnonymous && !showName && nameEl,
188+
!isAnonymous && !(showName||isNameRequired) && nameEl,
174189

175190
!isAnonymous &&
176-
showEmail &&
191+
(showEmail || isEmailRequired) &&
177192
createElement(
178193
'label',
179194
{
180195
htmlFor: 'email',
181196
className: 'form__label',
182197
},
198+
isEmailRequired ? [
199+
createElement(
200+
'span',
201+
{ className: 'form__label__text' },
202+
emailLabel,
203+
createElement('span', { className: 'form__label__text--required' }, ' (required)'),
204+
),
205+
emailEl,
206+
] :
183207
[emailLabel, emailEl],
184208
),
185-
!isAnonymous && !showEmail && emailEl,
209+
!isAnonymous && !(showEmail||isEmailRequired) && emailEl,
186210

187211
createElement(
188212
'label',

packages/feedback/src/widget/createWidget.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ export function createWidget({
159159
showName: options.showName,
160160
showEmail: options.showEmail,
161161
isAnonymous: options.isAnonymous,
162+
isNameRequired: options.isNameRequired,
163+
isEmailRequired: options.isEmailRequired,
162164
formTitle: options.formTitle,
163165
cancelButtonLabel: options.cancelButtonLabel,
164166
submitButtonLabel: options.submitButtonLabel,

packages/feedback/test/widget/Dialog.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ function renderDialog({
1010
showEmail = true,
1111
showBranding = false,
1212
isAnonymous = false,
13+
isNameRequired = false,
14+
isEmailRequired = false,
1315
formTitle = 'Feedback',
1416
defaultName = 'Foo Bar',
1517
defaultEmail = '[email protected]',
@@ -30,6 +32,8 @@ function renderDialog({
3032
isAnonymous,
3133
showName,
3234
showEmail,
35+
isNameRequired,
36+
isEmailRequired,
3337
showBranding,
3438
defaultName,
3539
defaultEmail,

packages/feedback/test/widget/Form.test.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ function renderForm({
99
showName = true,
1010
showEmail = true,
1111
isAnonymous = false,
12+
isNameRequired = false,
13+
isEmailRequired = false,
1214
defaultName = 'Foo Bar',
1315
defaultEmail = '[email protected]',
1416
nameLabel = 'Name',
@@ -25,6 +27,8 @@ function renderForm({
2527
isAnonymous,
2628
showName,
2729
showEmail,
30+
isNameRequired,
31+
isEmailRequired,
2832
defaultName,
2933
defaultEmail,
3034
nameLabel,
@@ -80,13 +84,15 @@ describe('Form', () => {
8084
emailPlaceholder: '[email protected]!',
8185
messageLabel: 'Description!',
8286
messagePlaceholder: 'What is the issue?!',
87+
isNameRequired: true,
88+
isEmailRequired: true,
8389
});
8490

8591
const nameLabel = formComponent.el.querySelector('label[htmlFor="name"]') as HTMLLabelElement;
8692
const emailLabel = formComponent.el.querySelector('label[htmlFor="email"]') as HTMLLabelElement;
8793
const messageLabel = formComponent.el.querySelector('label[htmlFor="message"]') as HTMLLabelElement;
88-
expect(nameLabel.textContent).toBe('Name!');
89-
expect(emailLabel.textContent).toBe('Email!');
94+
expect(nameLabel.textContent).toBe('Name! (required)');
95+
expect(emailLabel.textContent).toBe('Email! (required)');
9096
expect(messageLabel.textContent).toBe('Description! (required)');
9197

9298
const nameInput = formComponent.el.querySelector('[name="name"]') as HTMLInputElement;
@@ -110,6 +116,30 @@ describe('Form', () => {
110116
message.dispatchEvent(new KeyboardEvent('keyup'));
111117
});
112118

119+
it('submit is enabled if name is required and is not empty', () => {
120+
const formComponent = renderForm({isNameRequired: true});
121+
122+
const name = formComponent.el.querySelector('[name="name"]') as HTMLTextAreaElement;
123+
124+
name.value = 'Foo Bar';
125+
name.dispatchEvent(new KeyboardEvent('keyup'));
126+
127+
name.value = '';
128+
name.dispatchEvent(new KeyboardEvent('keyup'));
129+
});
130+
131+
it('submit is enabled if email is required and is not empty', () => {
132+
const formComponent = renderForm({isEmailRequired: true});
133+
134+
const email = formComponent.el.querySelector('[name="email"]') as HTMLTextAreaElement;
135+
136+
email.value = '[email protected]';
137+
email.dispatchEvent(new KeyboardEvent('keyup'));
138+
139+
email.value = '';
140+
email.dispatchEvent(new KeyboardEvent('keyup'));
141+
});
142+
113143
it('can show error', () => {
114144
const formComponent = renderForm();
115145
const errorEl = formComponent.el.querySelector('.form__error-container') as HTMLDivElement;
@@ -148,6 +178,8 @@ describe('Form', () => {
148178
it('does not show name or email inputs for anonymous mode', () => {
149179
const onSubmit = jest.fn();
150180
const formComponent = renderForm({
181+
isNameRequired: true,
182+
isEmailRequired: true,
151183
isAnonymous: true,
152184
onSubmit,
153185
});

0 commit comments

Comments
 (0)