@jbrowse/embedded-core 4.3.0 → 5.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,104 @@
1
+ import { getConf, setConf } from '@jbrowse/core/configuration';
2
+ import { createJBrowseThemeFromArgs } from '@jbrowse/core/ui';
3
+ import { resolvePalette } from '@jbrowse/core/ui/palette';
4
+ import { resolveStyleTheme } from '@jbrowse/core/ui/styleTheme';
5
+ import { BaseSessionModel } from '@jbrowse/product-core';
6
+ /**
7
+ * #stateModel EmbeddedSessionThemeMixin
8
+ * Theme getters shared by the single-view embedded sessions
9
+ * (react-linear-genome-view, react-circular-genome-view). Embedded products
10
+ * have no theme switching, so the active theme is always `default`; the config
11
+ * `theme` slot still applies via `configTheme`.
12
+ */
13
+ export function EmbeddedSessionThemeMixin(pluginManager) {
14
+ return BaseSessionModel(pluginManager)
15
+ .views(self => ({
16
+ /**
17
+ * #getter
18
+ * Serializable theme description (the canonical `themeOptions` contract
19
+ * shared with the app-core/web sessions). This is what crosses the RPC
20
+ * worker boundary — e.g. the canvas display reads
21
+ * `getSession(self).themeOptions` in its rpcProps so worker-baked colors
22
+ * (CDS frames, stroke fallback) honor the config `theme` slot.
23
+ */
24
+ get themeOptions() {
25
+ return {
26
+ configTheme: getConf(self, 'theme'),
27
+ themeName: 'default',
28
+ };
29
+ },
30
+ /**
31
+ * #getter
32
+ * Every color JBrowse renders, resolved to plain strings and free of any UI
33
+ * toolkit. This is what rendering reads. See the canonical
34
+ * `ThemeManagerSessionMixin` getter of the same name.
35
+ */
36
+ get palette() {
37
+ return resolvePalette(this.themeOptions);
38
+ },
39
+ /**
40
+ * #getter
41
+ * The palette plus the sizing tokens `makeStyles` reads. See the
42
+ * canonical `ThemeManagerSessionMixin` getter of the same name.
43
+ */
44
+ get styleTheme() {
45
+ return resolveStyleTheme(this.themeOptions);
46
+ },
47
+ /**
48
+ * #getter
49
+ * Resolved MUI theme, mirroring the product's ThemeProvider. Lets
50
+ * headless/RPC consumers derive theme-dependent state without a mounted
51
+ * component. Shares its colors with `palette` by construction.
52
+ */
53
+ get theme() {
54
+ return createJBrowseThemeFromArgs(this.themeOptions);
55
+ },
56
+ /**
57
+ * #method
58
+ * Raw `ThemeOptions` for the active theme, which every view's SVG export
59
+ * threads into each display's `renderSvg` as a `configTheme` and rebuilds
60
+ * outside React. The config slot is the whole answer here because it is
61
+ * the whole of an embedded product's theming: no picker, no `allThemes`,
62
+ * and it is what `setThemeMode` writes and `palette` resolves from. `name`
63
+ * is accepted and ignored — the app session's counterpart looks a named
64
+ * preset up in `allThemes()`.
65
+ */
66
+ getActiveThemeOptions(_name) {
67
+ // Its absence did not read as an unthemed export, it read as a *light*
68
+ // one. Every view's export calls this optionally
69
+ // (`session.getActiveThemeOptions?.(themeName)`), so a session without
70
+ // it handed `undefined` down the whole path — and undefined resolves to
71
+ // the default light palette at every step of it: the SVG chrome, the
72
+ // colors each display bakes into its own bodies, the background rect. A
73
+ // host following its own dark mode got a light figure out of
74
+ // `view.exportSvg()` with nothing anywhere saying why.
75
+ return this.themeOptions.configTheme;
76
+ },
77
+ }))
78
+ .actions(self => ({
79
+ /**
80
+ * #action
81
+ * Point the session at light or dark. One write, not two: the `theme`
82
+ * slot is what `themeOptions` ships to the renderer, so the labels baked
83
+ * in the worker follow it, and `palette` is derived from the same slot,
84
+ * so what React draws follows it too. An embedder who sets only a
85
+ * React-side palette leaves the baked labels behind.
86
+ *
87
+ * Merges rather than replaces, at both levels. `theme` is a frozen slot,
88
+ * so a bare `setConf(session, 'theme', { palette: { mode } })` — the
89
+ * obvious form, and what the build-your-own examples each wrote — drops
90
+ * every other key in it. That silently discards whatever the host passed
91
+ * as `createViewState`'s `configuration.theme` (a brand `primary`, say)
92
+ * the first time their dark-mode toggle fires. `resolvePalette` spreads
93
+ * `configTheme.palette` over the preset shallowly, so `mode` and
94
+ * `primary` are siblings and both levels have to survive.
95
+ */
96
+ setThemeMode(mode) {
97
+ const theme = getConf(self, 'theme') ?? {};
98
+ setConf(self, 'theme', {
99
+ ...theme,
100
+ palette: { ...theme.palette, mode },
101
+ });
102
+ },
103
+ }));
104
+ }