mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 10:51:07 +00:00
app: Rewrite of PMTiles viewer (pmtiles.io) [#49, #551, #555, #556] * Rewrite the app using SolidJS / Tailwind. * Make the map view mobile friendly. * Add an archive inspector for viewing the low level structure of PMTiles. * Add a tile inspector for viewing a single tile in isolation. * Support TileJSON. * Support raster archives.
This commit is contained in:
137
app/src/LayersPanel.tsx
Normal file
137
app/src/LayersPanel.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
import {
|
||||
type Accessor,
|
||||
For,
|
||||
type Setter,
|
||||
Show,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
} from "solid-js";
|
||||
import { colorForIdx } from "./utils";
|
||||
|
||||
export interface LayerVisibility {
|
||||
id: string;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
export function LayersPanel(props: {
|
||||
layerVisibility: Accessor<LayerVisibility[]>;
|
||||
setLayerVisibility: Setter<LayerVisibility[]>;
|
||||
layerFeatureCounts?: Record<string, number>;
|
||||
|
||||
basemapOption?: boolean;
|
||||
basemap?: Accessor<boolean>;
|
||||
setBasemap?: Setter<boolean>;
|
||||
}) {
|
||||
let checkallRef: HTMLInputElement | undefined;
|
||||
const [expanded, setExpanded] = createSignal<boolean>(true);
|
||||
|
||||
const onChange = (id: string) => {
|
||||
const newLayerVisibility = props
|
||||
.layerVisibility()
|
||||
.map((l: LayerVisibility) =>
|
||||
l.id === id ? { ...l, visible: !l.visible } : l,
|
||||
);
|
||||
props.setLayerVisibility(newLayerVisibility);
|
||||
};
|
||||
|
||||
const allChecked = createMemo(() => {
|
||||
const visibleLayersCount = props
|
||||
.layerVisibility()
|
||||
.filter((l: LayerVisibility) => l.visible).length;
|
||||
return visibleLayersCount === props.layerVisibility().length;
|
||||
});
|
||||
|
||||
const toggleAll = () => {
|
||||
props.setLayerVisibility(
|
||||
props
|
||||
.layerVisibility()
|
||||
.map((l: LayerVisibility) => ({ ...l, visible: !allChecked() })),
|
||||
);
|
||||
};
|
||||
|
||||
createEffect(() => {
|
||||
const visibleLayersCount = props
|
||||
.layerVisibility()
|
||||
.filter((l) => l.visible).length;
|
||||
const indeterminate =
|
||||
visibleLayersCount > 0 &&
|
||||
visibleLayersCount !== props.layerVisibility().length;
|
||||
if (checkallRef) {
|
||||
checkallRef.indeterminate = indeterminate;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="app-bg rounded app-border flex flex-col overflow-y-scroll max-h-100">
|
||||
<button
|
||||
type="button"
|
||||
classList={{
|
||||
"app-well": true,
|
||||
"rounded-t": expanded(),
|
||||
rounded: !expanded(),
|
||||
"cursor-pointer": true,
|
||||
"min-w-8": true,
|
||||
}}
|
||||
onClick={() => setExpanded(!expanded())}
|
||||
>
|
||||
{expanded() ? "-" : "+"}
|
||||
</button>
|
||||
<Show when={expanded()}>
|
||||
<div class="px-2 md:px-4 pb-2 md:pb-4">
|
||||
<Show when={props.basemapOption}>
|
||||
<div>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="background"
|
||||
checked={props.basemap?.()}
|
||||
onChange={() => props.setBasemap?.(!props.basemap?.())}
|
||||
/>
|
||||
<label class="ml-2 text-sm" for="background">
|
||||
Background
|
||||
</label>
|
||||
</div>
|
||||
</Show>
|
||||
<div>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="checkall"
|
||||
ref={checkallRef}
|
||||
checked={allChecked()}
|
||||
onChange={toggleAll}
|
||||
/>
|
||||
<label class="ml-2 text-sm" for="checkall">
|
||||
All Layers
|
||||
</label>
|
||||
</div>
|
||||
<For each={props.layerVisibility()}>
|
||||
{(l, i) => (
|
||||
<div class="ml-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={`check_${l.id}`}
|
||||
checked={l.visible}
|
||||
onChange={() => onChange(l.id)}
|
||||
/>
|
||||
<label class="ml-2 text-sm" for={`check_${l.id}`}>
|
||||
<span
|
||||
class="inline-block mr-2 w-[10px] h-[10px]"
|
||||
style={{ "background-color": colorForIdx(i()) }}
|
||||
/>
|
||||
{l.id}
|
||||
<Show when={props.layerFeatureCounts}>
|
||||
{(layerFeatureCounts) => (
|
||||
<span class="ml-1">
|
||||
({layerFeatureCounts()[l.id] || 0})
|
||||
</span>
|
||||
)}
|
||||
</Show>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user