Skip to content
Open
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
27 changes: 18 additions & 9 deletions addon/components/o-s-s/password-input.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="fx-col fx-1 fx-gap-px-6">
<OSS::InputContainer @errorMessage={{this.errorMessage}} ...attributes>
<OSS::InputContainer @feedbackMessage={{@feedbackMessage}} @errorMessage={{this.errorMessage}} ...attributes>
<:input>
<Input
@value={{@value}}
Expand All @@ -14,22 +14,31 @@
{{#if @disabled}}
<OSS::Icon class="font-color-gray-500" @icon={{this.visibilityIcon}} />
{{else}}
<OSS::Button class="margin-px-6" @icon={{this.visibilityIcon}} @square={{true}}
{{on "click" this.toggleVisibility}} />
<OSS::Button
class="margin-px-6"
@icon={{this.visibilityIcon}}
@square={{true}}
{{on "click" this.toggleVisibility}}
/>
{{/if}}
</:suffix>
</OSS::InputContainer>
{{#if @validates}}
<div class="fx-row fx-gap-px-12" data-control-name="password-input-validators">
<div class="fx-row fx-gap-px-12 fx-wrap" data-control-name="password-input-validators">
{{#each this.inputValidators as |inputValidator|}}
{{#let (this.validatorAttributes type=inputValidator) as |validator|}}
<div class="password-input-validator fx-row fx-gap-px-6"
data-control-name="password-input-validator-{{inputValidator}}">
<div
class="password-input-validator fx-row fx-gap-px-6"
data-control-name="password-input-validator-{{inputValidator}}"
>
<div class="validator-icon-container">
{{#each this.validationIcons as |validationIcon|}}
<OSS::Icon @icon={{validationIcon.icon}}
class="validator-icon {{validator.iconClass}}
{{this.validationIconVisibility validator=validator state=validationIcon.state}}" />
<OSS::Icon
@icon={{validationIcon.icon}}
class="validator-icon
{{validator.iconClass}}
{{this.validationIconVisibility validator=validator state=validationIcon.state}}"
/>
{{/each}}
</div>
<span class={{validator.labelClass}}>{{t validator.labelKey}}</span>
Expand Down
10 changes: 10 additions & 0 deletions addon/components/o-s-s/password-input.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ export default {
},
control: { type: 'text' }
},
feedbackMessage: {
description: 'A success, warning or error message that will be displayed below the input-group.',
table: {
type: {
summary: '{ type: string, value: string }'
},
defaultValue: { summary: 'undefined' }
},
control: { type: 'object' }
},
disabled: {
description: 'Whether or not the input is disabled',
table: {
Expand Down
2 changes: 2 additions & 0 deletions addon/components/o-s-s/password-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Component from '@glimmer/component';
import { assert } from '@ember/debug';
import { isEmpty } from '@ember/utils';
import { helper } from '@ember/component/helper';
import type { FeedbackMessage } from './input-container';

export type ValidatorSet = Record<string, { labelKey: string; regex: RegExp }>;
export const INPUT_VALIDATORS: ValidatorSet = {
Expand All @@ -17,6 +18,7 @@ interface OSSPasswordInputArgs {
value: string | null;
placeholder?: string;
errorMessage?: string;
feedbackMessage?: FeedbackMessage;
disabled?: boolean;
validates?(isPassing: boolean): void;
validatorSet?: ValidatorSet;
Expand Down
25 changes: 25 additions & 0 deletions tests/integration/components/o-s-s/password-input-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,31 @@ module('Integration | Component | o-s-s/password-input', function (hooks) {
});
});

module('feedbackMessage', () => {
test('Passing an error @feedbackMessage displays the message and sets the border to red', async function (assert) {
await render(
hbs`<OSS::PasswordInput @value="" @feedbackMessage={{hash type="error" value="This is an error message"}} />`
);
assert.dom('.oss-input-container').hasClass('oss-input-container--error');
assert.dom('.font-color-error-500').hasText('This is an error message');
});

test('Passing a @feedbackMessage without a value only applies the container state class', async function (assert) {
await render(hbs`<OSS::PasswordInput @value="" @feedbackMessage={{hash type="success"}} />`);
assert.dom('.oss-input-container').hasClass('oss-input-container--success');
assert.dom('.font-color-success-500').doesNotExist();
});

test('@errorMessage takes precedence over @feedbackMessage', async function (assert) {
await render(
hbs`<OSS::PasswordInput @value="" @errorMessage="Error takes priority" @feedbackMessage={{hash type="success" value="Success message"}} />`
);
assert.dom('.oss-input-container').hasClass('oss-input-container--errored');
assert.dom('.text-color-error').hasText('Error takes priority');
assert.dom('.font-color-success-500').doesNotExist();
});
});

test('it throws an error when the @value parameter is missing', async function (assert) {
setupOnerror((err: any) => {
assert.equal(err.message, 'Assertion Failed: [component][OSS::PasswordInput] The @value parameter is mandatory');
Expand Down
Loading