Search: separate Roman-to-Urdu toggle and on-screen keyboard toggle; keys hidden until asked
The header's flex rule overrode [hidden], so the keys showed on every page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
647b9fa369
commit
4c7e0559a7
@ -35,7 +35,8 @@ const fullTitle = title ? `${title} · دیوان` : 'دیوان · اردو ک
|
|||||||
<a class="wordmark" href="/">دیوان</a>
|
<a class="wordmark" href="/">دیوان</a>
|
||||||
<form class="search-form" action="/search" method="get" role="search">
|
<form class="search-form" action="/search" method="get" role="search">
|
||||||
<input type="search" name="q" id="q" value={q} placeholder="شعر، لفظ یا عبارت تلاش کریں" aria-label="تلاش" autocomplete="off" />
|
<input type="search" name="q" id="q" value={q} placeholder="شعر، لفظ یا عبارت تلاش کریں" aria-label="تلاش" autocomplete="off" />
|
||||||
<button type="button" id="kb-toggle" aria-label="اردو کی بورڈ" aria-pressed="false" title="اردو کی بورڈ (فونیٹک ٹائپنگ)">
|
<button type="button" id="rom-toggle" class="in-box" aria-label="رومن حروف سے اردو" aria-pressed="false" title="رومن حروف سے اردو ٹائپنگ (dil → دل)">اب</button>
|
||||||
|
<button type="button" id="kb-toggle" class="in-box" aria-label="اردو کی بورڈ" aria-pressed="false" title="اردو کی بورڈ">
|
||||||
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><rect x="2" y="6" width="20" height="12" rx="2"/><path d="M6 10h.01M10 10h.01M14 10h.01M18 10h.01M7 14h10" stroke-linecap="round" stroke-width="2"/></svg>
|
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><rect x="2" y="6" width="20" height="12" rx="2"/><path d="M6 10h.01M10 10h.01M14 10h.01M18 10h.01M7 14h10" stroke-linecap="round" stroke-width="2"/></svg>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@ -63,15 +64,20 @@ const fullTitle = title ? `${title} · دیوان` : 'دیوان · اردو ک
|
|||||||
try { localStorage.setItem('divan-font', root.classList.contains('nastaliq') ? 'nastaliq' : 'naskh'); } catch (e) {}
|
try { localStorage.setItem('divan-font', root.classList.contains('nastaliq') ? 'nastaliq' : 'naskh'); } catch (e) {}
|
||||||
label();
|
label();
|
||||||
};
|
};
|
||||||
// Urdu keyboard, Gboard/Windows Urdu layout: on-screen keys, and physical keys by position while open
|
// Urdu on-screen keyboard, Gboard/Windows Urdu layout
|
||||||
const BASE = [[...'طصھدٹپتبجح'], [...'مورنلہاکی'], [...'قفےسشغع']];
|
const BASE = [[...'طصھدٹپتبجح'], [...'مورنلہاکی'], [...'قفےسشغع']];
|
||||||
const SHIFT = [['ظ','ض','ذ','ڈ','ث','ّ','ۃ','ـ','چ','خ'], ['ژ','ز','ڑ','ں','ۂ','ء','آ','گ',''], ['','','ۓ','','ؤ','ئ','']];
|
const SHIFT = [['ظ','ض','ذ','ڈ','ث','ّ','ۃ','ـ','چ','خ'], ['ژ','ز','ڑ','ں','ۂ','ء','آ','گ',''], ['','','ۓ','','ؤ','ئ','']];
|
||||||
const KEYS = {}; // KeyQ -> [base, shift]
|
// Roman -> Urdu (phonetic) typing, its own toggle
|
||||||
['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM'].forEach((r, i) => [...r].forEach((c, j) => (KEYS['Key' + c] = [BASE[i][j], SHIFT[i][j]])));
|
const PHONETIC = {
|
||||||
const PUNCT = { Comma: '،', Period: '۔', Semicolon: '؛', Slash: '؟' };
|
q:'ق', w:'و', e:'ع', r:'ر', t:'ت', y:'ے', u:'ء', i:'ی', o:'ہ', p:'پ',
|
||||||
const q = document.getElementById('q'), kb = document.getElementById('kb'), kbBtn = document.getElementById('kb-toggle');
|
a:'ا', s:'س', d:'د', f:'ف', g:'گ', h:'ح', j:'ج', k:'ک', l:'ل',
|
||||||
|
z:'ز', x:'ش', c:'چ', v:'ط', b:'ب', n:'ن', m:'م',
|
||||||
|
A:'آ', T:'ٹ', D:'ڈ', R:'ڑ', N:'ں', Z:'ذ', S:'ص', G:'غ', H:'ھ', K:'خ', C:'ث', V:'ظ', X:'ژ', J:'ض', I:'ئ', O:'ۂ', Y:'ؤ',
|
||||||
|
',':'،', '.':'۔', '?':'؟', ';':'؛',
|
||||||
|
};
|
||||||
|
const q = document.getElementById('q'), kb = document.getElementById('kb'), kbBtn = document.getElementById('kb-toggle'), romBtn = document.getElementById('rom-toggle');
|
||||||
let shift = false;
|
let shift = false;
|
||||||
const key = (ch, cls = '') => ch ? `<button type="button" data-ch="${ch}"${cls}>${ch}</button>` : '';
|
const key = (ch) => ch ? `<button type="button" data-ch="${ch}">${ch}</button>` : '';
|
||||||
const render = () => {
|
const render = () => {
|
||||||
const L = shift ? SHIFT : BASE;
|
const L = shift ? SHIFT : BASE;
|
||||||
kb.innerHTML = `<div>${L[0].map((c) => key(c)).join('')}</div><div>${L[1].map((c) => key(c)).join('')}</div>` +
|
kb.innerHTML = `<div>${L[0].map((c) => key(c)).join('')}</div><div>${L[1].map((c) => key(c)).join('')}</div>` +
|
||||||
@ -99,11 +105,11 @@ const fullTitle = title ? `${title} · دیوان` : 'دیوان · اردو ک
|
|||||||
kbBtn.onclick = () => {
|
kbBtn.onclick = () => {
|
||||||
kb.hidden = !kb.hidden; kbBtn.setAttribute('aria-pressed', String(!kb.hidden)); q.focus();
|
kb.hidden = !kb.hidden; kbBtn.setAttribute('aria-pressed', String(!kb.hidden)); q.focus();
|
||||||
};
|
};
|
||||||
|
romBtn.onclick = () => { romBtn.setAttribute('aria-pressed', String(romBtn.getAttribute('aria-pressed') !== 'true')); q.focus(); };
|
||||||
q.addEventListener('keydown', (ev) => {
|
q.addEventListener('keydown', (ev) => {
|
||||||
if (kb.hidden || ev.ctrlKey || ev.metaKey || ev.altKey) return;
|
if (romBtn.getAttribute('aria-pressed') !== 'true' || ev.ctrlKey || ev.metaKey || ev.altKey) return;
|
||||||
const k = KEYS[ev.code], ch = k ? k[ev.shiftKey ? 1 : 0] : PUNCT[ev.code];
|
const ch = PHONETIC[ev.key];
|
||||||
if (k || ch) ev.preventDefault();
|
if (ch) { ev.preventDefault(); insert(ch); }
|
||||||
if (ch) insert(ch);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('theme-toggle').onclick = () => {
|
document.getElementById('theme-toggle').onclick = () => {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
/* Divan styles: Ganjoor's look (palette, gold pills, centred couplets with ✤), RTL, Naskh default. */
|
/* Divan styles: Ganjoor's look (palette, gold pills, centred couplets with ✤), RTL, Naskh default. */
|
||||||
|
[hidden] { display: none !important; } /* layout rules (e.g. .site-header .wrap flex) must not unhide */
|
||||||
:root {
|
:root {
|
||||||
--bg: #fbf6ea; --paper: #fffdf7; --poem: #f6edd6; --inner: #f6efe3; --nested: #eee3d0;
|
--bg: #fbf6ea; --paper: #fffdf7; --poem: #f6edd6; --inner: #f6efe3; --nested: #eee3d0;
|
||||||
--ink: #17130f; --muted: #635543; --lapis: #0d1d30; --gold: #b88828; --gold-light: #dfcd9f;
|
--ink: #17130f; --muted: #635543; --lapis: #0d1d30; --gold: #b88828; --gold-light: #dfcd9f;
|
||||||
@ -34,7 +35,7 @@ a:hover { color: var(--brand); }
|
|||||||
.search-form input, .toggles button {
|
.search-form input, .toggles button {
|
||||||
font: inherit; border: 1.5px solid var(--border); background: var(--inner); color: var(--ink); border-radius: 10px;
|
font: inherit; border: 1.5px solid var(--border); background: var(--inner); color: var(--ink); border-radius: 10px;
|
||||||
}
|
}
|
||||||
.search-form input { flex: 1; padding: 4px 14px; padding-inline-end: 40px; }
|
.search-form input { flex: 1; padding: 4px 14px; padding-inline-end: 76px; }
|
||||||
.search-form input:focus { outline: none; border-color: var(--gold); }
|
.search-form input:focus { outline: none; border-color: var(--gold); }
|
||||||
.toggles { display: flex; gap: 6px; }
|
.toggles { display: flex; gap: 6px; }
|
||||||
.toggles button { padding: 2px 12px; cursor: pointer; font-size: .85rem; }
|
.toggles button { padding: 2px 12px; cursor: pointer; font-size: .85rem; }
|
||||||
@ -108,9 +109,10 @@ h1::after { content: ''; display: block; width: 140px; height: 2px; background:
|
|||||||
h1 + .muted { text-align: center; margin-top: 0; }
|
h1 + .muted { text-align: center; margin-top: 0; }
|
||||||
|
|
||||||
/* Urdu keyboard */
|
/* Urdu keyboard */
|
||||||
#kb-toggle { position: absolute; inset-inline-end: 8px; top: 50%; transform: translateY(-50%); display: flex; padding: 4px; border: 0; background: none; color: var(--muted, currentColor); opacity: .7; cursor: pointer; border-radius: 6px; }
|
.in-box { position: absolute; inset-inline-end: 8px; top: 50%; transform: translateY(-50%); display: flex; padding: 4px; border: 0; background: none; color: var(--muted, currentColor); opacity: .7; cursor: pointer; border-radius: 6px; }
|
||||||
#kb-toggle:hover { opacity: 1; }
|
#rom-toggle { inset-inline-end: 38px; font: 600 .95rem/1 'Noto Naskh Arabic', serif; }
|
||||||
#kb-toggle[aria-pressed='true'] { color: var(--brand); opacity: 1; }
|
.in-box:hover { opacity: 1; }
|
||||||
|
.in-box[aria-pressed='true'] { color: var(--brand); opacity: 1; }
|
||||||
.site-header .kb:not([hidden]) { display: block; padding-bottom: 10px; } /* not the header's flex row */
|
.site-header .kb:not([hidden]) { display: block; padding-bottom: 10px; } /* not the header's flex row */
|
||||||
.kb div { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; margin-top: 4px; }
|
.kb div { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; margin-top: 4px; }
|
||||||
.kb button {
|
.kb button {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user