Files
sure/app/components/DS/dialog_controller.js
Guillem Arias 45b2701b4a fix(savings_goals): ring on_track color, contributions horizontal scroll, modal restored on back, chart saved fill
Ring on on_track / no_target_date goal cards rendered with no progress
arc — ring_color returned var(--text-primary) / var(--text-subdued)
which aren't real CSS custom properties (Sure's text tokens are Tailwind
utilities). Switch to var(--color-green-500) / var(--color-gray-400)
which ARE CSS vars from the Tailwind palette and resolve at SVG fill
time.

Contributions list had a horizontal scrollbar because the rows used
-mx-3 px-3 to extend the hover background, which pushed content beyond
the card padding. Drop the negative-margin trick and add
overflow-x-hidden to the scroll container. Rows still hover-highlight
inside the card bounds.

Modal cache restoration — Turbo cached pages with open <dialog> elements
inside <turbo-frame id="modal">. After dismissing the new-goal modal
and navigating to a goal detail page, browser back restored the cached
index page WITH the dialog still in the modal frame; the dialog's
Stimulus controller then ran auto-open and reopened it. Now the dialog
close handler empties the parent modal turbo-frame so the cache
snapshot is clean.

Chart saved-fill — bump area gradient stop-opacity 0.10 → 0.22 so the
contribution history is more visible against the dark canvas. Chart
was rendering correctly but the white-at-10%-opacity gradient was too
faint to read on top of the dashed projection.
2026-05-11 16:44:45 +02:00

45 lines
1.2 KiB
JavaScript

import { Controller } from "@hotwired/stimulus";
// Connects to data-controller="dialog"
export default class extends Controller {
static targets = ["content"]
static values = {
autoOpen: { type: Boolean, default: false },
reloadOnClose: { type: Boolean, default: false },
disableClickOutside: { type: Boolean, default: false },
};
connect() {
if (this.element.open) return;
if (this.autoOpenValue) {
this.element.showModal();
}
}
// If the user clicks anywhere outside of the visible content, close the dialog
clickOutside(e) {
if (this.disableClickOutsideValue) return;
if (!this.contentTarget.contains(e.target)) {
this.close();
}
}
close() {
this.element.close();
this.#clearParentModalFrame();
if (this.reloadOnCloseValue) {
Turbo.visit(window.location.href);
}
}
// When the dialog lives inside a top-level <turbo-frame id="modal">,
// emptying the frame on close stops Turbo's page cache from snapshotting
// an open dialog and reopening it on browser back.
#clearParentModalFrame() {
const frame = this.element.closest('turbo-frame[id="modal"]');
if (frame) frame.innerHTML = "";
}
}