diff --git a/src/mantine-core/src/Stepper/Step/Step.styles.ts b/src/mantine-core/src/Stepper/Step/Step.styles.ts index d0301f38138..a24286831e6 100644 --- a/src/mantine-core/src/Stepper/Step/Step.styles.ts +++ b/src/mantine-core/src/Stepper/Step/Step.styles.ts @@ -7,6 +7,7 @@ export interface StepStylesParams { radius: MantineNumberSize; allowStepClick: boolean; iconPosition: 'right' | 'left'; + orientation: 'vertical' | 'horizontal'; } export const iconSizes = { @@ -18,13 +19,33 @@ export const iconSizes = { }; export default createStyles( - (theme, { color, iconSize, size, radius, allowStepClick, iconPosition }: StepStylesParams) => { + ( + theme, + { color, iconSize, size, radius, allowStepClick, iconPosition, orientation }: StepStylesParams + ) => { const _iconSize = iconSize || theme.fn.size({ size, sizes: iconSizes }); const iconMargin = size === 'xl' || size === 'lg' ? theme.spacing.md : theme.spacing.sm; const _radius = theme.fn.size({ size: radius, sizes: theme.radius }); const colors = theme.fn.variant({ variant: 'filled', color }); const separatorDistanceFromIcon = theme.spacing.xs / 2; + const verticalOrientationStyles = { + step: { + justifyContent: 'flex-start', + minHeight: `${_iconSize + theme.spacing.xl + separatorDistanceFromIcon}px`, + marginTop: `${separatorDistanceFromIcon}px`, + overflow: 'hidden', + + '&:first-of-type': { + marginTop: 0, + }, + + '&:last-of-type': { + minHeight: 'auto', + }, + }, + } as const; + return { stepLoader: {}, @@ -32,14 +53,29 @@ export default createStyles( display: 'flex', flexDirection: iconPosition === 'left' ? 'row' : 'row-reverse', cursor: allowStepClick ? 'pointer' : 'default', - alignItems: 'center', + ...(orientation === 'vertical' + ? verticalOrientationStyles.step + : { + alignItems: 'center', + }), }, stepWrapper: { position: 'relative', - overflow: 'hidden', - flexShrink: 0, - marginBottom: separatorDistanceFromIcon, + }, + + verticalSeparator: { + top: `${_iconSize + separatorDistanceFromIcon}px`, + left: `${_iconSize / 2}px`, + height: '100vh', + position: 'absolute', + borderLeft: `2px solid ${ + theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[1] + }`, + }, + + verticalSeparatorActive: { + borderColor: theme.fn.variant({ variant: 'filled', color }).background, }, stepIcon: { @@ -85,6 +121,15 @@ export default createStyles( flexDirection: 'column', marginLeft: iconPosition === 'left' ? iconMargin : undefined, marginRight: iconPosition === 'right' ? iconMargin : undefined, + + ...(orientation === 'vertical' + ? { + marginTop: + _iconSize > theme.fn.size({ size, sizes: theme.fontSizes }) * 4 + ? _iconSize / 4 + : _iconSize / 12, + } + : null), }, stepLabel: { diff --git a/src/mantine-core/src/Stepper/Step/Step.tsx b/src/mantine-core/src/Stepper/Step/Step.tsx index 78a7b8ba618..c2d9ae1a426 100644 --- a/src/mantine-core/src/Stepper/Step/Step.tsx +++ b/src/mantine-core/src/Stepper/Step/Step.tsx @@ -65,6 +65,9 @@ export interface StepProps /** Static selector base */ __staticSelector?: string; + + /** Component orientation */ + orientation?: 'vertical' | 'horizontal'; } const defaultIconSizes = { @@ -98,12 +101,13 @@ export const Step = forwardRef( classNames, styles, unstyled, + orientation, ...others }: StepProps, ref ) => { const { classes, cx, theme } = useStyles( - { color, iconSize, size, radius, allowStepClick, iconPosition }, + { color, iconSize, size, radius, allowStepClick, iconPosition, orientation }, { name: __staticSelector, classNames, styles, unstyled } ); @@ -147,6 +151,13 @@ export const Step = forwardRef( ) ) : null} + {orientation === 'vertical' && ( +
+ )}
)} diff --git a/src/mantine-core/src/Stepper/Stepper.story.tsx b/src/mantine-core/src/Stepper/Stepper.story.tsx index bd60715494e..436a936ae37 100644 --- a/src/mantine-core/src/Stepper/Stepper.story.tsx +++ b/src/mantine-core/src/Stepper/Stepper.story.tsx @@ -122,10 +122,50 @@ storiesOf('Stepper', module) volutpat nunc accumsan at. Curabitur ac auctor ante, et convallis diam. Donec eget mi consectetur, pharetra urna et, volutpat nibh. Integer sit amet diam ligula. Phasellus ex purus, dictum non purus ut, viverra maximus sem. Sed luctus eget massa - vitae dapibus. Sed ante tortor, viverra at urna et, feugiat scelerisque dolor.`} - loading + vitae dapibus. Sed ante tortor, viverra at urna et, feugiat scelerisque dolor. Fusce lacinia lacus at sem luctus + accumsan nec nec turpis. Fusce interdum, orci id porta viverra, sem lorem porta + nibh, eget bibendum ligula sapien sit amet orci. Maecenas lobortis lorem dui, a + volutpat nunc accumsan at. Curabitur ac auctor ante, et convallis diam. Donec eget + mi consectetur, pharetra urna et, volutpat nibh.`} /> + + + diff --git a/src/mantine-core/src/Stepper/Stepper.tsx b/src/mantine-core/src/Stepper/Stepper.tsx index 2d58c2cf213..30406e4284d 100644 --- a/src/mantine-core/src/Stepper/Stepper.tsx +++ b/src/mantine-core/src/Stepper/Stepper.tsx @@ -134,7 +134,7 @@ export const Stepper: StepperComponent = forwardRef = { root: 'Root element', steps: 'Steps controls wrapper', separator: 'Separator line between step controls', + verticalSeparator: 'Vertical separator line between step controls', separatorActive: 'Separator active modifier', + verticalSeparatorActive: 'Vertical separator active modifier', content: 'Current step content wrapper', stepWrapper: 'Wrapper for the step icon and separator', step: 'Step control button',