diff --git a/packages/carbon-components-react/scss/components/skeleton-styles/_ai-skeleton-styles.scss b/packages/carbon-components-react/scss/components/skeleton-styles/_ai-skeleton-styles.scss
new file mode 100644
index 000000000000..c07f6ee77f00
--- /dev/null
+++ b/packages/carbon-components-react/scss/components/skeleton-styles/_ai-skeleton-styles.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/skeleton-styles/ai-skeleton-styles';
diff --git a/packages/carbon-components/scss/components/skeleton-styles/_ai-skeleton-styles.scss b/packages/carbon-components/scss/components/skeleton-styles/_ai-skeleton-styles.scss
new file mode 100644
index 000000000000..b75ddc45dd0a
--- /dev/null
+++ b/packages/carbon-components/scss/components/skeleton-styles/_ai-skeleton-styles.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/skeleton-styles/ai-skeleton-styles';
diff --git a/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap
index 013b80199dae..ed0294894503 100644
--- a/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap
+++ b/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap
@@ -17,6 +17,8 @@ Array [
"aiGradientStart02",
"aiInnerShadow",
"aiOverlay",
+ "aiSkeletonBackground",
+ "aiSkeletonElementBackground",
"background",
"backgroundActive",
"backgroundBrand",
diff --git a/packages/react/scss/components/skeleton-styles/_ai-skeleton-styles.scss b/packages/react/scss/components/skeleton-styles/_ai-skeleton-styles.scss
new file mode 100644
index 000000000000..c29b3da911ef
--- /dev/null
+++ b/packages/react/scss/components/skeleton-styles/_ai-skeleton-styles.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/skeleton-styles/ai-skeleton-styles';
diff --git a/packages/react/src/components/AiSkeleton/AiSkeletonIcon.stories.js b/packages/react/src/components/AiSkeleton/AiSkeletonIcon.stories.js
new file mode 100644
index 000000000000..0c435924623e
--- /dev/null
+++ b/packages/react/src/components/AiSkeleton/AiSkeletonIcon.stories.js
@@ -0,0 +1,38 @@
+/**
+ * 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.
+ */
+
+/* eslint-disable no-console */
+
+import React from 'react';
+
+import AiSkeletonIcon from './AiSkeletonIcon';
+
+export default {
+ title: 'Experimental/unstable__AiSkeleton/AiSkeletonIcon',
+ component: AiSkeletonIcon,
+};
+
+const propsSkeleton = {
+ style: {
+ margin: '50px',
+ },
+};
+
+const propsSkeleton2 = {
+ style: {
+ margin: '50px',
+ width: '24px',
+ height: '24px',
+ },
+};
+
+export const Default = () => (
+ <>
+
+
+ >
+);
diff --git a/packages/react/src/components/AiSkeleton/AiSkeletonIcon.tsx b/packages/react/src/components/AiSkeleton/AiSkeletonIcon.tsx
new file mode 100644
index 000000000000..e85843607273
--- /dev/null
+++ b/packages/react/src/components/AiSkeleton/AiSkeletonIcon.tsx
@@ -0,0 +1,47 @@
+/**
+ * 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 PropTypes from 'prop-types';
+import React from 'react';
+import classNames from 'classnames';
+import { usePrefix } from '../../internal/usePrefix';
+import { SkeletonIcon } from '../SkeletonIcon';
+
+interface AiSkeletonIconProps {
+ /**
+ * Specify an optional className to add.
+ */
+ className?: string;
+
+ /**
+ * The CSS styles.
+ */
+ style?: React.CSSProperties;
+}
+
+const AiSkeletonIcon = ({ className, ...rest }: AiSkeletonIconProps) => {
+ const prefix = usePrefix();
+ const AiSkeletonIconClasses = classNames(className, {
+ [`${prefix}--skeleton__icon--ai`]: true,
+ });
+
+ return ;
+};
+
+AiSkeletonIcon.propTypes = {
+ /**
+ * Specify an optional className to add.
+ */
+ className: PropTypes.string,
+
+ /**
+ * The CSS styles.
+ */
+ style: PropTypes.object,
+};
+
+export default AiSkeletonIcon;
diff --git a/packages/react/src/components/AiSkeleton/AiSkeletonPlaceholder.stories.js b/packages/react/src/components/AiSkeleton/AiSkeletonPlaceholder.stories.js
new file mode 100644
index 000000000000..5a6b323c50bf
--- /dev/null
+++ b/packages/react/src/components/AiSkeleton/AiSkeletonPlaceholder.stories.js
@@ -0,0 +1,19 @@
+/**
+ * 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.
+ */
+
+/* eslint-disable no-console */
+
+import React from 'react';
+
+import AiSkeletonPlaceholder from './AiSkeletonPlaceholder';
+
+export default {
+ title: 'Experimental/unstable__AiSkeleton/AiSkeletonPlaceholder',
+ component: AiSkeletonPlaceholder,
+};
+
+export const Default = () => ;
diff --git a/packages/react/src/components/AiSkeleton/AiSkeletonPlaceholder.tsx b/packages/react/src/components/AiSkeleton/AiSkeletonPlaceholder.tsx
new file mode 100644
index 000000000000..cc5e849a4fb9
--- /dev/null
+++ b/packages/react/src/components/AiSkeleton/AiSkeletonPlaceholder.tsx
@@ -0,0 +1,44 @@
+/**
+ * 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 React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import { usePrefix } from '../../internal/usePrefix';
+import { SkeletonPlaceholder } from '../SkeletonPlaceholder';
+
+export interface AiSkeletonPlaceholderProps {
+ /**
+ * Add a custom class to the component to set the height and width
+ */
+ className?: string;
+}
+
+const AiSkeletonPlaceholder = ({
+ className,
+ ...other
+}: AiSkeletonPlaceholderProps) => {
+ const prefix = usePrefix();
+ const AiSkeletonPlaceholderClasses = classNames(
+ { className, [`${prefix}--skeleton__placeholder--ai`]: true },
+ className
+ );
+
+ return (
+
+ );
+};
+
+AiSkeletonPlaceholder.propTypes = {
+ /**
+ * Add a custom class to the component
+ * to set the height and width
+ */
+ className: PropTypes.string,
+};
+
+export default AiSkeletonPlaceholder;
diff --git a/packages/react/src/components/AiSkeleton/AiSkeletonText.stories.js b/packages/react/src/components/AiSkeleton/AiSkeletonText.stories.js
new file mode 100644
index 000000000000..5f75ea23a228
--- /dev/null
+++ b/packages/react/src/components/AiSkeleton/AiSkeletonText.stories.js
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+/* eslint-disable no-console */
+
+import React from 'react';
+
+import AiSkeletonText from './AiSkeletonText';
+
+export default {
+ title: 'Experimental/unstable__AiSkeleton/AiSkeletonText',
+ component: AiSkeletonText,
+};
+
+export const Default = () => ;
+
+export const Playground = (args) => ;
+
+Playground.args = {
+ heading: false,
+ paragraph: false,
+ width: '100%',
+ lineCount: 3,
+};
+
+Playground.argTypes = {
+ className: {
+ control: false,
+ },
+ heading: {
+ control: {
+ type: 'boolean',
+ },
+ },
+ paragraph: {
+ control: {
+ type: 'boolean',
+ },
+ },
+ width: {
+ control: {
+ type: 'text',
+ },
+ },
+ lineCount: {
+ control: {
+ type: 'number',
+ },
+ },
+};
diff --git a/packages/react/src/components/AiSkeleton/AiSkeletonText.tsx b/packages/react/src/components/AiSkeleton/AiSkeletonText.tsx
new file mode 100644
index 000000000000..69a1b3a085e1
--- /dev/null
+++ b/packages/react/src/components/AiSkeleton/AiSkeletonText.tsx
@@ -0,0 +1,73 @@
+/**
+ * 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 PropTypes from 'prop-types';
+import React from 'react';
+import classNames from 'classnames';
+import { usePrefix } from '../../internal/usePrefix';
+import { SkeletonText } from '../SkeletonText';
+
+interface AiSkeletonTextProps {
+ /**
+ * Specify an optional className to be applied to the container node.
+ */
+ className?: string;
+
+ /**
+ * Generates skeleton text at a larger size.
+ */
+ heading?: boolean;
+
+ /**
+ * The number of lines shown if paragraph is true.
+ */
+ lineCount?: number;
+
+ /**
+ * Set this to true to generate multiple lines of text.
+ */
+ paragraph?: boolean;
+
+ /**
+ * Width (in px or %) of single line of text or max-width of paragraph lines.
+ */
+ width?: string;
+}
+
+const AiSkeletonText = ({ className, ...rest }: AiSkeletonTextProps) => {
+ const prefix = usePrefix();
+ const aiSkeletonTextClasses = classNames(className, {
+ [`${prefix}--skeleton__text--ai`]: true,
+ });
+
+ return ;
+};
+
+AiSkeletonText.propTypes = {
+ /**
+ * Specify an optional className to be applied to the container node
+ */
+ className: PropTypes.string,
+ /**
+ * generates skeleton text at a larger size
+ */
+ heading: PropTypes.bool,
+ /**
+ * the number of lines shown if paragraph is true
+ */
+ lineCount: PropTypes.number,
+ /**
+ * will generate multiple lines of text
+ */
+ paragraph: PropTypes.bool,
+ /**
+ * width (in px or %) of single line of text or max-width of paragraph lines
+ */
+ width: PropTypes.string,
+};
+
+export default AiSkeletonText;
diff --git a/packages/react/src/components/AiSkeleton/index.tsx b/packages/react/src/components/AiSkeleton/index.tsx
new file mode 100644
index 000000000000..439f4ce25736
--- /dev/null
+++ b/packages/react/src/components/AiSkeleton/index.tsx
@@ -0,0 +1,12 @@
+/**
+ * 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 AiSkeletonPlaceholder from './AiSkeletonPlaceholder';
+import AiSkeletonIcon from './AiSkeletonIcon';
+import AiSkeletonText from './AiSkeletonText';
+
+export { AiSkeletonText, AiSkeletonIcon, AiSkeletonPlaceholder };
diff --git a/packages/react/src/index.js b/packages/react/src/index.js
index b60de814261e..d3fd15860de2 100644
--- a/packages/react/src/index.js
+++ b/packages/react/src/index.js
@@ -305,6 +305,12 @@ export {
SlugContent as unstable__SlugContent,
SlugActions as unstable__SlugActions,
} from './components/Slug';
+
+export {
+ AiSkeletonText as unstable__AiSkeletonText,
+ AiSkeletonIcon as unstable__AiSkeletonIcon,
+ AiSkeletonPlaceholder as unstable__AiSkeletonPlaceholder,
+} from './components/AiSkeleton';
export {
ChatButton as unstable__ChatButton,
ChatButtonSkeleton as unstable__ChatButtonSkeleton,
diff --git a/packages/styles/__tests__/__snapshots__/styles-test.js.snap b/packages/styles/__tests__/__snapshots__/styles-test.js.snap
index 6dd6b5054b11..8e05a7caa4f1 100644
--- a/packages/styles/__tests__/__snapshots__/styles-test.js.snap
+++ b/packages/styles/__tests__/__snapshots__/styles-test.js.snap
@@ -617,6 +617,11 @@ Array [
"importPath": "@carbon/styles/scss/components/skeleton-styles/skeleton-styles",
"relativePath": "scss/components/skeleton-styles/skeleton-styles",
},
+ Object {
+ "filepath": "scss/components/skeleton-styles/_ai-skeleton-styles.scss",
+ "importPath": "@carbon/styles/scss/components/skeleton-styles/ai-skeleton-styles",
+ "relativePath": "scss/components/skeleton-styles/ai-skeleton-styles",
+ },
Object {
"filepath": "scss/components/slider/_index.scss",
"importPath": "@carbon/styles/scss/components/slider",
diff --git a/packages/styles/files.js b/packages/styles/files.js
index 6bb799fec74c..75bd138e0133 100644
--- a/packages/styles/files.js
+++ b/packages/styles/files.js
@@ -142,6 +142,7 @@ const files = [
'scss/components/select/_select.scss',
'scss/components/skeleton-styles/_index.scss',
'scss/components/skeleton-styles/_skeleton-styles.scss',
+ 'scss/components/skeleton-styles/_ai-skeleton-styles.scss',
'scss/components/slider/_index.scss',
'scss/components/slider/_slider.scss',
'scss/components/slug/_index.scss',
diff --git a/packages/styles/scss/__tests__/theme-test.js b/packages/styles/scss/__tests__/theme-test.js
index 0e166aed8762..933bdc1a2e10 100644
--- a/packages/styles/scss/__tests__/theme-test.js
+++ b/packages/styles/scss/__tests__/theme-test.js
@@ -162,6 +162,8 @@ describe('@carbon/styles/scss/theme', () => {
"ai-border-start",
"ai-border-end",
"ai-drop-shadow",
+ "ai-skeleton-background",
+ "ai-skeleton-element-background",
"ai-overlay",
"slug-callout-caret-center",
"slug-callout-caret-bottom",
diff --git a/packages/styles/scss/components/skeleton-styles/_ai-skeleton-styles.scss b/packages/styles/scss/components/skeleton-styles/_ai-skeleton-styles.scss
new file mode 100644
index 000000000000..9d2b24431a70
--- /dev/null
+++ b/packages/styles/scss/components/skeleton-styles/_ai-skeleton-styles.scss
@@ -0,0 +1,66 @@
+//
+// 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 '../../config' as *;
+@use '../../theme';
+@use '../../utilities/convert';
+
+@keyframes ai-skeleton-animation {
+ 0% {
+ transform: translateX(-100%);
+ }
+
+ 100% {
+ transform: translateX(100%);
+ }
+}
+
+/// AI Skeleton styles
+/// @access public
+/// @group skeleton
+@mixin ai-skeleton-styles {
+ .#{$prefix}--skeleton__text--ai,
+ .#{$prefix}--skeleton__placeholder--ai,
+ .#{$prefix}--skeleton__icon--ai {
+ overflow: hidden;
+ background: theme.$ai-skeleton-background;
+ }
+
+ .#{$prefix}--skeleton__text--ai::before,
+ .#{$prefix}--skeleton__placeholder--ai::before,
+ .#{$prefix}--skeleton__icon--ai::before {
+ animation: 1250ms ease-in-out ai-skeleton-animation infinite;
+ background: linear-gradient(
+ to right,
+ rgba(theme.get('ai-skeleton-element-background'), 0) 0%,
+ rgba(theme.get('ai-skeleton-element-background'), 0.5) 50%,
+ rgba(theme.get('ai-skeleton-element-background'), 0) 100%
+ );
+ }
+
+ .#{$prefix}--skeleton__placeholder--ai::before,
+ .#{$prefix}--skeleton__icon--ai::before {
+ inline-size: 200%;
+ }
+
+ // //skeleton placeholder
+ .#{$prefix}--skeleton__placeholder--ai {
+ border-radius: convert.to-rem(8px);
+ }
+
+ //skeleton text
+ .#{$prefix}--skeleton__text--ai {
+ border-radius: convert.to-rem(16px);
+ }
+
+ //skeleton icon
+ .#{$prefix}--skeleton__icon--ai {
+ border-radius: convert.to-rem(2px);
+ }
+}
+
+// rgba($ai-skeleton-element-background, 1)
diff --git a/packages/styles/scss/components/skeleton-styles/_index.scss b/packages/styles/scss/components/skeleton-styles/_index.scss
index 6db579792184..f42f370d822e 100644
--- a/packages/styles/scss/components/skeleton-styles/_index.scss
+++ b/packages/styles/scss/components/skeleton-styles/_index.scss
@@ -6,6 +6,9 @@
//
@forward 'skeleton-styles';
+@forward 'ai-skeleton-styles';
@use 'skeleton-styles';
+@use 'ai-skeleton-styles';
@include skeleton-styles.skeleton-styles;
+@include ai-skeleton-styles.ai-skeleton-styles;
diff --git a/packages/themes/src/g10.js b/packages/themes/src/g10.js
index 57010fe81d56..b4dba55dd464 100644
--- a/packages/themes/src/g10.js
+++ b/packages/themes/src/g10.js
@@ -9,6 +9,7 @@ import {
// Blue
blue10,
blue20,
+ blue20Hover,
blue30,
blue40,
blue60,
@@ -233,6 +234,10 @@ export const aiAuraHoverEnd = rgba(white, 0);
export const slugCalloutShadowOuter01 = rgba(blue70, 0.25);
export const slugCalloutShadowOuter02 = rgba(black, 0.1);
+// AI skeleton
+export const aiSkeletonBackground = blue20Hover;
+export const aiSkeletonElementBackground = blue100;
+
// AI Modal tokens
export const aiOverlay = rgba(blue100, 0.5);
diff --git a/packages/themes/src/g100.js b/packages/themes/src/g100.js
index a4cd52fdbdf7..f064bbe5dc23 100644
--- a/packages/themes/src/g100.js
+++ b/packages/themes/src/g100.js
@@ -12,6 +12,7 @@ import {
blue40,
blue60,
blue70,
+ blue70Hover,
blue80,
blue100,
@@ -238,6 +239,10 @@ export const aiAuraHoverEnd = rgba(black, 0);
export const slugCalloutShadowOuter01 = rgba(blue80, 0.25);
export const slugCalloutShadowOuter02 = rgba(black, 0.65);
+// AI skeleton
+export const aiSkeletonBackground = blue70Hover;
+export const aiSkeletonElementBackground = blue100;
+
// AI Modal tokens
export const aiOverlay = rgba(blue100, 0.5);
diff --git a/packages/themes/src/g90.js b/packages/themes/src/g90.js
index d394fac245a7..541277860acf 100644
--- a/packages/themes/src/g90.js
+++ b/packages/themes/src/g90.js
@@ -12,6 +12,7 @@ import {
blue40,
blue60,
blue70,
+ blue70Hover,
blue80,
blue100,
@@ -239,6 +240,10 @@ export const aiAuraHoverEnd = rgba(black, 0);
export const slugCalloutShadowOuter01 = rgba(blue80, 0.25);
export const slugCalloutShadowOuter02 = rgba(black, 0.65);
+// AI skeleton
+export const aiSkeletonBackground = blue70Hover;
+export const aiSkeletonElementBackground = blue100;
+
// AI Modal tokens
export const aiOverlay = rgba(blue100, 0.5);
diff --git a/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap b/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap
index 991d6d77023c..20d230f3bbef 100644
--- a/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap
+++ b/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap
@@ -273,6 +273,8 @@ Array [
"ai-border-start",
"ai-border-end",
"ai-drop-shadow",
+ "ai-skeleton-background",
+ "ai-skeleton-element-background",
"ai-overlay",
"slug-callout-caret-center",
"slug-callout-caret-bottom",
diff --git a/packages/themes/src/tokens/__tests__/metadata-test.js b/packages/themes/src/tokens/__tests__/metadata-test.js
index e27f2ccaab98..af39472abb05 100644
--- a/packages/themes/src/tokens/__tests__/metadata-test.js
+++ b/packages/themes/src/tokens/__tests__/metadata-test.js
@@ -1065,6 +1065,14 @@ test('metadata', () => {
"name": "ai-drop-shadow",
"type": "color",
},
+ Object {
+ "name": "ai-skeleton-background",
+ "type": "color",
+ },
+ Object {
+ "name": "ai-skeleton-element-background",
+ "type": "color",
+ },
Object {
"name": "ai-overlay",
"type": "color",
diff --git a/packages/themes/src/tokens/v11TokenGroup.js b/packages/themes/src/tokens/v11TokenGroup.js
index 08c1bfefcfe2..fe024e7e7b00 100644
--- a/packages/themes/src/tokens/v11TokenGroup.js
+++ b/packages/themes/src/tokens/v11TokenGroup.js
@@ -382,6 +382,8 @@ export const ai = TokenGroup.create({
'ai-border-start',
'ai-border-end',
'ai-drop-shadow',
+ 'ai-skeleton-background',
+ 'ai-skeleton-element-background',
'ai-overlay',
// Caret tokens
'slug-callout-caret-center',
diff --git a/packages/themes/src/white.js b/packages/themes/src/white.js
index bb2a67c55432..bfedc4095c7e 100644
--- a/packages/themes/src/white.js
+++ b/packages/themes/src/white.js
@@ -9,6 +9,7 @@ import {
// Blue
blue10,
blue20,
+ blue20Hover,
blue30,
blue40,
blue60,
@@ -233,6 +234,10 @@ export const aiAuraHoverEnd = rgba(white, 0);
export const slugCalloutShadowOuter01 = rgba(blue70, 0.25);
export const slugCalloutShadowOuter02 = rgba(black, 0.1);
+// AI skeleton
+export const aiSkeletonBackground = blue20Hover;
+export const aiSkeletonElementBackground = blue100;
+
// AI Modal tokens
export const aiOverlay = rgba(blue100, 0.5);