mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
chore(web): migrate CircleIconButton to @immich/ui IconButton (#18486)
* remove import and referenced file * first pass at replacing all CircleIconButtons * fix linting issues * fix combobox formatting issues * fix button context menu coloring * remove circle icon button from search history box * use theme switcher from UI lib * dark mode force the asset viewer icons * fix forced dark mode icons * dark mode memory viewer icons * fix: back button in memory viewer --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
d544053c67
commit
a02e1f5e7c
75 changed files with 822 additions and 556 deletions
|
|
@ -1,29 +0,0 @@
|
|||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { render, screen } from '@testing-library/svelte';
|
||||
|
||||
describe('CircleIconButton component', () => {
|
||||
it('should render as a button', () => {
|
||||
render(CircleIconButton, { icon: '', title: 'test' });
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toBeInTheDocument();
|
||||
expect(button).toHaveAttribute('type', 'button');
|
||||
expect(button).not.toHaveAttribute('href');
|
||||
expect(button).toHaveAttribute('title', 'test');
|
||||
});
|
||||
|
||||
it('should render as a link if href prop is set', () => {
|
||||
render(CircleIconButton, { props: { href: '/test', icon: '', title: 'test' } });
|
||||
const link = screen.getByRole('link');
|
||||
expect(link).toBeInTheDocument();
|
||||
expect(link).toHaveAttribute('href', '/test');
|
||||
expect(link).not.toHaveAttribute('type');
|
||||
});
|
||||
|
||||
it('should render icon inside button', () => {
|
||||
render(CircleIconButton, { icon: '', title: 'test' });
|
||||
const button = screen.getByRole('button');
|
||||
const icon = button.querySelector('svg');
|
||||
expect(icon).toBeInTheDocument();
|
||||
expect(icon).toHaveAttribute('aria-label', 'test');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type Color = 'transparent' | 'light' | 'dark' | 'red' | 'gray' | 'primary' | 'opaque' | 'alert' | 'neutral';
|
||||
export type Padding = '1' | '2' | '3';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
/**
|
||||
* Override the default styling of the button for specific use cases, such as the icon color.
|
||||
*/
|
||||
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',
|
||||
opaque: 'bg-transparent hover:bg-immich-bg/30 text-white hover:dark:text-white',
|
||||
light: 'bg-white hover:bg-[#d3d3d3]',
|
||||
red: 'text-red-400 bg-red-100 hover:bg-[#d3d3d3]',
|
||||
dark: 'bg-[#202123] hover:bg-[#d3d3d3]',
|
||||
alert: 'text-[#ff0000] hover:text-white',
|
||||
gray: 'bg-[#d3d3d3] hover:bg-[#e2e7e9] text-immich-dark-gray hover:text-black',
|
||||
neutral:
|
||||
'dark:bg-immich-dark-gray dark:text-gray-300 hover:dark:bg-immich-dark-gray/50 hover:dark:text-gray-300 bg-gray-200 text-gray-700 hover:bg-gray-300',
|
||||
primary:
|
||||
'bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 hover:dark:bg-immich-dark-primary/80 text-white dark:text-immich-dark-gray',
|
||||
};
|
||||
|
||||
const paddingClasses: Record<Padding, string> = {
|
||||
'1': 'p-1',
|
||||
'2': 'p-2',
|
||||
'3': 'p-3',
|
||||
};
|
||||
|
||||
let colorClass = $derived(colorClasses[color]);
|
||||
let mobileClass = $derived(hideMobile ? 'hidden sm:flex' : '');
|
||||
let paddingClass = $derived(paddingClasses[padding]);
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={href ? 'a' : 'button'}
|
||||
type={href ? undefined : type}
|
||||
{title}
|
||||
{href}
|
||||
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}"
|
||||
{onclick}
|
||||
{...rest}
|
||||
>
|
||||
<Icon path={icon} {size} ariaLabel={title} {viewBox} color="currentColor" />
|
||||
</svelte:element>
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { mdiClose, mdiMagnify } from '@mdi/js';
|
||||
import type { SearchOptions } from '$lib/utils/dipatch';
|
||||
import { mdiClose, mdiMagnify } from '@mdi/js';
|
||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { IconButton } from '@immich/ui';
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
|
|
@ -43,11 +43,13 @@
|
|||
? 'rounded-2xl'
|
||||
: 'rounded-t-lg'} bg-gray-200 p-2 dark:bg-immich-dark-gray gap-2 place-items-center h-full"
|
||||
>
|
||||
<CircleIconButton
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiMagnify}
|
||||
title={$t('search')}
|
||||
size="16"
|
||||
padding="2"
|
||||
aria-label={$t('search')}
|
||||
size="small"
|
||||
onclick={() => onSearch({ force: true })}
|
||||
/>
|
||||
<input
|
||||
|
|
@ -65,6 +67,14 @@
|
|||
</div>
|
||||
{/if}
|
||||
{#if name}
|
||||
<CircleIconButton icon={mdiClose} title={$t('clear_value')} size="16" padding="2" onclick={resetSearch} />
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
icon={mdiClose}
|
||||
aria-label={$t('clear_value')}
|
||||
size="small"
|
||||
onclick={resetSearch}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue