Appearance picker

Native light, dark, and system preferences synchronized through one document runtime.

Source
app/components/nitro_kit/appearance_picker.rb
API
NitroKit::AppearancePicker.new(id:, label: "Appearance")

Native preferences

Light, dark, and system remain labelled radio choices without JavaScript.

Default appearance

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/appearance_picker_page.rb
render NitroKit::AppearancePicker.new(id: "gallery-appearance-default")

Product language

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/appearance_picker_page.rb
render NitroKit::AppearancePicker.new(
  id: "gallery-appearance-product",
  label: "Color appearance"
)

Synchronized subscribers

Every mounted picker reflects the one document-owned preference.

Two controls for one preference

Navigation control
Settings control
Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/appearance_picker_page.rb
sample("Navigation control", slug: "navigation-control") do
  render NitroKit::AppearancePicker.new(
    id: "gallery-appearance-navigation",
    label: "Site appearance"
  )
end

sample("Settings control", slug: "settings-control") do
  render NitroKit::AppearancePicker.new(
    id: "gallery-appearance-settings",
    label: "Account appearance"
  )
end

Application composition

Appearance is a document preference, even when the control lives in a settings surface.

Personalization card

Viewport640 px · sm
Rubytest/dummy/app/components/gallery/components/appearance_picker_page.rb
render NitroKit::Card.new(id: "gallery-appearance-card") do |card|
  card.title("Personalization", level: 3)
  card.body do
    p { "Choose a fixed appearance or keep this browser in step with the operating system." }
    render NitroKit::AppearancePicker.new(
      id: "gallery-appearance-card-control",
      label: "Interface appearance"
    )
  end
  card.footer do
    render NitroKit::Badge.new("Saved in this browser", variant: :outline, color: :neutral)
  end
end