kaze 1.1.0 → 1.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 +79 -0
- data/README.md +4 -2
- data/lib/kaze/commands/app/base_stack.rb +6 -4
- data/lib/kaze/commands/app/hotwire_stack.rb +4 -4
- data/lib/kaze/commands/app/inertia_react_stack.rb +16 -13
- data/lib/kaze/commands/app/inertia_vue_stack.rb +16 -13
- data/lib/kaze/version.rb +1 -1
- data/stubs/hotwire/app/assets/tailwind/application.css +21 -0
- data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
- data/stubs/hotwire/app/components/dropdown_link_component.rb +1 -1
- data/stubs/hotwire/app/components/nav_link_component.rb +2 -2
- data/stubs/hotwire/app/components/primary_button_component.rb +1 -1
- data/stubs/hotwire/app/components/responsive_nav_link_component.rb +2 -2
- data/stubs/hotwire/app/components/secondary_button_component.rb +1 -1
- data/stubs/hotwire/app/components/text_input_component.rb +1 -1
- data/stubs/hotwire/app/views/auth/login.html.erb +2 -2
- data/stubs/hotwire/app/views/auth/register.html.erb +1 -1
- data/stubs/hotwire/app/views/auth/verify_email.html.erb +1 -1
- data/stubs/hotwire/app/views/dashboard/index.html.erb +1 -1
- data/stubs/hotwire/app/views/layouts/_navigation.html.erb +2 -2
- data/stubs/hotwire/app/views/layouts/application.html.erb +2 -2
- data/stubs/hotwire/app/views/layouts/guest.html.erb +1 -1
- data/stubs/hotwire/app/views/profile/edit.html.erb +3 -3
- data/stubs/hotwire/app/views/profile/partials/_update_profile_information_form.html.erb +1 -1
- data/stubs/hotwire/app/views/welcome/index.html.erb +4 -4
- data/stubs/inertia-react-ts/app/assets/tailwind/application.css +20 -0
- data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +3 -3
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/VerifyEmail.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +3 -3
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Pages/Welcome.tsx +3 -3
- data/stubs/inertia-react-ts/package.json +1 -5
- data/stubs/inertia-vue-ts/app/assets/tailwind/application.css +20 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +2 -2
- data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +2 -2
- data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +3 -3
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/VerifyEmail.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +3 -3
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Pages/Welcome.vue +3 -3
- data/stubs/inertia-vue-ts/package.json +1 -5
- metadata +9 -8
- data/stubs/default/app/assets/stylesheets/application.tailwind.css +0 -3
- data/stubs/hotwire/config/tailwind.config.js +0 -23
- data/stubs/inertia-react-ts/config/tailwind.config.js +0 -17
- data/stubs/inertia-vue-ts/config/tailwind.config.js +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5e82467be9ca0fc56c33e488d320544f53b023c124975da956167e8778743113
|
|
4
|
+
data.tar.gz: 2d58476a50e097f82aa30a584500870f865e0068181f54a97763556774583099
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 353840a73cff79d608500a90e6e9a2d61e8ff41b1b466d20c268ea6fc66104dfae9d1daee20e7d28b3d1a150d15f04621926fd058afe0dd2efea3bce9d337e79
|
|
7
|
+
data.tar.gz: 19c83590b63318188b6aead492cc89dd766d4db943f1034f4f7e778fcaa01192c109790d6926e8188217fa978b34369ce823a0f373513ecbe02c877ec84a353c
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [1.2.1] - 2026-10-21
|
|
10
|
+
|
|
11
|
+
No changes to scaffolding behaviour. Packaging, documentation and CI only.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- This changelog. It ships in the gem and is linked from the RubyGems page through `changelog_uri`
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- `homepage` and the README point at `github.com/cuonggt/kaze`, the current repository URL, rather than the `gtkvn` name that redirects to it
|
|
20
|
+
- Updated development dependencies, clearing 62 Dependabot advisories against `Gemfile.lock`. The lockfile is not shipped in the gem, so this affects contributors and CI only ([#16](https://github.com/cuonggt/kaze/pull/16))
|
|
21
|
+
- CI reports a single stable `Stub Tests` check alongside the per-stack jobs, so branch protection no longer depends on job names generated from the test matrix ([#18](https://github.com/cuonggt/kaze/pull/18))
|
|
22
|
+
|
|
23
|
+
### Documentation
|
|
24
|
+
|
|
25
|
+
- Recorded that Kaze targets Rails 8.1 on Ruby 3.4, and that Rails 8.0 is not supported ([#17](https://github.com/cuonggt/kaze/pull/17))
|
|
26
|
+
|
|
27
|
+
## [1.2.0] - 2026-10-21
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- `kaze install` no longer fails on current Rails. The `bin/bundle` fallback added in 1.1.0 only covered `install_gems` and `remove_gems`; all three stacks still invoked `bin/bundle` directly to add `tailwindcss-rails`. Rails has not generated that binstub since 7.1, so the step failed, `tailwindcss-rails` never reached the Gemfile, and the subsequent `tailwindcss:build` aborted with `UnrecognizedCommandError` ([#11](https://github.com/cuonggt/kaze/issues/11))
|
|
32
|
+
- A failed Tailwind or Node step now aborts the install instead of printing `Kaze scaffolding installed successfully.` over it. Exit statuses from these commands were discarded, so a completely failed build still reported success
|
|
33
|
+
- `run_command` reads subprocess output as UTF-8 and scrubs invalid bytes. Where no locale is configured — Docker images, CI containers, cron — Ruby tagged output as US-ASCII and any non-ASCII byte aborted the install with `invalid byte sequence in US-ASCII`. Vite triggered this on every Inertia install, via the check mark in its build summary
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- All three stacks migrated to Tailwind CSS v4 ([#14](https://github.com/cuonggt/kaze/pull/14)). `tailwindcss-rails` moves to `~> 4.0`, `config/tailwind.config.js` is removed, and the stylesheet entry point moves from `app/assets/stylesheets/application.tailwind.css` to `app/assets/tailwind/application.css`, which `tailwindcss-rails` 4.x expects. Configuration now lives in CSS: the Inter font as `@theme`, the forms plugin as `@plugin`, and the former `content` globs as `@source` directives. 76 renamed utilities were updated across the stubs, and Preflight's `cursor: default` on buttons is restored to `cursor: pointer`
|
|
38
|
+
- `tailwindcss`, `@tailwindcss/forms`, `autoprefixer` and `postcss` removed from the Inertia stubs. The gem's CLI builds the CSS and Vite only imports the result, so nothing consumed them
|
|
39
|
+
- Vite bumped to `^6.4.4` in the Inertia stubs, clearing two high and four moderate advisories ([#12](https://github.com/cuonggt/kaze/pull/12))
|
|
40
|
+
|
|
41
|
+
Together these take a freshly scaffolded Inertia application from seven npm advisories, five of them high, to zero.
|
|
42
|
+
|
|
43
|
+
### Internal
|
|
44
|
+
|
|
45
|
+
- CI runs against Rails 8.1 on Ruby 3.4, reports every matrix job rather than cancelling siblings on the first failure, and passes for the first time ([#13](https://github.com/cuonggt/kaze/pull/13), [#15](https://github.com/cuonggt/kaze/pull/15))
|
|
46
|
+
|
|
47
|
+
## [1.1.0] - 2025-10-31
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- Fall back to the system `bundle` when `bin/bundle` does not exist. Incomplete; see 1.2.0
|
|
52
|
+
|
|
53
|
+
## [1.0.1] - 2025-02-03
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- Remove the `hotwire_livereload_tags` helper when upgrading to hotwire-livereload v2 ([#10](https://github.com/cuonggt/kaze/pull/10))
|
|
58
|
+
|
|
59
|
+
## [1.0.0] - 2025-02-02
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- Pin `tailwindcss` to v3 ([#6](https://github.com/cuonggt/kaze/pull/6))
|
|
64
|
+
- Unpin the TypeScript version ([#7](https://github.com/cuonggt/kaze/pull/7))
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- Type error in the Login component's `setData` call ([#9](https://github.com/cuonggt/kaze/pull/9))
|
|
69
|
+
|
|
70
|
+
## Earlier releases
|
|
71
|
+
|
|
72
|
+
Releases before 1.0.0 are not catalogued here. See the [tags](https://github.com/cuonggt/kaze/tags) for their history.
|
|
73
|
+
|
|
74
|
+
[Unreleased]: https://github.com/cuonggt/kaze/compare/v1.2.1...HEAD
|
|
75
|
+
[1.2.1]: https://github.com/cuonggt/kaze/compare/v1.2.0...v1.2.1
|
|
76
|
+
[1.2.0]: https://github.com/cuonggt/kaze/compare/v1.1.0...v1.2.0
|
|
77
|
+
[1.1.0]: https://github.com/cuonggt/kaze/compare/v1.0.1...v1.1.0
|
|
78
|
+
[1.0.1]: https://github.com/cuonggt/kaze/compare/v1.0.0...v1.0.1
|
|
79
|
+
[1.0.0]: https://github.com/cuonggt/kaze/compare/v0.19.0...v1.0.0
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Heavily inspired by [Laravel Breeze](https://github.com/laravel/breeze), this gem offers authentication and application starter kits to give you a head start building your new [Rails](https://rubyonrails.org) application. These kits automatically scaffold your application with the routes, controllers, and views you need to register and authenticate your application's users.
|
|
6
6
|
|
|
7
|
-
[Kaze](https://github.com/
|
|
7
|
+
[Kaze](https://github.com/cuonggt/kaze) is a opinionated minimal, simple implementation of all authentication features that a modern web application should have, including login, registration, password reset, email verification. In addition, Kaze includes a simple "profile" page where the user may update their name, email address, and password.
|
|
8
8
|
|
|
9
9
|
Kaze provides scaffolding options based on [Hotwire](https://hotwired.dev) or [Inertia](https://inertiajs.com), with the choice of using Vue or React for the Inertia-based scaffolding.
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@ Kaze provides scaffolding options based on [Hotwire](https://hotwired.dev) or [I
|
|
|
13
13
|
Before creating your first project powered by Kaze, make sure that your local machine has Ruby installed. Ruby can be installed in minutes via [mise](https://mise.jdx.dev).
|
|
14
14
|
|
|
15
15
|
```
|
|
16
|
-
mise use -g ruby@3.
|
|
16
|
+
mise use -g ruby@3.4
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
After you have installed Ruby, you may install `rails` and `kaze` gems globally:
|
|
@@ -23,6 +23,8 @@ gem install rails
|
|
|
23
23
|
gem install kaze
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
Kaze is tested against Rails 8.1 on Ruby 3.4. Rails 8.0 is not supported: ActiveSupport 8.0 passes a `quirks_mode:` option to `JSON.generate` that the `json` gem removed in version 3, which breaks session cookies and `js-routes` in any application built on it. The incompatibility is fixed in Rails 8.1.
|
|
27
|
+
|
|
26
28
|
Then, you may create a new Rails application:
|
|
27
29
|
|
|
28
30
|
```
|
|
@@ -10,7 +10,7 @@ class Kaze::Commands::App::BaseStack
|
|
|
10
10
|
private
|
|
11
11
|
|
|
12
12
|
def bundle_command
|
|
13
|
-
@bundle_command ||= File.exist?("#{Dir.pwd}/bin/bundle") ? "#{Dir.pwd}/bin/bundle" :
|
|
13
|
+
@bundle_command ||= File.exist?("#{Dir.pwd}/bin/bundle") ? "#{Dir.pwd}/bin/bundle" : 'bundle'
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def install_gems(gems = [], group = nil)
|
|
@@ -65,14 +65,16 @@ class Kaze::Commands::App::BaseStack
|
|
|
65
65
|
|
|
66
66
|
def run_command(command)
|
|
67
67
|
Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
|
|
68
|
+
stdout.set_encoding(Encoding::UTF_8)
|
|
69
|
+
stderr.set_encoding(Encoding::UTF_8)
|
|
68
70
|
stdout_thread = Thread.new do
|
|
69
71
|
while line = stdout.gets do
|
|
70
|
-
say line
|
|
72
|
+
say line.scrub
|
|
71
73
|
end
|
|
72
74
|
end
|
|
73
75
|
stderr_thread = Thread.new do
|
|
74
76
|
while line = stderr.gets do
|
|
75
|
-
say line, :red
|
|
77
|
+
say line.scrub, :red
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
stdout_thread.join
|
|
@@ -82,7 +84,7 @@ class Kaze::Commands::App::BaseStack
|
|
|
82
84
|
end
|
|
83
85
|
|
|
84
86
|
def run_commands(commands)
|
|
85
|
-
commands.
|
|
87
|
+
commands.all? { |command| run_command(command).success? }
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
def say(message, color = nil)
|
|
@@ -3,7 +3,7 @@ class Kaze::Commands::App::HotwireStack < Kaze::Commands::App::BaseStack
|
|
|
3
3
|
# Gems...
|
|
4
4
|
return unless remove_gems([ 'sprockets-rails', 'stimulus-rails' ])
|
|
5
5
|
return unless install_gems([ 'propshaft', 'view_component', 'turbo-rails', 'dotenv', 'bcrypt' ])
|
|
6
|
-
run_command("#{
|
|
6
|
+
return unless run_command("#{bundle_command} add tailwindcss-rails --version=\"~> 4.0\"").success?
|
|
7
7
|
return unless install_gems([ 'hotwire-livereload' ], 'development')
|
|
8
8
|
return unless install_gems([ 'factory_bot_rails', 'faker' ], 'development, test')
|
|
9
9
|
|
|
@@ -52,11 +52,11 @@ class Kaze::Commands::App::HotwireStack < Kaze::Commands::App::BaseStack
|
|
|
52
52
|
|
|
53
53
|
# Tailwind...
|
|
54
54
|
FileUtils.copy_file("#{stubs_path}/default/app/assets/stylesheets/application.css", "#{Dir.pwd}/app/assets/stylesheets/application.css")
|
|
55
|
-
|
|
56
|
-
FileUtils.copy_file("#{stubs_path}/hotwire/
|
|
55
|
+
ensure_directory_exists("#{Dir.pwd}/app/assets/tailwind")
|
|
56
|
+
FileUtils.copy_file("#{stubs_path}/hotwire/app/assets/tailwind/application.css", "#{Dir.pwd}/app/assets/tailwind/application.css")
|
|
57
57
|
FileUtils.copy_file("#{stubs_path}/default/bin/dev", "#{Dir.pwd}/bin/dev")
|
|
58
58
|
FileUtils.copy_file("#{stubs_path}/default/Procfile.dev", "#{Dir.pwd}/Procfile.dev")
|
|
59
|
-
run_command("#{Dir.pwd}/bin/rails tailwindcss:build")
|
|
59
|
+
return unless run_command("#{Dir.pwd}/bin/rails tailwindcss:build").success?
|
|
60
60
|
|
|
61
61
|
say ''
|
|
62
62
|
say 'Kaze scaffolding installed successfully.', :green
|
|
@@ -3,7 +3,7 @@ class Kaze::Commands::App::InertiaReactStack < Kaze::Commands::App::BaseStack
|
|
|
3
3
|
# Gems...
|
|
4
4
|
return unless remove_gems([ 'sprockets-rails', 'turbo-rails', 'stimulus-rails' ])
|
|
5
5
|
return unless install_gems([ 'propshaft', 'inertia_rails', 'vite_rails', 'dotenv', 'bcrypt', 'js-routes' ])
|
|
6
|
-
run_command("#{
|
|
6
|
+
return unless run_command("#{bundle_command} add tailwindcss-rails --version=\"~> 4.0\"").success?
|
|
7
7
|
return unless install_gems([ 'factory_bot_rails', 'faker' ], 'development, test')
|
|
8
8
|
|
|
9
9
|
# NPM Packages...
|
|
@@ -51,8 +51,8 @@ class Kaze::Commands::App::InertiaReactStack < Kaze::Commands::App::BaseStack
|
|
|
51
51
|
|
|
52
52
|
# Tailwind / Vite...
|
|
53
53
|
FileUtils.copy_file("#{stubs_path}/default/app/assets/stylesheets/application.css", "#{Dir.pwd}/app/assets/stylesheets/application.css")
|
|
54
|
-
|
|
55
|
-
FileUtils.copy_file("#{stubs_path}/inertia-react-ts/
|
|
54
|
+
ensure_directory_exists("#{Dir.pwd}/app/assets/tailwind")
|
|
55
|
+
FileUtils.copy_file("#{stubs_path}/inertia-react-ts/app/assets/tailwind/application.css", "#{Dir.pwd}/app/assets/tailwind/application.css")
|
|
56
56
|
FileUtils.copy_file("#{stubs_path}/inertia-common/config/vite.json", "#{Dir.pwd}/config/vite.json")
|
|
57
57
|
FileUtils.copy_file("#{stubs_path}/inertia-react-ts/tsconfig.json", "#{Dir.pwd}/tsconfig.json")
|
|
58
58
|
FileUtils.copy_file("#{stubs_path}/inertia-react-ts/vite.config.ts", "#{Dir.pwd}/vite.config.ts")
|
|
@@ -61,20 +61,23 @@ class Kaze::Commands::App::InertiaReactStack < Kaze::Commands::App::BaseStack
|
|
|
61
61
|
FileUtils.copy_file("#{stubs_path}/default/Procfile.dev", "#{Dir.pwd}/Procfile.dev")
|
|
62
62
|
replace_in_file('#vite: bin/vite dev', 'vite: bin/vite dev', "#{Dir.pwd}/Procfile.dev")
|
|
63
63
|
run_command("#{Dir.pwd}/bin/rails generate js_routes:middleware")
|
|
64
|
-
run_command("#{Dir.pwd}/bin/rails tailwindcss:build")
|
|
64
|
+
return unless run_command("#{Dir.pwd}/bin/rails tailwindcss:build").success?
|
|
65
65
|
|
|
66
66
|
say ''
|
|
67
67
|
say 'Installing and building Node dependencies.', :magenta
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
node_dependencies_installed =
|
|
70
|
+
if File.exist?("#{Dir.pwd}/pnpm-lock.yaml")
|
|
71
|
+
run_commands([ 'pnpm install', 'pnpm run build' ])
|
|
72
|
+
elsif File.exist?("#{Dir.pwd}/yarn.lock")
|
|
73
|
+
run_commands([ 'yarn install', 'yarn build' ])
|
|
74
|
+
elsif File.exist?("#{Dir.pwd}/bun.lock") || File.exist?("#{Dir.pwd}/bun.lockb")
|
|
75
|
+
run_commands([ 'bun install', 'bun run build' ])
|
|
76
|
+
else
|
|
77
|
+
run_commands([ 'npm install', 'npm run build' ])
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
return unless node_dependencies_installed
|
|
78
81
|
|
|
79
82
|
say ''
|
|
80
83
|
say 'Kaze scaffolding installed successfully.', :green
|
|
@@ -3,7 +3,7 @@ class Kaze::Commands::App::InertiaVueStack < Kaze::Commands::App::BaseStack
|
|
|
3
3
|
# Gems...
|
|
4
4
|
return unless remove_gems([ 'sprockets-rails', 'turbo-rails', 'stimulus-rails' ])
|
|
5
5
|
return unless install_gems([ 'propshaft', 'inertia_rails', 'vite_rails', 'dotenv', 'bcrypt', 'js-routes' ])
|
|
6
|
-
run_command("#{
|
|
6
|
+
return unless run_command("#{bundle_command} add tailwindcss-rails --version=\"~> 4.0\"").success?
|
|
7
7
|
return unless install_gems([ 'factory_bot_rails', 'faker' ], 'development, test')
|
|
8
8
|
|
|
9
9
|
# NPM Packages...
|
|
@@ -51,8 +51,8 @@ class Kaze::Commands::App::InertiaVueStack < Kaze::Commands::App::BaseStack
|
|
|
51
51
|
|
|
52
52
|
# Tailwind / Vite...
|
|
53
53
|
FileUtils.copy_file("#{stubs_path}/default/app/assets/stylesheets/application.css", "#{Dir.pwd}/app/assets/stylesheets/application.css")
|
|
54
|
-
|
|
55
|
-
FileUtils.copy_file("#{stubs_path}/inertia-vue-ts/
|
|
54
|
+
ensure_directory_exists("#{Dir.pwd}/app/assets/tailwind")
|
|
55
|
+
FileUtils.copy_file("#{stubs_path}/inertia-vue-ts/app/assets/tailwind/application.css", "#{Dir.pwd}/app/assets/tailwind/application.css")
|
|
56
56
|
FileUtils.copy_file("#{stubs_path}/inertia-common/config/vite.json", "#{Dir.pwd}/config/vite.json")
|
|
57
57
|
FileUtils.copy_file("#{stubs_path}/inertia-vue-ts/tsconfig.json", "#{Dir.pwd}/tsconfig.json")
|
|
58
58
|
FileUtils.copy_file("#{stubs_path}/inertia-vue-ts/vite.config.ts", "#{Dir.pwd}/vite.config.ts")
|
|
@@ -61,20 +61,23 @@ class Kaze::Commands::App::InertiaVueStack < Kaze::Commands::App::BaseStack
|
|
|
61
61
|
FileUtils.copy_file("#{stubs_path}/default/Procfile.dev", "#{Dir.pwd}/Procfile.dev")
|
|
62
62
|
replace_in_file('#vite: bin/vite dev', 'vite: bin/vite dev', "#{Dir.pwd}/Procfile.dev")
|
|
63
63
|
run_command("#{Dir.pwd}/bin/rails generate js_routes:middleware")
|
|
64
|
-
run_command("#{Dir.pwd}/bin/rails tailwindcss:build")
|
|
64
|
+
return unless run_command("#{Dir.pwd}/bin/rails tailwindcss:build").success?
|
|
65
65
|
|
|
66
66
|
say ''
|
|
67
67
|
say 'Installing and building Node dependencies.', :magenta
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
node_dependencies_installed =
|
|
70
|
+
if File.exist?("#{Dir.pwd}/pnpm-lock.yaml")
|
|
71
|
+
run_commands([ 'pnpm install', 'pnpm run build' ])
|
|
72
|
+
elsif File.exist?("#{Dir.pwd}/yarn.lock")
|
|
73
|
+
run_commands([ 'yarn install', 'yarn build' ])
|
|
74
|
+
elsif File.exist?("#{Dir.pwd}/bun.lock") || File.exist?("#{Dir.pwd}/bun.lockb")
|
|
75
|
+
run_commands([ 'bun install', 'bun run build' ])
|
|
76
|
+
else
|
|
77
|
+
run_commands([ 'npm install', 'npm run build' ])
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
return unless node_dependencies_installed
|
|
78
81
|
|
|
79
82
|
say ''
|
|
80
83
|
say 'Kaze scaffolding installed successfully.', :green
|
data/lib/kaze/version.rb
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
@plugin "@tailwindcss/forms";
|
|
4
|
+
|
|
5
|
+
@source "../../../public/*.html";
|
|
6
|
+
@source "../../helpers/**/*.rb";
|
|
7
|
+
@source "../../components/**/*";
|
|
8
|
+
@source "../../views/**/*";
|
|
9
|
+
@source "../../javascript/**/*.js";
|
|
10
|
+
|
|
11
|
+
@theme {
|
|
12
|
+
--font-sans: Inter, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* Tailwind v4 Preflight resets buttons to `cursor: default`; keep the v3 behaviour. */
|
|
16
|
+
@layer base {
|
|
17
|
+
button:not(:disabled),
|
|
18
|
+
[role="button"]:not(:disabled) {
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -7,7 +7,7 @@ class DangerButtonComponent < ViewComponent::Base
|
|
|
7
7
|
|
|
8
8
|
def initialize(attributes = {})
|
|
9
9
|
attributes[:type] = attributes[:type] || 'submit'
|
|
10
|
-
attributes[:class] = "inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-
|
|
10
|
+
attributes[:class] = "inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-hidden focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150#{" #{attributes[:class]}" if attributes[:class]}"
|
|
11
11
|
@attributes = attributes.map { |key, attribute| "#{key}=\"#{attribute}\"" }
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -6,7 +6,7 @@ class DropdownLinkComponent < ViewComponent::Base
|
|
|
6
6
|
ERB
|
|
7
7
|
|
|
8
8
|
def initialize(attributes = {})
|
|
9
|
-
attributes[:class] = "block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-
|
|
9
|
+
attributes[:class] = "block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-hidden focus:bg-gray-100 dark:focus:bg-gray-800 transition duration-150 ease-in-out#{" #{attributes[:class]}" if attributes[:class]}"
|
|
10
10
|
@attributes = attributes.map { |key, attribute| "#{key}=\"#{attribute}\"" }
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -7,8 +7,8 @@ class NavLinkComponent < ViewComponent::Base
|
|
|
7
7
|
|
|
8
8
|
def initialize(attributes = {})
|
|
9
9
|
classes = attributes[:active] \
|
|
10
|
-
? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 dark:border-indigo-600 text-sm font-medium leading-5 text-gray-900 dark:text-gray-100 focus:outline-
|
|
11
|
-
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-700 focus:outline-
|
|
10
|
+
? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 dark:border-indigo-600 text-sm font-medium leading-5 text-gray-900 dark:text-gray-100 focus:outline-hidden focus:border-indigo-700 transition duration-150 ease-in-out' \
|
|
11
|
+
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-700 focus:outline-hidden focus:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 dark:focus:border-gray-700 transition duration-150 ease-in-out'
|
|
12
12
|
attributes[:class] = "#{classes}#{" #{attributes[:class]}" if attributes[:class]}"
|
|
13
13
|
@attributes = attributes.without(:active).map { |key, attribute| "#{key}=\"#{attribute}\"" }
|
|
14
14
|
end
|
|
@@ -7,7 +7,7 @@ class PrimaryButtonComponent < ViewComponent::Base
|
|
|
7
7
|
|
|
8
8
|
def initialize(attributes = {})
|
|
9
9
|
attributes[:type] = attributes[:type] || 'submit'
|
|
10
|
-
attributes[:class] = "inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-
|
|
10
|
+
attributes[:class] = "inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150#{" #{attributes[:class]}" if attributes[:class]}"
|
|
11
11
|
@attributes = attributes.map { |key, attribute| "#{key}=\"#{attribute}\"" }
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -7,8 +7,8 @@ class ResponsiveNavLinkComponent < ViewComponent::Base
|
|
|
7
7
|
|
|
8
8
|
def initialize(attributes = {})
|
|
9
9
|
classes = attributes[:active] \
|
|
10
|
-
? 'block w-full ps-3 pe-4 py-2 border-l-4 border-indigo-400 dark:border-indigo-600 text-start text-base font-medium text-indigo-700 dark:text-indigo-300 bg-indigo-50 dark:bg-indigo-900/50 focus:outline-
|
|
11
|
-
: 'block w-full ps-3 pe-4 py-2 border-l-4 border-transparent text-start text-base font-medium text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-gray-300 dark:hover:border-gray-600 focus:outline-
|
|
10
|
+
? 'block w-full ps-3 pe-4 py-2 border-l-4 border-indigo-400 dark:border-indigo-600 text-start text-base font-medium text-indigo-700 dark:text-indigo-300 bg-indigo-50 dark:bg-indigo-900/50 focus:outline-hidden focus:text-indigo-800 dark:focus:text-indigo-200 focus:bg-indigo-100 dark:focus:bg-indigo-900 focus:border-indigo-700 dark:focus:border-indigo-300 transition duration-150 ease-in-out' \
|
|
11
|
+
: 'block w-full ps-3 pe-4 py-2 border-l-4 border-transparent text-start text-base font-medium text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-gray-300 dark:hover:border-gray-600 focus:outline-hidden focus:text-gray-800 dark:focus:text-gray-200 focus:bg-gray-50 dark:focus:bg-gray-700 focus:border-gray-300 dark:focus:border-gray-600 transition duration-150 ease-in-out'
|
|
12
12
|
attributes[:class] = "#{classes}#{" #{attributes[:class]}" if attributes[:class]}"
|
|
13
13
|
@attributes = attributes.without(:active).map { |key, attribute| "#{key}=\"#{attribute}\"" }
|
|
14
14
|
end
|
|
@@ -7,7 +7,7 @@ class SecondaryButtonComponent < ViewComponent::Base
|
|
|
7
7
|
|
|
8
8
|
def initialize(attributes = {})
|
|
9
9
|
attributes[:type] = attributes[:type] || 'button'
|
|
10
|
-
attributes[:class] = "inline-flex items-center px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-500 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-300 uppercase tracking-widest shadow-
|
|
10
|
+
attributes[:class] = "inline-flex items-center px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-500 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-300 uppercase tracking-widest shadow-xs hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 disabled:opacity-25 transition ease-in-out duration-150#{" #{attributes[:class]}" if attributes[:class]}"
|
|
11
11
|
@attributes = attributes.map { |key, attribute| "#{key}=\"#{attribute}\"" }
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -5,7 +5,7 @@ class TextInputComponent < ViewComponent::Base
|
|
|
5
5
|
|
|
6
6
|
def initialize(attributes = {})
|
|
7
7
|
@disabled = attributes[:disabled] || false
|
|
8
|
-
attributes[:class] = "border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-
|
|
8
|
+
attributes[:class] = "border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-xs#{" #{attributes[:class]}" if attributes[:class]}"
|
|
9
9
|
@attributes = attributes.without(:disabled).map { |key, attribute| "#{key}=\"#{attribute}\"" }
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
<!-- Remember Me -->
|
|
17
17
|
<div class="block mt-4">
|
|
18
18
|
<label for="remember_me" class="inline-flex items-center">
|
|
19
|
-
<input id="remember_me" type="checkbox" class="rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-
|
|
19
|
+
<input id="remember_me" type="checkbox" class="rounded-sm dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-xs focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800" name="remember">
|
|
20
20
|
<span class="ms-2 text-sm text-gray-600 dark:text-gray-400">Remember me</span>
|
|
21
21
|
</label>
|
|
22
22
|
</div>
|
|
23
23
|
<div class="flex items-center justify-end mt-4">
|
|
24
|
-
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-
|
|
24
|
+
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="<%= password_request_path %>">
|
|
25
25
|
Forgot your password?
|
|
26
26
|
</a>
|
|
27
27
|
<%= render(PrimaryButtonComponent.new({ class: "ms-4" })) do %>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<%= render(InputErrorComponent.new({ class: "mt-2", message: @form.error_messages[:password_confirmation] })) %>
|
|
25
25
|
</div>
|
|
26
26
|
<div class="flex items-center justify-end mt-4">
|
|
27
|
-
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-
|
|
27
|
+
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="<%= login_path %>">
|
|
28
28
|
Already registered?
|
|
29
29
|
</a>
|
|
30
30
|
<%= render(PrimaryButtonComponent.new({ class: "ms-4" })) do %>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</form>
|
|
17
17
|
<form method="POST" action="<%= logout_path %>">
|
|
18
18
|
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
|
|
19
|
-
<button type="submit" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-
|
|
19
|
+
<button type="submit" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">
|
|
20
20
|
Log Out
|
|
21
21
|
</button>
|
|
22
22
|
</form>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<% end %>
|
|
6
6
|
<div class="py-12">
|
|
7
7
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
|
8
|
-
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-
|
|
8
|
+
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xs sm:rounded-lg">
|
|
9
9
|
<div class="p-6 text-gray-900 dark:text-gray-100">
|
|
10
10
|
You're logged in!
|
|
11
11
|
</div>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<div class="hidden sm:flex sm:items-center sm:ms-6">
|
|
21
21
|
<%= render DropdownComponent.new do |component| %>
|
|
22
22
|
<% component.with_trigger(classes: "") do %>
|
|
23
|
-
<button class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-
|
|
23
|
+
<button class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-hidden transition ease-in-out duration-150">
|
|
24
24
|
<div><%= Current.auth.user.name %></div>
|
|
25
25
|
<div class="ms-1">
|
|
26
26
|
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</div>
|
|
44
44
|
<!-- Hamburger -->
|
|
45
45
|
<div class="-me-2 flex items-center sm:hidden">
|
|
46
|
-
<button x-on:click="open = ! open" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-900 focus:outline-
|
|
46
|
+
<button x-on:click="open = ! open" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-900 focus:outline-hidden focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-500 dark:focus:text-gray-400 transition duration-150 ease-in-out">
|
|
47
47
|
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
|
48
48
|
<path :class="{'hidden': open, 'inline-flex': ! open }" class="inline-flex" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
|
49
49
|
<path :class="{'hidden': ! open, 'inline-flex': open }" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title><%= content_for(:title) || "Rails" %></title>
|
|
7
7
|
<%= csrf_meta_tags %>
|
|
8
8
|
<%= csp_meta_tag %>
|
|
9
|
-
<%= stylesheet_link_tag "tailwind", "
|
|
9
|
+
<%= stylesheet_link_tag "tailwind", "data-turbo-track": Rails.env.production? ? "reload" : "" %>
|
|
10
10
|
<%= stylesheet_link_tag "application", "data-turbo-track": Rails.env.production? ? "reload" : "" %>
|
|
11
11
|
<%= javascript_importmap_tags %>
|
|
12
12
|
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<%= render "layouts/navigation" %>
|
|
18
18
|
<!-- Page Heading -->
|
|
19
19
|
<% if content_for?(:header) %>
|
|
20
|
-
<header class="bg-white dark:bg-gray-800 shadow">
|
|
20
|
+
<header class="bg-white dark:bg-gray-800 shadow-sm">
|
|
21
21
|
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
|
22
22
|
<%= yield :header %>
|
|
23
23
|
</div>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title><%= content_for(:title) || "Rails" %></title>
|
|
7
7
|
<%= csrf_meta_tags %>
|
|
8
8
|
<%= csp_meta_tag %>
|
|
9
|
-
<%= stylesheet_link_tag "tailwind", "
|
|
9
|
+
<%= stylesheet_link_tag "tailwind", "data-turbo-track": Rails.env.production? ? "reload" : "" %>
|
|
10
10
|
<%= stylesheet_link_tag "application", "data-turbo-track": Rails.env.production? ? "reload" : "" %>
|
|
11
11
|
<%= javascript_importmap_tags %>
|
|
12
12
|
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
<% end %>
|
|
6
6
|
<div class="py-12">
|
|
7
7
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
|
|
8
|
-
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
|
8
|
+
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow-sm sm:rounded-lg">
|
|
9
9
|
<div class="max-w-xl">
|
|
10
10
|
<%= render "profile/partials/update_profile_information_form" %>
|
|
11
11
|
</div>
|
|
12
12
|
</div>
|
|
13
|
-
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
|
13
|
+
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow-sm sm:rounded-lg">
|
|
14
14
|
<div class="max-w-xl">
|
|
15
15
|
<%= render "profile/partials/update_password_form" %>
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
|
-
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
|
18
|
+
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow-sm sm:rounded-lg">
|
|
19
19
|
<div class="max-w-xl">
|
|
20
20
|
<%= render "profile/partials/delete_user_form" %>
|
|
21
21
|
</div>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
<div>
|
|
28
28
|
<p class="text-sm mt-2 text-gray-800 dark:text-gray-200">
|
|
29
29
|
Your email address is unverified.
|
|
30
|
-
<button form="send-verification" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-
|
|
30
|
+
<button form="send-verification" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">
|
|
31
31
|
Click here to re-send the verification email.
|
|
32
32
|
</button>
|
|
33
33
|
</p>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title><%= content_for(:title) || "Rails" %></title>
|
|
7
7
|
<%= csrf_meta_tags %>
|
|
8
8
|
<%= csp_meta_tag %>
|
|
9
|
-
<%= stylesheet_link_tag "tailwind", "
|
|
9
|
+
<%= stylesheet_link_tag "tailwind", "data-turbo-track": Rails.env.production? ? "reload" : "" %>
|
|
10
10
|
<%= stylesheet_link_tag "application", "data-turbo-track": Rails.env.production? ? "reload" : "" %>
|
|
11
11
|
<%= javascript_importmap_tags %>
|
|
12
12
|
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>
|
|
@@ -20,19 +20,19 @@
|
|
|
20
20
|
<% if Current.auth.check? %>
|
|
21
21
|
<a
|
|
22
22
|
href="<%= dashboard_url %>"
|
|
23
|
-
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-
|
|
23
|
+
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-hidden focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white"
|
|
24
24
|
v-if="$page.props.auth.user">
|
|
25
25
|
Dashboard
|
|
26
26
|
</a>
|
|
27
27
|
<% else %>
|
|
28
28
|
<a
|
|
29
29
|
href="<%= login_url %>"
|
|
30
|
-
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-
|
|
30
|
+
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-hidden focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white">
|
|
31
31
|
Log in
|
|
32
32
|
</a>
|
|
33
33
|
<a
|
|
34
34
|
href="<%= register_url %>"
|
|
35
|
-
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-
|
|
35
|
+
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-hidden focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white">
|
|
36
36
|
Register
|
|
37
37
|
</a>
|
|
38
38
|
<% end %>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
@plugin "@tailwindcss/forms";
|
|
4
|
+
|
|
5
|
+
@source "../../../public/*.html";
|
|
6
|
+
@source "../../helpers/**/*.rb";
|
|
7
|
+
@source "../../views/**/*";
|
|
8
|
+
@source "../../javascript/**/*.tsx";
|
|
9
|
+
|
|
10
|
+
@theme {
|
|
11
|
+
--font-sans: Inter, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Tailwind v4 Preflight resets buttons to `cursor: default`; keep the v3 behaviour. */
|
|
15
|
+
@layer base {
|
|
16
|
+
button:not(:disabled),
|
|
17
|
+
[role="button"]:not(:disabled) {
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -5,7 +5,7 @@ export default function Checkbox({ className = '', ...props }: InputHTMLAttribut
|
|
|
5
5
|
<input
|
|
6
6
|
{...props}
|
|
7
7
|
type="checkbox"
|
|
8
|
-
className={`rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-
|
|
8
|
+
className={`rounded-sm dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-xs focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800 ${className}`}
|
|
9
9
|
/>
|
|
10
10
|
)
|
|
11
11
|
}
|