From 152ba5cc533810b1bf438754898db40e517e3849 Mon Sep 17 00:00:00 2001 From: JesusValera Date: Fri, 31 Oct 2025 12:12:57 +0100 Subject: [PATCH 1/3] Add "x" button to search input --- index.html | 13 +++++ .../wordInput/infrastructure/wordInput.ts | 45 +++++++++++++++++- src/styles/components.css | 47 ++++++++++++++++++- src/styles/responsive.css | 43 +++++++++++++++-- 4 files changed, 141 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index d42f9d9..604004e 100644 --- a/index.html +++ b/index.html @@ -159,6 +159,19 @@

Type a word or click numbers to aria-controls="word-suggestions" aria-live="polite" /> +
diff --git a/src/modules/wordInput/infrastructure/wordInput.ts b/src/modules/wordInput/infrastructure/wordInput.ts index 95f2964..aaa531d 100644 --- a/src/modules/wordInput/infrastructure/wordInput.ts +++ b/src/modules/wordInput/infrastructure/wordInput.ts @@ -16,7 +16,11 @@ export function setupWordInput(): void { elements.wordInput.addEventListener('focus', handleWordInput); elements.wordInput.addEventListener('blur', handleWordInputBlur); - // Handle click outside to close suggestions + const clearBtn = document.getElementById('clear-input-btn'); + if (clearBtn) { + clearBtn.addEventListener('click', handleClearInput); + } + document.addEventListener('click', e => { if (!elements.wordInput.contains(e.target as Node) && !elements.wordSuggestions.contains(e.target as Node)) { hideSuggestions(); @@ -24,6 +28,16 @@ export function setupWordInput(): void { }); } +function handleClearInput(): void { + elements.wordInput.value = ''; + elements.wordInput.classList.remove('error'); + resetBoxes(); + updateDisplay(); + hideSuggestions(); + toggleClearButton(false); + elements.wordInput.focus(); +} + function handleWordInputBlur(): void { hideSuggestions(); validateWordInput(); @@ -42,6 +56,11 @@ function validateWordInput(): void { if (wordExists) { elements.wordInput.classList.remove('error'); + const wordIndex = getWordIndex(value, state.wordlist); + if (wordIndex !== -1) { + setStateFromIndex(wordIndex); + updateDisplay(); + } return; } @@ -55,6 +74,8 @@ function validateWordInput(): void { function handleWordInput(): void { const value = elements.wordInput.value.trim().toLowerCase(); + toggleClearButton(elements.wordInput.value.length > 0); + if (!value) { hideSuggestions(); return; @@ -68,6 +89,12 @@ function handleWordInput(): void { return; } + // Hide suggestions if only 1 match and it's an exact match + if (matches.length === 1 && matches[0].toLowerCase() === value) { + hideSuggestions(); + return; + } + // Show suggestions showSuggestions(matches.slice(0, 10)); // Limit to 10 suggestions selectedSuggestionIndex = -1; @@ -202,6 +229,20 @@ export function clearWordInput(): void { elements.wordInput.value = ''; elements.wordInput.classList.remove('error'); hideSuggestions(); + toggleClearButton(false); +} + +function toggleClearButton(show: boolean): void { + const clearBtn = document.getElementById('clear-input-btn') as HTMLButtonElement | null; + if (clearBtn) { + if (show) { + clearBtn.disabled = false; + clearBtn.removeAttribute('aria-disabled'); + } else { + clearBtn.disabled = true; + clearBtn.setAttribute('aria-disabled', 'true'); + } + } } export function syncWordInputFromState(): void { @@ -212,10 +253,12 @@ export function syncWordInputFromState(): void { const word = getWordByIndex(wordIndex, state.wordlist); if (word && elements.wordInput.value !== word) { elements.wordInput.value = word; + toggleClearButton(true); } } else { if (elements.wordInput.value !== '') { elements.wordInput.value = ''; + toggleClearButton(false); } } } diff --git a/src/styles/components.css b/src/styles/components.css index 704fe59..145be09 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -463,7 +463,7 @@ .word-input { width: 100%; - padding: 1rem; + padding: 1rem 3.5rem 1rem 1rem; font-size: 2.2rem; font-weight: 700; font-family: 'Courier New', monospace; @@ -499,6 +499,51 @@ letter-spacing: 0.05em; } +.clear-input-btn { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + width: 36px; + height: 36px; + border-radius: 50%; + border: 2px solid var(--border); + background: var(--background); + color: var(--text-primary); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; + padding: 0; + opacity: 0.9; + z-index: 10; +} + +.clear-input-btn:hover { + opacity: 1; + background: var(--primary-color); + color: white; + border-color: var(--primary-color); + box-shadow: 0 4px 8px rgba(247, 147, 26, 0.3); +} + +.clear-input-btn:disabled, +.clear-input-btn[aria-disabled='true'] { + opacity: 0.3; + cursor: not-allowed; + background: var(--surface-light); + color: var(--text-secondary); + border-color: var(--border); + pointer-events: none; +} + +.clear-input-btn svg { + width: 20px; + height: 20px; + stroke-width: 2.5; +} + /* Word Info (Index display) */ .word-info { margin-top: 1.5rem; diff --git a/src/styles/responsive.css b/src/styles/responsive.css index 556e177..a229703 100644 --- a/src/styles/responsive.css +++ b/src/styles/responsive.css @@ -11,7 +11,7 @@ .word-input { font-size: 2rem; - padding: 1.25rem; + padding: 1.25rem 3.5rem 1.25rem 1.25rem; } .word-input::placeholder { @@ -102,13 +102,24 @@ .word-input { font-size: 1.75rem; - padding: 1.125rem 1.25rem; + padding: 1.125rem 3.5rem 1.125rem 1.25rem; } .word-input::placeholder { font-size: 1.75rem; } + .clear-input-btn { + width: 32px; + height: 32px; + right: 10px; + } + + .clear-input-btn svg { + width: 18px; + height: 18px; + } + .word-info { margin-top: 1.25rem; } @@ -234,13 +245,24 @@ .word-input { font-size: 1.5rem; - padding: 1rem; + padding: 1rem 3rem 1rem 1rem; } .word-input::placeholder { font-size: 1.5rem; } + .clear-input-btn { + width: 30px; + height: 30px; + right: 8px; + } + + .clear-input-btn svg { + width: 16px; + height: 16px; + } + .word-info { margin-top: 1rem; } @@ -302,13 +324,24 @@ .word-input { font-size: 1.35rem; - padding: 0.95rem; + padding: 0.95rem 3rem 0.95rem 0.95rem; } .word-input::placeholder { font-size: 1.35rem; } + .clear-input-btn { + width: 28px; + height: 28px; + right: 8px; + } + + .clear-input-btn svg { + width: 16px; + height: 16px; + } + .binary-display code { font-size: 0.9rem; } @@ -334,7 +367,7 @@ .word-input { font-size: 1.25rem; - padding: 0.875rem; + padding: 0.875rem 0.875rem 0.875rem 2.75rem; } .word-input::placeholder { From 4562f74cd9c1f11da57b0547220624568b783066 Mon Sep 17 00:00:00 2001 From: JesusValera Date: Fri, 31 Oct 2025 12:15:22 +0100 Subject: [PATCH 2/3] Reduce complexity toast.showToast() --- src/modules/display/infrastructure/toast.ts | 39 +++++++++++++-------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/modules/display/infrastructure/toast.ts b/src/modules/display/infrastructure/toast.ts index a650258..84e4046 100644 --- a/src/modules/display/infrastructure/toast.ts +++ b/src/modules/display/infrastructure/toast.ts @@ -30,40 +30,51 @@ export function showDisabledBoxToast(): void { } export function showToast(id: string, message: string, duration: number = 3000, className: string = 'toast'): void { + cleanupExistingToast(id); + const toast = createToastElement(id, message, className); + scheduleToastAnimations(id, toast, duration); +} + +function cleanupExistingToast(id: string): void { const existingToast = document.getElementById(id); - if (existingToast) { - existingToast.remove(); - } + existingToast?.remove(); + + clearToastTimers(id); +} +function clearToastTimers(id: string): void { const timers = toastTimers.get(id); if (timers) { if (timers.show) clearTimeout(timers.show); if (timers.hide) clearTimeout(timers.hide); if (timers.remove) clearTimeout(timers.remove); } +} - toastTimers.set(id, { show: null, hide: null, remove: null }); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const currentTimers = toastTimers.get(id)!; - +function createToastElement(id: string, message: string, className: string): HTMLElement { const toast = document.createElement('div'); toast.id = id; toast.className = className; toast.textContent = message; toast.setAttribute('role', 'alert'); toast.setAttribute('aria-live', 'polite'); - document.body.appendChild(toast); - currentTimers.show = setTimeout(() => { - toast.classList.add('show'); - }, 10); + return toast; +} + +function scheduleToastAnimations(id: string, toast: HTMLElement, duration: number): void { + toastTimers.set(id, { show: null, hide: null, remove: null }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const timers = toastTimers.get(id)!; + + timers.show = setTimeout(() => toast.classList.add('show'), 10); - currentTimers.hide = setTimeout(() => { + timers.hide = setTimeout(() => { toast.classList.remove('show'); - currentTimers.remove = setTimeout(() => { + timers.remove = setTimeout(() => { toast.remove(); - toastTimers.delete(id); // Clean up timer storage + toastTimers.delete(id); }, 300); }, duration); } From d60ff7e41115c1038a649eb5b1d33ac7d2d9d22b Mon Sep 17 00:00:00 2001 From: JesusValera Date: Fri, 31 Oct 2025 12:39:42 +0100 Subject: [PATCH 3/3] Change header sentence --- index.html | 4 +-- src/modules/bip39/infrastructure/elements.ts | 3 -- src/modules/i18n/domain/i18n.ts | 35 ++++++++----------- .../language/infrastructure/language.ts | 1 - src/styles/components.css | 15 ++------ src/styles/responsive.css | 14 -------- test/unit/bip39/infrastructure/dom.test.ts | 1 - test/unit/i18n/domain/i18n.test.ts | 2 +- 8 files changed, 18 insertions(+), 57 deletions(-) diff --git a/index.html b/index.html index 604004e..dfac19e 100644 --- a/index.html +++ b/index.html @@ -140,11 +140,10 @@

BIP39 Word Selector

-

Choose a BIP39 word by typing it or by clicking numbers (1-2048).

+

Choose a BIP39 word by typing it in the input field below or by clicking the number boxes (1-2048)

-

Type a word or click numbers to select

Type a word or click numbers to autocomplete="off" spellcheck="false" autofocus - aria-describedby="word-input-label" aria-autocomplete="list" aria-controls="word-suggestions" aria-live="polite" diff --git a/src/modules/bip39/infrastructure/elements.ts b/src/modules/bip39/infrastructure/elements.ts index a615db1..6cc149f 100644 --- a/src/modules/bip39/infrastructure/elements.ts +++ b/src/modules/bip39/infrastructure/elements.ts @@ -37,9 +37,6 @@ export const elements = { get wordInput() { return getElementById('word-input'); }, - get wordInputLabel() { - return getElementById('word-input-label'); - }, get wordSuggestions() { return getElementById('word-suggestions'); }, diff --git a/src/modules/i18n/domain/i18n.ts b/src/modules/i18n/domain/i18n.ts index c3b17b7..4d5b10a 100644 --- a/src/modules/i18n/domain/i18n.ts +++ b/src/modules/i18n/domain/i18n.ts @@ -13,7 +13,6 @@ export interface Translations { invalidWordMessage: string; wordlistLoadError: string; // Word input translations - wordInputLabel: string; wordInputPlaceholder: string; // Modal translations modalTitle: string; @@ -67,7 +66,7 @@ export const translations: Record = { languageLabel: 'Language', index: 'Index:', resetButton: 'Reset', - infoText: 'Choose a BIP39 word by typing it or by clicking numbers (1-2048).', + infoText: 'Choose a BIP39 word by typing it in the input field below or by clicking the number boxes (1-2048)', privacyTitle: 'Privacy Protected', privacyTooltip: 'This application runs entirely in your browser. No data is transmitted, stored, or tracked.', toggleTheme: 'Toggle dark/light mode', @@ -76,7 +75,6 @@ export const translations: Record = { invalidWordMessage: 'This word is not in the BIP39 wordlist', wordlistLoadError: '⚠️ Failed to load wordlist. Please refresh the page.', // Word input translations - wordInputLabel: 'Type a word or click numbers to select', wordInputPlaceholder: 'abandon', // Modal translations modalTitle: 'What is BIP39?', @@ -133,7 +131,8 @@ export const translations: Record = { languageLabel: 'Idioma', index: 'Índice:', resetButton: 'Reiniciar', - infoText: 'Elige una palabra BIP39 escribiéndola o haciendo clic en números (1-2048).', + infoText: + 'Elige una palabra BIP39 escribiéndola en el campo de texto o haciendo clic en las casillas numéricas (1-2048)', privacyTitle: 'Privacidad Protegida', privacyTooltip: 'Esta aplicación se ejecuta completamente en tu navegador. No se transmite, almacena ni rastrea ningún dato.', @@ -143,7 +142,6 @@ export const translations: Record = { invalidWordMessage: 'Esta palabra no está en la lista BIP39', wordlistLoadError: '⚠️ Error al cargar la lista de palabras. Por favor, recarga la página.', // Word input translations - wordInputLabel: 'Escribe una palabra o haz clic en números', wordInputPlaceholder: 'ábaco', // Modal translations modalTitle: '¿Qué es BIP39?', @@ -200,7 +198,8 @@ export const translations: Record = { languageLabel: 'Langue', index: 'Indice:', resetButton: 'Réinitialiser', - infoText: 'Choisissez un mot BIP39 en le tapant ou en cliquant sur des numéros (1-2048).', + infoText: + 'Choisissez un mot BIP39 en le tapant dans le champ de saisie ci-dessous ou en cliquant sur les cases numériques (1-2048)', privacyTitle: 'Confidentialité Protégée', privacyTooltip: "Cette application s'exécute entièrement dans votre navigateur. Aucune donnée n'est transmise, stockée ou suivie.", @@ -210,7 +209,6 @@ export const translations: Record = { invalidWordMessage: "Ce mot n'est pas dans la liste BIP39", wordlistLoadError: '⚠️ Échec du chargement de la liste de mots. Veuillez actualiser la page.', // Word input translations - wordInputLabel: 'Tapez un mot ou cliquez sur des numéros', wordInputPlaceholder: 'abaisser', // Modal translations modalTitle: "Qu'est-ce que BIP39?", @@ -267,7 +265,7 @@ export const translations: Record = { languageLabel: 'Jazyk', index: 'Index:', resetButton: 'Resetovat', - infoText: 'Vyberte slovo BIP39 jeho napsáním nebo kliknutím na čísla (1-2048).', + infoText: 'Vyberte slovo BIP39 jeho napsáním do vstupního pole níže nebo kliknutím na číselná pole (1-2048)', privacyTitle: 'Soukromí Chráněno', privacyTooltip: 'Tato aplikace běží zcela ve vašem prohlížeči. Žádná data nejsou přenášena, ukládána ani sledována.', @@ -277,7 +275,6 @@ export const translations: Record = { invalidWordMessage: 'Toto slovo není v seznamu BIP39', wordlistLoadError: '⚠️ Nepodařilo se načíst seznam slov. Obnovte prosím stránku.', // Word input translations - wordInputLabel: 'Napište slovo nebo klikněte na čísla', wordInputPlaceholder: 'abdikace', // Modal translations modalTitle: 'Co je BIP39?', @@ -334,7 +331,8 @@ export const translations: Record = { languageLabel: 'Lingua', index: 'Indice:', resetButton: 'Ripristina', - infoText: 'Scegli una parola BIP39 scrivendola o cliccando sui numeri (1-2048).', + infoText: + 'Scegli una parola BIP39 scrivendola nel campo di input qui sotto o cliccando sulle caselle numeriche (1-2048)', privacyTitle: 'Privacy Protetta', privacyTooltip: 'Questa applicazione viene eseguita interamente nel tuo browser. Nessun dato viene trasmesso, memorizzato o tracciato.', @@ -344,7 +342,6 @@ export const translations: Record = { invalidWordMessage: 'Questa parola non è nella lista BIP39', wordlistLoadError: '⚠️ Impossibile caricare la lista di parole. Ricarica la pagina.', // Word input translations - wordInputLabel: 'Scrivi una parola o clicca sui numeri', wordInputPlaceholder: 'abaco', // Modal translations modalTitle: "Cos'è BIP39?", @@ -401,7 +398,8 @@ export const translations: Record = { languageLabel: 'Idioma', index: 'Índice:', resetButton: 'Reiniciar', - infoText: 'Escolha uma palavra BIP39 digitando-a ou clicando nos números (1-2048).', + infoText: + 'Escolha uma palavra BIP39 digitando-a no campo de entrada abaixo ou clicando nas caixas numéricas (1-2048)', privacyTitle: 'Privacidade Protegida', privacyTooltip: 'Este aplicativo é executado inteiramente no seu navegador. Nenhum dado é transmitido, armazenado ou rastreado.', @@ -411,7 +409,6 @@ export const translations: Record = { invalidWordMessage: 'Esta palavra não está na lista BIP39', wordlistLoadError: '⚠️ Falha ao carregar a lista de palavras. Atualize a página.', // Word input translations - wordInputLabel: 'Digite uma palavra ou clique nos números', wordInputPlaceholder: 'abacate', // Modal translations modalTitle: 'O que é BIP39?', @@ -468,7 +465,7 @@ export const translations: Record = { languageLabel: '言語', index: 'インデックス:', resetButton: 'リセット', - infoText: 'BIP39単語を入力するか、数字をクリックして選択します(1-2048)。', + infoText: 'BIP39単語を下の入力フィールドに入力するか、数字ボックスをクリックして選択します(1-2048)', privacyTitle: 'プライバシー保護', privacyTooltip: 'このアプリケーションはブラウザ内で完全に動作します。データの送信、保存、追跡は一切行われません。', toggleTheme: 'ダークモード/ライトモードを切り替え', @@ -477,7 +474,6 @@ export const translations: Record = { invalidWordMessage: 'この単語はBIP39リストにありません', wordlistLoadError: '⚠️ ワードリストの読み込みに失敗しました。ページを更新してください。', // Word input translations - wordInputLabel: '単語を入力するか、数字をクリック', wordInputPlaceholder: 'あいこくしん', // Modal translations modalTitle: 'BIP39とは?', @@ -534,7 +530,7 @@ export const translations: Record = { languageLabel: '언어', index: '인덱스:', resetButton: '재설정', - infoText: 'BIP39 단어를 입력하거나 숫자를 클릭하여 선택하세요 (1-2048).', + infoText: 'BIP39 단어를 아래 입력 필드에 입력하거나 숫자 상자를 클릭하여 선택하세요 (1-2048)', privacyTitle: '개인정보 보호', privacyTooltip: '이 애플리케이션은 브라우저에서 완전히 실행됩니다. 데이터 전송, 저장 또는 추적이 없습니다.', toggleTheme: '다크 모드/라이트 모드 전환', @@ -543,7 +539,6 @@ export const translations: Record = { invalidWordMessage: '이 단어는 BIP39 목록에 없습니다', wordlistLoadError: '⚠️ 단어 목록을 로드하지 못했습니다. 페이지를 새로고침하세요.', // Word input translations - wordInputLabel: '단어를 입력하거나 숫자를 클릭', wordInputPlaceholder: '가격', // Modal translations modalTitle: 'BIP39란 무엇인가요?', @@ -600,7 +595,7 @@ export const translations: Record = { languageLabel: '语言', index: '索引:', resetButton: '重置', - infoText: '通过输入或点击数字选择 BIP39 单词 (1-2048)。', + infoText: '在下面的输入字段中输入 BIP39 单词或通过点击数字框选择 (1-2048)', privacyTitle: '隐私保护', privacyTooltip: '此应用程序完全在您的浏览器中运行。不会传输、存储或跟踪任何数据。', toggleTheme: '切换深色/浅色模式', @@ -609,7 +604,6 @@ export const translations: Record = { invalidWordMessage: '此单词不在 BIP39 列表中', wordlistLoadError: '⚠️ 加载单词列表失败。请刷新页面。', // Word input translations - wordInputLabel: '输入单词或点击数字', wordInputPlaceholder: '的', // Modal translations modalTitle: '什么是BIP39?', @@ -652,7 +646,7 @@ export const translations: Record = { languageLabel: '語言', index: '索引:', resetButton: '重置', - infoText: '通過輸入或點擊數字選擇 BIP39 單詞 (1-2048)。', + infoText: '在下面的輸入字段中輸入 BIP39 單詞或通過點擊數字框選擇 (1-2048)', privacyTitle: '隱私保護', privacyTooltip: '此應用程序完全在您的瀏覽器中運行。不會傳輸、存儲或跟蹤任何數據。', toggleTheme: '切換深色/淺色模式', @@ -661,7 +655,6 @@ export const translations: Record = { invalidWordMessage: '此單詞不在 BIP39 列表中', wordlistLoadError: '⚠️ 載入單詞列表失敗。請重新整理頁面。', // Word input translations - wordInputLabel: '輸入單詞或點擊數字', wordInputPlaceholder: '的', // Modal translations modalTitle: '什麼是BIP39?', diff --git a/src/modules/language/infrastructure/language.ts b/src/modules/language/infrastructure/language.ts index 44bb6ee..f4c07ee 100644 --- a/src/modules/language/infrastructure/language.ts +++ b/src/modules/language/infrastructure/language.ts @@ -168,7 +168,6 @@ function updateBasicUITranslations(): void { } function updateWordInputTranslations(): void { - elements.wordInputLabel.textContent = currentTranslations.wordInputLabel; elements.wordInput.placeholder = currentTranslations.wordInputPlaceholder; } diff --git a/src/styles/components.css b/src/styles/components.css index 145be09..a5ea935 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -202,9 +202,10 @@ .info-description { color: var(--text-secondary); margin: 0 0 3rem 0; - font-size: 1.15rem; + font-size: 1.4rem; line-height: 1.6; text-align: left; + letter-spacing: 0.05em; } /* Section Styles */ @@ -213,16 +214,6 @@ margin-bottom: 2.5rem; } -.section-title { - font-size: 1.3rem; - font-weight: 600; - color: var(--primary-color); - letter-spacing: 0.05em; - text-transform: uppercase; - margin-bottom: 1.5rem; - text-align: center; -} - /* Visually hidden class for accessibility */ .visually-hidden { position: absolute; @@ -453,8 +444,6 @@ box-shadow: 0 2px 6px rgba(247, 147, 26, 0.2); } -/* Word input label is now section-title */ - .word-input-wrapper { position: relative; width: 100%; diff --git a/src/styles/responsive.css b/src/styles/responsive.css index a229703..3024b60 100644 --- a/src/styles/responsive.css +++ b/src/styles/responsive.css @@ -26,11 +26,6 @@ min-height: 500px; } - .section-title { - font-size: 1rem; - margin-bottom: 1.25rem; - } - .title-section { width: 100%; } @@ -217,11 +212,6 @@ margin-bottom: 1.75rem; } - .section-title { - font-size: 0.9rem; - margin-bottom: 1.25rem; - } - .title-section h1 { font-size: 1.65rem; } @@ -357,10 +347,6 @@ padding: 1.25rem 0.75rem; } - .section-title { - font-size: 0.85rem; - } - .title-section h1 { font-size: 1.5rem; } diff --git a/test/unit/bip39/infrastructure/dom.test.ts b/test/unit/bip39/infrastructure/dom.test.ts index 9aec4de..a24ffb0 100644 --- a/test/unit/bip39/infrastructure/dom.test.ts +++ b/test/unit/bip39/infrastructure/dom.test.ts @@ -74,7 +74,6 @@ describe('DOM Elements', () => { it('should have word input elements defined', () => { expect(elements.wordInput).toBeDefined(); - expect(elements.wordInputLabel).toBeDefined(); expect(elements.wordSuggestions).toBeDefined(); }); diff --git a/test/unit/i18n/domain/i18n.test.ts b/test/unit/i18n/domain/i18n.test.ts index b2aec07..6d67d9b 100644 --- a/test/unit/i18n/domain/i18n.test.ts +++ b/test/unit/i18n/domain/i18n.test.ts @@ -66,7 +66,7 @@ describe('i18n', () => { expect(en.title).toBeDefined(); expect(en.resetButton).toBeDefined(); expect(en.infoText).toBeDefined(); - expect(en.wordInputLabel).toBeDefined(); + expect(en.wordInputPlaceholder).toBeDefined(); expect(en.modalTitle).toBeDefined(); }); });