shadcn-rails 0.2.0 → 0.2.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/CHANGELOG.md +66 -2
- data/README.md +21 -8
- data/__mocks__/@floating-ui/dom.js +67 -0
- data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +23 -2
- data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +4 -31
- data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +32 -41
- data/app/assets/javascripts/shadcn/controllers/hover_card_controller.js +29 -55
- data/app/assets/javascripts/shadcn/controllers/popover_controller.js +29 -54
- data/app/assets/javascripts/shadcn/controllers/select_controller.js +26 -8
- data/app/assets/javascripts/shadcn/controllers/tooltip_controller.js +28 -59
- data/app/assets/javascripts/shadcn/index.js +7 -1
- data/app/assets/javascripts/shadcn/utils/floating.js +179 -0
- data/app/assets/stylesheets/shadcn/base.css +32 -0
- data/app/components/shadcn/accordion_component.html.erb +8 -0
- data/app/components/shadcn/accordion_component.rb +6 -15
- data/app/components/shadcn/alert_component.html.erb +6 -0
- data/app/components/shadcn/alert_component.rb +0 -18
- data/app/components/shadcn/alert_dialog_component.html.erb +12 -0
- data/app/components/shadcn/alert_dialog_component.rb +7 -27
- data/app/components/shadcn/aspect_ratio_component.html.erb +7 -0
- data/app/components/shadcn/aspect_ratio_component.rb +4 -19
- data/app/components/shadcn/avatar_component.html.erb +20 -0
- data/app/components/shadcn/avatar_component.rb +8 -36
- data/app/components/shadcn/badge_component.html.erb +1 -0
- data/app/components/shadcn/badge_component.rb +0 -11
- data/app/components/shadcn/base_component.rb +15 -2
- data/app/components/shadcn/breadcrumb_component.html.erb +5 -0
- data/app/components/shadcn/breadcrumb_component.rb +6 -16
- data/app/components/shadcn/button_component.html.erb +18 -0
- data/app/components/shadcn/button_component.rb +1 -41
- data/app/components/shadcn/card_component.html.erb +8 -0
- data/app/components/shadcn/card_component.rb +2 -6
- data/app/components/shadcn/checkbox_component.html.erb +32 -0
- data/app/components/shadcn/checkbox_component.rb +4 -43
- data/app/components/shadcn/collapsible_component.html.erb +8 -0
- data/app/components/shadcn/collapsible_component.rb +6 -15
- data/app/components/shadcn/context_menu_component.html.erb +11 -0
- data/app/components/shadcn/context_menu_component.rb +6 -26
- data/app/components/shadcn/dialog_component.html.erb +14 -0
- data/app/components/shadcn/dialog_component.rb +8 -29
- data/app/components/shadcn/drawer_component.html.erb +12 -0
- data/app/components/shadcn/drawer_component.rb +7 -27
- data/app/components/shadcn/dropdown_menu_component.html.erb +14 -0
- data/app/components/shadcn/dropdown_menu_component.rb +9 -29
- data/app/components/shadcn/field_component.rb +7 -8
- data/app/components/shadcn/hover_card_component.html.erb +12 -0
- data/app/components/shadcn/hover_card_component.rb +7 -26
- data/app/components/shadcn/input_component.html.erb +18 -0
- data/app/components/shadcn/input_component.rb +2 -27
- data/app/components/shadcn/input_otp_component.rb +3 -3
- data/app/components/shadcn/kbd_component.html.erb +1 -0
- data/app/components/shadcn/kbd_component.rb +3 -10
- data/app/components/shadcn/label_component.html.erb +3 -0
- data/app/components/shadcn/label_component.rb +2 -18
- data/app/components/shadcn/menubar_component.html.erb +6 -0
- data/app/components/shadcn/menubar_component.rb +4 -15
- data/app/components/shadcn/native_select_component.html.erb +22 -0
- data/app/components/shadcn/native_select_component.rb +9 -39
- data/app/components/shadcn/navigation_menu_component.html.erb +6 -0
- data/app/components/shadcn/navigation_menu_component.rb +4 -15
- data/app/components/shadcn/pagination_component.html.erb +5 -0
- data/app/components/shadcn/pagination_component.rb +11 -15
- data/app/components/shadcn/popover_component.html.erb +15 -0
- data/app/components/shadcn/popover_component.rb +10 -30
- data/app/components/shadcn/progress_component.html.erb +13 -0
- data/app/components/shadcn/progress_component.rb +6 -26
- data/app/components/shadcn/radio_group_component.html.erb +8 -0
- data/app/components/shadcn/radio_group_component.rb +12 -26
- data/app/components/shadcn/scroll_area_component.html.erb +7 -0
- data/app/components/shadcn/scroll_area_component.rb +4 -16
- data/app/components/shadcn/select_component.html.erb +46 -0
- data/app/components/shadcn/select_component.rb +6 -80
- data/app/components/shadcn/separator_component.html.erb +5 -0
- data/app/components/shadcn/separator_component.rb +6 -14
- data/app/components/shadcn/sheet_component.html.erb +12 -0
- data/app/components/shadcn/sheet_component.rb +7 -27
- data/app/components/shadcn/sidebar_component.rb +2 -2
- data/app/components/shadcn/skeleton_component.html.erb +1 -0
- data/app/components/shadcn/skeleton_component.rb +4 -2
- data/app/components/shadcn/slider_component.html.erb +12 -0
- data/app/components/shadcn/slider_component.rb +2 -21
- data/app/components/shadcn/spinner_component.html.erb +18 -0
- data/app/components/shadcn/spinner_component.rb +2 -30
- data/app/components/shadcn/switch_component.html.erb +72 -0
- data/app/components/shadcn/switch_component.rb +4 -82
- data/app/components/shadcn/table_component.html.erb +9 -0
- data/app/components/shadcn/table_component.rb +2 -10
- data/app/components/shadcn/tabs_component.html.erb +8 -0
- data/app/components/shadcn/tabs_component.rb +4 -17
- data/app/components/shadcn/textarea_component.html.erb +13 -0
- data/app/components/shadcn/textarea_component.rb +6 -22
- data/app/components/shadcn/toast_component.html.erb +36 -0
- data/app/components/shadcn/toast_component.rb +6 -54
- data/app/components/shadcn/toggle_component.html.erb +12 -0
- data/app/components/shadcn/toggle_component.rb +6 -21
- data/app/components/shadcn/toggle_group_component.html.erb +14 -0
- data/app/components/shadcn/toggle_group_component.rb +6 -29
- data/app/components/shadcn/tooltip_component.html.erb +20 -0
- data/app/components/shadcn/tooltip_component.rb +13 -38
- data/lib/generators/shadcn/add/USAGE +24 -0
- data/lib/generators/shadcn/add/add_generator.rb +279 -0
- data/lib/generators/shadcn/install/USAGE +22 -0
- data/lib/generators/shadcn/install/install_generator.rb +8 -3
- data/lib/generators/shadcn/install/templates/initializer.rb.tt +7 -27
- data/lib/generators/shadcn/install/templates/shadcn.yml.tt +15 -31
- data/lib/shadcn/rails/version.rb +1 -1
- metadata +47 -45
- data/.dockerignore +0 -40
- data/CLAUDE.md +0 -612
- data/PROGRESS.md +0 -495
- data/Rakefile +0 -95
- data/__tests__/controllers/__snapshots__/calendar_controller.test.js.snap +0 -13
- data/__tests__/controllers/__snapshots__/popover_controller.test.js.snap +0 -46
- data/__tests__/controllers/__snapshots__/sheet_controller.test.js.snap +0 -111
- data/__tests__/controllers/__snapshots__/tabs_controller.test.js.snap +0 -27
- data/__tests__/controllers/accordion_controller.test.js +0 -904
- data/__tests__/controllers/calendar_controller.test.js +0 -1370
- data/__tests__/controllers/carousel_controller.test.js +0 -912
- data/__tests__/controllers/checkbox_controller.test.js +0 -454
- data/__tests__/controllers/collapsible_controller.test.js +0 -407
- data/__tests__/controllers/combobox_controller.test.js +0 -971
- data/__tests__/controllers/context_menu_controller.test.js +0 -905
- data/__tests__/controllers/date_picker_controller.test.js +0 -636
- data/__tests__/controllers/dialog_controller.test.js +0 -878
- data/__tests__/controllers/drawer_controller.test.js +0 -995
- data/__tests__/controllers/menubar_controller.test.js +0 -737
- data/__tests__/controllers/navigation_menu_controller.test.js +0 -599
- data/__tests__/controllers/popover_controller.test.js +0 -982
- data/__tests__/controllers/radio_group_controller.test.js +0 -640
- data/__tests__/controllers/resizable_controller.test.js +0 -680
- data/__tests__/controllers/select_controller.test.js +0 -678
- data/__tests__/controllers/sheet_controller.test.js +0 -986
- data/__tests__/controllers/slider_controller.test.js +0 -1036
- data/__tests__/controllers/switch_controller.test.js +0 -424
- data/__tests__/controllers/tabs_controller.test.js +0 -907
- data/__tests__/controllers/toggle_group_controller.test.js +0 -839
- data/__tests__/controllers/tooltip_controller.test.js +0 -808
- data/__tests__/helpers/stimulus-test-helper.js +0 -203
- data/babel.config.cjs +0 -5
- data/bin/bump +0 -321
- data/bin/console +0 -11
- data/bin/release +0 -205
- data/bin/setup +0 -8
- data/bin/test +0 -75
- data/jest.config.js +0 -19
- data/jest.setup.js +0 -8
- data/lib/generators/shadcn/component/component_generator.rb +0 -188
- data/lib/generators/shadcn/theme/theme_generator.rb +0 -128
- data/package-lock.json +0 -7438
- data/package.json +0 -71
- data/rollup.config.js +0 -29
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails/generators/base"
|
|
5
|
+
|
|
6
|
+
module Shadcn
|
|
7
|
+
module Generators
|
|
8
|
+
# Generator for adding shadcn components to your application
|
|
9
|
+
# Usage: rails generate shadcn:add button
|
|
10
|
+
# rails generate shadcn:add button card dialog
|
|
11
|
+
# rails generate shadcn:add button --exclude-controllers
|
|
12
|
+
class AddGenerator < ::Rails::Generators::Base
|
|
13
|
+
source_root File.expand_path("templates", __dir__)
|
|
14
|
+
|
|
15
|
+
argument :components, type: :array, default: [], banner: "component [component ...]"
|
|
16
|
+
|
|
17
|
+
class_option :all, type: :boolean, default: false,
|
|
18
|
+
desc: "Add all available components"
|
|
19
|
+
class_option :list, type: :boolean, default: false,
|
|
20
|
+
desc: "List all available components"
|
|
21
|
+
class_option :include_controllers, type: :boolean, default: true,
|
|
22
|
+
desc: "Include Stimulus controllers (default: true)"
|
|
23
|
+
class_option :exclude_controllers, type: :boolean, default: false,
|
|
24
|
+
desc: "Exclude Stimulus controllers"
|
|
25
|
+
class_option :force, type: :boolean, default: false,
|
|
26
|
+
desc: "Overwrite existing files"
|
|
27
|
+
class_option :path, type: :string, default: "app/components",
|
|
28
|
+
desc: "Path for components (default: app/components)"
|
|
29
|
+
|
|
30
|
+
desc "Adds shadcn components to your application for customization"
|
|
31
|
+
|
|
32
|
+
# Map component names to their files
|
|
33
|
+
COMPONENT_FILES = {
|
|
34
|
+
"accordion" => { component: "accordion_component.rb", controller: "accordion_controller.js" },
|
|
35
|
+
"alert" => { component: "alert_component.rb", controller: nil },
|
|
36
|
+
"alert_dialog" => { component: "alert_dialog_component.rb", controller: "dialog_controller.js" },
|
|
37
|
+
"aspect_ratio" => { component: "aspect_ratio_component.rb", controller: nil },
|
|
38
|
+
"avatar" => { component: "avatar_component.rb", controller: "avatar_controller.js" },
|
|
39
|
+
"badge" => { component: "badge_component.rb", controller: nil },
|
|
40
|
+
"breadcrumb" => { component: "breadcrumb_component.rb", controller: nil },
|
|
41
|
+
"button" => { component: "button_component.rb", controller: nil },
|
|
42
|
+
"button_group" => { component: "button_group_component.rb", controller: nil },
|
|
43
|
+
"calendar" => { component: "calendar_component.rb", controller: "calendar_controller.js" },
|
|
44
|
+
"card" => { component: "card_component.rb", controller: nil },
|
|
45
|
+
"carousel" => { component: "carousel_component.rb", controller: "carousel_controller.js" },
|
|
46
|
+
"checkbox" => { component: "checkbox_component.rb", controller: "checkbox_controller.js" },
|
|
47
|
+
"collapsible" => { component: "collapsible_component.rb", controller: "collapsible_controller.js" },
|
|
48
|
+
"combobox" => { component: "combobox_component.rb", controller: "combobox_controller.js" },
|
|
49
|
+
"command" => { component: "command_component.rb", controller: "command_controller.js" },
|
|
50
|
+
"context_menu" => { component: "context_menu_component.rb", controller: "context_menu_controller.js" },
|
|
51
|
+
"date_picker" => { component: "date_picker_component.rb", controller: "date_picker_controller.js" },
|
|
52
|
+
"dialog" => { component: "dialog_component.rb", controller: "dialog_controller.js" },
|
|
53
|
+
"drawer" => { component: "drawer_component.rb", controller: "drawer_controller.js" },
|
|
54
|
+
"dropdown_menu" => { component: "dropdown_menu_component.rb", controller: "dropdown_controller.js" },
|
|
55
|
+
"field" => { component: "field_component.rb", controller: nil },
|
|
56
|
+
"hover_card" => { component: "hover_card_component.rb", controller: "hover_card_controller.js" },
|
|
57
|
+
"input" => { component: "input_component.rb", controller: nil },
|
|
58
|
+
"input_group" => { component: "input_group_component.rb", controller: nil },
|
|
59
|
+
"input_otp" => { component: "input_otp_component.rb", controller: "input_otp_controller.js" },
|
|
60
|
+
"kbd" => { component: "kbd_component.rb", controller: nil },
|
|
61
|
+
"label" => { component: "label_component.rb", controller: nil },
|
|
62
|
+
"menubar" => { component: "menubar_component.rb", controller: "menubar_controller.js" },
|
|
63
|
+
"native_select" => { component: "native_select_component.rb", controller: nil },
|
|
64
|
+
"navigation_menu" => { component: "navigation_menu_component.rb", controller: "navigation_menu_controller.js" },
|
|
65
|
+
"pagination" => { component: "pagination_component.rb", controller: nil },
|
|
66
|
+
"popover" => { component: "popover_component.rb", controller: "popover_controller.js" },
|
|
67
|
+
"progress" => { component: "progress_component.rb", controller: nil },
|
|
68
|
+
"radio_group" => { component: "radio_group_component.rb", controller: "radio_group_controller.js" },
|
|
69
|
+
"resizable" => { component: "resizable_panel_group_component.rb", controller: "resizable_controller.js" },
|
|
70
|
+
"scroll_area" => { component: "scroll_area_component.rb", controller: "scroll_area_controller.js" },
|
|
71
|
+
"select" => { component: "select_component.rb", controller: "select_controller.js" },
|
|
72
|
+
"separator" => { component: "separator_component.rb", controller: nil },
|
|
73
|
+
"sheet" => { component: "sheet_component.rb", controller: "sheet_controller.js" },
|
|
74
|
+
"sidebar" => { component: "sidebar_component.rb", controller: "sidebar_controller.js" },
|
|
75
|
+
"skeleton" => { component: "skeleton_component.rb", controller: nil },
|
|
76
|
+
"slider" => { component: "slider_component.rb", controller: "slider_controller.js" },
|
|
77
|
+
"spinner" => { component: "spinner_component.rb", controller: nil },
|
|
78
|
+
"switch" => { component: "switch_component.rb", controller: "switch_controller.js" },
|
|
79
|
+
"table" => { component: "table_component.rb", controller: nil },
|
|
80
|
+
"tabs" => { component: "tabs_component.rb", controller: "tabs_controller.js" },
|
|
81
|
+
"textarea" => { component: "textarea_component.rb", controller: nil },
|
|
82
|
+
"toast" => { component: "toast_component.rb", controller: "toast_controller.js" },
|
|
83
|
+
"toggle" => { component: "toggle_component.rb", controller: "toggle_controller.js" },
|
|
84
|
+
"toggle_group" => { component: "toggle_group_component.rb", controller: "toggle_group_controller.js" },
|
|
85
|
+
"tooltip" => { component: "tooltip_component.rb", controller: "tooltip_controller.js" },
|
|
86
|
+
"typography" => { component: "typography_component.rb", controller: nil }
|
|
87
|
+
}.freeze
|
|
88
|
+
|
|
89
|
+
def validate_components
|
|
90
|
+
if options[:list]
|
|
91
|
+
display_available_components
|
|
92
|
+
exit 0
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if options[:all]
|
|
96
|
+
@components_to_add = COMPONENT_FILES.keys
|
|
97
|
+
else
|
|
98
|
+
validate_requested_components
|
|
99
|
+
@components_to_add = components
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def display_plan
|
|
104
|
+
say ""
|
|
105
|
+
say "Adding #{@components_to_add.length} component(s):", :green
|
|
106
|
+
@components_to_add.each { |c| say " - #{c}" }
|
|
107
|
+
if include_controllers?
|
|
108
|
+
controllers = @components_to_add.count { |c| COMPONENT_FILES[c][:controller] }
|
|
109
|
+
say ""
|
|
110
|
+
say "Including #{controllers} Stimulus controller(s)", :cyan if controllers > 0
|
|
111
|
+
end
|
|
112
|
+
say ""
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def add_components
|
|
116
|
+
@components_to_add.each do |component|
|
|
117
|
+
add_component(component)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def display_post_add_message
|
|
122
|
+
say ""
|
|
123
|
+
say "=" * 60, :green
|
|
124
|
+
say " Components added successfully!", :green
|
|
125
|
+
say "=" * 60, :green
|
|
126
|
+
say ""
|
|
127
|
+
say "Components are now in your application:", :yellow
|
|
128
|
+
say " - Ruby components: #{options[:path]}/shadcn/"
|
|
129
|
+
if include_controllers?
|
|
130
|
+
say " - Stimulus controllers: app/javascript/controllers/shadcn/"
|
|
131
|
+
end
|
|
132
|
+
say ""
|
|
133
|
+
say "These local files will take precedence over the gem's components."
|
|
134
|
+
say "You can now customize them as needed."
|
|
135
|
+
say ""
|
|
136
|
+
if include_controllers?
|
|
137
|
+
say "Note: Register the controllers in your Stimulus application:", :cyan
|
|
138
|
+
say ""
|
|
139
|
+
say " // In app/javascript/controllers/index.js"
|
|
140
|
+
say " import ShadcnDialog from \"./shadcn/dialog_controller\""
|
|
141
|
+
say " application.register(\"shadcn--dialog\", ShadcnDialog)"
|
|
142
|
+
say ""
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def display_available_components
|
|
149
|
+
say ""
|
|
150
|
+
say "Available shadcn components:", :green
|
|
151
|
+
say ""
|
|
152
|
+
|
|
153
|
+
# Group by category
|
|
154
|
+
categories = {
|
|
155
|
+
"Buttons & Actions" => %w[button button_group toggle toggle_group],
|
|
156
|
+
"Form Inputs" => %w[checkbox field input input_group input_otp label native_select radio_group select slider switch textarea],
|
|
157
|
+
"Data Display" => %w[avatar badge card kbd progress skeleton spinner table typography aspect_ratio scroll_area],
|
|
158
|
+
"Feedback" => %w[alert toast tooltip],
|
|
159
|
+
"Overlays" => %w[alert_dialog dialog drawer dropdown_menu hover_card popover sheet context_menu],
|
|
160
|
+
"Navigation" => %w[accordion breadcrumb collapsible menubar navigation_menu pagination separator tabs resizable],
|
|
161
|
+
"Advanced" => %w[calendar carousel combobox command date_picker sidebar]
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
categories.each do |category, comps|
|
|
165
|
+
available = comps & COMPONENT_FILES.keys
|
|
166
|
+
next if available.empty?
|
|
167
|
+
|
|
168
|
+
say " #{category}:", :yellow
|
|
169
|
+
available.each do |name|
|
|
170
|
+
controller_info = COMPONENT_FILES[name][:controller] ? " ✦" : ""
|
|
171
|
+
say " #{name}#{controller_info}"
|
|
172
|
+
end
|
|
173
|
+
say ""
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
say " ✦ = includes Stimulus controller", :cyan
|
|
177
|
+
say ""
|
|
178
|
+
say "Usage:", :yellow
|
|
179
|
+
say " rails generate shadcn:add button"
|
|
180
|
+
say " rails generate shadcn:add button card dialog"
|
|
181
|
+
say " rails generate shadcn:add --all"
|
|
182
|
+
say ""
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def validate_requested_components
|
|
186
|
+
if components.empty?
|
|
187
|
+
say "Error: Please specify at least one component or use --all", :red
|
|
188
|
+
say ""
|
|
189
|
+
display_available_components
|
|
190
|
+
exit 1
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
invalid = components - COMPONENT_FILES.keys
|
|
194
|
+
if invalid.any?
|
|
195
|
+
say "Error: Unknown component(s): #{invalid.join(', ')}", :red
|
|
196
|
+
say ""
|
|
197
|
+
display_available_components
|
|
198
|
+
exit 1
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def add_component(name)
|
|
203
|
+
files = COMPONENT_FILES[name]
|
|
204
|
+
|
|
205
|
+
# Copy Ruby component
|
|
206
|
+
copy_ruby_component(name, files[:component])
|
|
207
|
+
|
|
208
|
+
# Copy ERB template if it exists
|
|
209
|
+
copy_erb_template(name, files[:component])
|
|
210
|
+
|
|
211
|
+
# Copy Stimulus controller if requested and exists
|
|
212
|
+
if include_controllers? && files[:controller]
|
|
213
|
+
copy_stimulus_controller(name, files[:controller])
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def copy_ruby_component(name, filename)
|
|
218
|
+
source_path = gem_component_path(filename)
|
|
219
|
+
destination_path = File.join(options[:path], "shadcn", filename)
|
|
220
|
+
|
|
221
|
+
if File.exist?(destination_path) && !options[:force]
|
|
222
|
+
say " skip #{filename} (already exists, use --force to overwrite)", :yellow
|
|
223
|
+
else
|
|
224
|
+
copy_file source_path, destination_path
|
|
225
|
+
say " create #{filename}", :green
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def copy_erb_template(name, ruby_filename)
|
|
230
|
+
erb_filename = ruby_filename.sub(/\.rb$/, ".html.erb")
|
|
231
|
+
source_path = gem_component_path(erb_filename)
|
|
232
|
+
|
|
233
|
+
# Only copy if the template exists
|
|
234
|
+
return unless File.exist?(source_path)
|
|
235
|
+
|
|
236
|
+
destination_path = File.join(options[:path], "shadcn", erb_filename)
|
|
237
|
+
|
|
238
|
+
if File.exist?(destination_path) && !options[:force]
|
|
239
|
+
say " skip #{erb_filename} (already exists, use --force to overwrite)", :yellow
|
|
240
|
+
else
|
|
241
|
+
copy_file source_path, destination_path
|
|
242
|
+
say " create #{erb_filename}", :green
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def copy_stimulus_controller(name, filename)
|
|
247
|
+
source_path = gem_controller_path(filename)
|
|
248
|
+
destination_path = "app/javascript/controllers/shadcn/#{filename}"
|
|
249
|
+
|
|
250
|
+
# Create directory if it doesn't exist
|
|
251
|
+
directory = File.dirname(destination_path)
|
|
252
|
+
empty_directory directory unless File.directory?(directory)
|
|
253
|
+
|
|
254
|
+
if File.exist?(destination_path) && !options[:force]
|
|
255
|
+
say " skip #{filename} (already exists, use --force to overwrite)", :yellow
|
|
256
|
+
else
|
|
257
|
+
copy_file source_path, destination_path
|
|
258
|
+
say " create #{filename}", :green
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def gem_component_path(filename)
|
|
263
|
+
File.join(gem_root, "app/components/shadcn", filename)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def gem_controller_path(filename)
|
|
267
|
+
File.join(gem_root, "app/assets/javascripts/shadcn/controllers", filename)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def gem_root
|
|
271
|
+
@gem_root ||= File.expand_path("../../../../..", __FILE__)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def include_controllers?
|
|
275
|
+
options[:include_controllers] && !options[:exclude_controllers]
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Description:
|
|
2
|
+
Installs and configures shadcn-rails in your Rails application.
|
|
3
|
+
|
|
4
|
+
Example:
|
|
5
|
+
rails generate shadcn:install
|
|
6
|
+
|
|
7
|
+
This will create:
|
|
8
|
+
config/initializers/shadcn.rb
|
|
9
|
+
config/shadcn.yml
|
|
10
|
+
|
|
11
|
+
And configure:
|
|
12
|
+
Tailwind CSS (if present)
|
|
13
|
+
Stimulus controllers
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--theme=NAME Base color theme (default: neutral)
|
|
17
|
+
Available: neutral, slate, stone, zinc, gray
|
|
18
|
+
|
|
19
|
+
--dark-mode=MODE Dark mode strategy (default: class)
|
|
20
|
+
Available: class, media, both
|
|
21
|
+
|
|
22
|
+
--skip-tailwind Skip Tailwind CSS configuration
|
|
@@ -7,7 +7,7 @@ module Shadcn
|
|
|
7
7
|
module Generators
|
|
8
8
|
# Generator for installing shadcn-rails in a Rails application
|
|
9
9
|
# Usage: rails generate shadcn:install
|
|
10
|
-
class InstallGenerator < Rails::Generators::Base
|
|
10
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
11
11
|
source_root File.expand_path("templates", __dir__)
|
|
12
12
|
|
|
13
13
|
class_option :theme, type: :string, default: "neutral",
|
|
@@ -15,7 +15,7 @@ module Shadcn
|
|
|
15
15
|
class_option :css_variables, type: :boolean, default: true,
|
|
16
16
|
desc: "Use CSS variables for theming"
|
|
17
17
|
class_option :dark_mode, type: :string, default: "class",
|
|
18
|
-
desc: "Dark mode strategy (class, media,
|
|
18
|
+
desc: "Dark mode strategy (class, media, both)"
|
|
19
19
|
class_option :skip_tailwind, type: :boolean, default: false,
|
|
20
20
|
desc: "Skip Tailwind CSS configuration"
|
|
21
21
|
|
|
@@ -41,7 +41,7 @@ module Shadcn
|
|
|
41
41
|
"\n/*\n *= require shadcn/base\n *= require shadcn/components\n */\n"
|
|
42
42
|
end
|
|
43
43
|
else
|
|
44
|
-
say "Could not find application stylesheet. Please manually import shadcn
|
|
44
|
+
say "Could not find application stylesheet. Please manually import shadcn styles.", :yellow
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -81,6 +81,11 @@ module Shadcn
|
|
|
81
81
|
say " Click me"
|
|
82
82
|
say " <% end %>"
|
|
83
83
|
say ""
|
|
84
|
+
say "To add individual components to your app for customization:"
|
|
85
|
+
say ""
|
|
86
|
+
say " rails generate shadcn:add button"
|
|
87
|
+
say " rails generate shadcn:add --list"
|
|
88
|
+
say ""
|
|
84
89
|
say "For more information, visit: https://github.com/iheanyi/shadcn-rails"
|
|
85
90
|
say ""
|
|
86
91
|
end
|
|
@@ -2,34 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
# shadcn-rails configuration
|
|
4
4
|
Shadcn::Rails.configure do |config|
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# Base color theme: neutral, stone, zinc, gray, slate
|
|
5
|
+
# Base color theme
|
|
6
|
+
# Available themes: neutral, slate, stone, zinc, gray
|
|
9
7
|
config.base_color = "<%= options[:theme] %>"
|
|
10
8
|
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
# Default border radius for components
|
|
18
|
-
config.radius = "0.5rem"
|
|
19
|
-
|
|
20
|
-
# Dark mode strategy: :class, :media, or :selector
|
|
9
|
+
# Dark mode strategy
|
|
10
|
+
# Available strategies: :class, :media, :both
|
|
11
|
+
# - :class - Uses .dark class on <html> for manual toggling
|
|
12
|
+
# - :media - Uses @media (prefers-color-scheme: dark) for system preference
|
|
13
|
+
# - :both - Includes both for maximum flexibility
|
|
21
14
|
config.dark_mode = :<%= options[:dark_mode] %>
|
|
22
|
-
|
|
23
|
-
# Icon library to use: :lucide (default)
|
|
24
|
-
# config.icon_library = :lucide
|
|
25
|
-
|
|
26
|
-
# Register custom component aliases
|
|
27
|
-
# config.alias_component :my_button, MyCustomButtonComponent
|
|
28
|
-
|
|
29
|
-
# Register custom themes
|
|
30
|
-
# config.register_theme :corporate, {
|
|
31
|
-
# primary: "210 100% 50%",
|
|
32
|
-
# primary_foreground: "0 0% 100%",
|
|
33
|
-
# ...
|
|
34
|
-
# }
|
|
35
15
|
end
|
|
@@ -1,35 +1,19 @@
|
|
|
1
|
-
# shadcn-rails configuration
|
|
2
|
-
# This file
|
|
1
|
+
# shadcn-rails configuration
|
|
2
|
+
# This file stores component preferences and customizations
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
|
|
4
|
+
# Base color theme
|
|
5
|
+
# Available: neutral, slate, stone, zinc, gray
|
|
6
|
+
base_color: <%= options[:theme] %>
|
|
6
7
|
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
css: "app/assets/stylesheets/application.tailwind.css"
|
|
8
|
+
# Dark mode strategy
|
|
9
|
+
# Available: class, media, both
|
|
10
|
+
dark_mode: <%= options[:dark_mode] %>
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
# Component aliases (optional)
|
|
13
|
+
# Map custom names to shadcn components
|
|
14
|
+
# aliases:
|
|
15
|
+
# btn: button
|
|
16
|
+
# modal: dialog
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# Prefix for Tailwind utility classes (e.g., "tw-")
|
|
19
|
-
prefix: ""
|
|
20
|
-
|
|
21
|
-
# Dark mode configuration
|
|
22
|
-
dark_mode: "<%= options[:dark_mode] %>"
|
|
23
|
-
|
|
24
|
-
# Component aliases for path mapping
|
|
25
|
-
aliases:
|
|
26
|
-
components: "app/components"
|
|
27
|
-
ui: "app/components/shadcn"
|
|
28
|
-
lib: "lib"
|
|
29
|
-
hooks: "app/javascript/hooks"
|
|
30
|
-
|
|
31
|
-
# Custom themes (optional)
|
|
32
|
-
# themes:
|
|
33
|
-
# corporate:
|
|
34
|
-
# primary: "210 100% 50%"
|
|
35
|
-
# primary_foreground: "0 0% 100%"
|
|
18
|
+
# CSS variables (enabled by default)
|
|
19
|
+
css_variables: <%= options[:css_variables] %>
|