From 87eeed18ea32be4bbc6226a8f29ac51cbe7185e7 Mon Sep 17 00:00:00 2001 From: Nikhil Tomar <63502271+2nikhiltom@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:58:28 +0530 Subject: [PATCH] fix(typescript): adds TypeScript types to ChatButton & Skeleton (#17316) * fix(17291): rename .js to .tsx for preserve file history * fix(typescript): adds TypeScript types to ChatButto & Skeleton --- ...on.Skeleton.js => ChatButton.Skeleton.tsx} | 19 ++- .../src/components/ChatButton/ChatButton.js | 109 ------------ .../src/components/ChatButton/ChatButton.tsx | 157 ++++++++++++++++++ .../ChatButton/{index.js => index.tsx} | 6 +- 4 files changed, 177 insertions(+), 114 deletions(-) rename packages/react/src/components/ChatButton/{ChatButton.Skeleton.js => ChatButton.Skeleton.tsx} (69%) delete mode 100644 packages/react/src/components/ChatButton/ChatButton.js create mode 100644 packages/react/src/components/ChatButton/ChatButton.tsx rename packages/react/src/components/ChatButton/{index.js => index.tsx} (55%) diff --git a/packages/react/src/components/ChatButton/ChatButton.Skeleton.js b/packages/react/src/components/ChatButton/ChatButton.Skeleton.tsx similarity index 69% rename from packages/react/src/components/ChatButton/ChatButton.Skeleton.js rename to packages/react/src/components/ChatButton/ChatButton.Skeleton.tsx index 8056365c7f4d..5e7a09d63da0 100644 --- a/packages/react/src/components/ChatButton/ChatButton.Skeleton.js +++ b/packages/react/src/components/ChatButton/ChatButton.Skeleton.tsx @@ -1,5 +1,5 @@ /** - * Copyright IBM Corp. 2022 + * Copyright IBM Corp. 2024 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -9,8 +9,21 @@ import PropTypes from 'prop-types'; import React from 'react'; import cx from 'classnames'; import { usePrefix } from '../../internal/usePrefix'; - -const ChatButtonSkeleton = ({ className, size, ...rest }) => { +export interface ChatButtonSkeletonProps { + /** + * Specify an optional className to add. + */ + className?: string; + /** + * Specify the size of the `ChatButtonSkeleton`, from the following list of sizes: + */ + size?: 'sm' | 'md' | 'lg'; +} +const ChatButtonSkeleton = ({ + className, + size, + ...rest +}: ChatButtonSkeletonProps) => { const prefix = usePrefix(); const skeletonClasses = cx( className, diff --git a/packages/react/src/components/ChatButton/ChatButton.js b/packages/react/src/components/ChatButton/ChatButton.js deleted file mode 100644 index 6448fd2fa67d..000000000000 --- a/packages/react/src/components/ChatButton/ChatButton.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright IBM Corp. 2022 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import PropTypes from 'prop-types'; -import React from 'react'; -import classnames from 'classnames'; -import Button from '../Button'; -import { usePrefix } from '../../internal/usePrefix'; - -const ChatButton = React.forwardRef(function ChatButton( - { - className, - children, - disabled, - isQuickAction, - isSelected, - kind, - renderIcon, - size, - ...other - }, - ref -) { - const prefix = usePrefix(); - const classNames = classnames(className, { - [`${prefix}--chat-btn`]: true, - [`${prefix}--chat-btn--with-icon`]: renderIcon, - [`${prefix}--chat-btn--quick-action`]: isQuickAction, - [`${prefix}--chat-btn--quick-action--selected`]: isSelected, - }); - - const allowedSizes = ['sm', 'md', 'lg']; - - if (isQuickAction) { - kind = 'ghost'; - size = 'sm'; - } else { - // Do not allow size larger than `lg` - size = allowedSizes.includes(size) ? size : 'lg'; - } - - return ( - - ); -}); - -ChatButton.propTypes = { - /** - * Provide the contents of your Select - */ - children: PropTypes.node, - - /** - * Specify an optional className to be applied to the node containing the label and the select box - */ - className: PropTypes.string, - - /** - * Specify whether the `ChatButton` should be disabled - */ - disabled: PropTypes.bool, - - /** - * Specify whether the `ChatButton` should be rendered as a quick action button - */ - isQuickAction: PropTypes.bool, - - /** - * Specify whether the quick action `ChatButton` should be rendered as selected. This disables the input - */ - isSelected: PropTypes.bool, - - /** - * Specify the kind of `ChatButton` you want to create - */ - kind: PropTypes.oneOf([ - 'primary', - 'secondary', - 'danger', - 'ghost', - 'tertiary', - ]), - - /** - * Optional prop to specify an icon to be rendered. - * Can be a React component class - */ - renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), - - /** - * Specify the size of the `ChatButton`, from the following list of sizes: - */ - size: PropTypes.oneOf(['sm', 'md', 'lg']), -}; - -export default ChatButton; diff --git a/packages/react/src/components/ChatButton/ChatButton.tsx b/packages/react/src/components/ChatButton/ChatButton.tsx new file mode 100644 index 000000000000..304ff322365c --- /dev/null +++ b/packages/react/src/components/ChatButton/ChatButton.tsx @@ -0,0 +1,157 @@ +/** + * Copyright IBM Corp. 2024 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { type ComponentType, type FunctionComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Button from '../Button'; +import { usePrefix } from '../../internal/usePrefix'; + +export type ChatButtonKind = + | 'primary' + | 'secondary' + | 'danger' + | 'ghost' + | 'tertiary'; +export type ChatButtonSize = 'sm' | 'md' | 'lg'; + +export interface ChatButtonProps + extends React.ButtonHTMLAttributes { + /** + * Provide the contents of your Select + */ + children?: React.ReactNode; + /** + * Specify an optional className to be applied to the node containing the label and the select box + */ + className?: string; + /** + * Specify whether the `ChatButton` should be disabled + */ + disabled?: boolean; + /** + * Specify whether the `ChatButton` should be rendered as a quick action button + */ + isQuickAction?: boolean; + /** + * Specify whether the quick action `ChatButton` should be rendered as selected. This disables the input + */ + isSelected?: boolean; + /** + * Specify the kind of `ChatButton` you want to create + */ + kind?: ChatButtonKind; + /** + * Optional prop to specify an icon to be rendered. + * Can be a React component class + */ + renderIcon?: ComponentType | FunctionComponent; + /** + * Specify the size of the `ChatButton`, from the following list of sizes: + */ + size?: ChatButtonSize; +} + +const ChatButton = React.forwardRef( + function ChatButton( + { + className, + children, + disabled, + isQuickAction, + isSelected, + kind, + renderIcon, + size, + ...other + }: ChatButtonProps, + ref + ) { + const prefix = usePrefix(); + const classNames = classnames(className, { + [`${prefix}--chat-btn`]: true, + [`${prefix}--chat-btn--with-icon`]: renderIcon, + [`${prefix}--chat-btn--quick-action`]: isQuickAction, + [`${prefix}--chat-btn--quick-action--selected`]: isSelected, + }); + + const allowedSizes: ChatButtonSize[] = ['sm', 'md', 'lg']; + + if (isQuickAction) { + kind = 'ghost'; + size = 'sm'; + } else { + // Do not allow size larger than `lg` + size = allowedSizes.includes(size as ChatButtonSize) ? size : 'lg'; + } + + return ( + + ); + } +); + +ChatButton.propTypes = { + /** + * Provide the contents of your Select + */ + children: PropTypes.node, + + /** + * Specify an optional className to be applied to the node containing the label and the select box + */ + className: PropTypes.string, + + /** + * Specify whether the `ChatButton` should be disabled + */ + disabled: PropTypes.bool, + + /** + * Specify whether the `ChatButton` should be rendered as a quick action button + */ + isQuickAction: PropTypes.bool, + + /** + * Specify whether the quick action `ChatButton` should be rendered as selected. This disables the input + */ + isSelected: PropTypes.bool, + + /** + * Specify the kind of `ChatButton` you want to create + */ + kind: PropTypes.oneOf([ + 'primary', + 'secondary', + 'danger', + 'ghost', + 'tertiary', + ]), + + /** + * Optional prop to specify an icon to be rendered. + * Can be a React component class + */ + // @ts-expect-error: PropTypes are not expressive enough to cover this case + renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), + + /** + * Specify the size of the `ChatButton`, from the following list of sizes: + */ + size: PropTypes.oneOf(['sm', 'md', 'lg']), +}; + +export default ChatButton; diff --git a/packages/react/src/components/ChatButton/index.js b/packages/react/src/components/ChatButton/index.tsx similarity index 55% rename from packages/react/src/components/ChatButton/index.js rename to packages/react/src/components/ChatButton/index.tsx index 9dfac91ff41b..4fab393a8433 100644 --- a/packages/react/src/components/ChatButton/index.js +++ b/packages/react/src/components/ChatButton/index.tsx @@ -1,12 +1,14 @@ /** - * Copyright IBM Corp. 2022 + * Copyright IBM Corp. 2024 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import ChatButton from './ChatButton'; +import { type ChatButtonProps } from './ChatButton'; +import { type ChatButtonSkeletonProps } from './ChatButton.Skeleton'; export default ChatButton; -export { ChatButton }; +export { ChatButton, type ChatButtonProps, type ChatButtonSkeletonProps }; export { default as ChatButtonSkeleton } from './ChatButton.Skeleton';