@stack-spot/portal-layout 1.1.2 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/Layout.d.ts +2 -11
- package/dist/Layout.d.ts.map +1 -1
- package/dist/Layout.js +6 -13
- package/dist/Layout.js.map +1 -1
- package/dist/WelcomeTour.d.ts +2 -0
- package/dist/WelcomeTour.d.ts.map +1 -0
- package/dist/WelcomeTour.js +8 -0
- package/dist/WelcomeTour.js.map +1 -0
- package/dist/components/PortalSwitcher.d.ts +6 -0
- package/dist/components/PortalSwitcher.d.ts.map +1 -1
- package/dist/components/PortalSwitcher.js +34 -2
- package/dist/components/PortalSwitcher.js.map +1 -1
- package/dist/components/error/ErrorBoundary.d.ts +10 -1
- package/dist/components/error/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/error/ErrorBoundary.js +1 -1
- package/dist/components/error/ErrorBoundary.js.map +1 -1
- package/dist/components/error/ErrorManager.d.ts +1 -1
- package/dist/components/error/ErrorManager.d.ts.map +1 -1
- package/dist/components/error/SilentErrorBoundary.d.ts +10 -1
- package/dist/components/error/SilentErrorBoundary.d.ts.map +1 -1
- package/dist/components/tour/StepContainer.d.ts +29 -0
- package/dist/components/tour/StepContainer.d.ts.map +1 -0
- package/dist/components/tour/StepContainer.js +52 -0
- package/dist/components/tour/StepContainer.js.map +1 -0
- package/dist/components/tour/StepNavigation.d.ts +29 -0
- package/dist/components/tour/StepNavigation.d.ts.map +1 -0
- package/dist/components/tour/StepNavigation.js +36 -0
- package/dist/components/tour/StepNavigation.js.map +1 -0
- package/dist/components/tour/StepTitle.d.ts +17 -0
- package/dist/components/tour/StepTitle.d.ts.map +1 -0
- package/dist/components/tour/StepTitle.js +9 -0
- package/dist/components/tour/StepTitle.js.map +1 -0
- package/dist/components/tour/hook.d.ts +3 -0
- package/dist/components/tour/hook.d.ts.map +1 -0
- package/dist/components/tour/hook.js +10 -0
- package/dist/components/tour/hook.js.map +1 -0
- package/dist/components/tour/index.d.ts +5 -0
- package/dist/components/tour/index.d.ts.map +1 -0
- package/dist/components/tour/index.js +5 -0
- package/dist/components/tour/index.js.map +1 -0
- package/dist/components/tour/manager.d.ts +32 -0
- package/dist/components/tour/manager.d.ts.map +1 -0
- package/dist/components/tour/manager.js +98 -0
- package/dist/components/tour/manager.js.map +1 -0
- package/dist/components/tour/utils.d.ts +50 -0
- package/dist/components/tour/utils.d.ts.map +1 -0
- package/dist/components/tour/utils.js +60 -0
- package/dist/components/tour/utils.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/layout.css +1 -1
- package/package.json +7 -4
- package/readme.md +2 -0
- package/src/Layout.tsx +23 -41
- package/src/WelcomeTour.tsx +8 -0
- package/src/components/PortalSwitcher.tsx +42 -1
- package/src/components/error/ErrorBoundary.tsx +1 -1
- package/src/components/error/ErrorManager.ts +1 -1
- package/src/components/error/SilentErrorBoundary.tsx +1 -1
- package/src/components/tour/StepContainer.tsx +83 -0
- package/src/components/tour/StepNavigation.tsx +70 -0
- package/src/components/tour/StepTitle.tsx +27 -0
- package/src/components/tour/hook.ts +12 -0
- package/src/components/tour/index.ts +6 -0
- package/src/components/tour/manager.tsx +111 -0
- package/src/components/tour/utils.tsx +100 -0
- package/src/index.ts +1 -0
- package/src/layout.css +1 -1
- package/dist/components/tour/PortalSwitcherStep.d.ts +0 -8
- package/dist/components/tour/PortalSwitcherStep.d.ts.map +0 -1
- package/dist/components/tour/PortalSwitcherStep.js +0 -34
- package/dist/components/tour/PortalSwitcherStep.js.map +0 -1
- package/src/components/tour/PortalSwitcherStep.tsx +0 -39
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { theme } from '@stack-spot/portal-theme'
|
|
2
|
+
import { ReactNode } from 'react'
|
|
3
|
+
import { styled } from 'styled-components'
|
|
4
|
+
import { NavigationProps, StepNavigation } from './StepNavigation'
|
|
5
|
+
import { StepTitle } from './StepTitle'
|
|
6
|
+
import { useTour } from './hook'
|
|
7
|
+
|
|
8
|
+
interface StepContainerProps {
|
|
9
|
+
children: ReactNode,
|
|
10
|
+
/**
|
|
11
|
+
* The unique identifier for the step.
|
|
12
|
+
*/
|
|
13
|
+
stepKey: string,
|
|
14
|
+
/**
|
|
15
|
+
* The title for the step.
|
|
16
|
+
*/
|
|
17
|
+
title: string,
|
|
18
|
+
/**
|
|
19
|
+
* The position of the tour overlay related to the content being explained.
|
|
20
|
+
*/
|
|
21
|
+
position: PointingArrowPosition,
|
|
22
|
+
/**
|
|
23
|
+
* A customizable set of buttons for navigating the tour steps.
|
|
24
|
+
*/
|
|
25
|
+
customNavigation?: Omit<NavigationProps, 'stepKey'>,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Tutorial: the overlay component for showing a step on React Tour.
|
|
30
|
+
* @param props the react props for the component {@link StepContainerProps}.
|
|
31
|
+
*/
|
|
32
|
+
export const StepContainer = ({ title, stepKey, customNavigation, position, children }: StepContainerProps) => {
|
|
33
|
+
const { finishStep } = useTour()
|
|
34
|
+
return <BoxWithPointingArrow $position={position}>
|
|
35
|
+
<StepTitle title={title} onClose={() => finishStep(stepKey)} />
|
|
36
|
+
{children}
|
|
37
|
+
<StepNavigation stepKey={stepKey} {...(customNavigation || {})} />
|
|
38
|
+
</BoxWithPointingArrow>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type PointingArrowPosition = 'right' | 'top' | 'left' | 'bottom'
|
|
42
|
+
|
|
43
|
+
const BoxWithPointingArrow = styled.div < {
|
|
44
|
+
$position: PointingArrowPosition,
|
|
45
|
+
$top?: string,
|
|
46
|
+
$right?: string,
|
|
47
|
+
} > `
|
|
48
|
+
position: relative;
|
|
49
|
+
width: 100%;
|
|
50
|
+
background-color: ${theme.color.inverse[500]};
|
|
51
|
+
&::after {
|
|
52
|
+
content: '';
|
|
53
|
+
position: absolute;
|
|
54
|
+
border-width: 10px;
|
|
55
|
+
border-style: solid;
|
|
56
|
+
border-color: transparent;
|
|
57
|
+
margin-top: -5px;
|
|
58
|
+
border-right-color: ${theme.color.inverse[500]};
|
|
59
|
+
${({ $position, $top }) => $position === 'right' ?
|
|
60
|
+
`
|
|
61
|
+
top: ${$top || '16px'};
|
|
62
|
+
left: -18px;
|
|
63
|
+
` : ''}
|
|
64
|
+
${({ $position, $right }) => $position === 'top' ?
|
|
65
|
+
`
|
|
66
|
+
bottom: 96%;
|
|
67
|
+
right: ${$right || '16px'};
|
|
68
|
+
transform: rotate(90deg);
|
|
69
|
+
` : ''}
|
|
70
|
+
${({ $position, $top }) => $position === 'left' ?
|
|
71
|
+
`
|
|
72
|
+
top: ${$top || '16px'};
|
|
73
|
+
right: -18px;
|
|
74
|
+
transform: rotate(180deg);
|
|
75
|
+
` : ''}
|
|
76
|
+
${({ $position, $right }) => $position === 'bottom' ?
|
|
77
|
+
`
|
|
78
|
+
top: -13px;
|
|
79
|
+
right: ${$right || '16px'};
|
|
80
|
+
transform: rotate(90deg);
|
|
81
|
+
` : ''}
|
|
82
|
+
}
|
|
83
|
+
`
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Button, Flex, Text } from '@citric/core'
|
|
2
|
+
import '@stack-spot/portal-theme/dist/theme.css'
|
|
3
|
+
import { useTranslate } from '@stack-spot/portal-translate'
|
|
4
|
+
import { useTour } from './hook'
|
|
5
|
+
|
|
6
|
+
interface CustomNavigationButton {
|
|
7
|
+
/**
|
|
8
|
+
* The text content to render.
|
|
9
|
+
*/
|
|
10
|
+
text: string,
|
|
11
|
+
onClick?: () => void,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface NavigationProps {
|
|
15
|
+
/**
|
|
16
|
+
* The unique identifier of the step.
|
|
17
|
+
*/
|
|
18
|
+
stepKey: string,
|
|
19
|
+
/**
|
|
20
|
+
* The text and click handler for the button "next".
|
|
21
|
+
*/
|
|
22
|
+
nextButton?: CustomNavigationButton,
|
|
23
|
+
/**
|
|
24
|
+
* The text and click handler for the button "previous".
|
|
25
|
+
*/
|
|
26
|
+
prevButton?: CustomNavigationButton,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Tutorial: the component in a React Tour overlay that shows the next and previous buttons (for step navigation).
|
|
31
|
+
* @param props the react props for the component {@link NavigationProps}.
|
|
32
|
+
*/
|
|
33
|
+
export const StepNavigation = ({ stepKey, nextButton, prevButton }: NavigationProps) => {
|
|
34
|
+
const { currentStep, steps, prevStep, finishStep } = useTour()
|
|
35
|
+
const t = useTranslate(translations)
|
|
36
|
+
|
|
37
|
+
return <Flex w={12} px={5} py={2} mt="-1px" bg="inverse.500" justifyContent="space-between" alignItems="center">
|
|
38
|
+
<Text appearance="microtext1" colorScheme="inverse.contrastText">{currentStep + 1} {t.of} {steps.length}</Text>
|
|
39
|
+
<Flex sx={{ gap: '8px' }}>
|
|
40
|
+
{currentStep >= 1 &&
|
|
41
|
+
<Button sx={{ paddingInline: '20px' }} onClick={() => {
|
|
42
|
+
prevStep?.()
|
|
43
|
+
prevButton?.onClick?.()
|
|
44
|
+
}} size="sm" appearance="text" colorScheme="light">
|
|
45
|
+
{prevButton?.text || t.back}
|
|
46
|
+
</Button>}
|
|
47
|
+
<Button sx={{ paddingInline: '20px' }} onClick={() => {
|
|
48
|
+
nextButton?.onClick?.()
|
|
49
|
+
finishStep(stepKey)
|
|
50
|
+
}} size="sm" colorScheme="light">
|
|
51
|
+
{nextButton?.text || (currentStep < steps.length - 1 ? t.next : t.done)}
|
|
52
|
+
</Button>
|
|
53
|
+
</Flex>
|
|
54
|
+
</Flex>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const translations = {
|
|
58
|
+
en: {
|
|
59
|
+
of: 'of',
|
|
60
|
+
back: 'Back',
|
|
61
|
+
next: 'Next',
|
|
62
|
+
done: 'Done',
|
|
63
|
+
},
|
|
64
|
+
pt: {
|
|
65
|
+
of: 'de',
|
|
66
|
+
back: 'Voltar',
|
|
67
|
+
next: 'Próximo',
|
|
68
|
+
done: 'Finalizado',
|
|
69
|
+
},
|
|
70
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Button, Flex, IconBox, Text } from '@citric/core'
|
|
2
|
+
import { TimesMini } from '@citric/icons'
|
|
3
|
+
|
|
4
|
+
interface StepTitleProps {
|
|
5
|
+
/**
|
|
6
|
+
* The step's title.
|
|
7
|
+
*/
|
|
8
|
+
title: string,
|
|
9
|
+
/**
|
|
10
|
+
* A function to run once the step is closed.
|
|
11
|
+
*/
|
|
12
|
+
onClose?: () => void,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Tutorial: the component in a React Tour overlay that renders the title.
|
|
17
|
+
* @param props the react props for the component {@link StepTitleProps}.
|
|
18
|
+
*/
|
|
19
|
+
export const StepTitle = ({ title, onClose }: StepTitleProps) =>
|
|
20
|
+
<Flex w={12} pl={5} py={3} flexWrap="nowrap" justifyContent="space-between" alignItems="center">
|
|
21
|
+
<Text appearance="body2" colorScheme="inverse.contrastText" weight="medium"> {title} </Text>
|
|
22
|
+
<Button appearance="text" size="sm" onClick={() => onClose?.()} sx={{ ':hover': { borderColor: 'transparent !important' } }}>
|
|
23
|
+
<IconBox size="xs" colorIcon="inverse.contrastText">
|
|
24
|
+
<TimesMini />
|
|
25
|
+
</IconBox>
|
|
26
|
+
</Button>
|
|
27
|
+
</Flex>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
import { TourConfigExtra, tourManager } from './manager'
|
|
3
|
+
|
|
4
|
+
export const useTour = () => {
|
|
5
|
+
const [tourConfig, setTourConfig] = useState<TourConfigExtra>(tourManager.config)
|
|
6
|
+
|
|
7
|
+
useEffect(() => tourManager.subscribe((config) => {
|
|
8
|
+
setTourConfig(config)
|
|
9
|
+
}), [])
|
|
10
|
+
|
|
11
|
+
return tourConfig
|
|
12
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
|
|
2
|
+
export { StepContainer } from './StepContainer'
|
|
3
|
+
export { useTour } from './hook'
|
|
4
|
+
export { TourConfig, TourConfigListener, TourStep, WelcomeTour, tourManager } from './manager'
|
|
5
|
+
export { StackspotTourStep, hasFinishedTourStep, isNewTourStep, tourStepBuilder } from './utils'
|
|
6
|
+
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import WelcomeTour, { ReactourProps, ReactourStep } from 'reactour'
|
|
2
|
+
import { StackspotTourStep, finishTourStep, isNewTourStep, tourStepBuilder } from './utils'
|
|
3
|
+
|
|
4
|
+
export type TourConfig = Omit<ReactourProps, 'children'>
|
|
5
|
+
export type TourStep = ReactourStep
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Tutorial: the default configuration for a React Tour.
|
|
9
|
+
*/
|
|
10
|
+
const defaultTourConfig: TourConfig = Object.freeze({
|
|
11
|
+
steps: [],
|
|
12
|
+
isOpen: true,
|
|
13
|
+
onRequestClose: () => '',
|
|
14
|
+
showButtons: false,
|
|
15
|
+
showNavigation: false,
|
|
16
|
+
showNavigationNumber: false,
|
|
17
|
+
showNumber: false,
|
|
18
|
+
showCloseButton: false,
|
|
19
|
+
disableFocusLock: true,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export type TourConfigExtra = TourConfig & {
|
|
24
|
+
currentStep: number,
|
|
25
|
+
finishStep: (stepSelector: string) => void,
|
|
26
|
+
addStep: (step: StackspotTourStep) => void,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type TourConfigListener = (config: TourConfigExtra) => void
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* TourManager: provides state management for React Tour.
|
|
34
|
+
*/
|
|
35
|
+
class TourManager {
|
|
36
|
+
|
|
37
|
+
private _steps: TourStep[] = []
|
|
38
|
+
private _currentStep = 0
|
|
39
|
+
private observers: TourConfigListener[] = []
|
|
40
|
+
|
|
41
|
+
get config(): TourConfigExtra {
|
|
42
|
+
const config = {
|
|
43
|
+
...defaultTourConfig,
|
|
44
|
+
goToStep: this._currentStep,
|
|
45
|
+
update: `${this._currentStep}`,
|
|
46
|
+
steps: this._steps,
|
|
47
|
+
isOpen: !!this._steps.length && (this._currentStep < this._steps.length),
|
|
48
|
+
currentStep: this._currentStep,
|
|
49
|
+
nextStep: () => this.nextStep(),
|
|
50
|
+
prevStep: () => this.prevStep(),
|
|
51
|
+
finishStep: (stepSelector: string) => this.finishStep(stepSelector),
|
|
52
|
+
addStep: (step: StackspotTourStep) => this.addStep(step),
|
|
53
|
+
}
|
|
54
|
+
return config
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get currentStep() {
|
|
58
|
+
return this._currentStep
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get steps() {
|
|
62
|
+
return this._steps
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
addStep(step: StackspotTourStep) {
|
|
66
|
+
this.addRawStep(tourStepBuilder(step))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
addRawStep(step: TourStep) {
|
|
70
|
+
const stepAlreadyAdded = this._steps.some(it => it.selector == step.selector)
|
|
71
|
+
if (!stepAlreadyAdded && isNewTourStep(step)) {
|
|
72
|
+
this._steps = [...this._steps, step]
|
|
73
|
+
this.notify()
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
nextStep() {
|
|
78
|
+
this._currentStep = this._currentStep + 1
|
|
79
|
+
this.notify()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
prevStep() {
|
|
83
|
+
this._currentStep = this._currentStep - 1
|
|
84
|
+
this.notify()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
finishStep(stepSelector: string) {
|
|
88
|
+
finishTourStep(stepSelector)
|
|
89
|
+
this.nextStep()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
subscribe(updateFn: TourConfigListener) {
|
|
93
|
+
this.observers.push(updateFn)
|
|
94
|
+
this.notify()
|
|
95
|
+
return () => this.pullListener(updateFn)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private pullListener(updateFn: TourConfigListener) {
|
|
99
|
+
this.observers = this.observers.filter((obs) => obs !== updateFn)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private notify() {
|
|
103
|
+
this.observers.forEach((updateFn) => updateFn(this.config))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const tourManager = new TourManager()
|
|
109
|
+
|
|
110
|
+
export { TourConfigListener, WelcomeTour, tourManager }
|
|
111
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { getCookie, setCookie } from '@stack-spot/portal-components'
|
|
2
|
+
import { theme } from '@stack-spot/portal-theme'
|
|
3
|
+
import { ReactNode } from 'react'
|
|
4
|
+
import { ReactourStep } from 'reactour'
|
|
5
|
+
import { PointingArrowPosition, StepContainer } from './StepContainer'
|
|
6
|
+
import { NavigationProps } from './StepNavigation'
|
|
7
|
+
|
|
8
|
+
const TOUR_COOKIE = 'guided-tour-global'
|
|
9
|
+
|
|
10
|
+
const defaultExpires = new Date()
|
|
11
|
+
defaultExpires.setFullYear(new Date().getFullYear() + 1)
|
|
12
|
+
|
|
13
|
+
const getTourCookie = () => {
|
|
14
|
+
const currentTourObject = getCookie(TOUR_COOKIE)
|
|
15
|
+
return currentTourObject ? currentTourObject.split(',') : []
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Tutorial: marks the tour step as finished. This sets a cookie, preventing the tour from showing again.
|
|
20
|
+
* @param key the identifier for the step to mark as finished.
|
|
21
|
+
*/
|
|
22
|
+
export const finishTourStep = (key: string) => {
|
|
23
|
+
const finishedTours: string[] = getTourCookie()
|
|
24
|
+
if (!finishedTours.includes(key)) finishedTours.push(key)
|
|
25
|
+
setCookie(TOUR_COOKIE, finishedTours.toString(), { expires: defaultExpires.toUTCString() })
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Tutorial: verifies if the React Tour step has not finished yet.
|
|
30
|
+
*
|
|
31
|
+
* A step has not finished if the array stored as a cookie doesn't include the string value of `step.selector`.
|
|
32
|
+
* @param step the step config.
|
|
33
|
+
* @returns true if the step has not yet been marked as finished. False otherwise.
|
|
34
|
+
*/
|
|
35
|
+
export const isNewTourStep = (step: ReactourStep) => !hasFinishedTourStep(`${step.selector}`)
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Tutorial: verifies if the key passed as parameter refers to a React Tour step that has already finished.
|
|
39
|
+
*
|
|
40
|
+
* The key refers to a finished step if the array stored as a cookie includes it.
|
|
41
|
+
* If the cookie is set to 'disabled', then the step will be considered finished.Particularly useful in scenarios like e2e tests.
|
|
42
|
+
* @param key the step's identifier to check.
|
|
43
|
+
* @returns true if the key refers to a finished step. False otherwise.
|
|
44
|
+
*/
|
|
45
|
+
export const hasFinishedTourStep = (key: string) => {
|
|
46
|
+
const tourCookie = getTourCookie()
|
|
47
|
+
return tourCookie.includes(key) || tourCookie[0] === 'disabled'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface StackspotTourStep extends ReactourStep {
|
|
51
|
+
/**
|
|
52
|
+
* The step's title.
|
|
53
|
+
*/
|
|
54
|
+
title: string,
|
|
55
|
+
/**
|
|
56
|
+
* The unique identifier for the step (key).
|
|
57
|
+
*/
|
|
58
|
+
selector: string,
|
|
59
|
+
/**
|
|
60
|
+
* The step's content.
|
|
61
|
+
*/
|
|
62
|
+
content: ReactNode,
|
|
63
|
+
/**
|
|
64
|
+
* A set of properties for customizing the next and previous buttons.
|
|
65
|
+
*/
|
|
66
|
+
customNavigation?: NavigationProps,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Tutorial: utility for building a React Tour step. This already includes some default configuration for tours in Stackspot.
|
|
71
|
+
* @param options the options for building the step: {@link StackspotTourStep}.
|
|
72
|
+
* @returns the React Tour step.
|
|
73
|
+
*/
|
|
74
|
+
export const tourStepBuilder = ({
|
|
75
|
+
selector,
|
|
76
|
+
position,
|
|
77
|
+
title,
|
|
78
|
+
content,
|
|
79
|
+
style,
|
|
80
|
+
customNavigation,
|
|
81
|
+
...rest
|
|
82
|
+
}: StackspotTourStep): ReactourStep => ({
|
|
83
|
+
selector,
|
|
84
|
+
content: (<StepContainer
|
|
85
|
+
stepKey={selector}
|
|
86
|
+
position={position as PointingArrowPosition}
|
|
87
|
+
title={title}
|
|
88
|
+
customNavigation={customNavigation}>
|
|
89
|
+
{content}
|
|
90
|
+
</StepContainer>),
|
|
91
|
+
position,
|
|
92
|
+
style: {
|
|
93
|
+
backgroundColor: theme.color.inverse[500],
|
|
94
|
+
width: '256px',
|
|
95
|
+
padding: 0,
|
|
96
|
+
top: ['right', 'left'].includes(position as PointingArrowPosition) ? '-3px' : '0',
|
|
97
|
+
...(style || {}),
|
|
98
|
+
},
|
|
99
|
+
...(rest || {}),
|
|
100
|
+
})
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { PortalSwitcher } from './components/PortalSwitcher'
|
|
|
7
7
|
export { ActionItem, MenuContent, MenuGroup, Title } from './components/menu/MenuContent'
|
|
8
8
|
export { MenuSections } from './components/menu/MenuSections'
|
|
9
9
|
export * from './components/menu/types'
|
|
10
|
+
export * from './components/tour'
|
|
10
11
|
export * from './components/types'
|
|
11
12
|
export * from './elements'
|
|
12
13
|
export * from './errors'
|
package/src/layout.css
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { TourStep } from '@stack-spot/portal-components/Tour';
|
|
2
|
-
/**
|
|
3
|
-
* Tutorial: a React hook for retrieving the React Tour step that explains how the portal switcher works. The portal switcher is a component
|
|
4
|
-
* at the top left corner of the layout (header) that allows the user to switch between the different Stackspot portals.
|
|
5
|
-
* @returns the React Tour step for the PortalSwitcher.
|
|
6
|
-
*/
|
|
7
|
-
export declare const usePortalSwitcherStep: () => TourStep;
|
|
8
|
-
//# sourceMappingURL=PortalSwitcherStep.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PortalSwitcherStep.d.ts","sourceRoot":"","sources":["../../../src/components/tour/PortalSwitcherStep.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAmB,MAAM,oCAAoC,CAAA;AAG9E;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAO,QAgBxC,CAAA"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Image, Text } from '@citric/core';
|
|
3
|
-
import { tourStepBuilder } from '@stack-spot/portal-components/Tour';
|
|
4
|
-
import { useTranslate } from '@stack-spot/portal-translate';
|
|
5
|
-
/**
|
|
6
|
-
* Tutorial: a React hook for retrieving the React Tour step that explains how the portal switcher works. The portal switcher is a component
|
|
7
|
-
* at the top left corner of the layout (header) that allows the user to switch between the different Stackspot portals.
|
|
8
|
-
* @returns the React Tour step for the PortalSwitcher.
|
|
9
|
-
*/
|
|
10
|
-
export const usePortalSwitcherStep = () => {
|
|
11
|
-
const t = useTranslate(translations);
|
|
12
|
-
return tourStepBuilder({
|
|
13
|
-
selector: '.portal-switcher',
|
|
14
|
-
title: t.title,
|
|
15
|
-
content: _jsxs(_Fragment, { children: [_jsx(Image, { src: "https://marketing.stackspot.com/switch-v2.gif", alt: t.imageAlt }), _jsx(Box, { px: 5, py: 3, children: _jsx(Text, { appearance: "microtext1", colorScheme: "inverse.contrastText", children: t.description }) })] }),
|
|
16
|
-
position: 'right',
|
|
17
|
-
style: {
|
|
18
|
-
width: '300px',
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
const translations = {
|
|
23
|
-
en: {
|
|
24
|
-
title: 'Expand Your Horizons with Stackspot',
|
|
25
|
-
description: 'Easily switch between EDP and AI to enhance your projects. Access a wide range of resources with just one click and take your projects to a new level of efficiency. Start your journey now!',
|
|
26
|
-
imageAlt: 'GIF describing how to use product switcher and navigate between AI and EDP portals',
|
|
27
|
-
},
|
|
28
|
-
pt: {
|
|
29
|
-
title: 'Expanda Seus Horizontes com Stackspot',
|
|
30
|
-
description: 'Troque facilmente entre EDP e AI para aprimorar seus projetos. Acesse uma ampla gama de recursos com apenas um clique e leve seus projetos para um novo nível de eficiência. Comece sua jornada agora!',
|
|
31
|
-
imageAlt: 'GIF mostrando como usar o alternador de produtos e navegar entre os portais AI e EDP',
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
//# sourceMappingURL=PortalSwitcherStep.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PortalSwitcherStep.js","sourceRoot":"","sources":["../../../src/components/tour/PortalSwitcherStep.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAY,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAa,EAAE;IAClD,MAAM,CAAC,GAAG,YAAY,CAAC,YAAY,CAAC,CAAA;IACpC,OAAO,eAAe,CAAC;QACrB,QAAQ,EAAE,kBAAkB;QAC5B,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,8BACP,KAAC,KAAK,IAAC,GAAG,EAAC,+CAA+C,EAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,GAAI,EAC9E,KAAC,GAAG,IAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,UAAU,EAAC,YAAY,EAAC,WAAW,EAAC,sBAAsB,YAAE,CAAC,CAAC,WAAW,GAAQ,GACnF,IACL;QACH,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE;YACL,KAAK,EAAE,OAAO;SACf;KACF,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,YAAY,GAAG;IACnB,EAAE,EAAE;QACF,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EAAE,8LAA8L;QAC3M,QAAQ,EAAE,oFAAoF;KAC/F;IACD,EAAE,EAAE;QACF,KAAK,EAAE,uCAAuC;QAC9C,WAAW,EAAE,wMAAwM;QACrN,QAAQ,EAAE,sFAAsF;KACjG;CACF,CAAA"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Box, Image, Text } from '@citric/core'
|
|
2
|
-
import { TourStep, tourStepBuilder } from '@stack-spot/portal-components/Tour'
|
|
3
|
-
import { useTranslate } from '@stack-spot/portal-translate'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Tutorial: a React hook for retrieving the React Tour step that explains how the portal switcher works. The portal switcher is a component
|
|
7
|
-
* at the top left corner of the layout (header) that allows the user to switch between the different Stackspot portals.
|
|
8
|
-
* @returns the React Tour step for the PortalSwitcher.
|
|
9
|
-
*/
|
|
10
|
-
export const usePortalSwitcherStep = (): TourStep => {
|
|
11
|
-
const t = useTranslate(translations)
|
|
12
|
-
return tourStepBuilder({
|
|
13
|
-
selector: '.portal-switcher',
|
|
14
|
-
title: t.title,
|
|
15
|
-
content: <>
|
|
16
|
-
<Image src="https://marketing.stackspot.com/switch-v2.gif" alt={t.imageAlt} />
|
|
17
|
-
<Box px={5} py={3}>
|
|
18
|
-
<Text appearance="microtext1" colorScheme="inverse.contrastText">{t.description}</Text>
|
|
19
|
-
</Box>
|
|
20
|
-
</>,
|
|
21
|
-
position: 'right',
|
|
22
|
-
style: {
|
|
23
|
-
width: '300px',
|
|
24
|
-
},
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const translations = {
|
|
29
|
-
en: {
|
|
30
|
-
title: 'Expand Your Horizons with Stackspot',
|
|
31
|
-
description: 'Easily switch between EDP and AI to enhance your projects. Access a wide range of resources with just one click and take your projects to a new level of efficiency. Start your journey now!',
|
|
32
|
-
imageAlt: 'GIF describing how to use product switcher and navigate between AI and EDP portals',
|
|
33
|
-
},
|
|
34
|
-
pt: {
|
|
35
|
-
title: 'Expanda Seus Horizontes com Stackspot',
|
|
36
|
-
description: 'Troque facilmente entre EDP e AI para aprimorar seus projetos. Acesse uma ampla gama de recursos com apenas um clique e leve seus projetos para um novo nível de eficiência. Comece sua jornada agora!',
|
|
37
|
-
imageAlt: 'GIF mostrando como usar o alternador de produtos e navegar entre os portais AI e EDP',
|
|
38
|
-
},
|
|
39
|
-
}
|