1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
# frozen_string_literal: true
require "view_component/deprecation"
module ViewComponent
class Config
class << self
# `new` without any arguments initializes the default configuration, but
# it's important to differentiate in case that's no longer the case in
# future.
alias_method :default, :new
def defaults
ActiveSupport::OrderedOptions.new.merge!({
generate: default_generate_options,
previews: default_previews_options,
instrumentation_enabled: false
})
end
# @!attribute generate
# @return [ActiveSupport::OrderedOptions]
# The subset of configuration options relating to generators.
#
# All options under this namespace default to `false` unless otherwise
# stated.
#
# #### `#path`
#
# Where to put generated components. Defaults to `app/components`:
#
# config.view_component.generate.path = "lib/components"
#
# #### `#sidecar`
#
# Always generate a component with a sidecar directory:
#
# config.view_component.generate.sidecar = true
#
# #### `#stimulus_controller`
#
# Always generate a Stimulus controller alongside the component:
#
# config.view_component.generate.stimulus_controller = true
#
# #### `#typescript`
#
# Generate TypeScript files instead of JavaScript files:
#
# config.view_component.generate.typescript = true
#
# #### `#locale`
#
# Always generate translations file alongside the component:
#
# config.view_component.generate.locale = true
#
# #### `#distinct_locale_files`
#
# Always generate as many translations files as available locales:
#
# config.view_component.generate.distinct_locale_files = true
#
# One file will be generated for each configured `I18n.available_locales`,
# falling back to `[:en]` when no `available_locales` is defined.
#
# #### `#preview`
#
# Always generate a preview alongside the component:
#
# config.view_component.generate.preview = true
#
# #### #preview_path
#
# Path to generate preview:
#
# config.view_component.generate.preview_path = "test/components/previews"
#
# Required when there is more than one path defined in preview_paths.
# Defaults to `""`. If this is blank, the generator will use
# `ViewComponent.config.previews.paths` if defined,
# `"test/components/previews"` otherwise
#
# #### `#use_component_path_for_rspec_tests`
#
# Whether to use `config.generate.path` when generating new
# RSpec component tests:
#
# config.view_component.generate.use_component_path_for_rspec_tests = true
#
# When set to `true`, the generator will use the `path` to
# decide where to generate the new RSpec component test.
# For example, if the `path` is
# `app/views/components`, then the generator will create a new spec file
# in `spec/views/components/` rather than the default `spec/components/`.
# @!attribute previews
# @return [ActiveSupport::OrderedOptions]
# The subset of configuration options relating to previews.
#
# #### `#controller`
#
# The controller used for previewing components. Defaults to `ViewComponentsController`:
#
# config.view_component.previews.controller = "MyPreviewController"
#
# #### `#route`
#
# The entry route for component previews. Defaults to `/rails/view_components`:
#
# config.view_component.previews.route = "/my_previews"
#
# #### `#enabled`
#
# Whether component previews are enabled. Defaults to `true` in development and test environments:
#
# config.view_component.previews.enabled = false
#
# #### `#default_layout`
#
# A custom default layout used for the previews index page and individual previews. Defaults to `nil`:
#
# config.view_component.previews.default_layout = "preview_layout"
#
# @!attribute instrumentation_enabled
# @return [Boolean]
# Whether ActiveSupport notifications are enabled.
# Defaults to `false`.
def default_preview_paths
(default_rails_preview_paths + default_rails_engines_preview_paths).uniq
end
def default_rails_preview_paths
return [] unless defined?(Rails.root) && Dir.exist?("#{Rails.root}/test/components/previews")
["#{Rails.root}/test/components/previews"]
end
def default_rails_engines_preview_paths
return [] unless defined?(Rails::Engine)
registered_rails_engines_with_previews.map do |descendant|
"#{descendant.root}/test/components/previews"
end
end
def registered_rails_engines_with_previews
Rails::Engine.descendants.select do |descendant|
defined?(descendant.root) && Dir.exist?("#{descendant.root}/test/components/previews")
end
end
def default_generate_options
options = ActiveSupport::OrderedOptions.new(false)
options.preview_path = ""
options.path = "app/components"
options
end
def default_previews_options
options = ActiveSupport::OrderedOptions.new
options.controller = "ViewComponentsController"
options.route = "/rails/view_components"
options.enabled = defined?(Rails.env) && (Rails.env.development? || Rails.env.test?)
options.default_layout = nil
options.paths = default_preview_paths
options
end
end
# @!attribute current
# @return [ViewComponent::Config]
# Returns the current ViewComponent::Config. This is persisted against this
# class so that config options remain accessible before the rest of
# ViewComponent has loaded. Defaults to an instance of ViewComponent::Config
# with all other documented defaults set.
class_attribute :current, default: defaults, instance_predicate: false
def initialize
@config = self.class.defaults
end
delegate_missing_to :config
private
attr_reader :config
end
end
|