flotilla/src/lib/components/Spinner.svelte

38 lines
838 B
Svelte
Raw Normal View History

2024-08-14 00:58:26 +00:00
<script lang="ts">
import type {Snippet} from "svelte"
import cx from "classnames"
2024-08-14 00:58:26 +00:00
type Props = {
children?: Snippet
size?: "md" | "sm" | "xs"
2025-02-04 00:37:14 +00:00
loading?: boolean
// Reserves the spinner's slot while idle, so toggling `loading` doesn't reflow the button.
reserveSpace?: boolean
2026-06-24 20:10:06 +00:00
class?: string
}
const {
children,
size = "md",
loading = true,
reserveSpace = false,
...restProps
}: Props = $props()
2025-02-04 00:37:14 +00:00
const spinnerClass = $derived(
cx("spinner", {
"spinner-sm": size === "sm",
"spinner-xs": size === "xs",
}),
)
2024-08-14 00:58:26 +00:00
</script>
<div class={cx("flex items-center gap-2", restProps.class)}>
2024-08-14 00:58:26 +00:00
{#if loading}
<span class={spinnerClass}></span>
{:else if reserveSpace}
<span class={cx(spinnerClass, "invisible")}></span>
2024-08-14 00:58:26 +00:00
{/if}
2025-02-04 00:37:14 +00:00
{@render children?.()}
</div>