pi-ask-user 0.5.1 → 0.6.0
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/README.md +9 -3
- package/index.ts +1465 -1134
- package/package.json +1 -1
- package/single-select-layout.ts +41 -13
package/package.json
CHANGED
package/single-select-layout.ts
CHANGED
|
@@ -3,11 +3,18 @@ export interface QuestionOption {
|
|
|
3
3
|
description?: string;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
export interface AnnotatedRow {
|
|
7
|
+
line: string;
|
|
8
|
+
selected: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
6
11
|
export interface RenderSingleSelectRowsParams {
|
|
7
12
|
options: QuestionOption[];
|
|
8
13
|
selectedIndex: number;
|
|
9
14
|
width: number;
|
|
10
15
|
allowFreeform: boolean;
|
|
16
|
+
allowComment?: boolean;
|
|
17
|
+
commentEnabled?: boolean;
|
|
11
18
|
maxRows?: number;
|
|
12
19
|
hideDescriptions?: boolean;
|
|
13
20
|
}
|
|
@@ -65,25 +72,36 @@ interface ItemBlock {
|
|
|
65
72
|
lines: string[];
|
|
66
73
|
}
|
|
67
74
|
|
|
75
|
+
type ListItem =
|
|
76
|
+
| { type: "option"; option: QuestionOption }
|
|
77
|
+
| { type: "comment-toggle"; option: QuestionOption }
|
|
78
|
+
| { type: "freeform"; option: QuestionOption };
|
|
79
|
+
|
|
68
80
|
function buildItemBlocks(
|
|
69
81
|
options: QuestionOption[],
|
|
70
82
|
width: number,
|
|
71
83
|
allowFreeform: boolean,
|
|
84
|
+
allowComment: boolean,
|
|
85
|
+
commentEnabled: boolean,
|
|
72
86
|
selectedIndex: number,
|
|
73
87
|
hideDescriptions = false,
|
|
74
88
|
): ItemBlock[] {
|
|
75
89
|
const normalizedWidth = Math.max(12, width);
|
|
76
90
|
const freeformLabel = "Type something. — Enter a custom response";
|
|
77
|
-
const
|
|
91
|
+
const commentToggleLabel = `${commentEnabled ? "[✓]" : "[ ]"} Add extra context after selection`;
|
|
92
|
+
const allItems: ListItem[] = options.map((option) => ({ type: "option", option }));
|
|
93
|
+
if (allowComment) {
|
|
94
|
+
allItems.push({ type: "comment-toggle", option: { title: commentToggleLabel } });
|
|
95
|
+
}
|
|
78
96
|
if (allowFreeform) {
|
|
79
|
-
allItems.push({ type: "freeform"
|
|
97
|
+
allItems.push({ type: "freeform", option: { title: freeformLabel } });
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
return allItems.map((item, itemIndex) => {
|
|
83
101
|
const pointer = itemIndex === selectedIndex ? "→" : " ";
|
|
84
102
|
const lines: string[] = [];
|
|
85
103
|
|
|
86
|
-
if (item.type === "freeform") {
|
|
104
|
+
if (item.type === "comment-toggle" || item.type === "freeform") {
|
|
87
105
|
const prefix = `${pointer} `;
|
|
88
106
|
const wrapped = wrapText(item.option.title, Math.max(8, normalizedWidth - prefix.length));
|
|
89
107
|
wrapped.forEach((line, lineIndex) => {
|
|
@@ -114,8 +132,13 @@ function buildItemBlocks(
|
|
|
114
132
|
});
|
|
115
133
|
}
|
|
116
134
|
|
|
117
|
-
function flatten(blocks: ItemBlock[]):
|
|
118
|
-
return blocks.flatMap((block) =>
|
|
135
|
+
function flatten(blocks: ItemBlock[], selectedIndex: number): AnnotatedRow[] {
|
|
136
|
+
return blocks.flatMap((block) =>
|
|
137
|
+
block.lines.map((line) => ({
|
|
138
|
+
line,
|
|
139
|
+
selected: block.itemIndex === selectedIndex,
|
|
140
|
+
})),
|
|
141
|
+
);
|
|
119
142
|
}
|
|
120
143
|
|
|
121
144
|
export function renderSingleSelectRows({
|
|
@@ -123,12 +146,14 @@ export function renderSingleSelectRows({
|
|
|
123
146
|
selectedIndex,
|
|
124
147
|
width,
|
|
125
148
|
allowFreeform,
|
|
149
|
+
allowComment = false,
|
|
150
|
+
commentEnabled = false,
|
|
126
151
|
maxRows,
|
|
127
152
|
hideDescriptions,
|
|
128
|
-
}: RenderSingleSelectRowsParams):
|
|
129
|
-
const itemCount = options.length + (allowFreeform ? 1 : 0);
|
|
130
|
-
const blocks = buildItemBlocks(options, width, allowFreeform, selectedIndex, hideDescriptions);
|
|
131
|
-
const allRows = flatten(blocks);
|
|
153
|
+
}: RenderSingleSelectRowsParams): AnnotatedRow[] {
|
|
154
|
+
const itemCount = options.length + (allowComment ? 1 : 0) + (allowFreeform ? 1 : 0);
|
|
155
|
+
const blocks = buildItemBlocks(options, width, allowFreeform, allowComment, commentEnabled, selectedIndex, hideDescriptions);
|
|
156
|
+
const allRows = flatten(blocks, selectedIndex);
|
|
132
157
|
|
|
133
158
|
if (!Number.isFinite(maxRows) || !maxRows || maxRows <= 0 || allRows.length <= maxRows) {
|
|
134
159
|
return allRows;
|
|
@@ -142,8 +167,11 @@ export function renderSingleSelectRows({
|
|
|
142
167
|
const availableRows = safeMaxRows > 1 ? safeMaxRows - 1 : 1;
|
|
143
168
|
|
|
144
169
|
if (selectedBlock.lines.length >= availableRows) {
|
|
145
|
-
const visible = selectedBlock.lines.slice(0, availableRows)
|
|
146
|
-
|
|
170
|
+
const visible = selectedBlock.lines.slice(0, availableRows).map((line) => ({
|
|
171
|
+
line,
|
|
172
|
+
selected: true,
|
|
173
|
+
}));
|
|
174
|
+
if (safeMaxRows > 1) visible.push({ line: indicator, selected: false });
|
|
147
175
|
return visible.slice(0, safeMaxRows);
|
|
148
176
|
}
|
|
149
177
|
|
|
@@ -169,7 +197,7 @@ export function renderSingleSelectRows({
|
|
|
169
197
|
break;
|
|
170
198
|
}
|
|
171
199
|
|
|
172
|
-
const visible = flatten(blocks.slice(start, end));
|
|
173
|
-
visible.push(indicator);
|
|
200
|
+
const visible = flatten(blocks.slice(start, end), selectedIndex);
|
|
201
|
+
visible.push({ line: indicator, selected: false });
|
|
174
202
|
return visible.slice(0, safeMaxRows);
|
|
175
203
|
}
|