fix: Sticky submenu + emoji flags instead of images
1. Made Settings Submenu Sticky ✅ Problem: Settings submenu wasn't sticky like Dashboard Solution: Added sticky positioning to SubmenuBar Added classes: - sticky top-0 z-20 - bg-background/95 backdrop-blur - supports-[backdrop-filter]:bg-background/60 Result: ✅ Settings submenu now stays at top when scrolling 2. Switched to Emoji Flags ✅ Problem: Base64 images not showing in select options Better Solution: Use native emoji flags Benefits: - ✅ No image loading required - ✅ Native OS rendering - ✅ Smaller bundle size - ✅ Better performance - ✅ Always works (no broken images) Implementation: function countryCodeToEmoji(countryCode: string): string { const codePoints = countryCode .toUpperCase() .split('') .map(char => 127397 + char.charCodeAt(0)); return String.fromCodePoint(...codePoints); } // AE → 🇦🇪 // US → 🇺🇸 // ID → 🇮🇩 3. Updated Currency Select ✅ Before: [Image] United Arab Emirates dirham (AED) After: 🇦🇪 United Arab Emirates dirham (AED) - Emoji flag in label - No separate icon prop needed - Works immediately 4. Updated Store Summary ✅ Before: [Image] Your store is located in Indonesia After: 🇮🇩 Your store is located in Indonesia - Dynamic emoji flag based on currency - Cleaner implementation - No image loading 5. Simplified SearchableSelect ✅ - Removed icon prop (not needed with emoji) - Removed image rendering code - Simpler component API Files Modified: - SubmenuBar.tsx: Added sticky positioning - Store.tsx: Emoji flags + helper function - searchable-select.tsx: Removed icon support Why Emoji > Images: ✅ Universal support (all modern browsers/OS) ✅ No loading time ✅ No broken images ✅ Smaller code ✅ Native rendering ✅ Accessibility friendly
This commit is contained in:
@@ -22,8 +22,6 @@ export interface Option {
|
||||
label: React.ReactNode;
|
||||
/** Optional text used for filtering. Falls back to string label or value. */
|
||||
searchText?: string;
|
||||
/** Optional icon (base64 image or URL) to display before the label */
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
@@ -67,12 +65,7 @@ export function SearchableSelect({
|
||||
aria-disabled={disabled}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
>
|
||||
<div className="flex items-center gap-2 flex-1 min-w-0">
|
||||
{selected?.icon && (
|
||||
<img src={selected.icon} alt="" className="w-5 h-4 object-cover rounded-sm flex-shrink-0" />
|
||||
)}
|
||||
<span className="truncate">{selected ? selected.label : placeholder}</span>
|
||||
</div>
|
||||
{selected ? selected.label : placeholder}
|
||||
<ChevronsUpDown className="opacity-50 h-4 w-4 shrink-0" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
@@ -111,10 +104,7 @@ export function SearchableSelect({
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{opt.icon && (
|
||||
<img src={opt.icon} alt="" className="w-5 h-4 object-cover rounded-sm mr-2 flex-shrink-0" />
|
||||
)}
|
||||
<span className="truncate">{opt.label}</span>
|
||||
{opt.label}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandList>
|
||||
|
||||
Reference in New Issue
Block a user