@dloizides/ui-motion 1.0.2 → 1.2.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/CHANGELOG.md +20 -0
- package/README.md +20 -0
- package/dist/constants-BrJ7VJYu.d.mts +54 -0
- package/dist/constants-BrJ7VJYu.d.ts +54 -0
- package/dist/hairline/native.d.mts +9 -0
- package/dist/hairline/native.d.ts +9 -0
- package/dist/hairline/native.js +114 -0
- package/dist/hairline/native.js.map +1 -0
- package/dist/hairline/native.mjs +107 -0
- package/dist/hairline/native.mjs.map +1 -0
- package/dist/hairline/web.d.mts +9 -0
- package/dist/hairline/web.d.ts +9 -0
- package/dist/hairline/web.js +131 -0
- package/dist/hairline/web.js.map +1 -0
- package/dist/hairline/web.mjs +124 -0
- package/dist/hairline/web.mjs.map +1 -0
- package/dist/index.d.mts +90 -2
- package/dist/index.d.ts +90 -2
- package/dist/index.js +177 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +171 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +37 -6
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var reactNative = require('react-native');
|
|
5
|
+
var hairline = require('@lucasmarkes/hairline');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
|
|
8
|
+
// src/hairline/components/HairlineFigure.web.tsx
|
|
9
|
+
|
|
10
|
+
// src/hairline/constants.ts
|
|
11
|
+
var HAIRLINE_TEST_ID = "motion-hairline-figure";
|
|
12
|
+
var HAIRLINE_ASPECT_RATIO = 5 / 4;
|
|
13
|
+
var DEFAULT_HAIRLINE_INTENSITY = 0.5;
|
|
14
|
+
|
|
15
|
+
// src/hairline/HairlineFigureName.ts
|
|
16
|
+
var HairlineFigureName = /* @__PURE__ */ ((HairlineFigureName2) => {
|
|
17
|
+
HairlineFigureName2["Basket"] = "basket";
|
|
18
|
+
HairlineFigureName2["Branches"] = "branches";
|
|
19
|
+
HairlineFigureName2["Cabinet"] = "cabinet";
|
|
20
|
+
HairlineFigureName2["Dish"] = "dish";
|
|
21
|
+
HairlineFigureName2["Drawer"] = "drawer";
|
|
22
|
+
HairlineFigureName2["Elevator"] = "elevator";
|
|
23
|
+
HairlineFigureName2["Exploded"] = "exploded";
|
|
24
|
+
HairlineFigureName2["Keyboard"] = "keyboard";
|
|
25
|
+
HairlineFigureName2["Laptop"] = "laptop";
|
|
26
|
+
HairlineFigureName2["Lockers"] = "lockers";
|
|
27
|
+
HairlineFigureName2["Loupe"] = "loupe";
|
|
28
|
+
HairlineFigureName2["Padlock"] = "padlock";
|
|
29
|
+
HairlineFigureName2["Patch"] = "patch";
|
|
30
|
+
HairlineFigureName2["Phone"] = "phone";
|
|
31
|
+
HairlineFigureName2["Phosphor"] = "phosphor";
|
|
32
|
+
HairlineFigureName2["Plot"] = "plot";
|
|
33
|
+
HairlineFigureName2["Plug"] = "plug";
|
|
34
|
+
HairlineFigureName2["Query"] = "query";
|
|
35
|
+
HairlineFigureName2["Rail"] = "rail";
|
|
36
|
+
HairlineFigureName2["Riffle"] = "riffle";
|
|
37
|
+
HairlineFigureName2["Router"] = "router";
|
|
38
|
+
HairlineFigureName2["Sieve"] = "sieve";
|
|
39
|
+
HairlineFigureName2["Slow"] = "slow";
|
|
40
|
+
HairlineFigureName2["Terminal"] = "terminal";
|
|
41
|
+
HairlineFigureName2["Terrain"] = "terrain";
|
|
42
|
+
HairlineFigureName2["Turntable"] = "turntable";
|
|
43
|
+
HairlineFigureName2["Vault"] = "vault";
|
|
44
|
+
return HairlineFigureName2;
|
|
45
|
+
})(HairlineFigureName || {});
|
|
46
|
+
|
|
47
|
+
// src/hairline/data/figureRegistry.ts
|
|
48
|
+
var FIGURE_REGISTRY = {
|
|
49
|
+
["basket" /* Basket */]: hairline.basket,
|
|
50
|
+
["branches" /* Branches */]: hairline.branches,
|
|
51
|
+
["cabinet" /* Cabinet */]: hairline.cabinet,
|
|
52
|
+
["dish" /* Dish */]: hairline.dish,
|
|
53
|
+
["drawer" /* Drawer */]: hairline.drawer,
|
|
54
|
+
["elevator" /* Elevator */]: hairline.elevator,
|
|
55
|
+
["exploded" /* Exploded */]: hairline.exploded,
|
|
56
|
+
["keyboard" /* Keyboard */]: hairline.keyboard,
|
|
57
|
+
["laptop" /* Laptop */]: hairline.laptop,
|
|
58
|
+
["lockers" /* Lockers */]: hairline.lockers,
|
|
59
|
+
["loupe" /* Loupe */]: hairline.loupe,
|
|
60
|
+
["padlock" /* Padlock */]: hairline.padlock,
|
|
61
|
+
["patch" /* Patch */]: hairline.patch,
|
|
62
|
+
["phone" /* Phone */]: hairline.phone,
|
|
63
|
+
["phosphor" /* Phosphor */]: hairline.phosphor,
|
|
64
|
+
["plot" /* Plot */]: hairline.plot,
|
|
65
|
+
["plug" /* Plug */]: hairline.plug,
|
|
66
|
+
["query" /* Query */]: hairline.query,
|
|
67
|
+
["rail" /* Rail */]: hairline.rail,
|
|
68
|
+
["riffle" /* Riffle */]: hairline.riffle,
|
|
69
|
+
["router" /* Router */]: hairline.router,
|
|
70
|
+
["sieve" /* Sieve */]: hairline.sieve,
|
|
71
|
+
["slow" /* Slow */]: hairline.slow,
|
|
72
|
+
["terminal" /* Terminal */]: hairline.terminal,
|
|
73
|
+
["terrain" /* Terrain */]: hairline.terrain,
|
|
74
|
+
["turntable" /* Turntable */]: hairline.turntable,
|
|
75
|
+
["vault" /* Vault */]: hairline.vault
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/hairline/utils/hairlineVars.ts
|
|
79
|
+
var hairlineVars = (colors) => ({
|
|
80
|
+
"--hairline-plate": colors.background,
|
|
81
|
+
"--hairline-hi": colors.text,
|
|
82
|
+
"--hairline-edge": colors.textSecondary,
|
|
83
|
+
"--hairline-mid": colors.textTertiary !== void 0 ? colors.textTertiary : colors.border,
|
|
84
|
+
"--hairline-lo": colors.divider
|
|
85
|
+
});
|
|
86
|
+
var styles = reactNative.StyleSheet.create({
|
|
87
|
+
host: { width: "100%", aspectRatio: HAIRLINE_ASPECT_RATIO }
|
|
88
|
+
});
|
|
89
|
+
var toElement = (view) => view;
|
|
90
|
+
var HairlineFigure = ({
|
|
91
|
+
figure,
|
|
92
|
+
colors,
|
|
93
|
+
intensity = DEFAULT_HAIRLINE_INTENSITY,
|
|
94
|
+
label,
|
|
95
|
+
testID = HAIRLINE_TEST_ID
|
|
96
|
+
}) => {
|
|
97
|
+
const hostRef = react.useRef(null);
|
|
98
|
+
const figureRef = react.useRef(null);
|
|
99
|
+
const optionsRef = react.useRef({ intensity, label });
|
|
100
|
+
optionsRef.current = { intensity, label };
|
|
101
|
+
react.useEffect(() => {
|
|
102
|
+
const el = toElement(hostRef.current);
|
|
103
|
+
if (el === null) return void 0;
|
|
104
|
+
const vars = Object.entries(hairlineVars(colors));
|
|
105
|
+
vars.forEach(([name, value]) => el.style.setProperty(name, value));
|
|
106
|
+
return () => vars.forEach(([name]) => el.style.removeProperty(name));
|
|
107
|
+
}, [colors]);
|
|
108
|
+
react.useEffect(() => {
|
|
109
|
+
const el = toElement(hostRef.current);
|
|
110
|
+
if (el === null) return void 0;
|
|
111
|
+
const mounted = FIGURE_REGISTRY[figure](el, optionsRef.current);
|
|
112
|
+
figureRef.current = mounted;
|
|
113
|
+
return () => {
|
|
114
|
+
mounted.destroy();
|
|
115
|
+
figureRef.current = null;
|
|
116
|
+
};
|
|
117
|
+
}, [figure]);
|
|
118
|
+
react.useEffect(() => {
|
|
119
|
+
figureRef.current?.update({ intensity, label });
|
|
120
|
+
}, [intensity, label]);
|
|
121
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ref: hostRef, style: styles.host, testID });
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
exports.DEFAULT_HAIRLINE_INTENSITY = DEFAULT_HAIRLINE_INTENSITY;
|
|
125
|
+
exports.HAIRLINE_ASPECT_RATIO = HAIRLINE_ASPECT_RATIO;
|
|
126
|
+
exports.HAIRLINE_TEST_ID = HAIRLINE_TEST_ID;
|
|
127
|
+
exports.HairlineFigure = HairlineFigure;
|
|
128
|
+
exports.HairlineFigureName = HairlineFigureName;
|
|
129
|
+
exports.hairlineVars = hairlineVars;
|
|
130
|
+
//# sourceMappingURL=web.js.map
|
|
131
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hairline/constants.ts","../../src/hairline/HairlineFigureName.ts","../../src/hairline/data/figureRegistry.ts","../../src/hairline/utils/hairlineVars.ts","../../src/hairline/components/HairlineFigure.web.tsx"],"names":["HairlineFigureName","basket","branches","cabinet","dish","drawer","elevator","exploded","keyboard","laptop","lockers","loupe","padlock","patch","phone","phosphor","plot","plug","query","rail","riffle","router","sieve","slow","terminal","terrain","turntable","vault","StyleSheet","useRef","useEffect","View"],"mappings":"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","file":"web.js","sourcesContent":["export const HAIRLINE_TEST_ID = 'motion-hairline-figure';\nexport const HAIRLINE_ASPECT_RATIO = 5 / 4;\nexport const DEFAULT_HAIRLINE_INTENSITY = 0.5;\n","export const enum HairlineFigureName {\n Basket = 'basket',\n Branches = 'branches',\n Cabinet = 'cabinet',\n Dish = 'dish',\n Drawer = 'drawer',\n Elevator = 'elevator',\n Exploded = 'exploded',\n Keyboard = 'keyboard',\n Laptop = 'laptop',\n Lockers = 'lockers',\n Loupe = 'loupe',\n Padlock = 'padlock',\n Patch = 'patch',\n Phone = 'phone',\n Phosphor = 'phosphor',\n Plot = 'plot',\n Plug = 'plug',\n Query = 'query',\n Rail = 'rail',\n Riffle = 'riffle',\n Router = 'router',\n Sieve = 'sieve',\n Slow = 'slow',\n Terminal = 'terminal',\n Terrain = 'terrain',\n Turntable = 'turntable',\n Vault = 'vault',\n}\n","import {\n basket, branches, cabinet, dish, drawer, elevator, exploded, keyboard, laptop,\n lockers, loupe, padlock, patch, phone, phosphor, plot, plug, query, rail,\n riffle, router, sieve, slow, terminal, terrain, turntable, vault,\n type Figure, type HairlineOptions,\n} from '@lucasmarkes/hairline';\n\nimport { HairlineFigureName } from '../HairlineFigureName';\n\nexport type MountFigure = (el: HTMLElement, options?: HairlineOptions) => Figure;\n\nexport const FIGURE_REGISTRY: Record<HairlineFigureName, MountFigure> = {\n [HairlineFigureName.Basket]: basket,\n [HairlineFigureName.Branches]: branches,\n [HairlineFigureName.Cabinet]: cabinet,\n [HairlineFigureName.Dish]: dish,\n [HairlineFigureName.Drawer]: drawer,\n [HairlineFigureName.Elevator]: elevator,\n [HairlineFigureName.Exploded]: exploded,\n [HairlineFigureName.Keyboard]: keyboard,\n [HairlineFigureName.Laptop]: laptop,\n [HairlineFigureName.Lockers]: lockers,\n [HairlineFigureName.Loupe]: loupe,\n [HairlineFigureName.Padlock]: padlock,\n [HairlineFigureName.Patch]: patch,\n [HairlineFigureName.Phone]: phone,\n [HairlineFigureName.Phosphor]: phosphor,\n [HairlineFigureName.Plot]: plot,\n [HairlineFigureName.Plug]: plug,\n [HairlineFigureName.Query]: query,\n [HairlineFigureName.Rail]: rail,\n [HairlineFigureName.Riffle]: riffle,\n [HairlineFigureName.Router]: router,\n [HairlineFigureName.Sieve]: sieve,\n [HairlineFigureName.Slow]: slow,\n [HairlineFigureName.Terminal]: terminal,\n [HairlineFigureName.Terrain]: terrain,\n [HairlineFigureName.Turntable]: turntable,\n [HairlineFigureName.Vault]: vault,\n};\n","import type { ModeColors } from '@dloizides/design-tokens';\n\nimport type { HairlineVars } from '../types';\n\n/** Maps one theme mode's colour tokens onto the hairline palette vars (stroke width stays upstream). */\nexport const hairlineVars = (colors: ModeColors): HairlineVars => ({\n '--hairline-plate': colors.background,\n '--hairline-hi': colors.text,\n '--hairline-edge': colors.textSecondary,\n '--hairline-mid': colors.textTertiary !== undefined ? colors.textTertiary : colors.border,\n '--hairline-lo': colors.divider,\n});\n","import React, { useEffect, useRef } from 'react';\n\nimport { StyleSheet, View } from 'react-native';\n\nimport type { Figure } from '@lucasmarkes/hairline';\n\nimport { DEFAULT_HAIRLINE_INTENSITY, HAIRLINE_ASPECT_RATIO, HAIRLINE_TEST_ID } from '../constants';\nimport { FIGURE_REGISTRY } from '../data/figureRegistry';\nimport type { HairlineFigureProps } from '../types';\nimport { hairlineVars } from '../utils/hairlineVars';\n\nconst styles = StyleSheet.create({\n host: { width: '100%', aspectRatio: HAIRLINE_ASPECT_RATIO },\n});\n\nconst toElement = (view: View | null): HTMLElement | null => view as unknown as HTMLElement | null;\n\n/** Mounts a hairline figure on the host View's DOM node (RN-web); destroyed on unmount. */\nexport const HairlineFigure = ({\n figure,\n colors,\n intensity = DEFAULT_HAIRLINE_INTENSITY,\n label,\n testID = HAIRLINE_TEST_ID,\n}: HairlineFigureProps): React.ReactElement => {\n const hostRef = useRef<View>(null);\n const figureRef = useRef<Figure | null>(null);\n const optionsRef = useRef({ intensity, label });\n optionsRef.current = { intensity, label };\n\n useEffect(() => {\n const el = toElement(hostRef.current);\n if (el === null) return undefined;\n const vars = Object.entries(hairlineVars(colors));\n vars.forEach(([name, value]) => el.style.setProperty(name, value));\n return () => vars.forEach(([name]) => el.style.removeProperty(name));\n }, [colors]);\n\n useEffect(() => {\n const el = toElement(hostRef.current);\n if (el === null) return undefined;\n const mounted = FIGURE_REGISTRY[figure](el, optionsRef.current);\n figureRef.current = mounted;\n return () => {\n mounted.destroy();\n figureRef.current = null;\n };\n }, [figure]);\n\n useEffect(() => {\n figureRef.current?.update({ intensity, label });\n }, [intensity, label]);\n\n return <View ref={hostRef} style={styles.host} testID={testID} />;\n};\n"]}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
import { vault, turntable, terrain, terminal, slow, sieve, router, riffle, rail, query, plug, plot, phosphor, phone, patch, padlock, loupe, lockers, laptop, keyboard, exploded, elevator, drawer, dish, cabinet, branches, basket } from '@lucasmarkes/hairline';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/hairline/components/HairlineFigure.web.tsx
|
|
7
|
+
|
|
8
|
+
// src/hairline/constants.ts
|
|
9
|
+
var HAIRLINE_TEST_ID = "motion-hairline-figure";
|
|
10
|
+
var HAIRLINE_ASPECT_RATIO = 5 / 4;
|
|
11
|
+
var DEFAULT_HAIRLINE_INTENSITY = 0.5;
|
|
12
|
+
|
|
13
|
+
// src/hairline/HairlineFigureName.ts
|
|
14
|
+
var HairlineFigureName = /* @__PURE__ */ ((HairlineFigureName2) => {
|
|
15
|
+
HairlineFigureName2["Basket"] = "basket";
|
|
16
|
+
HairlineFigureName2["Branches"] = "branches";
|
|
17
|
+
HairlineFigureName2["Cabinet"] = "cabinet";
|
|
18
|
+
HairlineFigureName2["Dish"] = "dish";
|
|
19
|
+
HairlineFigureName2["Drawer"] = "drawer";
|
|
20
|
+
HairlineFigureName2["Elevator"] = "elevator";
|
|
21
|
+
HairlineFigureName2["Exploded"] = "exploded";
|
|
22
|
+
HairlineFigureName2["Keyboard"] = "keyboard";
|
|
23
|
+
HairlineFigureName2["Laptop"] = "laptop";
|
|
24
|
+
HairlineFigureName2["Lockers"] = "lockers";
|
|
25
|
+
HairlineFigureName2["Loupe"] = "loupe";
|
|
26
|
+
HairlineFigureName2["Padlock"] = "padlock";
|
|
27
|
+
HairlineFigureName2["Patch"] = "patch";
|
|
28
|
+
HairlineFigureName2["Phone"] = "phone";
|
|
29
|
+
HairlineFigureName2["Phosphor"] = "phosphor";
|
|
30
|
+
HairlineFigureName2["Plot"] = "plot";
|
|
31
|
+
HairlineFigureName2["Plug"] = "plug";
|
|
32
|
+
HairlineFigureName2["Query"] = "query";
|
|
33
|
+
HairlineFigureName2["Rail"] = "rail";
|
|
34
|
+
HairlineFigureName2["Riffle"] = "riffle";
|
|
35
|
+
HairlineFigureName2["Router"] = "router";
|
|
36
|
+
HairlineFigureName2["Sieve"] = "sieve";
|
|
37
|
+
HairlineFigureName2["Slow"] = "slow";
|
|
38
|
+
HairlineFigureName2["Terminal"] = "terminal";
|
|
39
|
+
HairlineFigureName2["Terrain"] = "terrain";
|
|
40
|
+
HairlineFigureName2["Turntable"] = "turntable";
|
|
41
|
+
HairlineFigureName2["Vault"] = "vault";
|
|
42
|
+
return HairlineFigureName2;
|
|
43
|
+
})(HairlineFigureName || {});
|
|
44
|
+
|
|
45
|
+
// src/hairline/data/figureRegistry.ts
|
|
46
|
+
var FIGURE_REGISTRY = {
|
|
47
|
+
["basket" /* Basket */]: basket,
|
|
48
|
+
["branches" /* Branches */]: branches,
|
|
49
|
+
["cabinet" /* Cabinet */]: cabinet,
|
|
50
|
+
["dish" /* Dish */]: dish,
|
|
51
|
+
["drawer" /* Drawer */]: drawer,
|
|
52
|
+
["elevator" /* Elevator */]: elevator,
|
|
53
|
+
["exploded" /* Exploded */]: exploded,
|
|
54
|
+
["keyboard" /* Keyboard */]: keyboard,
|
|
55
|
+
["laptop" /* Laptop */]: laptop,
|
|
56
|
+
["lockers" /* Lockers */]: lockers,
|
|
57
|
+
["loupe" /* Loupe */]: loupe,
|
|
58
|
+
["padlock" /* Padlock */]: padlock,
|
|
59
|
+
["patch" /* Patch */]: patch,
|
|
60
|
+
["phone" /* Phone */]: phone,
|
|
61
|
+
["phosphor" /* Phosphor */]: phosphor,
|
|
62
|
+
["plot" /* Plot */]: plot,
|
|
63
|
+
["plug" /* Plug */]: plug,
|
|
64
|
+
["query" /* Query */]: query,
|
|
65
|
+
["rail" /* Rail */]: rail,
|
|
66
|
+
["riffle" /* Riffle */]: riffle,
|
|
67
|
+
["router" /* Router */]: router,
|
|
68
|
+
["sieve" /* Sieve */]: sieve,
|
|
69
|
+
["slow" /* Slow */]: slow,
|
|
70
|
+
["terminal" /* Terminal */]: terminal,
|
|
71
|
+
["terrain" /* Terrain */]: terrain,
|
|
72
|
+
["turntable" /* Turntable */]: turntable,
|
|
73
|
+
["vault" /* Vault */]: vault
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/hairline/utils/hairlineVars.ts
|
|
77
|
+
var hairlineVars = (colors) => ({
|
|
78
|
+
"--hairline-plate": colors.background,
|
|
79
|
+
"--hairline-hi": colors.text,
|
|
80
|
+
"--hairline-edge": colors.textSecondary,
|
|
81
|
+
"--hairline-mid": colors.textTertiary !== void 0 ? colors.textTertiary : colors.border,
|
|
82
|
+
"--hairline-lo": colors.divider
|
|
83
|
+
});
|
|
84
|
+
var styles = StyleSheet.create({
|
|
85
|
+
host: { width: "100%", aspectRatio: HAIRLINE_ASPECT_RATIO }
|
|
86
|
+
});
|
|
87
|
+
var toElement = (view) => view;
|
|
88
|
+
var HairlineFigure = ({
|
|
89
|
+
figure,
|
|
90
|
+
colors,
|
|
91
|
+
intensity = DEFAULT_HAIRLINE_INTENSITY,
|
|
92
|
+
label,
|
|
93
|
+
testID = HAIRLINE_TEST_ID
|
|
94
|
+
}) => {
|
|
95
|
+
const hostRef = useRef(null);
|
|
96
|
+
const figureRef = useRef(null);
|
|
97
|
+
const optionsRef = useRef({ intensity, label });
|
|
98
|
+
optionsRef.current = { intensity, label };
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
const el = toElement(hostRef.current);
|
|
101
|
+
if (el === null) return void 0;
|
|
102
|
+
const vars = Object.entries(hairlineVars(colors));
|
|
103
|
+
vars.forEach(([name, value]) => el.style.setProperty(name, value));
|
|
104
|
+
return () => vars.forEach(([name]) => el.style.removeProperty(name));
|
|
105
|
+
}, [colors]);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
const el = toElement(hostRef.current);
|
|
108
|
+
if (el === null) return void 0;
|
|
109
|
+
const mounted = FIGURE_REGISTRY[figure](el, optionsRef.current);
|
|
110
|
+
figureRef.current = mounted;
|
|
111
|
+
return () => {
|
|
112
|
+
mounted.destroy();
|
|
113
|
+
figureRef.current = null;
|
|
114
|
+
};
|
|
115
|
+
}, [figure]);
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
figureRef.current?.update({ intensity, label });
|
|
118
|
+
}, [intensity, label]);
|
|
119
|
+
return /* @__PURE__ */ jsx(View, { ref: hostRef, style: styles.host, testID });
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export { DEFAULT_HAIRLINE_INTENSITY, HAIRLINE_ASPECT_RATIO, HAIRLINE_TEST_ID, HairlineFigure, HairlineFigureName, hairlineVars };
|
|
123
|
+
//# sourceMappingURL=web.mjs.map
|
|
124
|
+
//# sourceMappingURL=web.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hairline/constants.ts","../../src/hairline/HairlineFigureName.ts","../../src/hairline/data/figureRegistry.ts","../../src/hairline/utils/hairlineVars.ts","../../src/hairline/components/HairlineFigure.web.tsx"],"names":["HairlineFigureName"],"mappings":";;;;;;;;AAAO,IAAM,gBAAA,GAAmB;AACzB,IAAM,wBAAwB,CAAA,GAAI;AAClC,IAAM,0BAAA,GAA6B;;;ACFnC,IAAW,kBAAA,qBAAAA,mBAAAA,KAAX;AACL,EAAAA,oBAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,oBAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,oBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,oBAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,oBAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,oBAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,oBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,oBAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,oBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,oBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,oBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,oBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,oBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,oBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,oBAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,oBAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,oBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,oBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,oBAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,oBAAA,WAAA,CAAA,GAAY,WAAA;AACZ,EAAAA,oBAAA,OAAA,CAAA,GAAQ,OAAA;AA3BQ,EAAA,OAAAA,mBAAAA;AAAA,CAAA,EAAA,kBAAA,IAAA,EAAA;;;ACWX,IAAM,eAAA,GAA2D;AAAA,EACtE,yBAA6B,MAAA;AAAA,EAC7B,6BAA+B,QAAA;AAAA,EAC/B,2BAA8B,OAAA;AAAA,EAC9B,qBAA2B,IAAA;AAAA,EAC3B,yBAA6B,MAAA;AAAA,EAC7B,6BAA+B,QAAA;AAAA,EAC/B,6BAA+B,QAAA;AAAA,EAC/B,6BAA+B,QAAA;AAAA,EAC/B,yBAA6B,MAAA;AAAA,EAC7B,2BAA8B,OAAA;AAAA,EAC9B,uBAA4B,KAAA;AAAA,EAC5B,2BAA8B,OAAA;AAAA,EAC9B,uBAA4B,KAAA;AAAA,EAC5B,uBAA4B,KAAA;AAAA,EAC5B,6BAA+B,QAAA;AAAA,EAC/B,qBAA2B,IAAA;AAAA,EAC3B,qBAA2B,IAAA;AAAA,EAC3B,uBAA4B,KAAA;AAAA,EAC5B,qBAA2B,IAAA;AAAA,EAC3B,yBAA6B,MAAA;AAAA,EAC7B,yBAA6B,MAAA;AAAA,EAC7B,uBAA4B,KAAA;AAAA,EAC5B,qBAA2B,IAAA;AAAA,EAC3B,6BAA+B,QAAA;AAAA,EAC/B,2BAA8B,OAAA;AAAA,EAC9B,+BAAgC,SAAA;AAAA,EAChC,uBAA4B;AAC9B,CAAA;;;AClCO,IAAM,YAAA,GAAe,CAAC,MAAA,MAAsC;AAAA,EACjE,oBAAoB,MAAA,CAAO,UAAA;AAAA,EAC3B,iBAAiB,MAAA,CAAO,IAAA;AAAA,EACxB,mBAAmB,MAAA,CAAO,aAAA;AAAA,EAC1B,kBAAkB,MAAA,CAAO,YAAA,KAAiB,MAAA,GAAY,MAAA,CAAO,eAAe,MAAA,CAAO,MAAA;AAAA,EACnF,iBAAiB,MAAA,CAAO;AAC1B,CAAA;ACAA,IAAM,MAAA,GAAS,WAAW,MAAA,CAAO;AAAA,EAC/B,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,aAAa,qBAAA;AACtC,CAAC,CAAA;AAED,IAAM,SAAA,GAAY,CAAC,IAAA,KAA0C,IAAA;AAGtD,IAAM,iBAAiB,CAAC;AAAA,EAC7B,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA,GAAY,0BAAA;AAAA,EACZ,KAAA;AAAA,EACA,MAAA,GAAS;AACX,CAAA,KAA+C;AAC7C,EAAA,MAAM,OAAA,GAAU,OAAa,IAAI,CAAA;AACjC,EAAA,MAAM,SAAA,GAAY,OAAsB,IAAI,CAAA;AAC5C,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,EAAE,SAAA,EAAW,OAAO,CAAA;AAC9C,EAAA,UAAA,CAAW,OAAA,GAAU,EAAE,SAAA,EAAW,KAAA,EAAM;AAExC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,SAAA,CAAU,OAAA,CAAQ,OAAO,CAAA;AACpC,IAAA,IAAI,EAAA,KAAO,MAAM,OAAO,MAAA;AACxB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,YAAA,CAAa,MAAM,CAAC,CAAA;AAChD,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,IAAA,EAAM,KAAK,CAAA,KAAM,EAAA,CAAG,KAAA,CAAM,WAAA,CAAY,IAAA,EAAM,KAAK,CAAC,CAAA;AACjE,IAAA,OAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,IAAI,CAAA,KAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,EACrE,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,SAAA,CAAU,OAAA,CAAQ,OAAO,CAAA;AACpC,IAAA,IAAI,EAAA,KAAO,MAAM,OAAO,MAAA;AACxB,IAAA,MAAM,UAAU,eAAA,CAAgB,MAAM,CAAA,CAAE,EAAA,EAAI,WAAW,OAAO,CAAA;AAC9D,IAAA,SAAA,CAAU,OAAA,GAAU,OAAA;AACpB,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,CAAQ,OAAA,EAAQ;AAChB,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAA,CAAU,OAAA,EAAS,MAAA,CAAO,EAAE,SAAA,EAAW,OAAO,CAAA;AAAA,EAChD,CAAA,EAAG,CAAC,SAAA,EAAW,KAAK,CAAC,CAAA;AAErB,EAAA,2BAAQ,IAAA,EAAA,EAAK,GAAA,EAAK,SAAS,KAAA,EAAO,MAAA,CAAO,MAAM,MAAA,EAAgB,CAAA;AACjE","file":"web.mjs","sourcesContent":["export const HAIRLINE_TEST_ID = 'motion-hairline-figure';\nexport const HAIRLINE_ASPECT_RATIO = 5 / 4;\nexport const DEFAULT_HAIRLINE_INTENSITY = 0.5;\n","export const enum HairlineFigureName {\n Basket = 'basket',\n Branches = 'branches',\n Cabinet = 'cabinet',\n Dish = 'dish',\n Drawer = 'drawer',\n Elevator = 'elevator',\n Exploded = 'exploded',\n Keyboard = 'keyboard',\n Laptop = 'laptop',\n Lockers = 'lockers',\n Loupe = 'loupe',\n Padlock = 'padlock',\n Patch = 'patch',\n Phone = 'phone',\n Phosphor = 'phosphor',\n Plot = 'plot',\n Plug = 'plug',\n Query = 'query',\n Rail = 'rail',\n Riffle = 'riffle',\n Router = 'router',\n Sieve = 'sieve',\n Slow = 'slow',\n Terminal = 'terminal',\n Terrain = 'terrain',\n Turntable = 'turntable',\n Vault = 'vault',\n}\n","import {\n basket, branches, cabinet, dish, drawer, elevator, exploded, keyboard, laptop,\n lockers, loupe, padlock, patch, phone, phosphor, plot, plug, query, rail,\n riffle, router, sieve, slow, terminal, terrain, turntable, vault,\n type Figure, type HairlineOptions,\n} from '@lucasmarkes/hairline';\n\nimport { HairlineFigureName } from '../HairlineFigureName';\n\nexport type MountFigure = (el: HTMLElement, options?: HairlineOptions) => Figure;\n\nexport const FIGURE_REGISTRY: Record<HairlineFigureName, MountFigure> = {\n [HairlineFigureName.Basket]: basket,\n [HairlineFigureName.Branches]: branches,\n [HairlineFigureName.Cabinet]: cabinet,\n [HairlineFigureName.Dish]: dish,\n [HairlineFigureName.Drawer]: drawer,\n [HairlineFigureName.Elevator]: elevator,\n [HairlineFigureName.Exploded]: exploded,\n [HairlineFigureName.Keyboard]: keyboard,\n [HairlineFigureName.Laptop]: laptop,\n [HairlineFigureName.Lockers]: lockers,\n [HairlineFigureName.Loupe]: loupe,\n [HairlineFigureName.Padlock]: padlock,\n [HairlineFigureName.Patch]: patch,\n [HairlineFigureName.Phone]: phone,\n [HairlineFigureName.Phosphor]: phosphor,\n [HairlineFigureName.Plot]: plot,\n [HairlineFigureName.Plug]: plug,\n [HairlineFigureName.Query]: query,\n [HairlineFigureName.Rail]: rail,\n [HairlineFigureName.Riffle]: riffle,\n [HairlineFigureName.Router]: router,\n [HairlineFigureName.Sieve]: sieve,\n [HairlineFigureName.Slow]: slow,\n [HairlineFigureName.Terminal]: terminal,\n [HairlineFigureName.Terrain]: terrain,\n [HairlineFigureName.Turntable]: turntable,\n [HairlineFigureName.Vault]: vault,\n};\n","import type { ModeColors } from '@dloizides/design-tokens';\n\nimport type { HairlineVars } from '../types';\n\n/** Maps one theme mode's colour tokens onto the hairline palette vars (stroke width stays upstream). */\nexport const hairlineVars = (colors: ModeColors): HairlineVars => ({\n '--hairline-plate': colors.background,\n '--hairline-hi': colors.text,\n '--hairline-edge': colors.textSecondary,\n '--hairline-mid': colors.textTertiary !== undefined ? colors.textTertiary : colors.border,\n '--hairline-lo': colors.divider,\n});\n","import React, { useEffect, useRef } from 'react';\n\nimport { StyleSheet, View } from 'react-native';\n\nimport type { Figure } from '@lucasmarkes/hairline';\n\nimport { DEFAULT_HAIRLINE_INTENSITY, HAIRLINE_ASPECT_RATIO, HAIRLINE_TEST_ID } from '../constants';\nimport { FIGURE_REGISTRY } from '../data/figureRegistry';\nimport type { HairlineFigureProps } from '../types';\nimport { hairlineVars } from '../utils/hairlineVars';\n\nconst styles = StyleSheet.create({\n host: { width: '100%', aspectRatio: HAIRLINE_ASPECT_RATIO },\n});\n\nconst toElement = (view: View | null): HTMLElement | null => view as unknown as HTMLElement | null;\n\n/** Mounts a hairline figure on the host View's DOM node (RN-web); destroyed on unmount. */\nexport const HairlineFigure = ({\n figure,\n colors,\n intensity = DEFAULT_HAIRLINE_INTENSITY,\n label,\n testID = HAIRLINE_TEST_ID,\n}: HairlineFigureProps): React.ReactElement => {\n const hostRef = useRef<View>(null);\n const figureRef = useRef<Figure | null>(null);\n const optionsRef = useRef({ intensity, label });\n optionsRef.current = { intensity, label };\n\n useEffect(() => {\n const el = toElement(hostRef.current);\n if (el === null) return undefined;\n const vars = Object.entries(hairlineVars(colors));\n vars.forEach(([name, value]) => el.style.setProperty(name, value));\n return () => vars.forEach(([name]) => el.style.removeProperty(name));\n }, [colors]);\n\n useEffect(() => {\n const el = toElement(hostRef.current);\n if (el === null) return undefined;\n const mounted = FIGURE_REGISTRY[figure](el, optionsRef.current);\n figureRef.current = mounted;\n return () => {\n mounted.destroy();\n figureRef.current = null;\n };\n }, [figure]);\n\n useEffect(() => {\n figureRef.current?.update({ intensity, label });\n }, [intensity, label]);\n\n return <View ref={hostRef} style={styles.host} testID={testID} />;\n};\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { prefersReducedMotion, useReducedMotion } from '@dloizides/rn-web-hooks';
|
|
2
|
-
import { EasingFunction, Animated,
|
|
2
|
+
import { EasingFunction, Animated, ViewStyle, StyleProp, PressableProps } from 'react-native';
|
|
3
3
|
import { MotionEasings, MotionDurations } from '@dloizides/design-tokens';
|
|
4
4
|
export { DEFAULT_MOTION, Motion, MotionDurations, MotionEasings } from '@dloizides/design-tokens';
|
|
5
5
|
import React from 'react';
|
|
@@ -69,6 +69,7 @@ declare const MOTION_TEST_IDS: {
|
|
|
69
69
|
readonly collapse: "collapse";
|
|
70
70
|
readonly pressableScale: "pressable-scale";
|
|
71
71
|
readonly skeleton: "skeleton";
|
|
72
|
+
readonly reorder: "reorder";
|
|
72
73
|
};
|
|
73
74
|
/** Default press-in scale for {@link PressableScale}. */
|
|
74
75
|
declare const DEFAULT_PRESSED_SCALE = 0.96;
|
|
@@ -76,6 +77,14 @@ declare const DEFAULT_PRESSED_SCALE = 0.96;
|
|
|
76
77
|
declare const DEFAULT_FADE_TRANSLATE_Y = 8;
|
|
77
78
|
/** Default shimmer sweep duration (ms) for {@link Skeleton}. */
|
|
78
79
|
declare const DEFAULT_SKELETON_DURATION_MS = 1200;
|
|
80
|
+
/** Default focused scale for {@link useFocusLift}. */
|
|
81
|
+
declare const DEFAULT_FOCUS_SCALE = 1.06;
|
|
82
|
+
/** Default focused lift (px, upward) for {@link useFocusLift}. */
|
|
83
|
+
declare const DEFAULT_FOCUS_LIFT_PX = 8;
|
|
84
|
+
/** Default per-item stagger (ms) for {@link Reorder}. */
|
|
85
|
+
declare const DEFAULT_FLIP_STAGGER_MS = 18;
|
|
86
|
+
/** Default maximum number of items {@link Reorder} animates; the rest snap. */
|
|
87
|
+
declare const DEFAULT_FLIP_CAP = 8;
|
|
79
88
|
|
|
80
89
|
interface UseEnterExitOptions {
|
|
81
90
|
/** Whether the element should be visible (entered). */
|
|
@@ -108,6 +117,57 @@ interface UseEnterExitResult {
|
|
|
108
117
|
}
|
|
109
118
|
declare function useEnterExit(options: UseEnterExitOptions): UseEnterExitResult;
|
|
110
119
|
|
|
120
|
+
interface FocusLiftSpring {
|
|
121
|
+
stiffness: number;
|
|
122
|
+
damping: number;
|
|
123
|
+
}
|
|
124
|
+
interface FocusLiftOptions {
|
|
125
|
+
/** Scale while focused. Default 1.06. */
|
|
126
|
+
scale?: number;
|
|
127
|
+
/** Upward lift (px) while focused. Default 8. */
|
|
128
|
+
lift?: number;
|
|
129
|
+
}
|
|
130
|
+
interface FocusLiftTarget {
|
|
131
|
+
scale: number;
|
|
132
|
+
translateY: number;
|
|
133
|
+
}
|
|
134
|
+
interface UseFocusLiftResult {
|
|
135
|
+
/** Animated style to spread onto an `Animated.View`. */
|
|
136
|
+
style: Animated.WithAnimatedObject<ViewStyle>;
|
|
137
|
+
}
|
|
138
|
+
/** The transform a tile should settle at. Pure — the hook only springs toward it. */
|
|
139
|
+
declare function focusLiftTarget(focused: boolean, reduced: boolean, opts: FocusLiftOptions): FocusLiftTarget;
|
|
140
|
+
declare function useFocusLift(focused: boolean, spring: FocusLiftSpring, opts?: FocusLiftOptions): UseFocusLiftResult;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* computeFlipDeltas — the FLIP "invert" step, kept pure so it can be unit-tested
|
|
144
|
+
* without driving RN `Animated` or a layout pass.
|
|
145
|
+
*
|
|
146
|
+
* Given every item's slot BEFORE and AFTER a reorder, it returns, for each item that
|
|
147
|
+
* moved, the offset it must start from so it visually sits in its old slot — the
|
|
148
|
+
* caller then springs that offset to 0 ("play"). Items are staggered in their NEW
|
|
149
|
+
* reading order (row-first: y, then x). New items (no previous slot) and items that
|
|
150
|
+
* did not move are omitted. Past `cap` animated items the rest are omitted too, so
|
|
151
|
+
* they snap straight to their new slot — a long list does not play a long wave.
|
|
152
|
+
*/
|
|
153
|
+
interface LayoutBox {
|
|
154
|
+
x: number;
|
|
155
|
+
y: number;
|
|
156
|
+
}
|
|
157
|
+
interface FlipDelta {
|
|
158
|
+
key: string;
|
|
159
|
+
dx: number;
|
|
160
|
+
dy: number;
|
|
161
|
+
delayMs: number;
|
|
162
|
+
}
|
|
163
|
+
interface FlipOptions {
|
|
164
|
+
/** Delay (ms) added per animated item, in new reading order. */
|
|
165
|
+
staggerMs: number;
|
|
166
|
+
/** Maximum number of items that animate; the rest snap. */
|
|
167
|
+
cap: number;
|
|
168
|
+
}
|
|
169
|
+
declare function computeFlipDeltas(prev: ReadonlyMap<string, LayoutBox>, next: ReadonlyMap<string, LayoutBox>, opts: FlipOptions): FlipDelta[];
|
|
170
|
+
|
|
111
171
|
/**
|
|
112
172
|
* FadeIn — fades its children in (with a small upward translate) once, on mount.
|
|
113
173
|
* The lightweight, mount-only sibling of {@link useEnterExit} (which handles the
|
|
@@ -213,4 +273,32 @@ interface SkeletonProps {
|
|
|
213
273
|
}
|
|
214
274
|
declare const Skeleton: ({ width, height, borderRadius, duration, backgroundColor, highlightColor, style, testID, }: SkeletonProps) => React.ReactElement;
|
|
215
275
|
|
|
216
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Reorder — a keyed list whose moved items spring from their old slot to the new one
|
|
278
|
+
* when `itemKeys` changes order (FLIP; maths in computeFlipDeltas, play in playFlip).
|
|
279
|
+
* - web: RN-web `onLayout` (ResizeObserver) misses position-only moves, so OLD slots are
|
|
280
|
+
* read from the DOM during the render that changes the order (DOM still holds the last
|
|
281
|
+
* commit) and NEW slots in `useLayoutEffect` — after the DOM mutation, before paint.
|
|
282
|
+
* - native: `onLayout` reports moves; the flip plays one frame after they arrive.
|
|
283
|
+
* Reduced motion: nothing animates (the caller crossfades). Transform only.
|
|
284
|
+
*/
|
|
285
|
+
|
|
286
|
+
interface ReorderProps {
|
|
287
|
+
/** Stable item keys, in display order. */
|
|
288
|
+
itemKeys: readonly string[];
|
|
289
|
+
/** Renders the content for one key. */
|
|
290
|
+
children: (key: string) => React.ReactNode;
|
|
291
|
+
spring: {
|
|
292
|
+
stiffness: number;
|
|
293
|
+
damping: number;
|
|
294
|
+
};
|
|
295
|
+
/** Per-item stagger (ms). Default 18. */
|
|
296
|
+
staggerMs?: number;
|
|
297
|
+
/** Maximum animated items; the rest snap. Default 8. */
|
|
298
|
+
cap?: number;
|
|
299
|
+
/** Container testID; each item gets `${testID}-item-${key}`. */
|
|
300
|
+
testID?: string;
|
|
301
|
+
}
|
|
302
|
+
declare function Reorder({ itemKeys, children, spring, staggerMs, cap, testID, }: ReorderProps): React.ReactElement;
|
|
303
|
+
|
|
304
|
+
export { Collapse, type CollapseProps, DEFAULT_FADE_TRANSLATE_Y, DEFAULT_FLIP_CAP, DEFAULT_FLIP_STAGGER_MS, DEFAULT_FOCUS_LIFT_PX, DEFAULT_FOCUS_SCALE, DEFAULT_PRESSED_SCALE, DEFAULT_SKELETON_DURATION_MS, FadeIn, type FadeInProps, type FlipDelta, type FlipOptions, type FocusLiftOptions, type FocusLiftSpring, type FocusLiftTarget, type LayoutBox, MOTION_TEST_IDS, type MotionEasingName, PressableScale, type PressableScaleProps, Reorder, type ReorderProps, Skeleton, type SkeletonProps, type UseEnterExitOptions, type UseEnterExitResult, type UseFocusLiftResult, collapseTargetHeight, computeFlipDeltas, focusLiftTarget, motionDurations, motionEasingTokens, motionEasings, resolveDuration, resolveScale, shimmerRange, shouldUseNativeDriver, useEnterExit, useFocusLift };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { prefersReducedMotion, useReducedMotion } from '@dloizides/rn-web-hooks';
|
|
2
|
-
import { EasingFunction, Animated,
|
|
2
|
+
import { EasingFunction, Animated, ViewStyle, StyleProp, PressableProps } from 'react-native';
|
|
3
3
|
import { MotionEasings, MotionDurations } from '@dloizides/design-tokens';
|
|
4
4
|
export { DEFAULT_MOTION, Motion, MotionDurations, MotionEasings } from '@dloizides/design-tokens';
|
|
5
5
|
import React from 'react';
|
|
@@ -69,6 +69,7 @@ declare const MOTION_TEST_IDS: {
|
|
|
69
69
|
readonly collapse: "collapse";
|
|
70
70
|
readonly pressableScale: "pressable-scale";
|
|
71
71
|
readonly skeleton: "skeleton";
|
|
72
|
+
readonly reorder: "reorder";
|
|
72
73
|
};
|
|
73
74
|
/** Default press-in scale for {@link PressableScale}. */
|
|
74
75
|
declare const DEFAULT_PRESSED_SCALE = 0.96;
|
|
@@ -76,6 +77,14 @@ declare const DEFAULT_PRESSED_SCALE = 0.96;
|
|
|
76
77
|
declare const DEFAULT_FADE_TRANSLATE_Y = 8;
|
|
77
78
|
/** Default shimmer sweep duration (ms) for {@link Skeleton}. */
|
|
78
79
|
declare const DEFAULT_SKELETON_DURATION_MS = 1200;
|
|
80
|
+
/** Default focused scale for {@link useFocusLift}. */
|
|
81
|
+
declare const DEFAULT_FOCUS_SCALE = 1.06;
|
|
82
|
+
/** Default focused lift (px, upward) for {@link useFocusLift}. */
|
|
83
|
+
declare const DEFAULT_FOCUS_LIFT_PX = 8;
|
|
84
|
+
/** Default per-item stagger (ms) for {@link Reorder}. */
|
|
85
|
+
declare const DEFAULT_FLIP_STAGGER_MS = 18;
|
|
86
|
+
/** Default maximum number of items {@link Reorder} animates; the rest snap. */
|
|
87
|
+
declare const DEFAULT_FLIP_CAP = 8;
|
|
79
88
|
|
|
80
89
|
interface UseEnterExitOptions {
|
|
81
90
|
/** Whether the element should be visible (entered). */
|
|
@@ -108,6 +117,57 @@ interface UseEnterExitResult {
|
|
|
108
117
|
}
|
|
109
118
|
declare function useEnterExit(options: UseEnterExitOptions): UseEnterExitResult;
|
|
110
119
|
|
|
120
|
+
interface FocusLiftSpring {
|
|
121
|
+
stiffness: number;
|
|
122
|
+
damping: number;
|
|
123
|
+
}
|
|
124
|
+
interface FocusLiftOptions {
|
|
125
|
+
/** Scale while focused. Default 1.06. */
|
|
126
|
+
scale?: number;
|
|
127
|
+
/** Upward lift (px) while focused. Default 8. */
|
|
128
|
+
lift?: number;
|
|
129
|
+
}
|
|
130
|
+
interface FocusLiftTarget {
|
|
131
|
+
scale: number;
|
|
132
|
+
translateY: number;
|
|
133
|
+
}
|
|
134
|
+
interface UseFocusLiftResult {
|
|
135
|
+
/** Animated style to spread onto an `Animated.View`. */
|
|
136
|
+
style: Animated.WithAnimatedObject<ViewStyle>;
|
|
137
|
+
}
|
|
138
|
+
/** The transform a tile should settle at. Pure — the hook only springs toward it. */
|
|
139
|
+
declare function focusLiftTarget(focused: boolean, reduced: boolean, opts: FocusLiftOptions): FocusLiftTarget;
|
|
140
|
+
declare function useFocusLift(focused: boolean, spring: FocusLiftSpring, opts?: FocusLiftOptions): UseFocusLiftResult;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* computeFlipDeltas — the FLIP "invert" step, kept pure so it can be unit-tested
|
|
144
|
+
* without driving RN `Animated` or a layout pass.
|
|
145
|
+
*
|
|
146
|
+
* Given every item's slot BEFORE and AFTER a reorder, it returns, for each item that
|
|
147
|
+
* moved, the offset it must start from so it visually sits in its old slot — the
|
|
148
|
+
* caller then springs that offset to 0 ("play"). Items are staggered in their NEW
|
|
149
|
+
* reading order (row-first: y, then x). New items (no previous slot) and items that
|
|
150
|
+
* did not move are omitted. Past `cap` animated items the rest are omitted too, so
|
|
151
|
+
* they snap straight to their new slot — a long list does not play a long wave.
|
|
152
|
+
*/
|
|
153
|
+
interface LayoutBox {
|
|
154
|
+
x: number;
|
|
155
|
+
y: number;
|
|
156
|
+
}
|
|
157
|
+
interface FlipDelta {
|
|
158
|
+
key: string;
|
|
159
|
+
dx: number;
|
|
160
|
+
dy: number;
|
|
161
|
+
delayMs: number;
|
|
162
|
+
}
|
|
163
|
+
interface FlipOptions {
|
|
164
|
+
/** Delay (ms) added per animated item, in new reading order. */
|
|
165
|
+
staggerMs: number;
|
|
166
|
+
/** Maximum number of items that animate; the rest snap. */
|
|
167
|
+
cap: number;
|
|
168
|
+
}
|
|
169
|
+
declare function computeFlipDeltas(prev: ReadonlyMap<string, LayoutBox>, next: ReadonlyMap<string, LayoutBox>, opts: FlipOptions): FlipDelta[];
|
|
170
|
+
|
|
111
171
|
/**
|
|
112
172
|
* FadeIn — fades its children in (with a small upward translate) once, on mount.
|
|
113
173
|
* The lightweight, mount-only sibling of {@link useEnterExit} (which handles the
|
|
@@ -213,4 +273,32 @@ interface SkeletonProps {
|
|
|
213
273
|
}
|
|
214
274
|
declare const Skeleton: ({ width, height, borderRadius, duration, backgroundColor, highlightColor, style, testID, }: SkeletonProps) => React.ReactElement;
|
|
215
275
|
|
|
216
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Reorder — a keyed list whose moved items spring from their old slot to the new one
|
|
278
|
+
* when `itemKeys` changes order (FLIP; maths in computeFlipDeltas, play in playFlip).
|
|
279
|
+
* - web: RN-web `onLayout` (ResizeObserver) misses position-only moves, so OLD slots are
|
|
280
|
+
* read from the DOM during the render that changes the order (DOM still holds the last
|
|
281
|
+
* commit) and NEW slots in `useLayoutEffect` — after the DOM mutation, before paint.
|
|
282
|
+
* - native: `onLayout` reports moves; the flip plays one frame after they arrive.
|
|
283
|
+
* Reduced motion: nothing animates (the caller crossfades). Transform only.
|
|
284
|
+
*/
|
|
285
|
+
|
|
286
|
+
interface ReorderProps {
|
|
287
|
+
/** Stable item keys, in display order. */
|
|
288
|
+
itemKeys: readonly string[];
|
|
289
|
+
/** Renders the content for one key. */
|
|
290
|
+
children: (key: string) => React.ReactNode;
|
|
291
|
+
spring: {
|
|
292
|
+
stiffness: number;
|
|
293
|
+
damping: number;
|
|
294
|
+
};
|
|
295
|
+
/** Per-item stagger (ms). Default 18. */
|
|
296
|
+
staggerMs?: number;
|
|
297
|
+
/** Maximum animated items; the rest snap. Default 8. */
|
|
298
|
+
cap?: number;
|
|
299
|
+
/** Container testID; each item gets `${testID}-item-${key}`. */
|
|
300
|
+
testID?: string;
|
|
301
|
+
}
|
|
302
|
+
declare function Reorder({ itemKeys, children, spring, staggerMs, cap, testID, }: ReorderProps): React.ReactElement;
|
|
303
|
+
|
|
304
|
+
export { Collapse, type CollapseProps, DEFAULT_FADE_TRANSLATE_Y, DEFAULT_FLIP_CAP, DEFAULT_FLIP_STAGGER_MS, DEFAULT_FOCUS_LIFT_PX, DEFAULT_FOCUS_SCALE, DEFAULT_PRESSED_SCALE, DEFAULT_SKELETON_DURATION_MS, FadeIn, type FadeInProps, type FlipDelta, type FlipOptions, type FocusLiftOptions, type FocusLiftSpring, type FocusLiftTarget, type LayoutBox, MOTION_TEST_IDS, type MotionEasingName, PressableScale, type PressableScaleProps, Reorder, type ReorderProps, Skeleton, type SkeletonProps, type UseEnterExitOptions, type UseEnterExitResult, type UseFocusLiftResult, collapseTargetHeight, computeFlipDeltas, focusLiftTarget, motionDurations, motionEasingTokens, motionEasings, resolveDuration, resolveScale, shimmerRange, shouldUseNativeDriver, useEnterExit, useFocusLift };
|