@asafarim/shared-i18n 0.6.6 → 0.8.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/demo/dist/Icon Dropdown_Limited Languages.png +0 -0
- package/demo/dist/Select Dropdown_Text Only.png +0 -0
- package/demo/dist/assets/favicon-BZYZvBLo.svg +4 -0
- package/demo/dist/assets/index-BdjqKw_N.css +1 -0
- package/demo/dist/assets/index-C1Tq1uEr.js +191 -0
- package/demo/dist/favicon.svg +4 -0
- package/demo/dist/index.html +27 -0
- package/demo/dist/logo.svg +24 -0
- package/demo/node_modules/.bin/browserslist +21 -0
- package/demo/node_modules/.bin/browserslist.CMD +12 -0
- package/demo/node_modules/.bin/browserslist.ps1 +41 -0
- package/demo/node_modules/.bin/tsc +4 -4
- package/demo/node_modules/.bin/tsc.CMD +12 -0
- package/demo/node_modules/.bin/tsc.ps1 +41 -0
- package/demo/node_modules/.bin/tsserver +4 -4
- package/demo/node_modules/.bin/tsserver.CMD +12 -0
- package/demo/node_modules/.bin/tsserver.ps1 +41 -0
- package/demo/node_modules/.bin/vite +4 -4
- package/demo/node_modules/.bin/vite.CMD +12 -0
- package/demo/node_modules/.bin/vite.ps1 +41 -0
- package/demo/node_modules/.vite/deps/@asafarim_country-language-selector.js +848 -0
- package/demo/node_modules/.vite/deps/@asafarim_country-language-selector.js.map +7 -0
- package/demo/node_modules/.vite/deps/_metadata.json +76 -0
- package/demo/node_modules/.vite/deps/chunk-5WRI5ZAA.js +30 -0
- package/demo/node_modules/.vite/deps/chunk-5WRI5ZAA.js.map +7 -0
- package/demo/node_modules/.vite/deps/chunk-B3AHR5EX.js +1004 -0
- package/demo/node_modules/.vite/deps/chunk-B3AHR5EX.js.map +7 -0
- package/demo/node_modules/.vite/deps/chunk-E6BG6WAU.js +292 -0
- package/demo/node_modules/.vite/deps/chunk-E6BG6WAU.js.map +7 -0
- package/demo/node_modules/.vite/deps/chunk-MVARZQEG.js +280 -0
- package/demo/node_modules/.vite/deps/chunk-MVARZQEG.js.map +7 -0
- package/demo/node_modules/.vite/deps/i18next-browser-languagedetector.js +400 -0
- package/demo/node_modules/.vite/deps/i18next-browser-languagedetector.js.map +7 -0
- package/demo/node_modules/.vite/deps/i18next.js +2392 -0
- package/demo/node_modules/.vite/deps/i18next.js.map +7 -0
- package/demo/node_modules/.vite/deps/package.json +3 -0
- package/demo/node_modules/.vite/deps/react-dom.js +6 -0
- package/demo/node_modules/.vite/deps/react-dom.js.map +7 -0
- package/demo/node_modules/.vite/deps/react-dom_client.js +20217 -0
- package/demo/node_modules/.vite/deps/react-dom_client.js.map +7 -0
- package/demo/node_modules/.vite/deps/react-i18next.js +869 -0
- package/demo/node_modules/.vite/deps/react-i18next.js.map +7 -0
- package/demo/node_modules/.vite/deps/react.js +5 -0
- package/demo/node_modules/.vite/deps/react.js.map +7 -0
- package/demo/node_modules/.vite/deps/react_jsx-dev-runtime.js +278 -0
- package/demo/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +7 -0
- package/demo/node_modules/.vite/deps/react_jsx-runtime.js +6 -0
- package/demo/node_modules/.vite/deps/react_jsx-runtime.js.map +7 -0
- package/demo/package.json +27 -24
- package/demo/public/favicon.svg +4 -4
- package/demo/public/logo.svg +24 -24
- package/demo/src/App.tsx +129 -116
- package/demo/src/components/CountryLanguageDemo.tsx +140 -0
- package/demo/src/components/GetStartedSection.tsx +56 -56
- package/demo/src/components/KeyTable.tsx +29 -29
- package/demo/src/components/LanguageBar.tsx +102 -18
- package/demo/src/components/LanguageSwitcherDemo.module.css +114 -113
- package/demo/src/components/LanguageSwitcherDemo.tsx +256 -202
- package/demo/src/components/Logo.tsx +6 -6
- package/demo/src/components/OverviewSection.tsx +43 -43
- package/demo/src/components/Panel.tsx +15 -15
- package/demo/src/components/StatusCard.tsx +109 -109
- package/demo/src/index.css +644 -605
- package/demo/src/locales/de/demo.json +85 -0
- package/demo/src/locales/en/demo.json +85 -85
- package/demo/src/locales/fr/demo.json +85 -85
- package/demo/src/locales/it/demo.json +85 -0
- package/demo/src/locales/nl/demo.json +85 -85
- package/demo/src/main.tsx +29 -24
- package/demo/tsconfig.json +18 -18
- package/demo/tsconfig.node.json +10 -10
- package/demo/tsconfig.tsbuildinfo +1 -1
- package/demo/vite-env.d.ts +7 -7
- package/demo/vite.config.d.ts +2 -2
- package/demo/vite.config.js +10 -10
- package/dist/components/LanguageSwitcher.module.css +303 -303
- package/dist/locales/de/common.json +68 -0
- package/dist/locales/it/common.json +68 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +85 -84
package/demo/public/logo.svg
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
-
<stop offset="0%" stop-color="#3A5AFE" />
|
|
5
|
-
<stop offset="100%" stop-color="#14B8A6" />
|
|
6
|
-
</linearGradient>
|
|
7
|
-
<linearGradient id="accent" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
8
|
-
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="0.9" />
|
|
9
|
-
<stop offset="100%" stop-color="#FFFFFF" stop-opacity="0.2" />
|
|
10
|
-
</linearGradient>
|
|
11
|
-
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%" color-interpolation-filters="sRGB">
|
|
12
|
-
<feDropShadow dx="0" dy="8" stdDeviation="12" flood-color="#0B1220" flood-opacity="0.28" />
|
|
13
|
-
</filter>
|
|
14
|
-
</defs>
|
|
15
|
-
<rect width="180" height="180" rx="32" fill="url(#bg)" filter="url(#shadow)" />
|
|
16
|
-
<g transform="translate(45 45)">
|
|
17
|
-
<path d="M45 0C20.147 0 0 20.147 0 45C0 69.853 20.147 90 45 90C69.853 90 90 69.853 90 45C90 20.147 69.853 0 45 0ZM45 72C29.088 72 15.75 58.662 15.75 42.75C15.75 26.838 29.088 13.5 45 13.5C60.912 13.5 74.25 26.838 74.25 42.75C74.25 58.662 60.912 72 45 72Z" fill="white" opacity="0.2" />
|
|
18
|
-
<path d="M24 27H66C70.971 27 75 31.029 75 36V54C75 58.971 70.971 63 66 63H24C19.029 63 15 58.971 15 54V36C15 31.029 19.029 27 24 27Z" fill="url(#accent)" />
|
|
19
|
-
<path d="M36 54V45C36 40.029 40.029 36 45 36C49.971 36 54 40.029 54 45V54" stroke="#0B1220" stroke-width="4" stroke-linecap="round" />
|
|
20
|
-
<circle cx="45" cy="21" r="6" fill="white" />
|
|
21
|
-
<path d="M33 69H57" stroke="white" stroke-width="4" stroke-linecap="round" opacity="0.7" />
|
|
22
|
-
<path d="M27 15H63" stroke="white" stroke-width="4" stroke-linecap="round" opacity="0.4" />
|
|
23
|
-
</g>
|
|
24
|
-
</svg>
|
|
1
|
+
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#3A5AFE" />
|
|
5
|
+
<stop offset="100%" stop-color="#14B8A6" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="accent" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
8
|
+
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="0.9" />
|
|
9
|
+
<stop offset="100%" stop-color="#FFFFFF" stop-opacity="0.2" />
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%" color-interpolation-filters="sRGB">
|
|
12
|
+
<feDropShadow dx="0" dy="8" stdDeviation="12" flood-color="#0B1220" flood-opacity="0.28" />
|
|
13
|
+
</filter>
|
|
14
|
+
</defs>
|
|
15
|
+
<rect width="180" height="180" rx="32" fill="url(#bg)" filter="url(#shadow)" />
|
|
16
|
+
<g transform="translate(45 45)">
|
|
17
|
+
<path d="M45 0C20.147 0 0 20.147 0 45C0 69.853 20.147 90 45 90C69.853 90 90 69.853 90 45C90 20.147 69.853 0 45 0ZM45 72C29.088 72 15.75 58.662 15.75 42.75C15.75 26.838 29.088 13.5 45 13.5C60.912 13.5 74.25 26.838 74.25 42.75C74.25 58.662 60.912 72 45 72Z" fill="white" opacity="0.2" />
|
|
18
|
+
<path d="M24 27H66C70.971 27 75 31.029 75 36V54C75 58.971 70.971 63 66 63H24C19.029 63 15 58.971 15 54V36C15 31.029 19.029 27 24 27Z" fill="url(#accent)" />
|
|
19
|
+
<path d="M36 54V45C36 40.029 40.029 36 45 36C49.971 36 54 40.029 54 45V54" stroke="#0B1220" stroke-width="4" stroke-linecap="round" />
|
|
20
|
+
<circle cx="45" cy="21" r="6" fill="white" />
|
|
21
|
+
<path d="M33 69H57" stroke="white" stroke-width="4" stroke-linecap="round" opacity="0.7" />
|
|
22
|
+
<path d="M27 15H63" stroke="white" stroke-width="4" stroke-linecap="round" opacity="0.4" />
|
|
23
|
+
</g>
|
|
24
|
+
</svg>
|
package/demo/src/App.tsx
CHANGED
|
@@ -1,116 +1,129 @@
|
|
|
1
|
-
import { useState } from 'react'
|
|
2
|
-
import { useTranslation } from '@asafarim/shared-i18n'
|
|
3
|
-
import LanguageBar from './components/LanguageBar'
|
|
4
|
-
import Panel from './components/Panel'
|
|
5
|
-
import KeyTable from './components/KeyTable'
|
|
6
|
-
import StatusCard from './components/StatusCard'
|
|
7
|
-
import OverviewSection from './components/OverviewSection'
|
|
8
|
-
import GetStartedSection from './components/GetStartedSection'
|
|
9
|
-
import LanguageSwitcherDemo from './components/LanguageSwitcherDemo'
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<div>
|
|
73
|
-
<h3>
|
|
74
|
-
<KeyTable
|
|
75
|
-
namespace="
|
|
76
|
-
keys={[
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import { useTranslation } from '@asafarim/shared-i18n'
|
|
3
|
+
import LanguageBar from './components/LanguageBar'
|
|
4
|
+
import Panel from './components/Panel'
|
|
5
|
+
import KeyTable from './components/KeyTable'
|
|
6
|
+
import StatusCard from './components/StatusCard'
|
|
7
|
+
import OverviewSection from './components/OverviewSection'
|
|
8
|
+
import GetStartedSection from './components/GetStartedSection'
|
|
9
|
+
import LanguageSwitcherDemo from './components/LanguageSwitcherDemo'
|
|
10
|
+
import CountryLanguageDemo from './components/CountryLanguageDemo'
|
|
11
|
+
import Logo from './components/Logo'
|
|
12
|
+
|
|
13
|
+
type TabType = 'overview' | 'getStarted' | 'demo' | 'countryDemo'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export default function App() {
|
|
18
|
+
const { t } = useTranslation('demo')
|
|
19
|
+
const [activeTab, setActiveTab] = useState<TabType>('overview')
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className="app-container">
|
|
23
|
+
<header className="app-header">
|
|
24
|
+
<Logo />
|
|
25
|
+
<div className="header-content">
|
|
26
|
+
<h1>{t('title')}</h1>
|
|
27
|
+
<p className="subtitle">{t('subtitle')}</p>
|
|
28
|
+
</div>
|
|
29
|
+
<LanguageBar />
|
|
30
|
+
</header>
|
|
31
|
+
|
|
32
|
+
<main className="app-main">
|
|
33
|
+
<div className="nav-tabs">
|
|
34
|
+
<button
|
|
35
|
+
className={`nav-tab ${activeTab === 'overview' ? 'active' : ''}`}
|
|
36
|
+
onClick={() => setActiveTab('overview')}
|
|
37
|
+
>
|
|
38
|
+
Overview
|
|
39
|
+
</button>
|
|
40
|
+
<button
|
|
41
|
+
className={`nav-tab ${activeTab === 'getStarted' ? 'active' : ''}`}
|
|
42
|
+
onClick={() => setActiveTab('getStarted')}
|
|
43
|
+
>
|
|
44
|
+
Get Started
|
|
45
|
+
</button>
|
|
46
|
+
<button
|
|
47
|
+
className={`nav-tab ${activeTab === 'demo' ? 'active' : ''}`}
|
|
48
|
+
onClick={() => setActiveTab('demo')}
|
|
49
|
+
>
|
|
50
|
+
Demo
|
|
51
|
+
</button>
|
|
52
|
+
<button
|
|
53
|
+
className={`nav-tab ${activeTab === 'countryDemo' ? 'active' : ''}`}
|
|
54
|
+
onClick={() => setActiveTab('countryDemo')}
|
|
55
|
+
>
|
|
56
|
+
Country Selector
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
{activeTab === 'overview' && <OverviewSection />}
|
|
61
|
+
|
|
62
|
+
{activeTab === 'getStarted' && <GetStartedSection />}
|
|
63
|
+
|
|
64
|
+
{activeTab === 'demo' && (
|
|
65
|
+
<>
|
|
66
|
+
<Panel title="LanguageSwitcher Component">
|
|
67
|
+
<LanguageSwitcherDemo />
|
|
68
|
+
</Panel>
|
|
69
|
+
|
|
70
|
+
<Panel title="Translations">
|
|
71
|
+
<div className="panel-grid">
|
|
72
|
+
<div>
|
|
73
|
+
<h3>Common Namespace</h3>
|
|
74
|
+
<KeyTable
|
|
75
|
+
namespace="common"
|
|
76
|
+
keys={['welcome', 'language', 'apps.appName.identity', 'apps.description.identity']}
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
<div>
|
|
80
|
+
<h3>Identity Portal Namespace</h3>
|
|
81
|
+
<KeyTable
|
|
82
|
+
namespace="identityPortal"
|
|
83
|
+
keys={[
|
|
84
|
+
'navbar.admin-area',
|
|
85
|
+
'navbar.auth.signIn',
|
|
86
|
+
'navbar.auth.signOut',
|
|
87
|
+
'dashboard.title',
|
|
88
|
+
'dashboard.user-management.title'
|
|
89
|
+
]}
|
|
90
|
+
/>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</Panel>
|
|
94
|
+
|
|
95
|
+
<Panel title="Interpolation & Trans Component">
|
|
96
|
+
<InterpolationDemo />
|
|
97
|
+
</Panel>
|
|
98
|
+
|
|
99
|
+
<StatusCard />
|
|
100
|
+
</>
|
|
101
|
+
)}
|
|
102
|
+
|
|
103
|
+
{activeTab === 'countryDemo' && (
|
|
104
|
+
<Panel title="Country / Language Selector Examples">
|
|
105
|
+
<CountryLanguageDemo />
|
|
106
|
+
</Panel>
|
|
107
|
+
)}
|
|
108
|
+
</main>
|
|
109
|
+
</div>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function InterpolationDemo() {
|
|
114
|
+
const { t, i18n } = useTranslation('identityPortal')
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<div className="interpolation-demo">
|
|
118
|
+
<div className="demo-item">
|
|
119
|
+
<h4>navbar.auth.welcome with interpolation</h4>
|
|
120
|
+
<p className="demo-output">
|
|
121
|
+
{t('navbar.auth.welcome', { userName: 'Ali' })}
|
|
122
|
+
</p>
|
|
123
|
+
</div>
|
|
124
|
+
<div className="demo-item">
|
|
125
|
+
<h4>Current language: {i18n.language}</h4>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
)
|
|
129
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import type { ReactNode } from 'react'
|
|
3
|
+
import { CountryLanguageSelector } from '@asafarim/country-language-selector'
|
|
4
|
+
import styles from './LanguageSwitcherDemo.module.css'
|
|
5
|
+
|
|
6
|
+
interface DemoItemProps {
|
|
7
|
+
title: string
|
|
8
|
+
description: string
|
|
9
|
+
code: string
|
|
10
|
+
children: ReactNode
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function DemoItem({ title, description, code, children }: DemoItemProps) {
|
|
14
|
+
return (
|
|
15
|
+
<div className={styles.demoItem}>
|
|
16
|
+
<div className={styles.demoHeader}>
|
|
17
|
+
<h4 className={styles.demoTitle}>{title}</h4>
|
|
18
|
+
<p className={styles.demoDescription}>{description}</p>
|
|
19
|
+
</div>
|
|
20
|
+
<div className={styles.demoContent}>
|
|
21
|
+
<div className={styles.demoPreview}>
|
|
22
|
+
<div className={styles.previewLabel}>Preview</div>
|
|
23
|
+
{children}
|
|
24
|
+
</div>
|
|
25
|
+
<div className={styles.demoCode}>
|
|
26
|
+
<div className={styles.codeLabel}>Code</div>
|
|
27
|
+
<pre className={styles.codeBlock}>{code}</pre>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const countries = [
|
|
35
|
+
{
|
|
36
|
+
code: 'BE',
|
|
37
|
+
name: 'Belgium',
|
|
38
|
+
nativeName: 'België',
|
|
39
|
+
flag: '🇧🇪',
|
|
40
|
+
languages: [
|
|
41
|
+
{ code: 'nl', label: 'Dutch', nativeLabel: 'Nederlands' },
|
|
42
|
+
{ code: 'fr', label: 'French', nativeLabel: 'Français' },
|
|
43
|
+
{ code: 'de', label: 'German', nativeLabel: 'Deutsch' }
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
code: 'CH',
|
|
48
|
+
name: 'Switzerland',
|
|
49
|
+
nativeName: 'Schweiz',
|
|
50
|
+
flag: '🇨🇭',
|
|
51
|
+
languages: [
|
|
52
|
+
{ code: 'de', label: 'German', nativeLabel: 'Deutsch' },
|
|
53
|
+
{ code: 'fr', label: 'French', nativeLabel: 'Français' },
|
|
54
|
+
{ code: 'it', label: 'Italian', nativeLabel: 'Italiano' },
|
|
55
|
+
{ code: 'rm', label: 'Romansh', nativeLabel: 'Rumantsch' }
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
code: 'CA',
|
|
60
|
+
name: 'Canada',
|
|
61
|
+
nativeName: 'Canada',
|
|
62
|
+
flag: '🇨🇦',
|
|
63
|
+
languages: [
|
|
64
|
+
{ code: 'en', label: 'English' },
|
|
65
|
+
{ code: 'fr', label: 'French', nativeLabel: 'Français' }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
export default function CountryLanguageDemo() {
|
|
71
|
+
const [selectedLocale, setSelectedLocale] = useState({ country: 'BE', language: 'nl' })
|
|
72
|
+
const [customLocale, setCustomLocale] = useState({ country: 'CH', language: 'it' })
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<div className={styles.container}>
|
|
76
|
+
<DemoItem
|
|
77
|
+
title="Default Selector"
|
|
78
|
+
description="A standard country-language selector with compact trigger mode and persistence."
|
|
79
|
+
code={`<CountryLanguageSelector
|
|
80
|
+
countries={countries}
|
|
81
|
+
defaultValue={{ country: 'BE', language: 'nl' }}
|
|
82
|
+
persistKey="country-locale"
|
|
83
|
+
/>`}
|
|
84
|
+
>
|
|
85
|
+
<CountryLanguageSelector
|
|
86
|
+
countries={countries}
|
|
87
|
+
defaultValue={{ country: 'BE', language: 'nl' }}
|
|
88
|
+
persistKey="country-locale"
|
|
89
|
+
onChange={(locale) => setSelectedLocale(locale)}
|
|
90
|
+
/>
|
|
91
|
+
<p style={{ marginTop: '1rem' }}>
|
|
92
|
+
Selected locale: <strong>{selectedLocale.country}</strong> / <strong>{selectedLocale.language}</strong>
|
|
93
|
+
</p>
|
|
94
|
+
</DemoItem>
|
|
95
|
+
|
|
96
|
+
<DemoItem
|
|
97
|
+
title="Full Trigger Variant"
|
|
98
|
+
description="Render the current selection using full country and language names."
|
|
99
|
+
code={`<CountryLanguageSelector
|
|
100
|
+
countries={countries}
|
|
101
|
+
defaultValue={{ country: 'CA', language: 'fr' }}
|
|
102
|
+
triggerVariant="full"
|
|
103
|
+
/>`}
|
|
104
|
+
>
|
|
105
|
+
<CountryLanguageSelector
|
|
106
|
+
countries={countries}
|
|
107
|
+
defaultValue={{ country: 'CA', language: 'fr' }}
|
|
108
|
+
triggerVariant="full"
|
|
109
|
+
onChange={(locale) => setSelectedLocale(locale)}
|
|
110
|
+
/>
|
|
111
|
+
</DemoItem>
|
|
112
|
+
|
|
113
|
+
<DemoItem
|
|
114
|
+
title="Custom Trigger"
|
|
115
|
+
description="Use a custom trigger renderer to show selected country and language in your own button style."
|
|
116
|
+
code={`<CountryLanguageSelector
|
|
117
|
+
countries={countries}
|
|
118
|
+
defaultValue={{ country: 'CH', language: 'it' }}
|
|
119
|
+
renderTrigger={({ country, language, open }) => (
|
|
120
|
+
<button>{open ? 'Close' : 'Open'} {country.code} · {language.code}</button>
|
|
121
|
+
)}
|
|
122
|
+
/>`}
|
|
123
|
+
>
|
|
124
|
+
<CountryLanguageSelector
|
|
125
|
+
countries={countries}
|
|
126
|
+
defaultValue={{ country: 'CH', language: 'it' }}
|
|
127
|
+
renderTrigger={({ country, language, open }) => (
|
|
128
|
+
<button type="button" style={{ padding: '0.75rem 1rem', borderRadius: 8, border: '1px solid #ccc', background: open ? '#f0f4ff' : '#fff' }}>
|
|
129
|
+
{open ? 'Close' : 'Open'} {country.flag} {country.name} · {language.nativeLabel ?? language.label}
|
|
130
|
+
</button>
|
|
131
|
+
)}
|
|
132
|
+
onChange={(locale) => setCustomLocale(locale)}
|
|
133
|
+
/>
|
|
134
|
+
<p style={{ marginTop: '1rem' }}>
|
|
135
|
+
Custom trigger locale: <strong>{customLocale.country}</strong> / <strong>{customLocale.language}</strong>
|
|
136
|
+
</p>
|
|
137
|
+
</DemoItem>
|
|
138
|
+
</div>
|
|
139
|
+
)
|
|
140
|
+
}
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { useState } from 'react'
|
|
2
|
-
import { useTranslation } from '@asafarim/shared-i18n'
|
|
3
|
-
|
|
4
|
-
export default function GetStartedSection() {
|
|
5
|
-
const { t } = useTranslation('demo')
|
|
6
|
-
const [expandedStep, setExpandedStep] = useState<number>(0)
|
|
7
|
-
const getStarted = t('getStarted', { returnObjects: true }) as any
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<div className="get-started-section">
|
|
11
|
-
<div className="gs-header">
|
|
12
|
-
<h2 className="gs-title">{getStarted.heading}</h2>
|
|
13
|
-
<p className="gs-intro">{getStarted.intro}</p>
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<div className="steps-container">
|
|
17
|
-
{getStarted.steps.map((step: any, idx: number) => (
|
|
18
|
-
<div key={idx} className="step-item">
|
|
19
|
-
<button
|
|
20
|
-
className={`step-header ${expandedStep === idx ? 'expanded' : ''}`}
|
|
21
|
-
onClick={() => setExpandedStep(expandedStep === idx ? -1 : idx)}
|
|
22
|
-
>
|
|
23
|
-
<div className="step-number">{idx + 1}</div>
|
|
24
|
-
<div className="step-info">
|
|
25
|
-
<h3>{step.title}</h3>
|
|
26
|
-
<p>{step.description}</p>
|
|
27
|
-
</div>
|
|
28
|
-
<div className="step-toggle">
|
|
29
|
-
{expandedStep === idx ? '−' : '+'}
|
|
30
|
-
</div>
|
|
31
|
-
</button>
|
|
32
|
-
{expandedStep === idx && (
|
|
33
|
-
<div className="step-content">
|
|
34
|
-
<pre className="code-block">
|
|
35
|
-
<code>{step.code}</code>
|
|
36
|
-
</pre>
|
|
37
|
-
</div>
|
|
38
|
-
)}
|
|
39
|
-
</div>
|
|
40
|
-
))}
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
<div className="tips-section">
|
|
44
|
-
<div className="tips-icon">💡</div>
|
|
45
|
-
<div className="tips-content">
|
|
46
|
-
<h3>{getStarted.tips.title}</h3>
|
|
47
|
-
<ul className="tips-list">
|
|
48
|
-
{getStarted.tips.items.map((tip: string, idx: number) => (
|
|
49
|
-
<li key={idx}>{tip}</li>
|
|
50
|
-
))}
|
|
51
|
-
</ul>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import { useTranslation } from '@asafarim/shared-i18n'
|
|
3
|
+
|
|
4
|
+
export default function GetStartedSection() {
|
|
5
|
+
const { t } = useTranslation('demo')
|
|
6
|
+
const [expandedStep, setExpandedStep] = useState<number>(0)
|
|
7
|
+
const getStarted = t('getStarted', { returnObjects: true }) as any
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<div className="get-started-section">
|
|
11
|
+
<div className="gs-header">
|
|
12
|
+
<h2 className="gs-title">{getStarted.heading}</h2>
|
|
13
|
+
<p className="gs-intro">{getStarted.intro}</p>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div className="steps-container">
|
|
17
|
+
{getStarted.steps.map((step: any, idx: number) => (
|
|
18
|
+
<div key={idx} className="step-item">
|
|
19
|
+
<button
|
|
20
|
+
className={`step-header ${expandedStep === idx ? 'expanded' : ''}`}
|
|
21
|
+
onClick={() => setExpandedStep(expandedStep === idx ? -1 : idx)}
|
|
22
|
+
>
|
|
23
|
+
<div className="step-number">{idx + 1}</div>
|
|
24
|
+
<div className="step-info">
|
|
25
|
+
<h3>{step.title}</h3>
|
|
26
|
+
<p>{step.description}</p>
|
|
27
|
+
</div>
|
|
28
|
+
<div className="step-toggle">
|
|
29
|
+
{expandedStep === idx ? '−' : '+'}
|
|
30
|
+
</div>
|
|
31
|
+
</button>
|
|
32
|
+
{expandedStep === idx && (
|
|
33
|
+
<div className="step-content">
|
|
34
|
+
<pre className="code-block">
|
|
35
|
+
<code>{step.code}</code>
|
|
36
|
+
</pre>
|
|
37
|
+
</div>
|
|
38
|
+
)}
|
|
39
|
+
</div>
|
|
40
|
+
))}
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div className="tips-section">
|
|
44
|
+
<div className="tips-icon">💡</div>
|
|
45
|
+
<div className="tips-content">
|
|
46
|
+
<h3>{getStarted.tips.title}</h3>
|
|
47
|
+
<ul className="tips-list">
|
|
48
|
+
{getStarted.tips.items.map((tip: string, idx: number) => (
|
|
49
|
+
<li key={idx}>{tip}</li>
|
|
50
|
+
))}
|
|
51
|
+
</ul>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { useTranslation } from '@asafarim/shared-i18n'
|
|
2
|
-
|
|
3
|
-
interface KeyTableProps {
|
|
4
|
-
namespace: string
|
|
5
|
-
keys: string[]
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export default function KeyTable({ namespace, keys }: KeyTableProps) {
|
|
9
|
-
const { t } = useTranslation(namespace)
|
|
10
|
-
|
|
11
|
-
return (
|
|
12
|
-
<table className="key-table">
|
|
13
|
-
<thead>
|
|
14
|
-
<tr>
|
|
15
|
-
<th>Key</th>
|
|
16
|
-
<th>Value</th>
|
|
17
|
-
</tr>
|
|
18
|
-
</thead>
|
|
19
|
-
<tbody>
|
|
20
|
-
{keys.map((key) => (
|
|
21
|
-
<tr key={key}>
|
|
22
|
-
<td>{key}</td>
|
|
23
|
-
<td>{t(key)}</td>
|
|
24
|
-
</tr>
|
|
25
|
-
))}
|
|
26
|
-
</tbody>
|
|
27
|
-
</table>
|
|
28
|
-
)
|
|
29
|
-
}
|
|
1
|
+
import { useTranslation } from '@asafarim/shared-i18n'
|
|
2
|
+
|
|
3
|
+
interface KeyTableProps {
|
|
4
|
+
namespace: string
|
|
5
|
+
keys: string[]
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default function KeyTable({ namespace, keys }: KeyTableProps) {
|
|
9
|
+
const { t } = useTranslation(namespace)
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<table className="key-table">
|
|
13
|
+
<thead>
|
|
14
|
+
<tr>
|
|
15
|
+
<th>Key</th>
|
|
16
|
+
<th>Value</th>
|
|
17
|
+
</tr>
|
|
18
|
+
</thead>
|
|
19
|
+
<tbody>
|
|
20
|
+
{keys.map((key) => (
|
|
21
|
+
<tr key={key}>
|
|
22
|
+
<td>{key}</td>
|
|
23
|
+
<td>{t(key)}</td>
|
|
24
|
+
</tr>
|
|
25
|
+
))}
|
|
26
|
+
</tbody>
|
|
27
|
+
</table>
|
|
28
|
+
)
|
|
29
|
+
}
|