Skip to content

Commit

Permalink
feat: translations
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasm91 committed Jan 14, 2025
1 parent 24db697 commit 6707444
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 9 deletions.
18 changes: 16 additions & 2 deletions src/lib/components/CloseButton/CloseButton.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
<script lang="ts">
import IconButton from '$lib/components/IconButton/IconButton.svelte';
import { t } from '$lib/services/translation.svelte.js';
import type { CloseButtonProps } from '$lib/types.js';
import { mdiClose } from '@mdi/js';
const { size = 'medium', variant = 'ghost', ...restProps }: CloseButtonProps = $props();
const {
size = 'medium',
variant = 'ghost',
translations,
...restProps
}: CloseButtonProps = $props();
</script>

<IconButton {...restProps} icon={mdiClose} shape="round" {variant} {size} color="secondary" />
<IconButton
{...restProps}
icon={mdiClose}
shape="round"
{variant}
{size}
color="secondary"
title={t('close', translations)}
/>
6 changes: 3 additions & 3 deletions src/lib/components/Form/PasswordInput.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<script lang="ts">
import Input from '$lib/components/Form/Input.svelte';
import IconButton from '$lib/components/IconButton/IconButton.svelte';
import { t } from '$lib/services/translation.svelte.js';
import type { PasswordInputProps } from '$lib/types.js';
import { mdiEyeOffOutline, mdiEyeOutline } from '@mdi/js';
let {
value = $bindable<string>(),
showLabel = 'Show password',
hideLabel = 'Hide password',
translations,
isVisible = $bindable<boolean>(false),
color = 'secondary',
...props
Expand All @@ -24,7 +24,7 @@
class="m-1"
icon={isVisible ? mdiEyeOffOutline : mdiEyeOutline}
onclick={() => (isVisible = !isVisible)}
title={isVisible ? hideLabel : showLabel}
title={isVisible ? t('hidePassword', translations) : t('showPassword', translations)}
></IconButton>
{/if}
{/snippet}
Expand Down
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ export { default as ThemeSwitcher } from '$lib/components/ThemeSwitcher/ThemeSwi
export * from '$lib/services/theme.svelte.js';
export * from '$lib/types.js';
export * from '$lib/utilities/byte-units.js';
export * from '$lib/services/translation.svelte.js';
20 changes: 20 additions & 0 deletions src/lib/services/translation.svelte.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { TranslationProps } from '$lib/types.js';

const defaultTranslations = {
close: 'Close',
showPassword: 'Show password',
hidePassword: 'Hide password',
};

export type Translations = typeof defaultTranslations;

let translations = $state<Translations>(defaultTranslations);

export const translate = <T extends keyof Translations>(
key: T,
overrides?: TranslationProps<T>,
): string => overrides?.[key] ?? translations[key];
export const t = translate;
export const setTranslations = (newTranslations: Partial<Translations>) => {
translations = { ...defaultTranslations, ...newTranslations };
};
7 changes: 5 additions & 2 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Translations } from '$lib/services/translation.svelte.js';
import type { Snippet } from 'svelte';
import type {
HTMLAnchorAttributes,
Expand All @@ -20,6 +21,8 @@ export enum Theme {
Dark = 'dark',
}

export type TranslationProps<T extends keyof Translations> = { [K in T]?: string };

export type IconProps = {
icon: string;
title?: string;
Expand Down Expand Up @@ -56,6 +59,7 @@ export type CloseButtonProps = {
size?: Size;
variant?: Variants;
class?: string;
translations?: TranslationProps<'close'>;
} & ButtonOrAnchor;

export type IconButtonProps = ButtonBase & {
Expand Down Expand Up @@ -108,8 +112,7 @@ export type InputProps = BaseInputProps & {
};

export type PasswordInputProps = BaseInputProps & {
showLabel?: string;
hideLabel?: string;
translations?: TranslationProps<'showPassword' | 'hidePassword'>;
isVisible?: boolean;
};

Expand Down
3 changes: 3 additions & 0 deletions src/routes/components/close-button/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import filledExample from './FilledExample.svelte?raw';
import OutlineExample from './OutlineExample.svelte';
import outlineExample from './OutlineExample.svelte?raw';
import TranslationExample from './TranslationExample.svelte';
import translationExample from './TranslationExample.svelte?raw';
</script>

<ComponentPage name="CloseButton">
Expand All @@ -15,6 +17,7 @@
{ title: 'Basic', code: basicExample, component: BasicExample },
{ title: 'Outline', code: outlineExample, component: OutlineExample },
{ title: 'Filled', code: filledExample, component: FilledExample },
{ title: 'Translation', code: translationExample, component: TranslationExample },
]}
/>
</ComponentPage>
5 changes: 5 additions & 0 deletions src/routes/components/close-button/TranslationExample.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
import { CloseButton } from '@immich/ui';
</script>

<CloseButton translations={{ close: 'Close me' }} />
3 changes: 3 additions & 0 deletions src/routes/components/password-input/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import shapeExample from './ShapeExample.svelte?raw';
import SizeExample from './SizeExample.svelte';
import sizeExample from './SizeExample.svelte?raw';
import TranslationExample from './TranslationExample.svelte';
import translationExample from './TranslationExample.svelte?raw';
</script>

<ComponentPage name="PasswordInput">
Expand All @@ -19,6 +21,7 @@
{ title: 'States', code: basicExample, component: BasicExample },
{ title: 'Shapes', code: shapeExample, component: ShapeExample },
{ title: 'Sizes', code: sizeExample, component: SizeExample },
{ title: 'Translation', code: translationExample, component: TranslationExample },
]}
/>
</ComponentPage>
6 changes: 4 additions & 2 deletions src/routes/components/password-input/BasicExample.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<script lang="ts">
import { Stack, Field, PasswordInput } from '@immich/ui';
import { Field, PasswordInput, Stack } from '@immich/ui';
let value = $state('super-secret-password');
</script>

<Stack gap={4}>
<Field label="Empty">
<PasswordInput />
</Field>
<Field label="Password">
<PasswordInput value="super-secret-password" />
<PasswordInput bind:value />
</Field>
</Stack>
15 changes: 15 additions & 0 deletions src/routes/components/password-input/TranslationExample.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { Field, PasswordInput, Stack } from '@immich/ui';
</script>

<Stack gap={4}>
<Field label="Api Key">
<PasswordInput
value="super-secret-password"
translations={{
showPassword: 'Show Api key',
hidePassword: 'Hide Api key',
}}
/>
</Field>
</Stack>

0 comments on commit 6707444

Please sign in to comment.