Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## 0.3.2 (2026-03-16)

### Improvements

- **Marimo reactivity fix**: Removed camera and hover JS-to-Python sync to prevent continuous cell re-execution. Only user-initiated actions (selection, mode change) now trigger marimo reactive updates
- **Custom scroll zoom**: Replaced OrbitControls zoom with a custom wheel handler for much finer granularity
- **Selection hides completely**: Lasso/box selection now fully hides non-selected points (scale-to-zero for instanced meshes) instead of dimming
- **Auto zoom-to-fit on selection**: Camera automatically frames the selected points after lasso/box selection
- **Search filter modes**: Typing in the search bar dims non-matching points as a preview, pressing Run/Enter hides them completely
- **Hover via callback**: Properties panel hover now uses a direct JS callback instead of model sync, eliminating unnecessary Python round-trips

### Bug Fixes

- **setSelection scoping**: Moved `setSelection` helper to `createCanvas` scope so lasso/box/click handlers can access it
- **Camera debounce variable**: Fixed `_cameraDebounce` lexical declaration error by moving it to the correct scope

## 0.3.1 (2026-03-16)

### New Features
Expand All @@ -24,7 +40,7 @@

### New Features

- **Distance metrics sidebar**: Distance section with metric selector (euclidean, cosine, manhattan, dot product), configurable k-neighbors (0-50), and live nearest-neighbor display for the selected point
- **Distance metrics sidebar**: Distance section with metric selector (euclidean, cosine, manhattan, dot product), configurable k-neighbors (0-50) and live nearest-neighbor display for the selected point
- **Dimension mapping display**: Sidebar now shows active visual mapping fields: color field, size range, shape field and unique shape count

### Improvements
Expand All @@ -35,7 +51,7 @@

### New Features

- **6D parallel coordinates example**: Fashion-MNIST demo with PCA across 6+ dimensions, interactive axis mapping, and shape mapping to categorical labels
- **6D parallel coordinates example**: Fashion-MNIST demo with PCA across 6+ dimensions, interactive axis mapping and shape mapping to categorical labels

## 0.2.7 (2026-03-15)

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "anywidget-vector"
version = "0.3.1"
version = "0.3.2"
description = "Interactive 3D vector visualization with query UI for vector databases"
readme = "README.md"
license = "Apache-2.0"
Expand Down Expand Up @@ -73,6 +73,7 @@ select = ["E", "F", "W", "I", "UP", "B", "SIM", "RUF"]

[tool.ruff.lint.per-file-ignores]
"src/anywidget_vector/widget.py" = ["E501"] # Long lines in embedded JS
"src/anywidget_vector/ui/__init__.py" = ["E501"] # Long lines in embedded JS
"examples/**" = ["B007", "B018"] # Marimo cells use bare expressions for output

[tool.ty.environment]
Expand Down
40 changes: 26 additions & 14 deletions src/anywidget_vector/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,13 @@ def get_esm() -> str:

el.appendChild(wrapper);

// Auto-detect host theme (marimo uses Tailwind class="dark" on <html>)
// Auto-detect host theme (Tailwind dark/dark-theme class, data-theme, or prefers-color-scheme)
function detectHostDark() {{
const html = document.documentElement;
if (html.classList.contains("dark")) return true;
if (html.classList.contains("dark") || html.classList.contains("dark-theme")) return true;
if (html.dataset.theme === "dark") return true;
if (document.body?.classList.contains("dark") || document.body?.classList.contains("dark-theme")) return true;
if (document.body?.dataset.theme === "dark") return true;
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) return true;
return false;
}}
Expand All @@ -149,27 +151,37 @@ def get_esm() -> str:
model.save_changes();
}}

// Detect if we're inside a themed host (marimo, jupyter, etc.)
const hasHostTheme = !!el.getRootNode()?.host?.tagName?.startsWith("MARIMO-");
if (hasHostTheme) {{
wrapper.classList.add("avs-auto-theme");
model.set("dark_mode", detectHostDark());
applyTheme(detectHostDark());
// Watch host for live theme changes
const themeObserver = new MutationObserver(() => {{
// Always auto-detect and observe theme changes
let autoTheme = true;
model.set("dark_mode", detectHostDark());
applyTheme(detectHostDark());

const themeObserver = new MutationObserver(() => {{
if (!autoTheme) return;
const dark = detectHostDark();
if (model.get("dark_mode") !== dark) {{
model.set("dark_mode", dark);
applyTheme(dark);
}}
}});
themeObserver.observe(document.documentElement, {{ attributes: true, attributeFilter: ["class", "data-theme", "style"] }});
if (document.body) {{
themeObserver.observe(document.body, {{ attributes: true, attributeFilter: ["class", "data-theme", "style"] }});
}}
if (window.matchMedia) {{
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {{
if (!autoTheme) return;
const dark = detectHostDark();
if (model.get("dark_mode") !== dark) {{
model.set("dark_mode", dark);
applyTheme(dark);
}}
}});
themeObserver.observe(document.documentElement, {{ attributes: true, attributeFilter: ["class", "data-theme"] }});
}} else {{
applyTheme(model.get("dark_mode"));
}}

// Manual toggle from settings panel still works
// Manual toggle from settings panel disables auto-theme
model.on("change:dark_mode", () => {{
autoTheme = false;
applyTheme(model.get("dark_mode"));
}});

Expand Down
5 changes: 1 addition & 4 deletions src/anywidget_vector/ui/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,4 @@
color: var(--avs-text);
}

/* Hide dark mode toggle when host provides theme */
.avs-wrapper.avs-auto-theme .avs-theme-toggle {
display: none;
}
/* Dark mode toggle always visible — manual toggle disables auto-theme */
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading