From 140d7fadedfe90f4738abdfe30c63c59a0816e59 Mon Sep 17 00:00:00 2001 From: Alisa Romankova Date: Fri, 24 Nov 2023 20:36:08 +0100 Subject: [PATCH 1/3] refactor(InlineLoading): add TypeScript types --- .../{InlineLoading.js => InlineLoading.tsx} | 83 ++++++++++--------- .../InlineLoading/{index.js => index.ts} | 0 2 files changed, 44 insertions(+), 39 deletions(-) rename packages/react/src/components/InlineLoading/{InlineLoading.js => InlineLoading.tsx} (82%) rename packages/react/src/components/InlineLoading/{index.js => index.ts} (100%) diff --git a/packages/react/src/components/InlineLoading/InlineLoading.js b/packages/react/src/components/InlineLoading/InlineLoading.tsx similarity index 82% rename from packages/react/src/components/InlineLoading/InlineLoading.js rename to packages/react/src/components/InlineLoading/InlineLoading.tsx index 7b4bbc9ba6f2..8d893087f5e4 100644 --- a/packages/react/src/components/InlineLoading/InlineLoading.js +++ b/packages/react/src/components/InlineLoading/InlineLoading.tsx @@ -6,21 +6,57 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; import classNames from 'classnames'; import { CheckmarkFilled, ErrorFilled } from '@carbon/icons-react'; import Loading from '../Loading'; import { usePrefix } from '../../internal/usePrefix'; -export default function InlineLoading({ +export interface InlineLoadingProps + extends React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDivElement + > { + /** + * Specify a custom className to be applied to the container node + */ + className?: string; + + /** + * Specify the description for the inline loading text + */ + description?: React.ReactNode; + + /** + * Specify the description for the inline loading text + */ + iconDescription?: string; + + /** + * Provide an optional handler to be invoked when is + * successful + */ + onSuccess?: (...args: unknown[]) => unknown; + + /** + * Specify the loading status + */ + status?: 'inactive' | 'active' | 'finished' | 'error'; + + /** + * Provide a delay for the `setTimeout` for success + */ + successDelay?: number; +} + +const InlineLoading = ({ className, status = 'active', iconDescription, description, onSuccess, successDelay = 1500, - ...other -}) { + ...divProps +}: InlineLoadingProps) => { const prefix = usePrefix(); const loadingClasses = classNames(`${prefix}--inline-loading`, className); const getLoading = () => { @@ -70,43 +106,12 @@ export default function InlineLoading({ return (
+ {...divProps} + aria-live={'assertive' || divProps['aria-live']}> {loadingAnimation} {description && loadingText}
); -} - -InlineLoading.propTypes = { - /** - * Specify a custom className to be applied to the container node - */ - className: PropTypes.string, - - /** - * Specify the description for the inline loading text - */ - description: PropTypes.node, - - /** - * Specify the description for the inline loading text - */ - iconDescription: PropTypes.string, - - /** - * Provide an optional handler to be invoked when is - * successful - */ - onSuccess: PropTypes.func, - - /** - * Specify the loading status - */ - status: PropTypes.oneOf(['inactive', 'active', 'finished', 'error']), - - /** - * Provide a delay for the `setTimeout` for success - */ - successDelay: PropTypes.number, }; + +export default InlineLoading; diff --git a/packages/react/src/components/InlineLoading/index.js b/packages/react/src/components/InlineLoading/index.ts similarity index 100% rename from packages/react/src/components/InlineLoading/index.js rename to packages/react/src/components/InlineLoading/index.ts From a709195cc149e85ed54abcdc9a1d4983c1d94033 Mon Sep 17 00:00:00 2001 From: Alisa Romankova Date: Mon, 27 Nov 2023 11:53:17 +0100 Subject: [PATCH 2/3] refactor(InlineLoading): add types and fix usages --- .../components/ComposedModal/ModalFooter.tsx | 3 +- .../InlineLoading/InlineLoading.tsx | 56 +++++++++++++++++-- packages/react/src/components/Modal/Modal.tsx | 5 +- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/packages/react/src/components/ComposedModal/ModalFooter.tsx b/packages/react/src/components/ComposedModal/ModalFooter.tsx index 688040a74bd6..1d8100532c2c 100644 --- a/packages/react/src/components/ComposedModal/ModalFooter.tsx +++ b/packages/react/src/components/ComposedModal/ModalFooter.tsx @@ -6,6 +6,7 @@ import cx from 'classnames'; import { usePrefix } from '../../internal/usePrefix'; import { noopFn } from '../../internal/noopFn'; import InlineLoading from '../InlineLoading'; +import { InlineLoadingStatus } from '../InlineLoading/InlineLoading'; interface SecondaryButtonProps { buttonText: ReactNode; @@ -166,7 +167,7 @@ export interface ModalFooterProps { /** * loading status */ - loadingStatus?: string; + loadingStatus?: InlineLoadingStatus; /** * Specify the description for the loading text diff --git a/packages/react/src/components/InlineLoading/InlineLoading.tsx b/packages/react/src/components/InlineLoading/InlineLoading.tsx index 8d893087f5e4..74b9dbeea2c7 100644 --- a/packages/react/src/components/InlineLoading/InlineLoading.tsx +++ b/packages/react/src/components/InlineLoading/InlineLoading.tsx @@ -6,15 +6,28 @@ */ import React from 'react'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; import { CheckmarkFilled, ErrorFilled } from '@carbon/icons-react'; import Loading from '../Loading'; import { usePrefix } from '../../internal/usePrefix'; +export const InlineLoadingStatuses = [ + 'inactive', + 'active', + 'finished', + 'error', +] as const; + +export type InlineLoadingStatus = (typeof InlineLoadingStatuses)[number]; + export interface InlineLoadingProps - extends React.DetailedHTMLProps< - React.HTMLAttributes, - HTMLDivElement + extends Omit< + React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDivElement + >, + 'children' > { /** * Specify a custom className to be applied to the container node @@ -35,12 +48,12 @@ export interface InlineLoadingProps * Provide an optional handler to be invoked when is * successful */ - onSuccess?: (...args: unknown[]) => unknown; + onSuccess?: () => void; /** * Specify the loading status */ - status?: 'inactive' | 'active' | 'finished' | 'error'; + status?: InlineLoadingStatus; /** * Provide a delay for the `setTimeout` for success @@ -114,4 +127,37 @@ const InlineLoading = ({ ); }; +InlineLoading.propTypes = { + /** + * Specify a custom className to be applied to the container node + */ + className: PropTypes.string, + + /** + * Specify the description for the inline loading text + */ + description: PropTypes.node, + + /** + * Specify the description for the inline loading text + */ + iconDescription: PropTypes.string, + + /** + * Provide an optional handler to be invoked when is + * successful + */ + onSuccess: PropTypes.func, + + /** + * Specify the loading status + */ + status: PropTypes.oneOf(['inactive', 'active', 'finished', 'error']), + + /** + * Provide a delay for the `setTimeout` for success + */ + successDelay: PropTypes.number, +}; + export default InlineLoading; diff --git a/packages/react/src/components/Modal/Modal.tsx b/packages/react/src/components/Modal/Modal.tsx index 3168587f70de..ac4b27fa00c2 100644 --- a/packages/react/src/components/Modal/Modal.tsx +++ b/packages/react/src/components/Modal/Modal.tsx @@ -23,6 +23,7 @@ import { keys, match } from '../../internal/keyboard'; import { noopFn } from '../../internal/noopFn'; import { Text } from '../Text'; import { ReactAttr } from '../../types/common'; +import { InlineLoadingStatus } from '../InlineLoading/InlineLoading'; const getInstanceId = setupGetInstanceId(); @@ -101,7 +102,7 @@ export interface ModalProps extends ReactAttr { /** * Specify loading status */ - loadingStatus?: string; + loadingStatus?: InlineLoadingStatus; /** * Specify a label to be read by screen readers on the modal root node @@ -128,7 +129,7 @@ export interface ModalProps extends ReactAttr { * Specify an optional handler to be invoked when loading is * successful */ - onLoadingSuccess?: React.ReactEventHandler; + onLoadingSuccess?: () => void; /** * Specify a handler for closing modal. From e3cc88eb6725ce8c10465670bc25c48662aace4a Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Mon, 4 Dec 2023 15:31:25 -0600 Subject: [PATCH 3/3] fix(inlineloading): name prop spread ...rest --- .../react/src/components/InlineLoading/InlineLoading.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react/src/components/InlineLoading/InlineLoading.tsx b/packages/react/src/components/InlineLoading/InlineLoading.tsx index 74b9dbeea2c7..0f5d838936ef 100644 --- a/packages/react/src/components/InlineLoading/InlineLoading.tsx +++ b/packages/react/src/components/InlineLoading/InlineLoading.tsx @@ -68,7 +68,7 @@ const InlineLoading = ({ description, onSuccess, successDelay = 1500, - ...divProps + ...rest }: InlineLoadingProps) => { const prefix = usePrefix(); const loadingClasses = classNames(`${prefix}--inline-loading`, className); @@ -119,8 +119,8 @@ const InlineLoading = ({ return (
+ {...rest} + aria-live={'assertive' || rest['aria-live']}> {loadingAnimation} {description && loadingText}