richer_text 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e3e144daed92cf04465df7c11e55a30bec134bd6abd083b2ce76b078eb579323
4
- data.tar.gz: 348c16817e8d8faad41627f985bb6d4dbf7392cd67d04b9faed369cd2ade73a5
3
+ metadata.gz: 8ab9e5f516632d096522a7aa18daaad74e8c6b2eb5736bce0aff526e49a6f5a0
4
+ data.tar.gz: 532ff98188ba2b2425188cfcbec7cf80d5563d65339c7a247fdebb41d418247a
5
5
  SHA512:
6
- metadata.gz: 4e73645fe681761bc2941cc3814f4ecc2e84c6ad55060e4a62e84351393a6e6fe089a511c4e1a92072c52c6bc9a971d754706df22b57604789d3efc0dd44359e
7
- data.tar.gz: 78bfe77159991d5449f5bfb57dd9727bc5aafa87d648f06913089e791ca69165eab938f8095c82f408a78727c1620f1011fff99803db8dcb7ff53ca22c97f8ee
6
+ metadata.gz: 39981e09d8ce208402c1c66a1541a706af868ad1563d4497b5d919a452256da00308448a6c08a5751f5cebc4b1613c165a2c0ec4d9302a8356a0f33f27f653db
7
+ data.tar.gz: 5ea9229f6bfd06ab525ab96b543dc63eed8dcbd34b3419f2dda0fe1058dba8168d881e29871917916ba1b03be7b7d7372da1b233f7c37018528f7c867383d4a6
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # RicherText
2
- Short description and motivation.
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ RicherText aims to provide a richer text editing experience than what comes out of the box with ActionText in Rails. **It is however a seperate thing from ActionText** and is **not** backwards compatible.
4
+
5
+ RicherText uses React and TipTap under the hood to create an editor, this does mean that you'll have react and react-dom in your project, but you absolutely don't need to use it outside of the RicherText editor. Additionally there's currently a hard requirement for ActiveStorage as well.
6
6
 
7
7
  ## Installation
8
+
8
9
  Add this line to your application's Gemfile:
9
10
 
10
11
  ```ruby
@@ -12,17 +13,73 @@ gem "richer_text"
12
13
  ```
13
14
 
14
15
  And then execute:
16
+
15
17
  ```bash
16
18
  $ bundle
17
19
  ```
18
20
 
19
- Or install it yourself as:
21
+ Once you've installed the gem the next step is to run the Generator and install all required libraries.
22
+
20
23
  ```bash
21
- $ gem install richer_text
24
+ $ rails richer_text:install
25
+ ```
26
+
27
+ > [!IMPORTANT]
28
+ > If you wish to use highlight.js outside of RicherText you'll need to add some code to your javascript entry point.
29
+
30
+ ```js
31
+ const hljs = require("highlight.js");
32
+
33
+ document.addEventListener("turbo:load", (event) => {
34
+ document.querySelectorAll("pre").forEach((block) => {
35
+ hljs.highlightElement(block);
36
+ });
37
+ });
38
+ ```
39
+
40
+ ## Usage
41
+
42
+ > [!WARNING]
43
+ > You probably shouldn't use this gem / npm package (yet!) for anything serious. It's still undergoing development. But please do try it on a non-production app!
44
+
45
+ To use RicherText, once you've completed the installation process is a matter of doing the following:
46
+
47
+ **Add has_richer_text to a model**
48
+
49
+ Take a Post model where you'd like to add RicherText to write, and edit the body attribute:
50
+
51
+ ```ruby
52
+ class Post < ApplicationRecord
53
+ has_richer_text :body
54
+ end
55
+ ```
56
+
57
+ **Add the form helper to the form**
58
+
59
+ Inside of your form partial:
60
+
61
+ ```erb
62
+ <%= form.label :body %>
63
+ <%= form.richer_text_area :body %>
64
+ ```
65
+
66
+ Optionally you can pass arguments to the RicherText editor...
67
+
68
+ ```erb
69
+ <%= form.label :body %>
70
+ <%= form.richer_text_area :body, callouts: true, placeholder: "Write something..." %>
71
+ ```
72
+
73
+ **Render the richer text content**
74
+
75
+ ```erb
76
+ <%= @post.body %>
22
77
  ```
23
78
 
24
79
  ## Contributing
80
+
25
81
  Contribution directions go here.
26
82
 
27
83
  ## License
84
+
28
85
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,49 @@
1
+ require "action_view/helpers/tags/placeholderable"
2
+
3
+ module ActionView::Helpers
4
+ class Tags::Editor < Tags::Base
5
+ include Tags::Placeholderable
6
+
7
+ def render
8
+ options = @options.stringify_keys
9
+ options["value"] = options.fetch("value") { value&.to_html }
10
+ add_default_name_and_id(options)
11
+
12
+ @template_object.richer_text_area_tag(options["name"], options["value"], options.except("value"))
13
+ end
14
+ end
15
+
16
+ module FormHelper
17
+ def richer_text_area(object_name, method, options = {})
18
+ Tags::Editor.new(object_name, method, self, options).render
19
+ end
20
+ end
21
+
22
+ class FormBuilder
23
+ def richer_text_area(method, options = {})
24
+ @template.richer_text_area(@object_name, method, objectify_options(options))
25
+ end
26
+ end
27
+ end
28
+
29
+
30
+ module RicherText
31
+ module TagHelper
32
+ cattr_accessor(:id, instance_accessor: false) { 0 }
33
+
34
+ def richer_text_area_tag(name, value = nil, options = {})
35
+ options = options.symbolize_keys
36
+ options[:id] ||= "editor_input_#{TagHelper.id += 1}"
37
+ options[:class] ||= "editor-input"
38
+
39
+ # So that we can access the content in the tiptap editor
40
+ options[:content] ||= value
41
+
42
+ # editor_toolbar(id: options[:id]) + content_tag("textarea", value, options)
43
+ content_tag("div", data: { controller: "richer-text-editor", action: "editor:update->richer-text-editor#update" }) do
44
+ hidden_field_tag(name, value, { class: "w-full", data: { richer_text_editor_target: "input" } }) +
45
+ tag("richer-text-editor", options)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="richer-text-editor"
4
+ export default class extends Controller {
5
+ static targets = ["input"];
6
+
7
+ update(event) {
8
+ this.inputTarget.value = event.detail.html;
9
+ }
10
+ }
@@ -1,17 +1,18 @@
1
1
  module RicherText
2
2
  class RichText < ApplicationRecord
3
- belongs_to :record, polymorphic: true
3
+ belongs_to :record, polymorphic: true, touch: true
4
4
 
5
5
  serialize :body, RicherText::Content
6
6
 
7
7
  delegate :to_s, :nil?, to: :body
8
+ delegate :blank?, :empty?, :present?, to: :to_html
8
9
 
9
10
  has_many_attached :images
10
11
 
11
12
  before_save :update_images
12
13
 
13
14
  def to_html
14
- body&.to_html
15
+ body&.to_html&.to_s
15
16
  end
16
17
 
17
18
  private
@@ -0,0 +1,3 @@
1
+ <div class="richer-text">
2
+ <%= sanitize(content.to_html, attributes: %w(id class style data-color)) %>
3
+ </div>
@@ -0,0 +1,49 @@
1
+ require "pathname"
2
+
3
+ module RicherText
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root RicherText::Engine.root
7
+
8
+ def create_migrations
9
+ rails_command "railties:install:migrations FROM=active_storage,richer_text", inline: true
10
+ end
11
+
12
+ def copy_files
13
+ copy_file(
14
+ "app/views/richer_text/contents/_content.html.erb",
15
+ "app/views/richer_text/contents/_content.html.erb"
16
+ )
17
+ end
18
+
19
+ def install_javascript_dependencies
20
+ destination = Pathname(destination_root)
21
+
22
+ if destination.join("package.json").exist?
23
+ say "Adding dependencies to package.json", :green
24
+ run "yarn add react react-dom highlight.js @afomera/richer-text"
25
+ end
26
+
27
+ say "Adding import to application.js", :green
28
+ append_to_file "app/javascript/application.js", %(import "@afomera/richer-text"\n)
29
+ end
30
+
31
+ def install_stylesheet_dependencies
32
+ destination = Pathname(destination_root)
33
+
34
+ if destination.join("app/assets/stylesheets/application.tailwind.css").exist?
35
+ say "Adding import to application.tailwind.css", :green
36
+ prepend_to_file "app/assets/stylesheets/application.tailwind.css", %(@import "@afomera/richer-text/dist/css/richer-text.css";\n@import "highlight.js/styles/github-dark.css";\n)
37
+ end
38
+ end
39
+
40
+ def generate_stimulus_controller
41
+ say "Copying Stimulus controller", :green
42
+ copy_file "app/javascript/controllers/richer_text_editor_controller.js", "app/javascript/controllers/richer_text_editor_controller.js"
43
+
44
+ say "Updating Stimulus manifest", :green
45
+ rails_command "stimulus:manifest:update"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,6 +1,6 @@
1
1
  module RicherText
2
2
  class Content
3
- include Serialization
3
+ include ActiveModel::Conversion, Serialization, Rendering
4
4
 
5
5
  delegate :blank?, :empty?, :html_safe, :present?, to: :to_html
6
6
 
@@ -15,7 +15,7 @@ module RicherText
15
15
  end
16
16
 
17
17
  def to_s
18
- to_html
18
+ render partial: to_partial_path, layout: false, locals: { content: self }
19
19
  end
20
20
 
21
21
  def to_html
@@ -41,6 +41,7 @@ module RicherText
41
41
  end
42
42
  end
43
43
 
44
- attr_reader :body, :fragment
44
+ attr_reader :fragment
45
+ attr_accessor :body
45
46
  end
46
47
  end
@@ -10,5 +10,11 @@ module RicherText
10
10
  include RicherText::Attribute
11
11
  end
12
12
  end
13
+
14
+ initializer "richer_text.helper" do
15
+ ActiveSupport.on_load(:action_controller_base) do
16
+ helper RicherText::Engine.helpers
17
+ end
18
+ end
13
19
  end
14
20
  end
@@ -0,0 +1,13 @@
1
+ module RicherText
2
+ module Rendering
3
+ private
4
+
5
+ def render(*args, &block)
6
+ action_controller_renderer.render(*args, &block)
7
+ end
8
+
9
+ def action_controller_renderer
10
+ ActionController::Base.renderer
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module RicherText
2
- VERSION = "0.0.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/richer_text.rb CHANGED
@@ -9,6 +9,7 @@ module RicherText
9
9
 
10
10
  autoload :Attribute
11
11
  autoload :Content
12
+ autoload :Rendering
12
13
  autoload :Fragment
13
14
  autoload :Serialization
14
15
  end
@@ -1,4 +1,4 @@
1
- # desc "Explaining what the task does"
2
- # task :richer_text do
3
- # # Task goes here
4
- # end
1
+ desc "Installs RicherText into your application"
2
+ task "richer_text:install" do
3
+ Rails::Command.invoke :generate, ["richer_text:install"]
4
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: richer_text
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrea Fomera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-28 00:00:00.000000000 Z
11
+ date: 2023-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,18 +38,23 @@ files:
38
38
  - app/assets/stylesheets/richer_text/application.css
39
39
  - app/controllers/richer_text/application_controller.rb
40
40
  - app/helpers/richer_text/application_helper.rb
41
+ - app/helpers/richer_text/tag_helper.rb
42
+ - app/javascript/controllers/richer_text_editor_controller.js
41
43
  - app/jobs/richer_text/application_job.rb
42
44
  - app/mailers/richer_text/application_mailer.rb
43
45
  - app/models/richer_text/application_record.rb
44
46
  - app/models/richer_text/rich_text.rb
45
47
  - app/views/layouts/richer_text/application.html.erb
48
+ - app/views/richer_text/contents/_content.html.erb
46
49
  - config/routes.rb
47
50
  - db/migrate/20230107020316_create_richer_text_rich_texts.rb
51
+ - lib/generators/richer_text/install/install_generator.rb
48
52
  - lib/richer_text.rb
49
53
  - lib/richer_text/attribute.rb
50
54
  - lib/richer_text/content.rb
51
55
  - lib/richer_text/engine.rb
52
56
  - lib/richer_text/fragment.rb
57
+ - lib/richer_text/rendering.rb
53
58
  - lib/richer_text/serialization.rb
54
59
  - lib/richer_text/version.rb
55
60
  - lib/tasks/richer_text_tasks.rake