giggles 0.3.6 → 0.3.8
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/{chunk-FEQYHTG7.js → chunk-OYQZHF73.js} +1 -27
- package/dist/chunk-PVXJL6SX.js +29 -0
- package/dist/chunk-TFYBLNEZ.js +93 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -3
- package/dist/markdown/index.d.ts +8 -0
- package/dist/markdown/index.js +122 -0
- package/dist/ui/index.d.ts +49 -1
- package/dist/ui/index.js +115 -2
- package/package.json +12 -3
|
@@ -452,30 +452,6 @@ function FocusTrap({ children }) {
|
|
|
452
452
|
return /* @__PURE__ */ jsx5(FocusNodeContext.Provider, { value: id, children });
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
// src/core/theme.tsx
|
|
456
|
-
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
457
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
458
|
-
var defaultTheme = {
|
|
459
|
-
accentColor: "#6B9FD4",
|
|
460
|
-
selectedColor: "#8FBF7F",
|
|
461
|
-
hintColor: "#8A8A8A",
|
|
462
|
-
hintDimColor: "#5C5C5C",
|
|
463
|
-
hintHighlightColor: "#D4D4D4",
|
|
464
|
-
hintHighlightDimColor: "#A0A0A0",
|
|
465
|
-
indicator: "\u25B8",
|
|
466
|
-
checkedIndicator: "\u2713",
|
|
467
|
-
uncheckedIndicator: "\u25CB"
|
|
468
|
-
};
|
|
469
|
-
var ThemeContext = createContext4(defaultTheme);
|
|
470
|
-
function ThemeProvider({ theme, children }) {
|
|
471
|
-
const parent = useContext4(ThemeContext);
|
|
472
|
-
const merged = { ...parent, ...theme };
|
|
473
|
-
return /* @__PURE__ */ jsx6(ThemeContext.Provider, { value: merged, children });
|
|
474
|
-
}
|
|
475
|
-
function useTheme() {
|
|
476
|
-
return useContext4(ThemeContext);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
455
|
export {
|
|
480
456
|
GigglesError,
|
|
481
457
|
FocusProvider,
|
|
@@ -488,7 +464,5 @@ export {
|
|
|
488
464
|
FocusTrap,
|
|
489
465
|
useFocus,
|
|
490
466
|
FocusGroup,
|
|
491
|
-
useFocusState
|
|
492
|
-
ThemeProvider,
|
|
493
|
-
useTheme
|
|
467
|
+
useFocusState
|
|
494
468
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// src/core/theme.tsx
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var defaultTheme = {
|
|
5
|
+
accentColor: "#6B9FD4",
|
|
6
|
+
borderColor: "#5C5C5C",
|
|
7
|
+
selectedColor: "#8FBF7F",
|
|
8
|
+
hintColor: "#8A8A8A",
|
|
9
|
+
hintDimColor: "#5C5C5C",
|
|
10
|
+
hintHighlightColor: "#D4D4D4",
|
|
11
|
+
hintHighlightDimColor: "#A0A0A0",
|
|
12
|
+
indicator: "\u25B8",
|
|
13
|
+
checkedIndicator: "\u2713",
|
|
14
|
+
uncheckedIndicator: "\u25CB"
|
|
15
|
+
};
|
|
16
|
+
var ThemeContext = createContext(defaultTheme);
|
|
17
|
+
function ThemeProvider({ theme, children }) {
|
|
18
|
+
const parent = useContext(ThemeContext);
|
|
19
|
+
const merged = { ...parent, ...theme };
|
|
20
|
+
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: merged, children });
|
|
21
|
+
}
|
|
22
|
+
function useTheme() {
|
|
23
|
+
return useContext(ThemeContext);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
ThemeProvider,
|
|
28
|
+
useTheme
|
|
29
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useTheme
|
|
3
|
+
} from "./chunk-PVXJL6SX.js";
|
|
4
|
+
|
|
5
|
+
// src/ui/CodeBlock.tsx
|
|
6
|
+
import Prism from "prismjs";
|
|
7
|
+
import { Box, Text } from "ink";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
var defaultTokenColors = {
|
|
10
|
+
keyword: "#C678DD",
|
|
11
|
+
string: "#98C379",
|
|
12
|
+
number: "#D19A66",
|
|
13
|
+
comment: "#5C6370",
|
|
14
|
+
function: "#61AFEF",
|
|
15
|
+
operator: "#56B6C2",
|
|
16
|
+
punctuation: "#ABB2BF",
|
|
17
|
+
builtin: "#E5C07B",
|
|
18
|
+
className: "#E5C07B",
|
|
19
|
+
inserted: "#98C379",
|
|
20
|
+
deleted: "#E06C75"
|
|
21
|
+
};
|
|
22
|
+
function CodeBlock({ children, language, showBorder = true, tokenColors }) {
|
|
23
|
+
const theme = useTheme();
|
|
24
|
+
const colors = { ...defaultTokenColors, ...tokenColors };
|
|
25
|
+
const grammar = language ? Prism.languages[language] : void 0;
|
|
26
|
+
const content = grammar ? renderTokens(Prism.tokenize(children, grammar), colors) : /* @__PURE__ */ jsx(Text, { children });
|
|
27
|
+
if (!showBorder) {
|
|
28
|
+
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: content }) });
|
|
29
|
+
}
|
|
30
|
+
return /* @__PURE__ */ jsx(Box, { paddingX: 1, borderStyle: "single", borderColor: theme.borderColor, children: /* @__PURE__ */ jsx(Text, { children: content }) });
|
|
31
|
+
}
|
|
32
|
+
function renderTokens(tokens, colors) {
|
|
33
|
+
return tokens.map((token, idx) => {
|
|
34
|
+
if (typeof token === "string") {
|
|
35
|
+
return /* @__PURE__ */ jsx(Text, { children: token }, idx);
|
|
36
|
+
}
|
|
37
|
+
const color = getTokenColor(token.type, colors);
|
|
38
|
+
const content = Array.isArray(token.content) ? renderTokens(token.content, colors) : typeof token.content === "string" ? token.content : renderTokens([token.content], colors);
|
|
39
|
+
return color ? /* @__PURE__ */ jsx(Text, { color, children: content }, idx) : /* @__PURE__ */ jsx(Text, { children: content }, idx);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function getTokenColor(type, colors) {
|
|
43
|
+
switch (type) {
|
|
44
|
+
case "keyword":
|
|
45
|
+
case "tag":
|
|
46
|
+
case "boolean":
|
|
47
|
+
case "important":
|
|
48
|
+
return colors.keyword;
|
|
49
|
+
case "string":
|
|
50
|
+
case "char":
|
|
51
|
+
case "template-string":
|
|
52
|
+
case "attr-value":
|
|
53
|
+
return colors.string;
|
|
54
|
+
case "number":
|
|
55
|
+
return colors.number;
|
|
56
|
+
case "comment":
|
|
57
|
+
case "prolog":
|
|
58
|
+
case "doctype":
|
|
59
|
+
case "cdata":
|
|
60
|
+
return colors.comment;
|
|
61
|
+
case "function":
|
|
62
|
+
case "function-variable":
|
|
63
|
+
return colors.function;
|
|
64
|
+
case "operator":
|
|
65
|
+
case "arrow":
|
|
66
|
+
return colors.operator;
|
|
67
|
+
case "punctuation":
|
|
68
|
+
return colors.punctuation;
|
|
69
|
+
case "builtin":
|
|
70
|
+
case "constant":
|
|
71
|
+
case "symbol":
|
|
72
|
+
return colors.builtin;
|
|
73
|
+
case "class-name":
|
|
74
|
+
case "maybe-class-name":
|
|
75
|
+
return colors.className;
|
|
76
|
+
case "attr-name":
|
|
77
|
+
return colors.function;
|
|
78
|
+
case "inserted-sign":
|
|
79
|
+
case "inserted":
|
|
80
|
+
return colors.inserted;
|
|
81
|
+
case "deleted-sign":
|
|
82
|
+
case "deleted":
|
|
83
|
+
return colors.deleted;
|
|
84
|
+
case "unchanged":
|
|
85
|
+
return colors.comment;
|
|
86
|
+
default:
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export {
|
|
92
|
+
CodeBlock
|
|
93
|
+
};
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -9,14 +9,16 @@ import {
|
|
|
9
9
|
GigglesError,
|
|
10
10
|
InputProvider,
|
|
11
11
|
InputRouter,
|
|
12
|
-
ThemeProvider,
|
|
13
12
|
useFocus,
|
|
14
13
|
useFocusContext,
|
|
15
14
|
useFocusState,
|
|
16
15
|
useKeybindingRegistry,
|
|
17
|
-
useKeybindings
|
|
16
|
+
useKeybindings
|
|
17
|
+
} from "./chunk-OYQZHF73.js";
|
|
18
|
+
import {
|
|
19
|
+
ThemeProvider,
|
|
18
20
|
useTheme
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-PVXJL6SX.js";
|
|
20
22
|
|
|
21
23
|
// src/core/GigglesProvider.tsx
|
|
22
24
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CodeBlock
|
|
3
|
+
} from "../chunk-TFYBLNEZ.js";
|
|
4
|
+
import {
|
|
5
|
+
useTheme
|
|
6
|
+
} from "../chunk-PVXJL6SX.js";
|
|
7
|
+
|
|
8
|
+
// src/ui/Markdown.tsx
|
|
9
|
+
import Table from "cli-table3";
|
|
10
|
+
import { marked } from "marked";
|
|
11
|
+
import { useMemo } from "react";
|
|
12
|
+
import { Box, Text } from "ink";
|
|
13
|
+
import Link from "ink-link";
|
|
14
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
function Markdown({ children }) {
|
|
16
|
+
const tokens = useMemo(() => marked.lexer(children), [children]);
|
|
17
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: tokens.map((token, idx) => /* @__PURE__ */ jsx(TokenRenderer, { token }, idx)) });
|
|
18
|
+
}
|
|
19
|
+
function TokenRenderer({ token }) {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
const theme = useTheme();
|
|
22
|
+
switch (token.type) {
|
|
23
|
+
case "heading":
|
|
24
|
+
return /* @__PURE__ */ jsx(Box, { marginTop: token.depth === 1 ? 0 : 1, children: /* @__PURE__ */ jsx(Text, { bold: true, underline: token.depth === 1, children: renderInline(token.tokens, theme) }) });
|
|
25
|
+
case "paragraph": {
|
|
26
|
+
const hasLinks = (_a = token.tokens) == null ? void 0 : _a.some(
|
|
27
|
+
(t) => {
|
|
28
|
+
var _a2;
|
|
29
|
+
return t.type === "link" || t.type === "strong" && "tokens" in t && ((_a2 = t.tokens) == null ? void 0 : _a2.some((st) => st.type === "link"));
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
if (hasLinks) {
|
|
33
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "row", flexWrap: "wrap", children: renderInline(token.tokens, theme) });
|
|
34
|
+
}
|
|
35
|
+
return /* @__PURE__ */ jsx(Text, { children: renderInline(token.tokens, theme) });
|
|
36
|
+
}
|
|
37
|
+
case "code":
|
|
38
|
+
return /* @__PURE__ */ jsx(Box, { marginY: 1, children: /* @__PURE__ */ jsx(CodeBlock, { language: token.lang || void 0, children: token.text }) });
|
|
39
|
+
case "blockquote":
|
|
40
|
+
return /* @__PURE__ */ jsxs(Box, { marginY: 1, children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Text, { color: theme.borderColor, children: "\u2502 " }),
|
|
42
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: (_b = token.tokens) == null ? void 0 : _b.map((t, idx) => /* @__PURE__ */ jsx(TokenRenderer, { token: t }, idx)) })
|
|
43
|
+
] });
|
|
44
|
+
case "list":
|
|
45
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, children: token.items.map((item, idx) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
46
|
+
/* @__PURE__ */ jsx(Text, { children: token.ordered ? `${idx + 1}. ` : "\u2022 " }),
|
|
47
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: item.tokens.map((t, i) => /* @__PURE__ */ jsx(TokenRenderer, { token: t }, i)) })
|
|
48
|
+
] }, idx)) });
|
|
49
|
+
case "table":
|
|
50
|
+
return /* @__PURE__ */ jsx(TableRenderer, { token });
|
|
51
|
+
case "hr":
|
|
52
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(40) });
|
|
53
|
+
case "space":
|
|
54
|
+
return null;
|
|
55
|
+
default:
|
|
56
|
+
if ("text" in token && typeof token.text === "string") {
|
|
57
|
+
return /* @__PURE__ */ jsx(Text, { children: token.text });
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function TableRenderer({ token }) {
|
|
63
|
+
const table = new Table({
|
|
64
|
+
head: token.header.map((cell) => renderInlineToString(cell.tokens)),
|
|
65
|
+
style: { head: [], border: [] }
|
|
66
|
+
});
|
|
67
|
+
for (const row of token.rows) {
|
|
68
|
+
table.push(row.map((cell) => renderInlineToString(cell.tokens)));
|
|
69
|
+
}
|
|
70
|
+
return /* @__PURE__ */ jsx(Text, { children: table.toString() });
|
|
71
|
+
}
|
|
72
|
+
function renderInline(tokens, theme) {
|
|
73
|
+
if (!tokens) return null;
|
|
74
|
+
return tokens.map((token, idx) => {
|
|
75
|
+
switch (token.type) {
|
|
76
|
+
case "text":
|
|
77
|
+
return /* @__PURE__ */ jsx(Text, { children: token.text }, idx);
|
|
78
|
+
case "strong":
|
|
79
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, children: renderInline(token.tokens, theme) }, idx);
|
|
80
|
+
case "em":
|
|
81
|
+
return /* @__PURE__ */ jsx(Text, { italic: true, children: renderInline(token.tokens, theme) }, idx);
|
|
82
|
+
case "codespan":
|
|
83
|
+
return /* @__PURE__ */ jsxs(Text, { color: theme.accentColor, children: [
|
|
84
|
+
"`",
|
|
85
|
+
token.text,
|
|
86
|
+
"`"
|
|
87
|
+
] }, idx);
|
|
88
|
+
case "link":
|
|
89
|
+
return /* @__PURE__ */ jsx(Link, { url: token.href, children: /* @__PURE__ */ jsx(Text, { color: theme.accentColor, children: renderInlineToString(token.tokens) }) }, idx);
|
|
90
|
+
case "image":
|
|
91
|
+
return /* @__PURE__ */ jsxs(Text, { color: theme.accentColor, children: [
|
|
92
|
+
"[Image: ",
|
|
93
|
+
token.text || token.href,
|
|
94
|
+
"]"
|
|
95
|
+
] }, idx);
|
|
96
|
+
case "br":
|
|
97
|
+
return /* @__PURE__ */ jsx(Text, { children: "\n" }, idx);
|
|
98
|
+
case "del":
|
|
99
|
+
return /* @__PURE__ */ jsx(Text, { strikethrough: true, children: renderInline(token.tokens, theme) }, idx);
|
|
100
|
+
default:
|
|
101
|
+
if ("text" in token && typeof token.text === "string") {
|
|
102
|
+
return /* @__PURE__ */ jsx(Text, { children: token.text }, idx);
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function renderInlineToString(tokens) {
|
|
109
|
+
if (!tokens) return "";
|
|
110
|
+
return tokens.map((token) => {
|
|
111
|
+
if ("text" in token && typeof token.text === "string") {
|
|
112
|
+
return token.text;
|
|
113
|
+
}
|
|
114
|
+
if ("tokens" in token && Array.isArray(token.tokens)) {
|
|
115
|
+
return renderInlineToString(token.tokens);
|
|
116
|
+
}
|
|
117
|
+
return "";
|
|
118
|
+
}).join("");
|
|
119
|
+
}
|
|
120
|
+
export {
|
|
121
|
+
Markdown
|
|
122
|
+
};
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -159,4 +159,52 @@ type ViewportProps<T> = {
|
|
|
159
159
|
};
|
|
160
160
|
declare function Viewport<T>({ items, maxVisible, showLineNumbers, gap, paginatorStyle, render }: ViewportProps<T>): react_jsx_runtime.JSX.Element;
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
type BorderStyle = 'single' | 'double' | 'round' | 'bold' | 'singleDouble' | 'doubleSingle' | 'classic' | 'arrow';
|
|
163
|
+
type ModalProps = {
|
|
164
|
+
children: React__default.ReactNode;
|
|
165
|
+
onClose: () => void;
|
|
166
|
+
title?: string;
|
|
167
|
+
borderStyle?: BorderStyle;
|
|
168
|
+
};
|
|
169
|
+
declare function Modal({ children, onClose, title, borderStyle }: ModalProps): react_jsx_runtime.JSX.Element;
|
|
170
|
+
|
|
171
|
+
type BadgeVariant = 'round' | 'arrow' | 'plain';
|
|
172
|
+
type BadgeProps = {
|
|
173
|
+
children: string;
|
|
174
|
+
color?: string;
|
|
175
|
+
background?: string;
|
|
176
|
+
variant?: BadgeVariant;
|
|
177
|
+
};
|
|
178
|
+
declare function Badge({ children, color, background, variant }: BadgeProps): react_jsx_runtime.JSX.Element;
|
|
179
|
+
|
|
180
|
+
type PanelProps = {
|
|
181
|
+
children: React__default.ReactNode;
|
|
182
|
+
title?: string;
|
|
183
|
+
width?: number;
|
|
184
|
+
borderColor?: string;
|
|
185
|
+
footer?: React__default.ReactNode;
|
|
186
|
+
};
|
|
187
|
+
declare function Panel({ children, title, width, borderColor, footer }: PanelProps): react_jsx_runtime.JSX.Element;
|
|
188
|
+
|
|
189
|
+
type TokenColors = {
|
|
190
|
+
keyword: string;
|
|
191
|
+
string: string;
|
|
192
|
+
number: string;
|
|
193
|
+
comment: string;
|
|
194
|
+
function: string;
|
|
195
|
+
operator: string;
|
|
196
|
+
punctuation: string;
|
|
197
|
+
builtin: string;
|
|
198
|
+
className: string;
|
|
199
|
+
inserted: string;
|
|
200
|
+
deleted: string;
|
|
201
|
+
};
|
|
202
|
+
type CodeBlockProps = {
|
|
203
|
+
children: string;
|
|
204
|
+
language?: string;
|
|
205
|
+
showBorder?: boolean;
|
|
206
|
+
tokenColors?: Partial<TokenColors>;
|
|
207
|
+
};
|
|
208
|
+
declare function CodeBlock({ children, language, showBorder, tokenColors }: CodeBlockProps): react_jsx_runtime.JSX.Element;
|
|
209
|
+
|
|
210
|
+
export { Autocomplete, type AutocompleteRenderProps, Badge, type BadgeProps, type BadgeVariant, CodeBlock, CommandPalette, type CommandPaletteRenderProps, Confirm, Modal, MultiSelect, type MultiSelectRenderProps, Paginator, type PaginatorStyle, Panel, type PanelProps, Select, type SelectOption, type SelectRenderProps, TextInput, type TextInputRenderProps, type TokenColors, Viewport, type ViewportRenderProps, VirtualList, type VirtualListRenderProps };
|
package/dist/ui/index.js
CHANGED
|
@@ -3,9 +3,14 @@ import {
|
|
|
3
3
|
GigglesError,
|
|
4
4
|
useFocus,
|
|
5
5
|
useKeybindingRegistry,
|
|
6
|
-
useKeybindings
|
|
6
|
+
useKeybindings
|
|
7
|
+
} from "../chunk-OYQZHF73.js";
|
|
8
|
+
import {
|
|
9
|
+
CodeBlock
|
|
10
|
+
} from "../chunk-TFYBLNEZ.js";
|
|
11
|
+
import {
|
|
7
12
|
useTheme
|
|
8
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-PVXJL6SX.js";
|
|
9
14
|
|
|
10
15
|
// src/ui/CommandPalette.tsx
|
|
11
16
|
import { useState } from "react";
|
|
@@ -728,12 +733,120 @@ function Viewport({ items, maxVisible, showLineNumbers, gap, paginatorStyle, ren
|
|
|
728
733
|
}
|
|
729
734
|
);
|
|
730
735
|
}
|
|
736
|
+
|
|
737
|
+
// src/ui/Modal.tsx
|
|
738
|
+
import { Box as Box7, Text as Text9 } from "ink";
|
|
739
|
+
import { jsx as jsx9, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
740
|
+
function ModalInner({ children, onClose, title, borderStyle = "round" }) {
|
|
741
|
+
const focus = useFocus();
|
|
742
|
+
const theme = useTheme();
|
|
743
|
+
useKeybindings(focus, {
|
|
744
|
+
escape: onClose
|
|
745
|
+
});
|
|
746
|
+
return /* @__PURE__ */ jsxs10(
|
|
747
|
+
Box7,
|
|
748
|
+
{
|
|
749
|
+
flexDirection: "column",
|
|
750
|
+
alignSelf: "flex-start",
|
|
751
|
+
borderStyle,
|
|
752
|
+
borderColor: theme.borderColor,
|
|
753
|
+
paddingX: 1,
|
|
754
|
+
children: [
|
|
755
|
+
title != null && /* @__PURE__ */ jsx9(Text9, { bold: true, children: title }),
|
|
756
|
+
children
|
|
757
|
+
]
|
|
758
|
+
}
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
function Modal({ children, onClose, title, borderStyle }) {
|
|
762
|
+
return /* @__PURE__ */ jsx9(FocusTrap, { children: /* @__PURE__ */ jsx9(ModalInner, { onClose, title, borderStyle, children }) });
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// src/ui/Badge.tsx
|
|
766
|
+
import { Text as Text10 } from "ink";
|
|
767
|
+
import { jsx as jsx10, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
768
|
+
var glyphs = {
|
|
769
|
+
round: ["\uE0B6", "\uE0B4"],
|
|
770
|
+
arrow: ["\uE0B2", "\uE0B0"],
|
|
771
|
+
plain: ["", ""]
|
|
772
|
+
};
|
|
773
|
+
function Badge({ children, color, background, variant = "round" }) {
|
|
774
|
+
const theme = useTheme();
|
|
775
|
+
const bg = background ?? theme.accentColor;
|
|
776
|
+
const fg = color ?? "#000000";
|
|
777
|
+
const [left, right] = glyphs[variant];
|
|
778
|
+
const label = variant === "plain" ? ` ${children} ` : children;
|
|
779
|
+
return /* @__PURE__ */ jsxs11(Text10, { children: [
|
|
780
|
+
left && /* @__PURE__ */ jsx10(Text10, { color: bg, children: left }),
|
|
781
|
+
/* @__PURE__ */ jsx10(Text10, { color: fg, backgroundColor: bg, bold: true, children: label }),
|
|
782
|
+
right && /* @__PURE__ */ jsx10(Text10, { color: bg, children: right })
|
|
783
|
+
] });
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// src/ui/Panel.tsx
|
|
787
|
+
import { useState as useState7 } from "react";
|
|
788
|
+
import { Box as Box8, Text as Text11, measureElement } from "ink";
|
|
789
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
790
|
+
function Panel({ children, title, width, borderColor, footer }) {
|
|
791
|
+
const theme = useTheme();
|
|
792
|
+
const color = borderColor ?? theme.borderColor;
|
|
793
|
+
const [measuredWidth, setMeasuredWidth] = useState7(width ?? 0);
|
|
794
|
+
const effectiveWidth = width ?? measuredWidth;
|
|
795
|
+
const renderTopBorder = () => {
|
|
796
|
+
if (effectiveWidth === 0) return null;
|
|
797
|
+
if (title == null) {
|
|
798
|
+
return /* @__PURE__ */ jsxs12(Text11, { color, children: [
|
|
799
|
+
"\u256D",
|
|
800
|
+
"\u2500".repeat(Math.max(0, effectiveWidth - 2)),
|
|
801
|
+
"\u256E"
|
|
802
|
+
] });
|
|
803
|
+
}
|
|
804
|
+
const maxTitleWidth = Math.max(0, effectiveWidth - 5);
|
|
805
|
+
const displayTitle = title.length > maxTitleWidth ? title.slice(0, maxTitleWidth - 1) + "\u2026" : title;
|
|
806
|
+
const titlePart = `\u256D ${displayTitle} `;
|
|
807
|
+
const totalDashes = Math.max(1, effectiveWidth - titlePart.length - 1);
|
|
808
|
+
return /* @__PURE__ */ jsxs12(Text11, { children: [
|
|
809
|
+
/* @__PURE__ */ jsx11(Text11, { color, children: "\u256D " }),
|
|
810
|
+
/* @__PURE__ */ jsx11(Text11, { color, bold: true, children: displayTitle }),
|
|
811
|
+
/* @__PURE__ */ jsxs12(Text11, { color, children: [
|
|
812
|
+
" ",
|
|
813
|
+
"\u2500".repeat(totalDashes),
|
|
814
|
+
"\u256E"
|
|
815
|
+
] })
|
|
816
|
+
] });
|
|
817
|
+
};
|
|
818
|
+
return /* @__PURE__ */ jsxs12(
|
|
819
|
+
Box8,
|
|
820
|
+
{
|
|
821
|
+
flexDirection: "column",
|
|
822
|
+
width,
|
|
823
|
+
flexGrow: width == null ? 1 : void 0,
|
|
824
|
+
ref: (node) => {
|
|
825
|
+
if (node) {
|
|
826
|
+
const { width: w } = measureElement(node);
|
|
827
|
+
if (w !== measuredWidth) setMeasuredWidth(w);
|
|
828
|
+
}
|
|
829
|
+
},
|
|
830
|
+
children: [
|
|
831
|
+
renderTopBorder(),
|
|
832
|
+
/* @__PURE__ */ jsx11(Box8, { flexDirection: "column", flexGrow: 1, borderStyle: "round", borderTop: false, borderColor: color, paddingX: 1, children: footer ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
833
|
+
/* @__PURE__ */ jsx11(Box8, { flexDirection: "column", flexGrow: 1, children }),
|
|
834
|
+
footer
|
|
835
|
+
] }) : children })
|
|
836
|
+
]
|
|
837
|
+
}
|
|
838
|
+
);
|
|
839
|
+
}
|
|
731
840
|
export {
|
|
732
841
|
Autocomplete,
|
|
842
|
+
Badge,
|
|
843
|
+
CodeBlock,
|
|
733
844
|
CommandPalette,
|
|
734
845
|
Confirm,
|
|
846
|
+
Modal,
|
|
735
847
|
MultiSelect,
|
|
736
848
|
Paginator,
|
|
849
|
+
Panel,
|
|
737
850
|
Select,
|
|
738
851
|
TextInput,
|
|
739
852
|
Viewport,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "giggles",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
"./ui": {
|
|
22
22
|
"import": "./dist/ui/index.js",
|
|
23
23
|
"types": "./dist/ui/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./markdown": {
|
|
26
|
+
"import": "./dist/markdown/index.js",
|
|
27
|
+
"types": "./dist/markdown/index.d.ts"
|
|
24
28
|
}
|
|
25
29
|
},
|
|
26
30
|
"keywords": [
|
|
@@ -37,7 +41,7 @@
|
|
|
37
41
|
"build": "tsup",
|
|
38
42
|
"build:watch": "nodemon --watch src --ext ts,tsx --exec tsup",
|
|
39
43
|
"dev": "tsx --watch playground/index.tsx",
|
|
40
|
-
"dev:docs": "pnpm build &&
|
|
44
|
+
"dev:docs": "pnpm build && pnpm --filter documentation dev",
|
|
41
45
|
"lint": "prettier --write . && eslint . --fix"
|
|
42
46
|
},
|
|
43
47
|
"files": [
|
|
@@ -50,6 +54,7 @@
|
|
|
50
54
|
"devDependencies": {
|
|
51
55
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
|
52
56
|
"@types/node": "^22.0.0",
|
|
57
|
+
"@types/prismjs": "^1.26.6",
|
|
53
58
|
"@types/react": "^19.2.13",
|
|
54
59
|
"eslint": "^9.0.0",
|
|
55
60
|
"eslint-plugin-react": "^7.32.2",
|
|
@@ -64,6 +69,10 @@
|
|
|
64
69
|
"typescript-eslint": "^8.0.0"
|
|
65
70
|
},
|
|
66
71
|
"dependencies": {
|
|
67
|
-
"
|
|
72
|
+
"cli-table3": "^0.6.5",
|
|
73
|
+
"execa": "^9.6.1",
|
|
74
|
+
"ink-link": "^5.0.0",
|
|
75
|
+
"marked": "^17.0.3",
|
|
76
|
+
"prismjs": "^1.30.0"
|
|
68
77
|
}
|
|
69
78
|
}
|