@cyber-harbour/ui 1.0.72 → 1.0.74
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/dist/index.d.mts +76 -52
- package/dist/index.d.ts +76 -52
- package/dist/index.js +272 -213
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +305 -246
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Core/ContextMenu/ContextMenu.tsx +9 -5
- package/src/Core/Drawer/Drawer.tsx +2 -1
- package/src/Core/Modal/Modal.tsx +116 -0
- package/src/Core/Modal/index.ts +1 -0
- package/src/Core/Overlay/Overlay.tsx +4 -2
- package/src/Core/index.ts +1 -0
- package/src/Theme/themes/dark.ts +8 -0
- package/src/Theme/themes/light.ts +8 -0
- package/src/Theme/types.ts +8 -0
- package/src/Theme/utils.ts +2 -2
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ interface ContextMenuProps {
|
|
|
19
19
|
hasBorder?: boolean;
|
|
20
20
|
maxHeight?: number;
|
|
21
21
|
matchAnchorWidth?: boolean;
|
|
22
|
+
anchorIcon?: any;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export const ContextMenu = ({
|
|
@@ -36,6 +37,7 @@ export const ContextMenu = ({
|
|
|
36
37
|
hasBorder = true,
|
|
37
38
|
maxHeight = 500,
|
|
38
39
|
matchAnchorWidth = false,
|
|
40
|
+
anchorIcon,
|
|
39
41
|
}: ContextMenuProps) => {
|
|
40
42
|
const [anchorWidth, setAnchorWidth] = useState<number>(0);
|
|
41
43
|
const buttonRef = useRef<HTMLButtonElement | null>(null);
|
|
@@ -66,6 +68,7 @@ export const ContextMenu = ({
|
|
|
66
68
|
zIndex: `${9999}`,
|
|
67
69
|
width: anchorWidth && matchAnchorWidth ? `${anchorWidth}px` : undefined,
|
|
68
70
|
}}
|
|
71
|
+
containerClassName="cb-ui-context-menu"
|
|
69
72
|
>
|
|
70
73
|
<StyledButton
|
|
71
74
|
onClick={onClick}
|
|
@@ -78,11 +81,12 @@ export const ContextMenu = ({
|
|
|
78
81
|
$hasBorder={hasBorder}
|
|
79
82
|
>
|
|
80
83
|
<StyledAnchor>{anchor}</StyledAnchor>
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
{anchorIcon ||
|
|
85
|
+
(isOpen ? (
|
|
86
|
+
<ChevronUpIcon width={theme.contextMenu.icon.size} height={theme.contextMenu.icon.size} />
|
|
87
|
+
) : (
|
|
88
|
+
<ChevronDownIcon width={theme.contextMenu.icon.size} height={theme.contextMenu.icon.size} />
|
|
89
|
+
))}
|
|
86
90
|
</StyledButton>
|
|
87
91
|
</Popover>
|
|
88
92
|
);
|
|
@@ -36,7 +36,8 @@ const DrawerWithOutclick = ({ onClose, children, width, header }: DrawerProps) =
|
|
|
36
36
|
if (
|
|
37
37
|
drawerRef.current &&
|
|
38
38
|
!drawerRef.current.contains(target) &&
|
|
39
|
-
!target.closest('.
|
|
39
|
+
!target.closest('.cb-ui-context-menu') &&
|
|
40
|
+
!target.closest('.cb-ui-backdrop')
|
|
40
41
|
) {
|
|
41
42
|
onClose();
|
|
42
43
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Overlay } from '../Overlay';
|
|
3
|
+
import { createStyledComponent, FabricComponent, generatePropertySpaceStyle, propToRem, pxToRem } from '../../Theme';
|
|
4
|
+
|
|
5
|
+
type ModalProps = {
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
width?: number;
|
|
8
|
+
children: any;
|
|
9
|
+
isNested?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
interface ModalChildrenProps extends FabricComponent<Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>> {
|
|
13
|
+
children: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const Modal = ({ children, onClose, isNested = false, width }: ModalProps) => {
|
|
17
|
+
return (
|
|
18
|
+
<Overlay onOutsideClick={onClose} isLocked={!isNested}>
|
|
19
|
+
<StyledContainer $width={width}>{children}</StyledContainer>
|
|
20
|
+
</Overlay>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const ModalHeader = createStyledComponent<ModalChildrenProps>(
|
|
25
|
+
styled.div(({ theme, p = theme.modal.padding, px, pl, pr }) => {
|
|
26
|
+
const left = pl || px || p;
|
|
27
|
+
const right = pr || px || p;
|
|
28
|
+
return `
|
|
29
|
+
grid-area: modal-header;
|
|
30
|
+
position: relative;
|
|
31
|
+
&::after {
|
|
32
|
+
content: '';
|
|
33
|
+
position: absolute;
|
|
34
|
+
bottom: 0;
|
|
35
|
+
left: ${typeof left === 'string' ? left : pxToRem(left)};
|
|
36
|
+
right: ${typeof right === 'string' ? right : pxToRem(right)};
|
|
37
|
+
height: ${pxToRem(1)};
|
|
38
|
+
background-color: ${theme.modal.borderColor};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
${generatePropertySpaceStyle(theme, 'padding', p)};
|
|
42
|
+
`;
|
|
43
|
+
}),
|
|
44
|
+
{
|
|
45
|
+
ignoreStyles: ['padding'],
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export const ModalBody = createStyledComponent<ModalChildrenProps>(
|
|
50
|
+
styled.div(
|
|
51
|
+
({ theme, p = theme.modal.padding }) => `
|
|
52
|
+
grid-area: modal-body;
|
|
53
|
+
max-height: 100%;
|
|
54
|
+
overflow-y: auto;
|
|
55
|
+
${generatePropertySpaceStyle(theme, 'padding', p)};
|
|
56
|
+
`
|
|
57
|
+
),
|
|
58
|
+
{
|
|
59
|
+
ignoreStyles: ['padding'],
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export const ModalFooter = createStyledComponent<ModalChildrenProps>(
|
|
64
|
+
styled.div(({ theme, p = theme.modal.padding, px, pl, pr }) => {
|
|
65
|
+
const left = pl || px || p;
|
|
66
|
+
const right = pr || px || p;
|
|
67
|
+
return `
|
|
68
|
+
grid-area: modal-footer;
|
|
69
|
+
position: relative;
|
|
70
|
+
&::after {
|
|
71
|
+
content: '';
|
|
72
|
+
position: absolute;
|
|
73
|
+
top: ${pxToRem(1)};
|
|
74
|
+
left: ${typeof left === 'string' ? left : pxToRem(left)};
|
|
75
|
+
right: ${typeof right === 'string' ? right : pxToRem(right)};
|
|
76
|
+
height: ${pxToRem(1)};
|
|
77
|
+
background-color: ${theme.modal.borderColor};
|
|
78
|
+
}
|
|
79
|
+
${generatePropertySpaceStyle(theme, 'padding', p)};
|
|
80
|
+
`;
|
|
81
|
+
}),
|
|
82
|
+
{
|
|
83
|
+
ignoreStyles: ['padding'],
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const StyledContainer = styled.div<{ $width?: number }>(
|
|
88
|
+
({ theme, $width = theme.modal.width }) => `
|
|
89
|
+
display: grid;
|
|
90
|
+
grid-template-areas:
|
|
91
|
+
"modal-header"
|
|
92
|
+
"modal-body"
|
|
93
|
+
"modal-footer";
|
|
94
|
+
grid-template-rows: auto 1fr auto;
|
|
95
|
+
position: absolute;
|
|
96
|
+
z-index:${theme.zIndex.modal};
|
|
97
|
+
top: 0;
|
|
98
|
+
left: 0;
|
|
99
|
+
width: 100%;
|
|
100
|
+
height: 100%;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
background-color: ${theme.modal.background};
|
|
103
|
+
@media (min-width: ${theme.breakpoints.m}px) {
|
|
104
|
+
top: 50%;
|
|
105
|
+
left: 50%;
|
|
106
|
+
transform: translate(-50%, -50%);
|
|
107
|
+
height: auto;
|
|
108
|
+
max-height: 90dvh;
|
|
109
|
+
width: ${propToRem($width, theme.baseSize)};
|
|
110
|
+
max-width: 90vw;
|
|
111
|
+
border: 1px solid ${theme.modal.borderColor};
|
|
112
|
+
box-shadow: ${theme.modal.shadow};
|
|
113
|
+
border-radius: ${theme.modal.borderRadius};
|
|
114
|
+
}
|
|
115
|
+
`
|
|
116
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Modal';
|
|
@@ -12,14 +12,16 @@ export type OverlayProps = {
|
|
|
12
12
|
appendPosition?: Position;
|
|
13
13
|
prepend?: any;
|
|
14
14
|
prependPosition?: Position;
|
|
15
|
+
isLocked?: boolean;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export const Overlay = createComponent<OverlayProps>(
|
|
18
|
-
({ children, onOutsideClick, prepend, append, prependPosition, appendPosition, ...props }) => {
|
|
19
|
-
useBodyScrollLock(
|
|
19
|
+
({ children, onOutsideClick, prepend, append, prependPosition, appendPosition, isLocked = true, ...props }) => {
|
|
20
|
+
useBodyScrollLock(isLocked);
|
|
20
21
|
return createPortal(
|
|
21
22
|
<Container
|
|
22
23
|
{...props}
|
|
24
|
+
className="cb-ui-backdrop"
|
|
23
25
|
onClick={(e) => {
|
|
24
26
|
if (e.target === e.currentTarget && onOutsideClick) {
|
|
25
27
|
onOutsideClick();
|
package/src/Core/index.ts
CHANGED
package/src/Theme/themes/dark.ts
CHANGED
|
@@ -992,6 +992,14 @@ export const darkThemePx: Theme = {
|
|
|
992
992
|
gap: 6,
|
|
993
993
|
background: 'rgba(0, 0, 0, 0.5)',
|
|
994
994
|
},
|
|
995
|
+
modal: {
|
|
996
|
+
padding: 20,
|
|
997
|
+
width: 545,
|
|
998
|
+
shadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.25)',
|
|
999
|
+
borderColor: '#1E2226',
|
|
1000
|
+
background: '#0F1317',
|
|
1001
|
+
borderRadius: 8,
|
|
1002
|
+
},
|
|
995
1003
|
};
|
|
996
1004
|
|
|
997
1005
|
export const darkTheme = convertPaletteToRem(darkThemePx, darkThemePx.baseSize) as DefaultTheme;
|
|
@@ -991,6 +991,14 @@ export const lightThemePx: Theme = {
|
|
|
991
991
|
gap: 6,
|
|
992
992
|
background: 'rgba(16, 16, 16, 0.1)',
|
|
993
993
|
},
|
|
994
|
+
modal: {
|
|
995
|
+
padding: 20,
|
|
996
|
+
width: 545,
|
|
997
|
+
shadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.25)',
|
|
998
|
+
borderColor: '#EBEBEB',
|
|
999
|
+
background: '#FFFFFF',
|
|
1000
|
+
borderRadius: 8,
|
|
1001
|
+
},
|
|
994
1002
|
};
|
|
995
1003
|
|
|
996
1004
|
export const lightTheme = convertPaletteToRem(lightThemePx, lightThemePx.baseSize) as DefaultTheme;
|
package/src/Theme/types.ts
CHANGED
|
@@ -335,6 +335,14 @@ export type Theme = {
|
|
|
335
335
|
background: string;
|
|
336
336
|
gap: string | number;
|
|
337
337
|
};
|
|
338
|
+
modal: {
|
|
339
|
+
padding: string | number;
|
|
340
|
+
width: number;
|
|
341
|
+
shadow: string;
|
|
342
|
+
borderColor: string;
|
|
343
|
+
background: string;
|
|
344
|
+
borderRadius: string | number;
|
|
345
|
+
};
|
|
338
346
|
};
|
|
339
347
|
|
|
340
348
|
//TODO check and refactoring
|
package/src/Theme/utils.ts
CHANGED
|
@@ -88,8 +88,8 @@ const IGNORE_CONVERT_KEYS: Record<string, string[] | boolean> = {
|
|
|
88
88
|
*/
|
|
89
89
|
export const propToRem = (value: number | string, baseSize: number = 16): string => {
|
|
90
90
|
// Check if value ends with units that should not be converted to rem
|
|
91
|
-
if (typeof value === 'string' && /(%|d?vh|d?vw)$/.test(value.trim())) {
|
|
92
|
-
return value; // Return percentage and
|
|
91
|
+
if (typeof value === 'string' && /(%|d?vh|d?vw|d?rem)$/.test(value.trim())) {
|
|
92
|
+
return value; // Return percentage, viewport and rem values as-is
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
const numericValue = typeof value === 'string' ? parseFloat(value) : value;
|