feat: Update plugin manager integration with lucide-react icons and improve RoomInput component logic
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
))}
|
||||
</>
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user