fix email settings: missing providers, a11y, no-JS support
show all 10 providers in three groups (popular, transactional, advanced) with category headings. fix phx-change clobbering text fields, async test email sending state, integer parse crash on bad port. add keyboard focus on card radios, fieldset legend, WCAG-compliant badge contrast, responsive grid. extract shared save_config into Mailer, add no-JS controller fallback with configured_adapter hidden field for adapter change detection. remove CardRadioScroll JS hook (no longer needed). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1459,6 +1459,10 @@
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
|
||||
@media (max-width: 30rem) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.card-radio-card {
|
||||
@@ -1483,6 +1487,11 @@
|
||||
background: color-mix(in oklch, var(--t-surface-sunken) 50%, transparent);
|
||||
}
|
||||
|
||||
&:has(:focus-visible) {
|
||||
outline: 2px solid var(--t-accent, oklch(0.55 0.2 250));
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&.card-radio-card-selected {
|
||||
border-color: var(--t-text-primary, #171717);
|
||||
background: var(--t-surface-sunken, #e5e5e5);
|
||||
@@ -4272,7 +4281,7 @@
|
||||
}
|
||||
|
||||
.card-radio-recommended {
|
||||
background: var(--admin-accent, oklch(0.65 0.2 145));
|
||||
background: oklch(0.45 0.15 145);
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -4338,6 +4347,29 @@
|
||||
color: var(--t-status-error, oklch(0.6 0.2 25));
|
||||
}
|
||||
|
||||
/* ── Provider group headings ── */
|
||||
|
||||
.card-radio-group-heading {
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
color: var(--admin-text-primary);
|
||||
margin: 1rem 0 0;
|
||||
}
|
||||
|
||||
.card-radio-group-heading:first-of-type {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.card-radio-group-desc {
|
||||
font-size: 0.75rem;
|
||||
color: var(--admin-text-muted);
|
||||
margin: 0.125rem 0 0;
|
||||
}
|
||||
|
||||
.card-radio-group-hint {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ── Email adapter config ── */
|
||||
|
||||
.admin-adapter-config {
|
||||
@@ -4345,10 +4377,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
|
||||
&[hidden] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Campaign form ── */
|
||||
|
||||
@@ -507,28 +507,6 @@ const CollectionFilters = {
|
||||
}
|
||||
}
|
||||
|
||||
const CardRadioScroll = {
|
||||
mounted() {
|
||||
this.el.addEventListener("change", (e) => {
|
||||
if (!e.target.matches('input[type="radio"]')) return
|
||||
const key = e.target.value
|
||||
const form = this.el.closest("form")
|
||||
if (!form) return
|
||||
|
||||
form.querySelectorAll("[data-adapter]").forEach((section) => {
|
||||
const match = section.dataset.adapter === key
|
||||
section.hidden = !match
|
||||
section.querySelectorAll("input, textarea, select, button[type='submit']").forEach((input) => {
|
||||
input.disabled = !match
|
||||
})
|
||||
})
|
||||
|
||||
const target = document.getElementById(`adapter-config-${key}`)
|
||||
if (target) target.scrollIntoView({ behavior: "smooth", block: "nearest" })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Analytics export: reads the current period and filters from the DOM at click time
|
||||
// so the download URL is always correct, even if clicked before the LiveView re-render.
|
||||
const AnalyticsExport = {
|
||||
@@ -704,7 +682,7 @@ const EditorKeyboard = {
|
||||
const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||
const liveSocket = new LiveSocket("/live", Socket, {
|
||||
params: {_csrf_token: csrfToken, screen_width: window.innerWidth},
|
||||
hooks: {...colocatedHooks, ColorSync, Lightbox, CartPersist, CartDrawer, ProductImageScroll, SearchModal, CollectionFilters, CardRadioScroll, AnalyticsInit, AnalyticsExport, ChartTooltip, DirtyGuard, EditorKeyboard},
|
||||
hooks: {...colocatedHooks, ColorSync, Lightbox, CartPersist, CartDrawer, ProductImageScroll, SearchModal, CollectionFilters, AnalyticsInit, AnalyticsExport, ChartTooltip, DirtyGuard, EditorKeyboard},
|
||||
})
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
|
||||
Reference in New Issue
Block a user