Unverified Commit 496af5da authored by Tasso Evangelista's avatar Tasso Evangelista Committed by GitHub

Merge branch 'develop' into fix/tags

parents 6935a792 661398df
......@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [0.13.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.12.0...v0.13.0) (2020-07-14)
### Features
* usePosition ([#259](https://github.com/RocketChat/Rocket.Chat.Fuselage/issues/259)) ([b395d8c](https://github.com/RocketChat/Rocket.Chat.Fuselage/commit/b395d8c2e619d2ba26c5cfbee77275d0fbf9526a))
# [0.12.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.11.0...v0.12.0) (2020-07-14)
### Bug Fixes
* fuselage-hooks bundling ([#258](https://github.com/RocketChat/Rocket.Chat.Fuselage/issues/258)) ([8539ccf](https://github.com/RocketChat/Rocket.Chat.Fuselage/commit/8539ccf878e6923eb42735298e05dc16435d90ce))
* Options Styles ([#260](https://github.com/RocketChat/Rocket.Chat.Fuselage/issues/260)) ([410387e](https://github.com/RocketChat/Rocket.Chat.Fuselage/commit/410387eb6a049e68f6f6f7391a7e0919c0bdf2ec))
### Features
* Margins not only for Box ([#256](https://github.com/RocketChat/Rocket.Chat.Fuselage/issues/256)) ([94e71a8](https://github.com/RocketChat/Rocket.Chat.Fuselage/commit/94e71a80eb37d5145c1d1b2f532d23a782fee07b))
# [0.11.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.10.0...v0.11.0) (2020-07-11)
......
{
"version": "0.11.0",
"version": "0.13.0",
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [
......
......@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [0.13.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.12.0...v0.13.0) (2020-07-14)
**Note:** Version bump only for package @rocket.chat/css-in-js
# [0.12.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.11.0...v0.12.0) (2020-07-14)
**Note:** Version bump only for package @rocket.chat/css-in-js
# [0.11.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.10.0...v0.11.0) (2020-07-11)
**Note:** Version bump only for package @rocket.chat/css-in-js
......
{
"name": "@rocket.chat/css-in-js",
"version": "0.11.0",
"version": "0.13.0",
"description": "Toolset to transpile and use CSS on runtime",
"homepage": "https://rocket.chat/Rocket.Chat.Fuselage",
"author": {
......
......@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [0.13.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.12.0...v0.13.0) (2020-07-14)
### Features
* usePosition ([#259](https://github.com/RocketChat/Rocket.Chat.Fuselage/issues/259)) ([b395d8c](https://github.com/RocketChat/Rocket.Chat.Fuselage/commit/b395d8c2e619d2ba26c5cfbee77275d0fbf9526a))
# [0.12.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.11.0...v0.12.0) (2020-07-14)
### Bug Fixes
* fuselage-hooks bundling ([#258](https://github.com/RocketChat/Rocket.Chat.Fuselage/issues/258)) ([8539ccf](https://github.com/RocketChat/Rocket.Chat.Fuselage/commit/8539ccf878e6923eb42735298e05dc16435d90ce))
# [0.11.0](https://github.com/RocketChat/Rocket.Chat.Fuselage/compare/v0.10.0...v0.11.0) (2020-07-11)
......
......@@ -64,18 +64,20 @@ yarn add @rocket.chat/fuselage-hooks
- [Parameters](#parameters-9)
- [useMutableCallback](#usemutablecallback)
- [Parameters](#parameters-10)
- [useResizeObserver](#useresizeobserver)
- [usePosition](#useposition)
- [Parameters](#parameters-11)
- [useSafely](#usesafely)
- [useResizeObserver](#useresizeobserver)
- [Parameters](#parameters-12)
- [useStableArray](#usestablearray)
- [useSafely](#usesafely)
- [Parameters](#parameters-13)
- [useLocalStorage](#uselocalstorage)
- [useStableArray](#usestablearray)
- [Parameters](#parameters-14)
- [useSessionStorage](#usesessionstorage)
- [useLocalStorage](#uselocalstorage)
- [Parameters](#parameters-15)
- [useToggle](#usetoggle)
- [useSessionStorage](#usesessionstorage)
- [Parameters](#parameters-16)
- [useToggle](#usetoggle)
- [Parameters](#parameters-17)
- [useUniqueId](#useuniqueid)
### useAutoFocus
......@@ -211,6 +213,18 @@ Hook to create a stable callback from a mutable one.
Returns **function (...args: P): T** a stable callback
### usePosition
Hook to deal with sessionStorage
#### Parameters
- `reference` **[Element](https://developer.mozilla.org/docs/Web/API/Element)** the anchor
- `targetEl` **[Element](https://developer.mozilla.org/docs/Web/API/Element)** the element to be positioned
- `options` **PostionOptions** options to position
Returns **(PositionStyle | null)** a state and a setter function
### useResizeObserver
Hook to track dimension changes in a DOM element using the ResizeObserver API.
......
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [getPositionStyle](./fuselage-hooks.getpositionstyle.md)
## getPositionStyle variable
<b>Signature:</b>
```typescript
getPositionStyle: ({ placement, container, targetBoundaries, variantStore, target }: {
placement: Placements;
target: DOMRect;
container: DOMRect;
targetBoundaries: Boundaries;
variantStore: VariantBoundaries;
}) => PositionStyle | null
```
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [getTargetBoundaries](./fuselage-hooks.gettargetboundaries.md)
## getTargetBoundaries variable
<b>Signature:</b>
```typescript
getTargetBoundaries: ({ referenceBox, target, margin }: {
referenceBox: DOMRect;
target: DOMRect;
margin?: number;
}) => Boundaries
```
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [getVariantBoundaries](./fuselage-hooks.getvariantboundaries.md)
## getVariantBoundaries variable
<b>Signature:</b>
```typescript
getVariantBoundaries: ({ referenceBox, target }: {
referenceBox: DOMRect;
target: DOMRect;
}) => VariantBoundaries
```
......@@ -19,6 +19,9 @@
| Variable | Description |
| --- | --- |
| [getPositionStyle](./fuselage-hooks.getpositionstyle.md) | |
| [getTargetBoundaries](./fuselage-hooks.gettargetboundaries.md) | |
| [getVariantBoundaries](./fuselage-hooks.getvariantboundaries.md) | |
| [useAutoFocus](./fuselage-hooks.useautofocus.md) | Hook to automatically request focus for an DOM element. |
| [useBreakpoints](./fuselage-hooks.usebreakpoints.md) | Hook to catch which responsive design' breakpoints are active. |
| [useDebouncedCallback](./fuselage-hooks.usedebouncedcallback.md) | Hook to memoize a debounced version of a callback. |
......@@ -30,6 +33,7 @@
| [useMediaQuery](./fuselage-hooks.usemediaquery.md) | Hook to listen to a media query. |
| [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 with sessionStorage |
| [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 |
......@@ -37,3 +41,12 @@
| [useToggle](./fuselage-hooks.usetoggle.md) | Hook to create a toggleable boolean state. |
| [useUniqueId](./fuselage-hooks.useuniqueid.md) | Hook to keep a unique ID string. |
## Type Aliases
| Type Alias | Description |
| --- | --- |
| [Placements](./fuselage-hooks.placements.md) | |
| [PositionFlipOrder](./fuselage-hooks.positionfliporder.md) | |
| [Positions](./fuselage-hooks.positions.md) | |
| [PostionOptions](./fuselage-hooks.postionoptions.md) | |
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [Placements](./fuselage-hooks.placements.md)
## Placements type
<b>Signature:</b>
```typescript
export declare type Placements = 'top-start' | 'top-middle' | 'top-end' | 'bottom-start' | 'bottom-middle' | 'bottom-end' | 'left-start' | 'left-middle' | 'left-end' | 'right-start' | 'right-middle' | 'right-end' | Positions;
```
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [PositionFlipOrder](./fuselage-hooks.positionfliporder.md)
## PositionFlipOrder type
<b>Signature:</b>
```typescript
export declare type PositionFlipOrder = {
top: string;
right: string;
bottom: string;
left: string;
};
```
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [Positions](./fuselage-hooks.positions.md)
## Positions type
<b>Signature:</b>
```typescript
export declare type Positions = 'top' | 'left' | 'bottom' | 'right';
```
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) &gt; [PostionOptions](./fuselage-hooks.postionoptions.md)
## PostionOptions type
<b>Signature:</b>
```typescript
export declare type PostionOptions = {
margin?: number;
container?: Element;
placement?: Placements;
watch?: 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; [usePosition](./fuselage-hooks.useposition.md)
## usePosition variable
Hook to deal with sessionStorage
<b>Signature:</b>
```typescript
usePosition: (reference: Element, targetEl: Element, options: PostionOptions) => PositionStyle | null
```
{
"name": "@rocket.chat/fuselage-hooks",
"version": "0.11.0",
"version": "0.13.0",
"description": "React hooks for Fuselage, Rocket.Chat's design system and UI toolkit",
"homepage": "https://rocket.chat/Rocket.Chat.Fuselage",
"author": {
......@@ -77,7 +77,7 @@
"access": "public"
},
"dependencies": {
"@rocket.chat/fuselage-tokens": "^0.11.0",
"@rocket.chat/fuselage-tokens": "^0.13.0",
"use-subscription": "^1.4.1"
}
}
......@@ -11,6 +11,7 @@ export * from './useMediaQueries';
export * from './useMediaQuery';
export * from './useMergedRefs';
export * from './useMutableCallback';
export * from './usePosition';
export * from './useResizeObserver';
export * from './useSafely';
export * from './useStableArray';
......
......@@ -33,12 +33,22 @@ export const useMediaQueries = (...queries: string[]): boolean[] => {
},
subscribe: (cb: () => void) => {
mediaQueryLists.forEach((mediaQueryList) => {
mediaQueryList.addEventListener('change', cb);
if (typeof mediaQueryList.addEventListener === 'function') {
mediaQueryList.addEventListener('change', cb);
return;
}
mediaQueryList.addListener(cb);
});
return () => {
mediaQueryLists.forEach((mediaQueryList) => {
mediaQueryList.removeEventListener('change', cb);
if (typeof mediaQueryList.removeEventListener === 'function') {
mediaQueryList.removeEventListener('change', cb);
return;
}
mediaQueryList.removeListener(cb);
});
};
},
......
import { getPositionStyle, getTargetBoundaries, getVariantBoundaries } from './usePosition';
// TODO: add tests targeting the hook itself
const container = {
bottom: 1000,
height: 1000,
left: 0,
right: 1024,
top: 0,
width: 1024,
x: 0,
y: 0,
} as DOMRect;
const referenceBox = {
bottom: 300,
height: 100,
left: 0,
right: 100,
top: 200,
width: 100,
x: 0,
y: 200,
} as DOMRect;
const target = {
bottom: 50,
height: 50,
left: 0,
right: 50,
top: 0,
width: 50,
x: 0,
y: 0,
} as DOMRect;
describe('usePosition hook', () => {
describe('getTargetBoundaries', () => {
it('...', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
expect(targetBoundaries.t).toEqual(150);
expect(targetBoundaries.b).toEqual(300);
expect(targetBoundaries.r).toEqual(100);
expect(targetBoundaries.l).toEqual(-50);
});
});
describe('getPositionStyle function', () => {
it('returns a style for placement bottom-start', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'bottom-start', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('0px');
expect(style.top).toEqual('300px');
});
it('returns a style for placement bottom-start if the element height does not fit', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'bottom-start',
container: {
...container,
bottom: 300,
height: 300,
},
targetBoundaries,
variantStore,
target });
expect(style.left).toEqual('0px');
expect(style.top).toEqual('150px');
});
it('returns a style for placement bottom-middle', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'bottom-middle', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('25px');
expect(style.top).toEqual('300px');
});
it('returns a style for placement bottom-middle if the element height does not fit', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'bottom-middle',
container: {
...container,
bottom: 300,
height: 300,
},
targetBoundaries,
variantStore,
target });
expect(style.left).toEqual('25px');
expect(style.top).toEqual('150px');
});
it('returns a style for placement bottom-end', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'bottom-end', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('50px');
expect(style.top).toEqual('300px');
});
it('returns a style for placement bottom-end if the element height does not fit', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'bottom-end',
container: {
...container,
bottom: 300,
height: 300,
},
targetBoundaries,
variantStore,
target });
expect(style.left).toEqual('50px');
expect(style.top).toEqual('150px');
});
it('returns a style for placement top-start', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'top-start', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('0px');
expect(style.top).toEqual('150px');
});
it('returns a style for placement top-start if the element height does not fit', () => {
const box = { ...referenceBox, top: 10, y: 10, bottom: 110 };
const targetBoundaries = getTargetBoundaries({ referenceBox: box, target });
const variantStore = getVariantBoundaries({ referenceBox: box, target });
const style = getPositionStyle({ placement: 'top-start', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('0px');
expect(style.top).toEqual('110px');
});
it('returns a style for placement top-middle', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'top-middle', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('25px');
expect(style.top).toEqual('150px');
});
it('returns a style for placement top-middle if the element height does not fit', () => {
const box = { ...referenceBox, top: 10, y: 10, bottom: 110 };
const targetBoundaries = getTargetBoundaries({ referenceBox: box, target });
const variantStore = getVariantBoundaries({ referenceBox: box, target });
const style = getPositionStyle({ placement: 'top-middle', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('25px');
expect(style.top).toEqual('110px');
});
it('returns a style for placement top-end', () => {
const targetBoundaries = getTargetBoundaries({ referenceBox, target });
const variantStore = getVariantBoundaries({ referenceBox, target });
const style = getPositionStyle({ placement: 'top-end', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('50px');
expect(style.top).toEqual('150px');
});
it('returns a style for placement top-end if the element height does not fit', () => {
const box = { ...referenceBox, top: 10, y: 10, bottom: 110 };
const targetBoundaries = getTargetBoundaries({ referenceBox: box, target });
const variantStore = getVariantBoundaries({ referenceBox: box, target });
const style = getPositionStyle({ placement: 'top-end', container, targetBoundaries, variantStore, target });
expect(style.left).toEqual('50px');
expect(style.top).toEqual('110px');
});
});
});
import { useEffect, RefObject, useCallback, useRef } from 'react';
import { useDebouncedState } from './useDebouncedState';
export type PositionOptions = {
margin?: number;
container?: Element;
placement?: Placements;
watch?: boolean;
};
export type PositionFlipOrder = {
top: string;
right: string;
bottom: string;
left: string;
};
type Boundaries = {
t: number,
b: number,
r: number,
l: number,
}
type VariantBoundaries = {
vm: number,
vs: number,
ve: number,
hs: number,
he: number,