Favivon - Correção

This commit is contained in:
2026-05-30 19:59:39 -03:00
parent 76ddaa815d
commit d7dfd221f0
32859 changed files with 5459654 additions and 404 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022-2025 Poimandres
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+233
View File
@@ -0,0 +1,233 @@
# its-fine
[![Size](https://img.shields.io/bundlephobia/minzip/its-fine?label=gzip&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/package/its-fine)
[![Version](https://img.shields.io/npm/v/its-fine?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/its-fine)
[![Downloads](https://img.shields.io/npm/dt/its-fine.svg?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/its-fine)
[![Twitter](https://img.shields.io/twitter/follow/pmndrs?label=%40pmndrs&style=flat&colorA=000000&colorB=000000&logo=twitter&logoColor=000000)](https://twitter.com/pmndrs)
[![Discord](https://img.shields.io/discord/740090768164651008?style=flat&colorA=000000&colorB=000000&label=discord&logo=discord&logoColor=000000)](https://discord.gg/poimandres)
<p align="left">
<a id="cover" href="#cover">
<img src=".github/itsfine.jpg" alt="It's gonna be alright" />
</a>
</p>
A collection of escape hatches for React.
As such, you can go beyond React's component abstraction; components are self-aware and can tap into the [React Fiber](https://youtu.be/ZCuYPiUIONs) tree. This enables powerful abstractions that can modify or extend React behavior without explicitly taking reconciliation into your own hands.
## Table of Contents
- [Components](#components)
- [FiberProvider](#fiberprovider)
- [Hooks](#hooks)
- [useFiber](#useFiber)
- [useContainer](#useContainer)
- [useNearestChild](#useNearestChild)
- [useNearestParent](#useNearestParent)
- [useContextMap](#useContextMap)
- [useContextBridge](#useContextBridge)
- [Utils](#utils)
- [traverseFiber](#traverseFiber)
## Components
### FiberProvider
A react-internal `Fiber` provider. This component binds React children to the React Fiber tree. Call its-fine hooks within this.
> **Note**: pmndrs renderers like react-three-fiber implement this internally to make use of [`useContextBridge`](#usecontextbridge), so you would only need this when using hooks inside of `react-dom` or `react-native`.
```tsx
import * as ReactDOM from 'react-dom/client'
import { FiberProvider, useFiber } from 'its-fine'
function App() {
const fiber = useFiber()
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<FiberProvider>
<App />
</FiberProvider>,
)
```
## Hooks
Useful React hook abstractions for manipulating and querying from a component. These must be called within a [`FiberProvider`](#fiberprovider) component.
### useFiber
Returns the current react-internal `Fiber`. This is an implementation detail of [react-reconciler](https://github.com/facebook/react/tree/main/packages/react-reconciler).
```tsx
import * as React from 'react'
import { type Fiber, useFiber } from 'its-fine'
function Component() {
// Returns the current component's react-internal Fiber
const fiber: Fiber<null> | undefined = useFiber()
// function Component() {}
if (fiber) console.log(fiber.type)
}
```
### useContainer
Returns the current react-reconciler container info passed to `Reconciler.createContainer`.
In react-dom, a container will point to the root DOM element; in react-three-fiber, it will point to the root Zustand store.
```tsx
import * as React from 'react'
import { useContainer } from 'its-fine'
function Component() {
// Returns the current renderer's root container
const container: HTMLDivElement | undefined = useContainer<HTMLDivElement>()
// <div> (e.g. react-dom)
if (container) console.log(container)
}
```
### useNearestChild
Returns the nearest react-reconciler child instance or the node created from `Reconciler.createInstance`.
In react-dom, this would be a DOM element; in react-three-fiber this would be an `Instance` descriptor.
```tsx
import * as React from 'react'
import { useNearestChild } from 'its-fine'
function Component() {
// Returns a React Ref which points to the nearest child <div /> element.
// Omit the element type to match the nearest element of any kind
const childRef: React.MutableRefObject<HTMLDivElement | undefined> = useNearestChild<HTMLDivElement>('div')
// Access child Ref on mount
React.useEffect(() => {
// <div> (e.g. react-dom)
const child = childRef.current
if (child) console.log(child)
}, [])
// A child element, can live deep down another component
return <div />
}
```
### useNearestParent
Returns the nearest react-reconciler parent instance or the node created from `Reconciler.createInstance`.
In react-dom, this would be a DOM element; in react-three-fiber this would be an instance descriptor.
```tsx
import * as React from 'react'
import { useNearestParent } from 'its-fine'
function Component() {
// Returns a React Ref which points to the nearest parent <div /> element.
// Omit the element type to match the nearest element of any kind
const parentRef: React.MutableRefObject<HTMLDivElement | undefined> = useNearestParent<HTMLDivElement>('div')
// Access parent Ref on mount
React.useEffect(() => {
// <div> (e.g. react-dom)
const parent = parentRef.current
if (parent) console.log(parent)
}, [])
}
// A parent element wrapping Component, can live deep up another component
;<div>
<Component />
</div>
```
### useContextMap
Returns a map of all contexts and their values.
```tsx
import * as React from 'react'
import { useContextMap } from 'its-fine'
const SomeContext = React.createContext<string>(null!)
function Component() {
const contextMap = useContextMap()
return contextMap.get(SomeContext)
}
```
### useContextBridge
React Context currently cannot be shared across [React renderers](https://reactjs.org/docs/codebase-overview.html#renderers) but explicitly forwarded between providers (see [react#17275](https://github.com/facebook/react/issues/17275)). This hook returns a `ContextBridge` of live context providers to pierce Context across renderers.
Pass `ContextBridge` as a component to a secondary renderer to enable context-sharing within its children.
```tsx
import * as React from 'react'
// react-nil is a secondary renderer that is usually used for testing.
// This also includes Fabric, react-three-fiber, etc
import * as ReactNil from 'react-nil'
// react-dom is a primary renderer that works on top of a secondary renderer.
// This also includes react-native, react-pixi, etc.
import * as ReactDOM from 'react-dom/client'
import { type ContextBridge, useContextBridge, FiberProvider } from 'its-fine'
function Canvas(props: { children: React.ReactNode }) {
// Returns a bridged context provider that forwards context
const Bridge: ContextBridge = useContextBridge()
// Renders children with bridged context into a secondary renderer
ReactNil.render(<Bridge>{props.children}</Bridge>)
}
// A React Context whose provider lives in react-dom
const DOMContext = React.createContext<string>(null!)
// A component that reads from DOMContext
function Component() {
// "Hello from react-dom"
console.log(React.useContext(DOMContext))
}
// Renders into a primary renderer like react-dom or react-native,
// DOMContext wraps Canvas and is bridged into Component
ReactDOM.createRoot(document.getElementById('root')!).render(
<FiberProvider>
<DOMContext.Provider value="Hello from react-dom">
<Canvas>
<Component />
</Canvas>
</DOMContext.Provider>
</FiberProvider>,
)
```
## Utils
Additional exported utility functions for raw handling of Fibers.
### traverseFiber
Traverses up or down a `Fiber`, return `true` to stop and select a node.
```ts
import { type Fiber, traverseFiber } from 'its-fine'
// Traverses through the Fiber tree, returns the current node when `true` is passed via selector
const parentDiv: Fiber<HTMLDivElement> | undefined = traverseFiber<HTMLDivElement>(
// Input Fiber to traverse
fiber as Fiber,
// Whether to ascend and walk up the tree. Will walk down if `false`
true,
// A Fiber node selector, returns the first match when `true` is passed
(node: Fiber<HTMLDivElement | null>) => node.type === 'div',
)
```
+2
View File
@@ -0,0 +1,2 @@
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("react");function y(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const o=y(m),f=(()=>{var e,t;return typeof window!="undefined"&&(((e=window.document)==null?void 0:e.createElement)||((t=window.navigator)==null?void 0:t.product)==="ReactNative")})()?o.useLayoutEffect:o.useEffect;function i(e,t,n){if(!e)return;if(n(e)===!0)return e;let r=t?e.return:e.child;for(;r;){const u=i(r,t,n);if(u)return u;r=t?null:r.sibling}}function l(e){try{return Object.defineProperties(e,{_currentRenderer:{get(){return null},set(){}},_currentRenderer2:{get(){return null},set(){}}})}catch(t){return e}}const a=l(o.createContext(null));class d extends o.Component{render(){return o.createElement(a.Provider,{value:this._reactInternals},this.props.children)}}function s(){const e=o.useContext(a);if(e===null)throw new Error("its-fine: useFiber must be called within a <FiberProvider />!");const t=o.useId();return o.useMemo(()=>{for(const r of[e,e==null?void 0:e.alternate]){if(!r)continue;const u=i(r,!1,p=>{let c=p.memoizedState;for(;c;){if(c.memoizedState===t)return!0;c=c.next}});if(u)return u}},[e,t])}function h(){const e=s(),t=o.useMemo(()=>i(e,!0,n=>{var r;return((r=n.stateNode)==null?void 0:r.containerInfo)!=null}),[e]);return t==null?void 0:t.stateNode.containerInfo}function v(e){const t=s(),n=o.useRef(void 0);return f(()=>{var r;n.current=(r=i(t,!1,u=>typeof u.type=="string"&&(e===void 0||u.type===e)))==null?void 0:r.stateNode},[t]),n}function C(e){const t=s(),n=o.useRef(void 0);return f(()=>{var r;n.current=(r=i(t,!0,u=>typeof u.type=="string"&&(e===void 0||u.type===e)))==null?void 0:r.stateNode},[t]),n}const w=Symbol.for("react.context"),g=e=>e!==null&&typeof e=="object"&&"$$typeof"in e&&e.$$typeof===w;function b(){const e=s(),[t]=o.useState(()=>new Map);t.clear();let n=e;for(;n;){const r=n.type;g(r)&&r!==a&&!t.has(r)&&t.set(r,o.use(l(r))),n=n.return}return t}function x(){const e=b();return o.useMemo(()=>Array.from(e.keys()).reduce((t,n)=>r=>o.createElement(t,null,o.createElement(n.Provider,{...r,value:e.get(n)})),t=>o.createElement(d,{...t})),[e])}exports.FiberProvider=d;exports.traverseFiber=i;exports.useContainer=h;exports.useContextBridge=x;exports.useContextMap=b;exports.useFiber=s;exports.useNearestChild=v;exports.useNearestParent=C;
//# sourceMappingURL=index.cjs.map
+1
View File
File diff suppressed because one or more lines are too long
+82
View File
@@ -0,0 +1,82 @@
import * as React from 'react';
import type ReactReconciler from 'react-reconciler';
/**
* Represents a react-internal Fiber node.
*/
export type Fiber<T = any> = Omit<ReactReconciler.Fiber, 'stateNode'> & {
stateNode: T;
};
/**
* Represents a {@link Fiber} node selector for traversal.
*/
export type FiberSelector<T = any> = (
/** The current {@link Fiber} node. */
node: Fiber<T | null>) => boolean | void;
/**
* Traverses up or down a {@link Fiber}, return `true` to stop and select a node.
*/
export declare function traverseFiber<T = any>(
/** Input {@link Fiber} to traverse. */
fiber: Fiber | undefined,
/** Whether to ascend and walk up the tree. Will walk down if `false`. */
ascending: boolean,
/** A {@link Fiber} node selector, returns the first match when `true` is passed. */
selector: FiberSelector<T>): Fiber<T> | undefined;
/**
* A react-internal {@link Fiber} provider. This component binds React children to the React Fiber tree. Call its-fine hooks within this.
*/
export declare class FiberProvider extends React.Component<{
children?: React.ReactNode;
}> {
private _reactInternals;
render(): React.JSX.Element;
}
/**
* Returns the current react-internal {@link Fiber}. This is an implementation detail of [react-reconciler](https://github.com/facebook/react/tree/main/packages/react-reconciler).
*/
export declare function useFiber(): Fiber<null> | undefined;
/**
* Represents a react-reconciler container instance.
*/
export interface ContainerInstance<T = any> {
containerInfo: T;
}
/**
* Returns the current react-reconciler container info passed to {@link ReactReconciler.Reconciler.createContainer}.
*
* In react-dom, a container will point to the root DOM element; in react-three-fiber, it will point to the root Zustand store.
*/
export declare function useContainer<T = any>(): T | undefined;
/**
* Returns the nearest react-reconciler child instance or the node created from {@link ReactReconciler.HostConfig.createInstance}.
*
* In react-dom, this would be a DOM element; in react-three-fiber this would be an instance descriptor.
*/
export declare function useNearestChild<T = any>(
/** An optional element type to filter to. */
type?: keyof React.JSX.IntrinsicElements): React.RefObject<T | undefined>;
/**
* Returns the nearest react-reconciler parent instance or the node created from {@link ReactReconciler.HostConfig.createInstance}.
*
* In react-dom, this would be a DOM element; in react-three-fiber this would be an instance descriptor.
*/
export declare function useNearestParent<T = any>(
/** An optional element type to filter to. */
type?: keyof React.JSX.IntrinsicElements): React.RefObject<T | undefined>;
export type ContextMap = Map<React.Context<any>, any> & {
get<T>(context: React.Context<T>): T | undefined;
};
/**
* Returns a map of all contexts and their values.
*/
export declare function useContextMap(): ContextMap;
/**
* Represents a react-context bridge provider component.
*/
export type ContextBridge = React.FC<React.PropsWithChildren<{}>>;
/**
* React Context currently cannot be shared across [React renderers](https://reactjs.org/docs/codebase-overview.html#renderers) but explicitly forwarded between providers (see [react#17275](https://github.com/facebook/react/issues/17275)). This hook returns a {@link ContextBridge} of live context providers to pierce Context across renderers.
*
* Pass {@link ContextBridge} as a component to a secondary renderer to enable context-sharing within its children.
*/
export declare function useContextBridge(): ContextBridge;
+125
View File
@@ -0,0 +1,125 @@
import * as o from "react";
const f = /* @__PURE__ */ (() => {
var e, t;
return typeof window != "undefined" && (((e = window.document) == null ? void 0 : e.createElement) || ((t = window.navigator) == null ? void 0 : t.product) === "ReactNative");
})() ? o.useLayoutEffect : o.useEffect;
function i(e, t, r) {
if (!e) return;
if (r(e) === !0) return e;
let n = t ? e.return : e.child;
for (; n; ) {
const u = i(n, t, r);
if (u) return u;
n = t ? null : n.sibling;
}
}
function l(e) {
try {
return Object.defineProperties(e, {
_currentRenderer: {
get() {
return null;
},
set() {
}
},
_currentRenderer2: {
get() {
return null;
},
set() {
}
}
});
} catch (t) {
return e;
}
}
const a = /* @__PURE__ */ l(/* @__PURE__ */ o.createContext(null));
class m extends o.Component {
render() {
return /* @__PURE__ */ o.createElement(a.Provider, { value: this._reactInternals }, this.props.children);
}
}
function c() {
const e = o.useContext(a);
if (e === null) throw new Error("its-fine: useFiber must be called within a <FiberProvider />!");
const t = o.useId();
return o.useMemo(() => {
for (const n of [e, e == null ? void 0 : e.alternate]) {
if (!n) continue;
const u = i(n, !1, (d) => {
let s = d.memoizedState;
for (; s; ) {
if (s.memoizedState === t) return !0;
s = s.next;
}
});
if (u) return u;
}
}, [e, t]);
}
function w() {
const e = c(), t = o.useMemo(
() => i(e, !0, (r) => {
var n;
return ((n = r.stateNode) == null ? void 0 : n.containerInfo) != null;
}),
[e]
);
return t == null ? void 0 : t.stateNode.containerInfo;
}
function v(e) {
const t = c(), r = o.useRef(void 0);
return f(() => {
var n;
r.current = (n = i(
t,
!1,
(u) => typeof u.type == "string" && (e === void 0 || u.type === e)
)) == null ? void 0 : n.stateNode;
}, [t]), r;
}
function y(e) {
const t = c(), r = o.useRef(void 0);
return f(() => {
var n;
r.current = (n = i(
t,
!0,
(u) => typeof u.type == "string" && (e === void 0 || u.type === e)
)) == null ? void 0 : n.stateNode;
}, [t]), r;
}
const p = Symbol.for("react.context"), b = (e) => e !== null && typeof e == "object" && "$$typeof" in e && e.$$typeof === p;
function h() {
const e = c(), [t] = o.useState(() => /* @__PURE__ */ new Map());
t.clear();
let r = e;
for (; r; ) {
const n = r.type;
b(n) && n !== a && !t.has(n) && t.set(n, o.use(l(n))), r = r.return;
}
return t;
}
function x() {
const e = h();
return o.useMemo(
() => Array.from(e.keys()).reduce(
(t, r) => (n) => /* @__PURE__ */ o.createElement(t, null, /* @__PURE__ */ o.createElement(r.Provider, { ...n, value: e.get(r) })),
(t) => /* @__PURE__ */ o.createElement(m, { ...t })
),
[e]
);
}
export {
m as FiberProvider,
i as traverseFiber,
w as useContainer,
x as useContextBridge,
h as useContextMap,
c as useFiber,
v as useNearestChild,
y as useNearestParent
};
//# sourceMappingURL=index.js.map
+1
View File
File diff suppressed because one or more lines are too long
+50
View File
@@ -0,0 +1,50 @@
{
"name": "its-fine",
"version": "2.0.0",
"description": "A collection of escape hatches for React.",
"keywords": [
"react",
"fiber",
"internal",
"reconciler",
"hooks"
],
"author": "Cody Bennett (https://github.com/codyjasonbennett)",
"maintainers": [
"Paul Henschel (https://github.com/drcmda)"
],
"homepage": "https://github.com/pmndrs/its-fine",
"repository": "https://github.com/pmndrs/its-fine",
"license": "MIT",
"files": [
"dist/*"
],
"type": "module",
"types": "./dist/index.d.ts",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"react-native": "./dist/index.js",
"sideEffects": false,
"devDependencies": {
"@types/node": "^22.13.4",
"@types/react": "^19.0.0",
"@types/react-test-renderer": "^19.0.0",
"react": "^19.0.0",
"react-nil": "^2.0.0",
"react-test-renderer": "^19.0.0",
"rimraf": "^6.0.1",
"typescript": "^5.7.3",
"vite": "^6.1.0",
"vitest": "^3.0.6"
},
"dependencies": {
"@types/react-reconciler": "^0.28.9"
},
"peerDependencies": {
"react": "^19.0.0"
},
"scripts": {
"build": "rimraf dist && vite build && tsc",
"test": "vitest run"
}
}