skelett för högerklicks/f5-meny, a la protype
This commit is contained in:
parent
053f483c36
commit
14bad11a65
79
src/components/menu.svelte
Normal file
79
src/components/menu.svelte
Normal file
@ -0,0 +1,79 @@
|
||||
<script>
|
||||
import { appState } from "$lib/stores.svelte"
|
||||
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index";
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import Gear from "svelte-radix/Gear.svelte";
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Root open={appState.menuOpen} onOpenChange={(v) => {appState.menuOpen = v}} closeFocus="textarea#doc.textarea">
|
||||
<DropdownMenu.Trigger asChild let:builder>
|
||||
<Button builders={[builder]} variant="ghost" class="absolute top-2 right-2" size="icon">
|
||||
<Gear class="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Content class="w-56">
|
||||
<DropdownMenu.Label>Inställningar</DropdownMenu.Label>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Group>
|
||||
<DropdownMenu.Item>
|
||||
Lägg till förkortning
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item>
|
||||
Statistik
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Group>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Group>
|
||||
<DropdownMenu.Item>
|
||||
Förkortningar
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item>
|
||||
Förinskriven text
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item>
|
||||
Textinställningar
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item>
|
||||
Tangentbord
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Group>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Group>
|
||||
<DropdownMenu.Sub>
|
||||
<DropdownMenu.SubTrigger>Anslut</DropdownMenu.SubTrigger>
|
||||
<DropdownMenu.SubContent>
|
||||
<DropdownMenu.Item>
|
||||
Distanstolkning
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item>
|
||||
Lokalt nätverk
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.SubContent>
|
||||
</DropdownMenu.Sub>
|
||||
</DropdownMenu.Group>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item>
|
||||
Hjälp
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item>Feedback
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item>Användarkonto
|
||||
<DropdownMenu.Shortcut>F12</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item>
|
||||
Logga ut
|
||||
<DropdownMenu.Shortcut>⇧⌘Q</DropdownMenu.Shortcut>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Root>
|
@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import Check from "svelte-radix/Check.svelte";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.CheckboxItemProps;
|
||||
type $$Events = DropdownMenuPrimitive.CheckboxItemEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let checked: $$Props["checked"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
bind:checked
|
||||
class={cn(
|
||||
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
on:focusin
|
||||
on:focusout
|
||||
on:pointerdown
|
||||
on:pointerleave
|
||||
on:pointermove
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.CheckboxIndicator>
|
||||
<Check class="h-4 w-4" />
|
||||
</DropdownMenuPrimitive.CheckboxIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import { cn, flyAndScale } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.ContentProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let sideOffset: $$Props["sideOffset"] = 4;
|
||||
export let transition: $$Props["transition"] = flyAndScale;
|
||||
export let transitionConfig: $$Props["transitionConfig"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.Content
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
{sideOffset}
|
||||
class={cn(
|
||||
"bg-popover text-popover-foreground z-50 min-w-[8rem] rounded-md border p-1 shadow-md focus:outline-none",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:keydown
|
||||
>
|
||||
<slot />
|
||||
</DropdownMenuPrimitive.Content>
|
@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.ItemProps & {
|
||||
inset?: boolean;
|
||||
};
|
||||
type $$Events = DropdownMenuPrimitive.ItemEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let inset: $$Props["inset"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.Item
|
||||
class={cn(
|
||||
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
inset && "pl-8",
|
||||
className
|
||||
)}
|
||||
on:click
|
||||
on:keydown
|
||||
on:focusin
|
||||
on:focusout
|
||||
on:pointerdown
|
||||
on:pointerleave
|
||||
on:pointermove
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</DropdownMenuPrimitive.Item>
|
@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.LabelProps & {
|
||||
inset?: boolean;
|
||||
};
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let inset: $$Props["inset"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.Label
|
||||
class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</DropdownMenuPrimitive.Label>
|
@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.RadioGroupProps;
|
||||
|
||||
export let value: $$Props["value"] = undefined;
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.RadioGroup {...$$restProps} bind:value>
|
||||
<slot />
|
||||
</DropdownMenuPrimitive.RadioGroup>
|
@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import DotFilled from "svelte-radix/DotFilled.svelte";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.RadioItemProps;
|
||||
type $$Events = DropdownMenuPrimitive.RadioItemEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let value: DropdownMenuPrimitive.RadioItemProps["value"];
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
class={cn(
|
||||
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
)}
|
||||
{value}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
on:focusin
|
||||
on:focusout
|
||||
on:pointerdown
|
||||
on:pointerleave
|
||||
on:pointermove
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.RadioIndicator>
|
||||
<DotFilled class="h-4 w-4 fill-current" />
|
||||
</DropdownMenuPrimitive.RadioIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</DropdownMenuPrimitive.RadioItem>
|
@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.SeparatorProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.Separator
|
||||
class={cn("bg-muted -mx-1 my-1 h-px", className)}
|
||||
{...$$restProps}
|
||||
/>
|
@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLSpanElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<span class={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...$$restProps}>
|
||||
<slot />
|
||||
</span>
|
@ -0,0 +1,29 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import { cn, flyAndScale } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.SubContentProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let transition: $$Props["transition"] = flyAndScale;
|
||||
export let transitionConfig: $$Props["transitionConfig"] = {
|
||||
x: -10,
|
||||
y: 0,
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn(
|
||||
"bg-popover text-popover-foreground z-50 min-w-[8rem] rounded-md border p-1 shadow-lg focus:outline-none",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:keydown
|
||||
on:focusout
|
||||
on:pointermove
|
||||
>
|
||||
<slot />
|
||||
</DropdownMenuPrimitive.SubContent>
|
@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import ChevronRight from "svelte-radix/ChevronRight.svelte";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = DropdownMenuPrimitive.SubTriggerProps & {
|
||||
inset?: boolean;
|
||||
};
|
||||
type $$Events = DropdownMenuPrimitive.SubTriggerEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let inset: $$Props["inset"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
class={cn(
|
||||
"data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
|
||||
inset && "pl-8",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
on:focusin
|
||||
on:focusout
|
||||
on:pointerleave
|
||||
on:pointermove
|
||||
>
|
||||
<slot />
|
||||
<ChevronRight class="ml-auto h-4 w-4" />
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
48
src/lib/components/ui/dropdown-menu/index.ts
Normal file
48
src/lib/components/ui/dropdown-menu/index.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||
import Item from "./dropdown-menu-item.svelte";
|
||||
import Label from "./dropdown-menu-label.svelte";
|
||||
import Content from "./dropdown-menu-content.svelte";
|
||||
import Shortcut from "./dropdown-menu-shortcut.svelte";
|
||||
import RadioItem from "./dropdown-menu-radio-item.svelte";
|
||||
import Separator from "./dropdown-menu-separator.svelte";
|
||||
import RadioGroup from "./dropdown-menu-radio-group.svelte";
|
||||
import SubContent from "./dropdown-menu-sub-content.svelte";
|
||||
import SubTrigger from "./dropdown-menu-sub-trigger.svelte";
|
||||
import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
|
||||
|
||||
const Sub = DropdownMenuPrimitive.Sub;
|
||||
const Root = DropdownMenuPrimitive.Root;
|
||||
const Trigger = DropdownMenuPrimitive.Trigger;
|
||||
const Group = DropdownMenuPrimitive.Group;
|
||||
|
||||
export {
|
||||
Sub,
|
||||
Root,
|
||||
Item,
|
||||
Label,
|
||||
Group,
|
||||
Trigger,
|
||||
Content,
|
||||
Shortcut,
|
||||
Separator,
|
||||
RadioItem,
|
||||
SubContent,
|
||||
SubTrigger,
|
||||
RadioGroup,
|
||||
CheckboxItem,
|
||||
//
|
||||
Root as DropdownMenu,
|
||||
Sub as DropdownMenuSub,
|
||||
Item as DropdownMenuItem,
|
||||
Label as DropdownMenuLabel,
|
||||
Group as DropdownMenuGroup,
|
||||
Content as DropdownMenuContent,
|
||||
Trigger as DropdownMenuTrigger,
|
||||
Shortcut as DropdownMenuShortcut,
|
||||
RadioItem as DropdownMenuRadioItem,
|
||||
Separator as DropdownMenuSeparator,
|
||||
RadioGroup as DropdownMenuRadioGroup,
|
||||
SubContent as DropdownMenuSubContent,
|
||||
SubTrigger as DropdownMenuSubTrigger,
|
||||
CheckboxItem as DropdownMenuCheckboxItem,
|
||||
};
|
@ -2,29 +2,16 @@
|
||||
import Textarea from '../components/textarea.svelte';
|
||||
import Dashboard from '../components/dashboard.svelte';
|
||||
import { db, deleteShortformList, type Shortform } from '../db/main';
|
||||
import { importShortforms } from '../db/import';
|
||||
|
||||
import Menu from "../components/menu.svelte";
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
|
||||
import { hotkeys } from '../modules/keyboard';
|
||||
let cache: Array<Shortform>;
|
||||
let showDashboard: boolean = true;
|
||||
db.shortforms
|
||||
.toArray()
|
||||
.then((shortforms) => {
|
||||
cache = shortforms;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
importShortforms([]);
|
||||
const deleteDefaultShortforms = () => {
|
||||
deleteShortformList(890324);
|
||||
cache = [];
|
||||
};
|
||||
let showDashboard: boolean = false;
|
||||
|
||||
const handleHotkeys = (e: KeyboardEvent) => {
|
||||
hotkeys.get(e.key)?.action(e);
|
||||
};
|
||||
|
||||
</script>
|
||||
<svelte:head>
|
||||
<title>SKRIVERT</title>
|
||||
@ -33,8 +20,9 @@
|
||||
|
||||
<div class="h-dvh w-full overflow-hidden" role="application">
|
||||
<div class="h-full">
|
||||
<Menu />
|
||||
<Textarea />
|
||||
<Dashboard open={showDashboard} />
|
||||
<!-- <Button variant="destructive" on:click={deleteDefaultShortforms}>Ta bort standardlista</Button>-->
|
||||
</div>
|
||||
<!--<Dashboard open={showDashboard} />-->
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user