Skip to content

Commit 5135c68

Browse files
hellobontempodrivera258
authored andcommitted
UI: add legend to Hds::Form::Radio::Group (#30768)
* add legend to Hds::Form::Radio::Group * add some tests for the radio groups in the wild
1 parent c1e653f commit 5135c68

File tree

5 files changed

+65
-38
lines changed

5 files changed

+65
-38
lines changed

ui/lib/core/addon/components/form-field.hbs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@
1717
data-test-input-group={{@attr.name}}
1818
as |G|
1919
>
20+
<G.Legend data-test-form-field-label={{@attr.name}}>{{this.labelString}}</G.Legend>
21+
{{#if this.helpTextString}}
22+
<G.HelperText data-test-help-text={{@attr.options.helpText}}>{{this.helpTextString}}</G.HelperText>
23+
{{/if}}
24+
{{#if @attr.options.subText}}
25+
<G.HelperText data-test-help-text={{@attr.options.subText}}>
26+
{{@attr.options.subText}}
27+
{{#if @attr.options.docLink}}
28+
<DocLink @path={{@attr.options.docLink}} data-test-doc-link={{@attr.options.docLink}}>
29+
See our documentation
30+
</DocLink>
31+
for help.
32+
{{/if}}
33+
</G.HelperText>
34+
{{/if}}
2035
{{#each (path-or-array @attr.options.possibleValues @model) as |val|}}
2136
<G.RadioField
2237
@id={{or val.id (this.radioValue val)}}

ui/lib/core/addon/components/form-field.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,23 @@ export default class FormFieldComponent extends Component {
152152
}
153153
return '';
154154
}
155+
155156
// both the path to mutate on the model, and the path to read the value from
156157
get valuePath() {
157158
return this.args.attr.options?.fieldValue || this.args.attr.name;
158159
}
160+
159161
get isReadOnly() {
160162
const readonly = this.args.attr.options?.readOnly || false;
161163
return readonly && this.args.mode === 'edit';
162164
}
165+
163166
get validationError() {
164167
const validations = this.args.modelValidations || {};
165168
const state = validations[this.valuePath];
166169
return state && !state.isValid ? state.errors.join(' ') : null;
167170
}
171+
168172
get validationWarning() {
169173
const validations = this.args.modelValidations || {};
170174
const state = validations[this.valuePath];

ui/tests/integration/components/config-ui/messages/page/create-and-edit-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ module('Integration | Component | messages/page/create-and-edit', function (hook
4545
await this.renderComponent();
4646

4747
assert.dom(GENERAL.title).hasText('Create message');
48+
assert.dom(GENERAL.fieldLabelbyAttr('authenticated')).hasText('Where should we display this message?');
4849
assert.dom(CUSTOM_MESSAGES.radio('authenticated')).exists();
4950
assert.dom(CUSTOM_MESSAGES.radio('unauthenticated')).exists();
5051
assert.dom(CUSTOM_MESSAGES.radio('authenticated')).isChecked();
5152
assert.dom(CUSTOM_MESSAGES.radio('unauthenticated')).isNotChecked();
53+
assert.dom(GENERAL.fieldLabelbyAttr('type')).hasText('Type');
5254
assert.dom(CUSTOM_MESSAGES.radio('banner')).exists();
5355
assert.dom(CUSTOM_MESSAGES.radio('modal')).exists();
5456
assert.dom(CUSTOM_MESSAGES.radio('banner')).isChecked();

ui/tests/integration/components/form-field-test.js

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -379,27 +379,45 @@ module('Integration | Component | form field', function (hooks) {
379379
assert.ok(spy.calledWith('myfield', false), 'onChange called with correct args');
380380
});
381381

382-
test('it renders: editType=radio / possibleValues - with passed custom id, label, subtext, helptext', async function (assert) {
382+
test('it renders: editType=radio / possibleValues - with passed custom id, label, subtext, help text for options and doc link, help text, subtext for field', async function (assert) {
383383
await setup.call(
384384
this,
385385
createAttr('myfield', '-', {
386+
docLink: '/docs',
386387
editType: 'radio',
388+
helpText: 'Some help text',
389+
label: 'Radio group legend',
387390
possibleValues: [
388391
{ value: 'foo', id: 'custom-id-1' },
389392
{ value: 'bar', label: 'Custom label 2', subText: 'Some subtext 2' },
390-
{ value: 'baz', label: 'Custom label 3', helpText: 'Some helptext 3' },
391-
{ value: 'qux', label: 'Custom label 4', subText: 'Some subtext 4', helpText: 'Some helptext 2' },
393+
{ value: 'baz', label: 'Custom label 3', helpText: 'Some help text 3' },
394+
{ value: 'qux', label: 'Custom label 4', subText: 'Some subtext 4', helpText: 'Some help text 2' },
392395
],
396+
subText: 'Some subtext',
393397
})
394398
);
399+
assert.dom(GENERAL.fieldLabel()).hasText('Radio group legend', 'it renders attribute label as legend');
400+
assert
401+
.dom(GENERAL.helpTextByAttr('Some subtext'))
402+
.hasText(
403+
'Some subtext See our documentation for help.',
404+
'renders the right subtext string from options'
405+
);
406+
assert
407+
.dom(`${GENERAL.helpTextByAttr('Some subtext')} ${GENERAL.docLinkByAttr('/docs')}`)
408+
.exists('renders `docLink` option as as link inside the subtext');
409+
assert
410+
.dom(GENERAL.helpTextByAttr('Some help text'))
411+
.hasText('Some help text', 'renders the right help text string from options');
412+
395413
// first item should have custom ID, label `foo`, and no subText/helpText
396414
assert
397415
.dom(GENERAL.radioByAttr('custom-id-1'))
398416
.hasAttribute('id', 'custom-id-1', 'renders the radio input with a custom `id` attribute');
399417
assert.dom(GENERAL.labelByGroupControlIndex(1)).hasText('foo', 'renders default label from `foo` value');
400418
assert
401419
.dom(GENERAL.helpTextByGroupControlIndex(1))
402-
.doesNotExist('does not render subtext/helptext for `foo`');
420+
.doesNotExist('does not render subtext/help text for `foo`');
403421
// second item should have custom label and subText but no helpText
404422
assert
405423
.dom(GENERAL.labelByGroupControlIndex(2))
@@ -411,33 +429,19 @@ module('Integration | Component | form field', function (hooks) {
411429
assert
412430
.dom(GENERAL.labelByGroupControlIndex(3))
413431
.hasText('Custom label 3', 'renders the custom label for `baz` from options');
414-
assert.dom(GENERAL.helpTextByGroupControlIndex(3)).doesNotExist('does not render the helptext for `baz`');
432+
assert
433+
.dom(GENERAL.helpTextByGroupControlIndex(3))
434+
.doesNotExist('does not render the help text for `baz`');
415435
// fourth item should have custom label and subText but no helpText (helpText is visible only if no subText is defined for any of the items)
416436
assert
417437
.dom(GENERAL.labelByGroupControlIndex(4))
418438
.hasText('Custom label 4', 'renders the custom label for `qux` from options');
419439
assert
420440
.dom(GENERAL.helpTextByGroupControlIndex(4))
421-
.exists({ count: 1 }, 'renders only the subtext for `qux` and not the helptext')
441+
.exists({ count: 1 }, 'renders only the subtext for `qux` and not the help text')
422442
.hasText('Some subtext 4', 'renders the right subtext string for `qux` from options');
423443
});
424444

425-
test('it renders: editType=radio / possibleValues - with passed helptext', async function (assert) {
426-
await setup.call(
427-
this,
428-
createAttr('myfield', '-', {
429-
editType: 'radio',
430-
possibleValues: [{ value: 'foo' }, { value: 'bar', helpText: 'Some helptext 2' }],
431-
})
432-
);
433-
// first item should not have helpText
434-
assert.dom(GENERAL.helpTextByGroupControlIndex(1)).doesNotExist('does not render helptext for `foo`');
435-
// second item should have helpText
436-
assert
437-
.dom(GENERAL.helpTextByGroupControlIndex(2))
438-
.hasText('Some helptext 2', 'renders the right helptext string for `bar` from options');
439-
});
440-
441445
test('it renders: editType=radio / possibleValues - with validation errors and warnings', async function (assert) {
442446
this.setProperties({
443447
attr: createAttr('myfield', '-', { editType: 'radio', possibleValues: ['foo', 'bar', 'baz'] }),
@@ -521,15 +525,15 @@ module('Integration | Component | form field', function (hooks) {
521525
assert.ok(spy.calledWith('myfield', ['baz', 'foo', 'bar']), 'onChange called with correct args');
522526
});
523527

524-
test('it renders: editType=checkboxList / possibleValues - with passed label, subtext, helptext, doclink', async function (assert) {
528+
test('it renders: editType=checkboxList / possibleValues - with passed label, subtext, help text, doclink', async function (assert) {
525529
await setup.call(
526530
this,
527531
createAttr('myfield', '-', {
528532
editType: 'checkboxList',
529533
possibleValues: ['foo', 'bar', 'baz'],
530534
label: 'Custom label',
531535
subText: 'Some subtext',
532-
helpText: 'Some helptext',
536+
helpText: 'Some help text',
533537
docLink: '/docs',
534538
})
535539
);
@@ -545,9 +549,9 @@ module('Integration | Component | form field', function (hooks) {
545549
.dom(`${GENERAL.helpTextByAttr('Some subtext')} ${GENERAL.docLinkByAttr('/docs')}`)
546550
.exists('renders `docLink` option as as link inside the subtext');
547551
assert
548-
.dom(GENERAL.helpTextByAttr('Some helptext'))
549-
.exists('renders `helptext` option as HelperText')
550-
.hasText('Some helptext', 'renders the right help text string from options');
552+
.dom(GENERAL.helpTextByAttr('Some help text'))
553+
.exists('renders `help text` option as HelperText')
554+
.hasText('Some help text', 'renders the right help text string from options');
551555
});
552556

553557
test('it renders: editType=checkboxList / possibleValues - with validation errors and warnings', async function (assert) {
@@ -632,15 +636,15 @@ module('Integration | Component | form field', function (hooks) {
632636
assert.ok(spy.calledWith('myfield', 'foo'), 'onChange called with correct args');
633637
});
634638

635-
test('it renders: editType=select / possibleValues - with passed label, subtext, helptext, doclink', async function (assert) {
639+
test('it renders: editType=select / possibleValues - with passed label, subtext, help text, doclink', async function (assert) {
636640
await setup.call(
637641
this,
638642
createAttr('myfield', 'string', {
639643
editType: 'select',
640644
possibleValues: ['foo', 'bar', 'baz'],
641645
label: 'Custom label',
642646
subText: 'Some subtext',
643-
helpText: 'Some helptext',
647+
helpText: 'Some help text',
644648
docLink: '/docs',
645649
})
646650
);
@@ -656,9 +660,9 @@ module('Integration | Component | form field', function (hooks) {
656660
.dom(`${GENERAL.helpTextByAttr('Some subtext')} ${GENERAL.docLinkByAttr('/docs')}`)
657661
.exists('renders `docLink` option as as link inside the subtext');
658662
assert
659-
.dom(GENERAL.helpTextByAttr('Some helptext'))
660-
.exists('renders `helptext` option as HelperText')
661-
.hasText('Some helptext', 'renders the right help text string from options');
663+
.dom(GENERAL.helpTextByAttr('Some help text'))
664+
.exists('renders `help text` option as HelperText')
665+
.hasText('Some help text', 'renders the right help text string from options');
662666
});
663667

664668
test('it renders: editType=select / possibleValues - with validation errors and warnings', async function (assert) {
@@ -731,15 +735,15 @@ module('Integration | Component | form field', function (hooks) {
731735
assert.ok(spy.calledWith('myfield', '987'), 'onChange called with correct args');
732736
});
733737

734-
test('it renders: editType=password / type=string - with passed label, placeholder, subtext, helptext, doclink', async function (assert) {
738+
test('it renders: editType=password / type=string - with passed label, placeholder, subtext, help text, doclink', async function (assert) {
735739
await setup.call(
736740
this,
737741
createAttr('myfield', 'string', {
738742
editType: 'password',
739743
placeholder: 'Custom placeholder',
740744
label: 'Custom label',
741745
subText: 'Some subtext',
742-
helpText: 'Some helptext',
746+
helpText: 'Some help text',
743747
docLink: '/docs',
744748
})
745749
);
@@ -758,9 +762,9 @@ module('Integration | Component | form field', function (hooks) {
758762
.dom(`${GENERAL.helpTextByAttr('Some subtext')} ${GENERAL.docLinkByAttr('/docs')}`)
759763
.exists('renders `docLink` option as as link inside the subtext');
760764
assert
761-
.dom(GENERAL.helpTextByAttr('Some helptext'))
762-
.exists('renders `helptext` option as HelperText')
763-
.hasText('Some helptext', 'renders the right help text string from options');
765+
.dom(GENERAL.helpTextByAttr('Some help text'))
766+
.exists('renders `help text` option as HelperText')
767+
.hasText('Some help text', 'renders the right help text string from options');
764768
});
765769

766770
test('it renders: editType=password / type=string - with validation errors and warnings', async function (assert) {

ui/tests/integration/components/mfa/method-form-test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ module('Integration | Component | mfa-method-form', function (hooks) {
3333
assert.dom('[data-test-input="period"]').exists('Period field ttl renders');
3434
assert.dom('[data-test-input="key_size"]').exists('Key size field input renders');
3535
assert.dom('[data-test-input="qr_size"]').exists('QR size field input renders');
36-
assert.dom('[data-test-input-group="algorithm"]').exists(`Algorithm field radio input renders`);
36+
assert
37+
.dom('[data-test-input-group="algorithm"]')
38+
.hasText('Algorithm The hashing algorithm used to generate the TOTP code. SHA1 SHA256 SHA512');
3739
assert
3840
.dom('[data-test-input="max_validation_attempts"]')
3941
.exists(`Max validation attempts field input renders`);

0 commit comments

Comments
 (0)