@tradly/asset
v1.0.5
Published
A reusable media gallery component for uploading and selecting images, videos, and files with Tradly authentication
Readme
@tradly/asset
A reusable React component package for uploading and selecting media (images, videos, files) with Tradly authentication support.
Features
- 📸 Upload and browse images
- 🎥 Upload and browse videos
- 📁 Upload and browse files
- 🔐 Tradly authentication support
- 🎨 Customizable UI
- 📱 Responsive design
- 🔄 Pagination support
- ⚡ Lightweight and performant
Installation
npm install @tradly/asset
# or
yarn add @tradly/assetPeer Dependencies
This package requires the following peer dependencies:
react(>=16.8.0)react-dom(>=16.8.0)@headlessui/react(^1.7.0) - for Tab componentsaxios(^0.24.0) - for API calls
Note:
- All pagination logic is built-in, no external pagination library needed!
- No Tradly SDK dependency - uses direct API calls
Basic Usage
import React, { useState } from "react";
import { MediaPopup, MediaApiService } from "@tradly/asset";
function MyComponent() {
const [isOpen, setIsOpen] = useState(false);
const [selectedMedia, setSelectedMedia] = useState(null);
// Initialize API service with your auth key
// API base URL is automatically detected from ENVIRONMENT:
// - Dev: https://api.dev.tradly.app
// - Prod: https://api.tradly.app
const apiService = new MediaApiService({
authKey: "your-tradly-auth-key", // Required: X-Auth-Key header
bearerToken: "your-bearer-token", // Required: Bearer token for Authorization header
// environment is auto-detected from process.env.ENVIRONMENT
// apiBaseUrl is auto-set based on environment (can be overridden)
});
const handleSelect = (mediaUrl) => {
setSelectedMedia(mediaUrl);
setIsOpen(false);
};
return (
<>
<button onClick={() => setIsOpen(true)}>
Open Media Gallery
</button>
<MediaPopup
isOpen={isOpen}
onClose={() => setIsOpen(false)}
onSelect={handleSelect}
options={["image", "video"]} // Options: 'image', 'video', 'file'
apiService={apiService}
/>
</>
);
}Advanced Usage
Upload Functionality
The package includes complete upload functionality using direct API calls. All upload logic is handled internally:
- Get S3 signed URLs via API call to
/v1/utils/S3signedUploadURL - Upload files to S3 using the signed URLs
- Save media metadata to your API
Configuration:
import { MediaApiService } from "@tradly/asset";
const apiService = new MediaApiService({
authKey: "your-auth-key", // Required: X-Auth-Key header
bearerToken: "your-bearer-token", // Required: Bearer token for Authorization header
environment: "dev", // Optional: 'dev' or 'production' (auto-detected from process.env.ENVIRONMENT)
apiBaseUrl: "https://api.tradly.app", // Optional: Override auto-detected base URL
});API Base URL Auto-Detection:
- If
environmentincludes 'dev' →https://api.dev.tradly.app - Otherwise →
https://api.tradly.app - You can override by providing
apiBaseUrlexplicitly
Using Individual Components
You can also use the components individually:
import { ImagesGallery, MediaApiService } from "@tradly/asset";
function CustomGallery() {
const apiService = new MediaApiService({
authKey: "your-auth-key",
baseUrl: "/api",
});
return (
<ImagesGallery
update_data={(url) => console.log("Selected:", url)}
closePopup={() => console.log("Closed")}
apiService={apiService}
/>
);
}Error Handling
<MediaPopup
isOpen={isOpen}
onClose={() => setIsOpen(false)}
onSelect={handleSelect}
apiService={apiService}
onError={(error) => {
console.error("Media gallery error:", error);
// Handle error (show toast, etc.)
}}
/>API Service Configuration
MediaApiService Options
const apiService = new MediaApiService({
authKey: "string", // Required: Authentication key for X-Auth-Key header
bearerToken: "string", // Required: Bearer token for Authorization header
environment: "string", // Optional: 'dev' or 'production' (auto-detected from process.env.ENVIRONMENT)
apiBaseUrl: "string", // Optional: Override auto-detected base URL (defaults: https://api.dev.tradly.app for dev, https://api.tradly.app for prod)
onError: (error) => {}, // Optional: Global error handler
});Methods
// Update auth key
apiService.setAuthKey("new-auth-key");
// Update API base URL (used for all API calls)
apiService.setApiBaseUrl("https://api.tradly.app");
// Set Bearer token
apiService.setBearerToken("new-bearer-token");Props
MediaPopup Props
| Prop | Type | Default | Description |
| ------------- | ----------------- | ----------------- | --------------------------------------------------- |
| isOpen | boolean | false | Controls popup visibility |
| onClose | function | - | Callback when popup closes |
| onSelect | function | - | Callback when media is selected |
| currentData | any | - | Currently selected media data |
| options | array | ['image'] | Media types to show: 'image', 'video', 'file' |
| apiService | MediaApiService | - | Required: API service instance |
| onError | function | - | Error handler callback |
| title | string | 'Media Gallery' | Popup title |
Styling
This package uses Tailwind CSS classes and supports full customization at every
component level. All components accept className props that allow you to
override default styles.
Quick Customization Example
<MediaPopup
isOpen={isOpen}
onClose={() => setIsOpen(false)}
onSelect={handleSelect}
apiService={apiService}
// Customize popup
overlayClassName="bg-black/60 backdrop-blur-sm"
containerClassName="max-w-4xl bg-gray-900 rounded-xl"
titleClassName="text-2xl font-bold text-white"
// Customize tabs
tabButtonActiveClassName="text-blue-400 border-b-2 border-blue-400"
// Customize gallery
gridClassName="grid grid-cols-4 gap-4"
imageItemClassName="rounded-lg border-2 hover:border-blue-500"
/>Available Styling Props
MediaPopup:
overlayClassName- Overlay/backdropcontainerClassName- Main popup containerheaderClassName- Header containertitleClassName- Title textcloseButtonClassName- Close buttontabListClassName- Tab list (passed to MediaTab)tabButtonClassName- Base tab buttontabButtonActiveClassName- Active tab buttontabButtonInactiveClassName- Inactive tab buttongridClassName- Media grid layoutimageItemClassName- Image item stylesvideoItemClassName- Video item stylespaginationContainerClassName- Pagination container
Individual Components: You can also style individual components when using
them separately. See STYLING_GUIDE.md for complete documentation.
Full Styling Guide
For detailed styling documentation with examples, see STYLING_GUIDE.md.
Examples
Image Only Gallery
<MediaPopup
isOpen={isOpen}
onClose={() => setIsOpen(false)}
onSelect={handleSelect}
options={["image"]}
apiService={apiService}
/>Video Only Gallery
<MediaPopup
isOpen={isOpen}
onClose={() => setIsOpen(false)}
onSelect={handleSelect}
options={["video"]}
apiService={apiService}
/>All Media Types
<MediaPopup
isOpen={isOpen}
onClose={() => setIsOpen(false)}
onSelect={handleSelect}
options={["image", "video", "file"]}
apiService={apiService}
/>Development
To develop or modify this package:
cd packages/asset
npm install
npm run devLicense
MIT
Support
For issues and questions, please open an issue on the repository.
