mirror of
https://github.com/anotherhadi/ilovetui.git
synced 2026-10-05 19:08:25 +02:00
+20
-2
@@ -15,6 +15,13 @@ import { setProp as _$setProp } from "@opentui/solid";
|
|||||||
import { createElement as _$createElement } from "@opentui/solid";
|
import { createElement as _$createElement } from "@opentui/solid";
|
||||||
import { TextAttributes } from "@opentui/core";
|
import { TextAttributes } from "@opentui/core";
|
||||||
import { Show } from "solid-js";
|
import { Show } from "solid-js";
|
||||||
|
function truncateWithEllipsis(text, maxWidth) {
|
||||||
|
if (maxWidth <= 0)
|
||||||
|
return "";
|
||||||
|
if (text.length <= maxWidth)
|
||||||
|
return text;
|
||||||
|
return text.substring(0, Math.max(0, maxWidth - 1)) + "\u2026";
|
||||||
|
}
|
||||||
function itemIndexAtScreenY(el, screenY) {
|
function itemIndexAtScreenY(el, screenY) {
|
||||||
const internals = el;
|
const internals = el;
|
||||||
if (!internals.linesPerItem)
|
if (!internals.linesPerItem)
|
||||||
@@ -25,8 +32,19 @@ function itemIndexAtScreenY(el, screenY) {
|
|||||||
const index = internals.scrollOffset + Math.floor(localY / internals.linesPerItem);
|
const index = internals.scrollOffset + Math.floor(localY / internals.linesPerItem);
|
||||||
return index >= 0 && index < el.options.length ? index : null;
|
return index >= 0 && index < el.options.length ? index : null;
|
||||||
}
|
}
|
||||||
|
var BORDER_WIDTH = 2;
|
||||||
|
var ITEM_LEFT_PADDING = 1;
|
||||||
|
var ITEM_INDICATOR_WIDTH = 2;
|
||||||
function Sidebar(props) {
|
function Sidebar(props) {
|
||||||
let select;
|
let select;
|
||||||
|
const contentWidth = () => Math.max(0, (props.width ?? 24) - BORDER_WIDTH);
|
||||||
|
const itemTextWidth = () => Math.max(0, contentWidth() - ITEM_LEFT_PADDING - ITEM_INDICATOR_WIDTH);
|
||||||
|
const displayTitle = () => props.title ? truncateWithEllipsis(props.title, contentWidth()) : props.title;
|
||||||
|
const displayItems = () => props.items.map((item) => ({
|
||||||
|
...item,
|
||||||
|
name: truncateWithEllipsis(item.name, itemTextWidth()),
|
||||||
|
description: truncateWithEllipsis(item.description, itemTextWidth())
|
||||||
|
}));
|
||||||
const handleMouseDown = (event) => {
|
const handleMouseDown = (event) => {
|
||||||
if (!select)
|
if (!select)
|
||||||
return;
|
return;
|
||||||
@@ -59,7 +77,7 @@ function Sidebar(props) {
|
|||||||
get children() {
|
get children() {
|
||||||
return [(() => {
|
return [(() => {
|
||||||
var _el$2 = _$createElement("text");
|
var _el$2 = _$createElement("text");
|
||||||
_$insert(_el$2, () => props.title);
|
_$insert(_el$2, displayTitle);
|
||||||
_$effect((_$p) => _$setProp(_el$2, "attributes", TextAttributes.BOLD, _$p));
|
_$effect((_$p) => _$setProp(_el$2, "attributes", TextAttributes.BOLD, _$p));
|
||||||
return _el$2;
|
return _el$2;
|
||||||
})(), (() => {
|
})(), (() => {
|
||||||
@@ -91,7 +109,7 @@ function Sidebar(props) {
|
|||||||
props.onConfirm?.(option);
|
props.onConfirm?.(option);
|
||||||
});
|
});
|
||||||
_$effect((_p$) => {
|
_$effect((_p$) => {
|
||||||
var _v$ = props.width ?? 24, _v$2 = theme.borderStyle, _v$3 = props.focused ? props.accentColor ?? theme.primary : props.mutedColor ?? theme.muted, _v$4 = props.focused, _v$5 = props.items, _v$6 = theme.mouse ? handleMouseDown : undefined, _v$7 = theme.mouse ? handleMouseScroll : undefined, _v$8 = props.backgroundColor ?? "transparent", _v$9 = props.textColor ?? presets.select.textColor, _v$0 = props.focusedBackgroundColor ?? "transparent", _v$1 = props.focusedTextColor ?? presets.select.focusedTextColor, _v$10 = props.selectedBackgroundColor ?? presets.select.selectedBackgroundColor, _v$11 = props.selectedTextColor ?? presets.select.selectedTextColor, _v$12 = props.descriptionColor ?? presets.select.descriptionColor, _v$13 = props.selectedDescriptionColor ?? presets.select.selectedDescriptionColor;
|
var _v$ = props.width ?? 24, _v$2 = theme.borderStyle, _v$3 = props.focused ? props.accentColor ?? theme.primary : props.mutedColor ?? theme.muted, _v$4 = props.focused, _v$5 = displayItems(), _v$6 = theme.mouse ? handleMouseDown : undefined, _v$7 = theme.mouse ? handleMouseScroll : undefined, _v$8 = props.backgroundColor ?? "transparent", _v$9 = props.textColor ?? presets.select.textColor, _v$0 = props.focusedBackgroundColor ?? "transparent", _v$1 = props.focusedTextColor ?? presets.select.focusedTextColor, _v$10 = props.selectedBackgroundColor ?? presets.select.selectedBackgroundColor, _v$11 = props.selectedTextColor ?? presets.select.selectedTextColor, _v$12 = props.descriptionColor ?? presets.select.descriptionColor, _v$13 = props.selectedDescriptionColor ?? presets.select.selectedDescriptionColor;
|
||||||
_v$ !== _p$.e && (_p$.e = _$setProp(_el$, "width", _v$, _p$.e));
|
_v$ !== _p$.e && (_p$.e = _$setProp(_el$, "width", _v$, _p$.e));
|
||||||
_v$2 !== _p$.t && (_p$.t = _$setProp(_el$, "borderStyle", _v$2, _p$.t));
|
_v$2 !== _p$.t && (_p$.t = _$setProp(_el$, "borderStyle", _v$2, _p$.t));
|
||||||
_v$3 !== _p$.a && (_p$.a = _$setProp(_el$, "borderColor", _v$3, _p$.a));
|
_v$3 !== _p$.a && (_p$.a = _$setProp(_el$, "borderColor", _v$3, _p$.a));
|
||||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
// @bun
|
// @bun
|
||||||
import {
|
import {
|
||||||
Sidebar
|
Sidebar
|
||||||
} from "../chunk-kd78dgfb.js";
|
} from "../chunk-15vweq1q.js";
|
||||||
import"../chunk-x7m82z3z.js";
|
import"../chunk-x7m82z3z.js";
|
||||||
import"../chunk-7f8jagy5.js";
|
import"../chunk-7f8jagy5.js";
|
||||||
import"../chunk-hcq62p48.js";
|
import"../chunk-hcq62p48.js";
|
||||||
|
|||||||
Vendored
+3
-3
@@ -1,10 +1,10 @@
|
|||||||
// @bun
|
// @bun
|
||||||
import {
|
|
||||||
Sidebar
|
|
||||||
} from "../chunk-kd78dgfb.js";
|
|
||||||
import {
|
import {
|
||||||
NotificationHost
|
NotificationHost
|
||||||
} from "../chunk-fqzxyvhv.js";
|
} from "../chunk-fqzxyvhv.js";
|
||||||
|
import {
|
||||||
|
Sidebar
|
||||||
|
} from "../chunk-15vweq1q.js";
|
||||||
import {
|
import {
|
||||||
Toggle
|
Toggle
|
||||||
} from "../chunk-mezyz219.js";
|
} from "../chunk-mezyz219.js";
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ export interface SidebarHandle {
|
|||||||
focus(): void;
|
focus(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function truncateWithEllipsis(text: string, maxWidth: number): string {
|
||||||
|
if (maxWidth <= 0) return "";
|
||||||
|
if (text.length <= maxWidth) return text;
|
||||||
|
return text.substring(0, Math.max(0, maxWidth - 1)) + "…";
|
||||||
|
}
|
||||||
|
|
||||||
function itemIndexAtScreenY(el: SelectRenderable, screenY: number): number | null {
|
function itemIndexAtScreenY(el: SelectRenderable, screenY: number): number | null {
|
||||||
const internals = el as unknown as { scrollOffset: number; linesPerItem: number };
|
const internals = el as unknown as { scrollOffset: number; linesPerItem: number };
|
||||||
if (!internals.linesPerItem) return null;
|
if (!internals.linesPerItem) return null;
|
||||||
@@ -40,9 +46,25 @@ export interface SidebarProps {
|
|||||||
selectedDescriptionColor?: ColorInput;
|
selectedDescriptionColor?: ColorInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BORDER_WIDTH = 2;
|
||||||
|
const ITEM_LEFT_PADDING = 1;
|
||||||
|
const ITEM_INDICATOR_WIDTH = 2;
|
||||||
|
|
||||||
export function Sidebar(props: SidebarProps) {
|
export function Sidebar(props: SidebarProps) {
|
||||||
let select: SelectRenderable | undefined;
|
let select: SelectRenderable | undefined;
|
||||||
|
|
||||||
|
const contentWidth = () => Math.max(0, (props.width ?? 24) - BORDER_WIDTH);
|
||||||
|
const itemTextWidth = () => Math.max(0, contentWidth() - ITEM_LEFT_PADDING - ITEM_INDICATOR_WIDTH);
|
||||||
|
|
||||||
|
const displayTitle = () => (props.title ? truncateWithEllipsis(props.title, contentWidth()) : props.title);
|
||||||
|
|
||||||
|
const displayItems = () =>
|
||||||
|
props.items.map((item) => ({
|
||||||
|
...item,
|
||||||
|
name: truncateWithEllipsis(item.name, itemTextWidth()),
|
||||||
|
description: truncateWithEllipsis(item.description, itemTextWidth()),
|
||||||
|
}));
|
||||||
|
|
||||||
const handleMouseDown = (event: MouseEvent) => {
|
const handleMouseDown = (event: MouseEvent) => {
|
||||||
if (!select) return;
|
if (!select) return;
|
||||||
const index = itemIndexAtScreenY(select, event.y);
|
const index = itemIndexAtScreenY(select, event.y);
|
||||||
@@ -70,7 +92,7 @@ export function Sidebar(props: SidebarProps) {
|
|||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
>
|
>
|
||||||
<Show when={props.title}>
|
<Show when={props.title}>
|
||||||
<text attributes={TextAttributes.BOLD}>{props.title}</text>
|
<text attributes={TextAttributes.BOLD}>{displayTitle()}</text>
|
||||||
<text> </text>
|
<text> </text>
|
||||||
</Show>
|
</Show>
|
||||||
<select
|
<select
|
||||||
@@ -88,7 +110,7 @@ export function Sidebar(props: SidebarProps) {
|
|||||||
flexGrow={1}
|
flexGrow={1}
|
||||||
focused={props.focused}
|
focused={props.focused}
|
||||||
showScrollIndicator
|
showScrollIndicator
|
||||||
options={props.items}
|
options={displayItems()}
|
||||||
onMouseDown={theme.mouse ? handleMouseDown : undefined}
|
onMouseDown={theme.mouse ? handleMouseDown : undefined}
|
||||||
onMouseScroll={theme.mouse ? handleMouseScroll : undefined}
|
onMouseScroll={theme.mouse ? handleMouseScroll : undefined}
|
||||||
backgroundColor={props.backgroundColor ?? "transparent"}
|
backgroundColor={props.backgroundColor ?? "transparent"}
|
||||||
|
|||||||
Reference in New Issue
Block a user