better_ui 0.3.0 → 0.5.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.

Potentially problematic release.


This version of better_ui might be problematic. Click here for more details.

Files changed (231) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +140 -230
  4. data/app/assets/stylesheets/better_ui/_base.scss +9 -0
  5. data/app/assets/stylesheets/better_ui/_components.scss +2 -0
  6. data/app/assets/stylesheets/better_ui/_utilities.scss +14 -0
  7. data/app/assets/stylesheets/better_ui/application.css +32 -0
  8. data/app/assets/stylesheets/better_ui/components/_avatar.scss +200 -0
  9. data/app/assets/stylesheets/better_ui/components/_badge.scss +154 -0
  10. data/app/assets/stylesheets/better_ui/components/_breadcrumb.scss +106 -0
  11. data/app/assets/stylesheets/better_ui/components/_button.scss +105 -0
  12. data/app/assets/stylesheets/better_ui/components/_card.scss +60 -0
  13. data/app/assets/stylesheets/better_ui/components/_heading.scss +81 -0
  14. data/app/assets/stylesheets/better_ui/components/_icon.scss +134 -0
  15. data/app/assets/stylesheets/better_ui/components/_index.scss +17 -0
  16. data/app/assets/stylesheets/better_ui/components/_link.scss +100 -0
  17. data/app/assets/stylesheets/better_ui/components/_panel.scss +104 -0
  18. data/app/assets/stylesheets/better_ui/components/_spinner.scss +129 -0
  19. data/app/assets/stylesheets/better_ui/components/_table.scss +156 -0
  20. data/app/assets/stylesheets/better_ui/components/_variables.scss +1 -0
  21. data/app/assets/stylesheets/better_ui.scss +4 -0
  22. data/app/components/better_ui/application/alert_component.html.erb +27 -0
  23. data/app/components/better_ui/application/alert_component.rb +202 -0
  24. data/app/components/better_ui/application/card_component.html.erb +24 -0
  25. data/app/components/better_ui/application/card_component.rb +53 -0
  26. data/app/components/better_ui/application/card_container_component.html.erb +8 -0
  27. data/app/components/better_ui/application/card_container_component.rb +14 -0
  28. data/app/components/better_ui/application/header_component.html.erb +88 -0
  29. data/app/components/better_ui/application/header_component.rb +188 -0
  30. data/app/components/better_ui/application/navbar_component.html.erb +294 -0
  31. data/app/components/better_ui/application/navbar_component.rb +249 -0
  32. data/app/components/better_ui/application/sidebar_component.html.erb +207 -0
  33. data/app/components/better_ui/application/sidebar_component.rb +318 -0
  34. data/app/components/better_ui/application/toast_component.html.erb +35 -0
  35. data/app/components/better_ui/application/toast_component.rb +223 -0
  36. data/app/components/better_ui/general/avatar_component.html.erb +19 -0
  37. data/app/components/better_ui/general/avatar_component.rb +171 -0
  38. data/app/components/better_ui/general/{badge/component.html.erb → badge_component.html.erb} +2 -6
  39. data/app/components/better_ui/general/badge_component.rb +135 -0
  40. data/app/components/better_ui/general/{breadcrumb/component.html.erb → breadcrumb_component.html.erb} +4 -4
  41. data/app/components/better_ui/general/breadcrumb_component.rb +130 -0
  42. data/app/components/better_ui/general/{button/component.html.erb → button_component.html.erb} +7 -7
  43. data/app/components/better_ui/general/button_component.rb +160 -0
  44. data/app/components/better_ui/general/heading_component.html.erb +1 -0
  45. data/app/components/better_ui/general/heading_component.rb +49 -0
  46. data/app/components/better_ui/general/icon_component.html.erb +2 -0
  47. data/app/components/better_ui/general/icon_component.rb +77 -0
  48. data/app/components/better_ui/general/link_component.html.erb +17 -0
  49. data/app/components/better_ui/general/link_component.rb +132 -0
  50. data/app/components/better_ui/general/panel_component.html.erb +27 -0
  51. data/app/components/better_ui/general/panel_component.rb +92 -0
  52. data/app/components/better_ui/general/spinner_component.html.erb +15 -0
  53. data/app/components/better_ui/general/spinner_component.rb +79 -0
  54. data/app/components/better_ui/general/table_component.html.erb +73 -0
  55. data/app/components/better_ui/general/table_component.rb +143 -0
  56. data/app/controllers/better_ui/application_controller.rb +1 -0
  57. data/app/helpers/better_ui/general/components/avatar_helper.rb +17 -0
  58. data/app/helpers/better_ui/general/components/badge_helper.rb +17 -0
  59. data/app/helpers/better_ui/general/components/breadcrumb_helper.rb +17 -0
  60. data/app/helpers/better_ui/general/components/button_helper.rb +17 -0
  61. data/app/helpers/better_ui/general/components/heading_helper.rb +17 -0
  62. data/app/helpers/better_ui/general/components/icon_helper.rb +17 -0
  63. data/app/helpers/better_ui/general/components/link_helper.rb +17 -0
  64. data/app/helpers/better_ui/general/components/panel_helper.rb +16 -0
  65. data/app/helpers/better_ui/general/components/spinner_helper.rb +17 -0
  66. data/app/helpers/better_ui/general/components/table_helper.rb +17 -0
  67. data/app/helpers/better_ui/general_helper.rb +15 -0
  68. data/app/helpers/better_ui_helper.rb +12 -0
  69. data/app/views/components/better_ui/general/table/_custom_body_row.html.erb +17 -0
  70. data/app/views/components/better_ui/general/table/_custom_footer_rows.html.erb +17 -0
  71. data/app/views/components/better_ui/general/table/_custom_header_rows.html.erb +12 -0
  72. data/app/views/layouts/component_preview.html.erb +32 -0
  73. data/config/initializers/lookbook.rb +12 -12
  74. data/config/routes.rb +2 -0
  75. data/lib/better_ui/engine.rb +92 -5
  76. data/lib/better_ui/version.rb +1 -1
  77. data/lib/better_ui.rb +32 -4
  78. data/lib/generators/better_ui/install_generator.rb +103 -0
  79. data/lib/generators/better_ui/stylesheet_generator.rb +159 -0
  80. data/lib/generators/better_ui/templates/README +125 -0
  81. data/lib/generators/better_ui/templates/components/_avatar.scss +200 -0
  82. data/lib/generators/better_ui/templates/components/_badge.scss +154 -0
  83. data/lib/generators/better_ui/templates/components/_breadcrumb.scss +106 -0
  84. data/lib/generators/better_ui/templates/components/_button.scss +109 -0
  85. data/lib/generators/better_ui/templates/components/_card.scss +60 -0
  86. data/lib/generators/better_ui/templates/components/_heading.scss +81 -0
  87. data/lib/generators/better_ui/templates/components/_icon.scss +134 -0
  88. data/lib/generators/better_ui/templates/components/_index.scss +17 -0
  89. data/lib/generators/better_ui/templates/components/_link.scss +100 -0
  90. data/lib/generators/better_ui/templates/components/_panel.scss +104 -0
  91. data/lib/generators/better_ui/templates/components/_spinner.scss +129 -0
  92. data/lib/generators/better_ui/templates/components/_table.scss +156 -0
  93. data/lib/generators/better_ui/templates/components/_variables.scss +0 -0
  94. data/lib/generators/better_ui/templates/components_stylesheet.scss +35 -0
  95. data/lib/generators/better_ui/templates/index.scss +18 -0
  96. data/lib/generators/better_ui/templates/initializer.rb +41 -0
  97. metadata +178 -147
  98. data/app/components/better_ui/application/card/component.html.erb +0 -20
  99. data/app/components/better_ui/application/card/component.rb +0 -214
  100. data/app/components/better_ui/application/main/component.html.erb +0 -9
  101. data/app/components/better_ui/application/main/component.rb +0 -123
  102. data/app/components/better_ui/application/navbar/component.html.erb +0 -92
  103. data/app/components/better_ui/application/navbar/component.rb +0 -136
  104. data/app/components/better_ui/application/sidebar/component.html.erb +0 -227
  105. data/app/components/better_ui/application/sidebar/component.rb +0 -130
  106. data/app/components/better_ui/general/accordion/component.html.erb +0 -5
  107. data/app/components/better_ui/general/accordion/component.rb +0 -92
  108. data/app/components/better_ui/general/accordion/item_component.html.erb +0 -12
  109. data/app/components/better_ui/general/accordion/item_component.rb +0 -176
  110. data/app/components/better_ui/general/alert/component.html.erb +0 -32
  111. data/app/components/better_ui/general/alert/component.rb +0 -242
  112. data/app/components/better_ui/general/avatar/component.html.erb +0 -20
  113. data/app/components/better_ui/general/avatar/component.rb +0 -301
  114. data/app/components/better_ui/general/badge/component.rb +0 -248
  115. data/app/components/better_ui/general/breadcrumb/component.rb +0 -187
  116. data/app/components/better_ui/general/button/component.rb +0 -214
  117. data/app/components/better_ui/general/divider/component.html.erb +0 -10
  118. data/app/components/better_ui/general/divider/component.rb +0 -226
  119. data/app/components/better_ui/general/dropdown/component.html.erb +0 -25
  120. data/app/components/better_ui/general/dropdown/component.rb +0 -170
  121. data/app/components/better_ui/general/dropdown/divider_component.html.erb +0 -1
  122. data/app/components/better_ui/general/dropdown/divider_component.rb +0 -41
  123. data/app/components/better_ui/general/dropdown/item_component.html.erb +0 -6
  124. data/app/components/better_ui/general/dropdown/item_component.rb +0 -119
  125. data/app/components/better_ui/general/field/component.html.erb +0 -27
  126. data/app/components/better_ui/general/field/component.rb +0 -37
  127. data/app/components/better_ui/general/heading/component.html.erb +0 -22
  128. data/app/components/better_ui/general/heading/component.rb +0 -257
  129. data/app/components/better_ui/general/icon/component.html.erb +0 -7
  130. data/app/components/better_ui/general/icon/component.rb +0 -239
  131. data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
  132. data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
  133. data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
  134. data/app/components/better_ui/general/input/datetime/component.rb +0 -223
  135. data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
  136. data/app/components/better_ui/general/input/radio/component.rb +0 -230
  137. data/app/components/better_ui/general/input/select/component.html.erb +0 -16
  138. data/app/components/better_ui/general/input/select/component.rb +0 -184
  139. data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
  140. data/app/components/better_ui/general/input/select/select_component.rb +0 -37
  141. data/app/components/better_ui/general/input/text/component.html.erb +0 -5
  142. data/app/components/better_ui/general/input/text/component.rb +0 -171
  143. data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
  144. data/app/components/better_ui/general/input/textarea/component.rb +0 -166
  145. data/app/components/better_ui/general/link/component.html.erb +0 -18
  146. data/app/components/better_ui/general/link/component.rb +0 -258
  147. data/app/components/better_ui/general/modal/component.html.erb +0 -5
  148. data/app/components/better_ui/general/modal/component.rb +0 -47
  149. data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
  150. data/app/components/better_ui/general/modal/modal_component.rb +0 -160
  151. data/app/components/better_ui/general/pagination/component.html.erb +0 -85
  152. data/app/components/better_ui/general/pagination/component.rb +0 -216
  153. data/app/components/better_ui/general/panel/component.html.erb +0 -28
  154. data/app/components/better_ui/general/panel/component.rb +0 -249
  155. data/app/components/better_ui/general/progress/component.html.erb +0 -11
  156. data/app/components/better_ui/general/progress/component.rb +0 -160
  157. data/app/components/better_ui/general/spinner/component.html.erb +0 -35
  158. data/app/components/better_ui/general/spinner/component.rb +0 -93
  159. data/app/components/better_ui/general/table/component.html.erb +0 -5
  160. data/app/components/better_ui/general/table/component.rb +0 -217
  161. data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
  162. data/app/components/better_ui/general/table/tbody_component.rb +0 -30
  163. data/app/components/better_ui/general/table/td_component.html.erb +0 -3
  164. data/app/components/better_ui/general/table/td_component.rb +0 -44
  165. data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
  166. data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
  167. data/app/components/better_ui/general/table/th_component.html.erb +0 -6
  168. data/app/components/better_ui/general/table/th_component.rb +0 -51
  169. data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
  170. data/app/components/better_ui/general/table/thead_component.rb +0 -28
  171. data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
  172. data/app/components/better_ui/general/table/tr_component.rb +0 -30
  173. data/app/components/better_ui/general/tabs/component.html.erb +0 -11
  174. data/app/components/better_ui/general/tabs/component.rb +0 -120
  175. data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
  176. data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
  177. data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
  178. data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
  179. data/app/components/better_ui/general/tag/component.html.erb +0 -3
  180. data/app/components/better_ui/general/tag/component.rb +0 -104
  181. data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
  182. data/app/components/better_ui/general/tooltip/component.rb +0 -239
  183. data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
  184. data/app/helpers/better_ui/application/components/card.rb +0 -11
  185. data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
  186. data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
  187. data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
  188. data/app/helpers/better_ui/application_helper.rb +0 -55
  189. data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
  190. data/app/helpers/better_ui/general/components/accordion.rb +0 -11
  191. data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
  192. data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
  193. data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
  194. data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
  195. data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
  196. data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
  197. data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
  198. data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
  199. data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -79
  200. data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -62
  201. data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
  202. data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
  203. data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
  204. data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
  205. data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
  206. data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
  207. data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
  208. data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -70
  209. data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
  210. data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
  211. data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
  212. data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
  213. data/app/helpers/better_ui/general/components/modal.rb +0 -11
  214. data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
  215. data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
  216. data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
  217. data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
  218. data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
  219. data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
  220. data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
  221. data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
  222. data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
  223. data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
  224. data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
  225. data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
  226. data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
  227. data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
  228. data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
  229. data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
  230. data/app/views/layouts/better_ui/application.html.erb +0 -17
  231. data/lib/better_ui/railtie.rb +0 -20
@@ -0,0 +1,223 @@
1
+ module BetterUi
2
+ module Application
3
+ class ToastComponent < ViewComponent::Base
4
+ attr_reader :title, :message, :variant, :icon, :dismissible, :classes, :data, :position, :duration, :auto_hide, :rounded
5
+
6
+ # Varianti di colore disponibili
7
+ VARIANTS = {
8
+ default: {
9
+ bg: "bg-black",
10
+ border: "border-gray-900",
11
+ title: "text-white",
12
+ text: "text-white",
13
+ icon: "text-white",
14
+ close: "text-white hover:bg-gray-800"
15
+ },
16
+ white: {
17
+ bg: "bg-white",
18
+ border: "border-gray-200",
19
+ title: "text-black",
20
+ text: "text-black",
21
+ icon: "text-black",
22
+ close: "text-black hover:bg-gray-100"
23
+ },
24
+ red: {
25
+ bg: "bg-red-500",
26
+ border: "border-red-600",
27
+ title: "text-white",
28
+ text: "text-white",
29
+ icon: "text-white",
30
+ close: "text-white hover:bg-red-600"
31
+ },
32
+ rose: {
33
+ bg: "bg-rose-500",
34
+ border: "border-rose-600",
35
+ title: "text-white",
36
+ text: "text-white",
37
+ icon: "text-white",
38
+ close: "text-white hover:bg-rose-600"
39
+ },
40
+ orange: {
41
+ bg: "bg-orange-500",
42
+ border: "border-orange-600",
43
+ title: "text-white",
44
+ text: "text-white",
45
+ icon: "text-white",
46
+ close: "text-white hover:bg-orange-600"
47
+ },
48
+ green: {
49
+ bg: "bg-green-500",
50
+ border: "border-green-600",
51
+ title: "text-white",
52
+ text: "text-white",
53
+ icon: "text-white",
54
+ close: "text-white hover:bg-green-600"
55
+ },
56
+ blue: {
57
+ bg: "bg-blue-500",
58
+ border: "border-blue-600",
59
+ title: "text-white",
60
+ text: "text-white",
61
+ icon: "text-white",
62
+ close: "text-white hover:bg-blue-600"
63
+ },
64
+ yellow: {
65
+ bg: "bg-yellow-500",
66
+ border: "border-yellow-600",
67
+ title: "text-black",
68
+ text: "text-black",
69
+ icon: "text-black",
70
+ close: "text-black hover:bg-yellow-600"
71
+ },
72
+ violet: {
73
+ bg: "bg-violet-500",
74
+ border: "border-violet-600",
75
+ title: "text-white",
76
+ text: "text-white",
77
+ icon: "text-white",
78
+ close: "text-white hover:bg-violet-600"
79
+ }
80
+ }
81
+
82
+ # Icone predefinite per ciascuna variante
83
+ DEFAULT_ICONS = {
84
+ default: "bell",
85
+ white: "info-circle",
86
+ red: "exclamation-circle",
87
+ rose: "exclamation-circle",
88
+ orange: "bell",
89
+ green: "check-circle",
90
+ blue: "info-circle",
91
+ yellow: "exclamation-triangle",
92
+ violet: "shield-exclamation"
93
+ }
94
+
95
+ # Posizioni possibili per i toast
96
+ POSITIONS = {
97
+ "top-right": "top-right",
98
+ "top-left": "top-left",
99
+ "bottom-right": "bottom-right",
100
+ "bottom-left": "bottom-left",
101
+ "top-center": "top-center",
102
+ "bottom-center": "bottom-center"
103
+ }
104
+
105
+ # Inizializzazione del componente
106
+ def initialize(
107
+ title: nil,
108
+ message: nil,
109
+ variant: :default,
110
+ icon: nil,
111
+ dismissible: true,
112
+ classes: nil,
113
+ data: {},
114
+ position: :"top-right",
115
+ duration: 5000,
116
+ auto_hide: true,
117
+ rounded: :sm
118
+ )
119
+ @title = title
120
+ @message = message
121
+ @variant = variant.to_sym
122
+ @icon = icon
123
+ @dismissible = dismissible
124
+ @classes = classes
125
+ @data = data || {}
126
+ @position = position.to_sym
127
+ @duration = duration
128
+ @auto_hide = auto_hide
129
+ @rounded = rounded.to_sym
130
+
131
+ # Aggiungiamo dati per il comportamento del toast
132
+ @data[:controller] = "toast" if @data[:controller].blank?
133
+ @data[:toast_duration_value] = @duration if @auto_hide
134
+ @data[:toast_auto_hide_value] = @auto_hide.to_s
135
+ @data[:toast_position_value] = @position.to_s
136
+ end
137
+
138
+ # Genera l'icona in base alla variante se non specificata
139
+ def effective_icon
140
+ return @icon if @icon.present?
141
+ DEFAULT_ICONS[@variant] || DEFAULT_ICONS[:default]
142
+ end
143
+
144
+ # Genera le classi per il container
145
+ def container_classes
146
+ styles = VARIANTS.fetch(@variant, VARIANTS[:default])
147
+ position_class = POSITIONS.fetch(@position, POSITIONS[:"top-right"])
148
+
149
+ [
150
+ "fixed z-50 p-4 border shadow-lg",
151
+ get_border_radius_class,
152
+ "transform transition-transform duration-300",
153
+ "data-toast-enter-from-class='translate-y-2 opacity-0'",
154
+ "data-toast-enter-to-class='translate-y-0 opacity-100'",
155
+ "data-toast-leave-from-class='translate-y-0 opacity-100'",
156
+ "data-toast-leave-to-class='translate-y-2 opacity-0'",
157
+ styles[:bg],
158
+ styles[:border],
159
+ position_class,
160
+ "min-w-[20rem] max-w-sm",
161
+ "flex items-start",
162
+ @classes
163
+ ].compact.join(" ")
164
+ end
165
+
166
+ # Genera il border-radius
167
+ def get_border_radius_class
168
+ ThemeHelper::BORDER_RADIUS[@rounded] || ThemeHelper::BORDER_RADIUS[:sm]
169
+ end
170
+
171
+ # Genera le classi per il titolo
172
+ def title_classes
173
+ styles = VARIANTS.fetch(@variant, VARIANTS[:default])
174
+
175
+ [
176
+ "font-medium",
177
+ styles[:title]
178
+ ].compact.join(" ")
179
+ end
180
+
181
+ # Genera le classi per il messaggio
182
+ def message_classes
183
+ styles = VARIANTS.fetch(@variant, VARIANTS[:default])
184
+
185
+ [
186
+ "mt-1",
187
+ styles[:text]
188
+ ].compact.join(" ")
189
+ end
190
+
191
+ # Genera le classi per l'icona
192
+ def icon_classes
193
+ styles = VARIANTS.fetch(@variant, VARIANTS[:default])
194
+
195
+ [
196
+ "flex-shrink-0",
197
+ "mr-3 mt-0.5",
198
+ styles[:icon]
199
+ ].compact.join(" ")
200
+ end
201
+
202
+ # Genera le classi per il pulsante di chiusura
203
+ def close_button_classes
204
+ styles = VARIANTS.fetch(@variant, VARIANTS[:default])
205
+
206
+ [
207
+ "ml-auto -mr-1.5 -mt-1.5 inline-flex h-8 w-8 rounded-lg p-1.5 focus:ring-2 focus:ring-gray-400",
208
+ styles[:close]
209
+ ].compact.join(" ")
210
+ end
211
+
212
+ # Genera le classi per il contenuto
213
+ def content_classes
214
+ "flex-1"
215
+ end
216
+
217
+ # Verifica se il componente deve essere reso
218
+ def render?
219
+ @title.present? || @message.present? || content.present?
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,19 @@
1
+ <div <%= avatar_attributes.to_s.html_safe %>>
2
+ <% if show_image? %>
3
+ <img
4
+ src="<%= @src %>"
5
+ alt="<%= @name || 'Avatar' %>"
6
+ class="bui-avatar__image"
7
+ width="<%= pixel_size %>"
8
+ height="<%= pixel_size %>"
9
+ >
10
+ <% else %>
11
+ <div class="bui-avatar__placeholder">
12
+ <%= initials %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <% if show_status? %>
17
+ <span class="<%= status_indicator_classes %>"></span>
18
+ <% end %>
19
+ </div>
@@ -0,0 +1,171 @@
1
+ module BetterUi
2
+ module General
3
+ class AvatarComponent < ViewComponent::Base
4
+ attr_reader :name, :src, :size, :shape, :status, :status_position, :type, :classes, :id
5
+
6
+ # Temi di colore disponibili
7
+ AVATAR_THEME = {
8
+ default: "bui-avatar--default",
9
+ white: "bui-avatar--white",
10
+ red: "bui-avatar--red",
11
+ rose: "bui-avatar--rose",
12
+ orange: "bui-avatar--orange",
13
+ green: "bui-avatar--green",
14
+ blue: "bui-avatar--blue",
15
+ yellow: "bui-avatar--yellow",
16
+ violet: "bui-avatar--violet",
17
+ gray: "bui-avatar--gray"
18
+ }
19
+
20
+ # Dimensioni disponibili
21
+ AVATAR_SIZES = {
22
+ xxsmall: "bui-avatar--xxsmall",
23
+ xsmall: "bui-avatar--xsmall",
24
+ small: "bui-avatar--small",
25
+ medium: "bui-avatar--medium",
26
+ large: "bui-avatar--large",
27
+ xlarge: "bui-avatar--xlarge",
28
+ xxlarge: "bui-avatar--xxlarge"
29
+ }
30
+
31
+ # Forme disponibili
32
+ AVATAR_SHAPES = {
33
+ circle: "bui-avatar--circle",
34
+ square: "bui-avatar--square",
35
+ rounded: "bui-avatar--rounded"
36
+ }
37
+
38
+ # Stati online disponibili
39
+ AVATAR_STATUS = {
40
+ online: "bui-avatar__status--online",
41
+ offline: "bui-avatar__status--offline",
42
+ busy: "bui-avatar__status--busy",
43
+ away: "bui-avatar__status--away"
44
+ }
45
+
46
+ # Posizioni dell'indicatore di stato
47
+ AVATAR_STATUS_POSITION = {
48
+ bottom_right: "bui-avatar__status--bottom-right",
49
+ bottom_left: "bui-avatar__status--bottom-left",
50
+ top_right: "bui-avatar__status--top-right",
51
+ top_left: "bui-avatar__status--top-left"
52
+ }
53
+
54
+ def initialize(
55
+ name: nil,
56
+ src: nil,
57
+ size: :medium,
58
+ shape: :circle,
59
+ status: nil,
60
+ status_position: :bottom_right,
61
+ type: :default,
62
+ classes: nil,
63
+ id: nil
64
+ )
65
+ @name = name
66
+ @src = src
67
+ @size = size.to_sym
68
+ @shape = shape.to_sym
69
+ @status = status&.to_sym
70
+ @status_position = status_position.to_sym
71
+ @type = type.to_sym
72
+ @classes = classes
73
+ @id = id
74
+ end
75
+
76
+ # Combina tutte le classi
77
+ def combined_classes
78
+ [
79
+ "bui-avatar", # Classe base per tutti gli avatar
80
+ get_avatar_theme_class,
81
+ get_avatar_size_class,
82
+ get_avatar_shape_class,
83
+ @classes
84
+ ].compact.join(" ")
85
+ end
86
+
87
+ def get_avatar_theme_class
88
+ AVATAR_THEME[@type] || AVATAR_THEME[:default]
89
+ end
90
+
91
+ def get_avatar_size_class
92
+ AVATAR_SIZES[@size] || AVATAR_SIZES[:medium]
93
+ end
94
+
95
+ def get_avatar_shape_class
96
+ AVATAR_SHAPES[@shape] || AVATAR_SHAPES[:circle]
97
+ end
98
+
99
+ def get_avatar_status_class
100
+ AVATAR_STATUS[@status] || ""
101
+ end
102
+
103
+ def get_avatar_status_position_class
104
+ AVATAR_STATUS_POSITION[@status_position] || AVATAR_STATUS_POSITION[:bottom_right]
105
+ end
106
+
107
+ # Restituisce gli attributi per l'avatar
108
+ def avatar_attributes
109
+ attrs = {
110
+ class: combined_classes,
111
+ id: @id
112
+ }
113
+
114
+ attrs
115
+ end
116
+
117
+ # Restituisce le classi per l'indicatore di stato
118
+ def status_indicator_classes
119
+ [
120
+ "bui-avatar__status",
121
+ get_avatar_status_class,
122
+ get_avatar_status_position_class
123
+ ].compact.join(" ")
124
+ end
125
+
126
+ # Determina se mostrare l'indicatore di stato
127
+ def show_status?
128
+ @status.present? && AVATAR_STATUS.key?(@status)
129
+ end
130
+
131
+ # Ottiene le iniziali dal nome
132
+ def initials
133
+ return "" unless @name.present?
134
+
135
+ words = @name.strip.split(/\s+/)
136
+ if words.size >= 2
137
+ "#{words[0][0]}#{words[1][0]}".upcase
138
+ else
139
+ @name[0..1].upcase
140
+ end
141
+ end
142
+
143
+ # Determina se mostrare l'immagine
144
+ def show_image?
145
+ @src.present?
146
+ end
147
+
148
+ # Ottiene le dimensioni dell'avatar in pixel
149
+ def pixel_size
150
+ case @size
151
+ when :xxsmall
152
+ 20
153
+ when :xsmall
154
+ 24
155
+ when :small
156
+ 32
157
+ when :medium
158
+ 40
159
+ when :large
160
+ 48
161
+ when :xlarge
162
+ 64
163
+ when :xxlarge
164
+ 96
165
+ else
166
+ 40
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -1,8 +1,4 @@
1
- <span <%= tag.attributes(badge_attributes) %>>
2
- <% if @variant == :dot %>
3
- <span class="<%= dot_classes %>"></span>
4
- <% end %>
5
-
1
+ <span <%= badge_attributes.to_s.html_safe %>>
6
2
  <% if @icon && @icon_position == :left %>
7
3
  <span class="<%= icon_classes %>">
8
4
  <%= render_icon(@icon) %>
@@ -20,4 +16,4 @@
20
16
  <% end %>
21
17
 
22
18
  <%= content %>
23
- </span>
19
+ </span>
@@ -0,0 +1,135 @@
1
+ module BetterUi
2
+ module General
3
+ class BadgeComponent < ViewComponent::Base
4
+ attr_reader :label, :type, :size, :icon, :icon_position, :rounded, :notification, :outline, :classes, :id
5
+
6
+ # Temi di colore disponibili
7
+ BADGE_THEME = {
8
+ default: "bui-badge--default",
9
+ white: "bui-badge--white",
10
+ red: "bui-badge--red",
11
+ rose: "bui-badge--rose",
12
+ orange: "bui-badge--orange",
13
+ green: "bui-badge--green",
14
+ blue: "bui-badge--blue",
15
+ yellow: "bui-badge--yellow",
16
+ violet: "bui-badge--violet",
17
+ gray: "bui-badge--gray"
18
+ }
19
+
20
+ # Dimensioni disponibili
21
+ BADGE_SIZES = {
22
+ small: "bui-badge--small",
23
+ medium: "bui-badge--medium",
24
+ large: "bui-badge--large"
25
+ }
26
+
27
+ # Border radius disponibili
28
+ BADGE_RADIUS = {
29
+ none: "bui-badge--square",
30
+ small: "bui-badge--square",
31
+ medium: "bui-badge--square",
32
+ large: "bui-badge--square",
33
+ full: "bui-badge--pill"
34
+ }
35
+
36
+ # Stati e varianti
37
+ BADGE_VARIANTS = {
38
+ outline: "bui-badge--outline",
39
+ notification: "bui-badge--notification"
40
+ }
41
+
42
+ # Inizializzazione del componente
43
+ def initialize(
44
+ label: nil,
45
+ type: :default,
46
+ size: :medium,
47
+ icon: nil,
48
+ icon_position: :left,
49
+ rounded: :medium,
50
+ notification: false,
51
+ outline: false,
52
+ classes: nil,
53
+ id: nil
54
+ )
55
+ @label = label
56
+ @type = type.to_sym
57
+ @size = size.to_sym
58
+ @icon = icon
59
+ @icon_position = icon_position.to_sym
60
+ @rounded = rounded.to_sym
61
+ @notification = notification
62
+ @outline = outline
63
+ @classes = classes
64
+ @id = id
65
+ end
66
+
67
+ # Combina tutte le classi
68
+ def combined_classes
69
+ [
70
+ "bui-badge", # Classe base per tutti i badge
71
+ get_badge_type_class,
72
+ get_badge_size_class,
73
+ get_border_radius_class,
74
+ @outline ? BADGE_VARIANTS[:outline] : "",
75
+ @notification ? BADGE_VARIANTS[:notification] : "",
76
+ @classes
77
+ ].compact.join(" ")
78
+ end
79
+
80
+ def get_badge_type_class
81
+ BADGE_THEME[@type] || BADGE_THEME[:default]
82
+ end
83
+
84
+ def get_badge_size_class
85
+ BADGE_SIZES[@size] || BADGE_SIZES[:medium]
86
+ end
87
+
88
+ def get_border_radius_class
89
+ BADGE_RADIUS[@rounded] || BADGE_RADIUS[:medium]
90
+ end
91
+
92
+ # Restituisce gli attributi per il badge
93
+ def badge_attributes
94
+ attrs = {
95
+ class: combined_classes,
96
+ id: @id
97
+ }
98
+
99
+ attrs
100
+ end
101
+
102
+ def icon_classes
103
+ if @icon_position == :left
104
+ "bui-badge__icon bui-badge__icon--left"
105
+ else
106
+ "bui-badge__icon bui-badge__icon--right"
107
+ end
108
+ end
109
+
110
+ def text_classes
111
+ "bui-badge__text"
112
+ end
113
+
114
+ # Helper per renderizzare le icone
115
+ def render_icon(icon_name)
116
+ # Mappa le dimensioni del badge alle dimensioni dell'icona
117
+ icon_size = case @size
118
+ when :large
119
+ :small
120
+ when :small
121
+ :tiny
122
+ else
123
+ :tiny
124
+ end
125
+
126
+ # Utilizziamo il componente Icon
127
+ render BetterUi::General::IconComponent.new(
128
+ name: icon_name,
129
+ size: icon_size,
130
+ fixed_width: true
131
+ )
132
+ end
133
+ end
134
+ end
135
+ end
@@ -1,7 +1,7 @@
1
- <nav <%= tag.attributes(breadcrumb_attributes) %>>
2
- <ol class="<%= BREADCRUMB_LIST_CLASSES %>">
1
+ <nav aria-label="Breadcrumb" class="<%= container_classes %>">
2
+ <ol class="bui-breadcrumb__list">
3
3
  <% @items.each_with_index do |item, index| %>
4
- <li class="<%= BREADCRUMB_ITEM_CLASSES %>">
4
+ <li class="bui-breadcrumb__item">
5
5
  <%= render link_for_item(item, active: last_item?(index)) %>
6
6
 
7
7
  <% unless last_item?(index) %>
@@ -12,4 +12,4 @@
12
12
  </li>
13
13
  <% end %>
14
14
  </ol>
15
- </nav>
15
+ </nav>
@@ -0,0 +1,130 @@
1
+ module BetterUi
2
+ module General
3
+ class BreadcrumbComponent < ViewComponent::Base
4
+ attr_reader :items, :separator, :size, :theme, :classes
5
+
6
+ # Temi di colore disponibili
7
+ BREADCRUMB_THEME = {
8
+ default: {
9
+ container: "bui-breadcrumb--default",
10
+ separator: "bui-breadcrumb__separator--default"
11
+ },
12
+ white: {
13
+ container: "bui-breadcrumb--white",
14
+ separator: "bui-breadcrumb__separator--white"
15
+ },
16
+ red: {
17
+ container: "bui-breadcrumb--red",
18
+ separator: "bui-breadcrumb__separator--red"
19
+ },
20
+ rose: {
21
+ container: "bui-breadcrumb--rose",
22
+ separator: "bui-breadcrumb__separator--rose"
23
+ },
24
+ orange: {
25
+ container: "bui-breadcrumb--orange",
26
+ separator: "bui-breadcrumb__separator--orange"
27
+ },
28
+ green: {
29
+ container: "bui-breadcrumb--green",
30
+ separator: "bui-breadcrumb__separator--green"
31
+ },
32
+ blue: {
33
+ container: "bui-breadcrumb--blue",
34
+ separator: "bui-breadcrumb__separator--blue"
35
+ },
36
+ yellow: {
37
+ container: "bui-breadcrumb--yellow",
38
+ separator: "bui-breadcrumb__separator--yellow"
39
+ },
40
+ violet: {
41
+ container: "bui-breadcrumb--violet",
42
+ separator: "bui-breadcrumb__separator--violet"
43
+ }
44
+ }
45
+
46
+ # Dimensioni disponibili
47
+ BREADCRUMB_SIZES = {
48
+ small: "bui-breadcrumb--small",
49
+ medium: "bui-breadcrumb--medium",
50
+ large: "bui-breadcrumb--large"
51
+ }
52
+
53
+ # Separatori predefiniti
54
+ BREADCRUMB_SEPARATORS = {
55
+ slash: "/",
56
+ chevron: "›",
57
+ arrow: "→",
58
+ dot: "•",
59
+ pipe: "|"
60
+ }
61
+
62
+ # Inizializzazione del componente
63
+ def initialize(
64
+ items: [],
65
+ separator: :chevron,
66
+ size: :medium,
67
+ theme: :default,
68
+ classes: nil
69
+ )
70
+ @items = items || []
71
+ @separator = separator.to_sym
72
+ @size = size.to_sym
73
+ @theme = theme.to_sym
74
+ @classes = classes
75
+ end
76
+
77
+ # Restituisce il separatore come stringa
78
+ def separator_text
79
+ if BREADCRUMB_SEPARATORS.key?(@separator)
80
+ BREADCRUMB_SEPARATORS[@separator]
81
+ else
82
+ @separator.to_s
83
+ end
84
+ end
85
+
86
+ # Genera le classi per il container
87
+ def container_classes
88
+ [
89
+ "bui-breadcrumb",
90
+ BREADCRUMB_SIZES.fetch(@size, BREADCRUMB_SIZES[:medium]),
91
+ BREADCRUMB_THEME.fetch(@theme, BREADCRUMB_THEME[:default])[:container],
92
+ @classes
93
+ ].compact.join(" ")
94
+ end
95
+
96
+ # Genera le classi per il separatore
97
+ def separator_classes
98
+ [
99
+ "bui-breadcrumb__separator",
100
+ BREADCRUMB_THEME.fetch(@theme, BREADCRUMB_THEME[:default])[:separator]
101
+ ].compact.join(" ")
102
+ end
103
+
104
+ # Verifica se un item è l'ultimo (attivo)
105
+ def last_item?(index)
106
+ index == @items.length - 1
107
+ end
108
+
109
+ # Crea un componente link per l'item
110
+ def link_for_item(item, active: false)
111
+ label = item.is_a?(Hash) ? item[:label] : item.to_s
112
+ href = item.is_a?(Hash) ? item[:url] : nil
113
+ icon = item.is_a?(Hash) ? item[:icon] : nil
114
+
115
+ BetterUi::General::LinkComponent.new(
116
+ label: label,
117
+ href: href,
118
+ theme: @theme,
119
+ icon: icon,
120
+ active: active
121
+ )
122
+ end
123
+
124
+ # Verifica se rendere il componente
125
+ def render?
126
+ @items.present? && @items.length > 0
127
+ end
128
+ end
129
+ end
130
+ end