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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97af3db39ecce4321a32c7d9665e315efdf96ba083675608ec3094d97eb202d2
4
- data.tar.gz: 6cbe421d337750c6ab154725650b236ac2ac15ec5b118dc1201f1b9b67c1ecb1
3
+ metadata.gz: 314d01dd20348f62a6246f377322f8228ef2b021a9f4fc8ce499d76987a19f64
4
+ data.tar.gz: 272d6ce0491dc17f9219050a89fcb5a8209cc61394d2c86007a74a5cf0c539ce
5
5
  SHA512:
6
- metadata.gz: e509fb2b7809f80aed827af9fe82c8555c0fc63d8513d54723d805ac0ab6fe2c4c8f2f5ba3900eb5a31f35f65be99008a78ecbf54c7fa0e8153f5ebc8652ac8e
7
- data.tar.gz: '007483292ba291241a3825cf79e6e8c5a3d9be9c93ac3cef567d970b3030d2f30d0d58911da5a4cea172d05fc220144a7dea4eaa2dbf7ae3043e42f5427f7a91'
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-l-10 faw-toast-border-green',
112
- alert: 'faw-toast-border-l-10 faw-toast-border-red',
113
- danger: 'faw-toast-border-l-10 faw-toast-border-red',
114
- info: 'faw-toast-border-l-10 faw-toast-border-sky',
115
- notice: 'faw-toast-border-l-10 faw-toast-border-sky',
116
- default: 'faw-toast-border-l-10 faw-toast-border-indigo'
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 left border indicating the message type (success, alert, info, etc.)
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-slideOut') {
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: 1rem; }
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: 100%;
39
- pointer-events: auto;
35
+ min-width: 300px;
36
+ text-align: center;
40
37
  background-color: white; }
41
- .faw-toast.faw-toast-border-l-10 {
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-left-color: #10b981; }
56
+ border-color: #10b981; }
46
57
  .faw-toast.faw-toast-border-red {
47
- border-left-color: #ef4444; }
58
+ border-color: #ef4444; }
48
59
  .faw-toast.faw-toast-border-sky {
49
- border-left-color: #0284c7; }
60
+ border-color: #0284c7; }
50
61
  .faw-toast.faw-toast-border-indigo {
51
- border-left-color: #6366f1; }
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: rgba(0, 0, 0, 0.2);
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-slideIn {
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-slideOut {
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,cAAc,EAAE,IAAI;EACpB,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;EACtB,GAAG,EAAE,MAAM;EAEX,wCAAsB;IACpB,GAAG,EAAE,IAAI;IACT,KAAK,EAAE,IAAI;EAGb,uCAAqB;IACnB,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,IAAI;EAGZ,2CAAyB;IACvB,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;EAGb,0CAAwB;IACtB,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;EAGZ,yCAAuB;IACrB,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,GAAG;IACT,SAAS,EAAE,gBAAgB;EAG7B,4CAA0B;IACxB,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,GAAG;IACT,SAAS,EAAE,gBAAgB;;AAI/B,UAAW;EACT,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,aAAa,EAAE,GAAG;EAClB,UAAU,EAAE,4BAAyB;EACrC,QAAQ,EAAE,QAAQ;EAClB,QAAQ,EAAE,MAAM;EAChB,SAAS,EAAE,0GAA0G;EACrH,SAAS,EAAE,KAAK;EAChB,KAAK,EAAE,IAAI;EACX,cAAc,EAAE,IAAI;EACpB,gBAAgB,EAAE,KAAK;EAEvB,gCAAwB;IACtB,iBAAiB,EAAE,IAAI;IACvB,iBAAiB,EAAE,KAAK;EAG1B,qCAA6B;IAC3B,iBAAiB,EAAE,OAAO;EAG5B,mCAA2B;IACzB,iBAAiB,EAAE,OAAO;EAG5B,mCAA2B;IACzB,iBAAiB,EAAE,OAAO;EAG5B,sCAA8B;IAC5B,iBAAiB,EAAE,OAAO;EAG5B,6BAAmB;IACjB,IAAI,EAAE,CAAC;EAGT,2BAAiB;IACf,MAAM,EAAE,OAAO;IACf,KAAK,EAAE,OAAO;IAEd,iCAAQ;MACN,KAAK,EAAE,OAAO;EAIlB,8BAAoB;IAClB,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,GAAG;IACX,gBAAgB,EAAE,kBAAkB;IACpC,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,mDAAmD;;AAIlE,4BASC;EARC,IAAK;IACH,SAAS,EAAE,gBAAgB;IAC3B,OAAO,EAAE,CAAC;EAEZ,EAAG;IACD,SAAS,EAAE,aAAa;IACxB,OAAO,EAAE,CAAC;AAId,6BASC;EARC,IAAK;IACH,SAAS,EAAE,aAAa;IACxB,OAAO,EAAE,CAAC;EAEZ,EAAG;IACD,SAAS,EAAE,gBAAgB;IAC3B,OAAO,EAAE,CAAC;AAId,6BAOC;EANC,IAAK;IACH,KAAK,EAAE,IAAI;EAEb,EAAG;IACD,KAAK,EAAE,CAAC",
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-right {
8
+ &.faw-toast-top-left {
10
9
  top: 1rem;
11
- right: 1rem;
10
+ left: 0.5rem;
12
11
  }
13
12
 
14
- &.faw-toast-top-left {
13
+ &.faw-toast-top-center {
15
14
  top: 1rem;
16
- left: 1rem;
15
+ left: 50%;
16
+ transform: translateX(-50%);
17
17
  }
18
18
 
19
- &.faw-toast-bottom-right {
20
- bottom: 1rem;
21
- right: 1rem;
19
+ &.faw-toast-top-right {
20
+ top: 3rem;
21
+ right: 0.5rem;
22
22
  }
23
23
 
24
- &.faw-toast-bottom-left {
24
+ &.faw-toast-bottom-right {
25
25
  bottom: 1rem;
26
- left: 1rem;
26
+ right: 0.5rem;
27
27
  }
28
28
 
29
- &.faw-toast-top-center {
30
- top: 1rem;
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-center {
35
+ &.faw-toast-bottom-left {
36
36
  bottom: 1rem;
37
- left: 50%;
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: 100%;
52
- pointer-events: auto;
48
+ min-width: 300px;
49
+ text-align: center;
53
50
  background-color: white;
54
51
 
55
- &.faw-toast-border-l-10 {
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-left-color: #10b981;
92
+ border-color: #10b981;
62
93
  }
63
94
 
64
95
  &.faw-toast-border-red {
65
- border-left-color: #ef4444;
96
+ border-color: #ef4444;
66
97
  }
67
98
 
68
99
  &.faw-toast-border-sky {
69
- border-left-color: #0284c7;
100
+ border-color: #0284c7;
70
101
  }
71
102
 
72
103
  &.faw-toast-border-indigo {
73
- border-left-color: #6366f1;
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: rgba(0, 0, 0, 0.2);
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
- @keyframes faw-toast-slideIn {
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-slideOut {
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
- <%# 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 %>
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-l-10 faw-toast-border-green',
12
- alert: 'faw-toast-border-l-10 faw-toast-border-red',
13
- danger: 'faw-toast-border-l-10 faw-toast-border-red',
14
- info: 'faw-toast-border-l-10 faw-toast-border-sky',
15
- notice: 'faw-toast-border-l-10 faw-toast-border-sky',
16
- default: 'faw-toast-border-l-10 faw-toast-border-indigo'
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
- FawToast.configuration.css_classes[type.to_sym] || FawToast.configuration.css_classes[:default]
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 { --faw-toast-duration: #{FawToast.configuration.duration_seconds}; }".html_safe
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FawToast
4
- VERSION = "1.2.2"
4
+ VERSION = "1.4.0"
5
5
  end
@@ -15,7 +15,7 @@ module FawToast
15
15
  inject_into_file "app/views/layouts/application.html.erb", after: "<head>" do
16
16
  <<-HTML
17
17
 
18
- <%= toast_css_variables %>
18
+ <%= toast_css_variables %>
19
19
  HTML
20
20
  end
21
21
  end
@@ -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-l-10 faw-toast-border-green',
14
- # alert: 'faw-toast-border-l-10 faw-toast-border-red',
15
- # info: 'faw-toast-border-l-10 faw-toast-border-sky',
16
- # notice: 'faw-toast-border-l-10 faw-toast-border-sky',
17
- # default: 'faw-toast-border-l-10 faw-toast-border-indigo'
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.2.2
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-26 00:00:00.000000000 Z
11
+ date: 2025-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails