Skip to content

fix(types): adapt types of events to reduce the usage of any-type #4328

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

Merged
merged 13 commits into from
Jun 18, 2025
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
8 changes: 8 additions & 0 deletions packages/components/scripts/post-build/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ const overwriteEvents = (tmp?: boolean) => {
'export type InteractionEvent<T> = FocusEvent;',
'export type InteractionEvent<T> = React.FocusEvent<T>;'
);
modelFileContent = modelFileContent.replace(
'export type GeneralEvent<T> = Event;',
'export type GeneralEvent<T> = React.SyntheticEvent<T>;'
);
modelFileContent = modelFileContent.replace(
'export type GeneralKeyboardEvent<T> = KeyboardEvent;',
'export type GeneralKeyboardEvent<T> = React.KeyboardEvent<T>;'
);
writeFileSync(modelFilePath, modelFileContent);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export default function DBAccordionItem(props: DBAccordionItemProps) {
<details
aria-disabled={getBooleanAsString(props.disabled)}
ref={_ref}
/* @ts-expect-error This is a new api for details */
name={state._name}
open={state._open}>
<summary onClick={(event) => state.handleToggle(event)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ import {
DEFAULT_VALID_MESSAGE,
DEFAULT_VALID_MESSAGE_ID_SUFFIX
} from '../../shared/constants';
import { ChangeEvent, ClickEvent } from '../../shared/model';
import {
ClickEvent,
GeneralEvent,
InputEvent,
InteractionEvent
} from '../../shared/model';
import DBCustomSelectList from '../custom-select-list/custom-select-list.lite';
import DBCustomSelectListItem from '../custom-select-list-item/custom-select-list-item.lite';
import DBCustomSelectDropdown from '../custom-select-dropdown/custom-select-dropdown.lite';
Expand Down Expand Up @@ -157,12 +162,15 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
state._validity = props.validation ?? 'no-validation';
}
},
handleDropdownToggle: (event: any) => {
handleDropdownToggle: (event: GeneralEvent<HTMLDetailsElement>) => {
if (props.onDropdownToggle) {
event.stopPropagation();
props.onDropdownToggle(event);
}
if (event.target.open) {
if (
event.target instanceof HTMLDetailsElement &&
event.target.open
) {
state._documentClickListenerCallbackId =
new DocumentClickListener().addCallback((event) =>
state.handleDocumentClose(event)
Expand All @@ -175,7 +183,7 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {

state.handleAutoPlacement();
state._observer?.observe(detailsRef);
if (!event.target.dataset.test) {
if (!event.target.dataset['test']) {
// We need this workaround for snapshot testing
state.handleOpenByKeyboardFocus();
}
Expand Down Expand Up @@ -239,8 +247,14 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
}`;
}
},
handleTagRemove: (option: CustomSelectOptionType, event: any) => {
event.stopPropagation();
handleTagRemove: (
option: CustomSelectOptionType,
event?: ClickEvent<HTMLButtonElement> | void
) => {
if (event) {
event.stopPropagation();
}

state.handleSelect(option.value);
state.handleSummaryFocus();
},
Expand Down Expand Up @@ -328,7 +342,7 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
(event.key === 'ArrowUp' ||
event.key === 'ArrowLeft')
) {
state.handleClose('close');
state.handleClose(undefined, true);
state.handleSummaryFocus();
} else {
// 3. Otherwise, we need to move to the first checkbox
Expand Down Expand Up @@ -357,7 +371,7 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
handleKeyboardPress: (event: any) => {
event.stopPropagation();
if (event.key === 'Escape' && detailsRef?.open) {
state.handleClose('close');
state.handleClose(undefined, true);
state.handleSummaryFocus();
} else if (
event.key === 'ArrowDown' ||
Expand All @@ -368,17 +382,23 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
state.handleArrowDownUp(event);
}
},
handleClose: (event: any) => {
handleClose: (
event?: InteractionEvent<HTMLDetailsElement> | void,
forceClose?: boolean
) => {
if (detailsRef) {
if (event === 'close') {
if (forceClose) {
detailsRef.open = false;
state.handleSummaryFocus();
} else if (detailsRef.open && event?.relatedTarget) {
const relatedTarget = event.relatedTarget as HTMLElement;
if (!detailsRef.contains(relatedTarget)) {
// We need to use delay here because the combination of `contains`
// and changing the DOM element causes a race condition inside browser
delay(() => (detailsRef.open = false), 1);
} else if (detailsRef.open && event) {
if (event.relatedTarget) {
const relatedTarget =
event.relatedTarget as HTMLElement;
if (!detailsRef.contains(relatedTarget)) {
// We need to use delay here because the combination of `contains`
// and changing the DOM element causes a race condition inside browser
delay(() => (detailsRef.open = false), 1);
}
}
}
}
Expand Down Expand Up @@ -444,7 +464,7 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
}
} else {
state.handleOptionSelected([value]);
state.handleClose('close');
state.handleClose(undefined, true);
}
}
},
Expand Down Expand Up @@ -515,12 +535,19 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
}
},
// Don't trigger onOptionSelected event
handleSearch: (event: any) => {
handleSearch: (
valueOrEvent?: InputEvent<HTMLInputElement> | string | void
) => {
if (valueOrEvent === undefined) {
return;
}

let filterText;

if (typeof event === 'string') {
filterText = event;
if (typeof valueOrEvent === 'string') {
filterText = valueOrEvent;
} else {
const event = valueOrEvent as InputEvent<HTMLInputElement>;
event.stopPropagation();

if (props.onSearch) {
Expand Down Expand Up @@ -596,8 +623,10 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {

onUpdate(() => {
if (detailsRef) {
detailsRef.addEventListener('focusout', (event: any) =>
state.handleClose(event)
detailsRef.addEventListener(
'focusout',
(event: InteractionEvent<HTMLDetailsElement>) =>
state.handleClose(event)
);
}
}, [detailsRef]);
Expand Down Expand Up @@ -833,7 +862,7 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
ref={detailsRef}
open={props.open}
/* @ts-expect-error details as an event named onToggle */
onToggle={(event: any) => state.handleDropdownToggle(event)}
onToggle={(event) => state.handleDropdownToggle(event)}
onKeyDown={(event) => state.handleKeyboardPress(event)}>
{props.children}
<Show when={props.options}>
Expand Down Expand Up @@ -872,7 +901,7 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
index
)}
onRemove={(
event: ClickEvent<HTMLButtonElement>
event?: ClickEvent<HTMLButtonElement> | void
) =>
state.handleTagRemove(
option,
Expand Down Expand Up @@ -909,7 +938,7 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
: undefined
}
onInput={(
event: ChangeEvent<HTMLInputElement>
event: InputEvent<HTMLInputElement>
) => state.handleSearch(event)}
/>
</div>
Expand Down Expand Up @@ -1028,7 +1057,9 @@ export default function DBCustomSelect(props: DBCustomSelectProps) {
size="small"
name={state._id}
form={state._id}
onClick={() => state.handleClose('close')}>
onClick={() =>
state.handleClose(undefined, true)
}>
{props.mobileCloseButtonText ??
DEFAULT_CLOSE_BUTTON}
</DBButton>
Expand Down
20 changes: 13 additions & 7 deletions packages/components/src/components/custom-select/model.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import {
BaseFormProps,
ClickEvent,
CloseEventState,
CustomFormProps,
DocumentScrollState,
FormMessageProps,
FormState,
FromValidState,
GeneralEvent,
GlobalProps,
GlobalState,
IconProps,
InputEvent,
InteractionEvent,
PlacementVerticalType,
PopoverState,
RequiredProps,
ShowIconProps,
ShowLabelProps,
Expand Down Expand Up @@ -72,20 +75,20 @@ export type DBCustomSelectEvents = {
/**
* Informs the user when dropdown was toggled.
*/
onDropdownToggle?: (event: any) => void;
onDropdownToggle?: (event: GeneralEvent<HTMLDetailsElement>) => void;
/**
* Informs the user when dropdown was toggled.
*/
dropdownToggle?: (event: any) => void;
dropdownToggle?: (event: GeneralEvent<HTMLDetailsElement>) => void;

/**
* Informs the user when a search was performed.
*/
onSearch?: (event: any) => void;
onSearch?: (event: InputEvent<HTMLInputElement>) => void;
/**
* Informs the user when a search was performed.
*/
search?: (event: any) => void;
search?: (event: InputEvent<HTMLInputElement>) => void;
};

export type DBCustomSelectDefaultProps = {
Expand Down Expand Up @@ -266,7 +269,10 @@ export type DBCustomSelectDefaultState = {
searchEnabled: boolean;
amountOptions: number;
setDescById: (descId?: string) => void;
handleTagRemove: (option: CustomSelectOptionType, event?: any) => void;
handleTagRemove: (
option: CustomSelectOptionType,
event?: ClickEvent<HTMLButtonElement> | void
) => void;
handleSummaryFocus: () => void;
handleSelect: (value?: string) => void;
handleSelectAll: (event: any) => void;
Expand All @@ -289,5 +295,5 @@ export type DBCustomSelectState = DBCustomSelectDefaultState &
GlobalState &
FormState &
FromValidState &
CloseEventState &
CloseEventState<InteractionEvent<HTMLDetailsElement>> &
DocumentScrollState;
49 changes: 33 additions & 16 deletions packages/components/src/components/drawer/drawer.lite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
import { DBDrawerProps, DBDrawerState } from './model';
import DBButton from '../button/button.lite';
import { DEFAULT_CLOSE_BUTTON } from '../../shared/constants';
import { cls, delay, getBooleanAsString } from '../../utils';
import { cls, delay, getBooleanAsString, isKeyboardEvent } from '../../utils';
import { ClickEvent, GeneralKeyboardEvent } from '../../shared/model';

useMetadata({});

Expand All @@ -21,24 +22,40 @@ export default function DBDrawer(props: DBDrawerProps) {
const dialogContainerRef = useRef<HTMLDivElement | any>(null);
const state = useStore<DBDrawerState>({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
handleClose: (event: any, forceClose?: boolean) => {
if (event.key === 'Escape') {
event.preventDefault();
}
handleClose: (
event?:
| ClickEvent<HTMLButtonElement | HTMLDialogElement>
| GeneralKeyboardEvent<HTMLDialogElement>
| void,
forceClose?: boolean
) => {
if (!event) return;

if (forceClose) {
event.stopPropagation();
}
if (isKeyboardEvent<HTMLButtonElement | HTMLDialogElement>(event)) {
if (event.key === 'Escape') {
event.preventDefault();

if (props.onClose) {
props.onClose(event);
}
}
} else {
if (forceClose) {
event.stopPropagation();

if (
forceClose ||
event.key === 'Escape' ||
(event.target.nodeName === 'DIALOG' &&
if (props.onClose) {
props.onClose(event);
}
}

if (
(event.target as any)?.nodeName === 'DIALOG' &&
event.type === 'click' &&
props.backdrop !== 'none')
) {
if (props.onClose) {
props.onClose(event);
props.backdrop !== 'none'
) {
if (props.onClose) {
props.onClose(event);
}
}
}
},
Expand Down
13 changes: 11 additions & 2 deletions packages/components/src/components/drawer/model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {
ClickEvent,
CloseEventProps,
CloseEventState,
GeneralEvent,
GeneralKeyboardEvent,
GlobalProps,
GlobalState,
InnerCloseButtonProps,
Expand Down Expand Up @@ -56,7 +59,10 @@ export type DBDrawerDefaultProps = {

export type DBDrawerProps = DBDrawerDefaultProps &
GlobalProps &
CloseEventProps &
CloseEventProps<
| ClickEvent<HTMLButtonElement | HTMLDialogElement>
| GeneralKeyboardEvent<HTMLDialogElement>
> &
InnerCloseButtonProps &
WidthProps &
SpacingProps;
Expand All @@ -67,4 +73,7 @@ export type DBDrawerDefaultState = {

export type DBDrawerState = DBDrawerDefaultState &
GlobalState &
CloseEventState;
CloseEventState<
| ClickEvent<HTMLButtonElement | HTMLDialogElement>
| GeneralKeyboardEvent<HTMLDialogElement>
>;
5 changes: 3 additions & 2 deletions packages/components/src/components/notification/model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
ClickEvent,
CloseEventProps,
CloseEventState,
GlobalProps,
Expand Down Expand Up @@ -85,7 +86,7 @@ export type DBNotificationDefaultProps = {

export type DBNotificationProps = DBNotificationDefaultProps &
GlobalProps &
CloseEventProps &
CloseEventProps<ClickEvent<HTMLButtonElement>> &
IconProps &
SemanticProps &
InnerCloseButtonProps &
Expand All @@ -97,4 +98,4 @@ export type DBNotificationDefaultState = {};

export type DBNotificationState = DBNotificationDefaultState &
GlobalState &
CloseEventState;
CloseEventState<ClickEvent<HTMLButtonElement>>;
Loading
Loading