Skip to content

Commit

Permalink
⚙️ Gizmos: Support ActionText
Browse files Browse the repository at this point in the history
- #709
- #2200 (review)

Markdown is cool, but it's nerd-forward.

ActionText is a much more human-friendly way of implementing rich text
in Rails applications.

I don't know enough about [Trix] to know if it will work in multi-user
contexts; or how it will work with rich-embeds, ala Notion or Google Docs

But I think it's a good-enough-default for now; and if we get to the point
where embeddables or multi-user editing of a field is important we can
figure that out.

[Trix]: https://trix-editor.org/
  • Loading branch information
zspencer committed Feb 16, 2024
1 parent b275438 commit 552000d
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 12 deletions.
36 changes: 36 additions & 0 deletions app/assets/stylesheets/actiontext.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
* inclusion directly in any other asset bundle and remove this file.
*
*= require trix
*/

/*
* We need to override trix.css’s image gallery styles to accommodate the
* <action-text-attachment> element we wrap around attachments. Otherwise,
* images in galleries will be squished by the max-width: 33%; rule.
*/
.trix-content .attachment-gallery > action-text-attachment,
.trix-content .attachment-gallery > .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}

.trix-content
.attachment-gallery.attachment-gallery--2
> action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--2 > .attachment,
.trix-content
.attachment-gallery.attachment-gallery--4
> action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--4 > .attachment {
flex-basis: 50%;
max-width: 50%;
}

.trix-content action-text-attachment .attachment {
padding: 0 !important;
max-width: 100% !important;
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.postcss.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@

@import "./utilities.scss";
@import "./components.scss";
@import "actiontext.css";
3 changes: 3 additions & 0 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ ActiveStorage.start();

import "@hotwired/turbo-rails";
import "./controllers/index.js";

import "trix";
import "@rails/actiontext";
14 changes: 14 additions & 0 deletions app/views/active_storage/blobs/_blob.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
<% if blob.representable? %>
<%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
<% end %>

<figcaption class="attachment__caption">
<% if caption = blob.try(:caption) %>
<%= caption %>
<% else %>
<span class="attachment__name"><%= blob.filename %></span>
<span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
<% end %>
</figcaption>
</figure>
3 changes: 3 additions & 0 deletions app/views/layouts/action_text/contents/_content.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="trix-content">
<%= yield -%>
</div>
27 changes: 27 additions & 0 deletions db/migrate/20240216213129_create_action_text_tables.action_text.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# This migration comes from action_text (originally 20180528164100)
class CreateActionTextTables < ActiveRecord::Migration[6.0]
def change
# Use Active Record's configured type for primary and foreign keys
primary_key_type, foreign_key_type = primary_and_foreign_key_types

create_table :action_text_rich_texts, id: primary_key_type do |t|
t.string :name, null: false
t.text :body, size: :long
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type

t.timestamps

t.index [:record_type, :record_id, :name], name: "index_action_text_rich_texts_uniqueness", unique: true
end
end

private

def primary_and_foreign_key_types
config = Rails.configuration.generators
setting = config.options[config.orm][:primary_key_type]
primary_key_type = setting || :primary_key
foreign_key_type = setting || :bigint
[primary_key_type, foreign_key_type]
end
end
12 changes: 11 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_02_07_040004) do
ActiveRecord::Schema[7.1].define(version: 2024_02_16_213129) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
Expand All @@ -30,6 +30,16 @@
"revoked",
], force: :cascade

create_table "action_text_rich_texts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name", null: false
t.text "body"
t.string "record_type", null: false
t.uuid "record_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
end

create_table "active_storage_attachments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@hotwired/stimulus-webpack-helpers": "^1.0.1",
"@hotwired/turbo-rails": "^8.0.2",
"@rails/actioncable": "^7.1.3",
"@rails/actiontext": "^7.1.3",
"@rails/activestorage": "^7.1.3",
"@sentry/browser": "^7.101.1",
"@tailwindcss/forms": "^0.5.7",
Expand All @@ -49,6 +50,7 @@
"postcss-import": "^16.0.1",
"postcss-preset-env": "^9.3.0",
"tailwindcss": "^3.4.1",
"trix": "^2.0.10",
"webpack": "^5.76.0",
"webpack-cli": "^5.1.4"
}
Expand Down
13 changes: 7 additions & 6 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is copied to spec/ when you run 'rails generate rspec:install'
require "spec_helper"
ENV["RAILS_ENV"] ||= "test"
require File.expand_path("../config/environment", __dir__)
require_relative "../config/environment"
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require "rspec/rails"
Expand All @@ -20,19 +20,20 @@
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
Dir[Rails.root.join("spec", "support", "**", "*.rb")].sort.each { |f| require f }
# Rails.root.glob('spec/support/**/*.rb').sort.each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
abort e.to_s.strip
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_paths = ["#{::Rails.root}/spec/fixtures"]
config.fixture_paths = [
Rails.root.join("spec/fixtures")
]

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
Expand All @@ -54,7 +55,7 @@
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
# https://rspec.info/features/6-0/rspec-rails
config.infer_spec_type_from_file_location!

# Filter lines from Rails gems in backtraces.
Expand Down
7 changes: 3 additions & 4 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# the additional setup, and require it from the spec files that actually need
# it.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
Expand Down Expand Up @@ -56,6 +56,7 @@
config.define_derived_metadata do |meta|
meta[:aggregate_failures] = true
end

# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
# # This allows you to limit a spec run to individual examples or groups
Expand All @@ -72,9 +73,7 @@
#
# # Limits the available syntax to the non-monkey patched syntax that is
# # recommended. For more details, see:
# # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
# # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
# # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/
# config.disable_monkey_patching!
#
# # Many RSpec users commonly either run the entire suite or an individual
Expand Down
14 changes: 13 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,14 @@
resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-7.1.3.tgz#4db480347775aeecd4dde2405659eef74a458881"
integrity sha512-ojNvnoZtPN0pYvVFtlO7dyEN9Oml1B6IDM+whGKVak69MMYW99lC2NOWXWeE3bmwEydbP/nn6ERcpfjHVjYQjA==

"@rails/activestorage@^7.1.3":
"@rails/actiontext@^7.1.3":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@rails/actiontext/-/actiontext-7.1.3.tgz#1b7aa2732c45cbc8a5708c54457c16fb81ce3da3"
integrity sha512-jwY0LJ0xpyIWkYs6BUMY4RcwVA3jZ+bFDPvv5KpKQnw+24BhJVtBLqF0XIsROaRCyabakueRyVuSG9NNhnLTvA==
dependencies:
"@rails/activestorage" ">= 7.1.0-alpha"

"@rails/activestorage@>= 7.1.0-alpha", "@rails/activestorage@^7.1.3":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@rails/activestorage/-/activestorage-7.1.3.tgz#e83ece6c5fd94b3ddf30a8cf3b8f78cad049e596"
integrity sha512-B+RFYAU8vdTPFg0IJcRp2ey0Qw9hpcUOqHHcWqftDJ76ZMBi9+m/UUeMJlNsSd0l9eD+1HLlFSo1X//cY4yiDw==
Expand Down Expand Up @@ -2109,6 +2116,11 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"

trix@^2.0.10:
version "2.0.10"
resolved "https://registry.yarnpkg.com/trix/-/trix-2.0.10.tgz#43f1ff7a94c42f708bd2bad3a2783147c0583698"
integrity sha512-a24w8rNVL+g9nDDdiDZwQVQ9AEWiXAmk9r0ZbwimczJi/xlaM+m0d6upAi0vysDNu0HsiYDFS1/VrR7HbX0Aig==

ts-interface-checker@^0.1.9:
version "0.1.13"
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
Expand Down

0 comments on commit 552000d

Please sign in to comment.