@shopify/cli-kit 3.31.1 → 3.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api.d.ts +2 -5
- package/dist/api.js +2 -5
- package/dist/api.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/environment/local.d.ts +1 -0
- package/dist/environment/local.js +4 -1
- package/dist/environment/local.js.map +1 -1
- package/dist/file.d.ts +10 -3
- package/dist/file.js +34 -34
- package/dist/file.js.map +1 -1
- package/dist/http/fetch.js +1 -1
- package/dist/http/fetch.js.map +1 -1
- package/dist/http.d.ts +0 -1
- package/dist/http.js +0 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -8
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/monorail.d.ts +1 -1
- package/dist/monorail.js.map +1 -1
- package/dist/npm.js +1 -1
- package/dist/npm.js.map +1 -1
- package/dist/output.d.ts +2 -2
- package/dist/output.js +1 -1
- package/dist/output.js.map +1 -1
- package/dist/path.d.ts +3 -1
- package/dist/path.js +2 -2
- package/dist/path.js.map +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/{json.d.ts → private/common/json.d.ts} +0 -0
- package/dist/{json.js → private/common/json.js} +0 -0
- package/dist/private/common/json.js.map +1 -0
- package/dist/private/node/analytics.d.ts +27 -0
- package/dist/private/node/analytics.js +57 -0
- package/dist/private/node/analytics.js.map +1 -0
- package/dist/private/node/api/graphql.d.ts +5 -0
- package/dist/private/node/api/graphql.js +63 -0
- package/dist/private/node/api/graphql.js.map +1 -0
- package/dist/{api/common.d.ts → private/node/api/headers.d.ts} +3 -8
- package/dist/{api/common.js → private/node/api/headers.js} +20 -60
- package/dist/private/node/api/headers.js.map +1 -0
- package/dist/private/node/ui/components/Alert.test.js +5 -5
- package/dist/private/node/ui/components/Alert.test.js.map +1 -1
- package/dist/private/node/ui/components/Banner.js +5 -5
- package/dist/private/node/ui/components/Banner.js.map +1 -1
- package/dist/private/node/ui/components/Banner.test.js +11 -11
- package/dist/private/node/ui/components/Banner.test.js.map +1 -1
- package/dist/private/node/ui/components/Command.test.js +3 -3
- package/dist/private/node/ui/components/Command.test.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +2 -2
- package/dist/private/node/ui/components/ConcurrentOutput.js +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.test.js +3 -3
- package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.test.js +9 -9
- package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
- package/dist/private/node/ui/components/FilePath.test.js +3 -3
- package/dist/private/node/ui/components/FilePath.test.js.map +1 -1
- package/dist/private/node/ui/components/FullScreen.js +11 -9
- package/dist/private/node/ui/components/FullScreen.js.map +1 -1
- package/dist/private/node/ui/components/Link.test.js +5 -5
- package/dist/private/node/ui/components/Link.test.js.map +1 -1
- package/dist/private/node/ui/components/List.test.js +5 -5
- package/dist/private/node/ui/components/List.test.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.d.ts +2 -2
- package/dist/private/node/ui/components/SelectInput.js +16 -24
- package/dist/private/node/ui/components/SelectInput.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.test.js +62 -32
- package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
- package/dist/private/node/ui/components/{Prompt.d.ts → SelectPrompt.d.ts} +4 -3
- package/dist/private/node/ui/components/SelectPrompt.js +46 -0
- package/dist/private/node/ui/components/SelectPrompt.js.map +1 -0
- package/dist/private/node/ui/components/{Prompt.test.d.ts → SelectPrompt.test.d.ts} +0 -0
- package/dist/private/node/ui/components/{Prompt.test.js → SelectPrompt.test.js} +7 -6
- package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -0
- package/dist/private/node/ui/components/Table.js +2 -2
- package/dist/private/node/ui/components/Table.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.d.ts +1 -1
- package/dist/private/node/ui/components/Tasks.js +3 -3
- package/dist/private/node/ui/components/Tasks.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.test.js +4 -4
- package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
- package/dist/private/node/ui/components/TextAnimation.js.map +1 -1
- package/dist/private/node/ui/components/TextInput.d.ts +9 -0
- package/dist/private/node/ui/components/TextInput.js +74 -0
- package/dist/private/node/ui/components/TextInput.js.map +1 -0
- package/dist/private/node/ui/components/TextInput.test.d.ts +1 -0
- package/dist/private/node/ui/components/TextInput.test.js +139 -0
- package/dist/private/node/ui/components/TextInput.test.js.map +1 -0
- package/dist/private/node/ui/components/TextPrompt.d.ts +8 -0
- package/dist/private/node/ui/components/TextPrompt.js +52 -0
- package/dist/private/node/ui/components/TextPrompt.js.map +1 -0
- package/dist/private/node/ui/components/TextPrompt.test.d.ts +1 -0
- package/dist/private/node/ui/components/TextPrompt.test.js +68 -0
- package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -0
- package/dist/private/node/ui/components/TokenizedText.test.js +3 -3
- package/dist/private/node/ui/components/TokenizedText.test.js.map +1 -1
- package/dist/private/node/ui/components/UserInput.test.js +3 -3
- package/dist/private/node/ui/components/UserInput.test.js.map +1 -1
- package/dist/private/node/ui/hooks/use-layout.d.ts +6 -3
- package/dist/private/node/ui/hooks/use-layout.js +17 -8
- package/dist/private/node/ui/hooks/use-layout.js.map +1 -1
- package/dist/private/node/ui.d.ts +2 -3
- package/dist/private/node/ui.js +7 -16
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/common/array.js +1 -1
- package/dist/public/common/array.js.map +1 -1
- package/dist/public/common/collection.js +1 -1
- package/dist/public/common/collection.js.map +1 -1
- package/dist/public/common/function.js +1 -1
- package/dist/public/common/function.js.map +1 -1
- package/dist/public/common/lang.js +1 -1
- package/dist/public/common/lang.js.map +1 -1
- package/dist/public/common/object.js +4 -4
- package/dist/public/common/object.js.map +1 -1
- package/dist/public/common/string.d.ts +55 -1
- package/dist/public/common/string.js +93 -1
- package/dist/public/common/string.js.map +1 -1
- package/dist/public/common/url.d.ts +7 -0
- package/dist/public/common/url.js +17 -0
- package/dist/public/common/url.js.map +1 -0
- package/dist/public/node/abort.d.ts +16 -0
- package/dist/public/node/abort.js +17 -0
- package/dist/public/node/abort.js.map +1 -0
- package/dist/public/node/analytics.d.ts +13 -0
- package/dist/public/node/analytics.js +82 -0
- package/dist/public/node/analytics.js.map +1 -0
- package/dist/public/node/api/admin.d.ts +11 -0
- package/dist/public/node/api/admin.js +70 -0
- package/dist/public/node/api/admin.js.map +1 -0
- package/dist/public/node/api/oxygen.d.ts +22 -0
- package/dist/public/node/api/oxygen.js +40 -0
- package/dist/public/node/api/oxygen.js.map +1 -0
- package/dist/{api → public/node/api}/partners.d.ts +11 -3
- package/dist/public/node/api/partners.js +40 -0
- package/dist/public/node/api/partners.js.map +1 -0
- package/dist/public/node/archiver.js +1 -1
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.js +1 -1
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/crypto.d.ts +42 -0
- package/dist/public/node/crypto.js +55 -0
- package/dist/public/node/crypto.js.map +1 -0
- package/dist/public/node/error-handler.js +3 -2
- package/dist/public/node/error-handler.js.map +1 -1
- package/dist/public/node/framework.js +1 -1
- package/dist/public/node/framework.js.map +1 -1
- package/dist/public/node/hooks/postrun.js +2 -2
- package/dist/public/node/hooks/postrun.js.map +1 -1
- package/dist/public/node/hooks/prerun.js +2 -2
- package/dist/public/node/hooks/prerun.js.map +1 -1
- package/dist/{template.d.ts → public/node/liquid.d.ts} +10 -2
- package/dist/{template.js → public/node/liquid.js} +18 -13
- package/dist/public/node/liquid.js.map +1 -0
- package/dist/public/node/node-package-manager.d.ts +3 -3
- package/dist/public/node/node-package-manager.js +1 -1
- package/dist/public/node/node-package-manager.js.map +1 -1
- package/dist/public/node/os.d.ts +16 -0
- package/dist/{os.js → public/node/os.js} +33 -29
- package/dist/public/node/os.js.map +1 -0
- package/dist/public/node/presets.d.ts +1 -1
- package/dist/public/node/presets.js +2 -2
- package/dist/public/node/presets.js.map +1 -1
- package/dist/public/node/ruby.d.ts +13 -9
- package/dist/public/node/ruby.js +91 -23
- package/dist/public/node/ruby.js.map +1 -1
- package/dist/public/node/tcp.d.ts +2 -0
- package/dist/public/node/tcp.js +9 -0
- package/dist/public/node/tcp.js.map +1 -1
- package/dist/public/node/toml.d.ts +15 -0
- package/dist/public/node/toml.js +20 -0
- package/dist/public/node/toml.js.map +1 -0
- package/dist/public/node/ui.d.ts +12 -17
- package/dist/public/node/ui.js +25 -29
- package/dist/public/node/ui.js.map +1 -1
- package/dist/public/node/vscode.d.ts +14 -0
- package/dist/{vscode.js → public/node/vscode.js} +13 -7
- package/dist/public/node/vscode.js.map +1 -0
- package/dist/session/authorize.d.ts +4 -0
- package/dist/session/authorize.js +8 -3
- package/dist/session/authorize.js.map +1 -1
- package/dist/{api/identity.d.ts → session/identity-token-validation.d.ts} +0 -0
- package/dist/{api/identity.js → session/identity-token-validation.js} +1 -1
- package/dist/session/identity-token-validation.js.map +1 -0
- package/dist/session/redirect-listener.js +6 -3
- package/dist/session/redirect-listener.js.map +1 -1
- package/dist/session/schema.d.ts +18 -18
- package/dist/session/store.js +1 -1
- package/dist/session/store.js.map +1 -1
- package/dist/session.js +3 -3
- package/dist/session.js.map +1 -1
- package/dist/system.d.ts +2 -2
- package/dist/system.js +1 -1
- package/dist/system.js.map +1 -1
- package/dist/testing/ui.d.ts +1 -1
- package/dist/testing/ui.js +1 -1
- package/dist/testing/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/inquirer/autocomplete.d.ts +2 -2
- package/dist/ui/inquirer/autocomplete.js +1 -1
- package/dist/ui/inquirer/autocomplete.js.map +1 -1
- package/dist/ui/inquirer/input.d.ts +2 -2
- package/dist/ui/inquirer/input.js.map +1 -1
- package/dist/ui/inquirer/password.d.ts +2 -2
- package/dist/ui/inquirer/password.js.map +1 -1
- package/dist/ui/inquirer/select.d.ts +2 -2
- package/dist/ui/inquirer/select.js +2 -2
- package/dist/ui/inquirer/select.js.map +1 -1
- package/package.json +30 -27
- package/dist/abort.d.ts +0 -1
- package/dist/abort.js +0 -2
- package/dist/abort.js.map +0 -1
- package/dist/analytics.d.ts +0 -44
- package/dist/analytics.js +0 -154
- package/dist/analytics.js.map +0 -1
- package/dist/api/admin.d.ts +0 -3
- package/dist/api/admin.js +0 -56
- package/dist/api/admin.js.map +0 -1
- package/dist/api/common.js.map +0 -1
- package/dist/api/identity.js.map +0 -1
- package/dist/api/oxygen.d.ts +0 -5
- package/dist/api/oxygen.js +0 -30
- package/dist/api/oxygen.js.map +0 -1
- package/dist/api/partners.js +0 -44
- package/dist/api/partners.js.map +0 -1
- package/dist/http/graphql.d.ts +0 -13
- package/dist/http/graphql.js +0 -12
- package/dist/http/graphql.js.map +0 -1
- package/dist/id.d.ts +0 -6
- package/dist/id.js +0 -18
- package/dist/id.js.map +0 -1
- package/dist/json.js.map +0 -1
- package/dist/os.d.ts +0 -10
- package/dist/os.js.map +0 -1
- package/dist/private/node/ui/components/Prompt.js +0 -23
- package/dist/private/node/ui/components/Prompt.js.map +0 -1
- package/dist/private/node/ui/components/Prompt.test.js.map +0 -1
- package/dist/string.d.ts +0 -28
- package/dist/string.js +0 -77
- package/dist/string.js.map +0 -1
- package/dist/template.js.map +0 -1
- package/dist/toml.d.ts +0 -3
- package/dist/toml.js +0 -8
- package/dist/toml.js.map +0 -1
- package/dist/vscode.d.ts +0 -8
- package/dist/vscode.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box } from 'ink';
|
|
1
|
+
import { Box, useStdout } from 'ink';
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
3
|
/**
|
|
4
4
|
* `FullScreen` renders all output in a new buffer and makes it full screen. This is useful when:
|
|
@@ -6,24 +6,26 @@ import React, { useEffect, useState } from 'react';
|
|
|
6
6
|
* - You want to respond to the resize event of the terminal. Whenever the user resizes their terminal window the output's height and width will be recalculated and re-rendered properly.
|
|
7
7
|
*/
|
|
8
8
|
const FullScreen = ({ children }) => {
|
|
9
|
+
const { stdout } = useStdout();
|
|
10
|
+
const standardOutput = stdout;
|
|
9
11
|
const [size, setSize] = useState({
|
|
10
|
-
columns:
|
|
11
|
-
rows:
|
|
12
|
+
columns: standardOutput.columns,
|
|
13
|
+
rows: standardOutput.rows,
|
|
12
14
|
});
|
|
13
15
|
useEffect(() => {
|
|
14
16
|
function onResize() {
|
|
15
17
|
setSize({
|
|
16
|
-
columns:
|
|
17
|
-
rows:
|
|
18
|
+
columns: standardOutput.columns,
|
|
19
|
+
rows: standardOutput.rows,
|
|
18
20
|
});
|
|
19
21
|
}
|
|
20
|
-
|
|
22
|
+
standardOutput.on('resize', onResize);
|
|
21
23
|
// switch to an alternate buffer
|
|
22
|
-
|
|
24
|
+
standardOutput.write('\u001B[?1049h');
|
|
23
25
|
return () => {
|
|
24
|
-
|
|
26
|
+
standardOutput.off('resize', onResize);
|
|
25
27
|
// switch back to the main buffer
|
|
26
|
-
|
|
28
|
+
standardOutput.write('\u001B[?1049l');
|
|
27
29
|
};
|
|
28
30
|
}, []);
|
|
29
31
|
return (React.createElement(Box, { width: size.columns, height: size.rows }, children));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullScreen.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FullScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"FullScreen.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FullScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,SAAS,EAAC,MAAM,KAAK,CAAA;AAClC,OAAO,KAAK,EAAE,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAA;AAEhD;;;;GAIG;AACH,MAAM,UAAU,GAAa,CAAC,EAAC,QAAQ,EAAC,EAAe,EAAE;IACvD,MAAM,EAAC,MAAM,EAAC,GAAG,SAAS,EAAE,CAAA;IAC5B,MAAM,cAAc,GAAG,MAAO,CAAA;IAE9B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;QAC/B,OAAO,EAAE,cAAc,CAAC,OAAO;QAC/B,IAAI,EAAE,cAAc,CAAC,IAAI;KAC1B,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,QAAQ;YACf,OAAO,CAAC;gBACN,OAAO,EAAE,cAAc,CAAC,OAAO;gBAC/B,IAAI,EAAE,cAAc,CAAC,IAAI;aAC1B,CAAC,CAAA;QACJ,CAAC;QAED,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACrC,gCAAgC;QAChC,cAAc,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;QACrC,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;YACtC,iCAAiC;YACjC,cAAc,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;QACvC,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,oBAAC,GAAG,IAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,IACxC,QAAQ,CACL,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,UAAU,CAAA","sourcesContent":["import {Box, useStdout} from 'ink'\nimport React, {useEffect, useState} from 'react'\n\n/**\n * `FullScreen` renders all output in a new buffer and makes it full screen. This is useful when:\n * - You want to preserve terminal history. `ink` [normally clears the terminal history](https://github.com/vadimdemedes/ink/issues/382) if the rendered output is taller than the terminal window. By rendering in a separate buffer history will be preserved and will be visible after pressing `Ctrl+C`.\n * - You want to respond to the resize event of the terminal. Whenever the user resizes their terminal window the output's height and width will be recalculated and re-rendered properly.\n */\nconst FullScreen: React.FC = ({children}): JSX.Element => {\n const {stdout} = useStdout()\n const standardOutput = stdout!\n\n const [size, setSize] = useState({\n columns: standardOutput.columns,\n rows: standardOutput.rows,\n })\n\n useEffect(() => {\n function onResize() {\n setSize({\n columns: standardOutput.columns,\n rows: standardOutput.rows,\n })\n }\n\n standardOutput.on('resize', onResize)\n // switch to an alternate buffer\n standardOutput.write('\\u001B[?1049h')\n return () => {\n standardOutput.off('resize', onResize)\n // switch back to the main buffer\n standardOutput.write('\\u001B[?1049l')\n }\n }, [])\n\n return (\n <Box width={size.columns} height={size.rows}>\n {children}\n </Box>\n )\n}\n\nexport default FullScreen\n"]}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { Link } from './Link.js';
|
|
2
|
-
import { renderString } from '../../ui.js';
|
|
3
2
|
import { describe, expect, test } from 'vitest';
|
|
4
3
|
import React from 'react';
|
|
4
|
+
import { render } from 'ink-testing-library';
|
|
5
5
|
describe('Link', async () => {
|
|
6
6
|
test("renders correctly with a fallback for terminals that don't support hyperlinks", async () => {
|
|
7
7
|
const link = {
|
|
8
8
|
url: 'https://example.com',
|
|
9
9
|
label: 'Example',
|
|
10
10
|
};
|
|
11
|
-
const {
|
|
12
|
-
expect(
|
|
11
|
+
const { lastFrame } = render(React.createElement(Link, { ...link }));
|
|
12
|
+
expect(lastFrame()).toMatchInlineSnapshot('"Example [2m( https://example.com )[22m"');
|
|
13
13
|
});
|
|
14
14
|
test("it doesn't render a fallback if only url is passed", async () => {
|
|
15
15
|
const link = {
|
|
16
16
|
url: 'https://example.com',
|
|
17
17
|
};
|
|
18
|
-
const {
|
|
19
|
-
expect(
|
|
18
|
+
const { lastFrame } = render(React.createElement(Link, { ...link }));
|
|
19
|
+
expect(lastFrame()).toMatchInlineSnapshot('"https://example.com"');
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
//# sourceMappingURL=Link.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Link.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"Link.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Link.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;IAC1B,IAAI,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,IAAI,GAAG;YACX,GAAG,EAAE,qBAAqB;YAC1B,KAAK,EAAE,SAAS;SACjB,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,IAAI,OAAK,IAAI,GAAI,CAAC,CAAA;QAE9C,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC,4CAA4C,CAAC,CAAA;IACzF,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,IAAI,GAAG;YACX,GAAG,EAAE,qBAAqB;SAC3B,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,IAAI,OAAK,IAAI,GAAI,CAAC,CAAA;QAE9C,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {Link} from './Link.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('Link', async () => {\n test(\"renders correctly with a fallback for terminals that don't support hyperlinks\", async () => {\n const link = {\n url: 'https://example.com',\n label: 'Example',\n }\n\n const {lastFrame} = render(<Link {...link} />)\n\n expect(lastFrame()).toMatchInlineSnapshot('\"Example \u001b[2m( https://example.com )\u001b[22m\"')\n })\n\n test(\"it doesn't render a fallback if only url is passed\", async () => {\n const link = {\n url: 'https://example.com',\n }\n\n const {lastFrame} = render(<Link {...link} />)\n\n expect(lastFrame()).toMatchInlineSnapshot('\"https://example.com\"')\n })\n})\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { List } from './List.js';
|
|
2
|
-
import { renderString } from '../../ui.js';
|
|
3
2
|
import { unstyled } from '../../../../output.js';
|
|
4
3
|
import { describe, expect, test } from 'vitest';
|
|
5
4
|
import React from 'react';
|
|
5
|
+
import { render } from 'ink-testing-library';
|
|
6
6
|
describe('List', async () => {
|
|
7
7
|
test('renders unordered items', async () => {
|
|
8
8
|
const options = {
|
|
@@ -10,8 +10,8 @@ describe('List', async () => {
|
|
|
10
10
|
items: ['Item 1', 'Item 2', 'Item 3'],
|
|
11
11
|
ordered: false,
|
|
12
12
|
};
|
|
13
|
-
const {
|
|
14
|
-
expect(unstyled(
|
|
13
|
+
const { lastFrame } = render(React.createElement(List, { ...options }));
|
|
14
|
+
expect(unstyled(lastFrame())).toMatchInlineSnapshot(`
|
|
15
15
|
"List title
|
|
16
16
|
• Item 1
|
|
17
17
|
• Item 2
|
|
@@ -23,8 +23,8 @@ describe('List', async () => {
|
|
|
23
23
|
items: ['Item 1', 'Item 2', 'Item 3'],
|
|
24
24
|
ordered: true,
|
|
25
25
|
};
|
|
26
|
-
const {
|
|
27
|
-
expect(unstyled(
|
|
26
|
+
const { lastFrame } = render(React.createElement(List, { ...options }));
|
|
27
|
+
expect(unstyled(lastFrame())).toMatchInlineSnapshot(`
|
|
28
28
|
" 1. Item 1
|
|
29
29
|
2. Item 2
|
|
30
30
|
3. Item 3"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"List.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/List.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"List.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/List.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;IAC1B,IAAI,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACrC,OAAO,EAAE,KAAK;SACf,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,IAAI,OAAK,OAAO,GAAI,CAAC,CAAA;QAEjD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACrC,OAAO,EAAE,IAAI;SACd,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,IAAI,OAAK,OAAO,GAAI,CAAC,CAAA;QAEjD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;KAIpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {List} from './List.js'\nimport {unstyled} from '../../../../output.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('List', async () => {\n test('renders unordered items', async () => {\n const options = {\n title: 'List title',\n items: ['Item 1', 'Item 2', 'Item 3'],\n ordered: false,\n }\n\n const {lastFrame} = render(<List {...options} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"List title\n • Item 1\n • Item 2\n • Item 3\"\n `)\n })\n\n test('renders ordered items', async () => {\n const options = {\n items: ['Item 1', 'Item 2', 'Item 3'],\n ordered: true,\n }\n\n const {lastFrame} = render(<List {...options} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \" 1. Item 1\n 2. Item 2\n 3. Item 3\"\n `)\n })\n})\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export interface Props<T> {
|
|
3
3
|
items: Item<T>[];
|
|
4
|
-
|
|
4
|
+
onChange: (item: Item<T>) => void;
|
|
5
5
|
}
|
|
6
6
|
export interface Item<T> {
|
|
7
7
|
label: string;
|
|
@@ -9,4 +9,4 @@ export interface Item<T> {
|
|
|
9
9
|
key?: string;
|
|
10
10
|
group?: string;
|
|
11
11
|
}
|
|
12
|
-
export default function SelectInput<T>({ items,
|
|
12
|
+
export default function SelectInput<T>({ items, onChange }: React.PropsWithChildren<Props<T>>): JSX.Element | null;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { isTruthy } from '../../../../environment/utilities.js';
|
|
2
1
|
import { isEqual } from '../../../../public/common/lang.js';
|
|
3
2
|
import { groupBy } from '../../../../public/common/collection.js';
|
|
4
3
|
import { mapValues } from '../../../../public/common/object.js';
|
|
5
4
|
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
6
|
-
import { Box,
|
|
5
|
+
import { Box, useInput, Text } from 'ink';
|
|
7
6
|
function groupItems(items) {
|
|
8
7
|
let index = 0;
|
|
9
8
|
return mapValues(groupBy(items, 'group'), (groupItems) => groupItems.map((groupItem) => {
|
|
@@ -12,53 +11,46 @@ function groupItems(items) {
|
|
|
12
11
|
return item;
|
|
13
12
|
}));
|
|
14
13
|
}
|
|
15
|
-
export default function SelectInput({ items,
|
|
14
|
+
export default function SelectInput({ items, onChange }) {
|
|
16
15
|
const [inputStack, setInputStack] = useState(null);
|
|
17
16
|
const [inputTimeout, setInputTimeout] = useState(null);
|
|
18
17
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
19
18
|
const keys = useRef(new Set(items.map((item) => item.key)));
|
|
20
|
-
const { exit: unmountInk } = useApp();
|
|
21
19
|
const groupedItems = groupItems(items);
|
|
20
|
+
const groupedItemsValues = Object.values(groupedItems).flat();
|
|
22
21
|
const groupTitles = Object.keys(groupedItems);
|
|
23
22
|
const previousItems = useRef(items);
|
|
23
|
+
const changeSelection = useCallback((index) => {
|
|
24
|
+
const groupedItem = groupedItemsValues.find((item) => item.index === index);
|
|
25
|
+
setSelectedIndex(index);
|
|
26
|
+
onChange(items.find((item) => item.value === groupedItem.value));
|
|
27
|
+
}, [items]);
|
|
24
28
|
// reset index when items change
|
|
25
29
|
useEffect(() => {
|
|
26
30
|
if (!isEqual(previousItems.current.map((item) => item.value), items.map((item) => item.value))) {
|
|
27
|
-
|
|
31
|
+
changeSelection(0);
|
|
28
32
|
}
|
|
29
33
|
previousItems.current = items;
|
|
30
34
|
}, [items]);
|
|
31
35
|
const handleInput = useCallback((input, key) => {
|
|
32
|
-
if (input === 'c' && key.ctrl) {
|
|
33
|
-
// Exceptions being throw in these hooks aren't being caught by our errorHandler.
|
|
34
|
-
// See also how we handle exceptions in CouncurrentOutput for reference.
|
|
35
|
-
process.exit(1);
|
|
36
|
-
}
|
|
37
36
|
const parsedInput = parseInt(input, 10);
|
|
38
37
|
if (parsedInput !== 0 && parsedInput <= items.length + 1) {
|
|
39
|
-
|
|
38
|
+
changeSelection(parsedInput - 1);
|
|
40
39
|
}
|
|
41
40
|
else if (keys.current.has(input)) {
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
44
|
-
|
|
41
|
+
const groupedItem = groupedItemsValues.find((item) => item.key === input);
|
|
42
|
+
if (groupedItem !== undefined) {
|
|
43
|
+
changeSelection(groupedItem.index);
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
if (key.upArrow) {
|
|
48
47
|
const lastIndex = items.length - 1;
|
|
49
|
-
|
|
48
|
+
changeSelection(selectedIndex === 0 ? lastIndex : selectedIndex - 1);
|
|
50
49
|
}
|
|
51
50
|
else if (key.downArrow) {
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
else if (key.return) {
|
|
55
|
-
onSelect(items[selectedIndex].value);
|
|
56
|
-
// This is a workaround needed because Ink behaves differently in CI when
|
|
57
|
-
// unmounting. See https://github.com/vadimdemedes/ink/pull/266
|
|
58
|
-
if (!isTruthy(process.env.CI))
|
|
59
|
-
unmountInk();
|
|
51
|
+
changeSelection(selectedIndex === items.length - 1 ? 0 : selectedIndex + 1);
|
|
60
52
|
}
|
|
61
|
-
}, [selectedIndex, items
|
|
53
|
+
}, [selectedIndex, items]);
|
|
62
54
|
useInput((input, key) => {
|
|
63
55
|
if (input.length > 0 && Object.values(key).every((value) => value === false)) {
|
|
64
56
|
const newInputStack = inputStack === null ? input : inputStack + input;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"SelectInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {isEqual} from '../../../../public/common/lang.js'\nimport {groupBy} from '../../../../public/common/collection.js'\nimport {mapValues} from '../../../../public/common/object.js'\nimport React, {useState, useEffect, useRef, useCallback} from 'react'\nimport {Box, Key, useInput, Text} from 'ink'\n\nexport interface Props<T> {\n items: Item<T>[]\n onChange: (item: Item<T>) => void\n}\n\nexport interface Item<T> {\n label: string\n value: T\n key?: string\n group?: string\n}\n\nfunction groupItems<T>(items: Item<T>[]) {\n let index = 0\n\n return mapValues(groupBy(items, 'group'), (groupItems) =>\n groupItems.map((groupItem) => {\n const item = {...groupItem, key: groupItem.key ?? (index + 1).toString(), index}\n index += 1\n return item\n }),\n )\n}\n\nexport default function SelectInput<T>({items, onChange}: React.PropsWithChildren<Props<T>>): JSX.Element | null {\n const [inputStack, setInputStack] = useState<string | null>(null)\n const [inputTimeout, setInputTimeout] = useState<NodeJS.Timeout | null>(null)\n const [selectedIndex, setSelectedIndex] = useState(0)\n const keys = useRef(new Set(items.map((item) => item.key)))\n const groupedItems = groupItems(items)\n const groupedItemsValues = Object.values(groupedItems).flat()\n const groupTitles = Object.keys(groupedItems)\n const previousItems = useRef<Item<T>[]>(items)\n\n const changeSelection = useCallback(\n (index: number) => {\n const groupedItem = groupedItemsValues.find((item) => item.index === index)!\n setSelectedIndex(index)\n onChange(items.find((item) => item.value === groupedItem.value)!)\n },\n [items],\n )\n\n // reset index when items change\n useEffect(() => {\n if (\n !isEqual(\n previousItems.current.map((item) => item.value),\n items.map((item) => item.value),\n )\n ) {\n changeSelection(0)\n }\n\n previousItems.current = items\n }, [items])\n\n const handleInput = useCallback(\n (input: string, key: Key) => {\n const parsedInput = parseInt(input, 10)\n\n if (parsedInput !== 0 && parsedInput <= items.length + 1) {\n changeSelection(parsedInput - 1)\n } else if (keys.current.has(input)) {\n const groupedItem = groupedItemsValues.find((item) => item.key === input)\n if (groupedItem !== undefined) {\n changeSelection(groupedItem.index)\n }\n }\n\n if (key.upArrow) {\n const lastIndex = items.length - 1\n\n changeSelection(selectedIndex === 0 ? lastIndex : selectedIndex - 1)\n } else if (key.downArrow) {\n changeSelection(selectedIndex === items.length - 1 ? 0 : selectedIndex + 1)\n }\n },\n [selectedIndex, items],\n )\n\n useInput((input, key) => {\n if (input.length > 0 && Object.values(key).every((value) => value === false)) {\n const newInputStack = inputStack === null ? input : inputStack + input\n\n setInputStack(newInputStack)\n\n if (inputTimeout !== null) {\n clearTimeout(inputTimeout)\n }\n\n setInputTimeout(\n setTimeout(() => {\n handleInput(newInputStack, key)\n setInputStack(null)\n setInputTimeout(null)\n }, 300),\n )\n } else {\n handleInput(input, key)\n }\n })\n\n return (\n <Box flexDirection=\"column\">\n {groupTitles.map((title) => {\n const hasTitle = title !== 'undefined'\n\n return (\n <Box key={title} flexDirection=\"column\" marginTop={hasTitle ? 1 : 0}>\n {hasTitle && (\n <Box marginLeft={3}>\n <Text bold>{title}</Text>\n </Box>\n )}\n {groupedItems[title]!.map((item) => {\n const isSelected = item.index === selectedIndex\n\n return (\n <Box key={item.key}>\n <Box marginRight={2}>{isSelected ? <Text color=\"cyan\">{`>`}</Text> : <Text> </Text>}</Box>\n\n <Text color={isSelected ? 'cyan' : undefined}>{`(${item.key}) ${item.label}`}</Text>\n </Box>\n )\n })}\n </Box>\n )\n })}\n\n <Box marginTop={1} marginLeft={3}>\n <Text dimColor>navigate with arrows, enter to select</Text>\n </Box>\n </Box>\n )\n}\n"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import SelectInput from './SelectInput.js';
|
|
2
|
-
import { waitForInputsToBeReady,
|
|
2
|
+
import { waitForInputsToBeReady, sendInput } from '../../../../testing/ui.js';
|
|
3
3
|
import { describe, expect, test, vi } from 'vitest';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { render } from 'ink-testing-library';
|
|
6
6
|
const ARROW_UP = '\u001B[A';
|
|
7
7
|
const ARROW_DOWN = '\u001B[B';
|
|
8
|
-
const ENTER = '\r';
|
|
9
8
|
describe('SelectInput', async () => {
|
|
10
9
|
test('move up with up arrow key', async () => {
|
|
10
|
+
const onChange = vi.fn();
|
|
11
11
|
const items = [
|
|
12
12
|
{
|
|
13
13
|
label: 'First',
|
|
@@ -22,7 +22,7 @@ describe('SelectInput', async () => {
|
|
|
22
22
|
value: 'third',
|
|
23
23
|
},
|
|
24
24
|
];
|
|
25
|
-
const renderInstance = render(React.createElement(SelectInput, { items: items,
|
|
25
|
+
const renderInstance = render(React.createElement(SelectInput, { items: items, onChange: onChange }));
|
|
26
26
|
await waitForInputsToBeReady();
|
|
27
27
|
await sendInput(renderInstance, ARROW_UP);
|
|
28
28
|
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
@@ -32,8 +32,10 @@ describe('SelectInput', async () => {
|
|
|
32
32
|
|
|
33
33
|
[2mnavigate with arrows, enter to select[22m"
|
|
34
34
|
`);
|
|
35
|
+
expect(onChange).toHaveBeenCalledWith(items[2]);
|
|
35
36
|
});
|
|
36
37
|
test('move down with down arrow key', async () => {
|
|
38
|
+
const onChange = vi.fn();
|
|
37
39
|
const items = [
|
|
38
40
|
{
|
|
39
41
|
label: 'First',
|
|
@@ -48,7 +50,7 @@ describe('SelectInput', async () => {
|
|
|
48
50
|
value: 'third',
|
|
49
51
|
},
|
|
50
52
|
];
|
|
51
|
-
const renderInstance = render(React.createElement(SelectInput, { items: items,
|
|
53
|
+
const renderInstance = render(React.createElement(SelectInput, { items: items, onChange: onChange }));
|
|
52
54
|
await waitForInputsToBeReady();
|
|
53
55
|
await sendInput(renderInstance, ARROW_DOWN);
|
|
54
56
|
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
@@ -58,30 +60,10 @@ describe('SelectInput', async () => {
|
|
|
58
60
|
|
|
59
61
|
[2mnavigate with arrows, enter to select[22m"
|
|
60
62
|
`);
|
|
61
|
-
|
|
62
|
-
test('select item with enter key', async () => {
|
|
63
|
-
const onEnter = vi.fn();
|
|
64
|
-
const items = [
|
|
65
|
-
{
|
|
66
|
-
label: 'First',
|
|
67
|
-
value: 'first',
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
label: 'Second',
|
|
71
|
-
value: 'second',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
label: 'Third',
|
|
75
|
-
value: 'third',
|
|
76
|
-
},
|
|
77
|
-
];
|
|
78
|
-
const renderInstance = render(React.createElement(SelectInput, { items: items, onSelect: onEnter }));
|
|
79
|
-
await waitForInputsToBeReady();
|
|
80
|
-
await sendInput(renderInstance, ARROW_DOWN);
|
|
81
|
-
await waitForChange(() => renderInstance.stdin.write(ENTER), () => onEnter.mock.calls.length);
|
|
82
|
-
expect(onEnter).toHaveBeenCalledWith(items[1].value);
|
|
63
|
+
expect(onChange).toHaveBeenCalledWith(items[1]);
|
|
83
64
|
});
|
|
84
65
|
test('handles keys with multiple digits', async () => {
|
|
66
|
+
const onChange = vi.fn();
|
|
85
67
|
const items = [
|
|
86
68
|
{
|
|
87
69
|
label: 'First',
|
|
@@ -97,7 +79,7 @@ describe('SelectInput', async () => {
|
|
|
97
79
|
key: '10',
|
|
98
80
|
},
|
|
99
81
|
];
|
|
100
|
-
const renderInstance = render(React.createElement(SelectInput, { items: items,
|
|
82
|
+
const renderInstance = render(React.createElement(SelectInput, { items: items, onChange: onChange }));
|
|
101
83
|
await waitForInputsToBeReady();
|
|
102
84
|
await sendInput(renderInstance, '1', '0');
|
|
103
85
|
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
@@ -107,8 +89,10 @@ describe('SelectInput', async () => {
|
|
|
107
89
|
|
|
108
90
|
[2mnavigate with arrows, enter to select[22m"
|
|
109
91
|
`);
|
|
92
|
+
expect(onChange).toHaveBeenCalledWith(items[2]);
|
|
110
93
|
});
|
|
111
94
|
test('handles custom keys', async () => {
|
|
95
|
+
const onChange = vi.fn();
|
|
112
96
|
const items = [
|
|
113
97
|
{
|
|
114
98
|
label: 'First',
|
|
@@ -124,7 +108,7 @@ describe('SelectInput', async () => {
|
|
|
124
108
|
key: 't',
|
|
125
109
|
},
|
|
126
110
|
];
|
|
127
|
-
const renderInstance = render(React.createElement(SelectInput, { items: items,
|
|
111
|
+
const renderInstance = render(React.createElement(SelectInput, { items: items, onChange: onChange }));
|
|
128
112
|
await waitForInputsToBeReady();
|
|
129
113
|
await sendInput(renderInstance, 't');
|
|
130
114
|
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
@@ -134,8 +118,10 @@ describe('SelectInput', async () => {
|
|
|
134
118
|
|
|
135
119
|
[2mnavigate with arrows, enter to select[22m"
|
|
136
120
|
`);
|
|
121
|
+
expect(onChange).toHaveBeenCalledWith(items[2]);
|
|
137
122
|
});
|
|
138
123
|
test('rotate after reaching the end of the list', async () => {
|
|
124
|
+
const onChange = vi.fn();
|
|
139
125
|
const items = [
|
|
140
126
|
{
|
|
141
127
|
label: 'First',
|
|
@@ -150,7 +136,7 @@ describe('SelectInput', async () => {
|
|
|
150
136
|
value: 'third',
|
|
151
137
|
},
|
|
152
138
|
];
|
|
153
|
-
const renderInstance = render(React.createElement(SelectInput, { items: items,
|
|
139
|
+
const renderInstance = render(React.createElement(SelectInput, { items: items, onChange: onChange }));
|
|
154
140
|
await waitForInputsToBeReady();
|
|
155
141
|
await sendInput(renderInstance, ARROW_DOWN);
|
|
156
142
|
await sendInput(renderInstance, ARROW_DOWN);
|
|
@@ -162,21 +148,23 @@ describe('SelectInput', async () => {
|
|
|
162
148
|
|
|
163
149
|
[2mnavigate with arrows, enter to select[22m"
|
|
164
150
|
`);
|
|
151
|
+
expect(onChange).toHaveBeenCalledWith(items[0]);
|
|
165
152
|
});
|
|
166
153
|
test('support groups', async () => {
|
|
154
|
+
const onChange = vi.fn();
|
|
167
155
|
const items = [
|
|
168
156
|
{ label: 'first', value: 'first', key: 'f' },
|
|
169
157
|
{ label: 'second', value: 'second', key: 's' },
|
|
170
158
|
{ label: 'third', value: 'third' },
|
|
171
159
|
{ label: 'fourth', value: 'fourth' },
|
|
172
|
-
{ label: 'fifth', value: 'fifth', group: 'Automations' },
|
|
160
|
+
{ label: 'fifth', value: 'fifth', group: 'Automations', key: 'a' },
|
|
173
161
|
{ label: 'sixth', value: 'sixth', group: 'Automations' },
|
|
174
162
|
{ label: 'seventh', value: 'seventh' },
|
|
175
163
|
{ label: 'eighth', value: 'eighth', group: 'Merchant Admin' },
|
|
176
164
|
{ label: 'ninth', value: 'ninth', group: 'Merchant Admin' },
|
|
177
165
|
{ label: 'tenth', value: 'tenth' },
|
|
178
166
|
];
|
|
179
|
-
const renderInstance = render(React.createElement(SelectInput, { items: items,
|
|
167
|
+
const renderInstance = render(React.createElement(SelectInput, { items: items, onChange: onChange }));
|
|
180
168
|
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
181
169
|
"[36m>[39m [36m(f) first[39m
|
|
182
170
|
(s) second
|
|
@@ -186,7 +174,48 @@ describe('SelectInput', async () => {
|
|
|
186
174
|
(6) tenth
|
|
187
175
|
|
|
188
176
|
[1mAutomations[22m
|
|
189
|
-
(
|
|
177
|
+
(a) fifth
|
|
178
|
+
(8) sixth
|
|
179
|
+
|
|
180
|
+
[1mMerchant Admin[22m
|
|
181
|
+
(9) eighth
|
|
182
|
+
(10) ninth
|
|
183
|
+
|
|
184
|
+
[2mnavigate with arrows, enter to select[22m"
|
|
185
|
+
`);
|
|
186
|
+
await waitForInputsToBeReady();
|
|
187
|
+
await sendInput(renderInstance, 'a');
|
|
188
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
189
|
+
" (f) first
|
|
190
|
+
(s) second
|
|
191
|
+
(3) third
|
|
192
|
+
(4) fourth
|
|
193
|
+
(5) seventh
|
|
194
|
+
(6) tenth
|
|
195
|
+
|
|
196
|
+
[1mAutomations[22m
|
|
197
|
+
[36m>[39m [36m(a) fifth[39m
|
|
198
|
+
(8) sixth
|
|
199
|
+
|
|
200
|
+
[1mMerchant Admin[22m
|
|
201
|
+
(9) eighth
|
|
202
|
+
(10) ninth
|
|
203
|
+
|
|
204
|
+
[2mnavigate with arrows, enter to select[22m"
|
|
205
|
+
`);
|
|
206
|
+
expect(onChange).toHaveBeenCalledWith(items[4]);
|
|
207
|
+
await sendInput(renderInstance, ARROW_UP);
|
|
208
|
+
await sendInput(renderInstance, ARROW_UP);
|
|
209
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
210
|
+
" (f) first
|
|
211
|
+
(s) second
|
|
212
|
+
(3) third
|
|
213
|
+
(4) fourth
|
|
214
|
+
[36m>[39m [36m(5) seventh[39m
|
|
215
|
+
(6) tenth
|
|
216
|
+
|
|
217
|
+
[1mAutomations[22m
|
|
218
|
+
(a) fifth
|
|
190
219
|
(8) sixth
|
|
191
220
|
|
|
192
221
|
[1mMerchant Admin[22m
|
|
@@ -195,6 +224,7 @@ describe('SelectInput', async () => {
|
|
|
195
224
|
|
|
196
225
|
[2mnavigate with arrows, enter to select[22m"
|
|
197
226
|
`);
|
|
227
|
+
expect(onChange).toHaveBeenCalledWith(items[6]);
|
|
198
228
|
});
|
|
199
229
|
});
|
|
200
230
|
//# sourceMappingURL=SelectInput.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectInput.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import SelectInput from './SelectInput.js'\nimport {waitForInputsToBeReady, waitForChange, sendInput} from '../../../../testing/ui.js'\nimport {describe, expect, test, vi} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\nconst ARROW_UP = '\\u001B[A'\nconst ARROW_DOWN = '\\u001B[B'\nconst ENTER = '\\r'\n\ndescribe('SelectInput', async () => {\n test('move up with up arrow key', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onSelect={() => {}} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_UP)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(3) Third\u001b[39m\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n })\n\n test('move down with down arrow key', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onSelect={() => {}} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n \u001b[36m>\u001b[39m \u001b[36m(2) Second\u001b[39m\n (3) Third\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n })\n\n test('select item with enter key', async () => {\n const onEnter = vi.fn()\n\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onSelect={onEnter} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_DOWN)\n await waitForChange(\n () => renderInstance.stdin.write(ENTER),\n () => onEnter.mock.calls.length,\n )\n\n expect(onEnter).toHaveBeenCalledWith(items[1]!.value)\n })\n\n test('handles keys with multiple digits', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Tenth',\n value: 'tenth',\n key: '10',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onSelect={() => {}} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, '1', '0')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(10) Tenth\u001b[39m\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n })\n\n test('handles custom keys', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n key: 't',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onSelect={() => {}} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, 't')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(t) Third\u001b[39m\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n })\n\n test('rotate after reaching the end of the list', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onSelect={() => {}} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_DOWN)\n await sendInput(renderInstance, ARROW_DOWN)\n await sendInput(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(1) First\u001b[39m\n (2) Second\n (3) Third\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n })\n\n test('support groups', async () => {\n const items = [\n {label: 'first', value: 'first', key: 'f'},\n {label: 'second', value: 'second', key: 's'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\n {label: 'fifth', value: 'fifth', group: 'Automations'},\n {label: 'sixth', value: 'sixth', group: 'Automations'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth', group: 'Merchant Admin'},\n {label: 'ninth', value: 'ninth', group: 'Merchant Admin'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(<SelectInput items={items} onSelect={() => {}} />)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(f) first\u001b[39m\n (s) second\n (3) third\n (4) fourth\n (5) seventh\n (6) tenth\n\n \u001b[1mAutomations\u001b[22m\n (7) fifth\n (8) sixth\n\n \u001b[1mMerchant Admin\u001b[22m\n (9) eighth\n (10) ninth\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"SelectInput.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import SelectInput from './SelectInput.js'\nimport {waitForInputsToBeReady, sendInput} from '../../../../testing/ui.js'\nimport {describe, expect, test, vi} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\nconst ARROW_UP = '\\u001B[A'\nconst ARROW_DOWN = '\\u001B[B'\n\ndescribe('SelectInput', async () => {\n test('move up with up arrow key', async () => {\n const onChange = vi.fn()\n\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_UP)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(3) Third\u001b[39m\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('move down with down arrow key', async () => {\n const onChange = vi.fn()\n\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n \u001b[36m>\u001b[39m \u001b[36m(2) Second\u001b[39m\n (3) Third\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[1]!)\n })\n\n test('handles keys with multiple digits', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Tenth',\n value: 'tenth',\n key: '10',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, '1', '0')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(10) Tenth\u001b[39m\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('handles custom keys', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n key: 't',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, 't')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(t) Third\u001b[39m\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('rotate after reaching the end of the list', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_DOWN)\n await sendInput(renderInstance, ARROW_DOWN)\n await sendInput(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(1) First\u001b[39m\n (2) Second\n (3) Third\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[0]!)\n })\n\n test('support groups', async () => {\n const onChange = vi.fn()\n\n const items = [\n {label: 'first', value: 'first', key: 'f'},\n {label: 'second', value: 'second', key: 's'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\n {label: 'fifth', value: 'fifth', group: 'Automations', key: 'a'},\n {label: 'sixth', value: 'sixth', group: 'Automations'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth', group: 'Merchant Admin'},\n {label: 'ninth', value: 'ninth', group: 'Merchant Admin'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(f) first\u001b[39m\n (s) second\n (3) third\n (4) fourth\n (5) seventh\n (6) tenth\n\n \u001b[1mAutomations\u001b[22m\n (a) fifth\n (8) sixth\n\n \u001b[1mMerchant Admin\u001b[22m\n (9) eighth\n (10) ninth\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, 'a')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (f) first\n (s) second\n (3) third\n (4) fourth\n (5) seventh\n (6) tenth\n\n \u001b[1mAutomations\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36m(a) fifth\u001b[39m\n (8) sixth\n\n \u001b[1mMerchant Admin\u001b[22m\n (9) eighth\n (10) ninth\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[4]!)\n\n await sendInput(renderInstance, ARROW_UP)\n await sendInput(renderInstance, ARROW_UP)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (f) first\n (s) second\n (3) third\n (4) fourth\n \u001b[36m>\u001b[39m \u001b[36m(5) seventh\u001b[39m\n (6) tenth\n\n \u001b[1mAutomations\u001b[22m\n (a) fifth\n (8) sixth\n\n \u001b[1mMerchant Admin\u001b[22m\n (9) eighth\n (10) ninth\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[6]!)\n })\n})\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Props as SelectProps } from './SelectInput.js';
|
|
2
2
|
import { Props as TableProps } from './Table.js';
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { ReactElement } from 'react';
|
|
4
4
|
export interface Props<T> {
|
|
5
5
|
message: string;
|
|
6
6
|
choices: SelectProps<T>['items'];
|
|
7
|
-
|
|
7
|
+
onSubmit: (value: T) => void;
|
|
8
8
|
infoTable?: TableProps['table'];
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
declare function SelectPrompt<T>({ message, choices, infoTable, onSubmit, }: React.PropsWithChildren<Props<T>>): ReactElement | null;
|
|
11
|
+
export { SelectPrompt };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import SelectInput from './SelectInput.js';
|
|
2
|
+
import Table from './Table.js';
|
|
3
|
+
import { handleCtrlC } from '../../ui.js';
|
|
4
|
+
import React, { useCallback, useState } from 'react';
|
|
5
|
+
import { Box, measureElement, Text, useApp, useInput, useStdout } from 'ink';
|
|
6
|
+
import { figures } from 'listr2';
|
|
7
|
+
import ansiEscapes from 'ansi-escapes';
|
|
8
|
+
function SelectPrompt({ message, choices, infoTable, onSubmit, }) {
|
|
9
|
+
const [answer, setAnswer] = useState(choices[0]);
|
|
10
|
+
const { exit: unmountInk } = useApp();
|
|
11
|
+
const [submitted, setSubmitted] = useState(false);
|
|
12
|
+
const { stdout } = useStdout();
|
|
13
|
+
const [height, setHeight] = useState(0);
|
|
14
|
+
const measuredRef = useCallback((node) => {
|
|
15
|
+
if (node !== null) {
|
|
16
|
+
const { height } = measureElement(node);
|
|
17
|
+
setHeight(height);
|
|
18
|
+
}
|
|
19
|
+
}, []);
|
|
20
|
+
useInput(useCallback((input, key) => {
|
|
21
|
+
handleCtrlC(input, key);
|
|
22
|
+
if (key.return) {
|
|
23
|
+
if (stdout && height >= stdout.rows) {
|
|
24
|
+
stdout.write(ansiEscapes.clearTerminal);
|
|
25
|
+
}
|
|
26
|
+
setSubmitted(true);
|
|
27
|
+
unmountInk();
|
|
28
|
+
onSubmit(answer.value);
|
|
29
|
+
}
|
|
30
|
+
}, [answer, onSubmit, height]));
|
|
31
|
+
return (React.createElement(Box, { flexDirection: "column", marginBottom: 1, ref: measuredRef },
|
|
32
|
+
React.createElement(Box, null,
|
|
33
|
+
React.createElement(Box, { marginRight: 2 },
|
|
34
|
+
React.createElement(Text, null, "?")),
|
|
35
|
+
React.createElement(Text, null, message)),
|
|
36
|
+
infoTable && !submitted && (React.createElement(Box, { marginLeft: 7 },
|
|
37
|
+
React.createElement(Table, { table: infoTable }))),
|
|
38
|
+
submitted ? (React.createElement(Box, null,
|
|
39
|
+
React.createElement(Box, { marginRight: 2 },
|
|
40
|
+
React.createElement(Text, { color: "cyan" }, figures.tick)),
|
|
41
|
+
React.createElement(Text, { color: "cyan" }, answer.label))) : (React.createElement(SelectInput, { items: choices, onChange: (item) => {
|
|
42
|
+
setAnswer(item);
|
|
43
|
+
} }))));
|
|
44
|
+
}
|
|
45
|
+
export { SelectPrompt };
|
|
46
|
+
//# sourceMappingURL=SelectPrompt.js.map
|