require "zeitwerk" require "lookbook/version" loader = Zeitwerk::Loader.for_gem loader.ignore("#{__dir__}/lookbook.rb") loader.push_dir("#{__dir__}/lookbook", namespace: Lookbook) loader.collapse("#{__dir__}/lookbook/*") loader.collapse("#{__dir__}/lookbook/*/*") loader.collapse("#{__dir__}/lookbook/*/*/*") loader.ignore("#{__dir__}/lookbook/support/evented_file_update_checker.rb") loader.ignore("#{__dir__}/lookbook/cable") loader.setup # The Lookbook application entry point. # # @api public module Lookbook class << self # Returns the installed Lookbook version # # @example :erb #

Using Lookbook v<%= Lookbook.version %>

# # @return [String] Version number string def version Lookbook::VERSION end # Provides access to the Lookbook config store # # @example :ruby # Lookbook.config.project_title = "MyApp" # # @return [ConfigStore] The config store object def config @_config ||= ConfigStore.init_from_config end # Get an array of component preview objects # # @return [Array] Array of preview entities def previews Engine.previews.to_a end # Get an array of documentation page objects # # @return [Array] Array of page entities def pages Engine.pages.to_a end # Get the global data store instance # # @return [Store] The global data store instance def data @_data ||= Store.new end # Replace the global data store contents # # @param new_data [Hash] Hash of data to store # @return [Store] The global data store instance def data=(new_data) @_data = Store.new(new_data) end # @!group Params # Add a custom `@param` tag input type # # @param name [Symbol] Unique input type name # @param partial_path [String] Path to the partial template used to render the input # @param opts [Hash] Set of default options to be passed to the input. Any supplied param options will override these values def add_input_type(name, partial_path, opts = {}) Engine.inputs.add_input(name, partial_path, opts) end # @!endgroup # @!group Inspector Panels # Add a custom inspector panel # # @example :ruby # Lookbook.add_panel(:info, "panels/info", { # label: "Extra Info" # }) # # @param name [Symbol, String] Unique panel name # @param partial_path [String] Path to the partial template used to render the panel # @param opts [Hash] Set of panel options # @option opts [String] :label The text to be displayed in the panel tab # @option opts [String] :hotkey [Keyboard shortcut](https://alpinejs.dev/directives/on#keyboard-events) used to switch to the panel # @option opts [Boolean] :disabled Disabled tabs are still accessible but are greyed out in the UI # @option opts [String] :copy If present, the panel will display a copy button that copies the value of this property to the clipboard when clicked # @option opts [Hash] :locals A hash of local variables that will be passed to the panel when it is rendered def add_panel(name, partial_path, opts = {}) Engine.panels.add_panel(name, partial_path, opts) end # Edit the properties of an existing inspector panel # # @example :ruby # Lookbook.update_panel(:notes, { # label: "Usage Info", # hotkey: "u", # }) # # @param name [Symbol, String] Name of target panel # @param opts [Hash] Set of panel options # @option opts [String] :label The text to be displayed in the panel tab # @option opts [String] :hotkey [Keyboard shortcut](https://alpinejs.dev/directives/on#keyboard-events) used to switch to the panel # @option opts [Boolean] :disabled Disabled tabs are still accessible but are greyed out in the UI # @option opts [String] :copy If present, the panel will display a copy button that copies the value of this property to the clipboard when clicked # @option opts [Hash] :locals A hash of local variables that will be passed to the panel when it is rendered def update_panel(name, opts) Engine.panels.update_panel(name, opts) end # Remove a panel from the inspector # # @example :ruby # Lookbook.remove_panel(:notes) # # @param name [Symbol, String] Name of target panel def remove_panel(name) Engine.panels.remove_panel(name) end # @!endgroup # @!group Custom Tags # Add a custom tag # # @param name [Symbol, String] Tag name # @param args [Array] Array of argument names # @yield [tag] The custom tag instance def add_tag(name, args = nil, &block) Engine.tags.add_tag(name, { named_args: args.to_a, after_parse: block }) end # @!endgroup # @!group Lifecycle Callbacks # Add a callback to run after app initialization. # # @example :ruby # Lookbook.after_initialize do |app| # puts "Lookbook has started!" # end # # @yield [app] Lookbook app def after_initialize(&block) Engine.hooks.add_hook(:after_initialize, block) end # Add a callback to run before Lookbook shuts down # # @yield [app] Lookbook app def before_exit(&block) Engine.hooks.add_hook(:before_exit, block) end # Add a callback to run when a change to a watched # file occurs. Only called when an evented file watcher is being # used to detect changes. # # @yield [app, changes] Lookbook app and hash of files changed, added & removed def after_change(&block) Engine.hooks.add_hook(:after_change, block) end # @!endgroup # @api private def broadcast(event_name, data = {}) Engine.websocket&.broadcast(event_name.to_s, data) end # @api private def engine Engine end # @api private def configure yield(config) end # @api private def logger @_logger ||= if Rails.logger.present? && config.log_use_rails_logger Rails.logger else logger = Logger.new($stdout) logger.level = config.log_level logger end end # @api private def debug_data { version: version, env: Rails.env.to_s, config: [ config.to_h, { dependencies: { actioncable: Engine.runtime_context.actioncable_installed?, listen: Engine.runtime_context.listen_installed?, view_component: config.using_view_component } }, {panels: Engine.panels.to_h}, {inputs: Engine.inputs.to_h}, {tags: Engine.tags.to_h} ].inject(:merge) } end alias_method :define_param_input, :add_input_type alias_method :define_panel, :add_panel alias_method :amend_panel, :update_panel alias_method :define_tag, :add_tag deprecate define_param_input: :add_input_type, deprecator: Deprecation deprecate define_panel: :add_panel, deprecator: Deprecation deprecate amend_panel: :update_panel, deprecator: Deprecation deprecate define_tag: :add_tag, deprecator: Deprecation end end require "rails" require "lookbook/engine"