react-undo-redo
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -15,8 +15,8 @@ { | ||
"react-dom": "18.2.0", | ||
"react-undo-redo": "2.0.1", | ||
"react-undo-redo": "2.1.0", | ||
"tiny-invariant": "1.3.1" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "18.0.37", | ||
"@types/react-dom": "18.0.11", | ||
"@types/react": "18.2.6", | ||
"@types/react-dom": "18.2.4", | ||
"html-webpack-harddisk-plugin": "2.0.0", | ||
@@ -26,6 +26,6 @@ "html-webpack-plugin": "5.5.1", | ||
"typescript": "5.0.4", | ||
"webpack": "5.80.0", | ||
"webpack-cli": "5.0.1", | ||
"webpack-dev-server": "4.13.3" | ||
"webpack": "5.83.1", | ||
"webpack-cli": "5.1.1", | ||
"webpack-dev-server": "4.15.0" | ||
} | ||
} |
import { ComponentType, ReactNode } from "react"; | ||
import { PresentReducer } from "./createReducer"; | ||
import { PresentReducer, UndoRedoOptions } from "./createReducer"; | ||
type Dispatch<Actions> = (action: Actions) => void; | ||
@@ -18,3 +18,3 @@ type UndoRedoProviderProps<Present> = { | ||
}; | ||
export declare function createContext<Present, Actions extends {}>(reducer: PresentReducer<Present, Actions>): { | ||
export declare function createContext<Present, Actions extends {}>(reducer: PresentReducer<Present, Actions>, options?: UndoRedoOptions<Actions>): { | ||
UndoRedoProvider: ComponentType<UndoRedoProviderProps<Present>>; | ||
@@ -21,0 +21,0 @@ usePresent: () => [Present, Dispatch<Actions>]; |
@@ -29,3 +29,3 @@ "use strict"; | ||
var createReducer_1 = require("./createReducer"); | ||
function createContext(reducer) { | ||
function createContext(reducer, options) { | ||
var Context = (0, react_1.createContext)([ | ||
@@ -47,3 +47,3 @@ { | ||
]); | ||
var undoRedoReducer = (0, createReducer_1.createReducer)(reducer); | ||
var undoRedoReducer = (0, createReducer_1.createReducer)(reducer, options); | ||
function UndoRedoProvider(_a) { | ||
@@ -50,0 +50,0 @@ var children = _a.children, initialState = _a.initialState, _b = _a.past, past = _b === void 0 ? [] : _b, _c = _a.future, future = _c === void 0 ? [] : _c; |
@@ -7,2 +7,5 @@ export type UndoRedoState<Present> = { | ||
export type PresentReducer<Present, Actions> = (state: Present, action: Actions) => Present; | ||
export type UndoRedoOptions<Actions> = { | ||
track?: (action: Actions) => boolean | undefined; | ||
}; | ||
export type UndoRedoReducer<Present, Actions> = (state: UndoRedoState<Present>, action: Actions) => UndoRedoState<Present>; | ||
@@ -20,5 +23,5 @@ declare const enum UndoRedoActionTypes { | ||
export type UndoRedoActions<Base> = Base | UndoAction | RedoAction; | ||
export declare function createReducer<Present, Actions extends {}>(presentReducer: PresentReducer<Present, Actions>): UndoRedoReducer<Present, UndoRedoActions<Actions>>; | ||
export declare function createReducer<Present, Actions extends {}>(presentReducer: PresentReducer<Present, Actions>, { track }?: UndoRedoOptions<Actions>): UndoRedoReducer<Present, UndoRedoActions<Actions>>; | ||
export declare function undo(): UndoAction; | ||
export declare function redo(): RedoAction; | ||
export {}; |
@@ -13,3 +13,5 @@ "use strict"; | ||
exports.redo = exports.undo = exports.createReducer = void 0; | ||
function createReducer(presentReducer) { | ||
var trackAll = function () { return true; }; | ||
function createReducer(presentReducer, _a) { | ||
var _b = _a === void 0 ? {} : _a, _c = _b.track, track = _c === void 0 ? trackAll : _c; | ||
return function reducer(state, action) { | ||
@@ -36,2 +38,10 @@ if ("type" in action) { | ||
} | ||
var isTrackableAction = track(action); | ||
if (!isTrackableAction) { | ||
return { | ||
past: function () { return state.past(); }, | ||
present: function () { return presentReducer(state.present(), action); }, | ||
future: function () { return state.future(); }, | ||
}; | ||
} | ||
var past = __spreadArray([state.present()], state.past(), true); | ||
@@ -38,0 +48,0 @@ var present = presentReducer(state.present(), action); |
@@ -1,2 +0,2 @@ | ||
declare enum CountActionTypes { | ||
export declare enum CountActionTypes { | ||
INCREMENT = "@@count/increment", | ||
@@ -11,3 +11,3 @@ DECREMENT = "@@count/decrement" | ||
}; | ||
type CountActions = IncrementAction | DecrementAction; | ||
export type CountActions = IncrementAction | DecrementAction; | ||
export declare const countReducer: (state: number, action: CountActions) => number; | ||
@@ -14,0 +14,0 @@ export declare const increment: () => IncrementAction; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.decrement = exports.increment = exports.countReducer = void 0; | ||
exports.decrement = exports.increment = exports.countReducer = exports.CountActionTypes = void 0; | ||
var tiny_invariant_1 = __importDefault(require("tiny-invariant")); | ||
@@ -13,3 +13,3 @@ var CountActionTypes; | ||
CountActionTypes["DECREMENT"] = "@@count/decrement"; | ||
})(CountActionTypes || (CountActionTypes = {})); | ||
})(CountActionTypes = exports.CountActionTypes || (exports.CountActionTypes = {})); | ||
var countReducer = function (state, action) { | ||
@@ -16,0 +16,0 @@ (0, tiny_invariant_1.default)(state != null, "Count reducer needs an initial state"); |
@@ -1,1 +0,1 @@ | ||
export { countReducer, increment } from "./countReducer"; | ||
export { countReducer, CountActions, CountActionTypes, increment } from "./countReducer"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.increment = exports.countReducer = void 0; | ||
exports.increment = exports.CountActionTypes = exports.countReducer = void 0; | ||
var countReducer_1 = require("./countReducer"); | ||
Object.defineProperty(exports, "countReducer", { enumerable: true, get: function () { return countReducer_1.countReducer; } }); | ||
Object.defineProperty(exports, "CountActionTypes", { enumerable: true, get: function () { return countReducer_1.CountActionTypes; } }); | ||
Object.defineProperty(exports, "increment", { enumerable: true, get: function () { return countReducer_1.increment; } }); |
{ | ||
"name": "react-undo-redo", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "A library to add undo-redo to any reducer", | ||
@@ -23,11 +23,11 @@ "main": "lib/index.js", | ||
"@testing-library/user-event": "^14.4.3", | ||
"@types/react": "18.0.37", | ||
"@types/react-dom": "18.0.11", | ||
"@types/react": "18.2.6", | ||
"@types/react-dom": "18.2.4", | ||
"husky": "8.0.3", | ||
"jest": "29.5.0", | ||
"jest-environment-jsdom": "29.5.0", | ||
"prettier": "2.8.7", | ||
"prettier": "2.8.8", | ||
"react": "18.2.0", | ||
"react-dom": "18.2.0", | ||
"rimraf": "5.0.0", | ||
"rimraf": "5.0.1", | ||
"ts-jest": "29.1.0", | ||
@@ -34,0 +34,0 @@ "typescript": "5.0.4" |
@@ -24,3 +24,3 @@ # react-undo-redo | ||
In order to create the provider and hooks to manage undo and redo you call `createUndoRedo` and pass the `reducer` you'd like to enhance. | ||
This methods returns a provider component and hooks to work with your state. | ||
This method returns a provider component and hooks to work with your state. | ||
The `reducer` you pass does not need any knowledge about this feature. | ||
@@ -35,2 +35,14 @@ | ||
`createUndoRedo` also accepts an options object as a second parameter. Currently available options: | ||
- `track` - function with signature `(action) => boolean`. It is invoked on every dispatch and defines whether the new state is avaiable for undo/redo. If function returns `false`, the state won't affect the change history. It is useful in situations, when the change is not reflected in the UI or the user cannot control over. | ||
```js | ||
import { createUndoRedo } from "react-undo-redo" | ||
const { UndoRedoProvider, usePast, usePresent, useFuture, useUndoRedo } = | ||
createUndoRedo(reducer, {track: (action) => action.type !== 'GET_NEW_TODOS'}) | ||
``` | ||
### `UndoRedoProvider` | ||
@@ -37,0 +49,0 @@ |
import { createReducer, redo, undo } from "./createReducer" | ||
import { countReducer, increment } from "./fixtures" | ||
import { | ||
CountActionTypes, | ||
CountActions, | ||
countReducer, | ||
increment, | ||
} from "./fixtures" | ||
@@ -40,2 +45,30 @@ describe("create reducer", () => { | ||
}) | ||
describe("with `track` callback", () => { | ||
it("moves the current present into the past when `track` callback returns `true`", () => { | ||
const reducer = createReducer(countReducer, { track: () => true }) | ||
const { past, present } = reducer(initialState, increment()) | ||
expect(past()).toEqual([0]) | ||
expect(present()).toEqual(1) | ||
}) | ||
it("updates the current present without changing the past and the future, when `track` callback returns `false`", () => { | ||
const trackOnlyIncrements = (action: CountActions) => | ||
action.type === CountActionTypes.DECREMENT | ||
const reducer = createReducer(countReducer, { | ||
track: trackOnlyIncrements, | ||
}) | ||
const untrackedState = reducer( | ||
{ past: () => [0], present: () => 1, future: () => [2] }, | ||
increment() | ||
) | ||
expect(untrackedState.past()).toEqual([0]) | ||
expect(untrackedState.present()).toEqual(2) | ||
expect(untrackedState.future()).toEqual([2]) | ||
}) | ||
}) | ||
}) |
@@ -12,2 +12,6 @@ export type UndoRedoState<Present> = { | ||
export type UndoRedoOptions<Actions> = { | ||
track?: (action: Actions) => boolean | undefined | ||
} | ||
export type UndoRedoReducer<Present, Actions> = ( | ||
@@ -33,4 +37,7 @@ state: UndoRedoState<Present>, | ||
const trackAll = () => true | ||
export function createReducer<Present, Actions extends {}>( | ||
presentReducer: PresentReducer<Present, Actions> | ||
presentReducer: PresentReducer<Present, Actions>, | ||
{ track = trackAll }: UndoRedoOptions<Actions> = {} | ||
): UndoRedoReducer<Present, UndoRedoActions<Actions>> { | ||
@@ -65,2 +72,11 @@ return function reducer( | ||
const isTrackableAction = track(action) | ||
if (!isTrackableAction) { | ||
return { | ||
past: () => state.past(), | ||
present: () => presentReducer(state.present(), action), | ||
future: () => state.future(), | ||
} | ||
} | ||
const past = [state.present(), ...state.past()] | ||
@@ -67,0 +83,0 @@ const present = presentReducer(state.present(), action) |
import invariant from "tiny-invariant" | ||
enum CountActionTypes { | ||
export enum CountActionTypes { | ||
INCREMENT = "@@count/increment", | ||
@@ -16,3 +16,3 @@ DECREMENT = "@@count/decrement", | ||
type CountActions = IncrementAction | DecrementAction | ||
export type CountActions = IncrementAction | DecrementAction | ||
@@ -19,0 +19,0 @@ export const countReducer = (state: number, action: CountActions): number => { |
@@ -1,1 +0,1 @@ | ||
export { countReducer, increment } from "./countReducer" | ||
export { countReducer, CountActions, CountActionTypes, increment } from "./countReducer" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
161920
893
119
0