Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onborda PR #29

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c67d2c4
setup local npm package environment
alexc-harrap Oct 28, 2024
81a99e1
Added nodemon for --watch on 'npm run dev'
alexc-harrap Oct 29, 2024
72dcd42
Update README.md
alexc-harrap Oct 29, 2024
934dbe9
Added optional TourComponent
alexc-harrap Oct 29, 2024
4614fe6
Added interactable toggle to Step to control pointer events of step s…
alexc-harrap Oct 29, 2024
12ade63
Fixed TourCard going off screen. tiur-wrapper now fixed to viewport
alexc-harrap Oct 29, 2024
89cbd5e
Step.selector now optional. When no selector is provided, card and po…
alexc-harrap Nov 4, 2024
524f638
Added optional Step.customQuerySelector for passing a custom querySel…
alexc-harrap Nov 4, 2024
49afe4e
Fixed MutationObserver not running for steps on nextRoute pages. Adde…
alexc-harrap Nov 5, 2024
23e80af
Cleaned up useEffects repeated/reduentant code. Moved TourComponent i…
alexc-harrap Nov 6, 2024
5a523b7
Added nextStepConditions to Step which enabled the ability to restric…
alexc-harrap Nov 6, 2024
fff9739
Updated README
alexc-harrap Nov 6, 2024
d705077
Added support for setting any step as current from TourCard.
alexc-harrap Nov 11, 2024
6f17dd2
Fixed observer timeout when new route is the same as current route
alexc-harrap Nov 11, 2024
b45b078
Added ability to store 'completed' steps in a new useState
alexc-harrap Nov 11, 2024
bec0eec
Added ability to set pre-completed status per step
alexc-harrap Nov 14, 2024
9425d88
Removed unused Tour.completedSteps
alexc-harrap Nov 14, 2024
dbded2e
Update README.md
alexc-harrap Nov 14, 2024
52886b8
Update README.md
alexc-harrap Nov 14, 2024
b79fce3
Update README.md
alexc-harrap Nov 14, 2024
eff7783
Added support for pre-started tour on mount
alexc-harrap Nov 14, 2024
c1039ce
Update README.md
alexc-harrap Nov 14, 2024
2b32a4c
Added onComplete callbacks to the Step object.
alexc-harrap Nov 15, 2024
731d695
Added tours[] to useOnborda context and pass current tour object to T…
alexc-harrap Nov 19, 2024
380f2b0
Update README.md
alexc-harrap Nov 19, 2024
c2ff9fe
Update README.md
alexc-harrap Nov 19, 2024
33c83c9
Added Tour.initialCompletedStepsState prop for fetching boolean[] ste…
alexc-harrap Nov 21, 2024
46d7fd3
Step.icon is now optional. Added TourCard.pendingRouteChange flag and…
alexc-harrap Nov 22, 2024
5dededf
Update README.md
alexc-harrap Nov 22, 2024
151f202
Update README.md
alexc-harrap Nov 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ yarn-debug.log*
yarn-error.log*

# vercel
.vercel
.vercel
/.idea
393 changes: 310 additions & 83 deletions README.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions dist/Onborda.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import React from "react";
import { OnbordaProps } from "./types";
/**
* Onborda Component
* @param {OnbordaProps} props
* @constructor
*/
declare const Onborda: React.FC<OnbordaProps>;
export default Onborda;
574 changes: 267 additions & 307 deletions dist/Onborda.js

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions dist/OnbordaContext.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React from "react";
import { OnbordaContextType } from "./types";
import { OnbordaContextType, OnbordaProviderProps } from "./types";
declare const useOnborda: () => OnbordaContextType;
declare const OnbordaProvider: React.FC<{
children: React.ReactNode;
}>;
declare const OnbordaProvider: React.FC<OnbordaProviderProps>;
export { OnbordaProvider, useOnborda };
68 changes: 60 additions & 8 deletions dist/OnbordaContext.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext, useState, useCallback } from "react";
import { createContext, useContext, useState, useCallback, useEffect } from "react";
// Example Hooks Usage:
// const { setCurrentStep, closeOnborda, startOnborda } = useOnborda();
// // To trigger a specific step
Expand All @@ -16,11 +16,27 @@ const useOnborda = () => {
}
return context;
};
const OnbordaProvider = ({ children, }) => {
const [currentTour, setCurrentTour] = useState(null);
const OnbordaProvider = ({ children, tours = [], activeTour = null, }) => {
const [currentTour, setCurrentTourState] = useState(null);
const [currentStep, setCurrentStepState] = useState(0);
const [isOnbordaVisible, setOnbordaVisible] = useState(false);
const [currentTourSteps, setCurrentTourStepsState] = useState([]);
const [completedSteps, setCompletedSteps] = useState(new Set());
// Start the active tour on mount
useEffect(() => {
if (activeTour) {
startOnborda(activeTour);
}
}, [activeTour]);
const setCurrentStep = useCallback((step, delay) => {
// If step is a string, find the index of the step with that id
if (typeof step === 'string') {
const index = currentTourSteps.findIndex((s) => s?.id === step);
if (index === -1) {
throw new Error(`Step with id ${step} not found`);
}
step = index;
}
if (delay) {
setTimeout(() => {
setCurrentStepState(step);
Expand All @@ -33,21 +49,57 @@ const OnbordaProvider = ({ children, }) => {
}
}, []);
const closeOnborda = useCallback(() => {
// If all steps are completed, call the onComplete function
if (completedSteps.size === currentTourSteps.length) {
tours.find((tour) => (tour.tour) === currentTour)?.onComplete?.();
}
setOnbordaVisible(false);
setCurrentTour(null);
}, []);
setCurrentTourState(null);
setCurrentTourStepsState([]);
setCurrentStepState(0);
setCompletedSteps(new Set());
}, [currentTour, currentTourSteps, completedSteps]);
const initializeCompletedSteps = useCallback(async (tour) => {
// Get the initial state of the completed steps
const completeSteps = tour?.initialCompletedStepsState && await tour.initialCompletedStepsState() || tour.steps.map(() => false);
const firstIncomplete = completeSteps.findIndex((result) => !result);
const completed = completeSteps.reduce((acc, result, index) => {
if (result) {
acc.push(index);
}
return acc;
}, []);
setCompletedSteps(new Set(completed));
// If all steps are completed, return the last step
return firstIncomplete === -1 ? tour.steps.length - 1 : firstIncomplete;
}, [currentTour]);
const setCurrentTour = useCallback((tourName) => {
if (!tourName) {
closeOnborda();
return;
}
setCurrentTourState(tourName);
const tour = tours.find((tour) => tour.tour === tourName);
setCurrentTourStepsState(tour?.steps || []);
tour && initializeCompletedSteps(tour).then(r => {
setCurrentStep(r);
setOnbordaVisible(true);
});
}, [tours]);
const startOnborda = useCallback((tourName) => {
setCurrentTour(tourName);
setCurrentStepState(0);
setOnbordaVisible(true);
}, []);
}, [setCurrentTour]);
return (_jsx(OnbordaContext.Provider, { value: {
tours,
currentTour,
currentStep,
currentTourSteps,
setCurrentStep,
closeOnborda,
startOnborda,
isOnbordaVisible,
completedSteps,
setCompletedSteps
}, children: children }));
};
export { OnbordaProvider, useOnborda };
3 changes: 3 additions & 0 deletions dist/OnbordaStyles.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from "react";
export declare const getCardStyle: (side: string) => React.CSSProperties;
export declare const getArrowStyle: (side: string) => React.CSSProperties;
165 changes: 165 additions & 0 deletions dist/OnbordaStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
export const getCardStyle = (side) => {
switch (side) {
case "top":
return {
transform: `translate(-50%, 0)`,
left: "50%",
bottom: "100%",
marginBottom: "25px",
};
case "bottom":
return {
transform: `translate(-50%, 0)`,
left: "50%",
top: "100%",
marginTop: "25px",
};
case "left":
return {
transform: `translate(0, -50%)`,
right: "100%",
top: "50%",
marginRight: "25px",
};
case "right":
return {
transform: `translate(0, -50%)`,
left: "100%",
top: "50%",
marginLeft: "25px",
};
case "top-left":
return {
bottom: "100%",
marginBottom: "25px",
};
case "top-right":
return {
right: 0,
bottom: "100%",
marginBottom: "25px",
};
case "bottom-left":
return {
top: "100%",
marginTop: "25px",
};
case "bottom-right":
return {
right: 0,
top: "100%",
marginTop: "25px",
};
case "right-bottom":
return {
left: "100%",
bottom: 0,
marginLeft: "25px",
};
case "right-top":
return {
left: "100%",
top: 0,
marginLeft: "25px",
};
case "left-bottom":
return {
right: "100%",
bottom: 0,
marginRight: "25px",
};
case "left-top":
return {
right: "100%",
top: 0,
marginRight: "25px",
};
default:
// Default case if no side is specified. Center the card to the screen
return {
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)', // Center the card
position: 'fixed', // Make sure it's positioned relative to the viewport
margin: '0',
};
}
};
export const getArrowStyle = (side) => {
switch (side) {
case "bottom":
return {
transform: `translate(-50%, 0) rotate(270deg)`,
left: "50%",
top: "-23px",
};
case "top":
return {
transform: `translate(-50%, 0) rotate(90deg)`,
left: "50%",
bottom: "-23px",
};
case "right":
return {
transform: `translate(0, -50%) rotate(180deg)`,
top: "50%",
left: "-23px",
};
case "left":
return {
transform: `translate(0, -50%) rotate(0deg)`,
top: "50%",
right: "-23px",
};
case "top-left":
return {
transform: `rotate(90deg)`,
left: "10px",
bottom: "-23px",
};
case "top-right":
return {
transform: `rotate(90deg)`,
right: "10px",
bottom: "-23px",
};
case "bottom-left":
return {
transform: `rotate(270deg)`,
left: "10px",
top: "-23px",
};
case "bottom-right":
return {
transform: `rotate(270deg)`,
right: "10px",
top: "-23px",
};
case "right-bottom":
return {
transform: `rotate(180deg)`,
left: "-23px",
bottom: "10px",
};
case "right-top":
return {
transform: `rotate(180deg)`,
left: "-23px",
top: "10px",
};
case "left-bottom":
return {
transform: `rotate(0deg)`,
right: "-23px",
bottom: "10px",
};
case "left-top":
return {
transform: `rotate(0deg)`,
right: "-23px",
top: "10px",
};
default:
return {}; // Default case if no side is specified
}
};
Loading