UI components
@media-sdk/ui-react@^0.3.0 provides reusable presentational React components for media search applications. Components render UI from props you pass in — they never call the API, manage search state, or own pagination logic.
pnpm add @media-sdk/ui-react@^0.3.0Peer dependency: React 18 or 19. @media-sdk/core is installed automatically because prop types reference Photo and Video.
Presentational-only philosophy
@media-sdk/ui-react follows a strict separation of concerns:
| Layer | Responsibility |
|---|---|
| Your app | Data fetching, search state, pagination logic, capability gating, analytics |
@media-sdk/react | Hooks and provider (useMediaSearch, useMediaVideos, MediaProvider) |
@media-sdk/ui-react | UI rendering — props in, JSX out |
Components do not:
- Call
searchPhotos,searchVideos, or anyMediaClientmethod - Read from
MediaProvidercontext - Decide which filters or tabs to show based on provider identity
- Fetch data on mount or manage internal query state
Your application layer wires hooks to components:
Your app (state + orchestration)
│
├── @media-sdk/ui-react ← UI rendering (props in, JSX out)
│
└── @media-sdk/react ← hooks, provider
│
▼
@media-sdk/core ← API client, types, cacheThis design lets you:
- Swap providers without changing UI components
- Replace any component with your own styled version
- Test UI in isolation with mock data
- Gate features with
useMediaCapabilitiesin your app, not inside the UI package
Component catalog
| Component | Purpose |
|---|---|
SearchBar | Controlled search input and submit button |
MediaTabs | Photos / Videos tab switcher |
PhotoGrid | Grid of photo cards |
VideoGrid | Grid of video cards |
PhotoPreview | Modal overlay for a selected photo |
VideoPreview | Modal overlay with video player |
Pagination | Previous / next page controls |
LoadingState | Accessible loading message |
ErrorState | Accessible error message |
Lower-level cards (PhotoCard, VideoCard) are used internally by grids and are part of the public API, but most apps compose grids directly.
Full prop tables: Components reference.
Minimal wiring example
import { useMediaSearch } from "@media-sdk/react";
import {
SearchBar,
PhotoGrid,
Pagination,
LoadingState,
ErrorState,
} from "@media-sdk/ui-react";
import { useState } from "react";
import type { Photo } from "@media-sdk/core";
function PhotoBrowser() {
const [query, setQuery] = useState("");
const [submittedQuery, setSubmittedQuery] = useState("");
const [selectedPhoto, setSelectedPhoto] = useState<Photo | null>(null);
const { data, loading, error, nextPage, previousPage } = useMediaSearch({
query: submittedQuery,
enabled: submittedQuery.length > 0,
});
return (
<>
<SearchBar
value={query}
onChange={setQuery}
onSubmit={(event) => {
event.preventDefault();
setSubmittedQuery(query);
}}
/>
{loading && <LoadingState message="Loading photos…" />}
{error && <ErrorState message={error.message} />}
{data && (
<>
<PhotoGrid
photos={data.items}
onPhotoSelect={setSelectedPhoto}
/>
<Pagination
page={data.pagination.page}
hasPrevious={data.pagination.hasPrevious}
hasNext={data.pagination.hasNext}
loading={loading}
ariaLabel="Photo results"
onPrevious={() => void previousPage()}
onNext={() => void nextPage()}
/>
</>
)}
</>
);
}Styling
Components ship with semantic CSS class names (for example search-form, photo-grid, pagination, preview-overlay). Import or override styles in your application. The reference demo at apps/web includes a complete stylesheet.
Public API
import {
SearchBar,
MediaTabs,
PhotoCard,
PhotoGrid,
PhotoPreview,
VideoCard,
VideoGrid,
VideoPreview,
Pagination,
LoadingState,
ErrorState,
type MediaTab,
} from "@media-sdk/ui-react";Internal utilities such as getPhotoSrc and getPlayableVideoLink are not part of the public API.
Next steps
- Components reference — full prop tables for every component
- React hooks —
useMediaSearch,useMediaVideos,enabled - Live demo — end-to-end wiring in
apps/web