Skip to content

Commit 90f4fc8

Browse files
authored
Merge pull request #13 from TENQUBE/refactor/12/stactIntergrated closed #12
refactor: stacks, allStacks integrated management (#12)
2 parents 0a20686 + 68785b6 commit 90f4fc8

18 files changed

Lines changed: 211 additions & 284 deletions

File tree

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,19 @@ You can see which stack is active.
139139
import { useStacks } from '@tenqube/react-stack'
140140

141141
const White = () => {
142-
const { stack, totalStack } = useStacks()
142+
const stacks = useStacks()
143143

144144
useEffect(() => {
145-
console.log(stack) // only view component stack
146-
console.log(totalStack) // Includes history stack due to hash
147-
}, [stack, totalStack])
145+
console.log(stacks)
146+
}, [stacks])
148147

149148
...
150149
}
151150
```
152151
```ts
153152
interface IScreen {
154-
readonly route: string
155-
readonly component: ReactNode
156-
readonly animation: AnimationType
153+
readonly route?: string
154+
readonly component?: ReactNode
155+
readonly animation?: AnimationType
157156
}
158157
```

dist/cjs/index.js

Lines changed: 53 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -33572,6 +33572,9 @@ var TransitionGroup$1 = TransitionGroup;
3357233572
const STORAGE_KEY_NAME = 'reactAllPrintedScreenStacks';
3357333573
const ANIMATION_DURATION = 250;
3357433574

33575+
const isHashRoute = (route) => {
33576+
return route[0] === '#';
33577+
};
3357533578
var PathSubDirectoryType;
3357633579
(function (PathSubDirectoryType) {
3357733580
PathSubDirectoryType[PathSubDirectoryType["Static"] = 0] = "Static";
@@ -33641,35 +33644,48 @@ const matchRouteToPathname = (stacks, pathname) => {
3364133644
}
3364233645
}
3364333646
};
33644-
const matchSingleRoute = (stack, pathname) => {
33645-
const matchData = explodeRouteSegments(stack.route);
33647+
const matchLastSingleRoute = (stacks, pathname) => {
33648+
const notHashStacks = stacks.filter(({ route }) => !isHashRoute(route));
33649+
const lastStack = notHashStacks[notHashStacks.length - 1];
33650+
const matchData = explodeRouteSegments(lastStack.route);
3364633651
const segments = pathname.split('#')[0].split('?')[0].split('/');
3364733652
const paths = segments.slice(1, segments.length);
3364833653
const { match } = matchRoute(paths, matchData);
3364933654
return match;
3365033655
};
3365133656

33657+
let Screen$1 = class Screen {
33658+
constructor({ route, component, animation }) {
33659+
this.route = route ? route : '*';
33660+
this.component = component ? component : null;
33661+
this.animation = typeof animation === 'undefined' ? exports.AnimationType.None : animation;
33662+
this.pathVariable = {};
33663+
}
33664+
setPathVariable(pathVariable) {
33665+
this.pathVariable = pathVariable;
33666+
}
33667+
};
33668+
3365233669
const ReactStackContext = React.createContext(null);
3365333670
const StackProvider = ({ children }) => {
3365433671
const screenList = React.useRef([]);
3365533672
const beforeHash = React.useRef('');
3365633673
const beforePathname = React.useRef('');
3365733674
const checkHistoryGo = React.useRef(false);
33658-
const aniDuration = React.useRef(ANIMATION_DURATION);
33659-
const [allStacks, setAllStacks] = React.useState([]);
3366033675
const [stacks, setStacks] = React.useState([]);
3366133676
const [isAddStack, setAddStack] = React.useState(null);
3366233677
const [historyIdx, setHistoryIdx] = React.useState(0);
33678+
const [aniDuration, setAniDuration] = React.useState(ANIMATION_DURATION);
3366333679
const [isMoveActive, setMoveActive] = React.useState(false);
3366433680
const [isMoveAction, setMoveAction] = React.useState(false);
3366533681
const [noDimmed, setNoDimmed] = React.useState(false);
3366633682
const addScreen = React.useCallback((data) => {
3366733683
screenList.current = [...screenList.current, data];
3366833684
}, []);
3366933685
const breakAnimation = React.useCallback(() => {
33670-
aniDuration.current = 0;
33686+
setAniDuration(0);
3367133687
setTimeout(() => {
33672-
aniDuration.current = ANIMATION_DURATION;
33688+
setAniDuration(ANIMATION_DURATION);
3367333689
}, ANIMATION_DURATION);
3367433690
}, []);
3367533691
const updateStacks = React.useCallback((to, isClear = false) => {
@@ -33679,7 +33695,6 @@ const StackProvider = ({ children }) => {
3367933695
setTimeout(() => {
3368033696
const stackData = matchRouteToPathname(screenList.current, to);
3368133697
setStacks([stackData]);
33682-
setAllStacks([stackData]);
3368333698
}, 20);
3368433699
return;
3368533700
}
@@ -33690,23 +33705,18 @@ const StackProvider = ({ children }) => {
3369033705
checkHistoryGo.current = true;
3369133706
breakAnimation();
3369233707
setTimeout(() => {
33693-
const removedTotalStack = allStacks.slice(allStacks.length + to, allStacks.length);
33694-
const removedHashSize = removedTotalStack.filter((stack) => typeof stack === 'string').length;
33695-
setStacks(stacks.slice(0, stacks.length + to + removedHashSize));
33696-
setAllStacks(allStacks.slice(0, allStacks.length + to));
33708+
setStacks(stacks.slice(0, stacks.length + to));
3369733709
}, 20);
3369833710
}
3369933711
else {
3370033712
setStacks(stacks.slice(0, stacks.length - 1));
33701-
setAllStacks(allStacks.slice(0, allStacks.length - 1));
3370233713
}
3370333714
}
3370433715
else {
3370533716
const stackData = matchRouteToPathname(screenList.current, to);
3370633717
setStacks([...stacks, stackData]);
33707-
setAllStacks([...allStacks, stackData]);
3370833718
}
33709-
}, [stacks, allStacks]);
33719+
}, [stacks]);
3371033720
const checkIsForward = React.useCallback(() => {
3371133721
const { state } = window.history;
3371233722
if (!state)
@@ -33728,61 +33738,41 @@ const StackProvider = ({ children }) => {
3372833738
beforePathname.current = pathname;
3372933739
if (pathname === bPath) {
3373033740
if (hash && !bHash) {
33731-
setAllStacks([...allStacks, hash]);
33732-
return;
33741+
setStacks([...stacks, new Screen$1({ route: hash })]);
3373333742
}
3373433743
if (hash && bHash) {
33735-
if (allStacks[allStacks.length - 2] === hash) {
33736-
setAllStacks(allStacks.slice(0, allStacks.length - 1));
33744+
if (stacks[stacks.length - 2].route === hash) {
33745+
setStacks(stacks.slice(0, stacks.length - 1));
3373733746
}
3373833747
else {
33739-
setAllStacks([...allStacks, hash]);
33748+
setStacks([...stacks, new Screen$1({ route: hash })]);
3374033749
}
33741-
return;
3374233750
}
3374333751
if (bHash && !hash) {
33744-
setAllStacks(allStacks.slice(0, allStacks.length - 1));
33745-
return;
33752+
setStacks(stacks.slice(0, stacks.length - 1));
3374633753
}
33754+
return;
3374733755
}
3374833756
updateStacks(checkIsForward() ? pathname : -1);
33749-
}, [allStacks, historyIdx]);
33757+
}, [stacks, historyIdx]);
3375033758
const initStorageStackData = React.useCallback(() => {
3375133759
const { pathname, hash } = window.location;
3375233760
const storageData = JSON.parse(window.sessionStorage.getItem(STORAGE_KEY_NAME));
3375333761
if (!storageData || storageData.length === 0)
3375433762
return;
33755-
const cacheRouteStack = storageData.filter((d) => typeof d !== 'string');
33756-
const cacheStack = cacheRouteStack.map(({ route }) => {
33757-
return matchRouteToPathname(screenList.current, route);
33763+
const storageStacks = storageData.map((route) => {
33764+
return isHashRoute(route)
33765+
? new Screen$1({ route })
33766+
: matchRouteToPathname(screenList.current, route);
3375833767
});
33759-
const cacheTotalStack = storageData.map((d) => {
33760-
return typeof d === 'string'
33761-
? d
33762-
: matchRouteToPathname(screenList.current, d.route);
33763-
});
33764-
const allStack = storageData.filter((d) => typeof d === 'string');
33765-
const isMatchStack = (() => {
33766-
if (!cacheStack[cacheStack.length - 1])
33767-
return true;
33768-
if (matchSingleRoute(cacheStack[cacheStack.length - 1], pathname))
33769-
return true;
33770-
return false;
33771-
})();
33772-
const isMatchallStack = (() => {
33773-
if (!allStack[allStack.length - 1])
33774-
return true;
33775-
if (allStack[allStack.length - 1] === hash)
33776-
return true;
33777-
return false;
33778-
})();
33779-
if (!isMatchStack || !isMatchallStack)
33768+
if (!matchLastSingleRoute(storageStacks, pathname)
33769+
|| (hash && storageStacks[storageStacks.length - 1].route !== hash)) {
3378033770
return false;
33771+
}
3378133772
breakAnimation();
33782-
setAllStacks(cacheTotalStack);
33783-
setStacks(cacheStack);
33773+
setStacks(storageStacks);
3378433774
return true;
33785-
}, [allStacks, historyIdx]);
33775+
}, [stacks, historyIdx]);
3378633776
React.useEffect(() => {
3378733777
if (isAddStack === null)
3378833778
return;
@@ -33792,20 +33782,20 @@ const StackProvider = ({ children }) => {
3379233782
setTimeout(() => {
3379333783
setMoveActive(false);
3379433784
setMoveAction(false);
33795-
}, aniDuration.current);
33785+
}, aniDuration);
3379633786
}, 20);
33797-
}, [stacks]);
33787+
}, [stacks, aniDuration]);
3379833788
React.useEffect(() => {
33799-
const storageData = allStacks.map((d) => typeof d === 'string' ? d : { route: d.route });
33789+
const storageData = stacks.map((d) => d.route);
3380033790
window.sessionStorage.setItem(STORAGE_KEY_NAME, JSON.stringify(storageData));
33801-
}, [allStacks]);
33791+
}, [stacks]);
3380233792
React.useEffect(() => {
3380333793
beforePathname.current = window.location.pathname;
3380433794
window.addEventListener('popstate', historyChangeStack);
3380533795
return () => {
3380633796
window.removeEventListener('popstate', historyChangeStack);
3380733797
};
33808-
}, [allStacks, historyIdx]);
33798+
}, [stacks, historyIdx]);
3380933799
React.useEffect(() => {
3381033800
var _a, _b;
3381133801
const index = (_b = (_a = window.history) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.index;
@@ -33836,32 +33826,20 @@ const StackProvider = ({ children }) => {
3383633826
setNoDimmed(false);
3383733827
}, ANIMATION_DURATION);
3383833828
}, []);
33839-
return (jsxRuntime.jsx("div", { className: "react-stack-area", children: jsxRuntime.jsxs(ReactStackContext.Provider, { value: { addScreen, stacks, allStacks, updateStacks, historyIdx, setHistoryIdx }, children: [children, jsxRuntime.jsx(TransitionGroup$1, { children: stacks.map(({ route, component, animation, pathVariable }, i, arr) => {
33840-
if (route === '#')
33829+
return (jsxRuntime.jsx("div", { className: "react-stack-area", children: jsxRuntime.jsxs(ReactStackContext.Provider, { value: { addScreen, stacks, updateStacks, historyIdx, setHistoryIdx }, children: [children, jsxRuntime.jsx(TransitionGroup$1, { children: stacks.map(({ route, component, animation, pathVariable }, i, arr) => {
33830+
if (isHashRoute(route))
3384133831
return null;
3384233832
const activePage = arr.length - 2;
3384333833
const activeIdx = arr.length - 1;
3384433834
const nextAnimation = (i < activeIdx && arr[i + 1]) ? arr[i + 1].animation : false;
33845-
return (jsxRuntime.jsx(CSSTransition$1, { timeout: aniDuration.current, classNames: `react-stack-box react-stack-${AnimationClassName[animation]}`, onExit: () => checkDimmed(animation), style: {
33846-
'transition': `all ${aniDuration.current / 1000}s`
33847-
}, children: jsxRuntime.jsxs("div", { "data-before-ani": nextAnimation !== false ? AnimationClassName[nextAnimation] : false, children: [React.cloneElement(component, Object.assign({ params: pathVariable })), arr[activeIdx].route !== null && !noDimmed && (isAddStack ? activePage === i : activePage + 1 === i) && isMoveActive && (jsxRuntime.jsx("div", { className: dimmedClassName(), style: {
33848-
'transition': `all ${aniDuration.current / 1000}s`
33835+
return (jsxRuntime.jsx(CSSTransition$1, { timeout: aniDuration, classNames: `react-stack-box react-stack-${AnimationClassName[animation]}`, onExit: () => checkDimmed(animation), style: {
33836+
'transition': `all ${aniDuration / 1000}s`
33837+
}, children: jsxRuntime.jsxs("div", { "data-before-ani": nextAnimation !== false ? AnimationClassName[nextAnimation] : false, children: [React.cloneElement(component, Object.assign({ params: pathVariable })), !isHashRoute(arr[activeIdx].route) && !noDimmed && (isAddStack ? activePage === i : activePage + 1 === i) && isMoveActive && (jsxRuntime.jsx("div", { className: dimmedClassName(), style: {
33838+
'transition': `all ${aniDuration / 1000}s`
3384933839
} }))] }) }, i));
3385033840
}) })] }) }));
3385133841
};
3385233842

33853-
let Screen$1 = class Screen {
33854-
constructor({ route, component, animation }) {
33855-
this.route = route;
33856-
this.component = component;
33857-
this.animation = typeof animation === 'undefined' ? exports.AnimationType.None : animation;
33858-
this.pathVariable = {};
33859-
}
33860-
setPathVariable(pathVariable) {
33861-
this.pathVariable = pathVariable;
33862-
}
33863-
};
33864-
3386533843
const Screen = ({ route, component, animation }) => {
3386633844
const { addScreen } = React.useContext(ReactStackContext);
3386733845
React.useLayoutEffect(() => {
@@ -33915,8 +33893,8 @@ const useNavigaiton = () => {
3391533893
};
3391633894

3391733895
const useStacks = () => {
33918-
const { stacks, allStacks } = React.useContext(ReactStackContext);
33919-
return { stacks, allStacks };
33896+
const { stacks } = React.useContext(ReactStackContext);
33897+
return stacks;
3392033898
};
3392133899

3392233900
function styleInject(css, ref) {

dist/cjs/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/cjs/types/data/screen.d.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
import { ReactElement } from 'react';
22
import { AnimationType } from '../interfaces';
33
export interface IScreen {
4-
readonly route: string | null;
5-
readonly component: ReactElement;
6-
readonly animation: AnimationType;
4+
readonly route?: string;
5+
readonly component?: ReactElement | null;
6+
readonly animation?: AnimationType;
77
pathVariable: unknown;
88
setPathVariable(pathVariable: unknown): void;
99
}
10+
interface IScreenParams {
11+
readonly route?: string | null;
12+
readonly component?: ReactElement | null;
13+
readonly animation?: AnimationType;
14+
}
1015
declare class Screen implements IScreen {
11-
readonly route: string | null;
12-
readonly component: ReactElement;
13-
readonly animation: AnimationType;
16+
readonly route: string;
17+
readonly component?: ReactElement | null;
18+
readonly animation?: AnimationType;
1419
pathVariable: unknown;
15-
constructor({ route, component, animation }: {
16-
route: any;
17-
component: any;
18-
animation: any;
19-
});
20+
constructor({ route, component, animation }: IScreenParams);
2021
setPathVariable(pathVariable: unknown): void;
2122
}
2223
export default Screen;
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
import { IScreen } from '../data/screen';
2-
declare const useStacks: () => {
3-
stacks: IScreen[];
4-
allStacks: Array<IScreen | string>;
5-
};
2+
declare const useStacks: () => IScreen[];
63
export default useStacks;

dist/cjs/types/utils/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { IScreen } from '../data/screen';
2-
export declare const parseToRoute: (route: string) => string;
2+
export declare const isHashRoute: (route: string) => boolean;
33
export declare const matchRouteToPathname: (stacks: IScreen[], pathname: string) => IScreen;
4-
export declare const matchSingleRoute: (stack: IScreen, pathname: string) => boolean;
4+
export declare const matchLastSingleRoute: (stacks: IScreen[], pathname: string) => boolean;

0 commit comments

Comments
 (0)