@shopify/cli-kit 3.46.2 → 3.47.0-pre.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/assets/cli-ruby/lib/graphql/extension_create.graphql +1 -0
- package/assets/cli-ruby/lib/graphql/extension_update_draft.graphql +1 -0
- package/assets/cli-ruby/lib/graphql/get_extension_registrations.graphql +1 -0
- package/assets/cli-ruby/lib/shopify_cli/theme/dev_server/cdn_fonts.rb +8 -3
- package/assets/cli-ruby/lib/shopify_cli/theme/dev_server/local_assets.rb +13 -4
- package/assets/cli-ruby/lib/shopify_cli/theme/dev_server.rb +1 -1
- package/assets/cli-ruby/lib/shopify_cli/theme/extension/dev_server/local_assets.rb +2 -1
- package/assets/cli-ruby/lib/shopify_cli/theme/extension/dev_server.rb +1 -1
- package/assets/cli-ruby/lib/shopify_cli/theme/repl/auth_dev_server.rb +1 -1
- package/dist/private/node/api.d.ts +1 -1
- package/dist/private/node/api.js +1 -1
- package/dist/private/node/api.js.map +1 -1
- package/dist/private/node/session/exchange.d.ts +1 -0
- package/dist/private/node/session/exchange.js +3 -1
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/identity.js +12 -0
- package/dist/private/node/session/identity.js.map +1 -1
- package/dist/private/node/session/scopes.js +5 -1
- package/dist/private/node/session/scopes.js.map +1 -1
- package/dist/private/node/session.d.ts +7 -0
- package/dist/private/node/session.js +8 -1
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/ui/components/Alert.js +7 -12
- package/dist/private/node/ui/components/Alert.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.js +7 -10
- package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -1
- package/dist/private/node/ui/components/Banner.js +9 -11
- package/dist/private/node/ui/components/Banner.js.map +1 -1
- package/dist/private/node/ui/components/Banner.test.js +63 -29
- package/dist/private/node/ui/components/Banner.test.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.js +5 -6
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.js +8 -11
- package/dist/private/node/ui/components/FatalError.js.map +1 -1
- package/dist/private/node/ui/components/List.js +2 -4
- package/dist/private/node/ui/components/List.js.map +1 -1
- package/dist/private/node/ui/components/List.test.js +32 -0
- package/dist/private/node/ui/components/List.test.js.map +1 -1
- package/dist/private/node/ui/components/Prompts/InfoTable.js +2 -3
- package/dist/private/node/ui/components/Prompts/InfoTable.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.d.ts +9 -7
- package/dist/private/node/ui/components/SelectInput.js +41 -61
- package/dist/private/node/ui/components/SelectInput.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.test.js +205 -62
- package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
- package/dist/private/node/ui/components/SelectPrompt.js +4 -16
- package/dist/private/node/ui/components/SelectPrompt.js.map +1 -1
- package/dist/private/node/ui/components/SelectPrompt.test.js +29 -0
- package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/TextAnimation.d.ts +2 -2
- package/dist/private/node/ui/components/TextAnimation.js +4 -3
- package/dist/private/node/ui/components/TextAnimation.js.map +1 -1
- package/dist/private/node/ui/hooks/use-select-state.d.ts +85 -0
- package/dist/private/node/ui/hooks/use-select-state.js +180 -0
- package/dist/private/node/ui/hooks/use-select-state.js.map +1 -0
- package/dist/private/node/ui.js +2 -1
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/api/business-platform.d.ts +10 -0
- package/dist/public/node/api/business-platform.js +25 -0
- package/dist/public/node/api/business-platform.js.map +1 -0
- package/dist/public/node/context/fqdn.d.ts +6 -0
- package/dist/public/node/context/fqdn.js +17 -0
- package/dist/public/node/context/fqdn.js.map +1 -1
- package/dist/public/node/metadata.d.ts +1 -1
- package/dist/public/node/metadata.js.map +1 -1
- package/dist/public/node/monorail.d.ts +2 -1
- package/dist/public/node/monorail.js +1 -1
- package/dist/public/node/monorail.js.map +1 -1
- package/dist/public/node/session.d.ts +7 -0
- package/dist/public/node/session.js +16 -0
- package/dist/public/node/session.js.map +1 -1
- package/dist/public/node/ui.d.ts +2 -2
- package/dist/public/node/ui.js +2 -2
- package/dist/public/node/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -18,6 +18,38 @@ describe('List', async () => {
|
|
|
18
18
|
• Item 3"
|
|
19
19
|
`);
|
|
20
20
|
});
|
|
21
|
+
test('renders items with margin or not', async () => {
|
|
22
|
+
const options = {
|
|
23
|
+
items: ['Item 1', 'Item 2', 'Item 3'],
|
|
24
|
+
margin: true,
|
|
25
|
+
};
|
|
26
|
+
const { lastFrame: marginLastFrame } = render(React.createElement(List, { ...options }));
|
|
27
|
+
expect(unstyled(marginLastFrame())).toMatchInlineSnapshot(`
|
|
28
|
+
" • Item 1
|
|
29
|
+
• Item 2
|
|
30
|
+
• Item 3"
|
|
31
|
+
`);
|
|
32
|
+
const { lastFrame: noMarginLastFrame } = render(React.createElement(List, { ...options, margin: false }));
|
|
33
|
+
expect(unstyled(noMarginLastFrame())).toMatchInlineSnapshot(`
|
|
34
|
+
"• Item 1
|
|
35
|
+
• Item 2
|
|
36
|
+
• Item 3"
|
|
37
|
+
`);
|
|
38
|
+
});
|
|
39
|
+
test('can give the text a color', async () => {
|
|
40
|
+
const options = {
|
|
41
|
+
title: 'List title',
|
|
42
|
+
items: ['Item 1', 'Item 2', 'Item 3'],
|
|
43
|
+
color: 'red',
|
|
44
|
+
};
|
|
45
|
+
const { lastFrame } = render(React.createElement(List, { ...options }));
|
|
46
|
+
expect(lastFrame()).toMatchInlineSnapshot(`
|
|
47
|
+
"[31mList title[39m
|
|
48
|
+
[31m•[39m [31mItem 1[39m
|
|
49
|
+
[31m•[39m [31mItem 2[39m
|
|
50
|
+
[31m•[39m [31mItem 3[39m"
|
|
51
|
+
`);
|
|
52
|
+
});
|
|
21
53
|
test('renders ordered items', async () => {
|
|
22
54
|
const options = {
|
|
23
55
|
items: ['Item 1', 'Item 2', '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,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAC1D,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,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;IAEF,IAAI,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,OAAO,GAAG;YACd,KAAK,EAAE;gBACL,YAAY;gBACZ;oBACE,IAAI,EAAE,SAAS;iBAChB;aACF;YACD,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,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {List} from './List.js'\nimport {unstyled} from '../../../../public/node/output.js'\nimport {render} from '../../testing/ui.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\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 test('title can be made of tokens', async () => {\n const options = {\n title: [\n 'List title',\n {\n bold: ' (bold)',\n },\n ],\n items: ['Item 1', 'Item 2', 'Item 3'],\n ordered: false,\n }\n\n const {lastFrame} = render(<List {...options} />)\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"List title \u001b[1m (bold)\u001b[22m\n • Item 1\n • Item 2\n • Item 3\"\n `)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"List.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/List.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {List} from './List.js'\nimport {unstyled} from '../../../../public/node/output.js'\nimport {render} from '../../testing/ui.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\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 items with margin or not', async () => {\n const options = {\n items: ['Item 1', 'Item 2', 'Item 3'],\n margin: true,\n }\n\n const {lastFrame: marginLastFrame} = render(<List {...options} />)\n\n expect(unstyled(marginLastFrame()!)).toMatchInlineSnapshot(`\n \" • Item 1\n • Item 2\n • Item 3\"\n `)\n\n const {lastFrame: noMarginLastFrame} = render(<List {...options} margin={false} />)\n\n expect(unstyled(noMarginLastFrame()!)).toMatchInlineSnapshot(`\n \"• Item 1\n • Item 2\n • Item 3\"\n `)\n })\n\n test('can give the text a color', async () => {\n const options = {\n title: 'List title',\n items: ['Item 1', 'Item 2', 'Item 3'],\n color: 'red',\n }\n\n const {lastFrame} = render(<List {...options} />)\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[31mList title\u001b[39m\n \u001b[31m•\u001b[39m \u001b[31mItem 1\u001b[39m\n \u001b[31m•\u001b[39m \u001b[31mItem 2\u001b[39m\n \u001b[31m•\u001b[39m \u001b[31mItem 3\u001b[39m\"\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 test('title can be made of tokens', async () => {\n const options = {\n title: [\n 'List title',\n {\n bold: ' (bold)',\n },\n ],\n items: ['Item 1', 'Item 2', 'Item 3'],\n ordered: false,\n }\n\n const {lastFrame} = render(<List {...options} />)\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"List title \u001b[1m (bold)\u001b[22m\n • Item 1\n • Item 2\n • Item 3\"\n `)\n })\n})\n"]}
|
|
@@ -16,10 +16,9 @@ const InfoTable = ({ table }) => {
|
|
|
16
16
|
React.createElement(Text, { color: section.color },
|
|
17
17
|
capitalize(section.header),
|
|
18
18
|
":"))),
|
|
19
|
-
React.createElement(Box, { marginLeft: section.header.length > 0 ? 2 : 0, flexGrow: 1, flexDirection: "column" },
|
|
19
|
+
React.createElement(Box, { marginLeft: section.header.length > 0 ? 2 : 0, flexGrow: 1, flexDirection: "column", gap: 1 },
|
|
20
20
|
React.createElement(List, { margin: false, items: section.items, color: section.color }),
|
|
21
|
-
section.helperText ?
|
|
22
|
-
React.createElement(Text, { color: section.color }, section.helperText))) : null))))));
|
|
21
|
+
section.helperText ? React.createElement(Text, { color: section.color }, section.helperText) : null))))));
|
|
23
22
|
};
|
|
24
23
|
export { InfoTable };
|
|
25
24
|
//# sourceMappingURL=InfoTable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfoTable.js","sourceRoot":"","sources":["../../../../../../src/private/node/ui/components/Prompts/InfoTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAA;AAC/B,OAAO,EAAC,UAAU,EAAC,MAAM,wCAAwC,CAAA;AAEjE,OAAO,EAAC,GAAG,EAAE,IAAI,EAAY,MAAM,KAAK,CAAA;AACxC,OAAO,KAA0B,MAAM,OAAO,CAAA;AAmB9C,MAAM,SAAS,GAAsC,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAC,CAAC,CAAC,CAAA;IAElH,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAChC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC1B,OAAO,IAAI,CAAC,GAAG,CACb,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACzC,OAAO,IAAI,CAAC,MAAM,CAAA;QACpB,CAAC,CAAC,CACH,CAAA;IACH,CAAC,CAAC,CACH,CAAA;IAED,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,IACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,oBAAC,GAAG,IAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAC5B,oBAAC,GAAG,IAAC,KAAK,EAAE,iBAAiB,GAAG,CAAC;YAC/B,oBAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK;gBAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;oBAAS,CAC5D,CACP;QACD,oBAAC,GAAG,IAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ;
|
|
1
|
+
{"version":3,"file":"InfoTable.js","sourceRoot":"","sources":["../../../../../../src/private/node/ui/components/Prompts/InfoTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAA;AAC/B,OAAO,EAAC,UAAU,EAAC,MAAM,wCAAwC,CAAA;AAEjE,OAAO,EAAC,GAAG,EAAE,IAAI,EAAY,MAAM,KAAK,CAAA;AACxC,OAAO,KAA0B,MAAM,OAAO,CAAA;AAmB9C,MAAM,SAAS,GAAsC,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAC,CAAC,CAAC,CAAA;IAElH,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAChC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC1B,OAAO,IAAI,CAAC,GAAG,CACb,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACzC,OAAO,IAAI,CAAC,MAAM,CAAA;QACpB,CAAC,CAAC,CACH,CAAA;IACH,CAAC,CAAC,CACH,CAAA;IAED,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,IACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,oBAAC,GAAG,IAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAC5B,oBAAC,GAAG,IAAC,KAAK,EAAE,iBAAiB,GAAG,CAAC;YAC/B,oBAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK;gBAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;oBAAS,CAC5D,CACP;QACD,oBAAC,GAAG,IAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC;YAC5F,oBAAC,IAAI,IAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,GAAI;YAClE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,oBAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAG,OAAO,CAAC,UAAU,CAAQ,CAAC,CAAC,CAAC,IAAI,CAChF,CACF,CACP,CAAC,CACE,CACP,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,SAAS,EAAC,CAAA","sourcesContent":["import {List} from '../List.js'\nimport {capitalize} from '../../../../../public/common/string.js'\nimport {InlineToken, TokenItem} from '../TokenizedText.js'\nimport {Box, Text, TextProps} from 'ink'\nimport React, {FunctionComponent} from 'react'\n\ntype Items = TokenItem<InlineToken>[]\n\nexport interface InfoTableSection {\n color?: TextProps['color']\n header: string\n helperText?: string\n items: Items\n}\n\nexport interface InfoTableProps {\n table:\n | {\n [header: string]: Items\n }\n | InfoTableSection[]\n}\n\nconst InfoTable: FunctionComponent<InfoTableProps> = ({table}) => {\n const sections = Array.isArray(table)\n ? table\n : Object.keys(table).map((header) => ({header, items: table[header]!, color: undefined, helperText: undefined}))\n\n const headerColumnWidth = Math.max(\n ...sections.map((section) => {\n return Math.max(\n ...section.header.split('\\n').map((line) => {\n return line.length\n }),\n )\n }),\n )\n\n return (\n <Box flexDirection=\"column\">\n {sections.map((section, index) => (\n <Box key={index} marginBottom={index === sections.length - 1 ? 0 : 1}>\n {section.header.length > 0 && (\n <Box width={headerColumnWidth + 1}>\n <Text color={section.color}>{capitalize(section.header)}:</Text>\n </Box>\n )}\n <Box marginLeft={section.header.length > 0 ? 2 : 0} flexGrow={1} flexDirection=\"column\" gap={1}>\n <List margin={false} items={section.items} color={section.color} />\n {section.helperText ? <Text color={section.color}>{section.helperText}</Text> : null}\n </Box>\n </Box>\n ))}\n </Box>\n )\n}\n\nexport {InfoTable}\n"]}
|
|
@@ -3,17 +3,13 @@ import { DOMElement } from 'ink';
|
|
|
3
3
|
declare module 'react' {
|
|
4
4
|
function forwardRef<T, P>(render: (props: P, ref: React.Ref<T>) => JSX.Element | null): (props: P & React.RefAttributes<T>) => JSX.Element | null;
|
|
5
5
|
}
|
|
6
|
-
interface OnChangeOptions<T> {
|
|
7
|
-
item: Item<T> | undefined;
|
|
8
|
-
usedShortcut: boolean;
|
|
9
|
-
}
|
|
10
6
|
export interface SelectInputProps<T> {
|
|
11
7
|
items: Item<T>[];
|
|
12
|
-
onChange
|
|
8
|
+
onChange?: (item: Item<T> | undefined) => void;
|
|
13
9
|
enableShortcuts?: boolean;
|
|
14
10
|
focus?: boolean;
|
|
15
11
|
emptyMessage?: string;
|
|
16
|
-
defaultValue?:
|
|
12
|
+
defaultValue?: T;
|
|
17
13
|
highlightedTerm?: string;
|
|
18
14
|
loading?: boolean;
|
|
19
15
|
errorMessage?: string;
|
|
@@ -21,12 +17,18 @@ export interface SelectInputProps<T> {
|
|
|
21
17
|
morePagesMessage?: string;
|
|
22
18
|
infoMessage?: string;
|
|
23
19
|
limit?: number;
|
|
20
|
+
submitWithShortcuts?: boolean;
|
|
21
|
+
onSubmit?: (item: Item<T>) => void;
|
|
24
22
|
}
|
|
25
23
|
export interface Item<T> {
|
|
26
24
|
label: string;
|
|
27
25
|
value: T;
|
|
28
26
|
key?: string;
|
|
29
27
|
group?: string;
|
|
28
|
+
helperText?: string;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface ItemWithKey<T> extends Item<T> {
|
|
32
|
+
key: string;
|
|
30
33
|
}
|
|
31
34
|
export declare const SelectInput: <T>(props: SelectInputProps<T> & React.RefAttributes<DOMElement>) => JSX.Element | null;
|
|
32
|
-
export {};
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { isEqual } from '../../../../public/common/lang.js';
|
|
2
1
|
import { debounce } from '../../../../public/common/function.js';
|
|
3
|
-
import
|
|
2
|
+
import { useSelectState } from '../hooks/use-select-state.js';
|
|
3
|
+
import { handleCtrlC } from '../../ui.js';
|
|
4
|
+
import React, { useRef, useCallback, forwardRef, useEffect } from 'react';
|
|
4
5
|
import { Box, useInput, Text } from 'ink';
|
|
5
6
|
import chalk from 'chalk';
|
|
6
7
|
import figures from 'figures';
|
|
7
8
|
import { createRequire } from 'module';
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
9
|
-
function rotateArray(array, rotation) {
|
|
10
|
-
const arrayCopy = array.slice();
|
|
11
|
-
return arrayCopy.splice(-(rotation ?? 0) % arrayCopy.length).concat(arrayCopy);
|
|
12
|
-
}
|
|
13
10
|
function highlightedLabel(label, term) {
|
|
14
11
|
if (!term) {
|
|
15
12
|
return label;
|
|
@@ -20,10 +17,16 @@ function highlightedLabel(label, term) {
|
|
|
20
17
|
});
|
|
21
18
|
}
|
|
22
19
|
// eslint-disable-next-line react/function-component-definition
|
|
23
|
-
function Item({ item, previousItem,
|
|
24
|
-
const isSelected = items.indexOf(item) === selectedIndex;
|
|
20
|
+
function Item({ item, previousItem, isSelected, highlightedTerm, enableShortcuts, items, hasAnyGroup, }) {
|
|
25
21
|
const label = highlightedLabel(item.label, highlightedTerm);
|
|
26
22
|
let title;
|
|
23
|
+
let labelColor;
|
|
24
|
+
if (isSelected) {
|
|
25
|
+
labelColor = 'cyan';
|
|
26
|
+
}
|
|
27
|
+
else if (item.disabled) {
|
|
28
|
+
labelColor = 'dim';
|
|
29
|
+
}
|
|
27
30
|
if (typeof previousItem === 'undefined' || item.group !== previousItem.group) {
|
|
28
31
|
title = item.group ?? (hasAnyGroup ? 'Other' : undefined);
|
|
29
32
|
}
|
|
@@ -32,10 +35,10 @@ function Item({ item, previousItem, selectedIndex, highlightedTerm, enableShortc
|
|
|
32
35
|
React.createElement(Text, { bold: true }, title))) : null,
|
|
33
36
|
React.createElement(Box, { key: item.key },
|
|
34
37
|
React.createElement(Box, { marginRight: 2 }, isSelected ? React.createElement(Text, { color: "cyan" }, `>`) : React.createElement(Text, null, " ")),
|
|
35
|
-
React.createElement(Text, { color:
|
|
38
|
+
React.createElement(Text, { color: labelColor }, enableShortcuts ? `(${item.key}) ${label}` : label))));
|
|
36
39
|
}
|
|
37
40
|
// eslint-disable-next-line react/function-component-definition
|
|
38
|
-
function SelectInputInner({ items: initialItems, onChange, enableShortcuts = true, focus = true, emptyMessage = 'No items to select.', defaultValue, highlightedTerm, loading = false, errorMessage, hasMorePages = false, morePagesMessage, infoMessage, limit, }, ref) {
|
|
41
|
+
function SelectInputInner({ items: initialItems, onChange, enableShortcuts = true, focus = true, emptyMessage = 'No items to select.', defaultValue, highlightedTerm, loading = false, errorMessage, hasMorePages = false, morePagesMessage, infoMessage, limit, submitWithShortcuts = false, onSubmit, }, ref) {
|
|
39
42
|
const sortBy = require('lodash/sortBy');
|
|
40
43
|
const hasAnyGroup = initialItems.some((item) => typeof item.group !== 'undefined');
|
|
41
44
|
const items = sortBy(initialItems, 'group');
|
|
@@ -43,69 +46,39 @@ function SelectInputInner({ items: initialItems, onChange, enableShortcuts = tru
|
|
|
43
46
|
...item,
|
|
44
47
|
key: item.key ?? (index + 1).toString(),
|
|
45
48
|
}));
|
|
46
|
-
const defaultValueIndex = defaultValue ? items.findIndex((item) => item.value === defaultValue.value) : -1;
|
|
47
|
-
const initialIndex = defaultValueIndex === -1 ? 0 : defaultValueIndex;
|
|
48
49
|
const hasLimit = typeof limit !== 'undefined' && items.length > limit;
|
|
49
50
|
const inputStack = useRef(null);
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
setSelectedIndex(newSelectedIndex);
|
|
56
|
-
if (typeof newRotateIndex !== 'undefined')
|
|
57
|
-
setRotateIndex(newRotateIndex);
|
|
58
|
-
const rotatedItems = hasLimit ? rotateArray(items, newRotateIndex).slice(0, limit) : items;
|
|
59
|
-
onChange({
|
|
60
|
-
item: rotatedItems[newSelectedIndex],
|
|
61
|
-
usedShortcut,
|
|
62
|
-
});
|
|
63
|
-
}, [hasLimit, items, limit, onChange]);
|
|
51
|
+
const state = useSelectState({
|
|
52
|
+
visibleOptionCount: limit,
|
|
53
|
+
options: itemsWithKeys,
|
|
54
|
+
defaultValue,
|
|
55
|
+
});
|
|
64
56
|
useEffect(() => {
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
onChange({
|
|
68
|
-
item: undefined,
|
|
69
|
-
usedShortcut: false,
|
|
70
|
-
});
|
|
71
|
-
// reset index when items change or the first time
|
|
57
|
+
if (typeof state.value !== 'undefined' && state.previousValue !== state.value) {
|
|
58
|
+
onChange?.(items.find((item) => item.value === state.value));
|
|
72
59
|
}
|
|
73
|
-
|
|
74
|
-
changeSelection({ newSelectedIndex: initialIndex, newRotateIndex: 0 });
|
|
75
|
-
}
|
|
76
|
-
else if (!isEqual(previousItems.current.map((item) => item.value), items.map((item) => item.value))) {
|
|
77
|
-
changeSelection({ newSelectedIndex: 0, newRotateIndex: 0 });
|
|
78
|
-
}
|
|
79
|
-
previousItems.current = items;
|
|
80
|
-
}, [changeSelection, initialIndex, items, onChange]);
|
|
60
|
+
}, [state.previousValue, state.value, items, onChange]);
|
|
81
61
|
const handleArrows = (key) => {
|
|
82
62
|
if (key.upArrow) {
|
|
83
|
-
|
|
84
|
-
const atFirstIndex = selectedIndex === 0;
|
|
85
|
-
const nextIndex = hasLimit ? selectedIndex : lastIndex;
|
|
86
|
-
const nextRotateIndex = atFirstIndex ? rotateIndex + 1 : rotateIndex;
|
|
87
|
-
const nextSelectedIndex = atFirstIndex ? nextIndex : selectedIndex - 1;
|
|
88
|
-
changeSelection({ newSelectedIndex: nextSelectedIndex, newRotateIndex: nextRotateIndex });
|
|
63
|
+
state.selectPreviousOption();
|
|
89
64
|
}
|
|
90
65
|
else if (key.downArrow) {
|
|
91
|
-
|
|
92
|
-
const nextIndex = hasLimit ? selectedIndex : 0;
|
|
93
|
-
const nextRotateIndex = atLastIndex ? rotateIndex - 1 : rotateIndex;
|
|
94
|
-
const nextSelectedIndex = atLastIndex ? nextIndex : selectedIndex + 1;
|
|
95
|
-
changeSelection({ newSelectedIndex: nextSelectedIndex, newRotateIndex: nextRotateIndex });
|
|
66
|
+
state.selectNextOption();
|
|
96
67
|
}
|
|
97
68
|
};
|
|
98
69
|
const handleShortcuts = useCallback((input) => {
|
|
99
|
-
if (
|
|
100
|
-
const itemWithKey =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
70
|
+
if (state.visibleOptions.map((item) => item.key).includes(input)) {
|
|
71
|
+
const itemWithKey = state.visibleOptions.find((item) => item.key === input);
|
|
72
|
+
const item = items.find((item) => item.value === itemWithKey?.value);
|
|
73
|
+
if (itemWithKey && !itemWithKey.disabled) {
|
|
74
|
+
// keep this order of operations so that there is no flickering
|
|
75
|
+
if (submitWithShortcuts && onSubmit && item) {
|
|
76
|
+
onSubmit(item);
|
|
77
|
+
}
|
|
78
|
+
state.selectOption({ option: itemWithKey });
|
|
106
79
|
}
|
|
107
80
|
}
|
|
108
|
-
}, [
|
|
81
|
+
}, [items, onSubmit, state, submitWithShortcuts]);
|
|
109
82
|
// disable exhaustive-deps because we want to memoize the debounce function itself
|
|
110
83
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
111
84
|
const debounceHandleShortcuts = useCallback(debounce((newInputStack) => {
|
|
@@ -113,6 +86,13 @@ function SelectInputInner({ items: initialItems, onChange, enableShortcuts = tru
|
|
|
113
86
|
inputStack.current = null;
|
|
114
87
|
}, 300), [handleShortcuts]);
|
|
115
88
|
useInput((input, key) => {
|
|
89
|
+
handleCtrlC(input, key);
|
|
90
|
+
if (typeof state.value !== 'undefined' && key.return) {
|
|
91
|
+
const item = items.find((item) => item.value === state.value);
|
|
92
|
+
if (item && onSubmit) {
|
|
93
|
+
onSubmit(item);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
116
96
|
// check that no special modifier (shift, control, etc.) is being pressed
|
|
117
97
|
if (enableShortcuts && input.length > 0 && Object.values(key).every((value) => value === false)) {
|
|
118
98
|
const newInputStack = inputStack.current === null ? input : inputStack.current + input;
|
|
@@ -139,7 +119,7 @@ function SelectInputInner({ items: initialItems, onChange, enableShortcuts = tru
|
|
|
139
119
|
}
|
|
140
120
|
else {
|
|
141
121
|
return (React.createElement(Box, { flexDirection: "column", ref: ref },
|
|
142
|
-
|
|
122
|
+
state.visibleOptions.map((item, index) => (React.createElement(Item, { key: item.key, item: item, previousItem: state.visibleOptions[index - 1], highlightedTerm: highlightedTerm, isSelected: item.value === state.value, items: state.visibleOptions, enableShortcuts: enableShortcuts, hasAnyGroup: hasAnyGroup }))),
|
|
143
123
|
React.createElement(Box, { marginTop: 1, marginLeft: 3, flexDirection: "column" },
|
|
144
124
|
hasMorePages ? (React.createElement(Text, null,
|
|
145
125
|
React.createElement(Text, { bold: true },
|
|
@@ -1 +1 @@
|
|
|
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 {debounce} from '../../../../public/common/function.js'\nimport React, {useState, useEffect, useRef, useCallback, forwardRef} from 'react'\nimport {Box, Key, useInput, Text, DOMElement} from 'ink'\nimport chalk from 'chalk'\nimport figures from 'figures'\nimport {createRequire} from 'module'\n\nconst require = createRequire(import.meta.url)\n\ndeclare module 'react' {\n function forwardRef<T, P>(\n render: (props: P, ref: React.Ref<T>) => JSX.Element | null,\n ): (props: P & React.RefAttributes<T>) => JSX.Element | null\n}\n\nfunction rotateArray<T>(array: T[], rotation?: number) {\n const arrayCopy = array.slice()\n return arrayCopy.splice(-(rotation ?? 0) % arrayCopy.length).concat(arrayCopy)\n}\n\ninterface OnChangeOptions<T> {\n item: Item<T> | undefined\n usedShortcut: boolean\n}\nexport interface SelectInputProps<T> {\n items: Item<T>[]\n onChange: ({item, usedShortcut}: OnChangeOptions<T>) => void\n enableShortcuts?: boolean\n focus?: boolean\n emptyMessage?: string\n defaultValue?: Item<T>\n highlightedTerm?: string\n loading?: boolean\n errorMessage?: string\n hasMorePages?: boolean\n morePagesMessage?: string\n infoMessage?: string\n limit?: number\n}\n\nexport interface Item<T> {\n label: string\n value: T\n key?: string\n group?: string\n}\n\ninterface ItemWithKey<T> extends Item<T> {\n key: string\n}\n\nfunction highlightedLabel(label: string, term: string | undefined) {\n if (!term) {\n return label\n }\n\n const regex = new RegExp(term, 'i')\n return label.replace(regex, (match) => {\n return chalk.bold(match)\n })\n}\n\ninterface ItemProps<T> {\n item: ItemWithKey<T>\n previousItem: ItemWithKey<T> | undefined\n items: ItemWithKey<T>[]\n selectedIndex: number\n highlightedTerm?: string\n enableShortcuts: boolean\n hasAnyGroup: boolean\n}\n\n// eslint-disable-next-line react/function-component-definition\nfunction Item<T>({\n item,\n previousItem,\n selectedIndex,\n highlightedTerm,\n enableShortcuts,\n items,\n hasAnyGroup,\n}: ItemProps<T>): JSX.Element {\n const isSelected = items.indexOf(item) === selectedIndex\n const label = highlightedLabel(item.label, highlightedTerm)\n let title: string | undefined\n\n if (typeof previousItem === 'undefined' || item.group !== previousItem.group) {\n title = item.group ?? (hasAnyGroup ? 'Other' : undefined)\n }\n\n return (\n <Box key={item.key} flexDirection=\"column\" marginTop={items.indexOf(item) !== 0 && title ? 1 : 0}>\n {title ? (\n <Box marginLeft={3}>\n <Text bold>{title}</Text>\n </Box>\n ) : null}\n\n <Box key={item.key}>\n <Box marginRight={2}>{isSelected ? <Text color=\"cyan\">{`>`}</Text> : <Text> </Text>}</Box>\n <Text color={isSelected ? 'cyan' : undefined}>{enableShortcuts ? `(${item.key}) ${label}` : label}</Text>\n </Box>\n </Box>\n )\n}\n\n// eslint-disable-next-line react/function-component-definition\nfunction SelectInputInner<T>(\n {\n items: initialItems,\n onChange,\n enableShortcuts = true,\n focus = true,\n emptyMessage = 'No items to select.',\n defaultValue,\n highlightedTerm,\n loading = false,\n errorMessage,\n hasMorePages = false,\n morePagesMessage,\n infoMessage,\n limit,\n }: SelectInputProps<T>,\n ref: React.ForwardedRef<DOMElement>,\n): JSX.Element | null {\n const sortBy = require('lodash/sortBy')\n const hasAnyGroup = initialItems.some((item) => typeof item.group !== 'undefined')\n const items = sortBy(initialItems, 'group') as Item<T>[]\n const itemsWithKeys = items.map((item, index) => ({\n ...item,\n key: item.key ?? (index + 1).toString(),\n })) as ItemWithKey<T>[]\n const defaultValueIndex = defaultValue ? items.findIndex((item) => item.value === defaultValue.value) : -1\n const initialIndex = defaultValueIndex === -1 ? 0 : defaultValueIndex\n const hasLimit = typeof limit !== 'undefined' && items.length > limit\n const inputStack = useRef<string | null>(null)\n const [selectedIndex, setSelectedIndex] = useState(initialIndex)\n const [rotateIndex, setRotateIndex] = useState(0)\n const slicedItemsWithKeys = hasLimit ? rotateArray(itemsWithKeys, rotateIndex).slice(0, limit) : itemsWithKeys\n const previousItems = useRef<Item<T>[] | undefined>(undefined)\n\n const changeSelection = useCallback(\n ({\n newSelectedIndex,\n newRotateIndex,\n usedShortcut = false,\n }: {\n newSelectedIndex: number\n usedShortcut?: boolean\n newRotateIndex?: number\n }) => {\n setSelectedIndex(newSelectedIndex)\n if (typeof newRotateIndex !== 'undefined') setRotateIndex(newRotateIndex)\n\n const rotatedItems = hasLimit ? rotateArray(items, newRotateIndex).slice(0, limit) : items\n\n onChange({\n item: rotatedItems[newSelectedIndex],\n usedShortcut,\n })\n },\n [hasLimit, items, limit, onChange],\n )\n\n useEffect(() => {\n if (items.length === 0) {\n // reset selection when items are empty\n onChange({\n item: undefined,\n usedShortcut: false,\n })\n // reset index when items change or the first time\n } else if (!previousItems.current) {\n changeSelection({newSelectedIndex: initialIndex, newRotateIndex: 0})\n } else if (\n !isEqual(\n previousItems.current.map((item) => item.value),\n items.map((item) => item.value),\n )\n ) {\n changeSelection({newSelectedIndex: 0, newRotateIndex: 0})\n }\n\n previousItems.current = items\n }, [changeSelection, initialIndex, items, onChange])\n\n const handleArrows = (key: Key) => {\n if (key.upArrow) {\n const lastIndex = items.length - 1\n const atFirstIndex = selectedIndex === 0\n const nextIndex = hasLimit ? selectedIndex : lastIndex\n const nextRotateIndex = atFirstIndex ? rotateIndex + 1 : rotateIndex\n const nextSelectedIndex = atFirstIndex ? nextIndex : selectedIndex - 1\n\n changeSelection({newSelectedIndex: nextSelectedIndex, newRotateIndex: nextRotateIndex})\n } else if (key.downArrow) {\n const atLastIndex = selectedIndex === (hasLimit ? limit : items.length) - 1\n const nextIndex = hasLimit ? selectedIndex : 0\n const nextRotateIndex = atLastIndex ? rotateIndex - 1 : rotateIndex\n const nextSelectedIndex = atLastIndex ? nextIndex : selectedIndex + 1\n\n changeSelection({newSelectedIndex: nextSelectedIndex, newRotateIndex: nextRotateIndex})\n }\n }\n\n const handleShortcuts = useCallback(\n (input: string) => {\n if (slicedItemsWithKeys.map((item) => item.key).includes(input)) {\n const itemWithKey = slicedItemsWithKeys.find((item) => item.key === input)\n if (itemWithKey !== undefined) {\n changeSelection({\n newSelectedIndex: items.findIndex((item) => item.value === itemWithKey.value),\n usedShortcut: true,\n })\n }\n }\n },\n [changeSelection, items, slicedItemsWithKeys],\n )\n\n // disable exhaustive-deps because we want to memoize the debounce function itself\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const debounceHandleShortcuts = useCallback(\n debounce((newInputStack) => {\n handleShortcuts(newInputStack)\n inputStack.current = null\n }, 300),\n [handleShortcuts],\n )\n\n useInput(\n (input, key) => {\n // check that no special modifier (shift, control, etc.) is being pressed\n if (enableShortcuts && input.length > 0 && Object.values(key).every((value) => value === false)) {\n const newInputStack = inputStack.current === null ? input : inputStack.current + input\n\n inputStack.current = newInputStack\n debounceHandleShortcuts(newInputStack)\n } else {\n debounceHandleShortcuts.cancel()\n inputStack.current = null\n handleArrows(key)\n }\n },\n {isActive: focus},\n )\n\n if (loading) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>Loading...</Text>\n </Box>\n )\n } else if (errorMessage && errorMessage.length > 0) {\n return (\n <Box marginLeft={3}>\n <Text color=\"red\">{errorMessage}</Text>\n </Box>\n )\n } else if (items.length === 0) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>{emptyMessage}</Text>\n </Box>\n )\n } else {\n return (\n <Box flexDirection=\"column\" ref={ref}>\n {slicedItemsWithKeys.map((item, index) => (\n <Item\n key={item.key}\n item={item}\n previousItem={slicedItemsWithKeys[index - 1]}\n highlightedTerm={highlightedTerm}\n selectedIndex={selectedIndex}\n items={slicedItemsWithKeys}\n enableShortcuts={enableShortcuts}\n hasAnyGroup={hasAnyGroup}\n />\n ))}\n\n <Box marginTop={1} marginLeft={3} flexDirection=\"column\">\n {hasMorePages ? (\n <Text>\n <Text bold>1-{items.length} of many</Text>\n {morePagesMessage ? ` ${morePagesMessage}` : null}\n </Text>\n ) : null}\n {hasLimit ? <Text dimColor>{`Showing ${limit} of ${items.length} items.`}</Text> : null}\n <Text dimColor>\n {infoMessage\n ? infoMessage\n : `Press ${figures.arrowUp}${figures.arrowDown} arrows to select, enter to confirm`}\n </Text>\n </Box>\n </Box>\n )\n }\n}\n\nexport const SelectInput = forwardRef(SelectInputInner)\n"]}
|
|
1
|
+
{"version":3,"file":"SelectInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,uCAAuC,CAAA;AAC9D,OAAO,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,EAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAC,MAAM,OAAO,CAAA;AACvE,OAAO,EAAC,GAAG,EAAO,QAAQ,EAAE,IAAI,EAAa,MAAM,KAAK,CAAA;AACxD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAC,aAAa,EAAC,MAAM,QAAQ,CAAA;AAEpC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAsC9C,SAAS,gBAAgB,CAAC,KAAa,EAAE,IAAwB;IAC/D,IAAI,CAAC,IAAI,EAAE;QACT,OAAO,KAAK,CAAA;KACb;IAED,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACnC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;AACJ,CAAC;AAYD,+DAA+D;AAC/D,SAAS,IAAI,CAAI,EACf,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,eAAe,EACf,KAAK,EACL,WAAW,GACE;IACb,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,CAAA;IAC3D,IAAI,KAAyB,CAAA;IAC7B,IAAI,UAAU,CAAA;IAEd,IAAI,UAAU,EAAE;QACd,UAAU,GAAG,MAAM,CAAA;KACpB;SAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;QACxB,UAAU,GAAG,KAAK,CAAA;KACnB;IAED,IAAI,OAAO,YAAY,KAAK,WAAW,IAAI,IAAI,CAAC,KAAK,KAAK,YAAY,CAAC,KAAK,EAAE;QAC5E,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAC1D;IAED,OAAO,CACL,oBAAC,GAAG,IAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7F,KAAK,CAAC,CAAC,CAAC,CACP,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAChB,oBAAC,IAAI,IAAC,IAAI,UAAE,KAAK,CAAQ,CACrB,CACP,CAAC,CAAC,CAAC,IAAI;QAER,oBAAC,GAAG,IAAC,GAAG,EAAE,IAAI,CAAC,GAAG;YAChB,oBAAC,GAAG,IAAC,WAAW,EAAE,CAAC,IAAG,UAAU,CAAC,CAAC,CAAC,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM,IAAE,GAAG,CAAQ,CAAC,CAAC,CAAC,oBAAC,IAAI,YAAS,CAAO;YAC1F,oBAAC,IAAI,IAAC,KAAK,EAAE,UAAU,IAAG,eAAe,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAQ,CAChF,CACF,CACP,CAAA;AACH,CAAC;AAED,+DAA+D;AAC/D,SAAS,gBAAgB,CACvB,EACE,KAAK,EAAE,YAAY,EACnB,QAAQ,EACR,eAAe,GAAG,IAAI,EACtB,KAAK,GAAG,IAAI,EACZ,YAAY,GAAG,qBAAqB,EACpC,YAAY,EACZ,eAAe,EACf,OAAO,GAAG,KAAK,EACf,YAAY,EACZ,YAAY,GAAG,KAAK,EACpB,gBAAgB,EAChB,WAAW,EACX,KAAK,EACL,mBAAmB,GAAG,KAAK,EAC3B,QAAQ,GACY,EACtB,GAAmC;IAEnC,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IACvC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,CAAA;IAClF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,EAAE,OAAO,CAAc,CAAA;IACxD,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAChD,GAAG,IAAI;QACP,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;KACxC,CAAC,CAAqB,CAAA;IACvB,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK,CAAA;IACrE,MAAM,UAAU,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAA;IAE9C,MAAM,KAAK,GAAG,cAAc,CAAC;QAC3B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,aAAa;QACtB,YAAY;KACb,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,KAAK,EAAE;YAC7E,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;SAC7D;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEvD,MAAM,YAAY,GAAG,CAAC,GAAQ,EAAE,EAAE;QAChC,IAAI,GAAG,CAAC,OAAO,EAAE;YACf,KAAK,CAAC,oBAAoB,EAAE,CAAA;SAC7B;aAAM,IAAI,GAAG,CAAC,SAAS,EAAE;YACxB,KAAK,CAAC,gBAAgB,EAAE,CAAA;SACzB;IACH,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,KAAa,EAAE,EAAE;QAChB,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;YAChE,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,CAAA;YAC3E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,KAAK,CAAC,CAAA;YAEpE,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE;gBACxC,+DAA+D;gBAC/D,IAAI,mBAAmB,IAAI,QAAQ,IAAI,IAAI,EAAE;oBAC3C,QAAQ,CAAC,IAAI,CAAC,CAAA;iBACf;gBAED,KAAK,CAAC,YAAY,CAAC,EAAC,MAAM,EAAE,WAAW,EAAC,CAAC,CAAA;aAC1C;SACF;IACH,CAAC,EACD,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAC9C,CAAA;IAED,kFAAkF;IAClF,uDAAuD;IACvD,MAAM,uBAAuB,GAAG,WAAW,CACzC,QAAQ,CAAC,CAAC,aAAa,EAAE,EAAE;QACzB,eAAe,CAAC,aAAa,CAAC,CAAA;QAC9B,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;IAC3B,CAAC,EAAE,GAAG,CAAC,EACP,CAAC,eAAe,CAAC,CAClB,CAAA;IAED,QAAQ,CACN,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACb,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAEvB,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE;YACpD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAA;YAE7D,IAAI,IAAI,IAAI,QAAQ,EAAE;gBACpB,QAAQ,CAAC,IAAI,CAAC,CAAA;aACf;SACF;QAED,yEAAyE;QACzE,IAAI,eAAe,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE;YAC/F,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,GAAG,KAAK,CAAA;YAEtF,UAAU,CAAC,OAAO,GAAG,aAAa,CAAA;YAClC,uBAAuB,CAAC,aAAa,CAAC,CAAA;SACvC;aAAM;YACL,uBAAuB,CAAC,MAAM,EAAE,CAAA;YAChC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;YACzB,YAAY,CAAC,GAAG,CAAC,CAAA;SAClB;IACH,CAAC,EACD,EAAC,QAAQ,EAAE,KAAK,EAAC,CAClB,CAAA;IAED,IAAI,OAAO,EAAE;QACX,OAAO,CACL,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAChB,oBAAC,IAAI,IAAC,QAAQ,uBAAkB,CAC5B,CACP,CAAA;KACF;SAAM,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;QAClD,OAAO,CACL,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAChB,oBAAC,IAAI,IAAC,KAAK,EAAC,KAAK,IAAE,YAAY,CAAQ,CACnC,CACP,CAAA;KACF;SAAM,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;QAC7B,OAAO,CACL,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAChB,oBAAC,IAAI,IAAC,QAAQ,UAAE,YAAY,CAAQ,CAChC,CACP,CAAA;KACF;SAAM;QACL,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,GAAG;YACjC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CACzC,oBAAC,IAAI,IACH,GAAG,EAAE,IAAI,CAAC,GAAG,EACb,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,GAAG,CAAC,CAAC,EAC7C,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EACtC,KAAK,EAAE,KAAK,CAAC,cAAc,EAC3B,eAAe,EAAE,eAAe,EAChC,WAAW,EAAE,WAAW,GACxB,CACH,CAAC;YAEF,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ;gBACrD,YAAY,CAAC,CAAC,CAAC,CACd,oBAAC,IAAI;oBACH,oBAAC,IAAI,IAAC,IAAI;;wBAAI,KAAK,CAAC,MAAM;mCAAgB;oBACzC,gBAAgB,CAAC,CAAC,CAAC,KAAK,gBAAgB,EAAE,CAAC,CAAC,CAAC,IAAI,CAC7C,CACR,CAAC,CAAC,CAAC,IAAI;gBACP,QAAQ,CAAC,CAAC,CAAC,oBAAC,IAAI,IAAC,QAAQ,UAAE,WAAW,KAAK,OAAO,KAAK,CAAC,MAAM,SAAS,CAAQ,CAAC,CAAC,CAAC,IAAI;gBACvF,oBAAC,IAAI,IAAC,QAAQ,UACX,WAAW;oBACV,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,SAAS,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,SAAS,qCAAqC,CAChF,CACH,CACF,CACP,CAAA;KACF;AACH,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAA","sourcesContent":["import {debounce} from '../../../../public/common/function.js'\nimport {useSelectState} from '../hooks/use-select-state.js'\nimport {handleCtrlC} from '../../ui.js'\nimport React, {useRef, useCallback, forwardRef, useEffect} from 'react'\nimport {Box, Key, useInput, Text, DOMElement} from 'ink'\nimport chalk from 'chalk'\nimport figures from 'figures'\nimport {createRequire} from 'module'\n\nconst require = createRequire(import.meta.url)\n\ndeclare module 'react' {\n function forwardRef<T, P>(\n render: (props: P, ref: React.Ref<T>) => JSX.Element | null,\n ): (props: P & React.RefAttributes<T>) => JSX.Element | null\n}\nexport interface SelectInputProps<T> {\n items: Item<T>[]\n onChange?: (item: Item<T> | undefined) => void\n enableShortcuts?: boolean\n focus?: boolean\n emptyMessage?: string\n defaultValue?: T\n highlightedTerm?: string\n loading?: boolean\n errorMessage?: string\n hasMorePages?: boolean\n morePagesMessage?: string\n infoMessage?: string\n limit?: number\n submitWithShortcuts?: boolean\n onSubmit?: (item: Item<T>) => void\n}\n\nexport interface Item<T> {\n label: string\n value: T\n key?: string\n group?: string\n helperText?: string\n disabled?: boolean\n}\n\nexport interface ItemWithKey<T> extends Item<T> {\n key: string\n}\n\nfunction highlightedLabel(label: string, term: string | undefined) {\n if (!term) {\n return label\n }\n\n const regex = new RegExp(term, 'i')\n return label.replace(regex, (match) => {\n return chalk.bold(match)\n })\n}\n\ninterface ItemProps<T> {\n item: ItemWithKey<T>\n previousItem: ItemWithKey<T> | undefined\n items: ItemWithKey<T>[]\n isSelected: boolean\n highlightedTerm?: string\n enableShortcuts: boolean\n hasAnyGroup: boolean\n}\n\n// eslint-disable-next-line react/function-component-definition\nfunction Item<T>({\n item,\n previousItem,\n isSelected,\n highlightedTerm,\n enableShortcuts,\n items,\n hasAnyGroup,\n}: ItemProps<T>): JSX.Element {\n const label = highlightedLabel(item.label, highlightedTerm)\n let title: string | undefined\n let labelColor\n\n if (isSelected) {\n labelColor = 'cyan'\n } else if (item.disabled) {\n labelColor = 'dim'\n }\n\n if (typeof previousItem === 'undefined' || item.group !== previousItem.group) {\n title = item.group ?? (hasAnyGroup ? 'Other' : undefined)\n }\n\n return (\n <Box key={item.key} flexDirection=\"column\" marginTop={items.indexOf(item) !== 0 && title ? 1 : 0}>\n {title ? (\n <Box marginLeft={3}>\n <Text bold>{title}</Text>\n </Box>\n ) : null}\n\n <Box key={item.key}>\n <Box marginRight={2}>{isSelected ? <Text color=\"cyan\">{`>`}</Text> : <Text> </Text>}</Box>\n <Text color={labelColor}>{enableShortcuts ? `(${item.key}) ${label}` : label}</Text>\n </Box>\n </Box>\n )\n}\n\n// eslint-disable-next-line react/function-component-definition\nfunction SelectInputInner<T>(\n {\n items: initialItems,\n onChange,\n enableShortcuts = true,\n focus = true,\n emptyMessage = 'No items to select.',\n defaultValue,\n highlightedTerm,\n loading = false,\n errorMessage,\n hasMorePages = false,\n morePagesMessage,\n infoMessage,\n limit,\n submitWithShortcuts = false,\n onSubmit,\n }: SelectInputProps<T>,\n ref: React.ForwardedRef<DOMElement>,\n): JSX.Element | null {\n const sortBy = require('lodash/sortBy')\n const hasAnyGroup = initialItems.some((item) => typeof item.group !== 'undefined')\n const items = sortBy(initialItems, 'group') as Item<T>[]\n const itemsWithKeys = items.map((item, index) => ({\n ...item,\n key: item.key ?? (index + 1).toString(),\n })) as ItemWithKey<T>[]\n const hasLimit = typeof limit !== 'undefined' && items.length > limit\n const inputStack = useRef<string | null>(null)\n\n const state = useSelectState({\n visibleOptionCount: limit,\n options: itemsWithKeys,\n defaultValue,\n })\n\n useEffect(() => {\n if (typeof state.value !== 'undefined' && state.previousValue !== state.value) {\n onChange?.(items.find((item) => item.value === state.value))\n }\n }, [state.previousValue, state.value, items, onChange])\n\n const handleArrows = (key: Key) => {\n if (key.upArrow) {\n state.selectPreviousOption()\n } else if (key.downArrow) {\n state.selectNextOption()\n }\n }\n\n const handleShortcuts = useCallback(\n (input: string) => {\n if (state.visibleOptions.map((item) => item.key).includes(input)) {\n const itemWithKey = state.visibleOptions.find((item) => item.key === input)\n const item = items.find((item) => item.value === itemWithKey?.value)\n\n if (itemWithKey && !itemWithKey.disabled) {\n // keep this order of operations so that there is no flickering\n if (submitWithShortcuts && onSubmit && item) {\n onSubmit(item)\n }\n\n state.selectOption({option: itemWithKey})\n }\n }\n },\n [items, onSubmit, state, submitWithShortcuts],\n )\n\n // disable exhaustive-deps because we want to memoize the debounce function itself\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const debounceHandleShortcuts = useCallback(\n debounce((newInputStack) => {\n handleShortcuts(newInputStack)\n inputStack.current = null\n }, 300),\n [handleShortcuts],\n )\n\n useInput(\n (input, key) => {\n handleCtrlC(input, key)\n\n if (typeof state.value !== 'undefined' && key.return) {\n const item = items.find((item) => item.value === state.value)\n\n if (item && onSubmit) {\n onSubmit(item)\n }\n }\n\n // check that no special modifier (shift, control, etc.) is being pressed\n if (enableShortcuts && input.length > 0 && Object.values(key).every((value) => value === false)) {\n const newInputStack = inputStack.current === null ? input : inputStack.current + input\n\n inputStack.current = newInputStack\n debounceHandleShortcuts(newInputStack)\n } else {\n debounceHandleShortcuts.cancel()\n inputStack.current = null\n handleArrows(key)\n }\n },\n {isActive: focus},\n )\n\n if (loading) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>Loading...</Text>\n </Box>\n )\n } else if (errorMessage && errorMessage.length > 0) {\n return (\n <Box marginLeft={3}>\n <Text color=\"red\">{errorMessage}</Text>\n </Box>\n )\n } else if (items.length === 0) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>{emptyMessage}</Text>\n </Box>\n )\n } else {\n return (\n <Box flexDirection=\"column\" ref={ref}>\n {state.visibleOptions.map((item, index) => (\n <Item\n key={item.key}\n item={item}\n previousItem={state.visibleOptions[index - 1]}\n highlightedTerm={highlightedTerm}\n isSelected={item.value === state.value}\n items={state.visibleOptions}\n enableShortcuts={enableShortcuts}\n hasAnyGroup={hasAnyGroup}\n />\n ))}\n\n <Box marginTop={1} marginLeft={3} flexDirection=\"column\">\n {hasMorePages ? (\n <Text>\n <Text bold>1-{items.length} of many</Text>\n {morePagesMessage ? ` ${morePagesMessage}` : null}\n </Text>\n ) : null}\n {hasLimit ? <Text dimColor>{`Showing ${limit} of ${items.length} items.`}</Text> : null}\n <Text dimColor>\n {infoMessage\n ? infoMessage\n : `Press ${figures.arrowUp}${figures.arrowDown} arrows to select, enter to confirm`}\n </Text>\n </Box>\n </Box>\n )\n }\n}\n\nexport const SelectInput = forwardRef(SelectInputInner)\n"]}
|