replace google material icons with phosphor icons
This commit is contained in:
@@ -13,12 +13,6 @@
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!-- Material Design Icons -->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
|
||||
@@ -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<HTMLButtonAttributes, 'class'> {
|
||||
icon?: string;
|
||||
icon?: IconDef;
|
||||
animate?: boolean;
|
||||
loading?: boolean;
|
||||
class?: ClassValue | null | undefined;
|
||||
@@ -25,7 +27,13 @@
|
||||
...others
|
||||
}: Props = $props();
|
||||
|
||||
let iconElement = $state<HTMLSpanElement | null>(null);
|
||||
type SVGInHTML = HTMLElement & SVGElement;
|
||||
let iconElement = $state<SVGInHTML | null>(null);
|
||||
$effect(() => {
|
||||
if (icon && ref) {
|
||||
iconElement = ref.querySelector('svg') as SVGInHTML | null;
|
||||
}
|
||||
});
|
||||
|
||||
const handleButtonClick: MouseEventHandler<HTMLButtonElement> = (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}
|
||||
<span class="material-symbols-outlined" bind:this={iconElement}>{icon}</span>
|
||||
<icon.component {...icon.props || defaultIconProps} />
|
||||
{/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;
|
||||
|
||||
@@ -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);
|
||||
</script>
|
||||
|
||||
<div class={['flex items-center', classValue]}>
|
||||
@@ -69,10 +71,8 @@
|
||||
onchange?.(value);
|
||||
}}
|
||||
>
|
||||
{#if value === 'indeterminate'}
|
||||
<span class="material-symbols-outlined">remove</span>
|
||||
{:else if value === true}
|
||||
<span class="material-symbols-outlined">check</span>
|
||||
{#if Icon}
|
||||
<Icon weight="bold" size="1.1em"></Icon>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ClassValue, MouseEventHandler } from 'svelte/elements';
|
||||
import { defaultIconProps, type IconDef } from './util';
|
||||
|
||||
interface Props {
|
||||
icon?: string;
|
||||
icon?: IconDef;
|
||||
iconPosition?: 'left' | 'right';
|
||||
disabled?: boolean;
|
||||
class?: ClassValue | null | undefined;
|
||||
@@ -22,7 +23,9 @@
|
||||
</script>
|
||||
|
||||
{#snippet iconSnippet()}
|
||||
<span class="material-symbols-outlined">{icon}</span>
|
||||
{#if icon}
|
||||
<icon.component {...icon.props || defaultIconProps} />
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
<button
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
| false
|
||||
| {
|
||||
text: string;
|
||||
icon: string;
|
||||
icon: IconDef;
|
||||
onclick?: MouseEventHandler<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
import { tweened } from 'svelte/motion';
|
||||
import { fade, fly } from 'svelte/transition';
|
||||
import { validateForm } from '@svelte-toolkit/validate';
|
||||
import { ArrowLeft, Check } from 'phosphor-svelte';
|
||||
import type { IconDef } from './util';
|
||||
|
||||
let {
|
||||
pages,
|
||||
@@ -321,7 +323,7 @@
|
||||
{#if i >= index}
|
||||
<span class="mb-[0.0625rem]">{i + 1}</span>
|
||||
{:else}
|
||||
<span class="material-symbols-outlined mt-0.5 text-2xl">check_small</span>
|
||||
<Check class="mt-0.5" size="1.5rem" weight="bold" />
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
@@ -339,7 +341,7 @@
|
||||
onclick={() => (index -= 1)}
|
||||
transition:fly={{ x: -200, duration: 200 }}
|
||||
>
|
||||
<span class="material-symbols-outlined text-base">arrow_back</span>
|
||||
<ArrowLeft />
|
||||
Back
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
import {
|
||||
ArrowUUpLeft,
|
||||
ArrowUUpRight,
|
||||
Plus,
|
||||
TextB,
|
||||
TextItalic,
|
||||
TextStrikethrough,
|
||||
@@ -51,12 +52,14 @@
|
||||
<div class="component">
|
||||
<p class="title">Button, Frameless Button, & Link</p>
|
||||
<div class="flex gap-4">
|
||||
<Button icon="add" loading={false} onclick={() => alert('Button clicked!')}>Click Me</Button>
|
||||
<Button icon="add" loading={true} onclick={() => alert('Button clicked!')}
|
||||
<Button icon={{ component: Plus }} loading={false} onclick={() => alert('Button clicked!')}
|
||||
>Click Me</Button
|
||||
>
|
||||
<Button icon={{ component: Plus }} loading={true} onclick={() => alert('Button clicked!')}
|
||||
>Loading Button</Button
|
||||
>
|
||||
|
||||
<FramelessButton icon="add">Click Me</FramelessButton>
|
||||
<FramelessButton icon={{ component: Plus }}>Click Me</FramelessButton>
|
||||
|
||||
<Link href="https://svelte.dev">Visit Svelte</Link>
|
||||
|
||||
@@ -136,7 +139,7 @@
|
||||
<DateInput bind:value={dateInputValue} />
|
||||
<div class="shrink-0">
|
||||
<Button
|
||||
icon="add"
|
||||
icon={{ component: Plus }}
|
||||
onclick={() => {
|
||||
dateInputValue = new Date();
|
||||
console.log('Dateinput value set to:', dateInputValue);
|
||||
|
||||
Reference in New Issue
Block a user