better_ui 0.1.1 → 0.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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/better_ui/general/dropdown/component.html.erb +14 -0
  3. data/app/components/better_ui/general/dropdown/component.rb +219 -0
  4. data/app/components/better_ui/general/dropdown/divider_component.html.erb +1 -0
  5. data/app/components/better_ui/general/dropdown/divider_component.rb +41 -0
  6. data/app/components/better_ui/general/dropdown/item_component.html.erb +6 -0
  7. data/app/components/better_ui/general/dropdown/item_component.rb +118 -0
  8. data/app/components/better_ui/general/modal/component.html.erb +42 -0
  9. data/app/components/better_ui/general/modal/component.rb +165 -0
  10. data/app/components/better_ui/general/pagination/component.html.erb +85 -0
  11. data/app/components/better_ui/general/pagination/component.rb +216 -0
  12. data/app/components/better_ui/general/tabs/component.html.erb +3 -0
  13. data/app/components/better_ui/general/tabs/component.rb +102 -0
  14. data/app/components/better_ui/general/tabs/panel_component.html.erb +3 -0
  15. data/app/components/better_ui/general/tabs/panel_component.rb +37 -0
  16. data/app/components/better_ui/general/tabs/tab_component.html.erb +13 -0
  17. data/app/components/better_ui/general/tabs/tab_component.rb +111 -0
  18. data/app/helpers/better_ui/application_helper.rb +9 -0
  19. data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +32 -0
  20. data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +79 -0
  21. data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +62 -0
  22. data/app/helpers/better_ui/general/components/modal/modal_helper.rb +95 -0
  23. data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +82 -0
  24. data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +62 -0
  25. data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +55 -0
  26. data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +62 -0
  27. data/lib/better_ui/version.rb +1 -1
  28. metadata +25 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6522f1369534716a8fe823429de29dad169ad4218482f5b3862b55f4f540831
4
- data.tar.gz: 58ffe37cb7d9f769727b46430684b50d0ddbd1254e6b67838a3e5ba52d3a387a
3
+ metadata.gz: 7b6dbaeb8dede2be21e4bcff93ba5a7793a08f9e84521c2b46bd8e879be6d072
4
+ data.tar.gz: b9f58c90c95a748e694018c85aff6ceeb23ecee0f155b8cb45d9b64dc78da2e1
5
5
  SHA512:
6
- metadata.gz: 9c3190b2940333413e85612676ab048b9c06a24a8138f99b202704cfc9799985386c03a37cb9485a7d57e2ca679ac1bd52535292d5ecaa36930667e5427404af
7
- data.tar.gz: f11573aa7341a77d293c2af1f1ff602cb9a7eaf494767175b93459b25cbdb4a0008eacff85f2d25d8c3bacedbb99800c6fb5ef74e28ec412ac8576c8b1ac184d
6
+ metadata.gz: 7bba346a1d310e3869a232212c8708bbff5ef18f048d9361acc895efa78709b6de1e78bfee44dc3b30db77daf3cf380093331d1443b90d0bb6c18a7ad5d9e2e3
7
+ data.tar.gz: be0e614d6d37d86946d7908e8f2ae0ff83a452dcfc7fc1dd29c42560f77a368bab654e556e767e2d06dcf26236281b9f39987221f0bbee451ff7a16d1125cf39
@@ -0,0 +1,14 @@
1
+ <div <%= tag.attributes(container_attributes) %>>
2
+ <button <%= tag.attributes(trigger_attributes) %>>
3
+ <%= @trigger %>
4
+ <svg class="ml-2 -mr-1 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
5
+ <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
6
+ </svg>
7
+ </button>
8
+
9
+ <div <%= tag.attributes(menu_attributes) %>>
10
+ <div class="py-1" role="none">
11
+ <%= content %>
12
+ </div>
13
+ </div>
14
+ </div>
@@ -0,0 +1,219 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ module General
5
+ module Dropdown
6
+ class Component < ViewComponent::Base
7
+ attr_reader :trigger, :position, :theme, :size, :rounded, :animation, :classes, :html_options
8
+
9
+ # Classi base per il contenitore dropdown
10
+ DROPDOWN_CONTAINER_CLASSES = "relative inline-block"
11
+
12
+ # Classi base per il pulsante trigger
13
+ DROPDOWN_TRIGGER_BASE_CLASSES = "inline-flex items-center justify-center border font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 transition-colors"
14
+
15
+ # Classi base per il menu dropdown
16
+ DROPDOWN_MENU_BASE_CLASSES = "absolute z-50 mt-2 origin-top-right bg-white border border-gray-200 shadow-lg focus:outline-none"
17
+
18
+ # Temi per il trigger del dropdown con classi Tailwind dirette
19
+ DROPDOWN_TRIGGER_THEME = {
20
+ default: "bg-white border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-blue-500",
21
+ white: "bg-white border-gray-300 text-gray-900 hover:bg-gray-50 focus:ring-gray-500",
22
+ red: "bg-red-600 border-red-600 text-white hover:bg-red-700 focus:ring-red-500",
23
+ rose: "bg-rose-600 border-rose-600 text-white hover:bg-rose-700 focus:ring-rose-500",
24
+ orange: "bg-orange-600 border-orange-600 text-white hover:bg-orange-700 focus:ring-orange-500",
25
+ green: "bg-green-600 border-green-600 text-white hover:bg-green-700 focus:ring-green-500",
26
+ blue: "bg-blue-600 border-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
27
+ yellow: "bg-yellow-500 border-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500",
28
+ violet: "bg-violet-600 border-violet-600 text-white hover:bg-violet-700 focus:ring-violet-500"
29
+ }.freeze
30
+
31
+ # Dimensioni del trigger con classi Tailwind dirette
32
+ DROPDOWN_TRIGGER_SIZE = {
33
+ small: "px-3 py-1.5 text-sm",
34
+ medium: "px-4 py-2 text-sm",
35
+ large: "px-6 py-3 text-base"
36
+ }.freeze
37
+
38
+ # Border radius con classi Tailwind dirette
39
+ DROPDOWN_ROUNDED = {
40
+ none: "rounded-none",
41
+ small: "rounded-md",
42
+ medium: "rounded-lg",
43
+ large: "rounded-xl",
44
+ full: "rounded-full"
45
+ }.freeze
46
+
47
+ # Posizioni del menu dropdown
48
+ DROPDOWN_POSITION = {
49
+ bottom: "top-full left-0",
50
+ top: "bottom-full left-0",
51
+ left: "top-0 right-full mr-2",
52
+ right: "top-0 left-full ml-2"
53
+ }.freeze
54
+
55
+ # Animazioni del dropdown
56
+ DROPDOWN_ANIMATION = {
57
+ fade: "transition-opacity duration-150",
58
+ slide: "transition-all duration-150 transform",
59
+ none: ""
60
+ }.freeze
61
+
62
+ def initialize(
63
+ trigger:,
64
+ position: :bottom,
65
+ theme: :default,
66
+ size: :medium,
67
+ rounded: :medium,
68
+ animation: :fade,
69
+ classes: nil,
70
+ **html_options
71
+ )
72
+ @trigger = trigger
73
+ @position = position.to_sym
74
+ @theme = theme.to_sym
75
+ @size = size.to_sym
76
+ @rounded = rounded.to_sym
77
+ @animation = animation.to_sym
78
+ @classes = classes
79
+ @html_options = html_options
80
+
81
+ validate_params
82
+ end
83
+
84
+ # Combina tutte le classi per il contenitore
85
+ def container_classes
86
+ [
87
+ DROPDOWN_CONTAINER_CLASSES,
88
+ @classes
89
+ ].compact.join(" ")
90
+ end
91
+
92
+ # Combina tutte le classi per il trigger
93
+ def trigger_classes
94
+ [
95
+ DROPDOWN_TRIGGER_BASE_CLASSES,
96
+ get_trigger_theme_classes,
97
+ get_trigger_size_classes,
98
+ get_trigger_rounded_classes
99
+ ].compact.join(" ")
100
+ end
101
+
102
+ # Combina tutte le classi per il menu
103
+ def menu_classes
104
+ [
105
+ DROPDOWN_MENU_BASE_CLASSES,
106
+ get_position_classes,
107
+ get_animation_classes,
108
+ get_menu_rounded_classes
109
+ ].compact.join(" ")
110
+ end
111
+
112
+ # Restituisce gli attributi per il contenitore
113
+ def container_attributes
114
+ attrs = {
115
+ class: container_classes,
116
+ "data-dropdown": true
117
+ }
118
+
119
+ @html_options.except(:class).each do |key, value|
120
+ attrs[key] = value
121
+ end
122
+
123
+ attrs
124
+ end
125
+
126
+ # Restituisce gli attributi per il trigger
127
+ def trigger_attributes
128
+ {
129
+ type: "button",
130
+ class: trigger_classes,
131
+ "data-dropdown-trigger": true,
132
+ "aria-expanded": "false",
133
+ "aria-haspopup": "true"
134
+ }
135
+ end
136
+
137
+ # Restituisce gli attributi per il menu
138
+ def menu_attributes
139
+ {
140
+ class: menu_classes,
141
+ "data-dropdown-menu": true,
142
+ role: "menu",
143
+ "aria-orientation": "vertical",
144
+ style: "display: none;"
145
+ }
146
+ end
147
+
148
+ # Verifica se rendere il componente
149
+ def render?
150
+ @trigger.present?
151
+ end
152
+
153
+ private
154
+
155
+ def get_trigger_theme_classes
156
+ DROPDOWN_TRIGGER_THEME[@theme] || DROPDOWN_TRIGGER_THEME[:default]
157
+ end
158
+
159
+ def get_trigger_size_classes
160
+ DROPDOWN_TRIGGER_SIZE[@size] || DROPDOWN_TRIGGER_SIZE[:medium]
161
+ end
162
+
163
+ def get_trigger_rounded_classes
164
+ DROPDOWN_ROUNDED[@rounded] || DROPDOWN_ROUNDED[:medium]
165
+ end
166
+
167
+ def get_menu_rounded_classes
168
+ DROPDOWN_ROUNDED[@rounded] || DROPDOWN_ROUNDED[:medium]
169
+ end
170
+
171
+ def get_position_classes
172
+ DROPDOWN_POSITION[@position] || DROPDOWN_POSITION[:bottom]
173
+ end
174
+
175
+ def get_animation_classes
176
+ DROPDOWN_ANIMATION[@animation] || DROPDOWN_ANIMATION[:fade]
177
+ end
178
+
179
+ def validate_params
180
+ validate_theme
181
+ validate_size
182
+ validate_rounded
183
+ validate_position
184
+ validate_animation
185
+ end
186
+
187
+ def validate_theme
188
+ unless DROPDOWN_TRIGGER_THEME.keys.include?(@theme)
189
+ raise ArgumentError, "Il tema deve essere uno tra: #{DROPDOWN_TRIGGER_THEME.keys.join(', ')}"
190
+ end
191
+ end
192
+
193
+ def validate_size
194
+ unless DROPDOWN_TRIGGER_SIZE.keys.include?(@size)
195
+ raise ArgumentError, "La dimensione deve essere una tra: #{DROPDOWN_TRIGGER_SIZE.keys.join(', ')}"
196
+ end
197
+ end
198
+
199
+ def validate_rounded
200
+ unless DROPDOWN_ROUNDED.keys.include?(@rounded)
201
+ raise ArgumentError, "Il border radius deve essere uno tra: #{DROPDOWN_ROUNDED.keys.join(', ')}"
202
+ end
203
+ end
204
+
205
+ def validate_position
206
+ unless DROPDOWN_POSITION.keys.include?(@position)
207
+ raise ArgumentError, "La posizione deve essere una tra: #{DROPDOWN_POSITION.keys.join(', ')}"
208
+ end
209
+ end
210
+
211
+ def validate_animation
212
+ unless DROPDOWN_ANIMATION.keys.include?(@animation)
213
+ raise ArgumentError, "L'animazione deve essere una tra: #{DROPDOWN_ANIMATION.keys.join(', ')}"
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
@@ -0,0 +1 @@
1
+ <div <%= tag.attributes(divider_attributes) %>></div>
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ module General
5
+ module Dropdown
6
+ class DividerComponent < ViewComponent::Base
7
+ attr_reader :classes, :html_options
8
+
9
+ # Classi base per il divisore del dropdown
10
+ DROPDOWN_DIVIDER_CLASSES = "border-t border-gray-100 my-1"
11
+
12
+ def initialize(classes: nil, **html_options)
13
+ @classes = classes
14
+ @html_options = html_options
15
+ end
16
+
17
+ # Combina tutte le classi per il divisore
18
+ def divider_classes
19
+ [
20
+ DROPDOWN_DIVIDER_CLASSES,
21
+ @classes
22
+ ].compact.join(" ")
23
+ end
24
+
25
+ # Restituisce gli attributi per il divisore
26
+ def divider_attributes
27
+ attrs = {
28
+ class: divider_classes,
29
+ role: "separator"
30
+ }
31
+
32
+ @html_options.except(:class).each do |key, value|
33
+ attrs[key] = value
34
+ end
35
+
36
+ attrs
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ <<%= tag_name %> <%= tag.attributes(item_attributes) %>>
2
+ <% if @icon.present? %>
3
+ <span class="mr-3 flex-shrink-0"><%= bui_icon(@icon, classes: "h-5 w-5") %></span>
4
+ <% end %>
5
+ <%= @text %>
6
+ </<%= tag_name %>>
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ module General
5
+ module Dropdown
6
+ class ItemComponent < ViewComponent::Base
7
+ include BetterUi::General::Components::Icon::IconHelper
8
+
9
+ attr_reader :text, :icon, :href, :theme, :disabled, :active, :classes, :html_options
10
+
11
+ # Classi base per l'elemento del dropdown
12
+ DROPDOWN_ITEM_BASE_CLASSES = "flex items-center w-full px-4 py-2 text-sm transition-colors"
13
+
14
+ # Temi per gli elementi del dropdown con classi Tailwind dirette
15
+ DROPDOWN_ITEM_THEME = {
16
+ default: "text-gray-700 hover:bg-gray-100 hover:text-gray-900",
17
+ white: "text-gray-900 hover:bg-gray-50",
18
+ red: "text-red-700 hover:bg-red-50 hover:text-red-900",
19
+ rose: "text-rose-700 hover:bg-rose-50 hover:text-rose-900",
20
+ orange: "text-orange-700 hover:bg-orange-50 hover:text-orange-900",
21
+ green: "text-green-700 hover:bg-green-50 hover:text-green-900",
22
+ blue: "text-blue-700 hover:bg-blue-50 hover:text-blue-900",
23
+ yellow: "text-yellow-700 hover:bg-yellow-50 hover:text-yellow-900",
24
+ violet: "text-violet-700 hover:bg-violet-50 hover:text-violet-900"
25
+ }.freeze
26
+
27
+ # Stati per gli elementi del dropdown
28
+ DROPDOWN_ITEM_STATE_DISABLED = "opacity-50 cursor-not-allowed pointer-events-none"
29
+ DROPDOWN_ITEM_STATE_ACTIVE = "bg-gray-100 text-gray-900"
30
+
31
+ def initialize(
32
+ text:,
33
+ icon: nil,
34
+ href: nil,
35
+ theme: :default,
36
+ disabled: false,
37
+ active: false,
38
+ classes: nil,
39
+ **html_options
40
+ )
41
+ @text = text
42
+ @icon = icon
43
+ @href = href
44
+ @theme = theme.to_sym
45
+ @disabled = disabled
46
+ @active = active
47
+ @classes = classes
48
+ @html_options = html_options
49
+
50
+ validate_params
51
+ end
52
+
53
+ # Combina tutte le classi per l'elemento
54
+ def item_classes
55
+ classes = [
56
+ DROPDOWN_ITEM_BASE_CLASSES,
57
+ get_theme_classes,
58
+ @classes
59
+ ]
60
+
61
+ classes << DROPDOWN_ITEM_STATE_DISABLED if @disabled
62
+ classes << DROPDOWN_ITEM_STATE_ACTIVE if @active
63
+
64
+ classes.compact.join(" ")
65
+ end
66
+
67
+ # Restituisce gli attributi per l'elemento
68
+ def item_attributes
69
+ attrs = {
70
+ class: item_classes,
71
+ role: "menuitem"
72
+ }
73
+
74
+ if @href.present? && !@disabled
75
+ attrs[:href] = @href
76
+ end
77
+
78
+ if @disabled
79
+ attrs["aria-disabled"] = "true"
80
+ attrs[:tabindex] = "-1"
81
+ end
82
+
83
+ @html_options.except(:class).each do |key, value|
84
+ attrs[key] = value
85
+ end
86
+
87
+ attrs
88
+ end
89
+
90
+ # Determina se usare un link o un button
91
+ def tag_name
92
+ @href.present? && !@disabled ? :a : :button
93
+ end
94
+
95
+ # Verifica se rendere il componente
96
+ def render?
97
+ @text.present?
98
+ end
99
+
100
+ private
101
+
102
+ def get_theme_classes
103
+ DROPDOWN_ITEM_THEME[@theme] || DROPDOWN_ITEM_THEME[:default]
104
+ end
105
+
106
+ def validate_params
107
+ validate_theme
108
+ end
109
+
110
+ def validate_theme
111
+ unless DROPDOWN_ITEM_THEME.keys.include?(@theme)
112
+ raise ArgumentError, "Il tema deve essere uno tra: #{DROPDOWN_ITEM_THEME.keys.join(', ')}"
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,42 @@
1
+ <%# Template per il modal %>
2
+ <% if @backdrop %>
3
+ <%= tag.div **backdrop_attributes do %>
4
+ <%= tag.div **container_attributes do %>
5
+ <%# Header del modal %>
6
+ <%= tag.div **header_attributes do %>
7
+ <h3 class="text-lg font-semibold" id="modal-title"><%= @title %></h3>
8
+ <% if @closable %>
9
+ <button type="button" class="text-gray-400 hover:text-gray-600 focus:outline-none focus:text-gray-600 transition-colors duration-200" aria-label="Chiudi modal">
10
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
11
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
12
+ </svg>
13
+ </button>
14
+ <% end %>
15
+ <% end %>
16
+
17
+ <%# Body del modal %>
18
+ <div class="p-6">
19
+ <%= content %>
20
+ </div>
21
+ <% end %>
22
+ <% end %>
23
+ <% else %>
24
+ <%= tag.div **container_attributes do %>
25
+ <%# Header del modal %>
26
+ <%= tag.div **header_attributes do %>
27
+ <h3 class="text-lg font-semibold" id="modal-title"><%= @title %></h3>
28
+ <% if @closable %>
29
+ <button type="button" class="text-gray-400 hover:text-gray-600 focus:outline-none focus:text-gray-600 transition-colors duration-200" aria-label="Chiudi modal">
30
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
31
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
32
+ </svg>
33
+ </button>
34
+ <% end %>
35
+ <% end %>
36
+
37
+ <%# Body del modal %>
38
+ <div class="p-6">
39
+ <%= content %>
40
+ </div>
41
+ <% end %>
42
+ <% end %>
@@ -0,0 +1,165 @@
1
+ module BetterUi
2
+ module General
3
+ module Modal
4
+ class Component < ViewComponent::Base
5
+ attr_reader :title, :theme, :size, :backdrop, :closable, :classes, :html_options
6
+
7
+ # Classi base sempre presenti per il backdrop
8
+ MODAL_BACKDROP_CLASSES = "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black bg-opacity-50"
9
+
10
+ # Classi base per il contenitore del modal
11
+ MODAL_CONTAINER_CLASSES = "relative bg-white shadow-xl w-full"
12
+
13
+ # Temi dell'header del modal con classi Tailwind dirette
14
+ MODAL_THEME = {
15
+ default: "bg-gray-50 border-b border-gray-200 text-gray-900",
16
+ white: "bg-white border-b border-gray-200 text-gray-900",
17
+ red: "bg-red-50 border-b border-red-200 text-red-900",
18
+ rose: "bg-rose-50 border-b border-rose-200 text-rose-900",
19
+ orange: "bg-orange-50 border-b border-orange-200 text-orange-900",
20
+ green: "bg-green-50 border-b border-green-200 text-green-900",
21
+ blue: "bg-blue-50 border-b border-blue-200 text-blue-900",
22
+ yellow: "bg-yellow-50 border-b border-yellow-200 text-yellow-900",
23
+ violet: "bg-violet-50 border-b border-violet-200 text-violet-900"
24
+ }
25
+
26
+ # Dimensioni con classi Tailwind dirette
27
+ MODAL_SIZES = {
28
+ small: "max-w-sm",
29
+ medium: "max-w-md",
30
+ large: "max-w-2xl"
31
+ }
32
+
33
+ # Border radius con classi Tailwind dirette
34
+ MODAL_ROUNDED = {
35
+ none: "rounded-none",
36
+ small: "rounded-md",
37
+ medium: "rounded-lg",
38
+ large: "rounded-xl",
39
+ full: "rounded-full"
40
+ }
41
+
42
+ # Inizializzazione del componente
43
+ def initialize(
44
+ title:,
45
+ theme: :default,
46
+ size: :medium,
47
+ rounded: :medium,
48
+ backdrop: true,
49
+ closable: true,
50
+ classes: nil,
51
+ **html_options
52
+ )
53
+ @title = title
54
+ @theme = theme.to_sym
55
+ @size = size.to_sym
56
+ @rounded = rounded.to_sym
57
+ @backdrop = backdrop
58
+ @closable = closable
59
+ @classes = classes
60
+ @html_options = html_options
61
+
62
+ validate_params
63
+ end
64
+
65
+ # Combina tutte le classi per il backdrop
66
+ def backdrop_classes
67
+ MODAL_BACKDROP_CLASSES
68
+ end
69
+
70
+ # Combina tutte le classi per il contenitore
71
+ def container_classes
72
+ [
73
+ MODAL_CONTAINER_CLASSES,
74
+ get_modal_size_classes,
75
+ get_modal_rounded_classes,
76
+ @classes,
77
+ @html_options[:class]
78
+ ].compact.join(" ")
79
+ end
80
+
81
+ # Combina tutte le classi per l'header
82
+ def header_classes
83
+ [
84
+ "flex items-center justify-between p-6",
85
+ get_modal_theme_classes
86
+ ].compact.join(" ")
87
+ end
88
+
89
+ def get_modal_theme_classes
90
+ MODAL_THEME[@theme] || MODAL_THEME[:default]
91
+ end
92
+
93
+ def get_modal_size_classes
94
+ MODAL_SIZES[@size] || MODAL_SIZES[:medium]
95
+ end
96
+
97
+ def get_modal_rounded_classes
98
+ MODAL_ROUNDED[@rounded] || MODAL_ROUNDED[:medium]
99
+ end
100
+
101
+ # Restituisce gli attributi per il backdrop
102
+ def backdrop_attributes
103
+ attrs = {
104
+ class: backdrop_classes
105
+ }
106
+
107
+ # Aggiungi altri attributi HTML se presenti
108
+ @html_options.except(:class).each do |key, value|
109
+ attrs[key] = value
110
+ end
111
+
112
+ attrs
113
+ end
114
+
115
+ # Restituisce gli attributi per il contenitore
116
+ def container_attributes
117
+ {
118
+ class: container_classes,
119
+ role: "dialog",
120
+ "aria-modal": "true",
121
+ "aria-labelledby": "modal-title"
122
+ }
123
+ end
124
+
125
+ # Restituisce gli attributi per l'header
126
+ def header_attributes
127
+ {
128
+ class: header_classes
129
+ }
130
+ end
131
+
132
+ # Verifica se rendere il componente
133
+ def render?
134
+ @title.present?
135
+ end
136
+
137
+ private
138
+
139
+ def validate_params
140
+ validate_theme
141
+ validate_size
142
+ validate_rounded
143
+ end
144
+
145
+ def validate_theme
146
+ unless MODAL_THEME.keys.include?(@theme)
147
+ raise ArgumentError, "Il tema deve essere uno tra: #{MODAL_THEME.keys.join(', ')}"
148
+ end
149
+ end
150
+
151
+ def validate_size
152
+ unless MODAL_SIZES.keys.include?(@size)
153
+ raise ArgumentError, "La dimensione deve essere una tra: #{MODAL_SIZES.keys.join(', ')}"
154
+ end
155
+ end
156
+
157
+ def validate_rounded
158
+ unless MODAL_ROUNDED.keys.include?(@rounded)
159
+ raise ArgumentError, "Il border radius deve essere uno tra: #{MODAL_ROUNDED.keys.join(', ')}"
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end