@thewhateverapp/tile-sdk 0.13.31 → 0.13.33
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/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/spec/host/OverlayHost.d.ts +68 -0
- package/dist/spec/host/OverlayHost.d.ts.map +1 -0
- package/dist/spec/host/OverlayHost.js +143 -0
- package/dist/spec/host/index.d.ts +7 -0
- package/dist/spec/host/index.d.ts.map +1 -0
- package/dist/spec/host/index.js +6 -0
- package/dist/spec/index.d.ts +29 -0
- package/dist/spec/index.d.ts.map +1 -0
- package/dist/spec/index.js +81 -0
- package/dist/spec/registry/ComponentRegistry.d.ts +208 -0
- package/dist/spec/registry/ComponentRegistry.d.ts.map +1 -0
- package/dist/spec/registry/ComponentRegistry.js +227 -0
- package/dist/spec/registry/composites/BottomSheet.d.ts +33 -0
- package/dist/spec/registry/composites/BottomSheet.d.ts.map +1 -0
- package/dist/spec/registry/composites/BottomSheet.js +98 -0
- package/dist/spec/registry/composites/CountdownCTA.d.ts +35 -0
- package/dist/spec/registry/composites/CountdownCTA.d.ts.map +1 -0
- package/dist/spec/registry/composites/CountdownCTA.js +91 -0
- package/dist/spec/registry/composites/Poll.d.ts +39 -0
- package/dist/spec/registry/composites/Poll.d.ts.map +1 -0
- package/dist/spec/registry/composites/Poll.js +76 -0
- package/dist/spec/registry/composites/Prediction.d.ts +37 -0
- package/dist/spec/registry/composites/Prediction.d.ts.map +1 -0
- package/dist/spec/registry/composites/Prediction.js +116 -0
- package/dist/spec/registry/composites/index.d.ts +33 -0
- package/dist/spec/registry/composites/index.d.ts.map +1 -0
- package/dist/spec/registry/composites/index.js +36 -0
- package/dist/spec/registry/index.d.ts +15 -0
- package/dist/spec/registry/index.d.ts.map +1 -0
- package/dist/spec/registry/index.js +24 -0
- package/dist/spec/registry/primitives/Button.d.ts +30 -0
- package/dist/spec/registry/primitives/Button.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Button.js +62 -0
- package/dist/spec/registry/primitives/Divider.d.ts +22 -0
- package/dist/spec/registry/primitives/Divider.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Divider.js +56 -0
- package/dist/spec/registry/primitives/Image.d.ts +27 -0
- package/dist/spec/registry/primitives/Image.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Image.js +36 -0
- package/dist/spec/registry/primitives/ProgressBar.d.ts +28 -0
- package/dist/spec/registry/primitives/ProgressBar.d.ts.map +1 -0
- package/dist/spec/registry/primitives/ProgressBar.js +50 -0
- package/dist/spec/registry/primitives/Row.d.ts +26 -0
- package/dist/spec/registry/primitives/Row.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Row.js +50 -0
- package/dist/spec/registry/primitives/Spacer.d.ts +18 -0
- package/dist/spec/registry/primitives/Spacer.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Spacer.js +25 -0
- package/dist/spec/registry/primitives/Stack.d.ts +22 -0
- package/dist/spec/registry/primitives/Stack.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Stack.js +41 -0
- package/dist/spec/registry/primitives/Text.d.ts +26 -0
- package/dist/spec/registry/primitives/Text.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Text.js +33 -0
- package/dist/spec/registry/primitives/index.d.ts +45 -0
- package/dist/spec/registry/primitives/index.d.ts.map +1 -0
- package/dist/spec/registry/primitives/index.js +55 -0
- package/dist/spec/renderer/BindingResolver.d.ts +35 -0
- package/dist/spec/renderer/BindingResolver.d.ts.map +1 -0
- package/dist/spec/renderer/BindingResolver.js +131 -0
- package/dist/spec/renderer/CaptionTrack.d.ts +22 -0
- package/dist/spec/renderer/CaptionTrack.d.ts.map +1 -0
- package/dist/spec/renderer/CaptionTrack.js +83 -0
- package/dist/spec/renderer/LayoutRenderer.d.ts +24 -0
- package/dist/spec/renderer/LayoutRenderer.d.ts.map +1 -0
- package/dist/spec/renderer/LayoutRenderer.js +66 -0
- package/dist/spec/renderer/OverlayCue.d.ts +20 -0
- package/dist/spec/renderer/OverlayCue.d.ts.map +1 -0
- package/dist/spec/renderer/OverlayCue.js +161 -0
- package/dist/spec/renderer/index.d.ts +10 -0
- package/dist/spec/renderer/index.d.ts.map +1 -0
- package/dist/spec/renderer/index.js +13 -0
- package/dist/spec/runtime/ActionRouter.d.ts +33 -0
- package/dist/spec/runtime/ActionRouter.d.ts.map +1 -0
- package/dist/spec/runtime/ActionRouter.js +84 -0
- package/dist/spec/runtime/OverlayRuntime.d.ts +84 -0
- package/dist/spec/runtime/OverlayRuntime.d.ts.map +1 -0
- package/dist/spec/runtime/OverlayRuntime.js +216 -0
- package/dist/spec/runtime/StateManager.d.ts +31 -0
- package/dist/spec/runtime/StateManager.d.ts.map +1 -0
- package/dist/spec/runtime/StateManager.js +60 -0
- package/dist/spec/runtime/TimeSync.d.ts +47 -0
- package/dist/spec/runtime/TimeSync.d.ts.map +1 -0
- package/dist/spec/runtime/TimeSync.js +140 -0
- package/dist/spec/runtime/index.d.ts +10 -0
- package/dist/spec/runtime/index.d.ts.map +1 -0
- package/dist/spec/runtime/index.js +13 -0
- package/dist/spec/schema.d.ts +889 -0
- package/dist/spec/schema.d.ts.map +1 -0
- package/dist/spec/schema.js +284 -0
- package/dist/spec/theme/ThemeProvider.d.ts +151 -0
- package/dist/spec/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/spec/theme/ThemeProvider.js +227 -0
- package/dist/spec/theme/index.d.ts +7 -0
- package/dist/spec/theme/index.d.ts.map +1 -0
- package/dist/spec/theme/index.js +12 -0
- package/dist/spec/types.d.ts +322 -0
- package/dist/spec/types.d.ts.map +1 -0
- package/dist/spec/types.js +36 -0
- package/package.json +8 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/spec/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay Spec Zod Schema
|
|
3
|
+
*
|
|
4
|
+
* Validates spec JSON at runtime for safety and error reporting.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Primitive Schemas
|
|
9
|
+
// =============================================================================
|
|
10
|
+
const SizeSchema = z.enum(['xs', 'sm', 'md', 'lg', 'xl', '2xl']);
|
|
11
|
+
const WeightSchema = z.enum(['normal', 'medium', 'semibold', 'bold']);
|
|
12
|
+
const ColorSchema = z.enum(['primary', 'secondary', 'success', 'warning', 'error', 'muted', 'white', 'black']);
|
|
13
|
+
const VariantSchema = z.enum(['solid', 'outline', 'ghost', 'link']);
|
|
14
|
+
const AlignSchema = z.enum(['left', 'center', 'right']);
|
|
15
|
+
const JustifySchema = z.enum(['start', 'center', 'end', 'between', 'around']);
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// Binding Schema
|
|
18
|
+
// =============================================================================
|
|
19
|
+
const BindingSchema = z.object({
|
|
20
|
+
$bind: z.string(),
|
|
21
|
+
fallback: z.unknown().optional(),
|
|
22
|
+
format: z.string().optional(),
|
|
23
|
+
});
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Action Schema
|
|
26
|
+
// =============================================================================
|
|
27
|
+
const ActionTypeSchema = z.enum([
|
|
28
|
+
'emit',
|
|
29
|
+
'setState',
|
|
30
|
+
'sequence',
|
|
31
|
+
'openTile',
|
|
32
|
+
'openFull',
|
|
33
|
+
'navigate',
|
|
34
|
+
'dismiss',
|
|
35
|
+
'fx',
|
|
36
|
+
]);
|
|
37
|
+
const ActionSchema = z.object({
|
|
38
|
+
$action: ActionTypeSchema,
|
|
39
|
+
payload: z.record(z.unknown()).optional(),
|
|
40
|
+
});
|
|
41
|
+
// =============================================================================
|
|
42
|
+
// Prop Value Schema (recursive)
|
|
43
|
+
// =============================================================================
|
|
44
|
+
const PropValueSchema = z.lazy(() => z.union([
|
|
45
|
+
z.string(),
|
|
46
|
+
z.number(),
|
|
47
|
+
z.boolean(),
|
|
48
|
+
z.null(),
|
|
49
|
+
BindingSchema,
|
|
50
|
+
ActionSchema,
|
|
51
|
+
z.array(PropValueSchema),
|
|
52
|
+
z.record(PropValueSchema),
|
|
53
|
+
]));
|
|
54
|
+
// =============================================================================
|
|
55
|
+
// Condition Schema (recursive)
|
|
56
|
+
// =============================================================================
|
|
57
|
+
const ConditionSchema = z.lazy(() => z.union([
|
|
58
|
+
// Binding condition
|
|
59
|
+
z.object({ $bind: z.string() }),
|
|
60
|
+
// Comparison condition
|
|
61
|
+
z.object({
|
|
62
|
+
op: z.enum(['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn']),
|
|
63
|
+
left: PropValueSchema,
|
|
64
|
+
right: PropValueSchema,
|
|
65
|
+
}),
|
|
66
|
+
// Logical condition
|
|
67
|
+
z.object({
|
|
68
|
+
op: z.enum(['and', 'or', 'not']),
|
|
69
|
+
conditions: z.array(ConditionSchema),
|
|
70
|
+
}),
|
|
71
|
+
]));
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// Sync Configuration
|
|
74
|
+
// =============================================================================
|
|
75
|
+
const TimeTransformSchema = z.object({
|
|
76
|
+
offsetMs: z.number().optional(),
|
|
77
|
+
scale: z.number().optional(),
|
|
78
|
+
});
|
|
79
|
+
const SyncConfigSchema = z.object({
|
|
80
|
+
timebase: z.enum(['player', 'wallClock']),
|
|
81
|
+
tick: z.enum(['raf', 'timeupdate']),
|
|
82
|
+
toleranceMs: z.number().min(0).max(1000),
|
|
83
|
+
onSeek: z.literal('recompute'),
|
|
84
|
+
transform: TimeTransformSchema.optional(),
|
|
85
|
+
freezeWhen: ConditionSchema.optional(),
|
|
86
|
+
});
|
|
87
|
+
// =============================================================================
|
|
88
|
+
// State Configuration
|
|
89
|
+
// =============================================================================
|
|
90
|
+
const StateConfigSchema = z.object({
|
|
91
|
+
local: z.record(z.unknown()),
|
|
92
|
+
});
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// Caption Track
|
|
95
|
+
// =============================================================================
|
|
96
|
+
const CaptionSegmentSchema = z.object({
|
|
97
|
+
startMs: z.number().min(0),
|
|
98
|
+
endMs: z.number().min(0),
|
|
99
|
+
text: z.string(),
|
|
100
|
+
speaker: z.string().optional(),
|
|
101
|
+
});
|
|
102
|
+
const CaptionStyleSchema = z.object({
|
|
103
|
+
position: z.enum(['top', 'bottom', 'center']),
|
|
104
|
+
size: SizeSchema,
|
|
105
|
+
background: z.enum(['none', 'solid', 'gradient']).optional(),
|
|
106
|
+
color: z.string().optional(),
|
|
107
|
+
});
|
|
108
|
+
const CaptionTrackSchema = z.object({
|
|
109
|
+
segments: z.array(CaptionSegmentSchema),
|
|
110
|
+
style: CaptionStyleSchema,
|
|
111
|
+
});
|
|
112
|
+
// =============================================================================
|
|
113
|
+
// Layout Node (recursive)
|
|
114
|
+
// =============================================================================
|
|
115
|
+
const LayoutNodeSchema = z.lazy(() => z.object({
|
|
116
|
+
type: z.string().min(1),
|
|
117
|
+
props: z.record(PropValueSchema).optional(),
|
|
118
|
+
children: z.array(LayoutNodeSchema).optional(),
|
|
119
|
+
key: z.string().optional(),
|
|
120
|
+
}));
|
|
121
|
+
// =============================================================================
|
|
122
|
+
// Placement
|
|
123
|
+
// =============================================================================
|
|
124
|
+
const TilePlacementSchema = z.object({
|
|
125
|
+
lane: z.enum(['top', 'center', 'bottom']),
|
|
126
|
+
inset: z.number().optional(),
|
|
127
|
+
align: AlignSchema.optional(),
|
|
128
|
+
});
|
|
129
|
+
const FullPlacementSchema = z.object({
|
|
130
|
+
type: z.enum(['fullscreen', 'inset', 'positioned']),
|
|
131
|
+
insets: z
|
|
132
|
+
.object({
|
|
133
|
+
top: z.number().optional(),
|
|
134
|
+
right: z.number().optional(),
|
|
135
|
+
bottom: z.number().optional(),
|
|
136
|
+
left: z.number().optional(),
|
|
137
|
+
})
|
|
138
|
+
.optional(),
|
|
139
|
+
position: z
|
|
140
|
+
.object({
|
|
141
|
+
x: z.union([z.number(), z.string()]),
|
|
142
|
+
y: z.union([z.number(), z.string()]),
|
|
143
|
+
})
|
|
144
|
+
.optional(),
|
|
145
|
+
});
|
|
146
|
+
const PlacementSchema = z.union([TilePlacementSchema, FullPlacementSchema]);
|
|
147
|
+
// =============================================================================
|
|
148
|
+
// Dismiss Policy
|
|
149
|
+
// =============================================================================
|
|
150
|
+
const DismissTriggerSchema = z.enum([
|
|
151
|
+
'tap-outside',
|
|
152
|
+
'swipe-down',
|
|
153
|
+
'timeout',
|
|
154
|
+
'action',
|
|
155
|
+
'time-window-end',
|
|
156
|
+
]);
|
|
157
|
+
const DismissPolicySchema = z.object({
|
|
158
|
+
on: z.array(DismissTriggerSchema),
|
|
159
|
+
animation: z.enum(['fade', 'slide', 'none']).optional(),
|
|
160
|
+
durationMs: z.number().min(0).optional(),
|
|
161
|
+
});
|
|
162
|
+
// =============================================================================
|
|
163
|
+
// Time Window
|
|
164
|
+
// =============================================================================
|
|
165
|
+
const TimeWindowSchema = z.object({
|
|
166
|
+
startMs: z.number().min(0).optional(),
|
|
167
|
+
endMs: z.number().min(0).optional(),
|
|
168
|
+
});
|
|
169
|
+
// =============================================================================
|
|
170
|
+
// Overlay Cue
|
|
171
|
+
// =============================================================================
|
|
172
|
+
const OverlayCueSchema = z.object({
|
|
173
|
+
id: z.string().min(1),
|
|
174
|
+
window: TimeWindowSchema,
|
|
175
|
+
visibleWhen: ConditionSchema.optional(),
|
|
176
|
+
placement: PlacementSchema,
|
|
177
|
+
dismiss: DismissPolicySchema.optional(),
|
|
178
|
+
layout: LayoutNodeSchema,
|
|
179
|
+
zIndex: z.number().optional(),
|
|
180
|
+
});
|
|
181
|
+
// =============================================================================
|
|
182
|
+
// Tracks Configuration
|
|
183
|
+
// =============================================================================
|
|
184
|
+
const TracksConfigSchema = z.object({
|
|
185
|
+
captions: CaptionTrackSchema.optional(),
|
|
186
|
+
overlays: z.array(OverlayCueSchema),
|
|
187
|
+
});
|
|
188
|
+
// =============================================================================
|
|
189
|
+
// Subscription Declaration
|
|
190
|
+
// =============================================================================
|
|
191
|
+
const SubscriptionDeclarationSchema = z.object({
|
|
192
|
+
id: z.string().min(1),
|
|
193
|
+
type: z.enum(['realtime', 'keyspace', 'host']),
|
|
194
|
+
channel: z.string().min(1),
|
|
195
|
+
target: z.string().min(1),
|
|
196
|
+
transform: z.string().optional(),
|
|
197
|
+
});
|
|
198
|
+
// =============================================================================
|
|
199
|
+
// Spec Metadata
|
|
200
|
+
// =============================================================================
|
|
201
|
+
const SpecMetaSchema = z.object({
|
|
202
|
+
title: z.string().optional(),
|
|
203
|
+
author: z.string().optional(),
|
|
204
|
+
description: z.string().optional(),
|
|
205
|
+
version: z.string().optional(),
|
|
206
|
+
});
|
|
207
|
+
// =============================================================================
|
|
208
|
+
// Main Overlay Spec Schema
|
|
209
|
+
// =============================================================================
|
|
210
|
+
export const OverlaySpecSchema = z.object({
|
|
211
|
+
specVersion: z.literal('1.0'),
|
|
212
|
+
id: z.string().min(1),
|
|
213
|
+
surface: z.enum(['tile', 'full']),
|
|
214
|
+
meta: SpecMetaSchema.optional(),
|
|
215
|
+
sync: SyncConfigSchema,
|
|
216
|
+
state: StateConfigSchema,
|
|
217
|
+
tracks: TracksConfigSchema,
|
|
218
|
+
subscriptions: z.array(SubscriptionDeclarationSchema).optional(),
|
|
219
|
+
});
|
|
220
|
+
// =============================================================================
|
|
221
|
+
// Validation Functions
|
|
222
|
+
// =============================================================================
|
|
223
|
+
export function validateSpec(spec) {
|
|
224
|
+
const result = OverlaySpecSchema.safeParse(spec);
|
|
225
|
+
if (result.success) {
|
|
226
|
+
return { success: true, data: result.data };
|
|
227
|
+
}
|
|
228
|
+
return { success: false, errors: result.error };
|
|
229
|
+
}
|
|
230
|
+
export function parseSpec(spec) {
|
|
231
|
+
return OverlaySpecSchema.parse(spec);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Validate spec against a profile (tile or full)
|
|
235
|
+
*/
|
|
236
|
+
export function validateAgainstProfile(spec, profile) {
|
|
237
|
+
const errors = [];
|
|
238
|
+
// Check overlay count
|
|
239
|
+
if (spec.tracks.overlays.length > profile.maxOverlays) {
|
|
240
|
+
errors.push(`Too many overlays: ${spec.tracks.overlays.length} (max ${profile.maxOverlays})`);
|
|
241
|
+
}
|
|
242
|
+
// Check text lengths in captions
|
|
243
|
+
if (spec.tracks.captions) {
|
|
244
|
+
for (const segment of spec.tracks.captions.segments) {
|
|
245
|
+
if (segment.text.length > profile.maxTextLength) {
|
|
246
|
+
errors.push(`Caption text too long: ${segment.text.length} chars (max ${profile.maxTextLength})`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Check for navigation actions if not allowed
|
|
251
|
+
if (!profile.allowNavigation) {
|
|
252
|
+
for (const cue of spec.tracks.overlays) {
|
|
253
|
+
if (hasNavigationAction(cue.layout)) {
|
|
254
|
+
errors.push(`Navigation actions not allowed in ${profile.name} profile`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return { valid: errors.length === 0, errors };
|
|
259
|
+
}
|
|
260
|
+
function hasNavigationAction(node) {
|
|
261
|
+
if (node.props) {
|
|
262
|
+
for (const value of Object.values(node.props)) {
|
|
263
|
+
if (typeof value === 'object' &&
|
|
264
|
+
value !== null &&
|
|
265
|
+
'$action' in value &&
|
|
266
|
+
(value.$action === 'navigate' ||
|
|
267
|
+
value.$action === 'openFull')) {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (node.children) {
|
|
273
|
+
for (const child of node.children) {
|
|
274
|
+
if (hasNavigationAction(child)) {
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
// =============================================================================
|
|
282
|
+
// Exports
|
|
283
|
+
// =============================================================================
|
|
284
|
+
export { SizeSchema, WeightSchema, ColorSchema, VariantSchema, AlignSchema, JustifySchema, BindingSchema, ActionSchema, PropValueSchema, ConditionSchema, LayoutNodeSchema, PlacementSchema, OverlayCueSchema, CaptionTrackSchema, };
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Provider
|
|
3
|
+
*
|
|
4
|
+
* Provides theming context for overlay spec components.
|
|
5
|
+
* AI agents can generate custom themes to style overlays.
|
|
6
|
+
*/
|
|
7
|
+
import { type ReactNode } from 'react';
|
|
8
|
+
export interface OverlayTheme {
|
|
9
|
+
/** Theme name/identifier */
|
|
10
|
+
name?: string;
|
|
11
|
+
/** Color palette */
|
|
12
|
+
colors: ThemeColors;
|
|
13
|
+
/** Typography */
|
|
14
|
+
typography: ThemeTypography;
|
|
15
|
+
/** Spacing scale */
|
|
16
|
+
spacing: ThemeSpacing;
|
|
17
|
+
/** Border radius */
|
|
18
|
+
radius: ThemeRadius;
|
|
19
|
+
/** Component-specific overrides */
|
|
20
|
+
components?: ThemeComponents;
|
|
21
|
+
}
|
|
22
|
+
export interface ThemeColors {
|
|
23
|
+
/** Primary brand color */
|
|
24
|
+
primary: string;
|
|
25
|
+
/** Primary color for text on primary background */
|
|
26
|
+
primaryForeground: string;
|
|
27
|
+
/** Secondary/muted color */
|
|
28
|
+
secondary: string;
|
|
29
|
+
secondaryForeground: string;
|
|
30
|
+
/** Background colors */
|
|
31
|
+
background: string;
|
|
32
|
+
backgroundMuted: string;
|
|
33
|
+
backgroundOverlay: string;
|
|
34
|
+
/** Foreground/text colors */
|
|
35
|
+
foreground: string;
|
|
36
|
+
foregroundMuted: string;
|
|
37
|
+
/** Semantic colors */
|
|
38
|
+
success: string;
|
|
39
|
+
warning: string;
|
|
40
|
+
error: string;
|
|
41
|
+
/** Border color */
|
|
42
|
+
border: string;
|
|
43
|
+
}
|
|
44
|
+
export interface ThemeTypography {
|
|
45
|
+
/** Font family for body text */
|
|
46
|
+
fontFamily: string;
|
|
47
|
+
/** Font family for headings */
|
|
48
|
+
fontFamilyHeading?: string;
|
|
49
|
+
/** Base font size */
|
|
50
|
+
fontSizeBase: string;
|
|
51
|
+
/** Size scale */
|
|
52
|
+
fontSizes: {
|
|
53
|
+
xs: string;
|
|
54
|
+
sm: string;
|
|
55
|
+
md: string;
|
|
56
|
+
lg: string;
|
|
57
|
+
xl: string;
|
|
58
|
+
'2xl': string;
|
|
59
|
+
};
|
|
60
|
+
/** Weight scale */
|
|
61
|
+
fontWeights: {
|
|
62
|
+
normal: number;
|
|
63
|
+
medium: number;
|
|
64
|
+
semibold: number;
|
|
65
|
+
bold: number;
|
|
66
|
+
};
|
|
67
|
+
/** Line heights */
|
|
68
|
+
lineHeights: {
|
|
69
|
+
tight: number;
|
|
70
|
+
normal: number;
|
|
71
|
+
relaxed: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export interface ThemeSpacing {
|
|
75
|
+
xs: string;
|
|
76
|
+
sm: string;
|
|
77
|
+
md: string;
|
|
78
|
+
lg: string;
|
|
79
|
+
xl: string;
|
|
80
|
+
'2xl': string;
|
|
81
|
+
}
|
|
82
|
+
export interface ThemeRadius {
|
|
83
|
+
none: string;
|
|
84
|
+
sm: string;
|
|
85
|
+
md: string;
|
|
86
|
+
lg: string;
|
|
87
|
+
full: string;
|
|
88
|
+
}
|
|
89
|
+
export interface ThemeComponents {
|
|
90
|
+
/** Caption-specific styling */
|
|
91
|
+
caption?: {
|
|
92
|
+
background?: string;
|
|
93
|
+
textColor?: string;
|
|
94
|
+
speakerColor?: string;
|
|
95
|
+
backdropBlur?: boolean;
|
|
96
|
+
borderRadius?: string;
|
|
97
|
+
padding?: string;
|
|
98
|
+
};
|
|
99
|
+
/** Button overrides */
|
|
100
|
+
button?: {
|
|
101
|
+
borderRadius?: string;
|
|
102
|
+
fontWeight?: number;
|
|
103
|
+
};
|
|
104
|
+
/** Card/container overrides */
|
|
105
|
+
card?: {
|
|
106
|
+
background?: string;
|
|
107
|
+
borderRadius?: string;
|
|
108
|
+
shadow?: string;
|
|
109
|
+
};
|
|
110
|
+
/** Progress bar overrides */
|
|
111
|
+
progressBar?: {
|
|
112
|
+
trackColor?: string;
|
|
113
|
+
height?: string;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export declare const defaultTheme: OverlayTheme;
|
|
117
|
+
export declare const darkTheme: OverlayTheme;
|
|
118
|
+
export declare const lightTheme: OverlayTheme;
|
|
119
|
+
export declare const neonTheme: OverlayTheme;
|
|
120
|
+
export declare const warmTheme: OverlayTheme;
|
|
121
|
+
export declare const coolTheme: OverlayTheme;
|
|
122
|
+
export interface ThemeProviderProps {
|
|
123
|
+
/** Theme to use */
|
|
124
|
+
theme?: Partial<OverlayTheme>;
|
|
125
|
+
/** Base theme to extend */
|
|
126
|
+
baseTheme?: OverlayTheme;
|
|
127
|
+
children: ReactNode;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Provides theme context to overlay components.
|
|
131
|
+
*/
|
|
132
|
+
export declare function ThemeProvider({ theme, baseTheme, children, }: ThemeProviderProps): JSX.Element;
|
|
133
|
+
/**
|
|
134
|
+
* Get the current theme.
|
|
135
|
+
*/
|
|
136
|
+
export declare function useTheme(): OverlayTheme;
|
|
137
|
+
/**
|
|
138
|
+
* Get theme colors.
|
|
139
|
+
*/
|
|
140
|
+
export declare function useThemeColors(): ThemeColors;
|
|
141
|
+
/**
|
|
142
|
+
* Get a specific color from the theme.
|
|
143
|
+
*/
|
|
144
|
+
export declare function useThemeColor(color: keyof ThemeColors | 'primary' | 'secondary' | 'success' | 'warning' | 'error'): string;
|
|
145
|
+
/**
|
|
146
|
+
* Generates CSS custom properties from a theme.
|
|
147
|
+
* Can be injected into a style tag for CSS-based theming.
|
|
148
|
+
*/
|
|
149
|
+
export declare function generateThemeCSS(theme: OverlayTheme): string;
|
|
150
|
+
export default ThemeProvider;
|
|
151
|
+
//# sourceMappingURL=ThemeProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../src/spec/theme/ThemeProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Provider
|
|
3
|
+
*
|
|
4
|
+
* Provides theming context for overlay spec components.
|
|
5
|
+
* AI agents can generate custom themes to style overlays.
|
|
6
|
+
*/
|
|
7
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Default Theme
|
|
10
|
+
// =============================================================================
|
|
11
|
+
export const defaultTheme = {
|
|
12
|
+
name: 'default',
|
|
13
|
+
colors: {
|
|
14
|
+
primary: '#a855f7', // purple-500
|
|
15
|
+
primaryForeground: '#ffffff',
|
|
16
|
+
secondary: '#6b7280', // gray-500
|
|
17
|
+
secondaryForeground: '#ffffff',
|
|
18
|
+
background: '#1f2937', // gray-800
|
|
19
|
+
backgroundMuted: '#374151', // gray-700
|
|
20
|
+
backgroundOverlay: 'rgba(0, 0, 0, 0.6)',
|
|
21
|
+
foreground: '#ffffff',
|
|
22
|
+
foregroundMuted: '#9ca3af', // gray-400
|
|
23
|
+
success: '#22c55e', // green-500
|
|
24
|
+
warning: '#eab308', // yellow-500
|
|
25
|
+
error: '#ef4444', // red-500
|
|
26
|
+
border: '#4b5563', // gray-600
|
|
27
|
+
},
|
|
28
|
+
typography: {
|
|
29
|
+
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
30
|
+
fontSizeBase: '16px',
|
|
31
|
+
fontSizes: {
|
|
32
|
+
xs: '0.75rem',
|
|
33
|
+
sm: '0.875rem',
|
|
34
|
+
md: '1rem',
|
|
35
|
+
lg: '1.125rem',
|
|
36
|
+
xl: '1.25rem',
|
|
37
|
+
'2xl': '1.5rem',
|
|
38
|
+
},
|
|
39
|
+
fontWeights: {
|
|
40
|
+
normal: 400,
|
|
41
|
+
medium: 500,
|
|
42
|
+
semibold: 600,
|
|
43
|
+
bold: 700,
|
|
44
|
+
},
|
|
45
|
+
lineHeights: {
|
|
46
|
+
tight: 1.25,
|
|
47
|
+
normal: 1.5,
|
|
48
|
+
relaxed: 1.75,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
spacing: {
|
|
52
|
+
xs: '0.25rem',
|
|
53
|
+
sm: '0.5rem',
|
|
54
|
+
md: '1rem',
|
|
55
|
+
lg: '1.5rem',
|
|
56
|
+
xl: '2rem',
|
|
57
|
+
'2xl': '2.5rem',
|
|
58
|
+
},
|
|
59
|
+
radius: {
|
|
60
|
+
none: '0',
|
|
61
|
+
sm: '0.25rem',
|
|
62
|
+
md: '0.5rem',
|
|
63
|
+
lg: '0.75rem',
|
|
64
|
+
full: '9999px',
|
|
65
|
+
},
|
|
66
|
+
components: {
|
|
67
|
+
caption: {
|
|
68
|
+
backdropBlur: true,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// Dark/Light Presets
|
|
74
|
+
// =============================================================================
|
|
75
|
+
export const darkTheme = {
|
|
76
|
+
...defaultTheme,
|
|
77
|
+
name: 'dark',
|
|
78
|
+
};
|
|
79
|
+
export const lightTheme = {
|
|
80
|
+
...defaultTheme,
|
|
81
|
+
name: 'light',
|
|
82
|
+
colors: {
|
|
83
|
+
...defaultTheme.colors,
|
|
84
|
+
background: '#f9fafb', // gray-50
|
|
85
|
+
backgroundMuted: '#f3f4f6', // gray-100
|
|
86
|
+
backgroundOverlay: 'rgba(255, 255, 255, 0.9)',
|
|
87
|
+
foreground: '#111827', // gray-900
|
|
88
|
+
foregroundMuted: '#6b7280', // gray-500
|
|
89
|
+
border: '#e5e7eb', // gray-200
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
// =============================================================================
|
|
93
|
+
// Vibrant Theme Presets (for AI to use)
|
|
94
|
+
// =============================================================================
|
|
95
|
+
export const neonTheme = {
|
|
96
|
+
...defaultTheme,
|
|
97
|
+
name: 'neon',
|
|
98
|
+
colors: {
|
|
99
|
+
...defaultTheme.colors,
|
|
100
|
+
primary: '#00ff88',
|
|
101
|
+
primaryForeground: '#000000',
|
|
102
|
+
background: '#0a0a0a',
|
|
103
|
+
backgroundOverlay: 'rgba(0, 0, 0, 0.85)',
|
|
104
|
+
success: '#00ff88',
|
|
105
|
+
warning: '#ffff00',
|
|
106
|
+
error: '#ff0055',
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
export const warmTheme = {
|
|
110
|
+
...defaultTheme,
|
|
111
|
+
name: 'warm',
|
|
112
|
+
colors: {
|
|
113
|
+
...defaultTheme.colors,
|
|
114
|
+
primary: '#f97316', // orange-500
|
|
115
|
+
background: '#292524', // stone-800
|
|
116
|
+
backgroundMuted: '#44403c', // stone-700
|
|
117
|
+
foregroundMuted: '#a8a29e', // stone-400
|
|
118
|
+
border: '#57534e', // stone-600
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
export const coolTheme = {
|
|
122
|
+
...defaultTheme,
|
|
123
|
+
name: 'cool',
|
|
124
|
+
colors: {
|
|
125
|
+
...defaultTheme.colors,
|
|
126
|
+
primary: '#06b6d4', // cyan-500
|
|
127
|
+
background: '#0c4a6e', // sky-900
|
|
128
|
+
backgroundMuted: '#075985', // sky-800
|
|
129
|
+
foregroundMuted: '#7dd3fc', // sky-300
|
|
130
|
+
border: '#0284c7', // sky-600
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
// =============================================================================
|
|
134
|
+
// Theme Context
|
|
135
|
+
// =============================================================================
|
|
136
|
+
const ThemeContext = createContext(defaultTheme);
|
|
137
|
+
/**
|
|
138
|
+
* Provides theme context to overlay components.
|
|
139
|
+
*/
|
|
140
|
+
export function ThemeProvider({ theme, baseTheme = defaultTheme, children, }) {
|
|
141
|
+
const mergedTheme = useMemo(() => {
|
|
142
|
+
if (!theme)
|
|
143
|
+
return baseTheme;
|
|
144
|
+
return {
|
|
145
|
+
...baseTheme,
|
|
146
|
+
...theme,
|
|
147
|
+
colors: { ...baseTheme.colors, ...theme.colors },
|
|
148
|
+
typography: { ...baseTheme.typography, ...theme.typography },
|
|
149
|
+
spacing: { ...baseTheme.spacing, ...theme.spacing },
|
|
150
|
+
radius: { ...baseTheme.radius, ...theme.radius },
|
|
151
|
+
components: { ...baseTheme.components, ...theme.components },
|
|
152
|
+
};
|
|
153
|
+
}, [theme, baseTheme]);
|
|
154
|
+
return (React.createElement(ThemeContext.Provider, { value: mergedTheme }, children));
|
|
155
|
+
}
|
|
156
|
+
// =============================================================================
|
|
157
|
+
// Hooks
|
|
158
|
+
// =============================================================================
|
|
159
|
+
/**
|
|
160
|
+
* Get the current theme.
|
|
161
|
+
*/
|
|
162
|
+
export function useTheme() {
|
|
163
|
+
return useContext(ThemeContext);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get theme colors.
|
|
167
|
+
*/
|
|
168
|
+
export function useThemeColors() {
|
|
169
|
+
return useTheme().colors;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get a specific color from the theme.
|
|
173
|
+
*/
|
|
174
|
+
export function useThemeColor(color) {
|
|
175
|
+
const colors = useThemeColors();
|
|
176
|
+
return colors[color] ?? colors.primary;
|
|
177
|
+
}
|
|
178
|
+
// =============================================================================
|
|
179
|
+
// CSS Variable Injection
|
|
180
|
+
// =============================================================================
|
|
181
|
+
/**
|
|
182
|
+
* Generates CSS custom properties from a theme.
|
|
183
|
+
* Can be injected into a style tag for CSS-based theming.
|
|
184
|
+
*/
|
|
185
|
+
export function generateThemeCSS(theme) {
|
|
186
|
+
return `
|
|
187
|
+
:root {
|
|
188
|
+
/* Colors */
|
|
189
|
+
--overlay-color-primary: ${theme.colors.primary};
|
|
190
|
+
--overlay-color-primary-fg: ${theme.colors.primaryForeground};
|
|
191
|
+
--overlay-color-secondary: ${theme.colors.secondary};
|
|
192
|
+
--overlay-color-secondary-fg: ${theme.colors.secondaryForeground};
|
|
193
|
+
--overlay-color-background: ${theme.colors.background};
|
|
194
|
+
--overlay-color-background-muted: ${theme.colors.backgroundMuted};
|
|
195
|
+
--overlay-color-background-overlay: ${theme.colors.backgroundOverlay};
|
|
196
|
+
--overlay-color-foreground: ${theme.colors.foreground};
|
|
197
|
+
--overlay-color-foreground-muted: ${theme.colors.foregroundMuted};
|
|
198
|
+
--overlay-color-success: ${theme.colors.success};
|
|
199
|
+
--overlay-color-warning: ${theme.colors.warning};
|
|
200
|
+
--overlay-color-error: ${theme.colors.error};
|
|
201
|
+
--overlay-color-border: ${theme.colors.border};
|
|
202
|
+
|
|
203
|
+
/* Typography */
|
|
204
|
+
--overlay-font-family: ${theme.typography.fontFamily};
|
|
205
|
+
--overlay-font-size-xs: ${theme.typography.fontSizes.xs};
|
|
206
|
+
--overlay-font-size-sm: ${theme.typography.fontSizes.sm};
|
|
207
|
+
--overlay-font-size-md: ${theme.typography.fontSizes.md};
|
|
208
|
+
--overlay-font-size-lg: ${theme.typography.fontSizes.lg};
|
|
209
|
+
--overlay-font-size-xl: ${theme.typography.fontSizes.xl};
|
|
210
|
+
--overlay-font-size-2xl: ${theme.typography.fontSizes['2xl']};
|
|
211
|
+
|
|
212
|
+
/* Spacing */
|
|
213
|
+
--overlay-spacing-xs: ${theme.spacing.xs};
|
|
214
|
+
--overlay-spacing-sm: ${theme.spacing.sm};
|
|
215
|
+
--overlay-spacing-md: ${theme.spacing.md};
|
|
216
|
+
--overlay-spacing-lg: ${theme.spacing.lg};
|
|
217
|
+
--overlay-spacing-xl: ${theme.spacing.xl};
|
|
218
|
+
|
|
219
|
+
/* Radius */
|
|
220
|
+
--overlay-radius-sm: ${theme.radius.sm};
|
|
221
|
+
--overlay-radius-md: ${theme.radius.md};
|
|
222
|
+
--overlay-radius-lg: ${theme.radius.lg};
|
|
223
|
+
--overlay-radius-full: ${theme.radius.full};
|
|
224
|
+
}
|
|
225
|
+
`.trim();
|
|
226
|
+
}
|
|
227
|
+
export default ThemeProvider;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Module Index
|
|
3
|
+
*
|
|
4
|
+
* Exports theme provider and presets for overlay styling.
|
|
5
|
+
*/
|
|
6
|
+
export { ThemeProvider, useTheme, useThemeColors, useThemeColor, generateThemeCSS, defaultTheme, darkTheme, lightTheme, neonTheme, warmTheme, coolTheme, type OverlayTheme, type ThemeColors, type ThemeTypography, type ThemeSpacing, type ThemeRadius, type ThemeComponents, type ThemeProviderProps, } from './ThemeProvider';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/spec/theme/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,EACb,gBAAgB,EAGhB,YAAY,EAGZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,SAAS,EAGT,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC"}
|