diff --git a/LICENSE b/LICENSE
index 7cc760f..acd7040 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
ISC License
-Copyright (c) 2021–2022 Alexey Raspopov
+Copyright (c) 2021–2024 Oleksii Raspopov
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
diff --git a/packages/oscillation/package.json b/packages/oscillation/package.json
index 80f6604..94ca780 100644
--- a/packages/oscillation/package.json
+++ b/packages/oscillation/package.json
@@ -3,7 +3,7 @@
"version": "0.2.0",
"description": "An animation library",
"license": "ISC",
- "author": "Alexey Raspopov",
+ "author": "Oleksii Raspopov",
"repository": "UnknownPrinciple/oscillation",
"main": "./oscillation.js",
"module": "./oscillation.js",
diff --git a/packages/react-oscillation/README.md b/packages/react-oscillation/README.md
deleted file mode 100644
index bde3675..0000000
--- a/packages/react-oscillation/README.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# React Oscillation
-
-Complementary React hooks and components for Oscillation library
-
- npm install react-oscillation
-
-## Usage
-
-```jsx
-import { useMotion, spring } from "react-oscillation";
-
-function Toggle({ checked, onChange }) {
- let { x } = useMotion(() => ({ x: spring(checked ? 100 : 0) }), [checked]);
- let transform = `translateX(${x}px)`;
- return (
-
- );
-}
-```
-
-## API
-
-### `useMotion(factory, deps)`
-
-Hook to translate arbitrary input into motion-based value. A `factory` function suppose to return an
-object that enumerates what values need to be advancing. Similar to `useMemo()`, `deps` array tracks
-dependencies to update motion target.
-
-```jsx
-import { useMotion, spring } from "react-oscillation";
-
-function Scene({ targetX, targetY }) {
- let { x, y } = useMotion(() => {
- return { x: spring(targetX), y: spring(targetY) };
- }, [targetX, targetY]);
- let transform = `translateX(${x}px, ${y}px)`;
- return (
-
- );
-}
-```
-
-### `useMotionState(initialValues)`
-
-Hook to translate arbitrary input into motion-based value just like `useMotion()` but additionally
-allows manually updating the target, similar to how `useState()` works.
-
-```jsx
-import { useMotionState, spring } from "react-oscillation";
-
-function Scene() {
- let [{ x, y }, setState] = useMotion({ x: 0, y: 0 });
- let transform = `translateX(${x}px, ${y}px)`;
- let randomize = () => {
- let randomX = Math.random() * 500;
- let randomY = Math.random() * 300;
- setState({ x: spring(randomX), y: spring(randomY) });
- };
- return (
-
- );
-}
-```
-
-### ``
-
-Component that provides motion-based values via render-prop. Suitable for cases where a small part
-of component's render should be updated but re-rendering the whole component is bad for performance.
-
-```jsx
-import { useMotionState, spring } from "react-oscillation";
-
-function Scene() {
- let [{ x, y }, setState] = useState({ x: 0, y: 0 });
- let randomize = () => {
- setState({ x: Math.random() * 500, y: Math.random() * 300 });
- };
- return (
-
-
- {({ x, y }) => {
- let transform = `translateX(${x}px, ${y}px)`;
- return ;
- }}
-
-
-
- );
-}
-```
diff --git a/packages/react-oscillation/jest.config.js b/packages/react-oscillation/jest.config.js
deleted file mode 100644
index 7107606..0000000
--- a/packages/react-oscillation/jest.config.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default {
- resetMocks: true,
- collectCoverage: true,
- transform: {
- "\\.js$": "./jest.transform.js",
- },
- moduleNameMapper: {
- // expects build artifacts
- oscillation$: "/../oscillation/build",
- },
-};
diff --git a/packages/react-oscillation/jest.transform.js b/packages/react-oscillation/jest.transform.js
deleted file mode 100644
index 9afd9b9..0000000
--- a/packages/react-oscillation/jest.transform.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import bj from "babel-jest";
-
-export default bj.createTransformer({
- presets: [["@babel/preset-env", { loose: true }], "@babel/preset-react"],
-});
diff --git a/packages/react-oscillation/modules/Motion.js b/packages/react-oscillation/modules/Motion.js
deleted file mode 100644
index 7789a03..0000000
--- a/packages/react-oscillation/modules/Motion.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { useMotion } from "./useMotion.js";
-
-export function Motion(props) {
- let values = useMotion(() => collect(props), [props]);
- return props.children(values);
-}
-
-function collect(source) {
- let result = {};
- for (let key in source) {
- if (typeof source[key] === "function") continue;
- result[key] = source[key];
- }
- return result;
-}
diff --git a/packages/react-oscillation/modules/__mocks__/host.js b/packages/react-oscillation/modules/__mocks__/host.js
deleted file mode 100644
index 25348e7..0000000
--- a/packages/react-oscillation/modules/__mocks__/host.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import { jest } from "@jest/globals";
-
-export default function instantiateMock() {
- let timestamp = 0;
- let performance = { now: jest.fn(() => timestamp) };
- let callbacks = {};
- let id = 0;
- let rAF = (cb) => {
- callbacks[id] = cb;
- return id++;
- };
-
- let cAF = (id) => {
- delete callbacks[id];
- };
-
- let step = (ms) => {
- let cbs = callbacks;
- callbacks = {};
- timestamp += ms;
- for (let k in cbs) {
- cbs[k](timestamp);
- }
- };
-
- let aAf = (steps, ms) => {
- for (var i = 0; i < steps; i++) {
- step(ms);
- }
- };
-
- global.performance = performance;
- global.requestAnimationFrame = jest.fn(rAF);
- global.cancelAnimationFrame = jest.fn(cAF);
- global.advanceAnimationFrame = aAf;
-}
diff --git a/packages/react-oscillation/modules/__tests__/Motion-test.js b/packages/react-oscillation/modules/__tests__/Motion-test.js
deleted file mode 100644
index 642ab55..0000000
--- a/packages/react-oscillation/modules/__tests__/Motion-test.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import * as React from "react";
-
-import { create, act } from "react-test-renderer";
-import { Motion } from "../Motion.js";
-
-import { spring } from "../spring.js";
-import instantiateMock from "../__mocks__/host.js";
-
-beforeEach(() => {
- instantiateMock();
-});
-
-test("proper react hooks data passing to the core library", () => {
- let snapshots = [];
- function Component({ value }) {
- return (
-
- {({ number, constant }) => {
- snapshots.push(number);
- return (
-
- {number}, {constant}
-
- );
- }}
-
- );
- }
- let renderer = create();
- expect(renderer.toJSON().children).toEqual(["0", ", ", "1"]);
- act(() => {
- renderer.update();
- });
- act(() => {
- advanceAnimationFrame(1, 0);
- advanceAnimationFrame(5, 1000 / 60);
- });
- expect(snapshots).toEqual([0, 0, 3.6720468997166984]);
- act(() => {
- advanceAnimationFrame(60, 1000 / 60);
- });
- expect(renderer.toJSON().children).toEqual(["10", ", ", "1"]);
-});
diff --git a/packages/react-oscillation/modules/__tests__/useMotion-test.js b/packages/react-oscillation/modules/__tests__/useMotion-test.js
deleted file mode 100644
index 9da4b1d..0000000
--- a/packages/react-oscillation/modules/__tests__/useMotion-test.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as React from "react";
-import { jest } from "@jest/globals";
-import { create, act } from "react-test-renderer";
-import { useMotion } from "../useMotion.js";
-import { useMotionState } from "../useMotionState.js";
-import { spring } from "../spring.js";
-import instantiateMock from "../__mocks__/host.js";
-
-beforeEach(() => {
- instantiateMock();
-});
-
-test("proper react hooks data passing to the core library", () => {
- let snapshots = [];
- function Component({ value }) {
- let { number, constant } = useMotion(() => ({ number: spring(value), constant: 1 }), [value]);
- snapshots.push(number);
- return (
-
- {number}, {constant}
-
- );
- }
- let renderer = create();
- expect(renderer.toJSON().children).toEqual(["0", ", ", "1"]);
- act(() => {
- renderer.update();
- });
- act(() => {
- advanceAnimationFrame(1, 0);
- advanceAnimationFrame(5, 1000 / 60);
- });
- expect(snapshots).toEqual([0, 0, 3.6720468997166984]);
- act(() => {
- advanceAnimationFrame(60, 1000 / 60);
- });
- expect(renderer.toJSON().children).toEqual(["10", ", ", "1"]);
-});
-
-test("proper react hooks setter scheduling", () => {
- let snapshots = [];
- let setStateFn;
- function Component() {
- let [state, setState] = useMotionState(() => ({ x: 0 }));
- snapshots.push(state.x);
- setStateFn = setState;
- return {state.x};
- }
- let renderer = create();
- expect(renderer.toJSON().children).toEqual(["0"]);
- act(() => {
- setStateFn({ x: spring(10) });
- advanceAnimationFrame(1, 0);
- advanceAnimationFrame(5, 1000 / 60);
- });
- expect(snapshots).toEqual([0, 3.6720468997166984]);
- let fn = jest.fn(() => ({ x: 0 }));
- act(() => {
- setStateFn(fn);
- });
- expect(fn).toHaveBeenCalledWith({ x: 3.6720468997166984 });
- expect(renderer.toJSON().children).toEqual(["0"]);
-});
diff --git a/packages/react-oscillation/modules/motionState.js b/packages/react-oscillation/modules/motionState.js
deleted file mode 100644
index fceb0b5..0000000
--- a/packages/react-oscillation/modules/motionState.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export function serializeMotionState(state) {
- let serialized = Object.create(state);
- for (let key in state) {
- let target = state[key];
- serialized[key] = isMotionConfig(target) ? target.value : target;
- }
- return serialized;
-}
-
-export function isMotionConfig(target) {
- return target != null && typeof target.update === "function";
-}
diff --git a/packages/react-oscillation/modules/spring.js b/packages/react-oscillation/modules/spring.js
deleted file mode 100644
index dc30ad7..0000000
--- a/packages/react-oscillation/modules/spring.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import { spring, springs } from "oscillation";
-
-// Re-exporting spring configs from the core library so the users
-// won't need to bother remembering different endpoints to import from
-export { spring, springs };
diff --git a/packages/react-oscillation/modules/useMotion.js b/packages/react-oscillation/modules/useMotion.js
deleted file mode 100644
index 785f660..0000000
--- a/packages/react-oscillation/modules/useMotion.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { useState, useLayoutEffect } from "react";
-import { requestMotion, cancelMotion } from "oscillation";
-import { serializeMotionState } from "./motionState.js";
-
-export function useMotion(factory, deps) {
- // initial state should be a snapshot of any values that factory() returns
- // this hook must synchronously return initial state
- let v = useState(() => serializeMotionState(factory()));
-
- // layout effect is used to schedule necessary animations immediately when
- // DOM elements are available
- // this effect directly uses `deps` as the source of dependencies and
- // intentionnaly omits tracking `state` since it will be up to date
- // every time the effect needs to be restarted
- useLayoutEffect(() => {
- let motionId = requestMotion(v[0], factory(), v[1]);
- return () => cancelMotion(motionId);
- }, deps);
-
- return v[0];
-}
diff --git a/packages/react-oscillation/modules/useMotionState.js b/packages/react-oscillation/modules/useMotionState.js
deleted file mode 100644
index 934e8f8..0000000
--- a/packages/react-oscillation/modules/useMotionState.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { useState, useRef, useCallback } from "react";
-import { requestMotion, cancelMotion } from "oscillation";
-import { isMotionConfig } from "./motionState.js";
-
-export function useMotionState(initialValue) {
- let v = useState(initialValue);
-
- // ref for saving motion id so the setter can cancel current animaiton
- // before starting a new one
- let idRef = useRef(null);
-
- let setMotionState = useCallback((values) => {
- cancelMotion(idRef.current);
-
- v[1]((state) => {
- // in the same way as setState(), this setter can receive a callback to determine
- // the next value based on the current one
- let nextValues = typeof values === "function" ? values(state) : values;
-
- // if any of new values require motion, trigger animaitons and save the id
- for (let key in nextValues) {
- if (isMotionConfig(nextValues[key])) {
- idRef.current = requestMotion(state, nextValues, v[1]);
- return state;
- }
- }
-
- // otherwise, assume immediate state change
- return nextValues;
- });
- }, []);
-
- return [v[0], setMotionState];
-}
diff --git a/packages/react-oscillation/package.json b/packages/react-oscillation/package.json
deleted file mode 100644
index 84e2ea2..0000000
--- a/packages/react-oscillation/package.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "react-oscillation",
- "version": "0.1.0",
- "description": "An animation library",
- "license": "ISC",
- "author": "Alexey Raspopov",
- "repository": "UnknownPrinciple/oscillation",
- "main": "./react-oscillation.js",
- "module": "./react-oscillation.js",
- "exports": "./react-oscillation.js",
- "type": "module",
- "sideEffects": false,
- "scripts": {
- "test": "jest --config jest.config.js",
- "build": "rollup --config rollup.config.js"
- },
- "dependencies": {
- "oscillation": "*"
- },
- "peerDependencies": {
- "react": "^17.0.0 || ^18.0.0"
- },
- "devDependencies": {
- "react": "^18.2.0",
- "react-test-renderer": "^18.2.0"
- }
-}
diff --git a/packages/react-oscillation/rollup.config.js b/packages/react-oscillation/rollup.config.js
deleted file mode 100644
index de4a1f5..0000000
--- a/packages/react-oscillation/rollup.config.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import copy from "rollup-plugin-copy";
-import size from "rollup-plugin-bundle-size";
-import multi from "@rollup/plugin-multi-entry";
-import externals from "rollup-plugin-auto-external";
-
-export default {
- input: ["modules/*.js", "!modules/motionState.js"],
- output: { file: "build/react-oscillation.js", format: "esm" },
- plugins: [
- externals(),
- multi(),
- size(),
- copy({
- targets: [
- { src: ["../../LICENSE", "README.md"], dest: "build" },
- { src: ["package.json"], dest: "build", transform: generatePkg },
- ],
- }),
- ],
-};
-
-function generatePkg(contents) {
- let pkg = JSON.parse(contents.toString());
- return JSON.stringify(
- {
- name: pkg.name,
- version: pkg.version,
- description: pkg.description,
- license: pkg.license,
- author: pkg.author,
- homepage: pkg.homepage,
- repository: pkg.repository,
- main: pkg.main,
- module: pkg.module,
- exports: pkg.exports,
- type: pkg.type,
- types: pkg.types,
- sideEffects: pkg.sideEffects,
- files: pkg.files,
- keywords: pkg.keywords,
- dependencies: pkg.dependencies,
- peerDependencies: pkg.peerDependencies,
- },
- null,
- 2,
- );
-}