<div id="button-preview-default"> <button class="lui-button lui-button--size-default lui-button--neutral--primary w-fit w-fit relative" data-controller="lui--button"> <div class="lui-tooltip hidden" data-controller="tooltips" data-tooltips-tippy-target-id-value="" data-tooltips-position-value="top" data-tooltips-interactive-value="false" > <div class="lui-tooltip__title"> this is a tooltip </div> </div> <div class="opacity-100 inline-flex" data-lui--button-target="leadingIcon"> <div class="flex items-center justify-center" style="width: 16px; height: 16px;"><i class="lui-button__icon lui-button__icon--default fa-regular fa-smile" data-lui--button-target="leadingIcon"></i></div> </div> <span class="lui-button__text opacity-100 inline-flex" data-lui--button-target="text"> Button </span> <div class="opacity-100 inline-flex" data-lui--button-target="trailingIcon"> <i class="lui-m_icon material-symbols-outlined" style="--lui-micon-size: 16px;"> house </i> </div> <div class="opacity-100 inline-flex" data-lui--button-target="statusDot"> <div class="lui-status_dot lui-status_dot--success"></div> </div> <div class="absolute w-full flex items-center justify-center opacity-0" data-lui--button-target="loadingIcon"> <i class="lui-m_icon animate-spin material-symbols-outlined" style="--lui-micon-size: 16px;"> progress_activity </i> </div> </button></div><script> const preview = document.getElementById('button-preview-default'); const button = preview.querySelector('.lui-button'); button.addEventListener('click', () => { button.dispatchEvent(new CustomEvent('lui--button:start-loading')); // Simulate work setTimeout(() => { button.dispatchEvent(new CustomEvent('lui--button:stop-loading')); }, 3000); });</script>No Usage documentation to display.
<% with_status_dot = preview_params.delete(:with_status_dot) with_counter = preview_params.delete(:with_counter) status_dot_kind = preview_params.delete(:status_dot_kind) counter_count = preview_params.delete(:counter_count)%><div id="button-preview-default"> <%= render LooposUi::Button.new(**preview_params) do |button| %> <%= button.with_status_dot(kind: status_dot_kind) if with_status_dot %> <%= button.with_counter(count: counter_count) if with_counter%> <% end %></div><script> const preview = document.getElementById('button-preview-default'); const button = preview.querySelector('.lui-button'); button.addEventListener('click', () => { button.dispatchEvent(new CustomEvent('lui--button:start-loading')); // Simulate work setTimeout(() => { button.dispatchEvent(new CustomEvent('lui--button:stop-loading')); }, 3000); });</script>No notes provided.
| Param | Description | Input |
|---|---|---|
|
— |
|
|
|
— |
|
|
|
— |
|
|
|
Button text |
|
|
|
Leading icon |
|
|
|
Trailing icon |
|
|
|
Show status dot on button |
|
|
|
— |
|
|
|
Show counter on button |
|
|
|
Disable button |
|
|
|
Counter count |
|
Description
The Button component is a simple button that can be used to trigger actions or navigate to different parts of the application.
Arguments
| Property | Description | Default Value |
|---|---|---|
kind |
(Deprecated, all button kinds are now neutral, will be removed) The kind of the button. Can be :app, :neutral, :success, or :danger. |
:app |
app |
(Deprecated, will be removed) The application type. If kind is :app and app is not provided, it defaults to LooposUi.config.app_type. |
nil |
text |
The text displayed on the button. | nil |
size |
The size of the button. Can be :default, :small, or :tiny. |
:default |
type |
The type of the button. Can be :primary, :secondary, or :tertiary. |
:primary |
href |
Decides the type of the button. If present, the button will be rendered as an anchor tag, otherwise as a button. | nil |
tag |
The wrapper HTML tag that should be used to create the button. Eg: button, a, label, etc. Default is button, unless you specify href |
button |
tag_options |
Hash with additional options to be passed to the tag builder. | {} |
leading_icon |
The icon displayed before the text. If the string is an app name, the respective app icon will be rendered | nil |
icon |
The icon displayed before the text, alternative way to set leading_icon. |
nil |
trailing_icon |
The icon displayed after the text. If the string is an app name, the respective app icon will be rendered | nil |
disabled |
Boolean value, controls whether the button/link is clickable. | false |
active |
Boolean value, controls whether the button/link is in an active state. | true |
When the kind is set to :app and the app property is not provided, it will default to LooposUi.config.app_type.
Color Customization
To customize button colors (primary color, hover color, border color, text color), use the ThemeContext component to wrap your buttons. This only works if button is of type primary:
<%= render LooposUi::ThemeContext.new(theme: { button: { primary_color: "apps-default-800-primary", hover_color: "apps-default-900-hover", border_color: "apps-default-800-primary", text_color: "general-global-white" }}) do %> <%= render LooposUi::Button.new(text: "Custom Button") %><% end %>icon, leading_icon, and trailing_icon should be a string with the FontAwesome icon class (for example, fa-regular fa-plus).
You can also pass in just the icon name - if the passed in value does not contain fa-, it will be prepended with fa-regular fa-{VALUE}. This way you can just pass in plus for the same effect.
The button component also supports Material Design Icons (MIcon). You can pass icon names like "home", "settings", "arrow_forward" etc. and they will be rendered as Material Design Icons with appropriate sizing based on the button size.
Presets
As most buttons will have the same kind, size, and type, there are some presets available to make it easier to create buttons.
The presets are defined in the LooposUi::Button::Presets module.
Currently, the available presets are:
new:delete:back:enable:copy:export:validation:
All presets accept the same arguments as the Button component, but most only require the href property.
Slots
There are three slots available for the Button component: counter, leading_icon and trailing_icon. The counter slot renders a LooposUi::Counter component next to the button content, while the other two add the respective icons.
The last two can also be passed in as properties, which is the heavily recommended way of doing it.
JavaScript/Stimulus Controller
The Button component includes a Stimulus controller (lui--button) that provides dynamic functionality for updating button content and handling icon interactions.
Whenever the button is rendered as:
- an anchor tag (
hrefpresent and not disabled), or - a
buttontag withtype: :submit, or - a
buttontag with aformattribute
the component will automatically add data-controller="lui--button" and data-action="lui--button#startLoading" to enable the loading state behavior (showing the spinner, disabling the button, and setting aria-busy/aria-disabled).
Controller Targets
| Target | Description |
|---|---|
text |
The text content span element within the button |
leadingIcon |
The leading icon element (when using FontAwesome icons) |
Controller Methods
| Method | Description |
|---|---|
rotateLeadingIcon() |
Toggles a 180-degree rotation on the leading icon. Useful for expand/collapse buttons. |
Dynamic Updates
The controller automatically watches for changes to specific data attributes and updates the button content accordingly:
data-text: Updates the button text contentdata-leading-icon: Updates the leading icon classdata-tooltip-title: Updates the tooltip if it exists
Usage Examples
Dynamic Text Updates
<%= render LooposUi::Button.new(text: "Initial Text", icon: :chevron-down) %><script> // Update button text dynamically const button = document.querySelector('[data-controller="lui--button"]') button.dataset.text = "Updated Text"</script>Integration with Other Components
The button controller is often used in conjunction with other components. For example, in the Log component:
<%= render LooposUi::Button.new( text: "Show More", leading_icon: "fa-regular fa-chevron-down", data: { action: "click->log#showMore log:toggleExpand->lui--button#rotateLeadingIcon" }) %>