faw_toast 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9d9054fe80f547f53c0c5bd6609cac4df141296d3ee4fbd28ba01ec3f74fe49b
4
+ data.tar.gz: 559b7cb87dbaf08f34bf9b6bc9f6a2088b9b148eec850316967b3448eb9c968f
5
+ SHA512:
6
+ metadata.gz: d0a8f13a9addd28afbf43dcb1c689d7a2ef418a9fce531e34bb7177afaad2289eb75b8c591894edb516ea1edbb9d1fec52518912fcb9de13b388597f1165e44c
7
+ data.tar.gz: ad1c7c85ddfdd1364ba1ded85c704c6427c7198cc0d797b760cd877c929f14dd0a9a36fc837747d010cffb37200dbb864d706c259230fc74865218c558e50a32
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # FawToast
2
+
3
+ A simple, configurable toast notification system for Rails applications. FawToast provides an easy way to display flash messages as toast notifications with minimal setup.
4
+
5
+ ## Features
6
+
7
+ - Easy integration with Rails 7+ applications
8
+ - CSS-only animations
9
+ - Configurable toast duration and position
10
+ - Customizable CSS classes for different flash types
11
+ - Support for standard flash types plus additional success and info types
12
+ - Simple to install and use
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'faw_toast'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ ```bash
25
+ bundle install
26
+ ```
27
+
28
+ Or install it yourself as:
29
+
30
+ ```bash
31
+ gem install faw_toast
32
+ ```
33
+
34
+ After installing the gem, run the installation generator:
35
+
36
+ ```bash
37
+ rails generate faw_toast:install
38
+ ```
39
+
40
+ This will:
41
+ 1. Create a configuration initializer at `config/initializers/faw_toast.rb`
42
+ 2. Add the toast container to your application layout
43
+ 3. Import the required stylesheet and JavaScript controller
44
+
45
+ ## Usage
46
+
47
+ FawToast works with Rails flash messages. You can use it like this:
48
+
49
+ ```ruby
50
+ # In your controller
51
+ def create
52
+ # Your logic here
53
+ flash[:success] = "Item was successfully created!"
54
+ redirect_to items_path
55
+ end
56
+ ```
57
+
58
+ FawToast supports the following flash types out of the box:
59
+ - `:success` - Green border
60
+ - `:alert` - Red border
61
+ - `:info` - Sky blue border
62
+ - `:notice` - Sky blue border
63
+ - Any other type will use the default indigo border
64
+
65
+ ## Configuration
66
+
67
+ You can configure FawToast by editing the initializer at `config/initializers/faw_toast.rb`:
68
+
69
+ ```ruby
70
+ FawToast.configure do |config|
71
+ # Duration in seconds for which the toast will be displayed
72
+ config.duration_seconds = '7s'
73
+
74
+ # Position of the toast container
75
+ # Available options: 'top-right', 'top-left', 'bottom-right', 'bottom-left', 'top-center', 'bottom-center'
76
+ config.position = 'top-right'
77
+
78
+ # CSS classes for different flash types
79
+ config.css_classes = {
80
+ success: 'border-l-10 border-green-500',
81
+ alert: 'border-l-10 border-red-500',
82
+ info: 'border-l-10 border-sky-600',
83
+ notice: 'border-l-10 border-sky-600',
84
+ default: 'border-l-10 border-indigo-500'
85
+ }
86
+ end
87
+ ```
88
+
89
+ ## How It Works
90
+
91
+ FawToast uses CSS animations to show and hide toast notifications automatically. Each toast includes:
92
+
93
+ 1. A colored left border indicating the message type (success, alert, info, etc.)
94
+ 2. The flash message content
95
+ 3. A progress bar that indicates how much time is left before the toast disappears
96
+
97
+ The toast appears with a slide-in animation, stays visible for the configured duration, and then slides out automatically. No JavaScript interaction is required for the basic functionality.
98
+
99
+ ## Development
100
+
101
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
102
+
103
+ ## Contributing
104
+
105
+ Bug reports and pull requests are welcome on GitHub at https://github.com/example/faw_toast.
106
+
107
+ ## License
108
+
109
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,129 @@
1
+ .faw-toast-container {
2
+ position: fixed;
3
+ z-index: 9999;
4
+ pointer-events: none;
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 0.5rem;
8
+
9
+ &.faw-toast-top-right {
10
+ top: 1rem;
11
+ right: 1rem;
12
+ }
13
+
14
+ &.faw-toast-top-left {
15
+ top: 1rem;
16
+ left: 1rem;
17
+ }
18
+
19
+ &.faw-toast-bottom-right {
20
+ bottom: 1rem;
21
+ right: 1rem;
22
+ }
23
+
24
+ &.faw-toast-bottom-left {
25
+ bottom: 1rem;
26
+ left: 1rem;
27
+ }
28
+
29
+ &.faw-toast-top-center {
30
+ top: 1rem;
31
+ left: 50%;
32
+ transform: translateX(-50%);
33
+ }
34
+
35
+ &.faw-toast-bottom-center {
36
+ bottom: 1rem;
37
+ left: 50%;
38
+ transform: translateX(-50%);
39
+ }
40
+ }
41
+
42
+ .faw-toast {
43
+ margin-bottom: 10px;
44
+ padding: 1rem;
45
+ border-radius: 4px;
46
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
47
+ position: relative;
48
+ overflow: hidden;
49
+ animation: faw-toast-slideIn 0.3s ease-in-out, faw-toast-slideOut 0.3s ease-in-out var(--faw-toast-duration) forwards;
50
+ max-width: 24rem;
51
+ width: 100%;
52
+ pointer-events: auto;
53
+ background-color: white;
54
+
55
+ &.faw-toast-border-l-10 {
56
+ border-left-width: 10px;
57
+ border-left-style: solid;
58
+ }
59
+
60
+ &.faw-toast-border-green-500 {
61
+ border-left-color: #10b981;
62
+ }
63
+
64
+ &.faw-toast-border-red-500 {
65
+ border-left-color: #ef4444;
66
+ }
67
+
68
+ &.faw-toast-border-sky-600 {
69
+ border-left-color: #0284c7;
70
+ }
71
+
72
+ &.faw-toast-border-indigo-500 {
73
+ border-left-color: #6366f1;
74
+ }
75
+
76
+ .faw-toast-content {
77
+ flex: 1;
78
+ }
79
+
80
+ .faw-toast-close {
81
+ cursor: pointer;
82
+ color: #6b7280;
83
+
84
+ &:hover {
85
+ color: #111827;
86
+ }
87
+ }
88
+
89
+ .faw-toast-progress {
90
+ position: absolute;
91
+ bottom: 0;
92
+ left: 0;
93
+ height: 3px;
94
+ background-color: rgba(0, 0, 0, 0.2);
95
+ width: 100%;
96
+ animation: faw-toast-progress var(--faw-toast-duration) linear;
97
+ }
98
+ }
99
+
100
+ @keyframes faw-toast-slideIn {
101
+ from {
102
+ transform: translateX(100%);
103
+ opacity: 0;
104
+ }
105
+ to {
106
+ transform: translateX(0);
107
+ opacity: 1;
108
+ }
109
+ }
110
+
111
+ @keyframes faw-toast-slideOut {
112
+ from {
113
+ transform: translateX(0);
114
+ opacity: 1;
115
+ }
116
+ to {
117
+ transform: translateX(100%);
118
+ opacity: 0;
119
+ }
120
+ }
121
+
122
+ @keyframes faw-toast-progress {
123
+ from {
124
+ width: 100%;
125
+ }
126
+ to {
127
+ width: 0;
128
+ }
129
+ }
@@ -0,0 +1,37 @@
1
+ // Self-initializing toast handler
2
+ document.addEventListener('DOMContentLoaded', function() {
3
+ console.log('DOMContentLoaded');
4
+ // Function to handle toast animations
5
+ function setupToastListeners() {
6
+ // Find all toast elements
7
+ const toasts = document.querySelectorAll('.faw-toast');
8
+
9
+ // Add animation end listeners to each toast
10
+ toasts.forEach(function(toast) {
11
+ toast.addEventListener('animationend', function(event) {
12
+ // Only remove the toast when the slideOut animation completes
13
+ if (event.animationName === 'faw-toast-slideOut') {
14
+ toast.remove();
15
+ }
16
+ });
17
+ });
18
+ }
19
+
20
+ // Initial setup
21
+ setupToastListeners();
22
+
23
+ // Also handle dynamically added toasts (for turbo/ajax)
24
+ const observer = new MutationObserver(function(mutations) {
25
+ mutations.forEach(function(mutation) {
26
+ if (mutation.addedNodes.length) {
27
+ setupToastListeners();
28
+ }
29
+ });
30
+ });
31
+
32
+ // Start observing the document for added nodes
33
+ observer.observe(document.body, {
34
+ childList: true,
35
+ subtree: true
36
+ });
37
+ });
@@ -0,0 +1,9 @@
1
+ <%# Toast partial for rendering flash messages %>
2
+ <% if flash.any? %>
3
+ <% flash.each do |type, message| %>
4
+ <div class="faw-toast <%= flash_class(type) %>">
5
+ <%= message %>
6
+ <div class="faw-toast-progress"></div>
7
+ </div>
8
+ <% end %>
9
+ <% end %>
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FawToast
4
+ class Configuration
5
+ attr_accessor :duration_seconds, :position, :css_classes
6
+
7
+ def initialize
8
+ @duration_seconds = "7s"
9
+ @position = 'top-right'
10
+ @css_classes = {
11
+ success: 'faw-toast-border-l-10 faw-toast-border-green-500',
12
+ alert: 'faw-toast-border-l-10 faw-toast-border-red-500',
13
+ info: 'faw-toast-border-l-10 faw-toast-border-sky-600',
14
+ notice: 'faw-toast-border-l-10 faw-toast-border-sky-600',
15
+ default: 'faw-toast-border-l-10 faw-toast-border-indigo-500'
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FawToast
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace FawToast
6
+
7
+ initializer "faw_toast.helpers" do
8
+ ActiveSupport.on_load(:action_controller) do
9
+ include FawToast::ToastHelper
10
+ end
11
+
12
+ ActiveSupport.on_load(:action_view) do
13
+ include FawToast::ToastHelper
14
+ end
15
+ end
16
+
17
+ initializer "faw_toast.flash_types" do
18
+ ActionController::Base.add_flash_types :success, :info
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FawToast
4
+ module ToastHelper
5
+ def flash_class(type)
6
+ FawToast.configuration.css_classes[type.to_sym] || FawToast.configuration.css_classes[:default]
7
+ end
8
+
9
+ def render_toast
10
+ render partial: "faw_toast/toast"
11
+ end
12
+
13
+ def toast_container
14
+ content_tag :div, id: "faw-toast-container", class: "faw-toast-container faw-toast-#{FawToast.configuration.position}" do
15
+ render_toast
16
+ end
17
+ end
18
+
19
+ def toast_css_variables
20
+ # Generate a style tag with CSS variables based on configuration
21
+ content_tag :style do
22
+ ":root { --faw-toast-duration: #{FawToast.configuration.duration_seconds}; }".html_safe
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FawToast
4
+ VERSION = "1.0.0"
5
+ end
data/lib/faw_toast.rb ADDED
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "faw_toast/version"
4
+ require_relative "faw_toast/engine"
5
+ require_relative "faw_toast/configuration"
6
+ require_relative "faw_toast/toast_helper"
7
+
8
+ module FawToast
9
+ class Error < StandardError; end
10
+
11
+ class << self
12
+ attr_writer :configuration
13
+
14
+ def configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ def configure
19
+ yield(configuration)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FawToast
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ desc "Installs FawToast configuration"
9
+
10
+ def copy_initializer
11
+ template "faw_toast.rb", "config/initializers/faw_toast.rb"
12
+ end
13
+
14
+ def add_css_variables_to_layout
15
+ inject_into_file "app/views/layouts/application.html.erb", after: "<head>" do
16
+ <<-HTML
17
+
18
+ <%= toast_css_variables %>
19
+ HTML
20
+ end
21
+ end
22
+
23
+ def add_toast_container_to_layout
24
+ inject_into_file "app/views/layouts/application.html.erb", before: "</body>" do
25
+ <<-HTML
26
+ <%= toast_container %>
27
+ HTML
28
+ end
29
+ end
30
+
31
+ def add_stylesheet_import
32
+ if File.exist?("app/assets/stylesheets/application.scss")
33
+ append_to_file "app/assets/stylesheets/application.scss" do
34
+ "\n@import \"faw_toast\";\n"
35
+ end
36
+ else
37
+ say "Please manually import the FawToast stylesheet in your application", :red
38
+ end
39
+ end
40
+
41
+ def add_javascript_import
42
+ if File.exist?("app/javascript/application.js")
43
+ append_to_file "app/javascript/application.js" do
44
+ "import \"faw_toast\"\n"
45
+ end
46
+ elsif File.exist?("app/assets/javascripts/application.js")
47
+ append_to_file "app/assets/javascripts/application.js" do
48
+ "//= require faw_toast\n"
49
+ end
50
+ else
51
+ say "Please manually import the FawToast JavaScript in your application", :red
52
+ end
53
+ end
54
+
55
+ def update_tsconfig
56
+ gem_path = `bundle show faw_toast`.chomp
57
+
58
+ # Default tsconfig structure if file doesn't exist
59
+ tsconfig = if File.exist?("tsconfig.json")
60
+ JSON.parse(File.read("tsconfig.json"))
61
+ else
62
+ {
63
+ "compilerOptions" => {
64
+ "baseUrl" => ".",
65
+ "paths" => {}
66
+ }
67
+ }
68
+ end
69
+
70
+ tsconfig["compilerOptions"] ||= {}
71
+ tsconfig["compilerOptions"]["paths"] ||= {}
72
+ tsconfig["compilerOptions"]["paths"]["faw_toast"] = ["#{gem_path}/app/javascript/faw_toast.js"]
73
+
74
+ File.write("tsconfig.json", JSON.pretty_generate(tsconfig))
75
+
76
+ say "Updated tsconfig.json with FawToast paths", :green
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ FawToast.configure do |config|
4
+ # Duration in seconds for which the toast will be displayed
5
+ # config.duration_seconds = '7s'
6
+
7
+ # Position of the toast container
8
+ # Available options: 'top-right', 'top-left', 'bottom-right', 'bottom-left', 'top-center', 'bottom-center'
9
+ # config.position = 'top-right'
10
+
11
+ # CSS classes for different flash types
12
+ # config.css_classes = {
13
+ # success: 'faw-toast-border-l-10 faw-toast-border-green-500',
14
+ # alert: 'faw-toast-border-l-10 faw-toast-border-red-500',
15
+ # info: 'faw-toast-border-l-10 faw-toast-border-sky-600',
16
+ # notice: 'faw-toast-border-l-10 faw-toast-border-sky-600',
17
+ # default: 'faw-toast-border-l-10 faw-toast-border-indigo-500'
18
+ # }
19
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: faw_toast
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - alexwebgr
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-04-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
27
+ description: FawToast provides an easy way to display flash messages as toast notifications
28
+ in Rails applications
29
+ email:
30
+ - info@example.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - LICENSE.txt
36
+ - README.md
37
+ - Rakefile
38
+ - app/assets/stylesheets/faw_toast.scss
39
+ - app/javascript/faw_toast.js
40
+ - app/views/faw_toast/_toast.html.erb
41
+ - lib/faw_toast.rb
42
+ - lib/faw_toast/configuration.rb
43
+ - lib/faw_toast/engine.rb
44
+ - lib/faw_toast/toast_helper.rb
45
+ - lib/faw_toast/version.rb
46
+ - lib/generators/faw_toast/install/install_generator.rb
47
+ - lib/generators/faw_toast/install/templates/faw_toast.rb
48
+ homepage: https://github.com/alexwebgr/faw_toast
49
+ licenses:
50
+ - MIT
51
+ metadata:
52
+ homepage_uri: https://github.com/alexwebgr/faw_toast
53
+ source_code_uri: https://github.com/alexwebgr/faw_toast
54
+ changelog_uri: https://github.com/alexwebgr/faw_toast/blob/main/CHANGELOG.md
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 3.0.0
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubygems_version: 3.3.7
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: A simple, configurable toast notification system for Rails applications
74
+ test_files: []