Skip to content

Commit

Permalink
fix(typescript): adds TypeScript types to ChatButton & Skeleton (#17316)
Browse files Browse the repository at this point in the history
* fix(17291): rename .js to .tsx for preserve file history

* fix(typescript): adds TypeScript types to ChatButto & Skeleton
  • Loading branch information
2nikhiltom committed Sep 3, 2024
1 parent 3f338ce commit 87eeed1
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 114 deletions.
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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,
Expand Down
109 changes: 0 additions & 109 deletions packages/react/src/components/ChatButton/ChatButton.js

This file was deleted.

157 changes: 157 additions & 0 deletions packages/react/src/components/ChatButton/ChatButton.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLButtonElement> {
/**
* 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<HTMLButtonElement, ChatButtonProps>(
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 (
<Button
disabled={disabled}
className={classNames}
kind={kind}
ref={ref}
size={size as ChatButtonSize}
renderIcon={renderIcon}
{...other}>
{children}
</Button>
);
}
);

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;
Original file line number Diff line number Diff line change
@@ -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';

0 comments on commit 87eeed1

Please sign in to comment.