@seed-design/lynx-react-scale-feedback 1.0.0 → 1.1.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/lib/PreferredMotionContext.d.ts +9 -0
- package/lib/PreferredMotionContext.d.ts.map +1 -0
- package/lib/PreferredMotionContext.js +6 -0
- package/lib/deprecated-global-props.d.ts +4 -0
- package/lib/deprecated-global-props.d.ts.map +1 -0
- package/lib/deprecated-global-props.js +12 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/use-host-global-props.d.ts +12 -0
- package/lib/use-host-global-props.d.ts.map +1 -0
- package/lib/use-host-global-props.js +13 -0
- package/lib/useScaleFeedback.d.ts +4 -3
- package/lib/useScaleFeedback.d.ts.map +1 -1
- package/lib/useScaleFeedback.js +18 -6
- package/package.json +5 -5
- package/src/PreferredMotionContext.ts +12 -0
- package/src/deprecated-global-props.ts +16 -0
- package/src/index.ts +1 -0
- package/src/use-host-global-props.ts +18 -0
- package/src/useScaleFeedback.test.ts +56 -2
- package/src/useScaleFeedback.ts +19 -6
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Context } from "@lynx-js/react";
|
|
2
|
+
/** 호스트가 선호하는 모션 강도. `"reduced"`이면 Scale Feedback을 끈다. */
|
|
3
|
+
export type PreferredMotion = "default" | "reduced";
|
|
4
|
+
/**
|
|
5
|
+
* @internal `@seed-design/lynx-react`의 `SeedProvider`가 `preferredMotion`을 넣는 context다.
|
|
6
|
+
* 앱은 `SeedProvider`로 값을 넘긴다.
|
|
7
|
+
*/
|
|
8
|
+
export declare const PreferredMotionContext: Context<PreferredMotion | undefined>;
|
|
9
|
+
//# sourceMappingURL=PreferredMotionContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreferredMotionContext.d.ts","sourceRoot":"","sources":["../src/PreferredMotionContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE7D,yDAAyD;AACzD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,OAAO,CAAC,eAAe,GAAG,SAAS,CAE5D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecated-global-props.d.ts","sourceRoot":"","sources":["../src/deprecated-global-props.ts"],"names":[],"mappings":"AAGA,wBAAgB,8BAA8B,IAAI,IAAI,CAOrD;AAED,sBAAsB;AACtB,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
let warned = false;
|
|
2
|
+
// TODO(next major): `motion` global prop 읽기를 제거한다. 앱은 `SeedProvider`에 `preferredMotion`을 넘긴다.
|
|
3
|
+
export function warnDeprecatedMotionGlobalProp() {
|
|
4
|
+
if (process.env.NODE_ENV === "production" || warned)
|
|
5
|
+
return;
|
|
6
|
+
warned = true;
|
|
7
|
+
console.warn("[@seed-design/lynx-react-scale-feedback] Reading `lynx.__globalProps.motion` is deprecated and will be removed in the next major version. Pass `preferredMotion` to `SeedProvider` instead.");
|
|
8
|
+
}
|
|
9
|
+
/** @internal 테스트용. */
|
|
10
|
+
export function resetDeprecatedMotionWarning() {
|
|
11
|
+
warned = false;
|
|
12
|
+
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GlobalProps } from "@lynx-js/types";
|
|
2
|
+
/**
|
|
3
|
+
* Reads global props according to `globalPropsMode`.
|
|
4
|
+
*
|
|
5
|
+
* `__GLOBAL_PROPS_MODE__` is a constant replaced at app build time, so the chosen function never
|
|
6
|
+
* changes within a bundle. In `"event"` mode, `useGlobalProps()` subscribes to changes. In
|
|
7
|
+
* `"reactive"` mode, the whole page re-renders when the host changes a value, so this reads
|
|
8
|
+
* `lynx.__globalProps` directly: `useGlobalProps()` returns the same value there but warns on every
|
|
9
|
+
* call in development builds.
|
|
10
|
+
*/
|
|
11
|
+
export declare const useHostGlobalProps: () => GlobalProps | undefined;
|
|
12
|
+
//# sourceMappingURL=use-host-global-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-host-global-props.d.ts","sourceRoot":"","sources":["../src/use-host-global-props.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,WAAW,GAAG,SAGvB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useGlobalProps } from "@lynx-js/react";
|
|
2
|
+
/**
|
|
3
|
+
* Reads global props according to `globalPropsMode`.
|
|
4
|
+
*
|
|
5
|
+
* `__GLOBAL_PROPS_MODE__` is a constant replaced at app build time, so the chosen function never
|
|
6
|
+
* changes within a bundle. In `"event"` mode, `useGlobalProps()` subscribes to changes. In
|
|
7
|
+
* `"reactive"` mode, the whole page re-renders when the host changes a value, so this reads
|
|
8
|
+
* `lynx.__globalProps` directly: `useGlobalProps()` returns the same value there but warns on every
|
|
9
|
+
* call in development builds.
|
|
10
|
+
*/
|
|
11
|
+
export const useHostGlobalProps = typeof __GLOBAL_PROPS_MODE__ !== "undefined" && __GLOBAL_PROPS_MODE__ === "event"
|
|
12
|
+
? useGlobalProps
|
|
13
|
+
: () => lynx.__globalProps;
|
|
@@ -40,9 +40,10 @@ export interface UseScaleFeedbackReturn {
|
|
|
40
40
|
* The target's transform is owned by this hook. Use a separate content layer
|
|
41
41
|
* when the element already uses translate, rotate, or another transform.
|
|
42
42
|
*
|
|
43
|
-
* Supported on Lynx Engine 3.6 and later.
|
|
44
|
-
* `
|
|
45
|
-
* `"reduced"` value
|
|
43
|
+
* Supported on Lynx Engine 3.6 and later. `preferredMotion: "reduced"` on
|
|
44
|
+
* `SeedProvider` disables scaling. Without it, the deprecated
|
|
45
|
+
* `GlobalProps.motion` fallback is used; only the exact `"reduced"` value
|
|
46
|
+
* disables scaling.
|
|
46
47
|
*/
|
|
47
48
|
export declare function useScaleFeedback(options?: UseScaleFeedbackOptions): UseScaleFeedbackReturn;
|
|
48
49
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScaleFeedback.d.ts","sourceRoot":"","sources":["../src/useScaleFeedback.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAc,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"useScaleFeedback.d.ts","sourceRoot":"","sources":["../src/useScaleFeedback.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAc,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAW/E,KAAK,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;AAE3D,KAAK,6BAA6B,GAAG,WAAW,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,CAAC;AAChG,KAAK,sBAAsB,GAAG,WAAW,CAAC,aAAa,CAAC,4BAA4B,CAAC,CAAC,CAAC;AAUvF,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC,4BAA4B,EAAE,sBAAsB,CAAC;IACrD,0BAA0B,EAAE,sBAAsB,CAAC;IACnD,6BAA6B,EAAE,sBAAsB,CAAC;CACvD;AAED,oGAAoG;AACpG,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,KAAK,CAAC;IACf,iBAAiB,EAAE,WAAW,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACjE,8BAA8B,EAAE,6BAA6B,CAAC;CAC/D;AAED,MAAM,WAAW,sBAAsB;IACrC,0DAA0D;IAC1D,yBAAyB,EAAE,yBAAyB,CAAC;IACrD,2DAA2D;IAC3D,wBAAwB,EAAE,wBAAwB,CAAC;CACpD;AAyDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,sBAAsB,CA6E9F"}
|
package/lib/useScaleFeedback.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { runOnMainThread, runOnBackground,
|
|
1
|
+
import { runOnMainThread, runOnBackground, useContext, useEffect, useMainThreadRef, useRef, } from "@lynx-js/react";
|
|
2
2
|
import { feedbackScaleDuration, feedbackScaleTimingFunction, } from "@seed-design/lynx-css/scale-feedback";
|
|
3
3
|
import { calculateScaleFeedback, isReducedMotion } from "./calculate-scale-feedback.js";
|
|
4
|
+
import { warnDeprecatedMotionGlobalProp } from "./deprecated-global-props.js";
|
|
5
|
+
import { PreferredMotionContext } from "./PreferredMotionContext.js";
|
|
6
|
+
import { useHostGlobalProps } from "./use-host-global-props.js";
|
|
4
7
|
function runScaleFeedback(targetRef, animationRef, scale, duration) {
|
|
5
8
|
"main thread";
|
|
6
9
|
const target = targetRef.current;
|
|
@@ -39,6 +42,11 @@ function readScaleFeedbackScale(target) {
|
|
|
39
42
|
return null;
|
|
40
43
|
return calculateScaleFeedback(width, height);
|
|
41
44
|
}
|
|
45
|
+
function readDeprecatedReducedMotion(motion) {
|
|
46
|
+
if (motion !== undefined)
|
|
47
|
+
warnDeprecatedMotionGlobalProp();
|
|
48
|
+
return isReducedMotion(motion);
|
|
49
|
+
}
|
|
42
50
|
/**
|
|
43
51
|
* Applies SEED Scale Feedback on the Lynx Main Thread.
|
|
44
52
|
*
|
|
@@ -50,14 +58,18 @@ function readScaleFeedbackScale(target) {
|
|
|
50
58
|
* The target's transform is owned by this hook. Use a separate content layer
|
|
51
59
|
* when the element already uses translate, rotate, or another transform.
|
|
52
60
|
*
|
|
53
|
-
* Supported on Lynx Engine 3.6 and later.
|
|
54
|
-
* `
|
|
55
|
-
* `"reduced"` value
|
|
61
|
+
* Supported on Lynx Engine 3.6 and later. `preferredMotion: "reduced"` on
|
|
62
|
+
* `SeedProvider` disables scaling. Without it, the deprecated
|
|
63
|
+
* `GlobalProps.motion` fallback is used; only the exact `"reduced"` value
|
|
64
|
+
* disables scaling.
|
|
56
65
|
*/
|
|
57
66
|
export function useScaleFeedback(options = {}) {
|
|
58
67
|
const { disabled = false, onTouchStart, onTouchEnd, onTouchCancel } = options;
|
|
59
|
-
const
|
|
60
|
-
const
|
|
68
|
+
const preferredMotion = useContext(PreferredMotionContext);
|
|
69
|
+
const globalProps = useHostGlobalProps();
|
|
70
|
+
const reducedMotion = preferredMotion !== undefined
|
|
71
|
+
? preferredMotion === "reduced"
|
|
72
|
+
: readDeprecatedReducedMotion(globalProps?.motion);
|
|
61
73
|
const targetRef = useMainThreadRef(null);
|
|
62
74
|
const animationRef = useMainThreadRef(null);
|
|
63
75
|
const scaleRef = useMainThreadRef(null);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-design/lynx-react-scale-feedback",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/daangn/seed-design.git",
|
|
@@ -31,16 +31,16 @@
|
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@lynx-js/react": ">=0.117.0",
|
|
33
33
|
"@lynx-js/types": ">=3.9.0",
|
|
34
|
-
"@seed-design/lynx-css": "^1.
|
|
34
|
+
"@seed-design/lynx-css": "^1.3.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@lynx-js/react": "^0.
|
|
37
|
+
"@lynx-js/react": "^0.129.0",
|
|
38
38
|
"@lynx-js/types": "^3.9.0",
|
|
39
|
-
"@seed-design/lynx-css": "1.
|
|
39
|
+
"@seed-design/lynx-css": "1.3.0",
|
|
40
40
|
"@seed-design/lynx-vitest-config": "0.0.0",
|
|
41
41
|
"@testing-library/jest-dom": "^6.9.1",
|
|
42
42
|
"jsdom": "^29.0.2",
|
|
43
|
-
"vitest": "^
|
|
43
|
+
"vitest": "^5.0.0"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createContext, type Context } from "@lynx-js/react";
|
|
2
|
+
|
|
3
|
+
/** 호스트가 선호하는 모션 강도. `"reduced"`이면 Scale Feedback을 끈다. */
|
|
4
|
+
export type PreferredMotion = "default" | "reduced";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @internal `@seed-design/lynx-react`의 `SeedProvider`가 `preferredMotion`을 넣는 context다.
|
|
8
|
+
* 앱은 `SeedProvider`로 값을 넘긴다.
|
|
9
|
+
*/
|
|
10
|
+
export const PreferredMotionContext: Context<PreferredMotion | undefined> = createContext<
|
|
11
|
+
PreferredMotion | undefined
|
|
12
|
+
>(undefined);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
let warned = false;
|
|
2
|
+
|
|
3
|
+
// TODO(next major): `motion` global prop 읽기를 제거한다. 앱은 `SeedProvider`에 `preferredMotion`을 넘긴다.
|
|
4
|
+
export function warnDeprecatedMotionGlobalProp(): void {
|
|
5
|
+
if (process.env.NODE_ENV === "production" || warned) return;
|
|
6
|
+
|
|
7
|
+
warned = true;
|
|
8
|
+
console.warn(
|
|
9
|
+
"[@seed-design/lynx-react-scale-feedback] Reading `lynx.__globalProps.motion` is deprecated and will be removed in the next major version. Pass `preferredMotion` to `SeedProvider` instead.",
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** @internal 테스트용. */
|
|
14
|
+
export function resetDeprecatedMotionWarning(): void {
|
|
15
|
+
warned = false;
|
|
16
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useGlobalProps } from "@lynx-js/react";
|
|
2
|
+
import type { GlobalProps } from "@lynx-js/types";
|
|
3
|
+
|
|
4
|
+
declare const __GLOBAL_PROPS_MODE__: "reactive" | "event" | undefined;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reads global props according to `globalPropsMode`.
|
|
8
|
+
*
|
|
9
|
+
* `__GLOBAL_PROPS_MODE__` is a constant replaced at app build time, so the chosen function never
|
|
10
|
+
* changes within a bundle. In `"event"` mode, `useGlobalProps()` subscribes to changes. In
|
|
11
|
+
* `"reactive"` mode, the whole page re-renders when the host changes a value, so this reads
|
|
12
|
+
* `lynx.__globalProps` directly: `useGlobalProps()` returns the same value there but warns on every
|
|
13
|
+
* call in development builds.
|
|
14
|
+
*/
|
|
15
|
+
export const useHostGlobalProps: () => GlobalProps | undefined =
|
|
16
|
+
typeof __GLOBAL_PROPS_MODE__ !== "undefined" && __GLOBAL_PROPS_MODE__ === "event"
|
|
17
|
+
? useGlobalProps
|
|
18
|
+
: () => lynx.__globalProps;
|
|
@@ -1,10 +1,33 @@
|
|
|
1
|
-
import { runOnMainThread } from "@lynx-js/react";
|
|
1
|
+
import { createElement, runOnMainThread, type ReactNode } from "@lynx-js/react";
|
|
2
2
|
import { renderHook, waitSchedule } from "@lynx-js/react/testing-library";
|
|
3
|
-
import { describe, expect, expectTypeOf, it } from "vitest";
|
|
3
|
+
import { afterEach, describe, expect, expectTypeOf, it, vi } from "vitest";
|
|
4
4
|
|
|
5
5
|
import { calculateScaleFeedback, isReducedMotion } from "./calculate-scale-feedback";
|
|
6
|
+
import { resetDeprecatedMotionWarning } from "./deprecated-global-props";
|
|
7
|
+
import { PreferredMotionContext } from "./PreferredMotionContext";
|
|
6
8
|
import { useScaleFeedback, type UseScaleFeedbackOptions } from "./useScaleFeedback";
|
|
7
9
|
|
|
10
|
+
interface TestLynxGlobal {
|
|
11
|
+
lynx?: { __globalProps?: Record<string, unknown> };
|
|
12
|
+
lynxTestingEnv?: {
|
|
13
|
+
backgroundThread: { globalThis: TestLynxGlobal };
|
|
14
|
+
mainThread: { globalThis: TestLynxGlobal };
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function setGlobalProps(globalProps: Record<string, unknown>) {
|
|
19
|
+
const env = (globalThis as unknown as TestLynxGlobal).lynxTestingEnv;
|
|
20
|
+
const globals = [
|
|
21
|
+
globalThis as unknown as TestLynxGlobal,
|
|
22
|
+
env?.backgroundThread.globalThis,
|
|
23
|
+
env?.mainThread.globalThis,
|
|
24
|
+
].filter((global): global is TestLynxGlobal => Boolean(global));
|
|
25
|
+
|
|
26
|
+
for (const global of globals) {
|
|
27
|
+
global.lynx = { ...global.lynx, __globalProps: globalProps };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
8
31
|
describe("useScaleFeedback", () => {
|
|
9
32
|
it("keeps the animation target from being flattened", () => {
|
|
10
33
|
const { result } = renderHook(() => useScaleFeedback());
|
|
@@ -24,6 +47,37 @@ describe("useScaleFeedback", () => {
|
|
|
24
47
|
});
|
|
25
48
|
});
|
|
26
49
|
|
|
50
|
+
describe("useScaleFeedback deprecated motion global prop", () => {
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
setGlobalProps({});
|
|
53
|
+
resetDeprecatedMotionWarning();
|
|
54
|
+
vi.restoreAllMocks();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("warns once when it falls back to GlobalProps.motion", () => {
|
|
58
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
59
|
+
setGlobalProps({ motion: "reduced" });
|
|
60
|
+
|
|
61
|
+
renderHook(() => useScaleFeedback());
|
|
62
|
+
renderHook(() => useScaleFeedback());
|
|
63
|
+
|
|
64
|
+
expect(warn).toHaveBeenCalledTimes(1);
|
|
65
|
+
expect(warn.mock.calls[0]?.[0]).toContain("lynx.__globalProps.motion");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("uses the provider value without reading GlobalProps.motion", () => {
|
|
69
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
70
|
+
setGlobalProps({ motion: "reduced" });
|
|
71
|
+
|
|
72
|
+
renderHook(() => useScaleFeedback(), {
|
|
73
|
+
wrapper: ({ children }: { children: ReactNode }) =>
|
|
74
|
+
createElement(PreferredMotionContext.Provider, { value: "default" }, children),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
expect(warn).not.toHaveBeenCalled();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
27
81
|
describe("calculateScaleFeedback", () => {
|
|
28
82
|
it.each([
|
|
29
83
|
{ width: 32, height: 32, expected: 30 / 32 },
|
package/src/useScaleFeedback.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runOnMainThread,
|
|
3
3
|
runOnBackground,
|
|
4
|
+
useContext,
|
|
4
5
|
useEffect,
|
|
5
|
-
useGlobalProps,
|
|
6
6
|
useMainThreadRef,
|
|
7
7
|
useRef,
|
|
8
8
|
} from "@lynx-js/react";
|
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
} from "@seed-design/lynx-css/scale-feedback";
|
|
15
15
|
|
|
16
16
|
import { calculateScaleFeedback, isReducedMotion } from "./calculate-scale-feedback.js";
|
|
17
|
+
import { warnDeprecatedMotionGlobalProp } from "./deprecated-global-props.js";
|
|
18
|
+
import { PreferredMotionContext } from "./PreferredMotionContext.js";
|
|
19
|
+
import { useHostGlobalProps } from "./use-host-global-props.js";
|
|
17
20
|
|
|
18
21
|
type LynxViewProps = IntrinsicElements["view"] & ViewProps;
|
|
19
22
|
|
|
@@ -109,6 +112,11 @@ function readScaleFeedbackScale(target: ScaleFeedbackElement | null): number | n
|
|
|
109
112
|
return calculateScaleFeedback(width, height);
|
|
110
113
|
}
|
|
111
114
|
|
|
115
|
+
function readDeprecatedReducedMotion(motion: unknown): boolean {
|
|
116
|
+
if (motion !== undefined) warnDeprecatedMotionGlobalProp();
|
|
117
|
+
return isReducedMotion(motion);
|
|
118
|
+
}
|
|
119
|
+
|
|
112
120
|
/**
|
|
113
121
|
* Applies SEED Scale Feedback on the Lynx Main Thread.
|
|
114
122
|
*
|
|
@@ -120,14 +128,19 @@ function readScaleFeedbackScale(target: ScaleFeedbackElement | null): number | n
|
|
|
120
128
|
* The target's transform is owned by this hook. Use a separate content layer
|
|
121
129
|
* when the element already uses translate, rotate, or another transform.
|
|
122
130
|
*
|
|
123
|
-
* Supported on Lynx Engine 3.6 and later.
|
|
124
|
-
* `
|
|
125
|
-
* `"reduced"` value
|
|
131
|
+
* Supported on Lynx Engine 3.6 and later. `preferredMotion: "reduced"` on
|
|
132
|
+
* `SeedProvider` disables scaling. Without it, the deprecated
|
|
133
|
+
* `GlobalProps.motion` fallback is used; only the exact `"reduced"` value
|
|
134
|
+
* disables scaling.
|
|
126
135
|
*/
|
|
127
136
|
export function useScaleFeedback(options: UseScaleFeedbackOptions = {}): UseScaleFeedbackReturn {
|
|
128
137
|
const { disabled = false, onTouchStart, onTouchEnd, onTouchCancel } = options;
|
|
129
|
-
const
|
|
130
|
-
const
|
|
138
|
+
const preferredMotion = useContext(PreferredMotionContext);
|
|
139
|
+
const globalProps = useHostGlobalProps() as SeedMotionGlobalProps | undefined;
|
|
140
|
+
const reducedMotion =
|
|
141
|
+
preferredMotion !== undefined
|
|
142
|
+
? preferredMotion === "reduced"
|
|
143
|
+
: readDeprecatedReducedMotion(globalProps?.motion);
|
|
131
144
|
const targetRef = useMainThreadRef<ScaleFeedbackElement | null>(null);
|
|
132
145
|
const animationRef = useMainThreadRef<MainThread.Animation>(null);
|
|
133
146
|
const scaleRef = useMainThreadRef<number | null>(null);
|