bullet_train 1.30.1 → 1.31.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9f6244b94a762526cb882b252268da769b8a57128a9c14146e8f59f02b4458b
4
- data.tar.gz: 77aaadf410ce7bdc6fe99f84e3683e537b0c7699e57186f0f0729d23e42b1978
3
+ metadata.gz: a7631610acdb95b0ad1120d15ac17d0194a53c70848cda583712dc36366364ea
4
+ data.tar.gz: c8fc83f427e8c53ca328585a7ca20ad63a5aed2680b493196d27bcda72800074
5
5
  SHA512:
6
- metadata.gz: b28b0737f177702aea10af4e93180458d5ae7b7b731d5f7925042287ee376872b99b0a9816457d52c0eecd7e8e99d4fae962466104c004db30c92c49517f9eab
7
- data.tar.gz: 609d5613617adb5819c61c2fe076126f1cff5a53074e254de6a622dcde0133c6ea1248ec3c0284acfa9e515fadcf4f05478058336066b8eab461e8487c4680da
6
+ metadata.gz: 9ad2b1f45b90d6c30287f54cad955ee76a712f25a617a43391c7e092f20a09464c9577ee637a8e5875457a7d92492828e3fecf0044fc016aa0237724ac7cbd6c
7
+ data.tar.gz: 8cfc6f818ab40c612d7c5b4e5828c3df9628d70050be6e7493acd7c3656e490870cac2577f17e66d96f591e0430a37bbfc19ba57401b03b183a443a8c2fd1cc3
@@ -1,15 +1,11 @@
1
1
  module DocumentationSupport
2
2
  extend ActiveSupport::Concern
3
3
 
4
- BULLET_TRAIN_BASE_PATH = `bundle show bullet_train`.chomp
4
+ BULLET_TRAIN_BASE_PATH = Gem::Specification.find_by_name("bullet_train").gem_dir
5
5
 
6
6
  def docs
7
7
  target = params[:page].presence || "index"
8
8
 
9
- # TODO For some reason this didn't work on Heroku.
10
- # all_paths = ([Rails.root.to_s] + `bundle show --paths`.lines.map(&:chomp))
11
- # @path = all_paths.map { |path| path + "/docs/#{target}.md" }.detect { |path| File.exist?(path) }
12
-
13
9
  @path = "#{BULLET_TRAIN_BASE_PATH}/docs/#{target}.md"
14
10
 
15
11
  render :docs, layout: "docs"
@@ -4,6 +4,7 @@ module Users::Base
4
4
  included do
5
5
  extend Devise::Models
6
6
  attr_accessor :profile_photo_removal
7
+ attr_accessor :color_scheme_preference # not stored, per-device
7
8
 
8
9
  if two_factor_authentication_enabled?
9
10
  devise :two_factor_authenticatable, :two_factor_backupable
@@ -0,0 +1,9 @@
1
+ <%= form_for [:account, @user], html: {id: dom_id(@user, :details), class: 'form'} do |form| %>
2
+ <% with_field_settings form: form do %>
3
+ <div class="sm:col-span-2"
4
+ data-controller="fields--color-scheme-preference"
5
+ data-action="color-scheme:changed@window->fields--color-scheme-preference#updateRadioButtons input->fields--color-scheme-preference#updateColorSchemePreference">
6
+ <%= render 'shared/fields/buttons', method: :color_scheme_preference %>
7
+ </div>
8
+ <% end %>
9
+ <% end %>
@@ -12,6 +12,13 @@
12
12
  <% box.body.render "account/users/form", user: @user %>
13
13
  <% end %>
14
14
 
15
+ <% unless BulletTrain::Themes::Light.force_color_scheme_to.presence %>
16
+ <%= render 'account/shared/box', divider: true do |box| %>
17
+ <% box.t title: '.preferences.header', description: '.preferences.description' %>
18
+ <% box.body.render "account/users/color_form", user: @user %>
19
+ <% end %>
20
+ <% end %>
21
+
15
22
  <% if two_factor_authentication_enabled? %>
16
23
  <div id="two-factor">
17
24
  <%= render partial: "devise/registrations/two_factor" %>
@@ -11,6 +11,9 @@ en:
11
11
  profile:
12
12
  header: Update Your Profile
13
13
  description: You can update the way your name is displayed and your time zone.
14
+ preferences:
15
+ header: Update Your Preferences
16
+ description: You can update the way this app looks on your current device.
14
17
  email_and_password:
15
18
  header: Update Your Email Address & Password
16
19
  description: When you change these credentials we'll email you a confirmation.
@@ -101,6 +104,17 @@ en:
101
104
  api_title: *locale
102
105
  api_description: *locale
103
106
  help: By default the interface language will adjust based on each team's language setting, but you can set a global personal preference for your account here.
107
+ color_scheme_preference:
108
+ _: &color_scheme_preference Appearance
109
+ label: *color_scheme_preference
110
+ heading: *color_scheme_preference
111
+ api_title: *color_scheme_preference
112
+ api_description: *color_scheme_preference
113
+ options:
114
+ light: Always Light
115
+ dark: Always Dark
116
+ system: Same as System
117
+ help: This only changes the appearance of this device.
104
118
  # 🚅 super scaffolding will insert new fields above this line.
105
119
  created_at:
106
120
  _: &created_at Signed Up At
@@ -198,6 +198,10 @@ These concepts are currently used by the `address_field` to dynamically update t
198
198
 
199
199
  [Read more about Dynamic Forms and Dependent Fields](/docs/field-partials/dynamic-forms-dependent-fields.md)
200
200
 
201
+ ## Color Scheme Awareness in Custom Fields
202
+
203
+ If you're creating custom field partials that need to respond to light/dark mode changes (e.g., for initializing third-party libraries with theme support), see [Responding to Color Scheme Changes](/docs/javascript.md#responding-to-color-scheme-changes) in the JavaScript documentation. The `code_editor` field partial provides a working example of this pattern.
204
+
201
205
  ## Additional Field Partials Documentation
202
206
  - [`address_field`](/docs/field-partials/address-field.md)
203
207
  - [`buttons`](/docs/field-partials/buttons.md)
data/docs/javascript.md CHANGED
@@ -79,3 +79,52 @@ If you experience slow Turbo interactions, check for script tags in the body of
79
79
  <script src="third-party-tracker.js" defer></script>
80
80
  </head>
81
81
  ```
82
+
83
+ ## Responding to Color Scheme Changes
84
+
85
+ Bullet Train's theme system includes a color scheme preference system that manages light/dark mode switching. When the color scheme changes (either through user preference or system settings), a `color-scheme:changed` event is dispatched on the window.
86
+
87
+ ### Accessing the Current Color Scheme
88
+
89
+ The color scheme preference is available globally via `window.colorScheme`:
90
+
91
+ ```javascript
92
+ // Get the current color scheme ('light' or 'dark')
93
+ const current = window.colorScheme.current
94
+
95
+ // Check if dark mode is active
96
+ const isDark = window.colorScheme.current === 'dark'
97
+
98
+ // Get the user's preference ('light', 'dark', or 'system')
99
+ const preference = window.colorScheme.preference
100
+ ```
101
+
102
+ If you want your custom theme to be always light, or always dark, set the following property in your project's `config/initializers/theme.rb` file:
103
+
104
+ ```rb
105
+ # Force the color scheme to :light or :dark.
106
+ # Defaults to nil, which offers users the ability to choose their preference in Account Details.
107
+ BulletTrain::Themes::Light.force_color_scheme_to = :light
108
+ ```
109
+
110
+ ### Listening for Color Scheme Changes
111
+
112
+ To respond to color scheme changes in your Stimulus controllers, listen for the `color-scheme:changed` event on the window:
113
+
114
+ ```erb
115
+ <div data-controller="my-custom-controller"
116
+ data-action="color-scheme:changed@window->my-custom-controller#updateComponentTheme">
117
+ <!-- Your content -->
118
+ </div>
119
+ ```
120
+
121
+ In your Stimulus controller:
122
+
123
+ ```javascript
124
+ export default class extends Controller {
125
+ updateComponentTheme() {
126
+ const isDark = window.colorScheme.current === 'dark'
127
+ // Apply dark or light theme to your component
128
+ }
129
+ }
130
+ ```
@@ -306,4 +306,4 @@ See [`account/users_helper` in BT core repo](https://github.com/bullet-train-co/
306
306
 
307
307
  ### For ejecting a theme partial and modifying it
308
308
 
309
- We recommend firing up a Bullet Train project and using its `bin/resolve` (see docs on [Indirection](indirection)) to get a copy of the partial field locally to modify.
309
+ We recommend firing up a Bullet Train project and using its `bin/resolve` (see docs on [Indirection](/docs/indirection)) to get a copy of the partial field locally to modify.
data/docs/themes.md CHANGED
@@ -132,6 +132,12 @@ This allows the theme engine to resolve which theme in the inheritance chain wil
132
132
 
133
133
  You're going to have to call your theme something and there are practical reasons to not call it something generic. If you're pursuing a heavily customized design, consider allowing the designer or designers who are creating the look-and-feel of your application to name their own masterpiece. Giving it a distinct name will really help differentiate things when you're ready to start introducing additional facets to your application or a totally new look-and-feel down the road.
134
134
 
135
+ ## Dark and Light Mode
136
+
137
+ Bullet Train themes include support for both dark and light color schemes. Users can toggle between dark mode, light mode, or system preference in their Account Details (accessible from the user menu). This preference is per-device and stored in the browser's `LocalStorage`.
138
+
139
+ If you're building custom components that need to respond to color scheme changes, see [Responding to Color Scheme Changes](/docs/javascript.md#responding-to-color-scheme-changes) in the JavaScript documentation.
140
+
135
141
  ## Additional Themes Documentation
136
142
 
137
143
  * [Installing Bullet Train Themes on Other Rails Projects](/docs/themes/on-other-rails-projects.md)
@@ -65,7 +65,7 @@ module BulletTrain
65
65
 
66
66
  # Look for showcase preview.
67
67
  file_name = source_file[:absolute_path].split("/").last
68
- showcase_partials = Dir.glob(`bundle show bullet_train-themes-light`.chomp + "/app/views/showcase/**/*.html.erb")
68
+ showcase_partials = Dir.glob(Gem::Specification.find_by_name("bullet_train-themes-light").gem_dir + "/app/views/showcase/**/*.html.erb")
69
69
  showcase_preview = showcase_partials.find { |partial| partial.split("/").last == file_name }
70
70
  if showcase_preview
71
71
  puts "Ejecting showcase preview for #{source_file[:relative_path]}"
@@ -191,11 +191,11 @@ module BulletTrain
191
191
  # If it's a full path, we need to make sure we're getting it from the right package.
192
192
  _, partial_view_package, partial_path_without_package = @needle.partition(/(bullet_train-core\/)?bullet_train[a-z|\-._0-9]*/)
193
193
 
194
- # Pop off `bullet_train-core` and the gem's version so we can call `bundle show` correctly.
194
+ # Pop off `bullet_train-core` and the gem's version so we can call `Gem::Specification.find_by_name` correctly.
195
195
  partial_view_package.gsub!("bullet_train-core/", "")
196
196
  partial_view_package.gsub!(/[-|.0-9]*$/, "") if partial_view_package.match?(/[-|.0-9]*$/)
197
197
 
198
- local_package_path = `bundle show #{partial_view_package}`.chomp
198
+ local_package_path = Gem::Specification.find_by_name(partial_view_package).gem_dir
199
199
  return local_package_path + partial_path_without_package
200
200
  else
201
201
  puts "You passed the absolute path for a partial literal, but we couldn't find the package name in the string:".red
@@ -223,7 +223,7 @@ module BulletTrain
223
223
  # If the developer enters a partial that is in bullet_train-base like devise/shared/oauth or devise/shared/links,
224
224
  # it will return a string starting with app/ so we simply point them to the file in this repository.
225
225
  if annotated_path.match?(/^<!-- BEGIN app/) && !ejected_theme?
226
- gem_path = `bundle show bullet_train`.chomp
226
+ gem_path = Gem::Specification.find_by_name("bullet_train").gem_dir
227
227
  "#{gem_path}/#{$1}"
228
228
  else
229
229
  $1
@@ -283,7 +283,7 @@ module BulletTrain
283
283
  absolute_file_path
284
284
  else
285
285
  # Search for the file in its respective gem. Fall back to the `light` theme if no gem is available.
286
- gem_path = [`bundle show bullet_train-themes-#{current_theme}`, `bundle show bullet_train-themes-light`].map(&:chomp).find(&:present?)
286
+ gem_path = [Gem::Specification.find_by_name("bullet_train-themes-#{current_theme}").gem_dir, Gem::Specification.find_by_name("bullet_train-themes-light").gem_dir].map(&:chomp).find(&:present?)
287
287
  return nil unless gem_path
288
288
 
289
289
  # At this point we can be more generic since we're inside the gem.
@@ -1,3 +1,3 @@
1
1
  module BulletTrain
2
- VERSION = "1.30.1"
2
+ VERSION = "1.31.0"
3
3
  end
@@ -55,7 +55,7 @@ namespace :bullet_train do
55
55
  gem_names = I18n.t("framework_packages").map { |key, value| key.to_s }
56
56
  gem_names.each do |gem|
57
57
  puts "Searching for locales in #{gem}...".blue
58
- gem_path = `bundle show #{gem}`.chomp
58
+ gem_path = Gem::Specification.find_by_name(gem).gem_dir
59
59
  gem_with_version = gem_path.split("/").last
60
60
  locales = Dir.glob("#{gem_path}/**/config/locales/**/*.yml").reject { |path| path.match?("dummy") }
61
61
  next if locales.empty?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.30.1
4
+ version: 1.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
@@ -500,6 +500,7 @@ files:
500
500
  - app/views/account/two_factors/destroy.html.erb
501
501
  - app/views/account/two_factors/verify.html.erb
502
502
  - app/views/account/users/_breadcrumbs.html.erb
503
+ - app/views/account/users/_color_form.html.erb
503
504
  - app/views/account/users/_fields.html.erb
504
505
  - app/views/account/users/_form.html.erb
505
506
  - app/views/account/users/_oauth.html.erb