Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#1398): Add keyPress event for input #1456

Merged
merged 1 commit into from
Dec 4, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ <h2>Focus</h2>
(_blur)="onBlurEvent($event)"
></goa-input>

<h2>Key Press</h2>
<goa-input name="foo" (_keyPress)="onKeyPressEvent($event)"></goa-input>

<h2>Prefix and Suffix</h2>
<goa-input name="input" prefix="$"></goa-input>
<goa-input name="input" suffix="items"></goa-input>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
}
}

updateInput(event: any) {

Check warning on line 53 in apps/angular-demo/src/app/input-component/input-component.component.ts

View workflow job for this annotation

GitHub Actions / build

Unexpected any. Specify a different type
this.wcVal = event.detail.value;
}

Expand All @@ -60,18 +60,22 @@
return d;
}

onInputChangeEvent(event: any) {

Check warning on line 63 in apps/angular-demo/src/app/input-component/input-component.component.ts

View workflow job for this annotation

GitHub Actions / build

Unexpected any. Specify a different type
console.log("onEvent", event.detail);
}

onFocusEvent(event: any) {

Check warning on line 67 in apps/angular-demo/src/app/input-component/input-component.component.ts

View workflow job for this annotation

GitHub Actions / build

Unexpected any. Specify a different type
console.log("on Focus Event: ", event.detail);
}

onBlurEvent(event: any) {

Check warning on line 71 in apps/angular-demo/src/app/input-component/input-component.component.ts

View workflow job for this annotation

GitHub Actions / build

Unexpected any. Specify a different type
console.log("on Blur Event: ", event.detail);
}

onKeyPressEvent(event: any) {
console.log("on Key Press Event: ", event.detail);
}

setDate(event: any) {
const raw = event.detail.value;
if (!raw) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,10 @@ <h2>Reactive Binding - Disabled</h2>
[formControl]="reactiveFormCtrl"
[attr.disabled]="true"
></goa-textarea>

<h2>On Key Press</h2>
<goa-textarea
name="comment-basic"
(_keyPress)="onKeyPress($event)"
value="Initial value"
></goa-textarea>
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ export class TextAreaComponent {
boundVal = "";
reactiveFormCtrl = new FormControl();

constructor() {}
constructor() { }

onChange(e: any) {
console.log("changed", e.detail.name, e.detail.value);
}

onKeyPress(e: any) {
console.log("changed", e.detail.name, e.detail.value, e.detail.key);
}
}
14 changes: 14 additions & 0 deletions apps/react-demo/src/routes/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export default function Input() {
console.log("onBlur -> Name :: Value ===", _name, " :: ", value);
}

function onKeyPressEvent(_name: string, value: string, key: string) {
console.log("onKeyPress -> Name :: Value :: Key ===", _name, " :: ", value, " :: ", key);
}

return (
<>
<h4>Date with a min and max and Date values</h4>
Expand Down Expand Up @@ -121,6 +125,16 @@ export default function Input() {
onBlur={onBlurChange}
/>


<h2>Key Press</h2>
<GoAInput
name=""
value=""
onChange={noop}
type="text"
onKeyPress={onKeyPressEvent}
/>

<h2>Prefix and Suffix</h2>
<GoAInput name="input" value="" prefix="$" onChange={noop} />
<GoAInput name="input" value="" suffix="items" onChange={noop} />
Expand Down
14 changes: 14 additions & 0 deletions apps/react-demo/src/routes/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export default function TextArea() {
console.log(name, value);
}

function onKeyPress(name: string, value: string, key: string) {
setValue(value);
console.log(name, value, key);
}

function onChange4(name: string, value: string) {
setValue4(value);
console.log(name, value);
Expand Down Expand Up @@ -95,6 +100,15 @@ export default function TextArea() {
ml="xl"
mr="2xl"
/>

<h2>on Key Press</h2>
<GoATextArea
rows={4}
name="comment"
value={value6}
onChange={onChange6}
onKeyPress={onKeyPress}
/>
</>
);
}
12 changes: 12 additions & 0 deletions libs/docs/src/components/common/Input.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,18 @@ import { Meta, Story } from "@storybook/addon-docs";
type="() => void"
description="Function invoked when an element loses focus"
/>
<Prop
name="onKeyPress"
lang="react"
type="(name: string, value: string | Date | number, key: string) => void"
description="Function invoked when a key is pressed within an input element"
/>
<Prop
name="_keyPress"
lang="angular"
type="() => void"
description="Function invoked when a key is pressed within an input element"
/>
</Props>

<details>
Expand Down
18 changes: 18 additions & 0 deletions libs/docs/src/components/common/TextArea.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,24 @@ import { GoATextArea } from "@abgov/react-components";
type="(name: string, value: string) => void"
description="Event triggered on each input value change"
/>
<Prop
name="onKeyPress"
lang="react"
type="(name: string, value: string, key:string) => void"
description="Event triggered on each key press"
/>
<Prop
name="_change"
lang="angular"
type="() => void"
description="Event triggered on each input value change"
/>
<Prop
name="_keyPress"
lang="angular"
type="() => void"
description="Event triggered on each key press"
/>
</Props>

<details>
Expand Down
58 changes: 32 additions & 26 deletions libs/react-components/src/lib/input/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,46 +93,40 @@ interface BaseProps extends Margins {
maxLength?: number;
}

type OnChange = (name: string, value: string) => void;
type OnFocus = (name: string, value: string) => void;
type OnBlur = (name: string, value: string) => void;
type OnChange<T = string> = (name: string, value: T) => void;
type OnFocus<T = string> = (name: string, value: T) => void;
type OnBlur<T = string> = (name: string, value: T) => void;
type OnKeyPress<T = string> = (name: string, value: T, key: string) => void;
export interface GoAInputProps extends BaseProps {
onChange: OnChange;
onChange: OnChange<string>;
value: string;
min?: number | string;
max?: number | string;
step?: number;
onFocus?: OnFocus;
onBlur?: OnBlur;
onFocus?: OnFocus<string>;
onBlur?: OnBlur<string>;
onKeyPress?: OnKeyPress<string>;
}

// legacy
export type InputProps = GoAInputProps;

type OnNumberChange = (name: string, value: number) => void;
type OnNumberFocus = (name: string, value: number) => void;
type OnNumberBlur = (name: string, value: number) => void;
export interface GoANumberInputProps extends BaseProps {
onChange: OnNumberChange;
interface GoANumberInputProps extends BaseProps {
onChange: OnChange<number>;
value: number;
min?: number;
max?: number;
step?: number;
onFocus?: OnNumberFocus;
onBlur?: OnNumberBlur;
onFocus?: OnFocus<number>;
onBlur?: OnBlur<number>;
onKeyPress?: OnKeyPress<number>;
}

type OnDateChange = (name: string, value: GoADate) => void;
type OnDateFocus = (name: string, value: GoADate) => void;
type OnDateBlur = (name: string, value: GoADate) => void;
export interface GoADateInputProps extends BaseProps {
onChange: OnDateChange;
interface GoADateInputProps extends BaseProps {
onChange: OnChange<GoADate>;
value: GoADate;
min?: GoADate;
max?: GoADate;
step?: number;
onFocus?: OnDateFocus;
onBlur?: OnDateBlur;
onFocus?: OnFocus<GoADate>;
onBlur?: OnBlur<GoADate>;
onKeyPress?: OnKeyPress<GoADate>;
}

export function GoAInput({
Expand Down Expand Up @@ -169,6 +163,7 @@ export function GoAInput({
onChange,
onFocus,
onBlur,
onKeyPress,
}: GoAInputProps & { type?: GoAInputType }): JSX.Element {
const ref = useRef<HTMLInputElement>(null);
useEffect(() => {
Expand All @@ -194,17 +189,24 @@ export function GoAInput({
onBlur?.(name, value);
};

const keypressListener = (e: unknown) => {
const { name, value, key } = (e as CustomEvent).detail;
onKeyPress?.(name, value, key);
}

current.addEventListener("_change", changeListener);
current.addEventListener("_trailingIconClick", clickListener);
current.addEventListener("_focus", focusListener);
current.addEventListener("_blur", blurListener);
current.addEventListener("_keyPress", keypressListener);
return () => {
current.removeEventListener("_change", changeListener);
current.removeEventListener("_trailingIconClick", clickListener);
current.removeEventListener("_focus", focusListener);
current.removeEventListener("_blur", blurListener);
current.removeEventListener("_keyPress", keypressListener);
};
}, [ref, onChange, onTrailingIconClick, onFocus, onBlur]);
}, [ref, onChange, onTrailingIconClick, onFocus, onBlur, onKeyPress]);

return (
<goa-input
Expand Down Expand Up @@ -244,7 +246,7 @@ export function GoAInput({
);
};

const onDateChangeHandler = (onChange: OnDateChange) => {
const onDateChangeHandler = (onChange: OnChange<GoADate>) => {
return (name: string, value: string) => {

if (!value) {
Expand Down Expand Up @@ -385,6 +387,9 @@ export function GoAInputNumber({
const onBlur = (name: string, value: string) => {
props.onBlur?.(name, parseInt(value));
};
const onKeyPress = (name: string, value: string, key: string) => {
props.onKeyPress?.(name, parseInt(value), key);
};
return (
<GoAInput
{...props}
Expand All @@ -395,6 +400,7 @@ export function GoAInputNumber({
onFocus={onFocus}
onBlur={onBlur}
type="number"
onKeyPress={onKeyPress}
/>
);
};
Expand Down
9 changes: 9 additions & 0 deletions libs/react-components/src/lib/textarea/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface GoATextAreaProps extends Margins {
testId?: string;
ariaLabel?: string;
onChange: (name: string, value: string) => void;
onKeyPress?: (name: string, value: string, key: string) => void;
}

export function GoATextArea({
Expand All @@ -57,6 +58,7 @@ export function GoATextArea({
mb,
ml,
onChange,
onKeyPress,
}: GoATextAreaProps): JSX.Element {
const el = useRef<HTMLTextAreaElement>(null);

Expand All @@ -70,9 +72,16 @@ export function GoATextArea({
onChange(name, value);
};

const keypressListener = (e: unknown) => {
const { name, value, key } = (e as CustomEvent).detail;
onKeyPress?.(name, value, key);
}

current.addEventListener("_change", listener);
current.addEventListener("_keyPress", keypressListener);
return () => {
current.removeEventListener("_change", listener);
current.removeEventListener("_keyPress", listener);
};
}, [el, onChange]);

Expand Down
11 changes: 10 additions & 1 deletion libs/web-components/src/components/input/Input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,25 @@ describe("GoAInput Component", () => {
});
const input = await findByTestId("input-test");
const change = jest.fn();
const keypress = jest.fn();

input.addEventListener("_change", (e: CustomEvent) => {
expect(e.detail.name).toBe("test-name");
expect(e.detail.value).toBe("foobar");
change();
});

await fireEvent.keyUp(input, { target: { value: "foobar" } });
input.addEventListener("_keyPress", (e: CustomEvent) => {
expect(e.detail.name).toBe("test-name");
expect(e.detail.value).toBe("foobar");
expect(e.detail.key).toBe("r");
keypress();
});

await fireEvent.keyUp(input, { target: { value: "foobar" }, key: 'r' });
await waitFor(() => {
expect(change).toBeCalledTimes(1);
expect(keypress).toBeCalledTimes(1);
});
});

Expand Down
6 changes: 6 additions & 0 deletions libs/web-components/src/components/input/Input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@
);
}, debounce);

input.dispatchEvent(
new CustomEvent("_keyPress", {
composed: true,
detail: { name, value: input.value, key: (e as KeyboardEvent).key }
}),
);
value = input.value;
}

Expand Down
23 changes: 23 additions & 0 deletions libs/web-components/src/components/text-area/TextArea.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,29 @@ describe("GoATextArea", () => {
})
})

it("handles the keypress event", async () => {
const onKeyPress = jest.fn();
const result = render(GoATextArea, {
name: "name",
value: "foo",
testid: "keypress",
});

const textarea = result.queryByTestId("keypress");
textarea.addEventListener("_keyPress", (e: CustomEvent) => {
expect(e.detail.name).toBe("name");
expect(e.detail.value).toBe("foo");
expect(e.detail.key).toBe("o");
onKeyPress();
});

await fireEvent.keyUp(textarea, { target: { value: 'foo' }, key: "o" });

await waitFor(() => {
expect(onKeyPress).toBeCalledTimes(1);
})
})

it("can be disabled", async () => {
const onChange = jest.fn();
const result = render(GoATextArea, {
Expand Down
Loading
Loading