@optilogic/core 1.4.0 → 1.6.0
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.cjs +249 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -10
- package/dist/index.d.ts +59 -10
- package/dist/index.js +247 -103
- package/dist/index.js.map +1 -1
- package/dist/styles.css +12 -0
- package/dist/tailwind-preset.cjs +10 -2
- package/dist/tailwind-preset.cjs.map +1 -1
- package/dist/tailwind-preset.js +10 -2
- package/dist/tailwind-preset.js.map +1 -1
- package/package.json +2 -2
- package/src/components/confirmation-modal.tsx +41 -6
- package/src/components/data-grid/components/CellEditor.tsx +5 -2
- package/src/components/data-grid/components/FilterPopover.tsx +7 -4
- package/src/components/data-grid/utils/dataProcessing.ts +2 -1
- package/src/components/modal.tsx +55 -1
- package/src/components/resizable-panel.tsx +1 -1
- package/src/components/theme-picker.tsx +4 -2
- package/src/index.ts +3 -0
- package/src/styles.css +12 -0
- package/src/tailwind-preset.ts +9 -0
- package/src/theme/index.ts +3 -0
- package/src/theme/presets.ts +166 -91
- package/src/theme/types.ts +8 -0
- package/src/theme/utils.ts +57 -0
package/src/theme/presets.ts
CHANGED
|
@@ -8,116 +8,130 @@
|
|
|
8
8
|
import type { Theme } from "./types";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Optilogic
|
|
11
|
+
* Optilogic Light Theme - Default light theme
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* The current Optilogic light theme, synced from platform-leapfrog. Indigo
|
|
14
|
+
* (#5766F2) primary on a soft lavender-white surface.
|
|
14
15
|
*/
|
|
15
|
-
export const
|
|
16
|
-
id: "optilogic-
|
|
17
|
-
name: "Optilogic
|
|
18
|
-
description: "
|
|
16
|
+
export const OPTILOGIC_LIGHT_THEME: Theme = {
|
|
17
|
+
id: "optilogic-light",
|
|
18
|
+
name: "Optilogic Light",
|
|
19
|
+
description: "The default Optilogic light theme",
|
|
19
20
|
author: "Optilogic",
|
|
20
|
-
background: "#
|
|
21
|
-
foreground: "#
|
|
22
|
-
card: "#
|
|
23
|
-
cardForeground: "#
|
|
24
|
-
popover: "#
|
|
25
|
-
popoverForeground: "#
|
|
26
|
-
primary: "#
|
|
27
|
-
primaryForeground: "#
|
|
28
|
-
|
|
21
|
+
background: "#F3F4FF",
|
|
22
|
+
foreground: "#000000",
|
|
23
|
+
card: "#EDEEFF",
|
|
24
|
+
cardForeground: "#000000",
|
|
25
|
+
popover: "#EDEEFF",
|
|
26
|
+
popoverForeground: "#000000",
|
|
27
|
+
primary: "#5766F2",
|
|
28
|
+
primaryForeground: "#000000",
|
|
29
|
+
primaryHover: "#4555E0",
|
|
30
|
+
accent: "#929BEF",
|
|
29
31
|
accentForeground: "#0C0A5A",
|
|
30
|
-
secondary: "#
|
|
31
|
-
secondaryForeground: "#
|
|
32
|
-
muted: "#
|
|
33
|
-
mutedForeground: "#
|
|
34
|
-
destructive: "#
|
|
32
|
+
secondary: "#CFD4FB",
|
|
33
|
+
secondaryForeground: "#000000",
|
|
34
|
+
muted: "#E8ECFF",
|
|
35
|
+
mutedForeground: "#2E2D5E",
|
|
36
|
+
destructive: "#DC2626",
|
|
35
37
|
destructiveForeground: "#FFFFFF",
|
|
36
|
-
success: "#
|
|
37
|
-
successForeground: "#
|
|
38
|
-
warning: "#
|
|
39
|
-
warningForeground: "#
|
|
40
|
-
chip: "#
|
|
41
|
-
chipForeground: "#
|
|
42
|
-
border: "#
|
|
43
|
-
input: "#
|
|
38
|
+
success: "#929BEF",
|
|
39
|
+
successForeground: "#0C0A5A",
|
|
40
|
+
warning: "#B45309",
|
|
41
|
+
warningForeground: "#FFFFFF",
|
|
42
|
+
chip: "#5766F2",
|
|
43
|
+
chipForeground: "#FFFFFF",
|
|
44
|
+
border: "#C8CEFF",
|
|
45
|
+
input: "#C8CEFF",
|
|
44
46
|
ring: "#5766F2",
|
|
45
|
-
popoverBorder: "#
|
|
46
|
-
divider: "#
|
|
47
|
-
toggleTrack: "#
|
|
47
|
+
popoverBorder: "#C8CEFF",
|
|
48
|
+
divider: "#B8BEE0",
|
|
49
|
+
toggleTrack: "#929BEF",
|
|
48
50
|
toggleTrackForeground: "#FFFFFF",
|
|
49
51
|
inputHover: "#5766F2",
|
|
50
|
-
chart1: "#
|
|
51
|
-
chart2: "#
|
|
52
|
-
chart3: "#
|
|
53
|
-
chart4: "#
|
|
54
|
-
chart5: "#
|
|
55
|
-
chart6: "#
|
|
56
|
-
chart7: "#
|
|
57
|
-
chart8: "#
|
|
58
|
-
chart9: "#
|
|
59
|
-
chart10: "#
|
|
60
|
-
chart11: "#
|
|
61
|
-
chart12: "#
|
|
52
|
+
chart1: "#5766F2",
|
|
53
|
+
chart2: "#929BEF",
|
|
54
|
+
chart3: "#CFD4FB",
|
|
55
|
+
chart4: "#0C0A5A",
|
|
56
|
+
chart5: "#B45309",
|
|
57
|
+
chart6: "#DC2626",
|
|
58
|
+
chart7: "#A855F7",
|
|
59
|
+
chart8: "#EC4899",
|
|
60
|
+
chart9: "#55548C",
|
|
61
|
+
chart10: "#0C0A5A",
|
|
62
|
+
chart11: "#C05621",
|
|
63
|
+
chart12: "#06B6D4",
|
|
62
64
|
radius: "0.5rem",
|
|
65
|
+
brandGradientFrom: "#1A7B4A",
|
|
66
|
+
brandGradientTo: "#72DA60",
|
|
63
67
|
};
|
|
64
68
|
|
|
65
69
|
/**
|
|
66
|
-
* Optilogic Dark Theme -
|
|
70
|
+
* Optilogic Dark Theme - Default dark mode
|
|
67
71
|
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
72
|
+
* The current Optilogic dark theme, synced from platform-leapfrog. Indigo
|
|
73
|
+
* primary on a deep navy surface.
|
|
70
74
|
*/
|
|
71
75
|
export const OPTILOGIC_DARK_THEME: Theme = {
|
|
72
76
|
id: "optilogic-dark",
|
|
73
77
|
name: "Optilogic Dark",
|
|
74
|
-
description: "Optilogic
|
|
78
|
+
description: "The default Optilogic dark theme",
|
|
75
79
|
author: "Optilogic",
|
|
76
|
-
background: "#
|
|
77
|
-
foreground: "#
|
|
78
|
-
card: "#
|
|
79
|
-
cardForeground: "#
|
|
80
|
-
popover: "#
|
|
81
|
-
popoverForeground: "#
|
|
82
|
-
primary: "#
|
|
83
|
-
primaryForeground: "#
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
80
|
+
background: "#141826",
|
|
81
|
+
foreground: "#E8EAF0",
|
|
82
|
+
card: "#2D3252",
|
|
83
|
+
cardForeground: "#E8EAF0",
|
|
84
|
+
popover: "#2D3252",
|
|
85
|
+
popoverForeground: "#E8EAF0",
|
|
86
|
+
primary: "#5766F2",
|
|
87
|
+
primaryForeground: "#FFFFFF",
|
|
88
|
+
primaryHover: "#7B8FF7",
|
|
89
|
+
accent: "#5766F2",
|
|
90
|
+
accentForeground: "#FFFFFF",
|
|
91
|
+
accentHover: "#7B8FF7",
|
|
92
|
+
secondary: "#2D3252",
|
|
93
|
+
secondaryForeground: "#E8EAF0",
|
|
94
|
+
muted: "#2D3252",
|
|
95
|
+
mutedForeground: "#C5C9D4",
|
|
90
96
|
destructive: "#EF4444",
|
|
91
97
|
destructiveForeground: "#FFFFFF",
|
|
92
|
-
success: "#
|
|
93
|
-
successForeground: "#
|
|
94
|
-
warning: "#
|
|
95
|
-
warningForeground: "#
|
|
96
|
-
chip: "#
|
|
97
|
-
chipForeground: "#
|
|
98
|
-
border: "#
|
|
99
|
-
input: "#
|
|
100
|
-
ring: "#
|
|
101
|
-
popoverBorder: "#
|
|
102
|
-
divider: "#
|
|
103
|
-
toggleTrack: "#
|
|
104
|
-
toggleTrackForeground: "#
|
|
105
|
-
inputHover: "#
|
|
106
|
-
chart1: "#
|
|
107
|
-
chart2: "#
|
|
108
|
-
chart3: "#
|
|
109
|
-
chart4: "#
|
|
110
|
-
chart5: "#
|
|
98
|
+
success: "#22C55E",
|
|
99
|
+
successForeground: "#141826",
|
|
100
|
+
warning: "#F59E0B",
|
|
101
|
+
warningForeground: "#141826",
|
|
102
|
+
chip: "#5766F2",
|
|
103
|
+
chipForeground: "#FFFFFF",
|
|
104
|
+
border: "#3A3F5C",
|
|
105
|
+
input: "#2D3252",
|
|
106
|
+
ring: "#7B8FF7",
|
|
107
|
+
popoverBorder: "#3A3F5C",
|
|
108
|
+
divider: "#363B5C",
|
|
109
|
+
toggleTrack: "#4A5068",
|
|
110
|
+
toggleTrackForeground: "#141826",
|
|
111
|
+
inputHover: "#7B8FF7",
|
|
112
|
+
chart1: "#7B8FF7",
|
|
113
|
+
chart2: "#5766F2",
|
|
114
|
+
chart3: "#22D3EE",
|
|
115
|
+
chart4: "#22C55E",
|
|
116
|
+
chart5: "#F59E0B",
|
|
111
117
|
chart6: "#EF4444",
|
|
112
|
-
chart7: "#
|
|
118
|
+
chart7: "#A855F7",
|
|
113
119
|
chart8: "#EC4899",
|
|
114
|
-
chart9: "#
|
|
120
|
+
chart9: "#C5C9D4",
|
|
115
121
|
chart10: "#14B8A6",
|
|
116
|
-
chart11: "#
|
|
117
|
-
chart12: "#
|
|
122
|
+
chart11: "#FB923C",
|
|
123
|
+
chart12: "#60A5FA",
|
|
118
124
|
radius: "0.5rem",
|
|
125
|
+
brandGradientFrom: "#1A7B4A",
|
|
126
|
+
brandGradientTo: "#50FFA7",
|
|
119
127
|
};
|
|
120
128
|
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated Use OPTILOGIC_LIGHT_THEME. Retained so existing imports resolve;
|
|
131
|
+
* now points at the current Optilogic Light theme.
|
|
132
|
+
*/
|
|
133
|
+
export const OPTILOGIC_LEGACY_THEME = OPTILOGIC_LIGHT_THEME;
|
|
134
|
+
|
|
121
135
|
/**
|
|
122
136
|
* Modern Light Theme - Clean, readable light mode
|
|
123
137
|
*
|
|
@@ -289,14 +303,64 @@ export const DARK_ELEGANT_THEME: Theme = {
|
|
|
289
303
|
};
|
|
290
304
|
|
|
291
305
|
/**
|
|
292
|
-
*
|
|
306
|
+
* Green Theme - Natural, earthy greens
|
|
307
|
+
*
|
|
308
|
+
* Synced from platform-leapfrog. Soft green primary on deep forest surfaces.
|
|
309
|
+
*/
|
|
310
|
+
export const GREEN_THEME: Theme = {
|
|
311
|
+
id: "green-theme",
|
|
312
|
+
name: "Green Theme",
|
|
313
|
+
description: "A green theme with natural, earthy tones",
|
|
314
|
+
author: "Optilogic",
|
|
315
|
+
background: "#1a2820",
|
|
316
|
+
foreground: "#E6F5EC",
|
|
317
|
+
card: "#2d4038",
|
|
318
|
+
cardForeground: "#E6F5EC",
|
|
319
|
+
popover: "#243630",
|
|
320
|
+
popoverForeground: "#E6F5EC",
|
|
321
|
+
primary: "#6FCF97",
|
|
322
|
+
primaryForeground: "#1a2820",
|
|
323
|
+
accent: "#6FCF97",
|
|
324
|
+
accentForeground: "#1a2820",
|
|
325
|
+
secondary: "#1f3329",
|
|
326
|
+
secondaryForeground: "#E6F5EC",
|
|
327
|
+
muted: "#354840",
|
|
328
|
+
mutedForeground: "#9DB8A8",
|
|
329
|
+
destructive: "#EB5757",
|
|
330
|
+
destructiveForeground: "#E6F5EC",
|
|
331
|
+
success: "#6FCF97",
|
|
332
|
+
successForeground: "#1a2820",
|
|
333
|
+
warning: "#F2C94C",
|
|
334
|
+
warningForeground: "#1a2820",
|
|
335
|
+
chip: "#3a5045",
|
|
336
|
+
chipForeground: "#C5E3D1",
|
|
337
|
+
border: "#243630",
|
|
338
|
+
input: "#243630",
|
|
339
|
+
ring: "#6FCF97",
|
|
340
|
+
chart1: "#6FCF97",
|
|
341
|
+
chart2: "#8FE3B0",
|
|
342
|
+
chart3: "#9DB8A8",
|
|
343
|
+
chart4: "#2d4038",
|
|
344
|
+
chart5: "#354840",
|
|
345
|
+
chart6: "#EB5757",
|
|
346
|
+
chart7: "#F2C94C",
|
|
347
|
+
chart8: "#56CCF2",
|
|
348
|
+
chart9: "#BB6BD9",
|
|
349
|
+
chart10: "#4ECDC4",
|
|
350
|
+
chart11: "#A8D8B9",
|
|
351
|
+
chart12: "#E07B39",
|
|
352
|
+
radius: "0.5rem",
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* All available preset themes (shown in the theme picker).
|
|
293
357
|
*/
|
|
294
358
|
export const PRESET_THEMES: Theme[] = [
|
|
295
|
-
|
|
359
|
+
OPTILOGIC_LIGHT_THEME,
|
|
296
360
|
OPTILOGIC_DARK_THEME,
|
|
297
361
|
MODERN_LIGHT_THEME,
|
|
298
362
|
MODERN_DARK_THEME,
|
|
299
|
-
|
|
363
|
+
GREEN_THEME,
|
|
300
364
|
];
|
|
301
365
|
|
|
302
366
|
/**
|
|
@@ -305,22 +369,33 @@ export const PRESET_THEMES: Theme[] = [
|
|
|
305
369
|
export const ALL_THEMES: Theme[] = PRESET_THEMES;
|
|
306
370
|
|
|
307
371
|
/**
|
|
308
|
-
*
|
|
372
|
+
* Retired preset IDs mapped to their current replacement, so themes saved
|
|
373
|
+
* under an old ID (e.g. in localStorage) resolve to a shipping preset.
|
|
374
|
+
*/
|
|
375
|
+
export const LEGACY_THEME_ID_MAP: Record<string, string> = {
|
|
376
|
+
"optilogic-legacy": OPTILOGIC_LIGHT_THEME.id,
|
|
377
|
+
"dark-elegant": OPTILOGIC_DARK_THEME.id,
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Get a preset theme by ID, transparently resolving retired IDs.
|
|
309
382
|
*/
|
|
310
383
|
export function getPresetTheme(id: string): Theme | undefined {
|
|
311
|
-
|
|
384
|
+
const resolvedId = LEGACY_THEME_ID_MAP[id] ?? id;
|
|
385
|
+
return ALL_THEMES.find((theme) => theme.id === resolvedId);
|
|
312
386
|
}
|
|
313
387
|
|
|
314
388
|
/**
|
|
315
389
|
* Get the default theme (fallback)
|
|
316
390
|
*/
|
|
317
391
|
export function getDefaultTheme(): Theme {
|
|
318
|
-
return
|
|
392
|
+
return OPTILOGIC_LIGHT_THEME;
|
|
319
393
|
}
|
|
320
394
|
|
|
321
395
|
/**
|
|
322
396
|
* Check if a theme is a preset (not user-created)
|
|
323
397
|
*/
|
|
324
398
|
export function isPresetTheme(themeId: string): boolean {
|
|
325
|
-
|
|
399
|
+
const resolvedId = LEGACY_THEME_ID_MAP[themeId] ?? themeId;
|
|
400
|
+
return ALL_THEMES.some((theme) => theme.id === resolvedId);
|
|
326
401
|
}
|
package/src/theme/types.ts
CHANGED
|
@@ -54,6 +54,14 @@ export interface Theme {
|
|
|
54
54
|
input: string; // --input
|
|
55
55
|
ring: string; // --ring (focus ring)
|
|
56
56
|
|
|
57
|
+
/** Hover states (optional, with fallbacks) */
|
|
58
|
+
primaryHover?: string; // --primary-hover (primary control hover; fallback: primary)
|
|
59
|
+
accentHover?: string; // --accent-hover (accent surface hover; fallback: derived from card+accent)
|
|
60
|
+
|
|
61
|
+
/** Brand identity gradient (optional, with fallbacks) */
|
|
62
|
+
brandGradientFrom?: string; // --brand-from (fallback: primary)
|
|
63
|
+
brandGradientTo?: string; // --brand-to (fallback: chart-2)
|
|
64
|
+
|
|
57
65
|
/** Elevated surface border (optional, with fallback) */
|
|
58
66
|
popoverBorder?: string; // --popover-border (floating surface border; fallback: border)
|
|
59
67
|
|
package/src/theme/utils.ts
CHANGED
|
@@ -110,6 +110,28 @@ export function themeToHsl(theme: Theme): ThemeHSL {
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Blend two hex colors by `amount` (0..1). Used to derive --accent-hover and
|
|
115
|
+
* --accent-active when a theme doesn't specify them explicitly, so theme
|
|
116
|
+
* switches always refresh those vars from the current card+accent pair.
|
|
117
|
+
*/
|
|
118
|
+
function blendHex(base: string, blend: string, amount: number): string {
|
|
119
|
+
const a = base.replace(/^#/, "");
|
|
120
|
+
const b = blend.replace(/^#/, "");
|
|
121
|
+
const ar = parseInt(a.substring(0, 2), 16);
|
|
122
|
+
const ag = parseInt(a.substring(2, 4), 16);
|
|
123
|
+
const ab = parseInt(a.substring(4, 6), 16);
|
|
124
|
+
const br = parseInt(b.substring(0, 2), 16);
|
|
125
|
+
const bg = parseInt(b.substring(2, 4), 16);
|
|
126
|
+
const bb = parseInt(b.substring(4, 6), 16);
|
|
127
|
+
const r = Math.round(ar + (br - ar) * amount);
|
|
128
|
+
const g = Math.round(ag + (bg - ag) * amount);
|
|
129
|
+
const bl = Math.round(ab + (bb - ab) * amount);
|
|
130
|
+
const hex = (v: number) =>
|
|
131
|
+
Math.max(0, Math.min(255, v)).toString(16).padStart(2, "0");
|
|
132
|
+
return "#" + hex(r) + hex(g) + hex(bl);
|
|
133
|
+
}
|
|
134
|
+
|
|
113
135
|
/**
|
|
114
136
|
* Derive an input hover border color from the theme's HSL values.
|
|
115
137
|
* Blends toward the foreground for a subtle but visible hover effect.
|
|
@@ -219,6 +241,37 @@ export function applyTheme(theme: Theme, targetElement?: HTMLElement): void {
|
|
|
219
241
|
`${hslTheme.hover ?? deriveHoverChannels(theme, hslTheme)} / 0.18`
|
|
220
242
|
);
|
|
221
243
|
|
|
244
|
+
// Hover-state tokens (optional, with fallbacks).
|
|
245
|
+
// --primary-hover: explicit value, else falls back to --primary via styles.css.
|
|
246
|
+
if (theme.primaryHover) {
|
|
247
|
+
element.style.setProperty("--primary-hover", hexToHsl(theme.primaryHover));
|
|
248
|
+
} else {
|
|
249
|
+
element.style.removeProperty("--primary-hover");
|
|
250
|
+
}
|
|
251
|
+
// --accent-hover / --accent-active: always re-derived from the current
|
|
252
|
+
// card+accent (explicit accentHover wins) so theme switches refresh them.
|
|
253
|
+
if (theme.card && theme.accent) {
|
|
254
|
+
const accentHover = theme.accentHover
|
|
255
|
+
? theme.accentHover
|
|
256
|
+
: blendHex(theme.card, theme.accent, 0.08);
|
|
257
|
+
const accentActive = blendHex(theme.card, theme.accent, 0.15);
|
|
258
|
+
element.style.setProperty("--accent-hover", hexToHsl(accentHover));
|
|
259
|
+
element.style.setProperty("--accent-active", hexToHsl(accentActive));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Brand identity gradient (optional). When unset, removeProperty lets the
|
|
263
|
+
// styles.css :root fallback (primary → chart-2) take over.
|
|
264
|
+
if (theme.brandGradientFrom) {
|
|
265
|
+
element.style.setProperty("--brand-from", hexToHsl(theme.brandGradientFrom));
|
|
266
|
+
} else {
|
|
267
|
+
element.style.removeProperty("--brand-from");
|
|
268
|
+
}
|
|
269
|
+
if (theme.brandGradientTo) {
|
|
270
|
+
element.style.setProperty("--brand-to", hexToHsl(theme.brandGradientTo));
|
|
271
|
+
} else {
|
|
272
|
+
element.style.removeProperty("--brand-to");
|
|
273
|
+
}
|
|
274
|
+
|
|
222
275
|
element.style.setProperty("--chart-1", hslTheme.chart1);
|
|
223
276
|
element.style.setProperty("--chart-2", hslTheme.chart2);
|
|
224
277
|
element.style.setProperty("--chart-3", hslTheme.chart3);
|
|
@@ -362,6 +415,10 @@ export function areThemesEqual(theme1: Theme, theme2: Theme): boolean {
|
|
|
362
415
|
"toggleTrackForeground",
|
|
363
416
|
"inputHover",
|
|
364
417
|
"hover",
|
|
418
|
+
"primaryHover",
|
|
419
|
+
"accentHover",
|
|
420
|
+
"brandGradientFrom",
|
|
421
|
+
"brandGradientTo",
|
|
365
422
|
"chart1",
|
|
366
423
|
"chart2",
|
|
367
424
|
"chart3",
|