[Retire] Rose::Form::Input (#2821)

* remove rose form input component folder

* remove component integration test

* remove _input styling and import ref

* remove import from addons

* remove app.scss form input styling

* replace form.input with Hds::Form::TextInput::Field

* remove assertions for disabled state, remove Hds replacement

* remove test that checks input field that no longer exists

* remove rose::form::input component from playgrouund.hbs

* remove @use 'input'
This commit is contained in:
Lauren authored and GitHub committed 2025-05-14 09:21:18 -04:00
1 parent d987f844de
commit 28ddec6898
13 files changed
+1 -384

No files matched your search

@@ -25,7 +25,6 @@
checkboxGroup=(component
'rose/form/checkbox/group' disabled=this.disabled
)
input=(component 'rose/form/input' disabled=this.disabled)
fieldset=(component 'rose/form/fieldset')
actions=(component
(if
@@ -1,70 +0,0 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
}}
{{#if @contextual}}
{{yield
(hash
label=(component 'rose/form/label' for=this.id error=@error)
helperText=(component
'rose/form/helper-text' id=(concat 'helper-text-' this.id) error=@error
)
field=(component
'rose/form/input/input'
id=this.id
name=@name
value=@value
type=@type
disabled=@disabled
error=@error
aria-describedby=(concat
(if @helperText (concat 'helper-text-' this.id))
(if @error (concat ' errors-' this.id))
)
)
errors=(component 'rose/form/errors' id=(concat 'errors-' this.id))
)
}}
{{else}}
<div class='rose-form-input'>
<Rose::Form::Label @for={{this.id}} @error={{@error}}>
{{@label}}
</Rose::Form::Label>
{{#if @helperText}}
<Rose::Form::HelperText
@id='helper-text-{{this.id}}'
@error={{@error}}
@link={{@link}}
@linkText={{@linkText}}
>
{{@helperText}}
</Rose::Form::HelperText>
{{/if}}
<div class='rose-input-wrapper'>
{{#if @icon}}
<Hds::Icon @name={{@icon}} @isInline={{true}} />
{{/if}}
<Rose::Form::Input::Input
...attributes
@id={{this.id}}
@name={{@name}}
@value={{@value}}
@type={{@type}}
@disabled={{@disabled}}
@error={{@error}}
@aria-describedby='{{if
@helperText
(concat "helper-text-" this.id)
}} {{if @error (concat "errors-" this.id)}}'
/>
</div>
{{yield
(hash errors=(component 'rose/form/errors' id=(concat 'errors-' this.id)))
}}
</div>
{{/if}}
@@ -1,13 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { generateComponentID } from '../../../../utilities/component-auto-id';
export default class RoseFormInputComponent extends Component {
// =attributes
id = generateComponentID();
}
@@ -1,16 +0,0 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
}}
{{! template-lint-disable no-builtin-form-components }}
<Input
...attributes
class='rose-form-input-field{{if @error " error"}}'
id={{@id}}
disabled={{@disabled}}
name={{@name}}
@type={{@type}}
@value={{@value}}
aria-describedby={{@aria-describedby}}
/>
@@ -1,6 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
export { default } from 'rose/components/rose/form/input';
@@ -1,6 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
export { default } from 'rose/components/rose/form/input/input';
@@ -6,7 +6,6 @@
@use 'label';
@use 'errors';
@use 'helper-text';
@use 'input';
@use 'checkbox';
@use 'select';
@use 'fieldset';
@@ -1,64 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@use '../../variables/sizing';
@use '../../utilities/type';
.rose-form-input {
margin-bottom: sizing.rems(m);
}
.rose-input-wrapper {
position: relative;
.rose-form-input-field {
padding-left: 30px;
}
}
.rose-form-input-field {
@include type.type(m);
display: inline-block;
box-sizing: border-box;
width: 100%;
margin-bottom: sizing.rems(xs);
padding: sizing.rems(xs);
color: var(--stark);
background-color: var(--subtle);
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2);
border-radius: sizing.rems(xxxs);
box-shadow: inset 0 3px 1px rgba(var(--stark-components), var(--opacity-4));
&::placeholder {
color: var(--ui-gray-subtler-1);
}
&.error {
color: var(--failure);
border-color: currentcolor;
}
&:not(:disabled, [readonly]) {
&:hover {
border-color: var(--ui-gray);
}
&:focus {
border-color: var(--info);
}
}
&:disabled {
cursor: not-allowed;
color: var(--ui-gray);
background-color: var(--ui-gray-subtler-6);
}
&[readonly] {
border-color: transparent;
box-shadow: none;
}
}
@@ -61,41 +61,6 @@
<item.key>Key</item.key>
<item.cell>Value</item.cell>
</list.item>
<Rose::Form::Input @contextual={{true}} as |input|>
<list.item as |item|>
<item.key>
<input.label>Key</input.label>
</item.key>
<item.cell>
<input.field />
</item.cell>
<item.cell>
<Rose::Button @style='secondary'>Add</Rose::Button>
</item.cell>
</list.item>
</Rose::Form::Input>
<Rose::Form::Input @contextual={{true}} as |input|>
<list.item as |item|>
<item.key>
<input.label>Key</input.label>
</item.key>
<item.cell>
<input.field />
</item.cell>
<item.cell>
<Rose::Button
@style='secondary'
@iconOnly='flight-icons/svg/trash-16'
title='Remove'
>
Remove
</Rose::Button>
</item.cell>
</list.item>
</Rose::Form::Input>
</Rose::List::KeyValue>
</layout.body>
@@ -33,7 +33,7 @@ module('Integration | Component | rose/form', function (hooks) {
await click('button:not([type="submit"])');
});
test('it can render contextual form components', async function (assert) {
test('it yields child form components', async function (assert) {
this.submit = () => {};
this.cancel = () => {};
this.select = () => {};
@@ -44,7 +44,6 @@ module('Integration | Component | rose/form', function (hooks) {
@disabled={{false}}
as |form|
>
<form.input @label="Input" @name="input-field" />
<Hds::Form::Textarea::Field
@value="This is my description"
name="textarea-field"
@@ -74,56 +73,11 @@ module('Integration | Component | rose/form', function (hooks) {
<form.checkbox @label="Checkbox" @name="checkbox-field" />
</Rose::Form>
`);
assert.ok(find('[name="input-field"]'));
assert.ok(find('[name="textarea-field"]'));
assert.ok(find('[name="select-field"]'));
assert.ok(find('[name="checkbox-field"]'));
});
test('it supports an editability toggle when @showEditToggle is true', async function (assert) {
assert.expect(12);
this.cancel = () => {
assert.ok(
true,
'cancel function may still be passed even for @showEditToggle',
);
};
this.submit = () => {};
await render(hbs`
<Rose::Form
@onSubmit={{this.submit}}
@cancel={{this.cancel}}
@showEditToggle={{true}}
as |form|
>
<form.input @label="Label" @value="value" />
<form.actions
@submitText="Save"
@cancelText="Cancel"
@enableEditText="Edit" />
</Rose::Form>
`);
// Before enabling edit mode, fields are disabled and the edit mode button is displayed
assert.ok(find('.rose-form'));
assert.strictEqual(findAll('input[disabled]').length, 1);
assert.strictEqual(findAll('button').length, 1);
assert.strictEqual(find('button').textContent.trim(), 'Edit');
// After entering edit mode, fields are enabled and save/cancel buttons are displayed
await click('button');
assert.strictEqual(findAll('input[disabled]').length, 0);
assert.strictEqual(findAll('button').length, 2);
assert.strictEqual(find('[type="submit"]').textContent.trim(), 'Save');
assert.strictEqual(
find('button:not([type="submit"])').textContent.trim(),
'Cancel',
);
// After canceling, fields are disabled again and the edit mode button is displayed
await click('button:not([type="submit"])');
assert.strictEqual(findAll('input[disabled]').length, 1);
assert.strictEqual(findAll('button').length, 1);
assert.strictEqual(find('button').textContent.trim(), 'Edit');
});
test('it re-enables read-only mode if the submit handler returns a resolving promise', async function (assert) {
this.cancel = () => {};
await render(hbs`
@@ -133,7 +87,6 @@ module('Integration | Component | rose/form', function (hooks) {
@showEditToggle={{true}}
as |form|
>
<form.input @label="Label" @value="value" />
<form.actions
@submitText="Save"
@cancelText="Cancel"
@@ -142,12 +95,10 @@ module('Integration | Component | rose/form', function (hooks) {
`);
// Before enabling edit mode, fields are disabled and the edit mode button is displayed
assert.ok(find('.rose-form'));
assert.strictEqual(findAll('input[disabled]').length, 1);
assert.strictEqual(findAll('button').length, 1);
assert.strictEqual(find('button').textContent.trim(), 'Edit');
// After entering edit mode, fields are enabled and save/cancel buttons are displayed
await click('button');
assert.strictEqual(findAll('input[disabled]').length, 0);
assert.strictEqual(findAll('button').length, 2);
assert.strictEqual(find('[type="submit"]').textContent.trim(), 'Save');
assert.strictEqual(
@@ -156,7 +107,6 @@ module('Integration | Component | rose/form', function (hooks) {
);
// After saving with failure, fields are enabled and save/cancel buttons are displayed
this.submit = () => reject();
assert.strictEqual(findAll('input[disabled]').length, 0);
assert.strictEqual(findAll('button').length, 2);
assert.strictEqual(find('[type="submit"]').textContent.trim(), 'Save');
assert.strictEqual(
@@ -166,7 +116,6 @@ module('Integration | Component | rose/form', function (hooks) {
// After saving with success, fields are disabled again and the edit mode button is displayed
this.submit = () => resolve();
await click('button[type="submit"]');
assert.strictEqual(findAll('input[disabled]').length, 1);
assert.strictEqual(findAll('button').length, 1);
assert.strictEqual(find('button').textContent.trim(), 'Edit');
});
@@ -1,104 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | rose/form/input', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Rose::Form::Input @value="Text" @label="Label" />`);
assert.strictEqual(await find('label').textContent.trim(), 'Label');
assert.strictEqual(await find('input').value, 'Text');
});
test('it displays optional helper text', async function (assert) {
await render(hbs`<Rose::Form::Input @helperText="Help me" />`);
const fieldEl = find('input');
const id = fieldEl.id;
const helperId = `helper-text-${id}`;
const helperTextEl = find('.rose-form-helper-text');
assert.strictEqual(helperTextEl.textContent.trim(), 'Help me');
assert.strictEqual(helperTextEl.id, helperId);
assert.strictEqual(
fieldEl.getAttribute('aria-describedby').trim(),
helperId,
);
});
test('it displays optional errors', async function (assert) {
await render(hbs`
<Rose::Form::Input @error={{true}} as |field|>
<field.errors as |errors|>
<errors.message>An error occurred.</errors.message>
</field.errors>
</Rose::Form::Input>
`);
const fieldEl = find('input');
const id = fieldEl.id;
const errorsId = `errors-${id}`;
const errorMessageEl = find('.rose-form-errors');
assert.strictEqual(errorMessageEl.id, errorsId);
assert.strictEqual(errorMessageEl.textContent.trim(), 'An error occurred.');
assert.strictEqual(
fieldEl.getAttribute('aria-describedby').split(' ')[1],
errorsId,
);
});
test('it is type="text" by default', async function (assert) {
await render(hbs`<Rose::Form::Input />`);
assert.strictEqual(await find('input').type, 'text');
});
test('it supports a @type attribute', async function (assert) {
await render(hbs`<Rose::Form::Input @type="password" />`);
assert.strictEqual(await find('input').type, 'password');
});
test('it supports disabled attribute', async function (assert) {
await render(hbs`<Rose::Form::Input @disabled={{true}} />`);
assert.ok(await find('[disabled]'));
});
test('it supports an icon using @icon', async function (assert) {
await render(hbs`<Rose::Form::Input @icon="search" />`);
assert.dom('.hds-icon').isVisible();
});
test('it supports readonly attribute', async function (assert) {
await render(hbs`<Rose::Form::Input readonly={{true}} />`);
assert.ok(await find('[readonly]'));
});
test('it gets an `error` class when @error=true', async function (assert) {
await render(hbs`<Rose::Form::Input @error={{true}} />`);
assert.ok(await find('.error'));
});
test('it supports a fully contextual usage', async function (assert) {
await render(hbs`
<Rose::Form::Input @value="Text" @error={{true}} @contextual={{true}} as |field|>
<field.label>Label</field.label>
<field.helperText>Help</field.helperText>
<field.field />
<field.errors as |errors|>
<errors.message>An error occurred.</errors.message>
</field.errors>
</Rose::Form::Input>
`);
assert.notOk(
find('.rose-form-input'),
'The form field wrapper element is not present in contextual mode',
);
assert.ok(find('.rose-form-label.error'));
assert.ok(find('.rose-form-helper-text.error'));
assert.ok(find('.rose-form-input-field.error'));
assert.ok(find('.rose-form-error-message'));
});
});
-8
View File
@@ -48,14 +48,6 @@
width: 66%;
}
.rose-form-input {
width: 100%;
.rose-form-input-field {
width: 100%;
}
}
.rose-dropdown {
$icon-width: sizing.rems(m) + sizing.rems(s);
$indent: $icon-width + sizing.rems(xs);
-8
View File
@@ -69,14 +69,6 @@
width: 66%;
}
.rose-form-input {
width: 100%;
.rose-form-input-field {
width: 100%;
}
}
.rose-dropdown {
$icon-width: sizing.rems(m) + sizing.rems(s);
$indent: $icon-width + sizing.rems(xs);