@toolr/ui-design 0.1.0 → 0.1.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.
- package/dist/index.d.ts +1 -23
- package/dist/index.js +0 -79
- package/index.ts +0 -7
- package/package.json +6 -2
- package/components/lib/theme-engine.ts +0 -97
- /package/dist/tokens/{tokens/primitives.css → primitives.css} +0 -0
- /package/dist/tokens/{tokens/semantic.css → semantic.css} +0 -0
- /package/dist/tokens/{tokens/theme.css → theme.css} +0 -0
- /package/dist/tokens/{tokens/tokens.json → tokens.json} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -7,28 +7,6 @@ import { ClassValue } from 'clsx';
|
|
|
7
7
|
|
|
8
8
|
type FormColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky';
|
|
9
9
|
|
|
10
|
-
declare const SCALE_KEYS: readonly ["black", "950", "900", "800", "700", "600", "500", "400", "300", "200"];
|
|
11
|
-
type ScaleKey = (typeof SCALE_KEYS)[number];
|
|
12
|
-
type ThemeId = 'oled' | 'dark' | 'night' | 'soft' | 'bright' | 'paper' | 'muted';
|
|
13
|
-
declare const DARK_THEMES: ThemeId[];
|
|
14
|
-
declare const LIGHT_THEMES: ThemeId[];
|
|
15
|
-
declare const BASE_THEMES: Record<ThemeId, {
|
|
16
|
-
label: string;
|
|
17
|
-
maxSat: number;
|
|
18
|
-
lightness: Record<ScaleKey, number>;
|
|
19
|
-
}>;
|
|
20
|
-
interface AccentDef {
|
|
21
|
-
id: FormColor;
|
|
22
|
-
hue: number | null;
|
|
23
|
-
dotColor: string;
|
|
24
|
-
}
|
|
25
|
-
declare const ACCENT_DEFS: AccentDef[];
|
|
26
|
-
declare function satCurve(l: number): number;
|
|
27
|
-
declare function hslToHex(h: number, s: number, l: number): string;
|
|
28
|
-
declare function generateScale(theme: ThemeId, hue: number | null, maxSat: number): Record<ScaleKey, string>;
|
|
29
|
-
declare function isLightTheme(themeId: ThemeId): boolean;
|
|
30
|
-
declare function applyTheme(themeId: ThemeId, accentHue: number | null, root?: HTMLElement): void;
|
|
31
|
-
|
|
32
10
|
type ToolrAppId = 'toolr' | 'configr' | 'reviewr' | 'vibr' | 'learnr' | 'planr' | 'seedr';
|
|
33
11
|
declare const TOOLR_APPS: Record<ToolrAppId, {
|
|
34
12
|
name: string;
|
|
@@ -2711,4 +2689,4 @@ declare function useNavigationHistory(initial?: BreadcrumbSegment[], maxEntries?
|
|
|
2711
2689
|
|
|
2712
2690
|
declare function cn(...inputs: ClassValue[]): string;
|
|
2713
2691
|
|
|
2714
|
-
export {
|
|
2692
|
+
export { AI_TOOL_LOGOS, AI_TOOL_NAMES, type AccentColor, ActionDialog, type ActionDialogProps, type ActionItem, AiActionButton, type AiActionButtonProps, type AiActionStatus, type AiCompletionResult, AiExecutionActionButtons, type AiExecutionActionButtonsProps, type AiToolConfig, AiToolIcon, type AiToolKey, AlertModal, type AlertModalProps, Badge, type BadgeColor, type BadgeProps, BottomPanelHeader, type BottomPanelHeaderProps, Breadcrumb, type BreadcrumbProps, type BreadcrumbSegment, type CapturedError, type CapturedIssuesApi, CapturedIssuesPanel, type CapturedIssuesPanelProps, type ChangedComponents, Checkbox, type CheckboxColor, type CheckboxProps, type CheckboxSize, type CheckboxVariant, type CodingToolId, type CodingToolPresetConfig, CollapseButton, type CollapseButtonProps, CollapsibleSection, type CollapsibleSectionProps, type ComponentVersion, ConfirmBadge, type ConfirmBadgeColor, type ConfirmBadgeProps, ConfirmModal, type ConfirmModalProps, type CreateSnapshotResult, type DetailRow, DetailSection, type DetailSectionProps, DetailViewWrapper, type DetailViewWrapperProps, type DiffSummary, type DiffTreeNode, type DirectoryStatus, EditorPlaceholderCard, type EditorPlaceholderCardProps, EditorToolbar, type EditorToolbarProps, type ErrorLogger, type ExecutionDetailRow, ExecutionDetailsPanel, type ExecutionDetailsPanelProps, type ExecutionStatus, ExtensionListCard, type ExtensionListCardProps, type ExtensionSource, type FileDiffInfo, type FileDiffStatus, FileDiffViewer, type FileDiffViewerProps, type FileEntry, FileStructureSection, type FileStructureSectionProps, FileTree, type FileTreeNode, type FileTreeProps, type FileTypeOption, FileTypeTabbedPromptEditor, type FileTypeTabbedPromptEditorProps, FilesPanel, type FilesPanelProps, FilterDropdown, type FilterDropdownProps, FormActions, type FormActionsProps, type FormColor, FrontmatterFormHeader, type FrontmatterFormHeaderProps, type GoldenLiveDiff, type GoldenMeta, type GoldenSnapshotsApi, type GoldenStatus, GoldenSyncPanel, type GoldenSyncPanelProps, ISSUE_TYPES, IconButton, type IconButtonColor, type IconButtonProps, type IconButtonStatus, type IconButtonVariant, type IconName, Input, type InputProps, type IssueReport, type IssueReportResult, type IssueType, Label, type LabelColor, type LabelProps, type LayoutTab, LayoutTabBar, type LayoutTabBarProps, type ModalKind, type ModalSize, NavCard, type NavCardProps, NavigationBar, type NavigationBarProps, NumberInput, type NumberInputProps, type PanelTab, type PreviewMode, type PromptEditorApi, type PromptPlaceholder, type PromptSnapshot, RegistryBrowser, type RegistryBrowserProps, RegistryCard, type RegistryCardProps, RegistryDetail, type RegistryDetailProps, type RegistryItemType, ReportBugForm, type ReportBugFormProps, type ResetResult, ResizableTextarea, type ResizableTextareaProps, SNIPPET_NAME_REGEX, type ScenarioOption, ScopeBadge, type ScopeType, type Screenshot, type ScreenshotAttachment, ScreenshotUploader, type ScreenshotUploaderProps, type SeedInfo, type SeedrItemStatus, SegmentedToggle, type SegmentedToggleOption, type SegmentedToggleProps, Select, type SelectOption, type SelectProps, type SelectionCardItem, SelectionGrid, type SelectionGridProps, SettingRow, type SettingRowProps, SimulatorPromptEditor, type SimulatorPromptEditorProps, type SnapshotBrowserApi, SnapshotBrowserPanel, type SnapshotBrowserPanelProps, SnapshotCard, type SnapshotCardProps, type SnapshotCategory, type SnapshotEntry, type SnapshotInfo, type SnapshotItem, SnapshotManager, type SnapshotManagerProps, type SnapshotScope, SnapshotTree, type SnapshotTreeProps, type SnapshotsManifest, type Snippet, type SnippetData, SnippetsEditor, type SnippetsEditorApi, type SnippetsEditorProps, SnippetsPanel, type SnippetsPanelProps, SortDropdown, type SortDropdownProps, type SortField, type StatusBanner, StatusCard, type StatusCardProps, type StatusItem, StatusOverview, type StatusOverviewProps, type SubmittedError, type SystemInfo, TOOLR_APPS, type Tab, TabBar, type TabBarProps, TabbedPromptEditor, type TabbedPromptEditorProps, Toggle, type ToggleColor, type ToggleProps, type ToggleSize, type ToggleVariant, type ToolDetectionResult, type ToolTab, type ToolrAppId, ToolrAppLogo, type ToolsPathsApi, ToolsPathsPanel, type ToolsPathsPanelProps, Tooltip, type TooltipAlign, TooltipButton, type TooltipContent, type TooltipPosition, type TrackedError, type UseCapturedIssuesOptions, type UseCapturedIssuesReturn, type UseGoldenSyncOptions, type UseGoldenSyncReturn, type UseNavigationHistoryReturn, type UsePromptEditorOptions, type UsePromptEditorReturn, type UseReportBugOptions, type UseReportBugReturn, type UseSnapshotBrowserOptions, type UseSnapshotBrowserReturn, type UseSnippetsEditorOptions, type UseSnippetsEditorReturn, type UseToolsPathsOptions, type UseToolsPathsReturn, VersionManager, type VersionManagerProps, cn, collectDirPaths, createErrorLogger, formatBytes, formatCategory, formatDate, getLanguage, getLanguageFromPath, iconMap, submitIssueReport, useCapturedIssues, useClickOutside, useDropdownMaxHeight, useGoldenSync, useNavigationHistory, usePromptEditor, useReportBug, useSnapshotBrowser, useSnippetsEditor, useToolsPaths };
|
package/dist/index.js
CHANGED
|
@@ -15,75 +15,6 @@ var FORM_COLORS = {
|
|
|
15
15
|
sky: { border: "border-sky-500/30", hover: "hover:bg-sky-500/20 hover:border-sky-500/40", focus: "focus:border-sky-500", selectedBg: "bg-sky-600/20", accent: "text-sky-400" }
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
// components/lib/theme-engine.ts
|
|
19
|
-
var SCALE_KEYS = ["black", "950", "900", "800", "700", "600", "500", "400", "300", "200"];
|
|
20
|
-
var DARK_THEMES = ["oled", "dark", "night", "soft"];
|
|
21
|
-
var LIGHT_THEMES = ["bright", "paper", "muted"];
|
|
22
|
-
var BASE_THEMES = {
|
|
23
|
-
oled: { label: "OLED", maxSat: 4, lightness: { black: 0, "950": 0, "900": 2, "800": 4, "700": 10, "600": 20, "500": 40, "400": 60, "300": 80, "200": 88 } },
|
|
24
|
-
dark: { label: "Dark", maxSat: 8, lightness: { black: 0, "950": 1.5, "900": 4, "800": 7, "700": 13, "600": 22, "500": 41, "400": 61, "300": 81, "200": 88 } },
|
|
25
|
-
night: { label: "Night", maxSat: 12, lightness: { black: 0, "950": 3, "900": 7, "800": 11, "700": 17, "600": 25, "500": 43, "400": 62, "300": 82, "200": 89 } },
|
|
26
|
-
soft: { label: "Soft", maxSat: 15, lightness: { black: 0, "950": 5, "900": 10, "800": 15, "700": 22, "600": 30, "500": 46, "400": 64, "300": 83, "200": 90 } },
|
|
27
|
-
bright: { label: "Bright", maxSat: 6, lightness: { black: 100, "950": 98, "900": 96, "800": 92, "700": 85, "600": 68, "500": 52, "400": 40, "300": 24, "200": 14 } },
|
|
28
|
-
paper: { label: "Paper", maxSat: 10, lightness: { black: 98, "950": 96, "900": 93, "800": 88, "700": 82, "600": 65, "500": 50, "400": 38, "300": 22, "200": 12 } },
|
|
29
|
-
muted: { label: "Muted", maxSat: 14, lightness: { black: 95, "950": 93, "900": 89, "800": 84, "700": 78, "600": 62, "500": 48, "400": 36, "300": 20, "200": 10 } }
|
|
30
|
-
};
|
|
31
|
-
var ACCENT_DEFS = [
|
|
32
|
-
{ id: "blue", hue: 220, dotColor: "#3b82f6" },
|
|
33
|
-
{ id: "violet", hue: 260, dotColor: "#8b5cf6" },
|
|
34
|
-
{ id: "orange", hue: 25, dotColor: "#f97316" },
|
|
35
|
-
{ id: "cyan", hue: 185, dotColor: "#06b6d4" },
|
|
36
|
-
{ id: "emerald", hue: 155, dotColor: "#10b981" },
|
|
37
|
-
{ id: "amber", hue: 38, dotColor: "#f59e0b" },
|
|
38
|
-
{ id: "sky", hue: 200, dotColor: "#0ea5e9" },
|
|
39
|
-
{ id: "indigo", hue: 235, dotColor: "#6366f1" },
|
|
40
|
-
{ id: "purple", hue: 275, dotColor: "#a855f7" },
|
|
41
|
-
{ id: "green", hue: 142, dotColor: "#22c55e" },
|
|
42
|
-
{ id: "yellow", hue: 55, dotColor: "#eab308" },
|
|
43
|
-
{ id: "red", hue: 0, dotColor: "#ef4444" },
|
|
44
|
-
{ id: "neutral", hue: null, dotColor: "#737373" }
|
|
45
|
-
];
|
|
46
|
-
function satCurve(l) {
|
|
47
|
-
return Math.min(l / 15, 1) * Math.max(0, 1 - l / 110);
|
|
48
|
-
}
|
|
49
|
-
function hslToHex(h, s, l) {
|
|
50
|
-
const a = s / 100 * Math.min(l / 100, 1 - l / 100);
|
|
51
|
-
const f = (n) => {
|
|
52
|
-
const k = (n + h / 30) % 12;
|
|
53
|
-
const c = l / 100 - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
54
|
-
return Math.round(255 * Math.max(0, Math.min(1, c))).toString(16).padStart(2, "0");
|
|
55
|
-
};
|
|
56
|
-
return `#${f(0)}${f(8)}${f(4)}`;
|
|
57
|
-
}
|
|
58
|
-
function generateScale(theme, hue, maxSat) {
|
|
59
|
-
const lightness = BASE_THEMES[theme].lightness;
|
|
60
|
-
const result = {};
|
|
61
|
-
for (const key of SCALE_KEYS) {
|
|
62
|
-
const l = lightness[key];
|
|
63
|
-
if (hue === null || maxSat === 0) {
|
|
64
|
-
const g = Math.round(255 * l / 100).toString(16).padStart(2, "0");
|
|
65
|
-
result[key] = `#${g}${g}${g}`;
|
|
66
|
-
} else {
|
|
67
|
-
result[key] = hslToHex(hue, maxSat * satCurve(l), l);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return result;
|
|
71
|
-
}
|
|
72
|
-
function isLightTheme(themeId) {
|
|
73
|
-
return LIGHT_THEMES.includes(themeId);
|
|
74
|
-
}
|
|
75
|
-
function applyTheme(themeId, accentHue, root = document.documentElement) {
|
|
76
|
-
const scale = generateScale(themeId, accentHue, BASE_THEMES[themeId].maxSat);
|
|
77
|
-
const light = isLightTheme(themeId);
|
|
78
|
-
for (const key of SCALE_KEYS) {
|
|
79
|
-
const prop = key === "black" ? "--color-black" : `--color-neutral-${key}`;
|
|
80
|
-
root.style.setProperty(prop, scale[key]);
|
|
81
|
-
}
|
|
82
|
-
root.style.setProperty("--color-white", light ? "#0a0a0a" : "#ffffff");
|
|
83
|
-
root.style.setProperty("--color-neutral-100", light ? "#1a1a1a" : "#f0f0f0");
|
|
84
|
-
root.style.setProperty("--color-neutral-50", light ? "#0f0f0f" : "#fafafa");
|
|
85
|
-
}
|
|
86
|
-
|
|
87
18
|
// components/lib/toolr-brand.tsx
|
|
88
19
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
89
20
|
var TOOLR_APPS = {
|
|
@@ -11117,7 +11048,6 @@ function useNavigationHistory(initial, maxEntries = 50) {
|
|
|
11117
11048
|
};
|
|
11118
11049
|
}
|
|
11119
11050
|
export {
|
|
11120
|
-
ACCENT_DEFS,
|
|
11121
11051
|
AI_TOOL_LOGOS,
|
|
11122
11052
|
AI_TOOL_NAMES,
|
|
11123
11053
|
ActionDialog,
|
|
@@ -11125,7 +11055,6 @@ export {
|
|
|
11125
11055
|
AiExecutionActionButtons,
|
|
11126
11056
|
AiToolIcon,
|
|
11127
11057
|
AlertModal,
|
|
11128
|
-
BASE_THEMES,
|
|
11129
11058
|
Badge,
|
|
11130
11059
|
BottomPanelHeader,
|
|
11131
11060
|
Breadcrumb,
|
|
@@ -11135,7 +11064,6 @@ export {
|
|
|
11135
11064
|
CollapsibleSection,
|
|
11136
11065
|
ConfirmBadge,
|
|
11137
11066
|
ConfirmModal,
|
|
11138
|
-
DARK_THEMES,
|
|
11139
11067
|
DetailSection,
|
|
11140
11068
|
DetailViewWrapper,
|
|
11141
11069
|
EditorPlaceholderCard,
|
|
@@ -11154,7 +11082,6 @@ export {
|
|
|
11154
11082
|
ISSUE_TYPES,
|
|
11155
11083
|
IconButton,
|
|
11156
11084
|
Input,
|
|
11157
|
-
LIGHT_THEMES,
|
|
11158
11085
|
Label,
|
|
11159
11086
|
LayoutTabBar,
|
|
11160
11087
|
NavCard,
|
|
@@ -11165,7 +11092,6 @@ export {
|
|
|
11165
11092
|
RegistryDetail,
|
|
11166
11093
|
ReportBugForm,
|
|
11167
11094
|
ResizableTextarea,
|
|
11168
|
-
SCALE_KEYS,
|
|
11169
11095
|
SNIPPET_NAME_REGEX,
|
|
11170
11096
|
ScopeBadge,
|
|
11171
11097
|
ScreenshotUploader,
|
|
@@ -11192,20 +11118,15 @@ export {
|
|
|
11192
11118
|
Tooltip,
|
|
11193
11119
|
TooltipButton,
|
|
11194
11120
|
VersionManager,
|
|
11195
|
-
applyTheme,
|
|
11196
11121
|
cn,
|
|
11197
11122
|
collectDirPaths,
|
|
11198
11123
|
createErrorLogger,
|
|
11199
11124
|
formatBytes,
|
|
11200
11125
|
formatCategory,
|
|
11201
11126
|
formatDate,
|
|
11202
|
-
generateScale,
|
|
11203
11127
|
getLanguage,
|
|
11204
11128
|
getLanguageFromPath,
|
|
11205
|
-
hslToHex,
|
|
11206
11129
|
iconMap,
|
|
11207
|
-
isLightTheme,
|
|
11208
|
-
satCurve,
|
|
11209
11130
|
submitIssueReport,
|
|
11210
11131
|
useCapturedIssues,
|
|
11211
11132
|
useClickOutside,
|
package/index.ts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
// Shared types
|
|
2
2
|
export { type FormColor } from './components/lib/form-colors.ts'
|
|
3
|
-
export {
|
|
4
|
-
SCALE_KEYS, type ScaleKey, type ThemeId,
|
|
5
|
-
DARK_THEMES, LIGHT_THEMES, BASE_THEMES,
|
|
6
|
-
type AccentDef, ACCENT_DEFS,
|
|
7
|
-
satCurve, hslToHex, generateScale,
|
|
8
|
-
isLightTheme, applyTheme,
|
|
9
|
-
} from './components/lib/theme-engine.ts'
|
|
10
3
|
export { ToolrAppLogo, TOOLR_APPS, type ToolrAppId } from './components/lib/toolr-brand.tsx'
|
|
11
4
|
export { AI_TOOL_LOGOS, AiToolIcon, AI_TOOL_NAMES, type AiToolKey } from './components/lib/ai-tools.tsx'
|
|
12
5
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toolr/ui-design",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
"types": "./dist/diagrams.d.ts"
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/twiced-technology-gmbh/toolr-ui-design.git"
|
|
37
|
+
},
|
|
34
38
|
"files": [
|
|
35
39
|
"dist",
|
|
36
40
|
"index.ts",
|
|
@@ -40,7 +44,7 @@
|
|
|
40
44
|
],
|
|
41
45
|
"scripts": {
|
|
42
46
|
"build": "tsup",
|
|
43
|
-
"postbuild": "cp -r tokens dist/tokens"
|
|
47
|
+
"postbuild": "rm -rf dist/tokens && cp -r tokens dist/tokens"
|
|
44
48
|
},
|
|
45
49
|
"peerDependencies": {
|
|
46
50
|
"react": "^18 || ^19",
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import type { FormColor } from './form-colors.ts'
|
|
2
|
-
|
|
3
|
-
/* ── Neutral scale types ──────────────────────────────────── */
|
|
4
|
-
|
|
5
|
-
export const SCALE_KEYS = ['black', '950', '900', '800', '700', '600', '500', '400', '300', '200'] as const
|
|
6
|
-
export type ScaleKey = (typeof SCALE_KEYS)[number]
|
|
7
|
-
|
|
8
|
-
/* ── Theme definitions ────────────────────────────────────── */
|
|
9
|
-
|
|
10
|
-
export type ThemeId = 'oled' | 'dark' | 'night' | 'soft' | 'bright' | 'paper' | 'muted'
|
|
11
|
-
|
|
12
|
-
export const DARK_THEMES: ThemeId[] = ['oled', 'dark', 'night', 'soft']
|
|
13
|
-
export const LIGHT_THEMES: ThemeId[] = ['bright', 'paper', 'muted']
|
|
14
|
-
|
|
15
|
-
export const BASE_THEMES: Record<ThemeId, { label: string; maxSat: number; lightness: Record<ScaleKey, number> }> = {
|
|
16
|
-
oled: { label: 'OLED', maxSat: 4, lightness: { black: 0, '950': 0, '900': 2, '800': 4, '700': 10, '600': 20, '500': 40, '400': 60, '300': 80, '200': 88 } },
|
|
17
|
-
dark: { label: 'Dark', maxSat: 8, lightness: { black: 0, '950': 1.5, '900': 4, '800': 7, '700': 13, '600': 22, '500': 41, '400': 61, '300': 81, '200': 88 } },
|
|
18
|
-
night: { label: 'Night', maxSat: 12, lightness: { black: 0, '950': 3, '900': 7, '800': 11, '700': 17, '600': 25, '500': 43, '400': 62, '300': 82, '200': 89 } },
|
|
19
|
-
soft: { label: 'Soft', maxSat: 15, lightness: { black: 0, '950': 5, '900': 10, '800': 15, '700': 22, '600': 30, '500': 46, '400': 64, '300': 83, '200': 90 } },
|
|
20
|
-
bright: { label: 'Bright', maxSat: 6, lightness: { black: 100, '950': 98, '900': 96, '800': 92, '700': 85, '600': 68, '500': 52, '400': 40, '300': 24, '200': 14 } },
|
|
21
|
-
paper: { label: 'Paper', maxSat: 10, lightness: { black: 98, '950': 96, '900': 93, '800': 88, '700': 82, '600': 65, '500': 50, '400': 38, '300': 22, '200': 12 } },
|
|
22
|
-
muted: { label: 'Muted', maxSat: 14, lightness: { black: 95, '950': 93, '900': 89, '800': 84, '700': 78, '600': 62, '500': 48, '400': 36, '300': 20, '200': 10 } },
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/* ── Accent definitions ───────────────────────────────────── */
|
|
26
|
-
|
|
27
|
-
export interface AccentDef {
|
|
28
|
-
id: FormColor
|
|
29
|
-
hue: number | null
|
|
30
|
-
dotColor: string
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const ACCENT_DEFS: AccentDef[] = [
|
|
34
|
-
{ id: 'blue', hue: 220, dotColor: '#3b82f6' },
|
|
35
|
-
{ id: 'violet', hue: 260, dotColor: '#8b5cf6' },
|
|
36
|
-
{ id: 'orange', hue: 25, dotColor: '#f97316' },
|
|
37
|
-
{ id: 'cyan', hue: 185, dotColor: '#06b6d4' },
|
|
38
|
-
{ id: 'emerald', hue: 155, dotColor: '#10b981' },
|
|
39
|
-
{ id: 'amber', hue: 38, dotColor: '#f59e0b' },
|
|
40
|
-
{ id: 'sky', hue: 200, dotColor: '#0ea5e9' },
|
|
41
|
-
{ id: 'indigo', hue: 235, dotColor: '#6366f1' },
|
|
42
|
-
{ id: 'purple', hue: 275, dotColor: '#a855f7' },
|
|
43
|
-
{ id: 'green', hue: 142, dotColor: '#22c55e' },
|
|
44
|
-
{ id: 'yellow', hue: 55, dotColor: '#eab308' },
|
|
45
|
-
{ id: 'red', hue: 0, dotColor: '#ef4444' },
|
|
46
|
-
{ id: 'neutral', hue: null, dotColor: '#737373' },
|
|
47
|
-
]
|
|
48
|
-
|
|
49
|
-
/* ── Color utilities ──────────────────────────────────────── */
|
|
50
|
-
|
|
51
|
-
export function satCurve(l: number): number {
|
|
52
|
-
return Math.min(l / 15, 1) * Math.max(0, 1 - l / 110)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function hslToHex(h: number, s: number, l: number): string {
|
|
56
|
-
const a = (s / 100) * Math.min(l / 100, 1 - l / 100)
|
|
57
|
-
const f = (n: number) => {
|
|
58
|
-
const k = (n + h / 30) % 12
|
|
59
|
-
const c = l / 100 - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)
|
|
60
|
-
return Math.round(255 * Math.max(0, Math.min(1, c))).toString(16).padStart(2, '0')
|
|
61
|
-
}
|
|
62
|
-
return `#${f(0)}${f(8)}${f(4)}`
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function generateScale(theme: ThemeId, hue: number | null, maxSat: number): Record<ScaleKey, string> {
|
|
66
|
-
const lightness = BASE_THEMES[theme].lightness
|
|
67
|
-
const result = {} as Record<ScaleKey, string>
|
|
68
|
-
for (const key of SCALE_KEYS) {
|
|
69
|
-
const l = lightness[key]
|
|
70
|
-
if (hue === null || maxSat === 0) {
|
|
71
|
-
const g = Math.round(255 * l / 100).toString(16).padStart(2, '0')
|
|
72
|
-
result[key] = `#${g}${g}${g}`
|
|
73
|
-
} else {
|
|
74
|
-
result[key] = hslToHex(hue, maxSat * satCurve(l), l)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return result
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/* ── Theme application helpers ────────────────────────────── */
|
|
81
|
-
|
|
82
|
-
export function isLightTheme(themeId: ThemeId): boolean {
|
|
83
|
-
return LIGHT_THEMES.includes(themeId)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function applyTheme(themeId: ThemeId, accentHue: number | null, root: HTMLElement = document.documentElement): void {
|
|
87
|
-
const scale = generateScale(themeId, accentHue, BASE_THEMES[themeId].maxSat)
|
|
88
|
-
const light = isLightTheme(themeId)
|
|
89
|
-
|
|
90
|
-
for (const key of SCALE_KEYS) {
|
|
91
|
-
const prop = key === 'black' ? '--color-black' : `--color-neutral-${key}`
|
|
92
|
-
root.style.setProperty(prop, scale[key])
|
|
93
|
-
}
|
|
94
|
-
root.style.setProperty('--color-white', light ? '#0a0a0a' : '#ffffff')
|
|
95
|
-
root.style.setProperty('--color-neutral-100', light ? '#1a1a1a' : '#f0f0f0')
|
|
96
|
-
root.style.setProperty('--color-neutral-50', light ? '#0f0f0f' : '#fafafa')
|
|
97
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|