@grundtone/core 2.0.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/README.md +78 -0
- package/assets/logo-16x16.png +0 -0
- package/assets/logo-180x180.png +0 -0
- package/assets/logo-192x192.png +0 -0
- package/assets/logo-32x32.png +0 -0
- package/assets/logo-512x512.png +0 -0
- package/assets/logo.png +0 -0
- package/dist/index.d.mts +305 -0
- package/dist/index.d.ts +305 -0
- package/dist/index.js +373 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +354 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +50 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
// src/theme.ts
|
|
2
|
+
var THEME_INJECTION_KEY = /* @__PURE__ */ Symbol("grundtone-theme");
|
|
3
|
+
|
|
4
|
+
// src/theme-preset.ts
|
|
5
|
+
var SEMANTIC_COLOR_KEYS = [
|
|
6
|
+
// Brand
|
|
7
|
+
"primary",
|
|
8
|
+
"primaryLight",
|
|
9
|
+
"primaryDark",
|
|
10
|
+
"onPrimary",
|
|
11
|
+
"secondary",
|
|
12
|
+
"secondaryLight",
|
|
13
|
+
"secondaryDark",
|
|
14
|
+
// Status
|
|
15
|
+
"success",
|
|
16
|
+
"successLight",
|
|
17
|
+
"successDark",
|
|
18
|
+
"warning",
|
|
19
|
+
"warningLight",
|
|
20
|
+
"warningDark",
|
|
21
|
+
"error",
|
|
22
|
+
"errorLight",
|
|
23
|
+
"errorDark",
|
|
24
|
+
"info",
|
|
25
|
+
"infoLight",
|
|
26
|
+
"infoDark",
|
|
27
|
+
// Surface
|
|
28
|
+
"background",
|
|
29
|
+
"backgroundAlt",
|
|
30
|
+
"surface",
|
|
31
|
+
"surfaceAlt",
|
|
32
|
+
"surfaceRaised",
|
|
33
|
+
"surfaceOverlay",
|
|
34
|
+
"modalBackdrop",
|
|
35
|
+
// Text
|
|
36
|
+
"text",
|
|
37
|
+
"textSecondary",
|
|
38
|
+
"textTertiary",
|
|
39
|
+
"textInverse",
|
|
40
|
+
"textPlaceholder",
|
|
41
|
+
"textDisabled",
|
|
42
|
+
// Border
|
|
43
|
+
"borderLight",
|
|
44
|
+
"borderMedium",
|
|
45
|
+
"borderStrong",
|
|
46
|
+
"borderInverse",
|
|
47
|
+
// Focus
|
|
48
|
+
"focus",
|
|
49
|
+
"focusRing",
|
|
50
|
+
// Neutral
|
|
51
|
+
"neutral"
|
|
52
|
+
];
|
|
53
|
+
var defaultColorPreset = {
|
|
54
|
+
// Brand
|
|
55
|
+
primary: "#0059b3",
|
|
56
|
+
primaryLight: "#3381cc",
|
|
57
|
+
primaryDark: "#003a7a",
|
|
58
|
+
onPrimary: "#ffffff",
|
|
59
|
+
secondary: "#6c757d",
|
|
60
|
+
secondaryLight: "#868e96",
|
|
61
|
+
secondaryDark: "#494f54",
|
|
62
|
+
// Status
|
|
63
|
+
success: "#198754",
|
|
64
|
+
successLight: "#d1e7dd",
|
|
65
|
+
successDark: "#146c43",
|
|
66
|
+
warning: "#ffc107",
|
|
67
|
+
warningLight: "#fff3cd",
|
|
68
|
+
warningDark: "#cc9a06",
|
|
69
|
+
error: "#dc3545",
|
|
70
|
+
errorLight: "#f8d7da",
|
|
71
|
+
errorDark: "#b02a37",
|
|
72
|
+
info: "#0dcaf0",
|
|
73
|
+
infoLight: "#cff4fc",
|
|
74
|
+
infoDark: "#0aa2c0",
|
|
75
|
+
// Surface
|
|
76
|
+
background: "#ffffff",
|
|
77
|
+
backgroundAlt: "#fafafa",
|
|
78
|
+
surface: "#f8f9fa",
|
|
79
|
+
surfaceAlt: "#f0f1f2",
|
|
80
|
+
surfaceRaised: "#ffffff",
|
|
81
|
+
surfaceOverlay: "rgba(255,255,255,0.95)",
|
|
82
|
+
modalBackdrop: "rgba(0,0,0,0.5)",
|
|
83
|
+
// Text
|
|
84
|
+
text: "#212529",
|
|
85
|
+
textSecondary: "#6c757d",
|
|
86
|
+
textTertiary: "#adb5bd",
|
|
87
|
+
textInverse: "#ffffff",
|
|
88
|
+
textPlaceholder: "#a3a3a3",
|
|
89
|
+
textDisabled: "#d4d4d4",
|
|
90
|
+
// Border
|
|
91
|
+
borderLight: "#dee2e6",
|
|
92
|
+
borderMedium: "#ced4da",
|
|
93
|
+
borderStrong: "#adb5bd",
|
|
94
|
+
borderInverse: "rgba(255,255,255,0.2)",
|
|
95
|
+
// Focus
|
|
96
|
+
focus: "#0059b3",
|
|
97
|
+
focusRing: "rgba(0,89,179,0.25)",
|
|
98
|
+
// Neutral
|
|
99
|
+
neutral: "#6c757d"
|
|
100
|
+
};
|
|
101
|
+
var defaultColorPresetDark = {
|
|
102
|
+
// Brand
|
|
103
|
+
primary: "#4dabf7",
|
|
104
|
+
primaryLight: "#74c0fc",
|
|
105
|
+
primaryDark: "#339af0",
|
|
106
|
+
onPrimary: "#121212",
|
|
107
|
+
secondary: "#adb5bd",
|
|
108
|
+
secondaryLight: "#ced4da",
|
|
109
|
+
secondaryDark: "#868e96",
|
|
110
|
+
// Status
|
|
111
|
+
success: "#51cf66",
|
|
112
|
+
successLight: "#1a3d20",
|
|
113
|
+
successDark: "#40c057",
|
|
114
|
+
warning: "#ffd43b",
|
|
115
|
+
warningLight: "#3d3a1a",
|
|
116
|
+
warningDark: "#fab005",
|
|
117
|
+
error: "#ff6b6b",
|
|
118
|
+
errorLight: "#3d1a1c",
|
|
119
|
+
errorDark: "#fa5252",
|
|
120
|
+
info: "#4dabf7",
|
|
121
|
+
infoLight: "#1a2e3d",
|
|
122
|
+
infoDark: "#339af0",
|
|
123
|
+
// Surface
|
|
124
|
+
background: "#121212",
|
|
125
|
+
backgroundAlt: "#1a1a1a",
|
|
126
|
+
surface: "#1e1e1e",
|
|
127
|
+
surfaceAlt: "#252525",
|
|
128
|
+
surfaceRaised: "#2a2a2a",
|
|
129
|
+
surfaceOverlay: "rgba(30,30,30,0.95)",
|
|
130
|
+
modalBackdrop: "rgba(0,0,0,0.7)",
|
|
131
|
+
// Text
|
|
132
|
+
text: "#ffffff",
|
|
133
|
+
textSecondary: "#b0b0b0",
|
|
134
|
+
textTertiary: "#808080",
|
|
135
|
+
textInverse: "#121212",
|
|
136
|
+
textPlaceholder: "#666666",
|
|
137
|
+
textDisabled: "#4a4a4a",
|
|
138
|
+
// Border
|
|
139
|
+
borderLight: "#404040",
|
|
140
|
+
borderMedium: "#505050",
|
|
141
|
+
borderStrong: "#606060",
|
|
142
|
+
borderInverse: "rgba(0,0,0,0.3)",
|
|
143
|
+
// Focus
|
|
144
|
+
focus: "#4dabf7",
|
|
145
|
+
focusRing: "rgba(77,171,247,0.25)",
|
|
146
|
+
// Neutral
|
|
147
|
+
neutral: "#9e9e9e"
|
|
148
|
+
};
|
|
149
|
+
var defaultSpacing = {
|
|
150
|
+
xs: "0.25rem",
|
|
151
|
+
// 4px — 0.5× base
|
|
152
|
+
sm: "0.5rem",
|
|
153
|
+
// 8px — 1× base
|
|
154
|
+
md: "1rem",
|
|
155
|
+
// 16px — 2× base
|
|
156
|
+
lg: "1.5rem",
|
|
157
|
+
// 24px — 3× base
|
|
158
|
+
xl: "2rem",
|
|
159
|
+
// 32px — 4× base
|
|
160
|
+
"2xl": "3rem",
|
|
161
|
+
// 48px — 6× base
|
|
162
|
+
"3xl": "4rem",
|
|
163
|
+
// 64px — 8× base
|
|
164
|
+
"4xl": "6rem"
|
|
165
|
+
// 96px — 12× base
|
|
166
|
+
};
|
|
167
|
+
var defaultTypography = {
|
|
168
|
+
fontFamily: {
|
|
169
|
+
base: "'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif",
|
|
170
|
+
heading: "'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif",
|
|
171
|
+
mono: "'IBM Plex Mono', 'Courier New', monospace"
|
|
172
|
+
},
|
|
173
|
+
fontSize: {
|
|
174
|
+
xs: "0.75rem",
|
|
175
|
+
sm: "0.875rem",
|
|
176
|
+
base: "1rem",
|
|
177
|
+
lg: "1.125rem",
|
|
178
|
+
xl: "1.25rem",
|
|
179
|
+
"2xl": "1.5rem",
|
|
180
|
+
"3xl": "1.875rem",
|
|
181
|
+
"4xl": "2.25rem",
|
|
182
|
+
"5xl": "3rem"
|
|
183
|
+
},
|
|
184
|
+
fontWeight: {
|
|
185
|
+
thin: 100,
|
|
186
|
+
light: 300,
|
|
187
|
+
normal: 400,
|
|
188
|
+
medium: 500,
|
|
189
|
+
semibold: 600,
|
|
190
|
+
bold: 700,
|
|
191
|
+
extrabold: 800
|
|
192
|
+
},
|
|
193
|
+
lineHeight: {
|
|
194
|
+
none: 1,
|
|
195
|
+
tight: 1.25,
|
|
196
|
+
snug: 1.375,
|
|
197
|
+
normal: 1.5,
|
|
198
|
+
relaxed: 1.625,
|
|
199
|
+
loose: 2
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
var defaultShadowDefinitions = {
|
|
203
|
+
xs: [{ x: 0, y: 1, blur: 2, spread: 0, color: "#000000", opacity: 0.05 }],
|
|
204
|
+
sm: [
|
|
205
|
+
{ x: 0, y: 1, blur: 3, spread: 0, color: "#000000", opacity: 0.1 },
|
|
206
|
+
{ x: 0, y: 1, blur: 2, spread: 0, color: "#000000", opacity: 0.06 }
|
|
207
|
+
],
|
|
208
|
+
md: [
|
|
209
|
+
{ x: 0, y: 4, blur: 6, spread: -1, color: "#000000", opacity: 0.1 },
|
|
210
|
+
{ x: 0, y: 2, blur: 4, spread: -1, color: "#000000", opacity: 0.06 }
|
|
211
|
+
],
|
|
212
|
+
lg: [
|
|
213
|
+
{ x: 0, y: 10, blur: 15, spread: -3, color: "#000000", opacity: 0.1 },
|
|
214
|
+
{ x: 0, y: 4, blur: 6, spread: -2, color: "#000000", opacity: 0.05 }
|
|
215
|
+
],
|
|
216
|
+
xl: [
|
|
217
|
+
{ x: 0, y: 20, blur: 25, spread: -5, color: "#000000", opacity: 0.1 },
|
|
218
|
+
{ x: 0, y: 10, blur: 10, spread: -5, color: "#000000", opacity: 0.04 }
|
|
219
|
+
],
|
|
220
|
+
"2xl": [
|
|
221
|
+
{ x: 0, y: 25, blur: 50, spread: -12, color: "#000000", opacity: 0.25 }
|
|
222
|
+
],
|
|
223
|
+
inner: [
|
|
224
|
+
{
|
|
225
|
+
x: 0,
|
|
226
|
+
y: 2,
|
|
227
|
+
blur: 4,
|
|
228
|
+
spread: 0,
|
|
229
|
+
color: "#000000",
|
|
230
|
+
opacity: 0.06,
|
|
231
|
+
inset: true
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
};
|
|
235
|
+
function hexToRgb(hex) {
|
|
236
|
+
const h = hex.replace("#", "");
|
|
237
|
+
const full = h.length === 3 ? h[0] + h[0] + h[1] + h[1] + h[2] + h[2] : h;
|
|
238
|
+
return {
|
|
239
|
+
r: parseInt(full.slice(0, 2), 16),
|
|
240
|
+
g: parseInt(full.slice(2, 4), 16),
|
|
241
|
+
b: parseInt(full.slice(4, 6), 16)
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function shadowLayersToCSS(layers) {
|
|
245
|
+
return layers.map((l) => {
|
|
246
|
+
const inset = l.inset ? "inset " : "";
|
|
247
|
+
const px = (n) => n === 0 ? "0" : `${n}px`;
|
|
248
|
+
const { r, g, b } = hexToRgb(l.color);
|
|
249
|
+
return `${inset}${px(l.x)} ${px(l.y)} ${px(l.blur)} ${px(l.spread)} rgba(${r}, ${g}, ${b}, ${l.opacity})`;
|
|
250
|
+
}).join(", ");
|
|
251
|
+
}
|
|
252
|
+
var defaultShadows = {
|
|
253
|
+
...Object.fromEntries(
|
|
254
|
+
Object.entries(defaultShadowDefinitions).map(([k, layers]) => [
|
|
255
|
+
k,
|
|
256
|
+
shadowLayersToCSS(layers)
|
|
257
|
+
])
|
|
258
|
+
),
|
|
259
|
+
none: "none"
|
|
260
|
+
};
|
|
261
|
+
var defaultRadius = {
|
|
262
|
+
none: "0",
|
|
263
|
+
xs: "0.125rem",
|
|
264
|
+
sm: "0.25rem",
|
|
265
|
+
md: "0.375rem",
|
|
266
|
+
lg: "0.5rem",
|
|
267
|
+
xl: "0.75rem",
|
|
268
|
+
"2xl": "1rem",
|
|
269
|
+
"3xl": "1.5rem",
|
|
270
|
+
full: "9999px"
|
|
271
|
+
};
|
|
272
|
+
var defaultTransitions = {
|
|
273
|
+
duration: { fast: "150ms", base: "300ms", slow: "500ms" },
|
|
274
|
+
timing: {
|
|
275
|
+
ease: "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
276
|
+
easeIn: "cubic-bezier(0.4, 0, 1, 1)",
|
|
277
|
+
easeOut: "cubic-bezier(0, 0, 0.2, 1)",
|
|
278
|
+
easeInOut: "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
279
|
+
linear: "linear"
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
var defaultZIndex = {
|
|
283
|
+
dropdown: 1e3,
|
|
284
|
+
sticky: 1020,
|
|
285
|
+
fixed: 1030,
|
|
286
|
+
modalBackdrop: 1040,
|
|
287
|
+
modal: 1050,
|
|
288
|
+
popover: 1060,
|
|
289
|
+
tooltip: 1070,
|
|
290
|
+
toast: 1080
|
|
291
|
+
};
|
|
292
|
+
function buildLightTheme(colors) {
|
|
293
|
+
const c = { ...defaultColorPreset, ...colors };
|
|
294
|
+
return {
|
|
295
|
+
mode: "light",
|
|
296
|
+
colors: c,
|
|
297
|
+
spacing: { ...defaultSpacing },
|
|
298
|
+
typography: { ...defaultTypography },
|
|
299
|
+
shadows: { ...defaultShadows },
|
|
300
|
+
shadowDefinitions: { ...defaultShadowDefinitions },
|
|
301
|
+
radius: { ...defaultRadius },
|
|
302
|
+
transitions: { ...defaultTransitions },
|
|
303
|
+
zIndex: { ...defaultZIndex }
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function buildDarkTheme(colors) {
|
|
307
|
+
const base = buildLightTheme(defaultColorPresetDark);
|
|
308
|
+
const c = { ...defaultColorPresetDark, ...colors };
|
|
309
|
+
return { ...base, mode: "dark", colors: c };
|
|
310
|
+
}
|
|
311
|
+
function createTheme(overrides) {
|
|
312
|
+
return {
|
|
313
|
+
light: buildLightTheme(overrides.light ?? {}),
|
|
314
|
+
dark: buildDarkTheme(overrides.dark ?? {})
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
var defaultTheme = buildLightTheme({});
|
|
318
|
+
|
|
319
|
+
// src/branding.ts
|
|
320
|
+
var LOGO_VARIANT_SIZES = {
|
|
321
|
+
primary: { width: 1080, height: 1080 },
|
|
322
|
+
favicon32: { width: 32, height: 32 },
|
|
323
|
+
favicon16: { width: 16, height: 16 },
|
|
324
|
+
appleTouchIcon: { width: 180, height: 180 },
|
|
325
|
+
pwa192: { width: 192, height: 192 },
|
|
326
|
+
pwa512: { width: 512, height: 512 }
|
|
327
|
+
};
|
|
328
|
+
var defaultBranding = {
|
|
329
|
+
name: "Grundtone",
|
|
330
|
+
tagline: "A cross-platform design system",
|
|
331
|
+
logos: {
|
|
332
|
+
primary: "@grundtone/core/assets/logo.png",
|
|
333
|
+
favicon32: "@grundtone/core/assets/logo-32x32.png",
|
|
334
|
+
favicon16: "@grundtone/core/assets/logo-16x16.png",
|
|
335
|
+
appleTouchIcon: "@grundtone/core/assets/logo-180x180.png",
|
|
336
|
+
pwa192: "@grundtone/core/assets/logo-192x192.png",
|
|
337
|
+
pwa512: "@grundtone/core/assets/logo-512x512.png"
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
function createBranding(overrides) {
|
|
341
|
+
if (!overrides) return { ...defaultBranding };
|
|
342
|
+
return {
|
|
343
|
+
name: overrides.name ?? defaultBranding.name,
|
|
344
|
+
tagline: overrides.tagline ?? defaultBranding.tagline,
|
|
345
|
+
logos: {
|
|
346
|
+
...defaultBranding.logos,
|
|
347
|
+
...overrides.logos
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export { LOGO_VARIANT_SIZES, SEMANTIC_COLOR_KEYS, THEME_INJECTION_KEY, createBranding, createTheme, defaultBranding, defaultColorPreset, defaultColorPresetDark, defaultRadius, defaultShadowDefinitions, defaultShadows, defaultSpacing, defaultTheme, defaultTransitions, defaultTypography, defaultZIndex, hexToRgb, shadowLayersToCSS };
|
|
353
|
+
//# sourceMappingURL=index.mjs.map
|
|
354
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/theme.ts","../src/theme-preset.ts","../src/branding.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { InjectionKey, Ref } from 'vue';\n\nexport type ThemeMode = 'light' | 'dark' | 'auto';\n\n/**\n * Semantic color tokens – configure these to match your brand.\n * All keys map to CSS var: --color-{kebab-case-key}\n *\n * Shade-based naming: `primaryLight`/`primaryDark` instead of state-based\n * (`primaryHover`/`primaryActive`). Components decide which shade to use\n * for hover, active, tint, etc.\n */\nexport interface ThemeColors {\n // Brand\n primary: string;\n primaryLight: string;\n primaryDark: string;\n onPrimary: string;\n secondary: string;\n secondaryLight: string;\n secondaryDark: string;\n // Status\n success: string;\n successLight: string;\n successDark: string;\n warning: string;\n warningLight: string;\n warningDark: string;\n error: string;\n errorLight: string;\n errorDark: string;\n info: string;\n infoLight: string;\n infoDark: string;\n // Surface\n background: string;\n backgroundAlt: string;\n surface: string;\n surfaceAlt: string;\n surfaceRaised: string;\n surfaceOverlay: string;\n modalBackdrop: string;\n // Text\n text: string;\n textSecondary: string;\n textTertiary: string;\n textInverse: string;\n textPlaceholder: string;\n textDisabled: string;\n // Border\n borderLight: string;\n borderMedium: string;\n borderStrong: string;\n borderInverse: string;\n // Focus\n focus: string;\n focusRing: string;\n // Neutral\n neutral: string;\n}\n\nexport interface ThemeSpacing {\n xs: string;\n sm: string;\n md: string;\n lg: string;\n xl: string;\n '2xl': string;\n '3xl': string;\n '4xl': string;\n}\n\nexport interface ThemeTypography {\n fontFamily: {\n base: string;\n heading: string;\n mono: string;\n };\n fontSize: {\n xs: string;\n sm: string;\n base: string;\n lg: string;\n xl: string;\n '2xl': string;\n '3xl': string;\n '4xl': string;\n '5xl': string;\n };\n fontWeight: {\n thin: number;\n light: number;\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n extrabold: number;\n };\n lineHeight: {\n none: number;\n tight: number;\n snug: number;\n normal: number;\n relaxed: number;\n loose: number;\n };\n}\n\nexport interface ThemeShadows {\n xs: string;\n sm: string;\n md: string;\n lg: string;\n xl: string;\n '2xl': string;\n inner: string;\n none: string;\n}\n\n/**\n * Structured shadow layer — platform-agnostic description of a single\n * CSS box-shadow layer. Web converts to CSS string; React Native converts\n * to iOS shadowColor/Offset/Opacity/Radius + Android elevation.\n */\nexport interface ShadowLayer {\n x: number;\n y: number;\n blur: number;\n spread: number;\n color: string;\n opacity: number;\n inset?: boolean;\n}\n\nexport interface ThemeRadius {\n none: string;\n xs: string;\n sm: string;\n md: string;\n lg: string;\n xl: string;\n '2xl': string;\n '3xl': string;\n full: string;\n}\n\nexport interface ThemeTransitions {\n duration: {\n fast: string;\n base: string;\n slow: string;\n };\n timing: {\n ease: string;\n easeIn: string;\n easeOut: string;\n easeInOut: string;\n linear: string;\n };\n}\n\nexport interface ThemeZIndex {\n dropdown: number;\n sticky: number;\n fixed: number;\n modalBackdrop: number;\n modal: number;\n popover: number;\n tooltip: number;\n toast: number;\n}\n\nexport interface Theme {\n mode: ThemeMode;\n colors: ThemeColors;\n spacing: ThemeSpacing;\n typography: ThemeTypography;\n shadows: ThemeShadows;\n shadowDefinitions: Record<string, ShadowLayer[]>;\n radius: ThemeRadius;\n transitions: ThemeTransitions;\n zIndex: ThemeZIndex;\n}\n\nexport interface ThemeProviderContext {\n theme: Readonly<Ref<Theme>>;\n mode: Readonly<Ref<ThemeMode>>;\n isDark: Readonly<Ref<boolean>>;\n isLight: Readonly<Ref<boolean>>;\n setMode: (mode: ThemeMode) => void;\n toggleMode: () => void;\n applyTheme: () => void;\n}\n\nexport const THEME_INJECTION_KEY: InjectionKey<ThemeProviderContext> =\n Symbol('grundtone-theme');\n\n/**\n * Theme configuration: either a single partial theme (applies to both modes)\n * or separate light/dark overrides for proper dark mode support.\n */\nexport type ThemeConfig =\n | Partial<Theme>\n | { light?: Partial<Theme>; dark?: Partial<Theme> };\n\nexport interface ThemeProviderProps {\n mode?: ThemeMode;\n theme?: ThemeConfig;\n enableTransitions?: boolean;\n persistMode?: boolean;\n storageKey?: string;\n}\n","/**\n * Grundtone Theme Preset\n *\n * Standard reference colors. When installing Grundtone, you MUST configure your\n * theme colors - either customize this preset or provide your own.\n * The design system will not apply colors until you explicitly pass a theme.\n *\n * @example\n * // Nuxt: Configure in nuxt.config.ts\n * grundtone: {\n * theme: {\n * light: { colors: { primary: '#your-brand', ... } },\n * dark: { colors: { primary: '#your-brand-dark', ... } }\n * }\n * }\n *\n * @example\n * // Vue: Pass to ThemeProvider\n * import { defaultTheme, createTheme } from '@grundtone/core';\n * <ThemeProvider :theme=\"defaultTheme\" />\n */\n\nimport type { ShadowLayer, Theme, ThemeShadows } from './theme';\n\nexport type ColorPreset = Theme['colors'];\n\n/**\n * Semantic color keys – all colors your app should configure.\n */\nexport const SEMANTIC_COLOR_KEYS = [\n // Brand\n 'primary',\n 'primaryLight',\n 'primaryDark',\n 'onPrimary',\n 'secondary',\n 'secondaryLight',\n 'secondaryDark',\n // Status\n 'success',\n 'successLight',\n 'successDark',\n 'warning',\n 'warningLight',\n 'warningDark',\n 'error',\n 'errorLight',\n 'errorDark',\n 'info',\n 'infoLight',\n 'infoDark',\n // Surface\n 'background',\n 'backgroundAlt',\n 'surface',\n 'surfaceAlt',\n 'surfaceRaised',\n 'surfaceOverlay',\n 'modalBackdrop',\n // Text\n 'text',\n 'textSecondary',\n 'textTertiary',\n 'textInverse',\n 'textPlaceholder',\n 'textDisabled',\n // Border\n 'borderLight',\n 'borderMedium',\n 'borderStrong',\n 'borderInverse',\n // Focus\n 'focus',\n 'focusRing',\n // Neutral\n 'neutral',\n] as const;\n\n/**\n * Standard reference colors (Bootstrap-inspired).\n * Copy and customize – do not use passively without reviewing.\n */\nexport const defaultColorPreset: ColorPreset = {\n // Brand\n primary: '#0059b3',\n primaryLight: '#3381cc',\n primaryDark: '#003a7a',\n onPrimary: '#ffffff',\n secondary: '#6c757d',\n secondaryLight: '#868e96',\n secondaryDark: '#494f54',\n // Status\n success: '#198754',\n successLight: '#d1e7dd',\n successDark: '#146c43',\n warning: '#ffc107',\n warningLight: '#fff3cd',\n warningDark: '#cc9a06',\n error: '#dc3545',\n errorLight: '#f8d7da',\n errorDark: '#b02a37',\n info: '#0dcaf0',\n infoLight: '#cff4fc',\n infoDark: '#0aa2c0',\n // Surface\n background: '#ffffff',\n backgroundAlt: '#fafafa',\n surface: '#f8f9fa',\n surfaceAlt: '#f0f1f2',\n surfaceRaised: '#ffffff',\n surfaceOverlay: 'rgba(255,255,255,0.95)',\n modalBackdrop: 'rgba(0,0,0,0.5)',\n // Text\n text: '#212529',\n textSecondary: '#6c757d',\n textTertiary: '#adb5bd',\n textInverse: '#ffffff',\n textPlaceholder: '#a3a3a3',\n textDisabled: '#d4d4d4',\n // Border\n borderLight: '#dee2e6',\n borderMedium: '#ced4da',\n borderStrong: '#adb5bd',\n borderInverse: 'rgba(255,255,255,0.2)',\n // Focus\n focus: '#0059b3',\n focusRing: 'rgba(0,89,179,0.25)',\n // Neutral\n neutral: '#6c757d',\n};\n\n/**\n * Dark mode preset (standard reference).\n */\nexport const defaultColorPresetDark: ColorPreset = {\n // Brand\n primary: '#4dabf7',\n primaryLight: '#74c0fc',\n primaryDark: '#339af0',\n onPrimary: '#121212',\n secondary: '#adb5bd',\n secondaryLight: '#ced4da',\n secondaryDark: '#868e96',\n // Status\n success: '#51cf66',\n successLight: '#1a3d20',\n successDark: '#40c057',\n warning: '#ffd43b',\n warningLight: '#3d3a1a',\n warningDark: '#fab005',\n error: '#ff6b6b',\n errorLight: '#3d1a1c',\n errorDark: '#fa5252',\n info: '#4dabf7',\n infoLight: '#1a2e3d',\n infoDark: '#339af0',\n // Surface\n background: '#121212',\n backgroundAlt: '#1a1a1a',\n surface: '#1e1e1e',\n surfaceAlt: '#252525',\n surfaceRaised: '#2a2a2a',\n surfaceOverlay: 'rgba(30,30,30,0.95)',\n modalBackdrop: 'rgba(0,0,0,0.7)',\n // Text\n text: '#ffffff',\n textSecondary: '#b0b0b0',\n textTertiary: '#808080',\n textInverse: '#121212',\n textPlaceholder: '#666666',\n textDisabled: '#4a4a4a',\n // Border\n borderLight: '#404040',\n borderMedium: '#505050',\n borderStrong: '#606060',\n borderInverse: 'rgba(0,0,0,0.3)',\n // Focus\n focus: '#4dabf7',\n focusRing: 'rgba(77,171,247,0.25)',\n // Neutral\n neutral: '#9e9e9e',\n};\n\n/**\n * 8px base unit spacing system.\n * All values are multiples of the 8px grid (4px = 0.5×, 8px = 1×, 16px = 2×, etc.).\n * Web: used as rem via CSS custom properties (--space-*).\n * React Native: convert to numbers (4, 8, 16, 24, 32, 48, 64, 80).\n */\nexport const defaultSpacing = {\n xs: '0.25rem', // 4px — 0.5× base\n sm: '0.5rem', // 8px — 1× base\n md: '1rem', // 16px — 2× base\n lg: '1.5rem', // 24px — 3× base\n xl: '2rem', // 32px — 4× base\n '2xl': '3rem', // 48px — 6× base\n '3xl': '4rem', // 64px — 8× base\n '4xl': '6rem', // 96px — 12× base\n} as const;\n\nexport const defaultTypography = {\n fontFamily: {\n base: \"'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif\",\n heading:\n \"'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif\",\n mono: \"'IBM Plex Mono', 'Courier New', monospace\",\n },\n fontSize: {\n xs: '0.75rem',\n sm: '0.875rem',\n base: '1rem',\n lg: '1.125rem',\n xl: '1.25rem',\n '2xl': '1.5rem',\n '3xl': '1.875rem',\n '4xl': '2.25rem',\n '5xl': '3rem',\n },\n fontWeight: {\n thin: 100,\n light: 300,\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n extrabold: 800,\n },\n lineHeight: {\n none: 1,\n tight: 1.25,\n snug: 1.375,\n normal: 1.5,\n relaxed: 1.625,\n loose: 2,\n },\n} as const;\n\n/**\n * Structured shadow definitions — single source of truth.\n * Web: converted to CSS box-shadow strings via shadowLayersToCSS().\n * React Native: converted to iOS/Android shadow styles via shadowToRN().\n */\nexport const defaultShadowDefinitions: Record<string, ShadowLayer[]> = {\n xs: [{ x: 0, y: 1, blur: 2, spread: 0, color: '#000000', opacity: 0.05 }],\n sm: [\n { x: 0, y: 1, blur: 3, spread: 0, color: '#000000', opacity: 0.1 },\n { x: 0, y: 1, blur: 2, spread: 0, color: '#000000', opacity: 0.06 },\n ],\n md: [\n { x: 0, y: 4, blur: 6, spread: -1, color: '#000000', opacity: 0.1 },\n { x: 0, y: 2, blur: 4, spread: -1, color: '#000000', opacity: 0.06 },\n ],\n lg: [\n { x: 0, y: 10, blur: 15, spread: -3, color: '#000000', opacity: 0.1 },\n { x: 0, y: 4, blur: 6, spread: -2, color: '#000000', opacity: 0.05 },\n ],\n xl: [\n { x: 0, y: 20, blur: 25, spread: -5, color: '#000000', opacity: 0.1 },\n { x: 0, y: 10, blur: 10, spread: -5, color: '#000000', opacity: 0.04 },\n ],\n '2xl': [\n { x: 0, y: 25, blur: 50, spread: -12, color: '#000000', opacity: 0.25 },\n ],\n inner: [\n {\n x: 0,\n y: 2,\n blur: 4,\n spread: 0,\n color: '#000000',\n opacity: 0.06,\n inset: true,\n },\n ],\n};\n\n/** Parse a hex color string (#RGB or #RRGGBB) to { r, g, b }. */\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } {\n const h = hex.replace('#', '');\n const full = h.length === 3 ? h[0] + h[0] + h[1] + h[1] + h[2] + h[2] : h;\n return {\n r: parseInt(full.slice(0, 2), 16),\n g: parseInt(full.slice(2, 4), 16),\n b: parseInt(full.slice(4, 6), 16),\n };\n}\n\n/** Convert structured shadow layers to a CSS box-shadow string. */\nexport function shadowLayersToCSS(layers: ShadowLayer[]): string {\n return layers\n .map(l => {\n const inset = l.inset ? 'inset ' : '';\n const px = (n: number) => (n === 0 ? '0' : `${n}px`);\n const { r, g, b } = hexToRgb(l.color);\n return `${inset}${px(l.x)} ${px(l.y)} ${px(l.blur)} ${px(l.spread)} rgba(${r}, ${g}, ${b}, ${l.opacity})`;\n })\n .join(', ');\n}\n\n/** CSS shadow strings derived from structured definitions. */\nexport const defaultShadows: ThemeShadows = {\n ...(Object.fromEntries(\n Object.entries(defaultShadowDefinitions).map(([k, layers]) => [\n k,\n shadowLayersToCSS(layers),\n ]),\n ) as Omit<ThemeShadows, 'none'>),\n none: 'none',\n};\n\nexport const defaultRadius = {\n none: '0',\n xs: '0.125rem',\n sm: '0.25rem',\n md: '0.375rem',\n lg: '0.5rem',\n xl: '0.75rem',\n '2xl': '1rem',\n '3xl': '1.5rem',\n full: '9999px',\n} as const;\n\nexport const defaultTransitions = {\n duration: { fast: '150ms', base: '300ms', slow: '500ms' },\n timing: {\n ease: 'cubic-bezier(0.4, 0, 0.2, 1)',\n easeIn: 'cubic-bezier(0.4, 0, 1, 1)',\n easeOut: 'cubic-bezier(0, 0, 0.2, 1)',\n easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)',\n linear: 'linear',\n },\n} as const;\n\nexport const defaultZIndex = {\n dropdown: 1000,\n sticky: 1020,\n fixed: 1030,\n modalBackdrop: 1040,\n modal: 1050,\n popover: 1060,\n tooltip: 1070,\n toast: 1080,\n} as const;\n\nfunction buildLightTheme(colors: Partial<ColorPreset>): Theme {\n const c = { ...defaultColorPreset, ...colors };\n return {\n mode: 'light',\n colors: c as Theme['colors'],\n spacing: { ...defaultSpacing },\n typography: { ...defaultTypography },\n shadows: { ...defaultShadows },\n shadowDefinitions: { ...defaultShadowDefinitions },\n radius: { ...defaultRadius },\n transitions: { ...defaultTransitions },\n zIndex: { ...defaultZIndex },\n };\n}\n\nfunction buildDarkTheme(colors: Partial<ColorPreset>): Theme {\n const base = buildLightTheme(defaultColorPresetDark);\n const c = { ...defaultColorPresetDark, ...colors };\n return { ...base, mode: 'dark', colors: c as Theme['colors'] };\n}\n\n/**\n * Create a theme with your brand colors.\n * Override only what you need – rest uses standard defaults.\n */\nexport function createTheme(overrides: {\n light?: Partial<ColorPreset>;\n dark?: Partial<ColorPreset>;\n}): { light: Theme; dark: Theme } {\n return {\n light: buildLightTheme(overrides.light ?? {}),\n dark: buildDarkTheme(overrides.dark ?? {}),\n };\n}\n\n/**\n * Default theme (standard colors).\n * Use createTheme() to customize – do not ship without reviewing colors.\n */\nexport const defaultTheme = buildLightTheme({});\n","/**\n * Grundtone Branding System\n *\n * Central branding definition — one source of truth for logo assets\n * and brand identity across web and React Native.\n *\n * @example\n * // Use defaults\n * import { defaultBranding } from '@grundtone/core';\n *\n * @example\n * // Override for your brand\n * import { createBranding } from '@grundtone/core';\n * const branding = createBranding({\n * name: 'My App',\n * tagline: 'Build something great',\n * logos: { primary: '/my-logo.png' },\n * });\n */\n\n/** Asset path for a single logo variant. */\nexport interface LogoVariants {\n /** Primary logo (1080×1080) */\n primary: string;\n /** Favicon 32×32 */\n favicon32: string;\n /** Favicon 16×16 */\n favicon16: string;\n /** Apple touch icon (180×180) */\n appleTouchIcon: string;\n /** PWA manifest icon (192×192) */\n pwa192: string;\n /** PWA manifest icon (512×512) */\n pwa512: string;\n}\n\nexport interface BrandingConfig {\n /** Brand name */\n name: string;\n /** Short tagline / description */\n tagline: string;\n /** Logo asset paths per variant */\n logos: LogoVariants;\n}\n\n/** Width and height metadata for each logo variant. */\nexport const LOGO_VARIANT_SIZES: Record<\n keyof LogoVariants,\n { width: number; height: number }\n> = {\n primary: { width: 1080, height: 1080 },\n favicon32: { width: 32, height: 32 },\n favicon16: { width: 16, height: 16 },\n appleTouchIcon: { width: 180, height: 180 },\n pwa192: { width: 192, height: 192 },\n pwa512: { width: 512, height: 512 },\n} as const;\n\n/**\n * Default branding — Grundtone reference assets.\n * Paths are relative to `@grundtone/core/assets/`.\n */\nexport const defaultBranding: BrandingConfig = {\n name: 'Grundtone',\n tagline: 'A cross-platform design system',\n logos: {\n primary: '@grundtone/core/assets/logo.png',\n favicon32: '@grundtone/core/assets/logo-32x32.png',\n favicon16: '@grundtone/core/assets/logo-16x16.png',\n appleTouchIcon: '@grundtone/core/assets/logo-180x180.png',\n pwa192: '@grundtone/core/assets/logo-192x192.png',\n pwa512: '@grundtone/core/assets/logo-512x512.png',\n },\n};\n\n/**\n * Create a branding config with your brand identity.\n * Override only what you need — the rest uses Grundtone defaults.\n */\nexport function createBranding(\n overrides?: Partial<BrandingConfig>,\n): BrandingConfig {\n if (!overrides) return { ...defaultBranding };\n\n return {\n name: overrides.name ?? defaultBranding.name,\n tagline: overrides.tagline ?? defaultBranding.tagline,\n logos: {\n ...defaultBranding.logos,\n ...overrides.logos,\n },\n };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@grundtone/core",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Core types and utilities for Grundtone",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"private": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/**",
|
|
13
|
+
"assets/**"
|
|
14
|
+
],
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./assets/*": "./assets/*"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/grundtone/grundtone.git",
|
|
26
|
+
"directory": "packages/core"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^20.17.45",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
34
|
+
"@typescript-eslint/parser": "^6.21.0",
|
|
35
|
+
"@vitejs/plugin-vue": "^5.0.3",
|
|
36
|
+
"eslint": "^8.56.0",
|
|
37
|
+
"rimraf": "^5.0.5",
|
|
38
|
+
"tsup": "^8.0.2"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"vue": "^3.5.13"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsup",
|
|
45
|
+
"dev": "tsup --watch",
|
|
46
|
+
"lint": "eslint src",
|
|
47
|
+
"test": "vitest --passWithNoTests",
|
|
48
|
+
"clean": "rimraf .turbo node_modules dist"
|
|
49
|
+
}
|
|
50
|
+
}
|