Skip to content

Commit

Permalink
Recalculate coordinates after each step (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyapasyuk committed Mar 18, 2024
1 parent 2620c94 commit 5c278e0
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 31 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,23 @@ First import this component where you want to use it

`import Wizard from "react-onboarding"`

Then just renders it
Then just render it

`<Wizard />`

### Props

| _Property_ | _Description_ | _Default value_ |
|----------------------|:-------------------------:|:---------------:|
| `rule` | array rules for wizard | none |
| `isShow` | Sets view mode | true |
| `prevButtonTitle` | title for previous button | Prev |
| `nextButtonTitle` | title for next button | Next |
| `closeButtonTitle` | Text on Close button | Close |
| `closeButtonElement` | | ReactNode |
| `pinColor` | | string |
| `lineColor` | | string |
| _Property_ | _Description_ | _type_ | _Default value_ |
|----------------------|:--------------------------|----------------|:---------------:|
| `rule` | array rules for wizard | `WizardStep[]` | |
| `isShow` | Sets view mode | `boolean?` | `true` |
| `prevButtonTitle` | title for previous button | `string?` | `Prev` |
| `nextButtonTitle` | title for next button | `string?` | `Next` |
| `closeButtonTitle` | Text on Close button | `string?` | `Close` |
| `closeButtonElement` | | `ReactNode?` | `<button>` |
| `pinColor` | | `string?` | `1787fc` |
| `lineColor` | | `string?` | `1787fc` |
| `isScrollToElement` | | `boolean?` | `false` |

### Example

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-onboarding",
"version": "1.4.1",
"types": "dist/index.d.ts",
"version": "1.5.0",
"types": "dist/types.ts",
"description": "Simple Wizard component for React",
"type": "module",
"main": "dist/wizard.umd.min.js",
Expand Down
77 changes: 75 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,30 @@ const rule = [
{
elementId: 'elementId2',
title: 'Title 2',
description: 'description 2',
description: (
<div>
<span style={{ marginRight: 5 }}>That is string description, but this is</span>
<a href="https://pasyuk.com" target="_blank">
link
</a>
</div>
),
},
{
elementId: 'elementId3',
title: 'Title 3',
description: 'description 3',
},
{
elementId: 'elementId4',
title: 'Title 4',
description: 'description 4',
},
{
elementId: 'elementId5',
title: 'Title 5',
description: 'description 5',
},
]

function App() {
Expand Down Expand Up @@ -61,7 +78,63 @@ function App() {
alt=""
/>
</header>
<Wizard rule={rule} pinColor="black" lineColor="black" />
<main>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
been the industry's standard dummy text ever since the 1500s, when an unknown printer took
a galley of type and scrambled it to make a type specimen book. It has survived not only
five centuries, but also the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus
PageMaker including versions of Lorem Ipsum.
</p>
<p id="elementId4">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
been the industry's standard dummy text ever since the 1500s, when an unknown printer took
a galley of type and scrambled it to make a type specimen book. It has survived not only
five centuries, but also the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus
PageMaker including versions of Lorem Ipsum.
</p>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
been the industry's standard dummy text ever since the 1500s, when an unknown printer took
a galley of type and scrambled it to make a type specimen book. It has survived not only
five centuries, but also the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus
PageMaker including versions of Lorem Ipsum.
</p>
<p id="elementId5">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
been the industry's standard dummy text ever since the 1500s, when an unknown printer took
a galley of type and scrambled it to make a type specimen book. It has survived not only
five centuries, but also the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus
PageMaker including versions of Lorem Ipsum.
</p>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
been the industry's standard dummy text ever since the 1500s, when an unknown printer took
a galley of type and scrambled it to make a type specimen book. It has survived not only
five centuries, but also the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus
PageMaker including versions of Lorem Ipsum.
</p>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
been the industry's standard dummy text ever since the 1500s, when an unknown printer took
a galley of type and scrambled it to make a type specimen book. It has survived not only
five centuries, but also the leap into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus
PageMaker including versions of Lorem Ipsum.
</p>
</main>
<Wizard rule={rule} pinColor="black" lineColor="black" isScrollToElement />
</div>
)
}
Expand Down
30 changes: 17 additions & 13 deletions src/Wizard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
import React, { useState, useEffect } from 'react'

import './style.css'
import { WizardProps, WizardStep } from '../../index'

type Coordinates = {
top: number
left: number
}
import { Coordinates, WizardProps, WizardStep } from './types'

const Wizard = ({
isShow = true,
Expand All @@ -18,28 +13,30 @@ const Wizard = ({
closeButtonElement,
pinColor = '#1787fc',
lineColor = '#1787fc',
isScrollToElement = false,
}: WizardProps) => {
const [isShowState, setShow] = useState<boolean>(isShow)
const [position, setPosition] = useState<Coordinates>({ top: 0, left: 0 })
const [coordinates, setCoordinates] = useState<Coordinates>({ top: 0, left: 0 })

const [currentStepNumber, setCurrentStepNumber] = useState<number>(0)
const currentStepContent = getStep(currentStepNumber, rule)

useEffect(() => {
setPosition(getCoords(getStep(currentStepNumber, rule).elementId))
setCoordinates(getCoords(getStep(currentStepNumber, rule).elementId, isScrollToElement))
}, [rule])

const onStepButtonClick = (stepNumber: number): void => {
setCurrentStepNumber(stepNumber)
setPosition(getCoords(getStep(stepNumber, rule).elementId))
setCoordinates(getCoords(getStep(stepNumber, rule).elementId, isScrollToElement))
}

if (!isShowState || !position) {
if (!isShowState || !coordinates) {
return null
}

return (
<div
style={{ left: position.left, top: position.top }}
style={{ left: coordinates.left, top: coordinates.top }}
className="Wizard__Wrapper"
data-wizard-onboarding
>
Expand Down Expand Up @@ -106,13 +103,20 @@ function getStep(stepNumber: number, rules: WizardStep[]): WizardStep {
return rules[stepNumber]
}

function getCoords(elementId: string): Coordinates {
function getCoords(elementId: string, isScrollToElement?: boolean): Coordinates {
const element = document.getElementById(elementId)
const coordinates = element?.getBoundingClientRect()

const top = (coordinates?.top || 0) + (coordinates?.height || 0) / 2
const top = (coordinates?.top || 0) + (coordinates?.height || 0) / 2 + window.scrollY
const left = (coordinates?.left || 0) + (coordinates?.width || 0)

if (isScrollToElement) {
window.scrollTo({
top: top - window.innerHeight / 2,
behavior: 'smooth',
})
}

return {
top,
left,
Expand Down
10 changes: 8 additions & 2 deletions index.d.ts → src/Wizard/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,24 @@ import * as React from 'react'
export interface WizardStep {
elementId: string
title: string
description?: string
description?: string | React.ReactNode
}

export interface Coordinates {
top: number
left: number
}

export interface WizardProps {
rule: WizardStep[]
isShow?: boolean
rule: Step[]
prevButtonTitle?: string
nextButtonTitle?: string
closeButtonTitle?: string
closeButtonElement?: React.ReactNode
lineColor?: string
pinColor?: string
isScrollToElement?: boolean
}

export default class Wizard extends React.Component<WizardProps> {}
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default defineConfig({
viteStaticCopy({
targets: [
{
src: path.resolve(__dirname, './index.d.ts'),
src: path.resolve(__dirname, './src/Wizard/types.ts'),
dest: './',
},
],
Expand Down

0 comments on commit 5c278e0

Please sign in to comment.