fix: address Storybook review findings

This commit is contained in:
vince 2026-06-18 19:01:53 +02:00
parent d95f064189
commit 17c9d24e31
8 changed files with 121 additions and 20 deletions

View file

@ -1,6 +1,16 @@
<script lang="ts">
import type { HTMLButtonAttributes } from "svelte/elements";
import IconGlyph from "./IconGlyph.svelte";
type ButtonProps = Omit<HTMLButtonAttributes, "type"> & {
label: string;
variant?: "primary" | "secondary" | "danger" | "ghost";
size?: "default" | "compact";
icon?: string;
loading?: boolean;
type?: "button" | "submit" | "reset";
};
let {
label,
variant = "primary",
@ -9,19 +19,14 @@
disabled = false,
loading = false,
type = "button",
}: {
label: string;
variant?: "primary" | "secondary" | "danger" | "ghost";
size?: "default" | "compact";
icon?: string;
disabled?: boolean;
loading?: boolean;
type?: "button" | "submit" | "reset";
} = $props();
class: className = "",
...buttonProps
}: ButtonProps = $props();
</script>
<button
class="ui-button"
{...buttonProps}
class={className ? `ui-button ${className}` : "ui-button"}
data-variant={variant}
data-size={size}
data-loading={loading}

View file

@ -1,20 +1,33 @@
<script lang="ts">
import type { HTMLButtonAttributes } from "svelte/elements";
import IconGlyph from "./IconGlyph.svelte";
type IconButtonProps = Omit<HTMLButtonAttributes, "type"> & {
icon: string;
label: string;
active?: boolean;
type?: "button" | "submit" | "reset";
};
let {
icon,
label,
active = false,
disabled = false,
}: {
icon: string;
label: string;
active?: boolean;
disabled?: boolean;
} = $props();
type = "button",
class: className = "",
...buttonProps
}: IconButtonProps = $props();
</script>
<button class="icon-button" aria-label={label} data-active={active} {disabled}>
<button
{...buttonProps}
class={className ? `icon-button ${className}` : "icon-button"}
aria-label={label}
data-active={active}
{disabled}
{type}
>
<IconGlyph name={icon} size="sm" />
</button>

View file

@ -1,7 +1,9 @@
import { render } from "svelte/server";
import { describe, expect, test } from "vitest";
import Button from "./Button.svelte";
import DashboardFrame from "./DashboardFrame.svelte";
import FooterCell from "./FooterCell.svelte";
import IconButton from "./IconButton.svelte";
import ServiceRow from "./ServiceRow.svelte";
import TelemetryCard from "./TelemetryCard.svelte";
import { dashboardPreviewFixtures } from "../fixtures";
@ -94,4 +96,31 @@ describe("dashboard UI components", () => {
expect(withoutProgress.body).not.toContain("telemetry-card__bar");
expect(withProgress.body).toContain("--metric-progress: 42%");
});
test("base button controls forward native attributes", () => {
const button = render(Button, {
props: {
label: "Refresh",
id: "refresh-action",
class: "custom-action",
"aria-controls": "refresh-target",
},
});
const iconButton = render(IconButton, {
props: {
icon: "mdi:refresh",
label: "Refresh status",
id: "refresh-icon-action",
class: "custom-icon-action",
"aria-expanded": "false",
},
});
expect(button.body).toContain("id=\"refresh-action\"");
expect(button.body).toContain("class=\"ui-button custom-action ");
expect(button.body).toContain("aria-controls=\"refresh-target\"");
expect(iconButton.body).toContain("id=\"refresh-icon-action\"");
expect(iconButton.body).toContain("class=\"icon-button custom-icon-action ");
expect(iconButton.body).toContain("aria-expanded=\"false\"");
});
});