chore(web): migration svelte 5 syntax (#13883)

This commit is contained in:
Alex
2024-11-14 08:43:25 -06:00
committed by GitHub
parent 9203a61709
commit 0b3742cf13
310 changed files with 6435 additions and 4176 deletions

View File

@@ -1,6 +1,4 @@
<script lang="ts" context="module">
import type { HTMLButtonAttributes, HTMLLinkAttributes } from 'svelte/elements';
<script lang="ts" module>
export type Color =
| 'primary'
| 'primary-inversed'
@@ -17,44 +15,47 @@
export type Size = 'tiny' | 'icon' | 'link' | 'sm' | 'base' | 'lg';
export type Rounded = 'lg' | '3xl' | 'full' | 'none';
export type Shadow = 'md' | false;
</script>
type BaseProps = {
class?: string;
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
type?: string;
href?: string;
color?: Color;
size?: Size;
rounded?: Rounded;
shadow?: Shadow;
fullwidth?: boolean;
border?: boolean;
};
class?: string;
children?: Snippet;
onclick?: (event: MouseEvent) => void;
onfocus?: () => void;
onblur?: () => void;
form?: string;
disabled?: boolean;
title?: string;
'aria-current'?: 'page' | 'step' | 'location' | 'date' | 'time' | undefined | null;
}
export type ButtonProps = HTMLButtonAttributes &
BaseProps & {
href?: never;
};
export type LinkProps = HTMLLinkAttributes &
BaseProps & {
type?: never;
};
export type Props = ButtonProps | LinkProps;
</script>
<script lang="ts">
type $$Props = Props;
export let type: $$Props['type'] = 'button';
export let href: $$Props['href'] = undefined;
export let color: Color = 'primary';
export let size: Size = 'base';
export let rounded: Rounded = '3xl';
export let shadow: Shadow = 'md';
export let fullwidth = false;
export let border = false;
let className = '';
export { className as class };
let {
type = 'button',
href = undefined,
color = 'primary',
size = 'base',
rounded = '3xl',
shadow = 'md',
fullwidth = false,
border = false,
class: className = '',
children,
onclick,
onfocus,
onblur,
...rest
}: Props = $props();
const colorClasses: Record<Color, string> = {
primary:
@@ -93,29 +94,31 @@
full: 'rounded-full',
};
$: computedClass = [
className,
colorClasses[color],
sizeClasses[size],
roundedClasses[rounded],
shadow === 'md' && 'shadow-md',
fullwidth && 'w-full',
border && 'border',
]
.filter(Boolean)
.join(' ');
let computedClass = $derived(
[
className,
colorClasses[color],
sizeClasses[size],
roundedClasses[rounded],
shadow === 'md' && 'shadow-md',
fullwidth && 'w-full',
border && 'border',
]
.filter(Boolean)
.join(' '),
);
</script>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<svelte:element
this={href ? 'a' : 'button'}
type={href ? undefined : type}
{href}
on:click
on:focus
on:blur
{onclick}
{onfocus}
{onblur}
class="inline-flex items-center justify-center transition-colors disabled:cursor-not-allowed disabled:opacity-60 disabled:pointer-events-none {computedClass}"
{...$$restProps}
{...rest}
>
<slot />
{@render children?.()}
</svelte:element>

View File

@@ -1,64 +1,64 @@
<script lang="ts" context="module">
import type { HTMLButtonAttributes, HTMLLinkAttributes } from 'svelte/elements';
<script lang="ts" module>
export type Color = 'transparent' | 'light' | 'dark' | 'gray' | 'primary' | 'opaque' | 'alert';
export type Padding = '1' | '2' | '3';
type BaseProps = {
icon: string;
title: string;
class?: string;
color?: Color;
padding?: Padding;
size?: string;
hideMobile?: true;
buttonSize?: string;
viewBox?: string;
};
export type ButtonProps = HTMLButtonAttributes &
BaseProps & {
href?: never;
};
export type LinkProps = HTMLLinkAttributes &
BaseProps & {
type?: never;
};
export type Props = ButtonProps | LinkProps;
</script>
<script lang="ts">
import Icon from '$lib/components/elements/icon.svelte';
type $$Props = Props;
export let type: $$Props['type'] = 'button';
export let href: $$Props['href'] = undefined;
export let icon: string;
export let color: Color = 'transparent';
export let title: string;
/**
* The padding of the button, used by the `p-{padding}` Tailwind CSS class.
*/
export let padding: Padding = '3';
/**
* Size of the button, used for a CSS value.
*/
export let size = '24';
export let hideMobile = false;
export let buttonSize: string | undefined = undefined;
/**
* viewBox attribute for the SVG icon.
*/
export let viewBox: string | undefined = undefined;
/**
* Override the default styling of the button for specific use cases, such as the icon color.
*/
let className = '';
export { className as class };
interface Props {
id?: string;
type?: string;
href?: string;
icon: string;
color?: Color;
title: string;
/**
* The padding of the button, used by the `p-{padding}` Tailwind CSS class.
*/
padding?: Padding;
/**
* Size of the button, used for a CSS value.
*/
size?: string;
hideMobile?: boolean;
buttonSize?: string | undefined;
/**
* viewBox attribute for the SVG icon.
*/
viewBox?: string | undefined;
class?: string;
'aria-hidden'?: boolean | undefined | null;
'aria-checked'?: 'true' | 'false' | undefined | null;
'aria-current'?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false' | undefined | null;
'aria-controls'?: string | undefined | null;
'aria-expanded'?: boolean;
'aria-haspopup'?: boolean;
tabindex?: number | undefined | null;
role?: string | undefined | null;
onclick: (e: MouseEvent) => void;
disabled?: boolean;
}
let {
type = 'button',
href = undefined,
icon,
color = 'transparent',
title,
padding = '3',
size = '24',
hideMobile = false,
buttonSize = undefined,
viewBox = undefined,
class: className = '',
onclick,
...rest
}: Props = $props();
const colorClasses: Record<Color, string> = {
transparent: 'bg-transparent hover:bg-[#d3d3d3] dark:text-immich-dark-fg',
@@ -77,12 +77,12 @@
'3': 'p-3',
};
$: colorClass = colorClasses[color];
$: mobileClass = hideMobile ? 'hidden sm:flex' : '';
$: paddingClass = paddingClasses[padding];
let colorClass = $derived(colorClasses[color]);
let mobileClass = $derived(hideMobile ? 'hidden sm:flex' : '');
let paddingClass = $derived(paddingClasses[padding]);
</script>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<svelte:element
this={href ? 'a' : 'button'}
type={href ? undefined : type}
@@ -91,8 +91,8 @@
style:width={buttonSize ? buttonSize + 'px' : ''}
style:height={buttonSize ? buttonSize + 'px' : ''}
class="flex place-content-center place-items-center rounded-full {colorClass} {paddingClass} transition-all disabled:cursor-default hover:dark:text-immich-dark-gray {className} {mobileClass}"
on:click
{...$$restProps}
{onclick}
{...rest}
>
<Icon path={icon} {size} ariaLabel={title} {viewBox} color="currentColor" />
</svelte:element>

View File

@@ -1,22 +1,25 @@
<script lang="ts" context="module">
<script lang="ts" module>
export type Color = 'transparent-primary' | 'transparent-gray';
type BaseProps = {
color?: Color;
};
export type Props = (LinkProps & BaseProps) | (ButtonProps & BaseProps);
</script>
<script lang="ts">
import Button, { type ButtonProps, type LinkProps } from '$lib/components/elements/buttons/button.svelte';
import Button from '$lib/components/elements/buttons/button.svelte';
import type { Snippet } from 'svelte';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type $$Props = Props;
interface Props {
href?: string;
color?: Color;
children?: Snippet;
onclick?: (e: MouseEvent) => void;
title?: string;
disabled?: boolean;
fullwidth?: boolean;
class?: string;
}
export let color: Color = 'transparent-gray';
let { color = 'transparent-gray', children, ...rest }: Props = $props();
</script>
<Button size="link" {color} shadow={false} rounded="lg" on:click {...$$restProps}>
<slot />
<Button size="link" {color} shadow={false} rounded="lg" {...rest}>
{@render children?.()}
</Button>

View File

@@ -2,13 +2,17 @@
import { t } from 'svelte-i18n';
import Button from './button.svelte';
/**
* Target for the skip link to move focus to.
*/
export let target: string = 'main';
export let text: string = $t('skip_to_content');
interface Props {
/**
* Target for the skip link to move focus to.
*/
target?: string;
text?: string;
}
let isFocused = false;
let { target = 'main', text = $t('skip_to_content') }: Props = $props();
let isFocused = $state(false);
const moveFocus = () => {
const targetEl = document.querySelector<HTMLElement>(target);
@@ -20,9 +24,9 @@
<Button
size={'sm'}
rounded="none"
on:click={moveFocus}
on:focus={() => (isFocused = true)}
on:blur={() => (isFocused = false)}
onclick={moveFocus}
onfocus={() => (isFocused = true)}
onblur={() => (isFocused = false)}
>
{text}
</Button>