mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-29 20:43:37 +03:00
new popover component in the breadcrumbs menu
This commit is contained in:
parent
c087e57158
commit
35b7cd780b
@ -5,9 +5,11 @@
|
||||
import { getContext } from 'svelte';
|
||||
import type { Writable } from 'svelte/store';
|
||||
import { IconHome, IconChevronRight } from '@tabler/icons-svelte';
|
||||
import Popover from '$lib/components/Popover';
|
||||
|
||||
let project: Writable<Project | null | undefined> = getContext('project');
|
||||
let session: Writable<Session | null | undefined> = getContext('session');
|
||||
let projects: Writable<any> = getContext('projects');
|
||||
</script>
|
||||
|
||||
<div class="flex flex-row items-center space-x-1 bg-zinc-900 text-zinc-400 h-8">
|
||||
@ -16,7 +18,28 @@
|
||||
</a>
|
||||
{#if $project}
|
||||
<IconChevronRight class="w-5 h-5 text-zinc-700" />
|
||||
<a class="hover:text-zinc-200" href="/projects/{$project.id}">{$project.title}</a>
|
||||
<div class="flex flex-col">
|
||||
<Popover>
|
||||
<div slot="button">
|
||||
{$project.title}
|
||||
</div>
|
||||
<div class="flex flex-col space-y-2">
|
||||
<ul class="flex flex-col space-y-2">
|
||||
{#each $projects || [] as project}
|
||||
<a
|
||||
href="/projects/{project.id}"
|
||||
class="p-2 rounded hover:bg-zinc-700 cursor-pointer truncate"
|
||||
>
|
||||
{project.title}</a
|
||||
>
|
||||
{/each}
|
||||
</ul>
|
||||
<span class="w-full border-t border-zinc-700" />
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="p-2 rounded hover:bg-zinc-700 cursor-pointer">Add project...</div>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
{/if}
|
||||
{#if $project && $session}
|
||||
<IconChevronRight class="w-5 h-5 text-zinc-700" />
|
||||
|
69
src/lib/components/Popover/Popover.svelte
Normal file
69
src/lib/components/Popover/Popover.svelte
Normal file
@ -0,0 +1,69 @@
|
||||
<script lang="ts">
|
||||
import { slide } from 'svelte/transition';
|
||||
import { cubicOut } from 'svelte/easing';
|
||||
|
||||
let showPopover: boolean = false;
|
||||
let anchor: HTMLButtonElement | undefined = undefined;
|
||||
let bottom: number;
|
||||
let left: number;
|
||||
|
||||
const initPosition = () =>
|
||||
({ bottom, left } = anchor?.getBoundingClientRect() ?? { bottom: 0, left: 0 });
|
||||
|
||||
$: anchor, initPosition();
|
||||
|
||||
function clickOutside(element: HTMLElement, callback: () => void) {
|
||||
const handleClick = (event: Event) => {
|
||||
const target = event.target as HTMLElement;
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
if (!element.contains(target)) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
document.body.addEventListener('click', handleClick);
|
||||
|
||||
return {
|
||||
update(newCallback: () => void) {
|
||||
callback = newCallback;
|
||||
},
|
||||
destroy() {
|
||||
document.removeEventListener('click', handleClick, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:resize={initPosition} on:keydown={() => (showPopover = false)} />
|
||||
|
||||
<div use:clickOutside={() => (showPopover = false)}>
|
||||
<button on:click={() => (showPopover = !showPopover)} bind:this={anchor} class="text-zinc-50"
|
||||
><slot name="button" /></button
|
||||
>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
{#if showPopover}
|
||||
<div
|
||||
role="dialog"
|
||||
aria-labelledby="Title"
|
||||
aria-describedby="Description"
|
||||
aria-orientation="vertical"
|
||||
transition:slide={{ duration: 150, easing: cubicOut }}
|
||||
on:click|stopPropagation
|
||||
class="wrapper z-50 bg-zinc-800 border border-zinc-700 text-zinc-50 rounded shadow-2xl min-w-[180px] max-w-[512px]"
|
||||
style="--popover-top: {`${bottom}px`}; --popover-left: {`${left}px`}"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
position: absolute;
|
||||
top: calc(var(--popover-top) + 4px);
|
||||
left: var(--popover-left);
|
||||
}
|
||||
</style>
|
3
src/lib/components/Popover/index.ts
Normal file
3
src/lib/components/Popover/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { default as Popover } from './Popover.svelte';
|
||||
|
||||
export default Popover;
|
@ -9,10 +9,11 @@
|
||||
import Breadcrumbs from '$lib/components/Breadcrumbs.svelte';
|
||||
|
||||
export let data: LayoutData;
|
||||
const { user, posthog } = data;
|
||||
const { user, posthog, projects } = data;
|
||||
|
||||
setContext('project', writable(null));
|
||||
setContext('session', writable(null));
|
||||
setContext('projects', projects);
|
||||
|
||||
user.subscribe(posthog.identify);
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user