better_ui_tmp 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.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +211 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/builds/application.js +1 -0
  6. data/app/assets/builds/better_ui.css +1 -0
  7. data/app/assets/stylesheets/better_ui.scss +3 -0
  8. data/app/components/better_ui/application/main/component.html.erb +5 -0
  9. data/app/components/better_ui/application/main/component.rb +99 -0
  10. data/app/components/better_ui/application/navbar/component.html.erb +219 -0
  11. data/app/components/better_ui/application/navbar/component.rb +148 -0
  12. data/app/components/better_ui/application/sidebar/component.html.erb +184 -0
  13. data/app/components/better_ui/application/sidebar/component.rb +129 -0
  14. data/app/components/better_ui/general/alert/component.html.erb +32 -0
  15. data/app/components/better_ui/general/alert/component.rb +242 -0
  16. data/app/components/better_ui/general/avatar/component.html.erb +20 -0
  17. data/app/components/better_ui/general/avatar/component.rb +301 -0
  18. data/app/components/better_ui/general/badge/component.html.erb +23 -0
  19. data/app/components/better_ui/general/badge/component.rb +248 -0
  20. data/app/components/better_ui/general/breadcrumb/component.html.erb +15 -0
  21. data/app/components/better_ui/general/breadcrumb/component.rb +186 -0
  22. data/app/components/better_ui/general/button/component.html.erb +34 -0
  23. data/app/components/better_ui/general/button/component.rb +214 -0
  24. data/app/components/better_ui/general/card/component.html.erb +21 -0
  25. data/app/components/better_ui/general/card/component.rb +37 -0
  26. data/app/components/better_ui/general/container/component.html.erb +8 -0
  27. data/app/components/better_ui/general/container/component.rb +158 -0
  28. data/app/components/better_ui/general/divider/component.html.erb +10 -0
  29. data/app/components/better_ui/general/divider/component.rb +226 -0
  30. data/app/components/better_ui/general/heading/component.html.erb +22 -0
  31. data/app/components/better_ui/general/heading/component.rb +257 -0
  32. data/app/components/better_ui/general/icon/component.html.erb +1 -0
  33. data/app/components/better_ui/general/icon/component.rb +222 -0
  34. data/app/components/better_ui/general/link/component.html.erb +18 -0
  35. data/app/components/better_ui/general/link/component.rb +255 -0
  36. data/app/components/better_ui/general/panel/component.html.erb +28 -0
  37. data/app/components/better_ui/general/panel/component.rb +249 -0
  38. data/app/components/better_ui/general/progress/component.html.erb +11 -0
  39. data/app/components/better_ui/general/progress/component.rb +160 -0
  40. data/app/components/better_ui/general/spinner/component.html.erb +35 -0
  41. data/app/components/better_ui/general/spinner/component.rb +93 -0
  42. data/app/components/better_ui/general/table/component.html.erb +5 -0
  43. data/app/components/better_ui/general/table/component.rb +217 -0
  44. data/app/components/better_ui/general/table/tbody_component.html.erb +3 -0
  45. data/app/components/better_ui/general/table/tbody_component.rb +30 -0
  46. data/app/components/better_ui/general/table/td_component.html.erb +3 -0
  47. data/app/components/better_ui/general/table/td_component.rb +44 -0
  48. data/app/components/better_ui/general/table/tfoot_component.html.erb +3 -0
  49. data/app/components/better_ui/general/table/tfoot_component.rb +28 -0
  50. data/app/components/better_ui/general/table/th_component.html.erb +6 -0
  51. data/app/components/better_ui/general/table/th_component.rb +51 -0
  52. data/app/components/better_ui/general/table/thead_component.html.erb +3 -0
  53. data/app/components/better_ui/general/table/thead_component.rb +28 -0
  54. data/app/components/better_ui/general/table/tr_component.html.erb +3 -0
  55. data/app/components/better_ui/general/table/tr_component.rb +30 -0
  56. data/app/components/better_ui/general/tag/component.html.erb +3 -0
  57. data/app/components/better_ui/general/tag/component.rb +104 -0
  58. data/app/components/better_ui/general/tooltip/component.html.erb +7 -0
  59. data/app/components/better_ui/general/tooltip/component.rb +239 -0
  60. data/app/controllers/better_ui/application_controller.rb +5 -0
  61. data/app/helpers/better_ui/application/components/main/main_helper.rb +42 -0
  62. data/app/helpers/better_ui/application/components/main.rb +13 -0
  63. data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +51 -0
  64. data/app/helpers/better_ui/application/components/navbar.rb +13 -0
  65. data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +51 -0
  66. data/app/helpers/better_ui/application/components/sidebar.rb +13 -0
  67. data/app/helpers/better_ui/application_helper.rb +10 -0
  68. data/app/helpers/better_ui/form_helper.rb +5 -0
  69. data/app/helpers/better_ui/general/components/alert/alert_helper.rb +29 -0
  70. data/app/helpers/better_ui/general/components/alert.rb +13 -0
  71. data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +29 -0
  72. data/app/helpers/better_ui/general/components/avatar.rb +13 -0
  73. data/app/helpers/better_ui/general/components/badge/badge_helper.rb +53 -0
  74. data/app/helpers/better_ui/general/components/badge.rb +13 -0
  75. data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +37 -0
  76. data/app/helpers/better_ui/general/components/breadcrumb.rb +13 -0
  77. data/app/helpers/better_ui/general/components/button/button_helper.rb +65 -0
  78. data/app/helpers/better_ui/general/components/button.rb +13 -0
  79. data/app/helpers/better_ui/general/components/card/card_helper.rb +37 -0
  80. data/app/helpers/better_ui/general/components/card.rb +13 -0
  81. data/app/helpers/better_ui/general/components/container/container_helper.rb +60 -0
  82. data/app/helpers/better_ui/general/components/container.rb +13 -0
  83. data/app/helpers/better_ui/general/components/divider/divider_helper.rb +63 -0
  84. data/app/helpers/better_ui/general/components/divider.rb +13 -0
  85. data/app/helpers/better_ui/general/components/heading/heading_helper.rb +72 -0
  86. data/app/helpers/better_ui/general/components/heading.rb +13 -0
  87. data/app/helpers/better_ui/general/components/icon/icon_helper.rb +16 -0
  88. data/app/helpers/better_ui/general/components/icon.rb +13 -0
  89. data/app/helpers/better_ui/general/components/link/link_helper.rb +89 -0
  90. data/app/helpers/better_ui/general/components/link.rb +13 -0
  91. data/app/helpers/better_ui/general/components/panel/panel_helper.rb +83 -0
  92. data/app/helpers/better_ui/general/components/panel.rb +13 -0
  93. data/app/helpers/better_ui/general/components/progress/progress_helper.rb +53 -0
  94. data/app/helpers/better_ui/general/components/progress.rb +11 -0
  95. data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +17 -0
  96. data/app/helpers/better_ui/general/components/spinner.rb +10 -0
  97. data/app/helpers/better_ui/general/components/table/table_helper.rb +13 -0
  98. data/app/helpers/better_ui/general/components/table/tbody_helper.rb +13 -0
  99. data/app/helpers/better_ui/general/components/table/td_helper.rb +19 -0
  100. data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +13 -0
  101. data/app/helpers/better_ui/general/components/table/th_helper.rb +19 -0
  102. data/app/helpers/better_ui/general/components/table/thead_helper.rb +13 -0
  103. data/app/helpers/better_ui/general/components/table/tr_helper.rb +13 -0
  104. data/app/helpers/better_ui/general/components/table.rb +25 -0
  105. data/app/helpers/better_ui/general/components/tag/tag_helper.rb +26 -0
  106. data/app/helpers/better_ui/general/components/tag.rb +15 -0
  107. data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +60 -0
  108. data/app/helpers/better_ui/general/components/tooltip.rb +13 -0
  109. data/app/helpers/better_ui/general_helper.rb +24 -0
  110. data/app/helpers/better_ui_helper.rb +16 -0
  111. data/app/javascript/application.js +1 -0
  112. data/app/jobs/better_ui/application_job.rb +4 -0
  113. data/app/mailers/better_ui/application_mailer.rb +6 -0
  114. data/app/models/better_ui/application_record.rb +5 -0
  115. data/app/views/components/better_ui/general/table/_custom_body_row.html.erb +17 -0
  116. data/app/views/components/better_ui/general/table/_custom_footer_rows.html.erb +17 -0
  117. data/app/views/components/better_ui/general/table/_custom_header_rows.html.erb +12 -0
  118. data/app/views/layouts/component_preview.html.erb +32 -0
  119. data/config/initializers/lookbook.rb +23 -0
  120. data/config/routes.rb +3 -0
  121. data/lib/better_ui/engine.rb +109 -0
  122. data/lib/better_ui/version.rb +3 -0
  123. data/lib/better_ui.rb +37 -0
  124. data/lib/generators/better_ui/install_generator.rb +103 -0
  125. data/lib/generators/better_ui/stylesheet_generator.rb +159 -0
  126. data/lib/generators/better_ui/templates/components/_avatar.scss +200 -0
  127. data/lib/generators/better_ui/templates/components/_badge.scss +154 -0
  128. data/lib/generators/better_ui/templates/components/_breadcrumb.scss +106 -0
  129. data/lib/generators/better_ui/templates/components/_button.scss +109 -0
  130. data/lib/generators/better_ui/templates/components/_card.scss +60 -0
  131. data/lib/generators/better_ui/templates/components/_heading.scss +81 -0
  132. data/lib/generators/better_ui/templates/components/_icon.scss +134 -0
  133. data/lib/generators/better_ui/templates/components/_index.scss +17 -0
  134. data/lib/generators/better_ui/templates/components/_link.scss +100 -0
  135. data/lib/generators/better_ui/templates/components/_panel.scss +104 -0
  136. data/lib/generators/better_ui/templates/components/_spinner.scss +129 -0
  137. data/lib/generators/better_ui/templates/components/_table.scss +156 -0
  138. data/lib/generators/better_ui/templates/components/_variables.scss +0 -0
  139. data/lib/generators/better_ui/templates/components_stylesheet.scss +35 -0
  140. data/lib/generators/better_ui/templates/index.scss +18 -0
  141. data/lib/generators/better_ui/templates/initializer.rb +41 -0
  142. data/lib/tasks/better_ui_tasks.rake +4 -0
  143. metadata +260 -0
@@ -0,0 +1,109 @@
1
+ require "view_component"
2
+ require "redcarpet"
3
+ require "coderay"
4
+ require "font-awesome-sass"
5
+ begin
6
+ require "lookbook"
7
+ rescue LoadError
8
+ # Lookbook non è richiesto, è una dipendenza opzionale
9
+ end
10
+ begin
11
+ require "listen"
12
+ rescue LoadError
13
+ # Listen non è richiesto, è una dipendenza opzionale
14
+ end
15
+ begin
16
+ require "action_cable"
17
+ rescue LoadError
18
+ # ActionCable non è richiesto, è una dipendenza opzionale
19
+ end
20
+
21
+ module BetterUi
22
+ # Engine Rails per Better UI
23
+ # Gestisce l'isolamento del namespace, le dipendenze, gli asset e le configurazioni
24
+ class Engine < ::Rails::Engine
25
+ isolate_namespace BetterUi
26
+
27
+ # Configurazione per rendere disponibili gli assets all'applicazione host
28
+ initializer "better_ui.assets" do |app|
29
+ # Aggiungi i percorsi asset
30
+ app.config.assets.paths << root.join("app", "assets", "stylesheets")
31
+ app.config.assets.paths << root.join("app", "assets", "images")
32
+ app.config.assets.paths << root.join("app", "assets", "fonts")
33
+
34
+ # Aggiungi i file SCSS e CSS alla precompilazione
35
+ if app.config.respond_to?(:assets)
36
+ app.config.assets.precompile += %w[
37
+ better_ui/application.css
38
+ better_ui/components/*.css
39
+ better_ui/components/**/*.css
40
+ better_ui/components/index.css
41
+ ]
42
+ end
43
+
44
+ # Configurazione per Propshaft se disponibile
45
+ if defined?(Propshaft) && app.config.respond_to?(:asset_host)
46
+ app.config.asset_host = app.config.asset_host
47
+ end
48
+ end
49
+
50
+ # Assicuriamo che gli helper siano correttamente caricati
51
+ config.autoload_paths << root.join("app", "helpers")
52
+ config.eager_load_paths << root.join("app", "helpers")
53
+
54
+ # Caricamento dei componenti helper
55
+ initializer "better_ui.load_helpers", before: :load_config_initializers do
56
+ # Carica prima i componenti singoli general
57
+ Dir.glob(root.join("app/helpers/better_ui/general/components/*.rb")).sort.each do |component|
58
+ require component
59
+ end
60
+
61
+ # Carica i componenti singoli application
62
+ Dir.glob(root.join("app/helpers/better_ui/application/components/*.rb")).sort.each do |component|
63
+ require component
64
+ end
65
+
66
+ # Poi carica il general_helper che li unisce tutti
67
+ require_relative "../../app/helpers/better_ui/general_helper" if File.exist?(root.join("app/helpers/better_ui/general_helper.rb"))
68
+
69
+ # Poi carica l'application_helper
70
+ require_relative "../../app/helpers/better_ui/application_helper" if File.exist?(root.join("app/helpers/better_ui/application_helper.rb"))
71
+
72
+ # Infine carica il modulo principale
73
+ require_relative "../../app/helpers/better_ui_helper" if File.exist?(root.join("app/helpers/better_ui_helper.rb"))
74
+ end
75
+
76
+ # Configurazione per rendere disponibili i componenti all'applicazione host
77
+ initializer "better_ui.view_helpers" do
78
+ ActiveSupport.on_load :action_controller do
79
+ helper BetterUi::Helper if defined?(BetterUi::Helper)
80
+ end
81
+
82
+ ActiveSupport.on_load :action_view do
83
+ include BetterUi::Helper if defined?(BetterUi::Helper)
84
+ end
85
+ end
86
+
87
+ # Configurazione per ViewComponent
88
+ config.view_component.preview_paths ||= []
89
+ config.view_component.preview_paths << root.join("test", "components", "previews")
90
+
91
+ # Configurazione per Lookbook in sviluppo e test
92
+ if defined?(Lookbook)
93
+ initializer "better_ui.lookbook" do
94
+ if Rails.env.development? || Rails.env.test?
95
+ config.lookbook = Lookbook
96
+ end
97
+ end
98
+ end
99
+
100
+ # Configurazione per l'uso personalizzato dei componenti
101
+ initializer "better_ui.custom_configuration", before: :load_config_initializers do |app|
102
+ app.config.to_prepare do
103
+ BetterUi.configure do |config|
104
+ # Configurazione di default, può essere sovrascritta dall'applicazione host
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,3 @@
1
+ module BetterUi
2
+ VERSION = "0.5.1"
3
+ end
data/lib/better_ui.rb ADDED
@@ -0,0 +1,37 @@
1
+ require "better_ui/version"
2
+ require "better_ui/engine"
3
+
4
+ module BetterUi
5
+ class Configuration
6
+ attr_accessor :button_defaults, :alert_defaults, :card_defaults, :tabs_defaults
7
+
8
+ def initialize
9
+ @button_defaults = {}
10
+ @alert_defaults = {}
11
+ @card_defaults = {}
12
+ @tabs_defaults = {}
13
+ end
14
+ end
15
+
16
+ class << self
17
+ def configuration
18
+ @configuration ||= Configuration.new
19
+ end
20
+
21
+ def configure
22
+ yield(configuration) if block_given?
23
+ end
24
+
25
+ # Metodo utile per accedere al percorso degli stilesheets
26
+ def stylesheets_path
27
+ File.join(File.dirname(__FILE__), '..', 'app', 'assets', 'stylesheets')
28
+ end
29
+ end
30
+ end
31
+
32
+ # Caricamento dei generator
33
+ require 'rails/generators'
34
+ if defined?(Rails::Generators)
35
+ require 'generators/better_ui/stylesheet_generator'
36
+ require 'generators/better_ui/install_generator'
37
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ module Generators
5
+ # Generatore per l'installazione di Better UI in un'applicazione Rails
6
+ #
7
+ # Questo generatore:
8
+ # 1. Aggiunge le dipendenze necessarie
9
+ # 2. Monta l'engine nelle routes
10
+ # 3. Aggiunge gli asset all'applicazione
11
+ # 4. Crea un file di configurazione initializer
12
+ # 5. Genera i file di stile personalizzabili (opzionalmente)
13
+ class InstallGenerator < Rails::Generators::Base
14
+ source_root File.expand_path('templates', __dir__)
15
+
16
+ desc "Installa Better UI nell'applicazione Rails"
17
+
18
+ class_option :skip_routes, type: :boolean, default: false,
19
+ desc: "Salta l'aggiunta del mount engine nelle routes"
20
+ class_option :skip_stylesheets, type: :boolean, default: false,
21
+ desc: "Salta la generazione dei file di stile personalizzabili"
22
+ class_option :skip_config, type: :boolean, default: false,
23
+ desc: "Salta la creazione del file di configurazione"
24
+
25
+ def mount_engine
26
+ return if options[:skip_routes]
27
+
28
+ route_file = "config/routes.rb"
29
+
30
+ if File.exist?(route_file)
31
+ mount_code = " mount BetterUi::Engine => '/better_ui'"
32
+
33
+ append_to_file route_file, injectible_routes(mount_code)
34
+
35
+ say "Engine di Better UI montato in #{route_file}", :green
36
+ else
37
+ say "File routes.rb non trovato. Salta il montaggio dell'engine.", :yellow
38
+ end
39
+ end
40
+
41
+ def copy_initializer
42
+ return if options[:skip_config]
43
+
44
+ template "initializer.rb", "config/initializers/better_ui.rb"
45
+ say "File di configurazione creato in config/initializers/better_ui.rb", :green
46
+ end
47
+
48
+ def add_assets
49
+ application_css = "app/assets/stylesheets/application.css"
50
+ application_scss = "app/assets/stylesheets/application.scss"
51
+
52
+ file_to_update = if File.exist?(application_scss)
53
+ application_scss
54
+ elsif File.exist?(application_css)
55
+ application_css
56
+ else
57
+ nil
58
+ end
59
+
60
+ if file_to_update
61
+ if file_to_update.end_with?('.css')
62
+ inject_into_file file_to_update, " *= require better_ui/application\n", before: " */\n"
63
+ else
64
+ append_to_file file_to_update, "\n@import 'better_ui/application';\n"
65
+ end
66
+
67
+ say "Better UI assets aggiunti a #{file_to_update}", :green
68
+ else
69
+ say "File CSS dell'applicazione non trovato. Salta l'aggiunta degli assets.", :yellow
70
+ end
71
+ end
72
+
73
+ def create_stylesheets
74
+ return if options[:skip_stylesheets]
75
+
76
+ generate "better_ui:stylesheet"
77
+ say "Fogli di stile personalizzabili generati", :green
78
+ end
79
+
80
+ def show_instructions
81
+ say "\n========================================================", :green
82
+ say "Better UI installato con successo!", :green
83
+ say "========================================================", :green
84
+ say "\nPer utilizzare i componenti nella tua applicazione:", :blue
85
+ say "- Accedi a http://localhost:3000/better_ui per vedere la documentazione", :blue
86
+ say "- Utilizza i componenti nel tuo codice, ad esempio:", :blue
87
+ say " <%= render BetterUi::General::ButtonComponent.new(label: 'Clicca qui') %>", :blue
88
+ say "\nPer personalizzare i componenti, modifica i file in:", :blue
89
+ say " app/assets/stylesheets/components/", :blue
90
+ say "- I file *_overrides.scss contengono le classi vuote per le personalizzazioni", :blue
91
+ say "\nPer configurare i valori predefiniti, modifica:", :blue
92
+ say " config/initializers/better_ui.rb", :blue
93
+ say "\n========================================================\n", :green
94
+ end
95
+
96
+ private
97
+
98
+ def injectible_routes(mount_code)
99
+ "\n#{mount_code}\n"
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ module Generators
5
+ # Generatore per creare file SCSS personalizzati per i componenti BetterUI
6
+ #
7
+ # Questo generatore crea:
8
+ # 1. Un foglio di stile principale che importa tutti i componenti usando @use/@forward
9
+ # 2. File di override per ogni componente che permettono personalizzazioni senza modificare i file originali
10
+ # 3. Un file indice che raccoglie tutti gli override usando @forward
11
+ class StylesheetGenerator < Rails::Generators::Base
12
+ source_root File.expand_path('templates', __dir__)
13
+
14
+ desc "Genera un foglio di stile SCSS di base per personalizzare i componenti di BetterUI"
15
+
16
+ # Opzioni configurabili
17
+ class_option :prefix, type: :string, default: "custom",
18
+ desc: "Prefisso da utilizzare per il foglio di stile (default: 'custom')"
19
+ class_option :path, type: :string, default: "app/assets/stylesheets",
20
+ desc: "Path dove installare i file CSS all'interno della cartella app (default: 'app/assets/stylesheets')"
21
+
22
+ # Lista dei file dei componenti da gestire
23
+ COMPONENT_FILES = [
24
+ '_variables.scss',
25
+ '_button.scss',
26
+ '_heading.scss',
27
+ '_breadcrumb.scss',
28
+ '_link.scss',
29
+ '_panel.scss',
30
+ '_icon.scss',
31
+ '_table.scss',
32
+ '_badge.scss',
33
+ '_spinner.scss',
34
+ '_avatar.scss',
35
+ '_card.scss'
36
+ ].freeze
37
+
38
+ # Crea il foglio di stile principale
39
+ def create_stylesheet
40
+ # Crea il file principale che importa tutti i componenti
41
+ template "components_stylesheet.scss",
42
+ File.join(options[:path], "#{options[:prefix]}_better_ui.scss")
43
+
44
+ # Crea la directory dei componenti se non esiste
45
+ directory = File.join(options[:path], "components")
46
+ FileUtils.mkdir_p(directory) unless File.directory?(directory)
47
+
48
+ # Crea il file indice che raccoglie tutti gli override
49
+ template "index.scss", File.join(directory, "_index.scss")
50
+ end
51
+
52
+ # Crea i file di override per ogni componente
53
+ def create_overrides
54
+ # Crea la directory dei componenti se non esiste
55
+ directory = File.join(options[:path], "components")
56
+ FileUtils.mkdir_p(directory) unless File.directory?(directory)
57
+
58
+ # Crea i file di override per ogni componente
59
+ COMPONENT_FILES.each do |filename|
60
+ # Nome del file di override (es. _button_overrides.scss)
61
+ override_filename = filename.sub('.scss', '_overrides.scss')
62
+ override_path = File.join(directory, override_filename)
63
+
64
+ # Crea il file di override solo se non esiste già
65
+ unless File.exist?(override_path)
66
+ # Percorso del file template originale
67
+ template_path = File.join(self.class.source_root, "components", filename)
68
+
69
+ # Se il file template esiste, crea il file di override basato su di esso
70
+ if File.exist?(template_path)
71
+ original_content = File.read(template_path)
72
+ override_content = generate_empty_override(original_content, filename)
73
+ create_file override_path, override_content
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ # Mostra le istruzioni README dopo l'esecuzione del generatore
80
+ def show_readme
81
+ readme "README" if behavior == :invoke
82
+ end
83
+
84
+ private
85
+
86
+ # Genera un file di override vuoto con le stesse classi del file originale
87
+ #
88
+ # @param content [String] Il contenuto del file SCSS originale
89
+ # @param filename [String] Il nome del file del componente
90
+ # @return [String] Il contenuto formattato del file di override
91
+ def generate_empty_override(content, filename)
92
+ # Estrae il nome del componente dal nome file (es. "_button.scss" -> "button")
93
+ component_name = filename.sub('_', '').sub('.scss', '')
94
+
95
+ # Intestazione del file di override
96
+ result = "/* ==============================\n"
97
+ result += " * #{component_name.capitalize} Component Overrides\n"
98
+ result += " * ==============================\n"
99
+ result += " * Questo file contiene le classi vuote per sovrascrivere gli stili di default.\n"
100
+ result += " * Aggiungi qui le tue personalizzazioni.\n"
101
+ result += " */\n\n"
102
+
103
+ # Aggiungiamo il layer di Tailwind se presente nell'originale
104
+ if content.include?('@layer components')
105
+ result += "@layer components {\n"
106
+ layer_present = true
107
+ end
108
+
109
+ # Estrae le classi principali (Block) usando regex
110
+ class_matches = content.scan(/\.(bui-[a-zA-Z0-9_-]+)\s*\{/)
111
+ class_matches.flatten.uniq.each do |css_class|
112
+ result += layer_present ? " " : ""
113
+ result += ".#{css_class} {\n // Aggiungi personalizzazioni qui\n#{layer_present ? " " : ""}}\n\n"
114
+ end
115
+
116
+ # Estrae classi modifier (es. &--small, &__icon, ecc.)
117
+ modifier_matches = content.scan(/&([a-zA-Z0-9_-]+)\s*\{/)
118
+ if !modifier_matches.empty?
119
+ # Raggruppa i modifier per classe principale
120
+ main_classes = class_matches.flatten.uniq
121
+ main_classes.each do |main_class|
122
+ # Estrae tutti i modifier di questa classe principale
123
+ class_content = extract_class_block(content, main_class)
124
+ modifiers = class_content.scan(/&([a-zA-Z0-9_-]+)\s*\{/).flatten.uniq
125
+
126
+ if !modifiers.empty?
127
+ result += layer_present ? " " : ""
128
+ result += ".#{main_class} {\n"
129
+
130
+ modifiers.each do |modifier|
131
+ result += layer_present ? " " : " "
132
+ result += "&#{modifier} {\n // Aggiungi personalizzazioni qui\n#{layer_present ? " " : " "}}\n\n"
133
+ end
134
+
135
+ result += layer_present ? " " : ""
136
+ result += "}\n\n"
137
+ end
138
+ end
139
+ end
140
+
141
+ # Chiude il layer se presente
142
+ result += "}\n" if layer_present
143
+
144
+ result
145
+ end
146
+
147
+ # Estrae il blocco di codice relativo a una classe CSS specifica
148
+ #
149
+ # @param content [String] Il contenuto del file SCSS completo
150
+ # @param css_class [String] Il nome della classe CSS da estrarre
151
+ # @return [String] Il blocco di codice della classe
152
+ def extract_class_block(content, css_class)
153
+ regex = /\.(#{css_class})\s*\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}/m
154
+ match = content.match(regex)
155
+ match ? match[2] : ""
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,200 @@
1
+ @layer components {
2
+ // Classe base per l'avatar (Block)
3
+ .bui-avatar {
4
+ @apply inline-flex items-center justify-center relative;
5
+
6
+ // Elements
7
+ &__image {
8
+ @apply object-cover;
9
+ }
10
+
11
+ &__placeholder {
12
+ @apply flex items-center justify-center font-medium text-white uppercase;
13
+ }
14
+
15
+ &__status {
16
+ @apply absolute bottom-0 right-0 block rounded-full ring-2 ring-white;
17
+
18
+ &--online {
19
+ @apply bg-green-400;
20
+ }
21
+
22
+ &--offline {
23
+ @apply bg-gray-400;
24
+ }
25
+
26
+ &--busy {
27
+ @apply bg-red-400;
28
+ }
29
+
30
+ &--away {
31
+ @apply bg-yellow-400;
32
+ }
33
+ }
34
+
35
+ &__presence {
36
+ @apply absolute block rounded-full ring-2 ring-white;
37
+ }
38
+
39
+ &__badge {
40
+ @apply absolute -top-1 -right-1 flex items-center justify-center;
41
+ }
42
+
43
+ // Modifiers (dimensioni)
44
+ &--xs {
45
+ @apply h-6 w-6;
46
+
47
+ .bui-avatar__placeholder {
48
+ @apply text-xs;
49
+ }
50
+
51
+ .bui-avatar__status {
52
+ @apply h-1.5 w-1.5;
53
+ }
54
+
55
+ .bui-avatar__badge {
56
+ @apply h-4 w-4 text-[0.6rem];
57
+ }
58
+ }
59
+
60
+ &--sm {
61
+ @apply h-8 w-8;
62
+
63
+ .bui-avatar__placeholder {
64
+ @apply text-xs;
65
+ }
66
+
67
+ .bui-avatar__status {
68
+ @apply h-2 w-2;
69
+ }
70
+
71
+ .bui-avatar__badge {
72
+ @apply h-5 w-5 text-xs;
73
+ }
74
+ }
75
+
76
+ &--md {
77
+ @apply h-10 w-10;
78
+
79
+ .bui-avatar__placeholder {
80
+ @apply text-sm;
81
+ }
82
+
83
+ .bui-avatar__status {
84
+ @apply h-2.5 w-2.5;
85
+ }
86
+
87
+ .bui-avatar__badge {
88
+ @apply h-6 w-6 text-xs;
89
+ }
90
+ }
91
+
92
+ &--lg {
93
+ @apply h-12 w-12;
94
+
95
+ .bui-avatar__placeholder {
96
+ @apply text-base;
97
+ }
98
+
99
+ .bui-avatar__status {
100
+ @apply h-3 w-3;
101
+ }
102
+
103
+ .bui-avatar__badge {
104
+ @apply h-7 w-7 text-sm;
105
+ }
106
+ }
107
+
108
+ &--xl {
109
+ @apply h-16 w-16;
110
+
111
+ .bui-avatar__placeholder {
112
+ @apply text-lg;
113
+ }
114
+
115
+ .bui-avatar__status {
116
+ @apply h-4 w-4;
117
+ }
118
+
119
+ .bui-avatar__badge {
120
+ @apply h-8 w-8 text-sm;
121
+ }
122
+ }
123
+
124
+ // Modifiers (colori placeholders)
125
+ &--gray {
126
+ .bui-avatar__placeholder {
127
+ @apply bg-gray-500;
128
+ }
129
+ }
130
+
131
+ &--red {
132
+ .bui-avatar__placeholder {
133
+ @apply bg-red-500;
134
+ }
135
+ }
136
+
137
+ &--blue {
138
+ .bui-avatar__placeholder {
139
+ @apply bg-blue-500;
140
+ }
141
+ }
142
+
143
+ &--green {
144
+ .bui-avatar__placeholder {
145
+ @apply bg-green-500;
146
+ }
147
+ }
148
+
149
+ &--violet {
150
+ .bui-avatar__placeholder {
151
+ @apply bg-violet-500;
152
+ }
153
+ }
154
+
155
+ &--orange {
156
+ .bui-avatar__placeholder {
157
+ @apply bg-orange-500;
158
+ }
159
+ }
160
+
161
+ &--yellow {
162
+ .bui-avatar__placeholder {
163
+ @apply bg-yellow-500 text-yellow-900;
164
+ }
165
+ }
166
+
167
+ // Modifiers (forma)
168
+ &--circle {
169
+ @apply rounded-full;
170
+
171
+ .bui-avatar__image,
172
+ .bui-avatar__placeholder {
173
+ @apply rounded-full;
174
+ }
175
+ }
176
+
177
+ &--square {
178
+ @apply rounded-md;
179
+
180
+ .bui-avatar__image,
181
+ .bui-avatar__placeholder {
182
+ @apply rounded-md;
183
+ }
184
+ }
185
+
186
+ // Modifiers (gruppo)
187
+ &--group {
188
+ @apply -ml-2 first:ml-0;
189
+ }
190
+ }
191
+
192
+ // Avatar group container
193
+ .bui-avatar-group {
194
+ @apply flex;
195
+
196
+ .bui-avatar {
197
+ @apply border-2 border-white;
198
+ }
199
+ }
200
+ }