matterviz 0.4.2 → 0.4.3
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/FilePicker.svelte +40 -50
- package/dist/api/optimade.js +10 -7
- package/dist/app.css +15 -0
- package/dist/brillouin/BrillouinZone.svelte +18 -9
- package/dist/brillouin/BrillouinZoneScene.svelte +20 -29
- package/dist/brillouin/compute.js +10 -16
- package/dist/brillouin/geometry.js +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte +18 -15
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +17 -113
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +104 -264
- package/dist/chempot-diagram/async-compute.svelte.js +12 -13
- package/dist/chempot-diagram/color.d.ts +21 -1
- package/dist/chempot-diagram/color.js +70 -1
- package/dist/chempot-diagram/compute.d.ts +7 -0
- package/dist/chempot-diagram/compute.js +85 -26
- package/dist/chempot-diagram/export.js +1 -6
- package/dist/chempot-diagram/temperature.js +9 -10
- package/dist/composition/BarChart.svelte +7 -9
- package/dist/composition/Composition.svelte +3 -8
- package/dist/composition/Formula.svelte +2 -2
- package/dist/composition/FormulaFilter.svelte +27 -93
- package/dist/composition/format.js +6 -8
- package/dist/composition/parse.js +50 -105
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +6 -17
- package/dist/convex-hull/ConvexHull2D.svelte +0 -2
- package/dist/convex-hull/ConvexHull3D.svelte +19 -47
- package/dist/convex-hull/ConvexHull4D.svelte +65 -95
- package/dist/convex-hull/StructurePopup.svelte +1 -1
- package/dist/convex-hull/gas-thermodynamics.js +21 -53
- package/dist/convex-hull/helpers.js +1 -7
- package/dist/convex-hull/thermodynamics.js +19 -27
- package/dist/coordination/CoordinationBarPlot.svelte +12 -21
- package/dist/element/BohrAtom.svelte +0 -1
- package/dist/element/ElementTile.svelte +26 -44
- package/dist/element/data.d.ts +2 -0
- package/dist/element/data.js +5 -1
- package/dist/element/index.d.ts +1 -1
- package/dist/element/index.js +1 -1
- package/dist/fermi-surface/FermiSurface.svelte +22 -23
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +2 -6
- package/dist/fermi-surface/FermiSurfaceScene.svelte +32 -77
- package/dist/fermi-surface/compute.js +22 -55
- package/dist/fermi-surface/parse.js +38 -70
- package/dist/file-viewer/JsonBrowser.svelte +1043 -0
- package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
- package/dist/file-viewer/PlotPanel.svelte +350 -0
- package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
- package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
- package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
- package/dist/file-viewer/detect.d.ts +11 -0
- package/dist/file-viewer/detect.js +381 -0
- package/dist/file-viewer/eligibility.d.ts +4 -0
- package/dist/file-viewer/eligibility.js +53 -0
- package/dist/file-viewer/host-protocol.d.ts +50 -0
- package/dist/file-viewer/host-transfer.d.ts +25 -0
- package/dist/file-viewer/host-transfer.js +42 -0
- package/dist/file-viewer/index.d.ts +5 -0
- package/dist/file-viewer/index.js +5 -0
- package/dist/file-viewer/main.d.ts +44 -0
- package/dist/file-viewer/main.js +535 -0
- package/dist/file-viewer/parse.d.ts +9 -0
- package/dist/file-viewer/parse.js +170 -0
- package/dist/file-viewer/plot-utils.d.ts +24 -0
- package/dist/file-viewer/plot-utils.js +191 -0
- package/dist/file-viewer/types.d.ts +4 -0
- package/dist/file-viewer/types.js +5 -0
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +57 -84
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/io/ExportPane.svelte +1 -1
- package/dist/io/decompress.d.ts +2 -0
- package/dist/io/decompress.js +3 -2
- package/dist/io/export.d.ts +7 -4
- package/dist/io/export.js +70 -18
- package/dist/io/file-drop.js +60 -35
- package/dist/io/url-drop.d.ts +2 -0
- package/dist/io/url-drop.js +28 -16
- package/dist/isosurface/Isosurface.svelte +687 -196
- package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
- package/dist/isosurface/IsosurfaceControls.svelte +564 -85
- package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
- package/dist/isosurface/VolumeSlice.svelte +224 -0
- package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
- package/dist/isosurface/coloring.d.ts +20 -0
- package/dist/isosurface/coloring.js +118 -0
- package/dist/isosurface/geometry-worker-types.d.ts +38 -0
- package/dist/isosurface/geometry.worker.d.ts +1 -0
- package/dist/isosurface/geometry.worker.js +59 -0
- package/dist/isosurface/grid.d.ts +10 -0
- package/dist/isosurface/grid.js +31 -0
- package/dist/isosurface/index.d.ts +4 -0
- package/dist/isosurface/index.js +4 -0
- package/dist/isosurface/profile.d.ts +12 -0
- package/dist/isosurface/profile.js +19 -0
- package/dist/isosurface/sampling.d.ts +34 -0
- package/dist/isosurface/sampling.js +408 -0
- package/dist/isosurface/slice-rendering.d.ts +13 -0
- package/dist/isosurface/slice-rendering.js +79 -0
- package/dist/isosurface/slice.d.ts +22 -2
- package/dist/isosurface/slice.js +200 -116
- package/dist/isosurface/types.d.ts +24 -1
- package/dist/isosurface/types.js +120 -8
- package/dist/json-path.d.ts +4 -0
- package/dist/json-path.js +89 -0
- package/dist/labels.js +1 -1
- package/dist/layout/InfoCard.svelte +1 -3
- package/dist/layout/SettingsSection.svelte +52 -61
- package/dist/layout/SettingsSection.svelte.d.ts +6 -7
- package/dist/layout/ViewerChrome.svelte +7 -1
- package/dist/layout/json-tree/JsonNode.svelte +14 -48
- package/dist/layout/json-tree/JsonTree.svelte +48 -95
- package/dist/layout/json-tree/JsonValue.svelte +3 -18
- package/dist/layout/json-tree/utils.d.ts +0 -3
- package/dist/layout/json-tree/utils.js +50 -179
- package/dist/marching-cubes.d.ts +8 -1
- package/dist/marching-cubes.js +115 -48
- package/dist/math.d.ts +3 -2
- package/dist/math.js +29 -38
- package/dist/overlays/ContextMenu.svelte +15 -32
- package/dist/overlays/DraggablePane.svelte +39 -58
- package/dist/overlays/DraggablePane.svelte.d.ts +1 -1
- package/dist/overlays/GlassChip.svelte +3 -1
- package/dist/periodic-table/PeriodicTableControls.svelte +26 -52
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +18 -34
- package/dist/phase-diagram/build-diagram.js +1 -6
- package/dist/phase-diagram/svg-to-diagram.js +9 -14
- package/dist/plot/bar/BarPlot.svelte +38 -42
- package/dist/plot/bar/SpacegroupBarPlot.svelte +18 -42
- package/dist/plot/box/BoxPlot.svelte +27 -23
- package/dist/plot/core/auto-place.d.ts +1 -1
- package/dist/plot/core/auto-place.js +1 -1
- package/dist/plot/core/data-transform.d.ts +1 -2
- package/dist/plot/core/data-transform.js +0 -10
- package/dist/plot/core/layout.d.ts +12 -5
- package/dist/plot/core/layout.js +37 -27
- package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
- package/dist/plot/core/pan-zoom.svelte.js +34 -17
- package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -21
- package/dist/plot/core/svg.js +0 -1
- package/dist/plot/core/utils/hierarchy-chart.d.ts +1 -0
- package/dist/plot/core/utils/hierarchy-chart.js +12 -0
- package/dist/plot/core/utils/hierarchy-labels.js +3 -2
- package/dist/plot/histogram/Histogram.svelte +21 -26
- package/dist/plot/sankey/sankey.js +13 -9
- package/dist/plot/scatter/BinnedScatterPlot.svelte +59 -43
- package/dist/plot/scatter/ScatterPlot.svelte +67 -52
- package/dist/plot/scatter/adaptive-density.d.ts +1 -1
- package/dist/plot/scatter/adaptive-density.js +36 -20
- package/dist/plot/sunburst/Sunburst.svelte +20 -20
- package/dist/plot/treemap/Treemap.svelte +175 -60
- package/dist/plot/treemap/Treemap.svelte.d.ts +6 -0
- package/dist/plot/treemap/index.d.ts +1 -0
- package/dist/plot/treemap/labels.d.ts +38 -0
- package/dist/plot/treemap/labels.js +80 -0
- package/dist/plot/treemap/treemap.d.ts +4 -2
- package/dist/plot/treemap/treemap.js +5 -2
- package/dist/rdf/RdfPlot.svelte +17 -35
- package/dist/rdf/calc-rdf.js +59 -44
- package/dist/rdf/index.d.ts +0 -1
- package/dist/sanitize.js +84 -26
- package/dist/scene/SceneCamera.svelte +1 -1
- package/dist/scene/SceneCamera.svelte.d.ts +1 -1
- package/dist/scene/index.d.ts +1 -2
- package/dist/scene/index.js +1 -1
- package/dist/scene/{props.js → props.svelte.js} +15 -1
- package/dist/settings.js +159 -482
- package/dist/spectral/Bands.svelte +151 -158
- package/dist/spectral/BrillouinBandsDos.svelte +4 -19
- package/dist/spectral/Dos.svelte +26 -24
- package/dist/spectral/helpers.js +40 -105
- package/dist/structure/AtomLegend.svelte +8 -13
- package/dist/structure/AtomLegend.svelte.d.ts +2 -3
- package/dist/structure/CellSelect.svelte +35 -10
- package/dist/structure/Structure.svelte +177 -99
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureCarousel.svelte +10 -3
- package/dist/structure/StructureControls.svelte +8 -26
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +65 -76
- package/dist/structure/StructureScene.svelte +75 -109
- package/dist/structure/StructureScene.svelte.d.ts +3 -1
- package/dist/structure/StructureViewport.svelte +120 -55
- package/dist/structure/StructureViewport.svelte.d.ts +3 -1
- package/dist/structure/atom-properties.d.ts +1 -1
- package/dist/structure/atom-properties.js +4 -3
- package/dist/structure/bond-order-perception.js +3 -8
- package/dist/structure/bonding.d.ts +0 -1
- package/dist/structure/bonding.js +16 -23
- package/dist/structure/export.js +50 -74
- package/dist/structure/format-detect.js +5 -7
- package/dist/structure/index.js +6 -12
- package/dist/structure/parse.js +38 -100
- package/dist/structure/partial-occupancy.js +7 -4
- package/dist/structure/pbc.js +8 -10
- package/dist/structure/polyhedra.js +5 -4
- package/dist/structure/prop-groups.d.ts +85 -0
- package/dist/structure/prop-groups.js +18 -0
- package/dist/symmetry/SymmetryStats.svelte +0 -4
- package/dist/symmetry/WyckoffTable.svelte +5 -4
- package/dist/symmetry/cell-transform.js +5 -14
- package/dist/symmetry/index.js +6 -9
- package/dist/table/HeatmapTable.svelte +61 -103
- package/dist/table/ToggleMenu.svelte +166 -44
- package/dist/table/ToggleMenu.svelte.d.ts +1 -1
- package/dist/theme/embedded.d.ts +18 -0
- package/dist/theme/embedded.js +206 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.js +1 -2
- package/dist/theme/themes.mjs +31 -60
- package/dist/tooltip/TooltipContent.svelte +1 -1
- package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
- package/dist/tooltip/index.d.ts +8 -1
- package/dist/trajectory/Trajectory.svelte +140 -120
- package/dist/trajectory/TrajectoryError.svelte +1 -66
- package/dist/trajectory/TrajectoryExportPane.svelte +0 -1
- package/dist/trajectory/TrajectoryInfoPane.svelte +55 -80
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
- package/dist/trajectory/extract.js +19 -29
- package/dist/trajectory/format-detect.d.ts +2 -0
- package/dist/trajectory/format-detect.js +7 -5
- package/dist/trajectory/frame-reader.js +3 -4
- package/dist/trajectory/helpers.js +16 -49
- package/dist/trajectory/index.js +2 -8
- package/dist/trajectory/parse/ase.js +1 -1
- package/dist/trajectory/parse/index.d.ts +4 -3
- package/dist/trajectory/parse/index.js +12 -17
- package/dist/trajectory/parse/vaspout-h5.d.ts +0 -1
- package/dist/trajectory/parse/vaspout-h5.js +1 -4
- package/dist/trajectory/parse/xyz.js +48 -2
- package/dist/trajectory/plotting.js +14 -37
- package/dist/xrd/XrdPlot.svelte +43 -68
- package/dist/xrd/calc-xrd.js +22 -58
- package/dist/xrd/parse.js +13 -22
- package/package.json +40 -8
- package/readme.md +6 -5
- package/dist/scene/types.d.ts +0 -26
- package/dist/tooltip/types.d.ts +0 -8
- package/dist/trajectory/constants.d.ts +0 -6
- package/dist/trajectory/constants.js +0 -11
- /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
- /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// Theme Detection for Embedded MatterViz Views
|
|
2
|
+
import { luminance } from '../colors';
|
|
3
|
+
import { COLOR_THEMES } from './';
|
|
4
|
+
// oxlint-disable-next-line import/no-unassigned-import -- registers built-in themes
|
|
5
|
+
import './themes.mjs';
|
|
6
|
+
// Per-element watcher (callback + last-seen theme for dedup + the element's own
|
|
7
|
+
// Shadow-host observer). Widgets can mount in different roots with different
|
|
8
|
+
// themes, so each is tracked and torn down independently.
|
|
9
|
+
const element_watchers = new Map();
|
|
10
|
+
// Shared document observer + media-query listener, created with the first widget
|
|
11
|
+
// and disconnected with the last (counted via element_watchers.size).
|
|
12
|
+
let doc_observer = null;
|
|
13
|
+
let media_query_listener = null;
|
|
14
|
+
// Pending debounce timer shared across all mutation sources; cleared before each
|
|
15
|
+
// reschedule so bursts of mutations collapse into a single notify_theme_change.
|
|
16
|
+
let notify_timer = null;
|
|
17
|
+
const observe_opts = { attributes: true, attributeFilter: [`class`, `data-theme`] };
|
|
18
|
+
export function detect_parent_theme(target_element) {
|
|
19
|
+
try {
|
|
20
|
+
// Check Shadow DOM context
|
|
21
|
+
if (target_element) {
|
|
22
|
+
const root_node = target_element.getRootNode();
|
|
23
|
+
if (root_node !== document && root_node instanceof ShadowRoot) {
|
|
24
|
+
const theme = check_element_hierarchy(root_node.host);
|
|
25
|
+
if (theme)
|
|
26
|
+
return theme;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Check document theme indicators
|
|
30
|
+
const theme_classes = [
|
|
31
|
+
`dark-theme`,
|
|
32
|
+
`light-theme`,
|
|
33
|
+
`vscode-dark`,
|
|
34
|
+
`vscode-light`,
|
|
35
|
+
`dark`,
|
|
36
|
+
`light`,
|
|
37
|
+
];
|
|
38
|
+
for (const cls of theme_classes) {
|
|
39
|
+
if (document.body.classList.contains(cls)) {
|
|
40
|
+
return cls.includes(`dark`) ? `dark` : `light`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// System preference
|
|
44
|
+
if (globalThis.matchMedia) {
|
|
45
|
+
if (globalThis.matchMedia(`(prefers-color-scheme: dark)`).matches)
|
|
46
|
+
return `dark`;
|
|
47
|
+
if (globalThis.matchMedia(`(prefers-color-scheme: light)`).matches)
|
|
48
|
+
return `light`;
|
|
49
|
+
}
|
|
50
|
+
// Jupyter Lab theme API
|
|
51
|
+
const jupyter_theme = globalThis.jupyterlab?.application?.shell?.dataset?.theme;
|
|
52
|
+
if (jupyter_theme) {
|
|
53
|
+
return jupyter_theme.includes(`dark`) ? `dark` : `light`;
|
|
54
|
+
}
|
|
55
|
+
// Jupyter CSS custom properties
|
|
56
|
+
const jp_bg = getComputedStyle(document.documentElement).getPropertyValue(`--jp-layout-color0`);
|
|
57
|
+
if (jp_bg) {
|
|
58
|
+
const is_dark = is_dark_color(jp_bg);
|
|
59
|
+
if (is_dark !== null)
|
|
60
|
+
return is_dark ? `dark` : `light`;
|
|
61
|
+
}
|
|
62
|
+
// Analyze background colors
|
|
63
|
+
const backgrounds = [
|
|
64
|
+
getComputedStyle(document.body).backgroundColor,
|
|
65
|
+
getComputedStyle(document.documentElement).backgroundColor,
|
|
66
|
+
];
|
|
67
|
+
for (const bg of backgrounds) {
|
|
68
|
+
const is_dark = is_dark_color(bg);
|
|
69
|
+
if (is_dark !== null)
|
|
70
|
+
return is_dark ? `dark` : `light`;
|
|
71
|
+
}
|
|
72
|
+
return `light`;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.warn(`Theme detection failed, defaulting to light:`, error);
|
|
76
|
+
return `light`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function check_element_hierarchy(element) {
|
|
80
|
+
let current_element = element;
|
|
81
|
+
while (current_element) {
|
|
82
|
+
// Check classes
|
|
83
|
+
const class_list = current_element.classList;
|
|
84
|
+
if (class_list.contains(`dark-theme`) ||
|
|
85
|
+
class_list.contains(`vscode-dark`) ||
|
|
86
|
+
class_list.contains(`dark`))
|
|
87
|
+
return `dark`;
|
|
88
|
+
if (class_list.contains(`light-theme`) ||
|
|
89
|
+
class_list.contains(`vscode-light`) ||
|
|
90
|
+
class_list.contains(`light`))
|
|
91
|
+
return `light`;
|
|
92
|
+
// Check data attributes
|
|
93
|
+
const data_theme = current_element.getAttribute(`data-theme`);
|
|
94
|
+
if (data_theme === `dark`)
|
|
95
|
+
return `dark`;
|
|
96
|
+
if (data_theme === `light`)
|
|
97
|
+
return `light`;
|
|
98
|
+
// Check computed styles
|
|
99
|
+
const computed_style = getComputedStyle(current_element);
|
|
100
|
+
const bg_color = computed_style.backgroundColor;
|
|
101
|
+
const text_color = computed_style.color;
|
|
102
|
+
const is_dark = is_dark_color(bg_color);
|
|
103
|
+
if (is_dark !== null)
|
|
104
|
+
return is_dark ? `dark` : `light`;
|
|
105
|
+
const text_is_dark = is_dark_color(text_color);
|
|
106
|
+
if (text_is_dark !== null)
|
|
107
|
+
return text_is_dark ? `light` : `dark`;
|
|
108
|
+
current_element = current_element.parentElement;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
function is_dark_color(color) {
|
|
113
|
+
if (!color || [`transparent`, `rgba(0, 0, 0, 0)`, `initial`, `inherit`].includes(color)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return luminance(color) < 0.5;
|
|
117
|
+
}
|
|
118
|
+
function notify_theme_change() {
|
|
119
|
+
notify_timer = null;
|
|
120
|
+
// Re-detect every element's theme; notify only those whose theme changed.
|
|
121
|
+
for (const [element, watcher] of element_watchers) {
|
|
122
|
+
const new_theme = detect_parent_theme(element);
|
|
123
|
+
if (new_theme !== watcher.theme) {
|
|
124
|
+
watcher.theme = new_theme;
|
|
125
|
+
watcher.callback(new_theme);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const schedule_notify = () => {
|
|
130
|
+
// Debounce: cancel any pending notify so only the latest mutation burst fires.
|
|
131
|
+
if (notify_timer)
|
|
132
|
+
clearTimeout(notify_timer);
|
|
133
|
+
notify_timer = setTimeout(notify_theme_change, 10);
|
|
134
|
+
};
|
|
135
|
+
function on_dom_mutation(mutations) {
|
|
136
|
+
if (mutations.some((mut) => mut.type === `attributes` &&
|
|
137
|
+
(mut.attributeName === `class` || mut.attributeName === `data-theme`)))
|
|
138
|
+
schedule_notify();
|
|
139
|
+
}
|
|
140
|
+
// Register a widget element + its theme-change callback. Returns a disposer that
|
|
141
|
+
// removes this element's subscriber and Shadow-host observer and, once the last
|
|
142
|
+
// widget is gone, disconnects the shared document/media-query watchers (fixing a
|
|
143
|
+
// leak where observers stayed attached for the page's lifetime).
|
|
144
|
+
export function watch_theme(target_element, callback) {
|
|
145
|
+
try {
|
|
146
|
+
// Shared document-level + system-preference watchers (created once for all).
|
|
147
|
+
if (!doc_observer) {
|
|
148
|
+
doc_observer = new MutationObserver(on_dom_mutation);
|
|
149
|
+
doc_observer.observe(document.documentElement, observe_opts);
|
|
150
|
+
if (document.body)
|
|
151
|
+
doc_observer.observe(document.body, observe_opts);
|
|
152
|
+
}
|
|
153
|
+
if (!media_query_listener && globalThis.matchMedia) {
|
|
154
|
+
media_query_listener = globalThis.matchMedia(`(prefers-color-scheme: dark)`);
|
|
155
|
+
media_query_listener.addEventListener(`change`, schedule_notify);
|
|
156
|
+
}
|
|
157
|
+
// Shadow DOM hosts (e.g. marimo cells) carry the theme class/data-theme but
|
|
158
|
+
// aren't reachable from document, so observe each widget's host individually
|
|
159
|
+
// (not just the first widget's).
|
|
160
|
+
let shadow_observer = null;
|
|
161
|
+
const root_node = target_element.getRootNode();
|
|
162
|
+
if (root_node instanceof ShadowRoot) {
|
|
163
|
+
shadow_observer = new MutationObserver(on_dom_mutation);
|
|
164
|
+
shadow_observer.observe(root_node.host, observe_opts);
|
|
165
|
+
}
|
|
166
|
+
element_watchers.set(target_element, {
|
|
167
|
+
callback,
|
|
168
|
+
theme: detect_parent_theme(target_element),
|
|
169
|
+
shadow_observer,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.warn(`Failed to setup theme watchers:`, error);
|
|
174
|
+
}
|
|
175
|
+
return () => {
|
|
176
|
+
element_watchers.get(target_element)?.shadow_observer?.disconnect();
|
|
177
|
+
element_watchers.delete(target_element);
|
|
178
|
+
if (element_watchers.size > 0)
|
|
179
|
+
return; // other widgets still need shared watchers
|
|
180
|
+
if (notify_timer) {
|
|
181
|
+
clearTimeout(notify_timer); // drop a pending notify; no widgets left to update
|
|
182
|
+
notify_timer = null;
|
|
183
|
+
}
|
|
184
|
+
doc_observer?.disconnect();
|
|
185
|
+
doc_observer = null;
|
|
186
|
+
media_query_listener?.removeEventListener(`change`, schedule_notify);
|
|
187
|
+
media_query_listener = null;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
export function get_theme_css(theme_type, is_shadow_dom = false) {
|
|
191
|
+
const theme_name = COLOR_THEMES[theme_type];
|
|
192
|
+
// Get theme data (matterviz/themes.js sets this)
|
|
193
|
+
const theme = globalThis.MATTERVIZ_THEMES?.[theme_name];
|
|
194
|
+
const css_map = globalThis.MATTERVIZ_CSS_MAP;
|
|
195
|
+
if (!theme || !css_map) {
|
|
196
|
+
console.warn(`Theme data not available, skipping theme application`);
|
|
197
|
+
return ``;
|
|
198
|
+
}
|
|
199
|
+
const css_vars = Object.entries(theme)
|
|
200
|
+
.map(([key, value]) => (css_map[key] ? `${css_map[key]}: ${value};` : ``))
|
|
201
|
+
.filter(Boolean)
|
|
202
|
+
.join(`\n\t`);
|
|
203
|
+
// Use :host for Shadow DOM, :root for regular DOM
|
|
204
|
+
const selector = is_shadow_dom ? `:host` : `:root`;
|
|
205
|
+
return `${selector} {\n\t${css_vars}\n}`;
|
|
206
|
+
}
|
package/dist/theme/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
var MATTERVIZ_THEMES: Record<string, Record<string, string>> | undefined;
|
|
3
|
+
var MATTERVIZ_CSS_MAP: Record<string, string> | undefined;
|
|
4
|
+
}
|
|
1
5
|
export declare const THEME_STORAGE_KEY = "matterviz-theme";
|
|
2
6
|
export declare const COLOR_THEMES: {
|
|
3
7
|
readonly light: "light";
|
package/dist/theme/index.js
CHANGED
|
@@ -68,6 +68,5 @@ export const apply_theme_to_dom = (mode) => {
|
|
|
68
68
|
});
|
|
69
69
|
root.setAttribute(`data-theme`, resolved);
|
|
70
70
|
// Set color-scheme to ensure form elements respect the theme
|
|
71
|
-
|
|
72
|
-
root.style.setProperty(`color-scheme`, color_scheme);
|
|
71
|
+
root.style.setProperty(`color-scheme`, THEME_TYPE[resolved]);
|
|
73
72
|
};
|
package/dist/theme/themes.mjs
CHANGED
|
@@ -2,23 +2,21 @@
|
|
|
2
2
|
// Note: This file needs to be symlinked into static/ to be importable by app.html before initial page render to prevent flashing colors before client-side JS kicks in. It also needs to be in src/lib so it gets packaged and shipped to NPM for use by the anywidgets in pymatviz.
|
|
3
3
|
// Can't use exports in this file as would then require type="module" in app.html to import which would defer until after HTML is ready (module files are always deferred).
|
|
4
4
|
|
|
5
|
-
// Text colors
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const page_bg_light = `#f1f3f5` // Light gray
|
|
13
|
-
const page_bg_dark = `#18171c` // Very dark blue
|
|
14
|
-
const page_bg_white = `#ffffff` // Pure white
|
|
15
|
-
const page_bg_black = `#000000` // Pure black
|
|
5
|
+
// Text colors (also GitHub corner bg + plot legend item color)
|
|
6
|
+
const txt = {
|
|
7
|
+
light: `#374151`, // Dark gray
|
|
8
|
+
dark: `#eee`, // Light gray
|
|
9
|
+
white: `#000000`, // Black
|
|
10
|
+
black: `#f5f5f5`, // Off-white
|
|
11
|
+
}
|
|
16
12
|
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
// Page backgrounds (also fullscreen structure bg + GitHub corner fg)
|
|
14
|
+
const page_bg = {
|
|
15
|
+
light: `#f1f3f5`, // Light gray
|
|
16
|
+
dark: `#18171c`, // Very dark blue
|
|
17
|
+
white: `#ffffff`, // Pure white
|
|
18
|
+
black: `#000000`, // Pure black
|
|
19
|
+
}
|
|
22
20
|
|
|
23
21
|
// Accents
|
|
24
22
|
const acc_light = `#4f46e5` // Indigo
|
|
@@ -26,7 +24,7 @@ const acc_dark = `cornflowerblue` // Light blue
|
|
|
26
24
|
const acc_white = `#2563eb` // Blue
|
|
27
25
|
const acc_black = `cornflowerblue`
|
|
28
26
|
|
|
29
|
-
// Helper
|
|
27
|
+
// Helper for common button-like background patterns
|
|
30
28
|
const btn_bg = (dark_op, light_op) => ({
|
|
31
29
|
light: `rgba(0, 0, 0, ${light_op})`,
|
|
32
30
|
dark: `rgba(255, 255, 255, ${dark_op})`,
|
|
@@ -34,13 +32,6 @@ const btn_bg = (dark_op, light_op) => ({
|
|
|
34
32
|
black: `rgba(255, 255, 255, ${dark_op})`,
|
|
35
33
|
})
|
|
36
34
|
|
|
37
|
-
const tooltip_bg = (light_bg, dark_bg, light_op = 0.95, dark_op = 0.95) => ({
|
|
38
|
-
light: `rgba(${light_bg}, ${light_op})`,
|
|
39
|
-
dark: `rgba(${dark_bg}, ${dark_op})`,
|
|
40
|
-
white: `rgba(255, 255, 255, 0.98)`,
|
|
41
|
-
black: `rgba(20, 20, 20, 0.98)`,
|
|
42
|
-
})
|
|
43
|
-
|
|
44
35
|
// Slight contrast shading drawn behind plot SVGs and structure canvases so they read
|
|
45
36
|
// as panels sitting on top of the page background. Shared so a plot and a structure
|
|
46
37
|
// shown side by side (e.g. trajectory view) get an identical tint. Kept subtle; light
|
|
@@ -54,13 +45,8 @@ const canvas_bg = {
|
|
|
54
45
|
|
|
55
46
|
const themes = {
|
|
56
47
|
// Core colors
|
|
57
|
-
'page-bg':
|
|
58
|
-
|
|
59
|
-
dark: page_bg_dark,
|
|
60
|
-
white: page_bg_white,
|
|
61
|
-
black: page_bg_black,
|
|
62
|
-
},
|
|
63
|
-
'text-color': { light: txt_light, dark: txt_dark, white: txt_white, black: txt_black },
|
|
48
|
+
'page-bg': page_bg,
|
|
49
|
+
'text-color': txt,
|
|
64
50
|
'surface-bg': {
|
|
65
51
|
light: `rgb(237, 238, 239)`,
|
|
66
52
|
dark: `rgb(33, 36, 43)`,
|
|
@@ -68,10 +54,10 @@ const themes = {
|
|
|
68
54
|
black: `rgb(19, 19, 19)`,
|
|
69
55
|
},
|
|
70
56
|
'border-color': {
|
|
71
|
-
light:
|
|
72
|
-
dark:
|
|
73
|
-
white:
|
|
74
|
-
black:
|
|
57
|
+
light: `#d1d5db`, // Gray border
|
|
58
|
+
dark: `#404040`, // Dark gray border
|
|
59
|
+
white: `#d1d5db`,
|
|
60
|
+
black: `#404040`,
|
|
75
61
|
},
|
|
76
62
|
'accent-color': {
|
|
77
63
|
light: acc_light,
|
|
@@ -158,7 +144,12 @@ const themes = {
|
|
|
158
144
|
'btn-disabled-bg': btn_bg(0.1, 0.05),
|
|
159
145
|
|
|
160
146
|
// Tooltips
|
|
161
|
-
'tooltip-bg':
|
|
147
|
+
'tooltip-bg': {
|
|
148
|
+
light: `rgba(243, 244, 246, 0.95)`,
|
|
149
|
+
dark: `rgba(0, 40, 60, 0.95)`,
|
|
150
|
+
white: `rgba(255, 255, 255, 0.98)`,
|
|
151
|
+
black: `rgba(20, 20, 20, 0.98)`,
|
|
152
|
+
},
|
|
162
153
|
'canvas-tooltip-bg': {
|
|
163
154
|
light: `rgba(226, 232, 240, 0.96)`,
|
|
164
155
|
dark: `rgba(15, 23, 42, 0.96)`,
|
|
@@ -181,12 +172,7 @@ const themes = {
|
|
|
181
172
|
// Plot & structure canvas backgrounds (shared subtle panel shading)
|
|
182
173
|
'plot-bg': canvas_bg,
|
|
183
174
|
'struct-bg': canvas_bg,
|
|
184
|
-
'struct-bg-fullscreen':
|
|
185
|
-
light: page_bg_light,
|
|
186
|
-
dark: page_bg_dark,
|
|
187
|
-
white: page_bg_white,
|
|
188
|
-
black: page_bg_black,
|
|
189
|
-
},
|
|
175
|
+
'struct-bg-fullscreen': page_bg,
|
|
190
176
|
|
|
191
177
|
// Pane backgrounds (DraggablePane, etc.)
|
|
192
178
|
'pane-bg': {
|
|
@@ -257,26 +243,11 @@ const themes = {
|
|
|
257
243
|
white: `1px solid rgba(0, 0, 0, 0.1)`,
|
|
258
244
|
black: `1px solid rgba(255, 255, 255, 0.1)`,
|
|
259
245
|
},
|
|
260
|
-
'plot-legend-item-color':
|
|
261
|
-
light: txt_light,
|
|
262
|
-
dark: txt_dark,
|
|
263
|
-
white: txt_white,
|
|
264
|
-
black: txt_black,
|
|
265
|
-
},
|
|
246
|
+
'plot-legend-item-color': txt,
|
|
266
247
|
'plot-legend-item-hover-bg-color': btn_bg(0.1, 0.1),
|
|
267
248
|
|
|
268
|
-
'github-corner-color':
|
|
269
|
-
|
|
270
|
-
dark: page_bg_dark,
|
|
271
|
-
white: page_bg_white,
|
|
272
|
-
black: page_bg_black,
|
|
273
|
-
},
|
|
274
|
-
'github-corner-bg': {
|
|
275
|
-
light: txt_light,
|
|
276
|
-
dark: txt_dark,
|
|
277
|
-
white: txt_white,
|
|
278
|
-
black: txt_black,
|
|
279
|
-
},
|
|
249
|
+
'github-corner-color': page_bg,
|
|
250
|
+
'github-corner-bg': txt,
|
|
280
251
|
'github-corner-bg-hover': {
|
|
281
252
|
light: `#1e40af`, // Darker, more modest blue for light mode
|
|
282
253
|
dark: `#60a5fa`, // Lighter blue for dark mode
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
// - If tooltip is a config object, render prefix/suffix around the default content
|
|
5
5
|
// - Otherwise, render just the default content
|
|
6
6
|
import { sanitize_html } from '../sanitize'
|
|
7
|
+
import type { TooltipConfig } from './'
|
|
7
8
|
import type { Snippet } from 'svelte'
|
|
8
|
-
import type { TooltipConfig } from './types'
|
|
9
9
|
|
|
10
10
|
let {
|
|
11
11
|
data,
|
package/dist/tooltip/index.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export type TooltipConfig<T> = {
|
|
3
|
+
prefix?: string | ((data: T) => string);
|
|
4
|
+
suffix?: string | ((data: T) => string);
|
|
5
|
+
};
|
|
6
|
+
export type TooltipProp<T, SnippetArgs extends unknown[] = [{
|
|
7
|
+
hover_data: T;
|
|
8
|
+
}]> = Snippet<SnippetArgs> | TooltipConfig<T>;
|
|
1
9
|
export { default as KCoords } from './KCoords.svelte';
|
|
2
10
|
export { default as TooltipContent } from './TooltipContent.svelte';
|
|
3
|
-
export type * from './types';
|