Skip to content

Commit

Permalink
Address XS code hygiene tasks
Browse files Browse the repository at this point in the history
Address the first 3 suggestions from microsoft#4968

As we remove `FC/VFC` I thought it'd be nice to add `ReactNode` return type basically to:
- Serve as an additional hint that the function follows React Component signature
- Limit usage of unsupported by React runtime return types
  • Loading branch information
OEvgeny committed Dec 20, 2023
1 parent a03e74d commit fa01151
Show file tree
Hide file tree
Showing 51 changed files with 366 additions and 316 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import React, { useCallback, useMemo, useState } from 'react';

import type { FC, PropsWithChildren } from 'react';
import React, { useCallback, useMemo, useState, type PropsWithChildren, type ReactNode } from 'react';

import ActivityAcknowledgementContext, { ActivityAcknowledgementContextType } from './private/Context';
import findLastIndex from '../../utils/findLastIndex';
Expand All @@ -9,9 +7,9 @@ import useActivityKeys from '../ActivityKeyer/useActivityKeys';
import usePrevious from '../../hooks/internal/usePrevious';
import useValueRef from '../../hooks/internal/useValueRef';

import type { ActivityAcknowledgement } from './private/types';
import { type ActivityAcknowledgement } from './private/types';

type ActivityAcknowledgementComposerProps = PropsWithChildren<{}>;
type ActivityAcknowledgementComposerProps = Readonly<PropsWithChildren<{}>>;

function findClosestActivityKeyIfNotExists(
activityKey: string,
Expand Down Expand Up @@ -42,7 +40,7 @@ function findClosestActivityKeyIfNotExists(
// If nothing is found, return `undefined`.
}

const ActivityAcknowledgementComposer: FC<ActivityAcknowledgementComposerProps> = ({ children }) => {
const ActivityAcknowledgementComposer = ({ children }: ActivityAcknowledgementComposerProps): ReactNode => {
const [activities] = useActivities();
const [allActivityKeys] = useActivityKeys();
const [rawLastAcknowledgedActivityKey, setRawLastAcknowledgedActivityKey] = useState<string | undefined>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import React, { useCallback, useMemo, useRef } from 'react';
import React, { useCallback, useMemo, useRef, type PropsWithChildren, type ReactNode } from 'react';

import ActivityKeyerContext from './private/Context';
import getActivityId from './private/getActivityId';
Expand All @@ -8,15 +8,16 @@ import uniqueId from './private/uniqueId';
import useActivities from '../../hooks/useActivities';
import useActivityKeyerContext from './private/useContext';

import type { ActivityKeyerContextType } from './private/Context';
import type { FC, PropsWithChildren } from 'react';
import type { WebChatActivity } from 'botframework-webchat-core';
import { type ActivityKeyerContextType } from './private/Context';
import { type WebChatActivity } from 'botframework-webchat-core';

type ActivityIdToKeyMap = Map<string, string>;
type ActivityToKeyMap = Map<WebChatActivity, string>;
type ClientActivityIdToKeyMap = Map<string, string>;
type KeyToActivityMap = Map<string, WebChatActivity>;

type ActivityKeyerComposerProps = Readonly<PropsWithChildren<{}>>;

/**
* React context composer component to assign a perma-key to every activity.
* This will support both `useGetActivityByKey` and `useGetKeyByActivity` custom hooks.
Expand All @@ -31,7 +32,7 @@ type KeyToActivityMap = Map<string, WebChatActivity>;
*
* Local key are only persisted in memory. On refresh, they will be a new random key.
*/
const ActivityKeyerComposer: FC<PropsWithChildren<{}>> = ({ children }) => {
const ActivityKeyerComposer = ({ children }: ActivityKeyerComposerProps): ReactNode => {
const existingContext = useActivityKeyerContext(false);

if (existingContext) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef } from 'react';
import React, { useEffect, useMemo, useRef, type PropsWithChildren, type ReactNode } from 'react';

import { SENDING, SEND_FAILED, SENT } from '../../types/internal/SendStatus';
import ActivitySendStatusContext from './private/Context';
Expand All @@ -10,15 +10,16 @@ import useGetKeyByActivity from '../ActivityKeyer/useGetKeyByActivity';
import useGetSendTimeoutForActivity from '../../hooks/useGetSendTimeoutForActivity';
import usePonyfill from '../../hooks/usePonyfill';

import type { ActivitySendStatusContextType } from './private/Context';
import type { FC, PropsWithChildren } from 'react';
import type { SendStatus } from '../../types/internal/SendStatus';
import { type ActivitySendStatusContextType } from './private/Context';
import { type SendStatus } from '../../types/internal/SendStatus';

// Magic numbers for `expiryByActivityKey`.
const EXPIRY_SEND_FAILED = -Infinity;
const EXPIRY_SENT = Infinity;

const ActivitySendStatusComposer: FC<PropsWithChildren<{}>> = ({ children }) => {
type ActivitySendStatusComposerProps = Readonly<PropsWithChildren<{}>>;

const ActivitySendStatusComposer = ({ children }: ActivitySendStatusComposerProps): ReactNode => {
const [activities] = useActivities();
const [{ clearTimeout, Date, setTimeout }] = usePonyfill();
const forceRender = useForceRender();
Expand Down
16 changes: 8 additions & 8 deletions packages/bundle/src/AddFullBundle.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { AttachmentForScreenReaderMiddleware, AttachmentMiddleware, StyleOptions } from 'botframework-webchat-api';
import { OneOrMany, singleToArray, warnOnce } from 'botframework-webchat-core';
import PropTypes from 'prop-types';
import React, { FC, ReactNode } from 'react';
import React, { type ReactNode } from 'react';

import { StrictFullBundleStyleOptions } from './types/FullBundleStyleOptions';
import AdaptiveCardsComposer from './adaptiveCards/AdaptiveCardsComposer';
import AdaptiveCardsPackage from './types/AdaptiveCardsPackage';
import AdaptiveCardsStyleOptions from './adaptiveCards/AdaptiveCardsStyleOptions';
import useComposerProps from './useComposerProps';

type AddFullBundleProps = {
type AddFullBundleProps = Readonly<{
adaptiveCardsHostConfig?: any;
adaptiveCardsPackage?: AdaptiveCardsPackage;
adaptiveCardsPackage?: Readonly<AdaptiveCardsPackage>;
attachmentForScreenReaderMiddleware?: OneOrMany<AttachmentForScreenReaderMiddleware>;
attachmentMiddleware?: OneOrMany<AttachmentMiddleware>;
children: ({ extraStyleSet }: { extraStyleSet: any }) => ReactNode;
Expand All @@ -20,18 +20,18 @@ type AddFullBundleProps = {
newLineOptions: { markdownRespectCRLF: boolean },
linkOptions: { externalLinkAlt: string }
) => string;
styleOptions?: StyleOptions & AdaptiveCardsStyleOptions;
styleSet?: any & { options: StrictFullBundleStyleOptions };
styleOptions?: Readonly<StyleOptions & AdaptiveCardsStyleOptions>;
styleSet?: any & Readonly<{ options: StrictFullBundleStyleOptions }>;

/** @deprecated Rename to "adaptiveCardsHostConfig" */
adaptiveCardHostConfig?: any;
};
}>;

const adaptiveCardHostConfigDeprecation = warnOnce(
'"adaptiveCardHostConfig" is deprecated. Please use "adaptiveCardsHostConfig" instead. "adaptiveCardHostConfig" will be removed on or after 2022-01-01.'
);

const AddFullBundle: FC<AddFullBundleProps> = ({
const AddFullBundle = ({
adaptiveCardHostConfig,
adaptiveCardsHostConfig,
adaptiveCardsPackage,
Expand All @@ -41,7 +41,7 @@ const AddFullBundle: FC<AddFullBundleProps> = ({
renderMarkdown,
styleOptions,
styleSet
}) => {
}: AddFullBundleProps): ReactNode => {
adaptiveCardHostConfig && adaptiveCardHostConfigDeprecation();

const patchedProps = useComposerProps({
Expand Down
11 changes: 5 additions & 6 deletions packages/bundle/src/FullComposer.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { Components } from 'botframework-webchat-component';
import PropTypes from 'prop-types';
import React from 'react';
import React, { type ReactNode } from 'react';

import AddFullBundle from './AddFullBundle';

import type { AddFullBundleProps } from './AddFullBundle';
import type { ComposerProps } from 'botframework-webchat-component';
import type { FC } from 'react';
import { type AddFullBundleProps } from './AddFullBundle';
import { type ComposerProps } from 'botframework-webchat-component';

const { Composer } = Components;

type FullComposerProps = ComposerProps & AddFullBundleProps;
type FullComposerProps = Readonly<ComposerProps & AddFullBundleProps>;

const FullComposer: FC<FullComposerProps> = props => (
const FullComposer = (props: FullComposerProps): ReactNode => (
<AddFullBundle {...props}>
{extraProps => (
<Composer {...props} {...extraProps}>
Expand Down
10 changes: 5 additions & 5 deletions packages/bundle/src/adaptiveCards/AdaptiveCardsComposer.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import * as defaultAdaptiveCardsPackage from 'adaptivecards';
import PropTypes from 'prop-types';
import React, { FC, ReactNode, useMemo } from 'react';
import React, { type ReactNode, useMemo } from 'react';

import AdaptiveCardsContext from './AdaptiveCardsContext';
import AdaptiveCardsPackage from '../types/AdaptiveCardsPackage';

type AdaptiveCardsComposerProps = {
type AdaptiveCardsComposerProps = Readonly<{
adaptiveCardsHostConfig: any;
adaptiveCardsPackage: AdaptiveCardsPackage;
children: ReactNode;
};
}>;

const AdaptiveCardsComposer: FC<AdaptiveCardsComposerProps> = ({
const AdaptiveCardsComposer = ({
adaptiveCardsHostConfig,
adaptiveCardsPackage,
children
}) => {
}: AdaptiveCardsComposerProps): ReactNode => {
const patchedAdaptiveCardsPackage = useMemo(
() => adaptiveCardsPackage || defaultAdaptiveCardsPackage,
[adaptiveCardsPackage]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import PropTypes from 'prop-types';
import React, { FC } from 'react';
import type { DirectLineAttachment } from 'botframework-webchat-core';
import React, { type ReactNode } from 'react';
import { type DirectLineAttachment } from 'botframework-webchat-core';

import AdaptiveCardContent from './AdaptiveCardContent';

type AdaptiveCardAttachmentProps = {
type AdaptiveCardAttachmentProps = Readonly<{
attachment: DirectLineAttachment;
disabled?: boolean;
};
}>;

const AdaptiveCardAttachment: FC<AdaptiveCardAttachmentProps> = ({ attachment: { content }, disabled }) => (
const AdaptiveCardAttachment = ({ attachment: { content }, disabled }: AdaptiveCardAttachmentProps): ReactNode => (
<AdaptiveCardContent content={content} disabled={disabled} />
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import React, { FC, useMemo } from 'react';
import React, { type ReactNode, useMemo } from 'react';

import AdaptiveCardRenderer from './AdaptiveCardRenderer';
import useParseAdaptiveCardJSON from '../hooks/internal/useParseAdaptiveCardJSON';
Expand All @@ -17,13 +17,13 @@ function stripSubmitAction(card) {
return { ...card, nextActions };
}

type AdaptiveCardContentProps = {
type AdaptiveCardContentProps = Readonly<{
actionPerformedClassName?: string;
content: any;
disabled?: boolean;
};
}>;

const AdaptiveCardContent: FC<AdaptiveCardContentProps> = ({ actionPerformedClassName, content, disabled }) => {
const AdaptiveCardContent = ({ actionPerformedClassName, content, disabled }: AdaptiveCardContentProps): ReactNode => {
const parseAdaptiveCardJSON = useParseAdaptiveCardJSON();

const card = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@

import { Components } from 'botframework-webchat-component';
import PropTypes from 'prop-types';
import React, { FC } from 'react';
import type { DirectLineAnimationCard } from 'botframework-webchat-core';
import React, { type ReactNode } from 'react';
import { type DirectLineAnimationCard } from 'botframework-webchat-core';

import CommonCard from './CommonCard';
import useStyleSet from '../../hooks/useStyleSet';

const { ImageContent, VideoContent } = Components;

type AnimationCardContentProps = {
type AnimationCardContentProps = Readonly<{
actionPerformedClassName?: string;
content: DirectLineAnimationCard;
disabled?: boolean;
};
}>;

const AnimationCardContent: FC<AnimationCardContentProps> = ({ actionPerformedClassName, content, disabled }) => {
const AnimationCardContent = ({
actionPerformedClassName,
content,
disabled
}: AnimationCardContentProps): ReactNode => {
const { media = [] } = content;
const [{ animationCardAttachment: animationCardAttachmentStyleSet }] = useStyleSet();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

import { Components } from 'botframework-webchat-component';
import PropTypes from 'prop-types';
import React, { FC } from 'react';
import type { DirectLineAudioCard } from 'botframework-webchat-core';
import React, { type ReactNode } from 'react';
import { type DirectLineAudioCard } from 'botframework-webchat-core';

import CommonCard from './CommonCard';
import useStyleSet from '../../hooks/useStyleSet';

const { AudioContent } = Components;

type AudioCardContentProps = {
type AudioCardContentProps = Readonly<{
actionPerformedClassName?: string;
content: DirectLineAudioCard;
disabled?: boolean;
};
}>;

const AudioCardContent: FC<AudioCardContentProps> = ({ actionPerformedClassName, content, disabled }) => {
const AudioCardContent = ({ actionPerformedClassName, content, disabled }: AudioCardContentProps): ReactNode => {
const [{ audioCardAttachment: audioCardAttachmentStyleSet }] = useStyleSet();
const { autostart = false, autoloop = false, image: { url: imageURL = '' } = {}, media = [] } = content;

Expand Down
11 changes: 6 additions & 5 deletions packages/bundle/src/adaptiveCards/Attachment/HeroCardContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { hooks } from 'botframework-webchat-component';
import PropTypes from 'prop-types';
import React, { FC, useMemo } from 'react';
import type { DirectLineHeroCard } from 'botframework-webchat-core';
import React, { type ReactNode, useMemo } from 'react';

import { type DirectLineHeroCard } from 'botframework-webchat-core';

import AdaptiveCardBuilder from './AdaptiveCardBuilder';
import AdaptiveCardRenderer from './AdaptiveCardRenderer';
Expand All @@ -10,13 +11,13 @@ import useStyleOptions from '../../hooks/useStyleOptions';

const { useDirection } = hooks;

type HeroCardContentProps = {
type HeroCardContentProps = Readonly<{
actionPerformedClassName?: string;
content: DirectLineHeroCard;
disabled?: boolean;
};
}>;

const HeroCardContent: FC<HeroCardContentProps> = ({ actionPerformedClassName, content, disabled }) => {
const HeroCardContent = ({ actionPerformedClassName, content, disabled }: HeroCardContentProps): ReactNode => {
const [adaptiveCardsPackage] = useAdaptiveCardsPackage();
const [styleOptions] = useStyleOptions();
const [direction] = useDirection();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { hooks } from 'botframework-webchat-component';
import PropTypes from 'prop-types';
import React, { FC, useMemo } from 'react';
import type { DirectLineOAuthCard } from 'botframework-webchat-core';
import React, { type ReactNode, useMemo } from 'react';
import { type DirectLineOAuthCard } from 'botframework-webchat-core';

import AdaptiveCardBuilder from './AdaptiveCardBuilder';
import AdaptiveCardRenderer from './AdaptiveCardRenderer';
Expand All @@ -10,13 +10,13 @@ import useStyleOptions from '../../hooks/useStyleOptions';

const { useDirection } = hooks;

type OAuthCardContentProps = {
type OAuthCardContentProps = Readonly<{
actionPerformedClassName?: string;
content: DirectLineOAuthCard;
disabled?: boolean;
};
}>;

const OAuthCardContent: FC<OAuthCardContentProps> = ({ actionPerformedClassName, content, disabled }) => {
const OAuthCardContent = ({ actionPerformedClassName, content, disabled }: OAuthCardContentProps): ReactNode => {
const [adaptiveCardsPackage] = useAdaptiveCardsPackage();
const [direction] = useDirection();
const [styleOptions] = useStyleOptions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import { hooks } from 'botframework-webchat-component';
import PropTypes from 'prop-types';
import React, { FC, useMemo } from 'react';
import type { DirectLineReceiptCard } from 'botframework-webchat-core';
import React, { type ReactNode, useMemo } from 'react';
import { type DirectLineReceiptCard } from 'botframework-webchat-core';

import AdaptiveCardBuilder from './AdaptiveCardBuilder';
import AdaptiveCardRenderer from './AdaptiveCardRenderer';
Expand All @@ -16,13 +16,13 @@ function nullOrUndefined(obj) {
return obj === null || typeof obj === 'undefined';
}

type ReceiptCardContentProps = {
type ReceiptCardContentProps = Readonly<{
actionPerformedClassName?: string;
content: DirectLineReceiptCard;
disabled?: boolean;
};
}>;

const ReceiptCardContent: FC<ReceiptCardContentProps> = ({ actionPerformedClassName, content, disabled }) => {
const ReceiptCardContent = ({ actionPerformedClassName, content, disabled }: ReceiptCardContentProps): ReactNode => {
const [adaptiveCardsPackage] = useAdaptiveCardsPackage();
const [direction] = useDirection();
const [styleOptions] = useStyleOptions();
Expand Down
Loading

0 comments on commit fa01151

Please sign in to comment.