Skip to content

Commit

Permalink
fix: support keyboard in header buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianWielga committed Aug 14, 2024
1 parent e2973c6 commit 66755de
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
32 changes: 28 additions & 4 deletions src/components/window/header/HeaderButton.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { css, cx } from "@emotion/css";
import { useTheme } from "@emotion/react";
import React, { ButtonHTMLAttributes, DetailedHTMLProps, forwardRef } from "react";
import React, {
ButtonHTMLAttributes,
DetailedHTMLProps,
forwardRef,
KeyboardEvent,
KeyboardEventHandler,
PointerEventHandler,
} from "react";
import { buttonReset } from "../footer/ButtonReset";

export type HeaderButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
export type HeaderButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
action?: PointerEventHandler<HTMLButtonElement> & KeyboardEventHandler<HTMLButtonElement>;
};

const useStyles = () => {
const { colors } = useTheme();
Expand All @@ -25,10 +34,25 @@ const useStyles = () => {
});
};

function filterByKeys<T = Element>(action: KeyboardEventHandler<T>, keys: KeyboardEvent["key"][]): KeyboardEventHandler<T> {
return (e: KeyboardEvent<T>) => {
if (!keys.includes(e.key)) return;
return action(e);
};
}

export const HeaderButton = forwardRef(function HeaderButton(
{ className, ...props }: HeaderButtonProps,
{ className, action, ...props }: HeaderButtonProps,
ref: React.ForwardedRef<HTMLButtonElement>,
): JSX.Element {
const headerButtonTheme = useStyles();
return <button className={cx(buttonReset, headerButtonTheme, className)} {...props} ref={ref} />;
return (
<button
className={cx(buttonReset, headerButtonTheme, className)}
onPointerDown={action}
onKeyDown={filterByKeys(action, ["Enter", " "])}
{...props}
ref={ref}
/>
);
});
2 changes: 1 addition & 1 deletion src/components/window/header/HeaderButtonClose.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface HeaderButtonCloseProps {

export function HeaderButtonClose({ closeDialog }: HeaderButtonCloseProps): JSX.Element {
return (
<HeaderButton name="close" onPointerDown={() => closeDialog()}>
<HeaderButton name="close" action={() => closeDialog()}>
<CloseIcon />
</HeaderButton>
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/window/header/HeaderButtonZoom.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useRef, PointerEvent } from "react";
import React, { UIEvent, useCallback, useRef } from "react";
import { HeaderButton } from "./HeaderButton";
import RestoreIcon from "./restore.svg";
import ZoomIcon from "./zoom.svg";
Expand All @@ -11,8 +11,8 @@ export interface HeaderButtonZoomProps {

export function HeaderButtonZoom({ zoomDialog, isMaximized, keepFocus }: HeaderButtonZoomProps): JSX.Element {
const ref = useRef<HTMLButtonElement>();
const onPointerDown = useCallback(
(event: PointerEvent) => {
const action = useCallback(
(event: UIEvent) => {
event.preventDefault();

zoomDialog();
Expand All @@ -24,7 +24,7 @@ export function HeaderButtonZoom({ zoomDialog, isMaximized, keepFocus }: HeaderB
);

return (
<HeaderButton name="zoom" ref={ref} onPointerDown={onPointerDown}>
<HeaderButton name="zoom" ref={ref} action={action}>
{isMaximized ? <RestoreIcon /> : <ZoomIcon />}
</HeaderButton>
);
Expand Down

0 comments on commit 66755de

Please sign in to comment.