@multiplatform.one/storybook 6.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/LICENSE +194 -0
- package/README.md +128 -0
- package/dist/cjs/CreatePreview.cjs +561 -0
- package/dist/cjs/CreatePreview.native.js +781 -0
- package/dist/cjs/CreatePreview.native.js.map +1 -0
- package/dist/cjs/index.cjs +32 -0
- package/dist/cjs/index.native.js +40 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/esm/CreatePreview.mjs +517 -0
- package/dist/esm/CreatePreview.mjs.map +1 -0
- package/dist/esm/CreatePreview.native.js +734 -0
- package/dist/esm/CreatePreview.native.js.map +1 -0
- package/dist/esm/index.mjs +4 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +12 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/jsx/CreatePreview.mjs +517 -0
- package/dist/jsx/CreatePreview.mjs.map +1 -0
- package/dist/jsx/CreatePreview.native.js +781 -0
- package/dist/jsx/CreatePreview.native.js.map +1 -0
- package/dist/jsx/index.js +4 -0
- package/dist/jsx/index.js.map +1 -0
- package/dist/jsx/index.mjs +4 -0
- package/dist/jsx/index.mjs.map +1 -0
- package/dist/jsx/index.native.js +40 -0
- package/dist/jsx/index.native.js.map +1 -0
- package/package.json +104 -0
- package/src/CreatePreview.tsx +750 -0
- package/src/index.native.ts +12 -0
- package/src/index.ts +7 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all) __defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
16
|
+
get: () => from[key],
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
28
|
+
value: mod,
|
|
29
|
+
enumerable: true
|
|
30
|
+
}) : target, mod));
|
|
31
|
+
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
|
|
32
|
+
value: true
|
|
33
|
+
}), mod);
|
|
34
|
+
var CreatePreview_exports = {};
|
|
35
|
+
__export(CreatePreview_exports, {
|
|
36
|
+
accentColorsChannelEvent: () => accentColorsChannelEvent,
|
|
37
|
+
accentOppositeChannelEvent: () => accentOppositeChannelEvent,
|
|
38
|
+
animationNamesChannelEvent: () => animationNamesChannelEvent,
|
|
39
|
+
baseOppositeChannelEvent: () => baseOppositeChannelEvent,
|
|
40
|
+
baseThemeColorsChannelEvent: () => baseThemeColorsChannelEvent,
|
|
41
|
+
createPreview: () => createPreview,
|
|
42
|
+
frappeDebugChannelEvent: () => frappeDebugChannelEvent,
|
|
43
|
+
themeColorsChannelEvent: () => themeColorsChannelEvent,
|
|
44
|
+
themeColorsOppositeChannelEvent: () => themeColorsOppositeChannelEvent
|
|
45
|
+
});
|
|
46
|
+
module.exports = __toCommonJS(CreatePreview_exports);
|
|
47
|
+
var import_react = require("react");
|
|
48
|
+
var import_theme = require("@multiplatform.one/theme");
|
|
49
|
+
var import_platform = require("@multiplatform.one/platform");
|
|
50
|
+
var import_react_cookie = require("react-cookie");
|
|
51
|
+
var import_tamagui = require("tamagui");
|
|
52
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
|
+
const themeColorsChannelEvent = "theme-addon/theme-colors";
|
|
54
|
+
const themeColorsOppositeChannelEvent = "theme-addon/theme-colors-opposite";
|
|
55
|
+
const baseThemeColorsChannelEvent = "theme-addon/base-theme-colors";
|
|
56
|
+
const baseOppositeChannelEvent = "theme-addon/base-colors-opposite";
|
|
57
|
+
const accentColorsChannelEvent = "theme-addon/accent-colors";
|
|
58
|
+
const accentOppositeChannelEvent = "theme-addon/accent-colors-opposite";
|
|
59
|
+
const animationNamesChannelEvent = "theme-addon/animation-names";
|
|
60
|
+
const frappeDebugChannelEvent = "frappe-addon/debug-state";
|
|
61
|
+
const knobOptions = {
|
|
62
|
+
fillStyle: Object.values(import_theme.FillStyle),
|
|
63
|
+
borderRadius: Object.values(import_theme.BorderRadius),
|
|
64
|
+
borderWidth: Object.values(import_theme.BorderWidth),
|
|
65
|
+
elevation: Object.values(import_theme.Elevation),
|
|
66
|
+
space: Object.values(import_theme.Space),
|
|
67
|
+
size: Object.values(import_theme.Size),
|
|
68
|
+
textAccent: Object.values(import_theme.TextAccent),
|
|
69
|
+
headingFont: Object.values(import_theme.HeadingFont),
|
|
70
|
+
bodyFont: Object.values(import_theme.BodyFont),
|
|
71
|
+
fontWeight: Object.values(import_theme.FontWeight),
|
|
72
|
+
animation: ["none", ...import_theme.animationNames]
|
|
73
|
+
};
|
|
74
|
+
const stateKnobFields = ["fillStyle", "borderRadius", "borderWidth", "elevation", "space", "size", "textAccent", "headingFont", "bodyFont", "fontWeight"];
|
|
75
|
+
function parseValue(value) {
|
|
76
|
+
if (typeof value !== "string") return value;
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(value);
|
|
79
|
+
} catch {
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const toTitleCase = str => str.replace(/([A-Z])/g, " $1").replace(/^./, s => s.toUpperCase());
|
|
84
|
+
function createControl(key) {
|
|
85
|
+
const name = toTitleCase(key);
|
|
86
|
+
const values = knobOptions[key] ?? [];
|
|
87
|
+
const serialized = values.map(value => value);
|
|
88
|
+
const labels = Object.fromEntries(serialized.map(v => [v, v.replace("$", "")]));
|
|
89
|
+
const fallback = import_theme.defaultKnobs[key];
|
|
90
|
+
return {
|
|
91
|
+
name,
|
|
92
|
+
description: name.toLowerCase(),
|
|
93
|
+
options: serialized,
|
|
94
|
+
control: {
|
|
95
|
+
type: "select",
|
|
96
|
+
labels
|
|
97
|
+
},
|
|
98
|
+
...(fallback !== void 0 && {
|
|
99
|
+
defaultValue: fallback
|
|
100
|
+
})
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function CanvasBackground({
|
|
104
|
+
children
|
|
105
|
+
}) {
|
|
106
|
+
const tamaguiTheme = (0, import_tamagui.useTheme)();
|
|
107
|
+
const bg = tamaguiTheme.background?.val;
|
|
108
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
109
|
+
if (bg) {
|
|
110
|
+
document.body.style.backgroundColor = bg;
|
|
111
|
+
document.documentElement.style.backgroundColor = bg;
|
|
112
|
+
}
|
|
113
|
+
}, [bg]);
|
|
114
|
+
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.YStack, {
|
|
115
|
+
flex: 1,
|
|
116
|
+
minHeight: "100vh",
|
|
117
|
+
backgroundColor: "$background",
|
|
118
|
+
children
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
let _channelEmit = null;
|
|
122
|
+
function getChannelEmit() {
|
|
123
|
+
if (_channelEmit) return _channelEmit;
|
|
124
|
+
try {
|
|
125
|
+
const mod = require("storybook/preview-api");
|
|
126
|
+
const channel = mod.addons.getChannel();
|
|
127
|
+
_channelEmit = (event, data) => channel.emit(event, data);
|
|
128
|
+
return _channelEmit;
|
|
129
|
+
} catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function AnimationNamesEmitter() {
|
|
134
|
+
const emittedRef = (0, import_react.useRef)(false);
|
|
135
|
+
(0, import_react.useEffect)(() => {
|
|
136
|
+
if (emittedRef.current) return;
|
|
137
|
+
emittedRef.current = true;
|
|
138
|
+
getChannelEmit()?.(animationNamesChannelEvent, import_theme.animationNames);
|
|
139
|
+
}, []);
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
function FrappeDebugEmitter() {
|
|
143
|
+
const prevRef = (0, import_react.useRef)("");
|
|
144
|
+
const syncRef = (0, import_react.useRef)(null);
|
|
145
|
+
const [tick, setTick] = (0, import_react.useState)(0);
|
|
146
|
+
(0, import_react.useEffect)(() => {
|
|
147
|
+
let cancelled = false;
|
|
148
|
+
async function resolve() {
|
|
149
|
+
try {
|
|
150
|
+
const {
|
|
151
|
+
__getActiveSyncModule
|
|
152
|
+
} = await import("@multiplatform.one/frappe");
|
|
153
|
+
const sync = __getActiveSyncModule();
|
|
154
|
+
if (sync && !cancelled) {
|
|
155
|
+
syncRef.current = sync;
|
|
156
|
+
setTick(t => t + 1);
|
|
157
|
+
return sync.subscribeStore(() => {
|
|
158
|
+
if (!cancelled) setTick(t => t + 1);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
} catch {}
|
|
162
|
+
}
|
|
163
|
+
const cleanupPromise = resolve();
|
|
164
|
+
let attempts = 0;
|
|
165
|
+
const interval = setInterval(async () => {
|
|
166
|
+
attempts++;
|
|
167
|
+
if (syncRef.current || cancelled || attempts >= 10) {
|
|
168
|
+
clearInterval(interval);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
await resolve();
|
|
172
|
+
}, 2e3);
|
|
173
|
+
return () => {
|
|
174
|
+
cancelled = true;
|
|
175
|
+
clearInterval(interval);
|
|
176
|
+
cleanupPromise.then(unsub => unsub?.());
|
|
177
|
+
};
|
|
178
|
+
}, []);
|
|
179
|
+
(0, import_react.useEffect)(() => {
|
|
180
|
+
if (!syncRef.current) return;
|
|
181
|
+
const emit = getChannelEmit();
|
|
182
|
+
if (!emit) return;
|
|
183
|
+
try {
|
|
184
|
+
const state = syncRef.current.__debug();
|
|
185
|
+
const key = JSON.stringify(state);
|
|
186
|
+
if (key === prevRef.current) return;
|
|
187
|
+
prevRef.current = key;
|
|
188
|
+
emit(frappeDebugChannelEvent, state);
|
|
189
|
+
} catch {}
|
|
190
|
+
}, [tick]);
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
function ThemeColorEmitter() {
|
|
194
|
+
const tamaguiTheme = (0, import_tamagui.useTheme)();
|
|
195
|
+
const prevRef = (0, import_react.useRef)("");
|
|
196
|
+
(0, import_react.useEffect)(() => {
|
|
197
|
+
const colors = [];
|
|
198
|
+
for (let i = 1; i <= 12; i++) {
|
|
199
|
+
const token = tamaguiTheme[`color${i}`];
|
|
200
|
+
colors.push(token?.val ?? "");
|
|
201
|
+
}
|
|
202
|
+
const key = colors.join("|");
|
|
203
|
+
if (key === prevRef.current) return;
|
|
204
|
+
prevRef.current = key;
|
|
205
|
+
getChannelEmit()?.(themeColorsChannelEvent, colors);
|
|
206
|
+
}, [tamaguiTheme]);
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
function BaseThemeColorEmitter() {
|
|
210
|
+
const tamaguiTheme = (0, import_tamagui.useTheme)();
|
|
211
|
+
const prevRef = (0, import_react.useRef)("");
|
|
212
|
+
(0, import_react.useEffect)(() => {
|
|
213
|
+
const colors = [];
|
|
214
|
+
for (let i = 1; i <= 12; i++) {
|
|
215
|
+
const token = tamaguiTheme[`color${i}`];
|
|
216
|
+
colors.push(token?.val ?? "");
|
|
217
|
+
}
|
|
218
|
+
const key = colors.join("|");
|
|
219
|
+
if (key === prevRef.current) return;
|
|
220
|
+
prevRef.current = key;
|
|
221
|
+
getChannelEmit()?.(baseThemeColorsChannelEvent, colors);
|
|
222
|
+
}, [tamaguiTheme]);
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
function OppositeThemeColorEmitter() {
|
|
226
|
+
const tamaguiTheme = (0, import_tamagui.useTheme)();
|
|
227
|
+
const prevRef = (0, import_react.useRef)("");
|
|
228
|
+
(0, import_react.useEffect)(() => {
|
|
229
|
+
const colors = [];
|
|
230
|
+
for (let i = 1; i <= 12; i++) {
|
|
231
|
+
const token = tamaguiTheme[`color${i}`];
|
|
232
|
+
colors.push(token?.val ?? "");
|
|
233
|
+
}
|
|
234
|
+
const key = colors.join("|");
|
|
235
|
+
if (key === prevRef.current) return;
|
|
236
|
+
prevRef.current = key;
|
|
237
|
+
getChannelEmit()?.(themeColorsOppositeChannelEvent, colors);
|
|
238
|
+
}, [tamaguiTheme]);
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
function ColorChannelEmitter({
|
|
242
|
+
event,
|
|
243
|
+
prefix = "color"
|
|
244
|
+
}) {
|
|
245
|
+
const tamaguiTheme = (0, import_tamagui.useTheme)();
|
|
246
|
+
const prevRef = (0, import_react.useRef)("");
|
|
247
|
+
(0, import_react.useEffect)(() => {
|
|
248
|
+
const colors = [];
|
|
249
|
+
let found = false;
|
|
250
|
+
for (let i = 1; i <= 12; i++) {
|
|
251
|
+
const token = tamaguiTheme[`${prefix}${i}`];
|
|
252
|
+
const val = token?.val ?? "";
|
|
253
|
+
colors.push(val);
|
|
254
|
+
if (val) found = true;
|
|
255
|
+
}
|
|
256
|
+
if (!found) return;
|
|
257
|
+
const key = colors.join("|");
|
|
258
|
+
if (key === prevRef.current) return;
|
|
259
|
+
prevRef.current = key;
|
|
260
|
+
getChannelEmit()?.(event, colors);
|
|
261
|
+
}, [tamaguiTheme, event, prefix]);
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
const tamaguiPropLeakPatterns = ["pressTheme", "scaleIcon", "borderTopRightRadius", "borderBottomRightRadius", "borderTopLeftRadius", "borderBottomLeftRadius"];
|
|
265
|
+
function suppressTamaguiDomWarnings() {
|
|
266
|
+
if (typeof window === "undefined") return;
|
|
267
|
+
const origError = console.error;
|
|
268
|
+
console.error = (...args) => {
|
|
269
|
+
const msg = args.map(a => typeof a === "string" ? a : "").join(" ");
|
|
270
|
+
if (msg.includes("React does not recognize the") && tamaguiPropLeakPatterns.some(p => msg.includes(p))) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
origError(...args);
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
suppressTamaguiDomWarnings();
|
|
277
|
+
function createPreview(options) {
|
|
278
|
+
const {
|
|
279
|
+
themeConfig,
|
|
280
|
+
i18n,
|
|
281
|
+
AppProvider,
|
|
282
|
+
decorators: extraDecorators = [],
|
|
283
|
+
parameters: extraParameters = {},
|
|
284
|
+
globalTypes: extraGlobalTypes = {}
|
|
285
|
+
} = options;
|
|
286
|
+
const enumKeys = Object.keys(knobOptions);
|
|
287
|
+
const generatedGlobalTypes = {};
|
|
288
|
+
for (const key of enumKeys) {
|
|
289
|
+
generatedGlobalTypes[key] = createControl(key);
|
|
290
|
+
}
|
|
291
|
+
for (const state of ["hover", "press", "focus", "focusVisible"]) {
|
|
292
|
+
for (const field of stateKnobFields) {
|
|
293
|
+
const stateKey = `${state}.${field}`;
|
|
294
|
+
const values = knobOptions[field] ?? [];
|
|
295
|
+
const serialized = values.map(value => value);
|
|
296
|
+
const labels = Object.fromEntries(serialized.map(v => [v, v.replace("$", "")]));
|
|
297
|
+
generatedGlobalTypes[stateKey] = {
|
|
298
|
+
name: `${toTitleCase(state)} ${toTitleCase(field)}`,
|
|
299
|
+
description: `${state} override for ${field}`,
|
|
300
|
+
options: serialized,
|
|
301
|
+
control: {
|
|
302
|
+
type: "select",
|
|
303
|
+
labels
|
|
304
|
+
},
|
|
305
|
+
defaultValue: ""
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const themeColorNames = ["", ...themeConfig.themeColors];
|
|
310
|
+
const themeSwatches = {};
|
|
311
|
+
const allThemes = themeConfig.tamagui.themes;
|
|
312
|
+
if (allThemes) {
|
|
313
|
+
for (const name of themeConfig.themeColors) {
|
|
314
|
+
const theme = allThemes[`light_${name}`] ?? allThemes[name];
|
|
315
|
+
if (!theme) continue;
|
|
316
|
+
const token = theme.color7;
|
|
317
|
+
if (typeof token === "string") {
|
|
318
|
+
themeSwatches[name] = token;
|
|
319
|
+
} else if (token && typeof token === "object" && "val" in token) {
|
|
320
|
+
themeSwatches[name] = String(token.val);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
generatedGlobalTypes.color = {
|
|
325
|
+
name: "Theme",
|
|
326
|
+
description: "Theme color palette",
|
|
327
|
+
options: themeColorNames,
|
|
328
|
+
control: {
|
|
329
|
+
type: "select",
|
|
330
|
+
labels: Object.fromEntries(themeColorNames.map(v => [v, v || "(none)"]))
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
generatedGlobalTypes.scheme = {
|
|
334
|
+
name: "Scheme",
|
|
335
|
+
description: "Color scheme (light/dark/system)",
|
|
336
|
+
options: ["system", "light", "dark"],
|
|
337
|
+
control: {
|
|
338
|
+
type: "select"
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
generatedGlobalTypes.locale = {
|
|
342
|
+
name: "Locale",
|
|
343
|
+
description: "Controls internationalization language",
|
|
344
|
+
options: [...i18n.languages],
|
|
345
|
+
control: {
|
|
346
|
+
type: "select"
|
|
347
|
+
},
|
|
348
|
+
toolbar: {
|
|
349
|
+
title: "Locale",
|
|
350
|
+
items: [...i18n.languages],
|
|
351
|
+
dynamicTitle: true
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
const globalTypes = {
|
|
355
|
+
...generatedGlobalTypes,
|
|
356
|
+
...extraGlobalTypes
|
|
357
|
+
};
|
|
358
|
+
const initialGlobals = {
|
|
359
|
+
locale: import_platform.config.get("I18N_DEFAULT_LANGUAGE", i18n.defaultLanguage),
|
|
360
|
+
color: "",
|
|
361
|
+
scheme: "system",
|
|
362
|
+
// Publish registered preset names so the manager-side ThemePanel can
|
|
363
|
+
// render a preset selector without importing the theme package.
|
|
364
|
+
__presetNames: (0, import_theme.getPresetNames)(),
|
|
365
|
+
// Publish available theme color names so the ThemePanel can show only
|
|
366
|
+
// colors that actually have registered Tamagui sub-themes.
|
|
367
|
+
__themeColors: themeColorNames,
|
|
368
|
+
__themeSwatches: themeSwatches,
|
|
369
|
+
preset: themeConfig.defaultPreset ?? ""
|
|
370
|
+
};
|
|
371
|
+
for (const key of enumKeys) {
|
|
372
|
+
if (!(key in initialGlobals)) {
|
|
373
|
+
initialGlobals[key] = "";
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
for (const state of ["hover", "press", "focus", "focusVisible"]) {
|
|
377
|
+
for (const field of stateKnobFields) {
|
|
378
|
+
initialGlobals[`${state}.${field}`] = "";
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const defaultParameters = {
|
|
382
|
+
actions: {
|
|
383
|
+
argTypesRegex: "^on[A-Z].*"
|
|
384
|
+
},
|
|
385
|
+
layout: "padded",
|
|
386
|
+
viewMode: "story",
|
|
387
|
+
controls: {
|
|
388
|
+
expanded: true,
|
|
389
|
+
hideNoControlsWarning: true,
|
|
390
|
+
matchers: {
|
|
391
|
+
color: /(background|color)$/i,
|
|
392
|
+
date: /Date$/
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
// Disable the built-in backgrounds addon — the CanvasBackground component
|
|
396
|
+
// manages the preview background via the Tamagui $background token so it
|
|
397
|
+
// stays in sync with the active color scheme.
|
|
398
|
+
backgrounds: {
|
|
399
|
+
disable: true
|
|
400
|
+
},
|
|
401
|
+
previewTabs: {
|
|
402
|
+
"storybook/docs/panel": {
|
|
403
|
+
hidden: true
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
a11y: {
|
|
407
|
+
test: false
|
|
408
|
+
},
|
|
409
|
+
docs: {
|
|
410
|
+
codePanel: true
|
|
411
|
+
},
|
|
412
|
+
darkMode: {
|
|
413
|
+
stylePreview: true
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
function FrameworkDecoratorInner({
|
|
417
|
+
Story,
|
|
418
|
+
context
|
|
419
|
+
}) {
|
|
420
|
+
const [knobs, setKnobs] = (0, import_theme.useTheme)();
|
|
421
|
+
const schemeGlobal = context.globals.scheme || "system";
|
|
422
|
+
const [resolvedScheme, setResolvedScheme] = (0, import_react.useState)(() => {
|
|
423
|
+
if (schemeGlobal === "light" || schemeGlobal === "dark") return schemeGlobal;
|
|
424
|
+
if (typeof window !== "undefined" && window.matchMedia) {
|
|
425
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
426
|
+
}
|
|
427
|
+
return "light";
|
|
428
|
+
});
|
|
429
|
+
(0, import_react.useEffect)(() => {
|
|
430
|
+
if (schemeGlobal === "light" || schemeGlobal === "dark") {
|
|
431
|
+
setResolvedScheme(schemeGlobal);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
if (typeof window === "undefined" || !window.matchMedia) {
|
|
435
|
+
setResolvedScheme("light");
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
439
|
+
const handler = () => setResolvedScheme(mq.matches ? "dark" : "light");
|
|
440
|
+
handler();
|
|
441
|
+
mq.addEventListener("change", handler);
|
|
442
|
+
return () => mq.removeEventListener("change", handler);
|
|
443
|
+
}, [schemeGlobal]);
|
|
444
|
+
const colorGlobal = context.globals.color || "";
|
|
445
|
+
const storyThemeParams = context.parameters?.theme;
|
|
446
|
+
const activePresetName = context.globals.preset;
|
|
447
|
+
const activePreset = activePresetName ? (0, import_theme.getPreset)(activePresetName) : void 0;
|
|
448
|
+
const knobUpdate = (0, import_react.useMemo)(() => {
|
|
449
|
+
const result = {};
|
|
450
|
+
const stateKeys = /* @__PURE__ */new Set(["hover", "press", "focus", "focusVisible"]);
|
|
451
|
+
for (const key of Object.keys(knobs)) {
|
|
452
|
+
if (stateKeys.has(key)) continue;
|
|
453
|
+
if (storyThemeParams && key in storyThemeParams) {
|
|
454
|
+
result[key] = storyThemeParams[key];
|
|
455
|
+
} else if (key in context.globals && context.globals[key] !== void 0 && context.globals[key] !== "") {
|
|
456
|
+
result[key] = parseValue(context.globals[key]);
|
|
457
|
+
} else if (activePreset && key in activePreset.knobs) {
|
|
458
|
+
result[key] = activePreset.knobs[key];
|
|
459
|
+
} else {
|
|
460
|
+
result[key] = import_theme.defaultKnobs[key];
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
for (const state of stateKeys) {
|
|
464
|
+
const stateObj = {};
|
|
465
|
+
let hasValues = false;
|
|
466
|
+
for (const field of stateKnobFields) {
|
|
467
|
+
const globalKey = `${state}.${field}`;
|
|
468
|
+
const val = context.globals[globalKey];
|
|
469
|
+
if (val) {
|
|
470
|
+
stateObj[field] = val;
|
|
471
|
+
hasValues = true;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (hasValues) {
|
|
475
|
+
result[state] = stateObj;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return result;
|
|
479
|
+
}, [knobs, context.globals, storyThemeParams, activePreset]);
|
|
480
|
+
(0, import_react.useEffect)(() => {
|
|
481
|
+
setKnobs(knobUpdate);
|
|
482
|
+
}, [knobUpdate, setKnobs]);
|
|
483
|
+
(0, import_react.useEffect)(() => {
|
|
484
|
+
i18n.instance.changeLanguage(context.globals.locale);
|
|
485
|
+
}, [context.globals.locale]);
|
|
486
|
+
const presetCtxValue = (0, import_react.useMemo)(() => ({
|
|
487
|
+
preset: {
|
|
488
|
+
...import_theme.defaultPreset,
|
|
489
|
+
theme: colorGlobal || import_theme.defaultPreset.theme,
|
|
490
|
+
knobs: {
|
|
491
|
+
...import_theme.defaultKnobs,
|
|
492
|
+
...knobUpdate
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
overrides: void 0
|
|
496
|
+
}), [knobUpdate, colorGlobal]);
|
|
497
|
+
const animationValue = presetCtxValue.preset.knobs.animation;
|
|
498
|
+
(0, import_react.useEffect)(() => {
|
|
499
|
+
const ms = animationValue === "none" ? "0ms" : animationValue === "quick" ? "100ms" : animationValue === "medium" ? "200ms" : animationValue === "slow" || animationValue === "lazy" ? "350ms" : animationValue === "bouncy" ? "300ms" : "200ms";
|
|
500
|
+
document.documentElement.style.setProperty("--mp-transition", ms);
|
|
501
|
+
}, [animationValue]);
|
|
502
|
+
const storyContent = /* @__PURE__ */(0, import_jsx_runtime.jsx)(CanvasBackground, {
|
|
503
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(Story, {
|
|
504
|
+
...context
|
|
505
|
+
})
|
|
506
|
+
});
|
|
507
|
+
const oppositeScheme = resolvedScheme === "dark" ? "light" : "dark";
|
|
508
|
+
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_theme.PresetContext.Provider, {
|
|
509
|
+
value: presetCtxValue,
|
|
510
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsxs)(AppProvider, {
|
|
511
|
+
themeConfig,
|
|
512
|
+
systemTheme: resolvedScheme,
|
|
513
|
+
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(AnimationNamesEmitter, {}), /* @__PURE__ */(0, import_jsx_runtime.jsx)(FrappeDebugEmitter, {}), /* @__PURE__ */(0, import_jsx_runtime.jsx)(BaseThemeColorEmitter, {}), colorGlobal ? /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.Theme, {
|
|
514
|
+
name: colorGlobal,
|
|
515
|
+
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(ThemeColorEmitter, {}), /* @__PURE__ */(0, import_jsx_runtime.jsx)(ColorChannelEmitter, {
|
|
516
|
+
event: accentColorsChannelEvent,
|
|
517
|
+
prefix: "accent"
|
|
518
|
+
}), storyContent]
|
|
519
|
+
}) : /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
|
|
520
|
+
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(ThemeColorEmitter, {}), /* @__PURE__ */(0, import_jsx_runtime.jsx)(ColorChannelEmitter, {
|
|
521
|
+
event: accentColorsChannelEvent,
|
|
522
|
+
prefix: "accent"
|
|
523
|
+
}), storyContent]
|
|
524
|
+
}), /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.Theme, {
|
|
525
|
+
name: oppositeScheme,
|
|
526
|
+
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(OppositeThemeColorEmitter, {}), colorGlobal ? /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.Theme, {
|
|
527
|
+
name: colorGlobal,
|
|
528
|
+
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(ColorChannelEmitter, {
|
|
529
|
+
event: baseOppositeChannelEvent
|
|
530
|
+
}), /* @__PURE__ */(0, import_jsx_runtime.jsx)(ColorChannelEmitter, {
|
|
531
|
+
event: accentOppositeChannelEvent,
|
|
532
|
+
prefix: "accent"
|
|
533
|
+
})]
|
|
534
|
+
}) : /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
|
|
535
|
+
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(ColorChannelEmitter, {
|
|
536
|
+
event: baseOppositeChannelEvent
|
|
537
|
+
}), /* @__PURE__ */(0, import_jsx_runtime.jsx)(ColorChannelEmitter, {
|
|
538
|
+
event: accentOppositeChannelEvent,
|
|
539
|
+
prefix: "accent"
|
|
540
|
+
})]
|
|
541
|
+
})]
|
|
542
|
+
})]
|
|
543
|
+
})
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
const frameworkDecorator = (Story, context) => /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_react_cookie.CookiesProvider, {
|
|
547
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(FrameworkDecoratorInner, {
|
|
548
|
+
Story,
|
|
549
|
+
context
|
|
550
|
+
})
|
|
551
|
+
});
|
|
552
|
+
return {
|
|
553
|
+
globalTypes,
|
|
554
|
+
initialGlobals,
|
|
555
|
+
parameters: {
|
|
556
|
+
...defaultParameters,
|
|
557
|
+
...extraParameters
|
|
558
|
+
},
|
|
559
|
+
decorators: [frameworkDecorator, ...extraDecorators]
|
|
560
|
+
};
|
|
561
|
+
}
|