diff --git a/src/components/NumberIcon/NumberIcon-v2.module.css b/src/components/NumberIcon/NumberIcon-v2.module.css
new file mode 100644
index 000000000..4b1559188
--- /dev/null
+++ b/src/components/NumberIcon/NumberIcon-v2.module.css
@@ -0,0 +1,84 @@
+@import '../../design-tokens/mixins.css';
+/*------------------------------------*\
+ # NUMBER ICON
+\*------------------------------------*/
+
+/**
+ * Number Icon displays a number enclosed in a circle.
+ *
+ * Centers the number text in the circle.
+ */
+.number-icon {
+ /* Line height set to 1 here since this should only ever be on 1 line and it evens out padding in circle. */
+ line-height: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ /* The circle part of the icon, made with borders. */
+ border: var(--eds-border-width-sm) solid;
+ border-color: inherit;
+ border-radius: var(--eds-border-radius-full);
+
+ cursor: pointer;
+}
+
+/**
+ * Size Variants.
+ */
+.number-icon--size-md {
+ height: 1.5rem;
+ width: 1.5rem;
+ min-width: 1.5rem;
+}
+
+.number-icon--size-lg {
+ height: 2rem;
+ width: 2rem;
+ min-width: 2rem;
+}
+
+/* Colors & Theme */
+
+/**
+ * Interactive States
+ */
+.number-icon--status-default {
+ color: var(--eds-theme-color-text-utility-interactive-primary);
+ border-color: var(--eds-theme-color-border-utility-interactive);
+ background-color: var(--eds-theme-color-background-utility-interactive-no-emphasis);
+
+ &:hover {
+ border-color: var(--eds-theme-color-border-utility-interactive-hover);
+ background-color: var(--eds-theme-color-background-utility-interactive-no-emphasis-hover);
+ }
+
+ &:active {
+ border-color: var(--eds-theme-color-border-utility-interactive-active);
+ background-color: var(--eds-theme-color-background-utility-interactive-no-emphasis-active);
+ }
+}
+
+.number-icon--status-completed {
+ color: var(--eds-theme-color-text-utility-inverse);
+ border-color: var(--eds-theme-color-background-utility-favorable-high-emphasis);
+ background-color: var(--eds-theme-color-background-utility-favorable-high-emphasis);
+
+ &:hover {
+ border-color: var(--eds-theme-color-background-utility-favorable-high-emphasis-hover);
+ background-color: var(--eds-theme-color-background-utility-favorable-high-emphasis-hover);
+ }
+
+ &:active {
+ border-color: var(--eds-theme-color-background-utility-favorable-high-emphasis-active);
+ background-color: var(--eds-theme-color-background-utility-favorable-high-emphasis-active);
+ }
+}
+
+.number-icon--status-incomplete {
+ color: var(--eds-theme-color-text-utility-neutral-secondary);
+ border-color: var(--eds-theme-color-border-utility-neutral-medium-emphasis);
+
+ border-style: dashed;
+ pointer-events: none;
+}
\ No newline at end of file
diff --git a/src/components/NumberIcon/NumberIcon-v2.stories.tsx b/src/components/NumberIcon/NumberIcon-v2.stories.tsx
new file mode 100644
index 000000000..ddc4deba3
--- /dev/null
+++ b/src/components/NumberIcon/NumberIcon-v2.stories.tsx
@@ -0,0 +1,114 @@
+import type { StoryObj, Meta } from '@storybook/react';
+import React from 'react';
+
+import { NumberIcon } from './NumberIcon-v2';
+
+export default {
+ title: 'Components/V2/NumberIcon',
+ component: NumberIcon,
+ parameters: {
+ badges: ['intro-1.0', 'current-2.0'],
+ },
+ args: {
+ 'aria-label': 'number icon example',
+ number: 1,
+ },
+ decorators: [(Story) =>
{Story()}
],
+} as Meta;
+
+type Args = React.ComponentProps;
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const Sizes: Story = {
+ args: {
+ status: 'default',
+ },
+ render: (args) => {
+ return (
+ <>
+
+
+ >
+ );
+ },
+ decorators: [
+ (Story) => {Story()}
,
+ ],
+};
+
+export const Completed: Story = {
+ args: {
+ ...Sizes.args,
+ status: 'completed',
+ },
+ render: Sizes.render,
+ decorators: Sizes.decorators,
+};
+
+export const Incomplete: Story = {
+ args: {
+ ...Sizes.args,
+ status: 'incomplete',
+ },
+ render: Sizes.render,
+ decorators: Sizes.decorators,
+};
+
+/**
+ * `NumberIcon` supports individual digits, with a maximum of two digits. By default,
+ * they are positioned as block-level elements. use `flex` or `display` to update positioning.
+ */
+export const DifferentNumbers: Story = {
+ /**
+ * Disables controls for args that have no affect on this story
+ */
+ argTypes: {
+ number: {
+ table: {
+ disable: true,
+ },
+ },
+ 'aria-label': {
+ table: {
+ disable: true,
+ },
+ },
+ },
+ render: (args) => (
+
+ {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 21, 32, 43, 54, 65, 76, 87, 98].map(
+ (number) => (
+
+ ),
+ )}
+
+ ),
+};
+
+/**
+ * This Implementation example shows how to use Number Icon to build a stepper-like component.
+ *
+ * - incomplete rows are aligned with each number icon to show progress
+ */
+export const NumberIconList: Story = {
+ parameters: {
+ badges: ['intro-1.0', 'current-2.0', 'implementationExample'],
+ },
+ render: () => (
+
+
+
+
+
+
+
+
+ ),
+};
diff --git a/src/components/NumberIcon/NumberIcon-v2.tsx b/src/components/NumberIcon/NumberIcon-v2.tsx
new file mode 100644
index 000000000..a08d35289
--- /dev/null
+++ b/src/components/NumberIcon/NumberIcon-v2.tsx
@@ -0,0 +1,75 @@
+import clsx from 'clsx';
+import React from 'react';
+
+import type { Size } from '../../util/variant-types';
+
+import Text from '../Text';
+import styles from './NumberIcon-v2.module.css';
+
+export interface Props {
+ // Component API
+ /**
+ * (Required) Screen-reader text for the number icon.
+ */
+ 'aria-label': string;
+ /**
+ * CSS class names that can be appended to the component.
+ */
+ className?: string;
+ // Design API
+ /**
+ * Whether `NumberIcon` can be focused on, clicked, etc.
+ */
+ isInteractive?: boolean;
+ /**
+ * Number to be shown as the icon. Maximum of two digits.
+ */
+ number?: number;
+ /**
+ * The size of the icon.
+ *
+ * **Default is `"lg"`**.
+ */
+ size?: Extract;
+ /**
+ * Indication of the status of the referenced item
+ */
+ status?: 'completed' | 'incomplete' | 'default';
+}
+
+/**
+ * `import {NumberIcon} from "@chanzuckerberg/eds";`
+ *
+ * Treats a numeral as an icon by wrapping it in a container and adding color/spacing.
+ *
+ */
+export const NumberIcon = ({
+ className,
+ isInteractive = false,
+ number,
+ status = 'default',
+ size = 'lg',
+ ...other
+}: Props) => {
+ const componentClassName = clsx(
+ className,
+ styles['number-icon'],
+ size && styles[`number-icon--size-${size}`],
+ status && styles[`number-icon--status-${status}`],
+ );
+
+ return (
+
+ {number}
+
+ );
+};
+
+NumberIcon.displayName = 'NumberIcon';
diff --git a/src/components/NumberIcon/index.ts b/src/components/NumberIcon/index.ts
index 27abe5f81..096c360ce 100644
--- a/src/components/NumberIcon/index.ts
+++ b/src/components/NumberIcon/index.ts
@@ -1 +1,2 @@
export { NumberIcon as default } from './NumberIcon';
+export { NumberIcon as NumberIconV2 } from './NumberIcon-v2';