better_ui 0.3.0 → 0.4.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.
Potentially problematic release.
This version of better_ui might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +174 -216
- data/app/assets/javascripts/better_ui/controllers/navbar_controller.js +138 -0
- data/app/assets/javascripts/better_ui/controllers/sidebar_controller.js +211 -0
- data/app/assets/javascripts/better_ui/controllers/toast_controller.js +161 -0
- data/app/assets/javascripts/better_ui/index.js +159 -0
- data/app/assets/javascripts/better_ui/toast_manager.js +77 -0
- data/app/assets/stylesheets/better_ui/application.css +30 -0
- data/app/components/better_ui/application/alert_component.html.erb +27 -0
- data/app/components/better_ui/application/alert_component.rb +196 -0
- data/app/components/better_ui/application/header_component.html.erb +88 -0
- data/app/components/better_ui/application/header_component.rb +188 -0
- data/app/components/better_ui/application/navbar_component.html.erb +294 -0
- data/app/components/better_ui/application/navbar_component.rb +249 -0
- data/app/components/better_ui/application/sidebar_component.html.erb +207 -0
- data/app/components/better_ui/application/sidebar_component.rb +318 -0
- data/app/components/better_ui/application/toast_component.html.erb +35 -0
- data/app/components/better_ui/application/toast_component.rb +188 -0
- data/app/components/better_ui/general/breadcrumb_component.html.erb +39 -0
- data/app/components/better_ui/general/breadcrumb_component.rb +132 -0
- data/app/components/better_ui/general/{button/component.html.erb → button_component.html.erb} +7 -7
- data/app/components/better_ui/general/button_component.rb +193 -0
- data/app/components/better_ui/general/heading_component.html.erb +25 -0
- data/app/components/better_ui/general/heading_component.rb +142 -0
- data/app/components/better_ui/general/icon_component.html.erb +2 -0
- data/app/components/better_ui/general/icon_component.rb +101 -0
- data/app/components/better_ui/general/panel_component.html.erb +27 -0
- data/app/components/better_ui/general/panel_component.rb +97 -0
- data/app/components/better_ui/general/table_component.html.erb +37 -0
- data/app/components/better_ui/general/table_component.rb +141 -0
- data/app/components/better_ui/theme_helper.rb +169 -0
- data/app/controllers/better_ui/application_controller.rb +1 -0
- data/app/controllers/better_ui/docs_controller.rb +34 -0
- data/app/helpers/better_ui_application_helper.rb +99 -0
- data/app/views/layouts/component_preview.html.erb +32 -0
- data/config/initializers/lookbook.rb +12 -12
- data/config/routes.rb +13 -0
- data/lib/better_ui/engine.rb +42 -5
- data/lib/better_ui/version.rb +1 -1
- data/lib/better_ui.rb +20 -4
- metadata +117 -157
- data/app/components/better_ui/application/card/component.html.erb +0 -20
- data/app/components/better_ui/application/card/component.rb +0 -214
- data/app/components/better_ui/application/main/component.html.erb +0 -9
- data/app/components/better_ui/application/main/component.rb +0 -123
- data/app/components/better_ui/application/navbar/component.html.erb +0 -92
- data/app/components/better_ui/application/navbar/component.rb +0 -136
- data/app/components/better_ui/application/sidebar/component.html.erb +0 -227
- data/app/components/better_ui/application/sidebar/component.rb +0 -130
- data/app/components/better_ui/general/accordion/component.html.erb +0 -5
- data/app/components/better_ui/general/accordion/component.rb +0 -92
- data/app/components/better_ui/general/accordion/item_component.html.erb +0 -12
- data/app/components/better_ui/general/accordion/item_component.rb +0 -176
- data/app/components/better_ui/general/alert/component.html.erb +0 -32
- data/app/components/better_ui/general/alert/component.rb +0 -242
- data/app/components/better_ui/general/avatar/component.html.erb +0 -20
- data/app/components/better_ui/general/avatar/component.rb +0 -301
- data/app/components/better_ui/general/badge/component.html.erb +0 -23
- data/app/components/better_ui/general/badge/component.rb +0 -248
- data/app/components/better_ui/general/breadcrumb/component.html.erb +0 -15
- data/app/components/better_ui/general/breadcrumb/component.rb +0 -187
- data/app/components/better_ui/general/button/component.rb +0 -214
- data/app/components/better_ui/general/divider/component.html.erb +0 -10
- data/app/components/better_ui/general/divider/component.rb +0 -226
- data/app/components/better_ui/general/dropdown/component.html.erb +0 -25
- data/app/components/better_ui/general/dropdown/component.rb +0 -170
- data/app/components/better_ui/general/dropdown/divider_component.html.erb +0 -1
- data/app/components/better_ui/general/dropdown/divider_component.rb +0 -41
- data/app/components/better_ui/general/dropdown/item_component.html.erb +0 -6
- data/app/components/better_ui/general/dropdown/item_component.rb +0 -119
- data/app/components/better_ui/general/field/component.html.erb +0 -27
- data/app/components/better_ui/general/field/component.rb +0 -37
- data/app/components/better_ui/general/heading/component.html.erb +0 -22
- data/app/components/better_ui/general/heading/component.rb +0 -257
- data/app/components/better_ui/general/icon/component.html.erb +0 -7
- data/app/components/better_ui/general/icon/component.rb +0 -239
- data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
- data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
- data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
- data/app/components/better_ui/general/input/datetime/component.rb +0 -223
- data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
- data/app/components/better_ui/general/input/radio/component.rb +0 -230
- data/app/components/better_ui/general/input/select/component.html.erb +0 -16
- data/app/components/better_ui/general/input/select/component.rb +0 -184
- data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
- data/app/components/better_ui/general/input/select/select_component.rb +0 -37
- data/app/components/better_ui/general/input/text/component.html.erb +0 -5
- data/app/components/better_ui/general/input/text/component.rb +0 -171
- data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
- data/app/components/better_ui/general/input/textarea/component.rb +0 -166
- data/app/components/better_ui/general/link/component.html.erb +0 -18
- data/app/components/better_ui/general/link/component.rb +0 -258
- data/app/components/better_ui/general/modal/component.html.erb +0 -5
- data/app/components/better_ui/general/modal/component.rb +0 -47
- data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
- data/app/components/better_ui/general/modal/modal_component.rb +0 -160
- data/app/components/better_ui/general/pagination/component.html.erb +0 -85
- data/app/components/better_ui/general/pagination/component.rb +0 -216
- data/app/components/better_ui/general/panel/component.html.erb +0 -28
- data/app/components/better_ui/general/panel/component.rb +0 -249
- data/app/components/better_ui/general/progress/component.html.erb +0 -11
- data/app/components/better_ui/general/progress/component.rb +0 -160
- data/app/components/better_ui/general/spinner/component.html.erb +0 -35
- data/app/components/better_ui/general/spinner/component.rb +0 -93
- data/app/components/better_ui/general/table/component.html.erb +0 -5
- data/app/components/better_ui/general/table/component.rb +0 -217
- data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
- data/app/components/better_ui/general/table/tbody_component.rb +0 -30
- data/app/components/better_ui/general/table/td_component.html.erb +0 -3
- data/app/components/better_ui/general/table/td_component.rb +0 -44
- data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
- data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
- data/app/components/better_ui/general/table/th_component.html.erb +0 -6
- data/app/components/better_ui/general/table/th_component.rb +0 -51
- data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
- data/app/components/better_ui/general/table/thead_component.rb +0 -28
- data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
- data/app/components/better_ui/general/table/tr_component.rb +0 -30
- data/app/components/better_ui/general/tabs/component.html.erb +0 -11
- data/app/components/better_ui/general/tabs/component.rb +0 -120
- data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
- data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
- data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
- data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
- data/app/components/better_ui/general/tag/component.html.erb +0 -3
- data/app/components/better_ui/general/tag/component.rb +0 -104
- data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
- data/app/components/better_ui/general/tooltip/component.rb +0 -239
- data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
- data/app/helpers/better_ui/application/components/card.rb +0 -11
- data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
- data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
- data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
- data/app/helpers/better_ui/application_helper.rb +0 -55
- data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
- data/app/helpers/better_ui/general/components/accordion.rb +0 -11
- data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
- data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
- data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
- data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
- data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
- data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
- data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
- data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
- data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -79
- data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -62
- data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
- data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
- data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
- data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
- data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
- data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
- data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
- data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -70
- data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
- data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
- data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
- data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
- data/app/helpers/better_ui/general/components/modal.rb +0 -11
- data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
- data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
- data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
- data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
- data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
- data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
- data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
- data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
- data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
- data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
- data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
- data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
- data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
- data/app/views/layouts/better_ui/application.html.erb +0 -17
- data/lib/better_ui/railtie.rb +0 -20
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module BetterUi
|
|
4
|
-
module General
|
|
5
|
-
module Dropdown
|
|
6
|
-
class Component < ViewComponent::Base
|
|
7
|
-
include BetterUi::General::Components::Icon::IconHelper
|
|
8
|
-
|
|
9
|
-
attr_reader :trigger, :position, :theme, :size, :rounded, :animation, :classes, :html_options
|
|
10
|
-
|
|
11
|
-
# Classi base spostate nel template HTML per migliore leggibilità
|
|
12
|
-
|
|
13
|
-
# Temi per il trigger del dropdown con classi Tailwind dirette
|
|
14
|
-
DROPDOWN_TRIGGER_THEME = {
|
|
15
|
-
default: "bg-white border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-blue-500",
|
|
16
|
-
white: "bg-white border-gray-300 text-gray-900 hover:bg-gray-50 focus:ring-gray-500",
|
|
17
|
-
red: "bg-red-600 border-red-600 text-white hover:bg-red-700 focus:ring-red-500",
|
|
18
|
-
rose: "bg-rose-600 border-rose-600 text-white hover:bg-rose-700 focus:ring-rose-500",
|
|
19
|
-
orange: "bg-orange-600 border-orange-600 text-white hover:bg-orange-700 focus:ring-orange-500",
|
|
20
|
-
green: "bg-green-600 border-green-600 text-white hover:bg-green-700 focus:ring-green-500",
|
|
21
|
-
blue: "bg-blue-600 border-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
|
|
22
|
-
yellow: "bg-yellow-500 border-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500",
|
|
23
|
-
violet: "bg-violet-600 border-violet-600 text-white hover:bg-violet-700 focus:ring-violet-500"
|
|
24
|
-
}.freeze
|
|
25
|
-
|
|
26
|
-
# Dimensioni del trigger con classi Tailwind dirette
|
|
27
|
-
DROPDOWN_TRIGGER_SIZE = {
|
|
28
|
-
small: "px-3 py-1.5 text-sm",
|
|
29
|
-
medium: "px-4 py-2 text-sm",
|
|
30
|
-
large: "px-6 py-3 text-base"
|
|
31
|
-
}.freeze
|
|
32
|
-
|
|
33
|
-
# Border radius con classi Tailwind dirette
|
|
34
|
-
DROPDOWN_ROUNDED = {
|
|
35
|
-
none: "rounded-none",
|
|
36
|
-
small: "rounded-md",
|
|
37
|
-
medium: "rounded-lg",
|
|
38
|
-
large: "rounded-xl",
|
|
39
|
-
full: "rounded-full"
|
|
40
|
-
}.freeze
|
|
41
|
-
|
|
42
|
-
# Posizioni del menu dropdown
|
|
43
|
-
DROPDOWN_POSITION = {
|
|
44
|
-
bottom: "top-full left-0",
|
|
45
|
-
top: "bottom-full left-0",
|
|
46
|
-
left: "top-0 right-full mr-2",
|
|
47
|
-
right: "top-0 left-full ml-2"
|
|
48
|
-
}.freeze
|
|
49
|
-
|
|
50
|
-
# Animazioni del dropdown
|
|
51
|
-
DROPDOWN_ANIMATION = {
|
|
52
|
-
fade: "transition-opacity duration-150",
|
|
53
|
-
slide: "transition-all duration-150 transform",
|
|
54
|
-
none: ""
|
|
55
|
-
}.freeze
|
|
56
|
-
|
|
57
|
-
def initialize(
|
|
58
|
-
trigger:,
|
|
59
|
-
position: :bottom,
|
|
60
|
-
theme: :default,
|
|
61
|
-
size: :medium,
|
|
62
|
-
rounded: :medium,
|
|
63
|
-
animation: :fade,
|
|
64
|
-
classes: nil,
|
|
65
|
-
**html_options
|
|
66
|
-
)
|
|
67
|
-
@trigger = trigger
|
|
68
|
-
@position = position.to_sym
|
|
69
|
-
@theme = theme.to_sym
|
|
70
|
-
@size = size.to_sym
|
|
71
|
-
@rounded = rounded.to_sym
|
|
72
|
-
@animation = animation.to_sym
|
|
73
|
-
@classes = classes
|
|
74
|
-
@html_options = html_options
|
|
75
|
-
|
|
76
|
-
validate_params
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Restituisce solo le classi dinamiche per il trigger
|
|
80
|
-
def dynamic_trigger_classes
|
|
81
|
-
[
|
|
82
|
-
get_trigger_theme_classes,
|
|
83
|
-
get_trigger_size_classes,
|
|
84
|
-
get_trigger_rounded_classes
|
|
85
|
-
].compact.join(" ")
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Restituisce solo le classi dinamiche per il menu
|
|
89
|
-
def dynamic_menu_classes
|
|
90
|
-
[
|
|
91
|
-
get_position_classes,
|
|
92
|
-
get_animation_classes,
|
|
93
|
-
get_menu_rounded_classes
|
|
94
|
-
].compact.join(" ")
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Metodi per attributi rimossi - ora gestiti direttamente nel template HTML
|
|
98
|
-
|
|
99
|
-
# Verifica se rendere il componente
|
|
100
|
-
def render?
|
|
101
|
-
@trigger.present?
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
private
|
|
105
|
-
|
|
106
|
-
def get_trigger_theme_classes
|
|
107
|
-
DROPDOWN_TRIGGER_THEME[@theme] || DROPDOWN_TRIGGER_THEME[:default]
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def get_trigger_size_classes
|
|
111
|
-
DROPDOWN_TRIGGER_SIZE[@size] || DROPDOWN_TRIGGER_SIZE[:medium]
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def get_trigger_rounded_classes
|
|
115
|
-
DROPDOWN_ROUNDED[@rounded] || DROPDOWN_ROUNDED[:medium]
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def get_menu_rounded_classes
|
|
119
|
-
DROPDOWN_ROUNDED[@rounded] || DROPDOWN_ROUNDED[:medium]
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def get_position_classes
|
|
123
|
-
DROPDOWN_POSITION[@position] || DROPDOWN_POSITION[:bottom]
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def get_animation_classes
|
|
127
|
-
DROPDOWN_ANIMATION[@animation] || DROPDOWN_ANIMATION[:fade]
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def validate_params
|
|
131
|
-
validate_theme
|
|
132
|
-
validate_size
|
|
133
|
-
validate_rounded
|
|
134
|
-
validate_position
|
|
135
|
-
validate_animation
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def validate_theme
|
|
139
|
-
unless DROPDOWN_TRIGGER_THEME.keys.include?(@theme)
|
|
140
|
-
raise ArgumentError, "Il tema deve essere uno tra: #{DROPDOWN_TRIGGER_THEME.keys.join(', ')}"
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def validate_size
|
|
145
|
-
unless DROPDOWN_TRIGGER_SIZE.keys.include?(@size)
|
|
146
|
-
raise ArgumentError, "La dimensione deve essere una tra: #{DROPDOWN_TRIGGER_SIZE.keys.join(', ')}"
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def validate_rounded
|
|
151
|
-
unless DROPDOWN_ROUNDED.keys.include?(@rounded)
|
|
152
|
-
raise ArgumentError, "Il border radius deve essere uno tra: #{DROPDOWN_ROUNDED.keys.join(', ')}"
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def validate_position
|
|
157
|
-
unless DROPDOWN_POSITION.keys.include?(@position)
|
|
158
|
-
raise ArgumentError, "La posizione deve essere una tra: #{DROPDOWN_POSITION.keys.join(', ')}"
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def validate_animation
|
|
163
|
-
unless DROPDOWN_ANIMATION.keys.include?(@animation)
|
|
164
|
-
raise ArgumentError, "L'animazione deve essere una tra: #{DROPDOWN_ANIMATION.keys.join(', ')}"
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<div <%= tag.attributes(divider_attributes) %>></div>
|
|
@@ -1,41 +0,0 @@
|
|
|
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
|
|
@@ -1,119 +0,0 @@
|
|
|
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
|
-
"data-bui-dropdown-target": "item"
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if @href.present? && !@disabled
|
|
76
|
-
attrs[:href] = @href
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
if @disabled
|
|
80
|
-
attrs["aria-disabled"] = "true"
|
|
81
|
-
attrs[:tabindex] = "-1"
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
@html_options.except(:class).each do |key, value|
|
|
85
|
-
attrs[key] = value
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
attrs
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# Determina se usare un link o un button
|
|
92
|
-
def tag_name
|
|
93
|
-
@href.present? && !@disabled ? :a : :button
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Verifica se rendere il componente
|
|
97
|
-
def render?
|
|
98
|
-
@text.present?
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
private
|
|
102
|
-
|
|
103
|
-
def get_theme_classes
|
|
104
|
-
DROPDOWN_ITEM_THEME[@theme] || DROPDOWN_ITEM_THEME[:default]
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def validate_params
|
|
108
|
-
validate_theme
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def validate_theme
|
|
112
|
-
unless DROPDOWN_ITEM_THEME.keys.include?(@theme)
|
|
113
|
-
raise ArgumentError, "Il tema deve essere uno tra: #{DROPDOWN_ITEM_THEME.keys.join(', ')}"
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<%# Form field component template %>
|
|
2
|
-
<div class="<%= BASE_CLASSES %>">
|
|
3
|
-
<% if label.present? %>
|
|
4
|
-
<label for="<%= id %>" class="<%= LABEL_CLASSES %>">
|
|
5
|
-
<%= label %>
|
|
6
|
-
<% if required %>
|
|
7
|
-
<span class="<%= REQUIRED_CLASSES %>">*</span>
|
|
8
|
-
<% end %>
|
|
9
|
-
</label>
|
|
10
|
-
<% end %>
|
|
11
|
-
|
|
12
|
-
<div class="mt-1">
|
|
13
|
-
<%= content %>
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<% if error.present? %>
|
|
17
|
-
<div class="<%= ERROR_CLASSES %>">
|
|
18
|
-
<%= error %>
|
|
19
|
-
</div>
|
|
20
|
-
<% end %>
|
|
21
|
-
|
|
22
|
-
<% if help_text.present? %>
|
|
23
|
-
<div class="<%= HELP_TEXT_CLASSES %>">
|
|
24
|
-
<%= help_text %>
|
|
25
|
-
</div>
|
|
26
|
-
<% end %>
|
|
27
|
-
</div>
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module BetterUi
|
|
4
|
-
module General
|
|
5
|
-
module Field
|
|
6
|
-
class Component < ViewComponent::Base
|
|
7
|
-
attr_reader :label, :name, :required, :error, :help_text, :id
|
|
8
|
-
|
|
9
|
-
renders_one :input
|
|
10
|
-
|
|
11
|
-
BASE_CLASSES = "flex flex-col space-y-2"
|
|
12
|
-
LABEL_CLASSES = "text-sm font-medium text-gray-700"
|
|
13
|
-
REQUIRED_CLASSES = "text-red-500 ml-1"
|
|
14
|
-
ERROR_CLASSES = "text-sm text-red-600 mt-1"
|
|
15
|
-
HELP_TEXT_CLASSES = "text-sm text-gray-500 mt-1"
|
|
16
|
-
|
|
17
|
-
def initialize(label:, name:, required: false, error: nil, help_text: nil, id: nil)
|
|
18
|
-
@label = label
|
|
19
|
-
@name = name
|
|
20
|
-
@required = required
|
|
21
|
-
@error = error
|
|
22
|
-
@help_text = help_text
|
|
23
|
-
@id = id
|
|
24
|
-
super()
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
def field_classes
|
|
30
|
-
classes = [BASE_CLASSES]
|
|
31
|
-
classes << ERROR_CLASSES if @error.present?
|
|
32
|
-
classes.join(" ")
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<%# Template per il heading %>
|
|
2
|
-
<div class="<%= container_classes %>">
|
|
3
|
-
<%= tag.public_send(heading_tag, **heading_attributes) do %>
|
|
4
|
-
<% if show_icon? %>
|
|
5
|
-
<span class="<%= icon_classes %>">
|
|
6
|
-
<%= render BetterUi::General::IconComponent.new(name: @icon) %>
|
|
7
|
-
</span>
|
|
8
|
-
<% end %>
|
|
9
|
-
|
|
10
|
-
<span><%= content %></span>
|
|
11
|
-
<% end %>
|
|
12
|
-
|
|
13
|
-
<% if show_subtitle? %>
|
|
14
|
-
<div class="<%= subtitle_classes %>">
|
|
15
|
-
<%= @subtitle %>
|
|
16
|
-
</div>
|
|
17
|
-
<% end %>
|
|
18
|
-
|
|
19
|
-
<% if show_divider? %>
|
|
20
|
-
<div class="<%= divider_classes %>"></div>
|
|
21
|
-
<% end %>
|
|
22
|
-
</div>
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
module BetterUi
|
|
2
|
-
module General
|
|
3
|
-
module Heading
|
|
4
|
-
class Component < ViewComponent::Base
|
|
5
|
-
attr_reader :level, :theme, :align, :size, :style, :icon, :subtitle, :with_divider
|
|
6
|
-
|
|
7
|
-
# Classi base sempre presenti
|
|
8
|
-
HEADING_BASE_CLASSES = "font-bold leading-tight"
|
|
9
|
-
|
|
10
|
-
# Temi con classi Tailwind dirette - LOGICA CORRETTA
|
|
11
|
-
HEADING_THEME_CLASSES = {
|
|
12
|
-
default: "text-white", # Testo bianco (per sfondi scuri)
|
|
13
|
-
white: "text-gray-900", # Testo nero (per sfondi chiari)
|
|
14
|
-
red: "text-red-500",
|
|
15
|
-
rose: "text-rose-500",
|
|
16
|
-
orange: "text-orange-500",
|
|
17
|
-
green: "text-green-500",
|
|
18
|
-
blue: "text-blue-500",
|
|
19
|
-
yellow: "text-yellow-600",
|
|
20
|
-
violet: "text-violet-500",
|
|
21
|
-
purple: "text-purple-500"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
# Allineamenti con classi Tailwind dirette
|
|
25
|
-
HEADING_ALIGN_CLASSES = {
|
|
26
|
-
left: "text-left",
|
|
27
|
-
center: "text-center",
|
|
28
|
-
right: "text-right"
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
# Dimensioni base (verranno combinate con level)
|
|
32
|
-
HEADING_SIZE_CLASSES = {
|
|
33
|
-
small: {
|
|
34
|
-
1 => "text-2xl sm:text-3xl",
|
|
35
|
-
2 => "text-xl sm:text-2xl",
|
|
36
|
-
3 => "text-lg sm:text-xl",
|
|
37
|
-
4 => "text-base sm:text-lg",
|
|
38
|
-
5 => "text-sm sm:text-base",
|
|
39
|
-
6 => "text-xs sm:text-sm"
|
|
40
|
-
},
|
|
41
|
-
medium: {
|
|
42
|
-
1 => "text-3xl sm:text-4xl",
|
|
43
|
-
2 => "text-2xl sm:text-3xl",
|
|
44
|
-
3 => "text-xl sm:text-2xl",
|
|
45
|
-
4 => "text-lg sm:text-xl",
|
|
46
|
-
5 => "text-base sm:text-lg",
|
|
47
|
-
6 => "text-sm sm:text-base"
|
|
48
|
-
},
|
|
49
|
-
large: {
|
|
50
|
-
1 => "text-4xl sm:text-5xl",
|
|
51
|
-
2 => "text-3xl sm:text-4xl",
|
|
52
|
-
3 => "text-2xl sm:text-3xl",
|
|
53
|
-
4 => "text-xl sm:text-2xl",
|
|
54
|
-
5 => "text-lg sm:text-xl",
|
|
55
|
-
6 => "text-base sm:text-lg"
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
# Stili con classi Tailwind dirette
|
|
60
|
-
HEADING_STYLE_CLASSES = {
|
|
61
|
-
normal: "",
|
|
62
|
-
bold: "font-extrabold",
|
|
63
|
-
italic: "italic",
|
|
64
|
-
underline: "underline"
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# Temi per subtitle - LOGICA CORRETTA
|
|
68
|
-
HEADING_SUBTITLE_THEME_CLASSES = {
|
|
69
|
-
default: "text-gray-300", # Testo grigio chiaro (per sfondi scuri)
|
|
70
|
-
white: "text-gray-600", # Testo grigio scuro (per sfondi chiari)
|
|
71
|
-
red: "text-red-400",
|
|
72
|
-
rose: "text-rose-400",
|
|
73
|
-
orange: "text-orange-400",
|
|
74
|
-
green: "text-green-400",
|
|
75
|
-
blue: "text-blue-400",
|
|
76
|
-
yellow: "text-yellow-500",
|
|
77
|
-
violet: "text-violet-400"
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
# Temi per divider - LOGICA CORRETTA
|
|
81
|
-
HEADING_DIVIDER_THEME_CLASSES = {
|
|
82
|
-
default: "border-gray-700", # Bordo grigio scuro (per sfondi scuri)
|
|
83
|
-
white: "border-gray-200", # Bordo grigio chiaro (per sfondi chiari)
|
|
84
|
-
red: "border-red-200",
|
|
85
|
-
rose: "border-rose-200",
|
|
86
|
-
orange: "border-orange-200",
|
|
87
|
-
green: "border-green-200",
|
|
88
|
-
blue: "border-blue-200",
|
|
89
|
-
yellow: "border-yellow-200",
|
|
90
|
-
violet: "border-violet-200"
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
# @param level [Integer] livello del heading (1-6)
|
|
94
|
-
# @param theme [Symbol] tema del colore (:default, :white, etc.)
|
|
95
|
-
# @param align [Symbol] allineamento (:left, :center, :right)
|
|
96
|
-
# @param size [Symbol] dimensione (:small, :medium, :large)
|
|
97
|
-
# @param style [Symbol] stile (:normal, :bold, :italic, :underline)
|
|
98
|
-
# @param icon [String] icona opzionale
|
|
99
|
-
# @param subtitle [String] sottotitolo opzionale
|
|
100
|
-
# @param with_divider [Boolean] mostra linea divisoria
|
|
101
|
-
# @param html_options [Hash] opzioni HTML per il container
|
|
102
|
-
def initialize(
|
|
103
|
-
level: 2,
|
|
104
|
-
theme: :white,
|
|
105
|
-
align: :left,
|
|
106
|
-
size: :medium,
|
|
107
|
-
style: :normal,
|
|
108
|
-
icon: nil,
|
|
109
|
-
subtitle: nil,
|
|
110
|
-
with_divider: false,
|
|
111
|
-
**html_options
|
|
112
|
-
)
|
|
113
|
-
@level = level.to_i.clamp(1, 6)
|
|
114
|
-
@theme = theme.to_sym
|
|
115
|
-
@align = align.to_sym
|
|
116
|
-
@size = size.to_sym
|
|
117
|
-
@style = style.to_sym
|
|
118
|
-
@icon = icon
|
|
119
|
-
@subtitle = subtitle
|
|
120
|
-
@with_divider = with_divider
|
|
121
|
-
@html_options = html_options
|
|
122
|
-
|
|
123
|
-
validate_params
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Combina tutte le classi per il heading
|
|
127
|
-
def heading_classes
|
|
128
|
-
[
|
|
129
|
-
HEADING_BASE_CLASSES,
|
|
130
|
-
get_theme_class,
|
|
131
|
-
get_align_class,
|
|
132
|
-
get_size_class,
|
|
133
|
-
get_style_class,
|
|
134
|
-
@html_options[:class]
|
|
135
|
-
].compact.join(" ")
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# Classi per il container principale
|
|
139
|
-
def container_classes
|
|
140
|
-
"mb-4"
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# Classi per il subtitle
|
|
144
|
-
def subtitle_classes
|
|
145
|
-
return "" unless @subtitle.present?
|
|
146
|
-
|
|
147
|
-
[
|
|
148
|
-
"mt-1 text-sm",
|
|
149
|
-
get_subtitle_theme_class,
|
|
150
|
-
get_align_class
|
|
151
|
-
].compact.join(" ")
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# Classi per il divider
|
|
155
|
-
def divider_classes
|
|
156
|
-
return "" unless @with_divider
|
|
157
|
-
|
|
158
|
-
[
|
|
159
|
-
"mt-2 border-t",
|
|
160
|
-
get_divider_theme_class
|
|
161
|
-
].compact.join(" ")
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
# Classi per l'icona
|
|
165
|
-
def icon_classes
|
|
166
|
-
return "" unless @icon.present?
|
|
167
|
-
"mr-2 inline-block"
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
# Restituisce gli attributi HTML per il heading
|
|
171
|
-
def heading_attributes
|
|
172
|
-
attrs = @html_options.except(:class)
|
|
173
|
-
attrs[:class] = heading_classes
|
|
174
|
-
attrs
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# Tag del heading basato sul level
|
|
178
|
-
def heading_tag
|
|
179
|
-
"h#{@level}"
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
# Determina se mostrare l'icona
|
|
183
|
-
def show_icon?
|
|
184
|
-
@icon.present?
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
# Determina se mostrare il subtitle
|
|
188
|
-
def show_subtitle?
|
|
189
|
-
@subtitle.present?
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
# Determina se mostrare il divider
|
|
193
|
-
def show_divider?
|
|
194
|
-
@with_divider
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
private
|
|
198
|
-
|
|
199
|
-
def get_theme_class
|
|
200
|
-
HEADING_THEME_CLASSES[@theme] || HEADING_THEME_CLASSES[:white]
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def get_align_class
|
|
204
|
-
HEADING_ALIGN_CLASSES[@align] || HEADING_ALIGN_CLASSES[:left]
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def get_size_class
|
|
208
|
-
size_map = HEADING_SIZE_CLASSES[@size] || HEADING_SIZE_CLASSES[:medium]
|
|
209
|
-
size_map[@level] || size_map[2]
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def get_style_class
|
|
213
|
-
HEADING_STYLE_CLASSES[@style] || HEADING_STYLE_CLASSES[:normal]
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def get_subtitle_theme_class
|
|
217
|
-
HEADING_SUBTITLE_THEME_CLASSES[@theme] || HEADING_SUBTITLE_THEME_CLASSES[:white]
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
def get_divider_theme_class
|
|
221
|
-
HEADING_DIVIDER_THEME_CLASSES[@theme] || HEADING_DIVIDER_THEME_CLASSES[:white]
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
def validate_params
|
|
225
|
-
validate_theme
|
|
226
|
-
validate_align
|
|
227
|
-
validate_size
|
|
228
|
-
validate_style
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
def validate_theme
|
|
232
|
-
unless HEADING_THEME_CLASSES.keys.include?(@theme)
|
|
233
|
-
raise ArgumentError, "Il tema deve essere uno tra: #{HEADING_THEME_CLASSES.keys.join(', ')}"
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
def validate_align
|
|
238
|
-
unless HEADING_ALIGN_CLASSES.keys.include?(@align)
|
|
239
|
-
raise ArgumentError, "L'allineamento deve essere uno tra: #{HEADING_ALIGN_CLASSES.keys.join(', ')}"
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def validate_size
|
|
244
|
-
unless HEADING_SIZE_CLASSES.keys.include?(@size)
|
|
245
|
-
raise ArgumentError, "La dimensione deve essere una tra: #{HEADING_SIZE_CLASSES.keys.join(', ')}"
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
def validate_style
|
|
250
|
-
unless HEADING_STYLE_CLASSES.keys.include?(@style)
|
|
251
|
-
raise ArgumentError, "Lo stile deve essere uno tra: #{HEADING_STYLE_CLASSES.keys.join(', ')}"
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
end
|
|
256
|
-
end
|
|
257
|
-
end
|