react-joyride
Advanced tools
Comparing version 3.0.0-4 to 3.0.0-5
@@ -17,2 +17,3 @@ import * as react_jsx_runtime from 'react/jsx-runtime'; | ||
readonly UPDATE: "update"; | ||
readonly COMPLETE: "complete"; | ||
}; | ||
@@ -102,2 +103,3 @@ declare const EVENTS: { | ||
type Placement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'; | ||
type SpotlightCSSProperties = Omit<CSSProperties, 'height' | 'width' | 'bottom' | 'left' | 'right' | 'top'>; | ||
interface Styles { | ||
@@ -115,4 +117,4 @@ beacon: CSSProperties; | ||
overlayLegacyCenter: CSSProperties; | ||
spotlight: CSSProperties; | ||
spotlightLegacy: CSSProperties; | ||
spotlight: SpotlightCSSProperties; | ||
spotlightLegacy: SpotlightCSSProperties; | ||
tooltip: CSSProperties; | ||
@@ -126,3 +128,3 @@ tooltipContainer: CSSProperties; | ||
interface StylesWithFloaterStyles extends Styles { | ||
floaterStyles: Styles$1; | ||
floaterStyles: PartialDeep<Styles$1>; | ||
} | ||
@@ -141,37 +143,2 @@ interface StylesOptions { | ||
type Listener = (state: State) => void; | ||
type PopperData = Parameters<NonNullable<Props$1['getPopper']>>[0]; | ||
declare class Store { | ||
private beaconPopper; | ||
private tooltipPopper; | ||
private data; | ||
private listener; | ||
private store; | ||
constructor(options?: StoreOptions); | ||
getState(): State; | ||
private getNextState; | ||
private getSteps; | ||
private hasUpdatedState; | ||
private setState; | ||
addListener: (listener: Listener) => void; | ||
setSteps: (steps: Array<Step>) => void; | ||
getHelpers(): StoreHelpers; | ||
getPopper: (name: "beacon" | "tooltip") => PopperData | null; | ||
setPopper: (name: "beacon" | "tooltip", popper: PopperData) => void; | ||
cleanupPoppers: () => void; | ||
close: (origin?: Origin | null) => void; | ||
go: (nextIndex: number) => void; | ||
info: () => State; | ||
next: () => void; | ||
open: () => void; | ||
prev: () => void; | ||
reset: (restart?: boolean) => void; | ||
skip: () => void; | ||
start: (nextIndex?: number) => void; | ||
stop: (advance?: boolean) => void; | ||
update: (state: Partial<State>) => void; | ||
} | ||
type StoreInstance = ReturnType<typeof createStore>; | ||
declare function createStore(options?: StoreOptions): Store; | ||
type FloaterProps = Omit<Props$1, 'content' | 'component'>; | ||
@@ -439,3 +406,3 @@ type SelectorOrElement = string | null | HTMLElement; | ||
type StepProps = Simplify<State & { | ||
callback?: Callback; | ||
cleanupPoppers: () => void; | ||
continuous: boolean; | ||
@@ -445,5 +412,6 @@ debug: boolean; | ||
nonce?: string; | ||
setPopper: NonNullable<FloaterProps['getPopper']>; | ||
shouldScroll: boolean; | ||
step: StepMerged; | ||
store: StoreInstance; | ||
updateState: (state: Partial<State>) => void; | ||
}>; | ||
@@ -460,5 +428,2 @@ type StoreHelpers = { | ||
}; | ||
type StoreOptions = Simplify<Props & { | ||
controlled: boolean; | ||
}>; | ||
type TooltipProps = { | ||
@@ -509,4 +474,5 @@ continuous: boolean; | ||
declare function Joyride(props: Props): react_jsx_runtime.JSX.Element | null; | ||
declare function ReactJoyride(props: Props): react_jsx_runtime.JSX.Element | null; | ||
export { ACTIONS, type Actions, type AnyObject, type BaseProps, type BeaconProps, type BeaconRenderProps, type CallBackProps, type Callback, EVENTS, type Events, type FloaterProps, LIFECYCLE, type Lifecycle, type Locale, type NarrowPlainObject, ORIGIN, type Origin, type OverlayProps, PORTAL_ELEMENT_ID, type Placement, type Props, STATUS, type SelectorOrElement, type State, type Status, type Step, type StepMerged, type StepProps, type StoreHelpers, type StoreOptions, type Styles, type StylesOptions, type StylesWithFloaterStyles, type TooltipProps, type TooltipRenderProps, ReactJoyride as default }; | ||
export { ACTIONS, type Actions, type AnyObject, type BaseProps, type BeaconProps, type BeaconRenderProps, type CallBackProps, type Callback, EVENTS, type Events, type FloaterProps, Joyride, LIFECYCLE, type Lifecycle, type Locale, type NarrowPlainObject, ORIGIN, type Origin, type OverlayProps, PORTAL_ELEMENT_ID, type Placement, type Props, STATUS, type SelectorOrElement, type SpotlightCSSProperties, type State, type Status, type Step, type StepMerged, type StepProps, type StoreHelpers, type Styles, type StylesOptions, type StylesWithFloaterStyles, type TooltipProps, type TooltipRenderProps, ReactJoyride as default }; |
{ | ||
"name": "react-joyride", | ||
"version": "3.0.0-4", | ||
"version": "3.0.0-5", | ||
"description": "Create guided tours for your apps", | ||
@@ -42,3 +42,2 @@ "author": "Gil Barbara <gilbarbara@gmail.com>", | ||
"@gilbarbara/hooks": "^0.8.2", | ||
"deep-diff": "^1.0.2", | ||
"deepmerge": "^4.3.1", | ||
@@ -50,3 +49,3 @@ "is-lite": "^1.2.1", | ||
"scrollparent": "^2.1.0", | ||
"tree-changes": "^0.11.2" | ||
"tree-changes-hook": "^0.11.2" | ||
}, | ||
@@ -76,2 +75,3 @@ "devDependencies": { | ||
"caniuse-lite": "^1.0.30001659", | ||
"chalk": "^5.3.0", | ||
"cross-env": "^7.0.3", | ||
@@ -138,2 +138,10 @@ "csstype": "^3.1.3", | ||
} | ||
], | ||
"no-restricted-syntax": [ | ||
"warn", | ||
{ | ||
"message": "Don't forget to remove calls to logger before committing.", | ||
"selector": | ||
"CallExpression[callee.name='logger']" | ||
} | ||
] | ||
@@ -140,0 +148,0 @@ }, |
import { noop } from '~/modules/helpers'; | ||
import { LIFECYCLE, STATUS } from '~/literals'; | ||
import { ACTIONS, LIFECYCLE, STATUS } from '~/literals'; | ||
@@ -74,3 +74,3 @@ import { FloaterProps, Locale, Props, State, Step } from '~/types'; | ||
export const defaultState: State = { | ||
action: 'init', | ||
action: ACTIONS.INIT, | ||
controlled: false, | ||
@@ -77,0 +77,0 @@ index: 0, |
@@ -12,2 +12,3 @@ export const ACTIONS = { | ||
UPDATE: 'update', | ||
COMPLETE: 'complete', | ||
} as const; | ||
@@ -14,0 +15,0 @@ |
@@ -58,3 +58,7 @@ import scroll from 'scroll'; | ||
*/ | ||
export function getElement(element: string | HTMLElement): HTMLElement | null { | ||
export function getElement(element?: string | HTMLElement): HTMLElement | null { | ||
if (!element) { | ||
return null; | ||
} | ||
if (typeof element === 'string') { | ||
@@ -61,0 +65,0 @@ try { |
@@ -119,10 +119,2 @@ import { isValidElement, ReactNode } from 'react'; | ||
export function hasValidKeys(object: Record<string, unknown>, keys?: Array<string>): boolean { | ||
if (!is.plainObject(object) || !is.array(keys)) { | ||
return false; | ||
} | ||
return Object.keys(object).every(d => keys.includes(d)); | ||
} | ||
/** | ||
@@ -146,4 +138,3 @@ * Convert hex to RGB | ||
const withContinuous = | ||
continuous && ([ACTIONS.PREV, ACTIONS.NEXT, ACTIONS.UPDATE] as Actions[]).includes(action); | ||
const withContinuous = continuous && ([ACTIONS.PREV, ACTIONS.NEXT] as Actions[]).includes(action); | ||
@@ -167,3 +158,3 @@ return step.disableBeacon || step.placement === 'center' || withContinuous; | ||
/* eslint-disable no-console */ | ||
const logFn = warn ? console.warn || console.error : console.log; | ||
const logFn = warn ? console.warn ?? console.error : console.log; | ||
@@ -170,0 +161,0 @@ if (debug) { |
@@ -35,3 +35,7 @@ import { Props as FloaterProps } from 'react-floater'; | ||
export function getMergedStep(props: Props, currentStep?: Step): StepMerged { | ||
export function getMergedStep(props: Props, currentStep?: Step): StepMerged | null { | ||
if (!currentStep) { | ||
return null; | ||
} | ||
const step = currentStep ?? {}; | ||
@@ -38,0 +42,0 @@ const mergedStep = deepmerge.all([defaultStep, getTourProps(props), step], { |
import { Props as FloaterProps } from 'react-floater'; | ||
import deepEqual from '@gilbarbara/deep-equal'; | ||
import is from 'is-lite'; | ||
import { getMergedStep } from '~/modules/step'; | ||
import { ACTIONS, LIFECYCLE, STATUS } from '~/literals'; | ||
import { Origin, State, Status, Step, StoreHelpers, StoreOptions } from '~/types'; | ||
import { Origin, Props, State, Status, Step, StoreHelpers } from '~/types'; | ||
import { hasValidKeys, objectKeys, omit } from './helpers'; | ||
type StateWithContinuous = State & { continuous: boolean }; | ||
@@ -23,3 +24,2 @@ type Listener = (state: State) => void; | ||
}; | ||
const validKeys = objectKeys(omit(defaultState, 'controlled', 'size')); | ||
@@ -29,7 +29,8 @@ class Store { | ||
private tooltipPopper: PopperData | null; | ||
private data: Map<string, any> = new Map(); | ||
private readonly data: Map<string, any> = new Map(); | ||
private listener: Listener | null; | ||
private store: Map<string, any> = new Map(); | ||
private readonly props: Props; | ||
private readonly store: Map<string, any> = new Map(); | ||
constructor(options?: StoreOptions) { | ||
constructor(options?: Props) { | ||
const { continuous = false, stepIndex, steps = [] } = options ?? {}; | ||
@@ -50,54 +51,42 @@ | ||
this.setSteps(steps); | ||
this.beaconPopper = null; | ||
this.tooltipPopper = null; | ||
this.listener = null; | ||
this.setSteps(steps); | ||
this.props = options ?? { steps: [] }; | ||
} | ||
public getState(): State { | ||
if (!this.store.size) { | ||
return { ...defaultState }; | ||
} | ||
private getStep(nextIndex?: number): Step | null { | ||
const steps = this.data.get('steps'); | ||
const { index } = this.getState(); | ||
return { | ||
action: this.store.get('action') || '', | ||
controlled: this.store.get('controlled') || false, | ||
index: parseInt(this.store.get('index'), 10), | ||
lifecycle: this.store.get('lifecycle') || '', | ||
origin: this.store.get('origin') || null, | ||
size: this.store.get('size') || 0, | ||
status: (this.store.get('status') as Status) || '', | ||
}; | ||
return getMergedStep(this.props, steps[nextIndex ?? index]); | ||
} | ||
private getNextState(state: Partial<State>, force: boolean = false): State { | ||
const { action, controlled, index, size, status } = this.getState(); | ||
const newIndex = is.number(state.index) ? state.index : index; | ||
const nextIndex = controlled && !force ? index : Math.min(Math.max(newIndex, 0), size); | ||
private getUpdatedIndex(nextIndex: number): number { | ||
const { size } = this.getState(); | ||
return { | ||
action: state.action ?? action, | ||
controlled, | ||
index: nextIndex, | ||
lifecycle: state.lifecycle ?? LIFECYCLE.INIT, | ||
origin: state.origin ?? null, | ||
size: state.size ?? size, | ||
status: nextIndex === size ? STATUS.FINISHED : state.status ?? status, | ||
}; | ||
return Math.min(Math.max(nextIndex, 0), size); | ||
} | ||
private getSteps(): Array<Step> { | ||
const steps = this.data.get('steps'); | ||
return Array.isArray(steps) ? steps : []; | ||
private hasUpdatedState(oldState: State): boolean { | ||
return !deepEqual(oldState, this.getState()); | ||
} | ||
private hasUpdatedState(oldState: State): boolean { | ||
const before = JSON.stringify(oldState); | ||
const after = JSON.stringify(this.getState()); | ||
private prepareState(patch: Partial<State>, forceIndex: boolean = false): State { | ||
const { action, controlled, index, size, status } = this.getState(); | ||
const newIndex = patch.index ?? index; | ||
return before !== after; | ||
return { | ||
action: patch.action ?? action, | ||
controlled, | ||
index: controlled && !forceIndex ? index : newIndex, | ||
lifecycle: patch.lifecycle ?? LIFECYCLE.INIT, | ||
origin: patch.origin ?? null, | ||
size: patch.size ?? size, | ||
status: patch.status ?? status, | ||
}; | ||
} | ||
private setState(nextState: Partial<StateWithContinuous>, initial: boolean = false) { | ||
private setState(patch: Partial<StateWithContinuous>, initial: boolean = false) { | ||
const state = this.getState(); | ||
@@ -114,3 +103,3 @@ | ||
...state, | ||
...nextState, | ||
...patch, | ||
}; | ||
@@ -126,4 +115,4 @@ | ||
if (initial) { | ||
this.store.set('controlled', nextState.controlled); | ||
this.store.set('continuous', nextState.continuous); | ||
this.store.set('controlled', patch.controlled); | ||
this.store.set('continuous', patch.continuous); | ||
} | ||
@@ -136,2 +125,43 @@ | ||
public updateState = (patch: Partial<State>, forceIndex = false) => { | ||
this.setState({ | ||
...this.getState(), | ||
...this.prepareState(patch, forceIndex), | ||
}); | ||
}; | ||
public cleanupPoppers = () => { | ||
this.beaconPopper = null; | ||
this.tooltipPopper = null; | ||
}; | ||
public getPopper = (name: 'beacon' | 'tooltip'): PopperData | null => { | ||
if (name === 'beacon') { | ||
return this.beaconPopper; | ||
} | ||
return this.tooltipPopper; | ||
}; | ||
public setPopper: NonNullable<FloaterProps['getPopper']> = (popper, type) => { | ||
if (type === 'wrapper') { | ||
this.beaconPopper = popper; | ||
} else { | ||
this.tooltipPopper = popper; | ||
} | ||
if (popper && this.store.get('lifecycle') === LIFECYCLE.COMPLETE) { | ||
this.updateState({ | ||
action: ACTIONS.UPDATE, | ||
lifecycle: LIFECYCLE.INIT, | ||
}); | ||
} | ||
const getPopper = this.getStep()?.floaterProps?.getPopper; | ||
if (getPopper) { | ||
getPopper(popper, type); | ||
} | ||
}; | ||
public addListener = (listener: Listener) => { | ||
@@ -141,2 +171,18 @@ this.listener = listener; | ||
public getState(): State { | ||
if (!this?.store?.size) { | ||
return { ...defaultState }; | ||
} | ||
return { | ||
action: this.store.get('action') || '', | ||
controlled: this.store.get('controlled') || false, | ||
index: parseInt(this.store.get('index'), 10), | ||
lifecycle: this.store.get('lifecycle') || '', | ||
origin: this.store.get('origin') || null, | ||
size: this.store.get('size') || 0, | ||
status: (this.store.get('status') as Status) || '', | ||
}; | ||
} | ||
public setSteps = (steps: Array<Step>) => { | ||
@@ -155,3 +201,3 @@ const { size, status } = this.getState(); | ||
this.setState(state); | ||
this.updateState(state); | ||
}; | ||
@@ -172,23 +218,2 @@ | ||
public getPopper = (name: 'beacon' | 'tooltip'): PopperData | null => { | ||
if (name === 'beacon') { | ||
return this.beaconPopper; | ||
} | ||
return this.tooltipPopper; | ||
}; | ||
public setPopper = (name: 'beacon' | 'tooltip', popper: PopperData) => { | ||
if (name === 'beacon') { | ||
this.beaconPopper = popper; | ||
} else { | ||
this.tooltipPopper = popper; | ||
} | ||
}; | ||
public cleanupPoppers = () => { | ||
this.beaconPopper = null; | ||
this.tooltipPopper = null; | ||
}; | ||
public close = (origin: Origin | null = null) => { | ||
@@ -201,4 +226,7 @@ const { index, status } = this.getState(); | ||
this.setState({ | ||
...this.getNextState({ action: ACTIONS.CLOSE, index: index + 1, origin }), | ||
this.updateState({ | ||
action: ACTIONS.CLOSE, | ||
index: index + 1, | ||
origin, | ||
lifecycle: LIFECYCLE.COMPLETE, | ||
}); | ||
@@ -214,6 +242,8 @@ }; | ||
const step = this.getSteps()[nextIndex]; | ||
const step = this.getStep(nextIndex); | ||
this.setState({ | ||
...this.getNextState({ action: ACTIONS.GO, index: nextIndex }), | ||
this.updateState({ | ||
action: ACTIONS.GO, | ||
index: nextIndex, | ||
lifecycle: LIFECYCLE.COMPLETE, | ||
status: step ? status : STATUS.FINISHED, | ||
@@ -232,3 +262,7 @@ }); | ||
this.setState(this.getNextState({ action: ACTIONS.NEXT, index: index + 1 })); | ||
this.updateState({ | ||
action: ACTIONS.NEXT, | ||
index: this.getUpdatedIndex(index + 1), | ||
lifecycle: LIFECYCLE.COMPLETE, | ||
}); | ||
}; | ||
@@ -243,5 +277,3 @@ | ||
this.setState({ | ||
...this.getNextState({ action: ACTIONS.UPDATE, lifecycle: LIFECYCLE.TOOLTIP }), | ||
}); | ||
this.updateState({ action: ACTIONS.UPDATE, lifecycle: LIFECYCLE.TOOLTIP }); | ||
}; | ||
@@ -256,4 +288,6 @@ | ||
this.setState({ | ||
...this.getNextState({ action: ACTIONS.PREV, index: index - 1 }), | ||
this.updateState({ | ||
action: ACTIONS.PREV, | ||
index: this.getUpdatedIndex(index - 1), | ||
lifecycle: LIFECYCLE.COMPLETE, | ||
}); | ||
@@ -269,4 +303,6 @@ }; | ||
this.setState({ | ||
...this.getNextState({ action: ACTIONS.RESET, index: 0 }), | ||
this.updateState({ | ||
action: ACTIONS.RESET, | ||
index: 0, | ||
lifecycle: LIFECYCLE.COMPLETE, | ||
status: restart ? STATUS.RUNNING : STATUS.READY, | ||
@@ -283,5 +319,5 @@ }); | ||
this.setState({ | ||
this.updateState({ | ||
action: ACTIONS.SKIP, | ||
lifecycle: LIFECYCLE.INIT, | ||
lifecycle: LIFECYCLE.COMPLETE, | ||
status: STATUS.SKIPPED, | ||
@@ -294,12 +330,10 @@ }); | ||
this.setState({ | ||
...this.getNextState( | ||
{ | ||
action: ACTIONS.START, | ||
index: is.number(nextIndex) ? nextIndex : index, | ||
}, | ||
true, | ||
), | ||
status: size ? STATUS.RUNNING : STATUS.WAITING, | ||
}); | ||
this.updateState( | ||
{ | ||
action: ACTIONS.START, | ||
index: is.number(nextIndex) ? nextIndex : index, | ||
status: size ? STATUS.RUNNING : STATUS.WAITING, | ||
}, | ||
true, | ||
); | ||
}; | ||
@@ -314,25 +348,9 @@ | ||
this.setState({ | ||
...this.getNextState({ action: ACTIONS.STOP, index: index + (advance ? 1 : 0) }), | ||
this.updateState({ | ||
action: ACTIONS.STOP, | ||
index: index + (advance ? 1 : 0), | ||
lifecycle: LIFECYCLE.COMPLETE, | ||
status: STATUS.PAUSED, | ||
}); | ||
}; | ||
public update = (state: Partial<State>) => { | ||
if (!hasValidKeys(state, validKeys)) { | ||
throw new Error(`State is not valid. Valid keys: ${validKeys.join(', ')}`); | ||
} | ||
this.setState({ | ||
...this.getNextState( | ||
{ | ||
...this.getState(), | ||
...state, | ||
action: state.action ?? ACTIONS.UPDATE, | ||
origin: state.origin ?? null, | ||
}, | ||
true, | ||
), | ||
}); | ||
}; | ||
} | ||
@@ -342,4 +360,4 @@ | ||
export default function createStore(options?: StoreOptions) { | ||
export default function createStore(options?: Props) { | ||
return new Store(options); | ||
} |
import { useMount, useSetState, useUnmount } from '@gilbarbara/hooks'; | ||
import is from 'is-lite'; | ||
import { canUseDOM } from '~/modules/dom'; | ||
import { PORTAL_ELEMENT_ID } from '~/literals'; | ||
@@ -22,6 +20,2 @@ | ||
useMount(() => { | ||
if (!canUseDOM()) { | ||
return; | ||
} | ||
if (portalElement) { | ||
@@ -50,3 +44,3 @@ if (is.domElement(portalElement)) { | ||
useUnmount(() => { | ||
if (!canUseDOM() || !element || useExternalPortal) { | ||
if (!element || useExternalPortal) { | ||
return; | ||
@@ -53,0 +47,0 @@ } |
import { CSSProperties, ReactNode } from 'react'; | ||
import { Styles as FloaterStyles } from 'react-floater'; | ||
import { ValueOf } from '@gilbarbara/types'; | ||
import { PartialDeep, ValueOf } from '@gilbarbara/types'; | ||
@@ -74,2 +74,7 @@ import { ACTIONS, EVENTS, LIFECYCLE, ORIGIN, STATUS } from '~/literals'; | ||
export type SpotlightCSSProperties = Omit< | ||
CSSProperties, | ||
'height' | 'width' | 'bottom' | 'left' | 'right' | 'top' | ||
>; | ||
export interface Styles { | ||
@@ -87,4 +92,4 @@ beacon: CSSProperties; | ||
overlayLegacyCenter: CSSProperties; | ||
spotlight: CSSProperties; | ||
spotlightLegacy: CSSProperties; | ||
spotlight: SpotlightCSSProperties; | ||
spotlightLegacy: SpotlightCSSProperties; | ||
tooltip: CSSProperties; | ||
@@ -99,3 +104,3 @@ tooltipContainer: CSSProperties; | ||
export interface StylesWithFloaterStyles extends Styles { | ||
floaterStyles: FloaterStyles; | ||
floaterStyles: PartialDeep<FloaterStyles>; | ||
} | ||
@@ -102,0 +107,0 @@ |
@@ -5,4 +5,2 @@ import { ElementType, MouseEventHandler, ReactNode, RefCallback } from 'react'; | ||
import type { StoreInstance } from '~/modules/store'; | ||
import { Actions, Events, Lifecycle, Locale, Origin, Placement, Status, Styles } from './common'; | ||
@@ -316,3 +314,3 @@ | ||
State & { | ||
callback?: Callback; | ||
cleanupPoppers: () => void; | ||
continuous: boolean; | ||
@@ -322,5 +320,6 @@ debug: boolean; | ||
nonce?: string; | ||
setPopper: NonNullable<FloaterProps['getPopper']>; | ||
shouldScroll: boolean; | ||
step: StepMerged; | ||
store: StoreInstance; | ||
updateState: (state: Partial<State>) => void; | ||
} | ||
@@ -340,8 +339,2 @@ >; | ||
export type StoreOptions = Simplify< | ||
Props & { | ||
controlled: boolean; | ||
} | ||
>; | ||
export type TooltipProps = { | ||
@@ -348,0 +341,0 @@ continuous: boolean; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
494112
11
32
39
7807
+ Addedtree-changes-hook@^0.11.2
- Removeddeep-diff@^1.0.2
- Removedtree-changes@^0.11.2
- Removeddeep-diff@1.0.2(transitive)