@dloizides/ui-motion 1.1.0 → 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.
@@ -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":"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","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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dloizides/ui-motion",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Themable, brand-agnostic React Native (RN-web) motion primitives — useEnterExit, FadeIn, Collapse, PressableScale, Skeleton — built on RN Animated, driven by @dloizides/design-tokens motion tokens, and gated on @dloizides/rn-web-hooks useReducedMotion (every animation collapses to instant under reduced-motion). Part of the dloizides.com shared UI kit.",
5
5
  "keywords": [
6
6
  "react",
@@ -48,6 +48,28 @@
48
48
  "types": "./dist/index.d.ts",
49
49
  "default": "./dist/index.js"
50
50
  }
51
+ },
52
+ "./hairline": {
53
+ "react-native": {
54
+ "types": "./dist/hairline/native.d.ts",
55
+ "default": "./dist/hairline/native.js"
56
+ },
57
+ "browser": {
58
+ "types": "./dist/hairline/web.d.ts",
59
+ "default": "./dist/hairline/web.js"
60
+ },
61
+ "require": {
62
+ "types": "./dist/hairline/web.d.ts",
63
+ "default": "./dist/hairline/web.js"
64
+ },
65
+ "import": {
66
+ "types": "./dist/hairline/web.d.mts",
67
+ "default": "./dist/hairline/web.mjs"
68
+ },
69
+ "default": {
70
+ "types": "./dist/hairline/web.d.ts",
71
+ "default": "./dist/hairline/web.js"
72
+ }
51
73
  }
52
74
  },
53
75
  "files": [
@@ -60,7 +82,7 @@
60
82
  "node": ">=18.0.0"
61
83
  },
62
84
  "scripts": {
63
- "build": "rimraf dist && tsup",
85
+ "build": "rimraf dist && npm run generate:hairline && tsup",
64
86
  "build:watch": "tsup --watch",
65
87
  "test": "jest",
66
88
  "test:watch": "jest --watch",
@@ -71,19 +93,22 @@
71
93
  "clean": "rimraf dist",
72
94
  "security:audit": "npm audit --audit-level=high",
73
95
  "deps:outdated": "npm outdated || exit 0",
74
- "deps:unused": "npx depcheck --ignores \"@types/jest,@types/node,@types/react,@types/react-dom,rimraf,react-native\"",
96
+ "deps:unused": "npx depcheck --ignores \"@types/jest,@types/node,@types/react,@types/react-dom,rimraf,react-native,react-native-webview\"",
75
97
  "deps:licenses": "npx license-checker --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;0BSD;Unlicense;CC0-1.0\"",
76
98
  "deps:health": "npm run deps:outdated && npm run deps:unused",
77
99
  "prepublishOnly": "npm run clean && npm run build && npm run test",
78
- "version": "npm run build"
100
+ "version": "npm run build",
101
+ "generate:hairline": "node scripts/generate-hairline-bundle.mjs"
79
102
  },
80
103
  "dependencies": {
81
104
  "@dloizides/design-tokens": "^1.7.0",
82
- "@dloizides/rn-web-hooks": "^1.1.0"
105
+ "@dloizides/rn-web-hooks": "^1.1.0",
106
+ "@lucasmarkes/hairline": "0.3.0"
83
107
  },
84
108
  "peerDependencies": {
85
109
  "react": ">=18.0.0",
86
- "react-native": ">=0.74.0"
110
+ "react-native": ">=0.74.0",
111
+ "react-native-webview": ">=13.0.0"
87
112
  },
88
113
  "devDependencies": {
89
114
  "@dloizides/design-tokens": "file:../design-tokens",
@@ -105,9 +130,15 @@
105
130
  "react-dom": "^19.2.4",
106
131
  "react-native": "0.81.5",
107
132
  "react-native-web": "^0.21.0",
133
+ "react-native-webview": "^13.15.0",
108
134
  "rimraf": "^5.0.0",
109
135
  "ts-jest": "^29.1.0",
110
136
  "tsup": "^8.0.0",
111
137
  "typescript": "^5.4.0"
138
+ },
139
+ "peerDependenciesMeta": {
140
+ "react-native-webview": {
141
+ "optional": true
142
+ }
112
143
  }
113
144
  }