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.
- checksums.yaml +4 -4
- data/README.md +257 -212
- data/Rakefile +11 -2
- data/app/components/better_ui/action_messages_component/action_messages_component.html.erb +48 -0
- data/app/components/better_ui/action_messages_component.rb +544 -0
- data/app/components/better_ui/application_component.rb +66 -0
- data/app/components/better_ui/button_component/button_component.html.erb +31 -0
- data/app/components/better_ui/button_component.rb +307 -0
- data/app/components/better_ui/card_component/card_component.html.erb +17 -0
- data/app/components/better_ui/card_component.rb +460 -0
- data/app/components/better_ui/drawer/header_component/header_component.html.erb +24 -0
- data/app/components/better_ui/drawer/header_component.rb +238 -0
- data/app/components/better_ui/drawer/layout_component/layout_component.html.erb +44 -0
- data/app/components/better_ui/drawer/layout_component.rb +270 -0
- data/app/components/better_ui/drawer/nav_group_component/nav_group_component.html.erb +10 -0
- data/app/components/better_ui/drawer/nav_group_component.rb +155 -0
- data/app/components/better_ui/drawer/nav_item_component/nav_item_component.html.erb +13 -0
- data/app/components/better_ui/drawer/nav_item_component.rb +225 -0
- data/app/components/better_ui/drawer/sidebar_component/sidebar_component.html.erb +17 -0
- data/app/components/better_ui/drawer/sidebar_component.rb +263 -0
- data/app/components/better_ui/forms/base_component.rb +450 -0
- data/app/components/better_ui/forms/checkbox_component/checkbox_component.html.erb +28 -0
- data/app/components/better_ui/forms/checkbox_component.rb +419 -0
- data/app/components/better_ui/forms/checkbox_group_component/checkbox_group_component.html.erb +40 -0
- data/app/components/better_ui/forms/checkbox_group_component.rb +363 -0
- data/app/components/better_ui/forms/number_input_component/number_input_component.html.erb +40 -0
- data/app/components/better_ui/forms/number_input_component.rb +320 -0
- data/app/components/better_ui/forms/password_input_component/password_input_component.html.erb +71 -0
- data/app/components/better_ui/forms/password_input_component.rb +206 -0
- data/app/components/better_ui/forms/text_input_component/text_input_component.html.erb +40 -0
- data/app/components/better_ui/forms/text_input_component.rb +258 -0
- data/app/components/better_ui/forms/textarea_component/textarea_component.html.erb +40 -0
- data/app/components/better_ui/forms/textarea_component.rb +329 -0
- data/app/form_builders/better_ui/ui_form_builder.rb +467 -0
- data/app/helpers/better_ui/application_helper.rb +325 -58
- data/app/views/layouts/better_ui/application.html.erb +1 -1
- data/config/routes.rb +1 -0
- data/lib/better_ui/engine.rb +34 -5
- data/lib/better_ui/version.rb +1 -1
- data/lib/better_ui.rb +32 -5
- data/lib/generators/better_ui/install/USAGE +44 -0
- data/lib/generators/better_ui/install/install_generator.rb +87 -0
- data/lib/generators/better_ui/install/templates/better_ui_theme.css.tt +280 -0
- data/lib/tasks/better_ui_tasks.rake +39 -4
- metadata +55 -203
- 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 -249
- data/app/components/better_ui/application/sidebar/component.rb +0 -187
- 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.html.erb +0 -34
- 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 -28
- data/app/components/better_ui/general/dropdown/component.rb +0 -192
- 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/grid/cell_component.html.erb +0 -3
- data/app/components/better_ui/general/grid/cell_component.rb +0 -390
- data/app/components/better_ui/general/grid/component.html.erb +0 -3
- data/app/components/better_ui/general/grid/component.rb +0 -301
- 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 -240
- 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/pin/component.html.erb +0 -1
- data/app/components/better_ui/general/input/pin/component.rb +0 -201
- 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/rating/component.html.erb +0 -4
- data/app/components/better_ui/general/input/rating/component.rb +0 -272
- data/app/components/better_ui/general/input/select/component.html.erb +0 -78
- data/app/components/better_ui/general/input/select/component.rb +0 -249
- 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/input/toggle/component.html.erb +0 -5
- data/app/components/better_ui/general/input/toggle/component.rb +0 -242
- 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/text/component.html.erb +0 -1
- data/app/components/better_ui/general/text/component.rb +0 -194
- 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/general/components/accordion/accordion_helper.rb +0 -73
- 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 -88
- data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -68
- data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
- data/app/helpers/better_ui/general/components/grid/grid_helper.rb +0 -145
- 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/pin/pin_helper.rb +0 -76
- 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/rating/rating_helper.rb +0 -70
- data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -86
- 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/input/toggle/toggle_helper.rb +0 -77
- 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/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/text/text_helper.rb +0 -83
- data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
- data/app/jobs/better_ui/application_job.rb +0 -4
- data/app/mailers/better_ui/application_mailer.rb +0 -6
- data/config/initializers/lookbook.rb +0 -23
- 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,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 %>
|