ModalChrome

NAME

App::Moneymoor::View::ModalChrome - the one canonical set of Selkie::Styles every modal, dialog and settings pane paints its chrome with.

DESCRIPTION

Modals are built fresh on every open, and each one used to hand-roll its own bold-blue title, grey label and dim italic hint from raw hex literals. Six copies of the same three values meant two things: the modals were frozen on a pseudo-TokyoNight palette no matter which of the eleven themes the user picked, and "make hints a touch dimmer" was a six-file change that would inevitably miss one.

modal-styles replaces those literals with one theme-derived bundle. Every entry is a semantic role, not a colour: pick the role that describes what the text is and the palette decides what it looks like.

ROLES

  • title โ€” the modal's own heading. Palette accent, bold: the one place in a modal that gets the theme's signature hue.

  • label โ€” a field caption ("Project", "Duration"). Reads at full fg-base weight because the user has to scan these to find the field they want.

  • dim โ€” supporting body copy that is present but not shouting: the grammar / syntax explainer walls, read-only context lines. fg-dim.

  • hint โ€” the trailing key-hint line ("Enter save ยท Esc cancel"). fg-dim plus italic โ€” the italic keeps it behind label in the hierarchy without dropping to fg-dimmer, which in several palettes (Nord's canonical comment grey most of all) falls under 1.5:1 contrast against bg-base and renders the hint effectively invisible. hint and dim text never sit adjacent in practice, so sharing the hue costs nothing.

  • warn โ€” a consequence the user should read before acting (the login screen's "there is no passphrase reset"). fg-amber, italic.

  • error โ€” a failed action or invalid input. fg-red.

EXAMPLES

The whole bundle at once, destructured into the names the modal's build method already used:


use App::Moneymoor::View::ModalChrome;

method build(App::Moneymoor::Theme :$theme! --> Selkie::Widget::Modal) {
    my %styles = modal-styles(:$theme);

    $content.add: Selkie::Widget::Text.new(
        text => ' Edit task', sizing => Sizing.fixed(1),
        style => %styles<title>,
    );
    $content.add: Selkie::Widget::Text.new(
        text => ' Title', sizing => Sizing.fixed(1),
        style => %styles<label>,
    );
    $content.add: Selkie::Widget::Text.new(
        text => ' Enter save ยท Esc cancel', sizing => Sizing.fixed(1),
        style => %styles<hint>,
    );
}

The returned styles are plain Selkie::Style objects โ€” immutable value types โ€” so a modal can safely hand the same one to a dozen Text widgets, and a caller that wants a variation merges rather than mutates:


my %styles = modal-styles(:$theme);
my $bold-label = %styles<label>.merge(Selkie::Style.new(bold => True));

THEME SWATCH

swatch-spans(:$theme) is a second, unrelated export sharing this module because it is the same kind of thing: a pure, theme-derived piece of chrome consumed by Screen::Settings' live theme-preview row. It returns eight Selkie::Widget::RichText::Spans โ€” one โ–ˆโ–ˆ colour chip per named palette slot, in a fixed order:


use App::Moneymoor::View::ModalChrome;

my @chips = swatch-spans(theme => $theme);
# accent, fg-red, fg-amber, fg-green, fg-blue, fg-purple, fg-cyan, bg-surface

Callers interleave their own separator spans (a plain-space Span between chips, as the doc example on swatch-spans above shows) โ€” the eight returned spans carry only the colour, so a positional test never has to skip over spacing.

NOTES

Modals are rebuilt per-open (see App::Moneymoor::Screen::Main::Modals), so injecting the theme at construction is enough to re-theme them: a live theme swap while a modal is open isn't reachable, because the Settings screen that performs the swap is itself the modal-free path. No live-patch machinery is needed here, unlike the long-lived widgets App::Moneymoor::Screen::Main.rebuild-captured-styles has to fix up.

SEE ALSO

App::Moneymoor::Theme โ€” the palette these roles resolve against.

App::Moneymoor v0.4.2

YNAB-style envelope budgeting: a derivation engine

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

DBIish:ver<0.6.7>:auth<zef:raku-community-modules>Notcurses::Native:ver<0.6.5+>:auth<zef:apogee>Selkie:ver<0.16.0+>:auth<zef:apogee>JSON::Fast:ver<0.19>:auth<cpan:TIMOTIMO>MacOS::NativeLib:ver<0.0.6>:auth<zef:lizmat>

Test Dependencies

Provides

  • App::Moneymoor
  • App::Moneymoor::Config
  • App::Moneymoor::DB
  • App::Moneymoor::Gateway::Account
  • App::Moneymoor::Gateway::Assignment
  • App::Moneymoor::Gateway::Category
  • App::Moneymoor::Gateway::Payee
  • App::Moneymoor::Gateway::Transaction
  • App::Moneymoor::Handlers::Boot
  • App::Moneymoor::Model::Account
  • App::Moneymoor::Model::Assignment
  • App::Moneymoor::Model::Category
  • App::Moneymoor::Model::CategoryGroup
  • App::Moneymoor::Model::Payee
  • App::Moneymoor::Model::Split
  • App::Moneymoor::Model::Transaction
  • App::Moneymoor::Screen::Accounts
  • App::Moneymoor::Screen::Budget
  • App::Moneymoor::Screen::Login
  • App::Moneymoor::Screen::Main
  • App::Moneymoor::Screen::Main::Keybinds
  • App::Moneymoor::Screen::Main::Modals
  • App::Moneymoor::Screen::Main::Subscriptions
  • App::Moneymoor::Screen::Reports
  • App::Moneymoor::Service::Budget
  • App::Moneymoor::Service::Icons
  • App::Moneymoor::Service::Target
  • App::Moneymoor::Service::Workspace
  • App::Moneymoor::StoreHandlers
  • App::Moneymoor::Theme
  • App::Moneymoor::Theme::Catppuccin
  • App::Moneymoor::Theme::Dracula
  • App::Moneymoor::Theme::Everforest
  • App::Moneymoor::Theme::Gruvbox
  • App::Moneymoor::Theme::Kanagawa
  • App::Moneymoor::Theme::Monokai
  • App::Moneymoor::Theme::Nord
  • App::Moneymoor::Theme::OneDark
  • App::Moneymoor::Theme::RosePine
  • App::Moneymoor::Theme::Solarized
  • App::Moneymoor::Theme::TokyoNight
  • App::Moneymoor::Themes
  • App::Moneymoor::UI
  • App::Moneymoor::Util::Money
  • App::Moneymoor::Util::Period
  • App::Moneymoor::View::BudgetRow
  • App::Moneymoor::View::EmptyState
  • App::Moneymoor::View::HintBar
  • App::Moneymoor::View::InspectorPane
  • App::Moneymoor::View::ModalChrome
  • App::Moneymoor::View::RegisterRow
  • App::Moneymoor::View::ReportRow
  • App::Moneymoor::Widget::BannerBar
  • App::Moneymoor::Widget::BootProgressModal

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite โ€” the markup and publishing tools behind this site.