faw_toast 1.2.2 → 1.4.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 +4 -4
- data/README.md +53 -8
- data/app/assets/javascripts/faw_toast.js +4 -1
- data/app/assets/stylesheets/faw_toast.css +77 -24
- data/app/assets/stylesheets/faw_toast.css.map +1 -1
- data/app/assets/stylesheets/faw_toast.scss +129 -28
- data/app/views/faw_toast/_toast.html.erb +5 -8
- data/lib/faw_toast/configuration.rb +8 -7
- data/lib/faw_toast/toast_helper.rb +43 -2
- data/lib/faw_toast/version.rb +1 -1
- data/lib/generators/faw_toast/install/install_generator.rb +1 -1
- data/lib/generators/faw_toast/install/templates/faw_toast.rb +9 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 314d01dd20348f62a6246f377322f8228ef2b021a9f4fc8ce499d76987a19f64
|
4
|
+
data.tar.gz: 272d6ce0491dc17f9219050a89fcb5a8209cc61394d2c86007a74a5cf0c539ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65ee75966b4fadf82dbf968d263753f105b7bdf5a1a0970496456ab8abbfbe2663ec50911aafd7afe645dd57b3e46770a687443099545bae7e2b817b00a2d962
|
7
|
+
data.tar.gz: 92ee429a17c88b3669d62e37d001f316670e81203bdff9129ae2f83eb5478795f776ed2d14679b340aa772628ff78a1832ab4066b7d789d1ca9e436f801b0a29
|
data/README.md
CHANGED
@@ -57,6 +57,8 @@ and if you are using `sprockets` include the following lines in your `config/man
|
|
57
57
|
|
58
58
|
## Usage
|
59
59
|
|
60
|
+
### Basic Usage
|
61
|
+
|
60
62
|
FawToast works with Rails flash messages. You can use it like this
|
61
63
|
|
62
64
|
```ruby
|
@@ -85,6 +87,28 @@ Turbo::StreamsChannel.broadcast_append_to(
|
|
85
87
|
)
|
86
88
|
```
|
87
89
|
|
90
|
+
### With Turbo Streams
|
91
|
+
|
92
|
+
For Turbo Streams applications, you can use the built-in `render_message` helper:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
# In your controller
|
96
|
+
def create
|
97
|
+
# Your logic here
|
98
|
+
render_message(:success, :ok, "Item was successfully created!")
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
The `render_message` method takes three parameters:
|
103
|
+
- `flash_type`: The type of flash message (:success, :alert, :danger, etc.)
|
104
|
+
- `status`: The HTTP status code to return (:ok, :created, etc.)
|
105
|
+
- `message`: The message to display in the toast
|
106
|
+
|
107
|
+
This helper automatically:
|
108
|
+
1. Sets the flash message
|
109
|
+
2. Renders a Turbo Stream that appends the toast to the toast container
|
110
|
+
3. Sets the appropriate HTTP status code
|
111
|
+
|
88
112
|
FawToast supports the following flash types out of the box:
|
89
113
|
- `:success` - Green border
|
90
114
|
- `:alert` - Red border
|
@@ -102,18 +126,21 @@ FawToast.configure do |config|
|
|
102
126
|
# Duration in seconds for which the toast will be displayed
|
103
127
|
config.duration_seconds = '7s'
|
104
128
|
|
129
|
+
# Background color of the progress bar. It can be any valid CSS color value
|
130
|
+
config.progress_bar_bg = "rgba(0, 0, 0, 0.2)"
|
131
|
+
|
105
132
|
# Position of the toast container
|
106
133
|
# Available options: 'top-right', 'top-left', 'bottom-right', 'bottom-left', 'top-center', 'bottom-center'
|
107
134
|
config.position = 'top-right'
|
108
135
|
|
109
136
|
# CSS classes for different flash types
|
110
137
|
config.css_classes = {
|
111
|
-
success: 'faw-toast-border-
|
112
|
-
alert: 'faw-toast-border-
|
113
|
-
danger: 'faw-toast-border-
|
114
|
-
info: 'faw-toast-border-
|
115
|
-
notice: 'faw-toast-border-
|
116
|
-
default: 'faw-toast-border-
|
138
|
+
success: 'faw-toast-border-green',
|
139
|
+
alert: 'faw-toast-border-red',
|
140
|
+
danger: 'faw-toast-border-red',
|
141
|
+
info: 'faw-toast-border-sky',
|
142
|
+
notice: 'faw-toast-border-sky',
|
143
|
+
default: 'faw-toast-border-indigo'
|
117
144
|
}
|
118
145
|
end
|
119
146
|
```
|
@@ -122,11 +149,29 @@ end
|
|
122
149
|
|
123
150
|
FawToast uses CSS animations to show and hide toast notifications automatically. Each toast includes:
|
124
151
|
|
125
|
-
1. A colored
|
152
|
+
1. A colored border indicating the message type (success, alert, info, etc.)
|
126
153
|
2. The flash message content
|
127
154
|
3. A progress bar that indicates how much time is left before the toast disappears
|
128
155
|
|
129
|
-
The toast appears with a slide-in animation, stays visible for the configured duration, and then slides out automatically
|
156
|
+
The toast appears with a slide-in animation, stays visible for the configured duration, and then slides out automatically.
|
157
|
+
|
158
|
+
The border position and animation direction are automatically determined based on the toast position:
|
159
|
+
|
160
|
+
- **For top-right and bottom-right positions:**
|
161
|
+
- The border is on the left side
|
162
|
+
- Toasts slide in from the right and slide out to the right
|
163
|
+
|
164
|
+
- **For top-left and bottom-left positions:**
|
165
|
+
- The border is on the right side
|
166
|
+
- Toasts slide in from the left and slide out to the left
|
167
|
+
|
168
|
+
- **For top-center position:**
|
169
|
+
- The border is at the top
|
170
|
+
- Toasts slide in from the top and slide out to the top
|
171
|
+
|
172
|
+
- **For bottom-center position:**
|
173
|
+
- The border is at the top
|
174
|
+
- Toasts slide in from the bottom and slide out to the bottom
|
130
175
|
|
131
176
|
## Development
|
132
177
|
|
@@ -8,7 +8,10 @@ function faw_init() {
|
|
8
8
|
toasts.forEach(function(toast) {
|
9
9
|
toast.addEventListener('animationend', function(event) {
|
10
10
|
// Only remove the toast when the slideOut animation completes
|
11
|
-
if (event.animationName === 'faw-toast-
|
11
|
+
if (event.animationName === 'faw-toast-slideOutRight' ||
|
12
|
+
event.animationName === 'faw-toast-slideOutLeft' ||
|
13
|
+
event.animationName === 'faw-toast-slideOutTop' ||
|
14
|
+
event.animationName === 'faw-toast-slideOutBottom') {
|
12
15
|
toast.remove();
|
13
16
|
}
|
14
17
|
});
|
@@ -1,54 +1,65 @@
|
|
1
1
|
.faw-toast-container {
|
2
2
|
position: fixed;
|
3
3
|
z-index: 9999;
|
4
|
-
pointer-events: none;
|
5
4
|
display: flex;
|
6
5
|
flex-direction: column;
|
7
6
|
gap: 0.5rem; }
|
8
|
-
.faw-toast-container.faw-toast-top-right {
|
9
|
-
top: 1rem;
|
10
|
-
right: 1rem; }
|
11
7
|
.faw-toast-container.faw-toast-top-left {
|
12
8
|
top: 1rem;
|
13
|
-
left:
|
14
|
-
.faw-toast-container.faw-toast-bottom-right {
|
15
|
-
bottom: 1rem;
|
16
|
-
right: 1rem; }
|
17
|
-
.faw-toast-container.faw-toast-bottom-left {
|
18
|
-
bottom: 1rem;
|
19
|
-
left: 1rem; }
|
9
|
+
left: 0.5rem; }
|
20
10
|
.faw-toast-container.faw-toast-top-center {
|
21
11
|
top: 1rem;
|
22
12
|
left: 50%;
|
23
13
|
transform: translateX(-50%); }
|
14
|
+
.faw-toast-container.faw-toast-top-right {
|
15
|
+
top: 3rem;
|
16
|
+
right: 0.5rem; }
|
17
|
+
.faw-toast-container.faw-toast-bottom-right {
|
18
|
+
bottom: 1rem;
|
19
|
+
right: 0.5rem; }
|
24
20
|
.faw-toast-container.faw-toast-bottom-center {
|
25
21
|
bottom: 1rem;
|
26
22
|
left: 50%;
|
27
23
|
transform: translateX(-50%); }
|
24
|
+
.faw-toast-container.faw-toast-bottom-left {
|
25
|
+
bottom: 1rem;
|
26
|
+
left: 0.5rem; }
|
28
27
|
|
29
28
|
.faw-toast {
|
30
|
-
margin-bottom: 10px;
|
31
29
|
padding: 1rem;
|
32
30
|
border-radius: 4px;
|
33
31
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
34
32
|
position: relative;
|
35
33
|
overflow: hidden;
|
36
|
-
animation: faw-toast-slideIn 0.3s ease-in-out, faw-toast-slideOut 0.3s ease-in-out var(--faw-toast-duration) forwards;
|
37
34
|
max-width: 24rem;
|
38
|
-
width:
|
39
|
-
|
35
|
+
min-width: 300px;
|
36
|
+
text-align: center;
|
40
37
|
background-color: white; }
|
41
|
-
.faw-toast.faw-toast-
|
38
|
+
.faw-toast.faw-toast-slide-left {
|
39
|
+
animation: faw-toast-slideInLeft 0.3s ease-in-out, faw-toast-slideOutLeft 0.3s ease-in-out var(--faw-toast-duration) forwards; }
|
40
|
+
.faw-toast.faw-toast-slide-top {
|
41
|
+
animation: faw-toast-slideInTop 0.3s ease-in-out, faw-toast-slideOutTop 0.3s ease-in-out var(--faw-toast-duration) forwards; }
|
42
|
+
.faw-toast.faw-toast-slide-right {
|
43
|
+
animation: faw-toast-slideInRight 0.3s ease-in-out, faw-toast-slideOutRight 0.3s ease-in-out var(--faw-toast-duration) forwards; }
|
44
|
+
.faw-toast.faw-toast-slide-bottom {
|
45
|
+
animation: faw-toast-slideInBottom 0.3s ease-in-out, faw-toast-slideOutBottom 0.3s ease-in-out var(--faw-toast-duration) forwards; }
|
46
|
+
.faw-toast.faw-toast-border-left-10 {
|
42
47
|
border-left-width: 10px;
|
43
48
|
border-left-style: solid; }
|
49
|
+
.faw-toast.faw-toast-border-top-10 {
|
50
|
+
border-top-width: 10px;
|
51
|
+
border-top-style: solid; }
|
52
|
+
.faw-toast.faw-toast-border-right-10 {
|
53
|
+
border-right-width: 10px;
|
54
|
+
border-right-style: solid; }
|
44
55
|
.faw-toast.faw-toast-border-green {
|
45
|
-
border-
|
56
|
+
border-color: #10b981; }
|
46
57
|
.faw-toast.faw-toast-border-red {
|
47
|
-
border-
|
58
|
+
border-color: #ef4444; }
|
48
59
|
.faw-toast.faw-toast-border-sky {
|
49
|
-
border-
|
60
|
+
border-color: #0284c7; }
|
50
61
|
.faw-toast.faw-toast-border-indigo {
|
51
|
-
border-
|
62
|
+
border-color: #6366f1; }
|
52
63
|
.faw-toast .faw-toast-content {
|
53
64
|
flex: 1; }
|
54
65
|
.faw-toast .faw-toast-close {
|
@@ -61,24 +72,66 @@
|
|
61
72
|
bottom: 0;
|
62
73
|
left: 0;
|
63
74
|
height: 3px;
|
64
|
-
background-color:
|
75
|
+
background-color: var(--faw-toast-progress-bar-bg);
|
65
76
|
width: 100%;
|
66
|
-
animation: faw-toast-progress var(--faw-toast-duration) linear; }
|
77
|
+
animation: faw-toast-progress var(--faw-toast-duration) linear forwards; }
|
67
78
|
|
68
|
-
@keyframes faw-toast-
|
79
|
+
@keyframes faw-toast-slideInRight {
|
69
80
|
from {
|
70
81
|
transform: translateX(100%);
|
71
82
|
opacity: 0; }
|
72
83
|
to {
|
73
84
|
transform: translateX(0);
|
74
85
|
opacity: 1; } }
|
75
|
-
@keyframes faw-toast-
|
86
|
+
@keyframes faw-toast-slideOutRight {
|
76
87
|
from {
|
77
88
|
transform: translateX(0);
|
78
89
|
opacity: 1; }
|
79
90
|
to {
|
80
91
|
transform: translateX(100%);
|
81
92
|
opacity: 0; } }
|
93
|
+
@keyframes faw-toast-slideInLeft {
|
94
|
+
from {
|
95
|
+
transform: translateX(-100%);
|
96
|
+
opacity: 0; }
|
97
|
+
to {
|
98
|
+
transform: translateX(0);
|
99
|
+
opacity: 1; } }
|
100
|
+
@keyframes faw-toast-slideOutLeft {
|
101
|
+
from {
|
102
|
+
transform: translateX(0);
|
103
|
+
opacity: 1; }
|
104
|
+
to {
|
105
|
+
transform: translateX(-100%);
|
106
|
+
opacity: 0; } }
|
107
|
+
@keyframes faw-toast-slideInTop {
|
108
|
+
from {
|
109
|
+
transform: translateY(-100%);
|
110
|
+
opacity: 0; }
|
111
|
+
to {
|
112
|
+
transform: translateY(0);
|
113
|
+
opacity: 1; } }
|
114
|
+
@keyframes faw-toast-slideOutTop {
|
115
|
+
from {
|
116
|
+
transform: translateY(0);
|
117
|
+
opacity: 1; }
|
118
|
+
to {
|
119
|
+
transform: translateY(-100%);
|
120
|
+
opacity: 0; } }
|
121
|
+
@keyframes faw-toast-slideInBottom {
|
122
|
+
from {
|
123
|
+
transform: translateY(100%);
|
124
|
+
opacity: 0; }
|
125
|
+
to {
|
126
|
+
transform: translateY(0);
|
127
|
+
opacity: 1; } }
|
128
|
+
@keyframes faw-toast-slideOutBottom {
|
129
|
+
from {
|
130
|
+
transform: translateY(0);
|
131
|
+
opacity: 1; }
|
132
|
+
to {
|
133
|
+
transform: translateY(100%);
|
134
|
+
opacity: 0; } }
|
82
135
|
@keyframes faw-toast-progress {
|
83
136
|
from {
|
84
137
|
width: 100%; }
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"version": 3,
|
3
|
-
"mappings": "AAAA,oBAAqB;EACnB,QAAQ,EAAE,KAAK;EACf,OAAO,EAAE,IAAI;EACb,
|
3
|
+
"mappings": "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",
|
4
4
|
"sources": ["faw_toast.scss"],
|
5
5
|
"names": [],
|
6
6
|
"file": "faw_toast.css"
|
@@ -1,76 +1,107 @@
|
|
1
1
|
.faw-toast-container {
|
2
2
|
position: fixed;
|
3
3
|
z-index: 9999;
|
4
|
-
pointer-events: none;
|
5
4
|
display: flex;
|
6
5
|
flex-direction: column;
|
7
6
|
gap: 0.5rem;
|
8
7
|
|
9
|
-
&.faw-toast-top-
|
8
|
+
&.faw-toast-top-left {
|
10
9
|
top: 1rem;
|
11
|
-
|
10
|
+
left: 0.5rem;
|
12
11
|
}
|
13
12
|
|
14
|
-
&.faw-toast-top-
|
13
|
+
&.faw-toast-top-center {
|
15
14
|
top: 1rem;
|
16
|
-
left:
|
15
|
+
left: 50%;
|
16
|
+
transform: translateX(-50%);
|
17
17
|
}
|
18
18
|
|
19
|
-
&.faw-toast-
|
20
|
-
|
21
|
-
right:
|
19
|
+
&.faw-toast-top-right {
|
20
|
+
top: 3rem;
|
21
|
+
right: 0.5rem;
|
22
22
|
}
|
23
23
|
|
24
|
-
&.faw-toast-bottom-
|
24
|
+
&.faw-toast-bottom-right {
|
25
25
|
bottom: 1rem;
|
26
|
-
|
26
|
+
right: 0.5rem;
|
27
27
|
}
|
28
28
|
|
29
|
-
&.faw-toast-
|
30
|
-
|
29
|
+
&.faw-toast-bottom-center {
|
30
|
+
bottom: 1rem;
|
31
31
|
left: 50%;
|
32
32
|
transform: translateX(-50%);
|
33
33
|
}
|
34
34
|
|
35
|
-
&.faw-toast-bottom-
|
35
|
+
&.faw-toast-bottom-left {
|
36
36
|
bottom: 1rem;
|
37
|
-
left:
|
38
|
-
transform: translateX(-50%);
|
37
|
+
left: 0.5rem;
|
39
38
|
}
|
40
39
|
}
|
41
40
|
|
42
41
|
.faw-toast {
|
43
|
-
margin-bottom: 10px;
|
44
42
|
padding: 1rem;
|
45
43
|
border-radius: 4px;
|
46
44
|
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
47
45
|
position: relative;
|
48
46
|
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
47
|
max-width: 24rem;
|
51
|
-
width:
|
52
|
-
|
48
|
+
min-width: 300px;
|
49
|
+
text-align: center;
|
53
50
|
background-color: white;
|
54
51
|
|
55
|
-
|
52
|
+
// Left-side animations (for top-left and bottom-left positions)
|
53
|
+
&.faw-toast-slide-left {
|
54
|
+
animation: faw-toast-slideInLeft 0.3s ease-in-out, faw-toast-slideOutLeft 0.3s ease-in-out var(--faw-toast-duration) forwards;
|
55
|
+
}
|
56
|
+
|
57
|
+
// Top animations (for top-center position)
|
58
|
+
&.faw-toast-slide-top {
|
59
|
+
animation: faw-toast-slideInTop 0.3s ease-in-out, faw-toast-slideOutTop 0.3s ease-in-out var(--faw-toast-duration) forwards;
|
60
|
+
}
|
61
|
+
|
62
|
+
// Right-side animations (for top-right and bottom-right positions)
|
63
|
+
&.faw-toast-slide-right {
|
64
|
+
animation: faw-toast-slideInRight 0.3s ease-in-out, faw-toast-slideOutRight 0.3s ease-in-out var(--faw-toast-duration) forwards;
|
65
|
+
}
|
66
|
+
|
67
|
+
// Bottom animations (for bottom-center position)
|
68
|
+
&.faw-toast-slide-bottom {
|
69
|
+
animation: faw-toast-slideInBottom 0.3s ease-in-out, faw-toast-slideOutBottom 0.3s ease-in-out var(--faw-toast-duration) forwards;
|
70
|
+
}
|
71
|
+
|
72
|
+
// Left border
|
73
|
+
&.faw-toast-border-left-10 {
|
56
74
|
border-left-width: 10px;
|
57
75
|
border-left-style: solid;
|
58
76
|
}
|
59
77
|
|
78
|
+
// Top border
|
79
|
+
&.faw-toast-border-top-10 {
|
80
|
+
border-top-width: 10px;
|
81
|
+
border-top-style: solid;
|
82
|
+
}
|
83
|
+
|
84
|
+
// Right border
|
85
|
+
&.faw-toast-border-right-10 {
|
86
|
+
border-right-width: 10px;
|
87
|
+
border-right-style: solid;
|
88
|
+
}
|
89
|
+
|
90
|
+
// Border colors
|
60
91
|
&.faw-toast-border-green {
|
61
|
-
border-
|
92
|
+
border-color: #10b981;
|
62
93
|
}
|
63
94
|
|
64
95
|
&.faw-toast-border-red {
|
65
|
-
border-
|
96
|
+
border-color: #ef4444;
|
66
97
|
}
|
67
98
|
|
68
99
|
&.faw-toast-border-sky {
|
69
|
-
border-
|
100
|
+
border-color: #0284c7;
|
70
101
|
}
|
71
102
|
|
72
103
|
&.faw-toast-border-indigo {
|
73
|
-
border-
|
104
|
+
border-color: #6366f1;
|
74
105
|
}
|
75
106
|
|
76
107
|
.faw-toast-content {
|
@@ -91,13 +122,14 @@
|
|
91
122
|
bottom: 0;
|
92
123
|
left: 0;
|
93
124
|
height: 3px;
|
94
|
-
background-color:
|
125
|
+
background-color: var(--faw-toast-progress-bar-bg);
|
95
126
|
width: 100%;
|
96
|
-
animation: faw-toast-progress var(--faw-toast-duration) linear;
|
127
|
+
animation: faw-toast-progress var(--faw-toast-duration) linear forwards;
|
97
128
|
}
|
98
129
|
}
|
99
130
|
|
100
|
-
|
131
|
+
// Right-side animations
|
132
|
+
@keyframes faw-toast-slideInRight {
|
101
133
|
from {
|
102
134
|
transform: translateX(100%);
|
103
135
|
opacity: 0;
|
@@ -108,7 +140,7 @@
|
|
108
140
|
}
|
109
141
|
}
|
110
142
|
|
111
|
-
@keyframes faw-toast-
|
143
|
+
@keyframes faw-toast-slideOutRight {
|
112
144
|
from {
|
113
145
|
transform: translateX(0);
|
114
146
|
opacity: 1;
|
@@ -119,6 +151,75 @@
|
|
119
151
|
}
|
120
152
|
}
|
121
153
|
|
154
|
+
// Left-side animations
|
155
|
+
@keyframes faw-toast-slideInLeft {
|
156
|
+
from {
|
157
|
+
transform: translateX(-100%);
|
158
|
+
opacity: 0;
|
159
|
+
}
|
160
|
+
to {
|
161
|
+
transform: translateX(0);
|
162
|
+
opacity: 1;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
@keyframes faw-toast-slideOutLeft {
|
167
|
+
from {
|
168
|
+
transform: translateX(0);
|
169
|
+
opacity: 1;
|
170
|
+
}
|
171
|
+
to {
|
172
|
+
transform: translateX(-100%);
|
173
|
+
opacity: 0;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
// Top animations
|
178
|
+
@keyframes faw-toast-slideInTop {
|
179
|
+
from {
|
180
|
+
transform: translateY(-100%);
|
181
|
+
opacity: 0;
|
182
|
+
}
|
183
|
+
to {
|
184
|
+
transform: translateY(0);
|
185
|
+
opacity: 1;
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
@keyframes faw-toast-slideOutTop {
|
190
|
+
from {
|
191
|
+
transform: translateY(0);
|
192
|
+
opacity: 1;
|
193
|
+
}
|
194
|
+
to {
|
195
|
+
transform: translateY(-100%);
|
196
|
+
opacity: 0;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
// Bottom animations
|
201
|
+
@keyframes faw-toast-slideInBottom {
|
202
|
+
from {
|
203
|
+
transform: translateY(100%);
|
204
|
+
opacity: 0;
|
205
|
+
}
|
206
|
+
to {
|
207
|
+
transform: translateY(0);
|
208
|
+
opacity: 1;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
@keyframes faw-toast-slideOutBottom {
|
213
|
+
from {
|
214
|
+
transform: translateY(0);
|
215
|
+
opacity: 1;
|
216
|
+
}
|
217
|
+
to {
|
218
|
+
transform: translateY(100%);
|
219
|
+
opacity: 0;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
122
223
|
@keyframes faw-toast-progress {
|
123
224
|
from {
|
124
225
|
width: 100%;
|
@@ -1,9 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
<div class="faw-toast
|
5
|
-
|
6
|
-
<div class="faw-toast-progress"></div>
|
7
|
-
</div>
|
8
|
-
<% end %>
|
1
|
+
<% flash.each do |type, message| %>
|
2
|
+
<div class="faw-toast <%= flash_class(type) %>">
|
3
|
+
<%= message %>
|
4
|
+
<div class="faw-toast-progress"></div>
|
5
|
+
</div>
|
9
6
|
<% end %>
|
@@ -2,18 +2,19 @@
|
|
2
2
|
|
3
3
|
module FawToast
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :duration_seconds, :position, :css_classes
|
5
|
+
attr_accessor :duration_seconds, :position, :css_classes, :progress_bar_bg
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@duration_seconds = "7s"
|
9
9
|
@position = 'top-right'
|
10
|
+
@progress_bar_bg = "rgba(0, 0, 0, 0.2)"
|
10
11
|
@css_classes = {
|
11
|
-
success: 'faw-toast-border-
|
12
|
-
alert: 'faw-toast-border-
|
13
|
-
danger: 'faw-toast-border-
|
14
|
-
info: 'faw-toast-border-
|
15
|
-
notice: 'faw-toast-border-
|
16
|
-
default: 'faw-toast-border-
|
12
|
+
success: 'faw-toast-border-green',
|
13
|
+
alert: 'faw-toast-border-red',
|
14
|
+
danger: 'faw-toast-border-red',
|
15
|
+
info: 'faw-toast-border-sky',
|
16
|
+
notice: 'faw-toast-border-sky',
|
17
|
+
default: 'faw-toast-border-indigo'
|
17
18
|
}
|
18
19
|
end
|
19
20
|
end
|
@@ -3,7 +3,12 @@
|
|
3
3
|
module FawToast
|
4
4
|
module ToastHelper
|
5
5
|
def flash_class(type)
|
6
|
-
|
6
|
+
position = FawToast.configuration.position
|
7
|
+
color_class = FawToast.configuration.css_classes[type.to_sym] || FawToast.configuration.css_classes[:default]
|
8
|
+
border_class = border_class_for_position(position)
|
9
|
+
animation_class = animation_class_for_position(position)
|
10
|
+
|
11
|
+
[color_class, border_class, animation_class].join(" ")
|
7
12
|
end
|
8
13
|
|
9
14
|
def render_toast
|
@@ -15,11 +20,47 @@ module FawToast
|
|
15
20
|
render_toast
|
16
21
|
end
|
17
22
|
end
|
23
|
+
|
24
|
+
def render_message(flash_type = :success, status = :ok, message = nil)
|
25
|
+
flash.now[flash_type] = message
|
26
|
+
render turbo_stream: turbo_stream.append("faw-toast-container", partial: "faw_toast/toast"), status: status
|
27
|
+
end
|
18
28
|
|
19
29
|
def toast_css_variables
|
20
30
|
# Generate a style tag with CSS variables based on configuration
|
21
31
|
content_tag :style do
|
22
|
-
":root {
|
32
|
+
":root {
|
33
|
+
--faw-toast-duration: #{FawToast.configuration.duration_seconds};
|
34
|
+
--faw-toast-progress-bar-bg: #{FawToast.configuration.progress_bar_bg};
|
35
|
+
}".html_safe
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def border_class_for_position(position)
|
42
|
+
case position
|
43
|
+
when 'top-left', 'bottom-left'
|
44
|
+
'faw-toast-border-right-10'
|
45
|
+
when 'top-center', 'bottom-center'
|
46
|
+
'faw-toast-border-top-10'
|
47
|
+
else # top-right, bottom-right, or any other
|
48
|
+
'faw-toast-border-left-10'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def animation_class_for_position(position)
|
53
|
+
case position
|
54
|
+
when 'top-right', 'bottom-right'
|
55
|
+
'faw-toast-slide-right'
|
56
|
+
when 'top-left', 'bottom-left'
|
57
|
+
'faw-toast-slide-left'
|
58
|
+
when 'top-center'
|
59
|
+
'faw-toast-slide-top'
|
60
|
+
when 'bottom-center'
|
61
|
+
'faw-toast-slide-bottom'
|
62
|
+
else
|
63
|
+
'faw-toast-slide-right' # Default
|
23
64
|
end
|
24
65
|
end
|
25
66
|
end
|
data/lib/faw_toast/version.rb
CHANGED
@@ -4,16 +4,20 @@ FawToast.configure do |config|
|
|
4
4
|
# Duration in seconds for which the toast will be displayed
|
5
5
|
# config.duration_seconds = '7s'
|
6
6
|
|
7
|
+
# Background color of the progress bar
|
8
|
+
# config.progress_bar_bg = "rgba(0, 0, 0, 0.2)"
|
9
|
+
|
7
10
|
# Position of the toast container
|
8
11
|
# Available options: 'top-right', 'top-left', 'bottom-right', 'bottom-left', 'top-center', 'bottom-center'
|
9
12
|
# config.position = 'top-right'
|
10
13
|
|
11
14
|
# CSS classes for different flash types
|
12
15
|
# config.css_classes = {
|
13
|
-
# success: 'faw-toast-border-
|
14
|
-
# alert: 'faw-toast-border-
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
16
|
+
# success: 'faw-toast-border-green',
|
17
|
+
# alert: 'faw-toast-border-red',
|
18
|
+
# danger: 'faw-toast-border-red',
|
19
|
+
# info: 'faw-toast-border-sky',
|
20
|
+
# notice: 'faw-toast-border-sky',
|
21
|
+
# default: 'faw-toast-border-indigo'
|
18
22
|
# }
|
19
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faw_toast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alexwebgr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|