better_ui 0.5.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 +137 -245
- 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/general/avatar_component.html.erb +2 -2
- data/app/components/better_ui/general/avatar_component.rb +29 -29
- data/app/components/better_ui/general/badge_component.html.erb +3 -3
- data/app/components/better_ui/general/badge_component.rb +32 -20
- data/app/components/better_ui/general/breadcrumb_component.html.erb +2 -2
- data/app/components/better_ui/general/breadcrumb_component.rb +23 -23
- data/app/components/better_ui/general/button_component.html.erb +6 -6
- data/app/components/better_ui/general/button_component.rb +20 -22
- data/app/components/better_ui/general/heading_component.html.erb +1 -25
- data/app/components/better_ui/general/heading_component.rb +17 -116
- data/app/components/better_ui/general/icon_component.html.erb +1 -1
- data/app/components/better_ui/general/icon_component.rb +33 -56
- data/app/components/better_ui/general/link_component.html.erb +4 -4
- data/app/components/better_ui/general/link_component.rb +28 -28
- data/app/components/better_ui/general/panel_component.rb +30 -41
- data/app/components/better_ui/general/spinner_component.html.erb +3 -3
- data/app/components/better_ui/general/spinner_component.rb +13 -13
- data/app/components/better_ui/general/table_component.rb +35 -59
- 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/config/routes.rb +2 -13
- data/lib/better_ui/engine.rb +67 -11
- data/lib/better_ui/version.rb +1 -1
- data/lib/better_ui.rb +10 -2
- data/lib/generators/better_ui/install_generator.rb +103 -0
- data/lib/generators/better_ui/stylesheet_generator.rb +93 -30
- data/lib/generators/better_ui/templates/README +74 -5
- data/lib/generators/better_ui/templates/components/_avatar.scss +199 -150
- data/lib/generators/better_ui/templates/components/_badge.scss +153 -141
- data/lib/generators/better_ui/templates/components/_breadcrumb.scss +105 -106
- data/lib/generators/better_ui/templates/components/_button.scss +104 -101
- data/lib/generators/better_ui/templates/components/_card.scss +56 -65
- data/lib/generators/better_ui/templates/components/_heading.scss +80 -179
- data/lib/generators/better_ui/templates/components/_icon.scss +133 -89
- data/lib/generators/better_ui/templates/components/_index.scss +17 -0
- data/lib/generators/better_ui/templates/components/_link.scss +99 -129
- data/lib/generators/better_ui/templates/components/_panel.scss +103 -143
- data/lib/generators/better_ui/templates/components/_spinner.scss +127 -130
- data/lib/generators/better_ui/templates/components/_table.scss +156 -105
- data/lib/generators/better_ui/templates/components/_variables.scss +0 -33
- data/lib/generators/better_ui/templates/components_stylesheet.scss +25 -56
- data/lib/generators/better_ui/templates/index.scss +18 -0
- data/lib/generators/better_ui/templates/initializer.rb +41 -0
- metadata +91 -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 -171
- data/app/controllers/better_ui/docs_controller.rb +0 -34
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.5.
|
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
98
|
name: lookbook
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '2.
|
104
|
-
type: :
|
103
|
+
version: '2.3'
|
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: '2.
|
110
|
+
version: '2.3'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: listen
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - "
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
118
|
-
type: :
|
117
|
+
version: '3.9'
|
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: '
|
132
|
-
type: :
|
131
|
+
version: '1.6'
|
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,12 +190,24 @@ 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
|
186
213
|
- app/components/better_ui/application/card_component.html.erb
|
@@ -215,9 +242,19 @@ files:
|
|
215
242
|
- app/components/better_ui/general/spinner_component.rb
|
216
243
|
- app/components/better_ui/general/table_component.html.erb
|
217
244
|
- app/components/better_ui/general/table_component.rb
|
218
|
-
- app/components/better_ui/theme_helper.rb
|
219
245
|
- app/controllers/better_ui/application_controller.rb
|
220
|
-
- app/
|
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
|
221
258
|
- app/jobs/better_ui/application_job.rb
|
222
259
|
- app/mailers/better_ui/application_mailer.rb
|
223
260
|
- app/models/better_ui/application_record.rb
|
@@ -230,6 +267,7 @@ files:
|
|
230
267
|
- lib/better_ui.rb
|
231
268
|
- lib/better_ui/engine.rb
|
232
269
|
- lib/better_ui/version.rb
|
270
|
+
- lib/generators/better_ui/install_generator.rb
|
233
271
|
- lib/generators/better_ui/stylesheet_generator.rb
|
234
272
|
- lib/generators/better_ui/templates/README
|
235
273
|
- lib/generators/better_ui/templates/components/_avatar.scss
|
@@ -239,12 +277,15 @@ files:
|
|
239
277
|
- lib/generators/better_ui/templates/components/_card.scss
|
240
278
|
- lib/generators/better_ui/templates/components/_heading.scss
|
241
279
|
- lib/generators/better_ui/templates/components/_icon.scss
|
280
|
+
- lib/generators/better_ui/templates/components/_index.scss
|
242
281
|
- lib/generators/better_ui/templates/components/_link.scss
|
243
282
|
- lib/generators/better_ui/templates/components/_panel.scss
|
244
283
|
- lib/generators/better_ui/templates/components/_spinner.scss
|
245
284
|
- lib/generators/better_ui/templates/components/_table.scss
|
246
285
|
- lib/generators/better_ui/templates/components/_variables.scss
|
247
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
|
248
289
|
- lib/tasks/better_ui_tasks.rake
|
249
290
|
homepage: https://github.com/alessiobussolari/better_ui
|
250
291
|
licenses:
|
@@ -254,6 +295,7 @@ metadata:
|
|
254
295
|
homepage_uri: https://github.com/alessiobussolari/better_ui
|
255
296
|
source_code_uri: https://github.com/alessiobussolari/better_ui
|
256
297
|
changelog_uri: https://github.com/alessiobussolari/better_ui/blob/main/CHANGELOG.md
|
298
|
+
rubygems_mfa_required: 'true'
|
257
299
|
post_install_message:
|
258
300
|
rdoc_options: []
|
259
301
|
require_paths:
|
@@ -262,7 +304,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
262
304
|
requirements:
|
263
305
|
- - ">="
|
264
306
|
- !ruby/object:Gem::Version
|
265
|
-
version: '0'
|
307
|
+
version: '3.0'
|
266
308
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
267
309
|
requirements:
|
268
310
|
- - ">="
|
@@ -272,5 +314,5 @@ requirements: []
|
|
272
314
|
rubygems_version: 3.5.11
|
273
315
|
signing_key:
|
274
316
|
specification_version: 4
|
275
|
-
summary:
|
317
|
+
summary: Elegant and reusable UI components for Rails with integrated documentation
|
276
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
|
-
}
|