diff --git a/e2e/components/ChatButton/ChatButton-test.avt.e2e.js b/e2e/components/ChatButton/ChatButton-test.avt.e2e.js new file mode 100644 index 000000000000..64f3728006dd --- /dev/null +++ b/e2e/components/ChatButton/ChatButton-test.avt.e2e.js @@ -0,0 +1,24 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const { expect, test } = require('@playwright/test'); +const { visitStory } = require('../../test-utils/storybook'); + +test.describe('ChatButton @avt', () => { + test('@avt-default-state', async ({ page }) => { + await visitStory(page, { + component: 'Button', + id: 'experimental-unstable-chatbutton--default', + globals: { + theme: 'white', + }, + }); + await expect(page).toHaveNoACViolations('ChatButton'); + }); +}); diff --git a/e2e/components/ChatButton/ChatButton-test.e2e.js b/e2e/components/ChatButton/ChatButton-test.e2e.js new file mode 100644 index 000000000000..506689a09c21 --- /dev/null +++ b/e2e/components/ChatButton/ChatButton-test.e2e.js @@ -0,0 +1,26 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const { test } = require('@playwright/test'); +const { themes } = require('../../test-utils/env'); +const { snapshotStory } = require('../../test-utils/storybook'); + +test.describe('ChatButton', () => { + themes.forEach((theme) => { + test.describe(theme, () => { + test('default @vrt', async ({ page }) => { + await snapshotStory(page, { + component: 'ChatButton', + id: 'experimental-unstable-chatbutton--default', + theme, + }); + }); + }); + }); +}); diff --git a/packages/carbon-components-react/scss/components/chat-button/_chat-button.scss b/packages/carbon-components-react/scss/components/chat-button/_chat-button.scss new file mode 100644 index 000000000000..6486d7f955a4 --- /dev/null +++ b/packages/carbon-components-react/scss/components/chat-button/_chat-button.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/chat-button/chat-button'; diff --git a/packages/carbon-components-react/scss/components/chat-button/_index.scss b/packages/carbon-components-react/scss/components/chat-button/_index.scss new file mode 100644 index 000000000000..2a93f58c0602 --- /dev/null +++ b/packages/carbon-components-react/scss/components/chat-button/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/chat-button'; diff --git a/packages/carbon-components/scss/components/chat-button/_chat-button.scss b/packages/carbon-components/scss/components/chat-button/_chat-button.scss new file mode 100644 index 000000000000..3356ea2e1480 --- /dev/null +++ b/packages/carbon-components/scss/components/chat-button/_chat-button.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/chat-button/chat-button'; diff --git a/packages/carbon-components/scss/components/chat-button/_index.scss b/packages/carbon-components/scss/components/chat-button/_index.scss new file mode 100644 index 000000000000..1c2ed0de5cdd --- /dev/null +++ b/packages/carbon-components/scss/components/chat-button/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/chat-button'; diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 27ed75d275f6..d589f1f2fde7 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -9696,6 +9696,66 @@ Map { }, }, }, + "unstable__ChatButton" => Object { + "$$typeof": Symbol(react.forward_ref), + "propTypes": Object { + "children": Object { + "type": "node", + }, + "className": Object { + "type": "string", + }, + "disabled": Object { + "type": "bool", + }, + "isQuickAction": Object { + "type": "bool", + }, + "isSelected": Object { + "type": "bool", + }, + "kind": Object { + "args": Array [ + Array [ + "primary", + "secondary", + "danger", + "ghost", + "tertiary", + ], + ], + "type": "oneOf", + }, + "size": Object { + "args": Array [ + Array [ + "sm", + "md", + "lg", + ], + ], + "type": "oneOf", + }, + }, + "render": [Function], + }, + "unstable__ChatButtonSkeleton" => Object { + "propTypes": Object { + "className": Object { + "type": "string", + }, + "size": Object { + "args": Array [ + Array [ + "sm", + "md", + "lg", + ], + ], + "type": "oneOf", + }, + }, + }, "unstable__FluidComboBox" => Object { "$$typeof": Symbol(react.forward_ref), "propTypes": Object { diff --git a/packages/react/scss/components/chat-button/_chat-button.scss b/packages/react/scss/components/chat-button/_chat-button.scss new file mode 100644 index 000000000000..c4bc30c2d3cb --- /dev/null +++ b/packages/react/scss/components/chat-button/_chat-button.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/chat-button/chat-button'; diff --git a/packages/react/scss/components/chat-button/_index.scss b/packages/react/scss/components/chat-button/_index.scss new file mode 100644 index 000000000000..8756e252b492 --- /dev/null +++ b/packages/react/scss/components/chat-button/_index.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/chat-button'; diff --git a/packages/react/src/__tests__/index-test.js b/packages/react/src/__tests__/index-test.js index c97af0534eda..40c89429b1b9 100644 --- a/packages/react/src/__tests__/index-test.js +++ b/packages/react/src/__tests__/index-test.js @@ -247,6 +247,8 @@ describe('Carbon Components React', () => { "unstable_Pagination", "unstable_Text", "unstable_TextDirection", + "unstable__ChatButton", + "unstable__ChatButtonSkeleton", "unstable__FluidComboBox", "unstable__FluidComboBoxSkeleton", "unstable__FluidDatePicker", diff --git a/packages/react/src/components/ChatButton/ChatButton.Skeleton.js b/packages/react/src/components/ChatButton/ChatButton.Skeleton.js new file mode 100644 index 000000000000..8056365c7f4d --- /dev/null +++ b/packages/react/src/components/ChatButton/ChatButton.Skeleton.js @@ -0,0 +1,38 @@ +/** + * 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 cx from 'classnames'; +import { usePrefix } from '../../internal/usePrefix'; + +const ChatButtonSkeleton = ({ className, size, ...rest }) => { + const prefix = usePrefix(); + const skeletonClasses = cx( + className, + `${prefix}--skeleton`, + `${prefix}--btn`, + `${prefix}--chat-btn`, + { [`${prefix}--layout--size-${size}`]: size } + ); + + return
; +}; + +ChatButtonSkeleton.propTypes = { + /** + * Specify an optional className to add. + */ + className: PropTypes.string, + + /** + * Specify the size of the `ChatButtonSkeleton`, from the following list of sizes: + */ + size: PropTypes.oneOf(['sm', 'md', 'lg']), +}; + +export default ChatButtonSkeleton; diff --git a/packages/react/src/components/ChatButton/ChatButton.js b/packages/react/src/components/ChatButton/ChatButton.js new file mode 100644 index 000000000000..6f181e854ecb --- /dev/null +++ b/packages/react/src/components/ChatButton/ChatButton.js @@ -0,0 +1,100 @@ +/** + * 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, + size, + ...other + }, + ref +) { + const prefix = usePrefix(); + const classNames = classnames(className, { + [`${prefix}--chat-btn`]: true, + [`${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', + ]), + + /** + * 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.stories.js b/packages/react/src/components/ChatButton/ChatButton.stories.js new file mode 100644 index 000000000000..8f2d940cb18d --- /dev/null +++ b/packages/react/src/components/ChatButton/ChatButton.stories.js @@ -0,0 +1,111 @@ +/** + * 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 React from 'react'; +import { ChatButton, ChatButtonSkeleton } from './'; +import { Add } from '@carbon/icons-react'; +import './chat-button-story.scss'; + +export default { + title: 'Experimental/unstable__ChatButton', + component: ChatButton, + parameters: {}, + argTypes: { + onChange: { + action: 'onChange', + table: { + disable: true, + }, + }, + children: { + table: { + disable: true, + }, + }, + className: { + table: { + disable: true, + }, + }, + defaultValue: { + table: { + disable: true, + }, + }, + id: { + table: { + disable: true, + }, + }, + light: { + table: { + disable: true, + }, + }, + }, +}; + +export const Default = () => ( +
+
+

Sizes

+
+ + Primary + + + Primary + + + Primary + +
+
+

Kinds

+
+ + Primary + + + Secondary + + + Tertiary + + + Ghost + + + Danger + +
+
+

Quick action

+
+ + Quick action + + + Selected and Enabled + + + Selected and Disabled + + + Disabled + +
+ +
+

Skeleton

+
+ + + +
+
+); diff --git a/packages/react/src/components/ChatButton/chat-button-story.scss b/packages/react/src/components/ChatButton/chat-button-story.scss new file mode 100644 index 000000000000..390e52faf6e7 --- /dev/null +++ b/packages/react/src/components/ChatButton/chat-button-story.scss @@ -0,0 +1,7 @@ +div[class*='test-button-'] { + margin-bottom: 4rem; + + & > * { + margin-right: 2rem; + } +} diff --git a/packages/react/src/components/ChatButton/index.js b/packages/react/src/components/ChatButton/index.js new file mode 100644 index 000000000000..9dfac91ff41b --- /dev/null +++ b/packages/react/src/components/ChatButton/index.js @@ -0,0 +1,12 @@ +/** + * 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 ChatButton from './ChatButton'; + +export default ChatButton; +export { ChatButton }; +export { default as ChatButtonSkeleton } from './ChatButton.Skeleton'; diff --git a/packages/react/src/index.js b/packages/react/src/index.js index da345daba76f..b60de814261e 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -305,3 +305,7 @@ export { SlugContent as unstable__SlugContent, SlugActions as unstable__SlugActions, } from './components/Slug'; +export { + ChatButton as unstable__ChatButton, + ChatButtonSkeleton as unstable__ChatButtonSkeleton, +} from './components/ChatButton'; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index d7d6d1094655..20ad3504b494 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -157,6 +157,10 @@ export { SlugContent as unstable__SlugContent, SlugActions as unstable__SlugActions, } from './components/Slug'; +export { + ChatButton as unstable__ChatButton, + ChatButtonSkeleton as unstable__ChatButtonSkeleton, +} from './components/ChatButton'; export * from './components/Stack'; export * from './components/Tooltip'; export { diff --git a/packages/styles/__tests__/__snapshots__/styles-test.js.snap b/packages/styles/__tests__/__snapshots__/styles-test.js.snap index 1218321f1810..6dd6b5054b11 100644 --- a/packages/styles/__tests__/__snapshots__/styles-test.js.snap +++ b/packages/styles/__tests__/__snapshots__/styles-test.js.snap @@ -127,6 +127,16 @@ Array [ "importPath": "@carbon/styles/scss/components/button/tokens", "relativePath": "scss/components/button/tokens", }, + Object { + "filepath": "scss/components/chat-button/_chat-button.scss", + "importPath": "@carbon/styles/scss/components/chat-button/chat-button", + "relativePath": "scss/components/chat-button/chat-button", + }, + Object { + "filepath": "scss/components/chat-button/_index.scss", + "importPath": "@carbon/styles/scss/components/chat-button", + "relativePath": "scss/components/chat-button", + }, Object { "filepath": "scss/components/checkbox/_checkbox.scss", "importPath": "@carbon/styles/scss/components/checkbox/checkbox", diff --git a/packages/styles/files.js b/packages/styles/files.js index b3e6537c806b..6bb799fec74c 100644 --- a/packages/styles/files.js +++ b/packages/styles/files.js @@ -44,6 +44,8 @@ const files = [ 'scss/components/button/_button.scss', 'scss/components/button/_index.scss', 'scss/components/button/_tokens.scss', + 'scss/components/chat-button/_chat-button.scss', + 'scss/components/chat-button/_index.scss', 'scss/components/checkbox/_checkbox.scss', 'scss/components/checkbox/_index.scss', 'scss/components/code-snippet/_code-snippet.scss', diff --git a/packages/styles/scss/components/_index.scss b/packages/styles/scss/components/_index.scss index 9d5f88bb42db..7119485e72c1 100644 --- a/packages/styles/scss/components/_index.scss +++ b/packages/styles/scss/components/_index.scss @@ -9,6 +9,7 @@ @use 'aspect-ratio'; @use 'breadcrumb'; @use 'button'; +@use 'chat-button'; @use 'checkbox'; @use 'code-snippet'; @use 'combo-box'; diff --git a/packages/styles/scss/components/chat-button/_chat-button.scss b/packages/styles/scss/components/chat-button/_chat-button.scss new file mode 100644 index 000000000000..29395c0ea7be --- /dev/null +++ b/packages/styles/scss/components/chat-button/_chat-button.scss @@ -0,0 +1,69 @@ +// +// Copyright IBM Corp. 2016, 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. +// + +@use '../button'; +@use '../../config' as *; +@use '../../theme' as *; +@use '../../type' as *; +@use '../../utilities/convert'; + +@mixin chat-button { + .#{$prefix}--chat-btn { + border-radius: convert.to-rem(24px); + } + + .#{$prefix}--chat-btn.#{$prefix}--btn--md { + border-radius: convert.to-rem(20px); + } + + .#{$prefix}--chat-btn.#{$prefix}--btn--sm { + border-radius: convert.to-rem(16px); + } + + // Quick action button + .#{$prefix}--chat-btn--quick-action { + align-items: center; + border: 1px solid $link-primary; + } + + .#{$prefix}--chat-btn--quick-action:hover:not(:active):not([disabled]) { + border-color: transparent; + background: $background-hover; + } + + .#{$prefix}--chat-btn--quick-action.#{$prefix}--btn--ghost:focus { + border-color: $focus; + box-shadow: inset 0 0 0 1px $focus; + } + + .#{$prefix}--chat-btn--quick-action.#{$prefix}--btn--ghost:hover:focus { + border-color: $focus; + box-shadow: inset 0 0 0 1px $focus-inset; + } + + .#{$prefix}--chat-btn--quick-action[disabled], + .#{$prefix}--chat-btn--quick-action[disabled]:hover { + border-color: button.$button-disabled; + color: button.$button-disabled; + } + + .#{$prefix}--chat-btn--quick-action--selected, + .#{$prefix}--chat-btn--quick-action--selected[disabled], + .#{$prefix}--chat-btn--quick-action--selected[disabled]:hover { + border-color: transparent; + background: $background-selected; + color: $text-secondary; + } + + .#{$prefix}--chat-btn--quick-action--selected:hover { + color: $text-secondary; + } + + .#{$prefix}--chat-btn.#{$prefix}--skeleton { + overflow: hidden; + } +} diff --git a/packages/styles/scss/components/chat-button/_index.scss b/packages/styles/scss/components/chat-button/_index.scss new file mode 100644 index 000000000000..e51b0e637392 --- /dev/null +++ b/packages/styles/scss/components/chat-button/_index.scss @@ -0,0 +1,11 @@ +// +// Copyright IBM Corp. 2018, 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. +// + +@forward 'chat-button'; +@use 'chat-button'; + +@include chat-button.chat-button;