web: use ClassValue from svelte/elements for class props

Replace class?: string with class?: ClassValue across Svelte components,
adopting the idiomatic Svelte 5 array syntax (class={["base", className]})
instead of string interpolation for combining static and dynamic classes.
This commit is contained in:
nemunaire 2026-05-19 21:17:04 +08:00
commit 0d0e220c06
18 changed files with 60 additions and 40 deletions

View file

@ -74,7 +74,7 @@
}
</script>
<Navbar class="{className} py-1" id="nav" container expand="xs" light style="z-index: 100">
<Navbar class={[className, "py-1"]} id="nav" container expand="xs" light style="z-index: 100">
<NavbarBrand
href="/"
class="me-3"

View file

@ -36,7 +36,7 @@
title?: string;
}
let { class: className = "", color = "primary", size = "", title }: Props = $props();
let { class: className, color = "primary", size = "", title }: Props = $props();
function getHelpPathFromProvider(ptype: string): string {
if ($providersSpecs && $providersSpecs[ptype]) {

View file

@ -38,7 +38,7 @@
}
let {
class: className = "",
class: className,
domainName,
currentCheckerName,
checksBase: checksBaseProp = undefined,
@ -65,7 +65,7 @@
}
</script>
<nav class="checker-sidebar d-flex flex-column h-100 {className}">
<nav class={["checker-sidebar d-flex flex-column h-100", className]}>
{#if !$checkers}
<div class="d-flex gap-2 align-items-center justify-content-center my-3 text-muted">
<Spinner size="sm" color="primary" />

View file

@ -22,18 +22,20 @@
-->
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import ImgProvider from "$lib/components/providers/ImgProvider.svelte";
import type { HappydnsDomain } from "$lib/api-base/types.gen";
interface Props {
class?: string;
class?: ClassValue;
domain: Pick<HappydnsDomain, 'domain' | 'id_provider'>;
}
let { class: className = "", domain }: Props = $props();
let { class: className, domain }: Props = $props();
</script>
<div class="d-flex my-1 {className}" style="min-width: 0">
<div class={["d-flex my-1", className]} style="min-width: 0">
<div class="d-inline-block text-center" style="width: 50px;">
<ImgProvider id_provider={domain.id_provider} />
</div>

View file

@ -24,13 +24,15 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import type { ClassValue } from "svelte/elements";
import { nsrrtype, rdatatostr } from "$lib/dns";
import type { dnsRR } from "$lib/dns_rr";
const dispatch = createEventDispatcher();
interface Props {
class: string;
class?: ClassValue;
record: dnsRR;
}
@ -42,7 +44,7 @@
</script>
<div
class="record d-flex gap-1 {className}"
class={["record d-flex gap-1", className]}
role="button"
tabindex="0"
onclick={openRecord}

View file

@ -22,17 +22,19 @@
-->
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import { Input } from "@sveltestrap/sveltestrap";
import { domains_by_groups } from "$lib/stores/domains";
import { t } from "$lib/translations";
interface Props {
class?: string;
class?: ClassValue;
selectedDomain: string;
}
let { class: className = "", selectedDomain = $bindable() }: Props = $props();
let { class: className, selectedDomain = $bindable() }: Props = $props();
</script>
{#key $domains_by_groups}

View file

@ -54,12 +54,12 @@
</script>
{#if !items}
<div class="d-flex gap-2 align-items-center justify-content-center my-3 {className}">
<div class={["d-flex gap-2 align-items-center justify-content-center my-3", className]}>
<Spinner color="primary" />
{$t("wait.retrieving-domains")}
</div>
{:else if items.length === 0}
<div class="text-center my-3 {className}">
<div class={["text-center my-3", className]}>
{$t("domains.filtered-no-result")}
</div>
{:else}

View file

@ -48,7 +48,7 @@
}
let {
class: className = "",
class: className,
edit = false,
ptype,
state: formstate,
@ -81,13 +81,13 @@
<ImgProvider {ptype} style="max-height: 5rem; width: auto;" />
</PageTitle>
{#if $providersSpecs == null}
<div class="mt-5 d-flex justify-content-center align-items-center gap-2 {className}">
<div class={["mt-5 d-flex justify-content-center align-items-center gap-2", className]}>
<Spinner color="primary" />
{$t("wait.retrieving-setting")}
</div>
{:else}
{#if form.form == null}
<div class="d-flex flex-fill justify-content-center align-items-center gap-2 {className}">
<div class={["d-flex flex-fill justify-content-center align-items-center gap-2", className]}>
<Spinner color="primary" />
{$t("wait.retrieving-setting")}
</div>

View file

@ -22,6 +22,8 @@
-->
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import { Button, Card, Icon } from "@sveltestrap/sveltestrap";
import DomainGroupList from "$lib/components/forms/DomainGroupList.svelte";
@ -35,11 +37,11 @@
import { t } from "$lib/translations";
interface Props {
class?: string;
class?: ClassValue;
filteredGroup?: string | null;
}
let { class: className = "", filteredGroup = $bindable(null) }: Props = $props();
let { class: className, filteredGroup = $bindable(null) }: Props = $props();
</script>
{#if $domains && $domains.length}

View file

@ -50,7 +50,7 @@
[key: string]: unknown;
}
let { class: className = "", items, ...rest }: Props = $props();
let { class: className, items, ...rest }: Props = $props();
if (!$providersSpecs) refreshProvidersSpecs();
@ -112,12 +112,12 @@
<NewProviderModal />
{#if !items || $providersSpecs == null}
<div class="d-flex gap-2 align-items-center justify-content-center my-3 {className}">
<div class={["d-flex gap-2 align-items-center justify-content-center my-3", className]}>
<Spinner color="primary" />
{$t("wait.retrieving-providers")}
</div>
{:else if items.length === 0}
<div class="text-center my-3 {className}">
<div class={["text-center my-3", className]}>
<form
onsubmit={(e) => {
e.preventDefault();

View file

@ -32,16 +32,18 @@
hljs.registerLanguage("dns", dns);
import type { ClassValue } from "svelte/elements";
interface Props {
class?: string;
class?: ClassValue;
dn: string;
origin: Domain;
rr: dnsRR;
}
let { class: className = "", dn, origin, rr = $bindable() }: Props = $props();
let { class: className, dn, origin, rr = $bindable() }: Props = $props();
</script>
<div class="text-truncate font-monospace {className}">
<div class={["text-truncate font-monospace", className]}>
{@html hljs.highlight(printRR(rr, dn, origin.domain), { language: "dns" }).value}
</div>

View file

@ -22,18 +22,20 @@
-->
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import RecordText from "$lib/components/records/RecordText.svelte";
import type { dnsRR } from "$lib/dns_rr";
import type { Domain } from "$lib/model/domain";
interface Props {
class?: string;
class?: ClassValue;
dn: string;
origin: Domain;
rrs: Array<dnsRR>;
}
let { class: className = "", dn, origin, rrs }: Props = $props();
let { class: className, dn, origin, rrs }: Props = $props();
</script>
<div class={className}>

View file

@ -22,11 +22,13 @@
-->
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import BasicInput from "$lib/components/inputs/basic.svelte";
import type { dnsTypeSOA } from "$lib/dns_rr";
interface Props {
class: string;
class?: ClassValue;
value?: dnsTypeSOA;
}

View file

@ -23,6 +23,7 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { ClassValue } from "svelte/elements";
import { Button, Icon, Table } from "@sveltestrap/sveltestrap";
import { getRrtype, newRR, rdatafields, type dnsRR } from "$lib/dns_rr";
@ -31,7 +32,7 @@
import { t } from "$lib/translations";
interface Props {
class?: string;
class?: ClassValue;
dn: string;
edit: boolean;
field: Snippet<[number, string]>;
@ -42,7 +43,7 @@
}
let {
class: className = "",
class: className,
dn,
edit,
field,

View file

@ -22,6 +22,8 @@
-->
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import {
Button,
Icon,
@ -33,14 +35,14 @@
import type { Domain } from "$lib/model/domain";
interface Props {
class?: string;
class?: ClassValue;
dn: string;
origin: Domain;
rr: dnsRR;
onopen?: () => void;
}
let { class: className = "", dn, origin, rr = $bindable(emptyRR()), onopen }: Props = $props();
let { class: className, dn, origin, rr = $bindable(emptyRR()), onopen }: Props = $props();
function openEditor() {
onopen?.();
@ -48,7 +50,7 @@
}
</script>
<div class="d-flex {className}">
<div class={["d-flex", className]}>
<RecordText
class="flex-fill m-0 px-1 bg-light sticky-top pt-1 pb-1 border-1 border-bottom"
{dn}

View file

@ -22,6 +22,8 @@
-->
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import { Button, Icon, Spinner } from "@sveltestrap/sveltestrap";
import { getDomain as APIGetDomain } from "$lib/api/domains";
@ -34,12 +36,12 @@
import { controls as ctrlDomainDelete } from "./ModalDomainDelete.svelte";
interface Props {
class?: string;
class?: ClassValue;
domain: Domain;
history: string;
}
let { class: className = "", domain, history }: Props = $props();
let { class: className, domain, history }: Props = $props();
async function getDomain(id: string): Promise<Domain> {
return await APIGetDomain(id);
@ -55,7 +57,7 @@
</script>
{#if $domains_idx[domain.id] && $thisZone}
<div class="d-flex flex-column {className}">
<div class={["d-flex flex-column", className]}>
{#if $domains_idx[domain.id].zone_history && history === $domains_idx[domain.id].zone_history[0]}
{#key $zoneDiffVersion}
{#await getCachedDiffZoneSummary(domain, "@", $thisZone.id)}

View file

@ -35,12 +35,12 @@
service?: HappydnsService;
}
let { service, class: className = "" }: Props = $props();
let { service, class: className }: Props = $props();
</script>
{#if service && $userSession.settings && $servicesSpecsLoaded && $servicesSpecs[service._svctype]}
{#if $servicesSpecs[service._svctype].categories?.length && !$userSession.settings.showrrtypes}
<div class="d-flex align-items-center gap-1 {className}">
<div class={["d-flex align-items-center gap-1", className]}>
{#each $servicesSpecs[service._svctype].categories as category}
<Badge color="secondary">
{category}
@ -48,7 +48,7 @@
{/each}
</div>
{:else if $servicesSpecs[service._svctype].record_types?.length && $userSession.settings.showrrtypes}
<div class="d-flex align-items-center gap-1 {className}">
<div class={["d-flex align-items-center gap-1", className]}>
{#each $servicesSpecs[service._svctype].record_types as rrtype}
<Badge color="info">
{nsrrtype(rrtype)}

View file

@ -25,6 +25,7 @@
import { preventDefault } from 'svelte/legacy';
import { createEventDispatcher } from "svelte";
import type { ClassValue } from "svelte/elements";
import { Button, Collapse, FormGroup, Input, Spinner } from "@sveltestrap/sveltestrap";
@ -37,7 +38,7 @@
const dispatch = createEventDispatcher();
interface Props {
class?: string;
class?: ClassValue;
value?: ResolverForm;
showDNSSEC?: boolean;
sortedDomains?: Array<Domain>;
@ -45,7 +46,7 @@
}
let {
class: className = "",
class: className,
value = $bindable({ domain: "", type: "ANY", resolver: "local" }),
showDNSSEC = $bindable(false),
sortedDomains = [],