<head> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Monsieur+La+Doulaise&display=swap" rel="stylesheet"></head><div class="contents lui-theme-context" style="--lui-theme-primary-font: "Monsieur La Doulaise", cursive; --lui-theme-button-primary-color: red; --lui-theme-button-border-color: green; --lui-theme-button-text-color: green; --lui-theme-button-hover-primary-color: blue; --lui-theme-button-hover-border-color: blue; --lui-theme-button-hover-text-color: blue;"> <button class="lui-button lui-button--themed lui-button--size-default lui-button--app--primary w-fit w-fit" data-controller="lui--button"> <span class="lui-button__text" data-lui--button-target="text"> Button inside theme context </span> </button> <div class="contents lui-theme-context" style="--lui-theme-button-primary-color: black; --lui-theme-button-border-color: aliceblue; --lui-theme-button-text-color: white; --lui-theme-button-hover-primary-color: grey; --lui-theme-button-hover-border-color: grey; --lui-theme-button-hover-text-color: grey;"> <button class="lui-button lui-button--themed lui-button--size-default lui-button--app--primary w-fit w-fit" data-controller="lui--button"> <span class="lui-button__text" data-lui--button-target="text"> Nested theme context </span> </button> </div></div><button class="lui-button lui-button--size-default lui-button--app--primary w-fit w-fit" data-controller="lui--button"> <span class="lui-button__text" data-lui--button-target="text"> Button outside theme context </span></button><div class="contents lui-theme-context" style="--lui-theme-tabs-layout-primary-color: red;"> <div class="lui-tabs_layout" data-controller="tabs" data-tabs-keep-tab-in-url-value="true"> <div class="lui-tabs_layout__tab_list" data-tabs-target="tabList" data-controller="lui--blurred-scroll"> <span data-action="click->tabs#changeTab" data-tabs-target="tab" data-tab-id="0" data-tab-title="Tab 1" class="lui-tabs_layout__tab_entry text-general-global-black lui-tabs_layout__tab_entry--active"> Tab 1 </span> </div> <div class="lui-tabs_layout__main"> <turbo-frame class="lui-tabs_layout__tab" data-tabs-target="panel" data-tab-id="0" hidden="hidden" id="lui-tab-Tab 1"> <p>Tab content here</p> </turbo-frame> </div> </div></div>ThemeContext
Description
Related components
| Used Components | Components where is Used |
|---|---|
| Label |
Usage rules
- ✅ Do
- ❌ Don't
<%# Put these in the head of the application layout you want to style %><head> <%# Inter fonts%> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet"> <%# Monsieur La Doulaise fonts %> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Monsieur+La+Doulaise&display=swap" rel="stylesheet"></head><%= render LooposUi::ThemeContext.new( theme: { #primary_font: "Inter", primary_font: '"Monsieur La Doulaise", cursive', button: { primary_color: "red", border_color: "green", text_color: "green", hover: { primary_color: "blue", border_color: "blue", text_color: "blue" } } }) do %> <%= render LooposUi::Button.new( text: "Button inside theme context", app: :app, type: :primary, size: :default, ) %> <%= render LooposUi::ThemeContext.new( theme: { button: { primary_color: "black", border_color: "aliceblue", text_color: "white", hover: { primary_color: "grey", border_color: "grey", text_color: "grey", } } }) do %> <%= render LooposUi::Button.new( text: "Nested theme context", app: :app, type: :primary, size: :default, ) %> <% end %><% end %><%= render LooposUi::Button.new( text: "Button outside theme context", app: :app, type: :primary, size: :default,) %><%= render LooposUi::ThemeContext.new( theme: { tabs_layout: { primary_color: "red" } }) do %> <%= render LooposUi::TabsLayout.new do |layout| %> <% layout.with_tab(title: "Tab 1") do %> <p>Tab content here</p> <% end %> <% end %><% end %>No notes provided.
No params configured.
Description
The ThemeContext component provides a way to customize the appearance of LooposUI components by setting CSS custom properties (variables) that control colors and other visual aspects. It acts as a theme provider that wraps other components and applies custom styling through CSS variables.
The ThemeContext uses a nested structure where you can define themes for different component types (like button, tabs_layout, etc.) and their specific properties.
Arguments
| Property | Default | Required | Description |
|---|---|---|---|
theme |
nil |
Yes | A hash containing theme configuration for different components. See the Theme Structure section for details. |
Theme Structure
The theme argument accepts a hash with the following structure:
{ # Global theme properties primary_color: "string", text_color: "string", # Component-specific themes button: { primary_color: "string", border_color: "string", text_color: "string", hover: { primary_color: "string", border_color: "string", text_color: "string", } }, tabs_layout: { primary_color: "string" # defaults to "app-800-primary" }}Supported Components
Currently, the following components support theming through ThemeContext:
- Button: Customize primary color, hover color, border color, and text color
- TabsLayout: Customize primary color for active tabs and hover states
CSS Variable Generation
The ThemeContext automatically generates CSS custom properties based on the theme structure. For example:
button.primary_colorbecomes--lui-theme-button-primary-colortabs_layout.primary_colorbecomes--lui-theme-tabs-layout-primary-color- Global
primary_colorbecomes--lui-theme-primary-color
Usage Examples
Basic Button Theming
<%= render LooposUi::ThemeContext.new(theme: { button: { primary_color: "#b53c00", hover_color: "#933100", border_color: "#7a2800", text_color: "#ffffff" }}) do %> <%= render LooposUi::Button.new(text: "Custom Button") %><% end %>TabsLayout Theming
<%= render LooposUi::ThemeContext.new(theme: { tabs_layout: { primary_color: "app-800-primary" }}) do %> <%= render LooposUi::TabsLayout.new do |layout| %> <% layout.with_tab(title: "Tab 1") do %> <p>Tab content here</p> <% end %> <% end %><% end %>Nested ThemeContext
You can nest ThemeContext components for more granular control:
<%= render LooposUi::ThemeContext.new(theme: { button: { primary_color: "#3b82f6" }}) do %> <%= render LooposUi::Button.new(text: "Blue Button") %> <%= render LooposUi::ThemeContext.new(theme: { button: { primary_color: "#ef4444" # This overrides the parent theme } }) do %> <%= render LooposUi::Button.new(text: "Red Button") %> <% end %><% end %>Color Values
The ThemeContext accepts various color value formats:
- Hex colors:
"#ff0000","#f00" - CSS color names:
"red","blue","transparent" - RGB/RGBA:
"rgb(255, 0, 0)","rgba(255, 0, 0, 0.5)" - HSL:
"hsl(0, 100%, 50%)" - LooposUI color tokens:
"app-800-primary","general-global-white"
Implementation Details
Default Values
Some components have default values defined in their theme structure:
tabs_layout.primary_colordefaults to"app-800-primary"
Theme Inheritance
When nested, child ThemeContext components can override parent theme values. The most specific theme value takes precedence.