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.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -2
  3. data/README.md +21 -8
  4. data/__mocks__/@floating-ui/dom.js +67 -0
  5. data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +23 -2
  6. data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +4 -31
  7. data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +32 -41
  8. data/app/assets/javascripts/shadcn/controllers/hover_card_controller.js +29 -55
  9. data/app/assets/javascripts/shadcn/controllers/popover_controller.js +29 -54
  10. data/app/assets/javascripts/shadcn/controllers/select_controller.js +26 -8
  11. data/app/assets/javascripts/shadcn/controllers/tooltip_controller.js +28 -59
  12. data/app/assets/javascripts/shadcn/index.js +7 -1
  13. data/app/assets/javascripts/shadcn/utils/floating.js +179 -0
  14. data/app/assets/stylesheets/shadcn/base.css +32 -0
  15. data/app/components/shadcn/accordion_component.html.erb +8 -0
  16. data/app/components/shadcn/accordion_component.rb +6 -15
  17. data/app/components/shadcn/alert_component.html.erb +6 -0
  18. data/app/components/shadcn/alert_component.rb +0 -18
  19. data/app/components/shadcn/alert_dialog_component.html.erb +12 -0
  20. data/app/components/shadcn/alert_dialog_component.rb +7 -27
  21. data/app/components/shadcn/aspect_ratio_component.html.erb +7 -0
  22. data/app/components/shadcn/aspect_ratio_component.rb +4 -19
  23. data/app/components/shadcn/avatar_component.html.erb +20 -0
  24. data/app/components/shadcn/avatar_component.rb +8 -36
  25. data/app/components/shadcn/badge_component.html.erb +1 -0
  26. data/app/components/shadcn/badge_component.rb +0 -11
  27. data/app/components/shadcn/base_component.rb +15 -2
  28. data/app/components/shadcn/breadcrumb_component.html.erb +5 -0
  29. data/app/components/shadcn/breadcrumb_component.rb +6 -16
  30. data/app/components/shadcn/button_component.html.erb +18 -0
  31. data/app/components/shadcn/button_component.rb +1 -41
  32. data/app/components/shadcn/card_component.html.erb +8 -0
  33. data/app/components/shadcn/card_component.rb +2 -6
  34. data/app/components/shadcn/checkbox_component.html.erb +32 -0
  35. data/app/components/shadcn/checkbox_component.rb +4 -43
  36. data/app/components/shadcn/collapsible_component.html.erb +8 -0
  37. data/app/components/shadcn/collapsible_component.rb +6 -15
  38. data/app/components/shadcn/context_menu_component.html.erb +11 -0
  39. data/app/components/shadcn/context_menu_component.rb +6 -26
  40. data/app/components/shadcn/dialog_component.html.erb +14 -0
  41. data/app/components/shadcn/dialog_component.rb +8 -29
  42. data/app/components/shadcn/drawer_component.html.erb +12 -0
  43. data/app/components/shadcn/drawer_component.rb +7 -27
  44. data/app/components/shadcn/dropdown_menu_component.html.erb +14 -0
  45. data/app/components/shadcn/dropdown_menu_component.rb +9 -29
  46. data/app/components/shadcn/field_component.rb +7 -8
  47. data/app/components/shadcn/hover_card_component.html.erb +12 -0
  48. data/app/components/shadcn/hover_card_component.rb +7 -26
  49. data/app/components/shadcn/input_component.html.erb +18 -0
  50. data/app/components/shadcn/input_component.rb +2 -27
  51. data/app/components/shadcn/input_otp_component.rb +3 -3
  52. data/app/components/shadcn/kbd_component.html.erb +1 -0
  53. data/app/components/shadcn/kbd_component.rb +3 -10
  54. data/app/components/shadcn/label_component.html.erb +3 -0
  55. data/app/components/shadcn/label_component.rb +2 -18
  56. data/app/components/shadcn/menubar_component.html.erb +6 -0
  57. data/app/components/shadcn/menubar_component.rb +4 -15
  58. data/app/components/shadcn/native_select_component.html.erb +22 -0
  59. data/app/components/shadcn/native_select_component.rb +9 -39
  60. data/app/components/shadcn/navigation_menu_component.html.erb +6 -0
  61. data/app/components/shadcn/navigation_menu_component.rb +4 -15
  62. data/app/components/shadcn/pagination_component.html.erb +5 -0
  63. data/app/components/shadcn/pagination_component.rb +11 -15
  64. data/app/components/shadcn/popover_component.html.erb +15 -0
  65. data/app/components/shadcn/popover_component.rb +10 -30
  66. data/app/components/shadcn/progress_component.html.erb +13 -0
  67. data/app/components/shadcn/progress_component.rb +6 -26
  68. data/app/components/shadcn/radio_group_component.html.erb +8 -0
  69. data/app/components/shadcn/radio_group_component.rb +12 -26
  70. data/app/components/shadcn/scroll_area_component.html.erb +7 -0
  71. data/app/components/shadcn/scroll_area_component.rb +4 -16
  72. data/app/components/shadcn/select_component.html.erb +46 -0
  73. data/app/components/shadcn/select_component.rb +6 -80
  74. data/app/components/shadcn/separator_component.html.erb +5 -0
  75. data/app/components/shadcn/separator_component.rb +6 -14
  76. data/app/components/shadcn/sheet_component.html.erb +12 -0
  77. data/app/components/shadcn/sheet_component.rb +7 -27
  78. data/app/components/shadcn/sidebar_component.rb +2 -2
  79. data/app/components/shadcn/skeleton_component.html.erb +1 -0
  80. data/app/components/shadcn/skeleton_component.rb +4 -2
  81. data/app/components/shadcn/slider_component.html.erb +12 -0
  82. data/app/components/shadcn/slider_component.rb +2 -21
  83. data/app/components/shadcn/spinner_component.html.erb +18 -0
  84. data/app/components/shadcn/spinner_component.rb +2 -30
  85. data/app/components/shadcn/switch_component.html.erb +72 -0
  86. data/app/components/shadcn/switch_component.rb +4 -82
  87. data/app/components/shadcn/table_component.html.erb +9 -0
  88. data/app/components/shadcn/table_component.rb +2 -10
  89. data/app/components/shadcn/tabs_component.html.erb +8 -0
  90. data/app/components/shadcn/tabs_component.rb +4 -17
  91. data/app/components/shadcn/textarea_component.html.erb +13 -0
  92. data/app/components/shadcn/textarea_component.rb +6 -22
  93. data/app/components/shadcn/toast_component.html.erb +36 -0
  94. data/app/components/shadcn/toast_component.rb +6 -54
  95. data/app/components/shadcn/toggle_component.html.erb +12 -0
  96. data/app/components/shadcn/toggle_component.rb +6 -21
  97. data/app/components/shadcn/toggle_group_component.html.erb +14 -0
  98. data/app/components/shadcn/toggle_group_component.rb +6 -29
  99. data/app/components/shadcn/tooltip_component.html.erb +20 -0
  100. data/app/components/shadcn/tooltip_component.rb +13 -38
  101. data/lib/generators/shadcn/add/USAGE +24 -0
  102. data/lib/generators/shadcn/add/add_generator.rb +279 -0
  103. data/lib/generators/shadcn/install/USAGE +22 -0
  104. data/lib/generators/shadcn/install/install_generator.rb +8 -3
  105. data/lib/generators/shadcn/install/templates/initializer.rb.tt +7 -27
  106. data/lib/generators/shadcn/install/templates/shadcn.yml.tt +15 -31
  107. data/lib/shadcn/rails/version.rb +1 -1
  108. metadata +47 -45
  109. data/.dockerignore +0 -40
  110. data/CLAUDE.md +0 -612
  111. data/PROGRESS.md +0 -495
  112. data/Rakefile +0 -95
  113. data/__tests__/controllers/__snapshots__/calendar_controller.test.js.snap +0 -13
  114. data/__tests__/controllers/__snapshots__/popover_controller.test.js.snap +0 -46
  115. data/__tests__/controllers/__snapshots__/sheet_controller.test.js.snap +0 -111
  116. data/__tests__/controllers/__snapshots__/tabs_controller.test.js.snap +0 -27
  117. data/__tests__/controllers/accordion_controller.test.js +0 -904
  118. data/__tests__/controllers/calendar_controller.test.js +0 -1370
  119. data/__tests__/controllers/carousel_controller.test.js +0 -912
  120. data/__tests__/controllers/checkbox_controller.test.js +0 -454
  121. data/__tests__/controllers/collapsible_controller.test.js +0 -407
  122. data/__tests__/controllers/combobox_controller.test.js +0 -971
  123. data/__tests__/controllers/context_menu_controller.test.js +0 -905
  124. data/__tests__/controllers/date_picker_controller.test.js +0 -636
  125. data/__tests__/controllers/dialog_controller.test.js +0 -878
  126. data/__tests__/controllers/drawer_controller.test.js +0 -995
  127. data/__tests__/controllers/menubar_controller.test.js +0 -737
  128. data/__tests__/controllers/navigation_menu_controller.test.js +0 -599
  129. data/__tests__/controllers/popover_controller.test.js +0 -982
  130. data/__tests__/controllers/radio_group_controller.test.js +0 -640
  131. data/__tests__/controllers/resizable_controller.test.js +0 -680
  132. data/__tests__/controllers/select_controller.test.js +0 -678
  133. data/__tests__/controllers/sheet_controller.test.js +0 -986
  134. data/__tests__/controllers/slider_controller.test.js +0 -1036
  135. data/__tests__/controllers/switch_controller.test.js +0 -424
  136. data/__tests__/controllers/tabs_controller.test.js +0 -907
  137. data/__tests__/controllers/toggle_group_controller.test.js +0 -839
  138. data/__tests__/controllers/tooltip_controller.test.js +0 -808
  139. data/__tests__/helpers/stimulus-test-helper.js +0 -203
  140. data/babel.config.cjs +0 -5
  141. data/bin/bump +0 -321
  142. data/bin/console +0 -11
  143. data/bin/release +0 -205
  144. data/bin/setup +0 -8
  145. data/bin/test +0 -75
  146. data/jest.config.js +0 -19
  147. data/jest.setup.js +0 -8
  148. data/lib/generators/shadcn/component/component_generator.rb +0 -188
  149. data/lib/generators/shadcn/theme/theme_generator.rb +0 -128
  150. data/package-lock.json +0 -7438
  151. data/package.json +0 -71
  152. data/rollup.config.js +0 -29
data/bin/release DELETED
@@ -1,205 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Release script for shadcn-rails
5
- # Publishes both Ruby gem and npm package
6
- #
7
- # Usage:
8
- # bin/release # Release current version
9
- # bin/release --dry-run # Show what would be released without publishing
10
-
11
- require "json"
12
- require "open3"
13
-
14
- VERSION_FILE = File.expand_path("../lib/shadcn/rails/version.rb", __dir__)
15
- PACKAGE_JSON = File.expand_path("../package.json", __dir__)
16
- GEMSPEC_FILE = File.expand_path("../shadcn-rails.gemspec", __dir__)
17
-
18
- class Release
19
- def initialize(dry_run: false)
20
- @dry_run = dry_run
21
- end
22
-
23
- def run
24
- puts "\n🚀 shadcn-rails Release\n"
25
- puts "=" * 50
26
-
27
- check_clean_working_directory
28
- check_versions_in_sync
29
- run_tests
30
- build_packages
31
- publish_packages unless @dry_run
32
- create_github_release unless @dry_run
33
-
34
- puts "\n✅ Release complete!"
35
- end
36
-
37
- private
38
-
39
- def ruby_version
40
- content = File.read(VERSION_FILE)
41
- content.match(/VERSION = "(.+?)"/)[1]
42
- end
43
-
44
- def npm_version
45
- package = JSON.parse(File.read(PACKAGE_JSON))
46
- package["version"]
47
- end
48
-
49
- def check_clean_working_directory
50
- step "Checking working directory"
51
-
52
- status, = run_command("git status --porcelain")
53
- unless status.empty?
54
- error "Working directory is not clean. Please commit or stash changes."
55
- end
56
-
57
- success "Working directory is clean"
58
- end
59
-
60
- def check_versions_in_sync
61
- step "Checking version sync"
62
-
63
- rv = ruby_version
64
- nv = npm_version
65
-
66
- if rv != nv
67
- error "Versions are out of sync!\n Ruby: #{rv}\n npm: #{nv}\n\nRun: bin/bump-version #{rv}"
68
- end
69
-
70
- @version = rv
71
- success "Versions in sync: #{@version}"
72
- end
73
-
74
- def run_tests
75
- step "Running tests"
76
-
77
- _, success = run_command("bin/test", stream: true)
78
- error "Tests failed" unless success
79
- end
80
-
81
- def build_packages
82
- step "Building packages"
83
-
84
- # Build npm package
85
- puts " Building npm package..."
86
- _, success = run_command("npm run build")
87
- error "npm build failed" unless success
88
-
89
- # Build gem
90
- puts " Building gem..."
91
- _, success = run_command("gem build #{GEMSPEC_FILE}")
92
- error "gem build failed" unless success
93
-
94
- @gem_file = "shadcn-rails-#{@version}.gem"
95
- unless File.exist?(@gem_file)
96
- error "Gem file not found: #{@gem_file}"
97
- end
98
-
99
- success "Packages built successfully"
100
- end
101
-
102
- def publish_packages
103
- step "Publishing packages"
104
-
105
- # Publish to RubyGems
106
- puts " Publishing to RubyGems..."
107
- _, success = run_command("gem push #{@gem_file}")
108
- unless success
109
- puts " ⚠️ Failed to publish gem (may need: gem signin)"
110
- end
111
-
112
- # Publish to npm
113
- puts " Publishing to npm..."
114
- _, success = run_command("npm publish")
115
- unless success
116
- puts " ⚠️ Failed to publish to npm (may need: npm login)"
117
- end
118
-
119
- # Clean up gem file
120
- File.delete(@gem_file) if File.exist?(@gem_file)
121
-
122
- success "Packages published"
123
- end
124
-
125
- def create_github_release
126
- step "Creating GitHub release"
127
-
128
- # Check if gh CLI is available
129
- _, success = run_command("which gh")
130
- unless success
131
- puts " ⚠️ GitHub CLI not found. Skipping GitHub release."
132
- puts " Install with: brew install gh"
133
- return
134
- end
135
-
136
- # Create tag if it doesn't exist
137
- tag = "v#{@version}"
138
- _, tag_exists = run_command("git rev-parse #{tag}")
139
-
140
- unless tag_exists
141
- puts " Creating tag #{tag}..."
142
- run_command("git tag #{tag}")
143
- run_command("git push origin #{tag}")
144
- end
145
-
146
- # Create GitHub release
147
- puts " Creating GitHub release..."
148
- changelog_section = extract_changelog_section
149
-
150
- run_command(%(gh release create #{tag} --title "v#{@version}" --notes "#{changelog_section}" #{@gem_file}))
151
-
152
- success "GitHub release created"
153
- end
154
-
155
- def extract_changelog_section
156
- return "Release v#{@version}" unless File.exist?("CHANGELOG.md")
157
-
158
- content = File.read("CHANGELOG.md")
159
- # Extract section for current version
160
- match = content.match(/## \[#{Regexp.escape(@version)}\].*?\n(.*?)(?=\n## \[|$)/m)
161
- match ? match[1].strip : "Release v#{@version}"
162
- end
163
-
164
- def step(message)
165
- puts "\n📦 #{message}..."
166
- end
167
-
168
- def success(message)
169
- puts " ✓ #{message}"
170
- end
171
-
172
- def error(message)
173
- puts "\n❌ Error: #{message}"
174
- exit 1
175
- end
176
-
177
- def run_command(cmd, stream: false)
178
- if @dry_run && cmd.match?(/gem push|npm publish|gh release|git tag|git push/)
179
- puts " [DRY RUN] Would run: #{cmd}"
180
- return ["", true]
181
- end
182
-
183
- if stream
184
- success = system(cmd)
185
- ["", success]
186
- else
187
- output, status = Open3.capture2e(cmd)
188
- [output.strip, status.success?]
189
- end
190
- end
191
- end
192
-
193
- # Parse arguments
194
- dry_run = ARGV.include?("--dry-run")
195
-
196
- if ARGV.include?("--help") || ARGV.include?("-h")
197
- puts "Usage: bin/release [options]"
198
- puts ""
199
- puts "Options:"
200
- puts " --dry-run Show what would be released without publishing"
201
- puts " --help Show this help message"
202
- exit 0
203
- end
204
-
205
- Release.new(dry_run: dry_run).run
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/bin/test DELETED
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Run all tests (Ruby and JavaScript)
5
- #
6
- # Usage:
7
- # bin/test # Run all tests
8
- # bin/test ruby # Run only Ruby tests
9
- # bin/test js # Run only JavaScript tests
10
-
11
- require "open3"
12
-
13
- class TestRunner
14
- def initialize(filter: nil)
15
- @filter = filter
16
- @failed = false
17
- end
18
-
19
- def run
20
- puts "\n🧪 Running tests\n"
21
- puts "=" * 50
22
-
23
- run_ruby_tests if @filter.nil? || @filter == "ruby"
24
- run_js_tests if @filter.nil? || @filter == "js"
25
-
26
- puts "\n" + "=" * 50
27
- if @failed
28
- puts "❌ Some tests failed"
29
- exit 1
30
- else
31
- puts "✅ All tests passed"
32
- end
33
- end
34
-
35
- private
36
-
37
- def run_ruby_tests
38
- step "Ruby tests"
39
- success = system("bundle exec rake test")
40
- @failed = true unless success
41
- end
42
-
43
- def run_js_tests
44
- step "JavaScript tests"
45
- success = system("npm test")
46
- @failed = true unless success
47
- end
48
-
49
- def step(name)
50
- puts "\n→ #{name}\n\n"
51
- end
52
- end
53
-
54
- # Parse arguments
55
- filter = case ARGV[0]
56
- when "ruby", "rb"
57
- "ruby"
58
- when "js", "javascript", "node"
59
- "js"
60
- when "-h", "--help"
61
- puts "Usage: bin/test [ruby|js]"
62
- puts ""
63
- puts " bin/test Run all tests"
64
- puts " bin/test ruby Run only Ruby tests"
65
- puts " bin/test js Run only JavaScript tests"
66
- exit 0
67
- when nil
68
- nil
69
- else
70
- puts "Unknown filter: #{ARGV[0]}"
71
- puts "Use: bin/test [ruby|js]"
72
- exit 1
73
- end
74
-
75
- TestRunner.new(filter: filter).run
data/jest.config.js DELETED
@@ -1,19 +0,0 @@
1
- /** @type {import('jest').Config} */
2
- export default {
3
- testEnvironment: 'jsdom',
4
- testMatch: ['**/__tests__/**/*.test.js'],
5
- moduleFileExtensions: ['js', 'json'],
6
- transform: {
7
- '^.+\\.js$': 'babel-jest'
8
- },
9
- transformIgnorePatterns: [
10
- '/node_modules/(?!@hotwired/stimulus|stimulus-use)'
11
- ],
12
- setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
13
- collectCoverageFrom: [
14
- 'app/assets/javascripts/shadcn/controllers/**/*.js',
15
- '!**/node_modules/**'
16
- ],
17
- coverageDirectory: 'coverage',
18
- verbose: true
19
- }
data/jest.setup.js DELETED
@@ -1,8 +0,0 @@
1
- import '@testing-library/jest-dom'
2
-
3
- // Make jest globals available in ESM modules
4
- import { jest } from '@jest/globals'
5
- globalThis.jest = jest
6
-
7
- // Mock scrollIntoView since JSDOM doesn't implement it
8
- Element.prototype.scrollIntoView = jest.fn()
@@ -1,188 +0,0 @@
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 individual shadcn components
9
- # Usage: rails generate shadcn:component button card dialog
10
- class ComponentGenerator < Rails::Generators::Base
11
- source_root File.expand_path("templates", __dir__)
12
-
13
- argument :components, type: :array, default: [], banner: "component [component ...]"
14
-
15
- class_option :all, type: :boolean, default: false,
16
- desc: "Install all available components"
17
- class_option :list, type: :boolean, default: false,
18
- desc: "List all available components"
19
-
20
- desc "Adds shadcn-rails components to your application"
21
-
22
- # List of all available components
23
- AVAILABLE_COMPONENTS = %w[
24
- accordion
25
- alert
26
- avatar
27
- badge
28
- button
29
- card
30
- checkbox
31
- collapsible
32
- dialog
33
- dropdown_menu
34
- input
35
- label
36
- popover
37
- progress
38
- scroll_area
39
- select
40
- separator
41
- sheet
42
- skeleton
43
- switch
44
- table
45
- tabs
46
- textarea
47
- toast
48
- tooltip
49
- ].freeze
50
-
51
- def validate_components
52
- if options[:list]
53
- display_available_components
54
- exit 0
55
- end
56
-
57
- if options[:all]
58
- @components_to_install = AVAILABLE_COMPONENTS
59
- else
60
- validate_requested_components
61
- @components_to_install = components
62
- end
63
- end
64
-
65
- def display_installation_plan
66
- say ""
67
- say "Installing #{@components_to_install.length} component(s):", :green
68
- @components_to_install.each { |c| say " - #{c}" }
69
- say ""
70
- end
71
-
72
- def install_components
73
- @components_to_install.each do |component|
74
- install_component(component)
75
- end
76
- end
77
-
78
- def display_usage_examples
79
- say ""
80
- say "=" * 60, :green
81
- say " Components installed successfully!", :green
82
- say "=" * 60, :green
83
- say ""
84
- say "Example usage:", :yellow
85
-
86
- @components_to_install.first(3).each do |component|
87
- display_component_example(component)
88
- end
89
-
90
- say ""
91
- end
92
-
93
- private
94
-
95
- def display_available_components
96
- say ""
97
- say "Available shadcn-rails components:", :green
98
- say ""
99
- AVAILABLE_COMPONENTS.each { |c| say " - #{c}" }
100
- say ""
101
- say "Usage: rails generate shadcn:component button card dialog"
102
- say " rails generate shadcn:component --all"
103
- say ""
104
- end
105
-
106
- def validate_requested_components
107
- if components.empty?
108
- say "Error: Please specify at least one component or use --all", :red
109
- say ""
110
- display_available_components
111
- exit 1
112
- end
113
-
114
- invalid = components - AVAILABLE_COMPONENTS
115
- if invalid.any?
116
- say "Error: Unknown component(s): #{invalid.join(', ')}", :red
117
- say ""
118
- display_available_components
119
- exit 1
120
- end
121
- end
122
-
123
- def install_component(name)
124
- # Components are already available from the gem
125
- # This generator just confirms installation and provides usage info
126
- say " ✓ #{name.titleize}Component is available", :green
127
- end
128
-
129
- def display_component_example(component)
130
- case component
131
- when "button"
132
- say <<~EXAMPLE
133
-
134
- Button:
135
- <%= render Shadcn::ButtonComponent.new(variant: :primary) do %>
136
- Click me
137
- <% end %>
138
- EXAMPLE
139
- when "card"
140
- say <<~EXAMPLE
141
-
142
- Card:
143
- <%= render Shadcn::CardComponent.new do |card| %>
144
- <% card.with_header do %>
145
- <% card.with_title { "Card Title" } %>
146
- <% end %>
147
- <% card.with_content { "Card content" } %>
148
- <% end %>
149
- EXAMPLE
150
- when "dialog"
151
- say <<~EXAMPLE
152
-
153
- Dialog:
154
- <%= render Shadcn::DialogComponent.new do |dialog| %>
155
- <% dialog.with_trigger do %>
156
- <%= render Shadcn::ButtonComponent.new { "Open" } %>
157
- <% end %>
158
- <% dialog.with_content do |content| %>
159
- <% content.with_title { "Dialog Title" } %>
160
- Dialog content here
161
- <% end %>
162
- <% end %>
163
- EXAMPLE
164
- when "input"
165
- say <<~EXAMPLE
166
-
167
- Input:
168
- <%= render Shadcn::LabelComponent.new(for: "email") { "Email" } %>
169
- <%= render Shadcn::InputComponent.new(
170
- type: "email",
171
- id: "email",
172
- name: "email",
173
- placeholder: "Enter your email"
174
- ) %>
175
- EXAMPLE
176
- else
177
- say <<~EXAMPLE
178
-
179
- #{component.titleize}:
180
- <%= render Shadcn::#{component.camelize}Component.new do %>
181
- Content here
182
- <% end %>
183
- EXAMPLE
184
- end
185
- end
186
- end
187
- end
188
- end
@@ -1,128 +0,0 @@
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 switching or customizing themes
9
- # Usage: rails generate shadcn:theme slate
10
- class ThemeGenerator < Rails::Generators::Base
11
- source_root File.expand_path("templates", __dir__)
12
-
13
- argument :theme_name, type: :string, default: "neutral",
14
- banner: "theme_name"
15
-
16
- class_option :list, type: :boolean, default: false,
17
- desc: "List all available themes"
18
-
19
- desc "Changes the shadcn-rails theme or creates a custom theme"
20
-
21
- AVAILABLE_THEMES = %w[neutral slate stone zinc gray].freeze
22
-
23
- def validate_theme
24
- if options[:list]
25
- display_available_themes
26
- exit 0
27
- end
28
-
29
- unless AVAILABLE_THEMES.include?(theme_name)
30
- say "Error: Unknown theme '#{theme_name}'", :red
31
- display_available_themes
32
- exit 1
33
- end
34
- end
35
-
36
- def update_initializer
37
- initializer_path = "config/initializers/shadcn.rb"
38
-
39
- if File.exist?(initializer_path)
40
- gsub_file initializer_path,
41
- /config\.base_color = ["']?\w+["']?/,
42
- "config.base_color = \"#{theme_name}\""
43
- say "Updated initializer to use '#{theme_name}' theme", :green
44
- else
45
- say "Initializer not found. Run 'rails generate shadcn:install' first.", :yellow
46
- end
47
- end
48
-
49
- def update_config_file
50
- config_path = "config/shadcn.yml"
51
-
52
- if File.exist?(config_path)
53
- gsub_file config_path,
54
- /base_color: \w+/,
55
- "base_color: #{theme_name}"
56
- say "Updated shadcn.yml to use '#{theme_name}' theme", :green
57
- end
58
- end
59
-
60
- def update_stylesheet
61
- # Check for theme import in stylesheet
62
- stylesheet_path = "app/assets/stylesheets/application.tailwind.css"
63
-
64
- if File.exist?(stylesheet_path)
65
- content = File.read(stylesheet_path)
66
-
67
- # Remove existing theme import
68
- AVAILABLE_THEMES.each do |theme|
69
- next if theme == "neutral" # neutral uses base.css
70
- gsub_file stylesheet_path, /@import ["']shadcn\/themes\/#{theme}["'];\n?/, ""
71
- end
72
-
73
- # Add new theme import if not neutral
74
- unless theme_name == "neutral"
75
- inject_into_file stylesheet_path, after: '@import "shadcn/base";' do
76
- "\n@import \"shadcn/themes/#{theme_name}\";"
77
- end
78
- end
79
-
80
- say "Updated stylesheet with '#{theme_name}' theme", :green
81
- end
82
- end
83
-
84
- def display_completion_message
85
- say ""
86
- say "Theme changed to '#{theme_name}'!", :green
87
- say ""
88
- say "The following colors are now active:", :yellow
89
- display_theme_preview(theme_name)
90
- say ""
91
- end
92
-
93
- private
94
-
95
- def display_available_themes
96
- say ""
97
- say "Available themes:", :green
98
- say ""
99
- AVAILABLE_THEMES.each do |theme|
100
- say " - #{theme}"
101
- end
102
- say ""
103
- say "Usage: rails generate shadcn:theme slate"
104
- say ""
105
- end
106
-
107
- def display_theme_preview(theme)
108
- case theme
109
- when "neutral"
110
- say " Primary: Pure black/white"
111
- say " Style: Clean, minimal"
112
- when "slate"
113
- say " Primary: Cool blue-gray"
114
- say " Style: Professional, corporate"
115
- when "stone"
116
- say " Primary: Warm gray-brown"
117
- say " Style: Earthy, natural"
118
- when "zinc"
119
- say " Primary: Cool gray"
120
- say " Style: Modern, sleek"
121
- when "gray"
122
- say " Primary: True gray"
123
- say " Style: Neutral, balanced"
124
- end
125
- end
126
- end
127
- end
128
- end