Photon OS Docs
Creating Apps

Photon UI Components

Native-style UI components for building Photon OS apps

Photon UI is a collection of components designed to give your app a native Photon OS look and feel. The components are distributed as a shadcn/ui compatible registry.

Prerequisites

Your project needs shadcn/ui configured. The components also require:

  • React
  • Tailwind CSS
  • The cn utility from shadcn/ui (installed automatically)

For a consistent look with Photon OS, use the official Photon theme when setting up shadcn/ui:

Open Photon Theme in shadcn/ui →

This theme includes:

  • Style: Radix Maia
  • Base color: Neutral
  • Accent: Indigo
  • Font: Figtree
  • Icons: Lucide

Using this theme ensures your app's colors, typography, and border radiuses match the Photon OS system UI.

Installation

Install All Components

To install all Photon UI components at once:

pnpm dlx shadcn@latest add https://os.photon.hydrais.com/r/photon-ui.json

Or with npx:

npx shadcn@latest add https://os.photon.hydrais.com/r/photon-ui.json

Install Individual Components

You can also install components individually:

pnpm dlx shadcn@latest add https://os.photon.hydrais.com/r/nav-bar.json
pnpm dlx shadcn@latest add https://os.photon.hydrais.com/r/tab-bar.json
# etc.

Components are installed to components/ui/photon/ in your project.

Available Components

ComponentDescriptionInstall URL
content-areaMain content container with responsive max-width and scrolling/r/content-area.json
nav-barHeader navigation bar container/r/nav-bar.json
nav-bar-titleTitle component for the navigation bar/r/nav-bar-title.json
nav-bar-back-buttonBack button with arrow icon for navigation/r/nav-bar-back-button.json
section-headerHeader for labeling content sections/r/section-header.json
section-listContainer for grouped list items with dividers/r/section-list.json
section-itemClickable list item with optional icon/r/section-item.json
tab-barBottom navigation tab bar container/r/tab-bar.json
tab-bar-itemTab bar item with icon and label/r/tab-bar-item.json

All URLs are prefixed with https://os.photon.hydrais.com.

Usage Examples

Basic App Layout

A typical Photon OS app uses PhotonNavBar at the top, PhotonContentArea for the main content, and optionally PhotonTabBar at the bottom:

import { PhotonNavBar } from "@/components/ui/photon/nav-bar";
import { PhotonNavBarTitle } from "@/components/ui/photon/nav-bar-title";
import { PhotonContentArea } from "@/components/ui/photon/content-area";
import { PhotonTabBar } from "@/components/ui/photon/tab-bar";
import { PhotonTabBarItem } from "@/components/ui/photon/tab-bar-item";
import { Home, Settings } from "lucide-react";

function App() {
  const [activeTab, setActiveTab] = useState("home");

  return (
    <div className="flex flex-col h-full">
      <PhotonNavBar>
        <PhotonNavBarTitle>My App</PhotonNavBarTitle>
      </PhotonNavBar>

      <PhotonContentArea>
        {/* Your main content here */}
      </PhotonContentArea>

      <PhotonTabBar>
        <PhotonTabBarItem
          label="Home"
          icon={Home}
          active={activeTab === "home"}
          onClick={() => setActiveTab("home")}
        />
        <PhotonTabBarItem
          label="Settings"
          icon={Settings}
          active={activeTab === "settings"}
          onClick={() => setActiveTab("settings")}
        />
      </PhotonTabBar>
    </div>
  );
}

When navigating to a detail view, use PhotonNavBarBackButton:

import { PhotonNavBar } from "@/components/ui/photon/nav-bar";
import { PhotonNavBarTitle } from "@/components/ui/photon/nav-bar-title";
import { PhotonNavBarBackButton } from "@/components/ui/photon/nav-bar-back-button";

function DetailPage({ onBack }: { onBack: () => void }) {
  return (
    <PhotonNavBar>
      <PhotonNavBarBackButton onClick={onBack} />
      <PhotonNavBarTitle>Details</PhotonNavBarTitle>
    </PhotonNavBar>
  );
}

Settings-Style Lists

Use PhotonSectionHeader, PhotonSectionList, and PhotonSectionItem for settings-style interfaces:

import { PhotonContentArea } from "@/components/ui/photon/content-area";
import { PhotonSectionHeader } from "@/components/ui/photon/section-header";
import { PhotonSectionList } from "@/components/ui/photon/section-list";
import { PhotonSectionItem } from "@/components/ui/photon/section-item";
import { User, Bell, Shield } from "lucide-react";

function SettingsPage() {
  return (
    <PhotonContentArea>
      <PhotonSectionHeader>Account</PhotonSectionHeader>
      <PhotonSectionList>
        <PhotonSectionItem
          label="Profile"
          icon={User}
          onClick={() => navigate("/profile")}
        />
        <PhotonSectionItem
          label="Notifications"
          icon={Bell}
          onClick={() => navigate("/notifications")}
        />
        <PhotonSectionItem
          label="Privacy"
          icon={Shield}
          onClick={() => navigate("/privacy")}
        />
      </PhotonSectionList>

      <PhotonSectionHeader>More</PhotonSectionHeader>
      <PhotonSectionList>
        <PhotonSectionItem
          label="About"
          onClick={() => navigate("/about")}
        />
      </PhotonSectionList>
    </PhotonContentArea>
  );
}

Component API Reference

PhotonNavBar

A header container for navigation elements.

<PhotonNavBar>
  {children}
</PhotonNavBar>

PhotonNavBarTitle

Displays the page title in the navigation bar.

<PhotonNavBarTitle>Page Title</PhotonNavBarTitle>

PhotonNavBarBackButton

A back button with an arrow icon.

PropTypeDescription
onClick() => voidCalled when the button is clicked

PhotonContentArea

A scrollable container for main content.

<PhotonContentArea>
  {children}
</PhotonContentArea>

PhotonSectionHeader

A header for labeling groups of content.

<PhotonSectionHeader>Section Title</PhotonSectionHeader>

PhotonSectionList

A container that adds dividers between child items.

<PhotonSectionList>
  {children}
</PhotonSectionList>

PhotonSectionItem

A clickable list item for navigation or actions.

PropTypeDescription
labelstringThe text to display
iconLucideIconOptional icon component from lucide-react
onClick() => voidCalled when the item is clicked

PhotonTabBar

A bottom navigation container.

<PhotonTabBar>
  {children}
</PhotonTabBar>

PhotonTabBarItem

A tab bar button with icon and label.

PropTypeDescription
labelstringThe text to display
iconLucideIconIcon component from lucide-react
activebooleanWhether this tab is currently active
onClick() => voidCalled when the tab is clicked

Customization

All components use Tailwind CSS classes and respect your project's theme variables like --primary, --muted, --border, etc. You can customize the components by editing the installed files in components/ui/photon/.