ultimate_turbo_modal 1.1.1 → 1.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: 1149adbc9b8dd940af463061bdfc46d09d1071531a0f08d73538a41c2d44ef52
4
- data.tar.gz: d5ce0192c54ff6f731758515a9ed60f839315759b70e9ceaba57ce2847ed298f
3
+ metadata.gz: a456aa7e0fdb49a0b9ae53817f965df422145433f6d981811cbb0172126422dd
4
+ data.tar.gz: 4fdb91772d698e7d1987024acb165f1ef8380446d600c5146b834025cb84c497
5
5
  SHA512:
6
- metadata.gz: 07b07aa40ab5c4000a6c06fa1d3ed410f7bebc3d44c46a670371e8e1044a168167cdd8a402865d26e3314b18c2e013b451a542c45a2a42e33d19cc8ce7b31f82
7
- data.tar.gz: 5dc24349c452b9c7c8a9280d4f8dd8a0c36dd89efb261b5aa8ae6715f3921aab0e15a128e704ce2eb21f0a94158ba621ca7760289efc1df17fa7180a1e2cbc1f
6
+ metadata.gz: 63ae9236655b7d2d300507413808a5771ca205dc12d08eecc48a3f256ddf24525f8b2b401a432a4df035d6fbd929c738e0a74c5bd1036a1f16b62b786ce756bb
7
+ data.tar.gz: d5fc098465cdba81f1981e49cce9721e049db78d02a448e734ea60f0c41b6119311a15e1ac922c7d0667d274431cb86bacaf9d3310c2ee51979f695cee3135ac
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,19 @@
1
- ## [Unreleased]
1
+ ## [1.2.0] - 2023-11-05
2
+
3
+ - Dark mode support
4
+ - Added header divider (configurable)
5
+ - Added footer section with divider (configurable)
6
+ - Tailwind flavor now uses data attributes to style elements
7
+ - Updated look and feel
8
+ - Simplified code a bit
9
+
10
+ ## [1.1.3] - 2023-11-01
11
+
12
+ - Added configuration block
13
+
14
+ ## [1.1.2] - 2023-10-31
15
+
16
+ - Bug fix
2
17
 
3
18
  ## [1.1.0] - 2023-10-31
4
19
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ultimate_turbo_modal (1.1.1)
4
+ ultimate_turbo_modal (1.2.0)
5
5
  phlex-rails (>= 1.0, < 2.0)
6
6
  rails (>= 7)
7
7
  stimulus-rails
data/README.md CHANGED
@@ -6,7 +6,7 @@ UTMR aims to be the be-all and end-all of Turbo Modals. I believe it is the best
6
6
 
7
7
  Under the hood, it uses [Stimulus](https://stimulus.hotwired.dev), [Turbo](https://turbo.hotwired.dev/), [el-transition](https://github.com/mmccall10/el-transition), and optionally [Idiomorph](https://github.com/bigskysoftware/idiomorph).
8
8
 
9
- It currently ships in a two flavors: Tailwind CSS, and regular, vanilla CSS. It is easy to create your own to suit your needs such as vanilla CSS or any other CSS framework you may prefer. See `lib/ultimate_turbo_modal/flavors/vanilla.rb` for an example code.
9
+ It currently ships in a two flavors: Tailwind CSS, and regular, vanilla CSS. It is easy to create your own variant to suit your needs. See `lib/ultimate_turbo_modal/flavors/vanilla.rb` for an example code.
10
10
 
11
11
 
12
12
  &nbsp;
@@ -34,7 +34,7 @@ It currently ships in a two flavors: Tailwind CSS, and regular, vanilla CSS. It
34
34
  &nbsp;
35
35
  ## Demo
36
36
 
37
- A demo application can be found at https://github.com/cmer/ultimate_turbo_modal-demo. A video demo can be seen here: [https://youtu.be/eG5uWTH74NA](https://youtu.be/eG5uWTH74NA)
37
+ A demo application can be found at https://github.com/cmer/ultimate_turbo_modal-demo. A video demo can be seen here: [https://youtu.be/BVRDXLN1I78](https://youtu.be/BVRDXLN1I78).
38
38
 
39
39
 
40
40
  &nbsp;
@@ -59,10 +59,18 @@ A demo application can be found at https://github.com/cmer/ultimate_turbo_modal-
59
59
  <%= turbo_frame_tag "modal" %>
60
60
  ``````
61
61
 
62
- 4. Set your desired flavor at `app/config/initializers/modal.rb`. The default is `:tailwind`.
62
+ 4. Set your desired flavor and default configuration at `app/config/initializers/ultimate_turbo_modal.rb`.
63
63
 
64
64
  ```ruby
65
- UltimateTurboModal.flavor = :tailwind # or :vanilla
65
+ UltimateTurboModal.configure do |config|
66
+ config.flavor = :tailwind
67
+ config.padding = true
68
+ config.advance = true
69
+ config.close_button = true
70
+ config.header = true
71
+ config.header_divider = true
72
+ config.footer_divider = true
73
+ end
66
74
  ```
67
75
 
68
76
  5. Register the Stimulus controller in `app/javascript/controllers/index.js` adding the following lines at the end.
@@ -72,7 +80,33 @@ import setupUltimateTurboModal from "ultimate_turbo_modal";
72
80
  setupUltimateTurboModal(application);
73
81
  ```
74
82
 
75
- 6. Optionally (but recommended), configure UTMR to use Idiomorph. See below for details.
83
+ 6. If using the Tailwind flavor, add the following to `tailwind.config.js`:
84
+
85
+ ```
86
+ // For npm/yarn
87
+ const { getUltimateTurboModalPath } = require('ultimate_turbo_modal/gemPath');
88
+
89
+ // If using Importmaps, use the following instead:
90
+ // const { execSync } = require('child_process');
91
+ //
92
+ // function getUltimateTurboModalPath() {
93
+ // const path = execSync('bundle show ultimate_turbo_modal').toString().trim();
94
+ // return `${path}/**/*.{erb,html,rb}`;
95
+ //}
96
+ ```
97
+
98
+ and then in the `content` section, add `getUltimateTurboModalPath()` as follow:
99
+
100
+ ```
101
+ content: [
102
+ './public/*.html',
103
+ './app/helpers/**/*.rb',
104
+ './app/javascript/**/*.js',
105
+ './app/views/**/*.{erb,haml,html,slim,rb}',
106
+ getUltimateTurboModalPath()
107
+ ```
108
+
109
+ 7. Optionally (but recommended), configure UTMR to use Idiomorph. See below for details.
76
110
 
77
111
  &nbsp;
78
112
  &nbsp;
@@ -122,6 +156,23 @@ When opening the modal, the URL in the URL bar will change to the URL of the vie
122
156
 
123
157
  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.
124
158
 
159
+ ### `title`, default: `nil`
160
+
161
+ Title to display in the modal header.
162
+
163
+ ### `header`, default: `true`
164
+
165
+ Whether to display a modal header.
166
+
167
+ ### `header_divider`, default: `true`
168
+
169
+ Whether to display a divider below the header.
170
+
171
+ ### `footer_divider`, default: `true`
172
+
173
+ Whether to display a divider above the footer. The divider will not appear if no footer was specified.
174
+
175
+
125
176
 
126
177
  ### Example usage with options
127
178
 
@@ -161,6 +212,11 @@ addEventListener("turbo:before-frame-render", (event) => {
161
212
  })
162
213
  ```
163
214
 
215
+ &nbsp;
216
+ &nbsp;
217
+ ## Thanks
218
+
219
+ Thanks to [@joeldrapper](https://github.com/KonnorRogers) and [@konnorrogers](https://github.com/KonnorRogers) for all the help!
164
220
 
165
221
  &nbsp;
166
222
  &nbsp;
@@ -1,90 +1,86 @@
1
1
  class UltimateTurboModal::Base < Phlex::HTML
2
- INCLUDES = %w[
3
- Turbo::FramesHelper
4
- Turbo::StreamsHelper
5
- Phlex::Rails::Helpers::ContentTag
6
- Phlex::Rails::Helpers::Routes
7
- Phlex::Rails::Helpers::Tag
8
- ].freeze
9
-
10
2
  # @param padding [Boolean] Whether to add padding around the modal content
11
3
  # @param close_button [Boolean] Whether to show a close button.
12
4
  # @param advance [Boolean] Whether to update the browser history when opening and closing the modal
13
- # @param advance_url [String] Override the URL to use when advancing the history
5
+ # @param header_divider [Boolean] Whether to show a divider between the header and the main content
6
+ # @param footer_divider [Boolean] Whether to show a divider between the main content and the footer
7
+ # @param title [String] The title of the modal
14
8
  # @param request [ActionDispatch::Request] The current Rails request object
15
- def initialize(padding: true, close_button: true, advance: true, request: nil)
9
+ def initialize(
10
+ padding: UltimateTurboModal.configuration.padding,
11
+ close_button: UltimateTurboModal.configuration.close_button,
12
+ advance: UltimateTurboModal.configuration.advance,
13
+ header: UltimateTurboModal.configuration.header,
14
+ header_divider: UltimateTurboModal.configuration.header_divider,
15
+ footer_divider: UltimateTurboModal.configuration.footer_divider,
16
+ title: nil, request: nil
17
+ )
16
18
  @padding = padding
17
19
  @close_button = close_button
18
- @advance = advance
19
- @advance_url = advance if advance && advance.is_a?(String)
20
+ @advance = !!advance
21
+ @advance_url = advance if advance.present? && advance.is_a?(String)
22
+ @title = title
23
+ @header = header
24
+ @header_divider = header_divider
25
+ @footer_divider = footer_divider
20
26
  @request = request
21
27
 
22
- self.class.include Turbo::FramesHelper
23
- self.class.include Turbo::StreamsHelper
24
- self.class.include Phlex::Rails::Helpers::ContentTag
25
- self.class.include Phlex::Rails::Helpers::Routes
26
- self.class.include Phlex::Rails::Helpers::Tag
28
+ unless self.class.include?(Turbo::FramesHelper)
29
+ self.class.include Turbo::FramesHelper
30
+ self.class.include Turbo::StreamsHelper
31
+ self.class.include Phlex::Rails::Helpers::ContentTag
32
+ self.class.include Phlex::Rails::Helpers::Routes
33
+ self.class.include Phlex::Rails::Helpers::Tag
34
+ end
27
35
  end
28
36
 
29
- def template(&)
37
+ def template(&block)
30
38
  if turbo_frame?
31
- turbo_frame_tag("modal") { modal(&) }
39
+ turbo_frame_tag("modal") do
40
+ modal(&block)
41
+ end
32
42
  elsif turbo_stream?
33
43
  Turbo::StreamsHelper.turbo_stream_action_tag("update", target: "modal") do
34
- template { modal(&) }
44
+ modal(&block)
35
45
  end
36
46
  else
37
- modal(&)
47
+ render block
38
48
  end
39
49
  end
40
50
 
51
+ def footer(&block)
52
+ @footer = block
53
+ end
54
+
41
55
  private
42
56
 
43
- attr_accessor :request
57
+ attr_accessor :request, :title
44
58
 
45
- def padding?
46
- !!@padding
47
- end
59
+ def padding? = !!@padding
48
60
 
49
- def advance?
50
- !!@advance
51
- end
61
+ def close_button? = !!@close_button
52
62
 
53
- def close_button?
54
- !!@close_button
55
- end
63
+ def title? = !!@title
56
64
 
57
- def turbo_stream?
58
- !!request&.format&.turbo_stream?
59
- end
65
+ def header? = !!@header
60
66
 
61
- def turbo_frame?
62
- !!request&.headers&.key?("Turbo-Frame")
63
- end
67
+ def footer? = @footer.present?
64
68
 
65
- def turbo?
66
- turbo_stream? || turbo_frame?
67
- end
69
+ def header_divider? = !!@header_divider && title?
68
70
 
69
- def advance_url
70
- return nil unless advance?
71
- @advance_url || request.original_url
72
- end
71
+ def footer_divider? = !!@footer_divider && footer?
73
72
 
74
- def method_missing(method, *, &block)
75
- INCLUDES.each { |mod| include_if_defined(mod) }
73
+ def turbo_stream? = !!request&.format&.turbo_stream?
76
74
 
77
- if self.class.method_defined?(method)
78
- send(method, *, &block)
79
- else
80
- super
81
- end
82
- end
75
+ def turbo_frame? = !!request&.headers&.key?("Turbo-Frame")
83
76
 
84
- def include_if_defined(mod_str)
85
- if defined?(mod.constantize) && !self.class.included_modules.include?(mod.constantize)
86
- self.class.include mod.constantize
87
- end
77
+ def turbo? = turbo_stream? || turbo_frame?
78
+
79
+ def advance? = !!@advance && !!@advance_url
80
+
81
+ def advance_url
82
+ return nil unless !!@advance
83
+ @advance_url || request&.original_url
88
84
  end
89
85
 
90
86
  def respond_to_missing?(method, include_private = false)
@@ -0,0 +1,68 @@
1
+ module UltimateTurboModal
2
+ class << self
3
+ attr_accessor :configuration
4
+ end
5
+
6
+ def self.configure
7
+ self.configuration ||= Configuration.new
8
+ yield(configuration) if block_given?
9
+ end
10
+
11
+ delegate :flavor, :flavor=, :close_button, :close_button=,
12
+ :advance, :advance=, :padding, :padding=, to: :configuration
13
+
14
+ class Configuration
15
+ attr_reader :flavor, :close_button, :advance, :padding, :header, :header_divider, :footer_divider
16
+
17
+ def initialize
18
+ @flavor = :tailwind
19
+ @close_button = true
20
+ @advance = true
21
+ @padding = true
22
+ @header = true
23
+ @header_divider = true
24
+ @footer_divider = true
25
+ end
26
+
27
+ def flavor=(flavor)
28
+ raise ArgumentError.new("Value must be a symbol.") unless flavor.is_a?(Symbol) || flavor.is_a?(String)
29
+ @flavor = flavor.to_sym
30
+ end
31
+
32
+ def close_button=(close_button)
33
+ raise ArgumentError.new("Value must be a boolean.") unless [true, false].include?(close_button)
34
+ @close_button = close_button
35
+ end
36
+
37
+ def advance=(advance)
38
+ raise ArgumentError.new("Value must be a boolean.") unless [true, false].include?(advance)
39
+ @advance = advance
40
+ end
41
+
42
+ def padding=(padding)
43
+ if [true, false].include?(padding) || padding.is_a?(String)
44
+ @padding = padding
45
+ else
46
+ raise ArgumentError.new("Value must be a boolean or a String.")
47
+ end
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
64
+ end
65
+ end
66
+
67
+ # Make sure the configuration object is set up when the gem is loaded.
68
+ UltimateTurboModal.configure
@@ -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.1"
4
+ VERSION = "1.2.0"
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 "ultimate_turbo_modal/configuration"
4
5
  require "ultimate_turbo_modal/railtie"
5
6
  require "ultimate_turbo_modal/base"
6
7
  Dir[File.join(__dir__, "ultimate_turbo_modal/flavors", "*.rb")].sort.each do |file|
@@ -10,8 +11,6 @@ end
10
11
  module UltimateTurboModal
11
12
  extend self
12
13
 
13
- DEFAULT_FLAVOR = :tailwind
14
-
15
14
  def new(**)
16
15
  modal_class.new(**)
17
16
  end
@@ -20,13 +19,5 @@ module UltimateTurboModal
20
19
  "UltimateTurboModal::Flavors::#{flavor.to_s.classify}".constantize
21
20
  end
22
21
 
23
- def flavor=(flavor)
24
- @flavor = flavor
25
- end
26
-
27
- def flavor
28
- defined?(@flavor) ? @flavor&.to_sym : DEFAULT_FLAVOR
29
- end
30
-
31
22
  class Error < StandardError; end
32
23
  end
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.1
4
+ version: 1.2.0
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-01 00:00:00.000000000 Z
11
+ date: 2023-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex-rails
@@ -92,6 +92,7 @@ files:
92
92
  - Rakefile
93
93
  - lib/ultimate_turbo_modal.rb
94
94
  - lib/ultimate_turbo_modal/base.rb
95
+ - lib/ultimate_turbo_modal/configuration.rb
95
96
  - lib/ultimate_turbo_modal/flavors/tailwind.rb
96
97
  - lib/ultimate_turbo_modal/flavors/vanilla.rb
97
98
  - lib/ultimate_turbo_modal/helpers/controller_helper.rb