multiple fixes

Signed-off-by: Hadi <[email protected]>
This commit is contained in:
Hadi
2026-09-01 16:35:10 +02:00
parent 038842878a
commit b329bdc074
19 changed files with 321 additions and 214 deletions
+45 -12
View File
@@ -1,14 +1,25 @@
import { type ColorInput, type SelectOption, TextAttributes } from "@opentui/core";
import { theme } from "../index.ts";
import { type ColorInput, type MouseEvent, type SelectOption, type SelectRenderable, TextAttributes } from "@opentui/core";
import { Show } from "solid-js";
import { presets, theme } from "../index.ts";
export interface SidebarHandle {
moveUp(): void;
moveDown(): void;
selectCurrent(): void;
focus(): void;
}
function itemIndexAtScreenY(el: SelectRenderable, screenY: number): number | null {
const internals = el as unknown as { scrollOffset: number; linesPerItem: number };
if (!internals.linesPerItem) return null;
const localY = screenY - el.screenY;
if (localY < 0) return null;
const index = internals.scrollOffset + Math.floor(localY / internals.linesPerItem);
return index >= 0 && index < el.options.length ? index : null;
}
export interface SidebarProps {
title: string;
title?: string;
items: SelectOption[];
width?: number;
focused?: boolean;
@@ -30,6 +41,21 @@ export interface SidebarProps {
}
export function Sidebar(props: SidebarProps) {
let select: SelectRenderable | undefined;
const handleMouseDown = (event: MouseEvent) => {
if (!select) return;
const index = itemIndexAtScreenY(select, event.y);
if (index !== null) select.setSelectedIndex(index);
};
const handleMouseScroll = (event: MouseEvent) => {
if (!select || !event.scroll) return;
const steps = Math.max(1, event.scroll.delta);
if (event.scroll.direction === "down") select.moveDown(steps);
else if (event.scroll.direction === "up") select.moveUp(steps);
};
return (
<box
width={props.width ?? 24}
@@ -38,14 +64,19 @@ export function Sidebar(props: SidebarProps) {
borderColor={props.focused ? (props.accentColor ?? theme.primary) : (props.mutedColor ?? theme.muted)}
flexDirection="column"
>
<text attributes={TextAttributes.BOLD}>{props.title}</text>
<Show when={props.title}>
<text attributes={TextAttributes.BOLD}>{props.title}</text>
<text> </text>
</Show>
<select
ref={(el) => {
select = el ?? undefined;
props.ref?.(
el && {
moveUp: () => el.moveUp(),
moveDown: () => el.moveDown(),
selectCurrent: () => el.selectCurrent(),
focus: () => el.focus(),
},
);
}}
@@ -53,14 +84,16 @@ export function Sidebar(props: SidebarProps) {
focused={props.focused}
showScrollIndicator
options={props.items}
backgroundColor={props.backgroundColor}
textColor={props.textColor}
focusedBackgroundColor={props.focusedBackgroundColor}
focusedTextColor={props.focusedTextColor}
selectedBackgroundColor={props.selectedBackgroundColor}
selectedTextColor={props.selectedTextColor}
descriptionColor={props.descriptionColor}
selectedDescriptionColor={props.selectedDescriptionColor}
onMouseDown={theme.mouse ? handleMouseDown : undefined}
onMouseScroll={theme.mouse ? handleMouseScroll : undefined}
backgroundColor={props.backgroundColor ?? "transparent"}
textColor={props.textColor ?? presets.select.textColor}
focusedBackgroundColor={props.focusedBackgroundColor ?? "transparent"}
focusedTextColor={props.focusedTextColor ?? presets.select.focusedTextColor}
selectedBackgroundColor={props.selectedBackgroundColor ?? presets.select.selectedBackgroundColor}
selectedTextColor={props.selectedTextColor ?? presets.select.selectedTextColor}
descriptionColor={props.descriptionColor ?? presets.select.descriptionColor}
selectedDescriptionColor={props.selectedDescriptionColor ?? presets.select.selectedDescriptionColor}
onChange={(_index, option) => {
if (!option) return;
props.onSelect(option);