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
46 changes: 22 additions & 24 deletions packages/ui/src/MaskedInput.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,29 +136,29 @@ describe('MaskedInput — Digit Input', () => {
expect(input.getValue()).toBe('1');
});

it('letter keys are ignored', () => {
it('letter keys fill editable slots', () => {
const input = new MaskedInput({}, { mask: '__/__/____' });
press(input, 'a');
press(input, 'z');
expect(input.getValue()).toBe('__/__/____');
expect(input.getValue()).toBe('az/__/____');
});

it('minus sign is ignored', () => {
it('minus sign fills editable slots', () => {
const input = new MaskedInput({}, { mask: '__' });
press(input, '-');
expect(input.getValue()).toBe('__');
expect(input.getValue()).toBe('-_');
});

it('slash is ignored', () => {
it('slash fills editable slots', () => {
const input = new MaskedInput({}, { mask: '__' });
press(input, '/');
expect(input.getValue()).toBe('__');
expect(input.getValue()).toBe('/_');
});

it('space is ignored', () => {
it('space fills editable slots', () => {
const input = new MaskedInput({}, { mask: '__' });
press(input, ' ');
expect(input.getValue()).toBe('__');
expect(input.getValue()).toBe(' _');
});
});

Expand Down Expand Up @@ -338,27 +338,25 @@ describe('MaskedInput — onChange', () => {
expect(onChange).toHaveBeenCalledTimes(1);
});

it('does NOT fire for ignored letter key', () => {
it('fires for letter keys', () => {
const onChange = vi.fn();
const input = new MaskedInput({}, { mask: '__' }, onChange);
// Pass onChange via options
const input2 = new MaskedInput({}, { mask: '__', onChange });
press(input2, 'a');
expect(onChange).not.toHaveBeenCalled();
const input = new MaskedInput({}, { mask: '__', onChange });
press(input, 'a');
expect(onChange).toHaveBeenCalledWith('a_');
});

it('does NOT fire for minus', () => {
it('fires for minus', () => {
const onChange = vi.fn();
const input = new MaskedInput({}, { mask: '__', onChange });
press(input, '-');
expect(onChange).not.toHaveBeenCalled();
expect(onChange).toHaveBeenCalledWith('-_');
});

it('does NOT fire for space', () => {
it('fires for space', () => {
const onChange = vi.fn();
const input = new MaskedInput({}, { mask: '__', onChange });
press(input, ' ');
expect(onChange).not.toHaveBeenCalled();
expect(onChange).toHaveBeenCalledWith(' _');
});

it('does NOT fire for backspace at slot 0', () => {
Expand Down Expand Up @@ -630,13 +628,13 @@ describe('MaskedInput — markDirty()', () => {
expect(spy).toHaveBeenCalled();
});

it('markDirty NOT called for invalid/ignored input', () => {
it('markDirty called for non-digit slot input', () => {
const input = freshInput();
const spy = vi.spyOn(input as any, 'markDirty');
press(input, 'a');
press(input, '-');
press(input, ' ');
expect(spy).not.toHaveBeenCalled();
expect(spy).toHaveBeenCalledTimes(3);
});

it('markDirty NOT called for backspace at slot 0', () => {
Expand Down Expand Up @@ -894,13 +892,13 @@ describe('MaskedInput (original tests)', () => {
expect(onChange).toHaveBeenCalledWith('__/__/____');
});

it('ignores non-digit characters', () => {
it('accepts non-digit characters in editable slots', () => {
const input = new MaskedInput({}, { mask: '__/__/____' });

input.handleKey({ key: 'a', ctrl: false, alt: false } as any);
input.handleKey({ key: '-', ctrl: false, alt: false } as any);

expect(input.getValue()).toBe('__/__/____');
expect(input.getValue()).toBe('a-/__/____');
});

it('handles arrow keys for cursor navigation', () => {
Expand Down Expand Up @@ -953,12 +951,12 @@ describe('MaskedInput (original tests)', () => {
it('getValue returns correctly formatted string', () => {
const input = new MaskedInput({}, { mask: '__-__' });

input.handleKey({ key: 'a', ctrl: false, alt: false } as any); // ignored
input.handleKey({ key: 'a', ctrl: false, alt: false } as any);
input.handleKey({ key: '1', ctrl: false, alt: false } as any);
input.handleKey({ key: '2', ctrl: false, alt: false } as any);
input.handleKey({ key: '3', ctrl: false, alt: false } as any);

expect(input.getValue()).toBe('12-3_');
expect(input.getValue()).toBe('a1-23');
});

it('home key moves cursor to first slot', () => {
Expand Down
10 changes: 5 additions & 5 deletions packages/ui/src/MaskedInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ export class MaskedInput extends Widget {
}
}

/** Insert a digit character at the current slot. Auto-advance past filled chars. */
private _insertDigit(char: string): void {
if (!/^\d$/.test(char)) return; // Only accept digits
/** Insert a character at the current slot. Auto-advance past filled chars. */
private _insertChar(char: string): void {
if (char.length !== 1) return;
if (this._cursorSlotIndex >= this._slots.length) return; // Already at end

this._slots[this._cursorSlotIndex] = char;
Expand Down Expand Up @@ -161,9 +161,9 @@ export class MaskedInput extends Widget {
break;

default:
// Single character input (digits)
// Single character input
if (event.key?.length === 1) {
this._insertDigit(event.key);
this._insertChar(event.key);
}
break;
}
Expand Down
Loading