Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nine-fans-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hashicorp/design-system-components": patch
---

`Form::Label` - Forced the `for` HTML attribute to be converted to a string
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: MPL-2.0
}}
<label class={{this.classNames}} for={{@controlId}} id={{this.id}} ...attributes>
<label class={{this.classNames}} for="{{@controlId}}" id={{this.id}} ...attributes>
{{yield}}
<Hds::Form::Indicator @isRequired={{@isRequired}} @isOptional={{@isOptional}} />
</label>
17 changes: 17 additions & 0 deletions showcase/app/templates/components/form/radio.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,21 @@
</SF.Item>
</Shw::Flex>

<Shw::Text::H3>Special cases</Shw::Text::H3>

<Shw::Flex as |SF|>
<SF.Item as |SFI|>
<SFI.Label>With <code>true/false</code> as boolean values</SFI.Label>
<Hds::Form::Radio::Group @name="control-booleans" as |G|>
{{#let (array true false) as |bools|}}
{{#each bools as |bool|}}
<G.RadioField @id={{bool}} @value={{bool}} as |F|>
<F.Label>{{bool}}</F.Label>
</G.RadioField>
{{/each}}
{{/let}}
</Hds::Form::Radio::Group>
</SF.Item>
</Shw::Flex>

</section>
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ module('Integration | Component | hds/form/label/index', function (hooks) {
assert.dom('#test-form-label').hasAttribute('for', 'my-control-id');
});

test('it renders a label with the "for" attribute even if the @controlId argument is a boolean', async function (assert) {
await render(
hbs`<Hds::Form::Label @controlId={{true}} id="test-form-label-true">True</Hds::Form::Label>
<Hds::Form::Label @controlId={{false}} id="test-form-label-false">False</Hds::Form::Label>
`
);
assert.dom('#test-form-label-true').hasAttribute('for', 'true');
assert.dom('#test-form-label-false').hasAttribute('for', 'false');
});

// ID

test('it renders a label with the correct "id" attribute if the @controlId argument is provided', async function (assert) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,31 @@ module('Integration | Component | hds/form/radio/group', function (hooks) {
);
});

test('it automatically provides all the ID relations between the elements when dynamically rendered using boolean values', async function (assert) {
await render(
hbs`<Hds::Form::Radio::Group as |G|>
<G.RadioField @value={{true}} @id={{true}} as |F|>
<F.Label>This is the label for the 'true' value</F.Label>
</G.RadioField>
<G.RadioField @value={{false}} @id={{false}} as |F|>
<F.Label>This is the label for the 'false' value</F.Label>
</G.RadioField>
</Hds::Form::Radio::Group>`
);

const inputs = this.element.querySelectorAll('input[type="radio"]');
const labels = this.element.querySelectorAll('label');

// the `true` value should be used for the `id` (input) and `for` (label) attributes
assert.dom(inputs[0]).hasAttribute('id', 'true');
assert.dom(labels[0]).hasAttribute('for', 'true');

// the `false` value should not be used, but the `id` (input) attribute should be generated and the `for` (label) attribute should match it
const generatedId = inputs[1].id;
assert.true(generatedId.startsWith('ember'));
assert.dom(labels[1]).hasAttribute('for', generatedId);
});

// NAME

test('it renders the defined name on all controls within a group', async function (assert) {
Expand Down