插件设置面板
插件设置面板
每个Blinko插件都可以拥有自己的设置面板,允许用户自定义插件行为。
插件设置面板
启用设置面板
在您的插件类中设置withSettingPanel = true
来启用设置面板:
export class MyPlugin extends BasePlugin {
// Enable settings panel
withSettingPanel = true;
// Render settings panel
renderSettingPanel = () => {
const container = document.createElement('div');
render(<Setting />, container);
return container;
};
}
创建设置组件
创建一个独立的Preact组件来管理设置界面:
// src/setting.tsx
import { useState, useEffect } from 'preact/hooks';
import type { JSXInternal } from 'preact/src/jsx';
/**
* Setting component for plugin configuration
* Handles API token and notification settings
*/
export function Setting(): JSXInternal.Element {
const [apiToken, setApiToken] = useState('');
const [notificationsEnabled, setNotificationsEnabled] = useState(true);
const i18n = window.Blinko.i18n;
// Fetch initial plugin configuration on component mount
useEffect(() => {
window.Blinko.api.config.getPluginConfig.query({
pluginName: 'my-note-plugin'
}).then((res: any) => {
setApiToken(res.apiToken)
})
}, []);
/**
* Handles saving of plugin settings
* Saves API token and closes settings panel
*/
const handleSave = async () => {
window.Blinko.toast.success(i18n.t('settingsSaved'));
window.Blinko.closeDialog();
await window.Blinko.api.config.setPluginConfig.mutate({
pluginName: 'my-note-plugin',
key: 'apiToken',
value: apiToken
});
window.Blinko.api.config.getPluginConfig.query({
pluginName: 'my-note-plugin'
});
};
return (
<div class="max-w-2xl mx-auto p-2 rounded-lg">
{/* API Token Input Section */}
<div class="mb-6">
<label class="block text-sm font-medium mb-2">
{i18n.t('apiTokenLabel')}
<input
value={apiToken}
onChange={(e) => setApiToken(e.currentTarget.value)}
placeholder={i18n.t('enterApiToken')}
class="mt-1 block w-full px-3 py-2 border rounded-md shadow-sm sm:text-sm bg-primary!"
/>
</label>
</div>
{/* Notification Settings Section */}
<div class="mb-6">
<label class="flex items-center space-x-2">
<input
type="checkbox"
checked={notificationsEnabled}
onChange={(e) => setNotificationsEnabled(e.currentTarget.checked)}
class="h-4 w-4 text-primary-foreground bg-primary rounded"
/>
<span class="text-sm text-desc">{i18n.t('enableNotifications')}</span>
</label>
</div>
{/* Save Button */}
<button
onClick={handleSave}
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md bg-primary text-primary-foreground"
>
{i18n.t('saveSettings')}
</button>
</div>
);
}
配置API
Blinko提供配置API用于保存和检索插件设置:
interface ConfigAPI {
getPluginConfig: {
query: (params: { pluginName: string }) => Promise<any>;
};
setPluginConfig: {
mutate: (params: {
pluginName: string;
key: string;
value: any;
}) => Promise<void>;
};
}
在插件中使用配置
您可以在插件的其他部分访问和使用这些设置:
export class MyPlugin extends BasePlugin {
private pluginName = 'my-note-plugin';
async init() {
// Load configuration
const config = await window.Blinko.api.config.getPluginConfig.query({
pluginName: this.pluginName
});
// Initialize features based on config
if (config.apiToken) {
this.initializeAPI(config.apiToken);
}
}
private initializeAPI(apiToken: string) {
// API initialization logic
}
}
最佳实践
- 类型安全
- 为您的配置使用TypeScript类型
- 为您的插件设置定义接口
interface PluginConfig {
apiToken: string;
notificationsEnabled: boolean;
}
// Type-safe config access
const config = await window.Blinko.api.config.getPluginConfig.query<PluginConfig>({
pluginName: 'my-note-plugin'
});
- 国际化
- 对所有文本使用Blinko的i18n系统
- 为所有设置标签提供翻译
// i18n usage example
const i18n = window.Blinko.i18n;
<label>{i18n.t('settings.apiToken.label')}</label>
<span>{i18n.t('settings.notifications.enable')}</span>
- 错误处理
- 优雅地处理API错误
- 为操作提供用户反馈
const handleSave = async () => {
try {
await window.Blinko.api.config.setPluginConfig.mutate({
pluginName: 'my-note-plugin',
key: 'apiToken',
value: apiToken
});
window.Blinko.toast.success(i18n.t('settings.saved'));
} catch (error) {
window.Blinko.toast.error(i18n.t('settings.saveError'));
}
};
- UI/UX最佳实践
- 使用与Blinko主题一致的样式
- 为用户操作提供即时反馈
- 使用适当的输入类型和验证
<input
type="text"
class="mt-1 block w-full px-3 py-2 border rounded-md shadow-sm"
pattern="[A-Za-z0-9]+"
required
aria-label={i18n.t('settings.apiToken.label')}
/>