diff --git a/packages/ui/src/components/banner/banner.tsx b/packages/ui/src/components/banner/banner.tsx index bf7909b1c..570dde959 100644 --- a/packages/ui/src/components/banner/banner.tsx +++ b/packages/ui/src/components/banner/banner.tsx @@ -1,7 +1,7 @@ import { ComponentChildren, h, JSX } from 'preact' -import { Props } from '../../types/types.js' import { createClassName } from '../../utilities/create-class-name.js' +import { createComponent } from '../../utilities/create-component.js' import styles from './banner.module.css' export type BannerProps = { @@ -11,15 +11,14 @@ export type BannerProps = { } export type BannerVariant = 'success' | 'warning' -export function Banner({ - children, - icon, - variant, - ...rest -}: Props): JSX.Element { +export const Banner = createComponent(function ( + { children, icon, variant, ...rest }, + ref +): JSX.Element { return (
{children}
) -} +}) diff --git a/packages/ui/src/components/button/button.tsx b/packages/ui/src/components/button/button.tsx index d5a8ad53e..fb8ecc85e 100644 --- a/packages/ui/src/components/button/button.tsx +++ b/packages/ui/src/components/button/button.tsx @@ -1,44 +1,55 @@ import { ComponentChildren, h, JSX } from 'preact' import { useCallback } from 'preact/hooks' -import { Props } from '../../types/types.js' +import { Event, EventHandler } from '../../types/event-handler.js' +import { FocusableComponentProps } from '../../types/focusable-component-props.js' import { createClassName } from '../../utilities/create-class-name.js' +import { createComponent } from '../../utilities/create-component.js' +import { noop } from '../../utilities/no-op.js' import { LoadingIndicator } from '../loading-indicator/loading-indicator.js' import styles from './button.module.css' -export type ButtonProps = { +export interface ButtonProps + extends FocusableComponentProps { children: ComponentChildren danger?: boolean disabled?: boolean fullWidth?: boolean loading?: boolean - onClick?: JSX.MouseEventHandler - propagateEscapeKeyDown?: boolean + onClick?: EventHandler.onClick secondary?: boolean } -export function Button({ - children, - danger = false, - disabled = false, - fullWidth = false, - loading = false, - onClick, - propagateEscapeKeyDown = true, - secondary = false, - ...rest -}: Props): JSX.Element { +export const Button = createComponent(function ( + { + blurOnEscapeKeyDown = true, + children, + danger = false, + disabled = false, + fullWidth = false, + loading = false, + onClick = noop, + onKeyDown = noop, + propagateEscapeKeyDown = true, + secondary = false, + ...rest + }, + ref +): JSX.Element { const handleKeyDown = useCallback( - function (event: JSX.TargetedKeyboardEvent): void { + function (event: Event.onKeyDown): void { + onKeyDown(event) if (event.key !== 'Escape') { return } if (propagateEscapeKeyDown === false) { event.stopPropagation() } - event.currentTarget.blur() + if (blurOnEscapeKeyDown === true) { + event.currentTarget.blur() + } }, - [propagateEscapeKeyDown] + [blurOnEscapeKeyDown, onKeyDown, propagateEscapeKeyDown] ) return ( @@ -59,15 +70,16 @@ export function Button({ ) : null} ) -} +}) diff --git a/packages/ui/src/components/button/stories/button-danger.stories.tsx b/packages/ui/src/components/button/stories/button-danger.stories.tsx index 569c925ec..6f081a85c 100644 --- a/packages/ui/src/components/button/stories/button-danger.stories.tsx +++ b/packages/ui/src/components/button/stories/button-danger.stories.tsx @@ -105,3 +105,11 @@ export const FullWidthLongText = function () { FullWidthLongText.parameters = { fixedWidth: true } + +export const BlurOnEscapeKeyDown = function () { + return ( + + ) +} diff --git a/packages/ui/src/components/button/stories/button-default.stories.tsx b/packages/ui/src/components/button/stories/button-default.stories.tsx index 6816a4074..66896cd33 100644 --- a/packages/ui/src/components/button/stories/button-default.stories.tsx +++ b/packages/ui/src/components/button/stories/button-default.stories.tsx @@ -101,3 +101,7 @@ export const FullWidthLongText = function () { FullWidthLongText.parameters = { fixedWidth: true } + +export const BlurOnEscapeKeyDown = function () { + return +} diff --git a/packages/ui/src/components/button/stories/button-secondary-danger.stories.tsx b/packages/ui/src/components/button/stories/button-secondary-danger.stories.tsx index 31b9f19c3..c155a18cb 100644 --- a/packages/ui/src/components/button/stories/button-secondary-danger.stories.tsx +++ b/packages/ui/src/components/button/stories/button-secondary-danger.stories.tsx @@ -111,3 +111,11 @@ export const FullWidthLongText = function () { FullWidthLongText.parameters = { fixedWidth: true } + +export const BlurOnEscapeKeyDown = function () { + return ( + + ) +} diff --git a/packages/ui/src/components/button/stories/button-secondary.stories.tsx b/packages/ui/src/components/button/stories/button-secondary.stories.tsx index 56d267192..bae98de6d 100644 --- a/packages/ui/src/components/button/stories/button-secondary.stories.tsx +++ b/packages/ui/src/components/button/stories/button-secondary.stories.tsx @@ -105,3 +105,11 @@ export const FullWidthLongText = function () { FullWidthLongText.parameters = { fixedWidth: true } + +export const BlurOnEscapeKeyDown = function () { + return ( + + ) +} diff --git a/packages/ui/src/components/checkbox/checkbox.tsx b/packages/ui/src/components/checkbox/checkbox.tsx index 4349cee5c..75381e60a 100644 --- a/packages/ui/src/components/checkbox/checkbox.tsx +++ b/packages/ui/src/components/checkbox/checkbox.tsx @@ -2,79 +2,90 @@ import { ComponentChildren, h, JSX } from 'preact' import { useCallback } from 'preact/hooks' import { IconControlCheckboxChecked12 } from '../../icons/icon-12/icon-control-checkbox-checked-12.js' -import { OnValueChange, Props } from '../../types/types.js' +import { Event, EventHandler } from '../../types/event-handler.js' +import { FocusableComponentProps } from '../../types/focusable-component-props.js' import { createClassName } from '../../utilities/create-class-name.js' +import { createComponent } from '../../utilities/create-component.js' +import { noop } from '../../utilities/no-op.js' import styles from './checkbox.module.css' -export type CheckboxProps = { +export interface CheckboxProps + extends FocusableComponentProps { children: ComponentChildren disabled?: boolean - name?: Name - onChange?: OmitThisParameter> - onValueChange?: OnValueChange - propagateEscapeKeyDown?: boolean + onChange?: EventHandler.onChange + onValueChange?: EventHandler.onValueChange value: boolean } -export function Checkbox({ - children, - disabled = false, - name, - onChange = function () {}, - onValueChange = function () {}, - propagateEscapeKeyDown = true, - value = false, - ...rest -}: Props>): JSX.Element { - const handleChange = useCallback( - function (event: JSX.TargetedEvent): void { - const newValue = event.currentTarget.checked - onValueChange(newValue, name) - onChange(event) +export const Checkbox = createComponent( + function ( + { + blurOnEscapeKeyDown = true, + children, + disabled = false, + onChange = noop, + onKeyDown = noop, + onValueChange = noop, + propagateEscapeKeyDown = true, + value, + ...rest }, - [name, onChange, onValueChange] - ) + ref + ): JSX.Element { + const handleChange = useCallback( + function (event: Event.onChange): void { + const newValue = event.currentTarget.checked + onValueChange(newValue) + onChange(event) + }, + [onChange, onValueChange] + ) - const handleKeyDown = useCallback( - function (event: JSX.TargetedKeyboardEvent): void { - if (event.key !== 'Escape') { - return - } - if (propagateEscapeKeyDown === false) { - event.stopPropagation() - } - event.currentTarget.blur() - }, - [propagateEscapeKeyDown] - ) + const handleKeyDown = useCallback( + function (event: Event.onKeyDown): void { + onKeyDown(event) + if (event.key !== 'Escape') { + return + } + if (propagateEscapeKeyDown === false) { + event.stopPropagation() + } + if (blurOnEscapeKeyDown === true) { + event.currentTarget.blur() + } + }, + [blurOnEscapeKeyDown, onKeyDown, propagateEscapeKeyDown] + ) - return ( -