Skip to content

Commit

Permalink
Backport 10.15 release line (#4265)
Browse files Browse the repository at this point in the history
* backport #4016

* backport #3996

* backport #4017

* backport #4019

* backport #4020

* backport #4026

* backport #4028
  • Loading branch information
JoviDeCroock committed Jan 24, 2024
1 parent f0144e6 commit 255d011
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 4 deletions.
11 changes: 11 additions & 0 deletions compat/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ declare namespace React {
export import Inputs = _hooks.Inputs;
export import PropRef = _hooks.PropRef;
export import Reducer = _hooks.Reducer;
export import Dispatch = _hooks.Dispatch;
export import Ref = _hooks.Ref;
export import StateUpdater = _hooks.StateUpdater;
export import useCallback = _hooks.useCallback;
Expand All @@ -49,6 +50,7 @@ declare namespace React {
): T;

// Preact Defaults
export import Context = preact.Context;
export import ContextType = preact.ContextType;
export import RefObject = preact.RefObject;
export import Component = preact.Component;
Expand Down Expand Up @@ -138,6 +140,10 @@ declare namespace React {
) => boolean
): C;

export interface RefAttributes<R> extends preact.Attributes {
ref?: preact.Ref<R> | undefined;
}

export interface ForwardFn<P = {}, T = any> {
(props: P, ref: ForwardedRef<T>): preact.ComponentChild;
displayName?: string;
Expand All @@ -147,6 +153,11 @@ declare namespace React {
current: T;
}

export interface ForwardRefExoticComponent<P>
extends preact.FunctionComponent<P> {
defaultProps?: Partial<P> | undefined;
}

export type ForwardedRef<T> =
| ((instance: T | null) => void)
| MutableRefObject<T | null>
Expand Down
11 changes: 10 additions & 1 deletion debug/src/debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ export function initDebug() {
let oldVnode = options.vnode;
let oldCatchError = options._catchError;
let oldRoot = options._root;
let oldRender = options._render;
let oldHook = options._hook;

const warnedComponents = !isWeakMapSupported
? null
: {
useEffect: new WeakMap(),
useLayoutEffect: new WeakMap(),
lazyPropTypes: new WeakMap()
};
};
const deprecations = [];

options._catchError = (error, vnode, oldVNode) => {
Expand Down Expand Up @@ -282,6 +284,13 @@ export function initDebug() {
if (oldBeforeDiff) oldBeforeDiff(internal, vnode);
};

options._render = vnode => {
if (oldRender) {
oldRender(vnode);
}
hooksAllowed = true;
};

options._hook = (internal, index, type) => {
if (!internal || !hooksAllowed) {
throw new Error('Hook can only be invoked from render methods.');
Expand Down
5 changes: 3 additions & 2 deletions hooks/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function useState<S = undefined>(): [
];

export type Reducer<S, A> = (prevState: S, action: A) => S;
export type Dispatch<A> = (action: A) => void;
/**
* An alternative to `useState`.
*
Expand All @@ -27,7 +28,7 @@ export type Reducer<S, A> = (prevState: S, action: A) => S;
export function useReducer<S, A>(
reducer: Reducer<S, A>,
initialState: S
): [S, (action: A) => void];
): [S, Dispatch<A>];

/**
* An alternative to `useState`.
Expand All @@ -43,7 +44,7 @@ export function useReducer<S, A, I>(
reducer: Reducer<S, A>,
initialArg: I,
init: (arg: I) => S
): [S, (action: A) => void];
): [S, Dispatch<A>];

/** @deprecated Use the `Ref` type instead. */
type PropRef<T> = MutableRef<T>;
Expand Down
1 change: 1 addition & 0 deletions hooks/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ options._render = internal => {
currentInternal.data.__hooks._pendingEffects.forEach(invokeCleanup);
currentInternal.data.__hooks._pendingEffects.forEach(invokeEffect);
currentInternal.data.__hooks._pendingEffects = [];
currentIndex = 0;
}
}
previousInternal = internal;
Expand Down
47 changes: 46 additions & 1 deletion hooks/test/browser/useEffect.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { act } from 'preact/test-utils';
import { act, teardown as teardownAct } from 'preact/test-utils';
import { createElement, render, Fragment, Component } from 'preact';
import { useEffect, useState, useRef } from 'preact/hooks';
import { setupScratch, teardown } from '../../../test/_util/helpers';
Expand Down Expand Up @@ -371,6 +371,51 @@ describe('useEffect', () => {
);
});

it('hooks should be called in right order', async () => {
teardownAct();

let increment;

const Counter = () => {
const [count, setCount] = useState(0);
useState('binggo!!');
const renderRoot = useRef();
useEffect(() => {
const div = renderRoot.current;
render(<Dummy />, div);
}, [count]);

increment = () => {
setCount(x => x + 1);
return Promise.resolve().then(() => setCount(x => x + 1));
};

return (
<div>
<div>Count: {count}</div>
<div ref={renderRoot} />
</div>
);
};

const Dummy = () => {
useState();
return <div>dummy</div>;
};

render(<Counter />, scratch);

expect(scratch.innerHTML).to.equal(
'<div><div>Count: 0</div><div></div></div>'
);
/** Using the act function will affect the timing of the useEffect */
await increment();

expect(scratch.innerHTML).to.equal(
'<div><div>Count: 2</div><div><div>dummy</div></div></div>'
);
});

it('handles errors correctly', () => {
class ErrorBoundary extends Component {
constructor(props) {
Expand Down
33 changes: 33 additions & 0 deletions src/jsx.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,9 @@ export namespace JSXInternal {
WheelEvent
>;

export type TargetedPictureInPictureEvent<Target extends EventTarget> =
TargetedEvent<Target, PictureInPictureEvent>;

export interface EventHandler<E extends TargetedEvent> {
(this: void, event: E): void;
}
Expand Down Expand Up @@ -1114,6 +1117,8 @@ export namespace JSXInternal {
export type WheelEventHandler<Target extends EventTarget> = EventHandler<
TargetedWheelEvent<Target>
>;
export type PictureInPictureEventHandler<Target extends EventTarget> =
EventHandler<TargetedPictureInPictureEvent<Target>>;

export interface DOMAttributes<Target extends EventTarget>
extends PreactDOMAttributes {
Expand Down Expand Up @@ -1142,6 +1147,10 @@ export namespace JSXInternal {
// Details Events
onToggle?: GenericEventHandler<Target> | undefined;

// Dialog Events
onClose?: GenericEventHandler<Target> | undefined;
onCancel?: GenericEventHandler<Target> | undefined;

// Focus Events
onFocus?: FocusEventHandler<Target> | undefined;
onFocusCapture?: FocusEventHandler<Target> | undefined;
Expand Down Expand Up @@ -1315,8 +1324,22 @@ export namespace JSXInternal {
onAnimationIterationCapture?: AnimationEventHandler<Target> | undefined;

// Transition Events
onTransitionCancel?: TransitionEventHandler<Target>;
onTransitionCancelCapture?: TransitionEventHandler<Target>;
onTransitionEnd?: TransitionEventHandler<Target>;
onTransitionEndCapture?: TransitionEventHandler<Target>;
onTransitionRun?: TransitionEventHandler<Target>;
onTransitionRunCapture?: TransitionEventHandler<Target>;
onTransitionStart?: TransitionEventHandler<Target>;
onTransitionStartCapture?: TransitionEventHandler<Target>;

// PictureInPicture Events
onEnterPictureInPicture?: PictureInPictureEventHandler<Target>;
onEnterPictureInPictureCapture?: PictureInPictureEventHandler<Target>;
onLeavePictureInPicture?: PictureInPictureEventHandler<Target>;
onLeavePictureInPictureCapture?: PictureInPictureEventHandler<Target>;
onResize?: PictureInPictureEventHandler<Target>;
onResizeCapture?: PictureInPictureEventHandler<Target>;
}

// All the WAI-ARIA 1.1 attributes from https://www.w3.org/TR/wai-aria-1.1/
Expand All @@ -1332,6 +1355,16 @@ export namespace JSXInternal {
'aria-autocomplete'?: Signalish<
'none' | 'inline' | 'list' | 'both' | undefined
>;
/**
* Defines a string value that labels the current element, which is intended to be converted into Braille.
* @see aria-label.
*/
'aria-braillelabel'?: Signalish<string | undefined>;
/**
* Defines a human-readable, author-localized abbreviated description for the role of an element, which is intended to be converted into Braille.
* @see aria-roledescription.
*/
'aria-brailleroledescription'?: Signalish<string | undefined>;
/** Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user. */
'aria-busy'?: Signalish<Booleanish | undefined>;
/**
Expand Down

0 comments on commit 255d011

Please sign in to comment.