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
11 changes: 11 additions & 0 deletions .changeset/cold-worlds-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@hashicorp/design-system-components": major
---

<!-- START components/dropdown -->

`Dropdown` - Removed the deprecated `@text` argument from the `HdsDropdownListItemInteractive` component.

To migrate run the codemod `v4/dropdown-list-item-interactive` (see [readme file](https://github.com/hashicorp/design-system/tree/main/packages/codemods/transforms/v4/dropdown-list-item-interactive))

<!-- END -->
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
<Hds::Icon @name="loading" />
</div>
<Hds::Text::Body @tag="div" @size="100" @weight="regular" class="hds-dropdown-list-item__interactive-text">
{{#if (has-block)}}
{{yield (hash Badge=(component "hds/badge" size="small"))}}
{{else}}
{{this.text}}
{{/if}}
{{yield (hash Badge=(component "hds/badge" size="small"))}}
</Hds::Text::Body>
</div>
{{else}}
Expand All @@ -34,11 +30,7 @@
</span>
{{/if}}
<Hds::Text::Body class="hds-dropdown-list-item__interactive-text" @tag="span" @size="200" @weight="medium">
{{#if (has-block)}}
{{yield (hash Badge=(component "hds/badge" size="small"))}}
{{else}}
{{this.text}}
{{/if}}
{{yield (hash Badge=(component "hds/badge" size="small"))}}
</Hds::Text::Body>
{{#if @trailingIcon}}
<span class="hds-dropdown-list-item__interactive-icon hds-dropdown-list-item__interactive-icon--trailing">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import Component from '@glimmer/component';
import { assert, deprecate } from '@ember/debug';
import { assert } from '@ember/debug';

import { HdsDropdownListItemInteractiveColorValues } from './types.ts';

Expand All @@ -13,7 +13,6 @@ import type { HdsInteractiveSignature } from '../../interactive';
import type { HdsDropdownListItemInteractiveColors } from './types.ts';
import type { ComponentLike } from '@glint/template';
import type { HdsBadgeSignature } from '../../badge/index.ts';
import type Owner from '@ember/owner';

export const DEFAULT_COLOR = HdsDropdownListItemInteractiveColorValues.Action;
export const COLORS: HdsDropdownListItemInteractiveColors[] = Object.values(
Expand All @@ -25,10 +24,6 @@ export interface HdsDropdownListItemInteractiveSignature {
color?: HdsDropdownListItemInteractiveColors;
icon?: HdsIconSignature['Args']['name'];
isLoading?: boolean;
/**
* @deprecated The `@text` argument for "Hds::Dropdown::ListItem::Interactive" has been deprecated. Please put text in the yielded block. See: https://helios.hashicorp.design/components/dropdown?tab=version%20history#4100
*/
text?: string;
trailingIcon?: HdsIconSignature['Args']['name'];
};
Blocks: {
Expand All @@ -42,41 +37,6 @@ export interface HdsDropdownListItemInteractiveSignature {
}

export default class HdsDropdownListItemInteractive extends Component<HdsDropdownListItemInteractiveSignature> {
constructor(
owner: Owner,
args: HdsDropdownListItemInteractiveSignature['Args']
) {
super(owner, args);

if (args.text !== undefined) {
deprecate(
'The `@text` argument for "Hds::Dropdown::ListItem::Interactive" has been deprecated. Please put text in the yielded block.',
false,
{
id: 'hds.dropdown.list-item.interactive',
until: '5.0.0',
url: 'https://helios.hashicorp.design/components/dropdown?tab=version%20history#4100',
for: '@hashicorp/design-system-components',
since: {
available: '4.10.0',
enabled: '5.0.0',
},
}
);
}
}

get text(): string {
const { text } = this.args;

assert(
'@text for "Hds::Dropdown::ListItem::Interactive" must have a valid value',
text !== undefined
);

return text;
}

get color(): HdsDropdownListItemInteractiveColors {
const { color = DEFAULT_COLOR } = this.args;

Expand Down
4 changes: 3 additions & 1 deletion showcase/app/components/mock/app/header/app-header.gts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ export default class MockAppHeaderAppHeader extends Component<MockAppHeaderAppHe
<dd.ToggleIcon @icon="user" @text="user menu" />
<dd.Title @text="Signed In" />
<dd.Description @text="email@domain.com" />
<dd.Interactive @href="#" @text="Account Settings" />
<dd.Interactive @href="#">
Account Settings
</dd.Interactive>
</HdsDropdown>
</:utilityActions>
</HdsAppHeader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ const SubSectionListItemNotInteractive: TemplateOnlyComponent = <template>
@text="A longer description that could span on multiple lines if the number of characters require more width than the dropdown provides by default."
/>
<HdsDropdownListItemSeparator />
<HdsDropdownListItemInteractive
@route="index"
@text="A longer item that could span multiple lines if the characters surpass a certain length"
/>
<HdsDropdownListItemInteractive @route="index">
A longer item that could span multiple lines if the characters
surpass a certain length
</HdsDropdownListItemInteractive>
</ul>
</div>
</SF.Item>
Expand All @@ -60,10 +60,10 @@ const SubSectionListItemNotInteractive: TemplateOnlyComponent = <template>
@text="A longer description that could span on multiple lines if the number of characters require more width than the dropdown provides by default."
/>
<HdsDropdownListItemSeparator />
<HdsDropdownListItemInteractive
@route="index"
@text="A longer item that could span multiple lines if the characters surpass a certain length"
/>
<HdsDropdownListItemInteractive @route="index">
A longer item that could span multiple lines if the characters
surpass a certain length
</HdsDropdownListItemInteractive>
</ul>
</div>
</SF.Item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module(

test('it should render the component as a <li> element with a CSS class that matches the component name', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @text="interactive" />`,
hbs`<Hds::Dropdown::ListItem::Interactive>interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert.dom('.hds-dropdown-list-item').hasTagName('li');
assert
Expand All @@ -35,19 +35,19 @@ module(

test('it should render the "list-item" with a button by default"', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @text="interactive" />`,
hbs`<Hds::Dropdown::ListItem::Interactive>interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert.dom('.hds-dropdown-list-item > button').exists();
});
test('it should render the "list-item" with a link if it has a @route parameter"', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @text="interactive" @route="index" />`,
hbs`<Hds::Dropdown::ListItem::Interactive @route="index">interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert.dom('.hds-dropdown-list-item > a').exists();
});
test('it should render the "list-item" with a link if it has a @href argument"', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @text="interactive" @href="#" />`,
hbs`<Hds::Dropdown::ListItem::Interactive @href="#">interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert.dom('.hds-dropdown-list-item > a').exists();
});
Expand All @@ -56,15 +56,15 @@ module(

test('it should render the "action" color as the default if no color is declared"', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @text="interactive" />`,
hbs`<Hds::Dropdown::ListItem::Interactive>interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert
.dom('.hds-dropdown-list-item')
.hasClass('hds-dropdown-list-item--color-action');
});
test('it should render the correct CSS color class if the @color prop is declared', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @color="critical" @text="interactive" @icon="trash" />`,
hbs`<Hds::Dropdown::ListItem::Interactive @color="critical" @icon="trash">interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert
.dom('.hds-dropdown-list-item')
Expand All @@ -75,32 +75,26 @@ module(

test('if an `@icon` is declared a leading icon should be rendered', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @icon="clipboard-copy" @text="interactive" />`,
hbs`<Hds::Dropdown::ListItem::Interactive @icon="clipboard-copy">interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert.dom('.hds-icon.hds-icon-clipboard-copy').exists();
});
test('if an `@trailingIcon` is declared a trailing icon should be rendered', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @trailingIcon="external-link" @text="interactive" />`,
hbs`<Hds::Dropdown::ListItem::Interactive @trailingIcon="external-link">interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert.dom('.hds-icon.hds-icon-external-link').exists();
});
test('if both an `@icon` and an `@trailingIcon` are declared both the leading and trailing icons should be rendered', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @icon="clipboard-copy" @trailingIcon="external-link" @text="interactive" />`,
hbs`<Hds::Dropdown::ListItem::Interactive @icon="clipboard-copy" @trailingIcon="external-link">interactive</Hds::Dropdown::ListItem::Interactive>`,
);
assert.dom('.hds-icon.hds-icon-clipboard-copy').exists();
assert.dom('.hds-icon.hds-icon-external-link').exists();
});

// CONTENT

test('it should render the text passed as @text prop', async function (assert) {
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @text="interactive text" />`,
);
assert.dom('.hds-dropdown-list-item').hasText('interactive text');
});
test('it should render the yielded content', async function (assert) {
await render(hbs`
<Hds::Dropdown::ListItem::Interactive>
Expand All @@ -109,29 +103,9 @@ module(
`);
assert.dom('.hds-dropdown-list-item').hasText('interactive');
});
test('it should render the text passed as @text prop if content is yielded', async function (assert) {
await render(hbs`
<Hds::Dropdown::ListItem::Interactive @text="erroneous">
interactive
</Hds::Dropdown::ListItem::Interactive>
`);
assert.dom('.hds-dropdown-list-item').doesNotContainText('erroneous');
});

// ASSERTIONS

test('it should throw an assertion if @text is missing/has no value and the component does not yield content', async function (assert) {
const errorMessage =
'@text for "Hds::Dropdown::ListItem::Interactive" must have a valid value';
assert.expect(2);
setupOnerror(function (error) {
assert.strictEqual(error.message, `Assertion Failed: ${errorMessage}`);
});
await render(hbs`<Hds::Dropdown::ListItem::Interactive />`);
assert.throws(function () {
throw new Error(errorMessage);
});
});
test('it should throw an assertion if an incorrect value for @color is provided', async function (assert) {
const errorMessage =
'@color for "Hds::Dropdown::ListItem::Interactive" must be one of the following: action, critical; received: foo';
Expand All @@ -140,7 +114,7 @@ module(
assert.strictEqual(error.message, `Assertion Failed: ${errorMessage}`);
});
await render(
hbs`<Hds::Dropdown::ListItem::Interactive @color="foo" @text="interactive text" />`,
hbs`<Hds::Dropdown::ListItem::Interactive @color="foo">interactive text</Hds::Dropdown::ListItem::Interactive>`,
);
assert.throws(function () {
throw new Error(errorMessage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,6 @@ It internally uses the [`Hds::Interactive`](/utilities/interactive) utility comp
<C.Property @name="<[I].Badge>" @type="yielded component">
The `Badge` component, yielded as contextual component inside `interactive` blocks of the `Dropdown`. It exposes the same API as the [`Badge` component](/components/badge).
</C.Property>
<C.Property @name="text" @required={{true}} @deprecated={{true}} @type="string">
Text to be used in the item. If no text value is defined and no content is yielded, an error will be thrown.
</C.Property>
<C.Property @name="color" @type="enum" @values={{array "action" "critical" }} @default="action">
Color applied to the text and (optional) icons.
</C.Property>
Expand Down