Files
cinny/src/app/features/settings/plugins/PluginNavSlot.tsx

49 lines
1.7 KiB
TypeScript

import React, { useSyncExternalStore } from 'react';
import { Avatar, Box, Text } from 'folds';
import { UILocation } from '@paarrot/plugin-manager';
import { NavItem, NavButton, NavItemContent } from '../../../components/nav';
import { pluginRegistry } from './PluginAPI';
import { subscribeToButtons, getStoreVersion } from './PluginButtonSlot';
interface PluginNavSlotProps {
/** The UI location to render nav list entries for. */
location: UILocation;
}
/**
* Renders plugin buttons as `NavItem` list entries, matching the style of
* built-in sidebar items like "Create Room" and "Message Search".
* Intended for locations that live inside the channel / room list, not toolbars.
*/
export function PluginNavSlot({ location }: PluginNavSlotProps): React.ReactElement | null {
useSyncExternalStore(subscribeToButtons, getStoreVersion);
const buttons = pluginRegistry.getButtonsForLocation(location);
if (buttons.length === 0) return null;
return (
<>
{buttons.map((button) => (
<NavItem key={button.id} variant="Background" radii="400">
<NavButton onClick={() => button.onClick?.()}>
<NavItemContent>
<Box as="span" grow="Yes" alignItems="Center" gap="200">
<Avatar size="200" radii="400">
<span aria-hidden style={{ fontSize: '1em', lineHeight: 1 }}>
{button.icon ?? '🔌'}
</span>
</Avatar>
<Box as="span" grow="Yes">
<Text as="span" size="Inherit" truncate>
{button.label}
</Text>
</Box>
</Box>
</NavItemContent>
</NavButton>
</NavItem>
))}
</>
);
}