diff --git a/src/app.html b/src/app.html index 983e301..2ec3a42 100644 --- a/src/app.html +++ b/src/app.html @@ -13,12 +13,6 @@ rel="stylesheet" /> - - - %sveltekit.head% diff --git a/src/lib/Button.svelte b/src/lib/Button.svelte index 2490c01..67267ca 100644 --- a/src/lib/Button.svelte +++ b/src/lib/Button.svelte @@ -2,9 +2,11 @@ import type { Snippet } from 'svelte'; import type { ClassValue, HTMLButtonAttributes, MouseEventHandler } from 'svelte/elements'; import Spinner from './Spinner.svelte'; + import type { IconComponentProps } from 'phosphor-svelte'; + import { defaultIconProps, type IconDef } from './util'; interface Props extends Omit { - icon?: string; + icon?: IconDef; animate?: boolean; loading?: boolean; class?: ClassValue | null | undefined; @@ -25,7 +27,13 @@ ...others }: Props = $props(); - let iconElement = $state(null); + type SVGInHTML = HTMLElement & SVGElement; + let iconElement = $state(null); + $effect(() => { + if (icon && ref) { + iconElement = ref.querySelector('svg') as SVGInHTML | null; + } + }); const handleButtonClick: MouseEventHandler = (event) => { if (animate) { @@ -41,8 +49,11 @@ const triggerAnimation = (className: string) => { if (icon && iconElement) { iconElement.classList.remove(className); - void iconElement.offsetWidth; - iconElement.classList.add(className); + + // make sure we have DOM reflow + requestAnimationFrame(() => { + iconElement?.classList.add(className); + }); } }; @@ -76,7 +87,7 @@ {type} bind:this={ref} class={[ - 'button group relative flex gap-3 overflow-hidden rounded-sm px-5', + 'button group relative flex items-center gap-3 overflow-hidden rounded-sm px-5', 'text-sui-background cursor-pointer py-3 font-medium transition-colors', !loading ? ' bg-sui-primary hover:bg-sui-secondary' : 'bg-sui-primary/50 cursor-not-allowed ', classValue @@ -87,7 +98,7 @@ {@render children()} {#if icon && !loading} - {icon} + {/if} {#if loading} @@ -140,12 +151,12 @@ } } - :global(button span.animate) { + :global(button svg.animate) { animation-name: loop; animation-duration: 0.5s; } - :global(button span.bounce) { + :global(button svg.bounce) { animation-name: bounce; animation-duration: 180ms; animation-timing-function: ease-in-out; diff --git a/src/lib/Checkbox.svelte b/src/lib/Checkbox.svelte index 63d1ef4..3966a92 100644 --- a/src/lib/Checkbox.svelte +++ b/src/lib/Checkbox.svelte @@ -7,6 +7,7 @@ import { validate } from '@svelte-toolkit/validate'; import { generateIdentifier } from './util'; import type { ClassValue } from 'svelte/elements'; + import { Check, Minus } from 'phosphor-svelte'; interface Props { name?: string; @@ -31,6 +32,7 @@ let id = $derived(generateIdentifier('checkbox', name)); let valid = $state(true); + let Icon = $derived(value === 'indeterminate' ? Minus : value ? Check : undefined);
@@ -69,10 +71,8 @@ onchange?.(value); }} > - {#if value === 'indeterminate'} - remove - {:else if value === true} - check + {#if Icon} + {/if} diff --git a/src/lib/FramelessButton.svelte b/src/lib/FramelessButton.svelte index d67d235..4c856be 100644 --- a/src/lib/FramelessButton.svelte +++ b/src/lib/FramelessButton.svelte @@ -1,9 +1,10 @@ {#snippet iconSnippet()} - {icon} + {#if icon} + + {/if} {/snippet}
{/each} @@ -339,7 +341,7 @@ onclick={() => (index -= 1)} transition:fly={{ x: -200, duration: 200 }} > - arrow_back + Back {/if} diff --git a/src/lib/util.ts b/src/lib/util.ts index 6a0f124..0f14a6d 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -1,3 +1,22 @@ +import type { IconComponentProps } from 'phosphor-svelte'; +import type { Component } from 'svelte'; + +/** + * IconDef is an object that represents an icon element from the phosphor library, alongside an optional set of typed properties. + */ +export type IconDef = { + component: Component; + props?: IconComponentProps; +}; + +/** + * Defines a set of default properties for icons used in the application. + */ +export const defaultIconProps: IconComponentProps = { + size: '1.2rem', + weight: 'bold' +}; + /** * MaybeGetter is a type that can either be a value of type T or a function that returns a value of type T. * This is useful for cases where you might want to pass a value directly or a function that computes the diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 6d39b2b..e41a62a 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -21,6 +21,7 @@ import { ArrowUUpLeft, ArrowUUpRight, + Plus, TextB, TextItalic, TextStrikethrough, @@ -51,12 +52,14 @@

Button, Frameless Button, & Link

- - + - Click Me + Click Me Visit Svelte @@ -136,7 +139,7 @@