diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
index f2be17fd003e..ef8a9eb4f750 100644
--- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
+++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
@@ -12,33 +12,7 @@ Map {
"type": "string",
},
"aiTextLabel": [Function],
- "align": Object {
- "args": Array [
- Array [
- "top",
- "top-left",
- "top-start",
- "top-right",
- "top-end",
- "bottom",
- "bottom-left",
- "bottom-start",
- "bottom-right",
- "bottom-end",
- "left",
- "left-bottom",
- "left-end",
- "left-top",
- "left-start",
- "right",
- "right-bottom",
- "right-end",
- "right-top",
- "right-start",
- ],
- ],
- "type": "oneOf",
- },
+ "align": [Function],
"aria-label": Object {
"type": "string",
},
@@ -10952,33 +10926,7 @@ Map {
"type": "string",
},
"aiTextLabel": [Function],
- "align": Object {
- "args": Array [
- Array [
- "top",
- "top-left",
- "top-start",
- "top-right",
- "top-end",
- "bottom",
- "bottom-left",
- "bottom-start",
- "bottom-right",
- "bottom-end",
- "left",
- "left-bottom",
- "left-end",
- "left-top",
- "left-start",
- "right",
- "right-bottom",
- "right-end",
- "right-top",
- "right-start",
- ],
- ],
- "type": "oneOf",
- },
+ "align": [Function],
"aria-label": Object {
"type": "string",
},
diff --git a/packages/react/src/components/AILabel/index.js b/packages/react/src/components/AILabel/index.js
deleted file mode 100644
index 0ef644a03c3e..000000000000
--- a/packages/react/src/components/AILabel/index.js
+++ /dev/null
@@ -1,274 +0,0 @@
-/**
- * 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.
- */
-
-import cx from 'classnames';
-import PropTypes from 'prop-types';
-import React from 'react';
-
-import { usePrefix } from '../../internal/usePrefix';
-import {
- Toggletip,
- ToggletipButton,
- ToggletipContent,
- ToggletipActions,
-} from '../Toggletip';
-import { IconButton } from '../IconButton';
-import { Undo } from '@carbon/icons-react';
-import { useId } from '../../internal/useId';
-import deprecate from '../../prop-types/deprecate';
-
-export const AILabelContent = React.forwardRef(function AILabelContent(
- { children, className },
- ref
-) {
- const prefix = usePrefix();
-
- const hasAILabelActions = React.Children.toArray(children).some(
- (child) => child.type?.displayName === 'AILabelActions'
- );
-
- const aiLabelContentClasses = cx(className, {
- [`${prefix}--slug-content`]: true,
- [`${prefix}--slug-content--with-actions`]: hasAILabelActions,
- });
-
- return (
-
- {children}
-
- );
-});
-
-AILabelContent.displayName = 'AILabelContent';
-AILabelContent.propTypes = {
- /**
- * Specify the content you want rendered inside the slug ToggleTip
- */
- children: PropTypes.node,
-
- /**
- * Specify an optional className to be added to the AI slug callout
- */
- className: PropTypes.string,
-};
-
-export const AILabelActions = React.forwardRef(function AILabelActions(
- { children, className },
- ref
-) {
- const prefix = usePrefix();
-
- const aiLabelActionsClasses = cx(className, {
- [`${prefix}--slug-actions`]: true,
- });
-
- return (
-
- {children}
-
- );
-});
-
-AILabelActions.displayName = 'AILabelActions';
-AILabelActions.propTypes = {
- /**
- * Specify the content you want rendered inside the slug callout toolbar
- */
- children: PropTypes.node,
-
- /**
- * Specify an optional className to be added to the AI slug toolbar
- */
- className: PropTypes.string,
-};
-
-export const AILabel = React.forwardRef(function AILabel(
- {
- aiText = 'AI',
- aiTextLabel,
- textLabel,
- align,
- autoAlign = true,
- children,
- className,
- kind = 'default',
- onRevertClick,
- revertActive,
- revertLabel = 'Revert to AI input',
- slugLabel = 'Show information',
- ['aria-label']: ariaLabel = 'Show information',
- size = 'xs',
- ...rest
- },
- ref
-) {
- const prefix = usePrefix();
- const id = useId('AILabel');
-
- const aiLabelClasses = cx(className, {
- [`${prefix}--slug`]: true,
- [`${prefix}--slug--revert`]: revertActive,
- });
-
- const aiLabelButtonClasses = cx({
- [`${prefix}--slug__button`]: true,
- [`${prefix}--slug__button--${size}`]: size,
- [`${prefix}--slug__button--${kind}`]: kind,
- [`${prefix}--slug__button--inline-with-content`]:
- kind === 'inline' && (aiTextLabel || textLabel),
- });
-
- const handleOnRevertClick = (evt) => {
- if (onRevertClick) {
- onRevertClick(evt);
- }
- };
-
- const ariaLabelText =
- !aiTextLabel && !textLabel
- ? `${aiText} - ${slugLabel || ariaLabel}`
- : `${aiText} - ${aiTextLabel || textLabel}`;
-
- return (
-
- {revertActive ? (
-
-
-
- ) : (
-
-
- {aiText}
- {kind === 'inline' && (aiTextLabel || textLabel) && (
-
- {aiTextLabel || textLabel}
-
- )}
-
- {children}
-
- )}
-
- );
-});
-
-AILabel.displayName = 'AILabel';
-AILabel.propTypes = {
- /**
- * Specify the content you want rendered inside the `AILabel` ToggleTip
- */
- AILabelContent: PropTypes.node,
-
- /**
- * Specify the correct translation of the AI text
- */
- aiText: PropTypes.string,
-
- /**
- * @deprecated
- * Specify additional text to be rendered next to the AI label in the inline variant
- */
- aiTextLabel: deprecate(
- PropTypes.string,
- '`aiTextLabel` on `AILabel` has been deprecated - Please use the `textLabel` prop instead'
- ),
-
- /**
- * Specify how the popover should align with the button
- */
- align: PropTypes.oneOf([
- 'top',
- 'top-left', // deprecated use top-start instead
- 'top-start',
- 'top-right', // deprecated use top-end instead
- 'top-end',
-
- 'bottom',
- 'bottom-left', // deprecated use bottom-start instead
- 'bottom-start',
- 'bottom-right', // deprecated use bottom-end instead
- 'bottom-end',
-
- 'left',
- 'left-bottom', // deprecated use left-end instead
- 'left-end',
- 'left-top', // deprecated use left-start instead
- 'left-start',
-
- 'right',
- 'right-bottom', // deprecated use right-end instead
- 'right-end',
- 'right-top', // deprecated use right-start instead
- 'right-start',
- ]),
-
- /**
- * Specify the text that will be provided to the aria-label of the `AILabel` button
- */
- 'aria-label': PropTypes.string,
-
- /**
- * Will auto-align the popover. This prop is currently experimental and is subject to future changes.
- */
- autoAlign: PropTypes.bool,
-
- /**
- * Specify the content you want rendered inside the `AILabel` ToggleTip
- */
- children: PropTypes.node,
-
- /**
- * Specify an optional className to be added to the `AILabel`
- */
- className: PropTypes.string,
-
- /**
- * Specify the type of `AILabel`, from the following list of types:
- */
- kind: PropTypes.oneOf(['default', 'inline']),
-
- /**
- * Callback function that fires when the revert button is clicked
- */
- onRevertClick: PropTypes.func,
-
- /**
- * Specify whether the revert button should be visible
- */
- revertActive: PropTypes.bool,
-
- /**
- * Specify the text that should be shown when the revert button is hovered
- */
- revertLabel: PropTypes.string,
-
- /**
- * Specify the size of the button, from the following list of sizes:
- */
- size: PropTypes.oneOf(['mini', '2xs', 'xs', 'sm', 'md', 'lg', 'xl']),
-
- /**
- * @deprecated
- * Specify the text that will be provided to the aria-label of the `AILabel` button
- */
- slugLabel: deprecate(
- PropTypes.string,
- '`slugLabel` on `AILabel` has been deprecated - Please use the `ariaLabel` prop instead'
- ),
-
- /**
- * Specify additional text to be rendered next to the AI label in the inline variant
- */
- textLabel: PropTypes.string,
-};
diff --git a/packages/react/src/components/AILabel/index.tsx b/packages/react/src/components/AILabel/index.tsx
new file mode 100644
index 000000000000..f066181b95f7
--- /dev/null
+++ b/packages/react/src/components/AILabel/index.tsx
@@ -0,0 +1,365 @@
+/**
+ * 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.
+ */
+
+import cx from 'classnames';
+import PropTypes from 'prop-types';
+import deprecateValuesWithin from '../../prop-types/deprecateValuesWithin';
+import React from 'react';
+
+import { usePrefix } from '../../internal/usePrefix';
+import {
+ Toggletip,
+ ToggletipButton,
+ ToggletipContent,
+ ToggletipActions,
+} from '../Toggletip';
+import { IconButton } from '../IconButton';
+import { Undo } from '@carbon/icons-react';
+import { useId } from '../../internal/useId';
+import deprecate from '../../prop-types/deprecate';
+
+export type AILabelContentProps = React.HTMLAttributes;
+
+export const AILabelContent = React.forwardRef(function AILabelContent(
+ { className, children, ...rest }: AILabelContentProps,
+ ref
+) {
+ const prefix = usePrefix();
+
+ const hasAILabelActions = React.Children.toArray(children).some((child) => {
+ const item = child as any;
+ item.type?.displayName === 'AILabelActions';
+ });
+
+ const aiLabelContentClasses = cx(className, {
+ [`${prefix}--slug-content`]: true,
+ [`${prefix}--slug-content--with-actions`]: hasAILabelActions,
+ });
+
+ return (
+
+ {children}
+
+ );
+});
+
+AILabelContent.displayName = 'AILabelContent';
+AILabelContent.propTypes = {
+ /**
+ * Specify the content you want rendered inside the slug ToggleTip
+ */
+ children: PropTypes.node,
+
+ /**
+ * Specify an optional className to be added to the AI slug callout
+ */
+ className: PropTypes.string,
+};
+
+export type AILabelActionsProps = React.HTMLAttributes;
+
+export const AILabelActions = React.forwardRef(function AILabelActions(
+ { className, children, ...rest }: AILabelActionsProps,
+ ref
+) {
+ const prefix = usePrefix();
+
+ const aiLabelActionsClasses = cx(className, {
+ [`${prefix}--slug-actions`]: true,
+ });
+
+ return (
+
+ {children}
+
+ );
+});
+
+AILabelActions.displayName = 'AILabelActions';
+AILabelActions.propTypes = {
+ /**
+ * Specify the content you want rendered inside the slug callout toolbar
+ */
+ children: PropTypes.node,
+
+ /**
+ * Specify an optional className to be added to the AI slug toolbar
+ */
+ className: PropTypes.string,
+};
+
+/**
+ * Deprecated popover alignment values.
+ * @deprecated Use NewPopoverAlignment instead.
+ */
+export type DeprecatedAlignment =
+ | 'top-left'
+ | 'top-right'
+ | 'bottom-left'
+ | 'bottom-right'
+ | 'left-bottom'
+ | 'left-top'
+ | 'right-bottom'
+ | 'right-top';
+
+export type NewAlignment =
+ | 'top'
+ | 'bottom'
+ | 'left'
+ | 'right'
+ | 'top-start'
+ | 'top-end'
+ | 'bottom-start'
+ | 'bottom-end'
+ | 'left-end'
+ | 'left-start'
+ | 'right-end'
+ | 'right-start';
+
+export type Alignment = DeprecatedAlignment | NewAlignment;
+
+const propMappingFunction = (deprecatedValue) => {
+ const mapping = {
+ 'top-left': 'top-start',
+ 'top-right': 'top-end',
+ 'bottom-left': 'bottom-start',
+ 'bottom-right': 'bottom-end',
+ 'left-bottom': 'left-end',
+ 'left-top': 'left-start',
+ 'right-bottom': 'right-end',
+ 'right-top': 'right-start',
+ };
+ return mapping[deprecatedValue];
+};
+
+interface AILabelProps {
+ AILabelContent?: React.ReactNode;
+ aiText?: string;
+ aiTextLabel?: string;
+ textLabel?: string;
+ align?: Alignment;
+ autoAlign?: boolean;
+ children?: React.ReactNode;
+ className?: string;
+ kind?: 'default' | 'inline';
+ onRevertClick?: (evt: React.MouseEvent) => void;
+ revertActive?: boolean;
+ revertLabel?: string;
+ size?: 'mini' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
+ 'aria-label'?: string;
+ slugLabel?: string;
+}
+
+export const AILabel = React.forwardRef(
+ function AILabel(
+ {
+ aiText = 'AI',
+ aiTextLabel,
+ textLabel,
+ align,
+ autoAlign = true,
+ children,
+ className,
+ kind = 'default',
+ onRevertClick,
+ revertActive,
+ revertLabel = 'Revert to AI input',
+ slugLabel = 'Show information',
+ ['aria-label']: ariaLabel = 'Show information',
+ size = 'xs',
+ ...rest
+ },
+ ref
+ ) {
+ const prefix = usePrefix();
+ const id = useId('AILabel');
+
+ const aiLabelClasses = cx(className, {
+ [`${prefix}--slug`]: true,
+ [`${prefix}--slug--revert`]: revertActive,
+ });
+
+ const aiLabelButtonClasses = cx({
+ [`${prefix}--slug__button`]: true,
+ [`${prefix}--slug__button--${size}`]: size,
+ [`${prefix}--slug__button--${kind}`]: kind,
+ [`${prefix}--slug__button--inline-with-content`]:
+ kind === 'inline' && (aiTextLabel || textLabel),
+ });
+
+ const handleOnRevertClick = (evt) => {
+ if (onRevertClick) {
+ onRevertClick(evt);
+ }
+ };
+
+ const ariaLabelText =
+ !aiTextLabel && !textLabel
+ ? `${aiText} - ${slugLabel || ariaLabel}`
+ : `${aiText} - ${aiTextLabel || textLabel}`;
+
+ return (
+
+ {revertActive ? (
+
+
+
+ ) : (
+
+
+ {aiText}
+ {kind === 'inline' && (aiTextLabel || textLabel) && (
+
+ {aiTextLabel || textLabel}
+
+ )}
+
+ {children}
+
+ )}
+
+ );
+ }
+);
+
+AILabel.displayName = 'AILabel';
+AILabel.propTypes = {
+ /**
+ * Specify the content you want rendered inside the `AILabel` ToggleTip
+ */
+ AILabelContent: PropTypes.node,
+
+ /**
+ * Specify the correct translation of the AI text
+ */
+ aiText: PropTypes.string,
+
+ /**
+ * @deprecated
+ * Specify additional text to be rendered next to the AI label in the inline variant
+ */
+ aiTextLabel: deprecate(
+ PropTypes.string,
+ '`aiTextLabel` on `AILabel` has been deprecated - Please use the `textLabel` prop instead'
+ ),
+
+ /**
+ * Specify how the popover should align with the button
+ */
+ align: deprecateValuesWithin(
+ PropTypes.oneOf([
+ 'top',
+ 'top-left', // deprecated use top-start instead
+ 'top-right', // deprecated use top-end instead
+
+ 'bottom',
+ 'bottom-left', // deprecated use bottom-start instead
+ 'bottom-right', // deprecated use bottom-end instead
+
+ 'left',
+ 'left-bottom', // deprecated use left-end instead
+ 'left-top', // deprecated use left-start instead
+
+ 'right',
+ 'right-bottom', // deprecated use right-end instead
+ 'right-top', // deprecated use right-start instead
+
+ // new values to match floating-ui
+ 'top-start',
+ 'top-end',
+ 'bottom-start',
+ 'bottom-end',
+ 'left-end',
+ 'left-start',
+ 'right-end',
+ 'right-start',
+ ]),
+ //allowed prop values
+ [
+ 'top',
+ 'top-start',
+ 'top-end',
+ 'bottom',
+ 'bottom-start',
+ 'bottom-end',
+ 'left',
+ 'left-start',
+ 'left-end',
+ 'right',
+ 'right-start',
+ 'right-end',
+ ],
+ //optional mapper function
+ propMappingFunction
+ ),
+
+ /**
+ * Specify the text that will be provided to the aria-label of the `AILabel` button
+ */
+ 'aria-label': PropTypes.string,
+
+ /**
+ * Will auto-align the popover. This prop is currently experimental and is subject to future changes.
+ */
+ autoAlign: PropTypes.bool,
+
+ /**
+ * Specify the content you want rendered inside the `AILabel` ToggleTip
+ */
+ children: PropTypes.node,
+
+ /**
+ * Specify an optional className to be added to the `AILabel`
+ */
+ className: PropTypes.string,
+
+ /**
+ * Specify the type of `AILabel`, from the following list of types:
+ */
+ kind: PropTypes.oneOf(['default', 'inline']),
+
+ /**
+ * Callback function that fires when the revert button is clicked
+ */
+ onRevertClick: PropTypes.func,
+
+ /**
+ * Specify whether the revert button should be visible
+ */
+ revertActive: PropTypes.bool,
+
+ /**
+ * Specify the text that should be shown when the revert button is hovered
+ */
+ revertLabel: PropTypes.string,
+
+ /**
+ * Specify the size of the button, from the following list of sizes:
+ */
+ size: PropTypes.oneOf(['mini', '2xs', 'xs', 'sm', 'md', 'lg', 'xl']),
+
+ /**
+ * @deprecated
+ * Specify the text that will be provided to the aria-label of the `AILabel` button
+ */
+ slugLabel: deprecate(
+ PropTypes.string,
+ '`slugLabel` on `AILabel` has been deprecated - Please use the `ariaLabel` prop instead'
+ ),
+
+ /**
+ * Specify additional text to be rendered next to the AI label in the inline variant
+ */
+ textLabel: PropTypes.string,
+};