From 238d764b0aa77806f65a86c34c5733f680674700 Mon Sep 17 00:00:00 2001 From: Hadi <112569860+anotherhadi@users.noreply.github.com> Date: Mon, 7 Sep 2026 14:36:17 +0200 Subject: [PATCH] ellipsis Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com> --- dist/{chunk-kd78dgfb.js => chunk-15vweq1q.js} | 22 ++++++++++++++-- dist/components/Sidebar.js | 2 +- dist/components/index.js | 6 ++--- src/components/Sidebar.tsx | 26 +++++++++++++++++-- 4 files changed, 48 insertions(+), 8 deletions(-) rename dist/{chunk-kd78dgfb.js => chunk-15vweq1q.js} (75%) diff --git a/dist/chunk-kd78dgfb.js b/dist/chunk-15vweq1q.js similarity index 75% rename from dist/chunk-kd78dgfb.js rename to dist/chunk-15vweq1q.js index 45a9ef5..026d649 100644 --- a/dist/chunk-kd78dgfb.js +++ b/dist/chunk-15vweq1q.js @@ -15,6 +15,13 @@ import { setProp as _$setProp } from "@opentui/solid"; import { createElement as _$createElement } from "@opentui/solid"; import { TextAttributes } from "@opentui/core"; 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) { const internals = el; if (!internals.linesPerItem) @@ -25,8 +32,19 @@ function itemIndexAtScreenY(el, screenY) { const index = internals.scrollOffset + Math.floor(localY / internals.linesPerItem); 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) { 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) => { if (!select) return; @@ -59,7 +77,7 @@ function Sidebar(props) { get children() { return [(() => { var _el$2 = _$createElement("text"); - _$insert(_el$2, () => props.title); + _$insert(_el$2, displayTitle); _$effect((_$p) => _$setProp(_el$2, "attributes", TextAttributes.BOLD, _$p)); return _el$2; })(), (() => { @@ -91,7 +109,7 @@ function Sidebar(props) { props.onConfirm?.(option); }); _$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$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)); diff --git a/dist/components/Sidebar.js b/dist/components/Sidebar.js index 3015dcb..95e2fc4 100644 --- a/dist/components/Sidebar.js +++ b/dist/components/Sidebar.js @@ -1,7 +1,7 @@ // @bun import { Sidebar -} from "../chunk-kd78dgfb.js"; +} from "../chunk-15vweq1q.js"; import"../chunk-x7m82z3z.js"; import"../chunk-7f8jagy5.js"; import"../chunk-hcq62p48.js"; diff --git a/dist/components/index.js b/dist/components/index.js index c2f9f52..3bfd6c8 100644 --- a/dist/components/index.js +++ b/dist/components/index.js @@ -1,10 +1,10 @@ // @bun -import { - Sidebar -} from "../chunk-kd78dgfb.js"; import { NotificationHost } from "../chunk-fqzxyvhv.js"; +import { + Sidebar +} from "../chunk-15vweq1q.js"; import { Toggle } from "../chunk-mezyz219.js"; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 745d330..421334e 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -9,6 +9,12 @@ export interface SidebarHandle { 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 { const internals = el as unknown as { scrollOffset: number; linesPerItem: number }; if (!internals.linesPerItem) return null; @@ -40,9 +46,25 @@ export interface SidebarProps { selectedDescriptionColor?: ColorInput; } +const BORDER_WIDTH = 2; +const ITEM_LEFT_PADDING = 1; +const ITEM_INDICATOR_WIDTH = 2; + export function Sidebar(props: SidebarProps) { 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) => { if (!select) return; const index = itemIndexAtScreenY(select, event.y); @@ -70,7 +92,7 @@ export function Sidebar(props: SidebarProps) { flexDirection="column" > - {props.title} + {displayTitle()}