Custom Inputs for @params
Lookbook ships with a number of pre-defined input types that are used when adding dynamic preview parameters to your previews.
However if you need an input type that isn’t provided by Lookbook (or want to override one of the existing ones) you can easily add your own and then reference them in your @param
tags.
Adding a custom param input
To define a custom input you can do so using the Lookbook.define_param_input
method when configuring your Lookbook installation:
Lookbook.define_param_input(<name>, <partial_path>, <opts?>)
<name> | A unique name for the input |
<partial_path> | Path to the partial template used to render the input |
<opts> | Set of default options to be passed to the input. Any supplied param options will override these values. |
For example, to create a customised url input with a https://
prefix in front of it you could do the following:
# config/application.rb
Lookbook.define_param_input(:url, "inputs/url")
<!-- app/views/inputs/_url.html.erb -->
<div style="display: flex; align-items: center;">
<strong>https://</strong>
<div style="padding-left: 6px">
<%= text_field_tag(name, value,
**input_options,
type: "url",
"x-model": "value"
) %>
</div>
</div>
This input field will then be rendered when using the url
input type in @param
tags:
class IframeComponentPreview < ViewComponent::Preview
# @param src url
def default(src: 'example.com')
render IframeComponent.new(src: src)
end
end
Template variables
The following local variables are available to input partial templates:
name
The name of the param this input should update.
<input name="<% name %>" />
value
The current value of the param.
<input value="<% value %>" />
input
The input type currently being rendered
<input type="<% input %>" />
input_options
Hash of options specified by the @param
tag. Generally expected to be passed to
a tag helper to be turned into a set of HTML attributes on the input, where appropriate.
<%= text_field_tag(name, value, **input_options) %>
choices
Array of selection options specified by the @param
tag, if available.
<%= select_tag(name, options_for_select(choices, value)) %>
Handling updates
Lookbook uses AlpineJS under the hood for all JavaScript interactions.
Custom input templates are automatically wrapped up as an Alpine component that takes care of handling updates to the preview when it’s value
property changes.
To bind the value of an input to the Alpine component’s value
property you can add an x-model
attribute to the input, like so:
<input x-model="value">
Any changes to the input value will then automatically update the preview and the URL.
To ensure that the preview does not get refreshed too often you may wish to throttle or debounce changes using a modifier:
<input x-model.debounce.300ms="value">
See the Alpine documentation on the x-model directive for full details of all available modifiers.
This technique will work for most types of <input>
elements, plus <textarea>
<select>
elements.
Manually triggering an update
If your custom input does not use a standard input element, you will need to manually update the Alpine component’s value
property.
This could be done in an @click
handler or however makes sense for the input you are building.
<button @click="value = 'YES'">Set to YES</button>
See the Alpine documentation on event handling for details on listening and responding to events.
Styling inputs
If you wish to specify custom CSS rules to style the contents of the input partial, just include a <style>
element in the template:
<style>
input {
border: 1px solid hotpink;
}
</style>
<input type="text"> <!-- will have a hotpink border -->
The <style>
element will be removed when the input is rendered and any styles will be automagically scoped to the input partial that they are defined in, so they will not affect other inputs or leak out to affect the styling of the UI in general.