Skip to content

Commit 367ea27

Browse files
committed
Theme the Trix / ActionText editor in light and dark
Trix ships with ActionText (a Rails built-in), so every ActiveAdmin app can have a rich-text field. Theme its chrome — toolbar, editor surface, link dialog, content pre/blockquote — off the --aa-* tokens so it follows the palette in both modes. Trix bakes its toolbar icons into the base CSS as black SVGs, so invert them in dark mode to keep them legible. The app still imports Trix's own base CSS; these rules only restyle it and are inert when no editor is present. Adds a Rich-text demo page to the dummy app plus a screenshot task producing img/trix-{light,dark}.png.
1 parent 689f6ad commit 367ea27

8 files changed

Lines changed: 105 additions & 0 deletions

File tree

‎app/assets/stylesheets/wigu/active_admin_theme.scss‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,3 +1959,50 @@ input[type='radio'] {
19591959
html:not([data-theme="light"]) { @include aa-dark-content; }
19601960
}
19611961
html[data-theme="dark"] { @include aa-dark-content; }
1962+
1963+
// Trix / ActionText editor. Trix ships with ActionText (a Rails built-in), so
1964+
// its chrome is themed here for every consumer; the app still imports Trix's
1965+
// own base CSS (trix/dist/trix). All rules key off the --aa-* tokens, so they
1966+
// follow the active palette in both light and dark, and are inert when no
1967+
// editor is on the page.
1968+
trix-toolbar {
1969+
.trix-button-group { border-color: var(--aa-border); }
1970+
.trix-button {
1971+
background: var(--aa-surface);
1972+
color: var(--aa-text);
1973+
border-bottom-color: var(--aa-border);
1974+
&:not(:first-child) { border-left-color: var(--aa-border); }
1975+
&:not(:disabled):hover { background: var(--aa-surface-hover); }
1976+
&.trix-active { background: var(--aa-selected); }
1977+
}
1978+
}
1979+
1980+
trix-editor {
1981+
background: var(--aa-input-bg);
1982+
border-color: var(--aa-input-border);
1983+
color: var(--aa-text);
1984+
&:empty:not(:focus)::before { color: var(--aa-text-muted); } // placeholder
1985+
}
1986+
1987+
.trix-content {
1988+
pre { background: var(--aa-surface-2); }
1989+
blockquote { border-left: 0.3em solid var(--aa-border); }
1990+
}
1991+
1992+
.trix-dialog {
1993+
background: var(--aa-surface);
1994+
color: var(--aa-text);
1995+
box-shadow: 0 2px 8px var(--aa-shadow);
1996+
input[type="text"], input[type="url"] {
1997+
background: var(--aa-input-bg);
1998+
border-color: var(--aa-input-border);
1999+
color: var(--aa-text);
2000+
}
2001+
.trix-button { background: var(--aa-accent); color: #fff; }
2002+
}
2003+
2004+
// Trix bakes its toolbar icons into the base CSS as black SVG background images
2005+
// on ::before; invert them in dark mode so they read on the dark toolbar.
2006+
@include aa-dark {
2007+
trix-toolbar .trix-button--icon::before { filter: invert(1); }
2008+
}

‎img/trix-dark.png‎

17.5 KB
Loading

‎img/trix-light.png‎

17.2 KB
Loading

‎test/dummy/app/admin/editor.rb‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Demo page with a real Trix (ActionText) editor so the theme's Trix chrome can
2+
# be seen and screenshotted. The hidden input carries sample formatted HTML that
3+
# Trix loads on init, exercising the toolbar states and .trix-content styles.
4+
ActiveAdmin.register_page "Rich text" do
5+
menu priority: 2
6+
7+
SAMPLE_HTML = <<~HTML
8+
<h1>Release notes</h1>
9+
<div>A <strong>themed</strong> Trix editor with <em>italics</em>, a
10+
<a href="https://example.com">link</a> and inline <code>code</code>.</div>
11+
<ul><li>First bullet</li><li>Second bullet</li></ul>
12+
<blockquote>Quoted text follows the theme border.</blockquote>
13+
<pre>$ bundle exec rake</pre>
14+
HTML
15+
16+
content do
17+
panel "Trix / ActionText" do
18+
value = ERB::Util.html_escape(SAMPLE_HTML)
19+
html = %(<input id="trix_demo" type="hidden" value="#{value}">) +
20+
%(<trix-editor input="trix_demo" class="trix-content"></trix-editor>)
21+
text_node(html.html_safe)
22+
end
23+
end
24+
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
//= require active_admin/base
2+
//= require trix
23
//= require wigu/server_clock
34
//= require wigu/theme_toggle
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
@import "active_admin/mixins";
22
@import "active_admin/base";
3+
@import "trix";
34
@import "wigu/active_admin_theme";

‎test/dummy/config/application.rb‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ class Application < Rails::Application
2828
config.logger = Logger.new($stdout)
2929
config.log_level = :warn
3030

31+
# action_text-trix ships trix.js / trix.css but doesn't add them to the
32+
# Sprockets load path on its own, so `//= require trix` / `@import "trix"`
33+
# (in active_admin.js / active_admin.scss) can't find them. Add its asset
34+
# dirs so the demo editor page gets Trix's base JS + CSS.
35+
trix_root = Gem::Specification.find_by_name("action_text-trix").gem_dir
36+
config.assets.paths << File.join(trix_root, "app/assets/javascripts")
37+
config.assets.paths << File.join(trix_root, "app/assets/stylesheets")
38+
3139
# Sprockets: compile on the fly, no digests — simplest thing that serves
3240
# active_admin.css / active_admin.js in dev/test.
3341
config.assets.compile = true

‎test/trix_screenshot.rb‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Regenerates img/trix-light.png / img/trix-dark.png — the themed Trix editor
2+
# (toolbar + sample content) in both palettes, for the PR/README. Same dummy app
3+
# and driver the clock screenshot uses; crops to the editor panel.
4+
require_relative "capybara_boot"
5+
require "capybara/dsl"
6+
7+
include Capybara::DSL
8+
9+
def shoot(theme, out)
10+
visit "/admin/rich_text"
11+
# Trix enhances <trix-editor> into a full toolbar on load; wait for it.
12+
find("trix-toolbar .trix-button--icon-bold", wait: 5)
13+
page.execute_script(%(document.documentElement.setAttribute('data-theme', '#{theme}')))
14+
sleep 0.4
15+
page.driver.save_screenshot(out, selector: ".panel")
16+
puts "wrote #{out} (#{File.size(out)} bytes)"
17+
end
18+
19+
page.driver.resize_window_to(page.driver.window_handles.first, 980, 720) rescue nil
20+
21+
shoot("light", File.expand_path("../img/trix-light.png", __dir__))
22+
shoot("dark", File.expand_path("../img/trix-dark.png", __dir__))
23+
24+
Capybara.reset_sessions!

0 commit comments

Comments
 (0)