Check component props for untranslated literals, and fail on a finding
i18n-literals checked title, aria-label, placeholder and alt on elements, but not the same English passed to a component, so a MenuItem label or a Popover ariaLabel written as a literal went through. It also excused a literal that happened to be a catalogue key. That exemption is meant for English held in a constant and translated where it renders, and a literal written straight into a JSX attribute has no such render site. No component passes its props through t(). And neither half of i18n:check was run with --check, so a finding printed and the script still exited 0. Component props are checked now, a key no longer excuses a literal in an attribute, and both scripts run with --check. That found 28 strings rendering English in every language: 19 already had keys and are wrapped, and 9 are new keys in all nine catalogues. The contact editor's Save and Saving… buttons are wrapped as well, on the same line.
This commit is contained in:
@@ -245,17 +245,17 @@ export function ThreadView({ threadId, mailboxId, onBack, actions, onNavigate, h
|
||||
<ArrowLeft size={20} />
|
||||
</button>
|
||||
<button className="icon-btn" title={t("Archive (e)")} onClick={() => void actions.archive(rowIds)}><Archive size={19} /></button>
|
||||
<button className="icon-btn" title={inJunk ? "Not spam" : "Report spam (!)"} onClick={() => void actions.spam(rowIds)}>{inJunk ? <ShieldCheck size={19} /> : <AlertOctagon size={19} />}</button>
|
||||
<button className="icon-btn" title={inJunk ? t("Not spam") : t("Report spam (!)")} onClick={() => void actions.spam(rowIds)}>{inJunk ? <ShieldCheck size={19} /> : <AlertOctagon size={19} />}</button>
|
||||
<button className="icon-btn" title={t("Delete (#)")} onClick={() => void actions.trash(rowIds)}><Trash2 size={19} /></button>
|
||||
<span className="tb-sep hide-mobile" />
|
||||
<button className="icon-btn hide-mobile" title={anyUnread ? "Mark as read" : "Mark as unread"} onClick={() => void actions.read(anyUnread, rowIds)}>{anyUnread ? <MailOpen size={19} /> : <Mail size={19} />}</button>
|
||||
<button className="icon-btn hide-mobile" title={anyUnread ? t("Mark as read") : t("Mark as unread")} onClick={() => void actions.read(anyUnread, rowIds)}>{anyUnread ? <MailOpen size={19} /> : <Mail size={19} />}</button>
|
||||
<button className="icon-btn hide-mobile" title={t("Move to (v)")} onClick={() => actions.move(rowIds)}><FolderInput size={19} /></button>
|
||||
<button className="icon-btn hide-mobile" title={t("Labels (l)")} onClick={(e) => setLabelAnchor({ x: e.clientX, y: e.clientY })}><Tag size={19} /></button>
|
||||
<button className="icon-btn" onClick={moreMenu.open} aria-label={t("More")}><MoreVertical size={19} /></button>
|
||||
<Popover anchor={moreMenu.anchor} onClose={moreMenu.close} align="start" width={240}>
|
||||
<MenuItem icon={<Star size={16} />} label={anyStarred ? "Remove star" : "Add star"} onClick={() => void actions.star(!anyStarred, rowIds)} />
|
||||
<MenuItem icon={<Star size={16} />} label={anyStarred ? t("Remove star") : t("Add star")} onClick={() => void actions.star(!anyStarred, rowIds)} />
|
||||
<MenuItem icon={<Tag size={16} />} label={t("Label…")} onClick={() => setLabelAnchor({ x: window.innerWidth / 2, y: 100 })} />
|
||||
<MenuItem icon={allExpanded ? <ChevronUp size={16} /> : <ChevronDown size={16} />} label={allExpanded ? "Collapse all" : "Expand all"} onClick={() => { setAllExpanded((v) => !v); setExpanded({}); }} />
|
||||
<MenuItem icon={allExpanded ? <ChevronUp size={16} /> : <ChevronDown size={16} />} label={allExpanded ? t("Collapse all") : t("Expand all")} onClick={() => { setAllExpanded((v) => !v); setExpanded({}); }} />
|
||||
<MenuSep />
|
||||
<MenuItem icon={<Printer size={16} />} label={t("Print conversation")} onClick={() => window.print()} />
|
||||
{last && accountId && (
|
||||
|
||||
Reference in New Issue
Block a user