Equicord/src/equicordplugins/commandPalette/ui/ActionsPanel.tsx
Jake 4134b9f4f8
CommandPalette: Rewrite with modular API and Raycast-style UI (#1165)
* CommandPalette: Rewrite with modular API and Raycast-style UI

Replace the monolithic palette with a command/page registry, capture-phase keyboard routing, fuzzy search with pins and aliases, form pages including Send DM with markdown preview, and a top-anchored shell layout.

* CommandPalette: Fix stylelint errors in palette CSS

Reorder selectors for no-descending-specificity, replace deprecated word-break, and use overflow shorthand on picker list.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-10 14:39:22 -04:00

68 lines
2.1 KiB
TypeScript

/*
* Vencord, a Discord client mod
* Copyright (c) 2026 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { classNameFactory } from "@utils/css";
import { useEffect, useRef } from "@webpack/common";
import type { PaletteAction } from "../api/types";
import { PaletteIcon } from "./PaletteIcon";
const cl = classNameFactory("vc-cmdpal-");
interface ActionsPanelProps {
actions: PaletteAction[];
selectedIndex: number;
onSelect(index: number): void;
onRun(action: PaletteAction): void;
}
function PanelRow({ action, selected, index, onSelect, onRun }: {
action: PaletteAction;
selected: boolean;
index: number;
onSelect(index: number): void;
onRun(action: PaletteAction): void;
}) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (selected) ref.current?.scrollIntoView({ block: "nearest" });
}, [selected]);
return (
<div
ref={ref}
className={cl("panel-row", { "panel-row-selected": selected })}
onMouseMove={() => { if (!selected) onSelect(index); }}
onClick={() => onRun(action)}
>
<div className={cl("chip-wrap", "chip-wrap-sm")}>
<PaletteIcon icon={action.icon} className={typeof action.icon === "string" ? cl("chip-img") : cl("panel-icon")} />
</div>
<span className={cl("panel-label")}>{action.label}</span>
</div>
);
}
export function ActionsPanel({ actions, selectedIndex, onSelect, onRun }: ActionsPanelProps) {
return (
<div className={cl("panel")}>
<div className={cl("panel-title")}>Actions</div>
<div className={cl("panel-list")}>
{actions.map((action, i) => (
<PanelRow
key={action.id}
action={action}
index={i}
selected={i === selectedIndex}
onSelect={onSelect}
onRun={onRun}
/>
))}
</div>
</div>
);
}