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
10 changes: 10 additions & 0 deletions apps/geolibre-desktop/src/components/layout/DesktopShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,10 @@
useNetcdfIdentify(mapControllerRef, mapReadyGeneration);
const [layerPanelWidth, setLayerPanelWidth] = useState(initialSidePanelWidth);
const [stylePanelWidth, setStylePanelWidth] = useState(initialSidePanelWidth);
const [stylePanelOpenRequest, setStylePanelOpenRequest] = useState(0);
const openStylePanel = useCallback(() => {
setStylePanelOpenRequest((request) => request + 1);
}, []);
const [notebookPanelWidth, setNotebookPanelWidth] = useState(DEFAULT_NOTEBOOK_PANEL_WIDTH);
// Opening the notebook (Processing → Jupyter Notebook) splits the workspace
// 50/50 between the map and the notebook: we size the notebook to half of the
Expand Down Expand Up @@ -1707,7 +1711,7 @@
disposed = true;
unlisten?.();
};
}, [

Check warning on line 1714 in apps/geolibre-desktop/src/components/layout/DesktopShell.tsx

View workflow job for this annotation

GitHub Actions / Build and test

React Hook useEffect has a missing dependency: 't'. Either include it or remove the dependency array
clearDropMessageLater,
finishDrop,
addDroppedRasters,
Expand Down Expand Up @@ -1855,7 +1859,7 @@
clearDropMessageLater();
}
},
[

Check warning on line 1862 in apps/geolibre-desktop/src/components/layout/DesktopShell.tsx

View workflow job for this annotation

GitHub Actions / Build and test

React Hook useCallback has a missing dependency: 't'. Either include it or remove the dependency array
clearDropMessageLater,
finishDrop,
addDroppedRasters,
Expand Down Expand Up @@ -2245,6 +2249,9 @@
onOpenRasterStylePanel={() =>
openRasterLayerPanel(createAppAPI(mapControllerRef))
}
onOpenStylePanel={
layoutOptions.stylePanelVisible ? openStylePanel : undefined
}
onOpenRasterSubset={setRasterSubsetLayer}
collapsed={collapsed}
onCollapsedChange={onCollapsedChange}
Expand All @@ -2268,6 +2275,7 @@
onOpenRasterStylePanel={() =>
openRasterLayerPanel(createAppAPI(mapControllerRef))
}
onOpenStylePanel={layoutOptions.stylePanelVisible ? openStylePanel : undefined}
onOpenRasterSubset={setRasterSubsetLayer}
autoCollapse={
storymapPresenting ||
Expand Down Expand Up @@ -2493,6 +2501,7 @@
<StylePanel
mapControllerRef={mapControllerRef}
onResizeStart={startStylePanelResize}
openRequest={stylePanelOpenRequest}
collapsed={collapsed}
onCollapsedChange={onCollapsedChange}
// Controlled mode ignores autoCollapse for collapsing (the
Expand All @@ -2513,6 +2522,7 @@
<StylePanel
mapControllerRef={mapControllerRef}
onResizeStart={startStylePanelResize}
openRequest={stylePanelOpenRequest}
autoCollapse={
notebookOpen ||
storymapPresenting ||
Expand Down
19 changes: 19 additions & 0 deletions apps/geolibre-desktop/src/components/panels/LayerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ interface LayerPanelProps {
onMaterializeDuckDBLayer: (layer: GeoLibreLayer) => void;
/** Open the floating Add Raster Layer panel for advanced raster styling. */
onOpenRasterStylePanel: () => void;
/**
* Select the target layer and expand the built-in Style panel. Left undefined
* when that panel is hidden (Settings → "Show Style panel"), which also hides
* the menu item — the panel is not mounted then, so the request would be
* dropped rather than queued.
*/
onOpenStylePanel?: () => void;
/**
* Open the floating Extract Subset panel for a COG/WMS/XYZ layer, letting the
* user draw a bounding box and export a clipped GeoTIFF.
Expand Down Expand Up @@ -608,6 +615,7 @@ export function LayerPanel({
onCancelGeometryEdit,
onMaterializeDuckDBLayer,
onOpenRasterStylePanel,
onOpenStylePanel,
onOpenRasterSubset,
autoCollapse = false,
collapsed: controlledCollapsed,
Expand Down Expand Up @@ -3364,6 +3372,17 @@ export function LayerPanel({
action item below has no such focus target, so each
lets Radix dismiss the menu on select rather than
leaving it pinned open. */}
{onOpenStylePanel && (
<DropdownMenuItem
onSelect={() => {
selectLayer(layer.id);
onOpenStylePanel();
}}
>
<Palette className="me-2 h-3.5 w-3.5" />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor icon-consistency nit: Palette is already used a few lines below (and in this same layer's menu) for "Open Style Manager" (line ~3757). Elsewhere in the app the Style panel itself is always represented by SlidersHorizontal (the shared-rail tab in DesktopShell.tsx, and the collapsed-rail icon in StylePanel.tsx). Reusing Palette here makes two different actions in the same context menu look identical, and misses the icon users already associate with the Style panel.

Suggested change
<Palette className="me-2 h-3.5 w-3.5" />
<SlidersHorizontal className="me-2 h-3.5 w-3.5" />

(SlidersHorizontal would need to be added to the lucide-react import list in this file.)

Confidence: medium — this is a UX/consistency nit, not a functional bug.

{t("layers.openStylePanel")}
</DropdownMenuItem>
)}
<DropdownMenuItem
onSelect={() => {
addLayerGroup(undefined, moveIds);
Expand Down
35 changes: 17 additions & 18 deletions apps/geolibre-desktop/src/components/panels/StylePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ function labelOverrideInvalid(
interface StylePanelProps {
mapControllerRef: RefObject<MapController | null>;
onResizeStart: (event: ReactPointerEvent<HTMLDivElement>) => void;
/** Incremented when another part of the UI explicitly requests this panel. */
openRequest?: number;
/**
* When this flips to `true` the panel collapses to its thin rail (it is not
* unmounted). Used to clear room when the notebook opens beside the map; the
Expand Down Expand Up @@ -984,6 +986,7 @@ function RasterStyleSlider({
export function StylePanel({
mapControllerRef,
onResizeStart,
openRequest = 0,
autoCollapse = false,
collapsed: controlledCollapsed,
onCollapsedChange,
Expand All @@ -998,8 +1001,8 @@ export function StylePanel({
const updateLayer = useAppStore((s) => s.updateLayer);
const moveLayer = useAppStore((s) => s.moveLayer);
const projectName = useAppStore((s) => s.projectName);
// Style starts on its rail on every platform. Selecting a real layer below
// expands it; selecting the special Background row does not.
// Style starts on its rail on every platform and remains there until the
// user explicitly expands it.
const [internalCollapsed, setInternalCollapsed] = useState(true);
// In the shared right-sidebar mode the parent owns collapse (controlled);
// otherwise the panel manages it locally. `setIsCollapsed` routes to whichever
Expand All @@ -1013,23 +1016,19 @@ export function StylePanel({
},
[isControlled, onCollapsedChange],
);
// Selecting a real layer expands the panel from its rail. Skipped while
// `autoCollapse` holds it closed (the notebook or a story-map presentation
// owns the workspace), so a selection made there cannot pop Style back open
// over them and defeat the auto-collapse below.
const previousSelectedLayerId = useRef(selectedLayerId);
// An explicit request (Layers → "Open Style panel") expands the panel from its
// rail. Skipped while `autoCollapse` holds it closed (the notebook or a
// story-map presentation owns the workspace), so a request made there cannot
// pop Style back open over them: the `autoCollapse` effect below acts only on
// transitions, so an expand that slipped through would stick until the
// notebook was closed and reopened. The request is still consumed so it does
// not fire later.
const previousOpenRequest = useRef(openRequest);
useEffect(() => {
const previous = previousSelectedLayerId.current;
previousSelectedLayerId.current = selectedLayerId;
if (
!autoCollapse &&
selectedLayerId &&
selectedLayerId !== previous &&
layers.some((candidate) => candidate.id === selectedLayerId)
) {
setIsCollapsed(false);
}
}, [autoCollapse, layers, selectedLayerId, setIsCollapsed]);
if (openRequest === previousOpenRequest.current) return;
previousOpenRequest.current = openRequest;
if (!autoCollapse) setIsCollapsed(false);
}, [autoCollapse, openRequest, setIsCollapsed]);
Comment on lines +1019 to +1031

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Open Style panel" menu item in LayerPanel is only hidden/disabled based on layoutOptions.stylePanelVisible — it stays enabled while autoCollapse is true for another reason (notebook open, story-map presenting, panelsCollapsed, etc., depending on the render mode). In that state this effect still consumes the request (previousOpenRequest.current = openRequest) but skips the setIsCollapsed(false), so clicking the menu item does nothing visible and gives no feedback that the request was dropped.

This mirrors the previous auto-expand-on-select behavior, so it may be an accepted tradeoff, but now that opening the panel is an explicit user action (vs. an incidental side effect of selecting a layer), a silent no-op is more likely to read as a bug to users. Worth considering whether the menu item should be disabled/hidden while autoCollapse would swallow the request, or whether the effect should defer the expand until autoCollapse clears instead of dropping it.

Confidence: low-medium — plausible UX gap rather than a clear defect, since the surrounding comments suggest this drop is intentional.

// Collapse to the rail when `autoCollapse` flips on (e.g. the notebook opens),
// and restore the prior expand/collapse state when it flips back off (notebook
// closes). Both act only on the transition so the user can still toggle the
Expand Down
1 change: 1 addition & 0 deletions apps/geolibre-desktop/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4892,6 +4892,7 @@
"bindWindowCumulative": "Everything up to the current step (cumulative)",
"bindCancel": "Cancel",
"bindConfirm": "Bind",
"openStylePanel": "Open Style panel",
"openRasterStylePanel": "Edit raster style…",
"exportRasterSuccess": "Raster exported.",
"exportRasterError": "Could not export this raster.",
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/first-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ See [Adding Data](../user-guide/adding-data.md) for every supported source.

## 3. Style the layer

1. Select the `countries` layer in the Layers panel. The [Style panel](../user-guide/styling.md) opens on the right.
1. Select the `countries` layer in the Layers panel, then expand the [Style panel](../user-guide/styling.md) on the right if it is collapsed.
2. Adjust the **Fill color**, **Outline color**, and **Fill opacity** to taste.
3. To make a choropleth, set **Style type** to **Graduated**, pick a numeric field (for example a population or GDP column), choose a **Colormap**, and click **Apply style type**.

Expand Down
Loading