feat(ui): searchable language picker and light-mode keyword modals

This commit is contained in:
Dwindi Ramadhana
2026-02-15 11:11:44 +07:00
parent 87aa842e0b
commit a7a854886d
5 changed files with 186 additions and 24 deletions

View File

@@ -604,6 +604,71 @@
});
})();
</script>
<script>
(() => {
const normalizeCode = (raw) => {
const input = String(raw || '').trim().replace('_', '-');
if (!input) return null;
const parts = input.split('-');
if (parts.length === 1) {
const code = parts[0].toLowerCase();
return /^[a-z]{2,3}$/.test(code) ? code : null;
}
const base = parts[0].toLowerCase();
const region = parts[1].toUpperCase();
const code = `${base}-${region}`;
return /^[a-z]{2,3}-[A-Z]{2}$/.test(code) ? code : null;
};
window.dewemojiPopulateLanguageOptions = (target) => {
const list = typeof target === 'string' ? document.getElementById(target) : target;
if (!list || list.dataset.generated === '1') return;
const codeToName = new Map();
list.querySelectorAll('option[data-code]').forEach((option) => {
const code = normalizeCode(option.dataset.code);
if (!code) return;
const fallbackName = String(option.value || '').replace(/\s+\([^)]+\)\s*$/, '').trim() || code;
codeToName.set(code, fallbackName);
});
if (!codeToName.has('und')) codeToName.set('und', 'Undetermined');
if (typeof Intl !== 'undefined' && typeof Intl.supportedValuesOf === 'function') {
const display = typeof Intl.DisplayNames === 'function'
? new Intl.DisplayNames(['en'], { type: 'language' })
: null;
Intl.supportedValuesOf('language').forEach((rawCode) => {
const code = normalizeCode(rawCode);
if (!code) return;
const name = display?.of(code) || display?.of(code.split('-')[0]) || code;
codeToName.set(code, name);
});
}
const entries = Array.from(codeToName.entries()).sort((a, b) => {
if (a[0] === 'und') return -1;
if (b[0] === 'und') return 1;
return a[1].localeCompare(b[1]);
});
list.innerHTML = '';
entries.forEach(([code, name]) => {
const option = document.createElement('option');
option.value = `${name} (${code})`;
option.dataset.code = code;
list.appendChild(option);
});
list.dataset.generated = '1';
};
document.querySelectorAll('datalist[data-language-options="1"]').forEach((list) => {
window.dewemojiPopulateLanguageOptions(list);
});
})();
</script>
@stack('scripts')
</body>
</html>