-
+
diff --git a/packages/eui/src/components/steps/step_horizontal.styles.ts b/packages/eui/src/components/steps/step_horizontal.styles.ts
index 118e820eae1..ef1a7b11460 100644
--- a/packages/eui/src/components/steps/step_horizontal.styles.ts
+++ b/packages/eui/src/components/steps/step_horizontal.styles.ts
@@ -76,6 +76,7 @@ export const euiStepHorizontalStyles = (euiThemeContext: UseEuiTheme) => {
// Adjust the size of the step number and connecting lines based on size
m: _generateStepSizeAndInset(euiStep.numberSize),
s: _generateStepSizeAndInset(euiStep.numberXSSize),
+ xs: _generateStepSizeAndInset(euiStep.numberXXSSize),
// Note: these selectors must be nested because focus/hover state
// is on the parent container, but affects specific children
enabled: css`
diff --git a/packages/eui/src/components/steps/step_horizontal.tsx b/packages/eui/src/components/steps/step_horizontal.tsx
index e420d7bcd64..ef71467f8d1 100644
--- a/packages/eui/src/components/steps/step_horizontal.tsx
+++ b/packages/eui/src/components/steps/step_horizontal.tsx
@@ -14,7 +14,12 @@ import React, {
MouseEventHandler,
} from 'react';
import { CommonProps } from '../common';
-import { EuiStepNumber, EuiStepStatus } from './step_number';
+import { useEuiTheme } from '../../services';
+import {
+ EuiStepNumber,
+ EuiStepNumberProps,
+ EuiStepStatus,
+} from './step_number';
import { EuiStepsHorizontalSizes } from './steps_horizontal';
import {
useI18nCompleteStep,
@@ -26,7 +31,6 @@ import {
useI18nErrorsStep,
useI18nLoadingStep,
} from './step_strings';
-import { useEuiTheme } from '../../services';
import {
euiStepHorizontalStyles,
euiStepHorizontalNumberStyles,
@@ -55,6 +59,13 @@ export interface EuiStepHorizontalProps
size?: EuiStepsHorizontalSizes;
}
+// The titleSize map is not 1 to 1; small == xs on the titleSize map
+const stepNumberSizeMap: Record = {
+ xs: 'none',
+ s: 'xs',
+ m: 'm',
+};
+
export const EuiStepHorizontal: FunctionComponent = ({
className,
step = 1,
@@ -119,7 +130,7 @@ export const EuiStepHorizontal: FunctionComponent = ({
className="euiStepHorizontal__number"
status={status}
number={step}
- titleSize={size === 's' ? 'xs' : 'm'} // The titleSize map is not 1 to 1; small == xs on the titleSize map
+ titleSize={stepNumberSizeMap[size]}
css={cssNumberStyles}
/>
diff --git a/packages/eui/src/components/steps/step_number.styles.ts b/packages/eui/src/components/steps/step_number.styles.ts
index 794f201c7b1..8dae030b78f 100644
--- a/packages/eui/src/components/steps/step_number.styles.ts
+++ b/packages/eui/src/components/steps/step_number.styles.ts
@@ -13,6 +13,7 @@ import {
euiFontSizeFromScale,
euiCanAnimate,
euiAnimScale,
+ logicalSizeCSS,
} from '../../global_styling';
import { UseEuiTheme } from '../../services';
import { euiStepVariables } from './step.styles';
@@ -60,6 +61,12 @@ export const euiStepNumberStyles = (euiThemeContext: UseEuiTheme) => {
euiFontSizeFromScale('xs', euiTheme)
)}
`,
+ none: css`
+ ${createStepsNumber(
+ euiStep.numberXXSSize,
+ euiFontSizeFromScale('xs', euiTheme)
+ )}
+ `,
// status
incomplete: css`
background-color: transparent;
@@ -141,5 +148,6 @@ export const euiStepNumberContentStyles = ({ euiTheme }: UseEuiTheme) => {
display: inline-block;
transform: translateY(-${euiTheme.border.width.thick});
`,
+ none: css(logicalSizeCSS(euiTheme.size.s)),
};
};
diff --git a/packages/eui/src/components/steps/step_number.test.tsx b/packages/eui/src/components/steps/step_number.test.tsx
index 0ff343c6867..68ae3209257 100644
--- a/packages/eui/src/components/steps/step_number.test.tsx
+++ b/packages/eui/src/components/steps/step_number.test.tsx
@@ -23,7 +23,7 @@ describe('EuiStepNumber', () => {
});
describe('props', () => {
- describe('has titleSize', () => {
+ describe('titleSize', () => {
it('is rendered', () => {
const { container } = render(
@@ -31,6 +31,18 @@ describe('EuiStepNumber', () => {
expect(container.firstChild).toMatchSnapshot();
});
+
+ describe('none', () => {
+ it('renders no visible number', () => {
+ const { container } = render(
+
+ );
+
+ expect(
+ container.querySelector('.euiStepNumber__number')
+ ).not.toBeInTheDocument();
+ });
+ });
});
describe('status', () => {
@@ -42,6 +54,38 @@ describe('EuiStepNumber', () => {
expect(container.firstChild).toMatchSnapshot();
});
+
+ if (['complete', 'warning', 'danger'].includes(status)) {
+ it('renders an icon', () => {
+ const { container } = render(
+
+ );
+
+ expect(
+ container.querySelector('.euiStepNumber__icon')
+ ).toBeInTheDocument();
+ });
+ } else if (status === 'loading') {
+ it('renders a loading spinner', () => {
+ const { container } = render(
+
+ );
+
+ expect(
+ container.querySelector('.euiStepNumber__loader')
+ ).toBeInTheDocument();
+ });
+ } else {
+ it('does not render an icon', () => {
+ const { container } = render(
+
+ );
+
+ expect(
+ container.querySelector('.euiStepNumber__icon')
+ ).not.toBeInTheDocument();
+ });
+ }
});
});
});
diff --git a/packages/eui/src/components/steps/step_number.tsx b/packages/eui/src/components/steps/step_number.tsx
index b530ad69935..8971086a6a2 100644
--- a/packages/eui/src/components/steps/step_number.tsx
+++ b/packages/eui/src/components/steps/step_number.tsx
@@ -10,8 +10,12 @@ import classNames from 'classnames';
import React, { FunctionComponent, HTMLAttributes, ReactNode } from 'react';
import { EuiScreenReaderOnly } from '../accessibility';
import { CommonProps } from '../common';
-import { EuiIcon } from '../icon';
-import { EuiStepProps } from './step';
+import { EuiIcon, IconSize } from '../icon';
+import { EuiLoadingSpinner } from '../loading';
+import { EuiLoadingSpinnerSize } from '../loading/loading_spinner';
+import { EuiTitleProps } from '../title';
+import { useEuiTheme } from '../../services';
+
import {
useI18nCompleteStep,
useI18nDisabledStep,
@@ -22,9 +26,6 @@ import {
useI18nLoadingStep,
useI18nCurrentStep,
} from './step_strings';
-import { EuiLoadingSpinner } from '../loading';
-
-import { useEuiTheme } from '../../services';
import {
euiStepNumberStyles,
euiStepNumberContentStyles,
@@ -51,9 +52,11 @@ export interface EuiStepNumberProps
status?: EuiStepStatus;
number?: number;
/**
- * Title sizing equivalent to EuiTitle, but only `m`, `s` and `xs`. Defaults to `s`
+ * Title sizing equivalent to EuiTitle, but only `m`, `s`, `xs`.
+ * `none` indicates no step number should be rendered.
+ * @default s
*/
- titleSize?: EuiStepProps['titleSize'];
+ titleSize?: Extract | 'none';
}
export const EuiStepNumber: FunctionComponent = ({
@@ -90,50 +93,72 @@ export const EuiStepNumber: FunctionComponent = ({
switch (status) {
// Loading spinner
- case 'loading':
+ case 'loading': {
+ const iconSizeMap: Record = {
+ none: 'm',
+ xs: 'l',
+ s: 'xl',
+ m: 'xl',
+ };
screenReaderText = ariaLabelsMap.loading;
content = (
);
break;
+ }
// Statuses with icons
case 'danger':
case 'warning':
- case 'complete':
+ case 'complete': {
const cssIconStyles = [
contentStyles.euiStepNumber__icon,
contentStyles[status],
+ // EuiIcon does not support a xxs size so far,
+ // we use custom sizing here instead
+ titleSize === 'none' && contentStyles[titleSize],
];
const iconTypeMap = {
danger: 'cross',
warning: 'warning',
complete: 'check',
};
+ const iconSizeMap: Record = {
+ xxs: 's',
+ xs: 's',
+ s: 'm',
+ m: 'm',
+ };
content = (
);
break;
+ }
// Statuses with numbers
case 'incomplete':
case 'current':
case 'disabled':
default:
+ screenReaderText = ariaLabelsMap[status || 'step'];
+
+ if (titleSize === 'none') {
+ break;
+ }
+
const cssNumberStyles = [
contentStyles.euiStepNumber__number,
status && contentStyles[status],
];
- screenReaderText = ariaLabelsMap[status || 'step'];
content = (
= {
title: 'Navigation/EuiSteps/EuiSteps',
component: EuiSteps,
@@ -31,46 +74,19 @@ type Story = StoryObj;
export const Playground: Story = {
args: {
- steps: [
- {
- title: 'Step 1',
- children: 'lorem ipsum',
- },
- {
- title: 'Step 2',
- children: 'lorem ipsum',
- status: 'current',
- },
- {
- title: 'Step 3',
- children: 'lorem ipsum',
- status: 'complete',
- },
- {
- title: 'Step 4',
- children: 'lorem ipsum',
- status: 'incomplete',
- },
- {
- title: 'Step 5',
- children: 'lorem ipsum',
- status: 'warning',
- },
- {
- title: 'Step 6',
- children: 'lorem ipsum',
- status: 'danger',
- },
- {
- title: 'Step 7',
- children: 'lorem ipsum',
- status: 'loading',
- },
- {
- title: 'Step 8',
- children: 'lorem ipsum',
- status: 'disabled',
- },
- ],
+ steps,
+ },
+};
+
+export const UnorderedSteps: Story = {
+ tags: ['vrt-only'],
+ parameters: {
+ controls: {
+ include: ['steps', 'titleSize'],
+ },
+ },
+ args: {
+ steps,
+ titleSize: 'xxs',
},
};
diff --git a/packages/eui/src/components/steps/steps.tsx b/packages/eui/src/components/steps/steps.tsx
index 0bc54f1a23c..759fdd4dc57 100644
--- a/packages/eui/src/components/steps/steps.tsx
+++ b/packages/eui/src/components/steps/steps.tsx
@@ -30,7 +30,9 @@ export interface EuiStepsProps
*/
headingElement?: string;
/**
- * Title sizing equivalent to EuiTitle, but only `m`, `s` and `xs`. Defaults to `s`
+ * Title sizing equivalent to **EuiTitle**, but only `m`, `s`, `xs` font sizes.
+ * The `xxs` size reduces the size of the accompanying step indicator, but not the title itself.
+ * @default s
*/
titleSize?: EuiStepProps['titleSize'];
}
diff --git a/packages/eui/src/components/steps/steps_horizontal.stories.tsx b/packages/eui/src/components/steps/steps_horizontal.stories.tsx
index 2c9846d309a..5603a9dc0e0 100644
--- a/packages/eui/src/components/steps/steps_horizontal.stories.tsx
+++ b/packages/eui/src/components/steps/steps_horizontal.stories.tsx
@@ -10,11 +10,56 @@ import type { Meta, StoryObj } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { moveStorybookControlsToCategory } from '../../../.storybook/utils';
+import { EuiStepHorizontalProps } from './step_horizontal';
import {
EuiStepsHorizontal,
EuiStepsHorizontalProps,
} from './steps_horizontal';
+const onClick = action('onClick');
+
+const steps: EuiStepHorizontalProps[] = [
+ {
+ title: 'Step 1',
+ onClick,
+ },
+ {
+ title: 'Step 2',
+ status: 'current',
+ onClick,
+ },
+ {
+ title: 'Step 3',
+ status: 'complete',
+ onClick,
+ },
+ {
+ title: 'Step 4',
+ status: 'incomplete',
+ onClick,
+ },
+ {
+ title: 'Step 5',
+ status: 'warning',
+ onClick,
+ },
+ {
+ title: 'Step 6',
+ status: 'danger',
+ onClick,
+ },
+ {
+ title: 'Step 7',
+ status: 'loading',
+ onClick,
+ },
+ {
+ title: 'Step 8',
+ status: 'disabled',
+ onClick,
+ },
+];
+
const meta: Meta = {
title: 'Navigation/EuiSteps/EuiStepsHorizontal',
component: EuiStepsHorizontal,
@@ -27,50 +72,21 @@ moveStorybookControlsToCategory(meta, ['size'], 'EuiStepHorizontal props');
export default meta;
type Story = StoryObj;
-const onClick = action('onClick');
-
export const Playground: Story = {
args: {
- steps: [
- {
- title: 'Step 1',
- onClick,
- },
- {
- title: 'Step 2',
- status: 'current',
- onClick,
- },
- {
- title: 'Step 3',
- status: 'complete',
- onClick,
- },
- {
- title: 'Step 4',
- status: 'incomplete',
- onClick,
- },
- {
- title: 'Step 5',
- status: 'warning',
- onClick,
- },
- {
- title: 'Step 6',
- status: 'danger',
- onClick,
- },
- {
- title: 'Step 7',
- status: 'loading',
- onClick,
- },
- {
- title: 'Step 8',
- status: 'disabled',
- onClick,
- },
- ],
+ steps,
+ },
+};
+
+export const UnorderedSteps: Story = {
+ tags: ['vrt-only'],
+ parameters: {
+ controls: {
+ include: ['steps', 'size'],
+ },
+ },
+ args: {
+ steps,
+ size: 'xs',
},
};
diff --git a/packages/eui/src/components/steps/steps_horizontal.tsx b/packages/eui/src/components/steps/steps_horizontal.tsx
index 9e594b2df62..62cc50d54f4 100644
--- a/packages/eui/src/components/steps/steps_horizontal.tsx
+++ b/packages/eui/src/components/steps/steps_horizontal.tsx
@@ -12,7 +12,7 @@ import { CommonProps } from '../common';
import { EuiStepHorizontal, EuiStepHorizontalProps } from './step_horizontal';
import { euiStepsHorizontalStyles } from './steps_horizontal.styles';
-export const SIZES = ['s', 'm'] as const;
+export const SIZES = ['xs', 's', 'm'] as const;
export type EuiStepsHorizontalSizes = (typeof SIZES)[number];
export interface EuiStepsHorizontalProps