giggles 0.7.1 → 0.7.3
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.
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-C77VBSPK.js";
|
|
4
4
|
|
|
5
5
|
// src/ui/CodeBlock.tsx
|
|
6
|
+
import { useMemo } from "react";
|
|
6
7
|
import { Box, Text } from "ink";
|
|
7
8
|
import Prism from "prismjs";
|
|
8
9
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -24,9 +25,12 @@ var defaultTokenColors = {
|
|
|
24
25
|
};
|
|
25
26
|
function CodeBlock({ children, language, tokenColors, ...boxProps }) {
|
|
26
27
|
const theme = useTheme();
|
|
27
|
-
const colors = { ...defaultTokenColors, ...tokenColors };
|
|
28
|
+
const colors = useMemo(() => ({ ...defaultTokenColors, ...tokenColors }), [tokenColors]);
|
|
28
29
|
const grammar = language ? Prism.languages[language] : void 0;
|
|
29
|
-
const content =
|
|
30
|
+
const content = useMemo(
|
|
31
|
+
() => grammar ? renderTokens(Prism.tokenize(children, grammar), colors) : /* @__PURE__ */ jsx(Text, { children }),
|
|
32
|
+
[children, grammar, colors]
|
|
33
|
+
);
|
|
30
34
|
return /* @__PURE__ */ jsx(Box, { paddingX: 1, borderStyle: theme.borderStyle, borderColor: theme.borderColor, ...boxProps, children: /* @__PURE__ */ jsx(Text, { children: content }) });
|
|
31
35
|
}
|
|
32
36
|
function renderTokens(tokens, colors) {
|
|
@@ -94,16 +94,16 @@ function useFocusNode(options) {
|
|
|
94
94
|
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
95
95
|
import { jsx } from "react/jsx-runtime";
|
|
96
96
|
function FocusTrap({ children }) {
|
|
97
|
-
const { id } = useFocusNode();
|
|
98
97
|
const store = useStore();
|
|
99
98
|
const previousFocusRef = useRef2(store.getFocusedId());
|
|
99
|
+
const { id } = useFocusNode();
|
|
100
100
|
useEffect2(() => {
|
|
101
101
|
const previousFocus = previousFocusRef.current;
|
|
102
102
|
store.setTrap(id);
|
|
103
103
|
store.focusFirstChild(id);
|
|
104
104
|
return () => {
|
|
105
105
|
store.clearTrap(id);
|
|
106
|
-
if (previousFocus) {
|
|
106
|
+
if (previousFocus && previousFocus !== id) {
|
|
107
107
|
store.focusNode(previousFocus);
|
|
108
108
|
}
|
|
109
109
|
};
|
|
@@ -277,6 +277,15 @@ var FocusStore = class {
|
|
|
277
277
|
}
|
|
278
278
|
return;
|
|
279
279
|
}
|
|
280
|
+
if (existing && existing.parentId !== parentId) {
|
|
281
|
+
if (existing.parentId) {
|
|
282
|
+
const oldParent = this.nodes.get(existing.parentId);
|
|
283
|
+
if (oldParent) {
|
|
284
|
+
oldParent.childrenIds = oldParent.childrenIds.filter((c) => c !== id);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
this.updateFocusKey(id, existing.parentId, existing.focusKey, void 0);
|
|
288
|
+
}
|
|
280
289
|
const node = { id, parentId, childrenIds: [], focusKey };
|
|
281
290
|
this.nodes.set(id, node);
|
|
282
291
|
this.parentMap.set(id, parentId);
|
package/dist/index.js
CHANGED
package/dist/markdown/index.js
CHANGED
package/dist/ui/index.d.ts
CHANGED
package/dist/ui/index.js
CHANGED
|
@@ -1,36 +1,124 @@
|
|
|
1
1
|
import {
|
|
2
|
+
FocusScope,
|
|
2
3
|
FocusTrap,
|
|
3
4
|
GigglesError,
|
|
4
5
|
useFocusNode,
|
|
6
|
+
useFocusScope,
|
|
5
7
|
useKeybindingRegistry,
|
|
6
8
|
useKeybindings
|
|
7
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-BHA3UFY2.js";
|
|
8
10
|
import {
|
|
9
11
|
CodeBlock
|
|
10
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-4MVZP2MB.js";
|
|
11
13
|
import {
|
|
12
14
|
useTheme
|
|
13
15
|
} from "../chunk-C77VBSPK.js";
|
|
14
16
|
|
|
15
17
|
// src/ui/CommandPalette.tsx
|
|
16
18
|
import { useState as useState2 } from "react";
|
|
17
|
-
import { Box as Box3, Text as
|
|
19
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
20
|
+
|
|
21
|
+
// src/ui/TextInput.tsx
|
|
22
|
+
import { useReducer, useRef } from "react";
|
|
23
|
+
import { Text } from "ink";
|
|
24
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
25
|
+
function TextInput({ label, value, onChange, onSubmit, placeholder, render, focusKey }) {
|
|
26
|
+
const focus = useFocusNode({ focusKey });
|
|
27
|
+
const cursorRef = useRef(value.length);
|
|
28
|
+
const [, forceRender] = useReducer((c) => c + 1, 0);
|
|
29
|
+
const cursor = Math.min(cursorRef.current, value.length);
|
|
30
|
+
cursorRef.current = cursor;
|
|
31
|
+
useKeybindings(
|
|
32
|
+
focus,
|
|
33
|
+
{
|
|
34
|
+
left: () => {
|
|
35
|
+
cursorRef.current = Math.max(0, cursorRef.current - 1);
|
|
36
|
+
forceRender();
|
|
37
|
+
},
|
|
38
|
+
right: () => {
|
|
39
|
+
cursorRef.current = Math.min(value.length, cursorRef.current + 1);
|
|
40
|
+
forceRender();
|
|
41
|
+
},
|
|
42
|
+
home: () => {
|
|
43
|
+
cursorRef.current = 0;
|
|
44
|
+
forceRender();
|
|
45
|
+
},
|
|
46
|
+
end: () => {
|
|
47
|
+
cursorRef.current = value.length;
|
|
48
|
+
forceRender();
|
|
49
|
+
},
|
|
50
|
+
backspace: () => {
|
|
51
|
+
const c = cursorRef.current;
|
|
52
|
+
if (c > 0) {
|
|
53
|
+
cursorRef.current = c - 1;
|
|
54
|
+
onChange(value.slice(0, c - 1) + value.slice(c));
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
delete: () => {
|
|
58
|
+
const c = cursorRef.current;
|
|
59
|
+
if (c < value.length) {
|
|
60
|
+
onChange(value.slice(0, c) + value.slice(c + 1));
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
...onSubmit && { enter: () => onSubmit(value) }
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
fallback: (input, key) => {
|
|
67
|
+
if (input.length === 1 && !key.ctrl && !key.return && !key.escape && !key.tab) {
|
|
68
|
+
const c = cursorRef.current;
|
|
69
|
+
cursorRef.current = c + 1;
|
|
70
|
+
onChange(value.slice(0, c) + input + value.slice(c));
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
bubble: ["tab", "shift+tab", "enter", "escape", "backspace", "delete", "left", "right", "home", "end"]
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
const before = value.slice(0, cursor);
|
|
77
|
+
const cursorChar = value[cursor] ?? " ";
|
|
78
|
+
const after = value.slice(cursor + 1);
|
|
79
|
+
if (render) {
|
|
80
|
+
return /* @__PURE__ */ jsx(Fragment, { children: render({ value, focused: focus.hasFocus, before, cursorChar, after, placeholder }) });
|
|
81
|
+
}
|
|
82
|
+
const displayValue = value.length > 0 ? value : placeholder ?? "";
|
|
83
|
+
const isPlaceholder = value.length === 0;
|
|
84
|
+
if (focus.hasFocus) {
|
|
85
|
+
const isPlaceholderVisible = value.length === 0 && placeholder != null;
|
|
86
|
+
const activeCursorChar = isPlaceholderVisible ? placeholder[0] ?? " " : cursorChar;
|
|
87
|
+
const activeAfter = isPlaceholderVisible ? placeholder.slice(1) : after;
|
|
88
|
+
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
89
|
+
label != null && /* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
90
|
+
label,
|
|
91
|
+
" "
|
|
92
|
+
] }),
|
|
93
|
+
before,
|
|
94
|
+
/* @__PURE__ */ jsx(Text, { inverse: true, children: activeCursorChar }),
|
|
95
|
+
isPlaceholderVisible ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: activeAfter }) : activeAfter
|
|
96
|
+
] });
|
|
97
|
+
}
|
|
98
|
+
return /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
99
|
+
label != null && /* @__PURE__ */ jsxs(Text, { children: [
|
|
100
|
+
label,
|
|
101
|
+
" "
|
|
102
|
+
] }),
|
|
103
|
+
isPlaceholder ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: displayValue }) : displayValue
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
18
106
|
|
|
19
107
|
// src/ui/VirtualList.tsx
|
|
20
|
-
import
|
|
108
|
+
import React2, { useEffect, useRef as useRef2, useState } from "react";
|
|
21
109
|
import { Box as Box2 } from "ink";
|
|
22
110
|
|
|
23
111
|
// src/ui/Paginator.tsx
|
|
24
|
-
import { Box, Text } from "ink";
|
|
25
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
112
|
+
import { Box, Text as Text2 } from "ink";
|
|
113
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
26
114
|
function Paginator({ total, offset, visible, gap = 0, style = "arrows", position }) {
|
|
27
115
|
const theme = useTheme();
|
|
28
116
|
if (style === "none" || total <= visible) return null;
|
|
29
117
|
const hasAbove = offset > 0;
|
|
30
118
|
const hasBelow = offset + visible < total;
|
|
31
119
|
if (style === "arrows") {
|
|
32
|
-
if (position === "above" && hasAbove) return /* @__PURE__ */
|
|
33
|
-
if (position === "below" && hasBelow) return /* @__PURE__ */
|
|
120
|
+
if (position === "above" && hasAbove) return /* @__PURE__ */ jsx2(Text2, { color: theme.accentColor, children: "\u2191" });
|
|
121
|
+
if (position === "below" && hasBelow) return /* @__PURE__ */ jsx2(Text2, { color: theme.accentColor, children: "\u2193" });
|
|
34
122
|
return null;
|
|
35
123
|
}
|
|
36
124
|
if (style === "dots") {
|
|
@@ -38,14 +126,14 @@ function Paginator({ total, offset, visible, gap = 0, style = "arrows", position
|
|
|
38
126
|
const totalPages = Math.ceil(total / visible);
|
|
39
127
|
const maxOffset = Math.max(1, total - visible);
|
|
40
128
|
const currentPage = Math.round(offset / maxOffset * (totalPages - 1));
|
|
41
|
-
return /* @__PURE__ */
|
|
129
|
+
return /* @__PURE__ */ jsx2(Text2, { children: Array.from({ length: totalPages }, (_, i) => /* @__PURE__ */ jsxs2(Text2, { dimColor: i !== currentPage, children: [
|
|
42
130
|
"\u25CF",
|
|
43
131
|
i < totalPages - 1 ? " " : ""
|
|
44
132
|
] }, i)) });
|
|
45
133
|
}
|
|
46
134
|
if (style === "counter") {
|
|
47
135
|
if (position === "above") return null;
|
|
48
|
-
return /* @__PURE__ */
|
|
136
|
+
return /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
49
137
|
offset + 1,
|
|
50
138
|
"\u2013",
|
|
51
139
|
Math.min(offset + visible, total),
|
|
@@ -58,14 +146,14 @@ function Paginator({ total, offset, visible, gap = 0, style = "arrows", position
|
|
|
58
146
|
const maxThumbOffset = totalLines - thumbSize;
|
|
59
147
|
const maxScrollOffset = total - visible;
|
|
60
148
|
const thumbOffset = maxScrollOffset === 0 ? 0 : Math.round(offset / maxScrollOffset * maxThumbOffset);
|
|
61
|
-
return /* @__PURE__ */
|
|
149
|
+
return /* @__PURE__ */ jsx2(Box, { flexDirection: "column", children: Array.from({ length: totalLines }, (_, i) => {
|
|
62
150
|
const isThumb = i >= thumbOffset && i < thumbOffset + thumbSize;
|
|
63
|
-
return /* @__PURE__ */
|
|
151
|
+
return /* @__PURE__ */ jsx2(Text2, { color: isThumb ? theme.accentColor : void 0, dimColor: !isThumb, children: isThumb ? "\u2588" : "\u2502" }, i);
|
|
64
152
|
}) });
|
|
65
153
|
}
|
|
66
154
|
|
|
67
155
|
// src/ui/VirtualList.tsx
|
|
68
|
-
import { jsx as
|
|
156
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
69
157
|
function VirtualList({
|
|
70
158
|
items,
|
|
71
159
|
highlightIndex,
|
|
@@ -76,7 +164,7 @@ function VirtualList({
|
|
|
76
164
|
render
|
|
77
165
|
}) {
|
|
78
166
|
const [internalOffset, setInternalOffset] = useState(0);
|
|
79
|
-
const offsetRef =
|
|
167
|
+
const offsetRef = useRef2(0);
|
|
80
168
|
const windowed = maxVisible != null && items.length > maxVisible;
|
|
81
169
|
let offset = 0;
|
|
82
170
|
if (windowed) {
|
|
@@ -101,7 +189,7 @@ function VirtualList({
|
|
|
101
189
|
}
|
|
102
190
|
}, [windowed, highlightIndex, controlledOffset, internalOffset]);
|
|
103
191
|
if (!windowed) {
|
|
104
|
-
return /* @__PURE__ */
|
|
192
|
+
return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", gap, children: items.map((item, index) => /* @__PURE__ */ jsx3(React2.Fragment, { children: render({ item, index }) }, index)) });
|
|
105
193
|
}
|
|
106
194
|
const visible = items.slice(offset, offset + maxVisible);
|
|
107
195
|
const paginatorProps = {
|
|
@@ -112,26 +200,26 @@ function VirtualList({
|
|
|
112
200
|
style: paginatorStyle
|
|
113
201
|
};
|
|
114
202
|
if (paginatorStyle === "scrollbar") {
|
|
115
|
-
return /* @__PURE__ */
|
|
116
|
-
/* @__PURE__ */
|
|
203
|
+
return /* @__PURE__ */ jsxs3(Box2, { flexDirection: "row", gap: 1, children: [
|
|
204
|
+
/* @__PURE__ */ jsx3(Box2, { flexDirection: "column", gap, flexGrow: 1, children: visible.map((item, i) => {
|
|
117
205
|
const index = offset + i;
|
|
118
|
-
return /* @__PURE__ */
|
|
206
|
+
return /* @__PURE__ */ jsx3(React2.Fragment, { children: render({ item, index }) }, index);
|
|
119
207
|
}) }),
|
|
120
|
-
/* @__PURE__ */
|
|
208
|
+
/* @__PURE__ */ jsx3(Paginator, { ...paginatorProps })
|
|
121
209
|
] });
|
|
122
210
|
}
|
|
123
|
-
return /* @__PURE__ */
|
|
124
|
-
/* @__PURE__ */
|
|
211
|
+
return /* @__PURE__ */ jsxs3(Box2, { flexDirection: "column", gap, children: [
|
|
212
|
+
/* @__PURE__ */ jsx3(Paginator, { ...paginatorProps, position: "above" }),
|
|
125
213
|
visible.map((item, i) => {
|
|
126
214
|
const index = offset + i;
|
|
127
|
-
return /* @__PURE__ */
|
|
215
|
+
return /* @__PURE__ */ jsx3(React2.Fragment, { children: render({ item, index }) }, index);
|
|
128
216
|
}),
|
|
129
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ jsx3(Paginator, { ...paginatorProps, position: "below" })
|
|
130
218
|
] });
|
|
131
219
|
}
|
|
132
220
|
|
|
133
221
|
// src/ui/CommandPalette.tsx
|
|
134
|
-
import {
|
|
222
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
135
223
|
var EMPTY_KEY = {
|
|
136
224
|
upArrow: false,
|
|
137
225
|
downArrow: false,
|
|
@@ -169,7 +257,6 @@ function Inner({
|
|
|
169
257
|
maxVisible = 10,
|
|
170
258
|
render
|
|
171
259
|
}) {
|
|
172
|
-
const focus = useFocusNode();
|
|
173
260
|
const theme = useTheme();
|
|
174
261
|
const [query, setQuery] = useState2("");
|
|
175
262
|
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
@@ -181,40 +268,27 @@ function Inner({
|
|
|
181
268
|
cmd.handler("", EMPTY_KEY);
|
|
182
269
|
onClose();
|
|
183
270
|
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
271
|
+
const handleChange = (value) => {
|
|
272
|
+
setQuery(value);
|
|
273
|
+
setSelectedIndex(0);
|
|
274
|
+
};
|
|
275
|
+
const scope = useFocusScope({
|
|
276
|
+
keybindings: {
|
|
187
277
|
escape: onClose,
|
|
188
278
|
enter: () => {
|
|
189
279
|
const cmd = filtered[clampedIndex];
|
|
190
280
|
if (cmd) onSelect(cmd);
|
|
191
281
|
},
|
|
192
282
|
up: () => setSelectedIndex((i) => (i - 1 + filtered.length) % filtered.length),
|
|
193
|
-
down: () => setSelectedIndex((i) => (i + 1) % filtered.length)
|
|
194
|
-
backspace: () => {
|
|
195
|
-
setQuery((q) => q.slice(0, -1));
|
|
196
|
-
setSelectedIndex(0);
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
fallback: (input, key) => {
|
|
201
|
-
if (input.length === 1 && !key.ctrl) {
|
|
202
|
-
setQuery((q) => q + input);
|
|
203
|
-
setSelectedIndex(0);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
283
|
+
down: () => setSelectedIndex((i) => (i + 1) % filtered.length)
|
|
206
284
|
}
|
|
207
|
-
);
|
|
285
|
+
});
|
|
208
286
|
if (render) {
|
|
209
|
-
return /* @__PURE__ */
|
|
287
|
+
return /* @__PURE__ */ jsx4(FocusScope, { handle: scope, children: render({ query, onChange: handleChange, filtered, selectedIndex: clampedIndex, onSelect }) });
|
|
210
288
|
}
|
|
211
|
-
return /* @__PURE__ */
|
|
212
|
-
/* @__PURE__ */
|
|
213
|
-
|
|
214
|
-
query.length > 0 ? /* @__PURE__ */ jsx3(Text2, { children: query }) : /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "Search commands\u2026" }),
|
|
215
|
-
/* @__PURE__ */ jsx3(Text2, { inverse: true, children: " " })
|
|
216
|
-
] }),
|
|
217
|
-
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", marginTop: 1, children: filtered.length === 0 ? /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "No commands found" }) : /* @__PURE__ */ jsx3(
|
|
289
|
+
return /* @__PURE__ */ jsx4(FocusScope, { handle: scope, children: /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", children: [
|
|
290
|
+
/* @__PURE__ */ jsx4(TextInput, { label: ">", value: query, onChange: handleChange, placeholder: "Search commands\u2026" }),
|
|
291
|
+
/* @__PURE__ */ jsx4(Box3, { flexDirection: "column", marginTop: 1, children: filtered.length === 0 ? /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: "No commands found" }) : /* @__PURE__ */ jsx4(
|
|
218
292
|
VirtualList,
|
|
219
293
|
{
|
|
220
294
|
items: filtered,
|
|
@@ -225,10 +299,10 @@ function Inner({
|
|
|
225
299
|
const highlighted = index === clampedIndex;
|
|
226
300
|
const keyColor = highlighted ? theme.hintHighlightColor : theme.hintColor;
|
|
227
301
|
const labelColor = highlighted ? theme.hintHighlightDimColor : theme.hintDimColor;
|
|
228
|
-
return /* @__PURE__ */
|
|
229
|
-
/* @__PURE__ */
|
|
230
|
-
/* @__PURE__ */
|
|
231
|
-
/* @__PURE__ */
|
|
302
|
+
return /* @__PURE__ */ jsxs4(Text3, { children: [
|
|
303
|
+
/* @__PURE__ */ jsx4(Text3, { dimColor: true, children: highlighted ? theme.indicator + " " : " " }),
|
|
304
|
+
/* @__PURE__ */ jsx4(Text3, { color: keyColor, bold: true, children: cmd.key }),
|
|
305
|
+
/* @__PURE__ */ jsxs4(Text3, { color: labelColor, children: [
|
|
232
306
|
" ",
|
|
233
307
|
cmd.name
|
|
234
308
|
] })
|
|
@@ -236,116 +310,30 @@ function Inner({
|
|
|
236
310
|
}
|
|
237
311
|
}
|
|
238
312
|
) }),
|
|
239
|
-
/* @__PURE__ */
|
|
240
|
-
] });
|
|
313
|
+
/* @__PURE__ */ jsx4(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: "\u2191\u2193 navigate \xB7 \u21B5 run \xB7 esc close" }) })
|
|
314
|
+
] }) });
|
|
241
315
|
}
|
|
242
316
|
function HintsBar() {
|
|
243
317
|
const registry = useKeybindingRegistry();
|
|
244
318
|
const theme = useTheme();
|
|
245
319
|
const commands = registry.available.filter((cmd) => cmd.name != null);
|
|
246
320
|
if (commands.length === 0) return null;
|
|
247
|
-
return /* @__PURE__ */
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
/* @__PURE__ */
|
|
321
|
+
return /* @__PURE__ */ jsx4(Box3, { flexWrap: "wrap", children: commands.map((cmd, index) => /* @__PURE__ */ jsxs4(Text3, { children: [
|
|
322
|
+
/* @__PURE__ */ jsx4(Text3, { color: theme.hintColor, bold: true, children: cmd.key }),
|
|
323
|
+
/* @__PURE__ */ jsxs4(Text3, { color: theme.hintDimColor, children: [
|
|
250
324
|
" ",
|
|
251
325
|
cmd.name
|
|
252
326
|
] }),
|
|
253
|
-
index < commands.length - 1 && /* @__PURE__ */
|
|
327
|
+
index < commands.length - 1 && /* @__PURE__ */ jsx4(Text3, { color: theme.hintDimColor, children: " \u2022 " })
|
|
254
328
|
] }, `${cmd.nodeId}-${cmd.key}`)) });
|
|
255
329
|
}
|
|
256
330
|
var noop = () => {
|
|
257
331
|
};
|
|
258
332
|
function CommandPalette({ onClose, interactive = true, maxVisible, render }) {
|
|
259
333
|
if (!interactive) {
|
|
260
|
-
return /* @__PURE__ */
|
|
334
|
+
return /* @__PURE__ */ jsx4(HintsBar, {});
|
|
261
335
|
}
|
|
262
|
-
return /* @__PURE__ */
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// src/ui/TextInput.tsx
|
|
266
|
-
import { useReducer, useRef as useRef2 } from "react";
|
|
267
|
-
import { Text as Text3 } from "ink";
|
|
268
|
-
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
269
|
-
function TextInput({ label, value, onChange, onSubmit, placeholder, render, focusKey }) {
|
|
270
|
-
const focus = useFocusNode({ focusKey });
|
|
271
|
-
const cursorRef = useRef2(value.length);
|
|
272
|
-
const [, forceRender] = useReducer((c) => c + 1, 0);
|
|
273
|
-
const cursor = Math.min(cursorRef.current, value.length);
|
|
274
|
-
cursorRef.current = cursor;
|
|
275
|
-
useKeybindings(
|
|
276
|
-
focus,
|
|
277
|
-
{
|
|
278
|
-
left: () => {
|
|
279
|
-
cursorRef.current = Math.max(0, cursorRef.current - 1);
|
|
280
|
-
forceRender();
|
|
281
|
-
},
|
|
282
|
-
right: () => {
|
|
283
|
-
cursorRef.current = Math.min(value.length, cursorRef.current + 1);
|
|
284
|
-
forceRender();
|
|
285
|
-
},
|
|
286
|
-
home: () => {
|
|
287
|
-
cursorRef.current = 0;
|
|
288
|
-
forceRender();
|
|
289
|
-
},
|
|
290
|
-
end: () => {
|
|
291
|
-
cursorRef.current = value.length;
|
|
292
|
-
forceRender();
|
|
293
|
-
},
|
|
294
|
-
backspace: () => {
|
|
295
|
-
const c = cursorRef.current;
|
|
296
|
-
if (c > 0) {
|
|
297
|
-
cursorRef.current = c - 1;
|
|
298
|
-
onChange(value.slice(0, c - 1) + value.slice(c));
|
|
299
|
-
}
|
|
300
|
-
},
|
|
301
|
-
delete: () => {
|
|
302
|
-
const c = cursorRef.current;
|
|
303
|
-
if (c < value.length) {
|
|
304
|
-
onChange(value.slice(0, c) + value.slice(c + 1));
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
...onSubmit && { enter: () => onSubmit(value) }
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
fallback: (input, key) => {
|
|
311
|
-
if (input.length === 1 && !key.ctrl && !key.return && !key.escape && !key.tab) {
|
|
312
|
-
const c = cursorRef.current;
|
|
313
|
-
cursorRef.current = c + 1;
|
|
314
|
-
onChange(value.slice(0, c) + input + value.slice(c));
|
|
315
|
-
}
|
|
316
|
-
},
|
|
317
|
-
bubble: ["tab", "shift+tab", "enter", "escape", "backspace", "delete", "left", "right", "home", "end"]
|
|
318
|
-
}
|
|
319
|
-
);
|
|
320
|
-
const before = value.slice(0, cursor);
|
|
321
|
-
const cursorChar = value[cursor] ?? " ";
|
|
322
|
-
const after = value.slice(cursor + 1);
|
|
323
|
-
if (render) {
|
|
324
|
-
return /* @__PURE__ */ jsx4(Fragment2, { children: render({ value, focused: focus.hasFocus, before, cursorChar, after, placeholder }) });
|
|
325
|
-
}
|
|
326
|
-
const displayValue = value.length > 0 ? value : placeholder ?? "";
|
|
327
|
-
const isPlaceholder = value.length === 0;
|
|
328
|
-
if (focus.hasFocus) {
|
|
329
|
-
const isPlaceholderVisible = value.length === 0 && placeholder != null;
|
|
330
|
-
const activeCursorChar = isPlaceholderVisible ? placeholder[0] ?? " " : cursorChar;
|
|
331
|
-
const activeAfter = isPlaceholderVisible ? placeholder.slice(1) : after;
|
|
332
|
-
return /* @__PURE__ */ jsxs4(Text3, { children: [
|
|
333
|
-
label != null && /* @__PURE__ */ jsxs4(Text3, { bold: true, children: [
|
|
334
|
-
label,
|
|
335
|
-
" "
|
|
336
|
-
] }),
|
|
337
|
-
before,
|
|
338
|
-
/* @__PURE__ */ jsx4(Text3, { inverse: true, children: activeCursorChar }),
|
|
339
|
-
isPlaceholderVisible ? /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: activeAfter }) : activeAfter
|
|
340
|
-
] });
|
|
341
|
-
}
|
|
342
|
-
return /* @__PURE__ */ jsxs4(Text3, { dimColor: true, children: [
|
|
343
|
-
label != null && /* @__PURE__ */ jsxs4(Text3, { children: [
|
|
344
|
-
label,
|
|
345
|
-
" "
|
|
346
|
-
] }),
|
|
347
|
-
isPlaceholder ? /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: displayValue }) : displayValue
|
|
348
|
-
] });
|
|
336
|
+
return /* @__PURE__ */ jsx4(FocusTrap, { children: /* @__PURE__ */ jsx4(Inner, { onClose: onClose ?? noop, maxVisible, render }) });
|
|
349
337
|
}
|
|
350
338
|
|
|
351
339
|
// src/ui/Select.tsx
|
|
@@ -891,7 +879,7 @@ function Badge({ children, color, background, variant = "round" }) {
|
|
|
891
879
|
// src/ui/Panel.tsx
|
|
892
880
|
import { useState as useState7 } from "react";
|
|
893
881
|
import { Box as Box9, Text as Text10, measureElement as measureElement2 } from "ink";
|
|
894
|
-
import { Fragment as
|
|
882
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
895
883
|
function Panel({ children, title, width, borderColor, footer, ...boxProps }) {
|
|
896
884
|
const theme = useTheme();
|
|
897
885
|
const color = borderColor ?? theme.borderColor;
|
|
@@ -944,7 +932,7 @@ function Panel({ children, title, width, borderColor, footer, ...boxProps }) {
|
|
|
944
932
|
borderTop: false,
|
|
945
933
|
borderColor: color,
|
|
946
934
|
paddingX: 1,
|
|
947
|
-
children: footer ? /* @__PURE__ */ jsxs12(
|
|
935
|
+
children: footer ? /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
948
936
|
/* @__PURE__ */ jsx11(Box9, { flexDirection: "column", flexGrow: 1, children }),
|
|
949
937
|
footer
|
|
950
938
|
] }) : children
|