Unverified Commit e537c5aa authored by Tasso Evangelista's avatar Tasso Evangelista
Browse files

Merge branch 'develop' of github.com:RocketChat/Rocket.Chat.Fuselage into feat/hocs

parents 82e54e4e f54a69d2
......@@ -66,18 +66,22 @@ yarn add @rocket.chat/fuselage-hooks
- [Parameters](#parameters-10)
- [usePosition](#useposition)
- [Parameters](#parameters-11)
- [useResizeObserver](#useresizeobserver)
- [usePrefersColorScheme](#usepreferscolorscheme)
- [Parameters](#parameters-12)
- [useSafely](#usesafely)
- [usePrefersReducedData](#useprefersreduceddata)
- [usePrefersReducedMotion](#useprefersreducedmotion)
- [useResizeObserver](#useresizeobserver)
- [Parameters](#parameters-13)
- [useStableArray](#usestablearray)
- [useSafely](#usesafely)
- [Parameters](#parameters-14)
- [useLocalStorage](#uselocalstorage)
- [useStableArray](#usestablearray)
- [Parameters](#parameters-15)
- [useSessionStorage](#usesessionstorage)
- [useLocalStorage](#uselocalstorage)
- [Parameters](#parameters-16)
- [useToggle](#usetoggle)
- [useSessionStorage](#usesessionstorage)
- [Parameters](#parameters-17)
- [useToggle](#usetoggle)
- [Parameters](#parameters-18)
- [useUniqueId](#useuniqueid)
### useAutoFocus
......@@ -226,6 +230,129 @@ Hook to deal and position an element using an anchor
Returns **PositionResult** The style containing top and left position
### usePrefersColorScheme
Hook to get the prefers-color-scheme value.
#### Parameters
- `scheme` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` if the prefers-color-scheme matches
### usePrefersReducedData
Hook to get the prefers-reduce-data value.
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` if the prefers-reduce-data is set reduce in the media queries that matches
### usePrefersReducedMotion
Hook to get the prefers-reduce-motion value.
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` if the prefers-reduce-motion is set reduce in the media queries that matches
### useResizeObserver
Hook to track dimension changes in a DOM element using the ResizeObserver API.
#### Parameters
- `options` **UseResizeObserverOptions** (optional, default `{}`)
- `options.debounceDelay`
Returns **{ref: RefObject<[Element](https://developer.mozilla.org/docs/Web/API/Element)>, contentBoxSize: ResizeObserverSize, borderBoxSize: ResizeObserverSize}** a triple containing the ref and the size information
### useSafely
Hook that wraps pairs of state and dispatcher to provide a new dispatcher
which can be safe and asynchronically called even after the component unmounted.
#### Parameters
- `pair` **\[S, (Dispatch<A> | DispatchWithoutAction)]** the state and dispatcher pair which will be patched
- `pair.0`
- `pair.1`
Returns **\[S, D]** a state value and safe dispatcher pair
### useStableArray
Hook to create an array with stable identity if its elements are equal.
#### Parameters
- `array` **T** the array
- `compare` **function (a: T, b: T): [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** the equality function that checks if two array elements are
equal (optional, default `Object.is`)
Returns **T** the passed array if the elements are NOT equals; the previously
stored array otherwise
### useLocalStorage
Hook to deal with localStorage
#### Parameters
- `key` the key associated to the value in the storage
- `initialValue` the value returned when the key is not found at the storage
Returns **any** a state and a setter function
### useSessionStorage
Hook to deal with sessionStorage
#### Parameters
- `key` the key associated to the value in the storage
- `initialValue` the value returned when the key is not found at the storage
Returns **any** a state and a setter function
### useToggle
Hook to create a toggleable boolean state.
#### Parameters
- `initialValue` **([boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) | function (): [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean))?** the initial value or the initial state generator function
Returns **\[[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), D]** a state boolean value and a state toggler function
### useUniqueId
Hook to keep a unique ID string.
Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the unique ID string
# <<<<<<< HEAD
### usePrefersColorScheme
Hook to get the prefers-color-scheme value.
#### Parameters
- `scheme` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` if the prefers-color-scheme matches
=======
### usePrefersReducedData
Hook to get the prefers-reduce-data value.
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` if the prefers-reduce-data is set reduce in the media queries that matches
### usePrefersReducedMotion
Hook to get the prefers-reduce-motion value.
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` if the prefers-reduce-motion is set reduce in the media queries that matches
### useResizeObserver
Hook to track dimension changes in a DOM element using the ResizeObserver API.
......
......@@ -7,7 +7,7 @@
<b>Signature:</b>
```typescript
getPositionStyle: ({ placement, container, targetBoundaries, variantStore, target }: {
getPositionStyle: ({ placement, container, targetBoundaries, variantStore, target, }: {
placement: Placements;
target: DOMRect;
container: DOMRect;
......
......@@ -7,7 +7,7 @@
<b>Signature:</b>
```typescript
getTargetBoundaries: ({ referenceBox, target, margin }: {
getTargetBoundaries: ({ referenceBox, target, margin, }: {
referenceBox?: DOMRect;
target?: DOMRect;
margin?: number;
......
......@@ -7,7 +7,7 @@
<b>Signature:</b>
```typescript
getVariantBoundaries: ({ referenceBox, target }: {
getVariantBoundaries: ({ referenceBox, target, }: {
referenceBox?: DOMRect;
target?: DOMRect;
}) => VariantBoundaries | null
......
......@@ -34,6 +34,9 @@
| [useMergedRefs](./fuselage-hooks.usemergedrefs.md) | Hook to merge refs and callbacks refs into a single callback ref. Useful when your component need a internal ref while receiving a forwared ref. |
| [useMutableCallback](./fuselage-hooks.usemutablecallback.md) | Hook to create a stable callback from a mutable one. |
| [usePosition](./fuselage-hooks.useposition.md) | Hook to deal and position an element using an anchor |
| [usePrefersColorScheme](./fuselage-hooks.usepreferscolorscheme.md) | Hook to get the prefers-color-scheme value. |
| [usePrefersReducedData](./fuselage-hooks.useprefersreduceddata.md) | Hook to get the prefers-reduce-data value. |
| [usePrefersReducedMotion](./fuselage-hooks.useprefersreducedmotion.md) | Hook to get the prefers-reduce-motion value. |
| [useResizeObserver](./fuselage-hooks.useresizeobserver.md) | Hook to track dimension changes in a DOM element using the ResizeObserver API. |
| [useSafely](./fuselage-hooks.usesafely.md) | Hook that wraps pairs of state and dispatcher to provide a new dispatcher which can be safe and asynchronically called even after the component unmounted. |
| [useSessionStorage](./fuselage-hooks.usesessionstorage.md) | Hook to deal with sessionStorage |
......
......@@ -7,10 +7,13 @@
<b>Signature:</b>
```typescript
export declare function useDebouncedReducer<S, R extends ReducerWithoutAction<S>>(reducer: R, initialArg: S, init: undefined, delay: number): [ReducerStateWithoutAction<R>, DispatchWithoutAction & {
flush: () => void;
cancel: () => void;
}];
export declare function useDebouncedReducer<S, R extends ReducerWithoutAction<S>>(reducer: R, initialArg: S, init: undefined, delay: number): [
ReducerStateWithoutAction<R>,
DispatchWithoutAction & {
flush: () => void;
cancel: () => void;
}
];
```
## Parameters
......@@ -24,5 +27,5 @@ export declare function useDebouncedReducer<S, R extends ReducerWithoutAction<S>
<b>Returns:</b>
\[ReducerStateWithoutAction&lt;R&gt;, DispatchWithoutAction &amp; { flush: () =&gt; void; cancel: () =&gt; void; }\]
\[ ReducerStateWithoutAction&lt;R&gt;, DispatchWithoutAction &amp; { flush: () =&gt; void; cancel: () =&gt; void; } \]
......@@ -7,10 +7,13 @@
<b>Signature:</b>
```typescript
export declare function useDebouncedReducer<S, R extends ReducerWithoutAction<S>, I>(reducer: R, initialArg: I, init: (arg: I) => ReducerStateWithoutAction<R>, delay: number): [ReducerStateWithoutAction<R>, DispatchWithoutAction & {
flush: () => void;
cancel: () => void;
}];
export declare function useDebouncedReducer<S, R extends ReducerWithoutAction<S>, I>(reducer: R, initialArg: I, init: (arg: I) => ReducerStateWithoutAction<R>, delay: number): [
ReducerStateWithoutAction<R>,
DispatchWithoutAction & {
flush: () => void;
cancel: () => void;
}
];
```
## Parameters
......@@ -24,5 +27,5 @@ export declare function useDebouncedReducer<S, R extends ReducerWithoutAction<S>
<b>Returns:</b>
\[ReducerStateWithoutAction&lt;R&gt;, DispatchWithoutAction &amp; { flush: () =&gt; void; cancel: () =&gt; void; }\]
\[ ReducerStateWithoutAction&lt;R&gt;, DispatchWithoutAction &amp; { flush: () =&gt; void; cancel: () =&gt; void; } \]
......@@ -7,10 +7,13 @@
<b>Signature:</b>
```typescript
export declare function useDebouncedReducer<S, A, R extends Reducer<S, A>>(reducer: R, initialArg: S, init: undefined, delay: number): [ReducerState<R>, Dispatch<A> & {
flush: () => void;
cancel: () => void;
}];
export declare function useDebouncedReducer<S, A, R extends Reducer<S, A>>(reducer: R, initialArg: S, init: undefined, delay: number): [
ReducerState<R>,
Dispatch<A> & {
flush: () => void;
cancel: () => void;
}
];
```
## Parameters
......@@ -24,5 +27,5 @@ export declare function useDebouncedReducer<S, A, R extends Reducer<S, A>>(reduc
<b>Returns:</b>
\[ReducerState&lt;R&gt;, Dispatch&lt;A&gt; &amp; { flush: () =&gt; void; cancel: () =&gt; void; }\]
\[ ReducerState&lt;R&gt;, Dispatch&lt;A&gt; &amp; { flush: () =&gt; void; cancel: () =&gt; void; } \]
......@@ -9,10 +9,13 @@ Hook to create a state with a debounced setter function.
<b>Signature:</b>
```typescript
export declare function useDebouncedState<S>(initialValue: S | (() => S), delay: number): [S, Dispatch<SetStateAction<S>> & {
flush: () => void;
cancel: () => void;
}];
export declare function useDebouncedState<S>(initialValue: S | (() => S), delay: number): [
S,
Dispatch<SetStateAction<S>> & {
flush: () => void;
cancel: () => void;
}
];
```
## Parameters
......@@ -24,7 +27,7 @@ export declare function useDebouncedState<S>(initialValue: S | (() => S), delay:
<b>Returns:</b>
\[S, Dispatch&lt;SetStateAction&lt;S&gt;&gt; &amp; { flush: () =&gt; void; cancel: () =&gt; void; }\]
\[ S, Dispatch&lt;SetStateAction&lt;S&gt;&gt; &amp; { flush: () =&gt; void; cancel: () =&gt; void; } \]
a state and debounced setter function
......@@ -9,10 +9,13 @@ Hook to debounce the state dispatcher function returned by hooks like `useState(
<b>Signature:</b>
```typescript
export declare function useDebouncedUpdates<S>([state, dispatch]: [S, DispatchWithoutAction], delay: number): [S, DispatchWithoutAction & {
flush: () => void;
cancel: () => void;
}];
export declare function useDebouncedUpdates<S>([state, dispatch]: [S, DispatchWithoutAction], delay: number): [
S,
DispatchWithoutAction & {
flush: () => void;
cancel: () => void;
}
];
```
## Parameters
......@@ -24,7 +27,7 @@ export declare function useDebouncedUpdates<S>([state, dispatch]: [S, DispatchWi
<b>Returns:</b>
\[S, DispatchWithoutAction &amp; { flush: () =&gt; void; cancel: () =&gt; void; }\]
\[ S, DispatchWithoutAction &amp; { flush: () =&gt; void; cancel: () =&gt; void; } \]
a state value and debounced dispatcher pair
......@@ -7,10 +7,13 @@
<b>Signature:</b>
```typescript
export declare function useDebouncedUpdates<S, A>([state, dispatch]: [S, Dispatch<A>], delay: number): [S, Dispatch<A> & {
flush: () => void;
cancel: () => void;
}];
export declare function useDebouncedUpdates<S, A>([state, dispatch]: [S, Dispatch<A>], delay: number): [
S,
Dispatch<A> & {
flush: () => void;
cancel: () => void;
}
];
```
## Parameters
......@@ -22,5 +25,5 @@ export declare function useDebouncedUpdates<S, A>([state, dispatch]: [S, Dispatc
<b>Returns:</b>
\[S, Dispatch&lt;A&gt; &amp; { flush: () =&gt; void; cancel: () =&gt; void; }\]
\[ S, Dispatch&lt;A&gt; &amp; { flush: () =&gt; void; cancel: () =&gt; void; } \]
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [usePrefersColorScheme](./fuselage-hooks.usepreferscolorscheme.md)
## usePrefersColorScheme variable
Hook to get the prefers-color-scheme value.
<b>Signature:</b>
```typescript
usePrefersColorScheme: (scheme?: string) => boolean
```
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [usePrefersReducedData](./fuselage-hooks.useprefersreduceddata.md)
## usePrefersReducedData variable
Hook to get the prefers-reduce-data value.
<b>Signature:</b>
```typescript
usePrefersReducedData: () => boolean
```
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [usePrefersReducedMotion](./fuselage-hooks.useprefersreducedmotion.md)
## usePrefersReducedMotion variable
Hook to get the prefers-reduce-motion value.
<b>Signature:</b>
```typescript
usePrefersReducedMotion: () => boolean
```
......@@ -9,7 +9,7 @@ Hook to track dimension changes in a DOM element using the ResizeObserver API.
<b>Signature:</b>
```typescript
useResizeObserver: ({ debounceDelay }?: UseResizeObserverOptions) => {
useResizeObserver: ({ debounceDelay, }?: UseResizeObserverOptions) => {
ref: RefObject<Element>;
contentBoxSize: ResizeObserverSize;
borderBoxSize: ResizeObserverSize;
......
......@@ -9,5 +9,5 @@ Hook that wraps pairs of state and dispatcher to provide a new dispatcher which
<b>Signature:</b>
```typescript
useSafely: <S, A, D extends DispatchWithoutAction | Dispatch<A>>([state, dispatcher]: [S, DispatchWithoutAction | Dispatch<A>]) => [S, D]
useSafely: <S, A, D extends DispatchWithoutAction | Dispatch<A>>([state, dispatcher,]: [S, DispatchWithoutAction | Dispatch<A>]) => [S, D]
```
......@@ -9,7 +9,9 @@ class MediaQueryListMock implements MediaQueryList {
changeEventListeners: Set<EventListener>;
constructor(media: string) {
_matchString: string;
constructor(media: string, matchString?: string) {
this._media = media;
this._onchange = null;
this.changeEventListeners = new Set([
......@@ -17,6 +19,7 @@ class MediaQueryListMock implements MediaQueryList {
this._onchange && this._onchange.call(this, ev);
},
]);
this._matchString = matchString;
}
get matches(): boolean {
......@@ -32,7 +35,7 @@ class MediaQueryListMock implements MediaQueryList {
);
}
return false;
return this._matchString && this._matchString === this._media;
}
get media(): string {
......@@ -88,7 +91,7 @@ class MediaQueryListMock implements MediaQueryList {
}
}
const matchMediaMock = (media: string): MediaQueryList =>
new MediaQueryListMock(media);
const matchMediaMock = (media: string, matchString?: string): MediaQueryList =>
new MediaQueryListMock(media, matchString);
export default matchMediaMock;
......@@ -12,6 +12,9 @@ export * from './useMediaQuery';
export * from './useMergedRefs';
export * from './useMutableCallback';
export * from './usePosition';
export * from './usePrefersColorScheme';
export * from './usePrefersReducedData';
export * from './usePrefersReducedMotion';
export * from './useResizeObserver';
export * from './useSafely';
export * from './useStableArray';
......
/**
* @jest-environment node
*/
import { FunctionComponent, createElement, StrictMode } from 'react';
import { renderToString } from 'react-dom/server';
import { usePrefersColorScheme } from '.';
describe('usePrefersColorScheme hook on server', () => {
it('should return false without matchMedia mocked', () => {
let matches: boolean;
const TestComponent: FunctionComponent = () => {
matches = usePrefersColorScheme();
return null;
};
renderToString(createElement(StrictMode, {}, createElement(TestComponent)));
expect(matches).toBe(false);
});
it('should return false with matchMedia mocked', () => {
let matches: boolean;
const TestComponent: FunctionComponent = () => {
matches = usePrefersColorScheme();
return null;
};
renderToString(createElement(StrictMode, {}, createElement(TestComponent)));
expect(matches).toBe(false);
});
});
import { createElement, FunctionComponent, StrictMode } from 'react';
import { render } from 'react-dom';
import { act } from 'react-dom/test-utils';
import { usePrefersColorScheme } from '.';
import matchMediaMock from './__mocks__/matchMedia';
describe('usePrefersColorScheme hook', () => {
let container: HTMLDivElement;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
container.remove();
container = null;
});
it('should return false on the initial call', () => {
let matches: boolean;
const TestComponent: FunctionComponent = () => {
matches = usePrefersColorScheme();
return null;
};
act(() => {
render(
createElement(StrictMode, {}, createElement(TestComponent)),
container
);
});
expect(matches).toBe(false);
});
it('should return true with matchMedia mocked and anything set', () => {
window.matchMedia = jest.fn((media) =>
matchMediaMock(media, '(prefers-color-scheme: light)')
);
let matches: boolean;
const TestComponent: FunctionComponent = () => {
matches = usePrefersColorScheme();
return null;
};
act(() => {
render(
createElement(StrictMode, {}, createElement(TestComponent)),
document.createElement('div')
);
});
expect(matches).toBe(true);
});
it('should return true with matchMedia mocked and light scheme set', () => {
window.matchMedia = jest.fn((media) =>
matchMediaMock(media, '(prefers-color-scheme: light)')
);
let matches: boolean;
const TestComponent: FunctionComponent = () => {
matches = usePrefersColorScheme('light');
return null;
};
act(() => {
render(
createElement(StrictMode, {}, createElement(TestComponent)),
document.createElement('div')
);
});
expect(matches).toBe(true);
});
it('should return true with matchMedia mocked and dark scheme set', () => {
window.matchMedia = jest.fn((media) =>
matchMediaMock(media, '(prefers-color-scheme: dark)')
);
let matches: boolean;
const TestComponent: FunctionComponent = () => {
matches = usePrefersColorScheme('dark');
return null;
};