ultimate_turbo_modal 1.1.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af46e6d6c899d0fcf8054272b157d5e0f286e183e9c0b15c4e3b883df629d4f4
4
- data.tar.gz: 91a99b9b60ea2892b2c030027d073218b4d751dd155a0bb84420bc6e60db628e
3
+ metadata.gz: 59ea5183cc13d4e04e3a9a63fad2f4c56d4656393b50af6888ffcc452ca47ee4
4
+ data.tar.gz: d36e383ba4dfd1affd9ebea7ed3c550773273ccf80b0cdcf9464cd892b083390
5
5
  SHA512:
6
- metadata.gz: ccff10a4c4fee7a554c58632d9850507be533877333b0b8caadf2966fbc5244719f828fdb4507674668129c6bfebee1e7cb3e7a7fae5fc1b8238eae8fb5ea637
7
- data.tar.gz: d636a2425ce101e4339cec01573e6a29aea861f36328bf4e6a8cd3513ccfe9a5979b4fa424fa69320a809ff94f80f4e28d3f39bbc7f6f6d6426217191fe9ea4c
6
+ metadata.gz: 0031bd558642b4f32643ce8a987e8dfa65cf9e2990590e21fd23926417f532619ac9498b69f86a98d10c7e5be04228015f216e0d222b15216b0afb91677beef2
7
+ data.tar.gz: 40b4e14d106a398016d88daa5dcfa0f77bc5432ba302d148f30597060a1f2b7559c8e3873866ebe4afbaba6f831b42c4182c19479bf222ba552fc2a3f4e357de
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.2
3
+
1
4
  require:
2
5
  - standard
3
6
  inherit_gem:
data/CHANGELOG.md CHANGED
@@ -1,4 +1,17 @@
1
- ## [1.1.2] - 2023-11-01
1
+ ## [1.2.1] - 2023-11-11
2
+
3
+ - Fix footer divider not showing
4
+
5
+ ## [1.2.0] - 2023-11-05
6
+
7
+ - Dark mode support
8
+ - Added header divider (configurable)
9
+ - Added footer section with divider (configurable)
10
+ - Tailwind flavor now uses data attributes to style elements
11
+ - Updated look and feel
12
+ - Simplified code a bit
13
+
14
+ ## [1.1.3] - 2023-11-01
2
15
 
3
16
  - Added configuration block
4
17
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ultimate_turbo_modal (1.1.2)
4
+ ultimate_turbo_modal (1.2.1)
5
5
  phlex-rails (>= 1.0, < 2.0)
6
6
  rails (>= 7)
7
7
  stimulus-rails
data/README.md CHANGED
@@ -67,19 +67,22 @@ UltimateTurboModal.configure do |config|
67
67
  config.padding = true
68
68
  config.advance = true
69
69
  config.close_button = true
70
+ config.header = true
71
+ config.header_divider = true
72
+ config.footer_divider = true
70
73
  end
71
74
  ```
72
75
 
73
76
  5. Register the Stimulus controller in `app/javascript/controllers/index.js` adding the following lines at the end.
74
77
 
75
- ```js
78
+ ```javascript
76
79
  import setupUltimateTurboModal from "ultimate_turbo_modal";
77
80
  setupUltimateTurboModal(application);
78
81
  ```
79
82
 
80
83
  6. If using the Tailwind flavor, add the following to `tailwind.config.js`:
81
84
 
82
- ```
85
+ ```javascript
83
86
  // For npm/yarn
84
87
  const { getUltimateTurboModalPath } = require('ultimate_turbo_modal/gemPath');
85
88
 
@@ -94,16 +97,17 @@ const { getUltimateTurboModalPath } = require('ultimate_turbo_modal/gemPath');
94
97
 
95
98
  and then in the `content` section, add `getUltimateTurboModalPath()` as follow:
96
99
 
97
- ```
98
- content: [
99
- './public/*.html',
100
- './app/helpers/**/*.rb',
101
- './app/javascript/**/*.js',
102
- './app/views/**/*.{erb,haml,html,slim,rb}',
103
- getUltimateTurboModalPath()
100
+ ```javascript
101
+ content: [
102
+ './public/*.html',
103
+ './app/helpers/**/*.rb',
104
+ './app/javascript/**/*.js',
105
+ './app/views/**/*.{erb,haml,html,slim,rb}',
106
+ getUltimateTurboModalPath()
107
+ ]
104
108
  ```
105
109
 
106
- 7. Optionally (but recommended), configure UTMR to use Idiomorph. See below for details.
110
+ 1. Optionally (but recommended), configure UTMR to use Idiomorph. See below for details.
107
111
 
108
112
  &nbsp;
109
113
  &nbsp;
@@ -153,6 +157,23 @@ When opening the modal, the URL in the URL bar will change to the URL of the vie
153
157
 
154
158
  If a URL is specified as a String, the browser history will advance, and the URL shown in the URL bad will be replaced by the URL specified.
155
159
 
160
+ ### `title`, default: `nil`
161
+
162
+ Title to display in the modal header.
163
+
164
+ ### `header`, default: `true`
165
+
166
+ Whether to display a modal header.
167
+
168
+ ### `header_divider`, default: `true`
169
+
170
+ Whether to display a divider below the header.
171
+
172
+ ### `footer_divider`, default: `true`
173
+
174
+ Whether to display a divider above the footer. The divider will not appear if no footer was specified.
175
+
176
+
156
177
 
157
178
  ### Example usage with options
158
179
 
@@ -182,7 +203,7 @@ In the meantime, add `<script src="https://unpkg.com/idiomorph"></script>` to yo
182
203
 
183
204
  And the following code to `application.js`:
184
205
 
185
- ```js
206
+ ```javascript
186
207
  addEventListener("turbo:before-frame-render", (event) => {
187
208
  event.detail.render = (currentElement, newElement) => {
188
209
  Idiomorph.morph(currentElement, newElement, {
@@ -192,6 +213,11 @@ addEventListener("turbo:before-frame-render", (event) => {
192
213
  })
193
214
  ```
194
215
 
216
+ &nbsp;
217
+ &nbsp;
218
+ ## Thanks
219
+
220
+ Thanks to [@joeldrapper](https://github.com/KonnorRogers) and [@konnorrogers](https://github.com/KonnorRogers) for all the help!
195
221
 
196
222
  &nbsp;
197
223
  &nbsp;
@@ -0,0 +1,8 @@
1
+ module Phlex
2
+ module DeferredRenderWithMainContent
3
+ def template(&)
4
+ output = capture(&)
5
+ super { unsafe_raw(output) }
6
+ end
7
+ end
8
+ end
@@ -1,19 +1,29 @@
1
1
  class UltimateTurboModal::Base < Phlex::HTML
2
+ prepend Phlex::DeferredRenderWithMainContent
2
3
  # @param padding [Boolean] Whether to add padding around the modal content
3
4
  # @param close_button [Boolean] Whether to show a close button.
4
5
  # @param advance [Boolean] Whether to update the browser history when opening and closing the modal
5
- # @param advance_url [String] Override the URL to use when advancing the history
6
+ # @param header_divider [Boolean] Whether to show a divider between the header and the main content
7
+ # @param footer_divider [Boolean] Whether to show a divider between the main content and the footer
8
+ # @param title [String] The title of the modal
6
9
  # @param request [ActionDispatch::Request] The current Rails request object
7
10
  def initialize(
8
11
  padding: UltimateTurboModal.configuration.padding,
9
12
  close_button: UltimateTurboModal.configuration.close_button,
10
13
  advance: UltimateTurboModal.configuration.advance,
11
- request: nil
14
+ header: UltimateTurboModal.configuration.header,
15
+ header_divider: UltimateTurboModal.configuration.header_divider,
16
+ footer_divider: UltimateTurboModal.configuration.footer_divider,
17
+ title: nil, request: nil
12
18
  )
13
19
  @padding = padding
14
20
  @close_button = close_button
15
21
  @advance = !!advance
16
22
  @advance_url = advance if advance.present? && advance.is_a?(String)
23
+ @title = title
24
+ @header = header
25
+ @header_divider = header_divider
26
+ @footer_divider = footer_divider
17
27
  @request = request
18
28
 
19
29
  unless self.class.include?(Turbo::FramesHelper)
@@ -25,55 +35,53 @@ class UltimateTurboModal::Base < Phlex::HTML
25
35
  end
26
36
  end
27
37
 
28
- def template(&)
38
+ def template(&block)
29
39
  if turbo_frame?
30
- turbo_frame_tag("modal") { modal(&) }
40
+ turbo_frame_tag("modal") do
41
+ modal(&block)
42
+ end
31
43
  elsif turbo_stream?
32
44
  Turbo::StreamsHelper.turbo_stream_action_tag("update", target: "modal") do
33
- template { modal(&) }
45
+ modal(&block)
34
46
  end
35
47
  else
36
- modal(&)
48
+ render block
37
49
  end
38
50
  end
39
51
 
52
+ def footer(&block)
53
+ @footer = block
54
+ end
55
+
40
56
  private
41
57
 
42
- attr_accessor :request
58
+ attr_accessor :request, :title
43
59
 
44
- def padding?
45
- !!@padding
46
- end
60
+ def padding? = !!@padding
47
61
 
48
- def advance?
49
- !!@advance
50
- end
62
+ def close_button? = !!@close_button
51
63
 
52
- def close_button?
53
- !!@close_button
54
- end
64
+ def title? = !!@title
55
65
 
56
- def turbo_stream?
57
- !!request&.format&.turbo_stream?
58
- end
66
+ def header? = !!@header
59
67
 
60
- def turbo_frame?
61
- !!request&.headers&.key?("Turbo-Frame")
62
- end
68
+ def footer? = @footer.present?
63
69
 
64
- def turbo?
65
- turbo_stream? || turbo_frame?
66
- end
70
+ def header_divider? = !!@header_divider && title?
67
71
 
68
- def advance_url
69
- return nil unless advance?
70
- @advance_url || request.original_url
71
- end
72
+ def footer_divider? = !!@footer_divider && footer?
72
73
 
73
- def include_if_defined(mod_str)
74
- if defined?(mod.constantize) && !self.class.included_modules.include?(mod.constantize)
75
- self.class.include mod.constantize
76
- end
74
+ def turbo_stream? = !!request&.format&.turbo_stream?
75
+
76
+ def turbo_frame? = !!request&.headers&.key?("Turbo-Frame")
77
+
78
+ def turbo? = turbo_stream? || turbo_frame?
79
+
80
+ def advance? = !!@advance && !!@advance_url
81
+
82
+ def advance_url
83
+ return nil unless !!@advance
84
+ @advance_url || request&.original_url
77
85
  end
78
86
 
79
87
  def respond_to_missing?(method, include_private = false)
@@ -12,27 +12,30 @@ module UltimateTurboModal
12
12
  :advance, :advance=, :padding, :padding=, to: :configuration
13
13
 
14
14
  class Configuration
15
- attr_reader :flavor, :close_button, :advance, :padding
15
+ attr_reader :flavor, :close_button, :advance, :padding, :header, :header_divider, :footer_divider
16
16
 
17
17
  def initialize
18
18
  @flavor = :tailwind
19
19
  @close_button = true
20
20
  @advance = true
21
21
  @padding = true
22
+ @header = true
23
+ @header_divider = true
24
+ @footer_divider = true
22
25
  end
23
26
 
24
27
  def flavor=(flavor)
25
- raise ArgumentError.new("Flavor must be a symbol.") unless flavor.is_a?(Symbol) || flavor.is_a?(String)
28
+ raise ArgumentError.new("Value must be a symbol.") unless flavor.is_a?(Symbol) || flavor.is_a?(String)
26
29
  @flavor = flavor.to_sym
27
30
  end
28
31
 
29
32
  def close_button=(close_button)
30
- raise ArgumentError.new("Close button must be a boolean.") unless [true, false].include?(close_button)
33
+ raise ArgumentError.new("Value must be a boolean.") unless [true, false].include?(close_button)
31
34
  @close_button = close_button
32
35
  end
33
36
 
34
37
  def advance=(advance)
35
- raise ArgumentError.new("Advance must be a boolean.") unless [true, false].include?(advance)
38
+ raise ArgumentError.new("Value must be a boolean.") unless [true, false].include?(advance)
36
39
  @advance = advance
37
40
  end
38
41
 
@@ -40,9 +43,24 @@ module UltimateTurboModal
40
43
  if [true, false].include?(padding) || padding.is_a?(String)
41
44
  @padding = padding
42
45
  else
43
- raise ArgumentError.new("Padding must be a boolean or a String.")
46
+ raise ArgumentError.new("Value must be a boolean or a String.")
44
47
  end
45
48
  end
49
+
50
+ def header=(header)
51
+ raise ArgumentError.new("Value must be a boolean.") unless [true, false].include?(header)
52
+ @header = header
53
+ end
54
+
55
+ def header_divider=(header_divider)
56
+ raise ArgumentError.new("Value must be a boolean.") unless [true, false].include?(header_divider)
57
+ @header_divider = header_divider
58
+ end
59
+
60
+ def footer_divider=(footer_divider)
61
+ raise ArgumentError.new("Value must be a boolean.") unless [true, false].include?(footer_divider)
62
+ @footer_divider = footer_divider
63
+ end
46
64
  end
47
65
  end
48
66
 
@@ -1,27 +1,33 @@
1
1
  module UltimateTurboModal::Flavors
2
2
  class Tailwind < UltimateTurboModal::Base
3
+
3
4
  private
4
5
 
5
6
  def modal(&)
7
+ outer_divs do
8
+ div_content do
9
+ div_header
10
+ div_main(&)
11
+ div_footer if footer?
12
+ end
13
+ end
14
+ end
15
+
16
+ def outer_divs(&)
6
17
  div_dialog do
7
18
  div_overlay
8
19
  div_outer do
9
- div_inner do
10
- div_border do
11
- button_close if close_button?
12
- yield
13
- end
14
- end
20
+ div_inner(&)
15
21
  end
16
22
  end
17
23
  end
18
24
 
19
25
  def div_dialog(&)
20
26
  div(id: "modal-container",
21
- class: "relative z-10",
27
+ class: "relative group",
22
28
  role: "dialog",
23
29
  aria: {
24
- labeled_by: "modal-title",
30
+ labeled_by: "modal-title-h",
25
31
  modal: true
26
32
  },
27
33
  data: {
@@ -29,71 +35,91 @@ module UltimateTurboModal::Flavors
29
35
  modal_target: "container",
30
36
  modal_advance_url_value: advance_url,
31
37
  action: "turbo:submit-end->modal#submitEnd keyup@window->modal#closeWithKeyboard click@window->modal#outsideModalClicked click->modal#outsideModalClicked",
32
- transition_enter: "ease-out duration-300",
38
+ transition_enter: "ease-out duration-100",
33
39
  transition_enter_start: "opacity-0",
34
40
  transition_enter_end: "opacity-100",
35
- transition_leave: "ease-in duration-200",
41
+ transition_leave: "ease-in duration-50",
36
42
  transition_leave_start: "opacity-100",
37
- transition_leave_end: "opacity-0"
43
+ transition_leave_end: "opacity-0",
44
+ padding: padding?.to_s,
45
+ title: title?.to_s,
46
+ header: header?.to_s,
47
+ close_button: close_button?.to_s,
48
+ header_divider: header_divider?.to_s,
49
+ footer_divider: footer_divider?.to_s
38
50
  }, &)
39
51
  end
40
52
 
41
- def div_overlay(&)
53
+ def div_overlay
42
54
  div(id: "modal-overlay",
43
- class: "fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity",
44
- data: {
45
- modal_target: "overlay",
46
- action: "click->modal#outsideModalClicked"
47
- })
55
+ class: "fixed inset-0 bg-gray-900 bg-opacity-50 transition-opacity dark:bg-opacity-80 z-40")
48
56
  end
49
57
 
50
58
  def div_outer(&)
51
59
  div(id: "modal-outer",
52
- class: "fixed inset-0 z-10 overflow-y-auto sm:max-w-[80%] md:max-w-3xl sm:mx-auto m-4",
53
- data: {
54
- modal_target: "modal"
55
- }, &)
60
+ class: "fixed inset-0 z-50 overflow-y-auto sm:max-w-[80%] md:max-w-3xl sm:mx-auto m-4", &)
56
61
  end
57
62
 
58
63
  def div_inner(&)
59
64
  div(id: "modal-inner",
60
- class: "flex min-h-full items-center justify-center p-1 sm:p-4",
61
- data: {
62
- modal_target: "innerModal"
63
- }, &)
65
+ class: "flex min-h-full items-center justify-center p-1 sm:p-4", &)
66
+ end
67
+
68
+ def div_content(&)
69
+ div(id: "modal-content",
70
+ class: "relative transform overflow-hidden rounded-lg bg-white text-left shadow transition-all
71
+ sm:my-8 sm:max-w-3xl dark:bg-gray-800 dark:text-white",
72
+ data: {modal_target: "content"}, &)
73
+ end
74
+
75
+ def div_main(&)
76
+ div(id: "modal-main", class: "group-data-[padding=true]:p-4 group-data-[padding=true]:pt-2", &)
64
77
  end
65
78
 
66
- def div_border(&)
67
- klass = "relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:max-w-3xl"
68
- klass = "#{klass} p-2 sm:p-4 md:p-6" if @padding == true
69
- klass = "#{klass} #{@padding}" if @padding.is_a?(String)
70
- div(id: "modal-border", class: klass, &)
79
+ def div_header(&)
80
+ div(id: "modal-header", class: "flex justify-between items-center w-full py-4 rounded-t dark:border-gray-600 group-data-[header-divider=true]:border-b group-data-[header=false]:absolute") do
81
+ div_title
82
+ button_close
83
+ end
71
84
  end
72
85
 
73
- def button_close(&)
74
- div(class: "absolute top-3 right-3") do
75
- button(type: "button",
76
- aria: {label: "close"},
77
- class: "ml-auto inline-flex items-center rounded bg-transparent p-1 text-sm text-gray-400 bg-white bg-opacity-20 hover:bg-gray-100 hover:bg-opacity-70 hover:text-gray-900",
78
- data: {
79
- action: "modal#hideModal"
80
- }) { icon_close }
86
+ def div_title
87
+ div(id: "modal-title", class: "pl-4") do
88
+ h3(id: "modal-title-h", class: "group-data-[title=false]:hidden text-lg font-semibold text-gray-900 dark:text-white") { @title }
81
89
  end
82
90
  end
83
91
 
92
+ def div_footer
93
+ div(id: "modal-footer", class: "flex p-4 rounded-b dark:border-gray-600 group-data-[footer-divider=true]:border-t") do
94
+ render @footer
95
+ end
96
+ end
97
+
98
+ def button_close
99
+ div(id: "modal-close", class: "mr-4") do
100
+ close_button_tag do
101
+ icon_close
102
+ span(class: "sr-only") { "Close modal" }
103
+ end
104
+ end
105
+ end
106
+
107
+ def close_button_tag(&)
108
+ button(type: "button",
109
+ aria: {label: "close"},
110
+ class: "text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm
111
+ p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white",
112
+ data: {
113
+ action: "modal#hideModal"
114
+ }, &)
115
+ end
116
+
84
117
  def icon_close
85
- svg(
86
- xmlns: "http://www.w3.org/2000/svg",
87
- fill: "none",
88
- viewbox: "0 0 24 24",
89
- stroke_width: "1.5",
90
- stroke: "currentColor",
91
- class: "w-5 h-5"
92
- ) do |s|
118
+ svg(class: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20") do |s|
93
119
  s.path(
94
- stroke_linecap: "round",
95
- stroke_linejoin: "round",
96
- d: "M6 18L18 6M6 6l12 12"
120
+ fill_rule: "evenodd",
121
+ d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",
122
+ clip_rule: "evenodd"
97
123
  )
98
124
  end
99
125
  end
@@ -1,17 +1,23 @@
1
1
  module UltimateTurboModal::Flavors
2
2
  class Vanilla < UltimateTurboModal::Base
3
+
3
4
  private
4
5
 
5
6
  def modal(&)
7
+ outer_divs do
8
+ div_content do
9
+ div_header
10
+ div_main(&)
11
+ div_footer if footer?
12
+ end
13
+ end
14
+ end
15
+
16
+ def outer_divs(&)
6
17
  div_dialog do
7
18
  div_overlay
8
- div_outer_container do
9
- div_inner_container do
10
- div_border do
11
- button_close if close_button?
12
- yield
13
- end
14
- end
19
+ div_outer do
20
+ div_inner(&)
15
21
  end
16
22
  end
17
23
  end
@@ -21,7 +27,7 @@ module UltimateTurboModal::Flavors
21
27
  class: "modal-container",
22
28
  role: "dialog",
23
29
  aria: {
24
- labeled_by: "modal-title",
30
+ labeled_by: "modal-title-h",
25
31
  modal: true
26
32
  },
27
33
  data: {
@@ -29,69 +35,84 @@ module UltimateTurboModal::Flavors
29
35
  modal_target: "container",
30
36
  modal_advance_url_value: advance_url,
31
37
  action: "turbo:submit-end->modal#submitEnd keyup@window->modal#closeWithKeyboard click@window->modal#outsideModalClicked click->modal#outsideModalClicked",
32
- transition_enter: "ease-out duration-300",
38
+ transition_enter: "ease-out duration-100",
33
39
  transition_enter_start: "opacity-0",
34
40
  transition_enter_end: "opacity-100",
35
- transition_leave: "ease-in duration-200",
41
+ transition_leave: "ease-in duration-50",
36
42
  transition_leave_start: "opacity-100",
37
- transition_leave_end: "opacity-0"
43
+ transition_leave_end: "opacity-0",
44
+ padding: padding?.to_s,
45
+ title: title?.to_s,
46
+ header: header?.to_s,
47
+ close_button: close_button?.to_s,
48
+ header_divider: header_divider?.to_s,
49
+ footer_divider: footer_divider?.to_s
38
50
  }, &)
39
51
  end
40
52
 
41
- def div_overlay(&)
42
- div(id: "modal-overlay",
43
- class: "modal-overlay",
44
- data: {
45
- modal_target: "overlay",
46
- action: "click->modal#outsideModalClicked"
47
- })
53
+ def div_overlay
54
+ div(id: "modal-overlay", class: "modal-overlay")
48
55
  end
49
56
 
50
- def div_outer_container(&)
51
- div(id: "modal-outer",
52
- class: "modal-outer",
53
- data: {
54
- modal_target: "modal"
55
- }, &)
57
+ def div_outer(&)
58
+ div(id: "modal-outer", class: "modal-outer", &)
56
59
  end
57
60
 
58
- def div_inner_container(&)
59
- div(id: "modal-inner",
60
- class: "modal-inner",
61
- data: {
62
- modal_target: "innerModal"
63
- }, &)
61
+ def div_inner(&)
62
+ div(id: "modal-inner", class: "modal-inner", &)
63
+ end
64
+
65
+ def div_content(&)
66
+ div(id: "modal-content", class: "modal-content", data: {modal_target: "content"}, &)
67
+ end
68
+
69
+ def div_main(&)
70
+ div(id: "modal-main", class: "modal-main", &)
64
71
  end
65
72
 
66
- def div_border(&)
67
- klass = "modal-border"
68
- klass = "#{klass} modal-padding" if @padding == true
69
- klass = "#{klass} #{@padding}" if @padding.is_a?(String)
70
- div(id: "modal-border", class: klass, &)
73
+ def div_header(&)
74
+ div(id: "modal-header", class: "modal-header") do
75
+ div_title
76
+ button_close
77
+ end
71
78
  end
72
79
 
73
- def button_close(&)
74
- div(class: "modal-close") do
75
- button(type: "button",
76
- aria: {label: "close"},
77
- data: {
78
- action: "modal#hideModal"
79
- }) { icon_close }
80
+ def div_title
81
+ div(id: "modal-title", class: "modal-title") do
82
+ h3(id: "modal-title-h", class: "modal-title-h") { @title }
80
83
  end
81
84
  end
82
85
 
86
+ def div_footer
87
+ div(id: "modal-footer", class: "modal-footer") do
88
+ render @footer
89
+ end
90
+ end
91
+
92
+ def button_close
93
+ div(id: "modal-close", class: "modal-close") do
94
+ close_button_tag do
95
+ icon_close
96
+ span(class: "sr-only") { "Close modal" }
97
+ end
98
+ end
99
+ end
100
+
101
+ def close_button_tag(&)
102
+ button(type: "button",
103
+ aria: {label: "close"},
104
+ class: "modal-close-button",
105
+ data: {
106
+ action: "modal#hideModal"
107
+ }, &)
108
+ end
109
+
83
110
  def icon_close
84
- svg(
85
- xmlns: "http://www.w3.org/2000/svg",
86
- fill: "none",
87
- viewbox: "0 0 24 24",
88
- stroke_width: "1.5",
89
- stroke: "currentColor",
90
- ) do |s|
111
+ svg(class: "modal-close-icon", fill: "currentColor", viewBox: "0 0 20 20") do |s|
91
112
  s.path(
92
- stroke_linecap: "round",
93
- stroke_linejoin: "round",
94
- d: "M6 18L18 6M6 6l12 12"
113
+ fill_rule: "evenodd",
114
+ d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",
115
+ clip_rule: "evenodd"
95
116
  )
96
117
  end
97
118
  end
@@ -1,9 +1,7 @@
1
1
  module UltimateTurboModal::Helpers
2
2
  module ViewHelper
3
- def modal(**)
4
- render UltimateTurboModal.new(request:, **) do
5
- yield
6
- end
3
+ def modal(**, &)
4
+ render(UltimateTurboModal.new(request:, **), &)
7
5
  end
8
6
  end
9
7
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UltimateTurboModal
4
- VERSION = "1.1.2"
4
+ VERSION = "1.2.1"
5
5
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "ultimate_turbo_modal/version"
4
+ require "phlex/deferred_render_with_main_content"
4
5
  require "ultimate_turbo_modal/configuration"
5
6
  require "ultimate_turbo_modal/railtie"
6
7
  require "ultimate_turbo_modal/base"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ultimate_turbo_modal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Mercier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-02 00:00:00.000000000 Z
11
+ date: 2023-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex-rails
@@ -90,6 +90,7 @@ files:
90
90
  - LICENSE.txt
91
91
  - README.md
92
92
  - Rakefile
93
+ - lib/phlex/deferred_render_with_main_content.rb
93
94
  - lib/ultimate_turbo_modal.rb
94
95
  - lib/ultimate_turbo_modal/base.rb
95
96
  - lib/ultimate_turbo_modal/configuration.rb