@jakubmazanec/cli 0.3.0-unstable.e1ae458 → 0.3.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/build/constants.js +8 -0
- package/build/constants.js.map +7 -0
- package/build/main.js +4 -0
- package/build/main.js.map +7 -0
- package/{dist → build}/program/Command.d.ts +1 -1
- package/build/program/Command.js +70 -0
- package/build/program/Command.js.map +7 -0
- package/{dist → build}/program/CommandAction.d.ts +1 -1
- package/build/program/CommandAction.js +2 -0
- package/build/program/CommandAction.js.map +7 -0
- package/build/program/CommandArguments.js +2 -0
- package/build/program/CommandArguments.js.map +7 -0
- package/build/program/CommandOptions.js +2 -0
- package/build/program/CommandOptions.js.map +7 -0
- package/{dist → build}/program/Program.d.ts +1 -1
- package/build/program/Program.js +191 -0
- package/build/program/Program.js.map +7 -0
- package/build/program/ProgramCreateOptions.js +2 -0
- package/build/program/ProgramCreateOptions.js.map +7 -0
- package/build/program/ProgramDetail.js +2 -0
- package/build/program/ProgramDetail.js.map +7 -0
- package/{dist → build}/program/ProgramError.d.ts +1 -1
- package/build/program/ProgramError.js +6 -0
- package/build/program/ProgramError.js.map +7 -0
- package/build/program/ProgramOptions.js +2 -0
- package/build/program/ProgramOptions.js.map +7 -0
- package/build/program/ProgramStreams.js +2 -0
- package/build/program/ProgramStreams.js.map +7 -0
- package/build/program/getProgramDetail.js +25 -0
- package/build/program/getProgramDetail.js.map +7 -0
- package/build/program.js +13 -0
- package/build/program.js.map +7 -0
- package/build/ui/ErrorDetail.js +2 -0
- package/build/ui/ErrorDetail.js.map +7 -0
- package/build/ui/Failure.js +20 -0
- package/build/ui/Failure.js.map +7 -0
- package/build/ui/Header.js +19 -0
- package/build/ui/Header.js.map +7 -0
- package/build/ui/Help.js +38 -0
- package/build/ui/Help.js.map +7 -0
- package/build/ui/Spinner.js +24 -0
- package/build/ui/Spinner.js.map +7 -0
- package/build/ui/colors.js +12 -0
- package/build/ui/colors.js.map +7 -0
- package/build/ui/form/Form.js +2 -0
- package/build/ui/form/Form.js.map +7 -0
- package/build/ui/form/FormConfig.js +2 -0
- package/build/ui/form/FormConfig.js.map +7 -0
- package/build/ui/form/FormProps.js +2 -0
- package/build/ui/form/FormProps.js.map +7 -0
- package/build/ui/form/FormResult.js +2 -0
- package/build/ui/form/FormResult.js.map +7 -0
- package/build/ui/form/FormRow.js +71 -0
- package/build/ui/form/FormRow.js.map +7 -0
- package/build/ui/form/FormRowConfig.js +2 -0
- package/build/ui/form/FormRowConfig.js.map +7 -0
- package/build/ui/form/FormRowsConfig.js +2 -0
- package/build/ui/form/FormRowsConfig.js.map +7 -0
- package/build/ui/form/FormValue.js +2 -0
- package/build/ui/form/FormValue.js.map +7 -0
- package/build/ui/form/FormValues.js +2 -0
- package/build/ui/form/FormValues.js.map +7 -0
- package/{dist → build}/ui/form/SelectInput.d.ts +1 -1
- package/build/ui/form/SelectInput.js +86 -0
- package/build/ui/form/SelectInput.js.map +7 -0
- package/build/ui/form/SelectInputItem.js +2 -0
- package/build/ui/form/SelectInputItem.js.map +7 -0
- package/build/ui/form/TextInput.js +129 -0
- package/build/ui/form/TextInput.js.map +7 -0
- package/build/ui/form/createForm.js +73 -0
- package/build/ui/form/createForm.js.map +7 -0
- package/build/ui/form.js +15 -0
- package/build/ui/form.js.map +7 -0
- package/build/ui/getErrorDetail.js +65 -0
- package/build/ui/getErrorDetail.js.map +7 -0
- package/build/ui/icons.js +13 -0
- package/build/ui/icons.js.map +7 -0
- package/build/ui/internals/Wrapper.js +48 -0
- package/build/ui/internals/Wrapper.js.map +7 -0
- package/build/ui/internals/programContext.js +4 -0
- package/build/ui/internals/programContext.js.map +7 -0
- package/build/ui/internals/rotate.js +6 -0
- package/build/ui/internals/rotate.js.map +7 -0
- package/build/ui/internals.js +5 -0
- package/build/ui/internals.js.map +7 -0
- package/build/ui/useProgram.js +20 -0
- package/build/ui/useProgram.js.map +7 -0
- package/build/ui.js +12 -0
- package/build/ui.js.map +7 -0
- package/package.json +38 -33
- package/{src → source}/program/CommandAction.ts +1 -1
- package/{src → source}/program/Program.ts +4 -4
- package/{src → source}/ui/Failure.tsx +9 -9
- package/{src → source}/ui/Header.tsx +8 -4
- package/{src → source}/ui/Help.tsx +4 -4
- package/{src → source}/ui/Spinner.tsx +1 -1
- package/{src → source}/ui/form/FormProps.ts +12 -18
- package/{src → source}/ui/form/FormRow.tsx +9 -9
- package/{src → source}/ui/form/FormValue.ts +3 -4
- package/{src → source}/ui/form/SelectInput.tsx +11 -15
- package/{src → source}/ui/form/TextInput.tsx +13 -10
- package/{src → source}/ui/getErrorDetail.ts +1 -1
- package/{src → source}/ui/internals/Wrapper.tsx +4 -4
- package/dist/constants.js +0 -8
- package/dist/constants.js.map +0 -1
- package/dist/main.js +0 -4
- package/dist/main.js.map +0 -1
- package/dist/program/Command.js +0 -63
- package/dist/program/Command.js.map +0 -1
- package/dist/program/CommandAction.js +0 -5
- package/dist/program/CommandAction.js.map +0 -1
- package/dist/program/CommandArguments.js +0 -5
- package/dist/program/CommandArguments.js.map +0 -1
- package/dist/program/CommandOptions.js +0 -5
- package/dist/program/CommandOptions.js.map +0 -1
- package/dist/program/Program.js +0 -168
- package/dist/program/Program.js.map +0 -1
- package/dist/program/ProgramCreateOptions.js +0 -5
- package/dist/program/ProgramCreateOptions.js.map +0 -1
- package/dist/program/ProgramDetail.js +0 -5
- package/dist/program/ProgramDetail.js.map +0 -1
- package/dist/program/ProgramError.js +0 -8
- package/dist/program/ProgramError.js.map +0 -1
- package/dist/program/ProgramOptions.js +0 -5
- package/dist/program/ProgramOptions.js.map +0 -1
- package/dist/program/ProgramStreams.js +0 -5
- package/dist/program/ProgramStreams.js.map +0 -1
- package/dist/program/getProgramDetail.js +0 -27
- package/dist/program/getProgramDetail.js.map +0 -1
- package/dist/program.js +0 -13
- package/dist/program.js.map +0 -1
- package/dist/ui/ErrorDetail.js +0 -5
- package/dist/ui/ErrorDetail.js.map +0 -1
- package/dist/ui/Failure.js +0 -65
- package/dist/ui/Failure.js.map +0 -1
- package/dist/ui/Header.js +0 -26
- package/dist/ui/Header.js.map +0 -1
- package/dist/ui/Help.js +0 -64
- package/dist/ui/Help.js.map +0 -1
- package/dist/ui/Spinner.js +0 -39
- package/dist/ui/Spinner.js.map +0 -1
- package/dist/ui/colors.js +0 -12
- package/dist/ui/colors.js.map +0 -1
- package/dist/ui/form/Form.js +0 -5
- package/dist/ui/form/Form.js.map +0 -1
- package/dist/ui/form/FormConfig.js +0 -5
- package/dist/ui/form/FormConfig.js.map +0 -1
- package/dist/ui/form/FormProps.js +0 -5
- package/dist/ui/form/FormProps.js.map +0 -1
- package/dist/ui/form/FormResult.js +0 -5
- package/dist/ui/form/FormResult.js.map +0 -1
- package/dist/ui/form/FormRow.js +0 -59
- package/dist/ui/form/FormRow.js.map +0 -1
- package/dist/ui/form/FormRowConfig.js +0 -5
- package/dist/ui/form/FormRowConfig.js.map +0 -1
- package/dist/ui/form/FormRowsConfig.js +0 -5
- package/dist/ui/form/FormRowsConfig.js.map +0 -1
- package/dist/ui/form/FormValue.js +0 -5
- package/dist/ui/form/FormValue.js.map +0 -1
- package/dist/ui/form/FormValues.js +0 -5
- package/dist/ui/form/FormValues.js.map +0 -1
- package/dist/ui/form/SelectInput.js +0 -113
- package/dist/ui/form/SelectInput.js.map +0 -1
- package/dist/ui/form/SelectInputItem.js +0 -5
- package/dist/ui/form/SelectInputItem.js.map +0 -1
- package/dist/ui/form/TextInput.js +0 -152
- package/dist/ui/form/TextInput.js.map +0 -1
- package/dist/ui/form/createForm.js +0 -72
- package/dist/ui/form/createForm.js.map +0 -1
- package/dist/ui/form.js +0 -15
- package/dist/ui/form.js.map +0 -1
- package/dist/ui/getErrorDetail.js +0 -72
- package/dist/ui/getErrorDetail.js.map +0 -1
- package/dist/ui/icons.js +0 -13
- package/dist/ui/icons.js.map +0 -1
- package/dist/ui/internals/Wrapper.js +0 -66
- package/dist/ui/internals/Wrapper.js.map +0 -1
- package/dist/ui/internals/programContext.js +0 -6
- package/dist/ui/internals/programContext.js.map +0 -1
- package/dist/ui/internals/rotate.js +0 -17
- package/dist/ui/internals/rotate.js.map +0 -1
- package/dist/ui/internals.js +0 -5
- package/dist/ui/internals.js.map +0 -1
- package/dist/ui/useProgram.js +0 -25
- package/dist/ui/useProgram.js.map +0 -1
- package/dist/ui.js +0 -12
- package/dist/ui.js.map +0 -1
- package/{dist → build}/constants.d.ts +0 -0
- package/{dist → build}/main.d.ts +0 -0
- package/{dist → build}/program/CommandArguments.d.ts +0 -0
- package/{dist → build}/program/CommandOptions.d.ts +0 -0
- package/{dist → build}/program/ProgramCreateOptions.d.ts +0 -0
- package/{dist → build}/program/ProgramDetail.d.ts +0 -0
- package/{dist → build}/program/ProgramOptions.d.ts +0 -0
- package/{dist → build}/program/ProgramStreams.d.ts +0 -0
- package/{dist → build}/program/getProgramDetail.d.ts +0 -0
- package/{dist → build}/program.d.ts +0 -0
- package/{dist → build}/ui/ErrorDetail.d.ts +0 -0
- package/{dist → build}/ui/Failure.d.ts +0 -0
- package/{dist → build}/ui/Header.d.ts +0 -0
- package/{dist → build}/ui/Help.d.ts +0 -0
- package/{dist → build}/ui/Spinner.d.ts +0 -0
- package/{dist → build}/ui/colors.d.ts +0 -0
- package/{dist → build}/ui/form/Form.d.ts +0 -0
- package/{dist → build}/ui/form/FormConfig.d.ts +0 -0
- package/{dist → build}/ui/form/FormProps.d.ts +0 -0
- package/{dist → build}/ui/form/FormResult.d.ts +0 -0
- package/{dist → build}/ui/form/FormRow.d.ts +0 -0
- package/{dist → build}/ui/form/FormRowConfig.d.ts +0 -0
- package/{dist → build}/ui/form/FormRowsConfig.d.ts +0 -0
- package/{dist → build}/ui/form/FormValue.d.ts +0 -0
- package/{dist → build}/ui/form/FormValues.d.ts +0 -0
- package/{dist → build}/ui/form/SelectInputItem.d.ts +0 -0
- package/{dist → build}/ui/form/TextInput.d.ts +0 -0
- package/{dist → build}/ui/form/createForm.d.ts +0 -0
- package/{dist → build}/ui/form.d.ts +3 -3
- package/{dist → build}/ui/getErrorDetail.d.ts +0 -0
- package/{dist → build}/ui/icons.d.ts +0 -0
- package/{dist → build}/ui/internals/Wrapper.d.ts +0 -0
- package/{dist → build}/ui/internals/programContext.d.ts +0 -0
- package/{dist → build}/ui/internals/rotate.d.ts +0 -0
- package/{dist → build}/ui/internals.d.ts +0 -0
- package/{dist → build}/ui/useProgram.d.ts +0 -0
- package/{dist → build}/ui.d.ts +3 -3
- package/{src → source}/constants.ts +0 -0
- package/{src → source}/main.ts +0 -0
- package/{src → source}/program/Command.ts +2 -2
- package/{src → source}/program/CommandArguments.ts +0 -0
- package/{src → source}/program/CommandOptions.ts +0 -0
- package/{src → source}/program/ProgramCreateOptions.ts +0 -0
- package/{src → source}/program/ProgramDetail.ts +0 -0
- package/{src → source}/program/ProgramError.ts +0 -0
- package/{src → source}/program/ProgramOptions.ts +0 -0
- package/{src → source}/program/ProgramStreams.ts +0 -0
- package/{src → source}/program/getProgramDetail.ts +0 -0
- package/{src → source}/program.ts +0 -0
- package/{src → source}/ui/ErrorDetail.ts +0 -0
- package/{src → source}/ui/colors.ts +0 -0
- package/{src → source}/ui/form/Form.ts +0 -0
- package/{src → source}/ui/form/FormConfig.ts +0 -0
- package/{src → source}/ui/form/FormResult.ts +0 -0
- package/{src → source}/ui/form/FormRowConfig.ts +0 -0
- package/{src → source}/ui/form/FormRowsConfig.ts +0 -0
- package/{src → source}/ui/form/FormValues.ts +0 -0
- package/{src → source}/ui/form/SelectInputItem.ts +0 -0
- package/{src → source}/ui/form/createForm.tsx +0 -0
- package/{src → source}/ui/form.ts +3 -3
- package/{src → source}/ui/icons.ts +0 -0
- package/{src → source}/ui/internals/programContext.ts +0 -0
- package/{src → source}/ui/internals/rotate.ts +0 -0
- package/{src → source}/ui/internals.ts +0 -0
- package/{src → source}/ui/useProgram.ts +0 -0
- package/{src → source}/ui.ts +3 -3
package/build/ui/Help.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { Box, Text } from "ink";
|
|
5
|
+
import * as colors from "./colors.js";
|
|
6
|
+
import { Header } from "./Header.js";
|
|
7
|
+
import * as icons from "./icons.js";
|
|
8
|
+
export function Help({ program, ...boxProps }) {
|
|
9
|
+
return /* @__PURE__ */ jsxs(Box, { ...boxProps, flexDirection: "column", children: [
|
|
10
|
+
/* @__PURE__ */ jsx(Text, { children: `${chalk[colors.notice](program.displayName ?? program.name ?? "?")} ${chalk[colors.muted](program.version ?? "?")}` }),
|
|
11
|
+
/* @__PURE__ */ jsx(Text, { color: colors.body, children: program.description }),
|
|
12
|
+
program.commands.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13
|
+
/* @__PURE__ */ jsx(Header, { icon: icons.info, marginTop: 1, children: /* @__PURE__ */ jsx(Text, { color: colors.highlighted, children: "Usage" }) }),
|
|
14
|
+
program.commands.map((command) => {
|
|
15
|
+
let line = `${chalk[colors.muted](program.bin ?? "?")} ${command.name}`;
|
|
16
|
+
if (command.parameters) {
|
|
17
|
+
if (command.parameters.some((parameterConfig) => !!parameterConfig.required)) {
|
|
18
|
+
line += ` ${chalk[colors.muted]("<parameters>")}`;
|
|
19
|
+
} else {
|
|
20
|
+
line += ` ${chalk[colors.muted]("[<parameters>]")}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (command.options) {
|
|
24
|
+
if (Object.entries(command.options).some(([, optionConfig]) => !!optionConfig.required)) {
|
|
25
|
+
line += ` ${chalk[colors.muted]("<options>")}`;
|
|
26
|
+
} else {
|
|
27
|
+
line += ` ${chalk[colors.muted]("[<options>]")}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (command.description) {
|
|
31
|
+
line += ` ${command.description}`;
|
|
32
|
+
}
|
|
33
|
+
return /* @__PURE__ */ jsx(Box, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx(Text, { children: line }) }, command.name);
|
|
34
|
+
})
|
|
35
|
+
] }) : null
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=Help.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../source/ui/Help.tsx"],
|
|
4
|
+
"sourcesContent": ["import chalk from 'chalk';\nimport {Box, type BoxProps, Text} from 'ink';\n\nimport {type Program} from '../program.js';\nimport * as colors from './colors.js';\nimport {Header} from './Header.js';\nimport * as icons from './icons.js';\n\n/**\n * {@link Help} component props.\n */\nexport type HelpProps = BoxProps & {\n /** {@link Program} instance. */\n program: Program;\n};\n\n/**\n * A component that renders help information.\n */\nexport function Help({program, ...boxProps}: HelpProps) {\n return (\n <Box {...boxProps} flexDirection=\"column\">\n <Text>{`${chalk[colors.notice](program.displayName ?? program.name ?? '?')} ${chalk[\n colors.muted\n ](program.version ?? '?')}`}</Text>\n <Text color={colors.body}>{program.description}</Text>\n\n {program.commands.length ?\n <>\n <Header icon={icons.info} marginTop={1}>\n <Text color={colors.highlighted}>Usage</Text>\n </Header>\n {program.commands.map((command) => {\n let line = `${chalk[colors.muted](program.bin ?? '?')} ${command.name}`;\n\n if (command.parameters) {\n if (command.parameters.some((parameterConfig) => !!parameterConfig.required)) {\n line += ` ${chalk[colors.muted]('<parameters>')}`;\n } else {\n line += ` ${chalk[colors.muted]('[<parameters>]')}`;\n }\n }\n\n if (command.options) {\n if (\n Object.entries(command.options).some(([, optionConfig]) => !!optionConfig.required)\n ) {\n line += ` ${chalk[colors.muted]('<options>')}`;\n } else {\n line += ` ${chalk[colors.muted]('[<options>]')}`;\n }\n }\n\n if (command.description) {\n line += ` ${command.description}`;\n }\n\n return (\n <Box key={command.name} marginLeft={2} flexDirection=\"column\">\n <Text>{line}</Text>\n </Box>\n );\n })}\n </>\n : null}\n </Box>\n );\n}\n"],
|
|
5
|
+
"mappings": ";AAsBM,SAME,UANF,KAME,YANF;AAtBN,OAAO,WAAW;AAClB,SAAQ,KAAoB,YAAW;AAGvC,YAAY,YAAY;AACxB,SAAQ,cAAa;AACrB,YAAY,WAAW;AAahB,gBAAS,KAAK,EAAC,SAAS,GAAG,SAAQ,GAAc;AACtD,SACE,qBAAC,OAAK,GAAG,UAAU,eAAc,UAC/B;AAAA,wBAAC,QAAM,aAAG,MAAM,OAAO,MAAM,EAAE,QAAQ,eAAe,QAAQ,QAAQ,GAAG,CAAC,IAAI,MAC5E,OAAO,KACT,EAAE,QAAQ,WAAW,GAAG,CAAC,IAAG;AAAA,IAC5B,oBAAC,QAAK,OAAO,OAAO,MAAO,kBAAQ,aAAY;AAAA,IAE9C,QAAQ,SAAS,SAChB,iCACE;AAAA,0BAAC,UAAO,MAAM,MAAM,MAAM,WAAW,GACnC,8BAAC,QAAK,OAAO,OAAO,aAAa,mBAAK,GACxC;AAAA,MACC,QAAQ,SAAS,IAAI,CAAC,YAAY;AACjC,YAAI,OAAO,GAAG,MAAM,OAAO,KAAK,EAAE,QAAQ,OAAO,GAAG,CAAC,IAAI,QAAQ,IAAI;AAErE,YAAI,QAAQ,YAAY;AACtB,cAAI,QAAQ,WAAW,KAAK,CAAC,oBAAoB,CAAC,CAAC,gBAAgB,QAAQ,GAAG;AAC5E,oBAAQ,IAAI,MAAM,OAAO,KAAK,EAAE,cAAc,CAAC;AAAA,UACjD,OAAO;AACL,oBAAQ,IAAI,MAAM,OAAO,KAAK,EAAE,gBAAgB,CAAC;AAAA,UACnD;AAAA,QACF;AAEA,YAAI,QAAQ,SAAS;AACnB,cACE,OAAO,QAAQ,QAAQ,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,YAAY,MAAM,CAAC,CAAC,aAAa,QAAQ,GAClF;AACA,oBAAQ,IAAI,MAAM,OAAO,KAAK,EAAE,WAAW,CAAC;AAAA,UAC9C,OAAO;AACL,oBAAQ,IAAI,MAAM,OAAO,KAAK,EAAE,aAAa,CAAC;AAAA,UAChD;AAAA,QACF;AAEA,YAAI,QAAQ,aAAa;AACvB,kBAAQ,IAAI,QAAQ,WAAW;AAAA,QACjC;AAEA,eACE,oBAAC,OAAuB,YAAY,GAAG,eAAc,UACnD,8BAAC,QAAM,gBAAK,KADJ,QAAQ,IAElB;AAAA,MAEJ,CAAC;AAAA,OACH,IACA;AAAA,KACJ;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
const SPINNER = {
|
|
6
|
+
interval: 80,
|
|
7
|
+
frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"]
|
|
8
|
+
};
|
|
9
|
+
export function Spinner() {
|
|
10
|
+
let [frame, setFrame] = useState(0);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
let timer = setInterval(() => {
|
|
13
|
+
setFrame((previousFrame) => {
|
|
14
|
+
let isLastFrame = previousFrame === SPINNER.frames.length - 1;
|
|
15
|
+
return isLastFrame ? 0 : previousFrame + 1;
|
|
16
|
+
});
|
|
17
|
+
}, SPINNER.interval);
|
|
18
|
+
return () => {
|
|
19
|
+
clearInterval(timer);
|
|
20
|
+
};
|
|
21
|
+
}, []);
|
|
22
|
+
return /* @__PURE__ */ jsx(Text, { children: SPINNER.frames[frame] });
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=Spinner.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../source/ui/Spinner.tsx"],
|
|
4
|
+
"sourcesContent": ["import {Text} from 'ink';\nimport {useEffect, useState} from 'react';\n\nconst SPINNER = {\n interval: 80,\n frames: ['\u280B', '\u2819', '\u2839', '\u2838', '\u283C', '\u2834', '\u2826', '\u2827', '\u2807', '\u280F'],\n};\n\n/**\n * Spinner component.\n */\nexport function Spinner() {\n let [frame, setFrame] = useState(0);\n\n useEffect(() => {\n let timer = setInterval(() => {\n setFrame((previousFrame) => {\n let isLastFrame = previousFrame === SPINNER.frames.length - 1;\n\n return isLastFrame ? 0 : previousFrame + 1;\n });\n }, SPINNER.interval);\n\n return () => {\n clearInterval(timer);\n };\n }, []);\n\n return <Text>{SPINNER.frames[frame]}</Text>;\n}\n"],
|
|
5
|
+
"mappings": ";AA4BS;AA5BT,SAAQ,YAAW;AACnB,SAAQ,WAAW,gBAAe;AAElC,MAAM,UAAU;AAAA,EACd,UAAU;AAAA,EACV,QAAQ,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAC3D;AAKO,gBAAS,UAAU;AACxB,MAAI,CAAC,OAAO,QAAQ,IAAI,SAAS,CAAC;AAElC,YAAU,MAAM;AACd,QAAI,QAAQ,YAAY,MAAM;AAC5B,eAAS,CAAC,kBAAkB;AAC1B,YAAI,cAAc,kBAAkB,QAAQ,OAAO,SAAS;AAE5D,eAAO,cAAc,IAAI,gBAAgB;AAAA,MAC3C,CAAC;AAAA,IACH,GAAG,QAAQ,QAAQ;AAEnB,WAAO,MAAM;AACX,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,oBAAC,QAAM,kBAAQ,OAAO,KAAK,GAAE;AACtC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
export const body = "white";
|
|
3
|
+
export const highlighted = "whiteBright";
|
|
4
|
+
export const muted = "gray";
|
|
5
|
+
export const unselected = "gray";
|
|
6
|
+
export const selected = "greenBright";
|
|
7
|
+
export const notice = "magenta";
|
|
8
|
+
export const info = "cyan";
|
|
9
|
+
export const success = "green";
|
|
10
|
+
export const warning = "yellow";
|
|
11
|
+
export const failure = "red";
|
|
12
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../source/ui/colors.ts"],
|
|
4
|
+
"sourcesContent": ["export const body = 'white';\nexport const highlighted = 'whiteBright';\nexport const muted = 'gray';\n\nexport const unselected = 'gray';\nexport const selected = 'greenBright';\n\nexport const notice = 'magenta';\n\nexport const info = 'cyan';\nexport const success = 'green';\nexport const warning = 'yellow';\nexport const failure = 'red';\n"],
|
|
5
|
+
"mappings": ";AAAO,aAAM,OAAO;AACb,aAAM,cAAc;AACpB,aAAM,QAAQ;AAEd,aAAM,aAAa;AACnB,aAAM,WAAW;AAEjB,aAAM,SAAS;AAEf,aAAM,OAAO;AACb,aAAM,UAAU;AAChB,aAAM,UAAU;AAChB,aAAM,UAAU;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback } from "react";
|
|
4
|
+
import { SelectInput } from "./SelectInput.js";
|
|
5
|
+
import { TextInput } from "./TextInput.js";
|
|
6
|
+
export function FormRow({
|
|
7
|
+
rowName,
|
|
8
|
+
config,
|
|
9
|
+
rows,
|
|
10
|
+
value,
|
|
11
|
+
focus,
|
|
12
|
+
isComplete,
|
|
13
|
+
onChange,
|
|
14
|
+
onComplete,
|
|
15
|
+
...boxProps
|
|
16
|
+
}) {
|
|
17
|
+
let handleChange = useCallback(
|
|
18
|
+
(newValue) => {
|
|
19
|
+
onChange(newValue, rowName);
|
|
20
|
+
},
|
|
21
|
+
[rowName, onChange]
|
|
22
|
+
);
|
|
23
|
+
let handleFinish = useCallback(
|
|
24
|
+
(newValue) => {
|
|
25
|
+
onComplete(newValue, rowName);
|
|
26
|
+
},
|
|
27
|
+
[rowName, onComplete]
|
|
28
|
+
);
|
|
29
|
+
let handleSelectFinish = useCallback(
|
|
30
|
+
(item) => {
|
|
31
|
+
onComplete(item.value, rowName);
|
|
32
|
+
},
|
|
33
|
+
[rowName, onComplete]
|
|
34
|
+
);
|
|
35
|
+
switch (config.type) {
|
|
36
|
+
case "text": {
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
TextInput,
|
|
39
|
+
{
|
|
40
|
+
label: config.label ?? "",
|
|
41
|
+
validate: config.validate,
|
|
42
|
+
value,
|
|
43
|
+
focus,
|
|
44
|
+
isComplete,
|
|
45
|
+
onChange: handleChange,
|
|
46
|
+
onSubmit: handleFinish,
|
|
47
|
+
...boxProps
|
|
48
|
+
},
|
|
49
|
+
String(rowName)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
case "select": {
|
|
53
|
+
return /* @__PURE__ */ jsx(
|
|
54
|
+
SelectInput,
|
|
55
|
+
{
|
|
56
|
+
label: config.label ?? "",
|
|
57
|
+
items: rows ? rows[rowName].choices : [],
|
|
58
|
+
focus,
|
|
59
|
+
isComplete,
|
|
60
|
+
onSelect: handleSelectFinish,
|
|
61
|
+
...boxProps
|
|
62
|
+
},
|
|
63
|
+
String(rowName)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
default: {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=FormRow.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../source/ui/form/FormRow.tsx"],
|
|
4
|
+
"sourcesContent": ["import {type BoxProps} from 'ink';\nimport {useCallback} from 'react';\n\nimport {type FormConfig} from './FormConfig.js';\nimport {type FormProps} from './FormProps.js';\nimport {type FormRowConfig} from './FormRowConfig.js';\nimport {SelectInput} from './SelectInput.js';\nimport {TextInput} from './TextInput.js';\n\n/**\n * Form row component props.\n */\ntype FormRowProps<C extends FormConfig> = BoxProps & {\n /** Form row configuration. */\n config: FormRowConfig;\n\n // TODO: Should all rows props be passed to each row?\n /** Props of all form rows. */\n rows: FormProps<C>['rows'] | null;\n\n /** Row name. */\n rowName: keyof C['rows'];\n\n /** Value. */\n value: unknown;\n\n /** Should component listen to Listen to user's input? Useful in case there are multiple input components at the same time and input must be \"routed\" to a specific component. */\n focus: boolean;\n\n /** Handler function that is called when value changes. */\n onChange: (value: unknown, inputName: keyof C['rows']) => void;\n\n /** Handler function that is called when the value is accepted. */\n onComplete: (value: unknown, inputName: keyof C['rows']) => void;\n\n /** Indicates whether value has been accepted. Component in the row then doesn't accept more input. */\n isComplete: boolean;\n};\n\n/**\n * Form row component.\n */\nexport function FormRow<C extends FormConfig>({\n rowName,\n config,\n rows,\n value,\n focus,\n isComplete,\n onChange,\n onComplete,\n ...boxProps\n}: FormRowProps<C>) {\n // TODO: Each input component handles values and events differently; the APIs should be adjusted.\n let handleChange = useCallback(\n (newValue: unknown) => {\n onChange(newValue, rowName);\n },\n [rowName, onChange],\n );\n\n let handleFinish = useCallback(\n (newValue: unknown) => {\n onComplete(newValue, rowName);\n },\n [rowName, onComplete],\n );\n\n let handleSelectFinish = useCallback(\n (item: {value: unknown}) => {\n onComplete(item.value, rowName);\n },\n [rowName, onComplete],\n );\n\n switch (config.type) {\n case 'text': {\n return (\n <TextInput\n key={String(rowName)}\n label={config.label ?? ''}\n validate={config.validate}\n value={value as string}\n focus={focus}\n isComplete={isComplete}\n onChange={handleChange}\n onSubmit={handleFinish}\n {...boxProps}\n />\n );\n }\n case 'select': {\n return (\n <SelectInput\n key={String(rowName)}\n label={config.label ?? ''}\n items={\n rows ?\n (\n (\n rows as {\n [key: string]: unknown;\n }\n )[rowName as string] as {choices: Array<{value: string; label: string}>}\n ).choices\n : []\n }\n focus={focus}\n isComplete={isComplete}\n onSelect={handleSelectFinish}\n {...boxProps}\n />\n );\n }\n default: {\n return null;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";AA8EQ;AA7ER,SAAQ,mBAAkB;AAK1B,SAAQ,mBAAkB;AAC1B,SAAQ,iBAAgB;AAmCjB,gBAAS,QAA8B;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAElB,MAAI,eAAe;AAAA,IACjB,CAAC,aAAsB;AACrB,eAAS,UAAU,OAAO;AAAA,IAC5B;AAAA,IACA,CAAC,SAAS,QAAQ;AAAA,EACpB;AAEA,MAAI,eAAe;AAAA,IACjB,CAAC,aAAsB;AACrB,iBAAW,UAAU,OAAO;AAAA,IAC9B;AAAA,IACA,CAAC,SAAS,UAAU;AAAA,EACtB;AAEA,MAAI,qBAAqB;AAAA,IACvB,CAAC,SAA2B;AAC1B,iBAAW,KAAK,OAAO,OAAO;AAAA,IAChC;AAAA,IACA,CAAC,SAAS,UAAU;AAAA,EACtB;AAEA,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK,QAAQ;AACX,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,OAAO,SAAS;AAAA,UACvB,UAAU,OAAO;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,UACV,UAAU;AAAA,UACT,GAAG;AAAA;AAAA,QARC,OAAO,OAAO;AAAA,MASrB;AAAA,IAEJ;AAAA,IACA,KAAK,UAAU;AACb,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,OAAO,SAAS;AAAA,UACvB,OACE,OAGM,KAGA,OAAiB,EACnB,UACF,CAAC;AAAA,UAEL;AAAA,UACA;AAAA,UACA,UAAU;AAAA,UACT,GAAG;AAAA;AAAA,QAhBC,OAAO,OAAO;AAAA,MAiBrB;AAAA,IAEJ;AAAA,IACA,SAAS;AACP,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Box, Text, useInput } from "ink";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
import { useEffect, useRef, useState } from "react";
|
|
6
|
+
import * as colors from "../colors.js";
|
|
7
|
+
import * as icons from "../icons.js";
|
|
8
|
+
import { rotate } from "../internals.js";
|
|
9
|
+
export function SelectInput({
|
|
10
|
+
label,
|
|
11
|
+
items,
|
|
12
|
+
focus = true,
|
|
13
|
+
initialIndex = 0,
|
|
14
|
+
limit: userDefinedLimit,
|
|
15
|
+
onSelect,
|
|
16
|
+
onHighlight,
|
|
17
|
+
isComplete,
|
|
18
|
+
...boxProps
|
|
19
|
+
}) {
|
|
20
|
+
let [rotatedIndex, setRotatedIndex] = useState(0);
|
|
21
|
+
let [selectedIndex, setSelectedIndex] = useState(initialIndex);
|
|
22
|
+
let hasLimit = typeof userDefinedLimit === "number" && items.length > userDefinedLimit;
|
|
23
|
+
let limit = hasLimit ? Math.min(userDefinedLimit, items.length) : items.length;
|
|
24
|
+
let previousItems = useRef(items);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!_.isEqual(
|
|
27
|
+
previousItems.current.map((item) => item.value),
|
|
28
|
+
items.map((item) => item.value)
|
|
29
|
+
)) {
|
|
30
|
+
setRotatedIndex(0);
|
|
31
|
+
setSelectedIndex(0);
|
|
32
|
+
}
|
|
33
|
+
previousItems.current = items;
|
|
34
|
+
}, [items]);
|
|
35
|
+
useInput(
|
|
36
|
+
(input, key) => {
|
|
37
|
+
if (input === "k" || key.upArrow) {
|
|
38
|
+
let lastIndex = (hasLimit ? limit : items.length) - 1;
|
|
39
|
+
let isAtFirstIndex = selectedIndex === 0;
|
|
40
|
+
let nextIndex = hasLimit ? selectedIndex : lastIndex;
|
|
41
|
+
let nextRotatedIndex = isAtFirstIndex ? rotatedIndex + 1 : rotatedIndex;
|
|
42
|
+
let nextSelectedIndex = isAtFirstIndex ? nextIndex : selectedIndex - 1;
|
|
43
|
+
setRotatedIndex(nextRotatedIndex);
|
|
44
|
+
setSelectedIndex(nextSelectedIndex);
|
|
45
|
+
let slicedItems = hasLimit ? rotate(items, nextRotatedIndex).slice(0, limit) : items;
|
|
46
|
+
if (typeof onHighlight === "function") {
|
|
47
|
+
onHighlight(slicedItems[nextSelectedIndex]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (input === "j" || key.downArrow) {
|
|
51
|
+
let isAtLastIndex = selectedIndex === (hasLimit ? limit : items.length) - 1;
|
|
52
|
+
let nextIndex = hasLimit ? selectedIndex : 0;
|
|
53
|
+
let nextRotatedIndex = isAtLastIndex ? rotatedIndex - 1 : rotatedIndex;
|
|
54
|
+
let nextSelectedIndex = isAtLastIndex ? nextIndex : selectedIndex + 1;
|
|
55
|
+
setRotatedIndex(nextRotatedIndex);
|
|
56
|
+
setSelectedIndex(nextSelectedIndex);
|
|
57
|
+
let slicedItems = hasLimit ? rotate(items, nextRotatedIndex).slice(0, limit) : items;
|
|
58
|
+
if (typeof onHighlight === "function") {
|
|
59
|
+
onHighlight(slicedItems[nextSelectedIndex]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (key.return) {
|
|
63
|
+
let slicedItems = hasLimit ? rotate(items, rotatedIndex).slice(0, limit) : items;
|
|
64
|
+
if (typeof onSelect === "function") {
|
|
65
|
+
onSelect(slicedItems[selectedIndex]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{ isActive: focus }
|
|
70
|
+
);
|
|
71
|
+
let visibleItems = hasLimit ? rotate(items, rotatedIndex).slice(0, limit) : items;
|
|
72
|
+
return /* @__PURE__ */ jsxs(Box, { ...boxProps, children: [
|
|
73
|
+
/* @__PURE__ */ jsx(Box, { marginRight: 1, children: /* @__PURE__ */ jsx(Text, { children: isComplete ? icons.success : icons.question }) }),
|
|
74
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
75
|
+
/* @__PURE__ */ jsx(Box, { marginRight: 1, children: /* @__PURE__ */ jsx(Text, { color: colors.highlighted, children: label }) }),
|
|
76
|
+
isComplete ? /* @__PURE__ */ jsx(Text, { color: colors.body, children: items[selectedIndex]?.label ?? String(items[selectedIndex]?.value) }) : /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: visibleItems.map((item, index) => {
|
|
77
|
+
let isSelected = index === selectedIndex;
|
|
78
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
79
|
+
/* @__PURE__ */ jsx(Box, { marginRight: 1, children: isSelected ? /* @__PURE__ */ jsx(Text, { color: colors.selected, children: icons.selectedCircle }) : /* @__PURE__ */ jsx(Text, { color: colors.unselected, children: icons.unselectedCircle }) }),
|
|
80
|
+
/* @__PURE__ */ jsx(Text, { color: isSelected ? colors.highlighted : colors.muted, children: item.label })
|
|
81
|
+
] }, item.value);
|
|
82
|
+
}) })
|
|
83
|
+
] })
|
|
84
|
+
] });
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=SelectInput.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../source/ui/form/SelectInput.tsx"],
|
|
4
|
+
"sourcesContent": ["import {Box, type BoxProps, type Key, Text, useInput} from 'ink';\nimport _ from 'lodash';\nimport {useEffect, useRef, useState} from 'react';\n\nimport * as colors from '../colors.js';\nimport * as icons from '../icons.js';\nimport {rotate} from '../internals.js';\nimport {type SelectInputItem} from './SelectInputItem.js';\n\n/**\n * {@linkcode SelectInput} component props.\n */\ntype SelectInputProps = BoxProps & {\n /** Text to display as a label. */\n label: string;\n\n /** Items to display in a list. */\n items: SelectInputItem[];\n\n /** Should component listen to user's input? Useful in case there are multiple input components at the same time and input must be handled only by a specific component. */\n focus?: boolean | undefined;\n\n /** Index of initially selected item. */\n initialIndex?: number | undefined;\n\n /** Number of items to display. */\n limit?: number | undefined;\n\n /** Handler function that is called when item is selected. */\n onSelect?: ((item: SelectInputItem) => void) | undefined;\n\n /** Handler function that is called when item is highlighted. */\n onHighlight?: ((item: SelectInputItem) => void) | undefined;\n\n /** Indicates whether value has been accepted. Component then doesn't accept more input. */\n isComplete?: boolean | undefined;\n};\n\n/**\n * Select input component.\n */\nexport function SelectInput({\n label,\n items,\n focus = true,\n initialIndex = 0,\n limit: userDefinedLimit,\n onSelect,\n onHighlight,\n isComplete,\n ...boxProps\n}: SelectInputProps): JSX.Element {\n let [rotatedIndex, setRotatedIndex] = useState(0);\n let [selectedIndex, setSelectedIndex] = useState(initialIndex);\n let hasLimit = typeof userDefinedLimit === 'number' && items.length > userDefinedLimit;\n let limit = hasLimit ? Math.min(userDefinedLimit as number, items.length) : items.length;\n let previousItems = useRef<SelectInputItem[]>(items);\n\n useEffect(() => {\n if (\n !_.isEqual(\n previousItems.current.map((item) => item.value),\n items.map((item) => item.value),\n )\n ) {\n setRotatedIndex(0);\n setSelectedIndex(0);\n }\n\n previousItems.current = items;\n }, [items]);\n\n useInput(\n (input: string, key: Key) => {\n if (input === 'k' || key.upArrow) {\n let lastIndex = (hasLimit ? limit : items.length) - 1;\n let isAtFirstIndex = selectedIndex === 0;\n let nextIndex = hasLimit ? selectedIndex : lastIndex;\n let nextRotatedIndex = isAtFirstIndex ? rotatedIndex + 1 : rotatedIndex;\n let nextSelectedIndex = isAtFirstIndex ? nextIndex : selectedIndex - 1;\n\n setRotatedIndex(nextRotatedIndex);\n setSelectedIndex(nextSelectedIndex);\n\n let slicedItems = hasLimit ? rotate(items, nextRotatedIndex).slice(0, limit) : items;\n\n if (typeof onHighlight === 'function') {\n onHighlight(slicedItems[nextSelectedIndex] as SelectInputItem);\n }\n }\n\n if (input === 'j' || key.downArrow) {\n let isAtLastIndex = selectedIndex === (hasLimit ? limit : items.length) - 1;\n let nextIndex = hasLimit ? selectedIndex : 0;\n let nextRotatedIndex = isAtLastIndex ? rotatedIndex - 1 : rotatedIndex;\n let nextSelectedIndex = isAtLastIndex ? nextIndex : selectedIndex + 1;\n\n setRotatedIndex(nextRotatedIndex);\n setSelectedIndex(nextSelectedIndex);\n\n let slicedItems = hasLimit ? rotate(items, nextRotatedIndex).slice(0, limit) : items;\n\n if (typeof onHighlight === 'function') {\n onHighlight(slicedItems[nextSelectedIndex] as SelectInputItem);\n }\n }\n\n if (key.return) {\n let slicedItems = hasLimit ? rotate(items, rotatedIndex).slice(0, limit) : items;\n\n if (typeof onSelect === 'function') {\n onSelect(slicedItems[selectedIndex] as SelectInputItem);\n }\n }\n },\n {isActive: focus},\n );\n\n let visibleItems: SelectInputItem[] =\n hasLimit ? rotate(items, rotatedIndex).slice(0, limit) : items;\n\n return (\n <Box {...boxProps}>\n <Box marginRight={1}>\n <Text>{isComplete ? icons.success : icons.question}</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n <Box marginRight={1}>\n <Text color={colors.highlighted}>{label}</Text>\n </Box>\n {isComplete ?\n <Text color={colors.body}>\n {items[selectedIndex]?.label ?? String(items[selectedIndex]?.value)}\n </Text>\n : <Box flexDirection=\"column\">\n {visibleItems.map((item, index) => {\n let isSelected = index === selectedIndex;\n\n return (\n <Box key={item.value}>\n <Box marginRight={1}>\n {isSelected ?\n <Text color={colors.selected}>{icons.selectedCircle}</Text>\n : <Text color={colors.unselected}>{icons.unselectedCircle}</Text>}\n </Box>\n <Text color={isSelected ? colors.highlighted : colors.muted}>{item.label}</Text>\n </Box>\n );\n })}\n </Box>\n }\n </Box>\n </Box>\n );\n}\n"],
|
|
5
|
+
"mappings": ";AA4HQ,cAgBQ,YAhBR;AA5HR,SAAQ,KAA8B,MAAM,gBAAe;AAC3D,OAAO,OAAO;AACd,SAAQ,WAAW,QAAQ,gBAAe;AAE1C,YAAY,YAAY;AACxB,YAAY,WAAW;AACvB,SAAQ,cAAa;AAmCd,gBAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,MAAI,CAAC,cAAc,eAAe,IAAI,SAAS,CAAC;AAChD,MAAI,CAAC,eAAe,gBAAgB,IAAI,SAAS,YAAY;AAC7D,MAAI,WAAW,OAAO,qBAAqB,YAAY,MAAM,SAAS;AACtE,MAAI,QAAQ,WAAW,KAAK,IAAI,kBAA4B,MAAM,MAAM,IAAI,MAAM;AAClF,MAAI,gBAAgB,OAA0B,KAAK;AAEnD,YAAU,MAAM;AACd,QACE,CAAC,EAAE;AAAA,MACD,cAAc,QAAQ,IAAI,CAAC,SAAS,KAAK,KAAK;AAAA,MAC9C,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK;AAAA,IAChC,GACA;AACA,sBAAgB,CAAC;AACjB,uBAAiB,CAAC;AAAA,IACpB;AAEA,kBAAc,UAAU;AAAA,EAC1B,GAAG,CAAC,KAAK,CAAC;AAEV;AAAA,IACE,CAAC,OAAe,QAAa;AAC3B,UAAI,UAAU,OAAO,IAAI,SAAS;AAChC,YAAI,aAAa,WAAW,QAAQ,MAAM,UAAU;AACpD,YAAI,iBAAiB,kBAAkB;AACvC,YAAI,YAAY,WAAW,gBAAgB;AAC3C,YAAI,mBAAmB,iBAAiB,eAAe,IAAI;AAC3D,YAAI,oBAAoB,iBAAiB,YAAY,gBAAgB;AAErE,wBAAgB,gBAAgB;AAChC,yBAAiB,iBAAiB;AAElC,YAAI,cAAc,WAAW,OAAO,OAAO,gBAAgB,EAAE,MAAM,GAAG,KAAK,IAAI;AAE/E,YAAI,OAAO,gBAAgB,YAAY;AACrC,sBAAY,YAAY,iBAAiB,CAAoB;AAAA,QAC/D;AAAA,MACF;AAEA,UAAI,UAAU,OAAO,IAAI,WAAW;AAClC,YAAI,gBAAgB,mBAAmB,WAAW,QAAQ,MAAM,UAAU;AAC1E,YAAI,YAAY,WAAW,gBAAgB;AAC3C,YAAI,mBAAmB,gBAAgB,eAAe,IAAI;AAC1D,YAAI,oBAAoB,gBAAgB,YAAY,gBAAgB;AAEpE,wBAAgB,gBAAgB;AAChC,yBAAiB,iBAAiB;AAElC,YAAI,cAAc,WAAW,OAAO,OAAO,gBAAgB,EAAE,MAAM,GAAG,KAAK,IAAI;AAE/E,YAAI,OAAO,gBAAgB,YAAY;AACrC,sBAAY,YAAY,iBAAiB,CAAoB;AAAA,QAC/D;AAAA,MACF;AAEA,UAAI,IAAI,QAAQ;AACd,YAAI,cAAc,WAAW,OAAO,OAAO,YAAY,EAAE,MAAM,GAAG,KAAK,IAAI;AAE3E,YAAI,OAAO,aAAa,YAAY;AAClC,mBAAS,YAAY,aAAa,CAAoB;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAC,UAAU,MAAK;AAAA,EAClB;AAEA,MAAI,eACF,WAAW,OAAO,OAAO,YAAY,EAAE,MAAM,GAAG,KAAK,IAAI;AAE3D,SACE,qBAAC,OAAK,GAAG,UACP;AAAA,wBAAC,OAAI,aAAa,GAChB,8BAAC,QAAM,uBAAa,MAAM,UAAU,MAAM,UAAS,GACrD;AAAA,IAEA,qBAAC,OAAI,eAAc,UACjB;AAAA,0BAAC,OAAI,aAAa,GAChB,8BAAC,QAAK,OAAO,OAAO,aAAc,iBAAM,GAC1C;AAAA,MACC,aACC,oBAAC,QAAK,OAAO,OAAO,MACjB,gBAAM,aAAa,GAAG,SAAS,OAAO,MAAM,aAAa,GAAG,KAAK,GACpE,IACA,oBAAC,OAAI,eAAc,UAChB,uBAAa,IAAI,CAAC,MAAM,UAAU;AACjC,YAAI,aAAa,UAAU;AAE3B,eACE,qBAAC,OACC;AAAA,8BAAC,OAAI,aAAa,GACf,uBACC,oBAAC,QAAK,OAAO,OAAO,UAAW,gBAAM,gBAAe,IACpD,oBAAC,QAAK,OAAO,OAAO,YAAa,gBAAM,kBAAiB,GAC5D;AAAA,UACA,oBAAC,QAAK,OAAO,aAAa,OAAO,cAAc,OAAO,OAAQ,eAAK,OAAM;AAAA,aANjE,KAAK,KAOf;AAAA,MAEJ,CAAC,GACH;AAAA,OAEJ;AAAA,KACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { Box, Text, useInput } from "ink";
|
|
5
|
+
import { useEffect, useState } from "react";
|
|
6
|
+
import * as colors from "../colors.js";
|
|
7
|
+
import * as icons from "../icons.js";
|
|
8
|
+
export function TextInput({
|
|
9
|
+
label,
|
|
10
|
+
validate,
|
|
11
|
+
isComplete,
|
|
12
|
+
value: originalValue,
|
|
13
|
+
placeholder = "",
|
|
14
|
+
focus = true,
|
|
15
|
+
mask,
|
|
16
|
+
showCursor = true,
|
|
17
|
+
onChange,
|
|
18
|
+
onSubmit,
|
|
19
|
+
...boxProps
|
|
20
|
+
}) {
|
|
21
|
+
let [validationError, setValidationError] = useState("");
|
|
22
|
+
let [state, setState] = useState({
|
|
23
|
+
cursorOffset: (originalValue || "").length,
|
|
24
|
+
cursorWidth: 0
|
|
25
|
+
});
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
setState((previousState) => {
|
|
28
|
+
if (!focus || !showCursor) {
|
|
29
|
+
return previousState;
|
|
30
|
+
}
|
|
31
|
+
let newValue = originalValue || "";
|
|
32
|
+
if (previousState.cursorOffset > newValue.length - 1) {
|
|
33
|
+
return {
|
|
34
|
+
cursorOffset: newValue.length,
|
|
35
|
+
cursorWidth: 0
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return previousState;
|
|
39
|
+
});
|
|
40
|
+
}, [originalValue, focus, showCursor]);
|
|
41
|
+
let value = mask ? mask.repeat(originalValue.length) : originalValue;
|
|
42
|
+
let renderedValue = value;
|
|
43
|
+
let renderedPlaceholder = placeholder ? chalk[colors.muted](placeholder) : void 0;
|
|
44
|
+
if (showCursor && focus) {
|
|
45
|
+
renderedPlaceholder = placeholder.length > 0 ? chalk.inverse(placeholder[0]) + chalk[colors.muted](placeholder.slice(1)) : chalk.inverse(" ");
|
|
46
|
+
renderedValue = value.length > 0 ? "" : chalk.inverse(" ");
|
|
47
|
+
for (let [i, character] of Object.entries(value)) {
|
|
48
|
+
if (Number(i) >= state.cursorOffset && Number(i) <= state.cursorOffset) {
|
|
49
|
+
renderedValue += chalk.inverse(character);
|
|
50
|
+
} else {
|
|
51
|
+
renderedValue += character;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (value.length > 0 && state.cursorOffset === value.length) {
|
|
55
|
+
renderedValue += chalk.inverse(" ");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
useInput(
|
|
59
|
+
(input, key) => {
|
|
60
|
+
if (key.upArrow || key.downArrow || key.ctrl && input === "c" || key.shift && key.tab || key.tab) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (key.return) {
|
|
64
|
+
if (onSubmit) {
|
|
65
|
+
if (validate) {
|
|
66
|
+
try {
|
|
67
|
+
validate(originalValue);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
setValidationError(error.message);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (validationError) {
|
|
74
|
+
setValidationError("");
|
|
75
|
+
} else {
|
|
76
|
+
onSubmit(originalValue);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
let nextCursorOffset = state.cursorOffset;
|
|
82
|
+
let nextValue = originalValue;
|
|
83
|
+
let nextCursorWidth = 0;
|
|
84
|
+
if (key.leftArrow) {
|
|
85
|
+
if (showCursor) {
|
|
86
|
+
nextCursorOffset -= 1;
|
|
87
|
+
}
|
|
88
|
+
} else if (key.rightArrow) {
|
|
89
|
+
if (showCursor) {
|
|
90
|
+
nextCursorOffset += 1;
|
|
91
|
+
}
|
|
92
|
+
} else if (key.backspace || key.delete) {
|
|
93
|
+
if (state.cursorOffset > 0) {
|
|
94
|
+
nextValue = originalValue.slice(0, state.cursorOffset - 1) + originalValue.slice(state.cursorOffset, originalValue.length);
|
|
95
|
+
nextCursorOffset -= 1;
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
nextValue = originalValue.slice(0, state.cursorOffset) + input + originalValue.slice(state.cursorOffset, originalValue.length);
|
|
99
|
+
nextCursorOffset += input.length;
|
|
100
|
+
if (input.length > 1) {
|
|
101
|
+
nextCursorWidth = input.length;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (state.cursorOffset < 0) {
|
|
105
|
+
nextCursorOffset = 0;
|
|
106
|
+
}
|
|
107
|
+
if (state.cursorOffset > originalValue.length) {
|
|
108
|
+
nextCursorOffset = originalValue.length;
|
|
109
|
+
}
|
|
110
|
+
setState({
|
|
111
|
+
cursorOffset: nextCursorOffset,
|
|
112
|
+
cursorWidth: nextCursorWidth
|
|
113
|
+
});
|
|
114
|
+
if (nextValue !== originalValue) {
|
|
115
|
+
onChange(nextValue);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{ isActive: focus }
|
|
119
|
+
);
|
|
120
|
+
return /* @__PURE__ */ jsxs(Box, { ...boxProps, children: [
|
|
121
|
+
/* @__PURE__ */ jsx(Box, { marginRight: 1, children: /* @__PURE__ */ jsx(Text, { children: isComplete ? icons.success : icons.question }) }),
|
|
122
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
123
|
+
/* @__PURE__ */ jsx(Box, { marginRight: 1, children: /* @__PURE__ */ jsx(Text, { color: colors.highlighted, children: label }) }),
|
|
124
|
+
isComplete ? /* @__PURE__ */ jsx(Text, { color: colors.body, children: value }) : /* @__PURE__ */ jsx(Text, { color: colors.highlighted, children: placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue }),
|
|
125
|
+
validationError ? /* @__PURE__ */ jsx(Box, { marginTop: 0, children: /* @__PURE__ */ jsx(Text, { color: colors.warning, children: validationError }) }) : null
|
|
126
|
+
] })
|
|
127
|
+
] });
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=TextInput.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../source/ui/form/TextInput.tsx"],
|
|
4
|
+
"sourcesContent": ["// TODO: resolve\n/* eslint-disable complexity -- TODO */\nimport chalk from 'chalk';\nimport {Box, type BoxProps, Text, useInput} from 'ink';\nimport {useEffect, useState} from 'react';\n\nimport * as colors from '../colors.js';\nimport * as icons from '../icons.js';\n\n/**\n * Text input component props.\n */\nexport type TextInputProps = BoxProps & {\n /** Text to display as a label. */\n label: string;\n\n /** Text to display when `value` is empty. */\n placeholder?: string | undefined;\n\n /** Value. */\n value: string;\n\n /** Should component listen to Listen to user's input? Useful in case there are multiple input components at the same time and input must be handled only by a specific component. */\n focus?: boolean | undefined;\n\n /** Replace all chars and mask the value. Useful for password inputs. */\n mask?: string | undefined;\n\n /** Show cursor and allow navigation using arrow keys. */\n showCursor?: boolean | undefined;\n\n /** Validation function that is called when value changes. If this function throws an error*/\n validate?: ((value: string) => void) | undefined;\n\n /** Handler function that is called when value changes. */\n onChange: (value: string) => void;\n\n /** Handler function that is called when enter is pressed. */\n onSubmit?: ((value: string) => void) | undefined;\n\n /** Indicates whether value has been accepted. Component then doesn't accept more input. */\n isComplete?: boolean | undefined;\n};\n\n/**\n * Text input component.\n */\nexport function TextInput({\n label,\n validate,\n isComplete,\n value: originalValue,\n placeholder = '',\n focus = true,\n mask,\n showCursor = true,\n onChange,\n onSubmit,\n ...boxProps\n}: TextInputProps) {\n let [validationError, setValidationError] = useState('');\n let [state, setState] = useState({\n cursorOffset: (originalValue || '').length,\n cursorWidth: 0,\n });\n\n useEffect(() => {\n setState((previousState) => {\n if (!focus || !showCursor) {\n return previousState;\n }\n\n let newValue = originalValue || '';\n\n if (previousState.cursorOffset > newValue.length - 1) {\n return {\n cursorOffset: newValue.length,\n cursorWidth: 0,\n };\n }\n\n return previousState;\n });\n }, [originalValue, focus, showCursor]);\n\n let value = mask ? mask.repeat(originalValue.length) : originalValue;\n let renderedValue = value;\n let renderedPlaceholder = placeholder ? chalk[colors.muted](placeholder) : undefined;\n\n if (showCursor && focus) {\n renderedPlaceholder =\n placeholder.length > 0 ?\n chalk.inverse(placeholder[0]) + chalk[colors.muted](placeholder.slice(1))\n : chalk.inverse(' ');\n\n renderedValue = value.length > 0 ? '' : chalk.inverse(' ');\n\n for (let [i, character] of Object.entries(value)) {\n if (Number(i) >= state.cursorOffset && Number(i) <= state.cursorOffset) {\n renderedValue += chalk.inverse(character);\n } else {\n renderedValue += character;\n }\n }\n\n if (value.length > 0 && state.cursorOffset === value.length) {\n renderedValue += chalk.inverse(' ');\n }\n }\n\n useInput(\n (input, key) => {\n if (\n key.upArrow ||\n key.downArrow ||\n (key.ctrl && input === 'c') ||\n (key.shift && key.tab) ||\n key.tab\n ) {\n return;\n }\n\n if (key.return) {\n if (onSubmit) {\n if (validate) {\n try {\n validate(originalValue);\n } catch (error: unknown) {\n setValidationError((error as Error).message);\n\n return;\n }\n }\n\n if (validationError) {\n setValidationError('');\n } else {\n onSubmit(originalValue);\n }\n }\n\n return;\n }\n\n let nextCursorOffset = state.cursorOffset;\n let nextValue = originalValue;\n let nextCursorWidth = 0;\n\n if (key.leftArrow) {\n if (showCursor) {\n nextCursorOffset -= 1;\n }\n } else if (key.rightArrow) {\n if (showCursor) {\n nextCursorOffset += 1;\n }\n } else if (key.backspace || key.delete) {\n if (state.cursorOffset > 0) {\n nextValue =\n originalValue.slice(0, state.cursorOffset - 1) +\n originalValue.slice(state.cursorOffset, originalValue.length);\n\n nextCursorOffset -= 1;\n }\n } else {\n nextValue =\n originalValue.slice(0, state.cursorOffset) +\n input +\n originalValue.slice(state.cursorOffset, originalValue.length);\n\n nextCursorOffset += input.length;\n\n if (input.length > 1) {\n nextCursorWidth = input.length;\n }\n }\n\n if (state.cursorOffset < 0) {\n nextCursorOffset = 0;\n }\n\n if (state.cursorOffset > originalValue.length) {\n nextCursorOffset = originalValue.length;\n }\n\n setState({\n cursorOffset: nextCursorOffset,\n cursorWidth: nextCursorWidth,\n });\n\n if (nextValue !== originalValue) {\n onChange(nextValue);\n }\n },\n {isActive: focus},\n );\n\n return (\n <Box {...boxProps}>\n <Box marginRight={1}>\n <Text>{isComplete ? icons.success : icons.question}</Text>\n </Box>\n\n <Box flexDirection=\"column\">\n <Box marginRight={1}>\n <Text color={colors.highlighted}>{label}</Text>\n </Box>\n {isComplete ?\n <Text color={colors.body}>{value}</Text>\n : <Text color={colors.highlighted}>\n {placeholder ?\n value.length > 0 ?\n renderedValue\n : renderedPlaceholder\n : renderedValue}\n </Text>\n }\n {validationError ?\n <Box marginTop={0}>\n <Text color={colors.warning}>{validationError}</Text>\n </Box>\n : null}\n </Box>\n </Box>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|