@geenius/i18n 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/config.json +11 -0
- package/.github/CODEOWNERS +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +11 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +10 -0
- package/.github/dependabot.yml +11 -0
- package/.github/workflows/ci.yml +23 -0
- package/.github/workflows/release.yml +29 -0
- package/.nvmrc +1 -0
- package/.project/ACCOUNT.yaml +4 -0
- package/.project/IDEAS.yaml +7 -0
- package/.project/PROJECT.yaml +11 -0
- package/.project/ROADMAP.yaml +15 -0
- package/CHANGELOG.md +8 -0
- package/CODE_OF_CONDUCT.md +16 -0
- package/CONTRIBUTING.md +26 -0
- package/LICENSE +2 -0
- package/README.md +1 -0
- package/SECURITY.md +15 -0
- package/SUPPORT.md +8 -0
- package/package.json +75 -0
- package/packages/convex/package.json +42 -0
- package/packages/convex/src/index.ts +3 -0
- package/packages/convex/src/mutations.ts +65 -0
- package/packages/convex/src/queries.ts +54 -0
- package/packages/convex/src/schema.ts +26 -0
- package/packages/convex/tsconfig.json +18 -0
- package/packages/convex/tsup.config.ts +17 -0
- package/packages/react/README.md +1 -0
- package/packages/react/package.json +51 -0
- package/packages/react/src/components/index.tsx +87 -0
- package/packages/react/src/hooks/index.ts +4 -0
- package/packages/react/src/hooks/useI18n.tsx +50 -0
- package/packages/react/src/hooks/useI18nAdmin.ts +12 -0
- package/packages/react/src/hooks/useLocaleDetect.ts +10 -0
- package/packages/react/src/hooks/useTranslations.ts +11 -0
- package/packages/react/src/index.tsx +8 -0
- package/packages/react/src/pages/I18nAdminPage.tsx +42 -0
- package/packages/react/src/pages/LocalePreviewPage.tsx +54 -0
- package/packages/react/src/pages/index.ts +2 -0
- package/packages/react/tsconfig.json +19 -0
- package/packages/react/tsup.config.ts +12 -0
- package/packages/react-css/README.md +1 -0
- package/packages/react-css/package.json +36 -0
- package/packages/react-css/src/components/index.tsx +66 -0
- package/packages/react-css/src/hooks/index.ts +4 -0
- package/packages/react-css/src/index.tsx +4 -0
- package/packages/react-css/src/pages/LocaleSettingsPage.tsx +74 -0
- package/packages/react-css/src/pages/TranslationsPage.tsx +98 -0
- package/packages/react-css/src/styles.css +210 -0
- package/packages/react-css/tsconfig.json +19 -0
- package/packages/react-css/tsup.config.ts +10 -0
- package/packages/shared/README.md +1 -0
- package/packages/shared/package.json +44 -0
- package/packages/shared/src/__tests__/i18n.test.ts +78 -0
- package/packages/shared/src/config.ts +344 -0
- package/packages/shared/src/index.ts +106 -0
- package/packages/shared/src/types.ts +51 -0
- package/packages/shared/tsconfig.json +18 -0
- package/packages/shared/tsup.config.ts +11 -0
- package/packages/shared/vitest.config.ts +4 -0
- package/packages/solidjs/README.md +1 -0
- package/packages/solidjs/package.json +47 -0
- package/packages/solidjs/src/components/LocaleCard.tsx +44 -0
- package/packages/solidjs/src/components/LocaleStatsCard.tsx +35 -0
- package/packages/solidjs/src/components/LocaleSwitcher.tsx +65 -0
- package/packages/solidjs/src/components/MissingKeyAlert.tsx +21 -0
- package/packages/solidjs/src/components/RTLWrapper.tsx +13 -0
- package/packages/solidjs/src/components/TranslationKeyRow.tsx +41 -0
- package/packages/solidjs/src/components/index.ts +6 -0
- package/packages/solidjs/src/index.tsx +8 -0
- package/packages/solidjs/src/pages/I18nAdminPage.tsx +188 -0
- package/packages/solidjs/src/pages/LocalePreviewPage.tsx +99 -0
- package/packages/solidjs/src/pages/index.ts +2 -0
- package/packages/solidjs/src/primitives/I18nProvider.tsx +56 -0
- package/packages/solidjs/src/primitives/createI18nAdmin.ts +7 -0
- package/packages/solidjs/src/primitives/createLocaleDetect.ts +8 -0
- package/packages/solidjs/src/primitives/createTranslations.ts +22 -0
- package/packages/solidjs/src/primitives/index.ts +4 -0
- package/packages/solidjs/tsconfig.json +20 -0
- package/packages/solidjs/tsup.config.ts +12 -0
- package/packages/solidjs-css/README.md +1 -0
- package/packages/solidjs-css/package.json +33 -0
- package/packages/solidjs-css/src/components/LocaleCard.tsx +45 -0
- package/packages/solidjs-css/src/components/LocaleStatsCard.tsx +43 -0
- package/packages/solidjs-css/src/components/LocaleSwitcher.tsx +51 -0
- package/packages/solidjs-css/src/components/MissingKeyAlert.tsx +24 -0
- package/packages/solidjs-css/src/components/RTLWrapper.tsx +16 -0
- package/packages/solidjs-css/src/components/TranslationKeyRow.tsx +47 -0
- package/packages/solidjs-css/src/components/index.ts +6 -0
- package/packages/solidjs-css/src/i18n.css +1322 -0
- package/packages/solidjs-css/src/index.tsx +3 -0
- package/packages/solidjs-css/src/pages/I18nAdminPage.tsx +134 -0
- package/packages/solidjs-css/src/pages/LocalePreviewPage.tsx +116 -0
- package/packages/solidjs-css/src/pages/index.ts +2 -0
- package/packages/solidjs-css/src/primitives/index.ts +1 -0
- package/packages/solidjs-css/tsconfig.json +20 -0
- package/packages/solidjs-css/tsup.config.bundled_dcjc4sct21j.mjs +18 -0
- package/packages/solidjs-css/tsup.config.ts +14 -0
- package/pnpm-workspace.yaml +2 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Show } from 'solid-js'
|
|
2
|
+
import type { Component } from 'solid-js'
|
|
3
|
+
import type { Locale } from '@geenius-i18n/shared'
|
|
4
|
+
import { LOCALE_INFO } from '@geenius-i18n/shared'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale: Locale
|
|
8
|
+
coverage: number
|
|
9
|
+
isSelected: boolean
|
|
10
|
+
onSelect: (l: Locale) => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const LocaleCard: Component<Props> = (props) => {
|
|
14
|
+
const info = () => LOCALE_INFO[props.locale]
|
|
15
|
+
const barModifier = () =>
|
|
16
|
+
props.coverage >= 90 ? 'i18n__locale-card-bar-fill--complete'
|
|
17
|
+
: props.coverage >= 70 ? 'i18n__locale-card-bar-fill--partial'
|
|
18
|
+
: 'i18n__locale-card-bar-fill--low'
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<button
|
|
22
|
+
type="button"
|
|
23
|
+
class={`i18n__locale-card${props.isSelected ? ' i18n__locale-card--selected' : ''}`}
|
|
24
|
+
onClick={() => props.onSelect(props.locale)}
|
|
25
|
+
>
|
|
26
|
+
<div class="i18n__locale-card-header">
|
|
27
|
+
<span class="i18n__locale-card-flag">{info()?.flag}</span>
|
|
28
|
+
<div class="i18n__locale-card-info">
|
|
29
|
+
<span class="i18n__locale-card-name">{info()?.nativeName}</span>
|
|
30
|
+
<span class="i18n__locale-card-code">{info()?.name} — {props.locale.toUpperCase()}</span>
|
|
31
|
+
</div>
|
|
32
|
+
<Show when={info()?.direction === 'rtl'}>
|
|
33
|
+
<span class="i18n__locale-card-rtl">RTL</span>
|
|
34
|
+
</Show>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="i18n__locale-card-bar">
|
|
37
|
+
<div
|
|
38
|
+
class={`i18n__locale-card-bar-fill ${barModifier()}`}
|
|
39
|
+
style={{ width: `${props.coverage}%` }}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
<span class="i18n__locale-card-coverage">{props.coverage}%</span>
|
|
43
|
+
</button>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Show } from 'solid-js'
|
|
2
|
+
import type { Component } from 'solid-js'
|
|
3
|
+
import type { LocaleStat } from '@geenius-i18n/shared'
|
|
4
|
+
import { LOCALE_INFO } from '@geenius-i18n/shared'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
stat: LocaleStat
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const LocaleStatsCard: Component<Props> = (props) => {
|
|
11
|
+
const info = () => LOCALE_INFO[props.stat.locale]
|
|
12
|
+
const barModifier = () =>
|
|
13
|
+
props.stat.coverage >= 90 ? 'i18n__stats-card-bar-fill--complete'
|
|
14
|
+
: props.stat.coverage >= 70 ? 'i18n__stats-card-bar-fill--partial'
|
|
15
|
+
: 'i18n__stats-card-bar-fill--low'
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div class="i18n__stats-card">
|
|
19
|
+
<div class="i18n__stats-card-header">
|
|
20
|
+
<span class="i18n__stats-card-flag">{info()?.flag}</span>
|
|
21
|
+
<span class="i18n__stats-card-locale">{info()?.nativeName}</span>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="i18n__stats-card-coverage">
|
|
24
|
+
<span class="i18n__stats-card-keys">{props.stat.totalKeys} keys</span>
|
|
25
|
+
<span class="i18n__stats-card-percent">{props.stat.coverage}%</span>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="i18n__stats-card-bar">
|
|
28
|
+
<div
|
|
29
|
+
class={`i18n__stats-card-bar-fill ${barModifier()}`}
|
|
30
|
+
style={{ width: `${props.stat.coverage}%` }}
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="i18n__stats-card-counts">
|
|
34
|
+
<Show when={props.stat.missingKeys > 0}>
|
|
35
|
+
<span class="i18n__stats-card-missing">{props.stat.missingKeys} missing</span>
|
|
36
|
+
</Show>
|
|
37
|
+
<Show when={props.stat.missingKeys === 0}>
|
|
38
|
+
<span class="i18n__stats-card-complete">Complete</span>
|
|
39
|
+
</Show>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createSignal, Show, For } from 'solid-js'
|
|
2
|
+
import type { Component } from 'solid-js'
|
|
3
|
+
import type { Locale } from '@geenius-i18n/shared'
|
|
4
|
+
import { LOCALE_INFO } from '@geenius-i18n/shared'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locales: Locale[]
|
|
8
|
+
current: Locale
|
|
9
|
+
onChange: (l: Locale) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const LocaleSwitcher: Component<Props> = (props) => {
|
|
13
|
+
const [open, setOpen] = createSignal(false)
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div class="i18n__locale-switcher">
|
|
17
|
+
<button
|
|
18
|
+
type="button"
|
|
19
|
+
class="i18n__locale-switcher-trigger"
|
|
20
|
+
onClick={() => setOpen((o) => !o)}
|
|
21
|
+
>
|
|
22
|
+
<span class="i18n__locale-switcher-flag">{LOCALE_INFO[props.current]?.flag}</span>
|
|
23
|
+
<span class="i18n__locale-switcher-label">{LOCALE_INFO[props.current]?.nativeName}</span>
|
|
24
|
+
<span class="i18n__locale-switcher-arrow">▾</span>
|
|
25
|
+
</button>
|
|
26
|
+
|
|
27
|
+
<Show when={open()}>
|
|
28
|
+
<div class="i18n__locale-switcher-dropdown">
|
|
29
|
+
<For each={props.locales}>
|
|
30
|
+
{(locale) => {
|
|
31
|
+
const info = LOCALE_INFO[locale]
|
|
32
|
+
return (
|
|
33
|
+
<button
|
|
34
|
+
type="button"
|
|
35
|
+
class={`i18n__locale-switcher-option${locale === props.current ? ' i18n__locale-switcher-option--active' : ''}`}
|
|
36
|
+
onClick={() => { props.onChange(locale); setOpen(false) }}
|
|
37
|
+
>
|
|
38
|
+
<span class="i18n__locale-switcher-option-flag">{info?.flag}</span>
|
|
39
|
+
<span class="i18n__locale-switcher-option-name">{info?.nativeName}</span>
|
|
40
|
+
<Show when={info?.direction === 'rtl'}>
|
|
41
|
+
<span class="i18n__locale-switcher-option-rtl">RTL</span>
|
|
42
|
+
</Show>
|
|
43
|
+
</button>
|
|
44
|
+
)
|
|
45
|
+
}}
|
|
46
|
+
</For>
|
|
47
|
+
</div>
|
|
48
|
+
</Show>
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Show } from 'solid-js'
|
|
2
|
+
import type { Component } from 'solid-js'
|
|
3
|
+
import type { Locale } from '@geenius-i18n/shared'
|
|
4
|
+
import { LOCALE_INFO } from '@geenius-i18n/shared'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
count: number
|
|
8
|
+
locale: Locale
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const MissingKeyAlert: Component<Props> = (props) => {
|
|
12
|
+
return (
|
|
13
|
+
<Show when={props.count > 0}>
|
|
14
|
+
<div class="i18n__missing-alert">
|
|
15
|
+
<span class="i18n__missing-alert-icon">⚠️</span>
|
|
16
|
+
<span class="i18n__missing-alert-text">
|
|
17
|
+
<span class="i18n__missing-alert-count">{props.count}</span>
|
|
18
|
+
{' '}missing key{props.count > 1 ? 's' : ''} for{' '}
|
|
19
|
+
<strong>{LOCALE_INFO[props.locale]?.name}</strong>
|
|
20
|
+
</span>
|
|
21
|
+
</div>
|
|
22
|
+
</Show>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ParentComponent } from 'solid-js'
|
|
2
|
+
import type { Locale } from '@geenius-i18n/shared'
|
|
3
|
+
import { LOCALE_INFO } from '@geenius-i18n/shared'
|
|
4
|
+
|
|
5
|
+
export const RTLWrapper: ParentComponent<{ locale?: Locale }> = (props) => {
|
|
6
|
+
const dir = () => props.locale ? LOCALE_INFO[props.locale]?.direction ?? 'ltr' : 'ltr'
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
class={`i18n__rtl-wrapper i18n__rtl-wrapper--${dir()}`}
|
|
11
|
+
dir={dir()}
|
|
12
|
+
>
|
|
13
|
+
{props.children}
|
|
14
|
+
</div>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Show } from 'solid-js'
|
|
2
|
+
import type { Component } from 'solid-js'
|
|
3
|
+
import type { Locale } from '@geenius-i18n/shared'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
translationKey: string
|
|
7
|
+
value: string
|
|
8
|
+
locale: Locale
|
|
9
|
+
namespace?: string
|
|
10
|
+
onEdit?: (key: string, value: string) => void
|
|
11
|
+
onDelete?: (key: string) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const TranslationKeyRow: Component<Props> = (props) => {
|
|
15
|
+
return (
|
|
16
|
+
<div class="i18n__key-row">
|
|
17
|
+
<div class="i18n__key-row-key">{props.translationKey}</div>
|
|
18
|
+
<div class="i18n__key-row-value">{props.value}</div>
|
|
19
|
+
<div class="i18n__key-row-locale">
|
|
20
|
+
<span class="i18n__key-row-locale-badge">{props.locale.toUpperCase()}</span>
|
|
21
|
+
<Show when={props.namespace}>
|
|
22
|
+
<span class="i18n__key-row-namespace">{props.namespace}</span>
|
|
23
|
+
</Show>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="i18n__key-row-actions">
|
|
26
|
+
<Show when={props.onEdit}>
|
|
27
|
+
<button
|
|
28
|
+
type="button"
|
|
29
|
+
class="i18n__key-row-btn i18n__key-row-btn--edit"
|
|
30
|
+
onClick={() => props.onEdit?.(props.translationKey, props.value)}
|
|
31
|
+
>
|
|
32
|
+
Edit
|
|
33
|
+
</button>
|
|
34
|
+
</Show>
|
|
35
|
+
<Show when={props.onDelete}>
|
|
36
|
+
<button
|
|
37
|
+
type="button"
|
|
38
|
+
class="i18n__key-row-btn i18n__key-row-btn--delete"
|
|
39
|
+
onClick={() => props.onDelete?.(props.translationKey)}
|
|
40
|
+
>
|
|
41
|
+
Delete
|
|
42
|
+
</button>
|
|
43
|
+
</Show>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { LocaleSwitcher } from './LocaleSwitcher'
|
|
2
|
+
export { RTLWrapper } from './RTLWrapper'
|
|
3
|
+
export { LocaleStatsCard } from './LocaleStatsCard'
|
|
4
|
+
export { MissingKeyAlert } from './MissingKeyAlert'
|
|
5
|
+
export { TranslationKeyRow } from './TranslationKeyRow'
|
|
6
|
+
export { LocaleCard } from './LocaleCard'
|