dlnk_toast 0.1.0 → 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: 79d9562b09be7d950804a9a8ef92b03639b46ffc0482a1cc2cd2521ce6b3b258
4
- data.tar.gz: f0d679777b69412f81931ab7bde6abc862bb9a0d113fd035422f33cb39067d51
3
+ metadata.gz: 2d7b5f06be0565adefda429ed01d9b17960d10accc1e252896d922191f2fb097
4
+ data.tar.gz: 35c99d4fc80ea2bb5c1d843154ecd4b7ff5876b82b6459e6cac9dcfe5439fc57
5
5
  SHA512:
6
- metadata.gz: 47c4823b8cc92e1e3189dcc6d31a678129f6272817dac0b708f8c4195bdeccaf195320f2564cb4a7c7048ae68d7cf94ad289040616f96843e268081526de7cfc
7
- data.tar.gz: 35f1ca56f77df72772c85efc1e9675088a262d30bbe0a3fa13ff6927efcfcfc3b4795af2bf1527baeefdf920b4fa8db447e7a56ce42aae577c9672b57e3ac788
6
+ metadata.gz: 8d513b4642d262d9ee55c34b76784a48084dbacdd3a39f9bce40032d8e5c1f23c833b47b4494e767c329660e208d6c52282f2099d796ff8dc47e449590de9add
7
+ data.tar.gz: 5eb7fa43c9a76b18e18321ad87cc5c42670f98a2d76102ee923b83e4d73ddafc2a3e95d6a8503b180c31477950da08731198a05ae64b2301e8f17edf1e6c6348
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.1] - 2026-02-24
4
+
5
+ ### Fixed
6
+ - Install generator now creates Stimulus bridge controller (`dlnk_toast_controller.js`)
7
+ - Install generator now adds `stylesheet_link_tag` to layouts (required by Propshaft)
8
+ - Fixed importmap pin to resolve to `dlnk_toast/toast_controller.js`
9
+ - Generator detects and skips layouts that already include dlnk_toast
10
+
11
+ ### Changed
12
+ - Generator injects into all standard layouts (application, admin, auth)
13
+ - Improved post-install output
14
+
3
15
  ## [0.1.0] - 2026-02-24
4
16
 
5
17
  ### Added
@@ -9,6 +21,6 @@
9
21
  - Vanilla CSS with CSS variables for customization
10
22
  - Responsive design with mobile support
11
23
  - Accessibility features (ARIA labels, roles)
12
- - i18n support (English, French)
24
+ - I18n support (English, French)
13
25
  - Rails generator for easy installation
14
26
  - Configuration system for toast duration
data/README.md CHANGED
@@ -2,15 +2,17 @@
2
2
 
3
3
  Simple, elegant toast notifications for Rails 7+ applications using Hotwire and vanilla CSS.
4
4
 
5
+ Flash-based — just use `redirect_to ..., notice:` or `flash[:alert]` and toasts appear automatically.
6
+
5
7
  ## Features
6
8
 
7
- - Flash-based notifications (notice/alert)
8
- - 🎯 Stimulus controller for UX (pause on hover, dismiss)
9
- - 🎨 Vanilla CSS with CSS variables for easy customization
10
- - 📱 Responsive design
11
- - Built-in accessibility (ARIA labels, roles)
12
- - 🌍 Internationalization (i18n) support
13
- - 🚀 Zero JavaScript bundle impact (uses importmap)
9
+ - Flash-based notifications (`notice` and `alert`)
10
+ - Stimulus controller (pause on hover, click to dismiss)
11
+ - Vanilla CSS with CSS variables for easy theming
12
+ - Responsive (full-width on mobile)
13
+ - Accessible (ARIA roles and labels)
14
+ - I18n support (English, French built-in)
15
+ - Importmap-friendly
14
16
 
15
17
  ## Installation
16
18
 
@@ -20,40 +22,70 @@ Add to your Gemfile:
20
22
  gem "dlnk_toast"
21
23
  ```
22
24
 
23
- Then run the installer:
25
+ Then run:
24
26
 
25
27
  ```bash
26
28
  bundle install
27
29
  bin/rails generate dlnk_toast:install
28
30
  ```
29
31
 
30
- The installer will:
31
- - Create `config/initializers/dlnk_toast.rb`
32
- - Add the Stimulus controller to your importmap (if present)
33
- - Inject the toast partial into your layouts
32
+ The generator will:
33
+
34
+ 1. Create `config/initializers/dlnk_toast.rb`
35
+ 2. Pin the Stimulus controller in `config/importmap.rb`
36
+ 3. Create a bridge controller at `app/javascript/controllers/dlnk_toast_controller.js`
37
+ 4. Add `stylesheet_link_tag "dlnk_toast/application"` to your layouts
38
+ 5. Inject `<%= render "dlnk_toast/toast" %>` before `</body>` in your layouts
39
+
40
+ ### Manual setup
41
+
42
+ If you prefer to set things up yourself:
43
+
44
+ **Importmap** — `config/importmap.rb`:
45
+
46
+ ```ruby
47
+ pin "dlnk_toast/toast_controller", to: "dlnk_toast/toast_controller.js"
48
+ ```
49
+
50
+ **Stimulus bridge** — `app/javascript/controllers/dlnk_toast_controller.js`:
51
+
52
+ ```js
53
+ export { default } from "dlnk_toast/toast_controller"
54
+ ```
55
+
56
+ This bridge file is needed because Stimulus auto-loading only discovers controllers
57
+ inside `app/javascript/controllers/`. The bridge re-exports the gem's controller
58
+ under the identifier `dlnk-toast`.
59
+
60
+ **Stylesheet** — in each layout's `<head>`:
61
+
62
+ ```erb
63
+ <%= stylesheet_link_tag "dlnk_toast/application", "data-turbo-track": "reload" %>
64
+ ```
65
+
66
+ **Partial** — before `</body>` in each layout:
67
+
68
+ ```erb
69
+ <%= render "dlnk_toast/toast" %>
70
+ ```
34
71
 
35
72
  ## Usage
36
73
 
37
74
  Use Rails flash messages as usual:
38
75
 
39
76
  ```ruby
40
- def create
41
- @user = User.new(user_params)
42
- if @user.save
43
- redirect_to @user, notice: "User created successfully"
44
- else
45
- render :new, alert: "Failed to create user"
46
- end
47
- end
77
+ redirect_to @video, notice: "Video published"
48
78
  ```
49
79
 
50
- Your flash messages will automatically appear as toasts!
80
+ ```ruby
81
+ redirect_to root_path, alert: "Access denied"
82
+ ```
51
83
 
52
84
  ## Customization
53
85
 
54
86
  ### CSS Variables
55
87
 
56
- Override these in your `app/assets/stylesheets/application.css`:
88
+ Override in your application stylesheet:
57
89
 
58
90
  ```css
59
91
  :root {
@@ -61,9 +93,10 @@ Override these in your `app/assets/stylesheets/application.css`:
61
93
  --dlnk-toast-border: #1f1f1f;
62
94
  --dlnk-toast-text: #ffffff;
63
95
  --dlnk-toast-text-dim: #6B6B6B;
64
- --dlnk-toast-accent: #D4A017; /* Success color */
65
- --dlnk-toast-error: #ef4444; /* Alert color */
66
- --dlnk-toast-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
96
+ --dlnk-toast-accent: #D4A017;
97
+ --dlnk-toast-error: #ef4444;
98
+ --dlnk-toast-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
99
+ 0 10px 10px -5px rgba(0, 0, 0, 0.04);
67
100
  }
68
101
  ```
69
102
 
@@ -73,13 +106,13 @@ Edit `config/initializers/dlnk_toast.rb`:
73
106
 
74
107
  ```ruby
75
108
  DlnkToast.configure do |config|
76
- config.duration = 5000 # milliseconds
109
+ config.duration = 5000 # milliseconds (default: 4000)
77
110
  end
78
111
  ```
79
112
 
80
- ### Manual Rendering
113
+ ### Helper
81
114
 
82
- If you need to render toasts outside of layouts:
115
+ A `render_toast` helper is available if you need to render toasts outside layouts:
83
116
 
84
117
  ```erb
85
118
  <%= render_toast %>
@@ -87,23 +120,21 @@ If you need to render toasts outside of layouts:
87
120
 
88
121
  ## Translations
89
122
 
90
- Translations are provided for English and French. Add custom ones to your locale files:
123
+ Built-in translations for `en` and `fr`. Override in your locale files:
91
124
 
92
125
  ```yaml
93
- # config/locales/en.yml
94
- en:
126
+ fr:
95
127
  dlnk_toast:
96
- close: "Close"
128
+ close: "Fermer"
97
129
  ```
98
130
 
99
- ## Browser Support
131
+ ## Requirements
100
132
 
101
- Works in all modern browsers that support CSS Grid, Flexbox, and CSS custom properties.
133
+ - Ruby >= 3.0
134
+ - Rails >= 7.0
135
+ - Propshaft or Sprockets
136
+ - Importmap-rails (for Stimulus controller)
102
137
 
103
138
  ## License
104
139
 
105
- MIT License. See LICENSE file for details.
106
-
107
- ## Contributing
108
-
109
- Bug reports and pull requests are welcome on GitHub.
140
+ MIT
@@ -1,51 +1,9 @@
1
- <% if flash[:notice].present? %>
2
- <div class="dlnk-toast dlnk-toast--enter dlnk-toast--notice"
3
- role="status"
4
- aria-live="polite"
5
- data-controller="dlnk-toast"
6
- data-dlnk-toast-duration-value="<%= DlnkToast.configuration.duration %>"
7
- data-action="mouseenter->dlnk-toast#pause mouseleave->dlnk-toast#resume">
8
- <div class="dlnk-toast__body">
9
- <div class="dlnk-toast__content">
10
- <svg class="dlnk-toast__icon dlnk-toast__icon--success" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
11
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
12
- </svg>
13
- <span class="dlnk-toast__message"><%= flash[:notice] %></span>
14
- <button data-action="dlnk-toast#close" aria-label="<%= t('dlnk_toast.close') %>" class="dlnk-toast__close">
15
- <svg class="dlnk-toast__close-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
16
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
17
- </svg>
18
- </button>
19
- </div>
20
- <div class="dlnk-toast__progress-bar">
21
- <div data-dlnk-toast-target="progress" class="dlnk-toast__progress dlnk-toast__progress--success" style="width: 100%"></div>
22
- </div>
23
- </div>
24
- </div>
25
- <% end %>
1
+ <div id="dlnk-toast-container">
2
+ <% if flash[:notice].present? %>
3
+ <%= render "dlnk_toast/toast_message", type: :notice, message: flash[:notice] %>
4
+ <% end %>
26
5
 
27
- <% if flash[:alert].present? %>
28
- <div class="dlnk-toast dlnk-toast--enter dlnk-toast--alert"
29
- role="alert"
30
- aria-live="assertive"
31
- data-controller="dlnk-toast"
32
- data-dlnk-toast-duration-value="<%= DlnkToast.configuration.duration %>"
33
- data-action="mouseenter->dlnk-toast#pause mouseleave->dlnk-toast#resume">
34
- <div class="dlnk-toast__body">
35
- <div class="dlnk-toast__content">
36
- <svg class="dlnk-toast__icon dlnk-toast__icon--error" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
37
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
38
- </svg>
39
- <span class="dlnk-toast__message"><%= flash[:alert] %></span>
40
- <button data-action="dlnk-toast#close" aria-label="<%= t('dlnk_toast.close') %>" class="dlnk-toast__close">
41
- <svg class="dlnk-toast__close-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
42
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
43
- </svg>
44
- </button>
45
- </div>
46
- <div class="dlnk-toast__progress-bar">
47
- <div data-dlnk-toast-target="progress" class="dlnk-toast__progress dlnk-toast__progress--error" style="width: 100%"></div>
48
- </div>
49
- </div>
50
- </div>
51
- <% end %>
6
+ <% if flash[:alert].present? %>
7
+ <%= render "dlnk_toast/toast_message", type: :alert, message: flash[:alert] %>
8
+ <% end %>
9
+ </div>
@@ -0,0 +1,33 @@
1
+ <% type = local_assigns[:type]&.to_sym || :notice %>
2
+ <% msg = local_assigns[:message] %>
3
+ <% is_notice = type == :notice %>
4
+
5
+ <div class="dlnk-toast dlnk-toast--enter dlnk-toast--<%= is_notice ? 'notice' : 'alert' %>"
6
+ role="<%= is_notice ? 'status' : 'alert' %>"
7
+ aria-live="<%= is_notice ? 'polite' : 'assertive' %>"
8
+ data-controller="dlnk-toast"
9
+ data-dlnk-toast-duration-value="<%= DlnkToast.configuration.duration %>"
10
+ data-action="mouseenter->dlnk-toast#pause mouseleave->dlnk-toast#resume">
11
+ <div class="dlnk-toast__body">
12
+ <div class="dlnk-toast__content">
13
+ <% if is_notice %>
14
+ <svg class="dlnk-toast__icon dlnk-toast__icon--success" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
15
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
16
+ </svg>
17
+ <% else %>
18
+ <svg class="dlnk-toast__icon dlnk-toast__icon--error" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
19
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
20
+ </svg>
21
+ <% end %>
22
+ <span class="dlnk-toast__message"><%= msg %></span>
23
+ <button data-action="dlnk-toast#close" aria-label="<%= t('dlnk_toast.close') %>" class="dlnk-toast__close">
24
+ <svg class="dlnk-toast__close-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
25
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
26
+ </svg>
27
+ </button>
28
+ </div>
29
+ <div class="dlnk-toast__progress-bar">
30
+ <div data-dlnk-toast-target="progress" class="dlnk-toast__progress dlnk-toast__progress--<%= is_notice ? 'success' : 'error' %>" style="width: 100%"></div>
31
+ </div>
32
+ </div>
33
+ </div>
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DlnkToast
2
4
  class Engine < ::Rails::Engine
3
5
  isolate_namespace DlnkToast
@@ -18,5 +20,14 @@ module DlnkToast
18
20
  I18n.load_path << locale unless I18n.load_path.include?(locale)
19
21
  end
20
22
  end
23
+
24
+ initializer "dlnk_toast.turbo_streams" do
25
+ ActiveSupport.on_load(:action_view) do
26
+ if defined?(Turbo::Streams::TagBuilder) &&
27
+ !Turbo::Streams::TagBuilder.ancestors.include?(DlnkToast::Streams)
28
+ Turbo::Streams::TagBuilder.prepend(DlnkToast::Streams)
29
+ end
30
+ end
31
+ end
21
32
  end
22
33
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DlnkToast
4
+ module Streams
5
+ # Append a toast notification via Turbo Stream.
6
+ #
7
+ # turbo_stream.toast(:notice, "Saved!")
8
+ # turbo_stream.toast(:alert, "Something went wrong.")
9
+ #
10
+ def toast(type, message)
11
+ return if message.blank?
12
+
13
+ append "dlnk-toast-container",
14
+ partial: "dlnk_toast/toast_message",
15
+ locals: { type: type.to_sym, message: message }
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module DlnkToast
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/dlnk_toast.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "dlnk_toast/version"
2
2
  require "dlnk_toast/configuration"
3
+ require "dlnk_toast/streams"
3
4
  require "dlnk_toast/engine"
4
5
 
5
6
  module DlnkToast
@@ -9,35 +9,59 @@ module DlnkToast
9
9
 
10
10
  def copy_initializer
11
11
  copy_file "initializer.rb", "config/initializers/dlnk_toast.rb"
12
- say "Created config/initializers/dlnk_toast.rb"
13
12
  end
14
13
 
15
- def add_importmap_pin
14
+ def setup_importmap
16
15
  return unless File.exist?("config/importmap.rb")
17
- append_to_file "config/importmap.rb", "\npin \"dlnk_toast\", preload: true"
18
- say "Added dlnk_toast to importmap.rb"
16
+
17
+ append_to_file "config/importmap.rb",
18
+ %(\npin "dlnk_toast/toast_controller", to: "dlnk_toast/toast_controller.js"\n)
19
+ end
20
+
21
+ def create_stimulus_bridge
22
+ create_file "app/javascript/controllers/dlnk_toast_controller.js",
23
+ %(export { default } from "dlnk_toast/toast_controller"\n)
19
24
  end
20
25
 
21
- def inject_toast_in_layouts
22
- inject_into_file "app/views/layouts/application.html.erb", before: "</body>" do
23
- "\n <%= render 'dlnk_toast/toast' %>\n"
26
+ def inject_stylesheet
27
+ %w[application admin auth].each do |layout|
28
+ path = "app/views/layouts/#{layout}.html.erb"
29
+ next unless File.exist?(path)
30
+
31
+ content = File.read(path)
32
+ next if content.include?("dlnk_toast/application")
33
+
34
+ inject_into_file path,
35
+ after: /stylesheet_link_tag\s+:app.*\n/ do
36
+ %( <%= stylesheet_link_tag "dlnk_toast/application", "data-turbo-track": "reload" %>\n)
37
+ end
24
38
  end
25
- say "Added toast partial to app/views/layouts/application.html.erb"
39
+ end
40
+
41
+ def inject_toast_partial
42
+ %w[application admin auth].each do |layout|
43
+ path = "app/views/layouts/#{layout}.html.erb"
44
+ next unless File.exist?(path)
45
+
46
+ content = File.read(path)
47
+ next if content.include?("dlnk_toast/toast")
26
48
 
27
- if File.exist?("app/views/layouts/admin.html.erb")
28
- inject_into_file "app/views/layouts/admin.html.erb", before: "</body>" do
29
- "\n <%= render 'dlnk_toast/toast' %>\n"
49
+ inject_into_file path, before: "</body>" do
50
+ "\n <%= render \"dlnk_toast/toast\" %>\n "
30
51
  end
31
- say "Added toast partial to app/views/layouts/admin.html.erb"
32
52
  end
33
53
  end
34
54
 
35
- def display_next_steps
36
- say "\n✓ DlnkToast installed successfully!"
37
- say "\nNext steps:"
38
- say " 1. Customize CSS variables in app/assets/stylesheets/application.css"
39
- say " 2. Adjust toast duration in config/initializers/dlnk_toast.rb if needed"
40
- say " 3. Flash notices/alerts will now appear as toasts!"
55
+ def display_post_install
56
+ say ""
57
+ say "DlnkToast installed!", :green
58
+ say ""
59
+ say " Stylesheet: dlnk_toast/application.css added to layouts"
60
+ say " Controller: dlnk_toast_controller.js bridge created"
61
+ say " Partial: dlnk_toast/toast injected before </body>"
62
+ say " Config: config/initializers/dlnk_toast.rb"
63
+ say ""
64
+ say "Customize colors by overriding --dlnk-toast-* CSS variables."
41
65
  end
42
66
  end
43
67
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dlnk_toast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril
@@ -66,11 +66,13 @@ files:
66
66
  - app/helpers/dlnk_toast/toast_helper.rb
67
67
  - app/javascript/dlnk_toast/toast_controller.js
68
68
  - app/views/dlnk_toast/_toast.html.erb
69
+ - app/views/dlnk_toast/_toast_message.html.erb
69
70
  - config/locales/en.yml
70
71
  - config/locales/fr.yml
71
72
  - lib/dlnk_toast.rb
72
73
  - lib/dlnk_toast/configuration.rb
73
74
  - lib/dlnk_toast/engine.rb
75
+ - lib/dlnk_toast/streams.rb
74
76
  - lib/dlnk_toast/version.rb
75
77
  - lib/generators/dlnk_toast/install/install_generator.rb
76
78
  - lib/generators/dlnk_toast/install/templates/initializer.rb