feat: Update plugin manager integration with lucide-react icons and improve RoomInput component logic

This commit is contained in:
2026-07-06 01:30:25 +10:00
parent c57797ffe4
commit 1f71fd7a51
7 changed files with 62 additions and 42 deletions

View File

@@ -149,6 +149,16 @@ interface MessageContext {
### 🎨 UI API
Plugins also receive `ctx.lucide` — the full [lucide-react](https://lucide.dev/) icon set for custom renderers and UI.
```javascript
const { Link, Search, X } = ctx.lucide;
ctx.ui.registerRenderer('message', (msg, defaultRenderer) => {
return ctx.React.createElement(Link, { size: 16 });
});
```
Register custom renderers:
```javascript

View File

@@ -1,5 +1,6 @@
import React, { useSyncExternalStore } from 'react';
import { IconButton } from 'folds';
import * as lucide from 'lucide-react';
import { UILocation } from '@paarrot/plugin-manager';
import { pluginRegistry } from './PluginAPI';
@@ -38,6 +39,35 @@ interface PluginButtonSlotProps {
location: UILocation;
}
type LucideIconComponent = React.ComponentType<{
size?: number | string;
strokeWidth?: number | string;
}>;
function renderPluginButtonIcon(button: {
icon?: string;
lucideIcon?: string;
}): React.ReactNode {
const lucideName =
button.lucideIcon ??
(typeof button.icon === 'string' && button.icon.startsWith('lucide:')
? button.icon.slice('lucide:'.length)
: undefined);
if (lucideName) {
const IconComponent = (lucide as Record<string, LucideIconComponent | undefined>)[lucideName];
if (IconComponent) {
return <IconComponent size={18} strokeWidth={2} aria-hidden />;
}
}
return (
<span aria-hidden style={{ fontSize: '1.1em', lineHeight: 1 }}>
{button.icon ?? '🔌'}
</span>
);
}
/**
* Renders all plugin-registered buttons for the given UI location.
* Correctly handles components that mount before OR after plugins load,
@@ -61,9 +91,7 @@ export function PluginButtonSlot({ location }: PluginButtonSlotProps): React.Rea
title={button.label}
onClick={() => button.onClick?.()}
>
<span aria-hidden style={{ fontSize: '1.1em', lineHeight: 1 }}>
{button.icon ?? '🔌'}
</span>
{renderPluginButtonIcon(button)}
</IconButton>
))}
</>

View File

@@ -1,5 +1,6 @@
import React, { useEffect } from 'react';
import { MatrixClient } from 'matrix-js-sdk';
import * as lucide from 'lucide-react';
import { Plugin, createPluginContext } from '@paarrot/plugin-manager';
import { pluginMarketplaceManager, pluginRegistry } from './PluginAPI';
import { sendNotification } from '../../../utils/tauri';
@@ -79,6 +80,7 @@ export function PluginLoader({ matrixClient, children }: PluginLoaderProps) {
matrixClient.off(eventType as any, handler as any),
},
React,
lucide,
});
console.log('[PluginLoader] compatContext.React:', !!compatContext.React);