mirror of
				https://github.com/gpxstudio/gpx.studio.git
				synced 2025-11-04 05:21:09 +00:00 
			
		
		
		
	layer settings
This commit is contained in:
		@@ -3,8 +3,8 @@
 | 
			
		||||
 | 
			
		||||
	import CustomControl from '$lib/components/custom-control/CustomControl.svelte';
 | 
			
		||||
	import LayerTree from './LayerTree.svelte';
 | 
			
		||||
	import LayerControlSettings from './LayerControlSettings.svelte';
 | 
			
		||||
 | 
			
		||||
	import Label from '$lib/components/ui/label/label.svelte';
 | 
			
		||||
	import { Separator } from '$lib/components/ui/separator';
 | 
			
		||||
	import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
 | 
			
		||||
 | 
			
		||||
@@ -40,9 +40,9 @@
 | 
			
		||||
			<ScrollArea>
 | 
			
		||||
				<div class="h-fit max-h-[50vh]">
 | 
			
		||||
					<div class="p-2">
 | 
			
		||||
						<Label>Basemaps</Label>
 | 
			
		||||
						<LayerTree
 | 
			
		||||
							layerTree={basemapTree}
 | 
			
		||||
							label="Basemaps"
 | 
			
		||||
							name="basemaps"
 | 
			
		||||
							onValueChange={(id) => {
 | 
			
		||||
								if (map) {
 | 
			
		||||
@@ -53,9 +53,9 @@
 | 
			
		||||
					</div>
 | 
			
		||||
					<Separator class="w-full" />
 | 
			
		||||
					<div class="p-2">
 | 
			
		||||
						<Label>Overlays</Label>
 | 
			
		||||
						<LayerTree
 | 
			
		||||
							layerTree={overlayTree}
 | 
			
		||||
							label="Overlays"
 | 
			
		||||
							name="overlays"
 | 
			
		||||
							multiple={true}
 | 
			
		||||
							onValueChange={(id, checked) => {
 | 
			
		||||
@@ -84,7 +84,9 @@
 | 
			
		||||
						/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<Separator class="w-full" />
 | 
			
		||||
					<div class="p-2">TODO: Add layer settings</div>
 | 
			
		||||
					<div class="p-2">
 | 
			
		||||
						<LayerControlSettings />
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</ScrollArea>
 | 
			
		||||
		</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,68 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import CustomControl from '$lib/components/custom-control/CustomControl.svelte';
 | 
			
		||||
	import LayerTree from './LayerTree.svelte';
 | 
			
		||||
 | 
			
		||||
	import { Button } from '$lib/components/ui/button';
 | 
			
		||||
	import Label from '$lib/components/ui/label/label.svelte';
 | 
			
		||||
	import { Separator } from '$lib/components/ui/separator';
 | 
			
		||||
	import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
 | 
			
		||||
	import * as Sheet from '$lib/components/ui/sheet';
 | 
			
		||||
 | 
			
		||||
	import Fa from 'svelte-fa';
 | 
			
		||||
	import { faGear } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
 | 
			
		||||
	import {
 | 
			
		||||
		basemaps,
 | 
			
		||||
		basemapTree,
 | 
			
		||||
		overlays,
 | 
			
		||||
		overlayTree,
 | 
			
		||||
		opacities,
 | 
			
		||||
		defaultBasemap
 | 
			
		||||
	} from '$lib/assets/layers';
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<Sheet.Root>
 | 
			
		||||
	<Sheet.Trigger class="w-full">
 | 
			
		||||
		<Button variant="secondary" class="w-full px-1 py-1.5">
 | 
			
		||||
			<Fa icon={faGear} class="mr-2" />
 | 
			
		||||
			Manage layers
 | 
			
		||||
		</Button>
 | 
			
		||||
	</Sheet.Trigger>
 | 
			
		||||
	<Sheet.Content>
 | 
			
		||||
		<Sheet.Header>
 | 
			
		||||
			<Sheet.Title>Layer settings</Sheet.Title>
 | 
			
		||||
			<Sheet.Description>
 | 
			
		||||
				Select the map layers you want to show in the interface and adjust their settings.
 | 
			
		||||
			</Sheet.Description>
 | 
			
		||||
		</Sheet.Header>
 | 
			
		||||
		<ScrollArea class="h-[35vh] pr-4">
 | 
			
		||||
			<div>
 | 
			
		||||
				<LayerTree
 | 
			
		||||
					layerTree={basemapTree}
 | 
			
		||||
					label="Basemaps"
 | 
			
		||||
					name="basemapSettings"
 | 
			
		||||
					multiple={true}
 | 
			
		||||
					onValueChange={(id) => {
 | 
			
		||||
						// TODO
 | 
			
		||||
					}}
 | 
			
		||||
				/>
 | 
			
		||||
			</div>
 | 
			
		||||
		</ScrollArea>
 | 
			
		||||
		<Separator class="my-2" />
 | 
			
		||||
		<ScrollArea class="h-[35vh] pr-4">
 | 
			
		||||
			<div>
 | 
			
		||||
				<LayerTree
 | 
			
		||||
					layerTree={overlayTree}
 | 
			
		||||
					label="Overlays"
 | 
			
		||||
					name="overlaySettings"
 | 
			
		||||
					multiple={true}
 | 
			
		||||
					onValueChange={(id, checked) => {
 | 
			
		||||
						// TODO
 | 
			
		||||
					}}
 | 
			
		||||
				/>
 | 
			
		||||
			</div>
 | 
			
		||||
		</ScrollArea>
 | 
			
		||||
		<Separator class="my-2" />
 | 
			
		||||
		<Button variant="secondary" class="w-full px-1 py-1.5">Add custom layer</Button>
 | 
			
		||||
	</Sheet.Content>
 | 
			
		||||
</Sheet.Root>
 | 
			
		||||
@@ -2,13 +2,39 @@
 | 
			
		||||
	import LayerTreeNode from './LayerTreeNode.svelte';
 | 
			
		||||
	import { type LayerTreeType } from '$lib/assets/layers';
 | 
			
		||||
 | 
			
		||||
	import * as Collapsible from '$lib/components/ui/collapsible';
 | 
			
		||||
	import { Button } from '$lib/components/ui/button';
 | 
			
		||||
 | 
			
		||||
	import Fa from 'svelte-fa';
 | 
			
		||||
	import { faChevronDown, faChevronLeft } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
 | 
			
		||||
	export let layerTree: LayerTreeType;
 | 
			
		||||
	export let label: string;
 | 
			
		||||
	export let name: string;
 | 
			
		||||
	export let multiple: boolean = false;
 | 
			
		||||
 | 
			
		||||
	export let onValueChange: (id: string, checked: boolean) => void;
 | 
			
		||||
 | 
			
		||||
	let open = true;
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<fieldset class="min-w-64">
 | 
			
		||||
	<LayerTreeNode {name} node={layerTree} {multiple} {onValueChange} />
 | 
			
		||||
	<Collapsible.Root bind:open>
 | 
			
		||||
		<Collapsible.Trigger class="w-full"
 | 
			
		||||
			><Button
 | 
			
		||||
				variant="ghost"
 | 
			
		||||
				class="w-full flex flex-row justify-between py-0 px-1 h-fit hover:bg-background"
 | 
			
		||||
			>
 | 
			
		||||
				<span class="mr-2">{label}</span>
 | 
			
		||||
				{#if open}
 | 
			
		||||
					<Fa icon={faChevronDown} size="xs" />
 | 
			
		||||
				{:else}
 | 
			
		||||
					<Fa icon={faChevronLeft} size="xs" />
 | 
			
		||||
				{/if}
 | 
			
		||||
			</Button></Collapsible.Trigger
 | 
			
		||||
		>
 | 
			
		||||
		<Collapsible.Content>
 | 
			
		||||
			<LayerTreeNode {name} node={layerTree} {multiple} {onValueChange} />
 | 
			
		||||
		</Collapsible.Content>
 | 
			
		||||
	</Collapsible.Root>
 | 
			
		||||
</fieldset>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										106
									
								
								website/src/lib/components/ui/sheet/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								website/src/lib/components/ui/sheet/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
import { Dialog as SheetPrimitive } from "bits-ui";
 | 
			
		||||
import { type VariantProps, tv } from "tailwind-variants";
 | 
			
		||||
 | 
			
		||||
import Portal from "./sheet-portal.svelte";
 | 
			
		||||
import Overlay from "./sheet-overlay.svelte";
 | 
			
		||||
import Content from "./sheet-content.svelte";
 | 
			
		||||
import Header from "./sheet-header.svelte";
 | 
			
		||||
import Footer from "./sheet-footer.svelte";
 | 
			
		||||
import Title from "./sheet-title.svelte";
 | 
			
		||||
import Description from "./sheet-description.svelte";
 | 
			
		||||
 | 
			
		||||
const Root = SheetPrimitive.Root;
 | 
			
		||||
const Close = SheetPrimitive.Close;
 | 
			
		||||
const Trigger = SheetPrimitive.Trigger;
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
	Root,
 | 
			
		||||
	Close,
 | 
			
		||||
	Trigger,
 | 
			
		||||
	Portal,
 | 
			
		||||
	Overlay,
 | 
			
		||||
	Content,
 | 
			
		||||
	Header,
 | 
			
		||||
	Footer,
 | 
			
		||||
	Title,
 | 
			
		||||
	Description,
 | 
			
		||||
	//
 | 
			
		||||
	Root as Sheet,
 | 
			
		||||
	Close as SheetClose,
 | 
			
		||||
	Trigger as SheetTrigger,
 | 
			
		||||
	Portal as SheetPortal,
 | 
			
		||||
	Overlay as SheetOverlay,
 | 
			
		||||
	Content as SheetContent,
 | 
			
		||||
	Header as SheetHeader,
 | 
			
		||||
	Footer as SheetFooter,
 | 
			
		||||
	Title as SheetTitle,
 | 
			
		||||
	Description as SheetDescription,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const sheetVariants = tv({
 | 
			
		||||
	base: "fixed z-50 gap-4 bg-background p-6 shadow-lg",
 | 
			
		||||
	variants: {
 | 
			
		||||
		side: {
 | 
			
		||||
			top: "inset-x-0 top-0 border-b",
 | 
			
		||||
			bottom: "inset-x-0 bottom-0 border-t",
 | 
			
		||||
			left: "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
 | 
			
		||||
			right: "inset-y-0 right-0 h-full w-3/4  border-l sm:max-w-sm",
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	defaultVariants: {
 | 
			
		||||
		side: "right",
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const sheetTransitions = {
 | 
			
		||||
	top: {
 | 
			
		||||
		in: {
 | 
			
		||||
			y: "-100%",
 | 
			
		||||
			duration: 500,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
		out: {
 | 
			
		||||
			y: "-100%",
 | 
			
		||||
			duration: 300,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	bottom: {
 | 
			
		||||
		in: {
 | 
			
		||||
			y: "100%",
 | 
			
		||||
			duration: 500,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
		out: {
 | 
			
		||||
			y: "100%",
 | 
			
		||||
			duration: 300,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	left: {
 | 
			
		||||
		in: {
 | 
			
		||||
			x: "-100%",
 | 
			
		||||
			duration: 500,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
		out: {
 | 
			
		||||
			x: "-100%",
 | 
			
		||||
			duration: 300,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	right: {
 | 
			
		||||
		in: {
 | 
			
		||||
			x: "100%",
 | 
			
		||||
			duration: 500,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
		out: {
 | 
			
		||||
			x: "100%",
 | 
			
		||||
			duration: 300,
 | 
			
		||||
			opacity: 1,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type Side = VariantProps<typeof sheetVariants>["side"];
 | 
			
		||||
							
								
								
									
										47
									
								
								website/src/lib/components/ui/sheet/sheet-content.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								website/src/lib/components/ui/sheet/sheet-content.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { Dialog as SheetPrimitive } from "bits-ui";
 | 
			
		||||
	import X from "lucide-svelte/icons/x";
 | 
			
		||||
	import { fly } from "svelte/transition";
 | 
			
		||||
	import {
 | 
			
		||||
		SheetOverlay,
 | 
			
		||||
		SheetPortal,
 | 
			
		||||
		type Side,
 | 
			
		||||
		sheetTransitions,
 | 
			
		||||
		sheetVariants,
 | 
			
		||||
	} from "./index.js";
 | 
			
		||||
	import { cn } from "$lib/utils.js";
 | 
			
		||||
 | 
			
		||||
	type $$Props = SheetPrimitive.ContentProps & {
 | 
			
		||||
		side?: Side;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	let className: $$Props["class"] = undefined;
 | 
			
		||||
	export let side: $$Props["side"] = "right";
 | 
			
		||||
	export { className as class };
 | 
			
		||||
	export let inTransition: $$Props["inTransition"] = fly;
 | 
			
		||||
	export let inTransitionConfig: $$Props["inTransitionConfig"] =
 | 
			
		||||
		sheetTransitions[side ?? "right"].in;
 | 
			
		||||
	export let outTransition: $$Props["outTransition"] = fly;
 | 
			
		||||
	export let outTransitionConfig: $$Props["outTransitionConfig"] =
 | 
			
		||||
		sheetTransitions[side ?? "right"].out;
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<SheetPortal>
 | 
			
		||||
	<SheetOverlay />
 | 
			
		||||
	<SheetPrimitive.Content
 | 
			
		||||
		{inTransition}
 | 
			
		||||
		{inTransitionConfig}
 | 
			
		||||
		{outTransition}
 | 
			
		||||
		{outTransitionConfig}
 | 
			
		||||
		class={cn(sheetVariants({ side }), className)}
 | 
			
		||||
		{...$$restProps}
 | 
			
		||||
	>
 | 
			
		||||
		<slot />
 | 
			
		||||
		<SheetPrimitive.Close
 | 
			
		||||
			class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary"
 | 
			
		||||
		>
 | 
			
		||||
			<X class="h-4 w-4" />
 | 
			
		||||
			<span class="sr-only">Close</span>
 | 
			
		||||
		</SheetPrimitive.Close>
 | 
			
		||||
	</SheetPrimitive.Content>
 | 
			
		||||
</SheetPortal>
 | 
			
		||||
							
								
								
									
										13
									
								
								website/src/lib/components/ui/sheet/sheet-description.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								website/src/lib/components/ui/sheet/sheet-description.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { Dialog as SheetPrimitive } from "bits-ui";
 | 
			
		||||
	import { cn } from "$lib/utils.js";
 | 
			
		||||
 | 
			
		||||
	type $$Props = SheetPrimitive.DescriptionProps;
 | 
			
		||||
 | 
			
		||||
	let className: $$Props["class"] = undefined;
 | 
			
		||||
	export { className as class };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<SheetPrimitive.Description class={cn("text-sm text-muted-foreground", className)} {...$$restProps}>
 | 
			
		||||
	<slot />
 | 
			
		||||
</SheetPrimitive.Description>
 | 
			
		||||
							
								
								
									
										16
									
								
								website/src/lib/components/ui/sheet/sheet-footer.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								website/src/lib/components/ui/sheet/sheet-footer.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import type { HTMLAttributes } from "svelte/elements";
 | 
			
		||||
	import { cn } from "$lib/utils.js";
 | 
			
		||||
 | 
			
		||||
	type $$Props = HTMLAttributes<HTMLDivElement>;
 | 
			
		||||
 | 
			
		||||
	let className: $$Props["class"] = undefined;
 | 
			
		||||
	export { className as class };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div
 | 
			
		||||
	class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
 | 
			
		||||
	{...$$restProps}
 | 
			
		||||
>
 | 
			
		||||
	<slot />
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										13
									
								
								website/src/lib/components/ui/sheet/sheet-header.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								website/src/lib/components/ui/sheet/sheet-header.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import type { HTMLAttributes } from "svelte/elements";
 | 
			
		||||
	import { cn } from "$lib/utils.js";
 | 
			
		||||
 | 
			
		||||
	type $$Props = HTMLAttributes<HTMLDivElement>;
 | 
			
		||||
 | 
			
		||||
	let className: $$Props["class"] = undefined;
 | 
			
		||||
	export { className as class };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div class={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...$$restProps}>
 | 
			
		||||
	<slot />
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										21
									
								
								website/src/lib/components/ui/sheet/sheet-overlay.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								website/src/lib/components/ui/sheet/sheet-overlay.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { Dialog as SheetPrimitive } from "bits-ui";
 | 
			
		||||
	import { fade } from "svelte/transition";
 | 
			
		||||
	import { cn } from "$lib/utils.js";
 | 
			
		||||
 | 
			
		||||
	type $$Props = SheetPrimitive.OverlayProps;
 | 
			
		||||
 | 
			
		||||
	let className: $$Props["class"] = undefined;
 | 
			
		||||
	export let transition: $$Props["transition"] = fade;
 | 
			
		||||
	export let transitionConfig: $$Props["transitionConfig"] = {
 | 
			
		||||
		duration: 150,
 | 
			
		||||
	};
 | 
			
		||||
	export { className as class };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<SheetPrimitive.Overlay
 | 
			
		||||
	{transition}
 | 
			
		||||
	{transitionConfig}
 | 
			
		||||
	class={cn("fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ", className)}
 | 
			
		||||
	{...$$restProps}
 | 
			
		||||
/>
 | 
			
		||||
							
								
								
									
										13
									
								
								website/src/lib/components/ui/sheet/sheet-portal.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								website/src/lib/components/ui/sheet/sheet-portal.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { Dialog as SheetPrimitive } from "bits-ui";
 | 
			
		||||
	import { cn } from "$lib/utils.js";
 | 
			
		||||
 | 
			
		||||
	type $$Props = SheetPrimitive.PortalProps;
 | 
			
		||||
 | 
			
		||||
	let className: $$Props["class"] = undefined;
 | 
			
		||||
	export { className as class };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<SheetPrimitive.Portal class={cn(className)} {...$$restProps}>
 | 
			
		||||
	<slot />
 | 
			
		||||
</SheetPrimitive.Portal>
 | 
			
		||||
							
								
								
									
										16
									
								
								website/src/lib/components/ui/sheet/sheet-title.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								website/src/lib/components/ui/sheet/sheet-title.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { Dialog as SheetPrimitive } from "bits-ui";
 | 
			
		||||
	import { cn } from "$lib/utils.js";
 | 
			
		||||
 | 
			
		||||
	type $$Props = SheetPrimitive.TitleProps;
 | 
			
		||||
 | 
			
		||||
	let className: $$Props["class"] = undefined;
 | 
			
		||||
	export { className as class };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<SheetPrimitive.Title
 | 
			
		||||
	class={cn("text-lg font-semibold text-foreground", className)}
 | 
			
		||||
	{...$$restProps}
 | 
			
		||||
>
 | 
			
		||||
	<slot />
 | 
			
		||||
</SheetPrimitive.Title>
 | 
			
		||||
		Reference in New Issue
	
	Block a user