Skip to content

Commit

Permalink
chore: Safe typings for 27 components (#1763)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorlanigan authored Dec 7, 2023
1 parent 2d8a5d0 commit 6c5a325
Show file tree
Hide file tree
Showing 21 changed files with 118 additions and 40 deletions.
75 changes: 74 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,80 @@ module.exports = {
},
},
{
files: ['src/attribute-editor/**'],
files: [
'src/alert/**',
'src/anchor-navigation/**',
'src/annotation-context/**',
// 'src/app-layout/**',
// 'src/area-chart/**',
'src/attribute-editor/**',
'src/autosuggest/**',
'src/badge/**',
// 'src/bar-chart/**',
'src/box/**',
'src/breadcrumb-group/**',
'src/button/**',
'src/button-dropdown/**',
'src/calendar/**',
// 'src/cards/**',
'src/checkbox/**',
// 'src/code-editor/**',
// 'src/collection-preferences/**',
'src/column-layout/**',
'src/container/**',
// 'src/content-layout/**',
// 'src/contexts/**',
'src/date-input/**',
'src/date-picker/**',
'src/date-range-picker/**',
// 'src/drawer/**',
'src/expandable-section/**',
'src/file-upload/**',
'src/flashbar/**',
'src/form/**',
'src/form-field/**',
'src/grid/**',
'src/header/**',
'src/help-panel/**',
// 'src/hotspot/**',
// 'src/i18n/**',
'src/icon/**',
'src/input/**',
// 'src/internal/**',
// 'src/line-chart/**',
'src/link/**',
// 'src/mixed-line-bar-chart/**',
// 'src/modal/**',
// 'src/multiselect/**',
// 'src/pagination/**',
// 'src/pie-chart/**',
// 'src/popover/**',
// 'src/progress-bar/**',
// 'src/property-filter/**',
// 'src/radio-group/**',
// 'src/s3-resource-selector/**',
// 'src/segmented-control/**',
// 'src/select/**',
// 'src/side-navigation/**',
// 'src/space-between/**',
// 'src/spinner/**',
// 'src/split-panel/**',
// 'src/status-indicator/**',
// 'src/table/**',
// 'src/tabs/**',
// 'src/tag-editor/**',
// 'src/text-content/**',
// 'src/text-filter/**',
// 'src/textarea/**',
// 'src/theming/**',
// 'src/tiles/**',
// 'src/time-input/**',
// 'src/toggle/**',
// 'src/token-group/**',
// 'src/top-navigation/**',
// 'src/tutorial-panel/**',
// 'src/wizard/**',
],
excludedFiles: [
'src/**/__tests__/**',
'src/**/__integ__/**',
Expand Down
2 changes: 1 addition & 1 deletion src/alert/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export { AlertProps };

const Alert = React.forwardRef(
({ type = 'info', visible = true, ...props }: AlertProps, ref: React.Ref<AlertProps.Ref>) => {
const baseComponentProps = useBaseComponent('Alert');
const baseComponentProps = useBaseComponent<HTMLDivElement>('Alert');

const { funnelInteractionId, submissionAttempt, funnelState, errorCount } = useFunnel();
const { stepNumber, stepNameSelector } = useFunnelStep();
Expand Down
2 changes: 1 addition & 1 deletion src/alert/internal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const typeToIcon: Record<AlertProps.Type, IconProps['name']> = {
info: 'status-info',
};

type InternalAlertProps = SomeRequired<AlertProps, 'type'> & InternalBaseComponentProps;
type InternalAlertProps = SomeRequired<AlertProps, 'type'> & InternalBaseComponentProps<HTMLDivElement>;

const useDiscoveredAction = createUseDiscoveredAction(awsuiPluginsInternal.alert.onActionRegistered);

Expand Down
2 changes: 1 addition & 1 deletion src/anchor-navigation/use-scroll-spy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function useScrollSpy({
}, [hrefs]);

// Get the bounding rectangle of an element by href
const getRectByHref = useCallback(href => {
const getRectByHref = useCallback((href: string) => {
return document.getElementById(href.slice(1))?.getBoundingClientRect();
}, []);

Expand Down
2 changes: 1 addition & 1 deletion src/annotation-context/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export default function AnnotationContext({

applyDisplayName(AnnotationContext, 'AnnotationContext');

function removeKey<T extends Record<string, any>>(key: keyof T, object: T) {
function removeKey<T extends Record<string, unknown>>(key: keyof T, object: T) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { [key]: _, ...remainingObject } = object;
return remainingObject;
Expand Down
8 changes: 4 additions & 4 deletions src/area-chart/async-store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import { unstable_batchedUpdates } from 'react-dom';
import { usePrevious } from '../../internal/hooks/use-previous';

type Selector<S, R> = (state: S) => R;
type Listener<S> = (state: S, prevState: S) => any;
type Listener<S> = (state: S, prevState: S) => void;

export interface ReadonlyAsyncStore<S> {
get(): S;
subscribe<R>(selector: Selector<S, R>, listener: Listener<S>): () => void;
unsubscribe(listener: Listener<any>): void;
unsubscribe(listener: Listener<S>): void;
}

export default class AsyncStore<S> implements ReadonlyAsyncStore<S> {
_state: S;
_listeners: [Selector<S, any>, Listener<any>][] = [];
_listeners: [Selector<S, unknown>, Listener<S>][] = [];

constructor(state: S) {
this._state = state;
Expand Down Expand Up @@ -46,7 +46,7 @@ export default class AsyncStore<S> implements ReadonlyAsyncStore<S> {
return () => this.unsubscribe(listener);
}

unsubscribe(listener: Listener<any>): void {
unsubscribe(listener: Listener<S>): void {
for (let index = 0; index < this._listeners.length; index++) {
const [, storedListener] = this._listeners[index];

Expand Down
2 changes: 1 addition & 1 deletion src/autosuggest/autosuggest-option.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { HighlightType } from '../internal/components/options-list/utils/use-hig
import { useInternalI18n } from '../i18n/context';

export interface AutosuggestOptionProps extends BaseComponentProps {
nativeAttributes?: Record<string, any>;
nativeAttributes?: React.HTMLAttributes<HTMLDivElement>;
highlightText: string;
option: AutosuggestItem;
highlighted: boolean;
Expand Down
4 changes: 2 additions & 2 deletions src/breadcrumb-group/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ export interface BreadcrumbItemProps<T extends BreadcrumbGroupProps.Item> {
export interface EllipsisDropdownProps {
ariaLabel?: BreadcrumbGroupProps['expandAriaLabel'];
dropdownItems: ReadonlyArray<LinkItem>;
onDropdownItemClick: CancelableEventHandler<{ id: string; event?: any }>;
onDropdownItemFollow: CancelableEventHandler<{ id: string; event?: any }>;
onDropdownItemClick: CancelableEventHandler<{ id: string }>;
onDropdownItemFollow: CancelableEventHandler<{ id: string }>;
}
8 changes: 5 additions & 3 deletions src/button/internal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import { usePerformanceMarks } from '../internal/hooks/use-performance-marks';
export type InternalButtonProps = Omit<ButtonProps, 'variant'> & {
variant?: ButtonProps['variant'] | 'flashbar-icon' | 'breadcrumb-group' | 'menu-trigger' | 'modal-dismiss';
badge?: boolean;
__nativeAttributes?: Record<string, any>;
__nativeAttributes?:
| (React.HTMLAttributes<HTMLAnchorElement> & React.HTMLAttributes<HTMLButtonElement>)
| Record<`data-${string}`, string>;
__iconClass?: string;
__activated?: boolean;
} & InternalBaseComponentProps;
} & InternalBaseComponentProps<HTMLAnchorElement | HTMLButtonElement>;

export const InternalButton = React.forwardRef(
(
Expand Down Expand Up @@ -136,7 +138,7 @@ export const InternalButton = React.forwardRef(
...props,
...__nativeAttributes,
// https://github.com/microsoft/TypeScript/issues/36659
ref: useMergeRefs(buttonRef as any, __internalRootRef),
ref: useMergeRefs(buttonRef, __internalRootRef),
'aria-label': ariaLabel,
'aria-describedby': ariaDescribedby,
'aria-expanded': ariaExpanded,
Expand Down
5 changes: 2 additions & 3 deletions src/column-layout/flexible-column-layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,11 @@ export default function FlexibleColumnLayout({
>
{flattenedChildren.map((child, i) => {
// If this react child is a primitive value, the key will be undefined
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const key = (child as any).key;
const key = (child as Record<'key', unknown>).key;

return (
<div
key={key}
key={key ? String(key) : undefined}
className={clsx(styles.item, {
[styles['first-column']]: i % columnCount === 0,
})}
Expand Down
2 changes: 1 addition & 1 deletion src/file-upload/file-input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function FileInput(
onChange(target.files ? Array.from(target.files) : []);
};

const nativeAttributes: Record<string, any> = {
const nativeAttributes: React.HTMLAttributes<HTMLInputElement> = {
'aria-labelledby': joinStrings(formFieldContext.ariaLabelledby, uploadButtonLabelId),
'aria-describedby': formFieldContext.ariaDescribedby,
};
Expand Down
2 changes: 1 addition & 1 deletion src/flashbar/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function useFlashbar({
const ref = useRef<HTMLDivElement | null>(null);
const [breakpoint, breakpointRef] = useContainerBreakpoints(['xs']);
const mergedRef = useMergeRefs(ref, breakpointRef, __internalRootRef);
const isReducedMotion = useReducedMotion(breakpointRef as any);
const isReducedMotion = useReducedMotion(ref);
const isVisualRefresh = useVisualRefresh();
const [previousItems, setPreviousItems] = useState<ReadonlyArray<FlashbarProps.MessageDefinition>>(items);
const [nextFocusId, setNextFocusId] = useState<string | null>(null);
Expand Down
2 changes: 1 addition & 1 deletion src/form-field/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export namespace FormFieldProps {
}
}

export interface InternalFormFieldProps extends FormFieldProps, InternalBaseComponentProps {
export interface InternalFormFieldProps extends FormFieldProps, InternalBaseComponentProps<HTMLDivElement> {
/**
* Visually hide the label.
*/
Expand Down
9 changes: 5 additions & 4 deletions src/grid/internal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ const InternalGrid = React.forwardRef(
__internalRootRef = null,
...restProps
}: InternalGridProps,
ref: React.Ref<any>
ref: React.Ref<HTMLDivElement>
) => {
let [defaultBreakpoint, defaultRef]: [Breakpoint | null, React.Ref<any>] = useContainerBreakpoints(undefined);
let [defaultBreakpoint, defaultRef]: [Breakpoint | null, React.Ref<HTMLDivElement>] =
useContainerBreakpoints(undefined);
if (__breakpoint !== undefined) {
defaultBreakpoint = __breakpoint;
defaultRef = ref;
Expand Down Expand Up @@ -74,11 +75,11 @@ const InternalGrid = React.forwardRef(
{flattenedChildren.map((child, i) => {
// If this react child is a primitive value, the key will be undefined
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const key = (child as any).key;
const key = (child as Record<'key', unknown>).key;

return (
<div
key={key}
key={key ? String(key) : undefined}
className={clsx(
styles['grid-column'],
getColumnClassNames('colspan', gridDefinition[i]?.colspan, defaultBreakpoint),
Expand Down
2 changes: 1 addition & 1 deletion src/input/internal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface InternalInputProps
__rightIcon?: IconProps['name'];
__onRightIconClick?: () => void;

__nativeAttributes?: Record<string, any>;
__nativeAttributes?: React.InputHTMLAttributes<HTMLInputElement>;
__noBorderRadius?: boolean;

__onDelayedInput?: NonCancelableEventHandler<BaseChangeDetail>;
Expand Down
5 changes: 4 additions & 1 deletion src/internal/breakpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ export function matchBreakpointMapping<T>(subset: Partial<Record<Breakpoint, T>>
/**
* Get the named breakpoint for a provided width, optionally filtering to a subset of breakpoints.
*/
export function getMatchingBreakpoint(width: number, breakpointFilter?: readonly Breakpoint[]): Breakpoint {
export function getMatchingBreakpoint<T extends readonly Breakpoint[]>(
width: number,
breakpointFilter?: T
): T[number] | 'default' {
for (const [breakpoint, breakpointWidth] of BREAKPOINT_MAPPING) {
if (width > breakpointWidth && (!breakpointFilter || breakpointFilter.indexOf(breakpoint) !== -1)) {
return breakpoint;
Expand Down
4 changes: 2 additions & 2 deletions src/internal/components/autosuggest-input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Dropdown from '../dropdown';
import { FormFieldValidationControlProps, useFormFieldContext } from '../../context/form-field-context';
import { BaseComponentProps, getBaseProps } from '../../base-component';
import { BaseKeyDetail, fireCancelableEvent, fireNonCancelableEvent, NonCancelableEventHandler } from '../../events';
import InternalInput from '../../../input/internal';
import InternalInput, { InternalInputProps } from '../../../input/internal';
import {
BaseChangeDetail,
BaseInputProps,
Expand Down Expand Up @@ -211,7 +211,7 @@ const AutosuggestInput = React.forwardRef(
};

const expanded = open && dropdownExpanded;
const nativeAttributes = {
const nativeAttributes: InternalInputProps['__nativeAttributes'] = {
name,
placeholder,
autoFocus,
Expand Down
4 changes: 2 additions & 2 deletions src/internal/components/masked-input/use-mask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface UseMaskHook {
onChange: NonCancelableEventHandler<InputProps.ChangeDetail>;
onKeyDown: CancelableEventHandler<InputProps.KeyDetail>;
onBlur: NonCancelableEventHandler<null>;
onPaste: (event: ClipboardEvent) => void;
onPaste: (event: React.ClipboardEvent) => void;
}

interface UseMaskProps {
Expand Down Expand Up @@ -110,7 +110,7 @@ const useMask = ({

onBlur && onBlur();
},
onPaste: (event: ClipboardEvent) => {
onPaste: (event: React.ClipboardEvent) => {
const text = (event.clipboardData || (window as any).clipboardData).getData('text');

const selectionStart = inputRef.current?.selectionStart || 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import { useContainerQuery } from '@cloudscape-design/component-toolkit';
*
* @param triggers The relevant breakpoints to trigger for.
*/
export function useContainerBreakpoints<T extends readonly Breakpoint[]>(
triggers?: T
): [T[number] | 'default' | null, React.Ref<any>] {
export function useContainerBreakpoints<T extends readonly Breakpoint[], E extends Element = any>(triggers?: T) {
// triggers.join() gives us a stable value to use for the dependencies argument
const triggersDep = triggers?.join();
// eslint-disable-next-line react-hooks/exhaustive-deps
return useContainerQuery(rect => getMatchingBreakpoint(rect.contentBoxWidth, triggers), [triggersDep]);
return useContainerQuery(rect => getMatchingBreakpoint(rect.contentBoxWidth, triggers), [triggersDep]) as [
'default' | T[number] | null,
React.Ref<E>
];
}
4 changes: 2 additions & 2 deletions src/internal/hooks/use-base-component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useTelemetry } from '../use-telemetry';
import { PACKAGE_VERSION } from '../../environment';
import useFocusVisible from '../focus-visible';

export interface InternalBaseComponentProps {
__internalRootRef?: MutableRefObject<any> | null;
export interface InternalBaseComponentProps<T = any> {
__internalRootRef?: MutableRefObject<T | null> | null;
}

/**
Expand Down
5 changes: 2 additions & 3 deletions src/link/internal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from '../internal/analytics/selectors';
import { LinkDefaultVariantContext } from '../internal/context/link-default-variant-context';

type InternalLinkProps = InternalBaseComponentProps &
type InternalLinkProps = InternalBaseComponentProps<HTMLAnchorElement> &
Omit<LinkProps, 'variant'> & {
variant?: LinkProps['variant'] | 'top-navigation' | 'link' | 'recovery';
};
Expand Down Expand Up @@ -142,8 +142,7 @@ const InternalLink = React.forwardRef(
id: linkId,
...baseProps,
// https://github.com/microsoft/TypeScript/issues/36659
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ref: useMergeRefs(linkRef as any, __internalRootRef),
ref: useMergeRefs(linkRef, __internalRootRef),
className: clsx(
styles.link,
baseProps.className,
Expand Down

0 comments on commit 6c5a325

Please sign in to comment.