diff --git a/src/features/file/grid.tsx b/src/features/file/grid.tsx index b98b2a1..9dd0162 100644 --- a/src/features/file/grid.tsx +++ b/src/features/file/grid.tsx @@ -3,6 +3,7 @@ import { debounce, Mutation } from "~/utilities"; import { Column, GridApi as GridCompApi, Grid as GridComp } from "~/components/grid"; import { createDataSet, DataSetNode, DataSetRowNode } from "~/components/table"; import { SelectionItem } from "../selectable"; +import { useI18n } from "../i18n"; import css from "./grid.module.css" export type Entry = { key: string } & { [lang: string]: string }; @@ -29,12 +30,14 @@ const groupBy = (rows: DataSetRowNode[]) => { } export function Grid(props: { class?: string, rows: Entry[], locales: string[], api?: (api: GridApi) => any }) { + const { t } = useI18n(); + const rows = createMemo(() => createDataSet(props.rows, { group: { by: 'key', with: groupBy } })); const locales = createMemo(() => props.locales); const columns = createMemo[]>(() => [ { id: 'key', - label: 'Key', + label: t('feature.file.grid.key'), renderer: ({ value }) => value.split('.').at(-1), }, ...locales().map>(lang => ({ diff --git a/src/routes/(editor)/edit.tsx b/src/routes/(editor)/edit.tsx index f54b183..ff24889 100644 --- a/src/routes/(editor)/edit.tsx +++ b/src/routes/(editor)/edit.tsx @@ -10,6 +10,7 @@ import { Tab, Tabs } from "~/components/tabs"; import { isServer } from "solid-js/web"; import { Prompt, PromptApi } from "~/components/prompt"; import EditBlankImage from '~/assets/edit-blank.svg' +import { useI18n } from "~/features/i18n"; import css from "./edit.module.css"; const isInstalledPWA = !isServer && window.matchMedia('(display-mode: standalone)').matches; @@ -72,6 +73,7 @@ export default function Edit(props: ParentProps) { const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => { const filesContext = useFiles(); + const { t } = useI18n(); const tabs = createMemo(() => filesContext.files().map(({ key, handle }) => { const [api, setApi] = createSignal<(GridApi & { addLocale(locale: string): void })>(); @@ -234,18 +236,18 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => { }); const commands = { - open: createCommand('open folder', async () => { + open: createCommand(t('page.edit.command.open'), async () => { const directory = await window.showDirectoryPicker({ mode: 'readwrite' }); await filesContext.open(directory); }, { key: 'o', modifier: Modifier.Control }), - close: createCommand('close folder', async () => { + close: createCommand(t('page.edit.command.close'), async () => { filesContext.remove('__root__'); }), - closeTab: createCommand('close tab', async (id: string) => { + closeTab: createCommand(t('page.edit.command.closeTab'), async (id: string) => { filesContext.remove(id); }, { key: 'w', modifier: Modifier.Control | (isInstalledPWA ? Modifier.None : Modifier.Alt) }), - save: createCommand('save', async () => { + save: createCommand(t('page.edit.command.save'), async () => { await Promise.allSettled(mutatedData().map(async ([file, data]) => { // TODO :: add the newly created file to the known files list to that the save file picker is not shown again on subsequent saves const handle = file.existing ? file.handle : await window.showSaveFilePicker({ suggestedName: file.name, excludeAcceptAllOption: true, types: [{ description: 'JSON file', accept: { 'application/json': ['.json'] } }] }); @@ -257,7 +259,7 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => { stream.close(); })); }, { key: 's', modifier: Modifier.Control }), - saveAs: createCommand('save as', (handle?: FileSystemFileHandle) => { + saveAs: createCommand(t('page.edit.command.saveAs'), (handle?: FileSystemFileHandle) => { console.log('save as ...', handle); window.showSaveFilePicker({ @@ -271,13 +273,13 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => { }); }, { key: 's', modifier: Modifier.Control | Modifier.Shift }), - selectAll: createCommand('select all', () => { + selectAll: createCommand(t('page.edit.command.selectAll'), () => { api()?.selectAll(); }, { key: 'a', modifier: Modifier.Control }), - clearSelection: createCommand('clear selection', () => { + clearSelection: createCommand(t('page.edit.command.clearSelection'), () => { api()?.clearSelection(); }), - delete: createCommand('delete selected items', () => { + delete: createCommand(t('page.edit.command.delete'), () => { const { selection, remove } = api() ?? {}; if (!selection || !remove) { @@ -286,7 +288,7 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => { remove(selection().map(s => s.key)); }, { key: 'delete', modifier: Modifier.None }), - inserNewKey: createCommand('insert new key', async () => { + insertKey: createCommand(t('page.edit.command.insertKey'), async () => { const formData = await newKeyPrompt()?.showModal(); const key = formData?.get('key')?.toString(); @@ -296,7 +298,7 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => { api()?.addKey(key); }), - inserNewLanguage: createCommand('insert new language', async () => { + insertLanguage: createCommand(t('page.edit.command.insertLanguage'), async () => { const formData = await newLanguagePrompt()?.showModal(); const locale = formData?.get('locale')?.toString(); @@ -316,27 +318,27 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => { } - + - + - + - - + + - + - + diff --git a/src/routes/(editor)/welcome.module.css b/src/routes/(editor)/welcome.module.css index a0e4468..0d6c5d2 100644 --- a/src/routes/(editor)/welcome.module.css +++ b/src/routes/(editor)/welcome.module.css @@ -8,11 +8,14 @@ grid: 3em / repeat(5, 3em); } + & > h1 { + margin-block-end: 0; + } + ul { display: flex; flex-flow: column; gap: var(--padding-s); padding-inline-start: var(--padding-l); - margin: 0; } } \ No newline at end of file diff --git a/src/routes/(editor)/welcome.tsx b/src/routes/(editor)/welcome.tsx index 4fe6e06..798b0b3 100644 --- a/src/routes/(editor)/welcome.tsx +++ b/src/routes/(editor)/welcome.tsx @@ -1,19 +1,21 @@ import { A } from "@solidjs/router"; import LandingImage from '../../assets/landing.svg' import css from "./welcome.module.css"; +import { useI18n } from "~/features/i18n"; export default function Welcome() { + const { t } = useI18n(); + return
-

Hi, welcome!

- Lets get started +

{t('page.welcome.title')}

+ {t('page.welcome.subtitle')}
; } diff --git a/src/routes/editor.module.css b/src/routes/editor.module.css index df2e722..bd91cc6 100644 --- a/src/routes/editor.module.css +++ b/src/routes/editor.module.css @@ -77,8 +77,9 @@ } & > dialog { - inset-inline-end: anchor(right); - inset-block-start: anchor(bottom); + inset-inline-start: anchor(start); + inset-block-start: anchor(end); + position-try-fallbacks: flip-inline; padding: var(--padding-m); border: none;