@cyber-harbour/ui 1.0.36 → 1.0.38
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 +5 -20
- package/dist/index.d.ts +5 -20
- package/dist/index.js +96 -92
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +91 -87
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Core/Flex/FlexContainer.tsx +20 -16
- package/src/Core/Sidebar/Sidebar.tsx +1 -1
- package/src/Core/Sidebar/SidebarItem.tsx +8 -8
- package/src/Graph2D/Graph2D.tsx +11 -11
- package/src/Graph2D/GraphLoader.tsx +9 -21
- package/src/Theme/GlobalStyle.tsx +9 -3
- package/src/Theme/themes/dark.ts +96 -92
- package/src/Theme/themes/light.ts +15 -11
- package/src/Theme/types.ts +4 -0
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties,
|
|
1
|
+
import { CSSProperties, forwardRef } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
export type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
|
@@ -22,20 +22,23 @@ export interface FlexContainerProps {
|
|
|
22
22
|
as?: any; // TODO: fix type to styled component or intrinsic element
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export const FlexContainer = (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
export const FlexContainer: any = forwardRef<HTMLElement, FlexContainerProps>(function FlexContainer(
|
|
26
|
+
{
|
|
27
|
+
children,
|
|
28
|
+
direction = 'row',
|
|
29
|
+
wrap = 'nowrap',
|
|
30
|
+
justify = 'flex-start',
|
|
31
|
+
align = 'stretch',
|
|
32
|
+
alignContent,
|
|
33
|
+
gap,
|
|
34
|
+
rowGap,
|
|
35
|
+
columnGap,
|
|
36
|
+
className,
|
|
37
|
+
style,
|
|
38
|
+
as = 'div',
|
|
39
|
+
},
|
|
40
|
+
ref
|
|
41
|
+
) {
|
|
39
42
|
return (
|
|
40
43
|
<StyledFlexContainer
|
|
41
44
|
as={as}
|
|
@@ -49,11 +52,12 @@ export const FlexContainer = ({
|
|
|
49
52
|
$columnGap={columnGap}
|
|
50
53
|
className={className}
|
|
51
54
|
style={style}
|
|
55
|
+
ref={ref}
|
|
52
56
|
>
|
|
53
57
|
{children}
|
|
54
58
|
</StyledFlexContainer>
|
|
55
59
|
);
|
|
56
|
-
};
|
|
60
|
+
});
|
|
57
61
|
|
|
58
62
|
interface StyledFlexContainerProps {
|
|
59
63
|
$direction: FlexDirection;
|
|
@@ -59,7 +59,7 @@ const StyledContainer = styled.aside<StyledProps>(
|
|
|
59
59
|
width: 100%;
|
|
60
60
|
height: 25dvh;
|
|
61
61
|
transform: translateY(-100%);
|
|
62
|
-
background: ${theme.
|
|
62
|
+
background: ${theme.sidebar.background};
|
|
63
63
|
border-right: 1px solid ${theme.sidebar.border};
|
|
64
64
|
|
|
65
65
|
width: ${theme.sidebar.width};
|
|
@@ -84,15 +84,15 @@ const StyledItem = styled.a<StyledProps>(
|
|
|
84
84
|
cursor: pointer;
|
|
85
85
|
text-decoration: none;
|
|
86
86
|
border-radius: 8px;
|
|
87
|
-
color: ${theme.
|
|
88
|
-
background: ${theme.
|
|
87
|
+
color: ${theme.sidebar.text.default};
|
|
88
|
+
background: ${theme.sidebar.item.default.background};
|
|
89
89
|
transition: background 0.3s ease-in-out, color 0.3s ease-in-out;
|
|
90
90
|
position: relative;
|
|
91
91
|
${
|
|
92
92
|
$active
|
|
93
93
|
? `
|
|
94
|
-
background: ${theme.
|
|
95
|
-
color: ${theme.
|
|
94
|
+
background: ${theme.sidebar.item.active.background};
|
|
95
|
+
color: ${theme.sidebar.text.active};
|
|
96
96
|
`
|
|
97
97
|
: ''
|
|
98
98
|
}
|
|
@@ -101,8 +101,8 @@ const StyledItem = styled.a<StyledProps>(
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
&:hover {
|
|
104
|
-
background: ${theme.
|
|
105
|
-
color: ${theme.
|
|
104
|
+
background: ${theme.sidebar.item.hover.background};
|
|
105
|
+
color: ${theme.sidebar.text.hover};
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
&:before {
|
|
@@ -114,12 +114,12 @@ const StyledItem = styled.a<StyledProps>(
|
|
|
114
114
|
width: 0px;
|
|
115
115
|
border-top-right-radius: 5px;
|
|
116
116
|
border-bottom-right-radius: 5px;
|
|
117
|
-
background:
|
|
117
|
+
background: rgba(0, 0, 0, 0);
|
|
118
118
|
transition: background 0.4s ease-in-out, width 0.3s ease-in-out;
|
|
119
119
|
${
|
|
120
120
|
$active
|
|
121
121
|
? `
|
|
122
|
-
background: ${theme.
|
|
122
|
+
background: ${theme.sidebar.text.active};
|
|
123
123
|
width: 5px;
|
|
124
124
|
`
|
|
125
125
|
: ''
|
package/src/Graph2D/Graph2D.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ForceGraph2D, { ForceGraphMethods, LinkObject, NodeObject } from 'react-force-graph-2d';
|
|
2
2
|
import { Graph2DProps } from './types';
|
|
3
|
-
import { useEffect, useRef, useState, useCallback
|
|
3
|
+
import { useEffect, useRef, useState, useCallback } from 'react';
|
|
4
4
|
import { forceCollide } from 'd3-force';
|
|
5
5
|
import { styled, useTheme } from 'styled-components';
|
|
6
6
|
import eyeLightIcon from './eye_light.png';
|
|
@@ -11,16 +11,16 @@ import GraphLoader from './GraphLoader';
|
|
|
11
11
|
|
|
12
12
|
// Створюємо та налаштовуємо об'єкти зображень
|
|
13
13
|
const imgEyeLightIcon = new Image();
|
|
14
|
-
imgEyeLightIcon.src = eyeLightIcon;
|
|
14
|
+
imgEyeLightIcon.src = eyeLightIcon.replace('./', '/');
|
|
15
15
|
|
|
16
16
|
const imgEyeLightHoverIcon = new Image();
|
|
17
|
-
imgEyeLightHoverIcon.src = eyeLightHoverIcon;
|
|
17
|
+
imgEyeLightHoverIcon.src = eyeLightHoverIcon.replace('./', '/');
|
|
18
18
|
|
|
19
19
|
const imgGroupLightIcon = new Image();
|
|
20
|
-
imgGroupLightIcon.src = groupLightIcon;
|
|
20
|
+
imgGroupLightIcon.src = groupLightIcon.replace('./', '/');
|
|
21
21
|
|
|
22
22
|
const imgGroupLightHoverIcon = new Image();
|
|
23
|
-
imgGroupLightHoverIcon.src = groupLightHoverIcon;
|
|
23
|
+
imgGroupLightHoverIcon.src = groupLightHoverIcon.replace('./', '/');
|
|
24
24
|
|
|
25
25
|
export const Graph2D = ({
|
|
26
26
|
graphData,
|
|
@@ -274,9 +274,9 @@ export const Graph2D = ({
|
|
|
274
274
|
const iconSize = buttonRadius * 0.3; // Розмір іконки відносно радіуса кнопки (зменшено вдвічі)
|
|
275
275
|
|
|
276
276
|
// Вибір іконки в залежності від стану наведення для верхньої кнопки (сховати)
|
|
277
|
-
const groupIcon =
|
|
277
|
+
const groupIcon = hoverBottomButton ? imgGroupLightHoverIcon : imgGroupLightIcon;
|
|
278
278
|
// Додаємо іконку ока для кнопки "згорнути дочірні вузли"
|
|
279
|
-
const eyeIcon =
|
|
279
|
+
const eyeIcon = hoverTopButton ? imgEyeLightHoverIcon : imgEyeLightIcon;
|
|
280
280
|
|
|
281
281
|
const renderEyeIcon = () => {
|
|
282
282
|
try {
|
|
@@ -308,17 +308,17 @@ export const Graph2D = ({
|
|
|
308
308
|
}
|
|
309
309
|
};
|
|
310
310
|
// Використовуємо безпосередньо зображення, якщо воно вже завантажене
|
|
311
|
-
if (
|
|
311
|
+
if (groupIcon.complete) {
|
|
312
312
|
// Розміщуємо іконку в центрі нижньої половини кнопки
|
|
313
313
|
|
|
314
314
|
renderGroupIcon();
|
|
315
315
|
} else {
|
|
316
316
|
// Якщо зображення ще не завантажене, додаємо обробник завершення завантаження
|
|
317
|
-
|
|
317
|
+
groupIcon.onload = () => {
|
|
318
318
|
renderGroupIcon();
|
|
319
319
|
};
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
groupIcon.onerror = () => {
|
|
322
322
|
console.warn('Error loading eye icon image');
|
|
323
323
|
};
|
|
324
324
|
}
|
|
@@ -560,7 +560,7 @@ export const Graph2D = ({
|
|
|
560
560
|
};
|
|
561
561
|
|
|
562
562
|
const renderGrid = (ctx: CanvasRenderingContext2D, globalScale: number) => {
|
|
563
|
-
if (isRendering) return; // Не малюємо сітку під час рендерингу
|
|
563
|
+
if (isRendering || loading) return; // Не малюємо сітку під час рендерингу
|
|
564
564
|
// This will be called before each rendering frame
|
|
565
565
|
ctx.getTransform();
|
|
566
566
|
ctx.save();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ContentLoader from 'react-content-loader';
|
|
3
|
-
import styled from 'styled-components';
|
|
3
|
+
import styled, { useTheme } from 'styled-components';
|
|
4
4
|
|
|
5
5
|
const LoaderWrapper = styled.div`
|
|
6
6
|
position: absolute;
|
|
@@ -21,29 +21,17 @@ interface GraphLoaderProps {
|
|
|
21
21
|
|
|
22
22
|
const GraphLoader: React.FC<GraphLoaderProps> = ({ width = 280, height = 280 }) => {
|
|
23
23
|
// Helper function to create a rect from line coordinates
|
|
24
|
-
const
|
|
25
|
-
// Calculate length and angle of the line
|
|
26
|
-
const length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
|
27
|
-
const angle = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI;
|
|
28
|
-
|
|
29
|
-
// Calculate center point of the line
|
|
30
|
-
const centerX = (x1 + x2) / 2;
|
|
31
|
-
const centerY = (y1 + y2) / 2;
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<rect
|
|
35
|
-
x={centerX - length / 2}
|
|
36
|
-
y={centerY - thickness / 2}
|
|
37
|
-
width={length}
|
|
38
|
-
height={thickness}
|
|
39
|
-
transform={`rotate(${angle}, ${centerX}, ${centerY})`}
|
|
40
|
-
/>
|
|
41
|
-
);
|
|
42
|
-
};
|
|
24
|
+
const theme = useTheme();
|
|
43
25
|
|
|
44
26
|
return (
|
|
45
27
|
<LoaderWrapper>
|
|
46
|
-
<ContentLoader
|
|
28
|
+
<ContentLoader
|
|
29
|
+
foregroundColor={theme.contentLoader.foreground}
|
|
30
|
+
backgroundColor={theme.contentLoader.background}
|
|
31
|
+
width={width}
|
|
32
|
+
height={height}
|
|
33
|
+
viewBox="0 0 280 280"
|
|
34
|
+
>
|
|
47
35
|
<path d="m55 38-0.97266 0.22852 7.0801 30.092-18.355-20.979-0.75195 0.6582 19.596 22.395 0.43164 1.834 0.97266-0.22852 0.75195-0.6582-0.37695-0.42969 9.625-27.912-0.94531-0.32617-9.4375 27.371-0.10547-0.12109zm8 34-0.78516 0.61914 0.0957 0.12305-12.311 13.258 0.73242 0.67969 12.205-13.145 14.277 18.084 0.78516-0.61914-14.373-18.207 0.10547-0.11328zm15 19-0.48438 0.875 46.992 25.996 8e-3 4e-3 20.506 11.592-28.182 4.5449 0.15998 0.98819 29.418-4.7441 0.25 0.14062-12.555 24.143 0.88672 0.46094 13-25 15 25 26 30v18l-11 18 0.85352 0.52148 9.8008-16.039-4.6543 33.518 0.99023 0.13867 4.7793-34.408 7.2305 16.27 0.91406-0.40625-7.9141-17.807v-17.104l18 12.316 0.56445-0.82617-18.896-12.928-25.855-29.836-14.633-24.387 0.01562-0.02344h23.805v-1h-23.152l13.848-21.234 55.201-28.791-0.45898-0.88476 0.77734 0.62305 11.402-14.25 16.668-11.842-0.58008-0.81641-16.785 11.928-11.486 14.355-55.434 28.912-14.277 21.893-7.7617-27.166-0.96094 0.27344 7.7227 27.031-1.1191 0.17969-21.604-12.211zm140.43-12.912-6.957-17.338-0.92773 0.37305 6.957 17.338zm-6.957-17.338 0.72266 0.69336 16.232-16.896-0.7207-0.69336zm-3.4766 137.25 5 15 0.94922-0.31641-5-15zm-91-63-0.48047-0.87695-31 17 0.48047 0.87695zm-31 17 5 18 0.96289-0.26758-5-18zm0 0-0.70703-0.70703-12.898 12.898-17.881 9.9336 0.48633 0.875 18-10zm5 18-0.64062-0.76758-18 15 0.64062 0.76758z" />
|
|
48
36
|
<circle cx="229.92" cy="63.7318" r="5" transform="rotate(173.661 229.92 63.7318)" />
|
|
49
37
|
<circle cx="227.711" cy="43.8541" r="5" transform="rotate(173.661 227.711 43.8541)" />
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createGlobalStyle } from 'styled-components';
|
|
2
2
|
|
|
3
|
-
export const GlobalStyle = createGlobalStyle
|
|
3
|
+
export const GlobalStyle = createGlobalStyle(
|
|
4
|
+
({ theme }) => `
|
|
4
5
|
*, *::before, *::after {
|
|
5
6
|
box-sizing: border-box;
|
|
6
7
|
margin: 0;
|
|
@@ -8,5 +9,10 @@ export const GlobalStyle = createGlobalStyle`
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
body, html {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
background: ${theme.colors.backgroundBase};
|
|
13
|
+
color: ${theme.colors.text.main};
|
|
14
|
+
font-family: ${theme.typography.fontFamily};
|
|
15
|
+
font-size: ${theme.baseSize}px;
|
|
16
|
+
}
|
|
17
|
+
`
|
|
18
|
+
);
|