Source Navigation
Source Navigation
Cette page est générée automatiquement à partir du dépôt local au moment de la génération de la documentation.
Fichiers inclus
packages/common/src/lib/widgets/navigation/navigation.declaration.tspackages/common/src/lib/widgets/navigation/navigation.config.tspackages/common/src/lib/widgets/navigation/Navigation.svelte
packages/common/src/lib/widgets/navigation/navigation.declaration.ts
import { widgetFactorySvelte, type WidgetProps } from '$lib/api/managers/widget';import { type NavigationConfig, navigationConfigSchema } from './navigation.config';import type { WidgetDeclaration } from '$lib/api/managers/widget/widget-declaration';
export const declaration = { factory: () => import('./Navigation.svelte').then((Navigation) => widgetFactorySvelte(Navigation)), schema: () => navigationConfigSchema,} satisfies WidgetDeclaration;
export type NavigationProps = WidgetProps<NavigationConfig>;packages/common/src/lib/widgets/navigation/navigation.config.ts
import { iconSchema } from '$lib/api/icons';import { defineWidgetConfig } from '$lib/api/managers/configuration';import { inToolbarSchemaFrom } from '$lib/api/managers/configuration/models/widget/widget-in-toolbar.schema';import { extentSchema } from '$lib/api/domain/api-extent.schema';import { BELGIUM_EXTENT } from '$lib/api/domain/api-extent.utils';import { z } from 'zod';
const fullZoomSchema = z .object({ label: z.string().default('Afficher toute la Belgique'), extent: extentSchema.default(BELGIUM_EXTENT), }) .prefault({});
const scaleStepSchema = z.object({ minScale: z.number().optional(), maxScale: z.number().optional(), label: z.string(),});const scaleStepsSchema = z.array(scaleStepSchema).default([ { maxScale: 500, label: 'Maison', }, { minScale: 501, maxScale: 2500, label: 'Rue', }, { minScale: 2501, maxScale: 15000, label: 'Quartier', }, { minScale: 15001, maxScale: 50000, label: 'Commune', }, { minScale: 50001, maxScale: 100000, label: 'Arrondissement', }, { minScale: 100001, maxScale: 500000, label: 'Province', }, { minScale: 500001, maxScale: 1200000, label: 'Région', }, { minScale: 1200001, label: 'Pays', },]);
export const navigationConfigSchema = defineWidgetConfig({ inToolbar: inToolbarSchemaFrom(false), config: z .object({ scales: scaleStepsSchema, displayScaleLabels: z.boolean().default(true), fullZoom: fullZoomSchema, displayFullZoom: z.boolean().default(true), fullZoomIcon: iconSchema.optional(), }) .prefault({}),});
export type ScaleStep = z.infer<typeof scaleStepSchema>;
export type NavigationConfig = z.infer<typeof navigationConfigSchema>;packages/common/src/lib/widgets/navigation/Navigation.svelte
<!--Helpful to understand zoom and scale management of esri : https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#mapview-lods--><script lang="ts"> import { Button } from '$lib/components/shadcn/ui/button'; import type { ScaleStep } from './navigation.config'; import { onDestroy } from 'svelte'; import { getMapManager } from '$lib/api/map'; import Globe from 'lucide-svelte/icons/globe'; import Icon from '$lib/components/icon/Icon.svelte'; import type { NavigationProps } from './navigation.declaration';
let { fullConfig }: NavigationProps = $props(); const { config } = fullConfig;
const mapManager = getMapManager(); const scaleTool = mapManager.tools.scale; const zoomTool = mapManager.tools.zoom;
let sliderValue: number | undefined = $state(); const scales: ScaleStep[] = config.scales; let currentStep: ScaleStep | undefined = $derived(scales[sliderValue!]); const sliderMaxValue = scales.length - 1;
const scaleWatchUnsubscriber = mapManager.tools.events.watch( 'SCALE', (scale) => { sliderValue = scales.findIndex( (scaleStep) => (!scaleStep.minScale || scaleStep.minScale <= scale) && (!scaleStep.maxScale || scaleStep.maxScale >= scale), ); }, { initial: true }, );
function updateMap() { if (!currentStep) return; if (currentStep.minScale && currentStep.maxScale) { scaleTool.setScale((currentStep.minScale + currentStep.maxScale) / 2); } else { scaleTool.setScale(currentStep.minScale ?? currentStep.maxScale ?? 0); } }
function zoomToFullExtent() { zoomTool.zoomToExtent(config.fullZoom.extent); }
onDestroy(() => scaleWatchUnsubscriber());</script>
<!-- Style à adapter quand tailwind sera mergé --><div> <div>{currentStep?.label}</div> <div class="flex gap-2"> <input class="slider" type="range" bind:value={sliderValue} onchange={updateMap} min="0" max={sliderMaxValue} step="1" /> {#if config.displayFullZoom} <Button variant={'outline'} class="full-zoom-button gv-rounded-full gv-p-0 gv-size-5 gv-overflow-hidden" onclick={zoomToFullExtent} title={config.fullZoom.label} > <Icon icon={config.fullZoomIcon} alt="Icon fullscreen"> <Globe class="gv-size-full" /> </Icon> </Button> {/if} </div></div>
<style> .slider { width: var(--gv-navigation-slider-width, 200px); }</style>