Skip to content

Commit

Permalink
feat: mark current <T> as legacy, new <T> uses snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryLie committed Nov 2, 2024
1 parent edaf7e2 commit 7d0c9f0
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 26 deletions.
69 changes: 69 additions & 0 deletions src/lib/LegacyT.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<script>
import { t } from '.';
import { run } from 'svelte/legacy';
/**
* @type {string}
*/
export let msg;
/**
* @type {string}
*/
export let ctx = undefined;
/**
* @type {string}
*/
export let cmt = undefined;
let strings;
run(() => {
strings = $t({
message: msg,
context: ctx,
comment: cmt
}).split('#');
if (strings.length > 6) {
console.error('svelte-i18n-lingui:', '<T> component can only have a maximum of 5 slots.');
}
// TODO: Other prop validations
//
// else if (strings.length < 2) {
// console.error(
// 'svelte-i18n-lingui:',
// '<T> component must only be used for interpolation and contain at least one # sign for slots.'
// );
// } else if (strings.length !== Object.keys($$slots).length + 1) {
// console.error(
// 'svelte-i18n-lingui:',
// "The number of slots on the message and the one passed in to the component dosent't match"
// );
// } else {
// strings.slice(1).forEach((str, i) => {
// if (i === 0 && $$slots.default) {
// console.error('abc');
// }
// });
// }
});
</script>

<!--
@component
A translation component used to support interpolation.
If there is no need to interleave elements or components inside a message,
the `t` store should be used instead for simplicity and consistency.
- Usage:
```svelte
<T msg="Click # for more information" ctx="if any" cmt="if any">
<a href="https://example.com">{$t`here`}`</a>
</T>
```
-->

<!-- Put in the same line to prevent automatic whtiespace insertion -->
{strings[0] ?? ''}<slot />{strings[1] ?? ''}<slot name="1" />{strings[2] ?? ''}<slot
name="2"
/>{strings[3] ?? ''}<slot name="3" />{strings[4] ?? ''}<slot name="4" />{strings[5] ?? ''}
File renamed without changes.
32 changes: 13 additions & 19 deletions src/lib/T.svelte
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
<!-- @migration-task Error while migrating Svelte code: This migration would change the name of a slot making the component unusable -->
<script>
import { t } from '.';
/**
* @type {string}
*/
export let msg;
/**
* @type {string}
*/
export let ctx = undefined;
/**
* @type {string}
* @typedef {import('svelte').Snippet} Snippet
*/
export let cmt = undefined;
let strings;
/** @type {{ msg: string, ctx?: string, cmt?: string, children?: Snippet, second?: Snippet, third?: Snippet, fourth?: Snippet, fifth?: Snippet }} */
let { msg, ctx, cmt, children, second, third, fourth, fifth } = $props();
$: {
strings = $t({
let strings = $derived(
$t({
message: msg,
context: ctx,
comment: cmt
}).split('#');
}).split('#')
);
$effect(() => {
if (strings.length > 6) {
console.error('svelte-i18n-lingui:', '<T> component can only have a maximum of 5 slots.');
}
Expand All @@ -46,7 +40,7 @@
// }
// });
// }
}
});
</script>

<!--
Expand All @@ -64,6 +58,6 @@ the `t` store should be used instead for simplicity and consistency.
-->

<!-- Put in the same line to prevent automatic whtiespace insertion -->
{strings[0] ?? ''}<slot />{strings[1] ?? ''}<slot name="1" />{strings[2] ?? ''}<slot
name="2"
/>{strings[3] ?? ''}<slot name="3" />{strings[4] ?? ''}<slot name="4" />{strings[5] ?? ''}
{strings[0] ?? ''}{@render children?.()}{strings[1] ?? ''}{@render second?.()}{strings[2] ??
''}{@render third?.()}{strings[3] ?? ''}{@render fourth?.()}{strings[4] ??
''}{@render fifth?.()}{strings[5] ?? ''}
30 changes: 30 additions & 0 deletions src/lib/T.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { it, expect } from 'vitest';
import { render, screen, cleanup } from '@testing-library/svelte';
import { messageCatalog } from '../helpers/test.js';

import T from './T.svelte';
import { locale } from '.';

it('When there are no translation catalog, show the message as-is', () => {
render(T, { msg: 'hello' });
expect(screen.getByText('hello')).toBeDefined();
});

it('When translation catalog is set, show the translated message', () => {
locale.set('ja', messageCatalog);
render(T, { msg: 'hello' });
expect(screen.getByText('こんにちは')).toBeDefined();
});

it('Respects context and ignores comment when set', () => {
render(T, { msg: 'right', ctx: 'direction' });
expect(screen.getByText('右')).toBeDefined();
cleanup();

render(T, { msg: 'right', ctx: 'correct' });
expect(screen.getByText('正しい')).toBeDefined();
cleanup();

render(T, { msg: 'right', ctx: 'correct', cmt: 'Comment for translator' });
expect(screen.getByText('正しい')).toBeDefined();
});
18 changes: 12 additions & 6 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { locale, t, msg, plural } from '$lib';
import { getText } from '../fixtures/random.ts';
import T from '$lib/T.svelte';
import LegacyT from '$lib/LegacyT.svelte';
import TestComponent from '../fixtures/TestComponent.svelte';
let { data } = $props();
Expand Down Expand Up @@ -84,7 +85,7 @@
Comment: {$t({ message: 'Commented message', comment: 'This is a comment for the translator' })}
</p>
<p>
Interpolation inside component:
Interpolation inside component:<br />
<T msg="Click # to learn more" ctx="ABC" cmt="Comment for translator">
<a href="https://svelte.dev/tutorial" target="_blank">{$t`Svelte tutorial`}</a>
</T>
Expand All @@ -94,16 +95,21 @@
</T>
<br />
<T msg="Click # here # to # learn # more #" ctx="ABC" cmt="Comment for translator">
<span>1</span>
{#snippet second()}2{/snippet}
{#snippet third()}3{/snippet}
{#snippet fourth()}4{/snippet}
{#snippet fifth()}5{/snippet}
</T>
<br />
Legacy T:
<LegacyT msg="Click # here # to # learn # more #" ctx="ABC" cmt="Comment for translator">
<span>0</span>
<!-- @migration-task: migrate this slot by hand, `1` is an invalid identifier -->
<span slot="1">1</span>
<!-- @migration-task: migrate this slot by hand, `2` is an invalid identifier -->
<span slot="2">2</span>
<!-- @migration-task: migrate this slot by hand, `3` is an invalid identifier -->
<span slot="3">3</span>
<!-- @migration-task: migrate this slot by hand, `4` is an invalid identifier -->
<span slot="4">4</span>
</T>
</LegacyT>
<br />
Whitespace test:
<T msg="Click # to learn more">{$t`hello`}</T><T msg="Click # to learn more">{$t`hello`}</T>
Expand Down
3 changes: 2 additions & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { svelteTesting } from '@testing-library/svelte/vite';

export default defineConfig({
plugins: [svelte({ hot: !process.env.VITEST })],
plugins: [svelte({ hot: !process.env.VITEST }), svelteTesting()],
test: {
globals: true,
environment: 'jsdom',
Expand Down

0 comments on commit 7d0c9f0

Please sign in to comment.