@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.
@@ -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';
@@ -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
+ };