prompt-language-shell 0.3.0 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/PLAN.md +103 -54
- package/dist/index.js +2 -25
- package/dist/services/components.js +104 -0
- package/dist/services/config.js +63 -12
- package/dist/services/process.js +6 -0
- package/dist/types/components.js +11 -0
- package/dist/ui/Column.js +1 -1
- package/dist/ui/Command.js +2 -72
- package/dist/ui/Component.js +12 -5
- package/dist/ui/Config.js +169 -10
- package/dist/ui/Feedback.js +15 -4
- package/dist/ui/List.js +16 -2
- package/dist/ui/Main.js +145 -117
- package/dist/ui/Message.js +5 -0
- package/dist/ui/Plan.js +194 -0
- package/package.json +2 -1
package/dist/ui/Command.js
CHANGED
|
@@ -1,80 +1,12 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Box, Text } from 'ink';
|
|
4
|
-
import { TaskType } from '../types/components.js';
|
|
5
|
-
import { Label } from './Label.js';
|
|
6
|
-
import { List } from './List.js';
|
|
7
4
|
import { Spinner } from './Spinner.js';
|
|
8
5
|
const MIN_PROCESSING_TIME = 1000; // purely for visual effect
|
|
9
|
-
// Color palette
|
|
10
|
-
const ColorPalette = {
|
|
11
|
-
[TaskType.Config]: {
|
|
12
|
-
description: '#ffffff', // white
|
|
13
|
-
type: '#5c9ccc', // cyan
|
|
14
|
-
},
|
|
15
|
-
[TaskType.Plan]: {
|
|
16
|
-
description: '#ffffff', // white
|
|
17
|
-
type: '#5ccccc', // magenta
|
|
18
|
-
},
|
|
19
|
-
[TaskType.Execute]: {
|
|
20
|
-
description: '#ffffff', // white
|
|
21
|
-
type: '#4a9a7a', // green
|
|
22
|
-
},
|
|
23
|
-
[TaskType.Answer]: {
|
|
24
|
-
description: '#ffffff', // white
|
|
25
|
-
type: '#9c5ccc', // purple
|
|
26
|
-
},
|
|
27
|
-
[TaskType.Report]: {
|
|
28
|
-
description: '#ffffff', // white
|
|
29
|
-
type: '#cc9c5c', // orange
|
|
30
|
-
},
|
|
31
|
-
[TaskType.Define]: {
|
|
32
|
-
description: '#ffffff', // white
|
|
33
|
-
type: '#cc9c5c', // amber
|
|
34
|
-
},
|
|
35
|
-
[TaskType.Ignore]: {
|
|
36
|
-
description: '#cccc5c', // yellow
|
|
37
|
-
type: '#cc7a5c', // orange
|
|
38
|
-
},
|
|
39
|
-
[TaskType.Select]: {
|
|
40
|
-
description: '#888888', // grey
|
|
41
|
-
type: '#5c8cbc', // steel blue
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
function taskToListItem(task) {
|
|
45
|
-
const colors = ColorPalette[task.type];
|
|
46
|
-
const item = {
|
|
47
|
-
description: {
|
|
48
|
-
text: task.action,
|
|
49
|
-
color: colors.description,
|
|
50
|
-
},
|
|
51
|
-
type: {
|
|
52
|
-
text: task.type,
|
|
53
|
-
color: colors.type,
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
// Add children for Define tasks with options
|
|
57
|
-
if (task.type === TaskType.Define && Array.isArray(task.params?.options)) {
|
|
58
|
-
const selectColors = ColorPalette[TaskType.Select];
|
|
59
|
-
item.children = task.params.options.map((option) => ({
|
|
60
|
-
description: {
|
|
61
|
-
text: String(option),
|
|
62
|
-
color: selectColors.description,
|
|
63
|
-
},
|
|
64
|
-
type: {
|
|
65
|
-
text: TaskType.Select,
|
|
66
|
-
color: selectColors.type,
|
|
67
|
-
},
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
return item;
|
|
71
|
-
}
|
|
72
6
|
export function Command({ command, state, service, children, onError, onComplete, }) {
|
|
73
7
|
const done = state?.done ?? false;
|
|
74
8
|
const [error, setError] = useState(null);
|
|
75
9
|
const [isLoading, setIsLoading] = useState(state?.isLoading ?? !done);
|
|
76
|
-
const [message, setMessage] = useState('');
|
|
77
|
-
const [tasks, setTasks] = useState([]);
|
|
78
10
|
useEffect(() => {
|
|
79
11
|
// Skip processing if done (showing historical/final state)
|
|
80
12
|
if (done) {
|
|
@@ -95,10 +27,8 @@ export function Command({ command, state, service, children, onError, onComplete
|
|
|
95
27
|
const remainingTime = Math.max(0, MIN_PROCESSING_TIME - elapsed);
|
|
96
28
|
await new Promise((resolve) => setTimeout(resolve, remainingTime));
|
|
97
29
|
if (mounted) {
|
|
98
|
-
setMessage(result.message);
|
|
99
|
-
setTasks(result.tasks);
|
|
100
30
|
setIsLoading(false);
|
|
101
|
-
onComplete?.();
|
|
31
|
+
onComplete?.(result.message, result.tasks);
|
|
102
32
|
}
|
|
103
33
|
}
|
|
104
34
|
catch (err) {
|
|
@@ -122,5 +52,5 @@ export function Command({ command, state, service, children, onError, onComplete
|
|
|
122
52
|
mounted = false;
|
|
123
53
|
};
|
|
124
54
|
}, [command, done, service]);
|
|
125
|
-
return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column",
|
|
55
|
+
return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ["> pls ", command] }), isLoading && (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Spinner, {})] }))] }), error && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) })), children] }));
|
|
126
56
|
}
|
package/dist/ui/Component.js
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ComponentName } from '../types/components.js';
|
|
2
3
|
import { Command } from './Command.js';
|
|
3
4
|
import { Config } from './Config.js';
|
|
4
5
|
import { Feedback } from './Feedback.js';
|
|
6
|
+
import { Message } from './Message.js';
|
|
7
|
+
import { Plan } from './Plan.js';
|
|
5
8
|
import { Welcome } from './Welcome.js';
|
|
6
9
|
export function Component({ def }) {
|
|
7
10
|
switch (def.name) {
|
|
8
|
-
case
|
|
11
|
+
case ComponentName.Welcome:
|
|
9
12
|
return _jsx(Welcome, { ...def.props });
|
|
10
|
-
case
|
|
13
|
+
case ComponentName.Config: {
|
|
11
14
|
const props = def.props;
|
|
12
15
|
const state = def.state;
|
|
13
16
|
return _jsx(Config, { ...props, state: state });
|
|
14
17
|
}
|
|
15
|
-
case
|
|
16
|
-
return _jsx(Feedback, { ...def.props });
|
|
17
|
-
case 'command': {
|
|
18
|
+
case ComponentName.Command: {
|
|
18
19
|
const props = def.props;
|
|
19
20
|
const state = def.state;
|
|
20
21
|
return _jsx(Command, { ...props, state: state });
|
|
21
22
|
}
|
|
23
|
+
case ComponentName.Plan:
|
|
24
|
+
return _jsx(Plan, { ...def.props });
|
|
25
|
+
case ComponentName.Feedback:
|
|
26
|
+
return _jsx(Feedback, { ...def.props });
|
|
27
|
+
case ComponentName.Message:
|
|
28
|
+
return _jsx(Message, { ...def.props });
|
|
22
29
|
}
|
|
23
30
|
}
|
package/dist/ui/Config.js
CHANGED
|
@@ -1,20 +1,87 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Box, Text, useInput } from 'ink';
|
|
3
|
+
import { Box, Text, useInput, useFocus } from 'ink';
|
|
4
4
|
import TextInput from 'ink-text-input';
|
|
5
|
+
export var StepType;
|
|
6
|
+
(function (StepType) {
|
|
7
|
+
StepType["Text"] = "text";
|
|
8
|
+
StepType["Selection"] = "selection";
|
|
9
|
+
})(StepType || (StepType = {}));
|
|
10
|
+
function TextStep({ value, placeholder, validate, onChange, onSubmit, }) {
|
|
11
|
+
const [inputValue, setInputValue] = React.useState(value);
|
|
12
|
+
const [validationFailed, setValidationFailed] = React.useState(false);
|
|
13
|
+
const { isFocused } = useFocus({ autoFocus: true });
|
|
14
|
+
const handleChange = (newValue) => {
|
|
15
|
+
setInputValue(newValue);
|
|
16
|
+
onChange(newValue);
|
|
17
|
+
if (validationFailed) {
|
|
18
|
+
setValidationFailed(false);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const handleSubmit = (value) => {
|
|
22
|
+
if (!validate(value)) {
|
|
23
|
+
setValidationFailed(true);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
onSubmit(value);
|
|
27
|
+
};
|
|
28
|
+
// Handle input manually when validation fails
|
|
29
|
+
useInput((input, key) => {
|
|
30
|
+
if (!validationFailed)
|
|
31
|
+
return;
|
|
32
|
+
if (key.return) {
|
|
33
|
+
handleSubmit(inputValue);
|
|
34
|
+
}
|
|
35
|
+
else if (key.backspace || key.delete) {
|
|
36
|
+
const newValue = inputValue.slice(0, -1);
|
|
37
|
+
handleChange(newValue);
|
|
38
|
+
}
|
|
39
|
+
else if (!key.ctrl && !key.meta && input) {
|
|
40
|
+
const newValue = inputValue + input;
|
|
41
|
+
handleChange(newValue);
|
|
42
|
+
}
|
|
43
|
+
}, { isActive: validationFailed });
|
|
44
|
+
// When validation fails, show colored text
|
|
45
|
+
if (validationFailed) {
|
|
46
|
+
return (_jsxs(Text, { color: "#cc5c5c", children: [inputValue || placeholder, isFocused && _jsx(Text, { inverse: true, children: " " })] }));
|
|
47
|
+
}
|
|
48
|
+
return (_jsx(TextInput, { value: inputValue, onChange: handleChange, onSubmit: handleSubmit, placeholder: placeholder }));
|
|
49
|
+
}
|
|
50
|
+
function SelectionStep({ options, selectedIndex, isCurrentStep, }) {
|
|
51
|
+
return (_jsx(Box, { children: options.map((option, optIndex) => {
|
|
52
|
+
const isSelected = optIndex === selectedIndex;
|
|
53
|
+
return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { dimColor: !isSelected || !isCurrentStep, bold: isSelected, children: option.label }) }, option.value));
|
|
54
|
+
}) }));
|
|
55
|
+
}
|
|
5
56
|
export function Config({ steps, state, onFinished, onAborted }) {
|
|
6
57
|
const done = state?.done ?? false;
|
|
7
58
|
const [step, setStep] = React.useState(done ? steps.length : 0);
|
|
8
59
|
const [values, setValues] = React.useState(() => {
|
|
9
60
|
const initial = {};
|
|
10
|
-
steps.forEach((
|
|
11
|
-
|
|
12
|
-
|
|
61
|
+
steps.forEach((stepConfig) => {
|
|
62
|
+
switch (stepConfig.type) {
|
|
63
|
+
case StepType.Text:
|
|
64
|
+
if (stepConfig.value !== null) {
|
|
65
|
+
initial[stepConfig.key] = stepConfig.value;
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
case StepType.Selection:
|
|
69
|
+
initial[stepConfig.key] =
|
|
70
|
+
stepConfig.options[stepConfig.defaultIndex].value;
|
|
71
|
+
break;
|
|
72
|
+
default: {
|
|
73
|
+
const exhaustiveCheck = stepConfig;
|
|
74
|
+
throw new Error(`Unsupported step type: ${exhaustiveCheck}`);
|
|
75
|
+
}
|
|
13
76
|
}
|
|
14
77
|
});
|
|
15
78
|
return initial;
|
|
16
79
|
});
|
|
17
80
|
const [inputValue, setInputValue] = React.useState('');
|
|
81
|
+
const [selectedIndex, setSelectedIndex] = React.useState(() => {
|
|
82
|
+
const firstStep = steps[0];
|
|
83
|
+
return firstStep?.type === StepType.Selection ? firstStep.defaultIndex : 0;
|
|
84
|
+
});
|
|
18
85
|
const normalizeValue = (value) => {
|
|
19
86
|
if (value === null || value === undefined) {
|
|
20
87
|
return '';
|
|
@@ -23,16 +90,83 @@ export function Config({ steps, state, onFinished, onAborted }) {
|
|
|
23
90
|
};
|
|
24
91
|
useInput((input, key) => {
|
|
25
92
|
if (key.escape && !done && step < steps.length) {
|
|
93
|
+
// Save current value before aborting
|
|
94
|
+
const currentStepConfig = steps[step];
|
|
95
|
+
if (currentStepConfig) {
|
|
96
|
+
let currentValue = '';
|
|
97
|
+
switch (currentStepConfig.type) {
|
|
98
|
+
case StepType.Text:
|
|
99
|
+
currentValue = inputValue || values[currentStepConfig.key] || '';
|
|
100
|
+
break;
|
|
101
|
+
case StepType.Selection:
|
|
102
|
+
currentValue =
|
|
103
|
+
currentStepConfig.options[selectedIndex]?.value ||
|
|
104
|
+
values[currentStepConfig.key] ||
|
|
105
|
+
'';
|
|
106
|
+
break;
|
|
107
|
+
default: {
|
|
108
|
+
const exhaustiveCheck = currentStepConfig;
|
|
109
|
+
throw new Error(`Unsupported step type: ${exhaustiveCheck}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (currentValue) {
|
|
113
|
+
setValues({ ...values, [currentStepConfig.key]: currentValue });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
26
116
|
if (onAborted) {
|
|
27
117
|
onAborted();
|
|
28
118
|
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const currentStep = steps[step];
|
|
122
|
+
if (!done && step < steps.length && currentStep) {
|
|
123
|
+
switch (currentStep.type) {
|
|
124
|
+
case StepType.Selection:
|
|
125
|
+
if (key.tab) {
|
|
126
|
+
setSelectedIndex((prev) => (prev + 1) % currentStep.options.length);
|
|
127
|
+
}
|
|
128
|
+
else if (key.return) {
|
|
129
|
+
handleSubmit(currentStep.options[selectedIndex].value);
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
case StepType.Text:
|
|
133
|
+
// Text input handled by TextInput component
|
|
134
|
+
break;
|
|
135
|
+
default: {
|
|
136
|
+
const exhaustiveCheck = currentStep;
|
|
137
|
+
throw new Error(`Unsupported step type: ${exhaustiveCheck}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
29
140
|
}
|
|
30
141
|
});
|
|
31
142
|
const handleSubmit = (value) => {
|
|
32
143
|
const currentStepConfig = steps[step];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
144
|
+
let finalValue = '';
|
|
145
|
+
switch (currentStepConfig.type) {
|
|
146
|
+
case StepType.Selection:
|
|
147
|
+
// For selection, value is already validated by options
|
|
148
|
+
finalValue = value;
|
|
149
|
+
break;
|
|
150
|
+
case StepType.Text: {
|
|
151
|
+
// For text input
|
|
152
|
+
const normalizedInput = normalizeValue(value);
|
|
153
|
+
// Try user input first, then fall back to default
|
|
154
|
+
if (normalizedInput && currentStepConfig.validate(normalizedInput)) {
|
|
155
|
+
finalValue = normalizedInput;
|
|
156
|
+
}
|
|
157
|
+
else if (currentStepConfig.value &&
|
|
158
|
+
currentStepConfig.validate(currentStepConfig.value)) {
|
|
159
|
+
finalValue = currentStepConfig.value;
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
default: {
|
|
164
|
+
const exhaustiveCheck = currentStepConfig;
|
|
165
|
+
throw new Error(`Unsupported step type: ${exhaustiveCheck}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Don't allow empty or invalid value
|
|
169
|
+
if (!finalValue) {
|
|
36
170
|
return;
|
|
37
171
|
}
|
|
38
172
|
const newValues = { ...values, [currentStepConfig.key]: finalValue };
|
|
@@ -47,9 +181,34 @@ export function Config({ steps, state, onFinished, onAborted }) {
|
|
|
47
181
|
}
|
|
48
182
|
else {
|
|
49
183
|
setStep(step + 1);
|
|
184
|
+
// Reset selection index for next step
|
|
185
|
+
const nextStep = steps[step + 1];
|
|
186
|
+
if (nextStep?.type === StepType.Selection) {
|
|
187
|
+
setSelectedIndex(nextStep.defaultIndex);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const renderStepInput = (stepConfig, isCurrentStep) => {
|
|
192
|
+
switch (stepConfig.type) {
|
|
193
|
+
case StepType.Text:
|
|
194
|
+
if (isCurrentStep) {
|
|
195
|
+
return (_jsx(TextStep, { value: inputValue, placeholder: stepConfig.value || undefined, validate: stepConfig.validate, onChange: setInputValue, onSubmit: handleSubmit }));
|
|
196
|
+
}
|
|
197
|
+
return _jsx(Text, { dimColor: true, children: values[stepConfig.key] || '' });
|
|
198
|
+
case StepType.Selection: {
|
|
199
|
+
if (!isCurrentStep) {
|
|
200
|
+
const selectedOption = stepConfig.options.find((opt) => opt.value === values[stepConfig.key]);
|
|
201
|
+
return _jsx(Text, { dimColor: true, children: selectedOption?.label || '' });
|
|
202
|
+
}
|
|
203
|
+
return (_jsx(SelectionStep, { options: stepConfig.options, selectedIndex: selectedIndex, isCurrentStep: isCurrentStep }));
|
|
204
|
+
}
|
|
205
|
+
default: {
|
|
206
|
+
const exhaustiveCheck = stepConfig;
|
|
207
|
+
throw new Error(`Unsupported step type: ${exhaustiveCheck}`);
|
|
208
|
+
}
|
|
50
209
|
}
|
|
51
210
|
};
|
|
52
|
-
return (_jsx(Box, { flexDirection: "column",
|
|
211
|
+
return (_jsx(Box, { flexDirection: "column", children: steps.map((stepConfig, index) => {
|
|
53
212
|
const isCurrentStep = index === step && !done;
|
|
54
213
|
const isCompleted = index < step;
|
|
55
214
|
const wasAborted = index === step && done;
|
|
@@ -57,6 +216,6 @@ export function Config({ steps, state, onFinished, onAborted }) {
|
|
|
57
216
|
if (!shouldShow) {
|
|
58
217
|
return null;
|
|
59
218
|
}
|
|
60
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsx(Box, { children: _jsxs(Text, { children: [stepConfig.description, ":"] }) }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { color: "#5c8cbc", dimColor: !isCurrentStep, children: ">" }), _jsx(Text, { children: " " }),
|
|
219
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsx(Box, { children: _jsxs(Text, { children: [stepConfig.description, ":"] }) }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { color: "#5c8cbc", dimColor: !isCurrentStep, children: ">" }), _jsx(Text, { children: " " }), renderStepInput(stepConfig, isCurrentStep)] })] }, stepConfig.key));
|
|
61
220
|
}) }));
|
|
62
221
|
}
|
package/dist/ui/Feedback.js
CHANGED
|
@@ -3,20 +3,31 @@ import { Box, Text } from 'ink';
|
|
|
3
3
|
import { FeedbackType } from '../types/components.js';
|
|
4
4
|
function getSymbol(type) {
|
|
5
5
|
return {
|
|
6
|
+
[FeedbackType.Info]: 'ℹ',
|
|
6
7
|
[FeedbackType.Succeeded]: '✓',
|
|
7
8
|
[FeedbackType.Aborted]: '⊘',
|
|
8
9
|
[FeedbackType.Failed]: '✗',
|
|
9
10
|
}[type];
|
|
10
11
|
}
|
|
11
|
-
function
|
|
12
|
+
function getSymbolColor(type) {
|
|
12
13
|
return {
|
|
14
|
+
[FeedbackType.Info]: '#5c9ccc', // cyan
|
|
13
15
|
[FeedbackType.Succeeded]: '#00aa00', // green
|
|
14
16
|
[FeedbackType.Aborted]: '#cc9c5c', // orange
|
|
15
|
-
[FeedbackType.Failed]: '#
|
|
17
|
+
[FeedbackType.Failed]: '#cc5c5c', // red
|
|
18
|
+
}[type];
|
|
19
|
+
}
|
|
20
|
+
function getMessageColor(type) {
|
|
21
|
+
return {
|
|
22
|
+
[FeedbackType.Info]: '#aaaaaa', // light grey
|
|
23
|
+
[FeedbackType.Succeeded]: '#5ccc5c', // green
|
|
24
|
+
[FeedbackType.Aborted]: '#cc9c5c', // orange
|
|
25
|
+
[FeedbackType.Failed]: '#cc5c5c', // red
|
|
16
26
|
}[type];
|
|
17
27
|
}
|
|
18
28
|
export function Feedback({ type, message }) {
|
|
19
|
-
const
|
|
29
|
+
const symbolColor = getSymbolColor(type);
|
|
30
|
+
const messageColor = getMessageColor(type);
|
|
20
31
|
const symbol = getSymbol(type);
|
|
21
|
-
return (
|
|
32
|
+
return (_jsxs(Box, { children: [_jsxs(Text, { color: symbolColor, children: [symbol, " "] }), _jsx(Text, { color: messageColor, children: message })] }));
|
|
22
33
|
}
|
package/dist/ui/List.js
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
3
|
import { Label } from './Label.js';
|
|
4
|
-
export const List = ({ items, level = 0 }) => {
|
|
4
|
+
export const List = ({ items, level = 0, highlightedIndex = null, highlightedParentIndex = null, }) => {
|
|
5
5
|
const marginLeft = level > 0 ? 4 : 0;
|
|
6
|
-
return (_jsx(Box, { flexDirection: "column", marginLeft: marginLeft, children: items.map((item, index) =>
|
|
6
|
+
return (_jsx(Box, { flexDirection: "column", marginLeft: marginLeft, children: items.map((item, index) => {
|
|
7
|
+
// At level 0, track which parent is active for child highlighting
|
|
8
|
+
// At level > 0, only highlight if this parent is the active one
|
|
9
|
+
const shouldHighlightChildren = level === 0 ? highlightedParentIndex === index : false;
|
|
10
|
+
const isHighlighted = item.highlighted || (level > 0 && index === highlightedIndex);
|
|
11
|
+
const marker = item.marker || (isHighlighted ? ' → ' : ' - ');
|
|
12
|
+
// Use highlighted colors if available and item is highlighted
|
|
13
|
+
const descriptionColor = isHighlighted && item.description.highlightedColor
|
|
14
|
+
? item.description.highlightedColor
|
|
15
|
+
: item.description.color;
|
|
16
|
+
const typeColor = isHighlighted && item.type.highlightedColor
|
|
17
|
+
? item.type.highlightedColor
|
|
18
|
+
: item.type.color;
|
|
19
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "whiteBright", children: marker }), _jsx(Label, { description: item.description.text, descriptionColor: descriptionColor, type: item.type.text, typeColor: typeColor })] }), item.children && item.children.length > 0 && (_jsx(List, { items: item.children, level: level + 1, highlightedIndex: shouldHighlightChildren ? highlightedIndex : null }))] }, index));
|
|
20
|
+
}) }));
|
|
7
21
|
};
|