devonthesofa_obsidian-note-.../components/SettingsUI/LucideIconPicker.tsx

80 lines
1.8 KiB
TypeScript
Raw Normal View History

2025-11-21 07:51:00 +00:00
import React from "react";
2025-11-21 07:04:30 +00:00
import { StatusIcon } from "@/components/atoms/StatusIcon";
2025-11-21 07:51:00 +00:00
import { LucideIconModal } from "./LucideIconModal";
import { App } from "obsidian";
import { Input } from "@/components/atoms/Input";
const getAppInstance = (): App | undefined => {
return (window as typeof window & { app?: App }).app;
};
2025-11-21 07:04:30 +00:00
export interface LucideIconPickerProps {
value?: string;
onChange: (value: string) => void;
2025-11-21 07:33:25 +00:00
placeholder?: string;
allowTextInput?: boolean;
allowClear?: boolean;
2025-11-21 07:04:30 +00:00
}
export const LucideIconPicker: React.FC<LucideIconPickerProps> = ({
value = "",
onChange,
2025-11-21 07:51:00 +00:00
placeholder = "Choose Lucide icon",
2025-11-21 07:33:25 +00:00
allowTextInput = false,
allowClear = true,
2025-11-21 07:04:30 +00:00
}) => {
2025-11-21 07:51:00 +00:00
const openModal = () => {
const app = getAppInstance();
if (!app) {
console.warn("Cannot open Lucide icon modal without Obsidian app");
return;
2025-11-21 07:04:30 +00:00
}
2025-11-21 07:51:00 +00:00
const modal = new LucideIconModal(app, {
initialValue: value,
onSelect: (icon) => onChange(icon),
});
modal.open();
2025-11-21 07:04:30 +00:00
};
const handleClear = () => {
onChange("");
2025-11-21 07:33:25 +00:00
};
2025-11-21 07:04:30 +00:00
return (
2025-11-21 07:51:00 +00:00
<div className="lucide-icon-picker">
2025-11-21 07:33:25 +00:00
{allowTextInput && (
2025-11-21 07:04:30 +00:00
<Input
variant="text"
2025-11-21 07:33:25 +00:00
value={value}
2025-11-21 07:51:00 +00:00
onChange={(val) => onChange(val)}
2025-11-21 07:33:25 +00:00
placeholder="Emoji or icon name"
className="lucide-icon-picker__text-input"
2025-11-21 07:04:30 +00:00
/>
2025-11-21 07:33:25 +00:00
)}
2025-11-21 07:51:00 +00:00
<div className="lucide-icon-picker__row">
2025-11-21 07:33:25 +00:00
<button
type="button"
2025-11-21 07:51:00 +00:00
className="lucide-icon-picker__modal-button"
onClick={openModal}
2025-11-21 07:33:25 +00:00
>
2025-11-21 07:51:00 +00:00
<span className="lucide-icon-picker__preview">
<StatusIcon icon={value} lucideIcon={value} size={18} />
2025-11-21 07:33:25 +00:00
</span>
2025-11-21 07:51:00 +00:00
<span className="lucide-icon-picker__label">
2025-11-21 07:33:25 +00:00
{value || placeholder}
</span>
</button>
{allowClear && value && (
2025-11-21 07:04:30 +00:00
<button
type="button"
2025-11-21 07:33:25 +00:00
className="lucide-icon-picker__clear-trigger"
2025-11-21 07:04:30 +00:00
onClick={handleClear}
>
Clear
</button>
)}
</div>
</div>
);
};