polpo 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/theme.ts +2 -2
- package/.turbo/turbo-build.log +0 -77
- package/.turbo/turbo-lint.log +1 -1
- package/README.md +2 -5
- package/dist/chunk-CFYQBHH5.js +3 -0
- package/dist/chunk-CFYQBHH5.js.map +1 -0
- package/dist/chunk-MAWW6AA7.js +3 -0
- package/dist/chunk-MAWW6AA7.js.map +1 -0
- package/dist/get-modal-position-drle0OjP.d.cts +49 -0
- package/dist/get-modal-position-drle0OjP.d.ts +49 -0
- package/dist/helpers.cjs +1 -1
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts +9 -2
- package/dist/helpers.d.ts +9 -2
- package/dist/helpers.js +1 -1
- package/dist/hooks.cjs +1 -1
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +59 -21
- package/dist/hooks.d.ts +59 -21
- package/dist/hooks.js +1 -1
- package/dist/ui.cjs +601 -389
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.d.cts +97 -77
- package/dist/ui.d.ts +97 -77
- package/dist/ui.js +585 -373
- package/dist/ui.js.map +1 -1
- package/dist/use-modal-in-container-DiNW1PE_.d.cts +34 -0
- package/dist/use-modal-in-container-neGo-kMk.d.ts +34 -0
- package/package.json +5 -5
- package/src/components/buttons/button/button.stories.tsx +4 -4
- package/src/components/buttons/button/button.style.ts +10 -5
- package/src/components/buttons/button/button.tsx +7 -19
- package/src/components/cards/flip-card/flip-card.tsx +1 -1
- package/src/components/cursor/cursor.stories.tsx +35 -0
- package/src/components/cursor/cursor.style.ts +73 -0
- package/src/components/cursor/cursor.tsx +49 -0
- package/src/components/cursor/index.ts +1 -0
- package/src/components/form/checkbox/checkbox.stories.tsx +51 -0
- package/src/components/form/checkbox/checkbox.style.ts +73 -37
- package/src/components/form/checkbox/checkbox.tsx +38 -4
- package/src/components/form/field/field.stories.tsx +5 -1
- package/src/components/form/field/field.style.ts +12 -0
- package/src/components/form/field/field.tsx +3 -1
- package/src/components/form/field/field.types.ts +6 -0
- package/src/components/form/input-color/input-color.style.ts +5 -4
- package/src/components/form/input-color/input-color.tsx +41 -44
- package/src/components/form/radio/radio.stories.tsx +29 -5
- package/src/components/form/radio/radio.style.ts +45 -24
- package/src/components/form/radio/radio.tsx +22 -3
- package/src/components/form/select/options.tsx +119 -67
- package/src/components/form/select/select.stories.tsx +103 -42
- package/src/components/form/select/select.style.ts +10 -92
- package/src/components/form/select/select.tsx +19 -42
- package/src/components/form/select/select.types.ts +4 -21
- package/src/components/form/slider/slider.style.ts +2 -0
- package/src/components/icon/icons/social.tsx +17 -1
- package/src/components/index.ts +1 -0
- package/src/components/infinity-scroll/infinity-scroll.tsx +1 -1
- package/src/components/line/line.stories.tsx +3 -4
- package/src/components/modals/action-modal/action-modal.stories.tsx +58 -39
- package/src/components/modals/action-modal/action-modal.style.ts +13 -25
- package/src/components/modals/action-modal/action-modal.tsx +68 -70
- package/src/components/modals/aside-modal/aside-modal.stories.tsx +11 -15
- package/src/components/modals/aside-modal/aside-modal.style.ts +17 -37
- package/src/components/modals/aside-modal/aside-modal.tsx +41 -43
- package/src/components/modals/confirmation-modal/confirmation-modal.stories.tsx +21 -9
- package/src/components/modals/index.ts +2 -0
- package/src/components/modals/menu/index.ts +1 -0
- package/src/components/modals/menu/menu.stories.tsx +69 -0
- package/src/components/modals/menu/menu.style.ts +62 -0
- package/src/components/modals/menu/menu.tsx +142 -0
- package/src/components/modals/modal/backdrop.tsx +70 -0
- package/src/components/modals/modal/index.ts +1 -0
- package/src/components/modals/modal/modal.stories.tsx +325 -0
- package/src/components/modals/modal/modal.style.ts +62 -2
- package/src/components/modals/modal/modal.tsx +82 -123
- package/src/components/modals/portal/index.ts +1 -0
- package/src/components/modals/portal/portal.tsx +18 -0
- package/src/components/tabs/tabs-list.tsx +13 -10
- package/src/components/tabs/tabs.style.ts +48 -43
- package/src/components/tag/tag.stories.tsx +11 -12
- package/src/components/tag/tag.style.ts +9 -4
- package/src/components/tag/tag.tsx +2 -12
- package/src/components/tooltips/tooltip/tooltip.stories.tsx +5 -2
- package/src/components/tooltips/tooltip/tooltip.style.ts +37 -6
- package/src/components/tooltips/tooltip/tooltip.tsx +33 -19
- package/src/components/typography/typography.stories.tsx +3 -1
- package/src/components/typography/typography.tsx +21 -0
- package/src/contexts/theme-context/theme.animations.ts +91 -2
- package/src/contexts/theme-context/theme.defaults.ts +1 -1
- package/src/core/http-client.ts +49 -47
- package/src/core/variants/color.ts +3 -30
- package/src/core/variants/radius.ts +12 -41
- package/src/core/variants/size.ts +8 -33
- package/src/helpers/get-modal-position-relative-to-screen.ts +86 -0
- package/src/helpers/get-modal-position.ts +173 -28
- package/src/helpers/index.ts +1 -0
- package/src/hooks/index.ts +9 -3
- package/src/hooks/use-click-outside.ts +32 -0
- package/src/hooks/use-cookie.ts +124 -0
- package/src/hooks/use-dimensions.ts +11 -14
- package/src/hooks/use-dom-container.ts +32 -0
- package/src/hooks/use-event-listener.ts +4 -4
- package/src/hooks/use-geolocation.ts +63 -0
- package/src/hooks/use-in-view.ts +9 -11
- package/src/hooks/use-intersection-observer.ts +19 -0
- package/src/hooks/use-modal-in-container.ts +60 -52
- package/src/hooks/use-modal-transition.ts +54 -0
- package/src/hooks/use-modal.ts +21 -0
- package/src/hooks/use-mouse-position.ts +55 -7
- package/src/hooks/use-resize-observer.ts +18 -0
- package/src/stories/GettingStarted.mdx +2 -6
- package/svg/Name=npm, Category=social.svg +3 -0
- package/tsconfig.json +1 -0
- package/vite.config.ts +1 -0
- package/.turbo/daemon/f5c5c8fb195b01d0-turbo.log.2024-05-26 +0 -0
- package/.turbo/turbo-build$colon$watch.log +0 -96
- package/.turbo/turbo-build-storybook.log +0 -0
- package/.turbo/turbo-lint$colon$fix.log +0 -2
- package/dist/chunk-M4KRSYE7.js +0 -3
- package/dist/chunk-M4KRSYE7.js.map +0 -1
- package/dist/chunk-U5XSMSKZ.js +0 -3
- package/dist/chunk-U5XSMSKZ.js.map +0 -1
- package/dist/get-modal-position-DPftPoU2.d.cts +0 -28
- package/dist/get-modal-position-DPftPoU2.d.ts +0 -28
- package/src/components/form/select/select-option.tsx +0 -84
- package/src/hooks/use-observer.ts +0 -18
- package/src/hooks/use-on-click-outside-ref.ts +0 -17
package/src/core/http-client.ts
CHANGED
|
@@ -1,47 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* import axios, { AxiosInstance } from 'axios';
|
|
3
|
+
*
|
|
4
|
+
* export class HttpClient {
|
|
5
|
+
* private _instance: AxiosInstance;
|
|
6
|
+
* private _token: string;
|
|
7
|
+
*
|
|
8
|
+
* public logout = () => localStorage.removeItem('token');
|
|
9
|
+
*
|
|
10
|
+
* constructor(baseURL: string) {
|
|
11
|
+
* this._token = localStorage.getItem('token') ?? '';
|
|
12
|
+
*
|
|
13
|
+
* this._instance = axios.create({
|
|
14
|
+
* baseURL: baseURL,
|
|
15
|
+
* headers: {
|
|
16
|
+
* 'Content-Type': 'application/json',
|
|
17
|
+
* },
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* this._instance.interceptors.request.use(req => {
|
|
21
|
+
* const token = this.token;
|
|
22
|
+
* token !== null && req.headers.setAuthorization(`Bearer ${token}`);
|
|
23
|
+
*
|
|
24
|
+
* return req;
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* this._instance.interceptors.response.use(
|
|
28
|
+
* response => Promise.resolve(response),
|
|
29
|
+
* error => {
|
|
30
|
+
* error.response.status === 401 && this.logout();
|
|
31
|
+
* Promise.reject(error);
|
|
32
|
+
* },
|
|
33
|
+
* );
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* public get instance(): AxiosInstance {
|
|
37
|
+
* return this._instance;
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* public get token() {
|
|
41
|
+
* return this._token;
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* public set token(token: string) {
|
|
45
|
+
* this._token = token;
|
|
46
|
+
* localStorage.setItem('token', token);
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
*/
|
|
@@ -1,36 +1,9 @@
|
|
|
1
|
-
import { useClassNames } from '@polpo/hooks';
|
|
2
|
-
|
|
3
1
|
export enum ColorVariants {
|
|
4
|
-
Primary = '
|
|
5
|
-
Secondary = '
|
|
6
|
-
Tertiary = '
|
|
2
|
+
Primary = 'primary',
|
|
3
|
+
Secondary = 'secondary',
|
|
4
|
+
Tertiary = 'tertiary',
|
|
7
5
|
Info = 'info',
|
|
8
6
|
Active = 'active',
|
|
9
7
|
Warning = 'warning',
|
|
10
8
|
Alert = 'alert',
|
|
11
9
|
}
|
|
12
|
-
|
|
13
|
-
const getColorVariantClassName = (size: `${ColorVariants}`) => {
|
|
14
|
-
return `${size}-color`;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const ColorClassNames: Record<keyof typeof ColorVariants, string> = {
|
|
18
|
-
Primary: getColorVariantClassName(ColorVariants.Primary),
|
|
19
|
-
Secondary: getColorVariantClassName(ColorVariants.Secondary),
|
|
20
|
-
Tertiary: getColorVariantClassName(ColorVariants.Tertiary),
|
|
21
|
-
Info: getColorVariantClassName(ColorVariants.Info),
|
|
22
|
-
Active: getColorVariantClassName(ColorVariants.Active),
|
|
23
|
-
Warning: getColorVariantClassName(ColorVariants.Warning),
|
|
24
|
-
Alert: getColorVariantClassName(ColorVariants.Alert),
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const useColorClassName = (size: `${ColorVariants}`) =>
|
|
28
|
-
useClassNames(
|
|
29
|
-
Object.entries(ColorVariants).reduce(
|
|
30
|
-
(object, [key, value]) => ({
|
|
31
|
-
...object,
|
|
32
|
-
[ColorClassNames[key as keyof typeof ColorVariants]]: size === value,
|
|
33
|
-
}),
|
|
34
|
-
{},
|
|
35
|
-
),
|
|
36
|
-
);
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { css } from 'styled-components';
|
|
2
2
|
|
|
3
|
-
import { useClassNames } from '@polpo/hooks';
|
|
4
|
-
|
|
5
3
|
export enum RadiusVariants {
|
|
6
4
|
None = 'none',
|
|
7
5
|
Small = 'small',
|
|
@@ -10,47 +8,20 @@ export enum RadiusVariants {
|
|
|
10
8
|
Full = 'full',
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const RadiusClassNames: Record<keyof typeof RadiusVariants, string> = {
|
|
18
|
-
None: getRadiusVariantClassName(RadiusVariants.None),
|
|
19
|
-
Small: getRadiusVariantClassName(RadiusVariants.Small),
|
|
20
|
-
Medium: getRadiusVariantClassName(RadiusVariants.Medium),
|
|
21
|
-
Large: getRadiusVariantClassName(RadiusVariants.Large),
|
|
22
|
-
Full: getRadiusVariantClassName(RadiusVariants.Full),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const useRadiusClassName = (size: `${RadiusVariants}`) =>
|
|
26
|
-
useClassNames(
|
|
27
|
-
Object.entries(RadiusVariants).reduce(
|
|
28
|
-
(object, [key, value]) => ({
|
|
29
|
-
...object,
|
|
30
|
-
[RadiusClassNames[key as keyof typeof RadiusVariants]]: size === value,
|
|
31
|
-
}),
|
|
32
|
-
{},
|
|
33
|
-
),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
export const RadiusStyles = css`
|
|
37
|
-
&.${RadiusClassNames.None} {
|
|
11
|
+
export const RadiusStyles: Record<RadiusVariants, ReturnType<typeof css>> = {
|
|
12
|
+
[RadiusVariants.None]: css`
|
|
38
13
|
border-radius: 0;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
&.${RadiusClassNames.Small} {
|
|
14
|
+
`,
|
|
15
|
+
[RadiusVariants.Small]: css`
|
|
42
16
|
border-radius: 0.5em;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
&.${RadiusClassNames.Medium} {
|
|
17
|
+
`,
|
|
18
|
+
[RadiusVariants.Medium]: css`
|
|
46
19
|
border-radius: 1em;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
&.${RadiusClassNames.Large} {
|
|
20
|
+
`,
|
|
21
|
+
[RadiusVariants.Large]: css`
|
|
50
22
|
border-radius: 1.5em;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
&.${RadiusClassNames.Full} {
|
|
23
|
+
`,
|
|
24
|
+
[RadiusVariants.Full]: css`
|
|
54
25
|
border-radius: 100em;
|
|
55
|
-
|
|
56
|
-
|
|
26
|
+
`,
|
|
27
|
+
};
|
|
@@ -1,44 +1,19 @@
|
|
|
1
1
|
import { css } from 'styled-components';
|
|
2
2
|
|
|
3
|
-
import { useClassNames } from '@polpo/hooks';
|
|
4
|
-
|
|
5
3
|
export enum SizeVariants {
|
|
6
4
|
Small = 'small',
|
|
7
5
|
Medium = 'medium',
|
|
8
6
|
Large = 'large',
|
|
9
7
|
}
|
|
10
8
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const SizeClassNames: Record<keyof typeof SizeVariants, string> = {
|
|
16
|
-
Small: getSizeVariantClassName(SizeVariants.Small),
|
|
17
|
-
Medium: getSizeVariantClassName(SizeVariants.Medium),
|
|
18
|
-
Large: getSizeVariantClassName(SizeVariants.Large),
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export const useSizeClassName = (size: `${SizeVariants}`) =>
|
|
22
|
-
useClassNames(
|
|
23
|
-
Object.entries(SizeVariants).reduce(
|
|
24
|
-
(object, [key, value]) => ({
|
|
25
|
-
...object,
|
|
26
|
-
[SizeClassNames[key as keyof typeof SizeVariants]]: size === value,
|
|
27
|
-
}),
|
|
28
|
-
{},
|
|
29
|
-
),
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
export const SizeStyles = css`
|
|
33
|
-
&.${SizeClassNames.Small} {
|
|
9
|
+
export const SizeStyles: Record<SizeVariants, ReturnType<typeof css>> = {
|
|
10
|
+
[SizeVariants.Small]: css`
|
|
34
11
|
font-size: ${props => props.theme.constants.typography.small.fontSize};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
&.${SizeClassNames.Medium} {
|
|
12
|
+
`,
|
|
13
|
+
[SizeVariants.Medium]: css`
|
|
38
14
|
font-size: ${props => props.theme.constants.typography.label.fontSize};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
&.${SizeClassNames.Large} {
|
|
15
|
+
`,
|
|
16
|
+
[SizeVariants.Large]: css`
|
|
42
17
|
font-size: ${props => props.theme.constants.typography.body.fontSize};
|
|
43
|
-
|
|
44
|
-
|
|
18
|
+
`,
|
|
19
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { PositionContainer } from './get-modal-position';
|
|
2
|
+
|
|
3
|
+
export type GetModalPositionRelativeToScreenParams = {
|
|
4
|
+
position: PositionContainer;
|
|
5
|
+
windowOffset: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const getModalPositionRelativeToScreen = ({
|
|
9
|
+
position,
|
|
10
|
+
windowOffset,
|
|
11
|
+
}: GetModalPositionRelativeToScreenParams): Record<string, string> => {
|
|
12
|
+
switch (position) {
|
|
13
|
+
case PositionContainer.CENTER:
|
|
14
|
+
return {
|
|
15
|
+
top: '50%',
|
|
16
|
+
left: '50%',
|
|
17
|
+
transform: 'translate(-50%, -50%)',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
case PositionContainer.TOP:
|
|
21
|
+
case PositionContainer.TOP_CENTER:
|
|
22
|
+
return {
|
|
23
|
+
top: `${windowOffset}px`,
|
|
24
|
+
left: '50%',
|
|
25
|
+
transform: 'translateX(-50%)',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
case PositionContainer.TOP_LEFT:
|
|
29
|
+
case PositionContainer.LEFT_TOP:
|
|
30
|
+
return {
|
|
31
|
+
top: `${windowOffset}px`,
|
|
32
|
+
left: `${windowOffset}px`,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
case PositionContainer.TOP_RIGHT:
|
|
36
|
+
case PositionContainer.RIGHT_TOP:
|
|
37
|
+
return {
|
|
38
|
+
top: `${windowOffset}px`,
|
|
39
|
+
right: `${windowOffset}px`,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
case PositionContainer.BOTTOM:
|
|
43
|
+
case PositionContainer.BOTTOM_CENTER:
|
|
44
|
+
return {
|
|
45
|
+
bottom: `${windowOffset}px`,
|
|
46
|
+
left: '50%',
|
|
47
|
+
transform: 'translateX(-50%)',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
case PositionContainer.LEFT_BOTTOM:
|
|
51
|
+
case PositionContainer.BOTTOM_LEFT:
|
|
52
|
+
return {
|
|
53
|
+
bottom: `${windowOffset}px`,
|
|
54
|
+
left: `${windowOffset}px`,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
case PositionContainer.RIGHT_BOTTOM:
|
|
58
|
+
case PositionContainer.BOTTOM_RIGHT:
|
|
59
|
+
return {
|
|
60
|
+
bottom: `${windowOffset}px`,
|
|
61
|
+
right: `${windowOffset}px`,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
case PositionContainer.LEFT:
|
|
65
|
+
case PositionContainer.LEFT_CENTER:
|
|
66
|
+
return {
|
|
67
|
+
top: '50%',
|
|
68
|
+
left: `${windowOffset}px`,
|
|
69
|
+
transform: 'translateY(-50%)',
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
case PositionContainer.RIGHT:
|
|
73
|
+
case PositionContainer.RIGHT_CENTER:
|
|
74
|
+
return {
|
|
75
|
+
top: '50%',
|
|
76
|
+
right: `${windowOffset}px`,
|
|
77
|
+
transform: 'translateY(-50%)',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
top: '50%',
|
|
83
|
+
left: '50%',
|
|
84
|
+
transform: 'translate(-50%, -50%)',
|
|
85
|
+
};
|
|
86
|
+
};
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
export enum
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
export enum PositionContainer {
|
|
2
|
+
CENTER = 'center',
|
|
3
|
+
TOP = 'top',
|
|
4
|
+
TOP_LEFT = 'top left',
|
|
5
|
+
TOP_RIGHT = 'top right',
|
|
6
|
+
TOP_CENTER = 'top center',
|
|
7
|
+
LEFT = 'left',
|
|
8
|
+
LEFT_TOP = 'left top',
|
|
9
|
+
LEFT_BOTTOM = 'left bottom',
|
|
10
|
+
LEFT_CENTER = 'left center',
|
|
11
|
+
RIGHT = 'right',
|
|
12
|
+
RIGHT_TOP = 'right top',
|
|
13
|
+
RIGHT_BOTTOM = 'right bottom',
|
|
14
|
+
RIGHT_CENTER = 'right center',
|
|
15
|
+
BOTTOM = 'bottom',
|
|
16
|
+
BOTTOM_LEFT = 'bottom left',
|
|
17
|
+
BOTTOM_RIGHT = 'bottom right',
|
|
18
|
+
BOTTOM_CENTER = 'bottom center',
|
|
6
19
|
}
|
|
7
20
|
|
|
8
21
|
export type PositionObject = {
|
|
@@ -14,53 +27,185 @@ export type PositionObject = {
|
|
|
14
27
|
h: number;
|
|
15
28
|
};
|
|
16
29
|
|
|
30
|
+
export type ModalPosition = {
|
|
31
|
+
left: number;
|
|
32
|
+
top: number;
|
|
33
|
+
};
|
|
34
|
+
|
|
17
35
|
export type GetModalPositionParams = {
|
|
18
36
|
c: PositionObject;
|
|
19
37
|
m: PositionObject;
|
|
20
38
|
offset: number;
|
|
21
|
-
|
|
22
|
-
position?: `${POSITION}`;
|
|
23
|
-
distancePercentage?: number;
|
|
39
|
+
position: PositionContainer;
|
|
24
40
|
};
|
|
25
41
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
/*
|
|
43
|
+
* @description Calculates the position of the modal relative to the container
|
|
44
|
+
*
|
|
45
|
+
* @param c - The container's position object
|
|
46
|
+
* @param m - The modal's position object
|
|
47
|
+
* @param offset - The offset between the container and the modal
|
|
48
|
+
* @param position - The position of the modal
|
|
49
|
+
*
|
|
50
|
+
* -----------------------------------------------------------------------------
|
|
51
|
+
* @returns The position of the modal relative to the container
|
|
52
|
+
*/
|
|
53
|
+
export const getModalPosition = ({ c, m, offset, position }: GetModalPositionParams): ModalPosition => {
|
|
34
54
|
// Default bottom
|
|
35
55
|
let top = c.y + c.h + offset;
|
|
36
|
-
let left = c.x - (m.w - c.w);
|
|
56
|
+
let left = c.x - (m.w - c.w) * (50 / 100);
|
|
37
57
|
|
|
38
58
|
switch (position) {
|
|
39
|
-
case
|
|
59
|
+
case PositionContainer.TOP:
|
|
60
|
+
case PositionContainer.TOP_CENTER:
|
|
40
61
|
top = c.y - m.h - offset;
|
|
41
|
-
left = c.x - (m.w - c.w)
|
|
62
|
+
left = c.x - (m.w - c.w) / 2;
|
|
63
|
+
|
|
64
|
+
break;
|
|
65
|
+
case PositionContainer.TOP_LEFT:
|
|
66
|
+
top = c.y - m.h - offset;
|
|
67
|
+
left = c.x - m.w + c.w;
|
|
68
|
+
|
|
69
|
+
break;
|
|
70
|
+
|
|
71
|
+
case PositionContainer.TOP_RIGHT:
|
|
72
|
+
top = c.y - m.h - offset;
|
|
73
|
+
left = c.x;
|
|
74
|
+
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case PositionContainer.BOTTOM:
|
|
78
|
+
case PositionContainer.BOTTOM_CENTER:
|
|
79
|
+
top = c.y + c.h + offset;
|
|
80
|
+
left = c.x - (m.w - c.w) / 2;
|
|
42
81
|
|
|
43
82
|
break;
|
|
44
|
-
|
|
83
|
+
|
|
84
|
+
case PositionContainer.BOTTOM_LEFT:
|
|
45
85
|
top = c.y + c.h + offset;
|
|
46
|
-
left = c.x -
|
|
86
|
+
left = c.x - m.w + c.w;
|
|
87
|
+
|
|
88
|
+
break;
|
|
89
|
+
|
|
90
|
+
case PositionContainer.BOTTOM_RIGHT:
|
|
91
|
+
top = c.y + c.h + offset;
|
|
92
|
+
left = c.x;
|
|
93
|
+
|
|
94
|
+
break;
|
|
95
|
+
|
|
96
|
+
case PositionContainer.LEFT:
|
|
97
|
+
case PositionContainer.LEFT_CENTER:
|
|
98
|
+
top = c.y - (m.h - c.h) / 2;
|
|
99
|
+
left = c.x - m.w - offset;
|
|
47
100
|
|
|
48
101
|
break;
|
|
49
|
-
|
|
50
|
-
|
|
102
|
+
|
|
103
|
+
case PositionContainer.LEFT_TOP:
|
|
104
|
+
top = c.y - m.h + c.h;
|
|
51
105
|
left = c.x - m.w - offset;
|
|
52
106
|
|
|
53
107
|
break;
|
|
54
|
-
|
|
55
|
-
|
|
108
|
+
|
|
109
|
+
case PositionContainer.LEFT_BOTTOM:
|
|
110
|
+
top = c.y;
|
|
111
|
+
left = c.x - m.w - offset;
|
|
112
|
+
|
|
113
|
+
break;
|
|
114
|
+
|
|
115
|
+
case PositionContainer.RIGHT:
|
|
116
|
+
case PositionContainer.RIGHT_CENTER:
|
|
117
|
+
top = c.y - (m.h - c.h) / 2;
|
|
56
118
|
left = c.x + c.w + offset;
|
|
57
119
|
|
|
58
120
|
break;
|
|
121
|
+
|
|
122
|
+
case PositionContainer.RIGHT_TOP:
|
|
123
|
+
top = c.y - m.h + c.h;
|
|
124
|
+
left = c.x + c.w + offset;
|
|
125
|
+
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case PositionContainer.RIGHT_BOTTOM:
|
|
129
|
+
top = c.y;
|
|
130
|
+
left = c.x + c.w + offset;
|
|
131
|
+
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
left: Math.round(left),
|
|
137
|
+
top: Math.round(top),
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const getOppositePosition = (
|
|
142
|
+
{ top, left }: ModalPosition,
|
|
143
|
+
position: PositionContainer,
|
|
144
|
+
windowOffset: number,
|
|
145
|
+
m: PositionObject,
|
|
146
|
+
) => {
|
|
147
|
+
const positions = position.split(' ');
|
|
148
|
+
const newPosition = [];
|
|
149
|
+
const rightOffset = left + m.w + windowOffset - window.innerWidth;
|
|
150
|
+
const bottomOffset = top + m.h + windowOffset - window.innerHeight;
|
|
151
|
+
|
|
152
|
+
for (const p of positions) {
|
|
153
|
+
if (p === PositionContainer.TOP && top < windowOffset) {
|
|
154
|
+
newPosition.push(PositionContainer.BOTTOM);
|
|
155
|
+
} else if (p === PositionContainer.LEFT && left < windowOffset) {
|
|
156
|
+
newPosition.push(PositionContainer.RIGHT);
|
|
157
|
+
} else if (p === PositionContainer.BOTTOM && bottomOffset > 0) {
|
|
158
|
+
newPosition.push(PositionContainer.TOP);
|
|
159
|
+
} else if (p === PositionContainer.RIGHT && rightOffset > 0) {
|
|
160
|
+
newPosition.push(PositionContainer.LEFT);
|
|
161
|
+
} else {
|
|
162
|
+
newPosition.push(p);
|
|
163
|
+
}
|
|
59
164
|
}
|
|
60
165
|
|
|
166
|
+
return newPosition.join(' ') as PositionContainer;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const fixModalPosition = ({ top, left }: ModalPosition, m: PositionObject, windowOffset: number) => {
|
|
170
|
+
const rightOffset = left + m.w + windowOffset - window.innerWidth;
|
|
171
|
+
const bottomOffset = top + m.h + windowOffset - window.innerHeight;
|
|
172
|
+
|
|
173
|
+
left = rightOffset > 0 ? left - rightOffset : left;
|
|
174
|
+
top = bottomOffset > 0 ? top - bottomOffset : top;
|
|
175
|
+
|
|
176
|
+
left = left < windowOffset ? windowOffset : left;
|
|
177
|
+
top = top < windowOffset ? windowOffset : top;
|
|
178
|
+
|
|
179
|
+
return { top, left };
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
type getModalPositionRelativeToContainerParams = GetModalPositionParams & {
|
|
183
|
+
windowOffset: number;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export const getModalPositionRelativeToContainer = ({
|
|
187
|
+
c,
|
|
188
|
+
m,
|
|
189
|
+
offset,
|
|
190
|
+
windowOffset,
|
|
191
|
+
position,
|
|
192
|
+
}: getModalPositionRelativeToContainerParams): Record<string, string> => {
|
|
193
|
+
const params = { c, m, offset, position };
|
|
194
|
+
let modalContainerStyle = getModalPosition(params);
|
|
195
|
+
|
|
196
|
+
const oppositePosition = getOppositePosition(modalContainerStyle, position, windowOffset, m);
|
|
197
|
+
|
|
198
|
+
if (oppositePosition !== position) {
|
|
199
|
+
modalContainerStyle = getModalPosition({
|
|
200
|
+
...params,
|
|
201
|
+
position: oppositePosition,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const fixedPosition = fixModalPosition(modalContainerStyle, m, windowOffset);
|
|
206
|
+
|
|
61
207
|
return {
|
|
62
|
-
left:
|
|
63
|
-
|
|
64
|
-
top: top + m.h + windowOffset > window.innerHeight ? c.top - (top + m.h - window.innerHeight) - windowOffset : top,
|
|
208
|
+
left: `${fixedPosition.left}px`,
|
|
209
|
+
top: `${fixedPosition.top}px`,
|
|
65
210
|
};
|
|
66
211
|
};
|
package/src/helpers/index.ts
CHANGED
package/src/hooks/index.ts
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
export * from './use-async';
|
|
2
|
-
export * from './use-async';
|
|
3
2
|
export * from './use-classnames';
|
|
3
|
+
export * from './use-click-outside';
|
|
4
4
|
export * from './use-constant';
|
|
5
|
+
export * from './use-cookie';
|
|
5
6
|
export * from './use-debounce';
|
|
6
7
|
export * from './use-dimensions';
|
|
8
|
+
export * from './use-dom-container';
|
|
7
9
|
export * from './use-event-listener';
|
|
8
10
|
export * from './use-file-reader';
|
|
11
|
+
export * from './use-geolocation';
|
|
12
|
+
export * from './use-hover';
|
|
9
13
|
export * from './use-in-view';
|
|
10
14
|
export * from './use-input-handlers';
|
|
15
|
+
export * from './use-intersection-observer';
|
|
11
16
|
export * from './use-media-query';
|
|
17
|
+
export * from './use-modal';
|
|
12
18
|
export * from './use-modal-in-container';
|
|
19
|
+
export * from './use-modal-transition';
|
|
13
20
|
export * from './use-mouse-position';
|
|
14
|
-
export * from './use-observer';
|
|
15
|
-
export * from './use-on-click-outside-ref';
|
|
16
21
|
export * from './use-online-status';
|
|
17
22
|
export * from './use-render-count';
|
|
23
|
+
export * from './use-resize-observer';
|
|
18
24
|
export * from './use-safe-dispatch';
|
|
19
25
|
export * from './use-scroll';
|
|
20
26
|
export * from './use-state-history';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useEventListener } from './use-event-listener';
|
|
4
|
+
|
|
5
|
+
const checkIsOutside = (ref: RefObject<HTMLElement>, target: Node) => {
|
|
6
|
+
return ref.current && !ref.current.contains(target);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const useClickOutside = <T extends HTMLElement>(
|
|
10
|
+
ref: RefObject<T> | Array<RefObject<T>>,
|
|
11
|
+
callback: () => void,
|
|
12
|
+
) => {
|
|
13
|
+
useEventListener('keydown', e => {
|
|
14
|
+
if (e.key === 'Escape') {
|
|
15
|
+
callback();
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
useEventListener('mousedown', event => {
|
|
20
|
+
const target = event.target as Node;
|
|
21
|
+
|
|
22
|
+
if (!target?.isConnected) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const isOutside = (Array.isArray(ref) ? ref : [ref]).every(r => checkIsOutside(r, target));
|
|
27
|
+
|
|
28
|
+
if (isOutside) {
|
|
29
|
+
callback();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|