+ );
+}
+```
+
+## Kind
+
+Icon indicators can take the form of failed, caution major, caution minor,
+undefined, succeeded, normal, in-progressm incomplete, not started, pending,
+unknown, and informative.
+
+## Size
+
+Icon indicators have two size options 16 and 20. The default is 16.
+
+## Customizing the label
+
+You can set a string to customize the label of the Icon indicator.
+
+## Component API
+
+
+
+## Feedback
+
+Help us improve this component by providing feedback, asking questions on Slack,
+or updating this file on
+[GitHub](https://github.com/carbon-design-system/carbon/edit/main/packages/react/src/components/IconIndicator/IconIndicator.mdx).
diff --git a/packages/react/src/components/IconIndicator/IconIndicator.stories.js b/packages/react/src/components/IconIndicator/IconIndicator.stories.js
new file mode 100644
index 000000000000..5136ccb2def7
--- /dev/null
+++ b/packages/react/src/components/IconIndicator/IconIndicator.stories.js
@@ -0,0 +1,73 @@
+/**
+ * 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.
+ */
+
+import React from 'react';
+import IconIndicator from '.';
+import { IconIndicatorKinds } from './index';
+import mdx from './IconIndicator.mdx';
+
+export default {
+ title: 'Experimental/StatusIndicators/unstable__IconIndicator',
+ component: IconIndicator,
+ parameters: {
+ docs: {
+ page: mdx,
+ },
+ },
+};
+
+export const Default = () => {
+ return (
+
+ {IconIndicatorKinds.map((type) => (
+ <>
+
+
+ >
+ ))}
+
+ );
+};
+
+const PlaygroundStory = (props) => {
+ return ;
+};
+
+export const Playground = PlaygroundStory.bind({});
+
+Playground.args = {
+ label: 'Custom label',
+ kind: 'failed',
+ size: 16,
+};
+
+Playground.argTypes = {
+ label: {
+ control: {
+ type: 'text',
+ },
+ },
+ kind: {
+ control: {
+ type: 'select',
+ },
+ options: IconIndicatorKinds,
+ },
+ size: {
+ control: {
+ type: 'select',
+ },
+ options: [16, 20],
+ },
+};
diff --git a/packages/react/src/components/IconIndicator/__tests__/IconIndicator-test.js b/packages/react/src/components/IconIndicator/__tests__/IconIndicator-test.js
new file mode 100644
index 000000000000..6d122583ec1a
--- /dev/null
+++ b/packages/react/src/components/IconIndicator/__tests__/IconIndicator-test.js
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+import { render, screen } from '@testing-library/react';
+import React from 'react';
+import IconIndicator from '../index';
+
+describe('IconIndicator', () => {
+ it('should use a custom label', () => {
+ render();
+ expect(screen.getByText('label')).toBeInTheDocument();
+ });
+
+ it('should update with size prop', () => {
+ render();
+ expect(screen.getByText('label')).toHaveClass('cds--icon-indicator--20');
+ });
+
+ it('should update with kind prop', () => {
+ render();
+ expect(document.querySelector('svg')).toHaveClass(
+ 'cds--icon-indicator--pending'
+ );
+ });
+
+ it('should support a custom class name on the outermost element', () => {
+ const { container } = render(
+
+ );
+ expect(container.firstChild).toHaveClass('custom-class');
+ });
+
+ it('should support a ref on the outermost element', () => {
+ const ref = jest.fn();
+ const { container } = render(
+
+ );
+ expect(ref).toHaveBeenCalledWith(container.firstChild);
+ });
+});
diff --git a/packages/react/src/components/IconIndicator/docs/overview.mdx b/packages/react/src/components/IconIndicator/docs/overview.mdx
new file mode 100644
index 000000000000..747a86cea343
--- /dev/null
+++ b/packages/react/src/components/IconIndicator/docs/overview.mdx
@@ -0,0 +1,12 @@
+## Live demo
+
+
diff --git a/packages/react/src/components/IconIndicator/index.tsx b/packages/react/src/components/IconIndicator/index.tsx
new file mode 100644
index 000000000000..91f190734ef0
--- /dev/null
+++ b/packages/react/src/components/IconIndicator/index.tsx
@@ -0,0 +1,133 @@
+/**
+ * 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.
+ */
+
+import PropTypes from 'prop-types';
+import React from 'react';
+import cx from 'classnames';
+import { usePrefix } from '../../internal/usePrefix';
+import {
+ ErrorFilled,
+ CheckmarkFilled,
+ WarningAltFilled,
+ WarningAltInvertedFilled,
+ UndefinedFilled,
+ InProgress,
+ Incomplete,
+ CircleDash,
+ UnknownFilled,
+ WarningSquareFilled,
+ CheckmarkOutline,
+ PendingFilled,
+} from '@carbon/icons-react';
+
+export const IconIndicatorKinds = [
+ 'failed',
+ 'caution-major',
+ 'caution-minor',
+ 'undefined',
+ 'succeeded',
+ 'normal',
+ 'in-progress',
+ 'incomplete',
+ 'not-started',
+ 'pending',
+ 'unknown',
+ 'informative',
+];
+
+const iconTypes = {
+ failed: ErrorFilled,
+ ['caution-major']: WarningAltInvertedFilled,
+ ['caution-minor']: WarningAltFilled,
+ undefined: UndefinedFilled,
+ succeeded: CheckmarkFilled,
+ normal: CheckmarkOutline,
+ ['in-progress']: InProgress,
+ incomplete: Incomplete,
+ ['not-started']: CircleDash,
+ pending: PendingFilled,
+ unknown: UnknownFilled,
+ informative: WarningSquareFilled,
+};
+
+export type IconIndicatorKind = (typeof IconIndicatorKinds)[number];
+
+interface IconIndicatorProps {
+ /**
+ * Specify an optional className to add.
+ */
+ className?: string;
+
+ /**
+ * Specify the kind of icon to be used
+ */
+ kind: IconIndicatorKind;
+
+ /**
+ * Label next to the icon
+ */
+ label: string;
+
+ /**
+ * Specify the size of the Icon Indicator. Defaults to 16.
+ */
+ size?: 16 | 20;
+}
+
+export const IconIndicator = React.forwardRef(function IconIndicatorContent(
+ {
+ className: customClassName,
+ kind,
+ label,
+ size = 16,
+ ...rest
+ }: IconIndicatorProps,
+ ref: React.Ref
+) {
+ const prefix = usePrefix();
+ const classNames = cx(`${prefix}--icon-indicator`, customClassName, {
+ [`${prefix}--icon-indicator--20`]: size == 20,
+ });
+
+ const IconForKind = iconTypes[kind];
+ if (!IconForKind) {
+ return null;
+ }
+ return (
+
+
+ {label}
+
+ );
+});
+
+IconIndicator.propTypes = {
+ /**
+ * Specify an optional className to add.
+ */
+ className: PropTypes.string,
+
+ /**
+ * Specify the kind of the Icon Indicator
+ */
+ kind: PropTypes.oneOf(IconIndicatorKinds).isRequired,
+
+ /**
+ * Label next to the icon.
+ */
+ label: PropTypes.string.isRequired,
+
+ /**
+ * Specify the size of the Icon Indicator. Defaults to 16.
+ */
+ size: PropTypes.oneOf([16, 20]),
+};
+
+export default IconIndicator;
diff --git a/packages/react/src/index.js b/packages/react/src/index.js
index 8700ebd8142e..1319bc6b99df 100644
--- a/packages/react/src/index.js
+++ b/packages/react/src/index.js
@@ -335,3 +335,5 @@ export {
ChatButton as unstable__ChatButton,
ChatButtonSkeleton as unstable__ChatButtonSkeleton,
} from './components/ChatButton';
+
+export { IconIndicator as unstable__IconIndicator } from './components/IconIndicator';
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
index 7adc10746533..b60be8450aad 100644
--- a/packages/react/src/index.ts
+++ b/packages/react/src/index.ts
@@ -189,3 +189,4 @@ export * from './components/Tooltip/DefinitionTooltip';
export * from './components/Theme';
export * from './internal/usePrefix';
export { useIdPrefix } from './internal/useIdPrefix';
+export { IconIndicator as unstable__IconIndicator } from './components/IconIndicator';
diff --git a/packages/styles/__tests__/__snapshots__/styles-test.js.snap b/packages/styles/__tests__/__snapshots__/styles-test.js.snap
index ef00ac6812af..dcba62e42ef3 100644
--- a/packages/styles/__tests__/__snapshots__/styles-test.js.snap
+++ b/packages/styles/__tests__/__snapshots__/styles-test.js.snap
@@ -407,6 +407,16 @@ Array [
"importPath": "@carbon/styles/scss/components/fluid-time-picker",
"relativePath": "scss/components/fluid-time-picker",
},
+ Object {
+ "filepath": "scss/components/icon-indicator/_icon-indicator.scss",
+ "importPath": "@carbon/styles/scss/components/icon-indicator/icon-indicator",
+ "relativePath": "scss/components/icon-indicator/icon-indicator",
+ },
+ Object {
+ "filepath": "scss/components/icon-indicator/_index.scss",
+ "importPath": "@carbon/styles/scss/components/icon-indicator",
+ "relativePath": "scss/components/icon-indicator",
+ },
Object {
"filepath": "scss/components/inline-loading/_index.scss",
"importPath": "@carbon/styles/scss/components/inline-loading",
diff --git a/packages/styles/files.js b/packages/styles/files.js
index b31759d83e32..d1cd1c82e866 100644
--- a/packages/styles/files.js
+++ b/packages/styles/files.js
@@ -100,6 +100,8 @@ const files = [
'scss/components/fluid-text-input/_index.scss',
'scss/components/fluid-time-picker/_fluid-time-picker.scss',
'scss/components/fluid-time-picker/_index.scss',
+ 'scss/components/icon-indicator/_icon-indicator.scss',
+ 'scss/components/icon-indicator/_index.scss',
'scss/components/inline-loading/_index.scss',
'scss/components/inline-loading/_inline-loading.scss',
'scss/components/link/_index.scss',
diff --git a/packages/styles/scss/_zone.scss b/packages/styles/scss/_zone.scss
index bf79c8074a56..8f78b112fdc6 100644
--- a/packages/styles/scss/_zone.scss
+++ b/packages/styles/scss/_zone.scss
@@ -17,6 +17,7 @@
@use './components/button/tokens' as button;
@use './components/notification/tokens' as notification;
@use './components/tag/tokens' as tag;
+@use './components/icon-indicator/tokens' as icon-indicator;
/// Specify a Map of zones where the key will be used as part of the selector
/// and the value will be a map used to emit CSS Custom Properties for all color
@@ -31,7 +32,8 @@ $zones: (
$-components: (
button.$button-tokens,
notification.$notification-tokens,
- tag.$tag-tokens
+ tag.$tag-tokens,
+ icon-indicator.$status-tokens
);
@each $name, $theme in $zones {
diff --git a/packages/styles/scss/components/_index.scss b/packages/styles/scss/components/_index.scss
index 0877a1b896ec..a8f4126a8f09 100644
--- a/packages/styles/scss/components/_index.scss
+++ b/packages/styles/scss/components/_index.scss
@@ -38,6 +38,7 @@
@use 'fluid-text-input';
@use 'fluid-time-picker';
@use 'form';
+@use 'icon-indicator';
@use 'inline-loading';
@use 'link';
@use 'list';
diff --git a/packages/styles/scss/components/icon-indicator/_icon-indicator.scss b/packages/styles/scss/components/icon-indicator/_icon-indicator.scss
new file mode 100644
index 000000000000..2b91deb6a8a3
--- /dev/null
+++ b/packages/styles/scss/components/icon-indicator/_icon-indicator.scss
@@ -0,0 +1,90 @@
+//
+// 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 '../../theme' as *;
+@use '../../type' as *;
+@use '../../config' as *;
+@use '../../spacing' as *;
+@use '../../colors' as *;
+@use './tokens' as *;
+
+/// icon-indicator styles
+/// @access public
+/// @group tag
+@mixin icon-indicator {
+ .#{$prefix}--icon-indicator {
+ @include type-style('body-compact-01');
+
+ display: flex;
+ color: $text-secondary;
+ }
+
+ .#{$prefix}--icon-indicator svg {
+ align-self: center;
+ margin-inline-end: $spacing-03;
+ }
+
+ .#{$prefix}--icon-indicator--20 {
+ @include type-style('body-compact-02');
+ }
+
+ .#{$prefix}--icon-indicator--failed {
+ fill: $status-red;
+ }
+
+ .#{$prefix}--icon-indicator--caution-major {
+ fill: $status-orange;
+
+ path:first-of-type {
+ fill: $black;
+ }
+ }
+
+ .#{$prefix}--icon-indicator--caution-minor {
+ fill: $status-yellow;
+
+ path:first-of-type {
+ fill: $black;
+ }
+ }
+
+ .#{$prefix}--icon-indicator--undefined {
+ fill: $status-purple;
+ }
+
+ .#{$prefix}--icon-indicator--succeeded {
+ fill: $status-green;
+ }
+
+ .#{$prefix}--icon-indicator--normal {
+ fill: $status-blue;
+ }
+
+ .#{$prefix}--icon-indicator--in-progress {
+ fill: $status-blue;
+ }
+
+ .#{$prefix}--icon-indicator--incomplete {
+ fill: $status-blue;
+ }
+
+ .#{$prefix}--icon-indicator--not-started {
+ fill: $status-gray;
+ }
+
+ .#{$prefix}--icon-indicator--pending {
+ fill: $status-gray;
+ }
+
+ .#{$prefix}--icon-indicator--unknown {
+ fill: $status-gray;
+ }
+
+ .#{$prefix}--icon-indicator--informative {
+ fill: $status-blue;
+ }
+}
diff --git a/packages/styles/scss/components/icon-indicator/_index.scss b/packages/styles/scss/components/icon-indicator/_index.scss
new file mode 100644
index 000000000000..9c2a757521d6
--- /dev/null
+++ b/packages/styles/scss/components/icon-indicator/_index.scss
@@ -0,0 +1,16 @@
+//
+// 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 'icon-indicator';
+@forward 'tokens';
+
+@use '../../theme';
+@use 'icon-indicator';
+@use 'tokens';
+
+@include theme.add-component-tokens(tokens.$status-tokens);
+@include icon-indicator.icon-indicator;
diff --git a/packages/styles/scss/components/icon-indicator/_tokens.scss b/packages/styles/scss/components/icon-indicator/_tokens.scss
new file mode 100644
index 000000000000..253b532172dd
--- /dev/null
+++ b/packages/styles/scss/components/icon-indicator/_tokens.scss
@@ -0,0 +1,196 @@
+//
+// Copyright IBM Corp. 2020
+//
+// 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 'sass:color';
+@use 'sass:map';
+@use '../../config';
+@use '../../colors';
+@use '../../themes';
+@use '../../theme' as *;
+@use '../../utilities/component-tokens';
+@use '@carbon/themes/scss/component-tokens' as status;
+
+// status-red
+$status-red: (
+ fallback: map.get(status.$status-red, white-theme),
+ values: (
+ (
+ theme: themes.$white,
+ value: map.get(status.$status-red, white-theme),
+ ),
+ (
+ theme: themes.$g10,
+ value: map.get(status.$status-red, g-10),
+ ),
+ (
+ theme: themes.$g90,
+ value: map.get(status.$status-red, g-90),
+ ),
+ (
+ theme: themes.$g100,
+ value: map.get(status.$status-red, g-100),
+ ),
+ ),
+) !default;
+
+// status-orange
+$status-orange: (
+ fallback: map.get(status.$status-orange, white-theme),
+ values: (
+ (
+ theme: themes.$white,
+ value: map.get(status.$status-orange, white-theme),
+ ),
+ (
+ theme: themes.$g10,
+ value: map.get(status.$status-orange, g-10),
+ ),
+ (
+ theme: themes.$g90,
+ value: map.get(status.$status-orange, g-90),
+ ),
+ (
+ theme: themes.$g100,
+ value: map.get(status.$status-orange, g-100),
+ ),
+ ),
+) !default;
+
+// status-yellow
+$status-yellow: (
+ fallback: map.get(status.$status-yellow, white-theme),
+ values: (
+ (
+ theme: themes.$white,
+ value: map.get(status.$status-yellow, white-theme),
+ ),
+ (
+ theme: themes.$g10,
+ value: map.get(status.$status-yellow, g-10),
+ ),
+ (
+ theme: themes.$g90,
+ value: map.get(status.$status-yellow, g-90),
+ ),
+ (
+ theme: themes.$g100,
+ value: map.get(status.$status-yellow, g-100),
+ ),
+ ),
+) !default;
+
+// status-green
+$status-green: (
+ fallback: map.get(status.$status-green, white-theme),
+ values: (
+ (
+ theme: themes.$white,
+ value: map.get(status.$status-green, white-theme),
+ ),
+ (
+ theme: themes.$g10,
+ value: map.get(status.$status-green, g-10),
+ ),
+ (
+ theme: themes.$g90,
+ value: map.get(status.$status-green, g-90),
+ ),
+ (
+ theme: themes.$g100,
+ value: map.get(status.$status-green, g-100),
+ ),
+ ),
+) !default;
+
+// status-blue
+$status-blue: (
+ fallback: map.get(status.$status-blue, white-theme),
+ values: (
+ (
+ theme: themes.$white,
+ value: map.get(status.$status-blue, white-theme),
+ ),
+ (
+ theme: themes.$g10,
+ value: map.get(status.$status-blue, g-10),
+ ),
+ (
+ theme: themes.$g90,
+ value: map.get(status.$status-blue, g-90),
+ ),
+ (
+ theme: themes.$g100,
+ value: map.get(status.$status-blue, g-100),
+ ),
+ ),
+) !default;
+
+// status-purple
+$status-purple: (
+ fallback: map.get(status.$status-purple, white-theme),
+ values: (
+ (
+ theme: themes.$white,
+ value: map.get(status.$status-purple, white-theme),
+ ),
+ (
+ theme: themes.$g10,
+ value: map.get(status.$status-purple, g-10),
+ ),
+ (
+ theme: themes.$g90,
+ value: map.get(status.$status-purple, g-90),
+ ),
+ (
+ theme: themes.$g100,
+ value: map.get(status.$status-purple, g-100),
+ ),
+ ),
+) !default;
+
+// status-gray
+$status-gray: (
+ fallback: map.get(status.$status-gray, white-theme),
+ values: (
+ (
+ theme: themes.$white,
+ value: map.get(status.$status-gray, white-theme),
+ ),
+ (
+ theme: themes.$g10,
+ value: map.get(status.$status-gray, g-10),
+ ),
+ (
+ theme: themes.$g90,
+ value: map.get(status.$status-gray, g-90),
+ ),
+ (
+ theme: themes.$g100,
+ value: map.get(status.$status-gray, g-100),
+ ),
+ ),
+) !default;
+
+// Add to $status-tokens map
+$status-tokens: (
+ status-red: $status-red,
+ status-orange: $status-orange,
+ status-yellow: $status-yellow,
+ status-green: $status-green,
+ status-blue: $status-blue,
+ status-purple: $status-purple,
+ status-gray: $status-gray,
+);
+
+// Generate CSS custom properties for each token
+$status-red: component-tokens.get-var($status-red, 'status-red');
+$status-orange: component-tokens.get-var($status-orange, 'status-orange');
+$status-yellow: component-tokens.get-var($status-yellow, 'status-yellow');
+$status-green: component-tokens.get-var($status-green, 'status-green');
+$status-blue: component-tokens.get-var($status-blue, 'status-blue');
+$status-purple: component-tokens.get-var($status-purple, 'status-purple');
+$status-gray: component-tokens.get-var($status-gray, 'status-gray');
diff --git a/packages/themes/scss/_component-tokens.scss b/packages/themes/scss/_component-tokens.scss
index 0769ba109d05..060ba363e555 100644
--- a/packages/themes/scss/_component-tokens.scss
+++ b/packages/themes/scss/_component-tokens.scss
@@ -8,3 +8,4 @@
@forward 'generated/button-tokens';
@forward 'generated/tag-tokens';
@forward 'generated/notification-tokens';
+@forward 'generated/status-tokens';
diff --git a/packages/themes/src/component-tokens/status/index.js b/packages/themes/src/component-tokens/status/index.js
new file mode 100644
index 000000000000..ed8dbbdedc16
--- /dev/null
+++ b/packages/themes/src/component-tokens/status/index.js
@@ -0,0 +1 @@
+export * as statusTokens from './tokens';
diff --git a/packages/themes/src/component-tokens/status/tokens.js b/packages/themes/src/component-tokens/status/tokens.js
new file mode 100644
index 000000000000..b61b50bc5353
--- /dev/null
+++ b/packages/themes/src/component-tokens/status/tokens.js
@@ -0,0 +1,71 @@
+import {
+ red50,
+ red60,
+ orange40,
+ yellow30,
+ purple50,
+ purple60,
+ green40,
+ green50,
+ blue50,
+ blue70,
+ gray50,
+ gray60,
+ white,
+ gray100,
+} from '@carbon/colors';
+
+export const statusRed = {
+ whiteTheme: red60,
+ g10: red60,
+ g90: red50,
+ g100: red50,
+};
+
+export const statusOrange = {
+ whiteTheme: orange40,
+ g10: orange40,
+ g90: orange40,
+ g100: orange40,
+};
+
+export const statusYellow = {
+ whiteTheme: yellow30,
+ g10: yellow30,
+ g90: yellow30,
+ g100: yellow30,
+};
+
+export const statusPurple = {
+ whiteTheme: purple60,
+ g10: purple60,
+ g90: purple50,
+ g100: purple50,
+};
+
+export const statusGreen = {
+ whiteTheme: green50,
+ g10: green50,
+ g90: green40,
+ g100: green40,
+};
+
+export const statusBlue = {
+ whiteTheme: blue70,
+ g10: blue70,
+ g90: blue50,
+ g100: blue50,
+};
+
+export const statusGray = {
+ whiteTheme: gray60,
+ g10: gray60,
+ g90: gray50,
+ g100: gray50,
+};
+export const statusAccessibilityBackground = {
+ whiteTheme: white,
+ g10: white,
+ g90: gray100,
+ g100: gray100,
+};
diff --git a/packages/themes/src/index.js b/packages/themes/src/index.js
index 42843674e8bc..2c84f5e9dbea 100644
--- a/packages/themes/src/index.js
+++ b/packages/themes/src/index.js
@@ -13,6 +13,7 @@ import * as v10 from './v10';
import * as buttonTokens from './component-tokens/button';
import * as tagTokens from './component-tokens/tag';
import * as notificationTokens from './component-tokens/notification';
+import * as statusTokens from './component-tokens/status';
import { formatTokenName } from './tools';
import { unstable_metadata } from './tokens';
@@ -34,6 +35,7 @@ export {
buttonTokens,
tagTokens,
notificationTokens,
+ statusTokens,
unstable_metadata,
formatTokenName,
};
diff --git a/packages/themes/src/tokens/__tests__/metadata-test.js b/packages/themes/src/tokens/__tests__/metadata-test.js
index ce25421ff6a9..8a8e8a92ac97 100644
--- a/packages/themes/src/tokens/__tests__/metadata-test.js
+++ b/packages/themes/src/tokens/__tests__/metadata-test.js
@@ -1273,6 +1273,34 @@ test('metadata', () => {
"name": "notification-action-tertiary-inverse-text-on-color-disabled",
"type": "color",
},
+ Object {
+ "name": "status-red",
+ "type": "color",
+ },
+ Object {
+ "name": "status-orange",
+ "type": "color",
+ },
+ Object {
+ "name": "status-yellow",
+ "type": "color",
+ },
+ Object {
+ "name": "status-purple",
+ "type": "color",
+ },
+ Object {
+ "name": "status-green",
+ "type": "color",
+ },
+ Object {
+ "name": "status-blue",
+ "type": "color",
+ },
+ Object {
+ "name": "status-gray",
+ "type": "color",
+ },
Object {
"name": "tag-background-red",
"type": "color",
diff --git a/packages/themes/src/tokens/components.js b/packages/themes/src/tokens/components.js
index 8c98807421fd..6cb1549ef52b 100644
--- a/packages/themes/src/tokens/components.js
+++ b/packages/themes/src/tokens/components.js
@@ -92,3 +92,17 @@ export const tag = TokenGroup.create({
'tag-hover-warm-gray',
],
});
+
+export const status = TokenGroup.create({
+ name: 'Status',
+ properties: [],
+ tokens: [
+ 'status-red',
+ 'status-orange',
+ 'status-yellow',
+ 'status-purple',
+ 'status-green',
+ 'status-blue',
+ 'status-gray',
+ ],
+});
diff --git a/packages/themes/tasks/build.js b/packages/themes/tasks/build.js
index 9a1e2013b3ba..b4a6559157a6 100644
--- a/packages/themes/tasks/build.js
+++ b/packages/themes/tasks/build.js
@@ -20,6 +20,7 @@ const buildModulesTokensFile = require('./builders/modules-tokens');
const buildModulesButtonTokens = require('./builders/modules-button-tokens');
const buildModulesTagTokens = require('./builders/modules-tag-tokens');
const buildModulesNotificationTokens = require('./builders/modules-notification-tokens');
+const buildModulesStatusTokens = require('./builders/modules-status-tokens');
async function build() {
reporter.info('Building scss files for themes...');
@@ -69,6 +70,12 @@ async function build() {
return buildModulesNotificationTokens();
},
},
+ {
+ filepath: path.join(GENERATED_SCSS_DIR, '_status-tokens.scss'),
+ builder() {
+ return buildModulesStatusTokens();
+ },
+ },
];
for (const { filepath, builder } of files) {
diff --git a/packages/themes/tasks/builders/modules-status-tokens.js b/packages/themes/tasks/builders/modules-status-tokens.js
new file mode 100644
index 000000000000..84c3b292c902
--- /dev/null
+++ b/packages/themes/tasks/builders/modules-status-tokens.js
@@ -0,0 +1,43 @@
+/**
+ * Copyright IBM Corp. 2015, 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 { types: t } = require('@carbon/scss-generator');
+const { TokenFormat } = require('../../src/tokens');
+const { statusTokens } = require('../../src/component-tokens/status');
+const { FILE_BANNER, primitive } = require('./shared');
+const { paramCase } = require('change-case');
+
+function buildThemesFile() {
+ const imports = [t.SassModule('sass:map')];
+
+ const variables = Object.entries(statusTokens).flatMap(
+ ([key, statusToken]) => {
+ return [
+ t.Newline(),
+ t.Assignment({
+ id: t.Identifier(paramCase(key)),
+ init: t.SassMap({
+ properties: Object.entries(statusToken).map(([token, value]) => {
+ const id = TokenFormat.convert({
+ name: token,
+ format: TokenFormat.formats.scss,
+ });
+ return t.SassMapProperty(t.Identifier(id), primitive(value));
+ }),
+ }),
+ default: true,
+ }),
+ ];
+ }
+ );
+
+ return t.StyleSheet([FILE_BANNER, t.Newline(), ...imports, ...variables]);
+}
+
+module.exports = buildThemesFile;
diff --git a/packages/web-components/.storybook/_container.scss b/packages/web-components/.storybook/_container.scss
index 8397ebacc793..19c03457552d 100644
--- a/packages/web-components/.storybook/_container.scss
+++ b/packages/web-components/.storybook/_container.scss
@@ -15,9 +15,11 @@
@use '@carbon/styles/scss/components/button/tokens' as button-tokens;
@use '@carbon/styles/scss/components/notification/tokens' as notification-tokens;
@use '@carbon/styles/scss/components/tag/tokens' as tag-tokens;
+@use '@carbon/styles/scss/components/icon-indicator/tokens' as status-tokens;
@include theme.add-component-tokens(button-tokens.$button-tokens);
@include theme.add-component-tokens(notification-tokens.$notification-tokens);
@include theme.add-component-tokens(tag-tokens.$tag-tokens);
+@include theme.add-component-tokens(status-tokens.$status-tokens);
// Emit the flex-grid styles
@include grid.flex-grid();
diff --git a/packages/web-components/examples/components/icon-indicator/.gitignore b/packages/web-components/examples/components/icon-indicator/.gitignore
new file mode 100644
index 000000000000..d94d6e13e948
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/.gitignore
@@ -0,0 +1,22 @@
+# See https://help.github.com/ignore-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+
+# testing
+/coverage
+
+# production
+/build
+
+# misc
+.DS_Store
+.cache
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
diff --git a/packages/web-components/examples/components/icon-indicator/.sassrc b/packages/web-components/examples/components/icon-indicator/.sassrc
new file mode 100644
index 000000000000..956b9e0a3d8a
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/.sassrc
@@ -0,0 +1,6 @@
+{
+ "includePaths": [
+ "node_modules",
+ "../../node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/packages/web-components/examples/components/icon-indicator/cdn.html b/packages/web-components/examples/components/icon-indicator/cdn.html
new file mode 100644
index 000000000000..b3f88a71d4b4
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/cdn.html
@@ -0,0 +1,30 @@
+
+
+
+
+ @carbon/ibmdotcom-web-components example
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/web-components/examples/components/icon-indicator/index.html b/packages/web-components/examples/components/icon-indicator/index.html
new file mode 100644
index 000000000000..4adcb253ff0e
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/index.html
@@ -0,0 +1,30 @@
+
+
+
+
+ carbon-web-components example
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/web-components/examples/components/icon-indicator/package.json b/packages/web-components/examples/components/icon-indicator/package.json
new file mode 100644
index 000000000000..c94bb213b9a4
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "carbon-web-components-icon-indicator-example",
+ "version": "0.1.0",
+ "private": true,
+ "description": "Sample project for getting started with the Web Components from Carbon.",
+ "license": "Apache-2",
+ "main": "index.html",
+ "scripts": {
+ "build": "vite build",
+ "clean": "rimraf node_modules dist .cache",
+ "dev": "vite"
+ },
+ "dependencies": {
+ "@carbon/styles": "^1.34.0",
+ "@carbon/web-components": "latest",
+ "sass": "^1.64.1"
+ },
+ "devDependencies": {
+ "vite": "5.2.13",
+ "rimraf": "^3.0.2"
+ }
+}
diff --git a/packages/web-components/examples/components/icon-indicator/sandbox.config.json b/packages/web-components/examples/components/icon-indicator/sandbox.config.json
new file mode 100644
index 000000000000..a4df8557d7bf
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/sandbox.config.json
@@ -0,0 +1,3 @@
+{
+ "template": "node"
+}
diff --git a/packages/web-components/examples/components/icon-indicator/src/index.js b/packages/web-components/examples/components/icon-indicator/src/index.js
new file mode 100644
index 000000000000..4143768e5159
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/src/index.js
@@ -0,0 +1,10 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2020, 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 '@carbon/web-components/es/components/icon-indicator/index.js';
diff --git a/packages/web-components/examples/components/icon-indicator/src/styles.scss b/packages/web-components/examples/components/icon-indicator/src/styles.scss
new file mode 100644
index 000000000000..dcbf34e26210
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/src/styles.scss
@@ -0,0 +1,12 @@
+@use '@carbon/styles/scss/reset';
+@use '@carbon/styles/scss/theme';
+@use '@carbon/styles/scss/themes';
+
+@use '@carbon/styles/scss/components/icon-indicator/tokens' as status-tokens;
+@include theme.add-component-tokens(status-tokens.$status-tokens);
+
+:root {
+ @include theme.theme(themes.$white);
+ background-color: var(--cds-background);
+ color: var(--cds-text-primary);
+}
diff --git a/packages/web-components/examples/components/icon-indicator/vite.config.js b/packages/web-components/examples/components/icon-indicator/vite.config.js
new file mode 100644
index 000000000000..1e91b76eb5da
--- /dev/null
+++ b/packages/web-components/examples/components/icon-indicator/vite.config.js
@@ -0,0 +1,12 @@
+import { resolve } from "path";
+import { defineConfig } from "vite";
+
+export default defineConfig({
+ build: {
+ rollupOptions: {
+ input: {
+ main: resolve(__dirname, "index.html"),
+ },
+ },
+ },
+});
diff --git a/packages/web-components/src/components/data-table/stories/data-table-dynamic.stories.ts b/packages/web-components/src/components/data-table/stories/data-table-dynamic.stories.ts
index 487cf2a93d2a..196dbf9cb6ef 100644
--- a/packages/web-components/src/components/data-table/stories/data-table-dynamic.stories.ts
+++ b/packages/web-components/src/components/data-table/stories/data-table-dynamic.stories.ts
@@ -18,6 +18,7 @@ import Download16 from '@carbon/icons/lib/download/16.js';
// @ts-ignore
import Settings16 from '@carbon/icons/lib/settings/16.js';
import '../index';
+import '../../icon-indicator/index';
import storyDocs from './data-table.mdx';
const sizes = {
@@ -186,9 +187,11 @@ export const Default = {
3000
Round robin
Kevin's VM Groups
- Disabled
+
+
+
Load Balancer 1
@@ -196,7 +199,11 @@ export const Default = {
443
Round robin
Maureen's VM Groups
- Starting
+
Load Balancer 2
@@ -204,7 +211,11 @@ export const Default = {
80
DNS delegation
Andrew's VM Groups
- Active
+
Load Balancer 6
@@ -213,8 +224,10 @@ export const Default = {
Round robin
Marc's VM Groups
Disabled
+ >
Load Balancer 4
@@ -222,7 +235,11 @@ export const Default = {
443
Round robin
Mel's VM Groups
- Starting
+
Load Balancer 5
@@ -230,7 +247,11 @@ export const Default = {
80
DNS delegation
Ronja's VM Groups
- Active
+
@@ -308,8 +329,10 @@ export const Playground = {
Round robin
Kevin's VM Groups
Disabled
+ >
Expandable row content
@@ -321,7 +344,11 @@ export const Playground = {
443
Round robin
Maureen's VM Groups
- Starting
+
Expandable row content
@@ -333,7 +360,11 @@ export const Playground = {
80
DNS delegation
Andrew's VM Groups
- Active
+
Expandable row content
@@ -346,8 +377,10 @@ export const Playground = {
Round robin
Marc's VM Groups
Disabled
+ >
Expandable row content
@@ -359,7 +392,11 @@ export const Playground = {
443
Round robin
Mel's VM Groups
- Starting
+
Expandable row content
@@ -371,7 +408,11 @@ export const Playground = {
80
DNS delegation
Ronja's VM Groups
- Active
+
Expandable row content
diff --git a/packages/web-components/src/components/icon-indicator/defs.ts b/packages/web-components/src/components/icon-indicator/defs.ts
new file mode 100644
index 000000000000..96497c6d6d34
--- /dev/null
+++ b/packages/web-components/src/components/icon-indicator/defs.ts
@@ -0,0 +1,70 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2020, 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.
+ */
+
+export enum ICON_INDICATOR_KIND {
+ /**
+ * Failed
+ */
+ FAILED = 'failed',
+
+ /**
+ * Caution major.
+ */
+ 'CAUTION-MAJOR' = 'caution-major',
+
+ /**
+ * Caution minor.
+ */
+ 'CAUTION-MINOR' = 'caution-minor',
+
+ /**
+ * Undefined.
+ */
+ UNDEFINED = 'undefined',
+
+ /**
+ * Succeeded.
+ */
+ SUCCEEDED = 'succeeded',
+
+ /**
+ * Normal.
+ */
+ NORMAL = 'normal',
+
+ /**
+ * In-progress.
+ */
+ 'IN-PROGRESS' = 'in-progress',
+
+ /**
+ * Incomplete.
+ */
+ INCOMPLETE = 'incomplete',
+
+ /**
+ * Not started.
+ */
+ 'NOT-STARTED' = 'not-started',
+
+ /**
+ * Pending.
+ */
+ PENDING = 'pending',
+
+ /**
+ * Unknown.
+ */
+ UNKNOWN = 'unknown',
+
+ /**
+ * Informative.
+ */
+ INFORMATIVE = 'informative',
+}
diff --git a/packages/web-components/src/components/icon-indicator/docs/overview.mdx b/packages/web-components/src/components/icon-indicator/docs/overview.mdx
new file mode 100644
index 000000000000..4314c34fed03
--- /dev/null
+++ b/packages/web-components/src/components/icon-indicator/docs/overview.mdx
@@ -0,0 +1,12 @@
+## Live demo
+
+
diff --git a/packages/web-components/src/components/icon-indicator/icon-indicator.mdx b/packages/web-components/src/components/icon-indicator/icon-indicator.mdx
new file mode 100644
index 000000000000..ae1ebae9ca49
--- /dev/null
+++ b/packages/web-components/src/components/icon-indicator/icon-indicator.mdx
@@ -0,0 +1,40 @@
+import { ArgTypes, Markdown, Meta } from '@storybook/blocks';
+import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn';
+import * as IconIndicatorStories from './icon-indicator.stories';
+
+
+
+# Icon indicator
+
+The icon-indicator component is useful for communicating severity level
+information to users. The shapes and colors, communicate severity that enables
+users to quickly assess and identify status and respond accordingly.
+
+> 💡 Check our
+> [Stackblitz](https://stackblitz.com/github/carbon-design-system/carbon/tree/main/packages/web-components/examples/components/icon-indicator)
+> example implementation.
+
+[![Edit carbon-web-components](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/carbon-design-system/carbon/tree/main/packages/web-components/examples/components/icon-indicator)
+
+## Getting started
+
+Here's a quick example to get you started.
+
+### JS (via import)
+
+```javascript
+import '@carbon/web-components/es/components/icon-indicator/index.js';
+```
+
+{`${cdnJs({ components: ['icon-indicator'] })}`}
+{`${cdnCss()}`}
+
+### HTML
+
+```html
+
+```
+
+## `` attributes and properties
+
+
diff --git a/packages/web-components/src/components/icon-indicator/icon-indicator.scss b/packages/web-components/src/components/icon-indicator/icon-indicator.scss
new file mode 100644
index 000000000000..7834788b926d
--- /dev/null
+++ b/packages/web-components/src/components/icon-indicator/icon-indicator.scss
@@ -0,0 +1,67 @@
+//
+// Copyright IBM Corp. 2019, 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.
+//
+
+$css--plex: true !default;
+
+@use '@carbon/styles/scss/config' as *;
+@use '@carbon/styles/scss/components/icon-indicator/index' as *;
+
+:host(#{$prefix}-icon-indicator) {
+ @extend .#{$prefix}--icon-indicator;
+}
+
+:host(#{$prefix}-icon-indicator[size='20']) {
+ @extend .#{$prefix}--icon-indicator--20;
+}
+
+:host(#{$prefix}-icon-indicator[kind='failed']) svg {
+ @extend .#{$prefix}--icon-indicator--failed;
+}
+
+:host(#{$prefix}-icon-indicator[kind='caution-major']) svg {
+ @extend .#{$prefix}--icon-indicator--caution-major;
+}
+
+:host(#{$prefix}-icon-indicator[kind='caution-minor']) svg {
+ @extend .#{$prefix}--icon-indicator--caution-minor;
+}
+
+:host(#{$prefix}-icon-indicator[kind='undefined']) svg {
+ @extend .#{$prefix}--icon-indicator--undefined;
+}
+
+:host(#{$prefix}-icon-indicator[kind='succeeded']) svg {
+ @extend .#{$prefix}--icon-indicator--succeeded;
+}
+
+:host(#{$prefix}-icon-indicator[kind='normal']) svg {
+ @extend .#{$prefix}--icon-indicator--normal;
+}
+
+:host(#{$prefix}-icon-indicator[kind='in-progress']) svg {
+ @extend .#{$prefix}--icon-indicator--in-progress;
+}
+
+:host(#{$prefix}-icon-indicator[kind='incomplete']) svg {
+ @extend .#{$prefix}--icon-indicator--incomplete;
+}
+
+:host(#{$prefix}-icon-indicator[kind='not-started']) svg {
+ @extend .#{$prefix}--icon-indicator--not-started;
+}
+
+:host(#{$prefix}-icon-indicator[kind='pending']) svg {
+ @extend .#{$prefix}--icon-indicator--pending;
+}
+
+:host(#{$prefix}-icon-indicator[kind='unknown']) svg {
+ @extend .#{$prefix}--icon-indicator--unknown;
+}
+
+:host(#{$prefix}-icon-indicator[kind='informative']) svg {
+ @extend .#{$prefix}--icon-indicator--informative;
+}
diff --git a/packages/web-components/src/components/icon-indicator/icon-indicator.stories.ts b/packages/web-components/src/components/icon-indicator/icon-indicator.stories.ts
new file mode 100644
index 000000000000..7a3f1273018d
--- /dev/null
+++ b/packages/web-components/src/components/icon-indicator/icon-indicator.stories.ts
@@ -0,0 +1,86 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2019, 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.
+ */
+
+import { html } from 'lit';
+import './index';
+import { ICON_INDICATOR_KIND } from './defs';
+
+const kinds = [
+ 'failed',
+ 'caution-major',
+ 'caution-minor',
+ 'undefined',
+ 'succeeded',
+ 'normal',
+ 'in-progress',
+ 'incomplete',
+ 'not-started',
+ 'pending',
+ 'unknown',
+ 'informative',
+];
+
+export const Default = {
+ render: () => html`
+
+ ${kinds.map(
+ (kind) => html`
+
+
+ `
+ )}
+
+ `,
+};
+
+const defaultArgs = {
+ label: 'Custom label',
+ kind: ICON_INDICATOR_KIND.FAILED,
+ size: 16,
+};
+
+const controls = {
+ size: {
+ control: 'select',
+ description:
+ 'Specify the size of the Icon Indicator. Currently supports either 16 (default) or 20 sizes.',
+ options: [16, 20],
+ },
+ label: {
+ control: 'text',
+ description: 'Label next to the icon.',
+ },
+ kind: {
+ control: 'select',
+ description: 'Specify the kind of the Icon Indicator.',
+ options: kinds,
+ },
+};
+
+export const Playground = {
+ argTypes: controls,
+ args: defaultArgs,
+ render: ({ label, size, kind }) =>
+ html` `,
+};
+
+const meta = {
+ title: 'Experimental/Status Indicators/Icon Indicator',
+};
+
+export default meta;
diff --git a/packages/web-components/src/components/icon-indicator/icon-indicator.ts b/packages/web-components/src/components/icon-indicator/icon-indicator.ts
new file mode 100644
index 000000000000..b1320285add4
--- /dev/null
+++ b/packages/web-components/src/components/icon-indicator/icon-indicator.ts
@@ -0,0 +1,127 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2019, 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.
+ */
+
+import { LitElement, html } from 'lit';
+import { property } from 'lit/decorators.js';
+import { prefix } from '../../globals/settings';
+import { ICON_INDICATOR_KIND } from './defs';
+import ErrorFilled16 from '@carbon/icons/lib/error--filled/16.js';
+import ErrorFilled20 from '@carbon/icons/lib/error--filled/20.js';
+import WarningAltInvertedFilled16 from '@carbon/icons/lib/warning--alt-inverted--filled/16.js';
+import WarningAltInvertedFilled20 from '@carbon/icons/lib/warning--alt-inverted--filled/20.js';
+import WarningAltFilled16 from '@carbon/icons/lib/warning--alt--filled/16.js';
+import WarningAltFilled20 from '@carbon/icons/lib/warning--alt--filled/20.js';
+import UndefinedFilled16 from '@carbon/icons/lib/undefined--filled/16.js';
+import UndefinedFilled20 from '@carbon/icons/lib/undefined--filled/20.js';
+import CheckmarkFilled16 from '@carbon/icons/lib/checkmark--filled/16.js';
+import CheckmarkFilled20 from '@carbon/icons/lib/checkmark--filled/20.js';
+import CheckmarkOutline16 from '@carbon/icons/lib/checkmark--outline/16.js';
+import CheckmarkOutline20 from '@carbon/icons/lib/checkmark--outline/20.js';
+import InProgress16 from '@carbon/icons/lib/in-progress/16.js';
+import InProgress20 from '@carbon/icons/lib/in-progress/20.js';
+import Incomplete16 from '@carbon/icons/lib/incomplete/16.js';
+import Incomplete20 from '@carbon/icons/lib/incomplete/20.js';
+import CircleDash16 from '@carbon/icons/lib/circle-dash/16.js';
+import CircleDash20 from '@carbon/icons/lib/circle-dash/20.js';
+import Pending16 from '@carbon/icons/lib/pending--filled/16.js';
+import Pending20 from '@carbon/icons/lib/pending--filled/20.js';
+import UnknownFilled16 from '@carbon/icons/lib/unknown--filled/16.js';
+import UnknownFilled20 from '@carbon/icons/lib/unknown--filled/20.js';
+import WarningSquareFilled16 from '@carbon/icons/lib/warning-square--filled/16.js';
+import WarningSquareFilled20 from '@carbon/icons/lib/warning-square--filled/20.js';
+export { ICON_INDICATOR_KIND };
+
+import styles from './icon-indicator.scss?lit';
+import { carbonElement as customElement } from '../../globals/decorators/carbon-element';
+
+const iconMap = {
+ [ICON_INDICATOR_KIND.FAILED]: {
+ 16: ErrorFilled16,
+ 20: ErrorFilled20,
+ },
+ [ICON_INDICATOR_KIND['CAUTION-MAJOR']]: {
+ 16: WarningAltInvertedFilled16,
+ 20: WarningAltInvertedFilled20,
+ },
+ [ICON_INDICATOR_KIND['CAUTION-MINOR']]: {
+ 16: WarningAltFilled16,
+ 20: WarningAltFilled20,
+ },
+ [ICON_INDICATOR_KIND.UNDEFINED]: {
+ 16: UndefinedFilled16,
+ 20: UndefinedFilled20,
+ },
+ [ICON_INDICATOR_KIND.SUCCEEDED]: {
+ 16: CheckmarkFilled16,
+ 20: CheckmarkFilled20,
+ },
+ [ICON_INDICATOR_KIND.NORMAL]: {
+ 16: CheckmarkOutline16,
+ 20: CheckmarkOutline20,
+ },
+ [ICON_INDICATOR_KIND['IN-PROGRESS']]: {
+ 16: InProgress16,
+ 20: InProgress20,
+ },
+ [ICON_INDICATOR_KIND.INCOMPLETE]: {
+ 16: Incomplete16,
+ 20: Incomplete20,
+ },
+ [ICON_INDICATOR_KIND['NOT-STARTED']]: {
+ 16: CircleDash16,
+ 20: CircleDash20,
+ },
+ [ICON_INDICATOR_KIND.PENDING]: {
+ 16: Pending16,
+ 20: Pending20,
+ },
+ [ICON_INDICATOR_KIND.UNKNOWN]: {
+ 16: UnknownFilled16,
+ 20: UnknownFilled20,
+ },
+ [ICON_INDICATOR_KIND.INFORMATIVE]: {
+ 16: WarningSquareFilled16,
+ 20: WarningSquareFilled20,
+ },
+};
+
+/**
+ * Icon Indicator.
+ *
+ * @element cds-icon-indicator
+ */
+@customElement(`${prefix}-icon-indicator`)
+class CDSIconIndicator extends LitElement {
+ /**
+ * Icon indicator should be size 16 or 20
+ */
+ @property()
+ size = 16;
+
+ /**
+ * Label next to the icon.
+ */
+ @property()
+ label!: string;
+
+ /**
+ * Icon Indicator kind
+ */
+ @property()
+ kind!: ICON_INDICATOR_KIND;
+
+ render() {
+ const icon = iconMap[this.kind]?.[this.size];
+ return html`${icon()}${this.label}`;
+ }
+
+ static styles = styles; // `styles` here is a `CSSResult` generated by custom Vite loader
+}
+
+export default CDSIconIndicator;
diff --git a/packages/web-components/src/components/icon-indicator/index.ts b/packages/web-components/src/components/icon-indicator/index.ts
new file mode 100644
index 000000000000..4f59fbfc8300
--- /dev/null
+++ b/packages/web-components/src/components/icon-indicator/index.ts
@@ -0,0 +1,10 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2021, 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.
+ */
+
+import './icon-indicator';
diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts
index b655fce5cbbb..64996334ee96 100644
--- a/packages/web-components/src/index.ts
+++ b/packages/web-components/src/index.ts
@@ -67,6 +67,7 @@ export { default as CDSDropdownSkeleton } from './components/dropdown/dropdown-s
export { default as CDSFormItem } from './components/form/form-item';
export { default as CDSFormGroup } from './components/form-group/form-group';
export { default as CDSIconButton } from './components/icon-button/icon-button';
+export { default as CDSIconIndicator } from './components/icon-indicator/icon-indicator';
export { default as CDSTextInput } from './components/text-input/text-input';
export { default as CDSTextInputSkeleton } from './components/text-input/text-input-skeleton';
export { default as CDSInlineLoading } from './components/inline-loading/inline-loading';