Skip to content

Commit

Permalink
feat(Input): Added secure input functionality for typing passwords (#201
Browse files Browse the repository at this point in the history
)

* perf(Input): Use substring to remove last character

* feat(Input): Added secure input functionality for typing passwords

* chore: Updated input stories

* chore: Secure fallback value

---------

Co-authored-by: Dmytro Soldatov <[email protected]>
  • Loading branch information
CatchABus and CyberDex authored Nov 27, 2024
1 parent 8321d0f commit f0c3a99
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 50 deletions.
35 changes: 28 additions & 7 deletions src/Input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@ export type InputOptions = {
placeholder?: string;
value?: string;
maxLength?: number;
secure?: boolean;
align?: 'left' | 'center' | 'right';
padding?: Padding;
cleanOnFocus?: boolean;
nineSliceSprite?: [number, number, number, number];
addMask?: boolean;
};

const SECURE_CHARACTER = '*';

/**
* Container-based component that creates an input to read the user's text.
* @example
Expand All @@ -52,6 +55,8 @@ export class Input extends Container {
protected _bg?: Container | NineSliceSprite | Graphics;
protected inputMask: Container | NineSliceSprite | Graphics;
protected _cursor: Sprite;
protected _value: string = '';
protected _secure: boolean;
protected inputField: PixiText;
protected placeholder: PixiText;
protected editing = false;
Expand Down Expand Up @@ -109,6 +114,7 @@ export class Input extends Container {

this.options = options;
this.padding = options.padding;
this._secure = options.secure ?? false;

this.cursor = 'text';
this.interactive = true;
Expand Down Expand Up @@ -287,11 +293,11 @@ export class Input extends Container {
}

protected _delete(): void {
if (!this.editing || this.value.length === 0) return;
const array = this.value.split('');
const length = this.value.length;

if (!this.editing || length === 0) return;

array.pop();
this.value = array.join('');
this.value = this.value.substring(0, length - 1);

this.onChange.emit(this.value);
}
Expand Down Expand Up @@ -453,9 +459,13 @@ export class Input extends Container {

/** Sets the input text. */
set value(text: string) {
this.inputField.text = text;
const textLength = text.length;

if (text.length !== 0) {
this._value = text;
this.inputField.text = this.secure ? SECURE_CHARACTER.repeat(textLength) : text;

if (textLength !== 0)
{
this.placeholder.visible = false;
} else {
this.placeholder.visible = !this.editing;
Expand All @@ -466,7 +476,18 @@ export class Input extends Container {

/** Return text of the input. */
get value(): string {
return this.inputField.text;
return this._value;
}

set secure(val: boolean) {
this._secure = val;

// Update text based on secure state (useful for show/hide password implementations)
this.value = this._value;
}

get secure(): boolean {
return this._secure;
}

/**
Expand Down
50 changes: 25 additions & 25 deletions src/stories/input/InputGraphics.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { action } from '@storybook/addon-actions';
const args = {
text: '',
placeholder: 'Enter text',
secure: false,
align: ['center', 'left', 'right'],
textColor: '#000000',
backgroundColor: '#F1D583',
Expand All @@ -29,31 +30,29 @@ const args = {
onChange: action('Change'),
};

export const UseGraphics: StoryFn<typeof args & { align: 'center' | 'left' | 'right' }> = (
{
text,
amount,
border,
textColor,
fontSize,
backgroundColor,
borderColor,
width,
height,
radius,
maxLength,
align,
placeholder,
paddingTop,
paddingRight,
paddingBottom,
paddingLeft,
onChange,
cleanOnFocus,
addMask,
},
context,
) =>
export const UseGraphics: StoryFn<typeof args & { align: 'center' | 'left' | 'right' }> = ({
text,
amount,
border,
textColor,
fontSize,
backgroundColor,
borderColor,
width,
height,
radius,
maxLength,
align,
placeholder,
secure,
paddingTop,
paddingRight,
paddingBottom,
paddingLeft,
onChange,
cleanOnFocus,
addMask
}, context) =>
new PixiStory<typeof args>({
context,
init: (view) => {
Expand All @@ -75,6 +74,7 @@ export const UseGraphics: StoryFn<typeof args & { align: 'center' | 'left' | 'ri
maxLength,
align,
placeholder,
secure,
value: text,
padding: [paddingTop, paddingRight, paddingBottom, paddingLeft],
cleanOnFocus,
Expand Down
3 changes: 3 additions & 0 deletions src/stories/input/InputNineSliceSprite.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { action } from '@storybook/addon-actions';
const args = {
text: '',
placeholder: 'Enter text',
secure: false,
align: ['center', 'left', 'right'],
textColor: '#000000',
maxLength: 20,
Expand Down Expand Up @@ -37,6 +38,7 @@ export const UseNineSliceSprite: StoryFn<typeof args & { align: 'center' | 'left
maxLength,
align,
placeholder,
secure,
width,
height,
addMask,
Expand Down Expand Up @@ -66,6 +68,7 @@ export const UseNineSliceSprite: StoryFn<typeof args & { align: 'center' | 'left
maxLength,
align,
placeholder,
secure,
value: text,
addMask,
});
Expand Down
36 changes: 18 additions & 18 deletions src/stories/input/InputSprite.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { action } from '@storybook/addon-actions';
const args = {
text: '',
placeholder: 'Enter text',
secure: false,
align: ['center', 'left', 'right'],
textColor: '#000000',
maxLength: 20,
Expand All @@ -24,24 +25,22 @@ const args = {
onChange: action('Input'),
};

export const UseSprite: StoryFn<typeof args & { align: 'center' | 'left' | 'right' }> = (
{
text,
amount,
paddingTop,
paddingRight,
paddingBottom,
paddingLeft,
textColor,
fontSize,
maxLength,
align,
placeholder,
addMask,
onChange,
},
context,
) =>
export const UseSprite: StoryFn<typeof args & { align: 'center' | 'left' | 'right' }> = ({
text,
amount,
paddingTop,
paddingRight,
paddingBottom,
paddingLeft,
textColor,
fontSize,
maxLength,
align,
placeholder,
secure,
addMask,
onChange
}, context) =>
new PixiStory({
context,
init: (view) => {
Expand All @@ -63,6 +62,7 @@ export const UseSprite: StoryFn<typeof args & { align: 'center' | 'left' | 'righ
maxLength,
align,
placeholder,
secure,
value: text,
addMask,
});
Expand Down

0 comments on commit f0c3a99

Please sign in to comment.