finsignal-feed-explore
v2.18.1
Published
News feed explorer components for React web applications
Maintainers
Readme
finsignal-feed-explore
News feed explorer components for React web applications. A comprehensive library for displaying and interacting with financial news feeds.
Version 2.4.0 - FilterButton Component 🎯
New in this version:
- ✨ FilterButton - Self-contained filter button component with three states
- 🔄 Seamless integration with FeedList for filter management
- 🎨 Customizable colors for icons and badge
- 📦 Fully typed with TypeScript
Previous Updates (2.0.0) - Major Design Update 🎨
Version 2.0.0 included a complete redesign to match the native app UI:
- ✨ Larger, bolder titles (20px, 700 weight) for better readability
- 🎯 Improved source display with circular logos positioned after title
- 📐 Better content hierarchy and spacing matching native design
- 🎭 Professional action bar with left/right icon grouping
- 🔍 Larger icons (24px) with proper colors and opacity
- 💡 AI Insight styling with gradient background and sparkle icon
- 🖱️ Enhanced drag'n'drop visual feedback
Installation
npm install finsignal-feed-explore
# or
yarn add finsignal-feed-exploreQuick Start
import { FeedList } from 'finsignal-feed-explore';
import 'finsignal-feed-explore/dist/newsfeed.css';
function App() {
return (
<FeedList
onNewsClick={(news) => console.log('Clicked:', news)}
onFiltersApply={(filters) => console.log('Filters:', filters)}
/>
);
}Note:
apiUrlis optional. If not provided, the component will use the default API URL:https://explore-gateway.changesandbox.ru/- Russian localization is enabled by default. All filter labels and categories will be displayed in Russian.
Main Components
FeedList
The main component for displaying a news feed with filtering, infinite scroll, and interactive actions.
import { FeedList } from 'finsignal-feed-explore';
import 'finsignal-feed-explore/dist/newsfeed.css';
<FeedList
onNewsClick={(news) => handleNewsClick(news)}
onShowFilter={() => console.log('Filter button clicked')}
initialFilters={['earnings', 'ipo']}
enableInfiniteScroll={true}
enableDragDrop={true}
onDragStart={(news, e) => console.log('Drag started:', news.title)}
/>NewsSnippet
Individual news item component that can be used standalone.
import { NewsSnippet } from 'finsignal-feed-explore';
<NewsSnippet
news={newsItem}
onShareClick={() => {}}
onBookmarkClick={() => {}}
showShareIcon={true}
showBookmarkIcon={true}
/>FiltersOverlay
Filter overlay component for market events selection.
import { FiltersOverlay } from 'finsignal-feed-explore';
<FiltersOverlay
isOpen={isOpen}
selectedFilters={filters}
onClose={() => setIsOpen(false)}
onApply={(filters) => handleFiltersApply(filters)}
/>FilterButton
Self-contained filter button with three visual states that works seamlessly with FeedList.
import { FeedList, FilterButton } from 'finsignal-feed-explore';
import { useState } from 'react';
function NewsSidebar() {
const [isFiltersOpen, setIsFiltersOpen] = useState(false);
const [filterCount, setFilterCount] = useState(0);
return (
<div>
{/* Header with FilterButton */}
<header>
<FilterButton
isFiltersOpen={isFiltersOpen}
filterCount={filterCount}
onClick={() => setIsFiltersOpen(!isFiltersOpen)}
/>
<h2>Explore</h2>
</header>
{/* FeedList synced with FilterButton */}
<FeedList
isFiltersOpen={isFiltersOpen}
onFiltersOpenChange={setIsFiltersOpen}
onFiltersChange={(data) => setFilterCount(data.count)}
onNewsClick={(news) => console.log('Clicked:', news)}
/>
</div>
);
}Visual States:
- Normal - Filter icon (no active filters)
- With Badge - Filter icon + count badge (has active filters)
- Close - X icon (filters overlay is open)
Props:
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| isFiltersOpen | boolean | Yes | Whether filters overlay is open |
| filterCount | number | Yes | Number of active filters to show in badge |
| onClick | () => void | Yes | Click handler |
| className | string | No | Additional CSS class |
| closeIconColor | string | No | Color for close icon (default: #7863F6) |
| filterIconColor | string | No | Color for filter icon (default: #242429) |
| badgeBackgroundColor | string | No | Badge background color (default: #2d3339) |
| badgeTextColor | string | No | Badge text color (default: #ffffff) |
Features
- ✅ Beautiful news snippets based on modern design system
- ✅ Filter news by market events (earnings, IPO, M&A, etc.)
- ✅ Configurable action buttons (share, bookmark, like, dislike, AI)
- ✅ Callbacks for all user interactions
- ✅ API integration with
/api/v1/content/searchendpoint - ✅ Mock data fallback - Shows 3 example news items when API is unavailable
- ✅ Infinite scroll support
- ✅ Light theme (web optimized)
- ✅ Responsive design
- ✅ TypeScript support
- ✅ React Native Web compatible
API Reference
FeedList Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| apiUrl | string | No | Base API URL for fetching news (default: https://explore-gateway.changesandbox.ru/) |
| onNewsClick | (news: NewsItem) => void | No | Called when news item is clicked |
| onShareClick | (news: NewsItem) => void | No | Called when share button is clicked |
| onBookmarkClick | (news: NewsItem) => void | No | Called when bookmark button is clicked |
| onLikeClick | (news: NewsItem) => void | No | Called when like button is clicked |
| onDislikeClick | (news: NewsItem) => void | No | Called when dislike button is clicked |
| onAIClick | (news: NewsItem) => void | No | Called when AI button is clicked |
| onFiltersOpen | () => void | No | Called when filters overlay opens |
| onFiltersClose | () => void | No | Called when filters overlay closes |
| onFiltersApply | (filters: string[]) => void | No | Called when filters are applied |
| onShowFilter | () => void | No | Called when filter button is clicked (before opening internal overlay) |
| showShareIcon | boolean | No | Show/hide share button (default: true) |
| showBookmarkIcon | boolean | No | Show/hide bookmark button (default: true) |
| showLikeIcon | boolean | No | Show/hide like button (default: false) |
| showDislikeIcon | boolean | No | Show/hide dislike button (default: false) |
| showAIIcon | boolean | No | Show/hide AI button (default: true) |
| showFilterIcon | boolean | No | Show/hide filter button (default: true) |
| initialFilters | string[] | No | Initial market events filters |
| enableInfiniteScroll | boolean | No | Enable/disable infinite scroll (default: true) |
| marketEventsTaxonomy | MarketEventTaxonomyItem[] | No | Custom market events taxonomy |
| enableDragDrop | boolean | No | Enable drag'n'drop for news items (default: false). Data is automatically set in dataTransfer with key 'application/news-data' |
| onDragStart | (news: NewsItem, e: DragEvent) => void | No | Called when drag starts on a news item (after data is set in dataTransfer) |
| onDragEnd | (news: NewsItem, e: DragEvent) => void | No | Called when drag ends on a news item |
| feedType | 'trending' \| 'personal' \| 'hot' | No | Deprecated (v1.7.0 compat) - Feed type parameter (ignored in current version) |
| useMockData | boolean | No | Deprecated (v1.7.0 compat) - Use mock data flag (ignored in current version) |
Types
NewsItem
interface NewsItem {
id: string;
title: string;
content: string;
source?: string;
sourceUrl?: string;
sources?: Array<{
name: string;
url?: string;
logo?: string;
}>;
timestamp?: string;
cover?: string;
recommendation?: {
text: string;
priceRange?: string;
};
stocks?: Array<{
symbol: string;
price: string;
change: string;
changeType: 'positive' | 'negative';
logo?: string;
}>;
summary?: string;
tags?: string[];
personalizedKeyPoints?: string[];
market_events?: string[];
}Hooks
useFeedData
Hook for fetching and managing feed data.
import { useFeedData } from 'finsignal-feed-explore';
const { items, isLoading, hasMore, loadMore, refresh } = useFeedData({
filters: ['earnings'],
limit: 20
});useFilters
Hook for managing filter state.
import { useFilters } from 'finsignal-feed-explore';
const {
selectedMarketEvents,
isOpen,
toggleFilter,
clearFilters,
setFilters,
openFilters,
closeFilters
} = useFilters(['earnings']);Constants
MARKET_EVENT_TAXONOMY
Default market events taxonomy with categories like earnings, IPO, M&A, etc.
Russian localization is enabled by default - all filter labels and categories are automatically displayed in Russian.
import { MARKET_EVENT_TAXONOMY, MarketEventTaxonomyItem } from 'finsignal-feed-explore';
// Each item includes:
// - key: unique identifier (used for API communication)
// - name: English name
// - nameRu: Russian name (displayed in UI by default)
// - category: English category
// - categoryRu: Russian category (displayed in UI by default)
// No need to pass marketEventsTaxonomy prop - it's used internally by default
<FeedList />
// Or customize if needed:
<FeedList marketEventsTaxonomy={customTaxonomy} />MarketEventTaxonomyItem Structure:
interface MarketEventTaxonomyItem {
key: string; // e.g., 'earnings_quarterly_results'
name: string; // e.g., 'Quarterly earnings report'
nameRu: string; // e.g., 'Квартальные результаты'
category: string; // e.g., 'Earnings'
categoryRu: string; // e.g., 'Финансовые результаты'
}Categories included:
- Mergers & Acquisitions (Слияния и поглощения)
- Earnings (Финансовые результаты)
- Dividends & Capital Returns (Дивиденды и выплаты)
- Corporate Actions & Structure (Корпоративные действия)
- Management & Leadership Changes (Изменения в руководстве)
MOCK_NEWS
Mock news data for development and fallback scenarios.
import { MOCK_NEWS } from 'finsignal-feed-explore';
// Array of 3 example news items
console.log(MOCK_NEWS);DEFAULT_API_URL
Default API URL used when apiUrl is not provided.
import { DEFAULT_API_URL } from 'finsignal-feed-explore';
console.log(DEFAULT_API_URL); // 'https://explore-gateway.changesandbox.ru/'Utilities
formatTimestamp
Utility function for formatting timestamps.
import { formatTimestamp } from 'finsignal-feed-explore';
const formatted = formatTimestamp('2024-01-15T10:30:00Z');theme
Theme configuration object.
import { theme } from 'finsignal-feed-explore';
// Access theme colors, spacing, etc.
console.log(theme.colors);API Integration
The component expects the API to follow this structure:
Default API URL: https://explore-gateway.changesandbox.ru/
Endpoint: POST {apiUrl}/api/v1/content/search
Request:
{
"limit": 20,
"offset": 0,
"market_events": ["earnings", "ipo"]
}Response:
{
"items": [...],
"next_offset": 20,
"total": 100,
"offset": 0,
"limit": 20
}Drag & Drop Integration
Enable drag'n'drop to allow users to drag news items onto other components (e.g., a board or canvas).
How it works
- Enable drag'n'drop in FeedList:
<FeedList
enableDragDrop={true}
onDragStart={(news, e) => {
console.log('Started dragging:', news.title);
}}
/>- Handle drop in your target component:
const handleDrop = (event: React.DragEvent) => {
event.preventDefault();
// Get news data from dataTransfer
const newsDataStr = event.dataTransfer.getData('application/news-data');
if (newsDataStr) {
const newsData = JSON.parse(newsDataStr);
// newsData contains: { id, title, content, recommendation, stocks }
// Create a card or handle the news as needed
createNewsCard(newsData);
}
};
<div
onDrop={handleDrop}
onDragOver={(e) => e.preventDefault()}
>
{/* Your drop target */}
</div>Data Format
When dragging, the following data is automatically set in dataTransfer with key 'application/news-data':
{
id: string;
title: string;
content: string;
recommendation?: {
text: string;
priceRange?: string;
};
stocks?: Array<{
symbol: string;
price: string;
change: string;
changeType: 'positive' | 'negative';
}>;
}Mock Data
The widget automatically displays 3 example news items when:
- API is unavailable or returns an error
- No real news data is loaded yet
This ensures users always see content, even during development or API downtime.
Development
Building the package
# Install dependencies
npm install
# Build the package
npm run buildThe build process:
- Compiles TypeScript files to JavaScript
- Generates type definitions (.d.ts files)
- Copies all CSS files to dist directory
Testing locally
Before publishing, test the package locally:
# In the package directory
npm link
# In your test project (e.g., trading-diary-master/frontend)
npm link finsignal-feed-explorePublishing
# Update version in package.json (e.g., 2.4.0 -> 2.4.1)
# Update CHANGELOG.md with new changes
# Build and publish (build runs automatically before publish)
npm publishNote: The prepublishOnly script automatically runs npm run build before publishing.
Peer Dependencies
react: >=18.0.0
Dependencies
lucide-react: ^0.544.0 (for icons)react-native-web: ^0.20.0 (for cross-platform compatibility)
License
MIT
