@cyber-harbour/ui 1.0.17 → 1.0.19
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 +241 -83
- package/dist/index.d.ts +241 -83
- package/dist/index.js +148 -102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +147 -101
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/src/Core/Button/Button.tsx +110 -19
- package/src/Core/Button/index.ts +1 -1
- package/src/Core/Header/Header.tsx +15 -13
- package/src/Core/IconComponents/BallsMenu.tsx +15 -0
- package/src/Core/IconComponents/Check.tsx +13 -0
- package/src/Core/IconComponents/ChevronDown.tsx +18 -0
- package/src/Core/IconComponents/ChevronUp.tsx +18 -0
- package/src/Core/IconComponents/index.ts +4 -0
- package/src/Core/ListMenu/ListMenuItem.tsx +10 -14
- package/src/Core/ListMenu/ListMenuSection.tsx +1 -1
- package/src/Core/Pagination/Pagination.tsx +2 -2
- package/src/Core/Sidebar/Sidebar.tsx +47 -47
- package/src/Core/Sidebar/SidebarItem.tsx +3 -3
- package/src/Core/Table/Table.tsx +15 -6
- package/src/Core/Typography/Typography.tsx +2 -2
- package/src/Layouts/PageLayout/PageLayout.tsx +2 -1
- package/src/Theme/ThemeProvider.tsx +0 -1
- package/src/Theme/index.ts +2 -1
- package/src/Theme/styled.d.ts +7 -0
- package/src/Theme/theme.ts +451 -101
- package/src/Theme/types.ts +148 -0
- package/src/Theme/utils.ts +109 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyber-harbour/ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.19",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"dev": "tsup --config tsup.dev.config.ts",
|
|
17
17
|
"build": "cross-env NODE_ENV=production tsup",
|
|
18
18
|
"build:dev": "tsup",
|
|
19
|
+
"type:check": "tsc --noEmit",
|
|
19
20
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
20
21
|
"storybook": "storybook dev -p 6006",
|
|
21
22
|
"build-storybook": "storybook build",
|
|
@@ -1,24 +1,115 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import styled from 'styled-components';
|
|
3
|
+
import {
|
|
4
|
+
ButtonVariant,
|
|
5
|
+
ButtonSize,
|
|
6
|
+
ButtonColor,
|
|
7
|
+
getButtonStyles,
|
|
8
|
+
getButtonSizeStyles,
|
|
9
|
+
ButtonElementStyle,
|
|
10
|
+
} from '../../Theme';
|
|
2
11
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
color
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
background: ${(props) => props.theme.colors.primary.light};
|
|
14
|
-
}
|
|
15
|
-
`;
|
|
16
|
-
|
|
17
|
-
export interface ButtonProps {
|
|
18
|
-
children: any;
|
|
19
|
-
color?: string;
|
|
12
|
+
interface BaseButtonProps {
|
|
13
|
+
children?: any;
|
|
14
|
+
variant?: ButtonVariant;
|
|
15
|
+
color?: ButtonColor;
|
|
16
|
+
size?: ButtonSize;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
fullWidth?: boolean;
|
|
19
|
+
className?: string;
|
|
20
|
+
icon?: any;
|
|
21
|
+
iconPosition?: 'left' | 'right';
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
+
export type ButtonProps = BaseButtonProps &
|
|
25
|
+
(React.AnchorHTMLAttributes<HTMLAnchorElement> | React.ButtonHTMLAttributes<HTMLButtonElement>);
|
|
26
|
+
|
|
27
|
+
const getCss = (styles: ButtonElementStyle) => `
|
|
28
|
+
background: ${styles.background};
|
|
29
|
+
color: ${styles.text};
|
|
30
|
+
border-color: ${styles.border};
|
|
31
|
+
box-shadow: ${styles.boxShadow};
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
// Створюємо стилізований компонент, що використовує уніфіковану палітру
|
|
35
|
+
const StyledButton = styled.button<{
|
|
36
|
+
$variant: ButtonVariant;
|
|
37
|
+
$color: ButtonColor;
|
|
38
|
+
$size: ButtonSize;
|
|
39
|
+
$disabled: boolean;
|
|
40
|
+
$fullWidth: boolean;
|
|
41
|
+
$iconPosition: 'left' | 'right';
|
|
42
|
+
}>`
|
|
43
|
+
${({ $variant, $color, $size, $disabled, $fullWidth, $iconPosition, theme }) => {
|
|
44
|
+
const sizes = getButtonSizeStyles(theme, $size);
|
|
45
|
+
return `
|
|
46
|
+
${getCss(getButtonStyles(theme, $variant, $color, 'default'))}
|
|
47
|
+
font-size: ${sizes.fontSize};
|
|
48
|
+
gap: ${sizes.gap};
|
|
49
|
+
padding-block: ${sizes.paddingBlock};
|
|
50
|
+
padding-inline: ${sizes.paddingInline};
|
|
51
|
+
border-radius: ${sizes.borderRadius};
|
|
52
|
+
border-width: ${sizes.borderWidth};
|
|
53
|
+
border-style: solid;
|
|
54
|
+
width: ${$fullWidth ? '100%' : 'auto'};
|
|
55
|
+
cursor: ${$disabled ? 'not-allowed' : 'pointer'};
|
|
56
|
+
font-weight: 500;
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
text-decoration: none;
|
|
61
|
+
transition: all 0.2s ease;
|
|
62
|
+
outline: none;
|
|
63
|
+
|
|
64
|
+
${$iconPosition === 'right' ? 'flex-direction: row-reverse;' : ''}
|
|
65
|
+
|
|
66
|
+
&:hover {
|
|
67
|
+
${getCss(getButtonStyles(theme, $variant, $color, 'hover'))}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&:active {
|
|
71
|
+
${getCss(getButtonStyles(theme, $variant, $color, 'active'))}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&:disabled {
|
|
75
|
+
${getCss(getButtonStyles(theme, $variant, $color, 'disabled'))}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
svg {
|
|
79
|
+
width: ${sizes.iconSize};
|
|
80
|
+
height: ${sizes.iconSize};
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
}}
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
export const Button = ({
|
|
87
|
+
children,
|
|
88
|
+
variant = 'fill',
|
|
89
|
+
color = 'primary',
|
|
90
|
+
size = 'medium',
|
|
91
|
+
disabled = false,
|
|
92
|
+
fullWidth = false,
|
|
93
|
+
className,
|
|
94
|
+
icon,
|
|
95
|
+
iconPosition = 'left',
|
|
96
|
+
...props
|
|
97
|
+
}: ButtonProps) => {
|
|
98
|
+
return (
|
|
99
|
+
<StyledButton
|
|
100
|
+
as={'href' in props ? 'a' : 'button'}
|
|
101
|
+
$variant={variant}
|
|
102
|
+
$color={color}
|
|
103
|
+
$size={size}
|
|
104
|
+
$disabled={disabled}
|
|
105
|
+
$fullWidth={fullWidth}
|
|
106
|
+
$iconPosition={iconPosition}
|
|
107
|
+
disabled={disabled}
|
|
108
|
+
className={className}
|
|
109
|
+
{...props}
|
|
110
|
+
>
|
|
111
|
+
{icon}
|
|
112
|
+
<div>{children}</div>
|
|
113
|
+
</StyledButton>
|
|
114
|
+
);
|
|
24
115
|
};
|
package/src/Core/Button/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './Button';
|
|
@@ -5,24 +5,14 @@ interface HeaderProps {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export const Header = ({ children }: HeaderProps) => {
|
|
8
|
-
return
|
|
9
|
-
<StyledWrapper>
|
|
10
|
-
<StyledContainer>{children}</StyledContainer>
|
|
11
|
-
</StyledWrapper>
|
|
12
|
-
);
|
|
8
|
+
return <StyledContainer>{children}</StyledContainer>;
|
|
13
9
|
};
|
|
14
10
|
|
|
15
|
-
const
|
|
16
|
-
height: 56px;
|
|
17
|
-
`;
|
|
18
|
-
|
|
19
|
-
const StyledContainer = styled.div(
|
|
11
|
+
const StyledContainer = styled.header(
|
|
20
12
|
({ theme }) => `
|
|
21
13
|
display: flex;
|
|
22
|
-
position:
|
|
14
|
+
position: sticky;
|
|
23
15
|
top: 0;
|
|
24
|
-
left: 0;
|
|
25
|
-
right: 0;
|
|
26
16
|
z-index: 1000;
|
|
27
17
|
align-items: center;
|
|
28
18
|
justify-content: space-between;
|
|
@@ -31,5 +21,17 @@ const StyledContainer = styled.div(
|
|
|
31
21
|
height: 56px;
|
|
32
22
|
background-color: ${theme.colors.background};
|
|
33
23
|
border-bottom: 1px solid ${theme.colors.stroke.main};
|
|
24
|
+
|
|
25
|
+
&:before {
|
|
26
|
+
content: '';
|
|
27
|
+
display: block;
|
|
28
|
+
position: absolute;
|
|
29
|
+
top: 0;
|
|
30
|
+
left: 0;
|
|
31
|
+
width: 100%;
|
|
32
|
+
height: 25dvh;
|
|
33
|
+
transform: translateY(-100%);
|
|
34
|
+
background: ${theme.colors.background};
|
|
35
|
+
}
|
|
34
36
|
`
|
|
35
37
|
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
|
|
3
|
+
interface InfoCircleIconProps extends SVGProps<SVGSVGElement> {
|
|
4
|
+
fill?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const BallsMenu = ({ fill = 'currentColor', ...props }: InfoCircleIconProps) => {
|
|
8
|
+
return (
|
|
9
|
+
<svg viewBox="0 0 16 3" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
10
|
+
<ellipse cx="1.56746" cy="1.5" rx="1.53633" ry="1.5" fill={fill} />
|
|
11
|
+
<ellipse cx="7.71278" cy="1.5" rx="1.53633" ry="1.5" fill={fill} />
|
|
12
|
+
<ellipse cx="13.8581" cy="1.5" rx="1.53633" ry="1.5" fill={fill} />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
|
|
3
|
+
interface InfoCircleIconProps extends SVGProps<SVGSVGElement> {
|
|
4
|
+
fill?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const CheckIcon = ({ fill = 'currentColor', ...props }: InfoCircleIconProps) => {
|
|
8
|
+
return (
|
|
9
|
+
<svg viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
10
|
+
<path d="M14.4983 1L5.34428 11L1.18338 6.45455" stroke={fill} stroke-width="1.5" stroke-linejoin="round" />;
|
|
11
|
+
</svg>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
|
|
3
|
+
interface ChevronRightIconProps extends SVGProps<SVGSVGElement> {
|
|
4
|
+
fill?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const ChevronDownIcon = ({ fill = 'currentColor', ...props }: ChevronRightIconProps) => {
|
|
8
|
+
return (
|
|
9
|
+
<svg viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
10
|
+
<path
|
|
11
|
+
fill-rule="evenodd"
|
|
12
|
+
clip-rule="evenodd"
|
|
13
|
+
d="M17.4517 5.77798L16.4067 6.79197L10.8447 12.1899C10.0753 12.9367 8.82791 12.9367 8.05853 12.1899L2.49647 6.79197L1.45166 5.77798L3.54128 3.75L4.58609 4.76399L9.45161 9.48599L14.3172 4.76399L15.362 3.75L17.4517 5.77798Z"
|
|
14
|
+
fill={fill}
|
|
15
|
+
/>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
|
|
3
|
+
interface ChevronRightIconProps extends SVGProps<SVGSVGElement> {
|
|
4
|
+
fill?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const ChevronUpIcon = ({ fill = 'currentColor', ...props }: ChevronRightIconProps) => {
|
|
8
|
+
return (
|
|
9
|
+
<svg viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
10
|
+
<path
|
|
11
|
+
fill-rule="evenodd"
|
|
12
|
+
clip-rule="evenodd"
|
|
13
|
+
d="M0.20166 10.722L1.24661 9.70803L6.80863 4.31012C7.57801 3.56329 8.82541 3.56329 9.59479 4.31012L15.1569 9.70803L16.2017 10.722L14.112 12.75L13.0672 11.736L8.20171 7.01401L3.33611 11.736L2.29136 12.75L0.20166 10.722Z"
|
|
14
|
+
fill={fill}
|
|
15
|
+
/>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
@@ -32,3 +32,7 @@ export { StatisticIcon } from './StatisticIcon';
|
|
|
32
32
|
export { SunIcon } from './SunIcon';
|
|
33
33
|
export { UpRightArrowCircleIcon } from './UpRightArrowCircleIcon';
|
|
34
34
|
export { VectorIcon } from './VectorIcon';
|
|
35
|
+
export { BallsMenu } from './BallsMenu';
|
|
36
|
+
export { CheckIcon } from './Check';
|
|
37
|
+
export { ChevronDownIcon } from './ChevronDown';
|
|
38
|
+
export { ChevronUpIcon } from './ChevronUp';
|
|
@@ -47,16 +47,16 @@ const StyledItem = styled.li<StyledProps>(
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
::before {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
content: '';
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: 0;
|
|
53
|
+
left: 0;
|
|
54
|
+
width: 2px;
|
|
55
|
+
height: ${$active ? '100%' : 0};
|
|
56
|
+
border-radius: 2px;
|
|
57
|
+
transform: translateX(-25%);
|
|
58
|
+
background-color: ${$active ? theme.colors.primary.main : 'transparent'};
|
|
59
|
+
transition: background-color 0.3s ease-in-out, height 0.3s ease-in-out;
|
|
60
60
|
}
|
|
61
61
|
`
|
|
62
62
|
);
|
|
@@ -88,11 +88,7 @@ const StyledLink = styled.a<StyledProps>(
|
|
|
88
88
|
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
|
89
89
|
|
|
90
90
|
&:hover {
|
|
91
|
-
background-color: ${theme.colors.primary.lighter};
|
|
92
91
|
color: ${theme.colors.primary.main};
|
|
93
|
-
span {
|
|
94
|
-
background-color: ${theme.colors.primary.lighter};
|
|
95
|
-
}
|
|
96
92
|
}`
|
|
97
93
|
);
|
|
98
94
|
|
|
@@ -2,7 +2,7 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import { styled } from 'styled-components';
|
|
3
3
|
|
|
4
4
|
export interface ListMenuSectionProps {
|
|
5
|
-
items:
|
|
5
|
+
items: any;
|
|
6
6
|
title?: string;
|
|
7
7
|
}
|
|
8
8
|
export const ListMenuSection = ({ title, items }: ListMenuSectionProps) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FC, useCallback, useMemo } from 'react';
|
|
2
2
|
import { styled } from 'styled-components';
|
|
3
3
|
import { ChevronRightIcon } from '../IconComponents';
|
|
4
4
|
import { ChevronLeftIcon } from '../IconComponents';
|
|
@@ -16,7 +16,7 @@ const VISIBLE_GROUPE = 5;
|
|
|
16
16
|
const STEP = 1;
|
|
17
17
|
const ELLIPSIS = '...';
|
|
18
18
|
|
|
19
|
-
export const Pagination
|
|
19
|
+
export const Pagination = ({ total_items, limit, offset, onChangePage }: PaginationProps) => {
|
|
20
20
|
const currentPage = useMemo(() => (offset ? offset / limit + 1 : 1), [limit, offset]);
|
|
21
21
|
const pages = Math.ceil(total_items / limit);
|
|
22
22
|
const paginationItems: (number | string)[] = useMemo(() => {
|
|
@@ -15,61 +15,61 @@ export const Sidebar = ({ defaultCollapsed, children }: SidebarProps) => {
|
|
|
15
15
|
const [collapsed, setCollapsed] = React.useState(!!defaultCollapsed);
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</StyledContainer>
|
|
29
|
-
</StyledWrapper>
|
|
18
|
+
<StyledContainer $collapsed={collapsed}>
|
|
19
|
+
<SidebarContext.Provider
|
|
20
|
+
value={{
|
|
21
|
+
collapsed,
|
|
22
|
+
setCollapsed,
|
|
23
|
+
}}
|
|
24
|
+
>
|
|
25
|
+
{children}
|
|
26
|
+
</SidebarContext.Provider>
|
|
27
|
+
</StyledContainer>
|
|
30
28
|
);
|
|
31
29
|
};
|
|
32
30
|
|
|
33
|
-
const
|
|
34
|
-
({ $collapsed }) => `
|
|
35
|
-
|
|
31
|
+
const StyledContainer = styled.aside<StyledProps>(
|
|
32
|
+
({ theme, $collapsed }) => `
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
justify-content: space-between;
|
|
36
|
+
gap: 20px;
|
|
37
|
+
position: sticky;
|
|
38
|
+
z-index: 1000;
|
|
39
|
+
top: 0;
|
|
40
|
+
width: ${theme.sidebar.width};
|
|
41
|
+
padding: 12px;
|
|
36
42
|
height: 100%;
|
|
37
|
-
|
|
43
|
+
border-right: 1px solid ${theme.colors.stroke.light};
|
|
44
|
+
background: ${theme.colors.background};
|
|
45
|
+
${
|
|
46
|
+
$collapsed
|
|
47
|
+
? `
|
|
48
|
+
width: 65px;
|
|
49
|
+
`
|
|
50
|
+
: ''
|
|
51
|
+
}
|
|
38
52
|
|
|
53
|
+
&:before {
|
|
54
|
+
content: '';
|
|
55
|
+
display: block;
|
|
56
|
+
position: absolute;
|
|
57
|
+
top: 0;
|
|
58
|
+
left: 0;
|
|
59
|
+
width: 100%;
|
|
60
|
+
height: 25dvh;
|
|
61
|
+
transform: translateY(-100%);
|
|
62
|
+
background: ${theme.colors.background};
|
|
63
|
+
border-right: 1px solid ${theme.colors.stroke.light};
|
|
39
64
|
|
|
40
|
-
|
|
41
|
-
$
|
|
42
|
-
|
|
43
|
-
|
|
65
|
+
width: ${theme.sidebar.width};
|
|
66
|
+
${
|
|
67
|
+
$collapsed
|
|
68
|
+
? `
|
|
44
69
|
width: 65px;
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
`
|
|
71
|
+
: ''
|
|
47
72
|
}
|
|
48
|
-
`
|
|
49
73
|
}
|
|
50
74
|
`
|
|
51
75
|
);
|
|
52
|
-
|
|
53
|
-
const StyledContainer = styled.div<StyledProps>(
|
|
54
|
-
({ theme, $collapsed }) => `
|
|
55
|
-
display: flex;
|
|
56
|
-
flex-direction: column;
|
|
57
|
-
justify-content: space-between;
|
|
58
|
-
gap: 1px;
|
|
59
|
-
position: fixed;
|
|
60
|
-
z-index: 1000;
|
|
61
|
-
top: 56px;
|
|
62
|
-
left: 0;
|
|
63
|
-
width: 220px;
|
|
64
|
-
padding: 12px;
|
|
65
|
-
height: calc(100% - 56px);
|
|
66
|
-
border-right: 1px solid ${theme.colors.stroke.light};
|
|
67
|
-
background: ${theme.colors.background};
|
|
68
|
-
${
|
|
69
|
-
$collapsed &&
|
|
70
|
-
`
|
|
71
|
-
width: 65px;
|
|
72
|
-
`
|
|
73
|
-
}
|
|
74
|
-
`
|
|
75
|
-
);
|
|
@@ -112,15 +112,15 @@ const StyledItem = styled.a<StyledProps>(
|
|
|
112
112
|
top: 0;
|
|
113
113
|
height: 100%;
|
|
114
114
|
width: 0px;
|
|
115
|
-
border-top-right-radius:
|
|
116
|
-
border-bottom-right-radius:
|
|
115
|
+
border-top-right-radius: 5px;
|
|
116
|
+
border-bottom-right-radius: 5px;
|
|
117
117
|
background: rgaba(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
122
|
background: ${theme.colors.primary.main};
|
|
123
|
-
width:
|
|
123
|
+
width: 5px;
|
|
124
124
|
`
|
|
125
125
|
: ''
|
|
126
126
|
}
|
package/src/Core/Table/Table.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode, useMemo, CSSProperties } from 'react';
|
|
2
2
|
import { styled } from 'styled-components';
|
|
3
3
|
import { Row } from './Row';
|
|
4
4
|
import { Cell, HeadCell } from './Cell';
|
|
@@ -24,12 +24,12 @@ export type RenderHeaderCellProps<T = string> = {
|
|
|
24
24
|
interface TableProps {
|
|
25
25
|
columns: ColumnTable[];
|
|
26
26
|
rowCount: number;
|
|
27
|
-
renderCell: (props: RenderCellProps<any>) =>
|
|
28
|
-
renderHeaderCell: (props: RenderHeaderCellProps<any>) =>
|
|
27
|
+
renderCell: (props: RenderCellProps<any>) => any;
|
|
28
|
+
renderHeaderCell: (props: RenderHeaderCellProps<any>) => any;
|
|
29
29
|
rowIds?: string[];
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export const Table
|
|
32
|
+
export const Table = ({ columns, rowCount, renderCell, renderHeaderCell, rowIds }: TableProps) => {
|
|
33
33
|
const cellCount = columns.length;
|
|
34
34
|
|
|
35
35
|
const data = useMemo(() => {
|
|
@@ -49,7 +49,7 @@ export const Table: FC<TableProps> = ({ columns, rowCount, renderCell, renderHea
|
|
|
49
49
|
|
|
50
50
|
return (
|
|
51
51
|
<StyledTable>
|
|
52
|
-
<
|
|
52
|
+
<StyledHead>
|
|
53
53
|
<Row>
|
|
54
54
|
{columns.map(({ id, title, width }) => (
|
|
55
55
|
<HeadCell
|
|
@@ -62,7 +62,7 @@ export const Table: FC<TableProps> = ({ columns, rowCount, renderCell, renderHea
|
|
|
62
62
|
</HeadCell>
|
|
63
63
|
))}
|
|
64
64
|
</Row>
|
|
65
|
-
</
|
|
65
|
+
</StyledHead>
|
|
66
66
|
<tbody>
|
|
67
67
|
{data.map((cells, rowIndex) => (
|
|
68
68
|
<Row key={`row-${rowIndex}`} id={rowIds ? rowIds[rowIndex] : `row-${rowIndex}`}>
|
|
@@ -83,3 +83,12 @@ const StyledTable = styled.table`
|
|
|
83
83
|
border-spacing: 0;
|
|
84
84
|
table-layout: fixed;
|
|
85
85
|
`;
|
|
86
|
+
|
|
87
|
+
const StyledHead = styled.thead(
|
|
88
|
+
({ theme }) => `
|
|
89
|
+
background-color: ${theme.colors.background};
|
|
90
|
+
position: sticky;
|
|
91
|
+
top: 0;
|
|
92
|
+
z-index: 1;
|
|
93
|
+
`
|
|
94
|
+
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
2
|
import { CSSProperties, ElementType, ReactNode } from 'react';
|
|
3
|
-
import { ColorVariant, TypographyVariant } from '../../Theme
|
|
3
|
+
import { ColorVariant, TypographyVariant } from '../../Theme';
|
|
4
4
|
import { resolveThemeColor } from '../../Theme/utils';
|
|
5
5
|
|
|
6
6
|
export interface TypographyProps {
|
|
@@ -23,7 +23,7 @@ const StyledTypography = styled.div<{
|
|
|
23
23
|
// Resolve color from theme if it's a theme color path, or use the direct color value
|
|
24
24
|
|
|
25
25
|
return `
|
|
26
|
-
font-size: ${theme.typography[$variant]};
|
|
26
|
+
font-size: ${theme.typography.variants[$variant].fontSize};
|
|
27
27
|
font-weight: ${$weight};
|
|
28
28
|
font-style: ${$style};
|
|
29
29
|
color: ${resolveThemeColor(theme, $color) || theme.colors.text.main};
|
|
@@ -26,12 +26,13 @@ export const StyledContainer = styled.div<StyledContainerProps>(
|
|
|
26
26
|
({ $withHeader, $withSidebar }) => `
|
|
27
27
|
display: grid;
|
|
28
28
|
min-height: 100dvh;
|
|
29
|
+
position: relative;
|
|
29
30
|
grid-template-columns: ${$withSidebar ? 'auto 1fr' : '1fr'};
|
|
30
31
|
grid-template-rows: ${$withHeader ? 'auto 1fr' : '1fr'};
|
|
31
32
|
grid-template-areas: ${
|
|
32
33
|
$withHeader
|
|
33
34
|
? $withSidebar
|
|
34
|
-
? `'
|
|
35
|
+
? `'sidebar header' 'sidebar content'`
|
|
35
36
|
: `'header' 'content'`
|
|
36
37
|
: $withSidebar
|
|
37
38
|
? `'sidebar content'`
|
package/src/Theme/index.ts
CHANGED