@particle-network/ui-shared 0.0.1

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,31 @@
1
+ export type UXForegroundColor = 'default' | 'white' | 'foreground' | 'secondary' | 'tertiary' | 'primary' | 'success' | 'danger' | 'alert' | 'warning' | 'gold' | 'bullish' | 'bearish';
2
+ export type UXBackgroundColor = 'bg-default' | 'bg-300' | 'bg-200' | 'bg-400' | 'divider' | 'transparent' | 'overlay';
3
+ export type UXColor = UXForegroundColor | UXBackgroundColor;
4
+ export interface DynamicColors {
5
+ bullish?: string;
6
+ bearish?: string;
7
+ }
8
+ export type ThemeColors = Record<UXColor, string>;
9
+ export declare const colorMap: Record<'dark' | 'light', Record<UXColor, string>>;
10
+ export declare const foregroundColorList: readonly ["primary", "default", "secondary", "tertiary", "success", "danger", "alert", "warning", "gold", "bullish", "bearish"];
11
+ export declare const colorToCSSVariable: {
12
+ readonly default: "--heroui-foreground";
13
+ readonly foreground: "--heroui-foreground";
14
+ readonly secondary: "--heroui-foreground-300";
15
+ readonly white: "--color-white";
16
+ readonly tertiary: "--heroui-foreground-100";
17
+ readonly primary: "--heroui-primary";
18
+ readonly success: "--heroui-success";
19
+ readonly danger: "--heroui-danger";
20
+ readonly alert: "--heroui-alert";
21
+ readonly warning: "--heroui-warning";
22
+ readonly gold: "--heroui-gold";
23
+ readonly bullish: "--bullish-color";
24
+ readonly bearish: "--bearish-color";
25
+ };
26
+ export type ColorString = `#${string}`;
27
+ export declare function hexColorToHSLValue(hex: ColorString): string;
28
+ export declare function hexColorToHSL(hex: ColorString): string;
29
+ export declare function hslToHex(hslStr: string): string;
30
+ export declare const getHexColorFromCSSVariable: (color: UXForegroundColor) => string;
31
+ export declare const setColorWithOpacity: (color: string, opacity: number) => string;
package/dist/color.js ADDED
@@ -0,0 +1,183 @@
1
+ const colorMap = {
2
+ dark: {
3
+ default: '#FFFFFF',
4
+ white: '#FFFFFF',
5
+ foreground: '#FFFFFF',
6
+ secondary: '#A1A1AA',
7
+ tertiary: '#4E4E56',
8
+ primary: '#D745FF',
9
+ success: '#45B167',
10
+ danger: '#E84A5A',
11
+ alert: '#F57733',
12
+ warning: '#FF9821',
13
+ gold: '#FFB800',
14
+ bullish: '#FFAC34',
15
+ bearish: '#E84A5A',
16
+ 'bg-default': '#000000',
17
+ 'bg-200': '#1F1F23',
18
+ 'bg-300': '#17171C',
19
+ 'bg-400': '#0F0F0F',
20
+ overlay: '#17171C',
21
+ divider: '#282828',
22
+ transparent: 'transparent'
23
+ },
24
+ light: {
25
+ default: '#000000',
26
+ white: '#FFFFFF',
27
+ foreground: '#000000',
28
+ secondary: '#767A80',
29
+ tertiary: '#C0C0C9',
30
+ primary: '#D745FF',
31
+ success: '#2E9F4A',
32
+ danger: '#DE4A40',
33
+ alert: '#E65E16',
34
+ warning: '#FF9821',
35
+ gold: '#F38300',
36
+ bullish: '#FFAC34',
37
+ bearish: '#E84A5A',
38
+ 'bg-default': '#FFFFFF',
39
+ 'bg-200': '#E8E8ED',
40
+ 'bg-300': '#F0F0F2',
41
+ 'bg-400': '#F8F8FA',
42
+ overlay: '#FFFFFF',
43
+ divider: '#E0E0E6',
44
+ transparent: 'transparent'
45
+ }
46
+ };
47
+ const foregroundColorList = [
48
+ 'primary',
49
+ 'default',
50
+ 'secondary',
51
+ 'tertiary',
52
+ 'success',
53
+ 'danger',
54
+ 'alert',
55
+ 'warning',
56
+ 'gold',
57
+ 'bullish',
58
+ 'bearish'
59
+ ];
60
+ const colorToCSSVariable = {
61
+ default: '--heroui-foreground',
62
+ foreground: '--heroui-foreground',
63
+ secondary: '--heroui-foreground-300',
64
+ white: '--color-white',
65
+ tertiary: '--heroui-foreground-100',
66
+ primary: '--heroui-primary',
67
+ success: '--heroui-success',
68
+ danger: '--heroui-danger',
69
+ alert: '--heroui-alert',
70
+ warning: '--heroui-warning',
71
+ gold: '--heroui-gold',
72
+ bullish: '--bullish-color',
73
+ bearish: '--bearish-color'
74
+ };
75
+ function hexColorToHSLValue(hex) {
76
+ const hexWithoutHash = hex.replace('#', '');
77
+ const r = parseInt(hexWithoutHash.substring(0, 2), 16) / 255;
78
+ const g = parseInt(hexWithoutHash.substring(2, 4), 16) / 255;
79
+ const b = parseInt(hexWithoutHash.substring(4, 6), 16) / 255;
80
+ const max = Math.max(r, g, b);
81
+ const min = Math.min(r, g, b);
82
+ let h = 0;
83
+ let s = 0;
84
+ const l = (max + min) / 2;
85
+ if (max === min) {
86
+ h = 0;
87
+ s = 0;
88
+ } else {
89
+ const d = max - min;
90
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
91
+ switch(max){
92
+ case r:
93
+ h = (g - b) / d + (g < b ? 6 : 0);
94
+ break;
95
+ case g:
96
+ h = (b - r) / d + 2;
97
+ break;
98
+ case b:
99
+ h = (r - g) / d + 4;
100
+ break;
101
+ default:
102
+ h = 0;
103
+ break;
104
+ }
105
+ h /= 6;
106
+ }
107
+ return `${Math.round(360 * h)}, ${Math.round(100 * s)}%, ${Math.round(100 * l)}%`;
108
+ }
109
+ function hexColorToHSL(hex) {
110
+ const value = hexColorToHSLValue(hex);
111
+ return `hsl(${value})`;
112
+ }
113
+ function hslToHex(hslStr) {
114
+ const hslMatch = hslStr.match(/(\d*\.?\d+)\s+(\d*\.?\d+)%?\s+(\d*\.?\d+)%?/);
115
+ if (!hslMatch) throw new Error('Invalid HSL format');
116
+ let h = parseFloat(hslMatch[1]);
117
+ let s = parseFloat(hslMatch[2]);
118
+ let l = parseFloat(hslMatch[3]);
119
+ h = h % 360 / 360;
120
+ s = Math.min(100, s) / 100;
121
+ l = Math.min(100, l) / 100;
122
+ const c = (1 - Math.abs(2 * l - 1)) * s;
123
+ const x = c * (1 - Math.abs(6 * h % 2 - 1));
124
+ const m = l - c / 2;
125
+ let r, g, b;
126
+ if (h < 1 / 6) [r, g, b] = [
127
+ c,
128
+ x,
129
+ 0
130
+ ];
131
+ else if (h < 2 / 6) [r, g, b] = [
132
+ x,
133
+ c,
134
+ 0
135
+ ];
136
+ else if (h < 0.5) [r, g, b] = [
137
+ 0,
138
+ c,
139
+ x
140
+ ];
141
+ else if (h < 4 / 6) [r, g, b] = [
142
+ 0,
143
+ x,
144
+ c
145
+ ];
146
+ else if (h < 5 / 6) [r, g, b] = [
147
+ x,
148
+ 0,
149
+ c
150
+ ];
151
+ else [r, g, b] = [
152
+ c,
153
+ 0,
154
+ x
155
+ ];
156
+ const toHex = (n)=>Math.round((n + m) * 255).toString(16).padStart(2, '0');
157
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase();
158
+ }
159
+ const getHexColorFromCSSVariable = (color)=>{
160
+ const rootStyles = getComputedStyle(document.documentElement);
161
+ const value = rootStyles.getPropertyValue(colorToCSSVariable[color]).trim();
162
+ if (!value) return '#000000';
163
+ return value.startsWith('#') ? value : hslToHex(value);
164
+ };
165
+ const setColorWithOpacity = (color, opacity)=>{
166
+ let r, g, b;
167
+ if (color.startsWith('#')) {
168
+ const hex = color.slice(1);
169
+ const bigint = parseInt(hex, 16);
170
+ r = bigint >> 16 & 255;
171
+ g = bigint >> 8 & 255;
172
+ b = 255 & bigint;
173
+ } else {
174
+ const rgbaMatch = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*\d*\.?\d+)?\)$/);
175
+ if (rgbaMatch) {
176
+ r = parseInt(rgbaMatch[1]);
177
+ g = parseInt(rgbaMatch[2]);
178
+ b = parseInt(rgbaMatch[3]);
179
+ } else throw new Error('Invalid color format');
180
+ }
181
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`;
182
+ };
183
+ export { colorMap, colorToCSSVariable, foregroundColorList, getHexColorFromCSSVariable, hexColorToHSL, hexColorToHSLValue, hslToHex, setColorWithOpacity };
@@ -0,0 +1,5 @@
1
+ export * from './color';
2
+ export * from './radius';
3
+ export * from './size';
4
+ export * from './spacing';
5
+ export * from './theme';
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./color.js";
2
+ export * from "./radius.js";
3
+ export * from "./size.js";
4
+ export * from "./spacing.js";
5
+ export * from "./theme.js";
@@ -0,0 +1,10 @@
1
+ export type UXRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
2
+ export type RadiusType = UXRadius | number;
3
+ export declare const radiusMap: Record<UXRadius, number>;
4
+ export interface RadiusScale {
5
+ none: number;
6
+ sm: number;
7
+ md: number;
8
+ lg: number;
9
+ full: number;
10
+ }
package/dist/radius.js ADDED
@@ -0,0 +1,8 @@
1
+ const radiusMap = {
2
+ none: 0,
3
+ sm: 6,
4
+ md: 10,
5
+ lg: 14,
6
+ full: 9999
7
+ };
8
+ export { radiusMap };
package/dist/size.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export type UXSize = 'sm' | 'md' | 'lg';
2
+ export declare const sizeMap: Record<UXSize, number>;
package/dist/size.js ADDED
@@ -0,0 +1,6 @@
1
+ const sizeMap = {
2
+ sm: 24,
3
+ md: 30,
4
+ lg: 44
5
+ };
6
+ export { sizeMap };
@@ -0,0 +1,4 @@
1
+ export type UXSpacing = 'xs' | 'sm' | 'md' | 'lg';
2
+ export type SpacingType = 'xs' | 'sm' | 'md' | 'lg' | number;
3
+ export declare const spacingMap: Record<UXSpacing, number>;
4
+ export type SpacingScale = Record<UXSpacing, number>;
@@ -0,0 +1,7 @@
1
+ const spacingMap = {
2
+ xs: 2,
3
+ sm: 6,
4
+ md: 10,
5
+ lg: 14
6
+ };
7
+ export { spacingMap };
@@ -0,0 +1,6 @@
1
+ type Theme = 'dark' | 'light';
2
+ /**
3
+ * 监听主题变化(兼容 data-theme 和 class 两种方式)
4
+ */
5
+ export declare function useTheme(): Theme;
6
+ export {};
package/dist/theme.js ADDED
@@ -0,0 +1,27 @@
1
+ import { useEffect, useState } from "react";
2
+ function getCurrentTheme() {
3
+ const html = document.documentElement;
4
+ if (html.hasAttribute('data-theme')) return 'dark' === html.getAttribute('data-theme') ? 'dark' : 'light';
5
+ return html.classList.contains('dark') ? 'dark' : 'light';
6
+ }
7
+ function useTheme() {
8
+ const [theme, setTheme] = useState(getCurrentTheme);
9
+ useEffect(()=>{
10
+ const observer = new MutationObserver(()=>{
11
+ const newTheme = getCurrentTheme();
12
+ if (newTheme !== theme) setTheme(newTheme);
13
+ });
14
+ observer.observe(document.documentElement, {
15
+ attributes: true,
16
+ attributeFilter: [
17
+ 'class',
18
+ 'data-theme'
19
+ ]
20
+ });
21
+ return ()=>observer.disconnect();
22
+ }, [
23
+ theme
24
+ ]);
25
+ return theme;
26
+ }
27
+ export { useTheme };
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@particle-network/ui-shared",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js"
9
+ },
10
+ "./tailwind-preset": "./tailwind-preset.js"
11
+ },
12
+ "types": "./dist/index.d.ts",
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "rslib build",
18
+ "dev": "rslib build --watch",
19
+ "type-check": "npx tsc --noEmit -p ./tsconfig.json",
20
+ "lint": "eslint . --no-error-on-unmatched-pattern --quiet",
21
+ "lint:fix": "eslint . --fix --no-error-on-unmatched-pattern --quiet",
22
+ "clean": "rm -rf .turbo node_modules dist"
23
+ },
24
+ "devDependencies": {
25
+ "@rsbuild/plugin-react": "^1.3.5",
26
+ "@rslib/core": "^0.12.3",
27
+ "@types/react": "^19.0.0",
28
+ "react": "^19.0.0",
29
+ "typescript": "^5.8.3"
30
+ }
31
+ }