mirror of
https://github.com/we-promise/sure.git
synced 2026-07-12 21:05:20 +00:00
* fix(charts): restyle hover tooltips with soft shadow + larger radius Match the elevation pattern of DS::Select dropdown (shadow-lg + shadow-border-xs) and increase radius (rounded-lg → rounded-xl) + padding (p-2 → p-3) for better breathing. Drops the hard border in favour of the soft drop shadow. time_series_chart_controller: - p-2 → p-3, rounded-lg → rounded-xl - remove border border-secondary - add shadow-lg shadow-border-xs (theme-aware drop + border-edge) - add explicit text-primary (was missing per #2011's drift note) - add z-50 (matches goal_projection + sankey controllers) sankey_chart_controller: - bg-gray-700 text-white → bg-container text-primary (theme-aware; was broken in light mode after dark-bg flip) - p-2 rounded → p-3 rounded-xl - add shadow-lg shadow-border-xs - add font-sans for consistency with the other chart tooltips - add privacy-sensitive class (was missing — sankey money values were rendered in the clear with privacy mode on) DS::Tooltip (icon-trigger help, bg-inverse) is intentionally a different primitive and is not touched. Refs #2011 — className consolidation into a shared module is tracked separately and intentionally not closed by this PR; the new string applies to two of the three call sites today (time_series, sankey). The third (goal_projection_chart_controller) lives on the feat/goals-v2-architecture branch and will adopt the same string when goals v2 merges. * fix(charts): align every chart tooltip on the borderless soft-shadow card One visual contract for all three D3 tooltip surfaces, matching the design reference: p-4, rounded-2xl, shadow-xl, no edge ring in light mode. Dark mode keeps a 1px alpha-white ring since a shadow alone disappears against dark surfaces. - goal_projection_chart_controller drops its hand-copied class string (it still carried the old bordered recipe — the drift this util exists to prevent) and builds its two lines through the shared factory: secondary date line, tabular value line. - New content conventions exported alongside the container contract: context line = text-xs text-secondary, values = font-medium tabular-nums. Time-series and sankey adopt them. - Sankey node titles now escape before .html(); user-named categories were previously interpolated raw into the tooltip markup. * fix(charts): match the tooltip surface to the design reference exactly The previous pass approximated the reference with utility guesses (rounded-2xl, p-4, shadow-xl, dark ring). The actual spec is a hairline border ring composed with a soft 0 8px 24px drop shadow, 10px radius, 12x14 padding, and an 80ms left/top glide. Tailwind shadow utilities can't compose a ring with a custom drop shadow, so the surface moves into the design system as .chart-tooltip (theme-aware: dark swaps the ring to alpha-white and lets it carry the edge). Money/numeric figures also pick up the reference's mono treatment: font-mono + tabular-nums on every value across time-series, sankey, and goal-projection, so digits don't jitter while the scrubber moves. * fix(charts): tighten tooltip padding to 10x12 * feat(charts): give sankey and goal tooltips their missing context rows Chart tooltips answer three stacked questions: context (what am I looking at), value (how much), relation (vs what). Time-series already had all three; the other two were missing rows. - Sankey links showed a bare "$X (Y%)" with no indication of which flow was hovered. Links now lead with a swatch-dotted "Source → Target" context line; nodes get the same dot + name treatment, tying the card to the ribbon color. The context builder escapes node names centrally (they're user-named categories). - Goal projection adds a tertiary relation line — "52% of $20K target" — computed from the payload the chart already carries, for both the saved and projected segments. Hidden when the goal has no positive target. Template is i18n-wired like the existing tooltip strings (goals.show.projection.tooltip_target_relation). Verified with Playwright against the running app: all three surfaces pass computed-style and content assertions. * fix(charts): drop the color dot from sankey tooltip context The hover highlight on the diagram already identifies the ribbon; the swatch repeated it inside the card. Names alone keep the context line quieter. * fix(charts): use the app's sans money treatment in tooltips, not mono font-mono in this codebase marks code, keys, and admin surfaces; money is sans + tabular-nums everywhere else (cards, KPIs, tables). Keep the tabular figures for scrub stability, drop the mono. * fix(charts): address review — glide opt-in, no shadowed var, truncate cap - The 80ms left/top transition moved out of .chart-tooltip: it eased the snap-positioned goal tooltip but made cursor-following tooltips (sankey, time-series) trail the pointer by a frame. Goal projection opts back in via inline style; the component comment documents the split. - setRelation reuses _draw()'s targetAmount const instead of declaring a local 'target' that shadowed the target-date const. - Sankey context line gets max-w-64 so truncate has a constraint to fire against on deep flows. - Component comment now says 10x12 padding, matching the declaration. * Revert `schema.rb` changes --------- Co-authored-by: Juan José Mata <jjmata@jjmata.com>
40 lines
2.2 KiB
JavaScript
40 lines
2.2 KiB
JavaScript
// Single source of truth for the cursor-following tooltip used by the chart
|
|
// controllers (time-series, sankey, and goal-projection once it lands from the
|
|
// goals work). Keeping the visual contract here stops the bg / text / border /
|
|
// privacy-sensitive classes from drifting apart across the controllers, the way
|
|
// they had before (time-series was missing `text-primary` and `z-50`).
|
|
//
|
|
// This is the VISUAL contract only. Callers append their own behavioural
|
|
// classes (initial `opacity-0`, `top-0`, …) or set them via inline styles,
|
|
// because how each chart shows/hides and positions its tooltip differs.
|
|
//
|
|
// Not to be confused with DS::Tooltip — that is the info-icon hint primitive
|
|
// (bg-inverse, aria-describedby, anchored to a static trigger). This is a
|
|
// data-card surface created and updated inside D3 handler code.
|
|
// The surface itself lives in the design system as `.chart-tooltip`
|
|
// (sure-design-system/components.css): container bg, 10px radius, 12x14
|
|
// padding, hairline ring composed with a soft 8/24 drop shadow, 80ms
|
|
// left/top glide. It's a component class because Tailwind shadow utilities
|
|
// can't compose a ring with a custom drop shadow. This constant adds the
|
|
// behavioural classes shared by every chart tooltip.
|
|
export const CHART_TOOLTIP_CLASSES =
|
|
"chart-tooltip text-primary text-sm font-sans absolute pointer-events-none z-50 privacy-sensitive";
|
|
|
|
// Content conventions (kept here so the controllers stay aligned):
|
|
// - context line (date / node title): `text-xs text-secondary mb-1`
|
|
// - money / numeric figures: tabular-nums so digits don't jitter while the
|
|
// scrubber moves (sans, not mono — the app's money convention everywhere
|
|
// else); secondary parentheticals in `text-secondary`
|
|
export const CHART_TOOLTIP_CONTEXT_CLASSES = "text-xs text-secondary mb-1";
|
|
export const CHART_TOOLTIP_VALUE_CLASSES = "font-medium tabular-nums";
|
|
|
|
// Convenience factory for the raw-DOM idiom (no d3.select). Creates a hidden
|
|
// tooltip div carrying the shared contract and appends it to `parent`.
|
|
export function createChartTooltip(parent) {
|
|
const tooltip = document.createElement("div");
|
|
tooltip.className = CHART_TOOLTIP_CLASSES;
|
|
tooltip.style.display = "none";
|
|
parent.appendChild(tooltip);
|
|
return tooltip;
|
|
}
|