@deneb-ui/core 2.0.67 → 2.0.69
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.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/theme/contrast.d.ts +19 -0
- package/dist/theme/contrast.js +60 -0
- package/dist/theme/cssGenerator.d.ts +6 -0
- package/dist/theme/cssGenerator.js +100 -0
- package/dist/theme/fonts.d.ts +4 -0
- package/dist/theme/fonts.js +50 -0
- package/dist/theme/index.d.ts +6 -0
- package/dist/theme/index.js +22 -0
- package/dist/theme/palettes.d.ts +2 -0
- package/dist/theme/palettes.js +142 -0
- package/dist/theme/parser.d.ts +4 -0
- package/dist/theme/parser.js +87 -0
- package/dist/theme/types.d.ts +197 -0
- package/dist/theme/types.js +2 -0
- package/package.json +6 -2
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -23,3 +23,4 @@ __exportStar(require("./engine/domPatcher"), exports);
|
|
|
23
23
|
__exportStar(require("./engine/tokenResolver"), exports);
|
|
24
24
|
__exportStar(require("./engine/deepMerge"), exports);
|
|
25
25
|
__exportStar(require("./validation/styleSchemaValidator"), exports);
|
|
26
|
+
__exportStar(require("./theme"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether a color is considered "dark" based on perceived relative luminance.
|
|
3
|
+
* Uses standard ITU-R BT.601 formula (r*299 + g*587 + b*114) / 1000 < 130.
|
|
4
|
+
* Supports 3-digit and 6-digit hex values.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isDarkColor(color?: unknown): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Returns an auto-contrasting text color (default white for dark backgrounds, dark slate for light backgrounds).
|
|
9
|
+
*/
|
|
10
|
+
export declare function getAutoContrastTextColor(backgroundColor?: string, lightText?: string, darkText?: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Normalizes a 3-digit or 6-digit hex color to canonical 6-digit lowercase hex.
|
|
13
|
+
* Returns fallback if invalid.
|
|
14
|
+
*/
|
|
15
|
+
export declare function toHexColor(color: string | undefined, fallback: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Parses and returns a valid 6-char hex string, or null if invalid.
|
|
18
|
+
*/
|
|
19
|
+
export declare function normalizeHexColor(color: string | undefined): string | null;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDarkColor = isDarkColor;
|
|
4
|
+
exports.getAutoContrastTextColor = getAutoContrastTextColor;
|
|
5
|
+
exports.toHexColor = toHexColor;
|
|
6
|
+
exports.normalizeHexColor = normalizeHexColor;
|
|
7
|
+
/**
|
|
8
|
+
* Determines whether a color is considered "dark" based on perceived relative luminance.
|
|
9
|
+
* Uses standard ITU-R BT.601 formula (r*299 + g*587 + b*114) / 1000 < 130.
|
|
10
|
+
* Supports 3-digit and 6-digit hex values.
|
|
11
|
+
*/
|
|
12
|
+
function isDarkColor(color) {
|
|
13
|
+
if (typeof color !== 'string' || !color)
|
|
14
|
+
return false;
|
|
15
|
+
const hex = color.trim().toLowerCase();
|
|
16
|
+
if (!/^#[0-9a-f]{3,6}$/i.test(hex))
|
|
17
|
+
return false;
|
|
18
|
+
const fullHex = hex.length === 4
|
|
19
|
+
? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`
|
|
20
|
+
: hex;
|
|
21
|
+
const r = Number.parseInt(fullHex.slice(1, 3), 16);
|
|
22
|
+
const g = Number.parseInt(fullHex.slice(3, 5), 16);
|
|
23
|
+
const b = Number.parseInt(fullHex.slice(5, 7), 16);
|
|
24
|
+
return (r * 299 + g * 587 + b * 114) / 1000 < 130;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Returns an auto-contrasting text color (default white for dark backgrounds, dark slate for light backgrounds).
|
|
28
|
+
*/
|
|
29
|
+
function getAutoContrastTextColor(backgroundColor, lightText = '#ffffff', darkText = '#0f172a') {
|
|
30
|
+
return isDarkColor(backgroundColor) ? lightText : darkText;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Normalizes a 3-digit or 6-digit hex color to canonical 6-digit lowercase hex.
|
|
34
|
+
* Returns fallback if invalid.
|
|
35
|
+
*/
|
|
36
|
+
function toHexColor(color, fallback) {
|
|
37
|
+
if (!color)
|
|
38
|
+
return fallback;
|
|
39
|
+
const trimmed = color.trim();
|
|
40
|
+
if (/^#[0-9a-f]{6}$/i.test(trimmed))
|
|
41
|
+
return trimmed.toLowerCase();
|
|
42
|
+
if (/^#[0-9a-f]{3}$/i.test(trimmed)) {
|
|
43
|
+
return `#${trimmed[1]}${trimmed[1]}${trimmed[2]}${trimmed[2]}${trimmed[3]}${trimmed[3]}`.toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
return fallback;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Parses and returns a valid 6-char hex string, or null if invalid.
|
|
49
|
+
*/
|
|
50
|
+
function normalizeHexColor(color) {
|
|
51
|
+
if (!color)
|
|
52
|
+
return null;
|
|
53
|
+
const trimmed = color.trim();
|
|
54
|
+
if (/^#[0-9a-f]{6}$/i.test(trimmed))
|
|
55
|
+
return trimmed.toLowerCase();
|
|
56
|
+
if (/^#[0-9a-f]{3}$/i.test(trimmed)) {
|
|
57
|
+
return `#${trimmed[1]}${trimmed[1]}${trimmed[2]}${trimmed[2]}${trimmed[3]}${trimmed[3]}`.toLowerCase();
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TemplateThemeShape } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Computes all canonical CSS variables for a theme, automatically resolving
|
|
4
|
+
* dark/light mode contrasts, button states, card surfaces, and input tokens.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateThemeVariables(theme?: TemplateThemeShape | null): Record<string, string>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateThemeVariables = generateThemeVariables;
|
|
4
|
+
const contrast_1 = require("./contrast");
|
|
5
|
+
/**
|
|
6
|
+
* Computes all canonical CSS variables for a theme, automatically resolving
|
|
7
|
+
* dark/light mode contrasts, button states, card surfaces, and input tokens.
|
|
8
|
+
*/
|
|
9
|
+
function generateThemeVariables(theme) {
|
|
10
|
+
const customVars = {};
|
|
11
|
+
if (theme) {
|
|
12
|
+
for (const [key, val] of Object.entries(theme)) {
|
|
13
|
+
if (typeof val === 'string' || typeof val === 'number') {
|
|
14
|
+
const cssVarName = `--${key.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()}`;
|
|
15
|
+
customVars[cssVarName] = String(val);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const isDark = (0, contrast_1.isDarkColor)(theme?.backgroundColor);
|
|
20
|
+
const bgColor = theme?.backgroundColor || (isDark ? '#0f172a' : '#ffffff');
|
|
21
|
+
const textColor = theme?.textColor || (isDark ? '#f8fafc' : '#0f172a');
|
|
22
|
+
const mutedColor = theme?.mutedTextColor ||
|
|
23
|
+
(isDark ? 'rgba(248, 250, 252, 0.7)' : '#64748b');
|
|
24
|
+
const borderColor = theme?.borderColor ||
|
|
25
|
+
(isDark ? 'rgba(255, 255, 255, 0.1)' : '#e2e8f0');
|
|
26
|
+
const cardBg = theme?.cardBackgroundColor ||
|
|
27
|
+
theme?.surfaceColor ||
|
|
28
|
+
(isDark ? '#111a2e' : '#ffffff');
|
|
29
|
+
const cardBorder = isDark ? 'rgba(255, 255, 255, 0.09)' : borderColor;
|
|
30
|
+
const primaryColor = theme?.primaryColor || '#2563eb';
|
|
31
|
+
const secondaryColor = theme?.secondaryColor || (isDark ? '#1e293b' : '#0f172a');
|
|
32
|
+
const accentColor = theme?.accentColor || '#14b8a6';
|
|
33
|
+
const buttonBg = theme?.buttonBackgroundColor || primaryColor;
|
|
34
|
+
const autoButtonText = (0, contrast_1.getAutoContrastTextColor)(buttonBg);
|
|
35
|
+
const buttonText = theme?.buttonTextColor || autoButtonText;
|
|
36
|
+
const buttonSecondaryBg = isDark
|
|
37
|
+
? 'rgba(255, 255, 255, 0.08)'
|
|
38
|
+
: secondaryColor && !(0, contrast_1.isDarkColor)(secondaryColor)
|
|
39
|
+
? secondaryColor
|
|
40
|
+
: '#f1f5f9';
|
|
41
|
+
const buttonSecondaryText = isDark ? '#f8fafc' : '#0f172a';
|
|
42
|
+
return {
|
|
43
|
+
'--brand-color': primaryColor,
|
|
44
|
+
'--brand-primary': primaryColor,
|
|
45
|
+
'--primary-color': primaryColor,
|
|
46
|
+
'--color-primary': primaryColor,
|
|
47
|
+
'--brand-secondary': secondaryColor,
|
|
48
|
+
'--secondary-color': secondaryColor,
|
|
49
|
+
'--brand-accent': accentColor,
|
|
50
|
+
'--accent-color': accentColor,
|
|
51
|
+
'--page-background': bgColor,
|
|
52
|
+
'--page-bg': bgColor,
|
|
53
|
+
'--background': bgColor,
|
|
54
|
+
'--page-text': textColor,
|
|
55
|
+
'--heading-color': theme?.headingColor || (isDark ? '#ffffff' : secondaryColor),
|
|
56
|
+
'--color-heading': theme?.headingColor || (isDark ? '#ffffff' : secondaryColor),
|
|
57
|
+
'--muted-text': mutedColor,
|
|
58
|
+
'--text-muted': mutedColor,
|
|
59
|
+
'--color-text': textColor,
|
|
60
|
+
'--color-text-muted': mutedColor,
|
|
61
|
+
'--link-color': theme?.linkColor || primaryColor,
|
|
62
|
+
'--border-primary': borderColor,
|
|
63
|
+
'--border': borderColor,
|
|
64
|
+
'--color-border': borderColor,
|
|
65
|
+
'--color-surface': isDark ? 'rgba(255,255,255,0.05)' : '#ffffff',
|
|
66
|
+
'--card-bg': cardBg,
|
|
67
|
+
'--card-border': cardBorder,
|
|
68
|
+
'--product-card-bg': cardBg,
|
|
69
|
+
'--product-card-border': cardBorder,
|
|
70
|
+
'--tag-bg': isDark
|
|
71
|
+
? 'rgba(255, 255, 255, 0.08)'
|
|
72
|
+
: 'rgba(241, 245, 249, 0.9)',
|
|
73
|
+
'--tag-color': mutedColor,
|
|
74
|
+
'--card-shadow': isDark
|
|
75
|
+
? '0 10px 25px -5px rgba(0, 0, 0, 0.4)'
|
|
76
|
+
: '0 10px 25px -5px rgba(0, 0, 0, 0.05)',
|
|
77
|
+
'--header-bg': theme?.headerBackgroundColor || (isDark ? 'rgba(15, 23, 42, 0.85)' : 'rgba(255, 255, 255, 0.82)'),
|
|
78
|
+
'--input-bg': isDark ? '#1e293b' : '#ffffff',
|
|
79
|
+
'--input-border': isDark ? 'rgba(255, 255, 255, 0.15)' : '#cbd5e1',
|
|
80
|
+
'--input-color': textColor,
|
|
81
|
+
// Dedicated Button Design Tokens
|
|
82
|
+
'--button-bg': buttonBg,
|
|
83
|
+
'--button-text': buttonText,
|
|
84
|
+
'--button-primary-bg': buttonBg,
|
|
85
|
+
'--button-primary-text': buttonText,
|
|
86
|
+
'--button-secondary-bg': buttonSecondaryBg,
|
|
87
|
+
'--button-secondary-text': buttonSecondaryText,
|
|
88
|
+
'--button-outline-border': isDark ? 'rgba(255, 255, 255, 0.22)' : 'currentColor',
|
|
89
|
+
'--button-outline-text': isDark ? '#f8fafc' : textColor,
|
|
90
|
+
'--button-ghost-text': isDark ? '#f8fafc' : textColor,
|
|
91
|
+
'--hero-min-height': theme?.heroMinHeight || '72vh',
|
|
92
|
+
'--section-padding': theme?.sectionPadding || '5rem',
|
|
93
|
+
'--base-size': theme?.baseSize || '16px',
|
|
94
|
+
'--heading-font': theme?.headingFont || 'Inter, sans-serif',
|
|
95
|
+
'--body-font': theme?.bodyFont || 'Inter, sans-serif',
|
|
96
|
+
'--border-radius': theme?.borderRadius || '8px',
|
|
97
|
+
'--content-align': theme?.align || 'left',
|
|
98
|
+
...customVars,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { FontPairing } from './types';
|
|
2
|
+
export declare const GLOBAL_FONT_OPTIONS: readonly ["Inter", "Playfair Display", "DM Sans", "Poppins", "Montserrat", "Plus Jakarta Sans", "Georgia", "Editorial Serif"];
|
|
3
|
+
export type GlobalFontOption = (typeof GLOBAL_FONT_OPTIONS)[number];
|
|
4
|
+
export declare const FONT_PAIRINGS: FontPairing[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FONT_PAIRINGS = exports.GLOBAL_FONT_OPTIONS = void 0;
|
|
4
|
+
exports.GLOBAL_FONT_OPTIONS = [
|
|
5
|
+
'Inter',
|
|
6
|
+
'Playfair Display',
|
|
7
|
+
'DM Sans',
|
|
8
|
+
'Poppins',
|
|
9
|
+
'Montserrat',
|
|
10
|
+
'Plus Jakarta Sans',
|
|
11
|
+
'Georgia',
|
|
12
|
+
'Editorial Serif',
|
|
13
|
+
];
|
|
14
|
+
exports.FONT_PAIRINGS = [
|
|
15
|
+
{
|
|
16
|
+
id: 'modern-clean',
|
|
17
|
+
name: 'Modern & Clean',
|
|
18
|
+
headingFont: 'Plus Jakarta Sans',
|
|
19
|
+
bodyFont: 'Inter',
|
|
20
|
+
description: 'Crisp, contemporary tech and SaaS feel with high readability',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'editorial-luxury',
|
|
24
|
+
name: 'Editorial Luxury',
|
|
25
|
+
headingFont: 'Playfair Display',
|
|
26
|
+
bodyFont: 'Inter',
|
|
27
|
+
description: 'Elegant serif headline paired with neutral modern body text',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'tech-forward',
|
|
31
|
+
name: 'Tech Forward',
|
|
32
|
+
headingFont: 'Inter',
|
|
33
|
+
bodyFont: 'Inter',
|
|
34
|
+
description: 'Minimalist, uniform sans-serif design system',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'vibrant-lifestyle',
|
|
38
|
+
name: 'Vibrant Lifestyle',
|
|
39
|
+
headingFont: 'Poppins',
|
|
40
|
+
bodyFont: 'DM Sans',
|
|
41
|
+
description: 'Warm, geometric sans pairing suited for retail and wellness',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'classic-prestige',
|
|
45
|
+
name: 'Classic Prestige',
|
|
46
|
+
headingFont: 'Montserrat',
|
|
47
|
+
bodyFont: 'Inter',
|
|
48
|
+
description: 'Authoritative, balanced typography for premium brands',
|
|
49
|
+
},
|
|
50
|
+
];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./contrast"), exports);
|
|
19
|
+
__exportStar(require("./palettes"), exports);
|
|
20
|
+
__exportStar(require("./fonts"), exports);
|
|
21
|
+
__exportStar(require("./parser"), exports);
|
|
22
|
+
__exportStar(require("./cssGenerator"), exports);
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.THEME_PALETTES = void 0;
|
|
4
|
+
exports.THEME_PALETTES = [
|
|
5
|
+
// --- Light Themes ---
|
|
6
|
+
{
|
|
7
|
+
id: 'classic-luxe',
|
|
8
|
+
name: 'Classic Luxe',
|
|
9
|
+
badge: 'Light • Warm Luxe',
|
|
10
|
+
mode: 'light',
|
|
11
|
+
primary: '#1e293b',
|
|
12
|
+
secondary: '#d97706',
|
|
13
|
+
accent: '#f59e0b',
|
|
14
|
+
background: '#fdfbf7',
|
|
15
|
+
card: '#ffffff',
|
|
16
|
+
text: '#1e293b',
|
|
17
|
+
muted: '#64748b',
|
|
18
|
+
buttonBg: '#1e293b',
|
|
19
|
+
buttonText: '#ffffff',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'ocean-modern',
|
|
23
|
+
name: 'Ocean Modern',
|
|
24
|
+
badge: 'Light • Crisp Ocean',
|
|
25
|
+
mode: 'light',
|
|
26
|
+
primary: '#0284c7',
|
|
27
|
+
secondary: '#0369a1',
|
|
28
|
+
accent: '#38bdf8',
|
|
29
|
+
background: '#f8fafc',
|
|
30
|
+
card: '#ffffff',
|
|
31
|
+
text: '#0f172a',
|
|
32
|
+
muted: '#64748b',
|
|
33
|
+
buttonBg: '#0284c7',
|
|
34
|
+
buttonText: '#ffffff',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'forest-emerald',
|
|
38
|
+
name: 'Forest Emerald',
|
|
39
|
+
badge: 'Light • Organic Green',
|
|
40
|
+
mode: 'light',
|
|
41
|
+
primary: '#065f46',
|
|
42
|
+
secondary: '#047857',
|
|
43
|
+
accent: '#10b981',
|
|
44
|
+
background: '#f0fdf4',
|
|
45
|
+
card: '#ffffff',
|
|
46
|
+
text: '#064e3b',
|
|
47
|
+
muted: '#475569',
|
|
48
|
+
buttonBg: '#065f46',
|
|
49
|
+
buttonText: '#ffffff',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'warm-terracotta',
|
|
53
|
+
name: 'Warm Terracotta',
|
|
54
|
+
badge: 'Light • Artisanal',
|
|
55
|
+
mode: 'light',
|
|
56
|
+
primary: '#c2410c',
|
|
57
|
+
secondary: '#ea580c',
|
|
58
|
+
accent: '#f97316',
|
|
59
|
+
background: '#fffaf5',
|
|
60
|
+
card: '#ffffff',
|
|
61
|
+
text: '#431407',
|
|
62
|
+
muted: '#78350f',
|
|
63
|
+
buttonBg: '#c2410c',
|
|
64
|
+
buttonText: '#ffffff',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'velvet-berry',
|
|
68
|
+
name: 'Velvet Berry',
|
|
69
|
+
badge: 'Light • Vibrant Chic',
|
|
70
|
+
mode: 'light',
|
|
71
|
+
primary: '#9f1239',
|
|
72
|
+
secondary: '#be123c',
|
|
73
|
+
accent: '#f43f5e',
|
|
74
|
+
background: '#fff5f7',
|
|
75
|
+
card: '#ffffff',
|
|
76
|
+
text: '#4c0519',
|
|
77
|
+
muted: '#881337',
|
|
78
|
+
buttonBg: '#9f1239',
|
|
79
|
+
buttonText: '#ffffff',
|
|
80
|
+
},
|
|
81
|
+
// --- Dark Themes ---
|
|
82
|
+
{
|
|
83
|
+
id: 'sleek-obsidian',
|
|
84
|
+
name: 'Sleek Obsidian',
|
|
85
|
+
badge: 'Dark • Obsidian',
|
|
86
|
+
mode: 'dark',
|
|
87
|
+
primary: '#60a5fa',
|
|
88
|
+
secondary: '#38bdf8',
|
|
89
|
+
accent: '#93c5fd',
|
|
90
|
+
background: '#090d16',
|
|
91
|
+
card: '#131b2e',
|
|
92
|
+
text: '#f8fafc',
|
|
93
|
+
muted: '#94a3b8',
|
|
94
|
+
buttonBg: '#60a5fa',
|
|
95
|
+
buttonText: '#090d16',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: 'midnight-cyber',
|
|
99
|
+
name: 'Midnight Cyber',
|
|
100
|
+
badge: 'Dark • Neon Cyber',
|
|
101
|
+
mode: 'dark',
|
|
102
|
+
primary: '#818cf8',
|
|
103
|
+
secondary: '#6366f1',
|
|
104
|
+
accent: '#22d3ee',
|
|
105
|
+
background: '#09090b',
|
|
106
|
+
card: '#18181b',
|
|
107
|
+
text: '#f4f4f5',
|
|
108
|
+
muted: '#a1a1aa',
|
|
109
|
+
buttonBg: '#818cf8',
|
|
110
|
+
buttonText: '#09090b',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 'royal-gold-dark',
|
|
114
|
+
name: 'Royal Gold & Dark',
|
|
115
|
+
badge: 'Dark • Imperial Gold',
|
|
116
|
+
mode: 'dark',
|
|
117
|
+
primary: '#f59e0b',
|
|
118
|
+
secondary: '#d97706',
|
|
119
|
+
accent: '#fbbf24',
|
|
120
|
+
background: '#0c0a09',
|
|
121
|
+
card: '#1c1917',
|
|
122
|
+
text: '#f5f5f4',
|
|
123
|
+
muted: '#a8a29e',
|
|
124
|
+
buttonBg: '#f59e0b',
|
|
125
|
+
buttonText: '#0c0a09',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'emerald-nocturne',
|
|
129
|
+
name: 'Emerald Nocturne',
|
|
130
|
+
badge: 'Dark • Deep Emerald',
|
|
131
|
+
mode: 'dark',
|
|
132
|
+
primary: '#34d399',
|
|
133
|
+
secondary: '#10b981',
|
|
134
|
+
accent: '#6ee7b7',
|
|
135
|
+
background: '#022c22',
|
|
136
|
+
card: '#064e3b',
|
|
137
|
+
text: '#ecfdf5',
|
|
138
|
+
muted: '#a7f3d0',
|
|
139
|
+
buttonBg: '#34d399',
|
|
140
|
+
buttonText: '#022c22',
|
|
141
|
+
},
|
|
142
|
+
];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { VisualCustomization, TemplateThemeShape } from './types';
|
|
2
|
+
export declare function parseVisualCustomization(value: unknown): VisualCustomization;
|
|
3
|
+
export declare function customizationToTheme(customization: VisualCustomization): TemplateThemeShape;
|
|
4
|
+
export declare function mergeVisualCustomizationIntoTheme(baseTheme: TemplateThemeShape | null | undefined, customization: unknown): TemplateThemeShape | null;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseVisualCustomization = parseVisualCustomization;
|
|
4
|
+
exports.customizationToTheme = customizationToTheme;
|
|
5
|
+
exports.mergeVisualCustomizationIntoTheme = mergeVisualCustomizationIntoTheme;
|
|
6
|
+
function isPlainRecord(value) {
|
|
7
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function parseVisualCustomization(value) {
|
|
10
|
+
if (!isPlainRecord(value))
|
|
11
|
+
return { version: 1 };
|
|
12
|
+
return {
|
|
13
|
+
version: 1,
|
|
14
|
+
colors: isPlainRecord(value.colors)
|
|
15
|
+
? value.colors
|
|
16
|
+
: undefined,
|
|
17
|
+
colorReplacements: isPlainRecord(value.colorReplacements)
|
|
18
|
+
? value.colorReplacements
|
|
19
|
+
: undefined,
|
|
20
|
+
typography: isPlainRecord(value.typography)
|
|
21
|
+
? value.typography
|
|
22
|
+
: undefined,
|
|
23
|
+
spacing: isPlainRecord(value.spacing)
|
|
24
|
+
? value.spacing
|
|
25
|
+
: undefined,
|
|
26
|
+
layout: isPlainRecord(value.layout)
|
|
27
|
+
? value.layout
|
|
28
|
+
: undefined,
|
|
29
|
+
components: isPlainRecord(value.components)
|
|
30
|
+
? value.components
|
|
31
|
+
: undefined,
|
|
32
|
+
sections: isPlainRecord(value.sections)
|
|
33
|
+
? value.sections
|
|
34
|
+
: undefined,
|
|
35
|
+
elementStyles: isPlainRecord(value.elementStyles)
|
|
36
|
+
? value.elementStyles
|
|
37
|
+
: undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function customizationToTheme(customization) {
|
|
41
|
+
const colors = customization.colors ?? {};
|
|
42
|
+
return {
|
|
43
|
+
designCustomizationVersion: 1,
|
|
44
|
+
colorReplacements: customization.colorReplacements,
|
|
45
|
+
primaryColor: colors.primary,
|
|
46
|
+
secondaryColor: colors.secondary,
|
|
47
|
+
accentColor: colors.accent,
|
|
48
|
+
backgroundColor: colors.background,
|
|
49
|
+
textColor: colors.text,
|
|
50
|
+
surfaceColor: colors.surface ?? colors.cardBackground,
|
|
51
|
+
surfaceAltColor: colors.surfaceAlt,
|
|
52
|
+
headingColor: colors.heading ?? colors.text,
|
|
53
|
+
mutedTextColor: colors.mutedText,
|
|
54
|
+
borderColor: colors.border,
|
|
55
|
+
headerBackgroundColor: colors.headerBackground,
|
|
56
|
+
footerBackgroundColor: colors.footerBackground,
|
|
57
|
+
cardBackgroundColor: colors.cardBackground ?? colors.surface,
|
|
58
|
+
buttonBackgroundColor: colors.buttonBackground,
|
|
59
|
+
buttonTextColor: colors.buttonText,
|
|
60
|
+
...customization.typography,
|
|
61
|
+
...customization.spacing,
|
|
62
|
+
...customization.layout,
|
|
63
|
+
...customization.components,
|
|
64
|
+
sections: customization.sections,
|
|
65
|
+
elementStyles: customization.elementStyles,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function mergeVisualCustomizationIntoTheme(baseTheme, customization) {
|
|
69
|
+
const parsed = parseVisualCustomization(customization);
|
|
70
|
+
const hasOverrides = [
|
|
71
|
+
parsed.colors,
|
|
72
|
+
parsed.colorReplacements,
|
|
73
|
+
parsed.typography,
|
|
74
|
+
parsed.spacing,
|
|
75
|
+
parsed.layout,
|
|
76
|
+
parsed.components,
|
|
77
|
+
parsed.sections,
|
|
78
|
+
parsed.elementStyles,
|
|
79
|
+
].some((group) => Boolean(group &&
|
|
80
|
+
Object.values(group).some((value) => value !== undefined && value !== '')));
|
|
81
|
+
if (!hasOverrides)
|
|
82
|
+
return baseTheme ?? null;
|
|
83
|
+
return Object.fromEntries(Object.entries({
|
|
84
|
+
...(baseTheme ?? {}),
|
|
85
|
+
...customizationToTheme(parsed),
|
|
86
|
+
}).filter(([, value]) => value !== undefined));
|
|
87
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
export interface VisualCustomizationColors {
|
|
2
|
+
primary?: string;
|
|
3
|
+
secondary?: string;
|
|
4
|
+
accent?: string;
|
|
5
|
+
background?: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
surface?: string;
|
|
8
|
+
surfaceAlt?: string;
|
|
9
|
+
heading?: string;
|
|
10
|
+
mutedText?: string;
|
|
11
|
+
border?: string;
|
|
12
|
+
headerBackground?: string;
|
|
13
|
+
footerBackground?: string;
|
|
14
|
+
cardBackground?: string;
|
|
15
|
+
buttonBackground?: string;
|
|
16
|
+
buttonText?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface VisualCustomizationTypography {
|
|
19
|
+
headingFont?: string;
|
|
20
|
+
bodyFont?: string;
|
|
21
|
+
baseSize?: string;
|
|
22
|
+
headingScale?: string;
|
|
23
|
+
bodyLineHeight?: string;
|
|
24
|
+
headingLineHeight?: string;
|
|
25
|
+
headingWeight?: string;
|
|
26
|
+
bodyWeight?: string;
|
|
27
|
+
letterSpacing?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface VisualCustomizationSpacing {
|
|
30
|
+
heroMinHeight?: string;
|
|
31
|
+
sectionPadding?: string;
|
|
32
|
+
contentMaxWidth?: string;
|
|
33
|
+
containerPadding?: string;
|
|
34
|
+
sectionGap?: string;
|
|
35
|
+
elementGap?: string;
|
|
36
|
+
gridGap?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface VisualCustomizationLayout {
|
|
39
|
+
textAlign?: string;
|
|
40
|
+
contentAlign?: string;
|
|
41
|
+
heroTextAlign?: string;
|
|
42
|
+
cardTextAlign?: string;
|
|
43
|
+
gridColumns?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface VisualCustomizationComponents {
|
|
46
|
+
cardWidth?: string;
|
|
47
|
+
cardMinHeight?: string;
|
|
48
|
+
cardPadding?: string;
|
|
49
|
+
cardRadius?: string;
|
|
50
|
+
cardBorderWidth?: string;
|
|
51
|
+
cardShadow?: string;
|
|
52
|
+
buttonPadding?: string;
|
|
53
|
+
buttonRadius?: string;
|
|
54
|
+
buttonShadow?: string;
|
|
55
|
+
imageRadius?: string;
|
|
56
|
+
headerHeight?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface VisualCustomizationSectionOverride {
|
|
59
|
+
backgroundColor?: string;
|
|
60
|
+
textColor?: string;
|
|
61
|
+
headingColor?: string;
|
|
62
|
+
minHeight?: string;
|
|
63
|
+
padding?: string;
|
|
64
|
+
contentMaxWidth?: string;
|
|
65
|
+
gap?: string;
|
|
66
|
+
textAlign?: string;
|
|
67
|
+
contentAlign?: string;
|
|
68
|
+
cardBackgroundColor?: string;
|
|
69
|
+
cardWidth?: string;
|
|
70
|
+
cardMinHeight?: string;
|
|
71
|
+
cardRadius?: string;
|
|
72
|
+
gridColumns?: string;
|
|
73
|
+
visible?: boolean;
|
|
74
|
+
}
|
|
75
|
+
export interface VisualCustomizationElementStyle {
|
|
76
|
+
fontFamily?: string;
|
|
77
|
+
fontSize?: string;
|
|
78
|
+
lineHeight?: string;
|
|
79
|
+
fontWeight?: string;
|
|
80
|
+
letterSpacing?: string;
|
|
81
|
+
color?: string;
|
|
82
|
+
backgroundColor?: string;
|
|
83
|
+
textAlign?: string;
|
|
84
|
+
width?: string;
|
|
85
|
+
height?: string;
|
|
86
|
+
minWidth?: string;
|
|
87
|
+
minHeight?: string;
|
|
88
|
+
maxWidth?: string;
|
|
89
|
+
maxHeight?: string;
|
|
90
|
+
marginTop?: string;
|
|
91
|
+
marginRight?: string;
|
|
92
|
+
marginBottom?: string;
|
|
93
|
+
marginLeft?: string;
|
|
94
|
+
paddingTop?: string;
|
|
95
|
+
paddingRight?: string;
|
|
96
|
+
paddingBottom?: string;
|
|
97
|
+
paddingLeft?: string;
|
|
98
|
+
borderWidth?: string;
|
|
99
|
+
borderStyle?: string;
|
|
100
|
+
borderColor?: string;
|
|
101
|
+
borderRadius?: string;
|
|
102
|
+
boxShadow?: string;
|
|
103
|
+
opacity?: string;
|
|
104
|
+
display?: string;
|
|
105
|
+
flexDirection?: string;
|
|
106
|
+
justifyContent?: string;
|
|
107
|
+
alignItems?: string;
|
|
108
|
+
gap?: string;
|
|
109
|
+
}
|
|
110
|
+
export interface VisualCustomization {
|
|
111
|
+
version: 1;
|
|
112
|
+
colors?: VisualCustomizationColors;
|
|
113
|
+
colorReplacements?: Record<string, string>;
|
|
114
|
+
typography?: VisualCustomizationTypography;
|
|
115
|
+
spacing?: VisualCustomizationSpacing;
|
|
116
|
+
layout?: VisualCustomizationLayout;
|
|
117
|
+
components?: VisualCustomizationComponents;
|
|
118
|
+
sections?: Record<string, VisualCustomizationSectionOverride>;
|
|
119
|
+
elementStyles?: Record<string, VisualCustomizationElementStyle>;
|
|
120
|
+
}
|
|
121
|
+
export interface TemplateThemeShape {
|
|
122
|
+
primaryColor?: string;
|
|
123
|
+
secondaryColor?: string;
|
|
124
|
+
accentColor?: string;
|
|
125
|
+
backgroundColor?: string;
|
|
126
|
+
textColor?: string;
|
|
127
|
+
surfaceColor?: string;
|
|
128
|
+
surfaceAltColor?: string;
|
|
129
|
+
headingColor?: string;
|
|
130
|
+
mutedTextColor?: string;
|
|
131
|
+
borderColor?: string;
|
|
132
|
+
headerBackgroundColor?: string;
|
|
133
|
+
footerBackgroundColor?: string;
|
|
134
|
+
cardBackgroundColor?: string;
|
|
135
|
+
buttonBackgroundColor?: string;
|
|
136
|
+
buttonTextColor?: string;
|
|
137
|
+
headingFont?: string;
|
|
138
|
+
bodyFont?: string;
|
|
139
|
+
baseSize?: string;
|
|
140
|
+
headingScale?: string;
|
|
141
|
+
bodyLineHeight?: string;
|
|
142
|
+
headingLineHeight?: string;
|
|
143
|
+
headingWeight?: string;
|
|
144
|
+
bodyWeight?: string;
|
|
145
|
+
letterSpacing?: string;
|
|
146
|
+
heroMinHeight?: string;
|
|
147
|
+
sectionPadding?: string;
|
|
148
|
+
contentMaxWidth?: string;
|
|
149
|
+
containerPadding?: string;
|
|
150
|
+
sectionGap?: string;
|
|
151
|
+
elementGap?: string;
|
|
152
|
+
gridGap?: string;
|
|
153
|
+
textAlign?: string;
|
|
154
|
+
contentAlign?: string;
|
|
155
|
+
heroTextAlign?: string;
|
|
156
|
+
cardTextAlign?: string;
|
|
157
|
+
gridColumns?: string;
|
|
158
|
+
cardWidth?: string;
|
|
159
|
+
cardMinHeight?: string;
|
|
160
|
+
cardPadding?: string;
|
|
161
|
+
cardRadius?: string;
|
|
162
|
+
cardBorderWidth?: string;
|
|
163
|
+
cardShadow?: string;
|
|
164
|
+
buttonPadding?: string;
|
|
165
|
+
buttonRadius?: string;
|
|
166
|
+
buttonShadow?: string;
|
|
167
|
+
imageRadius?: string;
|
|
168
|
+
headerHeight?: string;
|
|
169
|
+
style?: string;
|
|
170
|
+
designCustomizationVersion?: number;
|
|
171
|
+
colorReplacements?: Record<string, string>;
|
|
172
|
+
sections?: Record<string, VisualCustomizationSectionOverride>;
|
|
173
|
+
elementStyles?: Record<string, VisualCustomizationElementStyle>;
|
|
174
|
+
[key: string]: unknown;
|
|
175
|
+
}
|
|
176
|
+
export interface ThemePalette {
|
|
177
|
+
id: string;
|
|
178
|
+
name: string;
|
|
179
|
+
badge: string;
|
|
180
|
+
mode: 'light' | 'dark';
|
|
181
|
+
primary: string;
|
|
182
|
+
secondary: string;
|
|
183
|
+
accent: string;
|
|
184
|
+
background: string;
|
|
185
|
+
card: string;
|
|
186
|
+
text: string;
|
|
187
|
+
muted: string;
|
|
188
|
+
buttonBg?: string;
|
|
189
|
+
buttonText?: string;
|
|
190
|
+
}
|
|
191
|
+
export interface FontPairing {
|
|
192
|
+
id: string;
|
|
193
|
+
name: string;
|
|
194
|
+
headingFont: string;
|
|
195
|
+
bodyFont: string;
|
|
196
|
+
description: string;
|
|
197
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deneb-ui/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.69",
|
|
4
4
|
"description": "Headless style engine for real-time Fivora visual editing — CSS variables, DOM patcher, and preview protocol.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
"./install-fonts": {
|
|
13
13
|
"types": "./dist/fonts/installProject.d.ts",
|
|
14
14
|
"default": "./dist/fonts/installProject.js"
|
|
15
|
+
},
|
|
16
|
+
"./theme": {
|
|
17
|
+
"types": "./dist/theme/index.d.ts",
|
|
18
|
+
"default": "./dist/theme/index.js"
|
|
15
19
|
}
|
|
16
20
|
},
|
|
17
21
|
"publishConfig": {
|
|
@@ -32,7 +36,7 @@
|
|
|
32
36
|
],
|
|
33
37
|
"scripts": {
|
|
34
38
|
"build": "tsc",
|
|
35
|
-
"test": "npm run build && node --test src/fonts/__tests__/fonts.test.cjs",
|
|
39
|
+
"test": "npm run build && node --test src/fonts/__tests__/fonts.test.cjs src/theme/__tests__/theme.test.cjs",
|
|
36
40
|
"prepublishOnly": "npm run build"
|
|
37
41
|
},
|
|
38
42
|
"keywords": [
|