@octanejs/motion 0.1.0 → 0.1.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @octanejs/motion
2
2
 
3
- [Framer Motion](https://motion.dev) for the [octane](https://github.com/octanejs/octane) renderer.
3
+ [Framer Motion](https://motion.dev) for the [octane](https://github.com/octanejs/octane) UI framework.
4
4
 
5
5
  Motion separates a framework-agnostic animation engine (`animate`) and gesture
6
6
  primitives (`hover`, `press`) from its React components (`motion.div`,
@@ -86,3 +86,9 @@ FLIPs). Also drag momentum/elastic physics, reduced-motion enforcement, and
86
86
  Stagger specifics: `when: 'beforeChildren' | 'afterChildren'` parent/child sequencing
87
87
  is not implemented, and a child's stagger index is fixed at registration order (a
88
88
  keyed reorder does not re-stagger).
89
+
90
+ ## Status
91
+
92
+ Current scope, known divergences, and verification status are tracked in the
93
+ generated [bindings status table](../../docs/bindings-status.md), sourced from
94
+ this package's [`status.json`](./status.json).
package/package.json CHANGED
@@ -1,8 +1,15 @@
1
1
  {
2
2
  "name": "@octanejs/motion",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
+ "octane": {
7
+ "hookSlots": {
8
+ "manual": [
9
+ "src"
10
+ ]
11
+ }
12
+ },
6
13
  "description": "Framer Motion bindings for the octane renderer — reuses motion-dom's animation engine, swaps the React components for octane host components.",
7
14
  "author": {
8
15
  "name": "Dominic Gannaway",
@@ -28,7 +35,7 @@
28
35
  },
29
36
  "dependencies": {
30
37
  "motion": "^12.0.0",
31
- "octane": "0.1.1"
38
+ "octane": "0.1.4"
32
39
  },
33
40
  "devDependencies": {
34
41
  "vitest": "^4.1.9"
package/src/index.ts CHANGED
@@ -171,7 +171,8 @@ function createMotionComponent(tag: string) {
171
171
  });
172
172
  provideContext(scope, StaggerContext, orch);
173
173
 
174
- const node = hostComponent(scope, '_m', tag, domProps(props), props.children) as HTMLElement;
174
+ // Slot 0 of this component's own block (one hostComponent per motion instance).
175
+ const node = hostComponent(scope, 0, tag, domProps(props), props.children) as HTMLElement;
175
176
 
176
177
  // Resolve a gesture/exit target to its values + its own (per-variant) transition,
177
178
  // so a variant target carrying a `transition` key honors it (like `animate` does).
package/src/useAnimate.ts CHANGED
@@ -5,8 +5,17 @@
5
5
  import { createScopedAnimate } from 'motion';
6
6
  import { useState, useEffect } from 'octane';
7
7
 
8
+ // Memoized — runs per hook call per render; the cache returns the identical
9
+ // Symbol.for-interned value without the concat + registry lookup.
10
+ const subCache = new Map<symbol, Map<string, symbol>>();
8
11
  function sub(slot: symbol | undefined, tag: string): symbol | undefined {
9
- return slot !== undefined ? Symbol.for((slot.description ?? '') + ':ua:' + tag) : undefined;
12
+ if (slot === undefined) return undefined;
13
+ let byTag = subCache.get(slot);
14
+ if (byTag === undefined) subCache.set(slot, (byTag = new Map()));
15
+ let sym = byTag.get(tag);
16
+ if (sym === undefined)
17
+ byTag.set(tag, (sym = Symbol.for((slot.description ?? '') + ':ua:' + tag)));
18
+ return sym;
10
19
  }
11
20
 
12
21
  export function useAnimate(...args: any[]): [any, any] {
@@ -5,13 +5,21 @@
5
5
  import { motionValue } from 'motion';
6
6
  import { useState } from 'octane';
7
7
 
8
+ // Memoized tagless sub-slot (single entry per caller slot) — same interned
9
+ // Symbol.for value, minus the per-render concat + registry lookup.
10
+ const mvSlotCache = new Map<symbol, symbol>();
11
+ function mvSlot(slot: symbol | undefined): symbol | undefined {
12
+ if (slot === undefined) return undefined;
13
+ let sym = mvSlotCache.get(slot);
14
+ if (sym === undefined)
15
+ mvSlotCache.set(slot, (sym = Symbol.for((slot.description ?? '') + ':mv')));
16
+ return sym;
17
+ }
18
+
8
19
  export function useMotionValue<T>(initial: T, ...args: any[]): any {
9
20
  const tail = args[args.length - 1];
10
21
  const slot = typeof tail === 'symbol' ? (tail as symbol) : undefined;
11
- const [mv] = useState(
12
- () => motionValue(initial),
13
- slot !== undefined ? Symbol.for((slot.description ?? '') + ':mv') : undefined,
14
- );
22
+ const [mv] = useState(() => motionValue(initial), mvSlot(slot));
15
23
  return mv;
16
24
  }
17
25
 
@@ -5,8 +5,17 @@
5
5
  // which returns the unsubscribe fn (and, for 'change', stops idle animations).
6
6
  import { useInsertionEffect } from 'octane';
7
7
 
8
+ // Memoized — runs per hook call per render; the cache returns the identical
9
+ // Symbol.for-interned value without the concat + registry lookup.
10
+ const subCache = new Map<symbol, Map<string, symbol>>();
8
11
  function sub(slot: symbol | undefined, tag: string): symbol | undefined {
9
- return slot !== undefined ? Symbol.for((slot.description ?? '') + ':umve:' + tag) : undefined;
12
+ if (slot === undefined) return undefined;
13
+ let byTag = subCache.get(slot);
14
+ if (byTag === undefined) subCache.set(slot, (byTag = new Map()));
15
+ let sym = byTag.get(tag);
16
+ if (sym === undefined)
17
+ byTag.set(tag, (sym = Symbol.for((slot.description ?? '') + ':umve:' + tag)));
18
+ return sym;
10
19
  }
11
20
 
12
21
  export function useMotionValueEvent(...args: any[]): void {
package/src/useScroll.ts CHANGED
@@ -5,8 +5,17 @@
5
5
  import { motionValue, scroll } from 'motion';
6
6
  import { useState, useEffect } from 'octane';
7
7
 
8
+ // Memoized — runs per hook call per render; the cache returns the identical
9
+ // Symbol.for-interned value without the concat + registry lookup.
10
+ const subCache = new Map<symbol, Map<string, symbol>>();
8
11
  function sub(slot: symbol | undefined, tag: string): symbol | undefined {
9
- return slot !== undefined ? Symbol.for((slot.description ?? '') + ':us:' + tag) : undefined;
12
+ if (slot === undefined) return undefined;
13
+ let byTag = subCache.get(slot);
14
+ if (byTag === undefined) subCache.set(slot, (byTag = new Map()));
15
+ let sym = byTag.get(tag);
16
+ if (sym === undefined)
17
+ byTag.set(tag, (sym = Symbol.for((slot.description ?? '') + ':us:' + tag)));
18
+ return sym;
10
19
  }
11
20
 
12
21
  export interface ScrollOptions {
package/src/useSpring.ts CHANGED
@@ -9,8 +9,17 @@ import { motionValue, attachFollow } from 'motion';
9
9
  import { useState, useInsertionEffect } from 'octane';
10
10
  import { isMotionValue } from './useMotionValue';
11
11
 
12
+ // Memoized — runs per hook call per render; the cache returns the identical
13
+ // Symbol.for-interned value without the concat + registry lookup.
14
+ const subCache = new Map<symbol, Map<string, symbol>>();
12
15
  function sub(slot: symbol | undefined, tag: string): symbol | undefined {
13
- return slot !== undefined ? Symbol.for((slot.description ?? '') + ':usp:' + tag) : undefined;
16
+ if (slot === undefined) return undefined;
17
+ let byTag = subCache.get(slot);
18
+ if (byTag === undefined) subCache.set(slot, (byTag = new Map()));
19
+ let sym = byTag.get(tag);
20
+ if (sym === undefined)
21
+ byTag.set(tag, (sym = Symbol.for((slot.description ?? '') + ':usp:' + tag)));
22
+ return sym;
14
23
  }
15
24
 
16
25
  export interface SpringOptions {
@@ -9,8 +9,17 @@
9
9
  import { transformValue, mapValue } from 'motion';
10
10
  import { useState, useEffect } from 'octane';
11
11
 
12
+ // Memoized — runs per hook call per render; the cache returns the identical
13
+ // Symbol.for-interned value without the concat + registry lookup.
14
+ const subCache = new Map<symbol, Map<string, symbol>>();
12
15
  function sub(slot: symbol | undefined, tag: string): symbol | undefined {
13
- return slot !== undefined ? Symbol.for((slot.description ?? '') + ':ut:' + tag) : undefined;
16
+ if (slot === undefined) return undefined;
17
+ let byTag = subCache.get(slot);
18
+ if (byTag === undefined) subCache.set(slot, (byTag = new Map()));
19
+ let sym = byTag.get(tag);
20
+ if (sym === undefined)
21
+ byTag.set(tag, (sym = Symbol.for((slot.description ?? '') + ':ut:' + tag)));
22
+ return sym;
14
23
  }
15
24
 
16
25
  export function useTransform(...args: any[]): any {