diff --git a/app/assets/stylesheets/wigu/active_admin_theme.scss b/app/assets/stylesheets/wigu/active_admin_theme.scss index dd4761d..f9306d8 100644 --- a/app/assets/stylesheets/wigu/active_admin_theme.scss +++ b/app/assets/stylesheets/wigu/active_admin_theme.scss @@ -1959,3 +1959,58 @@ input[type='radio'] { html:not([data-theme="light"]) { @include aa-dark-content; } } html[data-theme="dark"] { @include aa-dark-content; } + +// Trix / ActionText editor. Trix ships with ActionText (a Rails built-in), so +// its chrome is themed here for every consumer; the app still imports Trix's +// own base CSS (trix/dist/trix). All rules key off the --aa-* tokens, so they +// follow the active palette in both light and dark, and are inert when no +// editor is on the page. +trix-toolbar { + .trix-button-group { border-color: var(--aa-border); } + .trix-button { + background: var(--aa-surface); + color: var(--aa-text); + border-bottom-color: var(--aa-border); + &:not(:first-child) { border-left-color: var(--aa-border); } + &:not(:disabled):hover { background: var(--aa-surface-hover); } + &.trix-active { background: var(--aa-selected); } + } + // Trix dims idle icons to opacity 0.6 and disabled ones to 0.125 — both read + // as faint in either palette, the 0.125 so faint the block-format buttons + // (disabled until the editor is focused) look broken. Lift idle to 0.8 and + // disabled to 0.4: still clearly dimmer than idle, but legible. Trix keeps the + // active icon at 1 via a higher-specificity rule. + .trix-button--icon::before { opacity: 0.8; } + .trix-button--icon:disabled::before { opacity: 0.4; } +} + +trix-editor { + background: var(--aa-input-bg); + border-color: var(--aa-input-border); + color: var(--aa-text); + &:empty:not(:focus)::before { color: var(--aa-text-muted); } // placeholder +} + +.trix-content { + pre { background: var(--aa-surface-2); } + blockquote { border-left: 0.3em solid var(--aa-border); } +} + +.trix-dialog { + background: var(--aa-surface); + color: var(--aa-text); + box-shadow: 0 2px 8px var(--aa-shadow); + input[type="text"], input[type="url"] { + background: var(--aa-input-bg); + border-color: var(--aa-input-border); + color: var(--aa-text); + } + .trix-button { background: var(--aa-accent); color: #fff; } +} + +// Trix bakes its toolbar icons into the base CSS as black SVG background images +// on ::before; invert them in dark mode so they read on the dark toolbar (the +// idle/disabled opacity lift above applies in both modes). +@include aa-dark { + trix-toolbar .trix-button--icon::before { filter: invert(1); } +} diff --git a/img/trix-dark.png b/img/trix-dark.png new file mode 100644 index 0000000..d5c82d9 Binary files /dev/null and b/img/trix-dark.png differ diff --git a/img/trix-light.png b/img/trix-light.png new file mode 100644 index 0000000..5c22dc5 Binary files /dev/null and b/img/trix-light.png differ diff --git a/test/dummy/app/admin/editor.rb b/test/dummy/app/admin/editor.rb new file mode 100644 index 0000000..13f9b73 --- /dev/null +++ b/test/dummy/app/admin/editor.rb @@ -0,0 +1,24 @@ +# Demo page with a real Trix (ActionText) editor so the theme's Trix chrome can +# be seen and screenshotted. The hidden input carries sample formatted HTML that +# Trix loads on init, exercising the toolbar states and .trix-content styles. +ActiveAdmin.register_page "Rich text" do + menu priority: 2 + + SAMPLE_HTML = <<~HTML +

Release notes

+
A themed Trix editor with italics, a + link and inline code.
+ +
Quoted text follows the theme border.
+
$ bundle exec rake
+ HTML + + content do + panel "Trix / ActionText" do + value = ERB::Util.html_escape(SAMPLE_HTML) + html = %() + + %() + text_node(html.html_safe) + end + end +end diff --git a/test/dummy/app/assets/javascripts/active_admin.js b/test/dummy/app/assets/javascripts/active_admin.js index 6780be4..eeb250c 100644 --- a/test/dummy/app/assets/javascripts/active_admin.js +++ b/test/dummy/app/assets/javascripts/active_admin.js @@ -1,3 +1,4 @@ //= require active_admin/base +//= require trix //= require wigu/server_clock //= require wigu/theme_toggle diff --git a/test/dummy/app/assets/stylesheets/active_admin.scss b/test/dummy/app/assets/stylesheets/active_admin.scss index c0252fb..6ccb9ca 100644 --- a/test/dummy/app/assets/stylesheets/active_admin.scss +++ b/test/dummy/app/assets/stylesheets/active_admin.scss @@ -1,3 +1,4 @@ @import "active_admin/mixins"; @import "active_admin/base"; +@import "trix"; @import "wigu/active_admin_theme"; diff --git a/test/dummy/config/application.rb b/test/dummy/config/application.rb index 513502b..7537079 100644 --- a/test/dummy/config/application.rb +++ b/test/dummy/config/application.rb @@ -28,6 +28,14 @@ class Application < Rails::Application config.logger = Logger.new($stdout) config.log_level = :warn + # action_text-trix ships trix.js / trix.css but doesn't add them to the + # Sprockets load path on its own, so `//= require trix` / `@import "trix"` + # (in active_admin.js / active_admin.scss) can't find them. Add its asset + # dirs so the demo editor page gets Trix's base JS + CSS. + trix_root = Gem::Specification.find_by_name("action_text-trix").gem_dir + config.assets.paths << File.join(trix_root, "app/assets/javascripts") + config.assets.paths << File.join(trix_root, "app/assets/stylesheets") + # Sprockets: compile on the fly, no digests — simplest thing that serves # active_admin.css / active_admin.js in dev/test. config.assets.compile = true diff --git a/test/trix_screenshot.rb b/test/trix_screenshot.rb new file mode 100644 index 0000000..5e4f7d6 --- /dev/null +++ b/test/trix_screenshot.rb @@ -0,0 +1,32 @@ +# Regenerates img/trix-light.png / img/trix-dark.png — the themed Trix editor +# (toolbar + sample content) in both palettes, for the PR/README. Same dummy app +# and driver the clock screenshot uses; crops to the editor panel. +require_relative "capybara_boot" +require "capybara/dsl" + +include Capybara::DSL + +def shoot(theme, out) + visit "/admin/rich_text" + # Trix enhances into a full toolbar on load; wait for it. + find("trix-toolbar .trix-button--icon-bold", wait: 5) + # Place the cursor in the content so Trix enables the block-format buttons + # (quote/code/lists/nesting), which it disables while the editor is unfocused — + # the screenshot then shows the toolbar in its normal in-use state. + page.execute_script(<<~JS) + var ed = document.querySelector('trix-editor'); + ed.focus(); + if (ed.editor) ed.editor.setSelectedRange([5, 5]); + JS + page.execute_script(%(document.documentElement.setAttribute('data-theme', '#{theme}'))) + sleep 0.4 + page.driver.save_screenshot(out, selector: ".panel") + puts "wrote #{out} (#{File.size(out)} bytes)" +end + +page.driver.resize_window_to(page.driver.window_handles.first, 980, 720) rescue nil + +shoot("light", File.expand_path("../img/trix-light.png", __dir__)) +shoot("dark", File.expand_path("../img/trix-dark.png", __dir__)) + +Capybara.reset_sessions!