Module: ShadcnViewComponent::ThemeHelper

Defined in:
app/helpers/shadcn_view_component/theme_helper.rb

Overview

View helpers for the theming system.

<%= shadcn_theme_script_tag %>

shadcn_theme_script_tag is what stops the flash of the wrong palette: it runs before the first paint, reads the stored preference and puts .dark and data-shadcn-theme on itself, since does not exist yet.

Constant Summary collapse

"shadcn-ui-mode"
"shadcn-ui-theme"

Instance Method Summary collapse

Instance Method Details

#shadcn_mode(default: "system") ⇒ Object

The mode this request should render with: "light", "dark" or "system".



56
57
58
59
# File 'app/helpers/shadcn_view_component/theme_helper.rb', line 56

def shadcn_mode(default: "system")
  mode = cookies[MODE_COOKIE].to_s
  %w[light dark system].include?(mode) ? mode : default
end

#shadcn_theme_class(default: Themes::DEFAULT) ⇒ Object

The class to put on .



51
52
53
# File 'app/helpers/shadcn_view_component/theme_helper.rb', line 51

def shadcn_theme_class(default: Themes::DEFAULT)
  "theme-#{shadcn_theme_name(default:)}"
end

#shadcn_theme_name(default: Themes::DEFAULT) ⇒ Object

The colour theme this request should render with, from the cookie the store mirrors its localStorage value into. Lets a server-rendered page be correct on the very first byte.



45
46
47
48
# File 'app/helpers/shadcn_view_component/theme_helper.rb', line 45

def shadcn_theme_name(default: Themes::DEFAULT)
  name = cookies[THEME_COOKIE].to_s
  Themes.exists?(name) ? name : default
end

#shadcn_theme_script_tag(default_mode: "system", default_theme: Themes::DEFAULT) ⇒ Object

Emits the blocking snippet that applies the stored preference before the page paints. Put it in , as early as possible.

Parameters:

  • default_mode (String) (defaults to: "system")

    "system", "light" or "dark"

  • default_theme (String) (defaults to: Themes::DEFAULT)

    a name from ShadcnViewComponent::Themes



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'app/helpers/shadcn_view_component/theme_helper.rb', line 22

def shadcn_theme_script_tag(default_mode: "system", default_theme: Themes::DEFAULT)
  javascript_tag(nonce: true) do
    raw(<<~JS)
      (function () {
        try {
          var root = document.documentElement;
          var mode = localStorage.getItem("#{MODE_COOKIE}") || "#{default_mode}";
          var theme = localStorage.getItem("#{THEME_COOKIE}") || "#{default_theme}";
          var dark = mode === "dark" ||
            (mode === "system" && matchMedia("(prefers-color-scheme: dark)").matches);

          root.classList.toggle("dark", dark);
          root.style.colorScheme = dark ? "dark" : "light";
          root.dataset.shadcnTheme = theme;
        } catch (e) {}
      })();
    JS
  end
end