mirror of
https://github.com/immich-app/immich.git
synced 2025-11-04 19:43:10 -05:00
fix(web): Prevent changing asset location triggering keyboard shortcuts (#21451)
fix(web): Prevent changing asset location triggering asset keyboard shortcuts
This commit is contained in:
parent
b3372064e0
commit
225af973c1
@ -1,18 +1,24 @@
|
|||||||
import NumberRangeInput from '$lib/components/shared-components/number-range-input.svelte';
|
import NumberRangeInput from '$lib/components/shared-components/number-range-input.svelte';
|
||||||
import { render, type RenderResult } from '@testing-library/svelte';
|
import { render, type RenderResult } from '@testing-library/svelte';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import type { Mock } from 'vitest';
|
||||||
|
|
||||||
describe('NumberRangeInput component', () => {
|
describe('NumberRangeInput component', () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
let sut: RenderResult<NumberRangeInput>;
|
let sut: RenderResult<NumberRangeInput>;
|
||||||
let input: HTMLInputElement;
|
let input: HTMLInputElement;
|
||||||
|
let onInput: Mock;
|
||||||
|
let onKeyDown: Mock;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
onInput = vi.fn();
|
||||||
|
onKeyDown = vi.fn();
|
||||||
sut = render(NumberRangeInput, {
|
sut = render(NumberRangeInput, {
|
||||||
id: '',
|
id: '',
|
||||||
min: -90,
|
min: -90,
|
||||||
max: 90,
|
max: 90,
|
||||||
onInput: () => {},
|
onInput,
|
||||||
|
onKeyDown,
|
||||||
});
|
});
|
||||||
input = sut.getByRole('spinbutton') as HTMLInputElement;
|
input = sut.getByRole('spinbutton') as HTMLInputElement;
|
||||||
});
|
});
|
||||||
@ -21,35 +27,55 @@ describe('NumberRangeInput component', () => {
|
|||||||
expect(input.value).toBe('');
|
expect(input.value).toBe('');
|
||||||
await sut.rerender({ value: 10 });
|
await sut.rerender({ value: 10 });
|
||||||
expect(input.value).toBe('10');
|
expect(input.value).toBe('10');
|
||||||
|
expect(onInput).not.toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('restricts minimum value', async () => {
|
it('restricts minimum value', async () => {
|
||||||
await user.type(input, '-91');
|
await user.type(input, '-91');
|
||||||
expect(input.value).toBe('-90');
|
expect(input.value).toBe('-90');
|
||||||
|
expect(onInput).toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('restricts maximum value', async () => {
|
it('restricts maximum value', async () => {
|
||||||
await user.type(input, '09990');
|
await user.type(input, '09990');
|
||||||
expect(input.value).toBe('90');
|
expect(input.value).toBe('90');
|
||||||
|
expect(onInput).toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows entering negative numbers', async () => {
|
it('allows entering negative numbers', async () => {
|
||||||
await user.type(input, '-10');
|
await user.type(input, '-10');
|
||||||
expect(input.value).toBe('-10');
|
expect(input.value).toBe('-10');
|
||||||
|
expect(onInput).toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows entering zero', async () => {
|
it('allows entering zero', async () => {
|
||||||
await user.type(input, '0');
|
await user.type(input, '0');
|
||||||
expect(input.value).toBe('0');
|
expect(input.value).toBe('0');
|
||||||
|
expect(onInput).toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows entering decimal numbers', async () => {
|
it('allows entering decimal numbers', async () => {
|
||||||
await user.type(input, '-0.09001');
|
await user.type(input, '-0.09001');
|
||||||
expect(input.value).toBe('-0.09001');
|
expect(input.value).toBe('-0.09001');
|
||||||
|
expect(onInput).toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ignores text input', async () => {
|
it('ignores text input', async () => {
|
||||||
await user.type(input, 'test');
|
await user.type(input, 'test');
|
||||||
expect(input.value).toBe('');
|
expect(input.value).toBe('');
|
||||||
|
expect(onInput).toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test', async () => {
|
||||||
|
await user.type(input, 'd');
|
||||||
|
expect(onInput).not.toHaveBeenCalled();
|
||||||
|
expect(onKeyDown).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -20,6 +20,10 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onKeyDown = (event: KeyboardEvent) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
const onPaste = (event: ClipboardEvent) => {
|
const onPaste = (event: ClipboardEvent) => {
|
||||||
const pastedText = event.clipboardData?.getData('text/plain');
|
const pastedText = event.clipboardData?.getData('text/plain');
|
||||||
if (!pastedText) {
|
if (!pastedText) {
|
||||||
@ -42,10 +46,10 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="immich-form-label" for="latitude-input-{id}">{$t('latitude')}</label>
|
<label class="immich-form-label" for="latitude-input-{id}">{$t('latitude')}</label>
|
||||||
<NumberRangeInput id="latitude-input-{id}" min={-90} max={90} {onInput} {onPaste} bind:value={lat} />
|
<NumberRangeInput id="latitude-input-{id}" min={-90} max={90} {onKeyDown} {onInput} {onPaste} bind:value={lat} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="immich-form-label" for="longitude-input-{id}">{$t('longitude')}</label>
|
<label class="immich-form-label" for="longitude-input-{id}">{$t('longitude')}</label>
|
||||||
<NumberRangeInput id="longitude-input-{id}" min={-180} max={180} {onInput} {onPaste} bind:value={lng} />
|
<NumberRangeInput id="longitude-input-{id}" min={-180} max={180} {onKeyDown} {onInput} {onPaste} bind:value={lng} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { clamp } from 'lodash-es';
|
import { clamp } from 'lodash-es';
|
||||||
import type { ClipboardEventHandler } from 'svelte/elements';
|
import type { ClipboardEventHandler, KeyboardEventHandler } from 'svelte/elements';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
@ -11,6 +11,7 @@
|
|||||||
value?: number;
|
value?: number;
|
||||||
onInput: (value: number | null) => void;
|
onInput: (value: number | null) => void;
|
||||||
onPaste?: ClipboardEventHandler<HTMLInputElement>;
|
onPaste?: ClipboardEventHandler<HTMLInputElement>;
|
||||||
|
onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@ -22,6 +23,7 @@
|
|||||||
value = $bindable(),
|
value = $bindable(),
|
||||||
onInput,
|
onInput,
|
||||||
onPaste = undefined,
|
onPaste = undefined,
|
||||||
|
onKeyDown = undefined,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
const oninput = () => {
|
const oninput = () => {
|
||||||
@ -48,4 +50,5 @@
|
|||||||
bind:value
|
bind:value
|
||||||
{oninput}
|
{oninput}
|
||||||
onpaste={onPaste}
|
onpaste={onPaste}
|
||||||
|
onkeydown={onKeyDown}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user