@flemo/core 1.0.0
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/LICENSE +21 -0
- package/dist/core/TaskManger.d.ts +62 -0
- package/dist/core/__tests__/TaskManger.test.d.ts +1 -0
- package/dist/history/__tests__/store.test.d.ts +1 -0
- package/dist/history/store.d.ts +17 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.mjs +965 -0
- package/dist/navigate/__tests__/selfPopGuard.test.d.ts +1 -0
- package/dist/navigate/selfPopGuard.d.ts +12 -0
- package/dist/navigate/store.d.ts +9 -0
- package/dist/transition/__tests__/compileTransitionStyles.test.d.ts +7 -0
- package/dist/transition/compileTransitionStyles.d.ts +13 -0
- package/dist/transition/createRawTransition.d.ts +18 -0
- package/dist/transition/createTransition.d.ts +14 -0
- package/dist/transition/cssTypes.d.ts +22 -0
- package/dist/transition/cupertino.d.ts +2 -0
- package/dist/transition/decorator/createDecorator.d.ts +12 -0
- package/dist/transition/decorator/createRawDecorator.d.ts +19 -0
- package/dist/transition/decorator/decorator.d.ts +2 -0
- package/dist/transition/decorator/overlay.d.ts +2 -0
- package/dist/transition/decorator/typing.d.ts +24 -0
- package/dist/transition/layout.d.ts +2 -0
- package/dist/transition/material.d.ts +2 -0
- package/dist/transition/none.d.ts +2 -0
- package/dist/transition/store.d.ts +7 -0
- package/dist/transition/transition.d.ts +2 -0
- package/dist/transition/typing.d.ts +61 -0
- package/dist/utils/__tests__/findScrollable.test.d.ts +1 -0
- package/dist/utils/__tests__/getMatchedPathPattern.test.d.ts +1 -0
- package/dist/utils/__tests__/getParams.test.d.ts +1 -0
- package/dist/utils/__tests__/isServer.test.d.ts +1 -0
- package/dist/utils/findScrollable.d.ts +21 -0
- package/dist/utils/getMatchedPathPattern.d.ts +2 -0
- package/dist/utils/getParams.d.ts +4 -0
- package/dist/utils/isServer.d.ts +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks that flemo itself is about to call `window.history.back()`. The
|
|
3
|
+
* `popstate` it produces is then consumed by `consumeSelfInducedPop` so the
|
|
4
|
+
* popstate listener doesn't re-process a pop the navigation queue already owns.
|
|
5
|
+
*/
|
|
6
|
+
export declare function markSelfInducedPop(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Returns `true` once for each prior `markSelfInducedPop` call, balancing
|
|
9
|
+
* flemo-initiated `history.back()` calls against incoming `popstate` events.
|
|
10
|
+
* A genuine browser back/forward press is the event that overflows the count.
|
|
11
|
+
*/
|
|
12
|
+
export declare function consumeSelfInducedPop(): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type NavigateStatus = "IDLE" | "PUSHING" | "REPLACING" | "POPPING" | "COMPLETED";
|
|
2
|
+
interface NavigateStore {
|
|
3
|
+
status: NavigateStatus;
|
|
4
|
+
transitionTaskId: string | null;
|
|
5
|
+
setStatus: (status: NavigateStatus) => void;
|
|
6
|
+
setTransitionTaskId: (transitionTaskId: string | null) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const useNavigateStore: import('zustand').UseBoundStore<import('zustand').StoreApi<NavigateStore>>;
|
|
9
|
+
export default useNavigateStore;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AnimationOptions, InitialTarget } from './cssTypes';
|
|
2
|
+
import { Transition, TransitionVariant, TransitionVariantValue } from './typing';
|
|
3
|
+
import { Decorator } from './decorator/typing';
|
|
4
|
+
export type CssDecl = {
|
|
5
|
+
property: string;
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const collectAnimatedProperties: (transition: Transition) => string[];
|
|
9
|
+
export declare const targetToDecls: (target: TransitionVariantValue["value"] | InitialTarget) => CssDecl[];
|
|
10
|
+
export declare const easingToCss: (ease: AnimationOptions["ease"] | undefined) => string;
|
|
11
|
+
export declare const animationName: (scope: "screen" | "decorator", name: string, variant: TransitionVariant) => string;
|
|
12
|
+
export declare const compileTransitionStyles: (transitions: Iterable<Transition>, decorators: Iterable<Decorator>) => string;
|
|
13
|
+
export declare const variantHasAnimation: (transitionLike: Pick<Transition, "initial" | "variants">, variant: TransitionVariant) => boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { InitialTarget } from './cssTypes';
|
|
2
|
+
import { TransitionOptions, Transition, TransitionVariantValue, TransitionName } from './typing';
|
|
3
|
+
interface CreateRawTransitionProps {
|
|
4
|
+
name: TransitionName;
|
|
5
|
+
initial: InitialTarget;
|
|
6
|
+
idle: TransitionVariantValue;
|
|
7
|
+
pushOnEnter: TransitionVariantValue;
|
|
8
|
+
pushOnExit: TransitionVariantValue;
|
|
9
|
+
replaceOnEnter: TransitionVariantValue;
|
|
10
|
+
replaceOnExit: TransitionVariantValue;
|
|
11
|
+
popOnEnter: TransitionVariantValue;
|
|
12
|
+
popOnExit: TransitionVariantValue;
|
|
13
|
+
completedOnEnter: TransitionVariantValue;
|
|
14
|
+
completedOnExit: TransitionVariantValue;
|
|
15
|
+
options?: TransitionOptions;
|
|
16
|
+
}
|
|
17
|
+
export default function createRawTransition({ name, initial, idle, pushOnEnter, pushOnExit, replaceOnEnter, replaceOnExit, popOnEnter, popOnExit, completedOnExit, completedOnEnter, options }: CreateRawTransitionProps): Transition;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { InitialTarget } from './cssTypes';
|
|
2
|
+
import { TransitionOptions, Transition, TransitionVariantValue, TransitionName } from './typing';
|
|
3
|
+
interface CreateTransitionProps {
|
|
4
|
+
name: TransitionName;
|
|
5
|
+
initial: InitialTarget;
|
|
6
|
+
idle: TransitionVariantValue;
|
|
7
|
+
enter: TransitionVariantValue;
|
|
8
|
+
enterBack: TransitionVariantValue;
|
|
9
|
+
exit: TransitionVariantValue;
|
|
10
|
+
exitBack: TransitionVariantValue;
|
|
11
|
+
options?: TransitionOptions;
|
|
12
|
+
}
|
|
13
|
+
export default function createTransition({ name, initial, idle, enter, enterBack, exit, exitBack, options }: CreateTransitionProps): Transition;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type AnimationEasing = string | readonly [number, number, number, number] | [number, number, number, number];
|
|
2
|
+
export interface AnimationOptions {
|
|
3
|
+
duration?: number;
|
|
4
|
+
ease?: AnimationEasing;
|
|
5
|
+
delay?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface TransitionTarget {
|
|
8
|
+
x?: string | number;
|
|
9
|
+
y?: string | number;
|
|
10
|
+
z?: string | number;
|
|
11
|
+
scale?: string | number;
|
|
12
|
+
scaleX?: string | number;
|
|
13
|
+
scaleY?: string | number;
|
|
14
|
+
rotate?: string | number;
|
|
15
|
+
rotateX?: string | number;
|
|
16
|
+
rotateY?: string | number;
|
|
17
|
+
rotateZ?: string | number;
|
|
18
|
+
opacity?: number | string;
|
|
19
|
+
backgroundColor?: string;
|
|
20
|
+
[key: string]: string | number | undefined;
|
|
21
|
+
}
|
|
22
|
+
export type InitialTarget = TransitionTarget;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { InitialTarget } from '../cssTypes';
|
|
2
|
+
import { TransitionVariantValue } from '../typing';
|
|
3
|
+
import { DecoratorName, Decorator, DecoratorOptions } from './typing';
|
|
4
|
+
interface CreateDecoratorProps {
|
|
5
|
+
name: DecoratorName;
|
|
6
|
+
initial: InitialTarget;
|
|
7
|
+
enter: TransitionVariantValue;
|
|
8
|
+
exit: TransitionVariantValue;
|
|
9
|
+
options?: DecoratorOptions;
|
|
10
|
+
}
|
|
11
|
+
export default function createDecorator({ name, initial, enter, exit, options }: CreateDecoratorProps): Decorator;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { InitialTarget } from '../cssTypes';
|
|
2
|
+
import { TransitionVariantValue } from '../typing';
|
|
3
|
+
import { DecoratorName, Decorator, DecoratorOptions } from './typing';
|
|
4
|
+
interface CreateRawDecoratorProps {
|
|
5
|
+
name: DecoratorName;
|
|
6
|
+
initial: InitialTarget;
|
|
7
|
+
idle: TransitionVariantValue;
|
|
8
|
+
pushOnEnter: TransitionVariantValue;
|
|
9
|
+
pushOnExit: TransitionVariantValue;
|
|
10
|
+
replaceOnEnter: TransitionVariantValue;
|
|
11
|
+
replaceOnExit: TransitionVariantValue;
|
|
12
|
+
popOnEnter: TransitionVariantValue;
|
|
13
|
+
popOnExit: TransitionVariantValue;
|
|
14
|
+
completedOnEnter: TransitionVariantValue;
|
|
15
|
+
completedOnExit: TransitionVariantValue;
|
|
16
|
+
options?: DecoratorOptions;
|
|
17
|
+
}
|
|
18
|
+
export default function createRawDecorator({ name, initial, idle, pushOnEnter, pushOnExit, replaceOnEnter, replaceOnExit, popOnEnter, popOnExit, completedOnEnter, completedOnExit, options }: CreateRawDecoratorProps): Decorator;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseTransition, SwipeAnimate } from '../typing';
|
|
2
|
+
export interface RegisterDecorator {
|
|
3
|
+
}
|
|
4
|
+
export type DecoratorName = RegisterDecorator[keyof RegisterDecorator] | "overlay";
|
|
5
|
+
export type DecoratorOptions = {
|
|
6
|
+
onSwipeStart?: (triggered: boolean, options: {
|
|
7
|
+
animate: SwipeAnimate;
|
|
8
|
+
currentDecorator: HTMLDivElement;
|
|
9
|
+
prevDecorator: HTMLDivElement;
|
|
10
|
+
}) => void;
|
|
11
|
+
onSwipe?: (triggered: boolean, progress: number, options: {
|
|
12
|
+
animate: SwipeAnimate;
|
|
13
|
+
currentDecorator: HTMLDivElement;
|
|
14
|
+
prevDecorator: HTMLDivElement;
|
|
15
|
+
}) => void;
|
|
16
|
+
onSwipeEnd?: (triggered: boolean, options: {
|
|
17
|
+
animate: SwipeAnimate;
|
|
18
|
+
currentDecorator: HTMLDivElement;
|
|
19
|
+
prevDecorator: HTMLDivElement;
|
|
20
|
+
}) => void;
|
|
21
|
+
};
|
|
22
|
+
export interface Decorator extends Omit<BaseTransition, "name">, DecoratorOptions {
|
|
23
|
+
name: DecoratorName;
|
|
24
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TransitionName } from './typing';
|
|
2
|
+
interface TransitionStore {
|
|
3
|
+
defaultTransitionName: TransitionName;
|
|
4
|
+
setDefaultTransitionName: (defaultTransitionName: TransitionName) => void;
|
|
5
|
+
}
|
|
6
|
+
declare const useTransitionStore: import('zustand').UseBoundStore<import('zustand').StoreApi<TransitionStore>>;
|
|
7
|
+
export default useTransitionStore;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { NavigateStatus } from '../navigate/store';
|
|
2
|
+
import { AnimationOptions, InitialTarget, TransitionTarget } from './cssTypes';
|
|
3
|
+
import { DecoratorName } from './decorator/typing';
|
|
4
|
+
export interface RegisterTransition {
|
|
5
|
+
}
|
|
6
|
+
export type TransitionName = RegisterTransition[keyof RegisterTransition] | "none" | "cupertino" | "material" | "layout";
|
|
7
|
+
export type TransitionVariant = `${NavigateStatus}-${boolean}`;
|
|
8
|
+
export type TransitionVariantValue = {
|
|
9
|
+
value: TransitionTarget;
|
|
10
|
+
options: AnimationOptions;
|
|
11
|
+
};
|
|
12
|
+
export interface SwipeInfo {
|
|
13
|
+
point: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
offset: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
};
|
|
21
|
+
velocity: {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
};
|
|
25
|
+
delta: {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export type SwipeAnimate = (target: HTMLElement, value: TransitionTarget, options?: AnimationOptions) => Promise<void>;
|
|
31
|
+
export type TransitionOptions = {
|
|
32
|
+
decoratorName?: DecoratorName;
|
|
33
|
+
swipeDirection: "x" | "y";
|
|
34
|
+
onSwipeStart: (event: PointerEvent, info: SwipeInfo, options: {
|
|
35
|
+
animate: SwipeAnimate;
|
|
36
|
+
currentScreen: HTMLDivElement;
|
|
37
|
+
prevScreen: HTMLDivElement;
|
|
38
|
+
onStart?: (triggered: boolean) => void;
|
|
39
|
+
}) => Promise<boolean>;
|
|
40
|
+
onSwipe: (event: PointerEvent, info: SwipeInfo, options: {
|
|
41
|
+
animate: SwipeAnimate;
|
|
42
|
+
currentScreen: HTMLDivElement;
|
|
43
|
+
prevScreen: HTMLDivElement;
|
|
44
|
+
onProgress?: (triggered: boolean, progress: number) => void;
|
|
45
|
+
}) => number;
|
|
46
|
+
onSwipeEnd: (event: PointerEvent, info: SwipeInfo, options: {
|
|
47
|
+
animate: SwipeAnimate;
|
|
48
|
+
currentScreen: HTMLDivElement;
|
|
49
|
+
prevScreen: HTMLDivElement;
|
|
50
|
+
onStart?: (triggered: boolean) => void;
|
|
51
|
+
}) => Promise<boolean>;
|
|
52
|
+
} | {
|
|
53
|
+
decoratorName?: DecoratorName;
|
|
54
|
+
swipeDirection?: never;
|
|
55
|
+
};
|
|
56
|
+
export interface BaseTransition {
|
|
57
|
+
name: TransitionName;
|
|
58
|
+
initial: InitialTarget;
|
|
59
|
+
variants: Record<TransitionVariant, TransitionVariantValue>;
|
|
60
|
+
}
|
|
61
|
+
export type Transition = BaseTransition & TransitionOptions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default function findScrollable(startTarget: EventTarget | null, options?: {
|
|
2
|
+
direction?: "y" | "x";
|
|
3
|
+
markerSelector?: string;
|
|
4
|
+
depthLimit?: number;
|
|
5
|
+
verifyByScroll?: boolean;
|
|
6
|
+
}): {
|
|
7
|
+
element: HTMLElement | null;
|
|
8
|
+
hasMarker: boolean;
|
|
9
|
+
};
|
|
10
|
+
/** Whether the element's content overflows the given axis (sub-pixel safe). */
|
|
11
|
+
export declare function overflowsAxis(element: HTMLElement, direction: "y" | "x"): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the element actually scrolls on the given axis.
|
|
14
|
+
*
|
|
15
|
+
* Reads `overflowX` / `overflowY` from computed style — fast, read-only,
|
|
16
|
+
* and free of side effects. The previous implementation probed by writing
|
|
17
|
+
* to `scrollTop` / `scrollLeft` and reverting, which fired scroll events
|
|
18
|
+
* and interfered with `scroll-snap` / `scroll-behavior: smooth` consumers
|
|
19
|
+
* on every pointerdown that flowed through `findScrollable`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function canProgrammaticallyScroll(element: HTMLElement, direction: "y" | "x"): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function isServer(): boolean;
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flemo/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Framework-agnostic primitives for flemo: history, navigation, transitions, task manager.",
|
|
5
|
+
"main": "./dist/index.mjs",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"keywords": [
|
|
14
|
+
"flemo",
|
|
15
|
+
"router",
|
|
16
|
+
"transition",
|
|
17
|
+
"framework-agnostic"
|
|
18
|
+
],
|
|
19
|
+
"author": {
|
|
20
|
+
"name": "kimjh96",
|
|
21
|
+
"email": "kimjhs@kakao.com"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/kimjh96/flemo.git",
|
|
26
|
+
"directory": "packages/flemo-core"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/kimjh96/flemo/issues",
|
|
30
|
+
"email": "kimjhs@kakao.com"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://flemo-web.vercel.app",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"path-to-regexp": "^8.2.0",
|
|
36
|
+
"zustand": "^5.0.11"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^24.3.0",
|
|
40
|
+
"eslint": "^9.33.0",
|
|
41
|
+
"jsdom": "^25.0.1",
|
|
42
|
+
"typescript": "^5.9.2",
|
|
43
|
+
"vite": "^7.1.5",
|
|
44
|
+
"vite-plugin-dts": "^4.5.4",
|
|
45
|
+
"vitest": "^2.1.8",
|
|
46
|
+
"@flemo/eslint-config": "0.0.0",
|
|
47
|
+
"@flemo/tsconfig": "0.0.0"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "vite build",
|
|
54
|
+
"watch": "vite build --watch",
|
|
55
|
+
"dev": "vite build --watch",
|
|
56
|
+
"lint": "eslint \"**/*.{js,mjs,ts,jsx,tsx,mts}\"",
|
|
57
|
+
"typecheck": "tsc --noEmit",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"test:watch": "vitest",
|
|
60
|
+
"clean": "rm -rf dist .turbo"
|
|
61
|
+
}
|
|
62
|
+
}
|