Skip to main content

@ttoss/geovis-workspace

A React component that composes a sidebar-driven workspace around a GeoVis map. The sidebars are configured through a config object and the map is rendered from a GeoVis visualizationSpec; each sidebar only renders when defined.

Installation

pnpm add @ttoss/geovis-workspace

@ttoss/geovis, @ttoss/ui, @ttoss/react-i18n and react are peer dependencies.

Storybook

Interactive examples are available on Storybook.

Usage

The parent owns the selection state and derives the next visualizationSpec from it, so picking a menu item recolors the map. Seed the initial selection with getInitialSelection (reads each menu's defaultValue).

import { type VisualizationSpec } from '@ttoss/geovis';
import {
type GeovisWorkspaceConfig,
GeovisWorkspace,
getInitialSelection,
} from '@ttoss/geovis-workspace';
import * as React from 'react';

const config: GeovisWorkspaceConfig = {
leftSidebar: {
menus: [
{
id: 'variable',
title: 'Variável',
defaultValue: 'rate',
items: [
{ value: 'rate', label: 'Taxa cumulativa' },
{ value: 'range', label: 'Faixa (% da pop 65+)' },
],
},
],
},
rightSidebar: { title: 'Details' },
};

// Maps the current selection to a GeoVis spec — your domain logic.
const buildSpec = (
selection: Record<string, string | undefined>
): VisualizationSpec => {
// ...
};

export const Example = () => {
const [selection, setSelection] = React.useState(() => {
return getInitialSelection({ config });
});

const visualizationSpec = React.useMemo(() => {
return buildSpec(selection);
}, [selection]);

return (
<GeovisWorkspace
config={config}
visualizationSpec={visualizationSpec}
variables={selection}
onVariableChange={setSelection}
/>
);
};

variables and onVariableChange are optional: omit both to let the workspace manage the selection internally (seeded from defaultValue). Provide them to control it from the parent — required when the selection must drive the visualizationSpec. Selection is per menu group: choosing an item only affects its own group. Read the current selection anywhere inside the workspace with useGeovisWorkspace().

API

GeovisWorkspace props

PropTypeDescription
configGeovisWorkspaceConfigDescribes the sidebars. Required.
visualizationSpecVisualizationSpecGeoVis spec rendered in the main map area. Required.
variablesRecord<string, string | undefined>Controlled selection per menu group. Omit for uncontrolled.
onVariableChange(variables) => voidCalled with the full next selection when an item is picked.

GeovisWorkspaceConfig

PropertyTypeDescription
leftSidebar{ menus: GeovisWorkspaceMenu[] }Left sidebar config. Omit to hide it.
rightSidebarGeovisWorkspaceRightSidebarRight sidebar config. Omit to hide it.

GeovisWorkspaceMenu

PropertyTypeDescription
idstringUnique group identifier.
titlestringTitle shown above the group.
items{ value: string; label: string }[]Selectable items.
defaultValuestringItem selected by default in the group.

GeovisWorkspaceRightSidebar

PropertyTypeDescription
titlestringTitle shown at the top of the sidebar.
legendWithColorGeovisWorkspaceLegendWithColorColor-legend panel. Omit to hide it.

GeovisWorkspaceLegendWithColor

A declarative color-legend panel: a description, a swatch-per-class legend and a list of (optionally linked) data sources. Each block renders only when present.

PropertyTypeDescription
descriptionstringParagraph under the title.
legend{ title?: string; items: { color; label }[] }Class swatches (color + label).
sources{ title?: string; items: { label; href? }[] }Data sources; href adds a link.
const config: GeovisWorkspaceConfig = {
rightSidebar: {
title: 'POPULAÇÃO 65+ COMO % DA POPULAÇÃO TOTAL',
legendWithColor: {
description: 'Proporção da população total com 65 anos ou mais.',
legend: {
title: 'Classes',
items: [
{ color: '#eff3ff', label: '0% – 5%' },
{ color: '#08519c', label: '20% – 100%' },
],
},
sources: {
title: 'Fonte dos dados:',
items: [
{ label: 'SEADE (2025)', href: 'https://repositorio.seade.gov.br' },
{ label: 'Geometria: Distritos Municipais de São Paulo.' },
],
},
},
},
};