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

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,113 @@
1
+ import { getConf } 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 picker, so the palette is always `default` and the config
11
+ * `theme` slot supplies it; light or dark is the host's to drive, through
12
+ * `setThemeMode`.
13
+ */
14
+ export function EmbeddedSessionThemeMixin(pluginManager) {
15
+ return BaseSessionModel(pluginManager)
16
+ .volatile(() => ({
17
+ sessionThemeMode: undefined,
18
+ }))
19
+ .views(self => ({
20
+ /**
21
+ * #getter
22
+ * Serializable theme description (the canonical `themeOptions` contract
23
+ * shared with the app-core/web sessions). This is what crosses the RPC
24
+ * worker boundary — e.g. the canvas display reads
25
+ * `getSession(self).themeOptions` in its rpcProps so worker-baked colors
26
+ * (CDS frames, stroke fallback) honor the config `theme` slot.
27
+ */
28
+ get themeOptions() {
29
+ return {
30
+ configTheme: getConf(self, 'theme'),
31
+ themeName: 'default',
32
+ mode: self.sessionThemeMode,
33
+ };
34
+ },
35
+ /**
36
+ * #getter
37
+ * Every color JBrowse renders, resolved to plain strings and free of any UI
38
+ * toolkit. This is what rendering reads. See the canonical
39
+ * `ThemeManagerSessionMixin` getter of the same name.
40
+ */
41
+ get palette() {
42
+ return resolvePalette(this.themeOptions);
43
+ },
44
+ /**
45
+ * #getter
46
+ * The palette plus the sizing tokens `makeStyles` reads. See the
47
+ * canonical `ThemeManagerSessionMixin` getter of the same name.
48
+ */
49
+ get styleTheme() {
50
+ return resolveStyleTheme(this.themeOptions);
51
+ },
52
+ /**
53
+ * #getter
54
+ * Resolved MUI theme, mirroring the product's ThemeProvider. Lets
55
+ * headless/RPC consumers derive theme-dependent state without a mounted
56
+ * component. Shares its colors with `palette` by construction.
57
+ */
58
+ get theme() {
59
+ return createJBrowseThemeFromArgs(this.themeOptions);
60
+ },
61
+ /**
62
+ * #method
63
+ * Raw `ThemeOptions` for the active theme, which every view's SVG export
64
+ * threads into each display's `renderSvg` as a `configTheme` and rebuilds
65
+ * outside React. The config slot is the whole answer here because it is
66
+ * the whole of an embedded product's theming: no picker, no `allThemes`,
67
+ * and it is what `setThemeMode` writes and `palette` resolves from. `name`
68
+ * is accepted and ignored — the app session's counterpart looks a named
69
+ * preset up in `allThemes()`.
70
+ */
71
+ getActiveThemeOptions(_name) {
72
+ // the mode rides along, for the reason the comment below gives: these
73
+ // options are the whole of what the export path is handed
74
+ // Its absence did not read as an unthemed export, it read as a *light*
75
+ // one. Every view's export calls this optionally
76
+ // (`session.getActiveThemeOptions?.(themeName)`), so a session without
77
+ // it handed `undefined` down the whole path — and undefined resolves to
78
+ // the default light palette at every step of it: the SVG chrome, the
79
+ // colors each display bakes into its own bodies, the background rect. A
80
+ // host following its own dark mode got a light figure out of
81
+ // `view.exportSvg()` with nothing anywhere saying why.
82
+ const configTheme = this.themeOptions.configTheme;
83
+ return self.sessionThemeMode
84
+ ? {
85
+ ...configTheme,
86
+ palette: {
87
+ ...configTheme?.palette,
88
+ mode: self.sessionThemeMode,
89
+ },
90
+ }
91
+ : configTheme;
92
+ },
93
+ }))
94
+ .actions(self => ({
95
+ /**
96
+ * #action
97
+ * Switch the session to light or dark, leaving the host's configured
98
+ * colours alone. `themeOptions` carries the mode to the renderer, so
99
+ * labels drawn in the worker follow it, and `palette` is derived from
100
+ * the same args, so React-drawn elements follow it too. An embedder who
101
+ * sets only a React-side palette leaves the worker-drawn labels in the
102
+ * old mode.
103
+ *
104
+ * This used to write `palette.mode` into the config `theme` slot, which
105
+ * meant merging at two levels to avoid discarding the brand the host had
106
+ * passed to `createViewState`. Mode is its own axis now, so there is
107
+ * nothing to merge and nothing to discard.
108
+ */
109
+ setThemeMode(mode) {
110
+ self.sessionThemeMode = mode;
111
+ },
112
+ }));
113
+ }