Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"ccstatusline",
"Powerline",
"statusline",
"sublabel",
"Worktree",
"worktrees"
]
Expand Down
13 changes: 3 additions & 10 deletions src/tui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,19 +228,12 @@ export const App: React.FC = () => {
<Box marginTop={1}>
{screen === 'main' && (
<MainMenu
onSelect={(value) => {
onSelect={(value, index) => {
// Only persist menu selection if not exiting
if (value !== 'save' && value !== 'exit') {
const menuMap: Record<string, number> = {
lines: 0,
colors: 1,
powerline: 2,
terminalConfig: 3,
globalOverrides: 4,
install: 5
};
setMenuSelections({ ...menuSelections, main: menuMap[value] ?? 0 });
setMenuSelections({ ...menuSelections, main: index });
}

void handleMainMenuSelect(value);
}}
isClaudeInstalled={isClaudeInstalled}
Expand Down
94 changes: 42 additions & 52 deletions src/tui/components/InstallMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {
Box,
Text,
useInput
Text
} from 'ink';
import React, { useState } from 'react';
import React from 'react';

import { List } from './List';

export interface InstallMenuProps {
bunxAvailable: boolean;
Expand All @@ -20,36 +21,34 @@ export const InstallMenu: React.FC<InstallMenuProps> = ({
onSelectBunx,
onCancel
}) => {
const [selectedIndex, setSelectedIndex] = useState(0);
const maxIndex = 2; // npx, bunx (if available), and back

useInput((input, key) => {
if (key.escape) {
onCancel();
} else if (key.upArrow) {
if (selectedIndex === 2) {
setSelectedIndex(bunxAvailable ? 1 : 0); // Skip bunx if not available
} else {
setSelectedIndex(Math.max(0, selectedIndex - 1));
}
} else if (key.downArrow) {
if (selectedIndex === 0) {
setSelectedIndex(bunxAvailable ? 1 : 2); // Skip bunx if not available
} else if (selectedIndex === 1 && bunxAvailable) {
setSelectedIndex(2);
} else {
setSelectedIndex(Math.min(maxIndex, selectedIndex + 1));
}
} else if (key.return) {
if (selectedIndex === 0) {
onSelectNpx();
} else if (selectedIndex === 1 && bunxAvailable) {
function onSelect(value: string) {
switch (value) {
case 'npx':
onSelectNpx();
break;
case 'bunx':
if (bunxAvailable) {
onSelectBunx();
} else if (selectedIndex === 2) {
onCancel();
}
break;
case 'back':
onCancel();
break;
}
}

const listItems = [
{
label: 'npx - Node Package Execute',
value: 'npx'
},
{
label: 'bunx - Bun Package Execute',
sublabel: bunxAvailable ? undefined : '(not installed)',
value: 'bunx',
disabled: !bunxAvailable
}
});
];

return (
<Box flexDirection='column'>
Expand All @@ -69,29 +68,20 @@ export const InstallMenu: React.FC<InstallMenuProps> = ({
<Text dimColor>Select package manager to use:</Text>
</Box>

<Box marginTop={1} flexDirection='column'>
<Box>
<Text color={selectedIndex === 0 ? 'blue' : undefined}>
{selectedIndex === 0 ? '▶ ' : ' '}
npx - Node Package Execute
</Text>
</Box>

<Box>
<Text color={selectedIndex === 1 && bunxAvailable ? 'blue' : undefined} dimColor={!bunxAvailable}>
{selectedIndex === 1 && bunxAvailable ? '▶ ' : ' '}
bunx - Bun Package Execute
{!bunxAvailable && ' (not installed)'}
</Text>
</Box>
<List
color='blue'
marginTop={1}
items={listItems}
onSelect={(line) => {
if (line === 'back') {
onCancel();
return;
}

<Box marginTop={1}>
<Text color={selectedIndex === 2 ? 'blue' : undefined}>
{selectedIndex === 2 ? '▶ ' : ' '}
← Back
</Text>
</Box>
</Box>
onSelect(line);
}}
showBackButton={true}
/>

<Box marginTop={2}>
<Text dimColor>
Expand Down
79 changes: 25 additions & 54 deletions src/tui/components/LineSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { Settings } from '../../types/Settings';
import type { WidgetItem } from '../../types/Widget';

import { ConfirmDialog } from './ConfirmDialog';
import { List } from './List';

interface LineSelectorProps {
lines: WidgetItem[][];
Expand Down Expand Up @@ -59,7 +60,7 @@ const LineSelector: React.FC<LineSelectorProps> = ({
};

const deleteLine = (lineIndex: number) => {
// Don't allow deleting the last remaining line
// Don't allow deleting the last remaining line
if (localLines.length <= 1) {
return;
}
Expand Down Expand Up @@ -105,16 +106,6 @@ const LineSelector: React.FC<LineSelectorProps> = ({

if (key.escape) {
onBack();
} else if (key.upArrow) {
setSelectedIndex(Math.max(0, selectedIndex - 1));
} else if (key.downArrow) {
setSelectedIndex(Math.min(localLines.length, selectedIndex + 1));
} else if (key.return) {
if (selectedIndex === localLines.length) {
onBack();
} else {
onSelect(selectedIndex);
}
}
});

Expand Down Expand Up @@ -164,7 +155,6 @@ const LineSelector: React.FC<LineSelectorProps> = ({
<Text>
<Text>
☰ Line
{' '}
{selectedIndex + 1}
</Text>
{' '}
Expand Down Expand Up @@ -195,57 +185,38 @@ const LineSelector: React.FC<LineSelectorProps> = ({
);
}

const lineItems = localLines.map((line, index) => ({
label: `☰ Line ${index + 1}`,
sublabel: `(${line.length > 0 ? pluralize('widget', line.length, true) : 'empty'})`,
value: index
}));

return (
<>
<Box flexDirection='column'>
<Text bold>{title ?? 'Select Line to Edit'}</Text>
<Text dimColor>Choose which status line to configure</Text>
<Text dimColor>
Choose which status line to configure
</Text>
<Text dimColor>
{allowEditing ? (
localLines.length > 1
{allowEditing
? localLines.length > 1
? '(a) to append new line, (d) to delete line, ESC to go back'
: '(a) to append new line, ESC to go back'
) : 'ESC to go back'}
: 'ESC to go back'}
</Text>

<Box marginTop={1} flexDirection='column'>
{localLines.map((line, index) => {
const isSelected = selectedIndex === index;
const suffix = line.length
? pluralize('widget', line.length, true)
: 'empty';

return (
<Box key={index}>
<Text color={isSelected ? 'green' : undefined}>
<Text>{isSelected ? '▶ ' : ' '}</Text>
<Text>
<Text>
☰ Line
{' '}
{index + 1}
</Text>
{' '}
<Text dimColor={!isSelected}>
(
{suffix}
)
</Text>
</Text>
</Text>
</Box>
);
})}

<Box marginTop={1}>
<Text color={selectedIndex === localLines.length ? 'green' : undefined}>
{selectedIndex === localLines.length ? '▶ ' : ' '}
← Back
</Text>
</Box>
</Box>
<List
marginTop={1}
items={lineItems}
onSelect={(line) => {
if (line === 'back') {
onBack();
return;
}
onSelect(line);
}}
initialSelection={initialSelection}
showBackButton={true}
/>
</Box>
</>
);
Expand Down
Loading