Skip to content

larrykoo711/media-picker

Repository files navigation

@koo-labs/media-picker

Drop-in media picker for AIGC apps. Pexels-powered. Zero config.

npm bundle license

Docs · Demo · Issues


Screenshot

Install

pnpm add @koo-labs/media-picker

Usage

import { MediaPickerButton } from '@koo-labs/media-picker';
import '@koo-labs/media-picker/styles.css';

<MediaPickerButton onSelect={(media) => console.log(media)}>
  Pick Media
</MediaPickerButton>

Done.

API

<MediaPickerButton />

<MediaPickerButton
  onSelect={(media) => {}}   // Required
  multiple={false}           // Multi-select
  maxSelection={10}          // Max items
  defaultMediaType="photos"  // 'photos' | 'videos'
>
  Button Text
</MediaPickerButton>

<MediaPicker /> (Controlled)

const [open, setOpen] = useState(false);

<MediaPicker
  open={open}
  onOpenChange={setOpen}
  onSelect={(media) => setOpen(false)}
/>

Production Setup

⚠️ Never expose API keys in client code.

// Use proxy mode in production
import { configurePexelsClient } from '@koo-labs/media-picker';

configurePexelsClient({
  proxyUrl: '/api/pexels',  // Your backend proxy
});
Next.js proxy example
// app/api/pexels/[...path]/route.ts
import { NextRequest, NextResponse } from 'next/server';

const PEXELS_API_KEY = process.env.PEXELS_API_KEY!;

export async function GET(
  request: NextRequest,
  { params }: { params: { path: string[] } }
) {
  const path = params.path.join('/');
  const url = `https://api.pexels.com/${path}?${request.nextUrl.searchParams}`;

  const res = await fetch(url, {
    headers: { Authorization: PEXELS_API_KEY },
  });

  return NextResponse.json(await res.json());
}

Theming

:root {
  --mp-primary: #3b82f6;
  --mp-base-100: #ffffff;
  --mp-base-content: #1e293b;
}

Dark mode: add class="dark" to root.

License

MIT

About

Feed your AI with unlimited free media.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors