@cyber-harbour/ui 1.0.17 → 1.0.18
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 +212 -74
- package/dist/index.d.ts +212 -74
- package/dist/index.js +143 -102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +142 -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/ListMenu/ListMenuItem.tsx +10 -14
- package/src/Core/Pagination/Pagination.tsx +1 -1
- package/src/Core/Sidebar/Sidebar.tsx +47 -47
- package/src/Core/Sidebar/SidebarItem.tsx +3 -3
- 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
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// Типи для компонентної палітри
|
|
2
|
+
export type ButtonVariant = 'fill' | 'outlined' | 'empty';
|
|
3
|
+
export type ButtonColor = 'default' | 'primary' | 'secondary' | 'error';
|
|
4
|
+
export type ButtonState = 'default' | 'hover' | 'active' | 'disabled';
|
|
5
|
+
export type ButtonSize = 'small' | 'medium';
|
|
6
|
+
|
|
7
|
+
export type InputVariant = 'default' | 'outlined' | 'filled';
|
|
8
|
+
export type InputState = 'default' | 'focus' | 'error' | 'disabled';
|
|
9
|
+
export type InputSize = 'small' | 'medium' | 'large';
|
|
10
|
+
|
|
11
|
+
// Типи для spacing та breakpoints
|
|
12
|
+
export type Breakpoint = 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
13
|
+
|
|
14
|
+
// Тип для стилів елементів кнопок
|
|
15
|
+
export type ButtonElementStyle = {
|
|
16
|
+
background: string;
|
|
17
|
+
text: string;
|
|
18
|
+
border: string;
|
|
19
|
+
boxShadow: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Тип для розмірів кнопок
|
|
23
|
+
export type ButtonSizeStyle = {
|
|
24
|
+
fontSize: number | string;
|
|
25
|
+
paddingInline: number | string;
|
|
26
|
+
paddingBlock: number | string;
|
|
27
|
+
borderRadius: number | string;
|
|
28
|
+
borderWidth: number | string;
|
|
29
|
+
gap: number | string;
|
|
30
|
+
iconSize: number | string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Тип для палітри
|
|
34
|
+
export type Theme = {
|
|
35
|
+
mode: 'light' | 'dark';
|
|
36
|
+
colors: {
|
|
37
|
+
background: string;
|
|
38
|
+
primary: {
|
|
39
|
+
main: string;
|
|
40
|
+
light: string;
|
|
41
|
+
lighter: string;
|
|
42
|
+
lightest: string;
|
|
43
|
+
lightest2: string;
|
|
44
|
+
};
|
|
45
|
+
text: {
|
|
46
|
+
main: string;
|
|
47
|
+
light: string;
|
|
48
|
+
lighter: string;
|
|
49
|
+
invert: string;
|
|
50
|
+
};
|
|
51
|
+
stroke: {
|
|
52
|
+
main: string;
|
|
53
|
+
light: string;
|
|
54
|
+
lighter: string;
|
|
55
|
+
};
|
|
56
|
+
disable: string;
|
|
57
|
+
success: string;
|
|
58
|
+
error: string;
|
|
59
|
+
warning: string;
|
|
60
|
+
info: string;
|
|
61
|
+
};
|
|
62
|
+
typography: {
|
|
63
|
+
fontFamily: string;
|
|
64
|
+
lineHeight: number;
|
|
65
|
+
variants: {
|
|
66
|
+
h1: { fontSize: number | string };
|
|
67
|
+
h2: { fontSize: number | string };
|
|
68
|
+
h3: { fontSize: number | string };
|
|
69
|
+
body: { fontSize: number | string };
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
breakpoints: Record<Breakpoint, number>;
|
|
73
|
+
zIndex: {
|
|
74
|
+
dropdown: number;
|
|
75
|
+
sticky: number;
|
|
76
|
+
fixed: number;
|
|
77
|
+
backdrop: number;
|
|
78
|
+
modal: number;
|
|
79
|
+
popover: number;
|
|
80
|
+
tooltip: number;
|
|
81
|
+
};
|
|
82
|
+
button: {
|
|
83
|
+
fill: Record<ButtonColor, Record<ButtonState, ButtonElementStyle>>;
|
|
84
|
+
outlined: Record<ButtonColor, Record<ButtonState, ButtonElementStyle>>;
|
|
85
|
+
empty: Record<ButtonColor, Record<ButtonState, ButtonElementStyle>>;
|
|
86
|
+
sizes: Record<ButtonSize, ButtonSizeStyle>;
|
|
87
|
+
};
|
|
88
|
+
sidebar: {
|
|
89
|
+
background: string;
|
|
90
|
+
width: number;
|
|
91
|
+
collapsedWidth: number;
|
|
92
|
+
text: {
|
|
93
|
+
default: string;
|
|
94
|
+
active: string;
|
|
95
|
+
hover: string;
|
|
96
|
+
};
|
|
97
|
+
item: {
|
|
98
|
+
default: {
|
|
99
|
+
background: string;
|
|
100
|
+
border: string;
|
|
101
|
+
padding: string;
|
|
102
|
+
height: number;
|
|
103
|
+
};
|
|
104
|
+
active: {
|
|
105
|
+
background: string;
|
|
106
|
+
borderLeft: string;
|
|
107
|
+
padding: string;
|
|
108
|
+
height: number;
|
|
109
|
+
};
|
|
110
|
+
hover: {
|
|
111
|
+
background: string;
|
|
112
|
+
border: string;
|
|
113
|
+
padding: string;
|
|
114
|
+
height: number;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
section: {
|
|
118
|
+
background: string;
|
|
119
|
+
padding: string;
|
|
120
|
+
title: {
|
|
121
|
+
color: string;
|
|
122
|
+
fontSize: string;
|
|
123
|
+
fontWeight: number;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
delimeter: {
|
|
127
|
+
color: string;
|
|
128
|
+
thickness: number;
|
|
129
|
+
margin: string;
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
//TODO check and refactoring
|
|
135
|
+
|
|
136
|
+
type ThemeColors = Theme['colors'];
|
|
137
|
+
type ColorCategory = keyof ThemeColors;
|
|
138
|
+
|
|
139
|
+
export type NestedColorPaths =
|
|
140
|
+
| keyof Pick<ThemeColors, 'background' | 'disable'>
|
|
141
|
+
| `${Extract<ColorCategory, 'primary'>}.${keyof ThemeColors['primary']}`
|
|
142
|
+
| `${Extract<ColorCategory, 'text'>}.${keyof ThemeColors['text']}`
|
|
143
|
+
| `${Extract<ColorCategory, 'stroke'>}.${keyof ThemeColors['stroke']}`;
|
|
144
|
+
|
|
145
|
+
export type ColorVariant = NestedColorPaths;
|
|
146
|
+
|
|
147
|
+
// Typography variants type
|
|
148
|
+
export type TypographyVariant = 'h1' | 'h2' | 'h3' | 'body';
|
package/src/Theme/utils.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DefaultTheme } from 'styled-components';
|
|
2
|
+
import { Breakpoint, ButtonColor, ButtonSize, ButtonState, ButtonVariant } from './types';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Helper function to resolve nested color paths from theme
|
|
@@ -39,3 +40,111 @@ export const resolveThemeColor = (theme: DefaultTheme, colorPath: string | undef
|
|
|
39
40
|
|
|
40
41
|
return undefined;
|
|
41
42
|
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Converts a pixel value to rem units
|
|
46
|
+
*
|
|
47
|
+
* @param pxValue - The pixel value to convert. Can be a number or a string with 'px' suffix
|
|
48
|
+
* @param baseSize - Base font size in pixels. Default is 16px (browser default)
|
|
49
|
+
* @returns The value in rem units as a string (e.g., "1.25rem")
|
|
50
|
+
*/
|
|
51
|
+
export const pxToRem = (pxValue: number | string, baseSize: number = 16): string => {
|
|
52
|
+
// If pxValue is a string with 'px' suffix, extract the numeric value
|
|
53
|
+
const numericValue = typeof pxValue === 'string' ? parseFloat(pxValue.replace('px', '')) : pxValue;
|
|
54
|
+
|
|
55
|
+
// Handle invalid values
|
|
56
|
+
if (isNaN(numericValue)) {
|
|
57
|
+
console.warn(`Invalid pixel value: ${pxValue}`);
|
|
58
|
+
return '0';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Convert to rem and round to 4 decimal places for precision
|
|
62
|
+
const remValue = (numericValue / baseSize).toFixed(4).replace(/\.?0+$/, '');
|
|
63
|
+
|
|
64
|
+
return `${remValue}rem`;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Recursively converts all pixel values in an object to rem units
|
|
69
|
+
*
|
|
70
|
+
* @param obj - The object containing values to convert
|
|
71
|
+
* @param baseSize - Base font size in pixels. Default is 16px
|
|
72
|
+
* @returns A new object with pixel values converted to rem
|
|
73
|
+
*/
|
|
74
|
+
export const convertPaletteToRem = (obj: Record<string, any>, baseSize: number = 14): Record<string, any> => {
|
|
75
|
+
const result: Record<string, any> = {};
|
|
76
|
+
|
|
77
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
78
|
+
// If the value is an object and not null, recursively convert its properties
|
|
79
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
80
|
+
result[key] = convertPaletteToRem(value, baseSize);
|
|
81
|
+
}
|
|
82
|
+
// If value is a string and contains 'px', convert it to rem
|
|
83
|
+
else if (typeof value === 'string' && value.includes('px')) {
|
|
84
|
+
result[key] = pxToRem(value, baseSize);
|
|
85
|
+
}
|
|
86
|
+
// Handle numeric values that represent pixels for specific properties
|
|
87
|
+
else if (
|
|
88
|
+
typeof value === 'number' &&
|
|
89
|
+
['fontSize', 'width', 'height', 'padding', 'margin', 'gap', 'borderRadius', 'size'].some((prop) =>
|
|
90
|
+
key.toLowerCase().includes(prop.toLowerCase())
|
|
91
|
+
)
|
|
92
|
+
) {
|
|
93
|
+
result[key] = pxToRem(value, baseSize);
|
|
94
|
+
}
|
|
95
|
+
// Keep other values unchanged
|
|
96
|
+
else {
|
|
97
|
+
result[key] = value;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return result;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Вспоміжні функції для роботи з палітрою
|
|
105
|
+
/**
|
|
106
|
+
* Функція для отримання стилів кнопки за варіантом, кольором, станом та розміром
|
|
107
|
+
*/
|
|
108
|
+
export const getButtonStyles = <V extends ButtonVariant>(
|
|
109
|
+
theme: DefaultTheme,
|
|
110
|
+
variant: ButtonVariant,
|
|
111
|
+
color: ButtonColor,
|
|
112
|
+
state: ButtonState
|
|
113
|
+
) => {
|
|
114
|
+
return theme.button[variant][color][state];
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const getButtonSizeStyles = (theme: DefaultTheme, size: ButtonSize) => {
|
|
118
|
+
return theme.button.sizes[size];
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// /**
|
|
122
|
+
// * Функція для отримання стилів інпута за варіантом, станом та розміром
|
|
123
|
+
// */
|
|
124
|
+
// export const getInputStyles = (
|
|
125
|
+
// variant: InputVariant = 'default',
|
|
126
|
+
// state: InputState = 'default',
|
|
127
|
+
// size: InputSize = 'medium'
|
|
128
|
+
// ) => {
|
|
129
|
+
// const variantStyles = theme.input[variant][state];
|
|
130
|
+
// const sizeStyles = theme.input.sizes[size];
|
|
131
|
+
|
|
132
|
+
// return {
|
|
133
|
+
// ...variantStyles,
|
|
134
|
+
// ...sizeStyles,
|
|
135
|
+
// };
|
|
136
|
+
// };
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Функція для отримання типографічних стилів
|
|
140
|
+
*/
|
|
141
|
+
export const getTypographyStyles = (theme: DefaultTheme, variant: string = 'body') => {
|
|
142
|
+
return theme.typography.variants[variant as keyof typeof theme.typography.variants] || theme.typography.variants.body;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Функція для отримання медіа-запитів для breakpoints
|
|
147
|
+
*/
|
|
148
|
+
export const getBreakpoint = (theme: DefaultTheme, size: Breakpoint = 'm') => {
|
|
149
|
+
return `@media (min-width: ${theme.breakpoints[size]}px)`;
|
|
150
|
+
};
|