rails-clipboard-helper 0.1.0 → 0.1.2

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: 984e6c3a3d1e5ba1b5920f7314eb40852eb315215c7f890839b58f47b86231cd
4
- data.tar.gz: 649943b92152bfe760834a0308ec8d627d8b1c86ece18ec1a0e7cf1509e7c73d
3
+ metadata.gz: c0677492d465fef53bf7ac5e072f8588305f52c9fbf9ca492ea244dcc236536f
4
+ data.tar.gz: 8d7083bd4bbf188e7ccdf55f8ea10745dddcea0a5817d8d00eb7573d2a180a62
5
5
  SHA512:
6
- metadata.gz: 0e0a75285ebea6b01edcf0d1121d1eec6afee7be4cd3b1493989429326357db8706a2b4c894aea434bda48bbaf1b0d0efc34d07e5eacdc031d41ccaa97385b09
7
- data.tar.gz: 2bca1927f5d7522169762ffef27134917ab5bcb9619734d9b67fb63a907c8cba8fb70077ebe9271adeaab5125002aa13bc51bfc52828b8053126a7c820ec4337
6
+ metadata.gz: a08bc12b49178a98d48b116b08c98361d6e312eca98471d80fca5c92613ae73bf8ad7fd89178ed50de5513298c9615146234403c007b6622de9d8839487917f0
7
+ data.tar.gz: ab6aa201508f6d34af7c05741e94f03051ee0a8980906e465fd726e48fb8fb478c8d2fb9d7d560bddd4b45cf19a824facd445759d7d973e1c380c1d69b1b994f
data/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.2] - 2025-11-09
9
+
10
+ ### Changed
11
+ - Changed button default style to link-like appearance (no border, no background, blue text color)
12
+ - Added hover effect with underline on buttons
13
+ - Changed success feedback from background color to text color change (green)
14
+ - **BREAKING**: Replaced external JavaScript with inline JavaScript - no asset pipeline setup needed
15
+ - Removed `clipboard_javascript_tag` helper method (no longer needed)
16
+ - Removed Engine and Railtie (simplified gem structure)
17
+ - Removed dependency on `railties` (only requires `actionview` now)
18
+ - Updated documentation to remove JavaScript setup instructions
19
+
20
+ ## [0.1.1] - 2025-11-09
21
+
22
+ ### Fixed
23
+ - Fixed Railtie loading issue that prevented helper methods from being available in views
24
+ - Added proper conditional loading for both Engine and Railtie
25
+ - Improved helper method initialization in Rails applications
26
+
27
+ ### Added
28
+ - Added troubleshooting section to README
29
+ - Documented helper method not found error resolution
30
+
8
31
  ## [0.1.0] - 2025-11-09
9
32
 
10
33
  ### Added
@@ -26,5 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
26
49
  - Comprehensive RSpec tests
27
50
  - Documentation
28
51
 
52
+ [0.1.2]: https://github.com/dhq_boiler/rails-clipboard-helper/releases/tag/v0.1.2
53
+ [0.1.1]: https://github.com/dhq_boiler/rails-clipboard-helper/releases/tag/v0.1.1
29
54
  [0.1.0]: https://github.com/dhq_boiler/rails-clipboard-helper/releases/tag/v0.1.0
30
55
 
data/README.md CHANGED
@@ -5,9 +5,11 @@ A Rails view helper gem that displays a copy button alongside text content, allo
5
5
  ## Features
6
6
 
7
7
  - Easy text copying to clipboard
8
+ - **No JavaScript setup required** - works out of the box with inline JavaScript
9
+ - Link-style button design (no borders, no background)
8
10
  - Customizable styles
9
11
  - Uses modern Clipboard API
10
- - Visual feedback on successful copy
12
+ - Visual feedback on successful copy (icon and color change)
11
13
 
12
14
  ## Installation
13
15
 
@@ -25,43 +27,6 @@ bundle install
25
27
 
26
28
  ## Usage
27
29
 
28
- ### JavaScript Setup
29
-
30
- The gem uses Rails Engine to automatically make JavaScript available. You need to include it in your asset pipeline:
31
-
32
- **For Sprockets (Asset Pipeline):**
33
-
34
- Add to `app/assets/javascripts/application.js`:
35
- ```javascript
36
- //= require rails_clipboard_helper
37
- ```
38
-
39
- **For Importmap (Rails 7+):**
40
-
41
- Add to `config/importmap.rb`:
42
- ```ruby
43
- pin "rails_clipboard_helper"
44
- ```
45
-
46
- Then the JavaScript will be automatically loaded.
47
-
48
- **For esbuild/webpack:**
49
-
50
- The JavaScript file is located at `app/assets/javascripts/rails_clipboard_helper.js` in the gem.
51
- You may need to configure your build tool to include it.
52
-
53
- **Manual setup (alternative):**
54
-
55
- If you prefer not to use the asset pipeline, add to your layout:
56
- ```erb
57
- <%= clipboard_javascript_tag %>
58
- ```
59
-
60
- **Features:**
61
- - Automatic initialization on page load
62
- - Turbo/Hotwire support (turbo:load, turbo:render)
63
- - Turbolinks support (turbolinks:load)
64
- - Prevents duplicate event listeners
65
30
 
66
31
  ### Basic Usage
67
32
 
@@ -71,7 +36,7 @@ Use the `clipboard_copy` helper in your views:
71
36
  <%= clipboard_copy("Text you want to copy") %>
72
37
  ```
73
38
 
74
- By default, this displays an SVG copy icon. When clicked, it changes to a checkmark icon.
39
+ By default, this displays an SVG copy icon styled as a link (no border, no background). When clicked, it changes to a checkmark icon and the color briefly changes to green.
75
40
 
76
41
  ### Usage with Options
77
42
 
@@ -135,36 +100,48 @@ To display only the button and hide the content to be copied:
135
100
 
136
101
  ### Custom Styles
137
102
 
138
- You can customize the styles with your own CSS:
103
+ The button is styled as a link by default (no border, no background, blue color with underline on hover). You can customize the styles with your own CSS:
139
104
 
140
105
  ```css
106
+ /* Custom container style */
141
107
  .clipboard-container {
142
108
  display: flex;
143
109
  align-items: center;
144
110
  gap: 10px;
145
- padding: 10px;
146
- background: #f5f5f5;
147
- border-radius: 8px;
148
111
  }
149
112
 
113
+ /* Custom button style - override the link-like default */
150
114
  .clipboard-button {
115
+ color: #0066cc;
116
+ text-decoration: none;
117
+ cursor: pointer;
118
+ transition: color 0.2s;
119
+ }
120
+
121
+ .clipboard-button:hover {
122
+ color: #004499;
123
+ text-decoration: underline;
124
+ }
125
+
126
+ /* Or create a button-like style */
127
+ .my-button {
151
128
  padding: 8px 16px;
152
129
  background: #007bff;
153
- color: white;
154
- border: none;
130
+ color: white !important;
131
+ border: 1px solid #007bff;
155
132
  border-radius: 4px;
156
- cursor: pointer;
157
- transition: background 0.3s;
158
133
  }
159
134
 
160
- .clipboard-button:hover {
135
+ .my-button:hover {
161
136
  background: #0056b3;
137
+ text-decoration: none !important;
162
138
  }
163
139
 
140
+ /* Custom content style */
164
141
  .clipboard-content {
165
142
  font-family: monospace;
166
143
  padding: 5px 10px;
167
- background: white;
144
+ background: #f8f9fa;
168
145
  border: 1px solid #ddd;
169
146
  border-radius: 4px;
170
147
  }
@@ -213,6 +190,43 @@ This gem uses the modern Clipboard API, which is supported by:
213
190
 
214
191
  Requires HTTPS or localhost for operation.
215
192
 
193
+ ## Troubleshooting
194
+
195
+ ### Helper method `clipboard_copy` is not found
196
+
197
+ If you get an error like `undefined method 'clipboard_copy'`, try the following:
198
+
199
+ 1. **Restart your Rails server** after installing the gem:
200
+ ```bash
201
+ bundle install
202
+ rails restart # or ctrl+c and restart your server
203
+ ```
204
+
205
+ 2. **Verify the gem is installed:**
206
+ ```bash
207
+ bundle list | grep rails-clipboard-helper
208
+ ```
209
+
210
+ 3. **Check if the gem is required:**
211
+ The helper should be automatically included in your views.
212
+ If not, you can manually include it in `app/controllers/application_controller.rb`:
213
+ ```ruby
214
+ class ApplicationController < ActionController::Base
215
+ helper Rails::Clipboard::Helper::ViewHelpers
216
+ end
217
+ ```
218
+
219
+ 4. **Check your Rails version:**
220
+ This gem requires ActionView 6.0 or higher.
221
+
222
+ ### Copy button doesn't work
223
+
224
+ 1. **HTTPS requirement:**
225
+ The Clipboard API requires HTTPS (or localhost for development).
226
+
227
+ 2. **Check browser console:**
228
+ Open browser developer console (F12) and look for any JavaScript errors.
229
+
216
230
  ## Development
217
231
 
218
232
  After checking out the repo:
@@ -3,7 +3,7 @@
3
3
  module Rails
4
4
  module Clipboard
5
5
  module Helper
6
- VERSION = "0.1.0"
6
+ VERSION = "0.1.2"
7
7
  end
8
8
  end
9
9
  end
@@ -68,88 +68,44 @@ module Rails
68
68
  copied_content = ERB::Util.html_escape(copied_text)
69
69
  end
70
70
 
71
+ # Inline JavaScript for clipboard functionality
72
+ onclick_js = <<~JS.strip.gsub("\n", ' ')
73
+ (function(btn) {
74
+ const target = document.getElementById('#{unique_id}');
75
+ const text = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' ? target.value : target.textContent;
76
+ navigator.clipboard.writeText(text).then(() => {
77
+ const original = btn.innerHTML;
78
+ btn.innerHTML = '#{copied_content.gsub("'", "\\\\'")}';
79
+ btn.style.color = '#28a745';
80
+ setTimeout(() => {
81
+ btn.innerHTML = original;
82
+ btn.style.color = '#0066cc';
83
+ }, 2000);
84
+ }).catch(err => {
85
+ console.error('Failed to copy:', err);
86
+ alert('Failed to copy to clipboard');
87
+ });
88
+ })(this);
89
+ JS
90
+
71
91
  html = <<~HTML
72
92
  <div class="#{container_class}" style="display: flex; align-items: center; gap: 10px;">
93
+ #{show_content ? %Q(<span class="#{content_class}" id="#{unique_id}">#{ERB::Util.html_escape(content)}</span>) : %Q(<input type="hidden" id="#{unique_id}" value="#{ERB::Util.html_escape(content)}">)}
73
94
  <button
74
95
  type="button"
75
96
  class="#{button_class}"
76
- data-clipboard-target="#{unique_id}"
77
- data-original-html="#{ERB::Util.html_escape(button_content)}"
78
- data-copied-html="#{ERB::Util.html_escape(copied_content)}"
79
- style="padding: 5px 10px; cursor: pointer; border: 1px solid #ccc; border-radius: 4px; background: #f8f9fa; display: inline-flex; align-items: center; gap: 4px;"
97
+ style="padding: 0; cursor: pointer; border: none; background: none; color: #0066cc; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; font: inherit;"
98
+ onmouseover="this.style.textDecoration='underline';"
99
+ onmouseout="this.style.textDecoration='none';"
100
+ onclick="#{onclick_js}"
80
101
  >
81
102
  #{button_content}
82
103
  </button>
83
- #{show_content ? %Q(<span class="#{content_class}" id="#{unique_id}">#{ERB::Util.html_escape(content)}</span>) : %Q(<input type="hidden" id="#{unique_id}" value="#{ERB::Util.html_escape(content)}">)}
84
104
  </div>
85
105
  HTML
86
106
 
87
107
  html.html_safe
88
108
  end
89
-
90
- # Helper method that includes JavaScript (optional - JavaScript is auto-loaded)
91
- # This method is kept for backward compatibility
92
- #
93
- # Note: JavaScript is automatically loaded via asset pipeline.
94
- # You only need to call this method if you're not using the asset pipeline.
95
- def clipboard_javascript_tag
96
- javascript_tag do
97
- <<~JAVASCRIPT
98
- (function() {
99
- function initClipboardButtons() {
100
- document.querySelectorAll('[data-clipboard-target]').forEach(function(button) {
101
- if (button.dataset.clipboardInitialized) return;
102
- button.dataset.clipboardInitialized = 'true';
103
-
104
- button.addEventListener('click', function() {
105
- const targetId = this.getAttribute('data-clipboard-target');
106
- const targetElement = document.getElementById(targetId);
107
-
108
- // Support both old (text) and new (HTML) data attributes
109
- const originalContent = this.getAttribute('data-original-html') || this.getAttribute('data-original-text');
110
- const copiedContent = this.getAttribute('data-copied-html') || this.getAttribute('data-copied-text');
111
-
112
- let textToCopy;
113
- if (targetElement.tagName === 'INPUT' || targetElement.tagName === 'TEXTAREA') {
114
- textToCopy = targetElement.value;
115
- } else {
116
- textToCopy = targetElement.textContent;
117
- }
118
-
119
- navigator.clipboard.writeText(textToCopy).then(() => {
120
- // Use innerHTML for HTML content (SVG icons), textContent for plain text
121
- if (this.getAttribute('data-original-html')) {
122
- this.innerHTML = copiedContent;
123
- } else {
124
- this.textContent = copiedContent;
125
- }
126
- this.style.background = '#d4edda';
127
-
128
- setTimeout(() => {
129
- if (this.getAttribute('data-original-html')) {
130
- this.innerHTML = originalContent;
131
- } else {
132
- this.textContent = originalContent;
133
- }
134
- this.style.background = '#f8f9fa';
135
- }, 2000);
136
- }).catch(err => {
137
- console.error('Failed to copy to clipboard:', err);
138
- alert('Failed to copy');
139
- });
140
- });
141
- });
142
- }
143
-
144
- if (document.readyState === 'loading') {
145
- document.addEventListener('DOMContentLoaded', initClipboardButtons);
146
- } else {
147
- initClipboardButtons();
148
- }
149
- })();
150
- JAVASCRIPT
151
- end
152
- end
153
109
  end
154
110
  end
155
111
  end
@@ -2,12 +2,16 @@
2
2
 
3
3
  require_relative "helper/version"
4
4
  require_relative "helper/view_helpers"
5
- require_relative "helper/engine" if defined?(Rails::Engine)
6
5
 
7
6
  module Rails
8
7
  module Clipboard
9
8
  module Helper
10
9
  class Error < StandardError; end
10
+
11
+ # Automatically include view helpers in ActionView
12
+ if defined?(ActionView::Base)
13
+ ActionView::Base.include ViewHelpers
14
+ end
11
15
  end
12
16
  end
13
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-clipboard-helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - dhq_boiler
@@ -9,26 +9,6 @@ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: railties
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '6.0'
19
- - - "<"
20
- - !ruby/object:Gem::Version
21
- version: '9.0'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: '6.0'
29
- - - "<"
30
- - !ruby/object:Gem::Version
31
- version: '9.0'
32
12
  - !ruby/object:Gem::Dependency
33
13
  name: actionview
34
14
  requirement: !ruby/object:Gem::Requirement
@@ -61,11 +41,7 @@ files:
61
41
  - LICENSE.txt
62
42
  - README.md
63
43
  - Rakefile
64
- - app/assets/javascripts/rails_clipboard_helper.js
65
- - config/importmap.rb
66
44
  - lib/rails/clipboard/helper.rb
67
- - lib/rails/clipboard/helper/engine.rb
68
- - lib/rails/clipboard/helper/railtie.rb
69
45
  - lib/rails/clipboard/helper/version.rb
70
46
  - lib/rails/clipboard/helper/view_helpers.rb
71
47
  - sig/rails/clipboard/helper.rbs
@@ -1,67 +0,0 @@
1
- // Rails Clipboard Helper - Automatic clipboard functionality
2
- (function() {
3
- 'use strict';
4
-
5
- function initClipboardButtons() {
6
- document.querySelectorAll('[data-clipboard-target]').forEach(function(button) {
7
- // Skip if already initialized
8
- if (button.dataset.clipboardInitialized) return;
9
- button.dataset.clipboardInitialized = 'true';
10
-
11
- button.addEventListener('click', function() {
12
- const targetId = this.getAttribute('data-clipboard-target');
13
- const targetElement = document.getElementById(targetId);
14
-
15
- // Support both old (text) and new (HTML) data attributes
16
- const originalContent = this.getAttribute('data-original-html') || this.getAttribute('data-original-text');
17
- const copiedContent = this.getAttribute('data-copied-html') || this.getAttribute('data-copied-text');
18
-
19
- let textToCopy;
20
- if (targetElement.tagName === 'INPUT' || targetElement.tagName === 'TEXTAREA') {
21
- textToCopy = targetElement.value;
22
- } else {
23
- textToCopy = targetElement.textContent;
24
- }
25
-
26
- navigator.clipboard.writeText(textToCopy).then(() => {
27
- // Use innerHTML for HTML content (SVG icons), textContent for plain text
28
- if (this.getAttribute('data-original-html')) {
29
- this.innerHTML = copiedContent;
30
- } else {
31
- this.textContent = copiedContent;
32
- }
33
- this.style.background = '#d4edda';
34
-
35
- setTimeout(() => {
36
- if (this.getAttribute('data-original-html')) {
37
- this.innerHTML = originalContent;
38
- } else {
39
- this.textContent = originalContent;
40
- }
41
- this.style.background = '#f8f9fa';
42
- }, 2000);
43
- }).catch(err => {
44
- console.error('Failed to copy to clipboard:', err);
45
- alert('Failed to copy');
46
- });
47
- });
48
- });
49
- }
50
-
51
- // Initialize on DOMContentLoaded
52
- if (document.readyState === 'loading') {
53
- document.addEventListener('DOMContentLoaded', initClipboardButtons);
54
- } else {
55
- initClipboardButtons();
56
- }
57
-
58
- // Re-initialize on Turbo events (for Turbo/Hotwire support)
59
- if (typeof Turbo !== 'undefined') {
60
- document.addEventListener('turbo:load', initClipboardButtons);
61
- document.addEventListener('turbo:render', initClipboardButtons);
62
- }
63
-
64
- // Re-initialize on turbolinks events (for older Turbolinks support)
65
- document.addEventListener('turbolinks:load', initClipboardButtons);
66
- })();
67
-
data/config/importmap.rb DELETED
@@ -1,4 +0,0 @@
1
- # Pin npm packages by running ./bin/importmap
2
-
3
- pin "rails_clipboard_helper", to: "rails_clipboard_helper.js"
4
-
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rails
4
- module Clipboard
5
- module Helper
6
- class Engine < ::Rails::Engine
7
- isolate_namespace Rails::Clipboard::Helper
8
-
9
- initializer "rails_clipboard_helper.assets" do |app|
10
- app.config.assets.precompile += %w[rails_clipboard_helper.js] if app.config.respond_to?(:assets)
11
- end
12
-
13
- initializer "rails_clipboard_helper.view_helpers" do
14
- ActiveSupport.on_load(:action_view) do
15
- include Rails::Clipboard::Helper::ViewHelpers
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
-
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rails
4
- module Clipboard
5
- module Helper
6
- class Railtie < ::Rails::Railtie
7
- initializer "rails_clipboard_helper.view_helpers" do
8
- ActiveSupport.on_load(:action_view) do
9
- include Rails::Clipboard::Helper::ViewHelpers
10
- end
11
- end
12
-
13
- initializer "rails_clipboard_helper.assets" do |app|
14
- if app.config.respond_to?(:assets)
15
- app.config.assets.precompile += %w[rails_clipboard_helper.js]
16
- end
17
- end
18
-
19
- # Add paths for asset pipeline
20
- config.before_initialize do |app|
21
- if app.config.respond_to?(:assets)
22
- app.config.assets.paths << root.join("app", "assets", "javascripts")
23
- end
24
- end
25
-
26
- def self.root
27
- @root ||= Pathname.new(File.expand_path("../../../..", __dir__))
28
- end
29
- end
30
- end
31
- end
32
- end
33
-