better_ui 0.4.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.
- checksums.yaml +4 -4
- data/README.md +141 -189
- data/app/assets/stylesheets/better_ui/_base.scss +9 -0
- data/app/assets/stylesheets/better_ui/_components.scss +2 -0
- data/app/assets/stylesheets/better_ui/_utilities.scss +14 -0
- data/app/assets/stylesheets/better_ui/application.css +3 -1
- data/app/assets/stylesheets/better_ui/components/_avatar.scss +200 -0
- data/app/assets/stylesheets/better_ui/components/_badge.scss +154 -0
- data/app/assets/stylesheets/better_ui/components/_breadcrumb.scss +106 -0
- data/app/assets/stylesheets/better_ui/components/_button.scss +105 -0
- data/app/assets/stylesheets/better_ui/components/_card.scss +60 -0
- data/app/assets/stylesheets/better_ui/components/_heading.scss +81 -0
- data/app/assets/stylesheets/better_ui/components/_icon.scss +134 -0
- data/app/assets/stylesheets/better_ui/components/_index.scss +17 -0
- data/app/assets/stylesheets/better_ui/components/_link.scss +100 -0
- data/app/assets/stylesheets/better_ui/components/_panel.scss +104 -0
- data/app/assets/stylesheets/better_ui/components/_spinner.scss +129 -0
- data/app/assets/stylesheets/better_ui/components/_table.scss +156 -0
- data/app/assets/stylesheets/better_ui/components/_variables.scss +1 -0
- data/app/assets/stylesheets/better_ui.scss +4 -0
- data/app/components/better_ui/application/alert_component.html.erb +1 -1
- data/app/components/better_ui/application/alert_component.rb +95 -89
- data/app/components/better_ui/application/card_component.html.erb +24 -0
- data/app/components/better_ui/application/card_component.rb +53 -0
- data/app/components/better_ui/application/card_container_component.html.erb +8 -0
- data/app/components/better_ui/application/card_container_component.rb +14 -0
- data/app/components/better_ui/application/toast_component.rb +92 -57
- data/app/components/better_ui/general/avatar_component.html.erb +19 -0
- data/app/components/better_ui/general/avatar_component.rb +171 -0
- data/app/components/better_ui/general/badge_component.html.erb +19 -0
- data/app/components/better_ui/general/badge_component.rb +135 -0
- data/app/components/better_ui/general/breadcrumb_component.html.erb +7 -31
- data/app/components/better_ui/general/breadcrumb_component.rb +64 -66
- data/app/components/better_ui/general/button_component.html.erb +6 -6
- data/app/components/better_ui/general/button_component.rb +62 -95
- data/app/components/better_ui/general/heading_component.html.erb +1 -25
- data/app/components/better_ui/general/heading_component.rb +20 -113
- data/app/components/better_ui/general/icon_component.rb +37 -61
- data/app/components/better_ui/general/link_component.html.erb +17 -0
- data/app/components/better_ui/general/link_component.rb +132 -0
- data/app/components/better_ui/general/panel_component.rb +51 -56
- data/app/components/better_ui/general/spinner_component.html.erb +15 -0
- data/app/components/better_ui/general/spinner_component.rb +79 -0
- data/app/components/better_ui/general/table_component.html.erb +56 -20
- data/app/components/better_ui/general/table_component.rb +89 -87
- data/app/helpers/better_ui/general/components/avatar_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/badge_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/breadcrumb_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/button_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/heading_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/icon_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/link_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/panel_helper.rb +16 -0
- data/app/helpers/better_ui/general/components/spinner_helper.rb +17 -0
- data/app/helpers/better_ui/general/components/table_helper.rb +17 -0
- data/app/helpers/better_ui/general_helper.rb +15 -0
- data/app/helpers/better_ui_helper.rb +12 -0
- data/app/views/components/better_ui/general/table/_custom_body_row.html.erb +17 -0
- data/app/views/components/better_ui/general/table/_custom_footer_rows.html.erb +17 -0
- data/app/views/components/better_ui/general/table/_custom_header_rows.html.erb +12 -0
- data/config/routes.rb +2 -13
- data/lib/better_ui/engine.rb +66 -16
- data/lib/better_ui/version.rb +1 -1
- data/lib/better_ui.rb +12 -0
- data/lib/generators/better_ui/install_generator.rb +103 -0
- data/lib/generators/better_ui/stylesheet_generator.rb +159 -0
- data/lib/generators/better_ui/templates/README +125 -0
- data/lib/generators/better_ui/templates/components/_avatar.scss +200 -0
- data/lib/generators/better_ui/templates/components/_badge.scss +154 -0
- data/lib/generators/better_ui/templates/components/_breadcrumb.scss +106 -0
- data/lib/generators/better_ui/templates/components/_button.scss +109 -0
- data/lib/generators/better_ui/templates/components/_card.scss +60 -0
- data/lib/generators/better_ui/templates/components/_heading.scss +81 -0
- data/lib/generators/better_ui/templates/components/_icon.scss +134 -0
- data/lib/generators/better_ui/templates/components/_index.scss +17 -0
- data/lib/generators/better_ui/templates/components/_link.scss +100 -0
- data/lib/generators/better_ui/templates/components/_panel.scss +104 -0
- data/lib/generators/better_ui/templates/components/_spinner.scss +129 -0
- data/lib/generators/better_ui/templates/components/_table.scss +156 -0
- data/lib/generators/better_ui/templates/components/_variables.scss +0 -0
- data/lib/generators/better_ui/templates/components_stylesheet.scss +35 -0
- data/lib/generators/better_ui/templates/index.scss +18 -0
- data/lib/generators/better_ui/templates/initializer.rb +41 -0
- metadata +120 -49
- data/app/assets/javascripts/better_ui/controllers/navbar_controller.js +0 -138
- data/app/assets/javascripts/better_ui/controllers/sidebar_controller.js +0 -211
- data/app/assets/javascripts/better_ui/controllers/toast_controller.js +0 -161
- data/app/assets/javascripts/better_ui/index.js +0 -159
- data/app/assets/javascripts/better_ui/toast_manager.js +0 -77
- data/app/components/better_ui/theme_helper.rb +0 -169
- data/app/controllers/better_ui/docs_controller.rb +0 -34
- data/app/helpers/better_ui_application_helper.rb +0 -99
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: better_ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alessiobussolari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05-
|
11
|
+
date: 2025-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -28,44 +28,44 @@ dependencies:
|
|
28
28
|
name: view_component
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
33
|
+
version: '3.22'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.
|
40
|
+
version: '3.22'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: tailwindcss-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '4.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '4.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: redcarpet
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '3.6'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '3.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: coderay
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,86 +86,101 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 6.5
|
89
|
+
version: '6.5'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 6.5
|
96
|
+
version: '6.5'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: lookbook
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '2.3'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '2.3'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: listen
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - "
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
117
|
+
version: '3.9'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - "
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
124
|
+
version: '3.9'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: sqlite3
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
131
|
+
version: '1.6'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
138
|
+
version: '1.6'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: puma
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
145
|
+
version: '6.4'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
152
|
+
version: '6.4'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: rspec-rails
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- - "
|
157
|
+
- - "~>"
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
159
|
+
version: '6.1'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- - "
|
164
|
+
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
167
|
-
|
168
|
-
|
166
|
+
version: '6.1'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '1.59'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '1.59'
|
181
|
+
description: Better UI is a Rails gem that works as a mountable engine containing
|
182
|
+
reusable UI components, built with ViewComponent and Tailwind CSS, following the
|
183
|
+
BEM methodology. It includes documentation and interactive previews with Lookbook.
|
169
184
|
email:
|
170
185
|
- alessio.bussolari@pandev.it
|
171
186
|
executables: []
|
@@ -175,14 +190,30 @@ files:
|
|
175
190
|
- MIT-LICENSE
|
176
191
|
- README.md
|
177
192
|
- Rakefile
|
178
|
-
- app/assets/
|
179
|
-
- app/assets/
|
180
|
-
- app/assets/
|
181
|
-
- app/assets/
|
182
|
-
- app/assets/javascripts/better_ui/toast_manager.js
|
193
|
+
- app/assets/stylesheets/better_ui.scss
|
194
|
+
- app/assets/stylesheets/better_ui/_base.scss
|
195
|
+
- app/assets/stylesheets/better_ui/_components.scss
|
196
|
+
- app/assets/stylesheets/better_ui/_utilities.scss
|
183
197
|
- app/assets/stylesheets/better_ui/application.css
|
198
|
+
- app/assets/stylesheets/better_ui/components/_avatar.scss
|
199
|
+
- app/assets/stylesheets/better_ui/components/_badge.scss
|
200
|
+
- app/assets/stylesheets/better_ui/components/_breadcrumb.scss
|
201
|
+
- app/assets/stylesheets/better_ui/components/_button.scss
|
202
|
+
- app/assets/stylesheets/better_ui/components/_card.scss
|
203
|
+
- app/assets/stylesheets/better_ui/components/_heading.scss
|
204
|
+
- app/assets/stylesheets/better_ui/components/_icon.scss
|
205
|
+
- app/assets/stylesheets/better_ui/components/_index.scss
|
206
|
+
- app/assets/stylesheets/better_ui/components/_link.scss
|
207
|
+
- app/assets/stylesheets/better_ui/components/_panel.scss
|
208
|
+
- app/assets/stylesheets/better_ui/components/_spinner.scss
|
209
|
+
- app/assets/stylesheets/better_ui/components/_table.scss
|
210
|
+
- app/assets/stylesheets/better_ui/components/_variables.scss
|
184
211
|
- app/components/better_ui/application/alert_component.html.erb
|
185
212
|
- app/components/better_ui/application/alert_component.rb
|
213
|
+
- app/components/better_ui/application/card_component.html.erb
|
214
|
+
- app/components/better_ui/application/card_component.rb
|
215
|
+
- app/components/better_ui/application/card_container_component.html.erb
|
216
|
+
- app/components/better_ui/application/card_container_component.rb
|
186
217
|
- app/components/better_ui/application/header_component.html.erb
|
187
218
|
- app/components/better_ui/application/header_component.rb
|
188
219
|
- app/components/better_ui/application/navbar_component.html.erb
|
@@ -191,6 +222,10 @@ files:
|
|
191
222
|
- app/components/better_ui/application/sidebar_component.rb
|
192
223
|
- app/components/better_ui/application/toast_component.html.erb
|
193
224
|
- app/components/better_ui/application/toast_component.rb
|
225
|
+
- app/components/better_ui/general/avatar_component.html.erb
|
226
|
+
- app/components/better_ui/general/avatar_component.rb
|
227
|
+
- app/components/better_ui/general/badge_component.html.erb
|
228
|
+
- app/components/better_ui/general/badge_component.rb
|
194
229
|
- app/components/better_ui/general/breadcrumb_component.html.erb
|
195
230
|
- app/components/better_ui/general/breadcrumb_component.rb
|
196
231
|
- app/components/better_ui/general/button_component.html.erb
|
@@ -199,23 +234,58 @@ files:
|
|
199
234
|
- app/components/better_ui/general/heading_component.rb
|
200
235
|
- app/components/better_ui/general/icon_component.html.erb
|
201
236
|
- app/components/better_ui/general/icon_component.rb
|
237
|
+
- app/components/better_ui/general/link_component.html.erb
|
238
|
+
- app/components/better_ui/general/link_component.rb
|
202
239
|
- app/components/better_ui/general/panel_component.html.erb
|
203
240
|
- app/components/better_ui/general/panel_component.rb
|
241
|
+
- app/components/better_ui/general/spinner_component.html.erb
|
242
|
+
- app/components/better_ui/general/spinner_component.rb
|
204
243
|
- app/components/better_ui/general/table_component.html.erb
|
205
244
|
- app/components/better_ui/general/table_component.rb
|
206
|
-
- app/components/better_ui/theme_helper.rb
|
207
245
|
- app/controllers/better_ui/application_controller.rb
|
208
|
-
- app/
|
209
|
-
- app/helpers/
|
246
|
+
- app/helpers/better_ui/general/components/avatar_helper.rb
|
247
|
+
- app/helpers/better_ui/general/components/badge_helper.rb
|
248
|
+
- app/helpers/better_ui/general/components/breadcrumb_helper.rb
|
249
|
+
- app/helpers/better_ui/general/components/button_helper.rb
|
250
|
+
- app/helpers/better_ui/general/components/heading_helper.rb
|
251
|
+
- app/helpers/better_ui/general/components/icon_helper.rb
|
252
|
+
- app/helpers/better_ui/general/components/link_helper.rb
|
253
|
+
- app/helpers/better_ui/general/components/panel_helper.rb
|
254
|
+
- app/helpers/better_ui/general/components/spinner_helper.rb
|
255
|
+
- app/helpers/better_ui/general/components/table_helper.rb
|
256
|
+
- app/helpers/better_ui/general_helper.rb
|
257
|
+
- app/helpers/better_ui_helper.rb
|
210
258
|
- app/jobs/better_ui/application_job.rb
|
211
259
|
- app/mailers/better_ui/application_mailer.rb
|
212
260
|
- app/models/better_ui/application_record.rb
|
261
|
+
- app/views/components/better_ui/general/table/_custom_body_row.html.erb
|
262
|
+
- app/views/components/better_ui/general/table/_custom_footer_rows.html.erb
|
263
|
+
- app/views/components/better_ui/general/table/_custom_header_rows.html.erb
|
213
264
|
- app/views/layouts/component_preview.html.erb
|
214
265
|
- config/initializers/lookbook.rb
|
215
266
|
- config/routes.rb
|
216
267
|
- lib/better_ui.rb
|
217
268
|
- lib/better_ui/engine.rb
|
218
269
|
- lib/better_ui/version.rb
|
270
|
+
- lib/generators/better_ui/install_generator.rb
|
271
|
+
- lib/generators/better_ui/stylesheet_generator.rb
|
272
|
+
- lib/generators/better_ui/templates/README
|
273
|
+
- lib/generators/better_ui/templates/components/_avatar.scss
|
274
|
+
- lib/generators/better_ui/templates/components/_badge.scss
|
275
|
+
- lib/generators/better_ui/templates/components/_breadcrumb.scss
|
276
|
+
- lib/generators/better_ui/templates/components/_button.scss
|
277
|
+
- lib/generators/better_ui/templates/components/_card.scss
|
278
|
+
- lib/generators/better_ui/templates/components/_heading.scss
|
279
|
+
- lib/generators/better_ui/templates/components/_icon.scss
|
280
|
+
- lib/generators/better_ui/templates/components/_index.scss
|
281
|
+
- lib/generators/better_ui/templates/components/_link.scss
|
282
|
+
- lib/generators/better_ui/templates/components/_panel.scss
|
283
|
+
- lib/generators/better_ui/templates/components/_spinner.scss
|
284
|
+
- lib/generators/better_ui/templates/components/_table.scss
|
285
|
+
- lib/generators/better_ui/templates/components/_variables.scss
|
286
|
+
- lib/generators/better_ui/templates/components_stylesheet.scss
|
287
|
+
- lib/generators/better_ui/templates/index.scss
|
288
|
+
- lib/generators/better_ui/templates/initializer.rb
|
219
289
|
- lib/tasks/better_ui_tasks.rake
|
220
290
|
homepage: https://github.com/alessiobussolari/better_ui
|
221
291
|
licenses:
|
@@ -225,6 +295,7 @@ metadata:
|
|
225
295
|
homepage_uri: https://github.com/alessiobussolari/better_ui
|
226
296
|
source_code_uri: https://github.com/alessiobussolari/better_ui
|
227
297
|
changelog_uri: https://github.com/alessiobussolari/better_ui/blob/main/CHANGELOG.md
|
298
|
+
rubygems_mfa_required: 'true'
|
228
299
|
post_install_message:
|
229
300
|
rdoc_options: []
|
230
301
|
require_paths:
|
@@ -233,7 +304,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
233
304
|
requirements:
|
234
305
|
- - ">="
|
235
306
|
- !ruby/object:Gem::Version
|
236
|
-
version: '0'
|
307
|
+
version: '3.0'
|
237
308
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
238
309
|
requirements:
|
239
310
|
- - ">="
|
@@ -243,5 +314,5 @@ requirements: []
|
|
243
314
|
rubygems_version: 3.5.11
|
244
315
|
signing_key:
|
245
316
|
specification_version: 4
|
246
|
-
summary:
|
317
|
+
summary: Elegant and reusable UI components for Rails with integrated documentation
|
247
318
|
test_files: []
|
@@ -1,138 +0,0 @@
|
|
1
|
-
// Navbar controller per gestire il comportamento del menu mobile e dei dropdown
|
2
|
-
import { Controller } from "@hotwired/stimulus"
|
3
|
-
|
4
|
-
export default class extends Controller {
|
5
|
-
static targets = ["menu", "dropdown", "submenu"]
|
6
|
-
|
7
|
-
connect() {
|
8
|
-
// Verifica se siamo su mobile e aggiorna lo stato del menu
|
9
|
-
this.updateMenuState();
|
10
|
-
|
11
|
-
// Aggiungi un event listener per il resize della finestra
|
12
|
-
window.addEventListener("resize", this.updateMenuState.bind(this));
|
13
|
-
|
14
|
-
// Chiudi menu quando si clicca su un link (solo su mobile)
|
15
|
-
if (this.hasMenuTarget) {
|
16
|
-
const links = this.menuTarget.querySelectorAll("a");
|
17
|
-
links.forEach(link => {
|
18
|
-
link.addEventListener("click", () => {
|
19
|
-
// Se siamo su mobile, chiudi il menu
|
20
|
-
if (window.innerWidth < 768) {
|
21
|
-
this.closeMenu();
|
22
|
-
}
|
23
|
-
});
|
24
|
-
});
|
25
|
-
}
|
26
|
-
|
27
|
-
// Aggiungi listener per i click all'esterno del menu
|
28
|
-
document.addEventListener("click", this.handleClickOutside.bind(this))
|
29
|
-
}
|
30
|
-
|
31
|
-
disconnect() {
|
32
|
-
// Rimuovi event listener per il resize della finestra
|
33
|
-
window.removeEventListener("resize", this.updateMenuState.bind(this));
|
34
|
-
|
35
|
-
// Rimuovi listener al disconnette
|
36
|
-
document.removeEventListener("click", this.handleClickOutside.bind(this))
|
37
|
-
}
|
38
|
-
|
39
|
-
// Metodo per alternare l'apertura/chiusura del menu
|
40
|
-
toggleMenu(event) {
|
41
|
-
event.stopPropagation()
|
42
|
-
const isExpanded = this.menuTarget.classList.contains("hidden") === false
|
43
|
-
|
44
|
-
if (isExpanded) {
|
45
|
-
this.closeMenu()
|
46
|
-
} else {
|
47
|
-
this.openMenu()
|
48
|
-
}
|
49
|
-
}
|
50
|
-
|
51
|
-
// Metodo per chiudere il menu
|
52
|
-
closeMenu() {
|
53
|
-
this.menuTarget.classList.add("hidden")
|
54
|
-
|
55
|
-
// Aggiorna l'attributo aria-expanded
|
56
|
-
const button = this.element.querySelector("[aria-controls='navbar-menu']")
|
57
|
-
if (button) {
|
58
|
-
button.setAttribute("aria-expanded", "false")
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
// Metodo per aggiornare lo stato del menu in base alla dimensione della finestra
|
63
|
-
updateMenuState() {
|
64
|
-
if (this.hasMenuTarget) {
|
65
|
-
// Se siamo su desktop (md breakpoint - 768px)
|
66
|
-
if (window.innerWidth >= 768) {
|
67
|
-
// Assicurati che il menu sia visibile su desktop
|
68
|
-
this.menuTarget.classList.remove("hidden");
|
69
|
-
this.menuTarget.classList.add("md:block");
|
70
|
-
} else {
|
71
|
-
// Su mobile, nascondi il menu di default
|
72
|
-
this.menuTarget.classList.add("hidden");
|
73
|
-
}
|
74
|
-
|
75
|
-
// Aggiorna l'attributo aria-expanded
|
76
|
-
const button = this.element.querySelector("[aria-controls='navbar-menu']");
|
77
|
-
if (button) {
|
78
|
-
const isExpanded = window.innerWidth >= 768 ? "true" : "false";
|
79
|
-
button.setAttribute("aria-expanded", isExpanded);
|
80
|
-
}
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
openMenu() {
|
85
|
-
this.menuTarget.classList.remove("hidden")
|
86
|
-
|
87
|
-
// Chiudi tutti i dropdown nel menu mobile
|
88
|
-
if (this.hasSubmenuTarget) {
|
89
|
-
this.submenuTargets.forEach(submenu => {
|
90
|
-
submenu.classList.add("hidden")
|
91
|
-
})
|
92
|
-
}
|
93
|
-
|
94
|
-
// Aggiorna stato del pulsante
|
95
|
-
event.currentTarget.setAttribute("aria-expanded", "true")
|
96
|
-
}
|
97
|
-
|
98
|
-
toggleDropdown(event) {
|
99
|
-
event.stopPropagation()
|
100
|
-
const button = event.currentTarget
|
101
|
-
const dropdownId = button.getAttribute("aria-controls")
|
102
|
-
const dropdown = document.getElementById(dropdownId)
|
103
|
-
|
104
|
-
if (dropdown) {
|
105
|
-
const isExpanded = button.getAttribute("aria-expanded") === "true"
|
106
|
-
|
107
|
-
if (isExpanded) {
|
108
|
-
dropdown.classList.add("hidden")
|
109
|
-
button.setAttribute("aria-expanded", "false")
|
110
|
-
} else {
|
111
|
-
// Chiudi tutti gli altri dropdown prima di aprire quello corrente
|
112
|
-
if (this.hasSubmenuTarget) {
|
113
|
-
this.submenuTargets.forEach(submenu => {
|
114
|
-
if (submenu.id !== dropdownId) {
|
115
|
-
submenu.classList.add("hidden")
|
116
|
-
|
117
|
-
// Trova e aggiorna il pulsante associato
|
118
|
-
const associatedButton = this.element.querySelector(`[aria-controls='${submenu.id}']`)
|
119
|
-
if (associatedButton) {
|
120
|
-
associatedButton.setAttribute("aria-expanded", "false")
|
121
|
-
}
|
122
|
-
}
|
123
|
-
})
|
124
|
-
}
|
125
|
-
|
126
|
-
dropdown.classList.remove("hidden")
|
127
|
-
button.setAttribute("aria-expanded", "true")
|
128
|
-
}
|
129
|
-
}
|
130
|
-
}
|
131
|
-
|
132
|
-
handleClickOutside(event) {
|
133
|
-
// Chiudi il menu se si fa clic all'esterno
|
134
|
-
if (this.element.contains(event.target) === false) {
|
135
|
-
this.closeMenu()
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
@@ -1,211 +0,0 @@
|
|
1
|
-
// Sidebar controller per gestire il comportamento del menu laterale
|
2
|
-
import { Controller } from "@hotwired/stimulus"
|
3
|
-
|
4
|
-
export default class extends Controller {
|
5
|
-
static targets = ["container", "overlay", "toggleButton", "toggleIcon", "dropdown", "submenu", "chevron"]
|
6
|
-
static values = {
|
7
|
-
collapsed: { type: Boolean, default: false },
|
8
|
-
position: { type: String, default: "left" },
|
9
|
-
overlayOnMobile: { type: Boolean, default: true }
|
10
|
-
}
|
11
|
-
|
12
|
-
connect() {
|
13
|
-
// Applica lo stato iniziale
|
14
|
-
if (this.collapsedValue) {
|
15
|
-
this.collapse();
|
16
|
-
} else {
|
17
|
-
// Assicuriamo che la sidebar sia espansa all'inizio
|
18
|
-
this.containerTarget.style.transform = "translateX(0)";
|
19
|
-
}
|
20
|
-
|
21
|
-
// Imposta i listener per il ridimensionamento della finestra
|
22
|
-
window.addEventListener("resize", this.handleResize.bind(this));
|
23
|
-
|
24
|
-
// Gestisci lo stato iniziale in base alla dimensione della finestra
|
25
|
-
this.handleResize();
|
26
|
-
|
27
|
-
// Trova e apri i sottomenu con elementi attivi
|
28
|
-
this.openSubmenuWithActiveItems();
|
29
|
-
}
|
30
|
-
|
31
|
-
disconnect() {
|
32
|
-
// Rimuovi i listener all'uscita
|
33
|
-
window.removeEventListener("resize", this.handleResize.bind(this));
|
34
|
-
}
|
35
|
-
|
36
|
-
// Toggle dell'intera sidebar
|
37
|
-
toggle() {
|
38
|
-
if (this.isCollapsed()) {
|
39
|
-
this.expand();
|
40
|
-
} else {
|
41
|
-
this.collapse();
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
|
-
// Espandi la sidebar
|
46
|
-
expand() {
|
47
|
-
// Mostra la sidebar completa
|
48
|
-
this.containerTarget.classList.remove("transform-translate");
|
49
|
-
this.containerTarget.style.transform = "translateX(0)";
|
50
|
-
|
51
|
-
// Ruota l'icona del toggle button
|
52
|
-
if (this.hasToggleIconTarget) {
|
53
|
-
if (this.positionValue === "left") {
|
54
|
-
this.toggleIconTarget.style.transform = "rotate(0deg)";
|
55
|
-
} else {
|
56
|
-
this.toggleIconTarget.style.transform = "rotate(0deg)";
|
57
|
-
}
|
58
|
-
}
|
59
|
-
|
60
|
-
// Aggiorna lo stato
|
61
|
-
this.collapsedValue = false;
|
62
|
-
}
|
63
|
-
|
64
|
-
// Contrai la sidebar
|
65
|
-
collapse() {
|
66
|
-
const width = this.containerTarget.offsetWidth;
|
67
|
-
// Usa un valore più piccolo per mantenere visibile una parte della sidebar
|
68
|
-
const translateValue = this.positionValue === "left" ? `-${width - 10}px` : `${width - 10}px`;
|
69
|
-
|
70
|
-
// Nascondi la sidebar
|
71
|
-
this.containerTarget.classList.add("transform-translate");
|
72
|
-
this.containerTarget.style.transform = `translateX(${translateValue})`;
|
73
|
-
|
74
|
-
// Ruota l'icona del toggle button
|
75
|
-
if (this.hasToggleIconTarget) {
|
76
|
-
if (this.positionValue === "left") {
|
77
|
-
this.toggleIconTarget.style.transform = "rotate(180deg)";
|
78
|
-
} else {
|
79
|
-
this.toggleIconTarget.style.transform = "rotate(180deg)";
|
80
|
-
}
|
81
|
-
}
|
82
|
-
|
83
|
-
// Aggiorna lo stato
|
84
|
-
this.collapsedValue = true;
|
85
|
-
}
|
86
|
-
|
87
|
-
// Apri la sidebar
|
88
|
-
open() {
|
89
|
-
// Mostra la sidebar
|
90
|
-
this.containerTarget.style.transform = "translateX(0)";
|
91
|
-
|
92
|
-
// Mostra l'overlay se necessario
|
93
|
-
if (this.overlayOnMobileValue && window.innerWidth < 768) {
|
94
|
-
this.overlayTarget.classList.remove("hidden");
|
95
|
-
this.overlayTarget.classList.add("opacity-100");
|
96
|
-
document.body.classList.add("overflow-hidden");
|
97
|
-
}
|
98
|
-
|
99
|
-
// Aggiorna lo stato
|
100
|
-
this.collapsedValue = false;
|
101
|
-
}
|
102
|
-
|
103
|
-
// Chiudi la sidebar
|
104
|
-
close() {
|
105
|
-
// Se è già contratta su desktop, non fare nulla
|
106
|
-
if (this.collapsedValue && window.innerWidth >= 768) {
|
107
|
-
return;
|
108
|
-
}
|
109
|
-
|
110
|
-
// Su mobile, nascondi completamente
|
111
|
-
if (window.innerWidth < 768) {
|
112
|
-
const width = this.containerTarget.offsetWidth;
|
113
|
-
const translateValue = this.positionValue === "left" ? `-${width}px` : `${width}px`;
|
114
|
-
this.containerTarget.style.transform = `translateX(${translateValue})`;
|
115
|
-
|
116
|
-
// Nascondi l'overlay
|
117
|
-
this.overlayTarget.classList.add("hidden");
|
118
|
-
this.overlayTarget.classList.remove("opacity-100");
|
119
|
-
document.body.classList.remove("overflow-hidden");
|
120
|
-
} else {
|
121
|
-
// Su desktop, contrai
|
122
|
-
this.collapse();
|
123
|
-
}
|
124
|
-
}
|
125
|
-
|
126
|
-
// Verifica se la sidebar è contratta
|
127
|
-
isCollapsed() {
|
128
|
-
return this.collapsedValue;
|
129
|
-
}
|
130
|
-
|
131
|
-
// Handler per il ridimensionamento della finestra
|
132
|
-
handleResize() {
|
133
|
-
// Su mobile, mostra l'overlay se la sidebar è aperta
|
134
|
-
if (window.innerWidth < 768) {
|
135
|
-
const isHidden = this.containerTarget.style.transform.includes("translateX");
|
136
|
-
|
137
|
-
if (!isHidden && this.overlayOnMobileValue) {
|
138
|
-
this.overlayTarget.classList.remove("hidden");
|
139
|
-
} else {
|
140
|
-
this.overlayTarget.classList.add("hidden");
|
141
|
-
}
|
142
|
-
} else {
|
143
|
-
// Su desktop, nascondi l'overlay
|
144
|
-
this.overlayTarget.classList.add("hidden");
|
145
|
-
document.body.classList.remove("overflow-hidden");
|
146
|
-
|
147
|
-
// Ripristina lo stato della sidebar in base al valore di collapsed
|
148
|
-
if (this.collapsedValue) {
|
149
|
-
this.collapse();
|
150
|
-
} else {
|
151
|
-
this.expand();
|
152
|
-
}
|
153
|
-
}
|
154
|
-
}
|
155
|
-
|
156
|
-
// Toggle di un sottomenu
|
157
|
-
toggleSubmenu(event) {
|
158
|
-
const button = event.currentTarget;
|
159
|
-
const submenuId = button.getAttribute("aria-controls");
|
160
|
-
const submenu = document.getElementById(submenuId);
|
161
|
-
const chevron = button.querySelector("[data-sidebar-target='chevron']");
|
162
|
-
|
163
|
-
if (submenu) {
|
164
|
-
const isExpanded = button.getAttribute("aria-expanded") === "true";
|
165
|
-
|
166
|
-
if (isExpanded) {
|
167
|
-
// Chiudi il sottomenu
|
168
|
-
submenu.classList.add("hidden");
|
169
|
-
button.setAttribute("aria-expanded", "false");
|
170
|
-
if (chevron) {
|
171
|
-
chevron.querySelector("svg").style.transform = "rotate(0deg)";
|
172
|
-
}
|
173
|
-
} else {
|
174
|
-
// Apri il sottomenu
|
175
|
-
submenu.classList.remove("hidden");
|
176
|
-
button.setAttribute("aria-expanded", "true");
|
177
|
-
if (chevron) {
|
178
|
-
chevron.querySelector("svg").style.transform = "rotate(180deg)";
|
179
|
-
}
|
180
|
-
}
|
181
|
-
}
|
182
|
-
}
|
183
|
-
|
184
|
-
// Apri automaticamente i sottomenu che contengono elementi attivi
|
185
|
-
openSubmenuWithActiveItems() {
|
186
|
-
// Trova tutti i dropdown
|
187
|
-
if (this.hasDropdownTarget) {
|
188
|
-
this.dropdownTargets.forEach(dropdown => {
|
189
|
-
const submenuId = dropdown.getAttribute("aria-controls");
|
190
|
-
const submenu = document.getElementById(submenuId);
|
191
|
-
|
192
|
-
if (submenu) {
|
193
|
-
// Verifica se il sottomenu contiene elementi attivi
|
194
|
-
const activeItems = submenu.querySelectorAll(".bg-gray-100, .bg-gray-700, .bg-orange-700, .bg-blue-700");
|
195
|
-
|
196
|
-
if (activeItems.length > 0) {
|
197
|
-
// Apri il sottomenu
|
198
|
-
submenu.classList.remove("hidden");
|
199
|
-
dropdown.setAttribute("aria-expanded", "true");
|
200
|
-
|
201
|
-
// Ruota l'icona chevron se presente
|
202
|
-
const chevron = dropdown.querySelector("[data-sidebar-target='chevron']");
|
203
|
-
if (chevron) {
|
204
|
-
chevron.querySelector("svg").style.transform = "rotate(180deg)";
|
205
|
-
}
|
206
|
-
}
|
207
|
-
}
|
208
|
-
});
|
209
|
-
}
|
210
|
-
}
|
211
|
-
}
|