Items 16-22: Icon classification, accessibility, responsive design, API params
- Consolidate 5 weather icon methods into classifyWeatherIcon/applyWeatherIconClasses - Add focus-visible styles, ARIA attributes, keyboard nav on config button/modal - Add responsive breakpoints for departure cards, weather widget, config modal - Simplify CSS selectors: replace :not(:is(...)) chains with body.normal - Fix upsidedown layout margin assumption with transform-based centering - Upgrade weather icons from @2x to @4x for high-DPI displays - Add forecast window and transport filter params to SL departures API Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,9 @@ class ConfigManager {
|
||||
buttonContainer.id = this.options.configButtonId;
|
||||
buttonContainer.className = 'config-button';
|
||||
buttonContainer.title = 'Settings';
|
||||
buttonContainer.setAttribute('role', 'button');
|
||||
buttonContainer.setAttribute('aria-label', 'Open settings');
|
||||
buttonContainer.setAttribute('tabindex', '0');
|
||||
|
||||
buttonContainer.innerHTML = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
@@ -76,6 +79,12 @@ class ConfigManager {
|
||||
`;
|
||||
|
||||
buttonContainer.addEventListener('click', () => this.toggleConfigModal());
|
||||
buttonContainer.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
this.toggleConfigModal();
|
||||
}
|
||||
});
|
||||
document.body.appendChild(buttonContainer);
|
||||
}
|
||||
|
||||
@@ -88,6 +97,9 @@ class ConfigManager {
|
||||
modalContainer.id = this.options.configModalId;
|
||||
modalContainer.className = 'config-modal';
|
||||
modalContainer.style.display = 'none';
|
||||
modalContainer.setAttribute('role', 'dialog');
|
||||
modalContainer.setAttribute('aria-label', 'Settings');
|
||||
modalContainer.setAttribute('aria-modal', 'true');
|
||||
|
||||
// Clone the template content into the modal
|
||||
modalContainer.appendChild(template.content.cloneNode(true));
|
||||
@@ -122,7 +134,14 @@ class ConfigManager {
|
||||
this.setupTabs(modalContainer);
|
||||
|
||||
// Add event listeners
|
||||
modalContainer.querySelector('.config-modal-close').addEventListener('click', () => this.hideConfigModal());
|
||||
const closeBtn = modalContainer.querySelector('.config-modal-close');
|
||||
closeBtn.addEventListener('click', () => this.hideConfigModal());
|
||||
closeBtn.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
this.hideConfigModal();
|
||||
}
|
||||
});
|
||||
modalContainer.querySelector('#config-cancel-button').addEventListener('click', () => this.hideConfigModal());
|
||||
modalContainer.querySelector('#config-save-button').addEventListener('click', () => this.saveAndApplyConfig());
|
||||
modalContainer.querySelector('#test-image-button').addEventListener('click', () => {
|
||||
@@ -277,6 +296,8 @@ class ConfigManager {
|
||||
hideConfigModal() {
|
||||
const modal = document.getElementById(this.options.configModalId);
|
||||
modal.style.display = 'none';
|
||||
const configButton = document.getElementById(this.options.configButtonId);
|
||||
if (configButton) configButton.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,6 +306,8 @@ class ConfigManager {
|
||||
showConfigModal() {
|
||||
const modal = document.getElementById(this.options.configModalId);
|
||||
modal.style.display = 'flex';
|
||||
const closeBtn = modal.querySelector('.config-modal-close');
|
||||
if (closeBtn) closeBtn.focus();
|
||||
|
||||
// Reset to first tab
|
||||
const tabs = modal.querySelectorAll('.config-tab');
|
||||
|
||||
Reference in New Issue
Block a user