nån slags början på dashboard

This commit is contained in:
botvid johansson 2025-02-06 17:15:09 +01:00
parent 2a01935011
commit 29078a4255
20 changed files with 409 additions and 4 deletions

16
package-lock.json generated
View File

@ -15,7 +15,8 @@
"@oslojs/encoding": "^1.1.0", "@oslojs/encoding": "^1.1.0",
"@tauri-apps/api": "^2.2.0", "@tauri-apps/api": "^2.2.0",
"dexie": "^4.0.11", "dexie": "^4.0.11",
"drizzle-orm": "^0.38.4" "drizzle-orm": "^0.38.4",
"svelte-radix": "^2.0.1"
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^1.2.5", "@eslint/compat": "^1.2.5",
@ -7282,6 +7283,19 @@
"url": "https://opencollective.com/eslint" "url": "https://opencollective.com/eslint"
} }
}, },
"node_modules/svelte-radix": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/svelte-radix/-/svelte-radix-2.0.1.tgz",
"integrity": "sha512-YrX44Dj+Rp6YZuPSjdmyd6P8QTkb2NXwySUCZYzjwkP6Cl3dZaTBPPeaSOutP3v3ycQ2XwyNOpyn4p0QcN+uYQ==",
"license": "MIT",
"engines": {
"node": ">=18.0.0",
"npm": ">=7.0.0"
},
"peerDependencies": {
"svelte": "^5.0.0"
}
},
"node_modules/tabbable": { "node_modules/tabbable": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",

View File

@ -56,6 +56,7 @@
"@oslojs/encoding": "^1.1.0", "@oslojs/encoding": "^1.1.0",
"@tauri-apps/api": "^2.2.0", "@tauri-apps/api": "^2.2.0",
"dexie": "^4.0.11", "dexie": "^4.0.11",
"drizzle-orm": "^0.38.4" "drizzle-orm": "^0.38.4",
"svelte-radix": "^2.0.1"
} }
} }

View File

@ -0,0 +1,26 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from "bits-ui";
import { slide } from "svelte/transition";
import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.ContentProps;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = slide;
export let transitionConfig: $$Props["transitionConfig"] = {
duration: 200,
};
export { className as class };
</script>
<AccordionPrimitive.Content
class={cn("overflow-hidden text-sm", className)}
{transition}
{transitionConfig}
{...$$restProps}
>
<div class="pb-4 pt-0">
<slot />
</div>
</AccordionPrimitive.Content>

View File

@ -0,0 +1,14 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.ItemProps;
let className: $$Props["class"] = undefined;
export { className as class };
export let value: $$Props["value"];
</script>
<AccordionPrimitive.Item {value} class={cn("border-b", className)} {...$$restProps}>
<slot />
</AccordionPrimitive.Item>

View File

@ -0,0 +1,28 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from "bits-ui";
import ChevronDown from "svelte-radix/ChevronDown.svelte";
import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.TriggerProps;
type $$Events = AccordionPrimitive.TriggerEvents;
let className: $$Props["class"] = undefined;
export let level: AccordionPrimitive.HeaderProps["level"] = 3;
export { className as class };
</script>
<AccordionPrimitive.Header {level} class="flex">
<AccordionPrimitive.Trigger
class={cn(
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
className
)}
{...$$restProps}
on:click
>
<slot />
<ChevronDown
class="text-muted-foreground h-4 w-4 shrink-0 transition-transform duration-200"
/>
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>

View File

@ -0,0 +1,17 @@
import { Accordion as AccordionPrimitive } from "bits-ui";
import Content from "./accordion-content.svelte";
import Item from "./accordion-item.svelte";
import Trigger from "./accordion-trigger.svelte";
const Root = AccordionPrimitive.Root;
export {
Root,
Content,
Item,
Trigger,
//
Root as Accordion,
Content as AccordionContent,
Item as AccordionItem,
Trigger as AccordionTrigger,
};

View File

@ -0,0 +1,36 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import Cross2 from "svelte-radix/Cross2.svelte";
import * as Dialog from "./index.js";
import { cn, flyAndScale } from "$lib/utils.js";
type $$Props = DialogPrimitive.ContentProps;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = {
duration: 200,
};
export { className as class };
</script>
<Dialog.Portal>
<Dialog.Overlay />
<DialogPrimitive.Content
{transition}
{transitionConfig}
class={cn(
"bg-background fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-lg md:w-full",
className
)}
{...$$restProps}
>
<slot />
<DialogPrimitive.Close
class="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none"
>
<Cross2 class="h-4 w-4" />
<span class="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</Dialog.Portal>

View File

@ -0,0 +1,16 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = DialogPrimitive.DescriptionProps;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<DialogPrimitive.Description
class={cn("text-muted-foreground text-sm", className)}
{...$$restProps}
>
<slot />
</DialogPrimitive.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-1.5 text-center sm:text-left", className)} {...$$restProps}>
<slot />
</div>

View File

@ -0,0 +1,21 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import { fade } from "svelte/transition";
import { cn } from "$lib/utils.js";
type $$Props = DialogPrimitive.OverlayProps;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = fade;
export let transitionConfig: $$Props["transitionConfig"] = {
duration: 150,
};
export { className as class };
</script>
<DialogPrimitive.Overlay
{transition}
{transitionConfig}
class={cn("bg-background/80 fixed inset-0 z-50 backdrop-blur-sm ", className)}
{...$$restProps}
/>

View File

@ -0,0 +1,9 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
type $$Props = DialogPrimitive.PortalProps;
</script>
<DialogPrimitive.Portal {...$$restProps}>
<slot />
</DialogPrimitive.Portal>

View File

@ -0,0 +1,16 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = DialogPrimitive.TitleProps;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<DialogPrimitive.Title
class={cn("text-lg font-semibold leading-none tracking-tight", className)}
{...$$restProps}
>
<slot />
</DialogPrimitive.Title>

View File

@ -0,0 +1,37 @@
import { Dialog as DialogPrimitive } from "bits-ui";
import Title from "./dialog-title.svelte";
import Portal from "./dialog-portal.svelte";
import Footer from "./dialog-footer.svelte";
import Header from "./dialog-header.svelte";
import Overlay from "./dialog-overlay.svelte";
import Content from "./dialog-content.svelte";
import Description from "./dialog-description.svelte";
const Root = DialogPrimitive.Root;
const Trigger = DialogPrimitive.Trigger;
const Close = DialogPrimitive.Close;
export {
Root,
Title,
Portal,
Footer,
Header,
Trigger,
Overlay,
Content,
Description,
Close,
//
Root as Dialog,
Title as DialogTitle,
Portal as DialogPortal,
Footer as DialogFooter,
Header as DialogHeader,
Trigger as DialogTrigger,
Overlay as DialogOverlay,
Content as DialogContent,
Description as DialogDescription,
Close as DialogClose,
};

View File

@ -0,0 +1,29 @@
import Root from "./input.svelte";
export type FormInputEvent<T extends Event = Event> = T & {
currentTarget: EventTarget & HTMLInputElement;
};
export type InputEvents = {
blur: FormInputEvent<FocusEvent>;
change: FormInputEvent<Event>;
click: FormInputEvent<MouseEvent>;
focus: FormInputEvent<FocusEvent>;
focusin: FormInputEvent<FocusEvent>;
focusout: FormInputEvent<FocusEvent>;
keydown: FormInputEvent<KeyboardEvent>;
keypress: FormInputEvent<KeyboardEvent>;
keyup: FormInputEvent<KeyboardEvent>;
mouseover: FormInputEvent<MouseEvent>;
mouseenter: FormInputEvent<MouseEvent>;
mouseleave: FormInputEvent<MouseEvent>;
mousemove: FormInputEvent<MouseEvent>;
paste: FormInputEvent<ClipboardEvent>;
input: FormInputEvent<InputEvent>;
wheel: FormInputEvent<WheelEvent>;
};
export {
Root,
//
Root as Input,
};

View File

@ -0,0 +1,42 @@
<script lang="ts">
import type { HTMLInputAttributes } from "svelte/elements";
import type { InputEvents } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = HTMLInputAttributes;
type $$Events = InputEvents;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"] = undefined;
export { className as class };
// Workaround for https://github.com/sveltejs/svelte/issues/9305
// Fixed in Svelte 5, but not backported to 4.x.
export let readonly: $$Props["readonly"] = undefined;
</script>
<input
class={cn(
"border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
bind:value
{readonly}
on:blur
on:change
on:click
on:focus
on:focusin
on:focusout
on:keydown
on:keypress
on:keyup
on:mouseover
on:mouseenter
on:mouseleave
on:mousemove
on:paste
on:input
on:wheel|passive
{...$$restProps}
/>

View File

@ -0,0 +1,7 @@
import Root from "./label.svelte";
export {
Root,
//
Root as Label,
};

View File

@ -0,0 +1,19 @@
<script lang="ts">
import { Label as LabelPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = LabelPrimitive.Props;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<LabelPrimitive.Root
class={cn(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
className
)}
{...$$restProps}
>
<slot />
</LabelPrimitive.Root>

View File

@ -23,7 +23,7 @@
</script> </script>
<div class="h-full w-full" role="application"> <div class="h-full w-full" role="application">
<Dashboard /> <Dashboard open="true" />
<Textarea activeShortforms={cache} /> <Textarea activeShortforms={cache} />
<Button variant="destructive" on:click={deleteDefaultShortforms}>Ta bort standardlista</Button> <Button variant="destructive" on:click={deleteDefaultShortforms}>Ta bort standardlista</Button>

View File

@ -1 +1,45 @@
<h1 class="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">Skrivert</h1> <script>
import * as Accordion from '$lib/components/ui/accordion';
import AccordionItem from '$lib/components/ui/accordion/accordion-item.svelte';
import { Button } from '$lib/components/ui/button';
import * as Dialog from '$lib/components/ui/dialog';
import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label';
export let open;
</script>
<Dialog.Root bind:open closeOnOutsideClick={false}>
<Dialog.Trigger />
<Dialog.Content class="sm:max-w-[625px]">
<Dialog.Header>
<Dialog.Title>Skrivert</Dialog.Title>
<Dialog.Description
>Jag har ingen aning om vilken ton man författar såna här hjälptexter med. Det här är
iallafall ett program för skrivtolkar som gör typ det ett sånt program ska göra, men på sitt
sätt. Är du ny användare rekommenderar jag att följa kom igång-guiden.</Dialog.Description
>
</Dialog.Header>
<Accordion.Root class="w-full">
<Accordion.Item value="manual">
<Accordion.Trigger>Gör kom igång-guiden</Accordion.Trigger>
<Accordion.Content></Accordion.Content>
</Accordion.Item>
<Accordion.Item value="import">
<Accordion.Trigger>Importera förkortningar</Accordion.Trigger>
<Accordion.Content>Här importerar man saker</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="settings">
<Accordion.Trigger>Ändra inställningar</Accordion.Trigger>
<Accordion.Content>Här ändrar man inställningar</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="issues">
<Accordion.Trigger>Ge feedback eller rapportera fel</Accordion.Trigger>
<Accordion.Content>Här ger man feedback eller rapporterar fel</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="interpret">
<Accordion.Trigger>Börja skriva</Accordion.Trigger>
<Accordion.Content>Man för börja skriva på en gång om man vill.</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
</Dialog.Content>
</Dialog.Root>