better_ui 0.6.0 → 0.7.1

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 (198) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +257 -212
  3. data/Rakefile +11 -2
  4. data/app/components/better_ui/action_messages_component/action_messages_component.html.erb +48 -0
  5. data/app/components/better_ui/action_messages_component.rb +544 -0
  6. data/app/components/better_ui/application_component.rb +66 -0
  7. data/app/components/better_ui/button_component/button_component.html.erb +31 -0
  8. data/app/components/better_ui/button_component.rb +307 -0
  9. data/app/components/better_ui/card_component/card_component.html.erb +17 -0
  10. data/app/components/better_ui/card_component.rb +460 -0
  11. data/app/components/better_ui/drawer/header_component/header_component.html.erb +24 -0
  12. data/app/components/better_ui/drawer/header_component.rb +238 -0
  13. data/app/components/better_ui/drawer/layout_component/layout_component.html.erb +44 -0
  14. data/app/components/better_ui/drawer/layout_component.rb +270 -0
  15. data/app/components/better_ui/drawer/nav_group_component/nav_group_component.html.erb +10 -0
  16. data/app/components/better_ui/drawer/nav_group_component.rb +155 -0
  17. data/app/components/better_ui/drawer/nav_item_component/nav_item_component.html.erb +13 -0
  18. data/app/components/better_ui/drawer/nav_item_component.rb +225 -0
  19. data/app/components/better_ui/drawer/sidebar_component/sidebar_component.html.erb +17 -0
  20. data/app/components/better_ui/drawer/sidebar_component.rb +263 -0
  21. data/app/components/better_ui/forms/base_component.rb +450 -0
  22. data/app/components/better_ui/forms/checkbox_component/checkbox_component.html.erb +28 -0
  23. data/app/components/better_ui/forms/checkbox_component.rb +419 -0
  24. data/app/components/better_ui/forms/checkbox_group_component/checkbox_group_component.html.erb +40 -0
  25. data/app/components/better_ui/forms/checkbox_group_component.rb +363 -0
  26. data/app/components/better_ui/forms/number_input_component/number_input_component.html.erb +40 -0
  27. data/app/components/better_ui/forms/number_input_component.rb +320 -0
  28. data/app/components/better_ui/forms/password_input_component/password_input_component.html.erb +71 -0
  29. data/app/components/better_ui/forms/password_input_component.rb +206 -0
  30. data/app/components/better_ui/forms/text_input_component/text_input_component.html.erb +40 -0
  31. data/app/components/better_ui/forms/text_input_component.rb +258 -0
  32. data/app/components/better_ui/forms/textarea_component/textarea_component.html.erb +40 -0
  33. data/app/components/better_ui/forms/textarea_component.rb +329 -0
  34. data/app/form_builders/better_ui/ui_form_builder.rb +467 -0
  35. data/app/helpers/better_ui/application_helper.rb +325 -58
  36. data/app/views/layouts/better_ui/application.html.erb +1 -1
  37. data/config/routes.rb +1 -0
  38. data/lib/better_ui/engine.rb +34 -5
  39. data/lib/better_ui/version.rb +1 -1
  40. data/lib/better_ui.rb +32 -5
  41. data/lib/generators/better_ui/install/USAGE +44 -0
  42. data/lib/generators/better_ui/install/install_generator.rb +87 -0
  43. data/lib/generators/better_ui/install/templates/better_ui_theme.css.tt +280 -0
  44. data/lib/tasks/better_ui_tasks.rake +39 -4
  45. metadata +55 -203
  46. data/app/components/better_ui/application/card/component.html.erb +0 -20
  47. data/app/components/better_ui/application/card/component.rb +0 -214
  48. data/app/components/better_ui/application/main/component.html.erb +0 -9
  49. data/app/components/better_ui/application/main/component.rb +0 -123
  50. data/app/components/better_ui/application/navbar/component.html.erb +0 -92
  51. data/app/components/better_ui/application/navbar/component.rb +0 -136
  52. data/app/components/better_ui/application/sidebar/component.html.erb +0 -249
  53. data/app/components/better_ui/application/sidebar/component.rb +0 -187
  54. data/app/components/better_ui/general/accordion/component.html.erb +0 -5
  55. data/app/components/better_ui/general/accordion/component.rb +0 -92
  56. data/app/components/better_ui/general/accordion/item_component.html.erb +0 -12
  57. data/app/components/better_ui/general/accordion/item_component.rb +0 -176
  58. data/app/components/better_ui/general/alert/component.html.erb +0 -32
  59. data/app/components/better_ui/general/alert/component.rb +0 -242
  60. data/app/components/better_ui/general/avatar/component.html.erb +0 -20
  61. data/app/components/better_ui/general/avatar/component.rb +0 -301
  62. data/app/components/better_ui/general/badge/component.html.erb +0 -23
  63. data/app/components/better_ui/general/badge/component.rb +0 -248
  64. data/app/components/better_ui/general/breadcrumb/component.html.erb +0 -15
  65. data/app/components/better_ui/general/breadcrumb/component.rb +0 -187
  66. data/app/components/better_ui/general/button/component.html.erb +0 -34
  67. data/app/components/better_ui/general/button/component.rb +0 -214
  68. data/app/components/better_ui/general/divider/component.html.erb +0 -10
  69. data/app/components/better_ui/general/divider/component.rb +0 -226
  70. data/app/components/better_ui/general/dropdown/component.html.erb +0 -28
  71. data/app/components/better_ui/general/dropdown/component.rb +0 -192
  72. data/app/components/better_ui/general/dropdown/divider_component.html.erb +0 -1
  73. data/app/components/better_ui/general/dropdown/divider_component.rb +0 -41
  74. data/app/components/better_ui/general/dropdown/item_component.html.erb +0 -6
  75. data/app/components/better_ui/general/dropdown/item_component.rb +0 -119
  76. data/app/components/better_ui/general/field/component.html.erb +0 -27
  77. data/app/components/better_ui/general/field/component.rb +0 -37
  78. data/app/components/better_ui/general/grid/cell_component.html.erb +0 -3
  79. data/app/components/better_ui/general/grid/cell_component.rb +0 -390
  80. data/app/components/better_ui/general/grid/component.html.erb +0 -3
  81. data/app/components/better_ui/general/grid/component.rb +0 -301
  82. data/app/components/better_ui/general/heading/component.html.erb +0 -22
  83. data/app/components/better_ui/general/heading/component.rb +0 -257
  84. data/app/components/better_ui/general/icon/component.html.erb +0 -7
  85. data/app/components/better_ui/general/icon/component.rb +0 -240
  86. data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
  87. data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
  88. data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
  89. data/app/components/better_ui/general/input/datetime/component.rb +0 -223
  90. data/app/components/better_ui/general/input/pin/component.html.erb +0 -1
  91. data/app/components/better_ui/general/input/pin/component.rb +0 -201
  92. data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
  93. data/app/components/better_ui/general/input/radio/component.rb +0 -230
  94. data/app/components/better_ui/general/input/rating/component.html.erb +0 -4
  95. data/app/components/better_ui/general/input/rating/component.rb +0 -272
  96. data/app/components/better_ui/general/input/select/component.html.erb +0 -78
  97. data/app/components/better_ui/general/input/select/component.rb +0 -249
  98. data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
  99. data/app/components/better_ui/general/input/select/select_component.rb +0 -37
  100. data/app/components/better_ui/general/input/text/component.html.erb +0 -5
  101. data/app/components/better_ui/general/input/text/component.rb +0 -171
  102. data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
  103. data/app/components/better_ui/general/input/textarea/component.rb +0 -166
  104. data/app/components/better_ui/general/input/toggle/component.html.erb +0 -5
  105. data/app/components/better_ui/general/input/toggle/component.rb +0 -242
  106. data/app/components/better_ui/general/link/component.html.erb +0 -18
  107. data/app/components/better_ui/general/link/component.rb +0 -258
  108. data/app/components/better_ui/general/modal/component.html.erb +0 -5
  109. data/app/components/better_ui/general/modal/component.rb +0 -47
  110. data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
  111. data/app/components/better_ui/general/modal/modal_component.rb +0 -160
  112. data/app/components/better_ui/general/pagination/component.html.erb +0 -85
  113. data/app/components/better_ui/general/pagination/component.rb +0 -216
  114. data/app/components/better_ui/general/panel/component.html.erb +0 -28
  115. data/app/components/better_ui/general/panel/component.rb +0 -249
  116. data/app/components/better_ui/general/progress/component.html.erb +0 -11
  117. data/app/components/better_ui/general/progress/component.rb +0 -160
  118. data/app/components/better_ui/general/spinner/component.html.erb +0 -35
  119. data/app/components/better_ui/general/spinner/component.rb +0 -93
  120. data/app/components/better_ui/general/table/component.html.erb +0 -5
  121. data/app/components/better_ui/general/table/component.rb +0 -217
  122. data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
  123. data/app/components/better_ui/general/table/tbody_component.rb +0 -30
  124. data/app/components/better_ui/general/table/td_component.html.erb +0 -3
  125. data/app/components/better_ui/general/table/td_component.rb +0 -44
  126. data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
  127. data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
  128. data/app/components/better_ui/general/table/th_component.html.erb +0 -6
  129. data/app/components/better_ui/general/table/th_component.rb +0 -51
  130. data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
  131. data/app/components/better_ui/general/table/thead_component.rb +0 -28
  132. data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
  133. data/app/components/better_ui/general/table/tr_component.rb +0 -30
  134. data/app/components/better_ui/general/tabs/component.html.erb +0 -11
  135. data/app/components/better_ui/general/tabs/component.rb +0 -120
  136. data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
  137. data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
  138. data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
  139. data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
  140. data/app/components/better_ui/general/tag/component.html.erb +0 -3
  141. data/app/components/better_ui/general/tag/component.rb +0 -104
  142. data/app/components/better_ui/general/text/component.html.erb +0 -1
  143. data/app/components/better_ui/general/text/component.rb +0 -194
  144. data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
  145. data/app/components/better_ui/general/tooltip/component.rb +0 -239
  146. data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
  147. data/app/helpers/better_ui/application/components/card.rb +0 -11
  148. data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
  149. data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
  150. data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
  151. data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
  152. data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
  153. data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
  154. data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
  155. data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
  156. data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
  157. data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
  158. data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
  159. data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
  160. data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -88
  161. data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -68
  162. data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
  163. data/app/helpers/better_ui/general/components/grid/grid_helper.rb +0 -145
  164. data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
  165. data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
  166. data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
  167. data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
  168. data/app/helpers/better_ui/general/components/input/pin/pin_helper.rb +0 -76
  169. data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
  170. data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
  171. data/app/helpers/better_ui/general/components/input/rating/rating_helper.rb +0 -70
  172. data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -86
  173. data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
  174. data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
  175. data/app/helpers/better_ui/general/components/input/toggle/toggle_helper.rb +0 -77
  176. data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
  177. data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
  178. data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
  179. data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
  180. data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
  181. data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
  182. data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
  183. data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
  184. data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
  185. data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
  186. data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
  187. data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
  188. data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
  189. data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
  190. data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
  191. data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
  192. data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
  193. data/app/helpers/better_ui/general/components/text/text_helper.rb +0 -83
  194. data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
  195. data/app/jobs/better_ui/application_job.rb +0 -4
  196. data/app/mailers/better_ui/application_mailer.rb +0 -6
  197. data/config/initializers/lookbook.rb +0 -23
  198. data/lib/better_ui/railtie.rb +0 -20
@@ -1,242 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Input
6
- module Toggle
7
- class Component < ViewComponent::Base
8
- # Costanti con classi Tailwind dirette
9
- TOGGLE_THEME = {
10
- default: 'peer-checked:bg-gray-800',
11
- white: 'peer-checked:bg-white border peer-checked:border-gray-900',
12
- red: 'peer-checked:bg-red-600',
13
- rose: 'peer-checked:bg-rose-600',
14
- orange: 'peer-checked:bg-orange-600',
15
- green: 'peer-checked:bg-green-600',
16
- blue: 'peer-checked:bg-blue-600',
17
- yellow: 'peer-checked:bg-yellow-600',
18
- violet: 'peer-checked:bg-violet-600'
19
- }.freeze
20
-
21
- TOGGLE_TRACK_SIZE = {
22
- small: 'w-9 h-5',
23
- medium: 'w-11 h-6',
24
- large: 'w-14 h-7'
25
- }.freeze
26
-
27
- TOGGLE_THUMB_SIZE = {
28
- small: 'w-4 h-4',
29
- medium: 'w-5 h-5',
30
- large: 'w-6 h-6'
31
- }.freeze
32
-
33
- TOGGLE_THUMB_POSITION = {
34
- small: 'peer-checked:translate-x-4',
35
- medium: 'peer-checked:translate-x-5',
36
- large: 'peer-checked:translate-x-7'
37
- }.freeze
38
-
39
- TOGGLE_BASE_TRACK = 'relative bg-gray-300 rounded-full transition-colors duration-200 ease-in-out'.freeze
40
- TOGGLE_BASE_THUMB = 'bg-white rounded-full shadow-sm transform transition-transform duration-200 ease-in-out absolute top-0.5 left-0.5'.freeze
41
-
42
- TOGGLE_LABEL_GAP = {
43
- small: 'gap-2',
44
- medium: 'gap-2.5',
45
- large: 'gap-3'
46
- }.freeze
47
-
48
- TOGGLE_LABEL_TEXT = {
49
- small: 'text-sm',
50
- medium: 'text-base',
51
- large: 'text-lg'
52
- }.freeze
53
-
54
- attr_reader :name, :value, :checked, :required, :disabled,
55
- :label, :label_position, :theme, :size,
56
- :form, :classes, :options
57
-
58
- # @param name [String] Nome del campo toggle (obbligatorio)
59
- # @param value [String] Valore del toggle quando è attivo (default: "1")
60
- # @param checked [Boolean] Se il toggle è attivo
61
- # @param required [Boolean] Se il campo è obbligatorio
62
- # @param disabled [Boolean] Se il campo è disabilitato
63
- # @param label [String, nil] Testo della label associata al toggle
64
- # @param label_position [Symbol] Posizione della label (:left, :right)
65
- # @param theme [Symbol] Tema del componente (:default, :white, :red, :rose, :orange, :green, :blue, :yellow, :violet)
66
- # @param size [Symbol] Dimensione del componente (:small, :medium, :large)
67
- # @param form [ActionView::Helpers::FormBuilder, nil] Form builder Rails opzionale
68
- # @param classes [String] Classi CSS aggiuntive
69
- # @param options [Hash] Opzioni aggiuntive per l'input (es. data attributes)
70
- def initialize(name:, value: '1', checked: false, required: false, disabled: false,
71
- label: nil, label_position: :right, theme: :default,
72
- size: :medium, form: nil, classes: '', **options)
73
- @name = name
74
- @value = value
75
- @checked = checked
76
- @required = required
77
- @disabled = disabled
78
- @label = label
79
- @label_position = label_position.to_sym
80
- @theme = theme.to_sym
81
- @size = size.to_sym
82
- @form = form
83
- @classes = classes
84
- @options = options
85
-
86
- validate_params
87
- end
88
-
89
- private
90
-
91
- def validate_params
92
- validate_theme
93
- validate_size
94
- validate_label_position
95
- end
96
-
97
- def validate_theme
98
- return if TOGGLE_THEME.key?(@theme)
99
-
100
- raise ArgumentError, "Invalid theme: #{@theme}. Valid themes are: #{TOGGLE_THEME.keys.join(', ')}"
101
- end
102
-
103
- def validate_size
104
- return if TOGGLE_TRACK_SIZE.key?(@size)
105
-
106
- raise ArgumentError, "Invalid size: #{@size}. Valid sizes are: #{TOGGLE_TRACK_SIZE.keys.join(', ')}"
107
- end
108
-
109
- def validate_label_position
110
- return if [:left, :right].include?(@label_position)
111
-
112
- raise ArgumentError, "Invalid label_position: #{@label_position}. Valid positions are: left, right"
113
- end
114
-
115
- def container_classes
116
- base_classes = ['inline-flex', 'items-center']
117
- base_classes << TOGGLE_LABEL_GAP[@size]
118
- base_classes << (@disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer')
119
- base_classes << @classes if @classes.present?
120
- base_classes.join(' ')
121
- end
122
-
123
- def track_classes
124
- [
125
- TOGGLE_BASE_TRACK,
126
- TOGGLE_THEME[@theme],
127
- TOGGLE_TRACK_SIZE[@size]
128
- ].join(' ')
129
- end
130
-
131
- def thumb_classes
132
- [
133
- TOGGLE_BASE_THUMB,
134
- TOGGLE_THUMB_SIZE[@size],
135
- TOGGLE_THUMB_POSITION[@size]
136
- ].join(' ')
137
- end
138
-
139
- def input_attributes
140
- attrs = {
141
- type: 'checkbox',
142
- name: input_name,
143
- value: @value,
144
- class: 'sr-only peer',
145
- checked: @checked,
146
- required: @required,
147
- disabled: @disabled,
148
- id: input_id
149
- }
150
-
151
- attrs.merge(@options)
152
- end
153
-
154
- def input_name
155
- if @form
156
- @form.field_name(@name)
157
- else
158
- @name
159
- end
160
- end
161
-
162
- def input_id
163
- @options[:id] || "toggle_#{@name}"
164
- end
165
-
166
- def label_classes
167
- TOGGLE_LABEL_TEXT[@size]
168
- end
169
-
170
- def input_tag
171
- if @form
172
- form_checkbox
173
- else
174
- manual_input
175
- end
176
- end
177
-
178
- def form_checkbox
179
- @form.check_box(@name, {
180
- class: 'sr-only peer',
181
- id: input_id,
182
- checked: @checked,
183
- disabled: @disabled,
184
- required: @required,
185
- **@options
186
- }, @value, '0')
187
- end
188
-
189
- def manual_input
190
- attrs = input_attributes.map do |key, value|
191
- if value == true
192
- key.to_s
193
- elsif value == false || value.nil?
194
- nil
195
- else
196
- "#{key}=\"#{value}\""
197
- end
198
- end.compact.join(' ')
199
-
200
- "<input #{attrs} />".html_safe
201
- end
202
-
203
- def render_toggle_with_label
204
- if @label_position == :left
205
- label_left_content
206
- else
207
- label_right_content
208
- end
209
- end
210
-
211
- def label_left_content
212
- content_tag(:label, class: container_classes, for: input_id) do
213
- safe_join([
214
- content_tag(:span, @label, class: label_classes),
215
- render_toggle_switch
216
- ])
217
- end
218
- end
219
-
220
- def label_right_content
221
- content_tag(:label, class: container_classes, for: input_id) do
222
- safe_join([
223
- render_toggle_switch,
224
- content_tag(:span, @label, class: label_classes)
225
- ])
226
- end
227
- end
228
-
229
- def render_toggle_switch
230
- content_tag(:div, class: 'relative') do
231
- safe_join([
232
- input_tag,
233
- content_tag(:div, '', class: track_classes),
234
- content_tag(:div, '', class: thumb_classes)
235
- ])
236
- end
237
- end
238
- end
239
- end
240
- end
241
- end
242
- end
@@ -1,18 +0,0 @@
1
- <%# Template per il link %>
2
- <% if link? %>
3
- <%= link_to @href, **element_attributes do %>
4
- <% if show_icon? %>
5
- <span class="<%= icon_classes %>"><%= render_icon %></span>
6
- <% end %>
7
- <span class="<%= text_classes %>"><%= @label %></span>
8
- <%= content %>
9
- <% end %>
10
- <% else %>
11
- <%= tag.span(**element_attributes) do %>
12
- <% if show_icon? %>
13
- <span class="<%= icon_classes %>"><%= render_icon %></span>
14
- <% end %>
15
- <span class="<%= text_classes %>"><%= @label %></span>
16
- <%= content %>
17
- <% end %>
18
- <% end %>
@@ -1,258 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Link
4
- class Component < ViewComponent::Base
5
- attr_reader :label, :href, :theme, :orientation, :style, :size, :icon, :active, :disabled, :data, :method, :target
6
-
7
- # Classi base sempre presenti
8
- LINK_BASE_CLASSES = "transition-colors duration-200 no-underline"
9
-
10
- # Temi con classi Tailwind dirette - LOGICA CORRETTA
11
- LINK_THEME_CLASSES = {
12
- default: "text-white hover:text-gray-300", # Bianco per sfondi scuri
13
- white: "text-gray-900 hover:text-gray-700", # Nero per sfondi chiari
14
- red: "text-red-500 hover:text-red-600",
15
- rose: "text-rose-500 hover:text-rose-600",
16
- orange: "text-orange-500 hover:text-orange-600",
17
- green: "text-green-500 hover:text-green-600",
18
- blue: "text-blue-500 hover:text-blue-600",
19
- yellow: "text-yellow-600 hover:text-yellow-700",
20
- violet: "text-violet-500 hover:text-violet-600"
21
- }
22
-
23
- # Orientamenti con classi Tailwind dirette
24
- LINK_ORIENTATION_CLASSES = {
25
- horizontal: "inline-flex items-center",
26
- vertical: "flex flex-col items-center"
27
- }
28
-
29
- # Stili con classi Tailwind dirette
30
- LINK_STYLE_CLASSES = {
31
- default: "",
32
- underline: "underline",
33
- bold: "font-bold",
34
- text: "no-underline"
35
- }
36
-
37
- # Dimensioni con classi Tailwind dirette
38
- LINK_SIZE_CLASSES = {
39
- extra_small: "text-xs",
40
- small: "text-sm",
41
- medium: "text-base",
42
- large: "text-lg"
43
- }
44
-
45
- # Stati con classi Tailwind dirette
46
- LINK_STATE_CLASSES = {
47
- normal: "",
48
- active: "font-semibold",
49
- disabled: "opacity-50 cursor-not-allowed pointer-events-none"
50
- }
51
-
52
- # @param label [String] testo del link
53
- # @param href [String] URL di destinazione (nil per semplice testo)
54
- # @param theme [Symbol] tema del colore (:default, :white, etc.)
55
- # @param orientation [Symbol] orientamento (:horizontal, :vertical)
56
- # @param style [Symbol] stile (:default, :underline, :bold, :text)
57
- # @param size [Symbol] dimensione (:extra_small, :small, :medium, :large)
58
- # @param icon [String] icona opzionale
59
- # @param active [Boolean] stato attivo del link
60
- # @param disabled [Boolean] stato disabilitato del link
61
- # @param data [Hash] attributi data
62
- # @param method [Symbol] metodo HTTP (per Turbo)
63
- # @param target [String] target del link
64
- # @param html_options [Hash] opzioni HTML aggiuntive
65
- def initialize(
66
- label:,
67
- href: nil,
68
- theme: :white,
69
- orientation: :horizontal,
70
- style: :default,
71
- size: :medium,
72
- icon: nil,
73
- active: false,
74
- disabled: false,
75
- data: {},
76
- method: nil,
77
- target: nil,
78
- **html_options
79
- )
80
- @label = label
81
- @href = href
82
- @theme = theme.to_sym
83
- @orientation = orientation.to_sym
84
- @style = style.to_sym
85
- @size = size.to_sym
86
- @icon = icon
87
- @active = active
88
- @disabled = disabled
89
- @data = data || {}
90
- @method = method
91
- @target = target
92
- @html_options = html_options
93
-
94
- validate_params
95
- end
96
-
97
- # Determina se è un link attivo/corrente
98
- def active?
99
- @active
100
- end
101
-
102
- # Determina se è disabilitato
103
- def disabled?
104
- @disabled
105
- end
106
-
107
- # Determina se è un link o solo testo
108
- def link?
109
- @href.present? && !@disabled
110
- end
111
-
112
- # Combina tutte le classi CSS
113
- def combined_classes
114
- [
115
- LINK_BASE_CLASSES,
116
- get_theme_class,
117
- get_orientation_class,
118
- get_style_class,
119
- get_size_class,
120
- get_state_class,
121
- @html_options[:class]
122
- ].compact.join(" ")
123
- end
124
-
125
- # Classi per l'icona con dimensionamento proporzionale
126
- def icon_classes
127
- return "" unless @icon.present?
128
-
129
- # Definisce spacing e dimensioni icona basate su size
130
- base_spacing = case @orientation
131
- when :horizontal
132
- "mr-2"
133
- when :vertical
134
- "mb-1"
135
- else
136
- "mr-2"
137
- end
138
-
139
- icon_size = case @size
140
- when :extra_small
141
- "w-3 h-3"
142
- when :small
143
- "w-4 h-4"
144
- when :medium
145
- "w-5 h-5"
146
- when :large
147
- "w-6 h-6"
148
- else
149
- "w-5 h-5"
150
- end
151
-
152
- "#{base_spacing} #{icon_size} inline-block"
153
- end
154
-
155
- # Classi per il testo
156
- def text_classes
157
- "inline-block"
158
- end
159
-
160
- # Restituisce gli attributi per il link/span
161
- def element_attributes
162
- attrs = @html_options.except(:class)
163
- attrs[:class] = combined_classes
164
-
165
- if link?
166
- # Attributi specifici per i link
167
- if @method.present?
168
- attrs[:data] = @data.merge(turbo_method: @method)
169
- elsif @data.present?
170
- attrs[:data] = @data
171
- end
172
-
173
- attrs[:target] = @target if @target.present?
174
- attrs[:aria] ||= {}
175
- attrs[:aria][:current] = "page" if active?
176
- else
177
- # Attributi per span (testo semplice o disabilitato)
178
- attrs[:aria] ||= {}
179
- attrs[:aria][:disabled] = true if disabled?
180
- end
181
-
182
- attrs
183
- end
184
-
185
- # Determina se mostrare l'icona
186
- def show_icon?
187
- @icon.present?
188
- end
189
-
190
- # Renderizza l'icona
191
- def render_icon
192
- return nil unless show_icon?
193
-
194
- if @icon.is_a?(String)
195
- render BetterUi::General::IconComponent.new(name: @icon)
196
- else
197
- @icon # Assumiamo che sia già un componente renderizzato
198
- end
199
- end
200
-
201
- private
202
-
203
- def get_theme_class
204
- LINK_THEME_CLASSES[@theme] || LINK_THEME_CLASSES[:white]
205
- end
206
-
207
- def get_orientation_class
208
- LINK_ORIENTATION_CLASSES[@orientation] || LINK_ORIENTATION_CLASSES[:horizontal]
209
- end
210
-
211
- def get_style_class
212
- LINK_STYLE_CLASSES[@style] || LINK_STYLE_CLASSES[:default]
213
- end
214
-
215
- def get_size_class
216
- LINK_SIZE_CLASSES[@size] || LINK_SIZE_CLASSES[:medium]
217
- end
218
-
219
- def get_state_class
220
- return LINK_STATE_CLASSES[:disabled] if disabled?
221
- return LINK_STATE_CLASSES[:active] if active?
222
- LINK_STATE_CLASSES[:normal]
223
- end
224
-
225
- def validate_params
226
- validate_theme
227
- validate_orientation
228
- validate_style
229
- validate_size
230
- end
231
-
232
- def validate_theme
233
- unless LINK_THEME_CLASSES.keys.include?(@theme)
234
- raise ArgumentError, "Il tema deve essere uno tra: #{LINK_THEME_CLASSES.keys.join(', ')}"
235
- end
236
- end
237
-
238
- def validate_orientation
239
- unless LINK_ORIENTATION_CLASSES.keys.include?(@orientation)
240
- raise ArgumentError, "L'orientamento deve essere uno tra: #{LINK_ORIENTATION_CLASSES.keys.join(', ')}"
241
- end
242
- end
243
-
244
- def validate_style
245
- unless LINK_STYLE_CLASSES.keys.include?(@style)
246
- raise ArgumentError, "Lo stile deve essere uno tra: #{LINK_STYLE_CLASSES.keys.join(', ')}"
247
- end
248
- end
249
-
250
- def validate_size
251
- unless LINK_SIZE_CLASSES.keys.include?(@size)
252
- raise ArgumentError, "La dimensione deve essere una tra: #{LINK_SIZE_CLASSES.keys.join(', ')}"
253
- end
254
- end
255
- end
256
- end
257
- end
258
- end
@@ -1,5 +0,0 @@
1
- <%# Wrapper component con controller Stimulus e slots %>
2
- <div <%= tag.attributes(wrapper_attributes) %>>
3
- <%= trigger %>
4
- <%= modal %>
5
- </div>
@@ -1,47 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Modal
4
- class Component < ViewComponent::Base
5
- renders_one :trigger
6
- renders_one :modal
7
-
8
- attr_reader :close_on_backdrop, :close_on_escape, :lock_scroll, :classes, :html_options
9
-
10
-
11
-
12
- # Inizializzazione del wrapper component
13
- def initialize(
14
- close_on_backdrop: true,
15
- close_on_escape: true,
16
- lock_scroll: true,
17
- classes: nil,
18
- **html_options
19
- )
20
- @close_on_backdrop = close_on_backdrop
21
- @close_on_escape = close_on_escape
22
- @lock_scroll = lock_scroll
23
- @classes = classes
24
- @html_options = html_options
25
- end
26
-
27
- # Combina tutte le classi per il wrapper
28
- def wrapper_classes
29
- [@classes, @html_options[:class]].compact.join(" ")
30
- end
31
-
32
- # Restituisce gli attributi per il wrapper principale (con controller Stimulus)
33
- def wrapper_attributes
34
- {
35
- class: wrapper_classes,
36
- 'data-controller': 'bui-modal',
37
- 'data-bui-modal-close-on-backdrop-value': close_on_backdrop,
38
- 'data-bui-modal-close-on-escape-value': close_on_escape,
39
- 'data-bui-modal-lock-scroll-value': lock_scroll
40
- }.merge(@html_options.except(:class))
41
- end
42
-
43
-
44
- end
45
- end
46
- end
47
- end
@@ -1,52 +0,0 @@
1
- <%# Template per il modal content %>
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
- <%= helpers.bui_button(
10
- label: "Chiudi",
11
- icon: "x-mark",
12
- type: :white,
13
- size: :small,
14
- data: [
15
- { name: 'bui-modal-target', value: 'closeButton' },
16
- { name: 'action', value: 'click->bui-modal#closeButtonClicked' }
17
- ]
18
- ) %>
19
- <% end %>
20
- <% end %>
21
-
22
- <%# Body del modal %>
23
- <div class="p-6">
24
- <%= content %>
25
- </div>
26
- <% end %>
27
- <% end %>
28
- <% else %>
29
- <%= tag.div **container_attributes do %>
30
- <%# Header del modal %>
31
- <%= tag.div **header_attributes do %>
32
- <h3 class="text-lg font-semibold" id="modal-title"><%= @title %></h3>
33
- <% if @closable %>
34
- <%= helpers.bui_button(
35
- label: "Chiudi",
36
- icon: "x-mark",
37
- type: :white,
38
- size: :small,
39
- data: [
40
- { name: 'bui-modal-target', value: 'closeButton' },
41
- { name: 'action', value: 'click->bui-modal#closeButtonClicked' }
42
- ]
43
- ) %>
44
- <% end %>
45
- <% end %>
46
-
47
- <%# Body del modal %>
48
- <div class="p-6">
49
- <%= content %>
50
- </div>
51
- <% end %>
52
- <% end %>