mirror of
https://github.com/simonw/datasette.git
synced 2026-09-28 21:04:08 +02:00
Refactor mobile column actions to use the shared modal, refs #2790
This commit is contained in:
parent
328b2e6c6f
commit
17b19b4d27
3 changed files with 9 additions and 121 deletions
|
|
@ -982,61 +982,13 @@ p.zero-results {
|
|||
}
|
||||
|
||||
dialog.mobile-column-actions-dialog {
|
||||
--ink: #0f0f0f;
|
||||
--paper: #eef6ff;
|
||||
--muted: #6b6b6b;
|
||||
--rule: #d8e6f5;
|
||||
--accent: #1a56db;
|
||||
--card: #ffffff;
|
||||
border: none;
|
||||
border-radius: var(--modal-border-radius, 0.75rem);
|
||||
padding: 0;
|
||||
margin: auto;
|
||||
width: min(420px, calc(100vw - 32px));
|
||||
max-width: 95vw;
|
||||
max-height: min(640px, calc(100vh - 32px));
|
||||
box-shadow: var(--modal-shadow, 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04));
|
||||
animation: datasette-modal-slide-in var(--modal-animation-duration, 0.2s) ease-out;
|
||||
overflow: hidden;
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
background: var(--card);
|
||||
}
|
||||
|
||||
dialog.mobile-column-actions-dialog[open] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
dialog.mobile-column-actions-dialog::backdrop {
|
||||
background: var(--modal-backdrop-bg, rgba(0, 0, 0, 0.5));
|
||||
backdrop-filter: var(--modal-backdrop-blur, blur(4px));
|
||||
-webkit-backdrop-filter: var(--modal-backdrop-blur, blur(4px));
|
||||
animation: datasette-modal-fade-in var(--modal-animation-duration, 0.2s) ease-out;
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .modal-header {
|
||||
padding: 20px 24px 16px;
|
||||
border-bottom: 1px solid var(--rule);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .modal-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .modal-meta {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.7rem;
|
||||
color: var(--muted);
|
||||
background: var(--paper);
|
||||
padding: 3px 9px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .list-wrap {
|
||||
|
|
@ -1169,46 +1121,6 @@ dialog.mobile-column-actions-dialog::backdrop {
|
|||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .modal-footer {
|
||||
padding: 14px 20px;
|
||||
border-top: 1px solid var(--rule);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
background: var(--paper);
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .footer-info {
|
||||
flex: 1;
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 0.68rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .btn {
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
padding: 9px 20px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
font-family: inherit;
|
||||
transition: background 0.12s;
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
border: 1px solid var(--rule);
|
||||
}
|
||||
|
||||
.mobile-column-actions-dialog .btn-ghost:hover {
|
||||
background: var(--rule);
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
dialog.set-column-type-dialog {
|
||||
--ink: #0f0f0f;
|
||||
--paper: #eef6ff;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ function initMobileColumnActions(manager) {
|
|||
return;
|
||||
}
|
||||
|
||||
var dialog = document.createElement("dialog");
|
||||
var modal = DatasetteModal.create();
|
||||
var dialog = modal.dialog;
|
||||
dialog.className = "mobile-column-actions-dialog";
|
||||
dialog.id = MOBILE_COLUMN_DIALOG_ID;
|
||||
dialog.setAttribute("aria-labelledby", MOBILE_COLUMN_DIALOG_TITLE_ID);
|
||||
|
|
@ -78,10 +79,10 @@ function initMobileColumnActions(manager) {
|
|||
<div class="list-wrap mobile-column-list"></div>
|
||||
<div class="modal-footer">
|
||||
<span class="footer-info">Tap a column to reveal actions.</span>
|
||||
<button type="button" class="btn btn-ghost mobile-column-actions-done">Done</button>
|
||||
<button type="button" class="modal-btn modal-btn-ghost mobile-column-actions-done">Done</button>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(dialog);
|
||||
document.body.appendChild(modal);
|
||||
|
||||
triggerButton.setAttribute("aria-haspopup", "dialog");
|
||||
triggerButton.setAttribute("aria-controls", MOBILE_COLUMN_DIALOG_ID);
|
||||
|
|
@ -91,7 +92,6 @@ function initMobileColumnActions(manager) {
|
|||
var listWrap = dialog.querySelector(".mobile-column-list");
|
||||
var doneButton = dialog.querySelector(".mobile-column-actions-done");
|
||||
var expandedSectionId = null;
|
||||
var shouldRestoreFocus = true;
|
||||
|
||||
function updateExpandedSection() {
|
||||
Array.from(dialog.querySelectorAll(".col-header")).forEach((button) => {
|
||||
|
|
@ -128,16 +128,7 @@ function initMobileColumnActions(manager) {
|
|||
}
|
||||
|
||||
function closeDialog(options) {
|
||||
options = options || {};
|
||||
shouldRestoreFocus = options.restoreFocus !== false;
|
||||
if (dialog.open) {
|
||||
dialog.close();
|
||||
} else {
|
||||
triggerButton.setAttribute("aria-expanded", "false");
|
||||
if (shouldRestoreFocus) {
|
||||
triggerButton.focus();
|
||||
}
|
||||
}
|
||||
modal.close(options);
|
||||
}
|
||||
|
||||
function renderDialog() {
|
||||
|
|
@ -166,7 +157,8 @@ function initMobileColumnActions(manager) {
|
|||
topActions.className = "mobile-column-top-actions";
|
||||
|
||||
var showAllColumns = document.createElement("a");
|
||||
showAllColumns.className = "btn btn-ghost mobile-column-top-action";
|
||||
showAllColumns.className =
|
||||
"modal-btn modal-btn-ghost mobile-column-top-action";
|
||||
showAllColumns.href = manager.columnActions.showAllColumnsUrl();
|
||||
showAllColumns.textContent = "Show all columns";
|
||||
|
||||
|
|
@ -265,9 +257,7 @@ function initMobileColumnActions(manager) {
|
|||
if (!renderDialog()) {
|
||||
return;
|
||||
}
|
||||
if (!dialog.open) {
|
||||
dialog.showModal();
|
||||
}
|
||||
modal.show({ trigger: triggerButton });
|
||||
triggerButton.setAttribute("aria-expanded", "true");
|
||||
var focusTarget =
|
||||
dialog.querySelector(".mobile-column-top-action") ||
|
||||
|
|
@ -288,22 +278,8 @@ function initMobileColumnActions(manager) {
|
|||
closeDialog();
|
||||
});
|
||||
|
||||
dialog.addEventListener("click", function (ev) {
|
||||
if (ev.target === dialog) {
|
||||
closeDialog();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.addEventListener("cancel", function (ev) {
|
||||
ev.preventDefault();
|
||||
closeDialog();
|
||||
});
|
||||
|
||||
dialog.addEventListener("close", function () {
|
||||
triggerButton.setAttribute("aria-expanded", "false");
|
||||
if (shouldRestoreFocus) {
|
||||
triggerButton.focus();
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("resize", function () {
|
||||
|
|
|
|||
|
|
@ -1763,7 +1763,7 @@ def test_modal_lifecycle(page, datasette_server, shadow):
|
|||
|
||||
|
||||
@pytest.mark.playwright
|
||||
@pytest.mark.parametrize("name", ["jump", "columns"])
|
||||
@pytest.mark.parametrize("name", ["jump", "columns", "mobile"])
|
||||
def test_modal_consumers_dismiss_and_restore_focus(page, datasette_server, name):
|
||||
from playwright.sync_api import expect
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue