layer settings

This commit is contained in:
vcoppe
2024-04-14 15:36:41 +02:00
parent ac15f9064f
commit 6a8dfb5d5e
11 changed files with 346 additions and 5 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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"];

View 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>

View 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>

View 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>

View 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>

View 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}
/>

View 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>

View 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>