From c16f61dc3570766f6d1f6b92b568d728d0eb9d47 Mon Sep 17 00:00:00 2001 From: Gustavo Carvalho Date: Sun, 15 Feb 2026 01:06:55 -0300 Subject: [PATCH] feat: introduce SectionHeader component (#185) * feat: introduce SectionHeader component * fix: use ReactNode for label * fix: adjust gap spacing in SectionHeader component * fix: update text color classes in SectionHeader * fix: label prop --- src/SettingsApp.tsx | 2 +- src/components/EmojiPicker.tsx | 8 +++---- src/components/GifPicker.tsx | 22 +++++++++-------- src/components/SymbolPicker.tsx | 8 +++---- src/components/common/SectionHeader.tsx | 32 +++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 src/components/common/SectionHeader.tsx diff --git a/src/SettingsApp.tsx b/src/SettingsApp.tsx index 132c896..10b5aeb 100644 --- a/src/SettingsApp.tsx +++ b/src/SettingsApp.tsx @@ -326,7 +326,7 @@ function SettingsApp() { {(isSaving || saveMessage) && (
0 && (
-
- - - Recently used - +
+ } label="Recently used" />
} subHeader={ -
+
{searchQuery ? ( - <> - - Results for "{searchQuery}" - + } + label={`Results for "${searchQuery}"`} + rightContent={isLoading && } + /> ) : ( - <> - - Trending GIFs - + } + label="Trending GIFs" + rightContent={isLoading && } + /> )} - {isLoading && }
} footer={ diff --git a/src/components/SymbolPicker.tsx b/src/components/SymbolPicker.tsx index d143cbe..3d6c36f 100644 --- a/src/components/SymbolPicker.tsx +++ b/src/components/SymbolPicker.tsx @@ -4,6 +4,7 @@ import { clsx } from 'clsx' import { Clock } from 'lucide-react' import { useSymbolPicker } from '../hooks/useSymbolPicker' import { SearchBar } from './common/SearchBar' +import { SectionHeader } from './common/SectionHeader' import type { SymbolItem } from '../services/symbolService' import { PickerLayout } from './common/PickerLayout' @@ -229,11 +230,8 @@ export function SymbolPicker({ isDark, opacity }: SymbolPickerProps) { {/* Recent symbols */} {!searchQuery && !selectedCategory && recentSymbols.length > 0 && (
-
- - - Recently used - +
+ } label="Recently used" />
{recentSymbols.slice(0, 16).map((symbol, index) => ( diff --git a/src/components/common/SectionHeader.tsx b/src/components/common/SectionHeader.tsx new file mode 100644 index 0000000..b205333 --- /dev/null +++ b/src/components/common/SectionHeader.tsx @@ -0,0 +1,32 @@ +import { type ReactNode } from 'react' +import { clsx } from 'clsx' + +export interface SectionHeaderProps { + /** Icon to display (e.g., or ) */ + icon?: ReactNode + /** Label content to display (supports text, styled elements, or localization components) */ + label: ReactNode + /** Additional content to display on the right (e.g., loading spinner) */ + rightContent?: ReactNode + /** Additional CSS classes */ + className?: string +} + +/** + * Shared component for section headers like "Trending GIFs" and "Recently used" + */ +export function SectionHeader({ icon, label, rightContent, className }: SectionHeaderProps) { + return ( +
+ {icon} + {label} + {rightContent &&
{rightContent}
} +
+ ) +}