From 3357b43fd84d29e27a9d631443e3261349b52c60 Mon Sep 17 00:00:00 2001 From: JayaShakthi97 Date: Tue, 5 Nov 2024 21:01:02 +0530 Subject: [PATCH] feat(react): rename custom component `Stepper` to `TransitionStepper` --- packages/react/.storybook/story-config.ts | 4 + .../src/components/Carousel/Carousel.tsx | 6 +- packages/react/src/components/Step/Step.tsx | 2 +- .../TransitionStepper.stories.mdx | 128 +++++++++++++++++ .../TransitionStepper/TransitionStepper.tsx | 130 ++++++++++++++++++ .../__tests__/TransitionStepper.test.tsx | 41 ++++++ .../TransitionStepper.test.tsx.snap | 13 ++ .../src/components/TransitionStepper/index.ts | 20 +++ .../TransitionStepper/transition-stepper.scss | 30 ++++ .../react/src/components/Wizard/Wizard.tsx | 6 +- 10 files changed, 373 insertions(+), 7 deletions(-) create mode 100755 packages/react/src/components/TransitionStepper/TransitionStepper.stories.mdx create mode 100755 packages/react/src/components/TransitionStepper/TransitionStepper.tsx create mode 100755 packages/react/src/components/TransitionStepper/__tests__/TransitionStepper.test.tsx create mode 100644 packages/react/src/components/TransitionStepper/__tests__/__snapshots__/TransitionStepper.test.tsx.snap create mode 100755 packages/react/src/components/TransitionStepper/index.ts create mode 100755 packages/react/src/components/TransitionStepper/transition-stepper.scss diff --git a/packages/react/.storybook/story-config.ts b/packages/react/.storybook/story-config.ts index 5af36854..6cf57714 100644 --- a/packages/react/.storybook/story-config.ts +++ b/packages/react/.storybook/story-config.ts @@ -116,6 +116,7 @@ export type Stories = | 'Tab' | 'TabPanel' | 'Tabs' + | 'TransitionStepper' | 'TextField' | 'Toolbar' | 'Tooltip' @@ -397,6 +398,9 @@ const StoryConfig: StorybookConfig = { Tabs: { hierarchy: `${StorybookCategories.Navigation}/Tabs`, }, + TransitionStepper: { + hierarchy: `${StorybookCategories.Navigation}/Transition Stepper`, + }, TextField: { hierarchy: `${StorybookCategories.Inputs}/Text Field`, }, diff --git a/packages/react/src/components/Carousel/Carousel.tsx b/packages/react/src/components/Carousel/Carousel.tsx index 1366b1f3..6a926d79 100644 --- a/packages/react/src/components/Carousel/Carousel.tsx +++ b/packages/react/src/components/Carousel/Carousel.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2023-2024, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -31,7 +31,7 @@ import IconButton, {IconButtonVariants} from '../IconButton'; import ListItem from '../ListItem'; import ListItemIcon from '../ListItemIcon'; import ListItemText from '../ListItemText'; -import Stepper from '../Stepper'; +import TransitionStepper from '../TransitionStepper'; import './carousel.scss'; export type CarouselStep = { @@ -223,7 +223,7 @@ const Carousel: OverridableComponent> = forwardRef( - + ); diff --git a/packages/react/src/components/Step/Step.tsx b/packages/react/src/components/Step/Step.tsx index 39791ca2..e87ce882 100644 --- a/packages/react/src/components/Step/Step.tsx +++ b/packages/react/src/components/Step/Step.tsx @@ -17,7 +17,7 @@ */ import MuiStep from '@mui/material/Step'; -import type {StepTypeMap, MuiStepLabelProps as MuiStepProps} from '@mui/material/Step'; +import type {StepTypeMap, StepProps as MuiStepProps} from '@mui/material/Step'; import clsx from 'clsx'; import {forwardRef} from 'react'; import type {ElementType, Ref, ReactElement, ForwardRefExoticComponent} from 'react'; diff --git a/packages/react/src/components/TransitionStepper/TransitionStepper.stories.mdx b/packages/react/src/components/TransitionStepper/TransitionStepper.stories.mdx new file mode 100755 index 00000000..82f1fa86 --- /dev/null +++ b/packages/react/src/components/TransitionStepper/TransitionStepper.stories.mdx @@ -0,0 +1,128 @@ +import {ArgsTable, Source, Story, Canvas, Meta} from '@storybook/addon-docs'; +import dedent from 'ts-dedent'; +import TransitonStepper from './TransitionStepper.tsx'; +import StoryConfig from '../../../.storybook/story-config.ts'; +import Typography from '../Typography/index.ts'; + +export const meta = { + component: TransitonStepper, + title: StoryConfig.TransitionStepper.hierarchy, +}; + + + +export const Template = args => ; + +# TransitionStepper + +- [Overview](#overview) +- [Props](#props) +- [Usage](#usage) + +## Overview + +TransitonStepper can be used to compose wizards and carousels. + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec auctor porttitor dolor eget tristique. Nam + elementum, quam vel varius porttitor, purus est vestibulum augue, sed suscipit ligula metus at nibh. Donec + eleifend suscipit nisi mollis sollicitudin. Vestibulum fermentum odio at maximus lacinia. Phasellus leo ipsum, + vestibulum hendrerit enim vitae, ullamcorper tincidunt erat. Sed quam nulla, pharetra non mattis non, + fringilla non massa. Donec maximus finibus dui et suscipit. Suspendisse potenti. In imperdiet hendrerit + accumsan. Vivamus lacus nunc, mollis ut elementum eget, tempus vitae lectus. Ut molestie ante quis quam + aliquam pretium. Vestibulum dignissim, odio vel volutpat porta, enim nisl auctor turpis, vel imperdiet nisl + lorem id ligula. Proin varius scelerisque ligula ac consequat. + , + + Aliquam vel ex tortor. Proin sed ullamcorper massa. Sed eu fringilla risus, a faucibus tortor. Duis euismod + enim sit amet nunc condimentum, eget tristique ex ultricies. Suspendisse potenti. Phasellus risus ligula, + imperdiet in imperdiet ac, hendrerit eu quam. Aliquam leo risus, vulputate nec auctor viverra, dictum a elit. + Curabitur a accumsan lorem. Cras nec metus sed diam vehicula luctus nec sit amet dolor. Donec ac nibh finibus, + varius arcu sit amet, dapibus neque. Morbi orci augue, commodo vitae tincidunt vel, tincidunt at justo. + Quisque sem mauris, consectetur sit amet lobortis vel, consectetur sit amet massa. + , + + Praesent varius porta tellus, ac mattis quam blandit at. Vestibulum in nisi at est rhoncus posuere ac vitae + ligula. Phasellus molestie purus ac nulla vestibulum gravida. Morbi lacinia vehicula aliquam. Praesent mollis + mollis arcu eu finibus. Morbi at nunc quam. Aliquam sed urna quis erat elementum bibendum vitae eu massa. + , + + Sed placerat molestie tristique. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac + turpis egestas. Vestibulum at libero bibendum, tempor nunc vel, luctus ipsum. Aenean ut diam ligula. Ut + auctor, justo a tincidunt fermentum, nibh dui consectetur massa, eu congue sapien eros ut nisl. Nam nec + fringilla sem. Pellentesque facilisis fermentum nibh, in volutpat ipsum porttitor ut. Quisque auctor lorem et + dolor suscipit, nec rhoncus justo aliquam. Praesent elit sapien, tempor id mi et, fermentum accumsan justo. Ut + a justo tortor. Proin in nisl vel arcu congue tristique. Proin mattis condimentum orci, quis accumsan neque + auctor vel. + , + ], + }} + > + {Template.bind({})} + + + +## Props + + + +## Usage + +Import and use the `TransitonStepper` component in your components as follows. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec auctor porttitor dolor eget tristique. Nam + elementum, quam vel varius porttitor, purus est vestibulum augue, sed suscipit ligula metus at nibh. Donec + eleifend suscipit nisi mollis sollicitudin. Vestibulum fermentum odio at maximus lacinia. Phasellus leo ipsum, + vestibulum hendrerit enim vitae, ullamcorper tincidunt erat. Sed quam nulla, pharetra non mattis non, + fringilla non massa. Donec maximus finibus dui et suscipit. Suspendisse potenti. In imperdiet hendrerit + accumsan. Vivamus lacus nunc, mollis ut elementum eget, tempus vitae lectus. Ut molestie ante quis quam + aliquam pretium. Vestibulum dignissim, odio vel volutpat porta, enim nisl auctor turpis, vel imperdiet nisl + lorem id ligula. Proin varius scelerisque ligula ac consequat. + , + + Aliquam vel ex tortor. Proin sed ullamcorper massa. Sed eu fringilla risus, a faucibus tortor. Duis euismod + enim sit amet nunc condimentum, eget tristique ex ultricies. Suspendisse potenti. Phasellus risus ligula, + imperdiet in imperdiet ac, hendrerit eu quam. Aliquam leo risus, vulputate nec auctor viverra, dictum a elit. + Curabitur a accumsan lorem. Cras nec metus sed diam vehicula luctus nec sit amet dolor. Donec ac nibh finibus, + varius arcu sit amet, dapibus neque. Morbi orci augue, commodo vitae tincidunt vel, tincidunt at justo. + Quisque sem mauris, consectetur sit amet lobortis vel, consectetur sit amet massa. + , + + Praesent varius porta tellus, ac mattis quam blandit at. Vestibulum in nisi at est rhoncus posuere ac vitae + ligula. Phasellus molestie purus ac nulla vestibulum gravida. Morbi lacinia vehicula aliquam. Praesent mollis + mollis arcu eu finibus. Morbi at nunc quam. Aliquam sed urna quis erat elementum bibendum vitae eu massa. + , + + Sed placerat molestie tristique. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac + turpis egestas. Vestibulum at libero bibendum, tempor nunc vel, luctus ipsum. Aenean ut diam ligula. Ut + auctor, justo a tincidunt fermentum, nibh dui consectetur massa, eu congue sapien eros ut nisl. Nam nec + fringilla sem. Pellentesque facilisis fermentum nibh, in volutpat ipsum porttitor ut. Quisque auctor lorem et + dolor suscipit, nec rhoncus justo aliquam. Praesent elit sapien, tempor id mi et, fermentum accumsan justo. Ut + a justo tortor. Proin in nisl vel arcu congue tristique. Proin mattis condimentum orci, quis accumsan neque + auctor vel. + , + ] + } + /> + ); +}`} +/> diff --git a/packages/react/src/components/TransitionStepper/TransitionStepper.tsx b/packages/react/src/components/TransitionStepper/TransitionStepper.tsx new file mode 100755 index 00000000..4ad57ad9 --- /dev/null +++ b/packages/react/src/components/TransitionStepper/TransitionStepper.tsx @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import type {OverridableComponent} from '@mui/material/OverridableComponent'; +import clsx from 'clsx'; +import {forwardRef, useCallback, useEffect, useRef, useState} from 'react'; +import type {ElementType, Ref, ReactElement} from 'react'; +import Box from '../Box'; +import type {BoxProps, BoxTypeMap} from '../Box'; +import './transition-stepper.scss'; + +export type TransitionStepperProps = BoxProps & { + /** + * Animate the slide transition. + */ + animateOnSlide?: boolean; + /** + * Current step. + */ + currentStep: number; + /** + * Steps to be rendered. + */ + steps: ReactElement[]; +}; + +/** + * The TransitionStepper can be used to compose wizards and carousels. + * + * Demos: + * + * - [Stepper (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-stepper--overview) + * + * API: + * + * - inherits [Box API](https://mui.com/material-ui/api/box/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the TransitionStepper component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered TransitionStepper component. + */ +const TransitionStepper: OverridableComponent> = forwardRef( + ( + {animateOnSlide, className, currentStep = 0, steps}: TransitionStepperProps, + ref: Ref, + ): ReactElement => { + const [slideLeftPosition, setSlideLeftPosition] = useState(0); + const [slideContainerWidth, setSlideContainerWidth] = useState(0); + + const slideContainerRef: Ref = useRef(null); + + const classes: string = clsx('oxygen-transition-stepper', className); + + const slideContainer: (position: number) => void = useCallback( + (position: number): void => { + if (!animateOnSlide) { + return; + } + + const slideBy: number = position; + setSlideLeftPosition(slideBy * -1 * currentStep); + }, + [currentStep, animateOnSlide], + ); + + useEffect(() => { + if (!slideContainerRef?.current || !animateOnSlide) { + return () => {}; + } + + setSlideContainerWidth(slideContainerRef.current.offsetWidth); + + const handleResize = (): void => { + const width: number = slideContainerRef.current.offsetWidth; + setSlideContainerWidth(width); + slideContainer(width); + }; + + window.addEventListener('resize', handleResize); + + return (): void => { + window.removeEventListener('resize', handleResize); + }; + }, [animateOnSlide, slideContainer]); + + useEffect(() => { + slideContainer(slideContainerWidth); + }, [slideContainerWidth, slideContainer]); + + if (animateOnSlide) { + return ( + + + {steps.map((step: ReactElement) => ( + + {step} + + ))} + + + ); + } + + return steps[currentStep]; + }, +) as OverridableComponent>; + +export default TransitionStepper; diff --git a/packages/react/src/components/TransitionStepper/__tests__/TransitionStepper.test.tsx b/packages/react/src/components/TransitionStepper/__tests__/TransitionStepper.test.tsx new file mode 100755 index 00000000..891e82fb --- /dev/null +++ b/packages/react/src/components/TransitionStepper/__tests__/TransitionStepper.test.tsx @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {render} from '@unit-testing'; +import {ReactElement} from 'react'; +import Typography from '../../Typography'; +import TransitionStepper from '../TransitionStepper'; + +const steps: ReactElement[] = [ + Step 1, + Step 2, + Step 3, + Step 4, +]; + +describe('TransitionStepper', () => { + it('should render successfully', () => { + const {baseElement} = render(); + expect(baseElement).toBeTruthy(); + }); + + it('should match the snapshot', () => { + const {baseElement} = render(); + expect(baseElement).toMatchSnapshot(); + }); +}); diff --git a/packages/react/src/components/TransitionStepper/__tests__/__snapshots__/TransitionStepper.test.tsx.snap b/packages/react/src/components/TransitionStepper/__tests__/__snapshots__/TransitionStepper.test.tsx.snap new file mode 100644 index 00000000..8a7519e3 --- /dev/null +++ b/packages/react/src/components/TransitionStepper/__tests__/__snapshots__/TransitionStepper.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TransitionStepper should match the snapshot 1`] = ` + +
+

+ Step 1 +

+
+ +`; diff --git a/packages/react/src/components/TransitionStepper/index.ts b/packages/react/src/components/TransitionStepper/index.ts new file mode 100755 index 00000000..2b4c78d7 --- /dev/null +++ b/packages/react/src/components/TransitionStepper/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export {default} from './TransitionStepper'; +export * from './TransitionStepper'; diff --git a/packages/react/src/components/TransitionStepper/transition-stepper.scss b/packages/react/src/components/TransitionStepper/transition-stepper.scss new file mode 100755 index 00000000..6226bbbc --- /dev/null +++ b/packages/react/src/components/TransitionStepper/transition-stepper.scss @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +.oxygen-transition-stepper { + overflow: hidden; + + .oxygen-transition-stepper-container { + display: flex; + flex-direction: row; + justify-content: flex-start; + width: max-content; + position: relative; + transition: left 0.5s ease-in-out; + } +} diff --git a/packages/react/src/components/Wizard/Wizard.tsx b/packages/react/src/components/Wizard/Wizard.tsx index 479d00ce..0f28e2a1 100644 --- a/packages/react/src/components/Wizard/Wizard.tsx +++ b/packages/react/src/components/Wizard/Wizard.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2023-2024, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -28,7 +28,7 @@ import CardActions from '../CardActions'; import CardContent from '../CardContent'; import CardHeader from '../CardHeader'; import LinearProgress from '../LinearProgress'; -import Stepper from '../Stepper'; +import TransitionStepper from '../TransitionStepper'; import Typography from '../Typography'; import './wizard.scss'; @@ -174,7 +174,7 @@ const Wizard: OverridableComponent> = forwardRef( - +