Skip to content

Commit

Permalink
feat: stepper component (#832)
Browse files Browse the repository at this point in the history
  • Loading branch information
leduyhien152 committed Apr 16, 2024
1 parent 381834b commit c393607
Show file tree
Hide file tree
Showing 21 changed files with 671 additions and 21 deletions.
7 changes: 7 additions & 0 deletions .changeset/honest-readers-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@mochi-ui/stepper": major
"@mochi-ui/theme": minor
"@mochi-ui/core": minor
---

Add Stepper component
4 changes: 4 additions & 0 deletions packages/components/stepper/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ['custom/react'],
}
33 changes: 33 additions & 0 deletions packages/components/stepper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# @mochi-ui/stepper

The Stepper component is used for ...

> This is an internal utility, not intended for public usage.
For further details, visit our
[Stepper Documentation](https://ds.mochiui.com/?path=/docs/data-display-stepper--docs).

## Installation

Feel free to use the package manager of your choice:

```sh
# Using PNPM
pnpm i @mochi-ui/stepper

# Using NPM
npm i @mochi-ui/stepper

# Using Yarn
yarn add @mochi-ui/stepper
```

## Contribution

We welcome your contributions! For guidance on how to contribute, please refer
to our [Contribution Guidelines](/CONTRIBUTING.md).

## Licence

This project is licensed under the terms of the
[MIT license](https://choosealicense.com/licenses/mit/).
57 changes: 57 additions & 0 deletions packages/components/stepper/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@mochi-ui/stepper",
"version": "0.0.1",
"description": "A stepper component is used to indicate progress through a multi-step process.",
"keywords": [
"stepper"
],
"author": "@consolelabs",
"homepage": "https://ds.mochiui.com",
"license": "MIT",
"main": "src/index.ts",
"sideEffects": false,
"files": [
"dist"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/consolelabs/mochi-ui.git",
"directory": "packages/components/stepper"
},
"bugs": {
"url": "https://github.com/consolelabs/mochi-ui.git"
},
"scripts": {
"build": "tsup src --dts",
"build:fast": "tsup src",
"dev": "pnpm build:fast -- --watch",
"lint": "eslint src/ --cache",
"clean": "rimraf dist .turbo",
"typecheck": "tsc --noEmit",
"prepack": "clean-package",
"postpack": "clean-package restore"
},
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"dependencies": {
"@mochi-ui/icons": "workspace:*",
"@mochi-ui/theme": "workspace:*",
"@mochi-ui/typography": "workspace:*",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0"
},
"devDependencies": {
"clean-package": "^2.2.0",
"eslint-config-custom": "workspace:*",
"prettier": "^3.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tsconfig": "workspace:*"
},
"clean-package": "../../../clean-package.config.json"
}
50 changes: 50 additions & 0 deletions packages/components/stepper/src/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { createContext, useContext } from 'react'

export type StepItemStatus = 'current' | 'complete' | 'incomplete'

type StepperContextValue = {
/**
* The status of the step
*/
status: StepItemStatus
/**
* The total number of steps
*/
count: number
/**
* The index of the step
*/
step: number
/**
* Whether the step is the last step
*/
isLast?: boolean
/**
* Whether the step is the first step
*/
isFirst?: boolean
/**
* Whether the step is loading
*/
isLoading?: boolean
/**
* Whether the step has an error
*/
isError?: boolean
/**
* The orientation of the stepper
* @default 'vertical'
*/
orientation: 'horizontal' | 'vertical'
}

const StepperContext = createContext<StepperContextValue>({
status: 'incomplete',
count: 0,
step: 0,
orientation: 'vertical',
})

const useStepperContext = () => useContext(StepperContext)

export { type StepperContextValue, StepperContext, useStepperContext }
8 changes: 8 additions & 0 deletions packages/components/stepper/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// export types, component
export * from './stepper'
export * from './step-item'
export * from './step-indicator'
export * from './step-content'
export * from './step-title'
export * from './step-description'
export * from './step-separator'
26 changes: 26 additions & 0 deletions packages/components/stepper/src/step-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { PropsWithChildren, forwardRef } from 'react'
import { stepper } from '@mochi-ui/theme'

const { stepContentClsx } = stepper

interface StepContentProps extends PropsWithChildren {
className?: string
}

const StepContent = forwardRef<HTMLDivElement, StepContentProps>(
(props, ref) => {
const { className, ...restProps } = props

return (
<div
ref={ref}
className={stepContentClsx({ className })}
{...restProps}
/>
)
},
)

StepContent.displayName = 'StepContent'

export { StepContent, type StepContentProps }
29 changes: 29 additions & 0 deletions packages/components/stepper/src/step-description.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { PropsWithChildren, forwardRef } from 'react'
import { stepper } from '@mochi-ui/theme'
import { Typography } from '@mochi-ui/typography'

const { stepDescriptionClsx } = stepper

interface StepDescriptionProps extends PropsWithChildren {
className?: string
}

const StepDescription = forwardRef<HTMLDivElement, StepDescriptionProps>(
(props, ref) => {
const { className, ...restProps } = props

return (
<div ref={ref}>
<Typography
level="p5"
className={stepDescriptionClsx({ className })}
{...restProps}
/>
</div>
)
},
)

StepDescription.displayName = 'StepDescription'

export { StepDescription, type StepDescriptionProps }
51 changes: 51 additions & 0 deletions packages/components/stepper/src/step-indicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { PropsWithChildren, forwardRef } from 'react'
import { stepper } from '@mochi-ui/theme'
import { CheckLine, CloseLine, SpinnerLine } from '@mochi-ui/icons'
import { useStepperContext } from './context'

const { stepIndicatorClsx } = stepper

interface StepIndicatorProps extends PropsWithChildren {
className?: string
}

const StepIndicator = forwardRef<HTMLDivElement, StepIndicatorProps>(
(props, ref) => {
const { className, ...restProps } = props
const { step, status: stepStatus, isLoading, isError } = useStepperContext()

let status: 'loading' | 'error' | 'success' | 'current' | 'incomplete' =
'current'
let children = null
if (isLoading) {
status = 'loading'
children = <SpinnerLine className="w-full h-full text-primary-solid" />
} else if (isError) {
status = 'error'
children = <CloseLine className="w-4 h-4 text-text-contrast" />
} else if (stepStatus === 'complete') {
status = 'success'
children = <CheckLine className="w-4 h-4 text-text-contrast" />
} else {
status = stepStatus
children = step
}

return (
<div
ref={ref}
className={stepIndicatorClsx({
className,
status,
})}
{...restProps}
>
{children}
</div>
)
},
)

StepIndicator.displayName = 'StepIndicator'

export { StepIndicator, type StepIndicatorProps }
26 changes: 26 additions & 0 deletions packages/components/stepper/src/step-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { PropsWithChildren, forwardRef } from 'react'
import { stepper } from '@mochi-ui/theme'
import { useStepperContext } from './context'

const { stepClsx } = stepper

interface StepProps extends PropsWithChildren {
className?: string
}

const Step = forwardRef<HTMLDivElement, StepProps>((props, ref) => {
const { className, ...restProps } = props
const { isLast, orientation } = useStepperContext()

return (
<div
ref={ref}
className={stepClsx({ className, isLast, orientation })}
{...restProps}
/>
)
})

Step.displayName = 'Step'

export { Step, type StepProps }
28 changes: 28 additions & 0 deletions packages/components/stepper/src/step-separator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { PropsWithChildren, forwardRef } from 'react'
import { stepper } from '@mochi-ui/theme'
import { useStepperContext } from './context'

const { stepSeparatorClsx } = stepper

interface StepSeparatorProps extends PropsWithChildren {
className?: string
}

const StepSeparator = forwardRef<HTMLDivElement, StepSeparatorProps>(
(props, ref) => {
const { className, ...restProps } = props
const { isLast, orientation } = useStepperContext()

return (
<div
ref={ref}
className={stepSeparatorClsx({ className, isLast, orientation })}
{...restProps}
/>
)
},
)

StepSeparator.displayName = 'StepTitle'

export { StepSeparator, type StepSeparatorProps }
27 changes: 27 additions & 0 deletions packages/components/stepper/src/step-title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { PropsWithChildren, forwardRef } from 'react'
import { stepper } from '@mochi-ui/theme'
import { Typography } from '@mochi-ui/typography'

const { stepTitleClsx } = stepper

interface StepTitleProps extends PropsWithChildren {
className?: string
}

const StepTitle = forwardRef<HTMLDivElement, StepTitleProps>((props, ref) => {
const { className, ...restProps } = props

return (
<div ref={ref}>
<Typography
level="h8"
className={stepTitleClsx({ className })}
{...restProps}
/>
</div>
)
})

StepTitle.displayName = 'StepTitle'

export { StepTitle, type StepTitleProps }
Loading

0 comments on commit c393607

Please sign in to comment.