rails-clipboard-helper 0.1.1 → 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: d3cfba771d95ea5e83392dff778fb6dad90908bcc3fc6521d0c0bc85be57ed50
4
- data.tar.gz: a78992a6f8bce03a3484f6768ff22ab9d610f3945fee0cfcbb21c20f573684e5
3
+ metadata.gz: c0677492d465fef53bf7ac5e072f8588305f52c9fbf9ca492ea244dcc236536f
4
+ data.tar.gz: 8d7083bd4bbf188e7ccdf55f8ea10745dddcea0a5817d8d00eb7573d2a180a62
5
5
  SHA512:
6
- metadata.gz: 7b82e790f6209b28805d57fc3ba5af3cc9605b9e55677b4805e17e252a02470c305d97f4fda659d7ebd3de80bf78fc1521d858862bad3d82f0775e8658aa51bc
7
- data.tar.gz: d7e4577ecfcd9b1aa502244552ed8f3f9669010e5e0bf6486616f5bfcd318f2f5a61caac2f040f1179032560eb5bd73c1b2a78bd3eaf8628aa4d047d3724e7e7
6
+ metadata.gz: a08bc12b49178a98d48b116b08c98361d6e312eca98471d80fca5c92613ae73bf8ad7fd89178ed50de5513298c9615146234403c007b6622de9d8839487917f0
7
+ data.tar.gz: ab6aa201508f6d34af7c05741e94f03051ee0a8980906e465fd726e48fb8fb478c8d2fb9d7d560bddd4b45cf19a824facd445759d7d973e1c380c1d69b1b994f
data/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ 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
+
8
20
  ## [0.1.1] - 2025-11-09
9
21
 
10
22
  ### Fixed
@@ -37,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
37
49
  - Comprehensive RSpec tests
38
50
  - Documentation
39
51
 
52
+ [0.1.2]: https://github.com/dhq_boiler/rails-clipboard-helper/releases/tag/v0.1.2
40
53
  [0.1.1]: https://github.com/dhq_boiler/rails-clipboard-helper/releases/tag/v0.1.1
41
54
  [0.1.0]: https://github.com/dhq_boiler/rails-clipboard-helper/releases/tag/v0.1.0
42
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
  }
@@ -231,7 +208,7 @@ If you get an error like `undefined method 'clipboard_copy'`, try the following:
231
208
  ```
232
209
 
233
210
  3. **Check if the gem is required:**
234
- The helper should be automatically included in your views via Rails Engine/Railtie.
211
+ The helper should be automatically included in your views.
235
212
  If not, you can manually include it in `app/controllers/application_controller.rb`:
236
213
  ```ruby
237
214
  class ApplicationController < ActionController::Base
@@ -240,39 +217,16 @@ If you get an error like `undefined method 'clipboard_copy'`, try the following:
240
217
  ```
241
218
 
242
219
  4. **Check your Rails version:**
243
- This gem requires Rails 6.0 or higher.
244
-
245
- ### JavaScript not working / Copy button doesn't respond
220
+ This gem requires ActionView 6.0 or higher.
246
221
 
247
- 1. **Check if JavaScript is loaded:**
248
- Open browser developer console and look for any JavaScript errors.
222
+ ### Copy button doesn't work
249
223
 
250
- 2. **For Importmap (Rails 7+):**
251
- Make sure `config/importmap.rb` includes:
252
- ```ruby
253
- pin "rails_clipboard_helper"
254
- ```
255
-
256
- And run:
257
- ```bash
258
- bin/importmap pin rails_clipboard_helper
259
- ```
260
-
261
- 3. **For Sprockets:**
262
- Make sure `app/assets/javascripts/application.js` includes:
263
- ```javascript
264
- //= require rails_clipboard_helper
265
- ```
266
-
267
- 4. **Manual JavaScript inclusion:**
268
- If asset pipeline is not working, add this to your layout:
269
- ```erb
270
- <%= clipboard_javascript_tag %>
271
- ```
272
-
273
- 5. **HTTPS requirement:**
224
+ 1. **HTTPS requirement:**
274
225
  The Clipboard API requires HTTPS (or localhost for development).
275
226
 
227
+ 2. **Check browser console:**
228
+ Open browser developer console (F12) and look for any JavaScript errors.
229
+
276
230
  ## Development
277
231
 
278
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.1"
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
@@ -3,16 +3,15 @@
3
3
  require_relative "helper/version"
4
4
  require_relative "helper/view_helpers"
5
5
 
6
- if defined?(Rails::Engine)
7
- require_relative "helper/engine"
8
- elsif defined?(Rails::Railtie)
9
- require_relative "helper/railtie"
10
- end
11
-
12
6
  module Rails
13
7
  module Clipboard
14
8
  module Helper
15
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
16
15
  end
17
16
  end
18
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.1
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
-