updated button

fixed flickering on re-render (due to having color classes state be initialized empty) and made code cleaner
This commit is contained in:
axel 2025-04-11 22:02:06 +02:00
parent 54e988bd0a
commit 58477f579e
6 changed files with 38 additions and 53 deletions

View File

@ -1,10 +1,10 @@
<script lang="ts"> <script lang="ts">
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
import IconChevronLeft from "~icons/tabler/chevron-left";
import IconEclamationCircle from "~icons/tabler/exclamation-circle";
import Button from "../ui/Button.svelte"; import Button from "../ui/Button.svelte";
import HorizontalSpacer from "../ui/HorizontalSpacer.svelte"; import HorizontalSpacer from "../ui/HorizontalSpacer.svelte";
import ResourcePageHeader from "./ResourcePageHeader.svelte"; import ResourcePageHeader from "./ResourcePageHeader.svelte";
import IconEclamationCircle from "~icons/tabler/exclamation-circle";
import IconChevronLeft from "~icons/tabler/chevron-left";
let { let {
heading, heading,
@ -32,7 +32,7 @@
{#if error} {#if error}
<div transition:fade> <div transition:fade>
<Button Icon={IconEclamationCircle} type="button" color="red" onclick={() => error = null}>{error} (Click to dismiss)</Button> <Button Icon={IconEclamationCircle} type="button" color="danger" onclick={() => error = null}>{error} (Click to dismiss)</Button>
</div> </div>
{/if} {/if}
</div> </div>

View File

@ -1,15 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { ClassValue, HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements"; import type { ClassValue, HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
type Props = {
a?: boolean,
color?: "neutral" | "red" | "green",
inverted?: boolean,
Icon?: any,
extra?: ClassValue,
children?: any
} & HTMLButtonAttributes & HTMLAnchorAttributes;
let { let {
a, a,
color, color,
@ -18,42 +9,36 @@
children, children,
extra, extra,
...others ...others
}: Props = $props(); }: {
a?: boolean,
color?: "primary" | "danger" | "success",
inverted?: boolean,
Icon?: any,
extra?: ClassValue,
children?: any
} & HTMLButtonAttributes & HTMLAnchorAttributes = $props();
let baseClasses = $state("block flex items-center text-sm px-4 py-2 cursor-pointer rounded transition-all duration-300 ease-in-out"); const baseClasses = "block flex items-center text-sm px-4 py-2 cursor-pointer rounded transition-all duration-300 ease-in-out";
const defaultColors = "bg-neutral-800 hover:bg-neutral-600 text-white border border-transparent"; const colors = {
let colorClasses = $state(defaultColors); "normal": {
"danger": "bg-red-500 hover:bg-red-600 text-white border border-transparent",
"success": "bg-emerald-500 hover:bg-emerald-600 text-white border border-transparent",
"primary": "bg-neutral-800 hover:bg-neutral-600 text-white border border-transparent",
},
"inverted": {
"danger": "bg-white hover:bg-red-100 text-red-500 border border-red-500",
"success": "bg-white hover:bg-emerald-100 text-emerald-500 border border-emerald-500",
"primary": "bg-white hover:bg-neutral-100 text-neutral-800 border border-neutral-800",
},
};
let colorClasses = $derived(colors[inverted ? "inverted" : "normal"][color ?? "primary"]);
let fullClasses = $derived(baseClasses + " " + extra + " " + colorClasses); let fullClasses = $derived(baseClasses + " " + extra + " " + colorClasses);
$effect(() => {
if (!inverted) {
switch (color) {
case "red":
colorClasses = "bg-red-500 hover:bg-red-600 text-white border border-transparent";
break;
case "green":
colorClasses = "bg-emerald-500 hover:bg-emerald-600 text-white border border-transparent";
break;
default:
colorClasses= defaultColors;
}
} else {
switch (color) {
case "red":
colorClasses = "bg-white hover:bg-red-100 text-red-500 border border-red-500";
break;
case "green":
colorClasses = "bg-white hover:bg-emerald-100 text-emerald-500 border border-emerald-500";
break;
default:
colorClasses = "bg-white hover:bg-neutral-100 text-neutral-800 border border-neutral-800";
}
}
});
</script> </script>
{#if a} {#if a}
<a class={fullClasses} {...others}> <a class={fullClasses} {...others}>
{#if Icon} {#if Icon}

View File

@ -1,11 +1,11 @@
<script lang="ts"> <script lang="ts">
import IconPlus from "~icons/tabler/plus"; import { enhance } from "$app/forms";
import ResourceCard from "$lib/components/resources/ResourceCard.svelte";
import ResourceListPage from "$lib/components/resources/ResourceListPage.svelte";
import Button from "$lib/components/ui/Button.svelte";
import IconEdit from "~icons/tabler/edit"; import IconEdit from "~icons/tabler/edit";
import IconPlayerPlay from "~icons/tabler/player-play"; import IconPlayerPlay from "~icons/tabler/player-play";
import Button from "$lib/components/ui/Button.svelte"; import IconPlus from "~icons/tabler/plus";
import ResourceListPage from "$lib/components/resources/ResourceListPage.svelte";
import ResourceCard from "$lib/components/resources/ResourceCard.svelte";
import { enhance } from "$app/forms";
let { data } = $props(); let { data } = $props();
</script> </script>
@ -29,7 +29,7 @@
<Button Icon={IconEdit} a href="/dashboard/devices/{device.id}" extra="!p-2"/> <Button Icon={IconEdit} a href="/dashboard/devices/{device.id}" extra="!p-2"/>
{/if} {/if}
<form method="POST" action="/dashboard/devices/{device.id}?/wake" use:enhance> <form method="POST" action="/dashboard/devices/{device.id}?/wake" use:enhance>
<Button Icon={IconPlayerPlay} type="submit" color="green" extra="!p-2"></Button> <Button Icon={IconPlayerPlay} type="submit" color="success" extra="!p-2"></Button>
</form> </form>
{/snippet} {/snippet}
</ResourceCard> </ResourceCard>

View File

@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
import { enhance } from "$app/forms"; import { enhance } from "$app/forms";
import Button from "$lib/components/ui/Button.svelte";
import Collapsible from "$lib/components/ui/Collapsible.svelte";
import InputText from "$lib/components/forms/InputText.svelte"; import InputText from "$lib/components/forms/InputText.svelte";
import ResourceEditPage from "$lib/components/resources/ResourceEditPage.svelte"; import ResourceEditPage from "$lib/components/resources/ResourceEditPage.svelte";
import Button from "$lib/components/ui/Button.svelte";
import Collapsible from "$lib/components/ui/Collapsible.svelte";
import IconDeviceFloppy from "~icons/tabler/device-floppy"; import IconDeviceFloppy from "~icons/tabler/device-floppy";
import IconTrash from "~icons/tabler/trash"; import IconTrash from "~icons/tabler/trash";
@ -44,7 +44,7 @@
<div class="flex gap-5 items-center"> <div class="flex gap-5 items-center">
<Button Icon={IconDeviceFloppy}>{data.device ? "Update" : "Create"}</Button> <Button Icon={IconDeviceFloppy}>{data.device ? "Update" : "Create"}</Button>
{#if data.device} {#if data.device}
<Button Icon={IconTrash} color="red" inverted formaction="?/delete">Delete</Button> <Button Icon={IconTrash} color="danger" inverted formaction="?/delete">Delete</Button>
{/if} {/if}
</div> </div>
</form> </form>

View File

@ -30,7 +30,7 @@
<div class="flex gap-5 items-center"> <div class="flex gap-5 items-center">
<Button Icon={IconDeviceFloppy}>{data.group ? "Update" : "Create"}</Button> <Button Icon={IconDeviceFloppy}>{data.group ? "Update" : "Create"}</Button>
{#if data.group} {#if data.group}
<Button Icon={IconTrash} color="red" inverted formaction="?/delete">Delete</Button> <Button Icon={IconTrash} color="danger" inverted formaction="?/delete">Delete</Button>
{/if} {/if}
</div> </div>
</form> </form>

View File

@ -53,7 +53,7 @@
<div class="flex gap-5 items-center"> <div class="flex gap-5 items-center">
<Button Icon={IconDeviceFloppy}>{data.user ? "Update" : "Create"}</Button> <Button Icon={IconDeviceFloppy}>{data.user ? "Update" : "Create"}</Button>
{#if data.user} {#if data.user}
<Button Icon={IconTrash} color="red" inverted formaction="?/delete">Delete</Button> <Button Icon={IconTrash} color="danger" inverted formaction="?/delete">Delete</Button>
{/if} {/if}
</div> </div>
</form> </form>