# lostcoords-ui Rails rendering helpers with semantic HTML, native attributes and browser interactions. Install and styling: https://ui.lostcoords.com/installation.html Theming: https://ui.lostcoords.com/theming.html API JSON: https://ui.lostcoords.com/api.json Tailwind CSS v4 is required. Install the gem once; the Rails engine exposes all lc_* helpers without per-component imports. The engine includes a default light and dark theme. Override CSS variables only as needed. Use class: to merge Tailwind utilities, data: and aria: for native attributes. Block helpers capture Rails ERB. lc_button_to keeps Rails form, method and CSRF semantics. Each host application's lockfile pins its version. ## Theme colors Override only the roles you need. Soft status backgrounds are generated automatically. Primary controls actions, links, selection and focus. - `--background`: Page background - `--foreground`: Main text and headings - `--card`: Cards and grouped content - `--card-foreground`: Text on cards - `--card-input`: Fields on cards; defaults to --input - `--card-secondary`: Secondary buttons on cards; defaults to --secondary - `--popover`: Menus, popovers and dialogs - `--popover-foreground`: Text on menus, popovers and dialogs - `--primary`: Primary actions, links, selected states and keyboard focus - `--primary-foreground`: Text and icons on a solid primary background - `--secondary`: Secondary buttons - `--secondary-foreground`: Text on secondary buttons - `--muted`: Subtle backgrounds: badges, code, skeletons, table headers - `--muted-foreground`: Secondary text, hints and placeholders - `--accent`: Hovered rows, menu items and inline code - `--accent-foreground`: Text on accent backgrounds - `--destructive`: Errors and destructive actions - `--success`: Successful actions and positive feedback - `--warning`: Warnings and items needing attention - `--border`: Dividers and outlines - `--input`: Input and toggle fills - `--ring`: Keyboard focus ring; unset, it follows --primary ## lc_checkbox https://ui.lostcoords.com/components/checkbox.html#lc_checkbox ```ruby lc_checkbox(label, name: nil, value: "1", checked: false, unchecked_value: "0", hint: nil, card: false, **attributes, &block) ``` Checkboxes: https://ui.lostcoords.com/components/checkbox.html ```erb <%= lc_stack gap: :related do %> <%= lc_checkbox "Email me about comments", name: "notify[comments]", checked: true %> <%= lc_checkbox "Weekly digest", name: "notify[digest]", hint: "A summary every Monday." %> <%= lc_checkbox "Product news", name: "notify[news]", disabled: true %> <% end %> ``` ## lc_radio https://ui.lostcoords.com/components/radio.html#lc_radio ```ruby lc_radio(label, name:, value:, checked: false, hint: nil, card: false, **attributes, &block) ``` Radio group: https://ui.lostcoords.com/components/radio.html ```erb <%= lc_choice_group legend: "Plan", hint: "You can change plans at any time." do %> <%= lc_radio "Free", name: "plan", value: "free", checked: true %> <%= lc_radio "Team", name: "plan", value: "team", hint: "Shared projects and roles." %> <%= lc_radio "Enterprise", name: "plan", value: "enterprise" %> <% end %> ``` Cards: https://ui.lostcoords.com/components/radio.html ```erb <%= lc_choice_group legend: "Plan", class: "w-full max-w-md" do %> <%= lc_radio "Free", name: "my-component-plan", value: "free", hint: "Up to 3 projects.", card: true %> <%= lc_radio "Team", name: "my-component-plan", value: "team", hint: "Shared projects and roles.", card: true, checked: true do %> <%= lc_text "$12 per member, per month", size: :caption, tone: :muted %> <% end %> <%= lc_radio "Enterprise", name: "my-component-plan", value: "enterprise", hint: "SSO and audit logs.", card: true %> <% end %> ``` ## lc_switch https://ui.lostcoords.com/components/switch.html#lc_switch ```ruby lc_switch(label, name: nil, value: "1", checked: false, unchecked_value: "0", hint: nil, **attributes) ``` Switches: https://ui.lostcoords.com/components/switch.html ```erb <%= lc_stack gap: :related do %> <%= lc_switch "Public project", name: "project[public]", checked: true %> <%= lc_switch "Allow comments", name: "project[comments]", hint: "Members can comment on pages." %> <% end %> ``` Tabs: https://ui.lostcoords.com/components/tabs.html ```erb <%= lc_tabs id: "my-component-tabs", label: "Project", class: "w-full" do |tabs| %> <% tabs.panel "Overview" do %> <%= lc_text "Pages, members and recent changes." %> <% end %> <% tabs.panel "Activity" do %> <%= lc_text "Nothing new this week.", tone: :muted %> <% end %> <% tabs.panel "Settings" do %> <%= lc_switch "Public project", name: "project[public]" %> <% end %> <% end %> ``` Vertical, with manual activation: https://ui.lostcoords.com/components/tabs.html ```erb <%= lc_tabs id: "my-component-settings", label: "Settings", orientation: :vertical, activation: :manual, class: "w-full" do |tabs| %> <% tabs.panel "Profile" do %> <%= lc_text "Name, photo and contact details." %> <% end %> <% tabs.panel "Notifications" do %> <%= lc_switch "Email me about mentions", name: "settings[mentions]" %> <% end %> <% tabs.panel "Billing" do %> <%= lc_text "Plan, invoices and payment method.", tone: :muted %> <% end %> <% end %> ``` ## lc_choice_group https://ui.lostcoords.com/components/radio.html#lc_choice_group ```ruby lc_choice_group(legend:, **options, &block) ``` Radio group: https://ui.lostcoords.com/components/radio.html ```erb <%= lc_choice_group legend: "Plan", hint: "You can change plans at any time." do %> <%= lc_radio "Free", name: "plan", value: "free", checked: true %> <%= lc_radio "Team", name: "plan", value: "team", hint: "Shared projects and roles." %> <%= lc_radio "Enterprise", name: "plan", value: "enterprise" %> <% end %> ``` Cards: https://ui.lostcoords.com/components/radio.html ```erb <%= lc_choice_group legend: "Plan", class: "w-full max-w-md" do %> <%= lc_radio "Free", name: "my-component-plan", value: "free", hint: "Up to 3 projects.", card: true %> <%= lc_radio "Team", name: "my-component-plan", value: "team", hint: "Shared projects and roles.", card: true, checked: true do %> <%= lc_text "$12 per member, per month", size: :caption, tone: :muted %> <% end %> <%= lc_radio "Enterprise", name: "my-component-plan", value: "enterprise", hint: "SSO and audit logs.", card: true %> <% end %> ``` ## lc_code_block https://ui.lostcoords.com/components/code_block.html#lc_code_block ```ruby lc_code_block(source, id:, language: nil, title: nil, label: nil, max_lines: 10, **attributes, &block) ``` Plain source: https://ui.lostcoords.com/components/code_block.html ```erb <%= lc_code_block "def hello(name)\n puts name\nend", id: "my-component-ruby", language: :ruby, label: "Ruby greeting", class: "w-full" %> ``` With a filename: https://ui.lostcoords.com/components/code_block.html ```erb <%= lc_code_block "def hello(name)\n puts name\nend", id: "my-component-file", language: :ruby, title: "app/helpers/greeting_helper.rb", label: "Greeting helper", class: "w-full" %> ``` Collapsible source: https://ui.lostcoords.com/components/code_block.html ```erb <%= lc_code_block (1..15).map { |number| "puts #{number}" }.join("\n"), id: "my-component-long", language: :ruby, label: "Long Ruby snippet", max_lines: 5, class: "w-full" %> ``` ## lc_collapsible https://ui.lostcoords.com/components/collapsible.html#lc_collapsible ```ruby lc_collapsible(title: nil, open: false, card: true, summary_class: nil, indicator: :marker, button: nil, **attributes, &block) ``` Expandable content: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible class: "w-full", title: "Can I use my own colors?" do %>

Yes. Override the default theme values in your application stylesheet.

<% end %> ``` Row summary with a chevron: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible card: false, indicator: :chevron, class: "w-full max-w-80", summary_class: "rounded-2xl px-3 font-medium hover:bg-accent" do |collapsible| %> <% collapsible.summary do %> Language English <% end %> <%= lc_toggle_group label: "Language", value: "en" do %> <%= lc_toggle_group_item "English", value: "en", selected: true %> <%= lc_toggle_group_item "日本語", value: "ja" %> <% end %> <% end %> ``` Button summary: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible card: false, button: { variant: :secondary, size: :sm }, summary_class: "w-fit", class: "w-full max-w-80" do |collapsible| %> <% collapsible.summary do %> <%= lc_icon "user-plus", options: { "aria-hidden": true } %> Invite people <% end %> <%= lc_field label: "Email", id: "my-component-email" do |field| %> <%= lc_input name: "email", type: :email, **field %> <% end %> <% end %> ``` ## lc_copy_button https://ui.lostcoords.com/components/copy_button.html#lc_copy_button ```ruby lc_copy_button(label = nil, value: nil, source: nil, copied_label: nil, error_label: nil, reset_after: 2000, icon_only: false, variant: :secondary, size: :md, **attributes) ``` Motion feedback: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_copy_button "Copy link", value: "https://ui.lostcoords.com", copied_label: "Link copied", reset_after: 2500 %> <%= lc_copy_button "Copy link", value: "https://ui.lostcoords.com", icon_only: true, variant: :ghost %> ``` Labels, icons and disabled controls: https://ui.lostcoords.com/components/copy_button.html ```erb <%= lc_copy_button value: "https://ui.lostcoords.com", variant: :primary %> <%= lc_copy_button "Copy link", value: "https://ui.lostcoords.com", copied_label: "Link copied" %> <%= lc_copy_button "Copy link", value: "https://ui.lostcoords.com", icon_only: true, variant: :ghost %> <%= lc_copy_button value: "Unavailable", disabled: true %> ``` Copy from an element: https://ui.lostcoords.com/components/copy_button.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-md" do %> <%= lc_field label: "Share link", id: "my-component-link" do |field| %> <%= lc_input value: "https://ui.lostcoords.com", **field %> <% end %> <%= lc_copy_button "Copy current link", source: "my-component-link", copied_label: "Link copied", class: "w-full" %> <%= lc_text "Edit the link, then copy it. The button reads the current value each time.", size: :small, tone: :muted %> <% end %> ``` Translated labels: https://ui.lostcoords.com/components/copy_button.html ```erb <% I18n.with_locale(:ja) do %> <%= lc_copy_button value: "https://ui.lostcoords.com", lang: "ja" %> <% end %> <% I18n.with_locale(:es) do %> <%= lc_copy_button value: "https://ui.lostcoords.com", lang: "es" %> <% end %> ``` ## lc_description_list https://ui.lostcoords.com/components/description_list.html#lc_description_list ```ruby lc_description_list(**attributes, &block) list.item(term, detail = nil, **attributes, &block) ``` Details: https://ui.lostcoords.com/components/description_list.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.header title: "Workspace" %> <%= lc_description_list do |list| %> <%= list.item "Owner", "Ada Baker" %> <%= list.item "Plan" do %> <%= lc_badge "Team", tone: :primary %> <% end %> <%= list.item "Created", "March 4, 2026" %> <% end %> <% end %> ``` ## lc_dialog https://ui.lostcoords.com/components/dialog.html#lc_dialog ```ruby lc_dialog(id:, title:, description: nil, trigger: lc_t("lostcoords.ui.dialog.trigger"), kind: :modal, size: nil, detents: "fit", close_action: "lc-dialog#close", close_label: nil, title_attributes: {}, description_attributes: {}, **attributes, &block) dialog.actions(&block) dialog.footer(**attributes, &block) dialog.close(label = nil, variant: :secondary, **attributes) ``` Modal: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-dialog", title: "Create project", description: "Projects group pages and members.", trigger: "New project" do |dialog| %>
<%= lc_field label: "Project name", id: "my-component-dialog-name" do |field| %> <%= lc_input name: "project[name]", **field %> <% end %> <%= dialog.footer do %> <%= dialog.close %> <%= lc_button "Create project", type: :submit %> <% end %>
<% end %> ``` Mobile dialog: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-sheet", title: "Workspace details", trigger: "Open mobile dialog", detents: "fit" do %>

Drag the handle down to dismiss.

<%= lc_field label: "Workspace", id: "my-component-workspace" do |field| %> <%= lc_input value: "Design studio", **field %> <% end %> <% end %> ``` Mobile height options: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-sheet", title: "Notes", detents: "medium large" do %> <%= lc_textarea name: "notes", rows: 16, aria: { label: "Notes" }, placeholder: "Write something…" %> <% end %> ``` Compact dialog: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-context", title: "Quick details", trigger: "Open compact dialog", kind: :context do %>

A compact dialog for a short, focused task.

<% end %> <%= lc_dialog id: "my-component-invite", title: "Invite people", kind: :context do |dialog| %> <% dialog.trigger { |attrs| lc_button "Invite with your own trigger", variant: :ghost, **attrs } %>

This step marks itself data-dialog-size="md", so the compact dialog widens to 32rem while it shows.

<% end %> ``` Opened by your controller: https://ui.lostcoords.com/components/dialog.html ```erb
<%= lc_button "Show members", variant: :secondary, aria: { haspopup: "dialog", controls: "my-component-members" }, data: { action: "lc-dialog#open" } %> <%= lc_dialog id: "my-component-members", title: "Members", trigger: false, size: :lg, detents: "large", data: { lc_dialog_target: "dialog" } do |dialog| %> <%= dialog.actions do %> <%= lc_button "Invite", size: :sm %> <% end %> <% %w[Aiko Ben Chiara Dmitri Emi Farah Goro Hana].each do |name| %>

<%= name %>

<% end %> <% end %>
``` ## lc_confirm_sheet https://ui.lostcoords.com/components/dialog.html#lc_confirm_sheet ```ruby lc_confirm_sheet(**attributes) ``` Turbo confirm: https://ui.lostcoords.com/components/dialog.html ```erb <%# In the layout, once. %> <%= lc_confirm_sheet %> <%= lc_button_to "Delete project", "/projects/42", method: :delete, variant: :destructive, form: { data: { turbo_confirm: "Delete this project?", turbo_confirm_description: "Its pages and files are deleted for everyone.", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_button_to "Archive", "/projects/42/archival", form: { data: { turbo_confirm: "Archive this project?", turbo_confirm_accept: "Archive project", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_menu id: "my-component-menu", label: "Membership" do %> <%= lc_menu_option "Leave project", href: "/projects/42/membership", method: :delete, tone: :destructive, form: { data: { turbo_confirm: "Leave this project?", turbo_confirm_accept: "Leave", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <% end %> ``` ## lc_emoji_picker https://ui.lostcoords.com/components/emoji.html#lc_emoji_picker ```ruby lc_emoji_picker(form:, field:, label:, catalog_url:, value: nil, quick: [], recent: [], recent_scope: nil, auto_submit: false, **attributes) ``` Emoji picker: https://ui.lostcoords.com/components/emoji.html ```erb <%= fields_for :project do |form| %> <%= lc_emoji_picker form: form, field: :emoji, value: "✨", quick: %w[🥝 🍣 🍜 ☕], label: "Choose an emoji", catalog_url: "/emoji-catalog.html" %> <% end %> ``` ## lc_form_with https://ui.lostcoords.com/components/field.html#lc_form_with ```ruby lc_form_with(card: false, padding: :md, gap: nil, **options, &block) ``` Form builder: https://ui.lostcoords.com/components/field.html ```erb <%= lc_form_with model: DocsProject.invalid_example, url: "#", card: true, class: "w-full max-w-sm" do |form| %> <%= form.field :name, hint: "Shown to members." %> <%= form.field :email, as: :email_field, size: :sm, label: "Email (compact)" %> <%= form.switch :public, hint: "Anyone with the link can view." %> <%= form.submit "Save project" %> <% end %> ``` ## lc_glass https://ui.lostcoords.com/components/glass.html#lc_glass ```ruby lc_glass(shape: :bar, thick: false, as: :div, **attributes, &block) ``` Search bar: https://ui.lostcoords.com/components/glass.html ```erb
<%= lc_glass as: :label, class: "flex w-full max-w-sm items-center gap-related min-h-control-lg px-content" do %> <%= lc_icon "magnifying-glass", options: { class: "size-5 text-muted-foreground", "aria-hidden": true } %> <% end %>
``` ## lc_icon https://ui.lostcoords.com/components/button.html#lc_icon ```ruby lc_icon(name, variant: :outline, options: {}, path_options: {}) ``` Custom icons and content: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button variant: :secondary do %> <%= lc_icon "arrow-down-tray", options: { "aria-hidden": true, "data-icon": "inline-start" } %> Download report <% end %> <%= lc_button disabled: true, aria: { busy: true } do %> <%= lc_spinner size: :sm, label: nil, data: { icon: "inline-start" } %> Loading report… <% end %> ``` Button summary: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible card: false, button: { variant: :secondary, size: :sm }, summary_class: "w-fit", class: "w-full max-w-80" do |collapsible| %> <% collapsible.summary do %> <%= lc_icon "user-plus", options: { "aria-hidden": true } %> Invite people <% end %> <%= lc_field label: "Email", id: "my-component-email" do |field| %> <%= lc_input name: "email", type: :email, **field %> <% end %> <% end %> ``` Search bar: https://ui.lostcoords.com/components/glass.html ```erb
<%= lc_glass as: :label, class: "flex w-full max-w-sm items-center gap-related min-h-control-lg px-content" do %> <%= lc_icon "magnifying-glass", options: { class: "size-5 text-muted-foreground", "aria-hidden": true } %> <% end %>
``` Settings: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_section "Sign-in methods", id: "my-component", footnote: "Keep at least one way to sign in.", class: "w-full max-w-md" do %> <%= lc_list_group do %> <%= lc_list_row "Email", subtitle: "ada@example.com", icon: "envelope" do %> <%= lc_button "Change", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Passkey", subtitle: "Not set up", icon: "key" do %> <%= lc_button "Add", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Sign-in alerts", subtitle: "Email me when a new device signs in", icon: "bell", tag: :label, class: "cursor-pointer" do %> <% end %> <%= lc_list_row "Recovery codes", icon: "document-text", href: "#recovery-codes" do %> <%= lc_icon "chevron-right", variant: :mini, options: { class: "size-5 text-muted-foreground rtl:rotate-180", "aria-hidden": true } %> <% end %> <%= lc_list_row padded: false do %> <%= lc_list_item "Delete account", icon: "trash", tag: :button, type: "button", class: "w-full cursor-pointer rounded-[inherit] text-destructive transition-colors hover:bg-accent" %> <% end %> <% end %> <% end %> ``` ## lc_stack https://ui.lostcoords.com/components/foundations.html#lc_stack ```ruby lc_stack(gap: :content, as: :div, **attributes, &block) ``` Text styles: https://ui.lostcoords.com/components/foundations.html ```erb
<%= lc_heading "Weekend in Kyoto", level: 2, size: :title %> <%= lc_heading "Shared expenses", level: 3, size: :heading %> <%= lc_heading "Dinner with friends", level: 4, size: :subheading %> <%= lc_text do %>Use lc_stack to keep related content together.<% end %> <%= lc_text "Add a receipt or a short note for your group.", size: :small, tone: :muted %> <%= lc_text "Updated a few minutes ago", size: :caption, tone: :muted %>
``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` Checkboxes: https://ui.lostcoords.com/components/checkbox.html ```erb <%= lc_stack gap: :related do %> <%= lc_checkbox "Email me about comments", name: "notify[comments]", checked: true %> <%= lc_checkbox "Weekly digest", name: "notify[digest]", hint: "A summary every Monday." %> <%= lc_checkbox "Product news", name: "notify[news]", disabled: true %> <% end %> ``` Copy from an element: https://ui.lostcoords.com/components/copy_button.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-md" do %> <%= lc_field label: "Share link", id: "my-component-link" do |field| %> <%= lc_input value: "https://ui.lostcoords.com", **field %> <% end %> <%= lc_copy_button "Copy current link", source: "my-component-link", copied_label: "Link copied", class: "w-full" %> <%= lc_text "Edit the link, then copy it. The button reads the current value each time.", size: :small, tone: :muted %> <% end %> ``` Empty state: https://ui.lostcoords.com/components/empty_state.html ```erb <%= lc_empty_state class: "w-full" do %> <%= lc_icon_badge shape: :circle, tone: :primary, icon: "folder-plus", size: :lg%> <%= lc_stack gap: :tight, class: "max-w-xs" do %> <%= lc_heading "No projects yet", level: 3, size: :subheading %> <%= lc_text "Create a project to get started.", size: :small, tone: :muted %> <% end %> <%= lc_button "Create project" %> <% end %> ``` Grouped controls: https://ui.lostcoords.com/components/field.html ```erb <%= lc_stack class: "w-full max-w-sm" do %> <%= lc_fieldset legend: "Split", id: "my-component-split", hint: "Everyone pays the same share unless you change it." do %> <%= lc_inline do %> <%= lc_toggle "Equally", active: true %> <%= lc_toggle "By amount" %> <%= lc_toggle "By share" %> <% end %> <% end %> <%= lc_stack gap: :related do %> <%= lc_text "This app can", size: :label, tone: :muted %> <% end %> <% end %> ``` Focus a field: https://ui.lostcoords.com/components/kbd.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-sm" do %> <%= lc_field label: "Filter projects", id: "my-component-filter" do |field| %> <%= lc_input name: "q", type: :search, placeholder: "Press / to filter", data: lc_shortcut_data("/"), **field %> <% end %> <%= lc_text size: :small, tone: :muted do %> Press <%= lc_kbd "/" %> to filter, then <%= lc_kbd "escape" %> to clear. <% end %> <% end %> ``` Tones: https://ui.lostcoords.com/components/link.html ```erb <%= lc_stack gap: :related do %> <%= lc_text do %>Read the <%= lc_link "installation guide", "/installation.html" %> before you start.<% end %> <%= lc_text size: :small, tone: :muted do %>Questions? <%= lc_link "Contact support", "/components/link.html", tone: :muted %>.<% end %> <%= lc_text do %>See <%= lc_link "what's new", "/components/link.html", tone: :primary %> in this release.<% end %> <% end %> ``` Skip link: https://ui.lostcoords.com/components/skip_link.html ```erb <%= lc_stack gap: :related, class: "items-center" do %> <%= lc_text "Press Tab on this page: the skip link is the first thing to receive focus.", size: :small, tone: :muted %> <%= lc_skip_link "#examples", class: "not-sr-only static" %> <% end %> ``` Switches: https://ui.lostcoords.com/components/switch.html ```erb <%= lc_stack gap: :related do %> <%= lc_switch "Public project", name: "project[public]", checked: true %> <%= lc_switch "Allow comments", name: "project[comments]", hint: "Members can comment on pages." %> <% end %> ``` ## lc_inline https://ui.lostcoords.com/components/foundations.html#lc_inline ```ruby lc_inline(gap: :related, as: :div, **attributes, &block) ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` Expanded swap and decorative span: https://ui.lostcoords.com/components/button.html ```erb <%= lc_inline do %> <%= lc_button "New entry", icon: "plus", expanded_icon: "x-mark", size: :sm, aria: { expanded: false } %> <%= lc_button "New entry", icon: "plus", expanded_icon: "x-mark", size: :sm, aria: { expanded: true } %> <% end %> ``` Form actions: https://ui.lostcoords.com/components/field.html ```erb <%= lc_inline class: "justify-end" do %> <%= lc_button "Cancel", variant: :ghost %> <%= lc_button "Save changes", type: :submit %> <% end %> ``` Grouped controls: https://ui.lostcoords.com/components/field.html ```erb <%= lc_stack class: "w-full max-w-sm" do %> <%= lc_fieldset legend: "Split", id: "my-component-split", hint: "Everyone pays the same share unless you change it." do %> <%= lc_inline do %> <%= lc_toggle "Equally", active: true %> <%= lc_toggle "By amount" %> <%= lc_toggle "By share" %> <% end %> <% end %> <%= lc_stack gap: :related do %> <%= lc_text "This app can", size: :label, tone: :muted %> <% end %> <% end %> ``` Filters: https://ui.lostcoords.com/components/toggle.html ```erb <%= lc_inline role: "group", aria: { label: "Topics" } do %> <%= lc_toggle "Design", active: true %> <%= lc_toggle "Writing" %> <%= lc_toggle "Research" %> <% end %> ``` Navigation: https://ui.lostcoords.com/components/toggle.html ```erb <%= lc_inline do %> <%= lc_toggle "All projects", href: "/components/toggle.html", active: true, size: :sm %> <%= lc_toggle "Archived", href: "/components/badge.html", size: :sm %> <% end %> ``` Form values, native radios and reset: https://ui.lostcoords.com/components/toggle_group.html ```erb
<%= lc_toggle_group label: "Billing", name: "billing", value: "monthly" do %> <%= lc_toggle_group_item "Monthly", value: "monthly" %> <%= lc_toggle_group_item "Annual", value: "annual" %> <%= lc_toggle_group_item "Custom", value: "custom", disabled: true %> <% end %> <%= lc_inline role: "radiogroup", aria: { label: "Heard about us" } do %> <%= lc_toggle "A friend", name: "source", value: "friend", size: :sm %> <%= lc_toggle "Search", name: "source", value: "search", size: :sm %> <% end %> <%= lc_button "Reset", type: :reset, variant: :ghost, size: :sm %>
``` Tooltips: https://ui.lostcoords.com/components/tooltip.html ```erb <%= lc_inline gap: :content do %> <%= lc_tooltip "Copy a link to this page", id: "my-component-copy-tip" do |tip| %> <%= lc_icon_button "Copy link", icon: "link", **tip %> <% end %> <%= lc_tooltip "Only owners can archive", id: "my-component-archive-tip", side: :bottom do |tip| %> <%= lc_button "Archive", variant: :secondary, **tip %> <% end %> <% end %> ``` ## lc_container https://ui.lostcoords.com/components/foundations.html#lc_container ```ruby lc_container(size: :page, **attributes, &block) ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` ## lc_section https://ui.lostcoords.com/components/foundations.html#lc_section ```ruby lc_section(title:, level: 2, actions: nil, **attributes, &block) ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` ## lc_section_header https://ui.lostcoords.com/components/foundations.html#lc_section_header ```ruby lc_section_header(as: :header, **attributes, &block) ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` ## lc_list_section https://ui.lostcoords.com/components/list_group.html#lc_list_section ```ruby lc_list_section(heading, footnote: nil, level: 2, **attributes, &block) ``` Settings: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_section "Sign-in methods", id: "my-component", footnote: "Keep at least one way to sign in.", class: "w-full max-w-md" do %> <%= lc_list_group do %> <%= lc_list_row "Email", subtitle: "ada@example.com", icon: "envelope" do %> <%= lc_button "Change", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Passkey", subtitle: "Not set up", icon: "key" do %> <%= lc_button "Add", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Sign-in alerts", subtitle: "Email me when a new device signs in", icon: "bell", tag: :label, class: "cursor-pointer" do %> <% end %> <%= lc_list_row "Recovery codes", icon: "document-text", href: "#recovery-codes" do %> <%= lc_icon "chevron-right", variant: :mini, options: { class: "size-5 text-muted-foreground rtl:rotate-180", "aria-hidden": true } %> <% end %> <%= lc_list_row padded: false do %> <%= lc_list_item "Delete account", icon: "trash", tag: :button, type: "button", class: "w-full cursor-pointer rounded-[inherit] text-destructive transition-colors hover:bg-accent" %> <% end %> <% end %> <% end %> ``` ## lc_list_group https://ui.lostcoords.com/components/list_group.html#lc_list_group ```ruby lc_list_group(tag: :div, **attributes, &block) ``` Settings: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_section "Sign-in methods", id: "my-component", footnote: "Keep at least one way to sign in.", class: "w-full max-w-md" do %> <%= lc_list_group do %> <%= lc_list_row "Email", subtitle: "ada@example.com", icon: "envelope" do %> <%= lc_button "Change", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Passkey", subtitle: "Not set up", icon: "key" do %> <%= lc_button "Add", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Sign-in alerts", subtitle: "Email me when a new device signs in", icon: "bell", tag: :label, class: "cursor-pointer" do %> <% end %> <%= lc_list_row "Recovery codes", icon: "document-text", href: "#recovery-codes" do %> <%= lc_icon "chevron-right", variant: :mini, options: { class: "size-5 text-muted-foreground rtl:rotate-180", "aria-hidden": true } %> <% end %> <%= lc_list_row padded: false do %> <%= lc_list_item "Delete account", icon: "trash", tag: :button, type: "button", class: "w-full cursor-pointer rounded-[inherit] text-destructive transition-colors hover:bg-accent" %> <% end %> <% end %> <% end %> ``` Form rows: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_group class: "w-full max-w-md" do %> <%= lc_list_field "Description", icon: "pencil", id: "my-component-description" do %> <%= lc_input plain: true, id: "my-component-description", name: "description", placeholder: "Dinner at Ichiran" %> <% end %> <%= lc_list_field "Paid by", icon: "user", tag: :fieldset do %> <% end %> <%= lc_list_field "Date", icon: "calendar", id: "my-component-date" do %> <%= lc_input type: :date, plain: true, id: "my-component-date", name: "date", value: "2026-11-06" %> <% end %> <% end %> ``` ## lc_list_row https://ui.lostcoords.com/components/list_group.html#lc_list_row ```ruby lc_list_row(title = nil, subtitle: nil, icon: nil, href: nil, tag: nil, padded: true, **attributes, &block) ``` Settings: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_section "Sign-in methods", id: "my-component", footnote: "Keep at least one way to sign in.", class: "w-full max-w-md" do %> <%= lc_list_group do %> <%= lc_list_row "Email", subtitle: "ada@example.com", icon: "envelope" do %> <%= lc_button "Change", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Passkey", subtitle: "Not set up", icon: "key" do %> <%= lc_button "Add", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Sign-in alerts", subtitle: "Email me when a new device signs in", icon: "bell", tag: :label, class: "cursor-pointer" do %> <% end %> <%= lc_list_row "Recovery codes", icon: "document-text", href: "#recovery-codes" do %> <%= lc_icon "chevron-right", variant: :mini, options: { class: "size-5 text-muted-foreground rtl:rotate-180", "aria-hidden": true } %> <% end %> <%= lc_list_row padded: false do %> <%= lc_list_item "Delete account", icon: "trash", tag: :button, type: "button", class: "w-full cursor-pointer rounded-[inherit] text-destructive transition-colors hover:bg-accent" %> <% end %> <% end %> <% end %> ``` ## lc_list_field https://ui.lostcoords.com/components/list_group.html#lc_list_field ```ruby lc_list_field(label, icon: nil, id: nil, tag: :div, surface: true, **attributes, &block) ``` Form rows: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_group class: "w-full max-w-md" do %> <%= lc_list_field "Description", icon: "pencil", id: "my-component-description" do %> <%= lc_input plain: true, id: "my-component-description", name: "description", placeholder: "Dinner at Ichiran" %> <% end %> <%= lc_list_field "Paid by", icon: "user", tag: :fieldset do %> <% end %> <%= lc_list_field "Date", icon: "calendar", id: "my-component-date" do %> <%= lc_input type: :date, plain: true, id: "my-component-date", name: "date", value: "2026-11-06" %> <% end %> <% end %> ``` ## lc_list_item https://ui.lostcoords.com/components/list_group.html#lc_list_item ```ruby lc_list_item(title, subtitle: nil, icon: nil, tag: :div, **attributes, &block) ``` Settings: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_section "Sign-in methods", id: "my-component", footnote: "Keep at least one way to sign in.", class: "w-full max-w-md" do %> <%= lc_list_group do %> <%= lc_list_row "Email", subtitle: "ada@example.com", icon: "envelope" do %> <%= lc_button "Change", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Passkey", subtitle: "Not set up", icon: "key" do %> <%= lc_button "Add", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Sign-in alerts", subtitle: "Email me when a new device signs in", icon: "bell", tag: :label, class: "cursor-pointer" do %> <% end %> <%= lc_list_row "Recovery codes", icon: "document-text", href: "#recovery-codes" do %> <%= lc_icon "chevron-right", variant: :mini, options: { class: "size-5 text-muted-foreground rtl:rotate-180", "aria-hidden": true } %> <% end %> <%= lc_list_row padded: false do %> <%= lc_list_item "Delete account", icon: "trash", tag: :button, type: "button", class: "w-full cursor-pointer rounded-[inherit] text-destructive transition-colors hover:bg-accent" %> <% end %> <% end %> <% end %> ``` ## lc_menu https://ui.lostcoords.com/components/menu.html#lc_menu ```ruby lc_menu(id:, label: lc_t("lostcoords.ui.menu.label"), align: :end, trigger: :button, icon: "ellipsis-vertical", trigger_attributes: {}, wrapper_attributes: {}, **attributes, &block) ``` Select trigger: https://ui.lostcoords.com/components/button.html ```erb <%= lc_menu id: "my-component-menu", label: "Member", align: :start do |menu| %> <% menu.trigger(class: "min-w-44") { |attrs| lc_select_trigger "All members", **attrs } %> <%= lc_menu_option "All members", checked: true %> <%= lc_menu_option "Alex", checked: false %> <%= lc_menu_option "Sam", checked: false %> <% end %> ``` Turbo confirm: https://ui.lostcoords.com/components/dialog.html ```erb <%# In the layout, once. %> <%= lc_confirm_sheet %> <%= lc_button_to "Delete project", "/projects/42", method: :delete, variant: :destructive, form: { data: { turbo_confirm: "Delete this project?", turbo_confirm_description: "Its pages and files are deleted for everyone.", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_button_to "Archive", "/projects/42/archival", form: { data: { turbo_confirm: "Archive this project?", turbo_confirm_accept: "Archive project", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_menu id: "my-component-menu", label: "Membership" do %> <%= lc_menu_option "Leave project", href: "/projects/42/membership", method: :delete, tone: :destructive, form: { data: { turbo_confirm: "Leave this project?", turbo_confirm_accept: "Leave", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <% end %> ``` Actions: https://ui.lostcoords.com/components/menu.html ```erb <%= lc_menu id: "my-component-menu", label: "Project actions" do %> <%= lc_menu_option "Edit project", href: "/components/input.html" %> <%= lc_menu_option "Duplicate project" %> <%= lc_menu_option "Archive project", tone: :destructive %> <% end %> ``` Icon trigger, hints, choices and groups: https://ui.lostcoords.com/components/menu.html ```erb
<%= lc_menu id: "my-component-row-menu", label: "Actions for Alex", trigger: :icon do %> <%= lc_menu_option "Rename", icon: "pencil" %> <%= lc_menu_option "Move up", icon: "arrow-up", hint: "Second in the list" %> <%= lc_menu_option "Copy link" %> <%= lc_menu_option "Pinned", icon: "star", checkbox: true %> <%= lc_menu_option "Remove", icon: "trash", href: "/components/menu.html", method: :delete, tone: :destructive %> <% end %> <%= lc_menu id: "my-component-currency-menu", label: "Currency", align: :start do |menu| %> <% menu.trigger { |attrs| lc_select_trigger "Euro", **attrs } %> <%= lc_menu_group "Suggested", id: "my-component-suggested" do %> <%= lc_menu_option "Euro", hint: "EUR", leading: tag.span("€"), checked: true %> <%= lc_menu_option "Japanese yen", hint: "JPY", leading: tag.span("¥"), checked: false %> <% end %> <%= lc_menu_group "Other", id: "my-component-other" do %> <%= lc_menu_option "US dollar", hint: "USD", leading: tag.span("$"), checked: false %> <% end %> <% end %>
``` ## lc_popover https://ui.lostcoords.com/components/popover.html#lc_popover ```ruby lc_popover(id:, label: lc_t("lostcoords.ui.popover.trigger"), title: nil, align: :end, trigger_variant: :secondary, trigger: :button, icon: "ellipsis-vertical", trigger_attributes: {}, wrapper_attributes: {}, **attributes, &block) ``` Anchored content: https://ui.lostcoords.com/components/popover.html ```erb <%= lc_popover id: "my-component-popover", label: "Project details", title: "Design system" do %>

Updated a moment ago by Alex.

<% end %> ``` Opened from a row: https://ui.lostcoords.com/components/popover.html ```erb ``` ## lc_menu_option https://ui.lostcoords.com/components/menu.html#lc_menu_option ```ruby lc_menu_option(label = nil, href: nil, tone: :default, icon: nil, leading: nil, hint: nil, checked: nil, checkbox: false, method: nil, params: {}, form: {}, **attributes, &block) ``` Select trigger: https://ui.lostcoords.com/components/button.html ```erb <%= lc_menu id: "my-component-menu", label: "Member", align: :start do |menu| %> <% menu.trigger(class: "min-w-44") { |attrs| lc_select_trigger "All members", **attrs } %> <%= lc_menu_option "All members", checked: true %> <%= lc_menu_option "Alex", checked: false %> <%= lc_menu_option "Sam", checked: false %> <% end %> ``` Split button: https://ui.lostcoords.com/components/button.html ```erb <%= lc_split_button "Add expense", id: "my-component-menu", icon: "plus", menu_label: "More ways to add" do %> <%= lc_menu_option "Import a CSV", icon: "arrow-down-tray" %> <%= lc_menu_option "Scan a receipt", icon: "camera" %> <% end %> ``` Split button variants and sizes: https://ui.lostcoords.com/components/button.html ```erb <% [ [ :secondary, :sm ], [ :outline, :md ], [ :ghost, :lg ] ].each do |variant, size| %> <%= lc_split_button "Export", id: "my-component-#{variant}", variant: variant, size: size, menu_label: "Export options" do %> <%= lc_menu_option "Export as CSV" %> <%= lc_menu_option "Export as PDF" %> <% end %> <% end %> ``` Turbo confirm: https://ui.lostcoords.com/components/dialog.html ```erb <%# In the layout, once. %> <%= lc_confirm_sheet %> <%= lc_button_to "Delete project", "/projects/42", method: :delete, variant: :destructive, form: { data: { turbo_confirm: "Delete this project?", turbo_confirm_description: "Its pages and files are deleted for everyone.", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_button_to "Archive", "/projects/42/archival", form: { data: { turbo_confirm: "Archive this project?", turbo_confirm_accept: "Archive project", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_menu id: "my-component-menu", label: "Membership" do %> <%= lc_menu_option "Leave project", href: "/projects/42/membership", method: :delete, tone: :destructive, form: { data: { turbo_confirm: "Leave this project?", turbo_confirm_accept: "Leave", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <% end %> ``` Actions: https://ui.lostcoords.com/components/menu.html ```erb <%= lc_menu id: "my-component-menu", label: "Project actions" do %> <%= lc_menu_option "Edit project", href: "/components/input.html" %> <%= lc_menu_option "Duplicate project" %> <%= lc_menu_option "Archive project", tone: :destructive %> <% end %> ``` Icon trigger, hints, choices and groups: https://ui.lostcoords.com/components/menu.html ```erb
<%= lc_menu id: "my-component-row-menu", label: "Actions for Alex", trigger: :icon do %> <%= lc_menu_option "Rename", icon: "pencil" %> <%= lc_menu_option "Move up", icon: "arrow-up", hint: "Second in the list" %> <%= lc_menu_option "Copy link" %> <%= lc_menu_option "Pinned", icon: "star", checkbox: true %> <%= lc_menu_option "Remove", icon: "trash", href: "/components/menu.html", method: :delete, tone: :destructive %> <% end %> <%= lc_menu id: "my-component-currency-menu", label: "Currency", align: :start do |menu| %> <% menu.trigger { |attrs| lc_select_trigger "Euro", **attrs } %> <%= lc_menu_group "Suggested", id: "my-component-suggested" do %> <%= lc_menu_option "Euro", hint: "EUR", leading: tag.span("€"), checked: true %> <%= lc_menu_option "Japanese yen", hint: "JPY", leading: tag.span("¥"), checked: false %> <% end %> <%= lc_menu_group "Other", id: "my-component-other" do %> <%= lc_menu_option "US dollar", hint: "USD", leading: tag.span("$"), checked: false %> <% end %> <% end %>
``` ## lc_menu_group https://ui.lostcoords.com/components/menu.html#lc_menu_group ```ruby lc_menu_group(label, id:, **attributes, &block) ``` Icon trigger, hints, choices and groups: https://ui.lostcoords.com/components/menu.html ```erb
<%= lc_menu id: "my-component-row-menu", label: "Actions for Alex", trigger: :icon do %> <%= lc_menu_option "Rename", icon: "pencil" %> <%= lc_menu_option "Move up", icon: "arrow-up", hint: "Second in the list" %> <%= lc_menu_option "Copy link" %> <%= lc_menu_option "Pinned", icon: "star", checkbox: true %> <%= lc_menu_option "Remove", icon: "trash", href: "/components/menu.html", method: :delete, tone: :destructive %> <% end %> <%= lc_menu id: "my-component-currency-menu", label: "Currency", align: :start do |menu| %> <% menu.trigger { |attrs| lc_select_trigger "Euro", **attrs } %> <%= lc_menu_group "Suggested", id: "my-component-suggested" do %> <%= lc_menu_option "Euro", hint: "EUR", leading: tag.span("€"), checked: true %> <%= lc_menu_option "Japanese yen", hint: "JPY", leading: tag.span("¥"), checked: false %> <% end %> <%= lc_menu_group "Other", id: "my-component-other" do %> <%= lc_menu_option "US dollar", hint: "USD", leading: tag.span("$"), checked: false %> <% end %> <% end %>
``` ## lc_link https://ui.lostcoords.com/components/link.html#lc_link ```ruby lc_link(content = nil, url = nil, tone: :inherit, **attributes, &block) ``` Tones: https://ui.lostcoords.com/components/link.html ```erb <%= lc_stack gap: :related do %> <%= lc_text do %>Read the <%= lc_link "installation guide", "/installation.html" %> before you start.<% end %> <%= lc_text size: :small, tone: :muted do %>Questions? <%= lc_link "Contact support", "/components/link.html", tone: :muted %>.<% end %> <%= lc_text do %>See <%= lc_link "what's new", "/components/link.html", tone: :primary %> in this release.<% end %> <% end %> ``` ## lc_nav_list https://ui.lostcoords.com/components/nav_list.html#lc_nav_list ```ruby lc_nav_list(label:, compact: false, layout: :column, indicator: false, **attributes, &block) nav.link(label = nil, url = nil, icon: nil, current: false, indent: false, **attributes, &block) nav.group(title, **attributes, &block) ``` Sidebar: https://ui.lostcoords.com/components/nav_list.html ```erb <%= lc_nav_list label: "Settings", class: "w-full max-w-60" do |nav| %> <%= nav.group "Workspace" do %> <%= nav.link "General", "#general", current: true %> <%= nav.link "Members", "#members" %> <%= nav.link "Billing", "#billing" %> <% end %> <%= nav.group "Account" do %> <%= nav.link "Profile", "#profile" %> <%= nav.link "Notifications", "#notifications" %> <% end %> <% end %> ``` On this page: https://ui.lostcoords.com/components/nav_list.html ```erb <%= lc_nav_list label: "On this page", compact: true, class: "w-full max-w-48" do |nav| %> <%= nav.link "Overview", "#overview", current: true %> <%= nav.link "Usage", "#usage" %> <%= nav.link "Sizes", "#sizes", indent: true %> <%= nav.link "API reference", "#api" %> <% end %> ``` Row with a sliding indicator: https://ui.lostcoords.com/components/nav_list.html ```erb <%= lc_nav_list label: "Project", layout: :row, indicator: true, class: "w-full" do |nav| %> <%= nav.link "Overview", "#overview", icon: "document-text", current: true %> <%= nav.link "Activity", "#activity", icon: "clock" %> <%= nav.link "Files", "#files", icon: "paper-clip" %> <%= nav.link "Settings", "#settings", icon: "cog-6-tooth" %> <% end %> ``` Dock: https://ui.lostcoords.com/components/nav_list.html ```erb <%# On phones, fix it to the bottom with your own classes. layout: :responsive is a dock below sm and a row from sm. %> <%= lc_nav_list label: "Group", layout: :dock, indicator: true, class: lc_glass_class(thick: true, extra: "w-full max-w-sm") do |nav| %> <%= nav.link "Overview", "#overview", icon: "document-text", current: true %> <%= nav.link "Members", "#members", icon: "users" %> <%= nav.link "Activity", "#activity", icon: "clock" %> <%= nav.link "Stats", "#stats", icon: "chart-bar" %> <% end %> ``` ## lc_pager https://ui.lostcoords.com/components/pager.html#lc_pager ```ruby lc_pager(previous: nil, next: nil, label: lc_t("lostcoords.ui.pager.label"), compact: false, **attributes) ``` Pager: https://ui.lostcoords.com/components/pager.html ```erb <%= lc_pager previous: [ "Installation", "/components/pager.html" ], next: [ "Theming", "/components/pager.html" ], class: "w-full" %> ``` Compact: https://ui.lostcoords.com/components/pager.html ```erb <%= lc_pager previous: [ "Button", "/components/pager.html" ], next: [ "Card", "/components/pager.html" ], label: "Components", compact: true %> ``` ## lc_skip_link https://ui.lostcoords.com/components/skip_link.html#lc_skip_link ```ruby lc_skip_link(target = "#main", label: lc_t("lostcoords.ui.skip_link.label"), **attributes) ``` Skip link: https://ui.lostcoords.com/components/skip_link.html ```erb <%= lc_stack gap: :related, class: "items-center" do %> <%= lc_text "Press Tab on this page: the skip link is the first thing to receive focus.", size: :small, tone: :muted %> <%= lc_skip_link "#examples", class: "not-sr-only static" %> <% end %> ``` ## lc_breadcrumb https://ui.lostcoords.com/components/breadcrumb.html#lc_breadcrumb ```ruby lc_breadcrumb(items, label: lc_t("lostcoords.ui.breadcrumb.label"), **attributes) ``` Breadcrumb: https://ui.lostcoords.com/components/breadcrumb.html ```erb <%= lc_breadcrumb [ [ "Projects", "/components/breadcrumb.html" ], [ "Design system", "/components/breadcrumb.html" ], "Settings" ] %> ``` ## lc_tabs https://ui.lostcoords.com/components/tabs.html#lc_tabs ```ruby lc_tabs(id:, label:, selected: nil, orientation: :horizontal, activation: :automatic, list: {}, **attributes, &block) tabs.panel(label, value: nil, **attributes, &block) ``` Tabs: https://ui.lostcoords.com/components/tabs.html ```erb <%= lc_tabs id: "my-component-tabs", label: "Project", class: "w-full" do |tabs| %> <% tabs.panel "Overview" do %> <%= lc_text "Pages, members and recent changes." %> <% end %> <% tabs.panel "Activity" do %> <%= lc_text "Nothing new this week.", tone: :muted %> <% end %> <% tabs.panel "Settings" do %> <%= lc_switch "Public project", name: "project[public]" %> <% end %> <% end %> ``` Vertical, with manual activation: https://ui.lostcoords.com/components/tabs.html ```erb <%= lc_tabs id: "my-component-settings", label: "Settings", orientation: :vertical, activation: :manual, class: "w-full" do |tabs| %> <% tabs.panel "Profile" do %> <%= lc_text "Name, photo and contact details." %> <% end %> <% tabs.panel "Notifications" do %> <%= lc_switch "Email me about mentions", name: "settings[mentions]" %> <% end %> <% tabs.panel "Billing" do %> <%= lc_text "Plan, invoices and payment method.", tone: :muted %> <% end %> <% end %> ``` ## lc_button https://ui.lostcoords.com/components/button.html#lc_button ```ruby lc_button(content = nil, variant: :primary, tone: :default, size: :md, block: false, icon: nil, icon_position: :start, as: :button, expanded_icon: nil, **attributes, &content_block) ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` Reading content: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_prose do %>

Make room for the trip

A shared plan is easier to follow when each idea has room to breathe. Keep the essentials close and give a new topic a little more space.

Start with one clear decision, name the plan kyoto-weekend, then choose what comes next.

The best part of a plan is the space it leaves for a surprise.

Ready to begin?

Buttons and other app controls can opt out of reading styles.

<%= lc_button "Create a plan" %>
<% end %> ``` Hover and press: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_button "Hover or press", icon: "plus" %> <%= lc_button "Secondary", variant: :secondary %> <%= lc_icon_button "Add item", icon: "plus" %> ``` Title and actions: https://ui.lostcoords.com/components/alert.html ```erb <%= lc_alert "Your card was declined. Update the payment method to keep the workspace active.", title: "Payment failed" do |alert| %> <%= alert.actions do %> <%= lc_button "Update payment", size: :sm %> <%= lc_button "Dismiss", variant: :ghost, size: :sm %> <% end %> <% end %> ``` Default: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button "Create project" %> ``` Variants: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button "Primary" %> <%= lc_button "Secondary", variant: :secondary %> <%= lc_button "Outline", variant: :outline %> <%= lc_button "Ghost", variant: :ghost %> <%= lc_button "Glass", variant: :glass %> <%= lc_button "Delete", variant: :destructive %> ``` Destructive tone: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button "Revoke", variant: :ghost, tone: :destructive %> <%= lc_button "Sign out", variant: :outline, tone: :destructive %> <%= lc_button "Remove member", variant: :secondary, tone: :destructive %> <%= lc_button "Delete group", tone: :destructive %> ``` Glass over content: https://ui.lostcoords.com/components/button.html ```erb

Use glass for controls floating over content. Its translucency is subtle on a flat background.

<%= lc_button "Save", variant: :glass, icon: "bookmark" %> <%= lc_button "Share", variant: :glass, icon: "arrow-up-tray" %>
``` Sizes: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button "Small", size: :sm %> <%= lc_button "Default" %> <%= lc_button "Large", size: :lg %> ``` With an icon: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button "Create project", icon: "plus" %> <%= lc_button "Continue", icon: "arrow-right", icon_position: :end, variant: :secondary %> ``` Custom icons and content: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button variant: :secondary do %> <%= lc_icon "arrow-down-tray", options: { "aria-hidden": true, "data-icon": "inline-start" } %> Download report <% end %> <%= lc_button disabled: true, aria: { busy: true } do %> <%= lc_spinner size: :sm, label: nil, data: { icon: "inline-start" } %> Loading report… <% end %> ``` Loading: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button disabled: true, aria: { busy: true } do %> <%= lc_spinner size: :sm, label: nil, data: { icon: "inline-start" } %> Saving… <% end %> ``` Disabled: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button "Unavailable", disabled: true %> ``` Expanded swap and decorative span: https://ui.lostcoords.com/components/button.html ```erb <%= lc_inline do %> <%= lc_button "New entry", icon: "plus", expanded_icon: "x-mark", size: :sm, aria: { expanded: false } %> <%= lc_button "New entry", icon: "plus", expanded_icon: "x-mark", size: :sm, aria: { expanded: true } %> <% end %> ``` Default: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.header title: "Project notes", description: "Keep related content together." do %> <%= lc_button "Edit", variant: :secondary, size: :sm %> <% end %> <%= card.content do %> <%= lc_text "Notes, links and files for the launch." %> <% end %> <%= card.footer do %> <%= lc_button "Archive", variant: :ghost %> <%= lc_button "Share" %> <% end %> <% end %> ``` Custom spacing: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full [--lc-inset:var(--spacing-section)]" do |card| %> <%= card.header title: "Welcome", description: "Padding and the gaps between parts both follow --lc-inset." %> <%= card.footer do %> <%= lc_button "Get started" %> <% end %> <% end %> ``` With form controls: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "@container w-full" do |card| %> <%= card.header title: "Project settings" %> <%= card.content do %> <%= lc_field label: "Project name", id: "my-component-name" do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <%= card.footer do %> <%= lc_button "Save changes" %> <% end %> <% end %> ``` Modal: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-dialog", title: "Create project", description: "Projects group pages and members.", trigger: "New project" do |dialog| %>
<%= lc_field label: "Project name", id: "my-component-dialog-name" do |field| %> <%= lc_input name: "project[name]", **field %> <% end %> <%= dialog.footer do %> <%= dialog.close %> <%= lc_button "Create project", type: :submit %> <% end %>
<% end %> ``` Compact dialog: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-context", title: "Quick details", trigger: "Open compact dialog", kind: :context do %>

A compact dialog for a short, focused task.

<% end %> <%= lc_dialog id: "my-component-invite", title: "Invite people", kind: :context do |dialog| %> <% dialog.trigger { |attrs| lc_button "Invite with your own trigger", variant: :ghost, **attrs } %>

This step marks itself data-dialog-size="md", so the compact dialog widens to 32rem while it shows.

<% end %> ``` Opened by your controller: https://ui.lostcoords.com/components/dialog.html ```erb
<%= lc_button "Show members", variant: :secondary, aria: { haspopup: "dialog", controls: "my-component-members" }, data: { action: "lc-dialog#open" } %> <%= lc_dialog id: "my-component-members", title: "Members", trigger: false, size: :lg, detents: "large", data: { lc_dialog_target: "dialog" } do |dialog| %> <%= dialog.actions do %> <%= lc_button "Invite", size: :sm %> <% end %> <% %w[Aiko Ben Chiara Dmitri Emi Farah Goro Hana].each do |name| %>

<%= name %>

<% end %> <% end %>
``` Empty state: https://ui.lostcoords.com/components/empty_state.html ```erb <%= lc_empty_state class: "w-full" do %> <%= lc_icon_badge shape: :circle, tone: :primary, icon: "folder-plus", size: :lg%> <%= lc_stack gap: :tight, class: "max-w-xs" do %> <%= lc_heading "No projects yet", level: 3, size: :subheading %> <%= lc_text "Create a project to get started.", size: :small, tone: :muted %> <% end %> <%= lc_button "Create project" %> <% end %> ``` Form actions: https://ui.lostcoords.com/components/field.html ```erb <%= lc_inline class: "justify-end" do %> <%= lc_button "Cancel", variant: :ghost %> <%= lc_button "Save changes", type: :submit %> <% end %> ``` Settings: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_section "Sign-in methods", id: "my-component", footnote: "Keep at least one way to sign in.", class: "w-full max-w-md" do %> <%= lc_list_group do %> <%= lc_list_row "Email", subtitle: "ada@example.com", icon: "envelope" do %> <%= lc_button "Change", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Passkey", subtitle: "Not set up", icon: "key" do %> <%= lc_button "Add", variant: :secondary, size: :sm %> <% end %> <%= lc_list_row "Sign-in alerts", subtitle: "Email me when a new device signs in", icon: "bell", tag: :label, class: "cursor-pointer" do %> <% end %> <%= lc_list_row "Recovery codes", icon: "document-text", href: "#recovery-codes" do %> <%= lc_icon "chevron-right", variant: :mini, options: { class: "size-5 text-muted-foreground rtl:rotate-180", "aria-hidden": true } %> <% end %> <%= lc_list_row padded: false do %> <%= lc_list_item "Delete account", icon: "trash", tag: :button, type: "button", class: "w-full cursor-pointer rounded-[inherit] text-destructive transition-colors hover:bg-accent" %> <% end %> <% end %> <% end %> ``` Over dialogs and sticky headers: https://ui.lostcoords.com/components/toast.html ```erb <%# In an app, render the region once in the layout and append toasts with turbo_stream.append. %> <%= lc_toast_region id: "my-component-toasts" %> <%= lc_button "Save project", data: { controller: "toast-demo", action: "toast-demo#show", toast_demo_template_value: "my-component-toast", toast_demo_region_value: "my-component-toasts" } %> ``` Centred, at the top on phones: https://ui.lostcoords.com/components/toast.html ```erb <%# Centred at the bottom, and at the top on phones, clear of a bottom tab bar. %> <%= lc_toast_region id: "my-component-toasts", placement: :bottom_center, mobile_placement: :top_center %> <%= lc_button "Add expense", data: { controller: "toast-demo", action: "toast-demo#show", toast_demo_template_value: "my-component-toast", toast_demo_region_value: "my-component-toasts" } %> ``` Form values, native radios and reset: https://ui.lostcoords.com/components/toggle_group.html ```erb
<%= lc_toggle_group label: "Billing", name: "billing", value: "monthly" do %> <%= lc_toggle_group_item "Monthly", value: "monthly" %> <%= lc_toggle_group_item "Annual", value: "annual" %> <%= lc_toggle_group_item "Custom", value: "custom", disabled: true %> <% end %> <%= lc_inline role: "radiogroup", aria: { label: "Heard about us" } do %> <%= lc_toggle "A friend", name: "source", value: "friend", size: :sm %> <%= lc_toggle "Search", name: "source", value: "search", size: :sm %> <% end %> <%= lc_button "Reset", type: :reset, variant: :ghost, size: :sm %>
``` Tooltips: https://ui.lostcoords.com/components/tooltip.html ```erb <%= lc_inline gap: :content do %> <%= lc_tooltip "Copy a link to this page", id: "my-component-copy-tip" do |tip| %> <%= lc_icon_button "Copy link", icon: "link", **tip %> <% end %> <%= lc_tooltip "Only owners can archive", id: "my-component-archive-tip", side: :bottom do |tip| %> <%= lc_button "Archive", variant: :secondary, **tip %> <% end %> <% end %> ``` ## lc_button_link_to https://ui.lostcoords.com/components/button.html#lc_button_link_to ```ruby lc_button_link_to(content = nil, url = nil, variant: :primary, tone: :default, size: :md, block: false, icon: nil, icon_position: :start, **attributes, &content_block) ``` As a link: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button_link_to "Browse components", "/components/button.html", variant: :secondary %> ``` ## lc_button_to https://ui.lostcoords.com/components/button.html#lc_button_to ```ruby lc_button_to(content = nil, url = nil, variant: :primary, tone: :default, size: :md, block: false, icon: nil, icon_position: :start, **attributes, &content_block) ``` HTTP actions: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button_to "Archive project", "/projects/42", method: :delete, variant: :destructive, form: { data: { turbo_confirm: "Archive this project?" } } %> ``` Turbo confirm: https://ui.lostcoords.com/components/dialog.html ```erb <%# In the layout, once. %> <%= lc_confirm_sheet %> <%= lc_button_to "Delete project", "/projects/42", method: :delete, variant: :destructive, form: { data: { turbo_confirm: "Delete this project?", turbo_confirm_description: "Its pages and files are deleted for everyone.", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_button_to "Archive", "/projects/42/archival", form: { data: { turbo_confirm: "Archive this project?", turbo_confirm_accept: "Archive project", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <%= lc_menu id: "my-component-menu", label: "Membership" do %> <%= lc_menu_option "Leave project", href: "/projects/42/membership", method: :delete, tone: :destructive, form: { data: { turbo_confirm: "Leave this project?", turbo_confirm_accept: "Leave", controller: "confirm-demo", action: "confirm-demo#submit" } } %> <% end %> ``` ## lc_select_trigger https://ui.lostcoords.com/components/button.html#lc_select_trigger ```ruby lc_select_trigger(label = nil, size: :md, block: false, **attributes, &content) ``` Select trigger: https://ui.lostcoords.com/components/button.html ```erb <%= lc_menu id: "my-component-menu", label: "Member", align: :start do |menu| %> <% menu.trigger(class: "min-w-44") { |attrs| lc_select_trigger "All members", **attrs } %> <%= lc_menu_option "All members", checked: true %> <%= lc_menu_option "Alex", checked: false %> <%= lc_menu_option "Sam", checked: false %> <% end %> ``` Icon trigger, hints, choices and groups: https://ui.lostcoords.com/components/menu.html ```erb
<%= lc_menu id: "my-component-row-menu", label: "Actions for Alex", trigger: :icon do %> <%= lc_menu_option "Rename", icon: "pencil" %> <%= lc_menu_option "Move up", icon: "arrow-up", hint: "Second in the list" %> <%= lc_menu_option "Copy link" %> <%= lc_menu_option "Pinned", icon: "star", checkbox: true %> <%= lc_menu_option "Remove", icon: "trash", href: "/components/menu.html", method: :delete, tone: :destructive %> <% end %> <%= lc_menu id: "my-component-currency-menu", label: "Currency", align: :start do |menu| %> <% menu.trigger { |attrs| lc_select_trigger "Euro", **attrs } %> <%= lc_menu_group "Suggested", id: "my-component-suggested" do %> <%= lc_menu_option "Euro", hint: "EUR", leading: tag.span("€"), checked: true %> <%= lc_menu_option "Japanese yen", hint: "JPY", leading: tag.span("¥"), checked: false %> <% end %> <%= lc_menu_group "Other", id: "my-component-other" do %> <%= lc_menu_option "US dollar", hint: "USD", leading: tag.span("$"), checked: false %> <% end %> <% end %>
``` ## lc_split_button https://ui.lostcoords.com/components/button.html#lc_split_button ```ruby lc_split_button(label, id:, href: nil, menu_label: lc_t("lostcoords.ui.menu.label"), variant: :primary, tone: :default, size: :md, icon: nil, icon_position: :start, block: false, align: :end, action: {}, toggle: {}, menu: {}, **attributes, &items) ``` Split button: https://ui.lostcoords.com/components/button.html ```erb <%= lc_split_button "Add expense", id: "my-component-menu", icon: "plus", menu_label: "More ways to add" do %> <%= lc_menu_option "Import a CSV", icon: "arrow-down-tray" %> <%= lc_menu_option "Scan a receipt", icon: "camera" %> <% end %> ``` Split button variants and sizes: https://ui.lostcoords.com/components/button.html ```erb <% [ [ :secondary, :sm ], [ :outline, :md ], [ :ghost, :lg ] ].each do |variant, size| %> <%= lc_split_button "Export", id: "my-component-#{variant}", variant: variant, size: size, menu_label: "Export options" do %> <%= lc_menu_option "Export as CSV" %> <%= lc_menu_option "Export as PDF" %> <% end %> <% end %> ``` ## lc_icon_button https://ui.lostcoords.com/components/button.html#lc_icon_button ```ruby lc_icon_button(label, icon: nil, size: :md, shape: :circle, variant: :ghost, tone: :default, **attributes, &content) ``` Hover and press: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_button "Hover or press", icon: "plus" %> <%= lc_button "Secondary", variant: :secondary %> <%= lc_icon_button "Add item", icon: "plus" %> ``` Icon buttons: https://ui.lostcoords.com/components/button.html ```erb <%= lc_icon_button "Add project", icon: "plus" %> <%= lc_icon_button "Settings", icon: "cog-6-tooth", shape: :square %> <%= lc_icon_button "Search", icon: "magnifying-glass", size: :sm %> <%= lc_icon_button "Close", icon: "x-mark", size: :lg %> <%= lc_icon_button_link_to "Back to buttons", "/components/button.html", icon: "chevron-left", shape: :square %> <%= lc_icon_button "Account", size: :lg do %>AL<% end %> <%= lc_icon_button_to "Reload buttons", "/components/button.html", icon: "arrow-path", method: :get, form: { class: "contents" } %> <%= lc_icon_button "Edit", icon: "pencil", variant: :secondary %> <%= lc_icon_button "Delete file", icon: "trash", variant: :outline, tone: :destructive %> ``` Tooltips: https://ui.lostcoords.com/components/tooltip.html ```erb <%= lc_inline gap: :content do %> <%= lc_tooltip "Copy a link to this page", id: "my-component-copy-tip" do |tip| %> <%= lc_icon_button "Copy link", icon: "link", **tip %> <% end %> <%= lc_tooltip "Only owners can archive", id: "my-component-archive-tip", side: :bottom do |tip| %> <%= lc_button "Archive", variant: :secondary, **tip %> <% end %> <% end %> ``` ## lc_icon_button_link_to https://ui.lostcoords.com/components/button.html#lc_icon_button_link_to ```ruby lc_icon_button_link_to(label, url, icon: nil, size: :md, shape: :circle, variant: :ghost, tone: :default, **attributes, &content) ``` Icon buttons: https://ui.lostcoords.com/components/button.html ```erb <%= lc_icon_button "Add project", icon: "plus" %> <%= lc_icon_button "Settings", icon: "cog-6-tooth", shape: :square %> <%= lc_icon_button "Search", icon: "magnifying-glass", size: :sm %> <%= lc_icon_button "Close", icon: "x-mark", size: :lg %> <%= lc_icon_button_link_to "Back to buttons", "/components/button.html", icon: "chevron-left", shape: :square %> <%= lc_icon_button "Account", size: :lg do %>AL<% end %> <%= lc_icon_button_to "Reload buttons", "/components/button.html", icon: "arrow-path", method: :get, form: { class: "contents" } %> <%= lc_icon_button "Edit", icon: "pencil", variant: :secondary %> <%= lc_icon_button "Delete file", icon: "trash", variant: :outline, tone: :destructive %> ``` ## lc_icon_button_to https://ui.lostcoords.com/components/button.html#lc_icon_button_to ```ruby lc_icon_button_to(label, url, icon: nil, size: :md, shape: :circle, variant: :ghost, tone: :default, **attributes, &content) ``` Icon buttons: https://ui.lostcoords.com/components/button.html ```erb <%= lc_icon_button "Add project", icon: "plus" %> <%= lc_icon_button "Settings", icon: "cog-6-tooth", shape: :square %> <%= lc_icon_button "Search", icon: "magnifying-glass", size: :sm %> <%= lc_icon_button "Close", icon: "x-mark", size: :lg %> <%= lc_icon_button_link_to "Back to buttons", "/components/button.html", icon: "chevron-left", shape: :square %> <%= lc_icon_button "Account", size: :lg do %>AL<% end %> <%= lc_icon_button_to "Reload buttons", "/components/button.html", icon: "arrow-path", method: :get, form: { class: "contents" } %> <%= lc_icon_button "Edit", icon: "pencil", variant: :secondary %> <%= lc_icon_button "Delete file", icon: "trash", variant: :outline, tone: :destructive %> ``` ## lc_badge https://ui.lostcoords.com/components/badge.html#lc_badge ```ruby lc_badge(content = nil, tone: :neutral, shape: :rounded, **attributes, &block) ``` Tones: https://ui.lostcoords.com/components/badge.html ```erb <%= lc_badge "Draft" %> <%= lc_badge "Published", tone: :primary %> <%= lc_badge "Complete", tone: :success %> <%= lc_badge "Needs attention", tone: :warning %> <%= lc_badge "Failed", tone: :destructive %> ``` Pill status: https://ui.lostcoords.com/components/badge.html ```erb <%= lc_badge "On track", tone: :primary, shape: :pill %> <%= lc_badge "Pending", shape: :pill %> <%= lc_badge "3 errors", tone: :destructive, shape: :pill %> ``` Details: https://ui.lostcoords.com/components/description_list.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.header title: "Workspace" %> <%= lc_description_list do |list| %> <%= list.item "Owner", "Ada Baker" %> <%= list.item "Plan" do %> <%= lc_badge "Team", tone: :primary %> <% end %> <%= list.item "Created", "March 4, 2026" %> <% end %> <% end %> ``` ## lc_icon_badge https://ui.lostcoords.com/components/icon_badge.html#lc_icon_badge ```ruby lc_icon_badge(content = nil, icon: nil, size: :md, shape: :square, tone: :neutral, **attributes, &block) ``` Empty state: https://ui.lostcoords.com/components/empty_state.html ```erb <%= lc_empty_state class: "w-full" do %> <%= lc_icon_badge shape: :circle, tone: :primary, icon: "folder-plus", size: :lg%> <%= lc_stack gap: :tight, class: "max-w-xs" do %> <%= lc_heading "No projects yet", level: 3, size: :subheading %> <%= lc_text "Create a project to get started.", size: :small, tone: :muted %> <% end %> <%= lc_button "Create project" %> <% end %> ``` Shapes and sizes: https://ui.lostcoords.com/components/icon_badge.html ```erb <%= lc_icon_badge icon: "folder", size: :sm %> <%= lc_icon_badge icon: "folder" %> <%= lc_icon_badge icon: "document-text", size: :lg %> <%= lc_icon_badge icon: "document-text", size: :xl %> <%= lc_icon_badge "🍜", aria: { hidden: true } %> <%= lc_icon_badge "🍜", size: 7, shape: :plain, aria: { hidden: true } %> ``` Round icons and tones: https://ui.lostcoords.com/components/icon_badge.html ```erb <%= lc_icon_badge shape: :circle, size: :sm, icon: "sparkles", tone: :primary%> <%= lc_icon_badge shape: :circle, icon: "user-plus", tone: :neutral, size: :lg%> ``` ## lc_avatar https://ui.lostcoords.com/components/avatar.html#lc_avatar ```ruby lc_avatar(content = nil, src: nil, alt: nil, size: :md, ink: false, linked: false, as: :span, **attributes, &block) ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Initials and images: https://ui.lostcoords.com/components/avatar.html ```erb <%= lc_avatar "AL", ink: true, class: "bg-accent", aria: { label: "Alex Lee" } %> <%= lc_avatar "SK", size: :lg, ink: true, class: "bg-success-soft", aria: { label: "Sam Kim" } %> <%= lc_avatar "JR", ink: true, class: "bg-warning-soft", aria: { label: "Jamie Rivera" } %> <%= lc_avatar "MK", ink: true, class: "bg-destructive-soft", aria: { label: "Morgan Kim" } %> ``` Sizes: https://ui.lostcoords.com/components/avatar.html ```erb <% [ :xs, :sm, 7, :md, 11, :lg, :xl, :xxl ].each do |size| %> <%= lc_avatar "AL", size: size, ink: true, class: "bg-accent", aria: { label: "Alex Lee (#{size})" } %> <% end %> ``` Avatar groups: https://ui.lostcoords.com/components/avatar.html ```erb <%= lc_avatar_stack aria: { label: "Alex, Sam and Jamie" } do %> <%= lc_avatar "AL", ink: true, class: "bg-success-soft" %> <%= lc_avatar "SK", ink: true, class: "bg-warning-soft" %> <%= lc_avatar "JR", ink: true, class: "bg-destructive-soft" %> <% end %> ``` ## lc_avatar_stack https://ui.lostcoords.com/components/avatar.html#lc_avatar_stack ```ruby lc_avatar_stack(compact: false, row: {}, **attributes, &block) ``` Avatar groups: https://ui.lostcoords.com/components/avatar.html ```erb <%= lc_avatar_stack aria: { label: "Alex, Sam and Jamie" } do %> <%= lc_avatar "AL", ink: true, class: "bg-success-soft" %> <%= lc_avatar "SK", ink: true, class: "bg-warning-soft" %> <%= lc_avatar "JR", ink: true, class: "bg-destructive-soft" %> <% end %> ``` ## lc_card https://ui.lostcoords.com/components/card.html#lc_card ```ruby lc_card(href: nil, interactive: false, padding: :md, as: :div, **attributes, &block) card.header(title: nil, description: nil, level: 3, **attributes, &actions) card.title(content = nil, level: 3, **attributes, &block) card.description(content = nil, **attributes, &block) card.content(**attributes, &block) card.footer(**attributes, &block) ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` Default: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.header title: "Project notes", description: "Keep related content together." do %> <%= lc_button "Edit", variant: :secondary, size: :sm %> <% end %> <%= card.content do %> <%= lc_text "Notes, links and files for the launch." %> <% end %> <%= card.footer do %> <%= lc_button "Archive", variant: :ghost %> <%= lc_button "Share" %> <% end %> <% end %> ``` Compact: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card padding: :sm, class: "w-full" do |card| %> <%= card.header title: "Compact card", description: "Padding and gaps tighten together." %> <%= lc_text "A compact summary.", size: :small %> <% end %> ``` Linked card: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card href: "/components/card.html", class: "w-full" do |card| %> <%= card.header title: "Design system", description: "Open the project." %> <% end %> ``` Custom spacing: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full [--lc-inset:var(--spacing-section)]" do |card| %> <%= card.header title: "Welcome", description: "Padding and the gaps between parts both follow --lc-inset." %> <%= card.footer do %> <%= lc_button "Get started" %> <% end %> <% end %> ``` Edge-to-edge content: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card padding: :none, class: "w-full" do %> <% end %> ``` With form controls: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "@container w-full" do |card| %> <%= card.header title: "Project settings" %> <%= card.content do %> <%= lc_field label: "Project name", id: "my-component-name" do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <%= card.footer do %> <%= lc_button "Save changes" %> <% end %> <% end %> ``` Validation feedback: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.content do %> <%= lc_alert "Choose a unique project name.", tone: :destructive %> <%= lc_field label: "Project name", id: "my-component-name", error: "This name is already taken." do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <% end %> ``` Details: https://ui.lostcoords.com/components/description_list.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.header title: "Workspace" %> <%= lc_description_list do |list| %> <%= list.item "Owner", "Ada Baker" %> <%= list.item "Plan" do %> <%= lc_badge "Team", tone: :primary %> <% end %> <%= list.item "Created", "March 4, 2026" %> <% end %> <% end %> ``` ## lc_empty_state https://ui.lostcoords.com/components/empty_state.html#lc_empty_state ```ruby lc_empty_state(**attributes, &block) ``` Empty state: https://ui.lostcoords.com/components/empty_state.html ```erb <%= lc_empty_state class: "w-full" do %> <%= lc_icon_badge shape: :circle, tone: :primary, icon: "folder-plus", size: :lg%> <%= lc_stack gap: :tight, class: "max-w-xs" do %> <%= lc_heading "No projects yet", level: 3, size: :subheading %> <%= lc_text "Create a project to get started.", size: :small, tone: :muted %> <% end %> <%= lc_button "Create project" %> <% end %> ``` ## lc_spinner https://ui.lostcoords.com/components/spinner.html#lc_spinner ```ruby lc_spinner(size: :md, label: lc_t("lostcoords.ui.spinner.label"), **attributes) ``` Custom icons and content: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button variant: :secondary do %> <%= lc_icon "arrow-down-tray", options: { "aria-hidden": true, "data-icon": "inline-start" } %> Download report <% end %> <%= lc_button disabled: true, aria: { busy: true } do %> <%= lc_spinner size: :sm, label: nil, data: { icon: "inline-start" } %> Loading report… <% end %> ``` Loading: https://ui.lostcoords.com/components/button.html ```erb <%= lc_button disabled: true, aria: { busy: true } do %> <%= lc_spinner size: :sm, label: nil, data: { icon: "inline-start" } %> Saving… <% end %> ``` Sizes and labels: https://ui.lostcoords.com/components/spinner.html ```erb <%= lc_spinner size: :sm %> <%= lc_spinner label: "Loading projects" %> <%= lc_spinner size: :lg %> ``` ## lc_skeleton https://ui.lostcoords.com/components/skeleton.html#lc_skeleton ```ruby lc_skeleton(**attributes) ``` Placeholder: https://ui.lostcoords.com/components/skeleton.html ```erb
<%= lc_skeleton class: "h-5 w-48" %> <%= lc_skeleton class: "h-4 w-full" %> <%= lc_skeleton class: "h-4 w-3/4" %>
``` ## lc_alert https://ui.lostcoords.com/components/alert.html#lc_alert ```ruby lc_alert(message = nil, title: nil, tone: :destructive, **attributes, &block) alert.actions(**attributes, &block) ``` Error: https://ui.lostcoords.com/components/alert.html ```erb <%= lc_alert "That name is already taken." %> ``` Success: https://ui.lostcoords.com/components/alert.html ```erb <%= lc_alert "Changes saved.", tone: :success %> ``` Title and actions: https://ui.lostcoords.com/components/alert.html ```erb <%= lc_alert "Your card was declined. Update the payment method to keep the workspace active.", title: "Payment failed" do |alert| %> <%= alert.actions do %> <%= lc_button "Update payment", size: :sm %> <%= lc_button "Dismiss", variant: :ghost, size: :sm %> <% end %> <% end %> ``` Validation feedback: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.content do %> <%= lc_alert "Choose a unique project name.", tone: :destructive %> <%= lc_field label: "Project name", id: "my-component-name", error: "This name is already taken." do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <% end %> ``` ## lc_prose https://ui.lostcoords.com/components/foundations.html#lc_prose ```ruby lc_prose(**attributes, &block) ``` Reading content: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_prose do %>

Make room for the trip

A shared plan is easier to follow when each idea has room to breathe. Keep the essentials close and give a new topic a little more space.

Start with one clear decision, name the plan kyoto-weekend, then choose what comes next.

The best part of a plan is the space it leaves for a surprise.

Ready to begin?

Buttons and other app controls can opt out of reading styles.

<%= lc_button "Create a plan" %>
<% end %> ``` Japanese reading: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_prose lang: "ja" do %>

旅の計画に、少しの余白を。

みんなで予定を考えるときは、大切なことから順番に決めていきましょう。読みやすい行間と段落の間隔が、長い文章をたどる手助けになります。

最初に決めておきたいこと

予定が変わったら、グループにひとこと。少しの共有で、旅がもっと気軽になります。

何もしない時間も、旅の楽しみのひとつです。

<% end %> ``` ## lc_search https://ui.lostcoords.com/components/search.html#lc_search ```ruby lc_search(label:, src: nil, param: "q", placeholder: label, trigger: lc_t("lostcoords.ui.search.trigger"), empty: lc_t("lostcoords.ui.search.empty"), prompt: nil, shortcut: "mod+k", id: "lc-search", **attributes, &block) ``` Filtered in the browser: https://ui.lostcoords.com/components/search.html ```erb <%# Rows rendered in the block are filtered in the browser. Pass src: to have your server answer each query instead. %> <%= lc_search label: "Search the workspace", placeholder: "Search projects and people…", empty: "Nothing matches %{query}", id: "my-component", shortcut: nil do %> <%= lc_search_group "Projects" do %> <%= lc_search_result "Fieldwork", "#fieldwork", detail: "A quieter identity for an outdoor journal.", icon: "sun", keywords: "brand identity" %> <%= lc_search_result "Sunday House", "#sunday-house", detail: "A welcoming home for a neighborhood bakery.", icon: "home", keywords: "website" %> <% end %> <%= lc_search_group "People" do %> <%= lc_search_result "Alex Lee", "#alex-lee", detail: "Designer", icon: "user" %> <%= lc_search_result "Sam Kim", "#sam-kim", detail: "Developer", icon: "user" %> <% end %> <% end %> ``` ## lc_search_group https://ui.lostcoords.com/components/search.html#lc_search_group ```ruby lc_search_group(title, **attributes, &block) ``` Filtered in the browser: https://ui.lostcoords.com/components/search.html ```erb <%# Rows rendered in the block are filtered in the browser. Pass src: to have your server answer each query instead. %> <%= lc_search label: "Search the workspace", placeholder: "Search projects and people…", empty: "Nothing matches %{query}", id: "my-component", shortcut: nil do %> <%= lc_search_group "Projects" do %> <%= lc_search_result "Fieldwork", "#fieldwork", detail: "A quieter identity for an outdoor journal.", icon: "sun", keywords: "brand identity" %> <%= lc_search_result "Sunday House", "#sunday-house", detail: "A welcoming home for a neighborhood bakery.", icon: "home", keywords: "website" %> <% end %> <%= lc_search_group "People" do %> <%= lc_search_result "Alex Lee", "#alex-lee", detail: "Designer", icon: "user" %> <%= lc_search_result "Sam Kim", "#sam-kim", detail: "Developer", icon: "user" %> <% end %> <% end %> ``` ## lc_search_result https://ui.lostcoords.com/components/search.html#lc_search_result ```ruby lc_search_result(title, url, detail: nil, icon: nil, keywords: nil, **attributes, &block) ``` Filtered in the browser: https://ui.lostcoords.com/components/search.html ```erb <%# Rows rendered in the block are filtered in the browser. Pass src: to have your server answer each query instead. %> <%= lc_search label: "Search the workspace", placeholder: "Search projects and people…", empty: "Nothing matches %{query}", id: "my-component", shortcut: nil do %> <%= lc_search_group "Projects" do %> <%= lc_search_result "Fieldwork", "#fieldwork", detail: "A quieter identity for an outdoor journal.", icon: "sun", keywords: "brand identity" %> <%= lc_search_result "Sunday House", "#sunday-house", detail: "A welcoming home for a neighborhood bakery.", icon: "home", keywords: "website" %> <% end %> <%= lc_search_group "People" do %> <%= lc_search_result "Alex Lee", "#alex-lee", detail: "Designer", icon: "user" %> <%= lc_search_result "Sam Kim", "#sam-kim", detail: "Developer", icon: "user" %> <% end %> <% end %> ``` ## lc_sheet https://ui.lostcoords.com/components/dialog.html#lc_sheet ```ruby lc_sheet(tag: :div, anchored: false, detents: "fit", handle: false, size: nil, **attributes, &block) ``` Popover sheet: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_sheet id: "my-component-filters", popover: "auto", role: "dialog", aria: { labelledby: "my-component-filters-title" }, class: lc_glass_class(shape: :picker, extra: "sm:m-auto sm:w-80 sm:rounded-3xl text-foreground") do %>
<%= lc_heading "Filters", id: "my-component-filters-title", size: :title %>

A popover on desktop, a sheet you can swipe away on phones.

<% end %> ``` ## lc_input https://ui.lostcoords.com/components/input.html#lc_input ```ruby lc_input(name: nil, value: nil, type: :text, size: :md, plain: false, **attributes) ``` With form controls: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "@container w-full" do |card| %> <%= card.header title: "Project settings" %> <%= card.content do %> <%= lc_field label: "Project name", id: "my-component-name" do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <%= card.footer do %> <%= lc_button "Save changes" %> <% end %> <% end %> ``` Validation feedback: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.content do %> <%= lc_alert "Choose a unique project name.", tone: :destructive %> <%= lc_field label: "Project name", id: "my-component-name", error: "This name is already taken." do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <% end %> ``` Button summary: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible card: false, button: { variant: :secondary, size: :sm }, summary_class: "w-fit", class: "w-full max-w-80" do |collapsible| %> <% collapsible.summary do %> <%= lc_icon "user-plus", options: { "aria-hidden": true } %> Invite people <% end %> <%= lc_field label: "Email", id: "my-component-email" do |field| %> <%= lc_input name: "email", type: :email, **field %> <% end %> <% end %> ``` Copy from an element: https://ui.lostcoords.com/components/copy_button.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-md" do %> <%= lc_field label: "Share link", id: "my-component-link" do |field| %> <%= lc_input value: "https://ui.lostcoords.com", **field %> <% end %> <%= lc_copy_button "Copy current link", source: "my-component-link", copied_label: "Link copied", class: "w-full" %> <%= lc_text "Edit the link, then copy it. The button reads the current value each time.", size: :small, tone: :muted %> <% end %> ``` Modal: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-dialog", title: "Create project", description: "Projects group pages and members.", trigger: "New project" do |dialog| %>
<%= lc_field label: "Project name", id: "my-component-dialog-name" do |field| %> <%= lc_input name: "project[name]", **field %> <% end %> <%= dialog.footer do %> <%= dialog.close %> <%= lc_button "Create project", type: :submit %> <% end %>
<% end %> ``` Mobile dialog: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-sheet", title: "Workspace details", trigger: "Open mobile dialog", detents: "fit" do %>

Drag the handle down to dismiss.

<%= lc_field label: "Workspace", id: "my-component-workspace" do |field| %> <%= lc_input value: "Design studio", **field %> <% end %> <% end %> ``` Label and hint: https://ui.lostcoords.com/components/field.html ```erb <%= lc_field label: "Project name", id: "my-component-name", hint: "A short, memorable name.", class: "w-full max-w-sm" do |field| %> <%= lc_input name: "project[name]", **field %> <% end %> ``` Validation: https://ui.lostcoords.com/components/field.html ```erb <%= lc_field label: "Email address", id: "my-component-email", error: "Enter a valid email address.", class: "w-full max-w-sm" do |field| %> <%= lc_input name: "email", type: :email, value: "alex@", **field %> <% end %> ``` Sizes: https://ui.lostcoords.com/components/input.html ```erb <%= lc_input name: "title", placeholder: "Small", size: :sm, class: "max-w-sm", aria: { label: "Small input" } %> <%= lc_input name: "title", placeholder: "Default", class: "max-w-sm", aria: { label: "Default input" } %> <%= lc_input name: "title", placeholder: "Large", size: :lg, class: "max-w-sm", aria: { label: "Large input" } %> ``` Disabled and read-only: https://ui.lostcoords.com/components/input.html ```erb <%= lc_input value: "Read-only value", readonly: true, class: "max-w-sm", aria: { label: "Read-only input" } %> <%= lc_input placeholder: "Disabled", disabled: true, class: "max-w-sm", aria: { label: "Disabled input" } %> ``` Focus a field: https://ui.lostcoords.com/components/kbd.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-sm" do %> <%= lc_field label: "Filter projects", id: "my-component-filter" do |field| %> <%= lc_input name: "q", type: :search, placeholder: "Press / to filter", data: lc_shortcut_data("/"), **field %> <% end %> <%= lc_text size: :small, tone: :muted do %> Press <%= lc_kbd "/" %> to filter, then <%= lc_kbd "escape" %> to clear. <% end %> <% end %> ``` Form rows: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_group class: "w-full max-w-md" do %> <%= lc_list_field "Description", icon: "pencil", id: "my-component-description" do %> <%= lc_input plain: true, id: "my-component-description", name: "description", placeholder: "Dinner at Ichiran" %> <% end %> <%= lc_list_field "Paid by", icon: "user", tag: :fieldset do %> <% end %> <%= lc_list_field "Date", icon: "calendar", id: "my-component-date" do %> <%= lc_input type: :date, plain: true, id: "my-component-date", name: "date", value: "2026-11-06" %> <% end %> <% end %> ``` ## lc_textarea https://ui.lostcoords.com/components/textarea.html#lc_textarea ```ruby lc_textarea(content = nil, name: nil, **attributes, &block) ``` Mobile height options: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-sheet", title: "Notes", detents: "medium large" do %> <%= lc_textarea name: "notes", rows: 16, aria: { label: "Notes" }, placeholder: "Write something…" %> <% end %> ``` Textarea: https://ui.lostcoords.com/components/textarea.html ```erb <%= lc_textarea "A place for your notes.", name: "notes", rows: 4, class: "max-w-sm", aria: { label: "Notes" } %> ``` ## lc_select https://ui.lostcoords.com/components/select.html#lc_select ```ruby lc_select(options = nil, name: nil, selected: nil, size: :md, **attributes, &block) ``` Native select: https://ui.lostcoords.com/components/select.html ```erb <%= lc_select [["Design", "design"], ["Engineering", "engineering"]], name: "team", selected: "design", class: "max-w-sm", aria: { label: "Team" } %> ``` ## lc_field https://ui.lostcoords.com/components/field.html#lc_field ```ruby lc_field(label:, id:, hint: nil, error: nil, size: :md, **attributes, &block) ``` With form controls: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "@container w-full" do |card| %> <%= card.header title: "Project settings" %> <%= card.content do %> <%= lc_field label: "Project name", id: "my-component-name" do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <%= card.footer do %> <%= lc_button "Save changes" %> <% end %> <% end %> ``` Validation feedback: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.content do %> <%= lc_alert "Choose a unique project name.", tone: :destructive %> <%= lc_field label: "Project name", id: "my-component-name", error: "This name is already taken." do |field| %> <%= lc_input name: "project[name]", value: "Design system", **field %> <% end %> <% end %> <% end %> ``` Button summary: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible card: false, button: { variant: :secondary, size: :sm }, summary_class: "w-fit", class: "w-full max-w-80" do |collapsible| %> <% collapsible.summary do %> <%= lc_icon "user-plus", options: { "aria-hidden": true } %> Invite people <% end %> <%= lc_field label: "Email", id: "my-component-email" do |field| %> <%= lc_input name: "email", type: :email, **field %> <% end %> <% end %> ``` Copy from an element: https://ui.lostcoords.com/components/copy_button.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-md" do %> <%= lc_field label: "Share link", id: "my-component-link" do |field| %> <%= lc_input value: "https://ui.lostcoords.com", **field %> <% end %> <%= lc_copy_button "Copy current link", source: "my-component-link", copied_label: "Link copied", class: "w-full" %> <%= lc_text "Edit the link, then copy it. The button reads the current value each time.", size: :small, tone: :muted %> <% end %> ``` Modal: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-dialog", title: "Create project", description: "Projects group pages and members.", trigger: "New project" do |dialog| %>
<%= lc_field label: "Project name", id: "my-component-dialog-name" do |field| %> <%= lc_input name: "project[name]", **field %> <% end %> <%= dialog.footer do %> <%= dialog.close %> <%= lc_button "Create project", type: :submit %> <% end %>
<% end %> ``` Mobile dialog: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_dialog id: "my-component-sheet", title: "Workspace details", trigger: "Open mobile dialog", detents: "fit" do %>

Drag the handle down to dismiss.

<%= lc_field label: "Workspace", id: "my-component-workspace" do |field| %> <%= lc_input value: "Design studio", **field %> <% end %> <% end %> ``` Label and hint: https://ui.lostcoords.com/components/field.html ```erb <%= lc_field label: "Project name", id: "my-component-name", hint: "A short, memorable name.", class: "w-full max-w-sm" do |field| %> <%= lc_input name: "project[name]", **field %> <% end %> ``` Validation: https://ui.lostcoords.com/components/field.html ```erb <%= lc_field label: "Email address", id: "my-component-email", error: "Enter a valid email address.", class: "w-full max-w-sm" do |field| %> <%= lc_input name: "email", type: :email, value: "alex@", **field %> <% end %> ``` Rails forms: https://ui.lostcoords.com/components/field.html ```erb <%= form_with scope: :project, url: "#", class: "w-full max-w-sm" do |form| %> <%= lc_field label: "Project name", id: form.field_id(:name), hint: "Works with Rails form builders." do |field| %> <%= form.text_field :name, **field, class: lc_input_class %> <% end %> <% end %> ``` Focus a field: https://ui.lostcoords.com/components/kbd.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-sm" do %> <%= lc_field label: "Filter projects", id: "my-component-filter" do |field| %> <%= lc_input name: "q", type: :search, placeholder: "Press / to filter", data: lc_shortcut_data("/"), **field %> <% end %> <%= lc_text size: :small, tone: :muted do %> Press <%= lc_kbd "/" %> to filter, then <%= lc_kbd "escape" %> to clear. <% end %> <% end %> ``` ## lc_fieldset https://ui.lostcoords.com/components/field.html#lc_fieldset ```ruby lc_fieldset(legend:, id: nil, hint: nil, error: nil, size: :md, **attributes, &block) ``` Grouped controls: https://ui.lostcoords.com/components/field.html ```erb <%= lc_stack class: "w-full max-w-sm" do %> <%= lc_fieldset legend: "Split", id: "my-component-split", hint: "Everyone pays the same share unless you change it." do %> <%= lc_inline do %> <%= lc_toggle "Equally", active: true %> <%= lc_toggle "By amount" %> <%= lc_toggle "By share" %> <% end %> <% end %> <%= lc_stack gap: :related do %> <%= lc_text "This app can", size: :label, tone: :muted %> <% end %> <% end %> ``` ## lc_toggle_group https://ui.lostcoords.com/components/toggle_group.html#lc_toggle_group ```ruby lc_toggle_group(label:, name: nil, value: nil, as: :div, variant: :segmented, size: :md, **attributes, &block) ``` Row summary with a chevron: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible card: false, indicator: :chevron, class: "w-full max-w-80", summary_class: "rounded-2xl px-3 font-medium hover:bg-accent" do |collapsible| %> <% collapsible.summary do %> Language English <% end %> <%= lc_toggle_group label: "Language", value: "en" do %> <%= lc_toggle_group_item "English", value: "en", selected: true %> <%= lc_toggle_group_item "日本語", value: "ja" %> <% end %> <% end %> ``` Mutually exclusive choices: https://ui.lostcoords.com/components/toggle_group.html ```erb <%= lc_toggle_group label: "View", value: "month" do %> <%= lc_toggle_group_item "Week", value: "week" %> <%= lc_toggle_group_item "Month", value: "month", selected: true %> <%= lc_toggle_group_item "Year", value: "year" %> <% end %> ``` Navigation links: https://ui.lostcoords.com/components/toggle_group.html ```erb <%= lc_toggle_group label: "Period", as: :nav do %> <%= lc_toggle_group_item "Month", href: "/components/toggle_group.html", current: true %> <%= lc_toggle_group_item "Quarter", href: "/components/toggle.html" %> <%= lc_toggle_group_item "Year", href: "/components/tabs.html" %> <% end %> ``` Wrapping pills: https://ui.lostcoords.com/components/toggle_group.html ```erb <%= lc_toggle_group label: "Category", name: "category", value: "", variant: :pills do %> <%= lc_toggle_group_item "Leave unchanged", value: "" %> <%= lc_toggle_group_item "Food", value: "food" %> <%= lc_toggle_group_item "Transport", value: "transport" %> <%= lc_toggle_group_item "Lodging", value: "lodging" %> <% end %> ``` Form values, native radios and reset: https://ui.lostcoords.com/components/toggle_group.html ```erb
<%= lc_toggle_group label: "Billing", name: "billing", value: "monthly" do %> <%= lc_toggle_group_item "Monthly", value: "monthly" %> <%= lc_toggle_group_item "Annual", value: "annual" %> <%= lc_toggle_group_item "Custom", value: "custom", disabled: true %> <% end %> <%= lc_inline role: "radiogroup", aria: { label: "Heard about us" } do %> <%= lc_toggle "A friend", name: "source", value: "friend", size: :sm %> <%= lc_toggle "Search", name: "source", value: "search", size: :sm %> <% end %> <%= lc_button "Reset", type: :reset, variant: :ghost, size: :sm %>
``` ## lc_toggle_group_item https://ui.lostcoords.com/components/toggle_group.html#lc_toggle_group_item ```ruby lc_toggle_group_item(label = nil, value: nil, selected: nil, checked: nil, href: nil, current: nil, input: {}, **attributes, &block) ``` Row summary with a chevron: https://ui.lostcoords.com/components/collapsible.html ```erb <%= lc_collapsible card: false, indicator: :chevron, class: "w-full max-w-80", summary_class: "rounded-2xl px-3 font-medium hover:bg-accent" do |collapsible| %> <% collapsible.summary do %> Language English <% end %> <%= lc_toggle_group label: "Language", value: "en" do %> <%= lc_toggle_group_item "English", value: "en", selected: true %> <%= lc_toggle_group_item "日本語", value: "ja" %> <% end %> <% end %> ``` Mutually exclusive choices: https://ui.lostcoords.com/components/toggle_group.html ```erb <%= lc_toggle_group label: "View", value: "month" do %> <%= lc_toggle_group_item "Week", value: "week" %> <%= lc_toggle_group_item "Month", value: "month", selected: true %> <%= lc_toggle_group_item "Year", value: "year" %> <% end %> ``` Navigation links: https://ui.lostcoords.com/components/toggle_group.html ```erb <%= lc_toggle_group label: "Period", as: :nav do %> <%= lc_toggle_group_item "Month", href: "/components/toggle_group.html", current: true %> <%= lc_toggle_group_item "Quarter", href: "/components/toggle.html" %> <%= lc_toggle_group_item "Year", href: "/components/tabs.html" %> <% end %> ``` Wrapping pills: https://ui.lostcoords.com/components/toggle_group.html ```erb <%= lc_toggle_group label: "Category", name: "category", value: "", variant: :pills do %> <%= lc_toggle_group_item "Leave unchanged", value: "" %> <%= lc_toggle_group_item "Food", value: "food" %> <%= lc_toggle_group_item "Transport", value: "transport" %> <%= lc_toggle_group_item "Lodging", value: "lodging" %> <% end %> ``` Form values, native radios and reset: https://ui.lostcoords.com/components/toggle_group.html ```erb
<%= lc_toggle_group label: "Billing", name: "billing", value: "monthly" do %> <%= lc_toggle_group_item "Monthly", value: "monthly" %> <%= lc_toggle_group_item "Annual", value: "annual" %> <%= lc_toggle_group_item "Custom", value: "custom", disabled: true %> <% end %> <%= lc_inline role: "radiogroup", aria: { label: "Heard about us" } do %> <%= lc_toggle "A friend", name: "source", value: "friend", size: :sm %> <%= lc_toggle "Search", name: "source", value: "search", size: :sm %> <% end %> <%= lc_button "Reset", type: :reset, variant: :ghost, size: :sm %>
``` ## lc_toggle https://ui.lostcoords.com/components/toggle.html#lc_toggle ```ruby lc_toggle(label = nil, active: false, ghost: false, size: :md, href: nil, name: nil, value: nil, input: {}, **attributes, &block) ``` Grouped controls: https://ui.lostcoords.com/components/field.html ```erb <%= lc_stack class: "w-full max-w-sm" do %> <%= lc_fieldset legend: "Split", id: "my-component-split", hint: "Everyone pays the same share unless you change it." do %> <%= lc_inline do %> <%= lc_toggle "Equally", active: true %> <%= lc_toggle "By amount" %> <%= lc_toggle "By share" %> <% end %> <% end %> <%= lc_stack gap: :related do %> <%= lc_text "This app can", size: :label, tone: :muted %> <% end %> <% end %> ``` Form rows: https://ui.lostcoords.com/components/list_group.html ```erb <%= lc_list_group class: "w-full max-w-md" do %> <%= lc_list_field "Description", icon: "pencil", id: "my-component-description" do %> <%= lc_input plain: true, id: "my-component-description", name: "description", placeholder: "Dinner at Ichiran" %> <% end %> <%= lc_list_field "Paid by", icon: "user", tag: :fieldset do %> <% end %> <%= lc_list_field "Date", icon: "calendar", id: "my-component-date" do %> <%= lc_input type: :date, plain: true, id: "my-component-date", name: "date", value: "2026-11-06" %> <% end %> <% end %> ``` Filters: https://ui.lostcoords.com/components/toggle.html ```erb <%= lc_inline role: "group", aria: { label: "Topics" } do %> <%= lc_toggle "Design", active: true %> <%= lc_toggle "Writing" %> <%= lc_toggle "Research" %> <% end %> ``` Navigation: https://ui.lostcoords.com/components/toggle.html ```erb <%= lc_inline do %> <%= lc_toggle "All projects", href: "/components/toggle.html", active: true, size: :sm %> <%= lc_toggle "Archived", href: "/components/badge.html", size: :sm %> <% end %> ``` Disabled and ghost: https://ui.lostcoords.com/components/toggle.html ```erb <%= lc_toggle "Unavailable", disabled: true %> <%= lc_toggle "Add filter", ghost: true %> ``` Form values, native radios and reset: https://ui.lostcoords.com/components/toggle_group.html ```erb
<%= lc_toggle_group label: "Billing", name: "billing", value: "monthly" do %> <%= lc_toggle_group_item "Monthly", value: "monthly" %> <%= lc_toggle_group_item "Annual", value: "annual" %> <%= lc_toggle_group_item "Custom", value: "custom", disabled: true %> <% end %> <%= lc_inline role: "radiogroup", aria: { label: "Heard about us" } do %> <%= lc_toggle "A friend", name: "source", value: "friend", size: :sm %> <%= lc_toggle "Search", name: "source", value: "search", size: :sm %> <% end %> <%= lc_button "Reset", type: :reset, variant: :ghost, size: :sm %>
``` ## lc_table https://ui.lostcoords.com/components/table.html#lc_table ```ruby lc_table(**attributes, &block) ``` Records: https://ui.lostcoords.com/components/table.html ```erb
<%= lc_table do %> Recent activity ProjectStatusMembers WariWariActive4 Personal siteActive1 <% end %>
``` ## lc_toast https://ui.lostcoords.com/components/toast.html#lc_toast ```ruby lc_toast(message = nil, tone: :success, timeout: 4000, **attributes, &block) ``` Brief feedback: https://ui.lostcoords.com/components/toast.html ```erb <%= lc_toast "Project saved.", timeout: 0 %> ``` Over dialogs and sticky headers: https://ui.lostcoords.com/components/toast.html ```erb <%# In an app, render the region once in the layout and append toasts with turbo_stream.append. %> <%= lc_toast_region id: "my-component-toasts" %> <%= lc_button "Save project", data: { controller: "toast-demo", action: "toast-demo#show", toast_demo_template_value: "my-component-toast", toast_demo_region_value: "my-component-toasts" } %> ``` Centred, at the top on phones: https://ui.lostcoords.com/components/toast.html ```erb <%# Centred at the bottom, and at the top on phones, clear of a bottom tab bar. %> <%= lc_toast_region id: "my-component-toasts", placement: :bottom_center, mobile_placement: :top_center %> <%= lc_button "Add expense", data: { controller: "toast-demo", action: "toast-demo#show", toast_demo_template_value: "my-component-toast", toast_demo_region_value: "my-component-toasts" } %> ``` ## lc_toast_region https://ui.lostcoords.com/components/toast.html#lc_toast_region ```ruby lc_toast_region(placement: :bottom_end, mobile_placement: nil, **attributes, &block) ``` Over dialogs and sticky headers: https://ui.lostcoords.com/components/toast.html ```erb <%# In an app, render the region once in the layout and append toasts with turbo_stream.append. %> <%= lc_toast_region id: "my-component-toasts" %> <%= lc_button "Save project", data: { controller: "toast-demo", action: "toast-demo#show", toast_demo_template_value: "my-component-toast", toast_demo_region_value: "my-component-toasts" } %> ``` Centred, at the top on phones: https://ui.lostcoords.com/components/toast.html ```erb <%# Centred at the bottom, and at the top on phones, clear of a bottom tab bar. %> <%= lc_toast_region id: "my-component-toasts", placement: :bottom_center, mobile_placement: :top_center %> <%= lc_button "Add expense", data: { controller: "toast-demo", action: "toast-demo#show", toast_demo_template_value: "my-component-toast", toast_demo_region_value: "my-component-toasts" } %> ``` ## lc_tooltip https://ui.lostcoords.com/components/tooltip.html#lc_tooltip ```ruby lc_tooltip(text, id:, side: :top, **attributes, &block) ``` Tooltips: https://ui.lostcoords.com/components/tooltip.html ```erb <%= lc_inline gap: :content do %> <%= lc_tooltip "Copy a link to this page", id: "my-component-copy-tip" do |tip| %> <%= lc_icon_button "Copy link", icon: "link", **tip %> <% end %> <%= lc_tooltip "Only owners can archive", id: "my-component-archive-tip", side: :bottom do |tip| %> <%= lc_button "Archive", variant: :secondary, **tip %> <% end %> <% end %> ``` ## lc_heading https://ui.lostcoords.com/components/foundations.html#lc_heading ```ruby lc_heading(content = nil, level: 2, size: :heading, trim: false, **attributes, &block) ``` Text styles: https://ui.lostcoords.com/components/foundations.html ```erb
<%= lc_heading "Weekend in Kyoto", level: 2, size: :title %> <%= lc_heading "Shared expenses", level: 3, size: :heading %> <%= lc_heading "Dinner with friends", level: 4, size: :subheading %> <%= lc_text do %>Use lc_stack to keep related content together.<% end %> <%= lc_text "Add a receipt or a short note for your group.", size: :small, tone: :muted %> <%= lc_text "Updated a few minutes ago", size: :caption, tone: :muted %>
``` Japanese text: https://ui.lostcoords.com/components/foundations.html ```erb
<%= lc_heading "京都で過ごす週末、みんなの旅の記録", level: 3, size: :title %> <%= lc_text "宿泊費や食事代をまとめて記録。誰がいくら支払ったか、グループのみんなで確認できます。" %> <%= lc_text "レシートやメモを追加して、旅の思い出も一緒に残しましょう。", size: :small, tone: :muted %> <%= lc_text "最終更新:数分前", size: :caption, tone: :muted %>
``` Eyebrow: https://ui.lostcoords.com/components/foundations.html ```erb ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` Popover sheet: https://ui.lostcoords.com/components/dialog.html ```erb <%= lc_sheet id: "my-component-filters", popover: "auto", role: "dialog", aria: { labelledby: "my-component-filters-title" }, class: lc_glass_class(shape: :picker, extra: "sm:m-auto sm:w-80 sm:rounded-3xl text-foreground") do %>
<%= lc_heading "Filters", id: "my-component-filters-title", size: :title %>

A popover on desktop, a sheet you can swipe away on phones.

<% end %> ``` Empty state: https://ui.lostcoords.com/components/empty_state.html ```erb <%= lc_empty_state class: "w-full" do %> <%= lc_icon_badge shape: :circle, tone: :primary, icon: "folder-plus", size: :lg%> <%= lc_stack gap: :tight, class: "max-w-xs" do %> <%= lc_heading "No projects yet", level: 3, size: :subheading %> <%= lc_text "Create a project to get started.", size: :small, tone: :muted %> <% end %> <%= lc_button "Create project" %> <% end %> ``` ## lc_text https://ui.lostcoords.com/components/foundations.html#lc_text ```ruby lc_text(content = nil, size: :body, tone: :default, trim: false, as: :p, **attributes, &block) ``` Text styles: https://ui.lostcoords.com/components/foundations.html ```erb
<%= lc_heading "Weekend in Kyoto", level: 2, size: :title %> <%= lc_heading "Shared expenses", level: 3, size: :heading %> <%= lc_heading "Dinner with friends", level: 4, size: :subheading %> <%= lc_text do %>Use lc_stack to keep related content together.<% end %> <%= lc_text "Add a receipt or a short note for your group.", size: :small, tone: :muted %> <%= lc_text "Updated a few minutes ago", size: :caption, tone: :muted %>
``` Japanese text: https://ui.lostcoords.com/components/foundations.html ```erb
<%= lc_heading "京都で過ごす週末、みんなの旅の記録", level: 3, size: :title %> <%= lc_text "宿泊費や食事代をまとめて記録。誰がいくら支払ったか、グループのみんなで確認できます。" %> <%= lc_text "レシートやメモを追加して、旅の思い出も一緒に残しましょう。", size: :small, tone: :muted %> <%= lc_text "最終更新:数分前", size: :caption, tone: :muted %>
``` Eyebrow: https://ui.lostcoords.com/components/foundations.html ```erb ``` Page rhythm: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_stack gap: :section, class: "w-full max-w-xl" do %> <%= lc_section title: "Recent expenses", actions: capture { lc_button("Add expense", icon: "plus", size: :sm) } do %> <%= lc_card do %> <%= lc_inline class: "flex-nowrap justify-between" do %> <%= lc_text "Dinner with friends" %> <%= lc_text "¥8,400", class: "shrink-0 tabular-nums" %> <% end %> <% end %> <%= lc_card do %> <%= lc_text "Train tickets" %> <% end %> <% end %> <%= lc_stack as: :section, gap: :heading do %> <%= lc_section_header do %> <%= lc_stack gap: :tight do %> <%= lc_heading "Members" %> <%= lc_text "Everyone who can see this workspace.", size: :small, tone: :muted %> <% end %> <% end %> <%= lc_card do %> <%= lc_inline do %> <%= lc_avatar "AK", class: "bg-primary" %> <%= lc_stack gap: :tight do %> <%= lc_text "Alex Kim" %> <%= lc_text "Joined today", size: :small, tone: :muted %> <% end %> <% end %> <% end %> <% end %> <% end %> ``` Responsive containers: https://ui.lostcoords.com/components/foundations.html ```erb <%= lc_container do %> <%= lc_stack gap: :section do %> <%= lc_heading "Plan your next trip", level: 2, size: :title %>
<%= lc_section title: "Travel details", level: 3 do %> <%= lc_card do %> <%= lc_stack do %> <%= lc_text "Kyoto weekend", size: :body %> <%= lc_text "Keep shared costs and travel notes together.", size: :small, tone: :muted %> <%= lc_inline do %> <%= lc_button "Invite friends", size: :sm %> <%= lc_button "View itinerary", variant: :ghost, size: :sm %> <% end %> <% end %> <% end %> <% end %> <%= lc_section title: "Shared costs", level: 3 do %> <%= lc_card do %> <%= lc_text "No expenses yet", size: :body %> <% end %> <% end %>
<% end %> <% end %> ``` Default: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card class: "w-full" do |card| %> <%= card.header title: "Project notes", description: "Keep related content together." do %> <%= lc_button "Edit", variant: :secondary, size: :sm %> <% end %> <%= card.content do %> <%= lc_text "Notes, links and files for the launch." %> <% end %> <%= card.footer do %> <%= lc_button "Archive", variant: :ghost %> <%= lc_button "Share" %> <% end %> <% end %> ``` Compact: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card padding: :sm, class: "w-full" do |card| %> <%= card.header title: "Compact card", description: "Padding and gaps tighten together." %> <%= lc_text "A compact summary.", size: :small %> <% end %> ``` Edge-to-edge content: https://ui.lostcoords.com/components/card.html ```erb <%= lc_card padding: :none, class: "w-full" do %> <% end %> ``` Copy from an element: https://ui.lostcoords.com/components/copy_button.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-md" do %> <%= lc_field label: "Share link", id: "my-component-link" do |field| %> <%= lc_input value: "https://ui.lostcoords.com", **field %> <% end %> <%= lc_copy_button "Copy current link", source: "my-component-link", copied_label: "Link copied", class: "w-full" %> <%= lc_text "Edit the link, then copy it. The button reads the current value each time.", size: :small, tone: :muted %> <% end %> ``` Empty state: https://ui.lostcoords.com/components/empty_state.html ```erb <%= lc_empty_state class: "w-full" do %> <%= lc_icon_badge shape: :circle, tone: :primary, icon: "folder-plus", size: :lg%> <%= lc_stack gap: :tight, class: "max-w-xs" do %> <%= lc_heading "No projects yet", level: 3, size: :subheading %> <%= lc_text "Create a project to get started.", size: :small, tone: :muted %> <% end %> <%= lc_button "Create project" %> <% end %> ``` Grouped controls: https://ui.lostcoords.com/components/field.html ```erb <%= lc_stack class: "w-full max-w-sm" do %> <%= lc_fieldset legend: "Split", id: "my-component-split", hint: "Everyone pays the same share unless you change it." do %> <%= lc_inline do %> <%= lc_toggle "Equally", active: true %> <%= lc_toggle "By amount" %> <%= lc_toggle "By share" %> <% end %> <% end %> <%= lc_stack gap: :related do %> <%= lc_text "This app can", size: :label, tone: :muted %> <% end %> <% end %> ``` Focus a field: https://ui.lostcoords.com/components/kbd.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-sm" do %> <%= lc_field label: "Filter projects", id: "my-component-filter" do |field| %> <%= lc_input name: "q", type: :search, placeholder: "Press / to filter", data: lc_shortcut_data("/"), **field %> <% end %> <%= lc_text size: :small, tone: :muted do %> Press <%= lc_kbd "/" %> to filter, then <%= lc_kbd "escape" %> to clear. <% end %> <% end %> ``` Tones: https://ui.lostcoords.com/components/link.html ```erb <%= lc_stack gap: :related do %> <%= lc_text do %>Read the <%= lc_link "installation guide", "/installation.html" %> before you start.<% end %> <%= lc_text size: :small, tone: :muted do %>Questions? <%= lc_link "Contact support", "/components/link.html", tone: :muted %>.<% end %> <%= lc_text do %>See <%= lc_link "what's new", "/components/link.html", tone: :primary %> in this release.<% end %> <% end %> ``` Cards: https://ui.lostcoords.com/components/radio.html ```erb <%= lc_choice_group legend: "Plan", class: "w-full max-w-md" do %> <%= lc_radio "Free", name: "my-component-plan", value: "free", hint: "Up to 3 projects.", card: true %> <%= lc_radio "Team", name: "my-component-plan", value: "team", hint: "Shared projects and roles.", card: true, checked: true do %> <%= lc_text "$12 per member, per month", size: :caption, tone: :muted %> <% end %> <%= lc_radio "Enterprise", name: "my-component-plan", value: "enterprise", hint: "SSO and audit logs.", card: true %> <% end %> ``` Skip link: https://ui.lostcoords.com/components/skip_link.html ```erb <%= lc_stack gap: :related, class: "items-center" do %> <%= lc_text "Press Tab on this page: the skip link is the first thing to receive focus.", size: :small, tone: :muted %> <%= lc_skip_link "#examples", class: "not-sr-only static" %> <% end %> ``` Tabs: https://ui.lostcoords.com/components/tabs.html ```erb <%= lc_tabs id: "my-component-tabs", label: "Project", class: "w-full" do |tabs| %> <% tabs.panel "Overview" do %> <%= lc_text "Pages, members and recent changes." %> <% end %> <% tabs.panel "Activity" do %> <%= lc_text "Nothing new this week.", tone: :muted %> <% end %> <% tabs.panel "Settings" do %> <%= lc_switch "Public project", name: "project[public]" %> <% end %> <% end %> ``` Vertical, with manual activation: https://ui.lostcoords.com/components/tabs.html ```erb <%= lc_tabs id: "my-component-settings", label: "Settings", orientation: :vertical, activation: :manual, class: "w-full" do |tabs| %> <% tabs.panel "Profile" do %> <%= lc_text "Name, photo and contact details." %> <% end %> <% tabs.panel "Notifications" do %> <%= lc_switch "Email me about mentions", name: "settings[mentions]" %> <% end %> <% tabs.panel "Billing" do %> <%= lc_text "Plan, invoices and payment method.", tone: :muted %> <% end %> <% end %> ``` ## lc_kbd https://ui.lostcoords.com/components/kbd.html#lc_kbd ```ruby lc_kbd(keys, **attributes) ``` Focus a field: https://ui.lostcoords.com/components/kbd.html ```erb <%= lc_stack gap: :related, class: "w-full max-w-sm" do %> <%= lc_field label: "Filter projects", id: "my-component-filter" do |field| %> <%= lc_input name: "q", type: :search, placeholder: "Press / to filter", data: lc_shortcut_data("/"), **field %> <% end %> <%= lc_text size: :small, tone: :muted do %> Press <%= lc_kbd "/" %> to filter, then <%= lc_kbd "escape" %> to clear. <% end %> <% end %> ``` ## Blocks Docs-only composition examples: https://ui.lostcoords.com/blocks.html Copy and adapt the example files. Blocks are not importable library components. ### Application header A glass header with navigation, an account menu and room for your brand. https://ui.lostcoords.com/blocks/application_header.html Replace the sample brand, links and account actions with your application's content. Keep navigation destinations as links and account actions in the menu. The header's layout and scroll behavior live in the example files. app/views/shared/_application_header.html.erb ```erb <%# locals: (brand:, home: "/", home_label:, links: [], label: "Main", width: "max-w-5xl", navigation_class: "sm:flex") %> <%# links: [[label, url, current], …]. The block's content renders the actions at the end of the bar. %>
``` app/assets/stylesheets/application_header.css ```css .header-example__glass { opacity: 0; transition: opacity 300ms ease; } .header-example[data-scrolled] .header-example__glass { opacity: 1; } @media (prefers-reduced-motion: reduce) { .header-example__glass { transition: none; } } ``` app/javascript/controllers/blocks_header_controller.js ```javascript import { Controller } from "@hotwired/stimulus" export default class extends Controller { connect() { this.scroll() } // An open modal pins the body, so scrollY reads 0 until it closes; keep the // state the page had rather than fading the glass out behind the dialog. scroll() { if (document.body.dataset.modalScrollLock === "true") return this.element.toggleAttribute("data-scrolled", window.scrollY > 8) } } ``` ### Documentation layout A sidebar, page content and an "On this page" list, with a collapsible menu on phones. https://ui.lostcoords.com/blocks/docs_shell.html Render it as a layout: pass the sidebar and contents lists as locals and the page as the block. This documentation site uses it for every guide and component page. Mark the current page with current: true so the sidebar sets aria-current. The contents list appears from the xl breakpoint. app/views/shared/_docs_shell.html.erb ```erb <%# locals: (navigation:, contents: nil, menu_label: "Menu", width: nil) %> <%# navigation: the sidebar, usually lc_nav_list. contents: an optional "On this page" list for wide screens. %>
<%= menu_label %><%= lc_icon "chevron-down", options: { class: "size-4 transition-transform group-open/nav:rotate-180", "aria-hidden": true } %>
<%= navigation %>
<%= yield %>
<% if contents %> <% end %>
``` app/assets/stylesheets/docs_shell.css ```css /* The sidebar scrolls on its own without a visible scrollbar. */ .docs-shell__sidebar { scrollbar-width: none; } .docs-shell__sidebar::-webkit-scrollbar { display: none; } ``` ### Mobile navigation A floating navigation pill and an expanding stack of quick actions. https://ui.lostcoords.com/blocks/mobile_navigation.html Choose a small set of primary destinations and replace the sample quick actions. Copy the bottom spacing and safe-area rules with the controls, so page content remains reachable. Test keyboard visibility on a real phone. app/views/shared/_mobile_navigation.html.erb ```erb
<%= lc_icon "square-3-stack-3d", options: { class: "size-5", "aria-hidden": true } %> Studio <%= lc_avatar "AL", class: "bg-primary-soft text-primary", aria: { label: "Alex Lee" } %>
<%= lc_text "A space to make things", size: :caption, tone: :muted %>

Your little studio.

A few good ideas, and room for a few more.

On your desk

<%= lc_badge "This week" %>
<% [ [ "Brand refresh", "Finding a fresh perspective.", "swatch", :primary, "In progress" ], [ "Field notes", "Small observations, collected.", "book-open", :success, "Taking shape" ], [ "Summer collection", "Objects for everyday moments.", "sun", :neutral, "Just getting started" ] ].each do |title, description, icon, tone, status| %> <%= lc_card class: "flex flex-col gap-content" do %>
<%= lc_icon_badge shape: :circle, icon: icon, size: :lg, tone: tone%><%= lc_badge status %>

<%= title %>

<%= description %>

<%= lc_avatar "AL", size: :sm, class: "bg-background text-muted-foreground" %>You and your collaborators
<% end %> <% end %>
``` app/assets/stylesheets/mobile_navigation.css ```css .mobile-example { --dock-gap: max(1rem, env(safe-area-inset-right, 0px)); --dock-bottom: max(0.75rem, env(safe-area-inset-bottom, 0px)); --dock-size: 4rem; } .mobile-example__main { padding-block-end: calc(var(--dock-bottom) + var(--dock-size) + 2rem); } .mobile-example__tabs { position: fixed; z-index: var(--lc-z-sticky); inset-inline: max(1rem, env(safe-area-inset-left, 0px)) calc(var(--dock-gap) + var(--dock-size) + 0.75rem); bottom: var(--dock-bottom); } .mobile-example__tab { position: relative; display: flex; min-width: 0; min-height: 3.5rem; flex-direction: column; align-items: center; justify-content: center; gap: 0.25rem; border-radius: 999px; color: var(--muted-foreground); font-size: 0.6875rem; font-weight: 600; text-decoration: none; } .mobile-example__tab[aria-current="page"] { color: var(--primary); } .mobile-example__indicator { position: absolute; z-index: -1; inset-block: 0.25rem; inset-inline-start: 0; border-radius: 999px; background: color-mix(in oklab, var(--foreground) 7%, transparent); transition: translate 380ms var(--lc-ease-sheet, ease), width 380ms var(--lc-ease-sheet, ease); } .mobile-example__dock { position: fixed; z-index: calc(var(--lc-z-sticky) + 1); inset-inline-end: var(--dock-gap); bottom: var(--dock-bottom); } .mobile-example__trigger, .mobile-example__action { display: grid; width: var(--dock-size); height: var(--dock-size); place-items: center; padding: 0; color: var(--primary); cursor: pointer; } .mobile-example__trigger { position: relative; z-index: 2; } .mobile-example__trigger svg { transition: rotate 300ms var(--lc-ease-sheet, ease); } .mobile-example__trigger[aria-expanded="true"] svg { rotate: 135deg; } .mobile-example__actions { visibility: hidden; pointer-events: none; } .mobile-example__actions[data-open] { visibility: visible; } .mobile-example__scrim { position: fixed; inset: 0; border: 0; background: color-mix(in oklab, var(--foreground) 18%, transparent); opacity: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); transition: opacity 220ms ease; } .mobile-example__actions[data-open] .mobile-example__scrim { pointer-events: auto; opacity: 1; } .mobile-example__action { position: absolute; z-index: 1; inset: 0; width: 3.5rem; height: 3.5rem; margin: 0.25rem; color: var(--foreground); opacity: 0; transform: scale(0.4); transition: transform 300ms ease, opacity 150ms ease; } .mobile-example__actions[data-open] .mobile-example__action { pointer-events: auto; opacity: 1; transform: translateY(calc(var(--action-index) * -4.5rem)) scale(1); transition: transform 420ms cubic-bezier(0.34, 1.45, 0.64, 1), opacity 160ms ease; transition-delay: calc((var(--action-index) - 1) * 40ms); } .mobile-example__action-label { position: absolute; inset-inline-end: calc(100% + 0.75rem); width: max-content; max-width: calc(100vw - 7rem); padding: 0.5rem 0.875rem; border-radius: 999px; background: var(--background); box-shadow: var(--lc-shadow); color: var(--foreground); font-size: 0.875rem; font-weight: 600; } .mobile-example[data-keyboard] .mobile-example__tabs, .mobile-example[data-keyboard] .mobile-example__dock { display: none; } @media (width >= 40rem) { .mobile-example__tabs { position: relative; inset: auto; width: max-content; margin-inline: auto; margin-block-end: 1.5rem; } .mobile-example__tab { min-width: 7rem; min-height: 2.75rem; flex-direction: row; gap: 0.5rem; font-size: 0.875rem; } } @media (prefers-reduced-motion: reduce) { .mobile-example__indicator, .mobile-example__trigger svg, .mobile-example__scrim, .mobile-example__action, .mobile-example__actions[data-open] .mobile-example__action { transition: none; } } ``` app/javascript/controllers/blocks_mobile_navigation_controller.js ```javascript import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["link", "panel", "indicator", "status", "projects", "notes", "draft"] connect() { this.resizeObserver = new ResizeObserver(() => this.placeIndicator()) this.linkTargets.forEach((link) => this.resizeObserver.observe(link)) this.onViewportResize = () => this.keyboard() window.visualViewport?.addEventListener("resize", this.onViewportResize) this.placeIndicator() } disconnect() { this.resizeObserver.disconnect() window.visualViewport?.removeEventListener("resize", this.onViewportResize) } select(event) { event.preventDefault() this.show(event.currentTarget.hash.slice(1)) } home(event) { event.preventDefault() this.show("projects") } show(id) { for (const link of this.linkTargets) { if (link.hash === `#${id}`) link.setAttribute("aria-current", "page") else link.removeAttribute("aria-current") } for (const panel of this.panelTargets) panel.hidden = panel.id !== id this.placeIndicator() } placeIndicator() { const active = this.linkTargets.find((link) => link.getAttribute("aria-current") === "page") this.indicatorTarget.style.translate = `${active.offsetLeft}px 0` this.indicatorTarget.style.width = `${active.offsetWidth}px` } add({ params: { destination } }) { const draft = this.draftTarget.content.cloneNode(true) const title = destination === "projects" ? "Untitled project" : "A new thought" draft.querySelector("[data-draft-title]").textContent = title const list = destination === "projects" ? this.projectsTarget : this.notesTarget list.prepend(draft) this.show(destination) this.statusTarget.textContent = `${title} added. Your next idea starts here.` } keyboard() { const typing = document.activeElement?.matches("input, textarea, [contenteditable=true]") const inset = window.innerHeight - (window.visualViewport?.height ?? window.innerHeight) this.element.toggleAttribute("data-keyboard", typing && inset > 150) } } ``` ## Advanced styles Class helpers style custom markup; the application owns its behavior. Glass surfaces use lc_glass_class; lc_tw merges utility classes. Read https://github.com/lostcoords/ui#advanced-style-composition. - `lc_icon_badge_class(size: :md, shape: :square, tone: :neutral, extra: nil)` - `lc_avatar_class(size: :md, ink: false, linked: false, extra: nil)` - `lc_avatar_stack_class(compact: false, extra: nil)` - `lc_avatar_stack_row_class(extra: nil)` - `lc_badge_class(tone: :neutral, shape: :rounded, extra: nil)` - `lc_toggle_class(active: false, ghost: false, size: :md, extra: nil)` - `lc_button_class(variant: :primary, tone: :default, size: :md, block: false, extra: nil)` - `lc_select_trigger_class(size: :md, block: false, extra: nil)` - `lc_icon_button_class(shape: :square, size: :md, variant: :ghost, tone: :default, extra: nil)` - `lc_card_class(interactive: false, padding: :md, extra: nil)` - `lc_choice_label_class(card: false, extra: nil)` - `lc_checkbox_class(extra: nil)` - `lc_radio_class(extra: nil)` - `lc_switch_class(extra: nil)` - `lc_dialog_class(kind = :modal, size: nil, extra: nil)` - `lc_emoji_picker_groups` - `lc_emoji_picker_count` - `lc_emoji_picker_version` - `lc_emoji_picker_search_text(emoji)` - `lc_emoji_picker_search_name(emoji)` - `lc_emoji_picker_search_labels(emoji)` - `lc_emoji_picker_toneable?(emoji)` - `lc_alert_class(extra: nil)` - `lc_alert_icon(tone: :destructive)` - `lc_spinner_class(size: :md, extra: nil)` - `lc_skeleton_class(extra: nil)` - `lc_empty_state_class(extra: nil)` - `lc_toggle_group_class(extra: nil)` - `lc_toggle_group_item_class(active: false, extra: nil)` - `lc_input_class(size: :md, plain: false, extra: nil)` - `lc_select_class(size: :md, extra: nil)` - `lc_textarea_class(extra: nil)` - `lc_field_class(size: :md, extra: nil)` - `lc_field_label_class(size: :md, extra: nil)` - `lc_glass_class(shape: :bar, thick: false, extra: nil)` - `lc_stack_class(gap: :content, extra: nil)` - `lc_inline_class(gap: :related, extra: nil)` - `lc_container_class(size: :page, extra: nil)` - `lc_section_header_class(extra: nil)` - `lc_popover_class(align: :end, extra: nil)` - `lc_menu_popover_class(align: :end, extra: nil)` - `lc_menu_option_class(tone: :default, extra: nil)` - `lc_link_class(tone: :inherit, extra: nil)` - `lc_nav_link_class(compact: false, layout: :column, extra: nil)` - `lc_prose_class(extra: nil)` - `lc_table_class(extra: nil)` - `lc_tw(*classes)` - `lc_heading_class(size: :heading, trim: false, extra: nil)` - `lc_text_class(size: :body, tone: :default, trim: false, extra: nil)` - `lc_kbd_class(extra: nil)` - `lc_shortcut_data(keys, data = {})`