chore: consolidate platform split checks
Some checks failed
Dependency Audit / dependency-audit (push) Has been cancelled
Module Matrix / module-matrix (push) Has been cancelled

This commit is contained in:
2026-07-10 12:51:19 +02:00
parent 150b720f12
commit 635d25c74c
216 changed files with 23336 additions and 4077 deletions

View File

@@ -1,4 +1,4 @@
import { useEffect, useId, useMemo, useRef, useState } from "react";
import { i18nMessage } from "../../i18n/LanguageContext";import { useEffect, useId, useMemo, useRef, useState } from "react";
import type { CSSProperties, KeyboardEvent } from "react";
import { createPortal } from "react-dom";
import Button from "../Button";
@@ -8,8 +8,8 @@ import {
isValidEmailAddress,
normalizeEmailAddress,
parseMailboxAddressText,
type MailboxAddress
} from "../../utils/emailAddresses";
type MailboxAddress } from
"../../utils/emailAddresses";
type EmailAddressInputProps = {
value: MailboxAddress[];
@@ -35,10 +35,10 @@ export default function EmailAddressInput({
allowMultiple = true,
clearOnAdd = false,
disabled = false,
addLabel = "Add",
namePlaceholder = "Name",
addLabel = "i18n:govoplan-core.add.61cc55aa",
namePlaceholder = "i18n:govoplan-core.name.709a2322",
emailPlaceholder = "email@example.org",
emptyText = "No address added yet.",
emptyText = "i18n:govoplan-core.no_address_added_yet.809c4247",
compact = false,
showAddButton
}: EmailAddressInputProps) {
@@ -57,9 +57,9 @@ export default function EmailAddressInput({
const filteredSuggestions = useMemo(() => {
const query = entryText.trim().toLowerCase();
if (!query) return normalizedSuggestions.slice(0, 6);
return normalizedSuggestions
.filter((item) => `${item.name ?? ""} ${item.email}`.toLowerCase().includes(query))
.slice(0, 6);
return normalizedSuggestions.
filter((item) => `${item.name ?? ""} ${item.email}`.toLowerCase().includes(query)).
slice(0, 6);
}, [entryText, normalizedSuggestions]);
useEffect(() => {
@@ -103,17 +103,17 @@ export default function EmailAddressInput({
function commitAddress(candidate: MailboxAddress | null, sourceText = "") {
if (disabled) return false;
if (!candidate?.email) {
setError(sourceText ? "Use a valid address such as Name <email@example.org>." : "Enter an email address first.");
setError(sourceText ? "i18n:govoplan-core.use_a_valid_address_such_as_name_email_example_o.39cdbc3c" : "i18n:govoplan-core.enter_an_email_address_first.6d55dfd1");
return false;
}
const normalized = normalizeEmailAddress(candidate);
if (!isValidEmailAddress(normalized.email)) {
setError("Enter a valid email address.");
setError("i18n:govoplan-core.enter_a_valid_email_address.2e09edea");
return false;
}
if (allowMultiple && normalizedValue.some((address) => address.email === normalized.email)) {
setError("This address is already listed.");
setError("i18n:govoplan-core.this_address_is_already_listed.0f6d0ff2");
return false;
}
@@ -166,19 +166,19 @@ export default function EmailAddressInput({
aria-labelledby={`${inputId}-dialog-title`}
onKeyDown={(event) => {
if (event.key === "Escape") setDialogOpen(false);
}}
>
<h4 id={`${inputId}-dialog-title`}>Add address</h4>
}}>
<h4 id={`${inputId}-dialog-title`}>i18n:govoplan-core.add_address.a71075c4</h4>
<label>
<span>Name</span>
<span>i18n:govoplan-core.name.709a2322</span>
<input value={dialogName} onChange={(event) => setDialogName(event.target.value)} placeholder={namePlaceholder} autoFocus />
</label>
<label>
<span>Email address</span>
<span>i18n:govoplan-core.email_address.c94d3175</span>
<input value={dialogEmail} onChange={(event) => setDialogEmail(event.target.value)} placeholder={emailPlaceholder} inputMode="email" />
</label>
<div className="button-row compact-actions">
<Button type="button" onClick={() => setDialogOpen(false)}>Cancel</Button>
<Button type="button" onClick={() => setDialogOpen(false)}>i18n:govoplan-core.cancel.77dfd213</Button>
<Button type="button" variant="primary" onClick={commitDialogAddress}>{addLabel}</Button>
</div>
</div>,
@@ -193,54 +193,54 @@ export default function EmailAddressInput({
{normalizedValue.map((address) => {
const valid = isValidEmailAddress(address.email);
return (
<span className={`email-chip ${valid ? "" : "invalid"}`} key={address.email} title={valid ? address.email : "Invalid email address"}>
<span className={`email-chip ${valid ? "" : "invalid"}`} key={address.email} title={valid ? address.email : "i18n:govoplan-core.invalid_email_address.9e4ee6d7"}>
<span className="email-chip-main">{addressDisplayName(address)}</span>
{address.name && <span className="email-chip-address">{address.email}</span>}
{!disabled && (
<button type="button" className="email-chip-remove" aria-label={`Remove ${address.email}`} onClick={() => removeAddress(address.email)}>
{!disabled &&
<button type="button" className="email-chip-remove" aria-label={i18nMessage("i18n:govoplan-core.remove_value.a2d40d33", { value0: address.email })} onClick={() => removeAddress(address.email)}>
×
</button>
)}
</span>
);
}
</span>);
})}
</div>
{!disabled && (
<>
{!disabled &&
<>
<textarea
id={inputId}
className="email-address-textarea"
rows={1}
value={entryText}
onChange={(event) => {
setEntryText(event.target.value);
setError("");
}}
onKeyDown={handleTextKeyDown}
placeholder={`${namePlaceholder} <${emailPlaceholder}>`}
aria-label="Type a name and email address, then press Enter"
/>
{canUseAddButton && (
<button ref={addButtonRef} type="button" className="email-address-plus" aria-label="Open address form" title="Add address with form" onClick={() => setDialogOpen((open) => !open)}>
id={inputId}
className="email-address-textarea"
rows={1}
value={entryText}
onChange={(event) => {
setEntryText(event.target.value);
setError("");
}}
onKeyDown={handleTextKeyDown}
placeholder={i18nMessage("i18n:govoplan-core.value_value.27085f09", { value0: namePlaceholder, value1: emailPlaceholder })}
aria-label="i18n:govoplan-core.type_a_name_and_email_address_then_press_enter.7c8d43f0" />
{canUseAddButton &&
<button ref={addButtonRef} type="button" className="email-address-plus" aria-label="i18n:govoplan-core.open_address_form.f8ee560f" title="i18n:govoplan-core.add_address_with_form.13b3b3e7" onClick={() => setDialogOpen((open) => !open)}>
+
</button>
)}
}
</>
)}
}
</div>
{!disabled && filteredSuggestions.length > 0 && entryText.trim() && (
<div className="email-address-suggestions" role="listbox" aria-label="Address suggestions">
{filteredSuggestions.map((item) => (
<button type="button" key={item.email} onClick={() => applySuggestion(item)} role="option">
{!disabled && filteredSuggestions.length > 0 && entryText.trim() &&
<div className="email-address-suggestions" role="listbox" aria-label="i18n:govoplan-core.address_suggestions.45ba4a20">
{filteredSuggestions.map((item) =>
<button type="button" key={item.email} onClick={() => applySuggestion(item)} role="option">
<span>{addressDisplayName(item)}</span>
{item.name && <small>{item.email}</small>}
</button>
))}
)}
</div>
)}
}
{error && <p className="form-help danger-text">{error}</p>}
{addressDialog}
</div>
);
</div>);
}