use-propagate
Advanced tools
Comparing version 0.2.0-main.750531b to 0.2.0-main.b37d065
@@ -0,2 +1,5 @@ | ||
import React, { ReactNode } from 'react'; | ||
type Listener<T> = (value: T) => void; | ||
type Init = { | ||
@@ -12,2 +15,5 @@ /** | ||
declare function createPropagation<T>(init?: Init): { | ||
PropagationScope: React.MemoExoticComponent<({ children }: Readonly<{ | ||
children?: ReactNode | undefined; | ||
}>) => React.JSX.Element>; | ||
useListen: (listener: Listener<T>) => void; | ||
@@ -14,0 +20,0 @@ usePropagate: () => (value: T) => void; |
"use strict"; | ||
var __create = Object.create; | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getProtoOf = Object.getPrototypeOf; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
@@ -18,2 +20,10 @@ var __export = (target, all) => { | ||
}; | ||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
// If the importer is in node compatibility mode or this is not an ESM | ||
// file that has been converted to a CommonJS file using a Babel- | ||
// compatible transform (i.e. "__esModule" has not been set), then set | ||
// "default" to the CommonJS "module.exports" for node compatibility. | ||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
mod | ||
)); | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
@@ -28,15 +38,38 @@ | ||
// src/createPropagation.tsx | ||
var import_react = require("react"); | ||
// src/private/createPropagation.tsx | ||
var import_react = __toESM(require("react")); | ||
var import_react2 = require("react"); | ||
var import_use_ref_from = require("use-ref-from"); | ||
// src/private/createPropagateContextValue.tsx | ||
function createPropagationContextValue() { | ||
const listeners = /* @__PURE__ */ new Set(); | ||
return { | ||
addListener(listener) { | ||
listeners.add(listener); | ||
}, | ||
removeListener(listener) { | ||
listeners.delete(listener); | ||
}, | ||
runListeners(value) { | ||
listeners.forEach((listener) => listener(value)); | ||
} | ||
}; | ||
} | ||
// src/private/createPropagation.tsx | ||
function createPropagation(init = {}) { | ||
const { allowPropagateDuringRender } = init; | ||
const listeners = /* @__PURE__ */ new Set(); | ||
const addListener = (listener) => void listeners.add(listener); | ||
const removeListener = (listener) => void listeners.delete(listener); | ||
const context = (0, import_react2.createContext)(createPropagationContextValue()); | ||
let rendering = false; | ||
function PropagationScope({ children }) { | ||
const value = (0, import_react2.useMemo)(createPropagationContextValue, []); | ||
return /* @__PURE__ */ import_react.default.createElement(context.Provider, { value }, children); | ||
} | ||
return { | ||
PropagationScope: (0, import_react2.memo)(PropagationScope), | ||
useListen: (listener) => { | ||
const listenerRef = (0, import_use_ref_from.useRefFrom)(listener); | ||
const wrappingListener = (0, import_react.useMemo)(() => { | ||
const { addListener, removeListener } = (0, import_react2.useContext)(context); | ||
const wrappingListener = (0, import_react2.useMemo)(() => { | ||
const wrappingListener2 = (value) => listenerRef.current(value); | ||
@@ -46,7 +79,8 @@ addListener(wrappingListener2); | ||
}, [listenerRef]); | ||
(0, import_react.useEffect)(() => () => removeListener(wrappingListener), [wrappingListener]); | ||
(0, import_react2.useEffect)(() => () => removeListener(wrappingListener), [wrappingListener]); | ||
}, | ||
usePropagate: () => { | ||
rendering = true; | ||
(0, import_react.useLayoutEffect)(() => { | ||
const { runListeners } = (0, import_react2.useContext)(context); | ||
(0, import_react2.useLayoutEffect)(() => { | ||
rendering = false; | ||
@@ -60,3 +94,3 @@ }); | ||
} | ||
listeners.forEach((listener) => listener(value)); | ||
runListeners(value); | ||
}; | ||
@@ -63,0 +97,0 @@ } |
{ | ||
"name": "use-propagate", | ||
"version": "0.2.0-main.750531b", | ||
"version": "0.2.0-main.b37d065", | ||
"description": "Propagates an event to multiple subscribers using React hooks.", | ||
@@ -80,6 +80,7 @@ "files": [ | ||
"devDependencies": { | ||
"@babel/preset-env": "^7.24.6", | ||
"@babel/preset-react": "^7.24.6", | ||
"@babel/preset-typescript": "^7.24.6", | ||
"@testing-library/react": "^15.0.7", | ||
"@babel/preset-env": "^7.24.7", | ||
"@babel/preset-react": "^7.24.7", | ||
"@babel/preset-typescript": "^7.24.7", | ||
"@testing-library/dom": "^10.2.0", | ||
"@testing-library/react": "^16.0.0", | ||
"@tsconfig/recommended": "^1.0.6", | ||
@@ -93,9 +94,9 @@ "@tsconfig/strictest": "^2.0.5", | ||
"react-test-renderer": "^18.3.1", | ||
"tsup": "^8.0.2", | ||
"typescript": "^5.4.5" | ||
"tsup": "^8.1.0", | ||
"typescript": "^5.5.2" | ||
}, | ||
"dependencies": { | ||
"use-propagate": "^0.2.0-main.750531b", | ||
"use-propagate": "^0.2.0-main.b37d065", | ||
"use-ref-from": "^0.1.0" | ||
} | ||
} |
@@ -56,8 +56,66 @@ # `use-propagate` | ||
### PropagationScope | ||
The `PropagationScope` component allows you to create isolated scopes for propagation. This is useful when you want to limit the scope of propagation to a specific part of your component tree. | ||
Here's an example of how to use `PropagationScope`: | ||
```tsx | ||
import { createPropagation } from 'use-propagate'; | ||
const { useListen, usePropagate, PropagationScope } = createPropagation<string>(); | ||
const ParentComponent = () => { | ||
return ( | ||
<div> | ||
<PropagationScope> | ||
<ChildComponent1 /> | ||
<ChildComponent2 /> | ||
</PropagationScope> | ||
<ChildComponent3 /> | ||
</div> | ||
); | ||
}; | ||
const ChildComponent1 = () => { | ||
const propagate = usePropagate(); | ||
return <button onClick={() => propagate('Hello')}>Say Hello</button>; | ||
}; | ||
const ChildComponent2 = () => { | ||
useListen((message) => { | ||
console.log('ChildComponent2 received:', message); | ||
}); | ||
return <div>Child 2</div>; | ||
}; | ||
const ChildComponent3 = () => { | ||
useListen((message) => { | ||
console.log('ChildComponent3 received:', message); | ||
}); | ||
return <div>Child 3</div>; | ||
}; | ||
``` | ||
In this example: | ||
- `ChildComponent1` and `ChildComponent2` are wrapped in a `PropagationScope`. | ||
- When the button in `ChildComponent1` is clicked, it will propagate the message "Hello". | ||
- `ChildComponent2` will receive this message and log it. | ||
- `ChildComponent3`, which is outside the `PropagationScope`, will not receive the message. | ||
Using `PropagationScope` allows you to create multiple isolated propagation contexts within your application. This can be particularly useful in larger applications where you want to avoid unintended propagation between different parts of your component tree. | ||
Note that `useListen` and `usePropagate` will use the nearest `PropagationScope` in the component tree. If there's no `PropagationScope` ancestor, they will use a default global scope. | ||
## API | ||
```ts | ||
export function createPropagation<T>(): { | ||
export function createPropagation<T>(options?: { allowPropagateDuringRender?: boolean }): { | ||
PropagationScope: React.ComponentType<{ children?: React.ReactNode | undefined }>; | ||
useListen: (callback: (value: T) => void) => void; | ||
usePropagate: (value: T) => void; | ||
usePropagate: () => (value: T) => void; | ||
}; | ||
@@ -64,0 +122,0 @@ ``` |
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
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
26820
174
165
15