@hewnui/motion 0.0.0-stage → 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Himanshu Kumar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,33 @@
1
- # Temporary Holding Version
1
+ # @hewnui/motion
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Shared motion tokens and reduced-motion-aware primitives (`full`, `reduced`, `off`) used by Hewn components.
4
+
5
+ Part of [Hewn](https://hewnui.dev).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @hewnui/motion
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { resolveMotionMode, durations } from "@hewnui/motion";
17
+ ```
18
+
19
+ ## Modes
20
+
21
+ | Mode | Meaning |
22
+ |---|---|
23
+ | `full` | Motion enabled (default) |
24
+ | `reduced` | Shorter / quieter motion |
25
+ | `off` | No motion |
26
+
27
+ OS `prefers-reduced-motion: reduce` never elevates above `reduced`. Legacy preference `"on"` is accepted as a deprecated alias of `"full"` (dev-only console warning).
28
+
29
+ Docs: https://hewnui.dev/docs/motion
30
+
31
+ ## License
32
+
33
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1 @@
1
+ export declare function loadMotionFeatures(): Promise<import("motion/react").FeatureBundle>;
@@ -0,0 +1,4 @@
1
+ export async function loadMotionFeatures() {
2
+ const { domAnimation } = await import("motion/react");
3
+ return domAnimation;
4
+ }
@@ -0,0 +1,5 @@
1
+ export { durations, easings, motionCssVars, type MotionDuration, type MotionEasing, } from "./tokens.js";
2
+ export { springs, springSnappy, springSoft, enterTransition, type MotionSpring, } from "./springs.js";
3
+ export { motionModes, resolveMotionMode, isMotionMode, parseMotionPreference, coerceMotionMode, motionConfigReduced, type MotionMode, } from "./resolve.js";
4
+ export { iconState, fadeIn, drawIn, iconPop } from "./presets.js";
5
+ export { loadMotionFeatures } from "./features.js";
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { durations, easings, motionCssVars, } from "./tokens.js";
2
+ export { springs, springSnappy, springSoft, enterTransition, } from "./springs.js";
3
+ export { motionModes, resolveMotionMode, isMotionMode, parseMotionPreference, coerceMotionMode, motionConfigReduced, } from "./resolve.js";
4
+ export { iconState, fadeIn, drawIn, iconPop } from "./presets.js";
5
+ export { loadMotionFeatures } from "./features.js";
@@ -0,0 +1,26 @@
1
+ export declare const iconState: {
2
+ hidden: {
3
+ opacity: number;
4
+ scale: number;
5
+ filter: string;
6
+ };
7
+ visible: {
8
+ opacity: number;
9
+ scale: number;
10
+ filter: string;
11
+ };
12
+ };
13
+ export declare const fadeIn: {
14
+ readonly duration: 0.2;
15
+ };
16
+ export declare const drawIn: {
17
+ readonly duration: 0.36;
18
+ readonly ease: readonly [0.2, 0, 0, 1];
19
+ };
20
+ export declare const iconPop: {
21
+ readonly bounce: 0;
22
+ readonly type: "spring";
23
+ readonly stiffness: 420;
24
+ readonly damping: 30;
25
+ readonly mass: 0.7;
26
+ };
@@ -0,0 +1,17 @@
1
+ import { durations, easings } from "./tokens.js";
2
+ import { springs } from "./springs.js";
3
+ export const iconState = {
4
+ hidden: { opacity: 0, scale: 0.25, filter: "blur(4px)" },
5
+ visible: { opacity: 1, scale: 1, filter: "blur(0px)" },
6
+ };
7
+ export const fadeIn = {
8
+ duration: durations.base,
9
+ };
10
+ export const drawIn = {
11
+ duration: durations.slow,
12
+ ease: easings.standard,
13
+ };
14
+ export const iconPop = {
15
+ ...springs.snappy,
16
+ bounce: 0,
17
+ };
@@ -0,0 +1,17 @@
1
+ export declare const motionModes: readonly ["full", "reduced", "off"];
2
+ export type MotionMode = (typeof motionModes)[number];
3
+ /**
4
+ * Resolve the effective motion mode.
5
+ * An explicit user preference may only reduce motion further — never override
6
+ * `prefers-reduced-motion: reduce` into `full`.
7
+ */
8
+ export declare function resolveMotionMode(preference: MotionMode, osReduced: boolean): MotionMode;
9
+ export declare function isMotionMode(value: string): value is MotionMode;
10
+ /**
11
+ * Parse stored / prop motion preferences.
12
+ * Legacy `"on"` is accepted as a deprecated alias of `"full"` (breaking rename).
13
+ */
14
+ export declare function parseMotionPreference(value: string | null): MotionMode | null;
15
+ /** Accept `MotionMode` or the deprecated `"on"` alias (maps to `"full"`). */
16
+ export declare function coerceMotionMode(value: MotionMode | "on" | string | null | undefined, fallback?: MotionMode): MotionMode;
17
+ export declare function motionConfigReduced(effective: MotionMode): "never" | "always";
@@ -0,0 +1,51 @@
1
+ export const motionModes = ["full", "reduced", "off"];
2
+ const rank = {
3
+ full: 2,
4
+ reduced: 1,
5
+ off: 0,
6
+ };
7
+ /**
8
+ * Resolve the effective motion mode.
9
+ * An explicit user preference may only reduce motion further — never override
10
+ * `prefers-reduced-motion: reduce` into `full`.
11
+ */
12
+ export function resolveMotionMode(preference, osReduced) {
13
+ const ceiling = osReduced ? "reduced" : "full";
14
+ return rank[preference] <= rank[ceiling] ? preference : ceiling;
15
+ }
16
+ export function isMotionMode(value) {
17
+ return motionModes.includes(value);
18
+ }
19
+ /**
20
+ * Parse stored / prop motion preferences.
21
+ * Legacy `"on"` is accepted as a deprecated alias of `"full"` (breaking rename).
22
+ */
23
+ export function parseMotionPreference(value) {
24
+ if (value === "on") {
25
+ if (!isProductionEnv()) {
26
+ console.warn('[Hewn] Motion mode "on" is deprecated; use "full". Mapping "on" → "full".');
27
+ }
28
+ return "full";
29
+ }
30
+ if (value === "full")
31
+ return "full";
32
+ if (value === "reduced")
33
+ return "reduced";
34
+ if (value === "off")
35
+ return "off";
36
+ return null;
37
+ }
38
+ /** Accept `MotionMode` or the deprecated `"on"` alias (maps to `"full"`). */
39
+ export function coerceMotionMode(value, fallback = "full") {
40
+ if (value == null)
41
+ return fallback;
42
+ return parseMotionPreference(String(value)) ?? fallback;
43
+ }
44
+ export function motionConfigReduced(effective) {
45
+ return effective === "full" ? "never" : "always";
46
+ }
47
+ function isProductionEnv() {
48
+ const proc = globalThis
49
+ .process;
50
+ return proc?.env?.NODE_ENV === "production";
51
+ }
@@ -0,0 +1,42 @@
1
+ export declare const springs: {
2
+ readonly snappy: {
3
+ readonly type: "spring";
4
+ readonly stiffness: 420;
5
+ readonly damping: 30;
6
+ readonly mass: 0.7;
7
+ };
8
+ readonly soft: {
9
+ readonly type: "spring";
10
+ readonly stiffness: 280;
11
+ readonly damping: 28;
12
+ readonly mass: 0.9;
13
+ };
14
+ readonly enter: {
15
+ readonly type: "spring";
16
+ readonly stiffness: 340;
17
+ readonly damping: 30;
18
+ readonly mass: 0.8;
19
+ };
20
+ };
21
+ export type MotionSpring = keyof typeof springs;
22
+ /** @deprecated Prefer `springs.snappy`. */
23
+ export declare const springSnappy: {
24
+ readonly type: "spring";
25
+ readonly stiffness: 420;
26
+ readonly damping: 30;
27
+ readonly mass: 0.7;
28
+ };
29
+ /** @deprecated Prefer `springs.soft`. */
30
+ export declare const springSoft: {
31
+ readonly type: "spring";
32
+ readonly stiffness: 280;
33
+ readonly damping: 28;
34
+ readonly mass: 0.9;
35
+ };
36
+ /** @deprecated Prefer `springs.enter`. */
37
+ export declare const enterTransition: {
38
+ readonly type: "spring";
39
+ readonly stiffness: 340;
40
+ readonly damping: 30;
41
+ readonly mass: 0.8;
42
+ };
@@ -0,0 +1,26 @@
1
+ export const springs = {
2
+ snappy: {
3
+ type: "spring",
4
+ stiffness: 420,
5
+ damping: 30,
6
+ mass: 0.7,
7
+ },
8
+ soft: {
9
+ type: "spring",
10
+ stiffness: 280,
11
+ damping: 28,
12
+ mass: 0.9,
13
+ },
14
+ enter: {
15
+ type: "spring",
16
+ stiffness: 340,
17
+ damping: 30,
18
+ mass: 0.8,
19
+ },
20
+ };
21
+ /** @deprecated Prefer `springs.snappy`. */
22
+ export const springSnappy = springs.snappy;
23
+ /** @deprecated Prefer `springs.soft`. */
24
+ export const springSoft = springs.soft;
25
+ /** @deprecated Prefer `springs.enter`. */
26
+ export const enterTransition = springs.enter;
@@ -0,0 +1,30 @@
1
+ /** Duration tokens in seconds for Motion `transition.duration`. */
2
+ export declare const durations: {
3
+ readonly instant: 0;
4
+ readonly fast: 0.12;
5
+ readonly base: 0.2;
6
+ readonly slow: 0.36;
7
+ };
8
+ export type MotionDuration = keyof typeof durations;
9
+ /** Cubic-bezier tuples for Motion `transition.ease`. */
10
+ export declare const easings: {
11
+ readonly standard: readonly [0.2, 0, 0, 1];
12
+ readonly emphasized: readonly [0.16, 1, 0.3, 1];
13
+ readonly exit: readonly [0.4, 0, 1, 1];
14
+ readonly linear: "linear";
15
+ };
16
+ export type MotionEasing = keyof typeof easings;
17
+ /** CSS custom property names mirrored in `@hewnui/themes/motion.css`. */
18
+ export declare const motionCssVars: {
19
+ readonly durationInstant: "--kp-motion-duration-instant";
20
+ readonly durationFast: "--kp-motion-duration-fast";
21
+ readonly durationBase: "--kp-motion-duration";
22
+ readonly durationSlow: "--kp-motion-duration-slow";
23
+ readonly easeStandard: "--kp-motion-ease-standard";
24
+ readonly easeEmphasized: "--kp-motion-ease-emphasized";
25
+ readonly easeExit: "--kp-motion-ease-exit";
26
+ readonly easeLinear: "--kp-motion-ease-linear";
27
+ readonly ease: "--kp-motion-ease";
28
+ readonly stiffness: "--kp-motion-stiffness";
29
+ readonly damping: "--kp-motion-damping";
30
+ };
package/dist/tokens.js ADDED
@@ -0,0 +1,28 @@
1
+ /** Duration tokens in seconds for Motion `transition.duration`. */
2
+ export const durations = {
3
+ instant: 0,
4
+ fast: 0.12,
5
+ base: 0.2,
6
+ slow: 0.36,
7
+ };
8
+ /** Cubic-bezier tuples for Motion `transition.ease`. */
9
+ export const easings = {
10
+ standard: [0.2, 0, 0, 1],
11
+ emphasized: [0.16, 1, 0.3, 1],
12
+ exit: [0.4, 0, 1, 1],
13
+ linear: "linear",
14
+ };
15
+ /** CSS custom property names mirrored in `@hewnui/themes/motion.css`. */
16
+ export const motionCssVars = {
17
+ durationInstant: "--kp-motion-duration-instant",
18
+ durationFast: "--kp-motion-duration-fast",
19
+ durationBase: "--kp-motion-duration",
20
+ durationSlow: "--kp-motion-duration-slow",
21
+ easeStandard: "--kp-motion-ease-standard",
22
+ easeEmphasized: "--kp-motion-ease-emphasized",
23
+ easeExit: "--kp-motion-ease-exit",
24
+ easeLinear: "--kp-motion-ease-linear",
25
+ ease: "--kp-motion-ease",
26
+ stiffness: "--kp-motion-stiffness",
27
+ damping: "--kp-motion-damping",
28
+ };
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "@hewnui/motion",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.1",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/hewnui/Hewn.git",
8
+ "directory": "packages/motion"
9
+ },
10
+ "type": "module",
11
+ "sideEffects": false,
12
+ "files": [
13
+ "README.md",
14
+ "LICENSE",
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ },
25
+ "./package.json": "./package.json"
26
+ },
27
+ "peerDependencies": {
28
+ "motion": "^12.42.2",
29
+ "react": "^19.2.7"
30
+ },
31
+ "devDependencies": {
32
+ "motion": "12.42.2",
33
+ "react": "19.2.7",
34
+ "typescript": "6.0.3",
35
+ "vitest": "4.1.10",
36
+ "@hewnui/tsconfig": "0.0.0"
37
+ },
38
+ "homepage": "https://hewnui.dev",
39
+ "bugs": {
40
+ "url": "https://github.com/hewnui/Hewn/issues"
41
+ },
42
+ "author": "Himanshu Kumar",
43
+ "description": "Shared motion tokens and reduced-motion-aware primitives (full, reduced, off) used by Hewn components.",
44
+ "keywords": [
45
+ "react",
46
+ "motion",
47
+ "framer-motion",
48
+ "animation",
49
+ "reduced-motion",
50
+ "accessibility",
51
+ "design-tokens",
52
+ "hewnui"
53
+ ],
54
+ "scripts": {
55
+ "build": "tsc -p tsconfig.build.json && tsx ../../tooling/fix-esm-relative-extensions.ts dist",
56
+ "typecheck": "tsc --noEmit",
57
+ "test": "vitest run"
58
+ }
6
59
  }